Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Continued work toward converting to a register-based VM. (CVS 4698) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
92deff07bba2089bbe011f44defb3a0a |
User & Date: | drh 2008-01-09 02:15:39.000 |
Context
2008-01-09
| ||
18:31 | Fix the build for AIX and other systems where "char" is unsigned by default. (CVS 4699) (check-in: 47672af0c6 user: drh tags: trunk) | |
02:15 | Continued work toward converting to a register-based VM. (CVS 4698) (check-in: 92deff07bb user: drh tags: trunk) | |
2008-01-08
| ||
23:54 | Registerify the comparison opcodes. (CVS 4697) (check-in: 8862ce9cee user: drh tags: trunk) | |
Changes
Changes to src/expr.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** ** $Id: expr.c,v 1.339 2008/01/09 02:15:39 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Return the 'affinity' of the expression pExpr if any. ** |
︙ | ︙ | |||
2117 2118 2119 2120 2121 2122 2123 | if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){ Token *p = &pLeft->token; if( pLeft->op==TK_FLOAT ){ codeReal(v, (char*)p->z, p->n, 1, target); }else{ codeInteger(v, (char*)p->z, p->n, 1, target); } | > > > > > > | | < < | 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 | if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){ Token *p = &pLeft->token; if( pLeft->op==TK_FLOAT ){ codeReal(v, (char*)p->z, p->n, 1, target); }else{ codeInteger(v, (char*)p->z, p->n, 1, target); } }else{ int r1 = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Integer, 0, r1); sqlite3ExprCode(pParse, pExpr->pLeft, target); sqlite3VdbeAddOp3(v, OP_Subtract, target, r1, target); } inReg = target; break; } case TK_BITNOT: case TK_NOT: { assert( TK_BITNOT==OP_BitNot ); assert( TK_NOT==OP_Not ); sqlite3ExprCode(pParse, pExpr->pLeft, 0); sqlite3VdbeAddOp0(v, op); |
︙ | ︙ | |||
2241 2242 2243 2244 2245 2246 2247 | sqlite3VdbeAddOp0(v, OP_SCopy); j1 = sqlite3VdbeAddOp0(v, OP_NotNull); sqlite3VdbeAddOp1(v, OP_Pop, 2); sqlite3VdbeAddOp0(v, OP_Null); j2 = sqlite3VdbeAddOp0(v, OP_Goto); sqlite3VdbeJumpHere(v, j1); if( eType==IN_INDEX_ROWID ){ | | | 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 | sqlite3VdbeAddOp0(v, OP_SCopy); j1 = sqlite3VdbeAddOp0(v, OP_NotNull); sqlite3VdbeAddOp1(v, OP_Pop, 2); sqlite3VdbeAddOp0(v, OP_Null); j2 = sqlite3VdbeAddOp0(v, OP_Goto); sqlite3VdbeJumpHere(v, j1); if( eType==IN_INDEX_ROWID ){ j3 = sqlite3VdbeAddOp3(v, OP_MustBeInt, 0, 0, 1); j4 = sqlite3VdbeAddOp1(v, OP_NotExists, pExpr->iTable); j5 = sqlite3VdbeAddOp0(v, OP_Goto); sqlite3VdbeJumpHere(v, j3); sqlite3VdbeJumpHere(v, j4); }else{ sqlite3VdbeAddOp4(v, OP_MakeRecord, 1, 0, 0, &affinity, 1); j5 = sqlite3VdbeAddOp1(v, OP_Found, pExpr->iTable); |
︙ | ︙ | |||
2310 2311 2312 2313 2314 2315 2316 | sqlite3ExprCode(pParse, aListelem[i].pExpr, 0); if( pExpr->pLeft ){ sqlite3VdbeAddOp1(v, OP_SCopy, -1); jumpInst = codeCompare(pParse, pExpr->pLeft, aListelem[i].pExpr, OP_Ne, 0, 0, 0, SQLITE_JUMPIFNULL); sqlite3VdbeAddOp1(v, OP_Pop, 1); }else{ | | | 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 | sqlite3ExprCode(pParse, aListelem[i].pExpr, 0); if( pExpr->pLeft ){ sqlite3VdbeAddOp1(v, OP_SCopy, -1); jumpInst = codeCompare(pParse, pExpr->pLeft, aListelem[i].pExpr, OP_Ne, 0, 0, 0, SQLITE_JUMPIFNULL); sqlite3VdbeAddOp1(v, OP_Pop, 1); }else{ jumpInst = sqlite3VdbeAddOp3(v, OP_IfNot, 0, 0, 1); } sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target); sqlite3VdbeAddOp2(v, OP_Goto, 0, expr_end_label); sqlite3VdbeJumpHere(v, jumpInst); } if( pExpr->pLeft ){ sqlite3VdbeAddOp2(v, OP_Pop, 1, 0); |
︙ | ︙ | |||
2509 2510 2511 2512 2513 2514 2515 | sqlite3VdbeAddOp2(v, OP_Integer, 0, 0); sqlite3VdbeJumpHere(v, addr); sqlite3VdbeAddOp2(v, OP_Pop, 1, 0); break; } default: { sqlite3ExprCode(pParse, pExpr, 0); | | | 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 | sqlite3VdbeAddOp2(v, OP_Integer, 0, 0); sqlite3VdbeJumpHere(v, addr); sqlite3VdbeAddOp2(v, OP_Pop, 1, 0); break; } default: { sqlite3ExprCode(pParse, pExpr, 0); sqlite3VdbeAddOp3(v, OP_If, 0, dest, jumpIfNull!=0); break; } } } /* ** Generate code for a boolean expression such that a jump is made |
︙ | ︙ | |||
2623 2624 2625 2626 2627 2628 2629 | sqlite3ExprCode(pParse, pRight, 0); codeCompare(pParse, pLeft, pRight, OP_Gt, 0, 0, dest, jumpIfNull); break; } default: { sqlite3ExprCode(pParse, pExpr, 0); | | | 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 | sqlite3ExprCode(pParse, pRight, 0); codeCompare(pParse, pLeft, pRight, OP_Gt, 0, 0, dest, jumpIfNull); break; } default: { sqlite3ExprCode(pParse, pExpr, 0); sqlite3VdbeAddOp3(v, OP_IfNot, 0, dest, jumpIfNull!=0); break; } } } /* ** Do a deep comparison of two expression trees. Return TRUE (non-zero) |
︙ | ︙ |
Changes to src/insert.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** ** $Id: insert.c,v 1.219 2008/01/09 02:15:39 drh Exp $ */ #include "sqliteInt.h" /* ** Set P4 of the most recently inserted opcode to a column affinity ** string for index pIdx. A column affinity string has one character ** for each column in the table, according to the affinity of the column: |
︙ | ︙ | |||
775 776 777 778 779 780 781 | sqlite3VdbeAddOp2(v, OP_Move, 0, regRowid); } } /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid ** to generate a unique primary key value. */ if( !appendFlag ){ | | | | 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 | sqlite3VdbeAddOp2(v, OP_Move, 0, regRowid); } } /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid ** to generate a unique primary key value. */ if( !appendFlag ){ sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, sqlite3VdbeCurrentAddr(v)+2); sqlite3VdbeAddOp2(v, OP_Goto, -1, sqlite3VdbeCurrentAddr(v)+2); sqlite3VdbeAddOp3(v, OP_NewRowid, baseCur, regRowid, regAutoinc); sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid); } }else if( IsVirtual(pTab) ){ sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid); }else{ sqlite3VdbeAddOp3(v, OP_NewRowid, baseCur, regRowid, regAutoinc); appendFlag = 1; } |
︙ | ︙ |
Changes to src/pragma.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2003 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2003 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** ** $Id: pragma.c,v 1.163 2008/01/09 02:15:39 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* Ignore this whole file if pragmas are disabled */ #if !defined(SQLITE_OMIT_PRAGMA) && !defined(SQLITE_OMIT_PARSER) |
︙ | ︙ | |||
294 295 296 297 298 299 300 | ** database file. The cache size is actually the absolute value of ** this memory location. The sign of meta-value 2 determines the ** synchronous setting. A negative value means synchronous is off ** and a positive value means synchronous is on. */ if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){ static const VdbeOpList getCacheSize[] = { | | | < | > | | | > | | | | | 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 | ** database file. The cache size is actually the absolute value of ** this memory location. The sign of meta-value 2 determines the ** synchronous setting. A negative value means synchronous is off ** and a positive value means synchronous is on. */ if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){ static const VdbeOpList getCacheSize[] = { { OP_ReadCookie, 0, 1, 2}, /* 0 */ { OP_IfPos, 1, 6, 0}, { OP_Integer, 0, 2, 0}, { OP_Subtract, 1, 2, 1}, { OP_IfPos, 1, 6, 0}, { OP_Integer, 0, 1, 0}, /* 5 */ { OP_ResultRow, 1, 1, 0}, }; int addr; if( sqlite3ReadSchema(pParse) ) goto pragma_out; sqlite3VdbeUsesBtree(v, iDb); if( !zRight ){ sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", P4_STATIC); pParse->nMem += 2; addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize); sqlite3VdbeChangeP1(v, addr, iDb); sqlite3VdbeChangeP1(v, addr+5, SQLITE_DEFAULT_CACHE_SIZE); }else{ int size = atoi(zRight); if( size<0 ) size = -size; sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3VdbeAddOp1(v, OP_Integer, size); sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, 0, 2); addr = sqlite3VdbeAddOp2(v, OP_IfPos, 0, 0); sqlite3VdbeAddOp1(v, OP_Integer, -size); sqlite3VdbeJumpHere(v, addr); sqlite3VdbeAddOp2(v, OP_SetCookie, iDb, 2); pDb->pSchema->cache_size = size; sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } }else /* |
︙ | ︙ | |||
489 490 491 492 493 494 495 | goto pragma_out; } if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){ iLimit = 0x7fffffff; } sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1); | | | | | 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 | goto pragma_out; } if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){ iLimit = 0x7fffffff; } sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1); addr = sqlite3VdbeAddOp1(v, OP_IncrVacuum, iDb); sqlite3VdbeAddOp0(v, OP_Callback); sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr); sqlite3VdbeJumpHere(v, addr); }else #endif #ifndef SQLITE_OMIT_PAGER_PRAGMAS /* ** PRAGMA [database.]cache_size |
︙ | ︙ | |||
859 860 861 862 863 864 865 | HashElem *x; Hash *pTbls; int cnt = 0; if( OMIT_TEMPDB && i==1 ) continue; sqlite3CodeVerifySchema(pParse, i); | | | 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 | HashElem *x; Hash *pTbls; int cnt = 0; if( OMIT_TEMPDB && i==1 ) continue; sqlite3CodeVerifySchema(pParse, i); addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); sqlite3VdbeJumpHere(v, addr); /* Do an integrity check of the B-Tree */ pTbls = &db->aDb[i].pSchema->tblHash; for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ |
︙ | ︙ | |||
895 896 897 898 899 900 901 | */ for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); Index *pIdx; int loopTop; if( pTab->pIndex==0 ) continue; | | | 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 | */ for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); Index *pIdx; int loopTop; if( pTab->pIndex==0 ) continue; addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); sqlite3VdbeJumpHere(v, addr); sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead); sqlite3VdbeAddOp2(v, OP_Integer, 0, 2); loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0); sqlite3VdbeAddOp2(v, OP_AddImm, 2, 1); for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ |
︙ | ︙ | |||
941 942 943 944 945 946 947 | { OP_AddImm, 1, -1, 0}, { OP_String8, 0, 0, 0}, /* 8 */ { OP_String8, 0, 0, 0}, /* 9 */ { OP_Concat, 0, 0, 0}, { OP_Callback, 1, 0, 0}, }; if( pIdx->tnum==0 ) continue; | | | 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 | { OP_AddImm, 1, -1, 0}, { OP_String8, 0, 0, 0}, /* 8 */ { OP_String8, 0, 0, 0}, /* 9 */ { OP_Concat, 0, 0, 0}, { OP_Callback, 1, 0, 0}, }; if( pIdx->tnum==0 ) continue; addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); sqlite3VdbeJumpHere(v, addr); addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx); sqlite3VdbeChangeP1(v, addr+1, j+2); sqlite3VdbeChangeP2(v, addr+1, addr+4); sqlite3VdbeChangeP1(v, addr+3, j+2); sqlite3VdbeChangeP2(v, addr+3, addr+2); |
︙ | ︙ |
Changes to src/prepare.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the implementation of the sqlite3_prepare() ** interface, and routines that contribute to loading the database schema ** from disk. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the implementation of the sqlite3_prepare() ** interface, and routines that contribute to loading the database schema ** from disk. ** ** $Id: prepare.c,v 1.71 2008/01/09 02:15:39 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Fill the InitData structure with an error message that indicates ** that the database is corrupt. |
︙ | ︙ | |||
265 266 267 268 269 270 271 272 273 274 275 276 277 278 | }else{ DbSetProperty(db, iDb, DB_Empty); } pDb->pSchema->enc = ENC(db); size = meta[2]; if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; } pDb->pSchema->cache_size = size; sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); /* ** file_format==1 Version 3.0.0. ** file_format==2 Version 3.1.3. // ALTER TABLE ADD COLUMN ** file_format==3 Version 3.1.4. // ditto but with non-NULL defaults | > | 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 | }else{ DbSetProperty(db, iDb, DB_Empty); } pDb->pSchema->enc = ENC(db); size = meta[2]; if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; } if( size<0 ) size = -size; pDb->pSchema->cache_size = size; sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); /* ** file_format==1 Version 3.0.0. ** file_format==2 Version 3.1.3. // ALTER TABLE ADD COLUMN ** file_format==3 Version 3.1.4. // ditto but with non-NULL defaults |
︙ | ︙ |
Changes to src/select.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** ** $Id: select.c,v 1.394 2008/01/09 02:15:42 drh Exp $ */ #include "sqliteInt.h" /* ** Delete all the content of a Select structure but do not deallocate ** the select structure itself. |
︙ | ︙ | |||
394 395 396 397 398 399 400 | static void pushOntoSorter( Parse *pParse, /* Parser context */ ExprList *pOrderBy, /* The ORDER BY clause */ Select *pSelect /* The whole SELECT statement */ ){ Vdbe *v = pParse->pVdbe; sqlite3ExprCodeExprList(pParse, pOrderBy, 0); | | | | | | | | | | | | 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 | static void pushOntoSorter( Parse *pParse, /* Parser context */ ExprList *pOrderBy, /* The ORDER BY clause */ Select *pSelect /* The whole SELECT statement */ ){ Vdbe *v = pParse->pVdbe; sqlite3ExprCodeExprList(pParse, pOrderBy, 0); sqlite3VdbeAddOp1(v, OP_Sequence, pOrderBy->iECursor); sqlite3VdbeAddOp1(v, OP_Pull, pOrderBy->nExpr + 1); sqlite3VdbeAddOp1(v, OP_MakeRecord, pOrderBy->nExpr + 2); sqlite3VdbeAddOp1(v, OP_IdxInsert, pOrderBy->iECursor); if( pSelect->iLimit>=0 ){ int addr1, addr2; addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, pSelect->iLimit+1); sqlite3VdbeAddOp2(v, OP_AddImm, pSelect->iLimit+1, -1); addr2 = sqlite3VdbeAddOp0(v, OP_Goto); sqlite3VdbeJumpHere(v, addr1); sqlite3VdbeAddOp1(v, OP_Last, pOrderBy->iECursor); sqlite3VdbeAddOp1(v, OP_Delete, pOrderBy->iECursor); sqlite3VdbeJumpHere(v, addr2); pSelect->iLimit = -1; } } /* ** Add code to implement the OFFSET */ static void codeOffset( Vdbe *v, /* Generate code into this VM */ Select *p, /* The SELECT statement being coded */ int iContinue, /* Jump here to skip the current record */ int nPop /* Number of times to pop stack when jumping */ ){ if( p->iOffset>=0 && iContinue!=0 ){ int addr; sqlite3VdbeAddOp2(v, OP_AddImm, p->iOffset, -1); addr = sqlite3VdbeAddOp1(v, OP_IfNeg, p->iOffset); if( nPop>0 ){ sqlite3VdbeAddOp1(v, OP_Pop, nPop); } sqlite3VdbeAddOp2(v, OP_Goto, 0, iContinue); VdbeComment((v, "skip OFFSET records")); sqlite3VdbeJumpHere(v, addr); } } |
︙ | ︙ | |||
637 638 639 640 641 642 643 | ** then there should be a single item on the stack. Write this ** item into the set table with bogus data. */ case SRT_Set: { int addr2; assert( nColumn==1 ); | | | 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 | ** then there should be a single item on the stack. Write this ** item into the set table with bogus data. */ case SRT_Set: { int addr2; assert( nColumn==1 ); addr2 = sqlite3VdbeAddOp2(v, OP_IsNull, iMem, 0); p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affinity); if( pOrderBy ){ /* At first glance you would think we could optimize out the ** ORDER BY in this case since the order of entries in the set ** does not matter. But there might be a LIMIT clause, in which ** case the order does matter */ sqlite3VdbeAddOp2(v, OP_SCopy, iMem, 0); |
︙ | ︙ | |||
713 714 715 716 717 718 719 | #endif } /* Jump to the end of the loop if the LIMIT is reached. */ if( p->iLimit>=0 && pOrderBy==0 ){ sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1); | | | 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 | #endif } /* Jump to the end of the loop if the LIMIT is reached. */ if( p->iLimit>=0 && pOrderBy==0 ){ sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1); sqlite3VdbeAddOp2(v, OP_IfZero, p->iLimit, iBreak); } return 0; } /* ** Given an expression list, generate a KeyInfo structure that records ** the collating sequence for each expression in that expression list. |
︙ | ︙ | |||
848 849 850 851 852 853 854 | } } /* Jump to the end of the loop when the LIMIT is reached */ if( p->iLimit>=0 ){ sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1); | | | 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 | } } /* Jump to the end of the loop when the LIMIT is reached */ if( p->iLimit>=0 ){ sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1); sqlite3VdbeAddOp2(v, OP_IfZero, p->iLimit, brk); } /* The bottom of the loop */ sqlite3VdbeResolveLabel(v, cont); sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); sqlite3VdbeResolveLabel(v, brk); |
︙ | ︙ | |||
1764 1765 1766 1767 1768 1769 1770 | */ if( p->pLimit ){ p->iLimit = iLimit = ++pParse->nMem; pParse->nMem++; v = sqlite3GetVdbe(pParse); if( v==0 ) return; sqlite3ExprCode(pParse, p->pLimit, 0); | | | | | | | | | 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 | */ if( p->pLimit ){ p->iLimit = iLimit = ++pParse->nMem; pParse->nMem++; v = sqlite3GetVdbe(pParse); if( v==0 ) return; sqlite3ExprCode(pParse, p->pLimit, 0); sqlite3VdbeAddOp0(v, OP_MustBeInt); sqlite3VdbeAddOp2(v, OP_Move, 0, iLimit); VdbeComment((v, "LIMIT counter")); sqlite3VdbeAddOp2(v, OP_IfZero, iLimit, iBreak); sqlite3VdbeAddOp2(v, OP_SCopy, iLimit, 0); } if( p->pOffset ){ p->iOffset = iOffset = ++pParse->nMem; v = sqlite3GetVdbe(pParse); if( v==0 ) return; sqlite3ExprCode(pParse, p->pOffset, 0); sqlite3VdbeAddOp0(v, OP_MustBeInt); sqlite3VdbeAddOp2(v, p->pLimit==0 ? OP_Move : OP_Copy, 0, iOffset); VdbeComment((v, "OFFSET counter")); addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iOffset); sqlite3VdbeAddOp2(v, OP_Pop, 1, 0); sqlite3VdbeAddOp2(v, OP_Integer, 0, 0); sqlite3VdbeJumpHere(v, addr1); if( p->pLimit ){ sqlite3VdbeAddOp2(v, OP_Add, 0, 0); } } if( p->pLimit ){ addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iLimit); sqlite3VdbeAddOp1(v, OP_Pop, 1); sqlite3VdbeAddOp2(v, OP_Integer, -1, iLimit+1); addr2 = sqlite3VdbeAddOp0(v, OP_Goto); sqlite3VdbeJumpHere(v, addr1); sqlite3VdbeAddOp2(v, OP_Move, 0, iLimit+1); VdbeComment((v, "LIMIT+OFFSET")); sqlite3VdbeJumpHere(v, addr2); } } |
︙ | ︙ | |||
1944 1945 1946 1947 1948 1949 1950 | if( rc ){ goto multi_select_end; } p->pPrior = 0; p->iLimit = pPrior->iLimit; p->iOffset = pPrior->iOffset; if( p->iLimit>=0 ){ | | | 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 | if( rc ){ goto multi_select_end; } p->pPrior = 0; p->iLimit = pPrior->iLimit; p->iOffset = pPrior->iOffset; if( p->iLimit>=0 ){ addr = sqlite3VdbeAddOp1(v, OP_IfZero, p->iLimit); VdbeComment((v, "Jump ahead if LIMIT reached")); } rc = sqlite3Select(pParse, p, &dest, 0, 0, 0, aff); p->pPrior = pPrior; if( rc ){ goto multi_select_end; } |
︙ | ︙ | |||
3516 3517 3518 3519 3520 3521 3522 | ** order to signal the caller to abort. */ addrSetAbort = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp2(v, OP_Integer, 1, iAbortFlag); VdbeComment((v, "set abort flag")); sqlite3VdbeAddOp2(v, OP_Return, 0, 0); addrOutputRow = sqlite3VdbeCurrentAddr(v); | | | 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 | ** order to signal the caller to abort. */ addrSetAbort = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp2(v, OP_Integer, 1, iAbortFlag); VdbeComment((v, "set abort flag")); sqlite3VdbeAddOp2(v, OP_Return, 0, 0); addrOutputRow = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2); VdbeComment((v, "Groupby result generator entry point")); sqlite3VdbeAddOp2(v, OP_Return, 0, 0); finalizeAggFunctions(pParse, &sAggInfo); if( pHaving ){ sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL); } rc = selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy, |
︙ | ︙ | |||
3622 3623 3624 3625 3626 3627 3628 | */ sqlite3VdbeResolveLabel(v, addrGroupByChange); for(j=0; j<pGroupBy->nExpr; j++){ sqlite3VdbeAddOp2(v, OP_Move, iBMem+j, iAMem+j); } sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrOutputRow); VdbeComment((v, "output one row")); | | | 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 | */ sqlite3VdbeResolveLabel(v, addrGroupByChange); for(j=0; j<pGroupBy->nExpr; j++){ sqlite3VdbeAddOp2(v, OP_Move, iBMem+j, iAMem+j); } sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrOutputRow); VdbeComment((v, "output one row")); sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); VdbeComment((v, "check abort flag")); sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrReset); VdbeComment((v, "reset accumulator")); /* Update the aggregate accumulators based on the content of ** the current row */ |
︙ | ︙ |
Changes to src/update.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** ** $Id: update.c,v 1.165 2008/01/09 02:15:42 drh Exp $ */ #include "sqliteInt.h" #ifndef SQLITE_OMIT_VIRTUALTABLE /* Forward declaration */ static void updateVirtualTable( Parse *pParse, /* The parsing context */ |
︙ | ︙ | |||
464 465 466 467 468 469 470 | /* If the record number will change, push the record number as it ** will be after the update. (The old record number is currently ** on top of the stack.) */ if( chngRowid ){ sqlite3ExprCode(pParse, pRowidExpr, regNewRowid); | | | 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 | /* If the record number will change, push the record number as it ** will be after the update. (The old record number is currently ** on top of the stack.) */ if( chngRowid ){ sqlite3ExprCode(pParse, pRowidExpr, regNewRowid); sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid); } /* Compute new data for this record. */ for(i=0; i<pTab->nCol; i++){ if( i==pTab->iPKey ){ sqlite3VdbeAddOp2(v, OP_Null, 0, regData+i); |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.690 2008/01/09 02:15:42 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" /* ** The following global variable is incremented every time a cursor |
︙ | ︙ | |||
909 910 911 912 913 914 915 | */ case OP_Real: { /* same as TK_FLOAT, out2-prerelease */ pOut->flags = MEM_Real; pOut->r = *pOp->p4.pReal; break; } | | | 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 | */ case OP_Real: { /* same as TK_FLOAT, out2-prerelease */ pOut->flags = MEM_Real; pOut->r = *pOp->p4.pReal; break; } /* Opcode: String8 * P2 * P4 * ** ** P4 points to a nul terminated UTF-8 string. This opcode is transformed ** into an OP_String before it is executed for the first time. */ case OP_String8: { /* same as TK_STRING, out2-prerelease */ assert( pOp->p4.z!=0 ); pOp->opcode = OP_String; |
︙ | ︙ | |||
1019 1020 1021 1022 1023 1024 1025 | assert( pOp->p1 <= SQLITE_MAX_LENGTH ); sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0); pOut->enc = encoding; break; } #endif /* SQLITE_OMIT_BLOB_LITERAL */ | | | 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 | assert( pOp->p1 <= SQLITE_MAX_LENGTH ); sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0); pOut->enc = encoding; break; } #endif /* SQLITE_OMIT_BLOB_LITERAL */ /* Opcode: Variable P1 P2 * * * ** ** The value of variable P1 is written into register P2 or pushed ** onto the stack if P2 is zero. A variable is ** an unknown in the original SQL string as handed to sqlite3_compile(). ** Any occurance of the '?' character in the original SQL is considered ** a variable. Variables in the SQL string are number from left to ** right beginning with 1. The values of variables are set using the |
︙ | ︙ | |||
1042 1043 1044 1045 1046 1047 1048 | if( sqlite3VdbeMemTooBig(pVar) ){ goto too_big; } sqlite3VdbeMemShallowCopy(pOut, &p->aVar[j], MEM_Static); break; } | | | 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 | if( sqlite3VdbeMemTooBig(pVar) ){ goto too_big; } sqlite3VdbeMemShallowCopy(pOut, &p->aVar[j], MEM_Static); break; } /* Opcode: Pop P1 * * * * ** ** P1 elements are popped off of the top of stack and discarded. */ case OP_Pop: { /* no-push */ assert( pOp->p1>=0 ); popStack(&pTos, pOp->p1); assert( pTos>=&p->aStack[-1] ); |
︙ | ︙ | |||
1304 1305 1306 1307 1308 1309 1310 | pOut->flags = MEM_Str|MEM_Dyn|MEM_Term; pOut->xDel = 0; pOut->enc = encoding; pOut->z = zNew; break; } | | < < < | | > | < < < | | < | < < < | | < < < < < < < | < | > | 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 | pOut->flags = MEM_Str|MEM_Dyn|MEM_Term; pOut->xDel = 0; pOut->enc = encoding; pOut->z = zNew; break; } /* Opcode: Add P1 P2 P3 * * ** ** Add the value in P1 to the value in P2 and store the result in P3. ** If either operand is NULL, the result is NULL. */ /* Opcode: Multiply P1 P2 P3 * * ** ** ** Multiply the value in P1 by the value in P2 and store the result in P3. ** If either operand is NULL, the result is NULL. */ /* Opcode: Subtract P1 P2 P3 * * ** ** Subtract the value in P1 from the value in P2 and store the result ** in P3. ** If either operand is NULL, the result is NULL. */ /* Opcode: Divide * * * ** ** Divide the value in P1 by the value in P2 and store the result ** in P3. If the value in P2 is zero, then the result is NULL. ** If either operand is NULL, the result is NULL. */ /* Opcode: Remainder * * * ** ** Compute the remainder after integer division of the value in ** register P1 by the value in register P2 and store the result in P3. ** If the value in register P2 is zero the result is NULL. ** If either operand is NULL, the result is NULL. */ case OP_Add: /* same as TK_PLUS, in1, in2, out3 */ case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */ case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */ case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ |
︙ | ︙ | |||
1644 1645 1646 1647 1648 1649 1650 | pIn1->u.i = v; pIn1->flags = MEM_Int; break; } /* Opcode: MustBeInt P1 P2 P3 ** | > | | | | | < < < | | < < < | | | > | > | | | 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 | pIn1->u.i = v; pIn1->flags = MEM_Int; break; } /* Opcode: MustBeInt P1 P2 P3 ** ** Force the value in register P1 to be an integer. If P1==0 then ** use the top of the stack. If the value in P1 ** is not an integer and cannot be converted into an integer ** without data loss, then jump immediately to P2, or if P2==0 ** raise an SQLITE_MISMATCH exception. ** ** If the P1==0 and the top of the stack is not an integer ** and P2 is not zero and P3 is 1, then the stack is popped. ** In all other cases, the depth of the stack is unchanged. */ case OP_MustBeInt: { /* no-push, jump, in1 */ nPop = 0; applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding); if( (pIn1->flags & MEM_Int)==0 ){ if( pOp->p2==0 ){ rc = SQLITE_MISMATCH; goto abort_due_to_error; }else{ if( pOp->p3 && pOp->p1==0 ){ popStack(&pTos, 1); } pc = pOp->p2 - 1; } }else{ Release(pIn1); pIn1->flags = MEM_Int; } break; } /* Opcode: RealAffinity P1 * * * * ** ** If register P1 holds an integer convert it to a real value. |
︙ | ︙ | |||
1985 1986 1987 1988 1989 1990 1991 | }else{ pOut->u.i = v1; pOut->flags = MEM_Int; } break; } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < > | | | | | | | | | | | | | > | < < < < | < | < | < | < | < | | < | | | | | < | > | 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 | }else{ pOut->u.i = v1; pOut->flags = MEM_Int; } break; } /* Opcode: Not * * * ** ** Interpret the top of the stack as a boolean value. Replace it ** with its complement. If the top of the stack is NULL its value ** is unchanged. */ case OP_Not: { /* same as TK_NOT, no-push, in1 */ nPop = 0; if( pIn1->flags & MEM_Null ) break; /* Do nothing to NULLs */ sqlite3VdbeMemIntegerify(pIn1); assert( (pIn1->flags & MEM_Dyn)==0 ); pIn1->u.i = !pTos->u.i; pIn1->flags = MEM_Int; break; } /* Opcode: BitNot * * * ** ** Interpret the top of the stack as an value. Replace it ** with its ones-complement. If the top of the stack is NULL its ** value is unchanged. */ case OP_BitNot: { /* same as TK_BITNOT, no-push, in1 */ nPop = 0; if( pIn1->flags & MEM_Null ) break; /* Do nothing to NULLs */ sqlite3VdbeMemIntegerify(pIn1); assert( (pIn1->flags & MEM_Dyn)==0 ); pIn1->u.i = ~pTos->u.i; pIn1->flags = MEM_Int; break; } /* Opcode: Noop * * * ** ** Do nothing. This instruction is often useful as a jump ** destination. */ /* ** The magic Explain opcode are only inserted when explain==2 (which ** is to say when the EXPLAIN QUERY PLAN syntax is used.) ** This opcode records information from the optimizer. It is the ** the same as a no-op. This opcodesnever appears in a real VM program. */ case OP_Explain: case OP_Noop: { /* no-push */ break; } /* Opcode: If P1 P2 P3 * * ** ** Jump to P2 if the value in register P1 is true. The value is ** is considered true if it is numeric and non-zero. If the value ** in P1 is NULL then take the jump if P3 is true. */ /* Opcode: IfNot P1 P2 P3 * * ** ** Jump to P2 if the value in register P1 is False. The value is ** is considered true if it has a numeric value of zero. If the value ** in P1 is NULL then take the jump if P3 is true. */ case OP_If: /* no-push, jump, in1 */ case OP_IfNot: { /* no-push, jump, in1 */ int c; if( pIn1->flags & MEM_Null ){ c = pOp->p3; }else{ #ifdef SQLITE_OMIT_FLOATING_POINT c = sqlite3VdbeIntValue(pIn1); #else c = sqlite3VdbeRealValue(pIn1)!=0.0; #endif if( pOp->opcode==OP_IfNot ) c = !c; } if( c ){ pc = pOp->p2-1; } break; } /* Opcode: StackIsNull P1 P2 * ** ** Check the top of the stack and jump to P2 if the top of the stack ** is NULL. If P1 is positive, then pop P1 elements from the stack |
︙ | ︙ | |||
4754 4755 4756 4757 4758 4759 4760 | if( pMem->u.i<pNew->u.i){ pMem->u.i = pNew->u.i; } break; } #endif /* SQLITE_OMIT_AUTOINCREMENT */ | | | < < < < | | | | < < < < | | | | < < < < | | < < < < < < < < < < < < < | 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 | if( pMem->u.i<pNew->u.i){ pMem->u.i = pNew->u.i; } break; } #endif /* SQLITE_OMIT_AUTOINCREMENT */ /* Opcode: IfPos P1 P2 * ** ** If the value of memory cell P1 is 1 or greater, jump to P2. ** ** It is illegal to use this instruction on a memory cell that does ** not contain an integer. An assertion fault will result if you try. */ case OP_IfPos: { /* no-push, jump, in1 */ assert( pIn1->flags==MEM_Int ); if( pIn1->u.i>0 ){ pc = pOp->p2 - 1; } break; } /* Opcode: IfNeg P1 P2 * ** ** If the value of memory cell P1 is less than zero, jump to P2. ** ** It is illegal to use this instruction on a memory cell that does ** not contain an integer. An assertion fault will result if you try. */ case OP_IfNeg: { /* no-push, jump, in1 */ assert( pIn1->flags==MEM_Int ); if( pIn1->u.i<0 ){ pc = pOp->p2 - 1; } break; } /* Opcode: IfZero P1 P2 * ** ** If the value of memory cell P1 is exactly 0, jump to P2. ** ** It is illegal to use this instruction on a memory cell that does ** not contain an integer. An assertion fault will result if you try. */ case OP_IfZero: { /* no-push, jump, in1 */ assert( pIn1->flags==MEM_Int ); if( pIn1->u.i==0 ){ pc = pOp->p2 - 1; } break; } /* Opcode: AggStep P1 P2 P4 ** |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is reponsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is reponsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** ** $Id: where.c,v 1.279 2008/01/09 02:15:42 drh Exp $ */ #include "sqliteInt.h" /* ** The number of bits in a Bitmask. "BMS" means "BitMask Size". */ #define BMS (sizeof(Bitmask)*8) |
︙ | ︙ | |||
2325 2326 2327 2328 2329 2330 2331 | pTerm = findTerm(&wc, iCur, -1, notReady, WO_EQ|WO_IN, 0); assert( pTerm!=0 ); assert( pTerm->pExpr!=0 ); assert( pTerm->leftCursor==iCur ); assert( omitTable==0 ); codeEqualityTerm(pParse, pTerm, pLevel); nxt = pLevel->nxt; | | | 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 | pTerm = findTerm(&wc, iCur, -1, notReady, WO_EQ|WO_IN, 0); assert( pTerm!=0 ); assert( pTerm->pExpr!=0 ); assert( pTerm->leftCursor==iCur ); assert( omitTable==0 ); codeEqualityTerm(pParse, pTerm, pLevel); nxt = pLevel->nxt; sqlite3VdbeAddOp3(v, OP_MustBeInt, 0, nxt, 1); sqlite3VdbeAddOp2(v, OP_NotExists, iCur, nxt); VdbeComment((v, "pk")); pLevel->op = OP_Noop; }else if( pLevel->flags & WHERE_ROWID_RANGE ){ /* Case 2: We have an inequality comparison against the ROWID field. */ int testOp = OP_Noop; |
︙ | ︙ | |||
2762 2763 2764 2765 2766 2767 2768 | sqlite3VdbeJumpHere(v, pIn->topAddr-1); } sqlite3_free(pLevel->aInLoop); } sqlite3VdbeResolveLabel(v, pLevel->brk); if( pLevel->iLeftJoin ){ int addr; | | | | | | | 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 | sqlite3VdbeJumpHere(v, pIn->topAddr-1); } sqlite3_free(pLevel->aInLoop); } sqlite3VdbeResolveLabel(v, pLevel->brk); if( pLevel->iLeftJoin ){ int addr; addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); sqlite3VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor); if( pLevel->iIdxCur>=0 ){ sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur); } sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->top); sqlite3VdbeJumpHere(v, addr); } } /* The "break" point is here, just past the end of the outer loop. ** Set it. */ sqlite3VdbeResolveLabel(v, pWInfo->iBreak); /* Close all of the cursors that were opened by sqlite3WhereBegin. */ for(i=0, pLevel=pWInfo->a; i<pTabList->nSrc; i++, pLevel++){ struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom]; Table *pTab = pTabItem->pTab; assert( pTab!=0 ); if( pTab->isEphem || pTab->pSelect ) continue; if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){ sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor); } if( pLevel->pIdx!=0 ){ sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur); } /* If this scan uses an index, make code substitutions to read data ** from the index in preference to the table. Sometimes, this means ** the table need never be read from. This is a performance boost, ** as the vdbe level waits until the table is read before actually ** seeking the table cursor to the record corresponding to the current |
︙ | ︙ |