Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | :-) (CVS 56) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
b52dd82fe32c38c999aef4f07d046d04 |
User & Date: | drh 2000-06-06 03:31:22.000 |
Context
2000-06-06
| ||
13:54 | added IN and BETWEEN operators (CVS 57) (check-in: 54d198189b user: drh tags: trunk) | |
03:31 | :-) (CVS 56) (check-in: b52dd82fe3 user: drh tags: trunk) | |
01:50 | :-) (CVS 55) (check-in: bd8b2645cc user: drh tags: trunk) | |
Changes
Changes to src/expr.c.
︙ | ︙ | |||
19 20 21 22 23 24 25 | ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ************************************************************************* ** This file contains C code routines used for processing expressions ** | | | 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/ ** ************************************************************************* ** This file contains C code routines used for processing expressions ** ** $Id: expr.c,v 1.8 2000/06/06 03:31:22 drh Exp $ */ #include "sqliteInt.h" /* ** Walk an expression tree. Return 1 if the expression is constant ** and 0 if it involves variables. */ |
︙ | ︙ | |||
175 176 177 178 179 180 181 182 183 184 185 186 187 188 | case TK_IN: { Vdbe *v = pParse->pVdbe; if( v==0 ){ v = pParse->pVdbe = sqliteVdbeCreate(pParse->db->pBe); } if( v==0 ) return 1; if( pExpr->pSelect ){ /* Case 1: expr IN (SELECT ...) ** ** Generate code to write the results of the select into a temporary ** table. The cursor number of the temporary table is stored in ** iTable. */ | > > > | 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | case TK_IN: { Vdbe *v = pParse->pVdbe; if( v==0 ){ v = pParse->pVdbe = sqliteVdbeCreate(pParse->db->pBe); } if( v==0 ) return 1; if( sqliteExprResolveIds(pParse, pTabList, pExpr->pLeft) ){ return 1; } if( pExpr->pSelect ){ /* Case 1: expr IN (SELECT ...) ** ** Generate code to write the results of the select into a temporary ** table. The cursor number of the temporary table is stored in ** iTable. */ |
︙ | ︙ | |||
224 225 226 227 228 229 230 231 232 233 234 235 236 237 | sqliteExprCode(pParse, pE2); sqliteVdbeAddOp(v, OP_SetInsert, iSet, 0, 0, 0); break; } } } } } case TK_SELECT: { /* This has to be a scalar SELECT. Generate code to put the ** value of this select in a memory cell and record the number ** of the memory cell in iField. */ | > | 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | sqliteExprCode(pParse, pE2); sqliteVdbeAddOp(v, OP_SetInsert, iSet, 0, 0, 0); break; } } } } break; } case TK_SELECT: { /* This has to be a scalar SELECT. Generate code to put the ** value of this select in a memory cell and record the number ** of the memory cell in iField. */ |
︙ | ︙ | |||
585 586 587 588 589 590 591 592 593 594 595 596 597 598 | case TK_ISNULL: case TK_NOTNULL: { sqliteExprCode(pParse, pExpr->pLeft); sqliteVdbeAddOp(v, op, 0, dest, 0, 0); break; } case TK_IN: { if( pExpr->pSelect ){ sqliteVdbeAddOp(v, OP_Found, pExpr->iTable, dest, 0, 0); }else{ sqliteVdbeAddOp(v, OP_SetFound, pExpr->iTable, dest, 0, 0); } break; } | > | 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 | case TK_ISNULL: case TK_NOTNULL: { sqliteExprCode(pParse, pExpr->pLeft); sqliteVdbeAddOp(v, op, 0, dest, 0, 0); break; } case TK_IN: { sqliteExprCode(pParse, pExpr->pLeft); if( pExpr->pSelect ){ sqliteVdbeAddOp(v, OP_Found, pExpr->iTable, dest, 0, 0); }else{ sqliteVdbeAddOp(v, OP_SetFound, pExpr->iTable, dest, 0, 0); } break; } |
︙ | ︙ | |||
675 676 677 678 679 680 681 682 683 684 685 686 687 688 | case TK_ISNULL: case TK_NOTNULL: { sqliteExprCode(pParse, pExpr->pLeft); sqliteVdbeAddOp(v, op, 0, dest, 0, 0); break; } case TK_IN: { if( pExpr->pSelect ){ sqliteVdbeAddOp(v, OP_NotFound, pExpr->iTable, dest, 0, 0); }else{ sqliteVdbeAddOp(v, OP_SetNotFound, pExpr->iTable, dest, 0, 0); } break; } | > | 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 | case TK_ISNULL: case TK_NOTNULL: { sqliteExprCode(pParse, pExpr->pLeft); sqliteVdbeAddOp(v, op, 0, dest, 0, 0); break; } case TK_IN: { sqliteExprCode(pParse, pExpr->pLeft); if( pExpr->pSelect ){ sqliteVdbeAddOp(v, OP_NotFound, pExpr->iTable, dest, 0, 0); }else{ sqliteVdbeAddOp(v, OP_SetNotFound, pExpr->iTable, dest, 0, 0); } break; } |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
37 38 39 40 41 42 43 | ** 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. ** | | | 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. ** ** $Id: vdbe.c,v 1.19 2000/06/06 03:31:22 drh Exp $ */ #include "sqliteInt.h" #include <unistd.h> /* ** SQL is translated into a sequence of instructions to be ** executed by a virtual machine. Each instruction is an instance |
︙ | ︙ | |||
472 473 474 475 476 477 478 | */ static void SetInsert(Set *p, char *zKey){ SetElem *pElem; int h = sqliteHashNoCase(zKey, 0) % ArraySize(p->apHash); for(pElem=p->apHash[h]; pElem; pElem=pElem->pHash){ if( strcmp(pElem->zKey, zKey)==0 ) return; } | | | 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 | */ static void SetInsert(Set *p, char *zKey){ SetElem *pElem; int h = sqliteHashNoCase(zKey, 0) % ArraySize(p->apHash); for(pElem=p->apHash[h]; pElem; pElem=pElem->pHash){ if( strcmp(pElem->zKey, zKey)==0 ) return; } pElem = sqliteMalloc( sizeof(*pElem) + strlen(zKey) ); if( pElem==0 ) return; strcpy(pElem->zKey, zKey); pElem->pNext = p->pAll; p->pAll = pElem; pElem->pHash = p->apHash[h]; p->apHash[h] = pElem; } |
︙ | ︙ | |||
2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 | int tos = p->tos; if( tos<0 ) goto not_enough_stack; Stringify(p, tos); if( i>=0 && i<p->nSet && SetTest(&p->aSet[i], p->zStack[tos]) ){ pc = pOp->p2 - 1; } PopStack(p, 1); } /* Opcode: SetNotFound P1 P2 * ** ** Pop the stack once and compare the value popped off with the ** contents of set P1. If the element popped does not exists in ** set P1, then jump to P2. Otherwise fall through. */ case OP_SetNotFound: { int i = pOp->p1; int tos = p->tos; if( tos<0 ) goto not_enough_stack; Stringify(p, tos); if( i>=0 && i<p->nSet && !SetTest(&p->aSet[i], p->zStack[tos]) ){ pc = pOp->p2 - 1; } PopStack(p, 1); } /* An other opcode is illegal... */ default: { sprintf(zBuf,"%d",pOp->opcode); sqliteSetString(pzErrMsg, "unknown opcode ", zBuf, 0); | > > | 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 | int tos = p->tos; if( tos<0 ) goto not_enough_stack; 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: SetNotFound P1 P2 * ** ** Pop the stack once and compare the value popped off with the ** contents of set P1. If the element popped does not exists in ** set P1, then jump to P2. Otherwise fall through. */ case OP_SetNotFound: { int i = pOp->p1; int tos = p->tos; if( tos<0 ) goto not_enough_stack; Stringify(p, tos); if( i>=0 && i<p->nSet && !SetTest(&p->aSet[i], p->zStack[tos]) ){ pc = pOp->p2 - 1; } PopStack(p, 1); break; } /* An other opcode is illegal... */ default: { sprintf(zBuf,"%d",pOp->opcode); sqliteSetString(pzErrMsg, "unknown opcode ", zBuf, 0); |
︙ | ︙ |