Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Added length() and substr() functions (CVS 143) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
0eef538f3de66fede7c88f8be8c3458d |
User & Date: | drh 2000-08-28 15:51:44.000 |
Context
2000-08-28
| ||
16:21 | adding length() and substr() tests. fix shell.c bug (CVS 144) (check-in: b8cec9b938 user: drh tags: trunk) | |
15:51 | Added length() and substr() functions (CVS 143) (check-in: 0eef538f3d user: drh tags: trunk) | |
2000-08-22
| ||
18:30 | Version 1.0.3 (CVS 497) (check-in: d35a1f8b37 user: drh tags: trunk) | |
Changes
Changes to src/expr.c.
︙ | |||
20 21 22 23 24 25 26 | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | - + | ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions. ** |
︙ | |||
319 320 321 322 323 324 325 326 327 328 329 330 331 332 | 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 | + + | } aFunc[] = { { "count", 5, FN_Count }, { "min", 3, FN_Min }, { "max", 3, FN_Max }, { "sum", 3, FN_Sum }, { "avg", 3, FN_Avg }, { "fcnt", 4, FN_Fcnt }, /* Used for testing only */ { "length", 6, FN_Length}, { "substr", 6, FN_Substr}, }; int i; for(i=0; i<ArraySize(aFunc); i++){ if( aFunc[i].len==pToken->n && sqliteStrNICmp(pToken->z, aFunc[i].zName, aFunc[i].len)==0 ){ return aFunc[i].id; } |
︙ | |||
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 | 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 | + + + + + + + + + + + | case FN_Avg: case FN_Sum: { no_such_func = !allowAgg; too_many_args = n>1; too_few_args = n<1; is_agg = 1; break; } case FN_Length: { too_few_args = n<1; too_many_args = n>1; break; } case FN_Substr: { too_few_args = n<3; too_many_args = n>3; break; } /* The "fcnt(*)" function always returns the number of fetch ** operations that have occurred so far while processing the ** SQL statement. This information can be used by test procedures ** to verify that indices are being used properly to minimize ** searching. All arguments to fcnt() are ignored. fcnt() has ** no use (other than testing) that we are aware of. */ case FN_Fcnt: { n = 0; break; } default: break; } if( no_such_func ){ sqliteSetNString(&pParse->zErrMsg, "no such function: ", -1, pExpr->token.z, pExpr->token.n, 0); pParse->nErr++; nErr++; |
︙ | |||
570 571 572 573 574 575 576 | 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 | + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | break; } case TK_FUNCTION: { int id = pExpr->iColumn; int op; int i; ExprList *pList = pExpr->pList; switch( id ){ |
︙ |
Changes to src/sqliteInt.h.
︙ | |||
19 20 21 22 23 24 25 | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | - + | ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ************************************************************************* ** Internal interface definitions for SQLite. ** |
︙ | |||
95 96 97 98 99 100 101 102 103 104 105 106 107 108 | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | + + | #define FN_Unknown 0 #define FN_Count 1 #define FN_Min 2 #define FN_Max 3 #define FN_Sum 4 #define FN_Avg 5 #define FN_Fcnt 6 #define FN_Length 7 #define FN_Substr 8 /* ** Forward references to structures */ typedef struct Column Column; typedef struct Table Table; typedef struct Index Index; |
︙ |
Changes to src/vdbe.c.
︙ | |||
37 38 39 40 41 42 43 | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | - + | ** inplicit conversion from one type to the other occurs as necessary. ** ** Most of the code in this file is taken up by the sqliteVdbeExec() ** function which does the work of interpreting a VDBE program. ** But other routines are also provided to help in building up ** a program instruction by instruction. ** |
︙ | |||
784 785 786 787 788 789 790 791 792 793 794 795 796 797 | 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 | + | "String", "Null", "Pop", "Dup", "Pull", "Add", "AddImm", "Subtract", "Multiply", "Divide", "Min", "Max", "Like", "Glob", "Eq", "Ne", "Lt", "Le", "Gt", "Ge", "IsNull", "NotNull", "Negative", "And", "Or", "Not", "Concat", "Noop", "Strlen", "Substr", }; /* ** Given the name of an opcode, return its number. Return 0 if ** there is no match. ** ** This routine is used for testing and debugging. |
︙ | |||
3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 | 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | Stringify(p, tos); if( i>=0 && i<p->nSet && !SetTest(&p->aSet[i], p->zStack[tos]) ){ pc = pOp->p2 - 1; } PopStack(p, 1); break; } /* Opcode: Length * * * ** ** Interpret the top of the stack as a string. Replace the top of ** stack with an integer which is the length of the string. */ case OP_Strlen: { int tos = p->tos; int len; if( tos<0 ) goto not_enough_stack; Stringify(p, tos); len = p->aStack[tos].n-1; PopStack(p, 1); p->tos++; p->aStack[tos].i = len; p->aStack[tos].flags = STK_Int; break; } /* Opcode: Substr P1 P2 * ** ** This operation pops between 1 and 3 elements from the stack and ** pushes back a single element. The bottom-most element popped from ** the stack is a string and the element pushed back is also a string. ** The other two elements popped are integers. The integers are taken ** from the stack only if P1 and/or P2 are 0. When P1 or P2 are ** not zero, the value of the operand is used rather than the integer ** from the stack. In the sequel, we will use P1 and P2 to describe ** the two integers, even if those integers are really taken from the ** stack. ** ** The string pushed back onto the stack is a substring of the string ** that was popped. There are P2 characters in the substring. The ** first character of the substring is the P1-th character of the ** original string where the left-most character is 1 (not 0). If P1 ** is negative, then counting begins at the right instead of at the ** left. */ case OP_Substr: { int cnt; int start; int n; char *z; if( pOp->p2==0 ){ if( p->tos<0 ) goto not_enough_stack; Integerify(p, p->tos); cnt = p->aStack[p->tos].i; PopStack(p, 1); }else{ cnt = pOp->p2; } if( pOp->p1==0 ){ if( p->tos<0 ) goto not_enough_stack; Integerify(p, p->tos); start = p->aStack[p->tos].i; PopStack(p, 1); }else{ start = pOp->p1; } if( p->tos<0 ) goto not_enough_stack; Stringify(p, p->tos); n = p->aStack[p->tos].n - 1; if( start<0 ){ start += n; if( start<0 ){ cnt += start; start = 0; } } if( cnt<0 ) cnt = 0; if( cnt > n ){ cnt = n; } z = sqliteMalloc( cnt+1 ); if( z==0 ) goto no_mem; strncpy(z, p->zStack[p->tos], cnt); z[cnt] = 0; PopStack(p, 1); p->tos++; p->zStack[p->tos] = z; p->aStack[p->tos].n = cnt + 1; p->aStack[p->tos].flags = STK_Str|STK_Dyn; break; } /* An other opcode is illegal... */ default: { sprintf(zBuf,"%d",pOp->opcode); sqliteSetString(pzErrMsg, "unknown opcode ", zBuf, 0); rc = SQLITE_INTERNAL; |
︙ |
Changes to src/vdbe.h.
︙ | |||
23 24 25 26 27 28 29 | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | - + | ************************************************************************* ** Header file for the Virtual DataBase Engine (VDBE) ** ** This header defines the interface to the virtual database engine ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** |
︙ | |||
169 170 171 172 173 174 175 | 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | + + + - + | #define OP_Negative 83 #define OP_And 84 #define OP_Or 85 #define OP_Not 86 #define OP_Concat 87 #define OP_Noop 88 #define OP_Strlen 89 #define OP_Substr 90 |
︙ |