| | @@ -643,11 +643,11 @@ |
| 643 | 643 | ** |
| 644 | 644 | ** Requirements: [H10011] [H10014] |
| 645 | 645 | */ |
| 646 | 646 | #define SQLITE_VERSION "3.6.21" |
| 647 | 647 | #define SQLITE_VERSION_NUMBER 3006021 |
| 648 | | -#define SQLITE_SOURCE_ID "2009-11-23 13:17:27 39214aee6553db76309851e7aa74fcc02d4f59b7" |
| 648 | +#define SQLITE_SOURCE_ID "2009-11-25 21:05:09 5086bf8e838c824accda531afeb56a51dd40d795" |
| 649 | 649 | |
| 650 | 650 | /* |
| 651 | 651 | ** CAPI3REF: Run-Time Library Version Numbers {H10020} <S60100> |
| 652 | 652 | ** KEYWORDS: sqlite3_version |
| 653 | 653 | ** |
| | @@ -7534,10 +7534,13 @@ |
| 7534 | 7534 | SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*); |
| 7535 | 7535 | SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*); |
| 7536 | 7536 | SQLITE_PRIVATE void sqlite3VdbeProgramDelete(sqlite3 *, SubProgram *, int); |
| 7537 | 7537 | SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetValue(Vdbe*, int, u8); |
| 7538 | 7538 | SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int); |
| 7539 | +#ifndef SQLITE_OMIT_TRACE |
| 7540 | +SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); |
| 7541 | +#endif |
| 7539 | 7542 | |
| 7540 | 7543 | SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,char*,int); |
| 7541 | 7544 | SQLITE_PRIVATE void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord*); |
| 7542 | 7545 | SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); |
| 7543 | 7546 | |
| | @@ -10117,10 +10120,13 @@ |
| 10117 | 10120 | SQLITE_PRIVATE void sqlite3StatusSet(int, int); |
| 10118 | 10121 | |
| 10119 | 10122 | SQLITE_PRIVATE int sqlite3IsNaN(double); |
| 10120 | 10123 | |
| 10121 | 10124 | SQLITE_PRIVATE void sqlite3VXPrintf(StrAccum*, int, const char*, va_list); |
| 10125 | +#ifndef SQLITE_OMIT_TRACE |
| 10126 | +SQLITE_PRIVATE void sqlite3XPrintf(StrAccum*, const char*, ...); |
| 10127 | +#endif |
| 10122 | 10128 | SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...); |
| 10123 | 10129 | SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list); |
| 10124 | 10130 | SQLITE_PRIVATE char *sqlite3MAppendf(sqlite3*,char*,const char*,...); |
| 10125 | 10131 | #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) |
| 10126 | 10132 | SQLITE_PRIVATE void sqlite3DebugPrintf(const char*, ...); |
| | @@ -10144,11 +10150,10 @@ |
| 10144 | 10150 | SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*); |
| 10145 | 10151 | SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*); |
| 10146 | 10152 | SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*); |
| 10147 | 10153 | SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*); |
| 10148 | 10154 | SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*); |
| 10149 | | -SQLITE_PRIVATE void sqlite3ExprClear(sqlite3*, Expr*); |
| 10150 | 10155 | SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*); |
| 10151 | 10156 | SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); |
| 10152 | 10157 | SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int); |
| 10153 | 10158 | SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*); |
| 10154 | 10159 | SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*); |
| | @@ -16993,18 +16998,19 @@ |
| 16993 | 16998 | } |
| 16994 | 16999 | break; |
| 16995 | 17000 | case etSQLESCAPE: |
| 16996 | 17001 | case etSQLESCAPE2: |
| 16997 | 17002 | case etSQLESCAPE3: { |
| 16998 | | - int i, j, n, isnull; |
| 17003 | + int i, j, k, n, isnull; |
| 16999 | 17004 | int needQuote; |
| 17000 | 17005 | char ch; |
| 17001 | 17006 | char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote character */ |
| 17002 | 17007 | char *escarg = va_arg(ap,char*); |
| 17003 | 17008 | isnull = escarg==0; |
| 17004 | 17009 | if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)"); |
| 17005 | | - for(i=n=0; (ch=escarg[i])!=0; i++){ |
| 17010 | + k = precision; |
| 17011 | + for(i=n=0; (ch=escarg[i])!=0 && k!=0; i++, k--){ |
| 17006 | 17012 | if( ch==q ) n++; |
| 17007 | 17013 | } |
| 17008 | 17014 | needQuote = !isnull && xtype==etSQLESCAPE2; |
| 17009 | 17015 | n += i + 1 + needQuote*2; |
| 17010 | 17016 | if( n>etBUFSIZE ){ |
| | @@ -17016,19 +17022,21 @@ |
| 17016 | 17022 | }else{ |
| 17017 | 17023 | bufpt = buf; |
| 17018 | 17024 | } |
| 17019 | 17025 | j = 0; |
| 17020 | 17026 | if( needQuote ) bufpt[j++] = q; |
| 17021 | | - for(i=0; (ch=escarg[i])!=0; i++){ |
| 17022 | | - bufpt[j++] = ch; |
| 17027 | + k = i; |
| 17028 | + for(i=0; i<k; i++){ |
| 17029 | + bufpt[j++] = ch = escarg[i]; |
| 17023 | 17030 | if( ch==q ) bufpt[j++] = ch; |
| 17024 | 17031 | } |
| 17025 | 17032 | if( needQuote ) bufpt[j++] = q; |
| 17026 | 17033 | bufpt[j] = 0; |
| 17027 | 17034 | length = j; |
| 17028 | | - /* The precision is ignored on %q and %Q */ |
| 17029 | | - /* if( precision>=0 && precision<length ) length = precision; */ |
| 17035 | + /* The precision in %q and %Q means how many input characters to |
| 17036 | + ** consume, not the length of the output... |
| 17037 | + ** if( precision>=0 && precision<length ) length = precision; */ |
| 17030 | 17038 | break; |
| 17031 | 17039 | } |
| 17032 | 17040 | case etTOKEN: { |
| 17033 | 17041 | Token *pToken = va_arg(ap, Token*); |
| 17034 | 17042 | if( pToken ){ |
| | @@ -17302,10 +17310,22 @@ |
| 17302 | 17310 | sqlite3StrAccumFinish(&acc); |
| 17303 | 17311 | fprintf(stdout,"%s", zBuf); |
| 17304 | 17312 | fflush(stdout); |
| 17305 | 17313 | } |
| 17306 | 17314 | #endif |
| 17315 | + |
| 17316 | +#ifndef SQLITE_OMIT_TRACE |
| 17317 | +/* |
| 17318 | +** variable-argument wrapper around sqlite3VXPrintf(). |
| 17319 | +*/ |
| 17320 | +SQLITE_PRIVATE void sqlite3XPrintf(StrAccum *p, const char *zFormat, ...){ |
| 17321 | + va_list ap; |
| 17322 | + va_start(ap,zFormat); |
| 17323 | + sqlite3VXPrintf(p, 1, zFormat, ap); |
| 17324 | + va_end(ap); |
| 17325 | +} |
| 17326 | +#endif |
| 17307 | 17327 | |
| 17308 | 17328 | /************** End of printf.c **********************************************/ |
| 17309 | 17329 | /************** Begin file random.c ******************************************/ |
| 17310 | 17330 | /* |
| 17311 | 17331 | ** 2001 September 15 |
| | @@ -35101,11 +35121,11 @@ |
| 35101 | 35121 | rc = sqlite3PagerPagecount(pPager, &nMax); |
| 35102 | 35122 | if( rc!=SQLITE_OK ){ |
| 35103 | 35123 | goto pager_acquire_err; |
| 35104 | 35124 | } |
| 35105 | 35125 | |
| 35106 | | - if( nMax<(int)pgno || MEMDB || noContent ){ |
| 35126 | + if( MEMDB || nMax<(int)pgno || noContent ){ |
| 35107 | 35127 | if( pgno>pPager->mxPgno ){ |
| 35108 | 35128 | rc = SQLITE_FULL; |
| 35109 | 35129 | goto pager_acquire_err; |
| 35110 | 35130 | } |
| 35111 | 35131 | if( noContent ){ |
| | @@ -39075,11 +39095,13 @@ |
| 39075 | 39095 | assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno ); |
| 39076 | 39096 | assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); |
| 39077 | 39097 | assert( sqlite3PagerGetData(pPage->pDbPage) == data ); |
| 39078 | 39098 | assert( sqlite3PagerIswriteable(pPage->pDbPage) ); |
| 39079 | 39099 | assert( sqlite3_mutex_held(pBt->mutex) ); |
| 39080 | | - /*memset(&data[hdr], 0, pBt->usableSize - hdr);*/ |
| 39100 | +#ifdef SQLITE_SECURE_DELETE |
| 39101 | + memset(&data[hdr], 0, pBt->usableSize - hdr); |
| 39102 | +#endif |
| 39081 | 39103 | data[hdr] = (char)flags; |
| 39082 | 39104 | first = hdr + 8 + 4*((flags&PTF_LEAF)==0 ?1:0); |
| 39083 | 39105 | memset(&data[hdr+1], 0, 4); |
| 39084 | 39106 | data[hdr+7] = 0; |
| 39085 | 39107 | put2byte(&data[hdr+5], pBt->usableSize); |
| | @@ -44455,13 +44477,13 @@ |
| 44455 | 44477 | ** Erase the given database page and all its children. Return |
| 44456 | 44478 | ** the page to the freelist. |
| 44457 | 44479 | */ |
| 44458 | 44480 | static int clearDatabasePage( |
| 44459 | 44481 | BtShared *pBt, /* The BTree that contains the table */ |
| 44460 | | - Pgno pgno, /* Page number to clear */ |
| 44461 | | - int freePageFlag, /* Deallocate page if true */ |
| 44462 | | - int *pnChange |
| 44482 | + Pgno pgno, /* Page number to clear */ |
| 44483 | + int freePageFlag, /* Deallocate page if true */ |
| 44484 | + int *pnChange /* Add number of Cells freed to this counter */ |
| 44463 | 44485 | ){ |
| 44464 | 44486 | MemPage *pPage; |
| 44465 | 44487 | int rc; |
| 44466 | 44488 | unsigned char *pCell; |
| 44467 | 44489 | int i; |
| | @@ -51462,10 +51484,162 @@ |
| 51462 | 51484 | if( resetFlag ) pVdbe->aCounter[op-1] = 0; |
| 51463 | 51485 | return v; |
| 51464 | 51486 | } |
| 51465 | 51487 | |
| 51466 | 51488 | /************** End of vdbeapi.c *********************************************/ |
| 51489 | +/************** Begin file vdbetrace.c ***************************************/ |
| 51490 | +/* |
| 51491 | +** 2009 November 25 |
| 51492 | +** |
| 51493 | +** The author disclaims copyright to this source code. In place of |
| 51494 | +** a legal notice, here is a blessing: |
| 51495 | +** |
| 51496 | +** May you do good and not evil. |
| 51497 | +** May you find forgiveness for yourself and forgive others. |
| 51498 | +** May you share freely, never taking more than you give. |
| 51499 | +** |
| 51500 | +************************************************************************* |
| 51501 | +** |
| 51502 | +** This file contains code used to insert the values of host parameters |
| 51503 | +** (aka "wildcards") into the SQL text output by sqlite3_trace(). |
| 51504 | +*/ |
| 51505 | + |
| 51506 | +#ifndef SQLITE_OMIT_TRACE |
| 51507 | + |
| 51508 | +/* |
| 51509 | +** zSql is a zero-terminated string of UTF-8 SQL text. Return the number of |
| 51510 | +** bytes in this text up to but excluding the first character in |
| 51511 | +** a host parameter. If the text contains no host parameters, return |
| 51512 | +** the total number of bytes in the text. |
| 51513 | +*/ |
| 51514 | +static int findNextHostParameter(const char *zSql){ |
| 51515 | + int tokenType; |
| 51516 | + int nTotal = 0; |
| 51517 | + int n; |
| 51518 | + |
| 51519 | + while( zSql[0] ){ |
| 51520 | + n = sqlite3GetToken((u8*)zSql, &tokenType); |
| 51521 | + assert( n>0 && tokenType!=TK_ILLEGAL ); |
| 51522 | + if( tokenType==TK_VARIABLE ) break; |
| 51523 | + nTotal += n; |
| 51524 | + zSql += n; |
| 51525 | + } |
| 51526 | + return nTotal; |
| 51527 | +} |
| 51528 | + |
| 51529 | +/* |
| 51530 | +** Return a pointer to a string in memory obtained form sqlite3Malloc() which |
| 51531 | +** holds a copy of zRawSql but with host parameters expanded to their |
| 51532 | +** current values. |
| 51533 | +** |
| 51534 | +** The calling function is responsible for making sure the memory returned |
| 51535 | +** is eventually freed. |
| 51536 | +** |
| 51537 | +** ALGORITHM: Scan the input string looking for host parameters in any of |
| 51538 | +** these forms: ?, ?N, $A, @A, :A. Take care to avoid text within |
| 51539 | +** string literals, quoted identifier names, and comments. For text forms, |
| 51540 | +** the host parameter index is found by scanning the perpared |
| 51541 | +** statement for the corresponding OP_Variable opcode. Once the host |
| 51542 | +** parameter index is known, locate the value in p->aVar[]. Then render |
| 51543 | +** the value as a literal in place of the host parameter name. |
| 51544 | +*/ |
| 51545 | +SQLITE_PRIVATE char *sqlite3VdbeExpandSql( |
| 51546 | + Vdbe *p, /* The prepared statement being evaluated */ |
| 51547 | + const char *zRawSql /* Raw text of the SQL statement */ |
| 51548 | +){ |
| 51549 | + sqlite3 *db; /* The database connection */ |
| 51550 | + int idx; /* Index of a host parameter */ |
| 51551 | + int nextIndex = 1; /* Index of next ? host parameter */ |
| 51552 | + int n; /* Length of a token prefix */ |
| 51553 | + int i; /* Loop counter */ |
| 51554 | + int dummy; /* For holding a unused return value */ |
| 51555 | + Mem *pVar; /* Value of a host parameter */ |
| 51556 | + VdbeOp *pOp; /* For looping over opcodes */ |
| 51557 | + StrAccum out; /* Accumulate the output here */ |
| 51558 | + char zBase[100]; /* Initial working space */ |
| 51559 | + |
| 51560 | + db = p->db; |
| 51561 | + sqlite3StrAccumInit(&out, zBase, sizeof(zBase), |
| 51562 | + db->aLimit[SQLITE_LIMIT_LENGTH]); |
| 51563 | + out.db = db; |
| 51564 | + while( zRawSql[0] ){ |
| 51565 | + n = findNextHostParameter(zRawSql); |
| 51566 | + assert( n>0 ); |
| 51567 | + sqlite3StrAccumAppend(&out, zRawSql, n); |
| 51568 | + zRawSql += n; |
| 51569 | + if( zRawSql[0]==0 ) break; |
| 51570 | + if( zRawSql[0]=='?' ){ |
| 51571 | + zRawSql++; |
| 51572 | + if( sqlite3Isdigit(zRawSql[0]) ){ |
| 51573 | + idx = 0; |
| 51574 | + while( sqlite3Isdigit(zRawSql[0]) ){ |
| 51575 | + idx = idx*10 + zRawSql[0] - '0'; |
| 51576 | + zRawSql++; |
| 51577 | + } |
| 51578 | + }else{ |
| 51579 | + idx = nextIndex; |
| 51580 | + } |
| 51581 | + }else{ |
| 51582 | + assert( zRawSql[0]==':' || zRawSql[0]=='$' || zRawSql[0]=='@' ); |
| 51583 | + testcase( zRawSql[0]==':' ); |
| 51584 | + testcase( zRawSql[0]=='$' ); |
| 51585 | + testcase( zRawSql[0]=='@' ); |
| 51586 | + n = sqlite3GetToken((u8*)zRawSql, &dummy); |
| 51587 | + idx = 0; |
| 51588 | + for(i=0, pOp=p->aOp; ALWAYS(i<p->nOp); i++, pOp++){ |
| 51589 | + if( pOp->opcode!=OP_Variable ) continue; |
| 51590 | + if( pOp->p3>1 ) continue; |
| 51591 | + if( pOp->p4.z==0 ) continue; |
| 51592 | + if( memcmp(pOp->p4.z, zRawSql, n)==0 && pOp->p4.z[n]==0 ){ |
| 51593 | + idx = pOp->p1; |
| 51594 | + break; |
| 51595 | + } |
| 51596 | + } |
| 51597 | + assert( idx>0 ); |
| 51598 | + zRawSql += n; |
| 51599 | + } |
| 51600 | + nextIndex = idx + 1; |
| 51601 | + assert( idx>0 && idx<=p->nVar ); |
| 51602 | + pVar = &p->aVar[idx-1]; |
| 51603 | + if( pVar->flags & MEM_Null ){ |
| 51604 | + sqlite3StrAccumAppend(&out, "NULL", 4); |
| 51605 | + }else if( pVar->flags & MEM_Int ){ |
| 51606 | + sqlite3XPrintf(&out, "%lld", pVar->u.i); |
| 51607 | + }else if( pVar->flags & MEM_Real ){ |
| 51608 | + sqlite3XPrintf(&out, "%!.15g", pVar->r); |
| 51609 | + }else if( pVar->flags & MEM_Str ){ |
| 51610 | +#ifndef SQLITE_OMIT_UTF16 |
| 51611 | + if( ENC(db)!=SQLITE_UTF8 ){ |
| 51612 | + Mem utf8; |
| 51613 | + memset(&utf8, 0, sizeof(utf8)); |
| 51614 | + utf8.db = db; |
| 51615 | + sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, ENC(db), SQLITE_STATIC); |
| 51616 | + sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8); |
| 51617 | + sqlite3XPrintf(&out, "'%.*q'", utf8.n, utf8.z); |
| 51618 | + sqlite3VdbeMemRelease(&utf8); |
| 51619 | + }else |
| 51620 | +#endif |
| 51621 | + { |
| 51622 | + sqlite3XPrintf(&out, "'%.*q'", pVar->n, pVar->z); |
| 51623 | + } |
| 51624 | + }else if( pVar->flags & MEM_Zero ){ |
| 51625 | + sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero); |
| 51626 | + }else{ |
| 51627 | + assert( pVar->flags & MEM_Blob ); |
| 51628 | + sqlite3StrAccumAppend(&out, "x'", 2); |
| 51629 | + for(i=0; i<pVar->n; i++){ |
| 51630 | + sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff); |
| 51631 | + } |
| 51632 | + sqlite3StrAccumAppend(&out, "'", 1); |
| 51633 | + } |
| 51634 | + } |
| 51635 | + return sqlite3StrAccumFinish(&out); |
| 51636 | +} |
| 51637 | + |
| 51638 | +#endif /* #ifndef SQLITE_OMIT_TRACE */ |
| 51639 | + |
| 51640 | +/************** End of vdbetrace.c *******************************************/ |
| 51467 | 51641 | /************** Begin file vdbe.c ********************************************/ |
| 51468 | 51642 | /* |
| 51469 | 51643 | ** 2001 September 15 |
| 51470 | 51644 | ** |
| 51471 | 51645 | ** The author disclaims copyright to this source code. In place of |
| | @@ -57516,12 +57690,12 @@ |
| 57516 | 57690 | /* Copy the result of the function to the P3 register. We |
| 57517 | 57691 | ** do this regardless of whether or not an error occurred to ensure any |
| 57518 | 57692 | ** dynamic allocation in u.ch.sContext.s (a Mem struct) is released. |
| 57519 | 57693 | */ |
| 57520 | 57694 | sqlite3VdbeChangeEncoding(&u.ch.sContext.s, encoding); |
| 57521 | | - REGISTER_TRACE(pOp->p3, u.ch.pDest); |
| 57522 | 57695 | sqlite3VdbeMemMove(u.ch.pDest, &u.ch.sContext.s); |
| 57696 | + REGISTER_TRACE(pOp->p3, u.ch.pDest); |
| 57523 | 57697 | UPDATE_MAX_BLOBSIZE(u.ch.pDest); |
| 57524 | 57698 | |
| 57525 | 57699 | if( sqlite3SafetyOn(db) ){ |
| 57526 | 57700 | goto abort_due_to_misuse; |
| 57527 | 57701 | } |
| | @@ -57712,11 +57886,13 @@ |
| 57712 | 57886 | #endif /* local variables moved into u.cm */ |
| 57713 | 57887 | |
| 57714 | 57888 | u.cm.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); |
| 57715 | 57889 | if( u.cm.zTrace ){ |
| 57716 | 57890 | if( db->xTrace ){ |
| 57717 | | - db->xTrace(db->pTraceArg, u.cm.zTrace); |
| 57891 | + char *z = sqlite3VdbeExpandSql(p, u.cm.zTrace); |
| 57892 | + db->xTrace(db->pTraceArg, z); |
| 57893 | + sqlite3DbFree(db, z); |
| 57718 | 57894 | } |
| 57719 | 57895 | #ifdef SQLITE_DEBUG |
| 57720 | 57896 | if( (db->flags & SQLITE_SqlTrace)!=0 ){ |
| 57721 | 57897 | sqlite3DebugPrintf("SQL-trace: %s\n", u.cm.zTrace); |
| 57722 | 57898 | } |
| | @@ -58956,11 +59132,17 @@ |
| 58956 | 59132 | } |
| 58957 | 59133 | if( pExpr->flags & EP_ExpCollate ){ |
| 58958 | 59134 | pDup->pColl = pExpr->pColl; |
| 58959 | 59135 | pDup->flags |= EP_ExpCollate; |
| 58960 | 59136 | } |
| 58961 | | - sqlite3ExprClear(db, pExpr); |
| 59137 | + |
| 59138 | + /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This |
| 59139 | + ** prevents ExprDelete() from deleting the Expr structure itself, |
| 59140 | + ** allowing it to be repopulated by the memcpy() on the following line. |
| 59141 | + */ |
| 59142 | + ExprSetProperty(pExpr, EP_Static); |
| 59143 | + sqlite3ExprDelete(db, pExpr); |
| 58962 | 59144 | memcpy(pExpr, pDup, sizeof(*pExpr)); |
| 58963 | 59145 | sqlite3DbFree(db, pDup); |
| 58964 | 59146 | } |
| 58965 | 59147 | |
| 58966 | 59148 | /* |
| | @@ -60685,15 +60867,14 @@ |
| 60685 | 60867 | sqlite3ErrorMsg(pParse, "too many SQL variables"); |
| 60686 | 60868 | } |
| 60687 | 60869 | } |
| 60688 | 60870 | |
| 60689 | 60871 | /* |
| 60690 | | -** Clear an expression structure without deleting the structure itself. |
| 60691 | | -** Substructure is deleted. |
| 60872 | +** Recursively delete an expression tree. |
| 60692 | 60873 | */ |
| 60693 | | -SQLITE_PRIVATE void sqlite3ExprClear(sqlite3 *db, Expr *p){ |
| 60694 | | - assert( p!=0 ); |
| 60874 | +SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){ |
| 60875 | + if( p==0 ) return; |
| 60695 | 60876 | if( !ExprHasAnyProperty(p, EP_TokenOnly) ){ |
| 60696 | 60877 | sqlite3ExprDelete(db, p->pLeft); |
| 60697 | 60878 | sqlite3ExprDelete(db, p->pRight); |
| 60698 | 60879 | if( !ExprHasProperty(p, EP_Reduced) && (p->flags2 & EP2_MallocedToken)!=0 ){ |
| 60699 | 60880 | sqlite3DbFree(db, p->u.zToken); |
| | @@ -60702,18 +60883,10 @@ |
| 60702 | 60883 | sqlite3SelectDelete(db, p->x.pSelect); |
| 60703 | 60884 | }else{ |
| 60704 | 60885 | sqlite3ExprListDelete(db, p->x.pList); |
| 60705 | 60886 | } |
| 60706 | 60887 | } |
| 60707 | | -} |
| 60708 | | - |
| 60709 | | -/* |
| 60710 | | -** Recursively delete an expression tree. |
| 60711 | | -*/ |
| 60712 | | -SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){ |
| 60713 | | - if( p==0 ) return; |
| 60714 | | - sqlite3ExprClear(db, p); |
| 60715 | 60888 | if( !ExprHasProperty(p, EP_Static) ){ |
| 60716 | 60889 | sqlite3DbFree(db, p); |
| 60717 | 60890 | } |
| 60718 | 60891 | } |
| 60719 | 60892 | |
| | @@ -89109,10 +89282,11 @@ |
| 89109 | 89282 | struct sqlite3_index_constraint_usage *aUsage = |
| 89110 | 89283 | pVtabIdx->aConstraintUsage; |
| 89111 | 89284 | const struct sqlite3_index_constraint *aConstraint = |
| 89112 | 89285 | pVtabIdx->aConstraint; |
| 89113 | 89286 | |
| 89287 | + sqlite3ExprCachePush(pParse); |
| 89114 | 89288 | iReg = sqlite3GetTempRange(pParse, nConstraint+2); |
| 89115 | 89289 | for(j=1; j<=nConstraint; j++){ |
| 89116 | 89290 | for(k=0; k<nConstraint; k++){ |
| 89117 | 89291 | if( aUsage[k].argvIndex==j ){ |
| 89118 | 89292 | int iTerm = aConstraint[k].iTermOffset; |
| | @@ -89135,10 +89309,11 @@ |
| 89135 | 89309 | } |
| 89136 | 89310 | pLevel->op = OP_VNext; |
| 89137 | 89311 | pLevel->p1 = iCur; |
| 89138 | 89312 | pLevel->p2 = sqlite3VdbeCurrentAddr(v); |
| 89139 | 89313 | sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2); |
| 89314 | + sqlite3ExprCachePop(pParse, 1); |
| 89140 | 89315 | }else |
| 89141 | 89316 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 89142 | 89317 | |
| 89143 | 89318 | if( pLevel->plan.wsFlags & WHERE_ROWID_EQ ){ |
| 89144 | 89319 | /* Case 1: We can directly reference a single row using an |
| 89145 | 89320 | |