Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Change the sqlite3ExprCode() function so that callers can request that the result of the expression be left on the stack or in a register. (CVS 4673) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
61bfb77c4267b99ac8a8ef49355bcbc3 |
User & Date: | drh 2008-01-03 23:44:53.000 |
Context
2008-01-04
| ||
11:01 | Add OP_MemSet, for setting a memory cell to a string value. (CVS 4674) (check-in: 8bb9f970dd user: danielk1977 tags: trunk) | |
2008-01-03
| ||
23:44 | Change the sqlite3ExprCode() function so that callers can request that the result of the expression be left on the stack or in a register. (CVS 4673) (check-in: 61bfb77c42 user: drh tags: trunk) | |
18:56 | Fix typo in comment. Ticket #2870. (CVS 4672) (check-in: e97e457867 user: danielk1977 tags: trunk) | |
Changes
Changes to src/attach.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 ATTACH and DETACH commands. ** | | | 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 ATTACH and DETACH commands. ** ** $Id: attach.c,v 1.66 2008/01/03 23:44:53 drh Exp $ */ #include "sqliteInt.h" #ifndef SQLITE_OMIT_ATTACH /* ** Resolve an expression that was part of an ATTACH or DETACH statement. This ** is slightly different from resolving a normal SQL expression, because simple |
︙ | ︙ | |||
322 323 324 325 326 327 328 | SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey)) ){ pParse->nErr++; goto attach_end; } v = sqlite3GetVdbe(pParse); | | | | | 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 | SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey)) ){ pParse->nErr++; goto attach_end; } v = sqlite3GetVdbe(pParse); sqlite3ExprCode(pParse, pFilename, 0); sqlite3ExprCode(pParse, pDbname, 0); sqlite3ExprCode(pParse, pKey, 0); assert( v || db->mallocFailed ); if( v ){ sqlite3VdbeAddOp2(v, OP_Function, 0, nFunc); pFunc = sqlite3FindFunction(db, zFunc, strlen(zFunc), nFunc, SQLITE_UTF8,0); sqlite3VdbeChangeP4(v, -1, (char *)pFunc, P4_FUNCDEF); |
︙ | ︙ |
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.329 2008/01/03 23:44:53 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Return the 'affinity' of the expression pExpr if any. ** |
︙ | ︙ | |||
1780 1781 1782 1783 1784 1785 1786 | */ if( testAddr>0 && !sqlite3ExprIsConstant(pE2) ){ sqlite3VdbeChangeToNoop(v, testAddr-1, 3); testAddr = 0; } /* Evaluate the expression and insert it into the temp table */ | | | 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 | */ if( testAddr>0 && !sqlite3ExprIsConstant(pE2) ){ sqlite3VdbeChangeToNoop(v, testAddr-1, 3); testAddr = 0; } /* Evaluate the expression and insert it into the temp table */ sqlite3ExprCode(pParse, pE2, 0); sqlite3VdbeAddOp4(v, OP_MakeRecord, 1, 0, 0, &affinity, 1); sqlite3VdbeAddOp1(v, OP_IdxInsert, pExpr->iTable); } } sqlite3VdbeChangeP4(v, addr, (void *)&keyInfo, P4_KEYINFO); break; } |
︙ | ︙ | |||
1923 1924 1925 1926 1927 1928 1929 | } #endif } } /* ** Generate code into the current Vdbe to evaluate the given | | > > > > > | > | > > | > > | < > | > > > > | > | | > | > | 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 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 | } #endif } } /* ** Generate code into the current Vdbe to evaluate the given ** expression and leaves the result in a register on on the stack. ** ** If the target register number is negative, allocate a new ** register to store the result. If the target register number ** is zero then push the result onto the stack. Return the target ** register number regardless. ** ** This code depends on the fact that certain token values (ex: TK_EQ) ** are the same as opcode values (ex: OP_Eq) that implement the corresponding ** operation. Special comments in vdbe.c and the mkopcodeh.awk script in ** the make process cause these values to align. Assert()s in the code ** below verify that the numbers are aligned correctly. */ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ Vdbe *v = pParse->pVdbe; int op; int inReg = 0; int stackChng = 0; int subtarget = -1; assert( v!=0 || pParse->db->mallocFailed ); if( v==0 ) return 0; if( target<0 ){ target = ++pParse->nMem; }else if( target==0 ){ stackChng = 1; subtarget = 0; } if( pExpr==0 ){ op = TK_NULL; }else{ op = pExpr->op; } switch( op ){ case TK_AGG_COLUMN: { AggInfo *pAggInfo = pExpr->pAggInfo; struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg]; if( !pAggInfo->directMode ){ sqlite3VdbeAddOp1(v, OP_MemLoad, pCol->iMem); break; }else if( pAggInfo->useSortingIdx ){ sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdx, pCol->iSorterColumn, target); inReg = 1; break; } /* Otherwise, fall thru into the TK_COLUMN case */ } case TK_COLUMN: { if( pExpr->iTable<0 ){ /* This only happens when coding check constraints */ assert( pParse->ckOffset>0 ); sqlite3VdbeAddOp2(v, OP_Dup, pParse->ckOffset-pExpr->iColumn-1, 1); }else{ sqlite3ExprCodeGetColumn(v, pExpr->pTab, pExpr->iColumn, pExpr->iTable, target); inReg = 1; } break; } case TK_INTEGER: { codeInteger(v, (char*)pExpr->token.z, pExpr->token.n, 0); break; } |
︙ | ︙ | |||
2015 2016 2017 2018 2019 2020 2021 | sqlite3VdbeAddOp1(v, OP_MemLoad, pExpr->iTable); break; } #ifndef SQLITE_OMIT_CAST case TK_CAST: { /* Expressions of the form: CAST(pLeft AS token) */ int aff, to_op; | | | 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 | sqlite3VdbeAddOp1(v, OP_MemLoad, pExpr->iTable); break; } #ifndef SQLITE_OMIT_CAST case TK_CAST: { /* Expressions of the form: CAST(pLeft AS token) */ int aff, to_op; sqlite3ExprCode(pParse, pExpr->pLeft, 0); aff = sqlite3AffinityType(&pExpr->token); to_op = aff - SQLITE_AFF_TEXT + OP_ToText; assert( to_op==OP_ToText || aff!=SQLITE_AFF_TEXT ); assert( to_op==OP_ToBlob || aff!=SQLITE_AFF_NONE ); assert( to_op==OP_ToNumeric || aff!=SQLITE_AFF_NUMERIC ); assert( to_op==OP_ToInt || aff!=SQLITE_AFF_INTEGER ); assert( to_op==OP_ToReal || aff!=SQLITE_AFF_REAL ); |
︙ | ︙ | |||
2040 2041 2042 2043 2044 2045 2046 | case TK_EQ: { assert( TK_LT==OP_Lt ); assert( TK_LE==OP_Le ); assert( TK_GT==OP_Gt ); assert( TK_GE==OP_Ge ); assert( TK_EQ==OP_Eq ); assert( TK_NE==OP_Ne ); | | | | 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 | case TK_EQ: { assert( TK_LT==OP_Lt ); assert( TK_LE==OP_Le ); assert( TK_GT==OP_Gt ); assert( TK_GE==OP_Ge ); assert( TK_EQ==OP_Eq ); assert( TK_NE==OP_Ne ); sqlite3ExprCode(pParse, pExpr->pLeft, 0); sqlite3ExprCode(pParse, pExpr->pRight, 0); codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, 0, 0); stackChng = -1; break; } case TK_AND: case TK_OR: case TK_PLUS: |
︙ | ︙ | |||
2069 2070 2071 2072 2073 2074 2075 | assert( TK_REM==OP_Remainder ); assert( TK_BITAND==OP_BitAnd ); assert( TK_BITOR==OP_BitOr ); assert( TK_SLASH==OP_Divide ); assert( TK_LSHIFT==OP_ShiftLeft ); assert( TK_RSHIFT==OP_ShiftRight ); assert( TK_CONCAT==OP_Concat ); | | | | 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 | assert( TK_REM==OP_Remainder ); assert( TK_BITAND==OP_BitAnd ); assert( TK_BITOR==OP_BitOr ); assert( TK_SLASH==OP_Divide ); assert( TK_LSHIFT==OP_ShiftLeft ); assert( TK_RSHIFT==OP_ShiftRight ); assert( TK_CONCAT==OP_Concat ); sqlite3ExprCode(pParse, pExpr->pLeft, 0); sqlite3ExprCode(pParse, pExpr->pRight, 0); sqlite3VdbeAddOp0(v, op); stackChng = -1; break; } case TK_UMINUS: { Expr *pLeft = pExpr->pLeft; assert( pLeft ); |
︙ | ︙ | |||
2093 2094 2095 2096 2097 2098 2099 | } /* Fall through into TK_NOT */ } case TK_BITNOT: case TK_NOT: { assert( TK_BITNOT==OP_BitNot ); assert( TK_NOT==OP_Not ); | | | | 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 | } /* Fall through into TK_NOT */ } case TK_BITNOT: case TK_NOT: { assert( TK_BITNOT==OP_BitNot ); assert( TK_NOT==OP_Not ); sqlite3ExprCode(pParse, pExpr->pLeft, 0); sqlite3VdbeAddOp0(v, op); stackChng = 0; break; } case TK_ISNULL: case TK_NOTNULL: { int dest; assert( TK_ISNULL==OP_IsNull ); assert( TK_NOTNULL==OP_NotNull ); sqlite3VdbeAddOp1(v, OP_Integer, 1); sqlite3ExprCode(pParse, pExpr->pLeft, 0); dest = sqlite3VdbeCurrentAddr(v) + 2; sqlite3VdbeAddOp2(v, op, 1, dest); sqlite3VdbeAddOp1(v, OP_AddImm, -1); stackChng = 0; break; } case TK_AGG_FUNCTION: { |
︙ | ︙ | |||
2138 2139 2140 2141 2142 2143 2144 | u8 enc = ENC(db); CollSeq *pColl = 0; zId = (char*)pExpr->token.z; nId = pExpr->token.n; pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0); assert( pDef!=0 ); | | | 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 | u8 enc = ENC(db); CollSeq *pColl = 0; zId = (char*)pExpr->token.z; nId = pExpr->token.n; pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0); assert( pDef!=0 ); nExpr = sqlite3ExprCodeExprList(pParse, pList, 0); #ifndef SQLITE_OMIT_VIRTUALTABLE /* Possibly overload the function if the first argument is ** a virtual table column. ** ** For infix functions (LIKE, GLOB, REGEXP, and MATCH) use the ** second argument, not the first, as the argument to test to ** see if it is a column in a virtual table. This is done because |
︙ | ︙ | |||
2206 2207 2208 2209 2210 2211 2212 | sqlite3VdbeAddOp1(v, OP_Integer, 1); pParse->ckOffset = (ckOffset ? (ckOffset+1) : 0); /* Code the <expr> from "<expr> IN (...)". The temporary table ** pExpr->iTable contains the values that make up the (...) set. */ | | | 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 | sqlite3VdbeAddOp1(v, OP_Integer, 1); pParse->ckOffset = (ckOffset ? (ckOffset+1) : 0); /* Code the <expr> from "<expr> IN (...)". The temporary table ** pExpr->iTable contains the values that make up the (...) set. */ sqlite3ExprCode(pParse, pExpr->pLeft, 0); addr = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp2(v, OP_NotNull, -1, addr+4); /* addr + 0 */ sqlite3VdbeAddOp1(v, OP_Pop, 2); sqlite3VdbeAddOp0(v, OP_Null); sqlite3VdbeAddOp2(v, OP_Goto, 0, iLabel); if( eType==IN_INDEX_ROWID ){ int iAddr = sqlite3VdbeCurrentAddr(v)+3; |
︙ | ︙ | |||
2232 2233 2234 2235 2236 2237 2238 | break; } #endif case TK_BETWEEN: { Expr *pLeft = pExpr->pLeft; struct ExprList_item *pLItem = pExpr->pList->a; Expr *pRight = pLItem->pExpr; | | | | | | | | | | > > > | > | < < < < < < < < < < < < < < < < < < < < < < < < < < < | > | > > > > > > | > | 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 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 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 | break; } #endif case TK_BETWEEN: { Expr *pLeft = pExpr->pLeft; struct ExprList_item *pLItem = pExpr->pList->a; Expr *pRight = pLItem->pExpr; sqlite3ExprCode(pParse, pLeft, 0); sqlite3VdbeAddOp0(v, OP_Dup); sqlite3ExprCode(pParse, pRight, 0); codeCompare(pParse, pLeft, pRight, OP_Ge, 0, 0); sqlite3VdbeAddOp1(v, OP_Pull, 1); pLItem++; pRight = pLItem->pExpr; sqlite3ExprCode(pParse, pRight, 0); codeCompare(pParse, pLeft, pRight, OP_Le, 0, 0); sqlite3VdbeAddOp0(v, OP_And); break; } case TK_UPLUS: { sqlite3ExprCode(pParse, pExpr->pLeft, 0); stackChng = 0; break; } case TK_CASE: { int expr_end_label; int jumpInst; int nExpr; int i; ExprList *pEList; struct ExprList_item *aListelem; assert(pExpr->pList); assert((pExpr->pList->nExpr % 2) == 0); assert(pExpr->pList->nExpr > 0); pEList = pExpr->pList; aListelem = pEList->a; nExpr = pEList->nExpr; expr_end_label = sqlite3VdbeMakeLabel(v); if( pExpr->pLeft ){ sqlite3ExprCode(pParse, pExpr->pLeft, 0); } for(i=0; i<nExpr; i=i+2){ sqlite3ExprCode(pParse, aListelem[i].pExpr, 0); if( pExpr->pLeft ){ sqlite3VdbeAddOp2(v, OP_Dup, 1, 1); jumpInst = codeCompare(pParse, pExpr->pLeft, aListelem[i].pExpr, OP_Ne, 0, 1); sqlite3VdbeAddOp1(v, OP_Pop, 1); }else{ jumpInst = sqlite3VdbeAddOp2(v, OP_IfNot, 1, 0); } sqlite3ExprCode(pParse, aListelem[i+1].pExpr, 0); sqlite3VdbeAddOp2(v, OP_Goto, 0, expr_end_label); sqlite3VdbeJumpHere(v, jumpInst); } if( pExpr->pLeft ){ sqlite3VdbeAddOp2(v, OP_Pop, 1, 0); } if( pExpr->pRight ){ sqlite3ExprCode(pParse, pExpr->pRight, 0); }else{ sqlite3VdbeAddOp2(v, OP_Null, 0, 0); } sqlite3VdbeResolveLabel(v, expr_end_label); break; } #ifndef SQLITE_OMIT_TRIGGER case TK_RAISE: { if( !pParse->trigStack ){ sqlite3ErrorMsg(pParse, "RAISE() may only be used within a trigger-program"); return 0; } if( pExpr->iColumn!=OE_Ignore ){ assert( pExpr->iColumn==OE_Rollback || pExpr->iColumn == OE_Abort || pExpr->iColumn == OE_Fail ); sqlite3DequoteExpr(pParse->db, pExpr); sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, pExpr->iColumn, 0, (char*)pExpr->token.z, pExpr->token.n); } else { assert( pExpr->iColumn == OE_Ignore ); sqlite3VdbeAddOp2(v, OP_ContextPop, 0, 0); sqlite3VdbeAddOp2(v, OP_Goto, 0, pParse->trigStack->ignoreJump); VdbeComment((v, "raise(IGNORE)")); } stackChng = 0; break; } #endif } if( target && !inReg ){ sqlite3VdbeAddOp2(v, OP_MemStore, target, 1); stackChng = 0; } if( pParse->ckOffset ){ pParse->ckOffset += stackChng; assert( pParse->ckOffset ); } return target; } #ifndef SQLITE_OMIT_TRIGGER /* ** Generate code that evalutes the given expression and leaves the result ** on the stack. See also sqlite3ExprCode(). ** ** This routine might also cache the result and modify the pExpr tree ** so that it will make use of the cached result on subsequent evaluations ** rather than evaluate the whole expression again. Trivial expressions are ** not cached. If the expression is cached, its result is stored in a ** memory location. */ void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr){ Vdbe *v = pParse->pVdbe; VdbeOp *pOp; int iMem; int addr1, addr2; if( v==0 ) return; addr1 = sqlite3VdbeCurrentAddr(v); sqlite3ExprCode(pParse, pExpr, 0); addr2 = sqlite3VdbeCurrentAddr(v); if( addr2>addr1+1 || ((pOp = sqlite3VdbeGetOp(v, addr1))!=0 && pOp->opcode==OP_Function) ){ iMem = pExpr->iTable = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_MemStore, iMem, 0); pExpr->op = TK_REGISTER; } } #endif /* ** Generate code that pushes the value of every element of the given ** expression list onto the stack. ** ** Return the number of elements pushed onto the stack. */ int sqlite3ExprCodeExprList( Parse *pParse, /* Parsing context */ ExprList *pList, /* The expression list to be coded */ int target /* Where to write results */ ){ struct ExprList_item *pItem; int i, n, incr = 1; if( pList==0 ) return 0; n = pList->nExpr; if( target<0 ){ target = pParse->nMem+1; pParse->nMem += n; }else if( target==0 ){ incr = 0; } for(pItem=pList->a, i=n; i>0; i--, pItem++){ sqlite3ExprCode(pParse, pItem->pExpr, target); target += incr; } return n; } /* ** Generate code for a boolean expression such that a jump is made ** to the label "dest" if the expression is true but execution |
︙ | ︙ | |||
2449 2450 2451 2452 2453 2454 2455 | case TK_EQ: { assert( TK_LT==OP_Lt ); assert( TK_LE==OP_Le ); assert( TK_GT==OP_Gt ); assert( TK_GE==OP_Ge ); assert( TK_EQ==OP_Eq ); assert( TK_NE==OP_Ne ); | | | | | | | | | 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 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 | case TK_EQ: { assert( TK_LT==OP_Lt ); assert( TK_LE==OP_Le ); assert( TK_GT==OP_Gt ); assert( TK_GE==OP_Ge ); assert( TK_EQ==OP_Eq ); assert( TK_NE==OP_Ne ); sqlite3ExprCode(pParse, pExpr->pLeft, 0); sqlite3ExprCode(pParse, pExpr->pRight, 0); codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, dest, jumpIfNull); break; } case TK_ISNULL: case TK_NOTNULL: { assert( TK_ISNULL==OP_IsNull ); assert( TK_NOTNULL==OP_NotNull ); sqlite3ExprCode(pParse, pExpr->pLeft, 0); sqlite3VdbeAddOp2(v, op, 1, dest); break; } case TK_BETWEEN: { /* The expression "x BETWEEN y AND z" is implemented as: ** ** 1 IF (x < y) GOTO 3 ** 2 IF (x <= z) GOTO <dest> ** 3 ... */ int addr; Expr *pLeft = pExpr->pLeft; Expr *pRight = pExpr->pList->a[0].pExpr; sqlite3ExprCode(pParse, pLeft, 0); sqlite3VdbeAddOp2(v, OP_Dup, 0, 0); sqlite3ExprCode(pParse, pRight, 0); addr = codeCompare(pParse, pLeft, pRight, OP_Lt, 0, !jumpIfNull); pRight = pExpr->pList->a[1].pExpr; sqlite3ExprCode(pParse, pRight, 0); codeCompare(pParse, pLeft, pRight, OP_Le, dest, jumpIfNull); sqlite3VdbeAddOp2(v, OP_Integer, 0, 0); sqlite3VdbeJumpHere(v, addr); sqlite3VdbeAddOp2(v, OP_Pop, 1, 0); break; } default: { sqlite3ExprCode(pParse, pExpr, 0); sqlite3VdbeAddOp2(v, OP_If, jumpIfNull, dest); break; } } pParse->ckOffset = ckOffset; } |
︙ | ︙ | |||
2563 2564 2565 2566 2567 2568 2569 | } case TK_LT: case TK_LE: case TK_GT: case TK_GE: case TK_NE: case TK_EQ: { | | | | | | | | | 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 | } case TK_LT: case TK_LE: case TK_GT: case TK_GE: case TK_NE: case TK_EQ: { sqlite3ExprCode(pParse, pExpr->pLeft, 0); sqlite3ExprCode(pParse, pExpr->pRight, 0); codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, dest, jumpIfNull); break; } case TK_ISNULL: case TK_NOTNULL: { sqlite3ExprCode(pParse, pExpr->pLeft, 0); sqlite3VdbeAddOp2(v, op, 1, dest); break; } case TK_BETWEEN: { /* The expression is "x BETWEEN y AND z". It is implemented as: ** ** 1 IF (x >= y) GOTO 3 ** 2 GOTO <dest> ** 3 IF (x > z) GOTO <dest> */ int addr; Expr *pLeft = pExpr->pLeft; Expr *pRight = pExpr->pList->a[0].pExpr; sqlite3ExprCode(pParse, pLeft, 0); sqlite3VdbeAddOp2(v, OP_Dup, 0, 0); sqlite3ExprCode(pParse, pRight, 0); addr = sqlite3VdbeCurrentAddr(v); codeCompare(pParse, pLeft, pRight, OP_Ge, addr+3, !jumpIfNull); sqlite3VdbeAddOp2(v, OP_Pop, 1, 0); sqlite3VdbeAddOp2(v, OP_Goto, 0, dest); pRight = pExpr->pList->a[1].pExpr; sqlite3ExprCode(pParse, pRight, 0); codeCompare(pParse, pLeft, pRight, OP_Gt, dest, jumpIfNull); break; } default: { sqlite3ExprCode(pParse, pExpr, 0); sqlite3VdbeAddOp2(v, OP_IfNot, jumpIfNull, dest); break; } } pParse->ckOffset = ckOffset; } |
︙ | ︙ |
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.208 2008/01/03 23:44:53 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: |
︙ | ︙ | |||
656 657 658 659 660 661 662 | */ if( keyColumn<0 ){ sqlite3VdbeAddOp2(v, OP_Integer, -1, 0); }else if( useTempTable ){ sqlite3VdbeAddOp2(v, OP_Column, srcTab, keyColumn); }else{ assert( pSelect==0 ); /* Otherwise useTempTable is true */ | | | 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 | */ if( keyColumn<0 ){ sqlite3VdbeAddOp2(v, OP_Integer, -1, 0); }else if( useTempTable ){ sqlite3VdbeAddOp2(v, OP_Column, srcTab, keyColumn); }else{ assert( pSelect==0 ); /* Otherwise useTempTable is true */ sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, 0); sqlite3VdbeAddOp2(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3); sqlite3VdbeAddOp2(v, OP_Pop, 1, 0); sqlite3VdbeAddOp2(v, OP_Integer, -1, 0); sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0); } /* Cannot have triggers on a virtual table. If it were possible, |
︙ | ︙ | |||
679 680 681 682 683 684 685 | j = i; }else{ for(j=0; j<pColumn->nId; j++){ if( pColumn->a[j].idx==i ) break; } } if( pColumn && j>=pColumn->nId ){ | | | 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 | j = i; }else{ for(j=0; j<pColumn->nId; j++){ if( pColumn->a[j].idx==i ) break; } } if( pColumn && j>=pColumn->nId ){ sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, 0); }else if( useTempTable ){ sqlite3VdbeAddOp2(v, OP_Column, srcTab, j); }else{ assert( pSelect==0 ); /* Otherwise useTempTable is true */ sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr); } } |
︙ | ︙ | |||
723 724 725 726 727 728 729 | if( keyColumn>=0 ){ if( useTempTable ){ sqlite3VdbeAddOp2(v, OP_Column, srcTab, keyColumn); }else if( pSelect ){ sqlite3VdbeAddOp2(v, OP_Dup, nColumn - keyColumn - 1, 1); }else{ VdbeOp *pOp; | | | 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 | if( keyColumn>=0 ){ if( useTempTable ){ sqlite3VdbeAddOp2(v, OP_Column, srcTab, keyColumn); }else if( pSelect ){ sqlite3VdbeAddOp2(v, OP_Dup, nColumn - keyColumn - 1, 1); }else{ VdbeOp *pOp; sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, 0); pOp = sqlite3VdbeGetOp(v, sqlite3VdbeCurrentAddr(v) - 1); if( pOp && pOp->opcode==OP_Null ){ appendFlag = 1; pOp->opcode = OP_NewRowid; pOp->p1 = base; pOp->p2 = counterMem; } |
︙ | ︙ | |||
776 777 778 779 780 781 782 | } }else{ for(j=0; j<pColumn->nId; j++){ if( pColumn->a[j].idx==i ) break; } } if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){ | | | | 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 | } }else{ for(j=0; j<pColumn->nId; j++){ if( pColumn->a[j].idx==i ) break; } } if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){ sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, 0); }else if( useTempTable ){ sqlite3VdbeAddOp2(v, OP_Column, srcTab, j); }else if( pSelect ){ sqlite3VdbeAddOp2(v, OP_Dup, i+nColumn-j+IsVirtual(pTab), 1); }else{ sqlite3ExprCode(pParse, pList->a[j].pExpr, 0); } } /* Generate code to check constraints and generate index keys and ** do the insertion. */ #ifndef SQLITE_OMIT_VIRTUALTABLE |
︙ | ︙ | |||
1008 1009 1010 1011 1012 1013 1014 | } case OE_Ignore: { sqlite3VdbeAddOp2(v, OP_Pop, nCol+1+hasTwoRowids, 0); sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest); break; } case OE_Replace: { | | | 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 | } case OE_Ignore: { sqlite3VdbeAddOp2(v, OP_Pop, nCol+1+hasTwoRowids, 0); sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest); break; } case OE_Replace: { sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, 0); sqlite3VdbeAddOp2(v, OP_Push, nCol-i, 0); break; } } sqlite3VdbeJumpHere(v, addr); } |
︙ | ︙ |
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.383 2008/01/03 23:44:53 drh Exp $ */ #include "sqliteInt.h" /* ** Delete all the content of a Select structure but do not deallocate ** the select structure itself. |
︙ | ︙ | |||
383 384 385 386 387 388 389 | */ static void pushOntoSorter( Parse *pParse, /* Parser context */ ExprList *pOrderBy, /* The ORDER BY clause */ Select *pSelect /* The whole SELECT statement */ ){ Vdbe *v = pParse->pVdbe; | | | 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 | */ 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); sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, 0); sqlite3VdbeAddOp2(v, OP_Pull, pOrderBy->nExpr + 1, 0); sqlite3VdbeAddOp2(v, OP_MakeRecord, pOrderBy->nExpr + 2, 0); sqlite3VdbeAddOp2(v, OP_IdxInsert, pOrderBy->iECursor, 0); if( pSelect->iLimit>=0 ){ int addr1, addr2; addr1 = sqlite3VdbeAddOp2(v, OP_IfMemZero, pSelect->iLimit+1, 0); |
︙ | ︙ | |||
549 550 551 552 553 554 555 | sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, iMem+i+1); } }else if( eDest!=SRT_Exists ){ /* If the destination is an EXISTS(...) expression, the actual ** values returned by the SELECT are not required. */ for(i=0; i<n; i++){ | | | 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 | sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, iMem+i+1); } }else if( eDest!=SRT_Exists ){ /* If the destination is an EXISTS(...) expression, the actual ** values returned by the SELECT are not required. */ for(i=0; i<n; i++){ sqlite3ExprCode(pParse, pEList->a[i].pExpr, iMem+i+1); } } nColumn = n; /* If the DISTINCT keyword was present on the SELECT statement ** and this row has been seen before, then do not make this row ** part of the result. |
︙ | ︙ | |||
1746 1747 1748 1749 1750 1751 1752 | ** no rows. */ if( p->pLimit ){ p->iLimit = iLimit = ++pParse->nMem; pParse->nMem++; v = sqlite3GetVdbe(pParse); if( v==0 ) return; | | | | 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 | ** no rows. */ if( p->pLimit ){ p->iLimit = iLimit = ++pParse->nMem; pParse->nMem++; v = sqlite3GetVdbe(pParse); if( v==0 ) return; sqlite3ExprCode(pParse, p->pLimit, 0); sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0); sqlite3VdbeAddOp2(v, OP_MemStore, iLimit, 1); VdbeComment((v, "LIMIT counter")); sqlite3VdbeAddOp2(v, OP_IfMemZero, iLimit, iBreak); sqlite3VdbeAddOp2(v, OP_MemLoad, iLimit, 0); } if( p->pOffset ){ p->iOffset = iOffset = ++pParse->nMem; v = sqlite3GetVdbe(pParse); if( v==0 ) return; sqlite3ExprCode(pParse, p->pOffset, 0); sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0); sqlite3VdbeAddOp2(v, OP_MemStore, iOffset, p->pLimit==0); VdbeComment((v, "OFFSET counter")); addr1 = sqlite3VdbeAddOp2(v, OP_IfMemPos, iOffset, 0); sqlite3VdbeAddOp2(v, OP_Pop, 1, 0); sqlite3VdbeAddOp2(v, OP_Integer, 0, 0); sqlite3VdbeJumpHere(v, addr1); |
︙ | ︙ | |||
2974 2975 2976 2977 2978 2979 2980 | pAggInfo->directMode = 1; for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){ int nArg; int addrNext = 0; ExprList *pList = pF->pExpr->pList; if( pList ){ nArg = pList->nExpr; | | | 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 | pAggInfo->directMode = 1; for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){ int nArg; int addrNext = 0; ExprList *pList = pF->pExpr->pList; if( pList ){ nArg = pList->nExpr; sqlite3ExprCodeExprList(pParse, pList, 0); }else{ nArg = 0; } if( pF->iDistinct>=0 ){ addrNext = sqlite3VdbeMakeLabel(v); assert( nArg==1 ); codeDistinct_OLD(v, pF->iDistinct, addrNext, 1); |
︙ | ︙ | |||
3003 3004 3005 3006 3007 3008 3009 | sqlite3VdbeAddOp4(v, OP_AggStep, pF->iMem, nArg, 0, (void*)pF->pFunc, P4_FUNCDEF); if( addrNext ){ sqlite3VdbeResolveLabel(v, addrNext); } } for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){ | | < | 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 | sqlite3VdbeAddOp4(v, OP_AggStep, pF->iMem, nArg, 0, (void*)pF->pFunc, P4_FUNCDEF); if( addrNext ){ sqlite3VdbeResolveLabel(v, addrNext); } } for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){ sqlite3ExprCode(pParse, pC->pExpr, pC->iMem); } pAggInfo->directMode = 0; } #ifndef SQLITE_OMIT_TRIGGER /* ** This function is used when a SELECT statement is used to create a |
︙ | ︙ | |||
3514 3515 3516 3517 3518 3519 3520 | }else{ /* Rows are coming out in undetermined order. We have to push ** each row into a sorting index, terminate the first loop, ** then loop over the sorting index in order to get the output ** in sorted order */ groupBySort = 1; | | | 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 | }else{ /* Rows are coming out in undetermined order. We have to push ** each row into a sorting index, terminate the first loop, ** then loop over the sorting index in order to get the output ** in sorted order */ groupBySort = 1; sqlite3ExprCodeExprList(pParse, pGroupBy, 0); sqlite3VdbeAddOp2(v, OP_Sequence, sAggInfo.sortingIdx, 0); j = pGroupBy->nExpr+1; for(i=0; i<sAggInfo.nColumn; i++){ struct AggInfo_col *pCol = &sAggInfo.aCol[i]; if( pCol->iSorterColumn<j ) continue; sqlite3ExprCodeGetColumn(v, pCol->pTab, pCol->iColumn,pCol->iTable,0); j++; |
︙ | ︙ | |||
3542 3543 3544 3545 3546 3547 3548 | */ addrTopOfLoop = sqlite3VdbeCurrentAddr(v); for(j=0; j<pGroupBy->nExpr; j++){ if( groupBySort ){ sqlite3VdbeAddOp2(v, OP_Column, sAggInfo.sortingIdx, j); }else{ sAggInfo.directMode = 1; | | | 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 | */ addrTopOfLoop = sqlite3VdbeCurrentAddr(v); for(j=0; j<pGroupBy->nExpr; j++){ if( groupBySort ){ sqlite3VdbeAddOp2(v, OP_Column, sAggInfo.sortingIdx, j); }else{ sAggInfo.directMode = 1; sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, 0); } sqlite3VdbeAddOp2(v, OP_MemStore, iBMem+j, j<pGroupBy->nExpr-1); } for(j=pGroupBy->nExpr-1; j>=0; j--){ if( j<pGroupBy->nExpr-1 ){ sqlite3VdbeAddOp2(v, OP_MemLoad, iBMem+j, 0); } |
︙ | ︙ |
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.636 2008/01/03 23:44:53 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** The macro unlikely() is a hint that surrounds a boolean ** expression that is usually false. Macro likely() surrounds |
︙ | ︙ | |||
1734 1735 1736 1737 1738 1739 1740 | int sqlite3IsReadOnly(Parse*, Table*, int); void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); void sqlite3DeleteFrom(Parse*, SrcList*, Expr*); void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**); void sqlite3WhereEnd(WhereInfo*); void sqlite3ExprCodeGetColumn(Vdbe*, Table*, int, int, int); | | < | | 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 | int sqlite3IsReadOnly(Parse*, Table*, int); void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); void sqlite3DeleteFrom(Parse*, SrcList*, Expr*); void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**); void sqlite3WhereEnd(WhereInfo*); void sqlite3ExprCodeGetColumn(Vdbe*, Table*, int, int, int); int sqlite3ExprCode(Parse*, Expr*, int); void sqlite3ExprCodeAndCache(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*,const char*, const char*); Index *sqlite3FindIndex(sqlite3*,const char*, const char*); void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); |
︙ | ︙ |
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.155 2008/01/03 23:44:53 drh Exp $ */ #include "sqliteInt.h" #ifndef SQLITE_OMIT_VIRTUALTABLE /* Forward declaration */ static void updateVirtualTable( Parse *pParse, /* The parsing context */ |
︙ | ︙ | |||
463 464 465 466 467 468 469 | sqlite3VdbeAddOp2(v, OP_MemLoad, mem1, 0); /* 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 ){ | | | | 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 | sqlite3VdbeAddOp2(v, OP_MemLoad, mem1, 0); /* 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, 0); sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0); } /* Compute new data for this record. */ for(i=0; i<pTab->nCol; i++){ if( i==pTab->iPKey ){ sqlite3VdbeAddOp2(v, OP_Null, 0, 0); continue; } j = aXRef[i]; if( j<0 ){ sqlite3VdbeAddOp2(v, OP_Column, iCur, i); sqlite3ColumnDefault(v, pTab, i); }else{ sqlite3ExprCode(pParse, pChanges->a[j].pExpr, 0); } } /* Do constraint checks */ sqlite3GenerateConstraintChecks(pParse, pTab, iCur, aIdxUsed, chngRowid, 1, onError, addr); |
︙ | ︙ |
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.272 2008/01/03 23:44:53 drh Exp $ */ #include "sqliteInt.h" /* ** The number of bits in a Bitmask. "BMS" means "BitMask Size". */ #define BMS (sizeof(Bitmask)*8) |
︙ | ︙ | |||
1727 1728 1729 1730 1731 1732 1733 | 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 */ ){ Expr *pX = pTerm->pExpr; Vdbe *v = pParse->pVdbe; if( pX->op==TK_EQ ){ | | | 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 | 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 */ ){ Expr *pX = pTerm->pExpr; Vdbe *v = pParse->pVdbe; if( pX->op==TK_EQ ){ sqlite3ExprCode(pParse, pX->pRight, 0); }else if( pX->op==TK_ISNULL ){ sqlite3VdbeAddOp2(v, OP_Null, 0, 0); #ifndef SQLITE_OMIT_SUBQUERY }else{ int eType; int iTab; struct InLoop *pIn; |
︙ | ︙ | |||
2280 2281 2282 2283 2284 2285 2286 | pBestIdx->aConstraint; for(j=1; j<=nConstraint; j++){ int k; for(k=0; k<nConstraint; k++){ if( aUsage[k].argvIndex==j ){ int iTerm = aConstraint[k].iTermOffset; | | | 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 | pBestIdx->aConstraint; for(j=1; j<=nConstraint; j++){ int k; for(k=0; k<nConstraint; k++){ if( aUsage[k].argvIndex==j ){ int iTerm = aConstraint[k].iTermOffset; sqlite3ExprCode(pParse, wc.a[iTerm].pExpr->pRight, 0); break; } } if( k==nConstraint ) break; } iReg = ++pParse->nMem; pParse->nMem++; |
︙ | ︙ | |||
2343 2344 2345 2346 2347 2348 2349 | pEnd = pTerm; } if( pStart ){ Expr *pX; pX = pStart->pExpr; assert( pX!=0 ); assert( pStart->leftCursor==iCur ); | | | | 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 | pEnd = pTerm; } if( pStart ){ Expr *pX; pX = pStart->pExpr; assert( pX!=0 ); assert( pStart->leftCursor==iCur ); sqlite3ExprCode(pParse, pX->pRight, 0); sqlite3VdbeAddOp2(v, OP_ForceInt, pX->op==TK_LE || pX->op==TK_GT, brk); sqlite3VdbeAddOp2(v, bRev ? OP_MoveLt : OP_MoveGe, iCur, brk); VdbeComment((v, "pk")); disableTerm(pLevel, pStart); }else{ sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, brk); } if( pEnd ){ Expr *pX; pX = pEnd->pExpr; assert( pX!=0 ); assert( pEnd->leftCursor==iCur ); sqlite3ExprCode(pParse, pX->pRight, 0); pLevel->iMem = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_MemStore, pLevel->iMem, 1); if( pX->op==TK_LT || pX->op==TK_GT ){ testOp = bRev ? OP_Le : OP_Ge; }else{ testOp = bRev ? OP_Lt : OP_Gt; } |
︙ | ︙ | |||
2438 2439 2440 2441 2442 2443 2444 | if( topLimit ){ Expr *pX; int k = pIdx->aiColumn[j]; pTerm = findTerm(&wc, iCur, k, notReady, topOp, pIdx); assert( pTerm!=0 ); pX = pTerm->pExpr; assert( (pTerm->flags & TERM_CODED)==0 ); | | | 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 | if( topLimit ){ Expr *pX; int k = pIdx->aiColumn[j]; pTerm = findTerm(&wc, iCur, k, notReady, topOp, pIdx); assert( pTerm!=0 ); pX = pTerm->pExpr; assert( (pTerm->flags & TERM_CODED)==0 ); sqlite3ExprCode(pParse, pX->pRight, 0); sqlite3VdbeAddOp2(v, OP_IsNull, -(nEq*2+1), nxt); topEq = pTerm->eOperator & (WO_LE|WO_GE); disableTerm(pLevel, pTerm); testOp = OP_IdxGE; }else{ testOp = nEq>0 ? OP_IdxGE : OP_Noop; topEq = 1; |
︙ | ︙ | |||
2477 2478 2479 2480 2481 2482 2483 | if( btmLimit ){ Expr *pX; int k = pIdx->aiColumn[j]; pTerm = findTerm(&wc, iCur, k, notReady, btmOp, pIdx); assert( pTerm!=0 ); pX = pTerm->pExpr; assert( (pTerm->flags & TERM_CODED)==0 ); | | | 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 | if( btmLimit ){ Expr *pX; int k = pIdx->aiColumn[j]; pTerm = findTerm(&wc, iCur, k, notReady, btmOp, pIdx); assert( pTerm!=0 ); pX = pTerm->pExpr; assert( (pTerm->flags & TERM_CODED)==0 ); sqlite3ExprCode(pParse, pX->pRight, 0); sqlite3VdbeAddOp2(v, OP_IsNull, -(nEq+1), nxt); btmEq = pTerm->eOperator & (WO_LE|WO_GE); disableTerm(pLevel, pTerm); }else{ btmEq = 1; } if( nEq>0 || btmLimit ){ |
︙ | ︙ |