Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Factor constant subexpressions out of loops. (CVS 4942) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
2126db39854c751aea6c95c67894ed9b |
User & Date: | drh 2008-03-31 18:19:54.000 |
Context
2008-03-31
| ||
23:48 | Avoid duplicate OP_Column opcodes by remembering prior results. This is similar to CSE, but only applies to columns. (CVS 4943) (check-in: c29ee0fed2 user: drh tags: trunk) | |
18:19 | Factor constant subexpressions out of loops. (CVS 4942) (check-in: 2126db3985 user: drh tags: trunk) | |
17:41 | In setQuotedToken(), only make a malloced copy if the argument contains one or more " characters. (CVS 4941) (check-in: b266924b89 user: danielk1977 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.358 2008/03/31 18:19:54 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Return the 'affinity' of the expression pExpr if any. ** |
︙ | ︙ | |||
782 783 784 785 786 787 788 | sqlite3_free(pItem->zName); } sqlite3_free(pList->a); sqlite3_free(pList); } /* | | > | 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 | sqlite3_free(pItem->zName); } sqlite3_free(pList->a); sqlite3_free(pList); } /* ** Walk an expression tree. Call xFunc for each node visited. xFunc ** is called on the node before xFunc is called on the nodes children. ** ** The return value from xFunc determines whether the tree walk continues. ** 0 means continue walking the tree. 1 means do not walk children ** of the current node but continue with siblings. 2 means abandon ** the tree walk completely. ** ** The return value from this routine is 1 to abandon the tree walk |
︙ | ︙ | |||
1928 1929 1930 1931 1932 1933 1934 | ** ** With this routine, there is no guaranteed that results will ** be stored in target. The result might be stored in some other ** register if it is convenient to do so. The calling function ** must check the return code and move the results to the desired ** register. */ | | | | 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 | ** ** With this routine, there is no guaranteed that results will ** be stored in target. The result might be stored in some other ** register if it is convenient to do so. The calling function ** must check the return code and move the results to the desired ** register. */ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ Vdbe *v = pParse->pVdbe; /* The VM under construction */ int op; /* The opcode being coded */ int inReg = target; /* Results stored in register inReg */ int regFree1 = 0; /* If non-zero free this temporary register */ int regFree2 = 0; /* If non-zero free this temporary register */ int r1, r2, r3, r4; /* Various register numbers */ assert( v!=0 || pParse->db->mallocFailed ); assert( target>0 && target<=pParse->nMem ); if( v==0 ) return 0; if( pExpr==0 ){ op = TK_NULL; |
︙ | ︙ | |||
2223 2224 2225 2226 2227 2228 2229 | */ r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); j1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); sqlite3VdbeAddOp2(v, OP_Null, 0, target); j2 = sqlite3VdbeAddOp0(v, OP_Goto); sqlite3VdbeJumpHere(v, j1); if( eType==IN_INDEX_ROWID ){ | | | 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 | */ r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); j1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); sqlite3VdbeAddOp2(v, OP_Null, 0, target); j2 = sqlite3VdbeAddOp0(v, OP_Goto); sqlite3VdbeJumpHere(v, j1); if( eType==IN_INDEX_ROWID ){ j3 = sqlite3VdbeAddOp1(v, OP_MustBeInt, r1); j4 = sqlite3VdbeAddOp3(v, OP_NotExists, pExpr->iTable, 0, r1); j5 = sqlite3VdbeAddOp0(v, OP_Goto); sqlite3VdbeJumpHere(v, j3); sqlite3VdbeJumpHere(v, j4); }else{ r2 = regFree2 = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp4(v, OP_MakeRecord, r1, 1, r2, &affinity, 1); |
︙ | ︙ | |||
2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 | Expr *pLeft = pExpr->pLeft; struct ExprList_item *pLItem = pExpr->pList->a; Expr *pRight = pLItem->pExpr; r1 = sqlite3ExprCodeTemp(pParse, pLeft, ®Free1); r2 = sqlite3ExprCodeTemp(pParse, pRight, ®Free2); r3 = sqlite3GetTempReg(pParse); codeCompare(pParse, pLeft, pRight, OP_Ge, r1, r2, r3, SQLITE_STOREP2); pLItem++; pRight = pLItem->pExpr; sqlite3ReleaseTempReg(pParse, regFree2); r2 = sqlite3ExprCodeTemp(pParse, pRight, ®Free2); | > | | > | 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 | Expr *pLeft = pExpr->pLeft; struct ExprList_item *pLItem = pExpr->pList->a; Expr *pRight = pLItem->pExpr; r1 = sqlite3ExprCodeTemp(pParse, pLeft, ®Free1); r2 = sqlite3ExprCodeTemp(pParse, pRight, ®Free2); r3 = sqlite3GetTempReg(pParse); r4 = sqlite3GetTempReg(pParse); codeCompare(pParse, pLeft, pRight, OP_Ge, r1, r2, r3, SQLITE_STOREP2); pLItem++; pRight = pLItem->pExpr; sqlite3ReleaseTempReg(pParse, regFree2); r2 = sqlite3ExprCodeTemp(pParse, pRight, ®Free2); codeCompare(pParse, pLeft, pRight, OP_Le, r1, r2, r4, SQLITE_STOREP2); sqlite3VdbeAddOp3(v, OP_And, r3, r4, target); sqlite3ReleaseTempReg(pParse, r3); sqlite3ReleaseTempReg(pParse, r4); break; } case TK_UPLUS: { inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); break; } |
︙ | ︙ | |||
2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 | aListelem = pEList->a; nExpr = pEList->nExpr; endLabel = sqlite3VdbeMakeLabel(v); if( (pX = pExpr->pLeft)!=0 ){ cacheX = *pX; cacheX.iTable = sqlite3ExprCodeTemp(pParse, pX, ®Free1); cacheX.op = TK_REGISTER; opCompare.op = TK_EQ; opCompare.pLeft = &cacheX; pTest = &opCompare; } for(i=0; i<nExpr; i=i+2){ if( pX ){ opCompare.pRight = aListelem[i].pExpr; | > | 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 | aListelem = pEList->a; nExpr = pEList->nExpr; endLabel = sqlite3VdbeMakeLabel(v); if( (pX = pExpr->pLeft)!=0 ){ cacheX = *pX; cacheX.iTable = sqlite3ExprCodeTemp(pParse, pX, ®Free1); cacheX.op = TK_REGISTER; cacheX.iColumn = 0; opCompare.op = TK_EQ; opCompare.pLeft = &cacheX; pTest = &opCompare; } for(i=0; i<nExpr; i=i+2){ if( pX ){ opCompare.pRight = aListelem[i].pExpr; |
︙ | ︙ | |||
2377 2378 2379 2380 2381 2382 2383 | /* ** Generate code to evaluate an expression and store the results ** into a register. Return the register number where the results ** are stored. ** ** If the register is a temporary register that can be deallocated, | | | 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 | /* ** Generate code to evaluate an expression and store the results ** into a register. Return the register number where the results ** are stored. ** ** If the register is a temporary register that can be deallocated, ** then write its number into *pReg. If the result register is not ** a temporary, then set *pReg to zero. */ int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ int r1 = sqlite3GetTempReg(pParse); int r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1); if( r2==r1 ){ *pReg = r1; |
︙ | ︙ | |||
2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 | inReg = sqlite3ExprCode(pParse, pExpr, target); assert( target>0 ); if( pExpr->op!=TK_REGISTER ){ int iMem; iMem = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Copy, inReg, iMem); pExpr->iTable = iMem; pExpr->op = TK_REGISTER; } return inReg; } /* ** Generate code that pushes the value of every element of the given ** expression list into a sequence of registers beginning at target. ** ** Return the number of elements evaluated. | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 | inReg = sqlite3ExprCode(pParse, pExpr, target); assert( target>0 ); if( pExpr->op!=TK_REGISTER ){ int iMem; iMem = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Copy, inReg, iMem); pExpr->iTable = iMem; pExpr->iColumn = pExpr->op; pExpr->op = TK_REGISTER; } return inReg; } /* ** If pExpr is a constant expression, then evaluate the expression ** into a register and convert the expression into a TK_REGISTER ** expression. */ static int evalConstExpr(void *pArg, Expr *pExpr){ Parse *pParse = (Parse*)pArg; if( pExpr->op==TK_REGISTER ){ return 1; } if( sqlite3ExprIsConstantNotJoin(pExpr) ){ int r1 = ++pParse->nMem; int r2; r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1); if( r1!=r2 ) pParse->nMem--; pExpr->iColumn = pExpr->op; pExpr->op = TK_REGISTER; pExpr->iTable = r2; return 1; } return 0; } /* ** Preevaluate constant subexpressions within pExpr and store the ** results in registers. Modify pExpr so that the constant subexpresions ** are TK_REGISTER opcodes that refer to the precomputed values. */ void sqlite3ExprCodeConstants(Parse *pParse, Expr *pExpr){ walkExprTree(pExpr, evalConstExpr, pParse); } /* ** Generate code that pushes the value of every element of the given ** expression list into a sequence of registers beginning at target. ** ** Return the number of elements evaluated. |
︙ | ︙ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.682 2008/03/31 18:19:54 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** Include the configuration header output by 'configure' if it was run ** (otherwise we get an empty default). |
︙ | ︙ | |||
1126 1127 1128 1129 1130 1131 1132 | int nHeight; /* Height of the tree headed by this node */ #endif }; /* ** The following are the meanings of bits in the Expr.flags field. */ | | | | | | | | | | > | 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 | int nHeight; /* Height of the tree headed by this node */ #endif }; /* ** The following are the meanings of bits in the Expr.flags field. */ #define EP_FromJoin 0x0001 /* Originated in ON or USING clause of a join */ #define EP_Agg 0x0002 /* Contains one or more aggregate functions */ #define EP_Resolved 0x0004 /* IDs have been resolved to COLUMNs */ #define EP_Error 0x0008 /* Expression contains one or more errors */ #define EP_Distinct 0x0010 /* Aggregate function with DISTINCT keyword */ #define EP_VarSelect 0x0020 /* pSelect is correlated, not constant */ #define EP_Dequoted 0x0040 /* True if the string has been dequoted */ #define EP_InfixFunc 0x0080 /* True for an infix function: LIKE, GLOB, etc */ #define EP_ExpCollate 0x0100 /* Collating sequence specified explicitly */ #define EP_Constant 0x0200 /* A constant expression */ /* ** These macros can be used to test, set, or clear bits in the ** Expr.flags field. */ #define ExprHasProperty(E,P) (((E)->flags&(P))==(P)) #define ExprHasAnyProperty(E,P) (((E)->flags&(P))!=0) |
︙ | ︙ | |||
1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 | void sqlite3DeleteFrom(Parse*, SrcList*, Expr*); void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**, u8); void sqlite3WhereEnd(WhereInfo*); void sqlite3ExprCodeGetColumn(Vdbe*, Table*, int, int, int); int sqlite3ExprCode(Parse*, Expr*, int); int sqlite3ExprCodeTemp(Parse*, Expr*, int*); int sqlite3ExprCodeAndCache(Parse*, Expr*, int); int sqlite3ExprCodeExprList(Parse*, ExprList*, int); void sqlite3ExprIfTrue(Parse*, Expr*, int, int); void sqlite3ExprIfFalse(Parse*, Expr*, int, int); Table *sqlite3FindTable(sqlite3*,const char*, const char*); Table *sqlite3LocateTable(Parse*,int isView,const char*, const char*); Index *sqlite3FindIndex(sqlite3*,const char*, const char*); void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); | > > | 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 | void sqlite3DeleteFrom(Parse*, SrcList*, Expr*); void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**, u8); void sqlite3WhereEnd(WhereInfo*); void sqlite3ExprCodeGetColumn(Vdbe*, Table*, int, int, int); int sqlite3ExprCode(Parse*, Expr*, int); int sqlite3ExprCodeTemp(Parse*, Expr*, int*); int sqlite3ExprCodeTarget(Parse*, Expr*, int); int sqlite3ExprCodeAndCache(Parse*, Expr*, int); void sqlite3ExprCodeConstants(Parse*, Expr*); int sqlite3ExprCodeExprList(Parse*, ExprList*, int); void sqlite3ExprIfTrue(Parse*, Expr*, int, int); void sqlite3ExprIfFalse(Parse*, Expr*, int, int); Table *sqlite3FindTable(sqlite3*,const char*, const char*); Table *sqlite3LocateTable(Parse*,int isView,const char*, const char*); Index *sqlite3FindIndex(sqlite3*,const char*, const char*); void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); |
︙ | ︙ |
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.723 2008/03/31 18:19:54 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" /* ** The following global variable is incremented every time a cursor |
︙ | ︙ | |||
99 100 101 102 103 104 105 | } #endif /* ** Test a register to see if it exceeds the current maximum blob size. ** If it does, record the new maximum blob size. */ | | | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | } #endif /* ** Test a register to see if it exceeds the current maximum blob size. ** If it does, record the new maximum blob size. */ #if defined(SQLITE_TEST) && !defined(SQLITE_OMIT_BUILTIN_TEST) # define UPDATE_MAX_BLOBSIZE(P) updateMaxBlobsize(P) #else # define UPDATE_MAX_BLOBSIZE(P) #endif /* ** Release the memory associated with a register. This |
︙ | ︙ |
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.295 2008/03/31 18:19:54 drh Exp $ */ #include "sqliteInt.h" /* ** The number of bits in a Bitmask. "BMS" means "BitMask Size". */ #define BMS (sizeof(Bitmask)*8) |
︙ | ︙ | |||
531 532 533 534 535 536 537 | return 0; } #ifdef SQLITE_EBCDIC if( *pnoCase ) return 0; #endif pList = pExpr->pList; pRight = pList->a[0].pExpr; | | > | 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 | return 0; } #ifdef SQLITE_EBCDIC if( *pnoCase ) return 0; #endif pList = pExpr->pList; pRight = pList->a[0].pExpr; if( pRight->op!=TK_STRING && (pRight->op!=TK_REGISTER || pRight->iColumn!=TK_STRING) ){ return 0; } pLeft = pList->a[1].pExpr; if( pLeft->op!=TK_COLUMN ){ return 0; } pColl = pLeft->pColl; |
︙ | ︙ | |||
1748 1749 1750 1751 1752 1753 1754 | ** ** The current value for the constraint is left in register iReg. ** ** For a constraint of the form X=expr, the expression is evaluated and its ** result is left on the stack. For constraints of the form X IN (...) ** this routine sets up a loop that will iterate over all values of X. */ | | | > > | > | > > | 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 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 | ** ** The current value for the constraint is left in register iReg. ** ** For a constraint of the form X=expr, the expression is evaluated and its ** result is left on the stack. For constraints of the form X IN (...) ** this routine sets up a loop that will iterate over all values of X. */ static int codeEqualityTerm( Parse *pParse, /* The parsing context */ WhereTerm *pTerm, /* The term of the WHERE clause to be coded */ WhereLevel *pLevel, /* When level of the FROM clause we are working on */ int iTarget /* Attempt to leave results in this register */ ){ Expr *pX = pTerm->pExpr; Vdbe *v = pParse->pVdbe; int iReg; /* Register holding results */ if( iTarget<=0 ){ iReg = iTarget = sqlite3GetTempReg(pParse); } if( pX->op==TK_EQ ){ iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget); }else if( pX->op==TK_ISNULL ){ iReg = iTarget; sqlite3VdbeAddOp2(v, OP_Null, 0, iReg); #ifndef SQLITE_OMIT_SUBQUERY }else{ int eType; int iTab; struct InLoop *pIn; assert( pX->op==TK_IN ); iReg = iTarget; eType = sqlite3FindInIndex(pParse, pX, 1); iTab = pX->iTable; sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); VdbeComment((v, "%.*s", pX->span.n, pX->span.z)); if( pLevel->nIn==0 ){ pLevel->nxt = sqlite3VdbeMakeLabel(v); } |
︙ | ︙ | |||
1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 | sqlite3VdbeAddOp1(v, OP_IsNull, iReg); }else{ pLevel->nIn = 0; } #endif } disableTerm(pLevel, pTerm); } /* ** Generate code that will evaluate all == and IN constraints for an ** index. The values for all constraints are left on the stack. ** ** For example, consider table t1(a,b,c,d,e,f) with index i1(a,b,c). | > | 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 | sqlite3VdbeAddOp1(v, OP_IsNull, iReg); }else{ pLevel->nIn = 0; } #endif } disableTerm(pLevel, pTerm); return iReg; } /* ** Generate code that will evaluate all == and IN constraints for an ** index. The values for all constraints are left on the stack. ** ** For example, consider table t1(a,b,c,d,e,f) with index i1(a,b,c). |
︙ | ︙ | |||
1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 | regBase = pParse->nMem + 2; pParse->nMem += pLevel->nEq + 2 + nExtraReg; /* Evaluate the equality constraints */ assert( pIdx->nColumn>=nEq ); for(j=0; j<nEq; j++){ int k = pIdx->aiColumn[j]; pTerm = findTerm(pWC, iCur, k, notReady, pLevel->flags, pIdx); if( pTerm==0 ) break; assert( (pTerm->flags & TERM_CODED)==0 ); | > | > > > | 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 | regBase = pParse->nMem + 2; pParse->nMem += pLevel->nEq + 2 + nExtraReg; /* Evaluate the equality constraints */ assert( pIdx->nColumn>=nEq ); for(j=0; j<nEq; j++){ int r1; int k = pIdx->aiColumn[j]; pTerm = findTerm(pWC, iCur, k, notReady, pLevel->flags, pIdx); if( pTerm==0 ) break; assert( (pTerm->flags & TERM_CODED)==0 ); r1 = codeEqualityTerm(pParse, pTerm, pLevel, regBase+j); if( r1!=regBase+j ){ sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j); } if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){ sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->brk); } } return regBase; } |
︙ | ︙ | |||
2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 | } /* Split the WHERE clause into separate subexpressions where each ** subexpression is separated by an AND operator. */ initMaskSet(&maskSet); whereClauseInit(&wc, pParse, &maskSet); whereSplit(&wc, pWhere, TK_AND); /* Allocate and initialize the WhereInfo structure that will become the ** return value. */ db = pParse->db; pWInfo = sqlite3DbMallocZero(db, | > | 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 | } /* Split the WHERE clause into separate subexpressions where each ** subexpression is separated by an AND operator. */ initMaskSet(&maskSet); whereClauseInit(&wc, pParse, &maskSet); sqlite3ExprCodeConstants(pParse, pWhere); whereSplit(&wc, pWhere, TK_AND); /* Allocate and initialize the WhereInfo structure that will become the ** return value. */ db = pParse->db; pWInfo = sqlite3DbMallocZero(db, |
︙ | ︙ | |||
2363 2364 2365 2366 2367 2368 2369 | */ int r1; 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 ); | < | | < | 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 | */ int r1; 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 ); r1 = codeEqualityTerm(pParse, pTerm, pLevel, 0); nxt = pLevel->nxt; sqlite3VdbeAddOp2(v, OP_MustBeInt, r1, nxt); sqlite3VdbeAddOp3(v, OP_NotExists, iCur, nxt, r1); 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; int start; WhereTerm *pStart, *pEnd; |
︙ | ︙ |