| | @@ -1,8 +1,8 @@ |
| 1 | 1 | /****************************************************************************** |
| 2 | 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | | -** version 3.39.0. By combining all the individual C code files into this |
| 3 | +** version 3.40.0. By combining all the individual C code files into this |
| 4 | 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | 6 | ** possible if the files were compiled separately. Performance improvements |
| 7 | 7 | ** of 5% or more are commonly seen when SQLite is compiled as a single |
| 8 | 8 | ** translation unit. |
| | @@ -450,13 +450,13 @@ |
| 450 | 450 | ** |
| 451 | 451 | ** See also: [sqlite3_libversion()], |
| 452 | 452 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 453 | 453 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 454 | 454 | */ |
| 455 | | -#define SQLITE_VERSION "3.39.0" |
| 456 | | -#define SQLITE_VERSION_NUMBER 3039000 |
| 457 | | -#define SQLITE_SOURCE_ID "2022-06-25 14:57:57 14e166f40dbfa6e055543f8301525f2ca2e96a02a57269818b9e69e162e98918" |
| 455 | +#define SQLITE_VERSION "3.40.0" |
| 456 | +#define SQLITE_VERSION_NUMBER 3040000 |
| 457 | +#define SQLITE_SOURCE_ID "2022-07-18 19:32:30 22d280a5cd395abbedcfffbac3d3b3a614c327be25763ca380c1338a2a7bd33a" |
| 458 | 458 | |
| 459 | 459 | /* |
| 460 | 460 | ** CAPI3REF: Run-Time Library Version Numbers |
| 461 | 461 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 462 | 462 | ** |
| | @@ -6586,11 +6586,11 @@ |
| 6586 | 6586 | ** CAPI3REF: Return The Schema Name For A Database Connection |
| 6587 | 6587 | ** METHOD: sqlite3 |
| 6588 | 6588 | ** |
| 6589 | 6589 | ** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name |
| 6590 | 6590 | ** for the N-th database on database connection D, or a NULL pointer of N is |
| 6591 | | -** out of range. An N alue of 0 means the main database file. An N of 1 is |
| 6591 | +** out of range. An N value of 0 means the main database file. An N of 1 is |
| 6592 | 6592 | ** the "temp" schema. Larger values of N correspond to various ATTACH-ed |
| 6593 | 6593 | ** databases. |
| 6594 | 6594 | ** |
| 6595 | 6595 | ** Space to hold the string that is returned by sqlite3_db_name() is managed |
| 6596 | 6596 | ** by SQLite itself. The string might be deallocated by any operation that |
| | @@ -15553,67 +15553,67 @@ |
| 15553 | 15553 | #define OP_Checkpoint 3 |
| 15554 | 15554 | #define OP_JournalMode 4 |
| 15555 | 15555 | #define OP_Vacuum 5 |
| 15556 | 15556 | #define OP_VFilter 6 /* jump, synopsis: iplan=r[P3] zplan='P4' */ |
| 15557 | 15557 | #define OP_VUpdate 7 /* synopsis: data=r[P3@P2] */ |
| 15558 | | -#define OP_Goto 8 /* jump */ |
| 15559 | | -#define OP_Gosub 9 /* jump */ |
| 15560 | | -#define OP_InitCoroutine 10 /* jump */ |
| 15561 | | -#define OP_Yield 11 /* jump */ |
| 15562 | | -#define OP_MustBeInt 12 /* jump */ |
| 15563 | | -#define OP_Jump 13 /* jump */ |
| 15564 | | -#define OP_Once 14 /* jump */ |
| 15565 | | -#define OP_If 15 /* jump */ |
| 15566 | | -#define OP_IfNot 16 /* jump */ |
| 15567 | | -#define OP_IsNullOrType 17 /* jump, synopsis: if typeof(r[P1]) IN (P3,5) goto P2 */ |
| 15568 | | -#define OP_IfNullRow 18 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */ |
| 15558 | +#define OP_Init 8 /* jump, synopsis: Start at P2 */ |
| 15559 | +#define OP_Goto 9 /* jump */ |
| 15560 | +#define OP_Gosub 10 /* jump */ |
| 15561 | +#define OP_InitCoroutine 11 /* jump */ |
| 15562 | +#define OP_Yield 12 /* jump */ |
| 15563 | +#define OP_MustBeInt 13 /* jump */ |
| 15564 | +#define OP_Jump 14 /* jump */ |
| 15565 | +#define OP_Once 15 /* jump */ |
| 15566 | +#define OP_If 16 /* jump */ |
| 15567 | +#define OP_IfNot 17 /* jump */ |
| 15568 | +#define OP_IsNullOrType 18 /* jump, synopsis: if typeof(r[P1]) IN (P3,5) goto P2 */ |
| 15569 | 15569 | #define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */ |
| 15570 | | -#define OP_SeekLT 20 /* jump, synopsis: key=r[P3@P4] */ |
| 15571 | | -#define OP_SeekLE 21 /* jump, synopsis: key=r[P3@P4] */ |
| 15572 | | -#define OP_SeekGE 22 /* jump, synopsis: key=r[P3@P4] */ |
| 15573 | | -#define OP_SeekGT 23 /* jump, synopsis: key=r[P3@P4] */ |
| 15574 | | -#define OP_IfNotOpen 24 /* jump, synopsis: if( !csr[P1] ) goto P2 */ |
| 15575 | | -#define OP_IfNoHope 25 /* jump, synopsis: key=r[P3@P4] */ |
| 15576 | | -#define OP_NoConflict 26 /* jump, synopsis: key=r[P3@P4] */ |
| 15577 | | -#define OP_NotFound 27 /* jump, synopsis: key=r[P3@P4] */ |
| 15578 | | -#define OP_Found 28 /* jump, synopsis: key=r[P3@P4] */ |
| 15579 | | -#define OP_SeekRowid 29 /* jump, synopsis: intkey=r[P3] */ |
| 15580 | | -#define OP_NotExists 30 /* jump, synopsis: intkey=r[P3] */ |
| 15581 | | -#define OP_Last 31 /* jump */ |
| 15582 | | -#define OP_IfSmaller 32 /* jump */ |
| 15583 | | -#define OP_SorterSort 33 /* jump */ |
| 15584 | | -#define OP_Sort 34 /* jump */ |
| 15585 | | -#define OP_Rewind 35 /* jump */ |
| 15586 | | -#define OP_SorterNext 36 /* jump */ |
| 15587 | | -#define OP_Prev 37 /* jump */ |
| 15588 | | -#define OP_Next 38 /* jump */ |
| 15589 | | -#define OP_IdxLE 39 /* jump, synopsis: key=r[P3@P4] */ |
| 15590 | | -#define OP_IdxGT 40 /* jump, synopsis: key=r[P3@P4] */ |
| 15591 | | -#define OP_IdxLT 41 /* jump, synopsis: key=r[P3@P4] */ |
| 15592 | | -#define OP_IdxGE 42 /* jump, synopsis: key=r[P3@P4] */ |
| 15570 | +#define OP_IfNullRow 20 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */ |
| 15571 | +#define OP_SeekLT 21 /* jump, synopsis: key=r[P3@P4] */ |
| 15572 | +#define OP_SeekLE 22 /* jump, synopsis: key=r[P3@P4] */ |
| 15573 | +#define OP_SeekGE 23 /* jump, synopsis: key=r[P3@P4] */ |
| 15574 | +#define OP_SeekGT 24 /* jump, synopsis: key=r[P3@P4] */ |
| 15575 | +#define OP_IfNotOpen 25 /* jump, synopsis: if( !csr[P1] ) goto P2 */ |
| 15576 | +#define OP_IfNoHope 26 /* jump, synopsis: key=r[P3@P4] */ |
| 15577 | +#define OP_NoConflict 27 /* jump, synopsis: key=r[P3@P4] */ |
| 15578 | +#define OP_NotFound 28 /* jump, synopsis: key=r[P3@P4] */ |
| 15579 | +#define OP_Found 29 /* jump, synopsis: key=r[P3@P4] */ |
| 15580 | +#define OP_SeekRowid 30 /* jump, synopsis: intkey=r[P3] */ |
| 15581 | +#define OP_NotExists 31 /* jump, synopsis: intkey=r[P3] */ |
| 15582 | +#define OP_Last 32 /* jump */ |
| 15583 | +#define OP_IfSmaller 33 /* jump */ |
| 15584 | +#define OP_SorterSort 34 /* jump */ |
| 15585 | +#define OP_Sort 35 /* jump */ |
| 15586 | +#define OP_Rewind 36 /* jump */ |
| 15587 | +#define OP_SorterNext 37 /* jump */ |
| 15588 | +#define OP_Prev 38 /* jump */ |
| 15589 | +#define OP_Next 39 /* jump */ |
| 15590 | +#define OP_IdxLE 40 /* jump, synopsis: key=r[P3@P4] */ |
| 15591 | +#define OP_IdxGT 41 /* jump, synopsis: key=r[P3@P4] */ |
| 15592 | +#define OP_IdxLT 42 /* jump, synopsis: key=r[P3@P4] */ |
| 15593 | 15593 | #define OP_Or 43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ |
| 15594 | 15594 | #define OP_And 44 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ |
| 15595 | | -#define OP_RowSetRead 45 /* jump, synopsis: r[P3]=rowset(P1) */ |
| 15596 | | -#define OP_RowSetTest 46 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ |
| 15597 | | -#define OP_Program 47 /* jump */ |
| 15598 | | -#define OP_FkIfZero 48 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ |
| 15599 | | -#define OP_IfPos 49 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ |
| 15595 | +#define OP_IdxGE 45 /* jump, synopsis: key=r[P3@P4] */ |
| 15596 | +#define OP_RowSetRead 46 /* jump, synopsis: r[P3]=rowset(P1) */ |
| 15597 | +#define OP_RowSetTest 47 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ |
| 15598 | +#define OP_Program 48 /* jump */ |
| 15599 | +#define OP_FkIfZero 49 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ |
| 15600 | 15600 | #define OP_IsNull 50 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ |
| 15601 | 15601 | #define OP_NotNull 51 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ |
| 15602 | 15602 | #define OP_Ne 52 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */ |
| 15603 | 15603 | #define OP_Eq 53 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */ |
| 15604 | 15604 | #define OP_Gt 54 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */ |
| 15605 | 15605 | #define OP_Le 55 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */ |
| 15606 | 15606 | #define OP_Lt 56 /* jump, same as TK_LT, synopsis: IF r[P3]<r[P1] */ |
| 15607 | 15607 | #define OP_Ge 57 /* jump, same as TK_GE, synopsis: IF r[P3]>=r[P1] */ |
| 15608 | 15608 | #define OP_ElseEq 58 /* jump, same as TK_ESCAPE */ |
| 15609 | | -#define OP_IfNotZero 59 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ |
| 15610 | | -#define OP_DecrJumpZero 60 /* jump, synopsis: if (--r[P1])==0 goto P2 */ |
| 15611 | | -#define OP_IncrVacuum 61 /* jump */ |
| 15612 | | -#define OP_VNext 62 /* jump */ |
| 15613 | | -#define OP_Filter 63 /* jump, synopsis: if key(P3@P4) not in filter(P1) goto P2 */ |
| 15614 | | -#define OP_Init 64 /* jump, synopsis: Start at P2 */ |
| 15609 | +#define OP_IfPos 59 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ |
| 15610 | +#define OP_IfNotZero 60 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ |
| 15611 | +#define OP_DecrJumpZero 61 /* jump, synopsis: if (--r[P1])==0 goto P2 */ |
| 15612 | +#define OP_IncrVacuum 62 /* jump */ |
| 15613 | +#define OP_VNext 63 /* jump */ |
| 15614 | +#define OP_Filter 64 /* jump, synopsis: if key(P3@P4) not in filter(P1) goto P2 */ |
| 15615 | 15615 | #define OP_PureFunc 65 /* synopsis: r[P3]=func(r[P2@NP]) */ |
| 15616 | 15616 | #define OP_Function 66 /* synopsis: r[P3]=func(r[P2@NP]) */ |
| 15617 | 15617 | #define OP_Return 67 |
| 15618 | 15618 | #define OP_EndCoroutine 68 |
| 15619 | 15619 | #define OP_HaltIfNull 69 /* synopsis: if r[P3]=null halt */ |
| | @@ -15745,17 +15745,17 @@ |
| 15745 | 15745 | #define OPFLG_IN3 0x08 /* in3: P3 is an input */ |
| 15746 | 15746 | #define OPFLG_OUT2 0x10 /* out2: P2 is an output */ |
| 15747 | 15747 | #define OPFLG_OUT3 0x20 /* out3: P3 is an output */ |
| 15748 | 15748 | #define OPFLG_INITIALIZER {\ |
| 15749 | 15749 | /* 0 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\ |
| 15750 | | -/* 8 */ 0x01, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01, 0x03,\ |
| 15751 | | -/* 16 */ 0x03, 0x03, 0x01, 0x12, 0x09, 0x09, 0x09, 0x09,\ |
| 15752 | | -/* 24 */ 0x01, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x01,\ |
| 15750 | +/* 8 */ 0x01, 0x01, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01,\ |
| 15751 | +/* 16 */ 0x03, 0x03, 0x03, 0x12, 0x01, 0x09, 0x09, 0x09,\ |
| 15752 | +/* 24 */ 0x09, 0x01, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,\ |
| 15753 | 15753 | /* 32 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\ |
| 15754 | | -/* 40 */ 0x01, 0x01, 0x01, 0x26, 0x26, 0x23, 0x0b, 0x01,\ |
| 15755 | | -/* 48 */ 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\ |
| 15756 | | -/* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x01, 0x01,\ |
| 15754 | +/* 40 */ 0x01, 0x01, 0x01, 0x26, 0x26, 0x01, 0x23, 0x0b,\ |
| 15755 | +/* 48 */ 0x01, 0x01, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\ |
| 15756 | +/* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x03, 0x01, 0x01,\ |
| 15757 | 15757 | /* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\ |
| 15758 | 15758 | /* 72 */ 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10, 0x00,\ |
| 15759 | 15759 | /* 80 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02,\ |
| 15760 | 15760 | /* 88 */ 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x00, 0x00,\ |
| 15761 | 15761 | /* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x26, 0x26,\ |
| | @@ -19777,18 +19777,20 @@ |
| 19777 | 19777 | SQLITE_PRIVATE void sqlite3TreeViewColumnList(TreeView*, const Column*, int, u8); |
| 19778 | 19778 | SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView*, const SrcList*); |
| 19779 | 19779 | SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8); |
| 19780 | 19780 | SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8); |
| 19781 | 19781 | SQLITE_PRIVATE void sqlite3TreeViewUpsert(TreeView*, const Upsert*, u8); |
| 19782 | +#if TREETRACE_ENABLED |
| 19782 | 19783 | SQLITE_PRIVATE void sqlite3TreeViewDelete(const With*, const SrcList*, const Expr*, |
| 19783 | 19784 | const ExprList*,const Expr*, const Trigger*); |
| 19784 | 19785 | SQLITE_PRIVATE void sqlite3TreeViewInsert(const With*, const SrcList*, |
| 19785 | 19786 | const IdList*, const Select*, const ExprList*, |
| 19786 | 19787 | int, const Upsert*, const Trigger*); |
| 19787 | 19788 | SQLITE_PRIVATE void sqlite3TreeViewUpdate(const With*, const SrcList*, const ExprList*, |
| 19788 | 19789 | const Expr*, int, const ExprList*, const Expr*, |
| 19789 | 19790 | const Upsert*, const Trigger*); |
| 19791 | +#endif |
| 19790 | 19792 | #ifndef SQLITE_OMIT_TRIGGER |
| 19791 | 19793 | SQLITE_PRIVATE void sqlite3TreeViewTriggerStep(TreeView*, const TriggerStep*, u8, u8); |
| 19792 | 19794 | SQLITE_PRIVATE void sqlite3TreeViewTrigger(TreeView*, const Trigger*, u8, u8); |
| 19793 | 19795 | #endif |
| 19794 | 19796 | #ifndef SQLITE_OMIT_WINDOWFUNC |
| | @@ -29559,12 +29561,17 @@ |
| 29559 | 29561 | if( db->nVdbeExec>0 ){ |
| 29560 | 29562 | AtomicStore(&db->u1.isInterrupted, 1); |
| 29561 | 29563 | } |
| 29562 | 29564 | DisableLookaside; |
| 29563 | 29565 | if( db->pParse ){ |
| 29566 | + Parse *pParse; |
| 29564 | 29567 | sqlite3ErrorMsg(db->pParse, "out of memory"); |
| 29565 | 29568 | db->pParse->rc = SQLITE_NOMEM_BKPT; |
| 29569 | + for(pParse=db->pParse->pOuterParse; pParse; pParse = pParse->pOuterParse){ |
| 29570 | + pParse->nErr++; |
| 29571 | + pParse->rc = SQLITE_NOMEM; |
| 29572 | + } |
| 29566 | 29573 | } |
| 29567 | 29574 | } |
| 29568 | 29575 | return 0; |
| 29569 | 29576 | } |
| 29570 | 29577 | |
| | @@ -30426,12 +30433,12 @@ |
| 30426 | 30433 | } |
| 30427 | 30434 | break; |
| 30428 | 30435 | case etSQLESCAPE: /* %q: Escape ' characters */ |
| 30429 | 30436 | case etSQLESCAPE2: /* %Q: Escape ' and enclose in '...' */ |
| 30430 | 30437 | case etSQLESCAPE3: { /* %w: Escape " characters */ |
| 30431 | | - int i, j, k, n, isnull; |
| 30432 | | - int needQuote; |
| 30438 | + i64 i, j, k, n; |
| 30439 | + int needQuote, isnull; |
| 30433 | 30440 | char ch; |
| 30434 | 30441 | char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote character */ |
| 30435 | 30442 | char *escarg; |
| 30436 | 30443 | |
| 30437 | 30444 | if( bArgList ){ |
| | @@ -31115,12 +31122,12 @@ |
| 31115 | 31122 | int i; |
| 31116 | 31123 | sqlite3TreeViewPush(&pView, moreToFollow); |
| 31117 | 31124 | sqlite3TreeViewLine(pView, "COLUMNS"); |
| 31118 | 31125 | for(i=0; i<nCol; i++){ |
| 31119 | 31126 | u16 flg = aCol[i].colFlags; |
| 31120 | | - int moreToFollow = i<(nCol - 1); |
| 31121 | | - sqlite3TreeViewPush(&pView, moreToFollow); |
| 31127 | + int colMoreToFollow = i<(nCol - 1); |
| 31128 | + sqlite3TreeViewPush(&pView, colMoreToFollow); |
| 31122 | 31129 | sqlite3TreeViewLine(pView, 0); |
| 31123 | 31130 | printf(" %s", aCol[i].zCnName); |
| 31124 | 31131 | switch( aCol[i].eCType ){ |
| 31125 | 31132 | case COLTYPE_ANY: printf(" ANY"); break; |
| 31126 | 31133 | case COLTYPE_BLOB: printf(" BLOB"); break; |
| | @@ -31247,11 +31254,11 @@ |
| 31247 | 31254 | if( pItem->pSelect ){ |
| 31248 | 31255 | if( pItem->pTab ){ |
| 31249 | 31256 | Table *pTab = pItem->pTab; |
| 31250 | 31257 | sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1); |
| 31251 | 31258 | } |
| 31252 | | - assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); |
| 31259 | + assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); |
| 31253 | 31260 | sqlite3TreeViewSelect(pView, pItem->pSelect, (--n)>0); |
| 31254 | 31261 | } |
| 31255 | 31262 | if( pItem->fg.isTabFunc ){ |
| 31256 | 31263 | sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); |
| 31257 | 31264 | } |
| | @@ -32014,10 +32021,11 @@ |
| 32014 | 32021 | pUpsert = pUpsert->pNextUpsert; |
| 32015 | 32022 | } |
| 32016 | 32023 | sqlite3TreeViewPop(&pView); |
| 32017 | 32024 | } |
| 32018 | 32025 | |
| 32026 | +#if TREETRACE_ENABLED |
| 32019 | 32027 | /* |
| 32020 | 32028 | ** Generate a human-readable diagram of the data structure that go |
| 32021 | 32029 | ** into generating an DELETE statement. |
| 32022 | 32030 | */ |
| 32023 | 32031 | SQLITE_PRIVATE void sqlite3TreeViewDelete( |
| | @@ -32067,11 +32075,13 @@ |
| 32067 | 32075 | if( pTrigger ){ |
| 32068 | 32076 | sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1); |
| 32069 | 32077 | } |
| 32070 | 32078 | sqlite3TreeViewPop(&pView); |
| 32071 | 32079 | } |
| 32080 | +#endif /* TREETRACE_ENABLED */ |
| 32072 | 32081 | |
| 32082 | +#if TREETRACE_ENABLED |
| 32073 | 32083 | /* |
| 32074 | 32084 | ** Generate a human-readable diagram of the data structure that go |
| 32075 | 32085 | ** into generating an INSERT statement. |
| 32076 | 32086 | */ |
| 32077 | 32087 | SQLITE_PRIVATE void sqlite3TreeViewInsert( |
| | @@ -32135,11 +32145,13 @@ |
| 32135 | 32145 | if( pTrigger ){ |
| 32136 | 32146 | sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1); |
| 32137 | 32147 | } |
| 32138 | 32148 | sqlite3TreeViewPop(&pView); |
| 32139 | 32149 | } |
| 32150 | +#endif /* TREETRACE_ENABLED */ |
| 32140 | 32151 | |
| 32152 | +#if TREETRACE_ENABLED |
| 32141 | 32153 | /* |
| 32142 | 32154 | ** Generate a human-readable diagram of the data structure that go |
| 32143 | 32155 | ** into generating an UPDATE statement. |
| 32144 | 32156 | */ |
| 32145 | 32157 | SQLITE_PRIVATE void sqlite3TreeViewUpdate( |
| | @@ -32211,10 +32223,11 @@ |
| 32211 | 32223 | if( pTrigger ){ |
| 32212 | 32224 | sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1); |
| 32213 | 32225 | } |
| 32214 | 32226 | sqlite3TreeViewPop(&pView); |
| 32215 | 32227 | } |
| 32228 | +#endif /* TREETRACE_ENABLED */ |
| 32216 | 32229 | |
| 32217 | 32230 | #ifndef SQLITE_OMIT_TRIGGER |
| 32218 | 32231 | /* |
| 32219 | 32232 | ** Show a human-readable graph of a TriggerStep |
| 32220 | 32233 | */ |
| | @@ -35267,67 +35280,67 @@ |
| 35267 | 35280 | /* 3 */ "Checkpoint" OpHelp(""), |
| 35268 | 35281 | /* 4 */ "JournalMode" OpHelp(""), |
| 35269 | 35282 | /* 5 */ "Vacuum" OpHelp(""), |
| 35270 | 35283 | /* 6 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"), |
| 35271 | 35284 | /* 7 */ "VUpdate" OpHelp("data=r[P3@P2]"), |
| 35272 | | - /* 8 */ "Goto" OpHelp(""), |
| 35273 | | - /* 9 */ "Gosub" OpHelp(""), |
| 35274 | | - /* 10 */ "InitCoroutine" OpHelp(""), |
| 35275 | | - /* 11 */ "Yield" OpHelp(""), |
| 35276 | | - /* 12 */ "MustBeInt" OpHelp(""), |
| 35277 | | - /* 13 */ "Jump" OpHelp(""), |
| 35278 | | - /* 14 */ "Once" OpHelp(""), |
| 35279 | | - /* 15 */ "If" OpHelp(""), |
| 35280 | | - /* 16 */ "IfNot" OpHelp(""), |
| 35281 | | - /* 17 */ "IsNullOrType" OpHelp("if typeof(r[P1]) IN (P3,5) goto P2"), |
| 35282 | | - /* 18 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"), |
| 35285 | + /* 8 */ "Init" OpHelp("Start at P2"), |
| 35286 | + /* 9 */ "Goto" OpHelp(""), |
| 35287 | + /* 10 */ "Gosub" OpHelp(""), |
| 35288 | + /* 11 */ "InitCoroutine" OpHelp(""), |
| 35289 | + /* 12 */ "Yield" OpHelp(""), |
| 35290 | + /* 13 */ "MustBeInt" OpHelp(""), |
| 35291 | + /* 14 */ "Jump" OpHelp(""), |
| 35292 | + /* 15 */ "Once" OpHelp(""), |
| 35293 | + /* 16 */ "If" OpHelp(""), |
| 35294 | + /* 17 */ "IfNot" OpHelp(""), |
| 35295 | + /* 18 */ "IsNullOrType" OpHelp("if typeof(r[P1]) IN (P3,5) goto P2"), |
| 35283 | 35296 | /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"), |
| 35284 | | - /* 20 */ "SeekLT" OpHelp("key=r[P3@P4]"), |
| 35285 | | - /* 21 */ "SeekLE" OpHelp("key=r[P3@P4]"), |
| 35286 | | - /* 22 */ "SeekGE" OpHelp("key=r[P3@P4]"), |
| 35287 | | - /* 23 */ "SeekGT" OpHelp("key=r[P3@P4]"), |
| 35288 | | - /* 24 */ "IfNotOpen" OpHelp("if( !csr[P1] ) goto P2"), |
| 35289 | | - /* 25 */ "IfNoHope" OpHelp("key=r[P3@P4]"), |
| 35290 | | - /* 26 */ "NoConflict" OpHelp("key=r[P3@P4]"), |
| 35291 | | - /* 27 */ "NotFound" OpHelp("key=r[P3@P4]"), |
| 35292 | | - /* 28 */ "Found" OpHelp("key=r[P3@P4]"), |
| 35293 | | - /* 29 */ "SeekRowid" OpHelp("intkey=r[P3]"), |
| 35294 | | - /* 30 */ "NotExists" OpHelp("intkey=r[P3]"), |
| 35295 | | - /* 31 */ "Last" OpHelp(""), |
| 35296 | | - /* 32 */ "IfSmaller" OpHelp(""), |
| 35297 | | - /* 33 */ "SorterSort" OpHelp(""), |
| 35298 | | - /* 34 */ "Sort" OpHelp(""), |
| 35299 | | - /* 35 */ "Rewind" OpHelp(""), |
| 35300 | | - /* 36 */ "SorterNext" OpHelp(""), |
| 35301 | | - /* 37 */ "Prev" OpHelp(""), |
| 35302 | | - /* 38 */ "Next" OpHelp(""), |
| 35303 | | - /* 39 */ "IdxLE" OpHelp("key=r[P3@P4]"), |
| 35304 | | - /* 40 */ "IdxGT" OpHelp("key=r[P3@P4]"), |
| 35305 | | - /* 41 */ "IdxLT" OpHelp("key=r[P3@P4]"), |
| 35306 | | - /* 42 */ "IdxGE" OpHelp("key=r[P3@P4]"), |
| 35297 | + /* 20 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"), |
| 35298 | + /* 21 */ "SeekLT" OpHelp("key=r[P3@P4]"), |
| 35299 | + /* 22 */ "SeekLE" OpHelp("key=r[P3@P4]"), |
| 35300 | + /* 23 */ "SeekGE" OpHelp("key=r[P3@P4]"), |
| 35301 | + /* 24 */ "SeekGT" OpHelp("key=r[P3@P4]"), |
| 35302 | + /* 25 */ "IfNotOpen" OpHelp("if( !csr[P1] ) goto P2"), |
| 35303 | + /* 26 */ "IfNoHope" OpHelp("key=r[P3@P4]"), |
| 35304 | + /* 27 */ "NoConflict" OpHelp("key=r[P3@P4]"), |
| 35305 | + /* 28 */ "NotFound" OpHelp("key=r[P3@P4]"), |
| 35306 | + /* 29 */ "Found" OpHelp("key=r[P3@P4]"), |
| 35307 | + /* 30 */ "SeekRowid" OpHelp("intkey=r[P3]"), |
| 35308 | + /* 31 */ "NotExists" OpHelp("intkey=r[P3]"), |
| 35309 | + /* 32 */ "Last" OpHelp(""), |
| 35310 | + /* 33 */ "IfSmaller" OpHelp(""), |
| 35311 | + /* 34 */ "SorterSort" OpHelp(""), |
| 35312 | + /* 35 */ "Sort" OpHelp(""), |
| 35313 | + /* 36 */ "Rewind" OpHelp(""), |
| 35314 | + /* 37 */ "SorterNext" OpHelp(""), |
| 35315 | + /* 38 */ "Prev" OpHelp(""), |
| 35316 | + /* 39 */ "Next" OpHelp(""), |
| 35317 | + /* 40 */ "IdxLE" OpHelp("key=r[P3@P4]"), |
| 35318 | + /* 41 */ "IdxGT" OpHelp("key=r[P3@P4]"), |
| 35319 | + /* 42 */ "IdxLT" OpHelp("key=r[P3@P4]"), |
| 35307 | 35320 | /* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), |
| 35308 | 35321 | /* 44 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), |
| 35309 | | - /* 45 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), |
| 35310 | | - /* 46 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), |
| 35311 | | - /* 47 */ "Program" OpHelp(""), |
| 35312 | | - /* 48 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), |
| 35313 | | - /* 49 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), |
| 35322 | + /* 45 */ "IdxGE" OpHelp("key=r[P3@P4]"), |
| 35323 | + /* 46 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), |
| 35324 | + /* 47 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), |
| 35325 | + /* 48 */ "Program" OpHelp(""), |
| 35326 | + /* 49 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), |
| 35314 | 35327 | /* 50 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), |
| 35315 | 35328 | /* 51 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), |
| 35316 | 35329 | /* 52 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), |
| 35317 | 35330 | /* 53 */ "Eq" OpHelp("IF r[P3]==r[P1]"), |
| 35318 | 35331 | /* 54 */ "Gt" OpHelp("IF r[P3]>r[P1]"), |
| 35319 | 35332 | /* 55 */ "Le" OpHelp("IF r[P3]<=r[P1]"), |
| 35320 | 35333 | /* 56 */ "Lt" OpHelp("IF r[P3]<r[P1]"), |
| 35321 | 35334 | /* 57 */ "Ge" OpHelp("IF r[P3]>=r[P1]"), |
| 35322 | 35335 | /* 58 */ "ElseEq" OpHelp(""), |
| 35323 | | - /* 59 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), |
| 35324 | | - /* 60 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), |
| 35325 | | - /* 61 */ "IncrVacuum" OpHelp(""), |
| 35326 | | - /* 62 */ "VNext" OpHelp(""), |
| 35327 | | - /* 63 */ "Filter" OpHelp("if key(P3@P4) not in filter(P1) goto P2"), |
| 35328 | | - /* 64 */ "Init" OpHelp("Start at P2"), |
| 35336 | + /* 59 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), |
| 35337 | + /* 60 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), |
| 35338 | + /* 61 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), |
| 35339 | + /* 62 */ "IncrVacuum" OpHelp(""), |
| 35340 | + /* 63 */ "VNext" OpHelp(""), |
| 35341 | + /* 64 */ "Filter" OpHelp("if key(P3@P4) not in filter(P1) goto P2"), |
| 35329 | 35342 | /* 65 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"), |
| 35330 | 35343 | /* 66 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"), |
| 35331 | 35344 | /* 67 */ "Return" OpHelp(""), |
| 35332 | 35345 | /* 68 */ "EndCoroutine" OpHelp(""), |
| 35333 | 35346 | /* 69 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), |
| | @@ -68301,11 +68314,10 @@ |
| 68301 | 68314 | assert( sqlite3PagerIswriteable(pPage->pDbPage) ); |
| 68302 | 68315 | assert( pPage->pBt!=0 ); |
| 68303 | 68316 | assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE ); |
| 68304 | 68317 | assert( pPage->nOverflow==0 ); |
| 68305 | 68318 | assert( sqlite3_mutex_held(pPage->pBt->mutex) ); |
| 68306 | | - temp = 0; |
| 68307 | 68319 | src = data = pPage->aData; |
| 68308 | 68320 | hdr = pPage->hdrOffset; |
| 68309 | 68321 | cellOffset = pPage->cellOffset; |
| 68310 | 68322 | nCell = pPage->nCell; |
| 68311 | 68323 | assert( nCell==get2byte(&data[hdr+3]) || CORRUPT_DB ); |
| | @@ -68356,43 +68368,42 @@ |
| 68356 | 68368 | } |
| 68357 | 68369 | |
| 68358 | 68370 | cbrk = usableSize; |
| 68359 | 68371 | iCellLast = usableSize - 4; |
| 68360 | 68372 | iCellStart = get2byte(&data[hdr+5]); |
| 68361 | | - for(i=0; i<nCell; i++){ |
| 68362 | | - u8 *pAddr; /* The i-th cell pointer */ |
| 68363 | | - pAddr = &data[cellOffset + i*2]; |
| 68364 | | - pc = get2byte(pAddr); |
| 68365 | | - testcase( pc==iCellFirst ); |
| 68366 | | - testcase( pc==iCellLast ); |
| 68367 | | - /* These conditions have already been verified in btreeInitPage() |
| 68368 | | - ** if PRAGMA cell_size_check=ON. |
| 68369 | | - */ |
| 68370 | | - if( pc<iCellStart || pc>iCellLast ){ |
| 68371 | | - return SQLITE_CORRUPT_PAGE(pPage); |
| 68372 | | - } |
| 68373 | | - assert( pc>=iCellStart && pc<=iCellLast ); |
| 68374 | | - size = pPage->xCellSize(pPage, &src[pc]); |
| 68375 | | - cbrk -= size; |
| 68376 | | - if( cbrk<iCellStart || pc+size>usableSize ){ |
| 68377 | | - return SQLITE_CORRUPT_PAGE(pPage); |
| 68378 | | - } |
| 68379 | | - assert( cbrk+size<=usableSize && cbrk>=iCellStart ); |
| 68380 | | - testcase( cbrk+size==usableSize ); |
| 68381 | | - testcase( pc+size==usableSize ); |
| 68382 | | - put2byte(pAddr, cbrk); |
| 68383 | | - if( temp==0 ){ |
| 68384 | | - if( cbrk==pc ) continue; |
| 68385 | | - temp = sqlite3PagerTempSpace(pPage->pBt->pPager); |
| 68386 | | - memcpy(&temp[iCellStart], &data[iCellStart], usableSize - iCellStart); |
| 68387 | | - src = temp; |
| 68388 | | - } |
| 68389 | | - memcpy(&data[cbrk], &src[pc], size); |
| 68373 | + if( nCell>0 ){ |
| 68374 | + temp = sqlite3PagerTempSpace(pPage->pBt->pPager); |
| 68375 | + memcpy(&temp[iCellStart], &data[iCellStart], usableSize - iCellStart); |
| 68376 | + src = temp; |
| 68377 | + for(i=0; i<nCell; i++){ |
| 68378 | + u8 *pAddr; /* The i-th cell pointer */ |
| 68379 | + pAddr = &data[cellOffset + i*2]; |
| 68380 | + pc = get2byte(pAddr); |
| 68381 | + testcase( pc==iCellFirst ); |
| 68382 | + testcase( pc==iCellLast ); |
| 68383 | + /* These conditions have already been verified in btreeInitPage() |
| 68384 | + ** if PRAGMA cell_size_check=ON. |
| 68385 | + */ |
| 68386 | + if( pc<iCellStart || pc>iCellLast ){ |
| 68387 | + return SQLITE_CORRUPT_PAGE(pPage); |
| 68388 | + } |
| 68389 | + assert( pc>=iCellStart && pc<=iCellLast ); |
| 68390 | + size = pPage->xCellSize(pPage, &src[pc]); |
| 68391 | + cbrk -= size; |
| 68392 | + if( cbrk<iCellStart || pc+size>usableSize ){ |
| 68393 | + return SQLITE_CORRUPT_PAGE(pPage); |
| 68394 | + } |
| 68395 | + assert( cbrk+size<=usableSize && cbrk>=iCellStart ); |
| 68396 | + testcase( cbrk+size==usableSize ); |
| 68397 | + testcase( pc+size==usableSize ); |
| 68398 | + put2byte(pAddr, cbrk); |
| 68399 | + memcpy(&data[cbrk], &src[pc], size); |
| 68400 | + } |
| 68390 | 68401 | } |
| 68391 | 68402 | data[hdr+7] = 0; |
| 68392 | 68403 | |
| 68393 | | - defragment_out: |
| 68404 | +defragment_out: |
| 68394 | 68405 | assert( pPage->nFree>=0 ); |
| 68395 | 68406 | if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){ |
| 68396 | 68407 | return SQLITE_CORRUPT_PAGE(pPage); |
| 68397 | 68408 | } |
| 68398 | 68409 | assert( cbrk>=iCellFirst ); |
| | @@ -68461,13 +68472,13 @@ |
| 68461 | 68472 | return &aData[pc + x]; |
| 68462 | 68473 | } |
| 68463 | 68474 | iAddr = pc; |
| 68464 | 68475 | pTmp = &aData[pc]; |
| 68465 | 68476 | pc = get2byte(pTmp); |
| 68466 | | - if( pc<=iAddr+size ){ |
| 68477 | + if( pc<=iAddr ){ |
| 68467 | 68478 | if( pc ){ |
| 68468 | | - /* The next slot in the chain is not past the end of the current slot */ |
| 68479 | + /* The next slot in the chain comes before the current slot */ |
| 68469 | 68480 | *pRc = SQLITE_CORRUPT_PAGE(pPg); |
| 68470 | 68481 | } |
| 68471 | 68482 | return 0; |
| 68472 | 68483 | } |
| 68473 | 68484 | } |
| | @@ -68615,11 +68626,11 @@ |
| 68615 | 68626 | iPtr = hdr + 1; |
| 68616 | 68627 | if( data[iPtr+1]==0 && data[iPtr]==0 ){ |
| 68617 | 68628 | iFreeBlk = 0; /* Shortcut for the case when the freelist is empty */ |
| 68618 | 68629 | }else{ |
| 68619 | 68630 | while( (iFreeBlk = get2byte(&data[iPtr]))<iStart ){ |
| 68620 | | - if( iFreeBlk<iPtr+4 ){ |
| 68631 | + if( iFreeBlk<=iPtr ){ |
| 68621 | 68632 | if( iFreeBlk==0 ) break; /* TH3: corrupt082.100 */ |
| 68622 | 68633 | return SQLITE_CORRUPT_PAGE(pPage); |
| 68623 | 68634 | } |
| 68624 | 68635 | iPtr = iFreeBlk; |
| 68625 | 68636 | } |
| | @@ -69097,13 +69108,11 @@ |
| 69097 | 69108 | if( pCur ){ |
| 69098 | 69109 | pCur->iPage--; |
| 69099 | 69110 | pCur->pPage = pCur->apPage[pCur->iPage]; |
| 69100 | 69111 | } |
| 69101 | 69112 | testcase( pgno==0 ); |
| 69102 | | - assert( pgno!=0 || rc==SQLITE_CORRUPT |
| 69103 | | - || rc==SQLITE_IOERR_NOMEM |
| 69104 | | - || rc==SQLITE_NOMEM ); |
| 69113 | + assert( pgno!=0 || rc!=SQLITE_OK ); |
| 69105 | 69114 | return rc; |
| 69106 | 69115 | } |
| 69107 | 69116 | |
| 69108 | 69117 | /* |
| 69109 | 69118 | ** Release a MemPage. This should be called once for each prior |
| | @@ -72041,12 +72050,10 @@ |
| 72041 | 72050 | ** the new child page does not match the flags field of the parent (i.e. |
| 72042 | 72051 | ** if an intkey page appears to be the parent of a non-intkey page, or |
| 72043 | 72052 | ** vice-versa). |
| 72044 | 72053 | */ |
| 72045 | 72054 | static int moveToChild(BtCursor *pCur, u32 newPgno){ |
| 72046 | | - BtShared *pBt = pCur->pBt; |
| 72047 | | - |
| 72048 | 72055 | assert( cursorOwnsBtShared(pCur) ); |
| 72049 | 72056 | assert( pCur->eState==CURSOR_VALID ); |
| 72050 | 72057 | assert( pCur->iPage<BTCURSOR_MAX_DEPTH ); |
| 72051 | 72058 | assert( pCur->iPage>=0 ); |
| 72052 | 72059 | if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){ |
| | @@ -72056,11 +72063,12 @@ |
| 72056 | 72063 | pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); |
| 72057 | 72064 | pCur->aiIdx[pCur->iPage] = pCur->ix; |
| 72058 | 72065 | pCur->apPage[pCur->iPage] = pCur->pPage; |
| 72059 | 72066 | pCur->ix = 0; |
| 72060 | 72067 | pCur->iPage++; |
| 72061 | | - return getAndInitPage(pBt, newPgno, &pCur->pPage, pCur, pCur->curPagerFlags); |
| 72068 | + return getAndInitPage(pCur->pBt, newPgno, &pCur->pPage, pCur, |
| 72069 | + pCur->curPagerFlags); |
| 72062 | 72070 | } |
| 72063 | 72071 | |
| 72064 | 72072 | #ifdef SQLITE_DEBUG |
| 72065 | 72073 | /* |
| 72066 | 72074 | ** Page pParent is an internal (non-leaf) tree page. This function |
| | @@ -72162,11 +72170,11 @@ |
| 72162 | 72170 | assert( pCur->skipNext!=SQLITE_OK ); |
| 72163 | 72171 | return pCur->skipNext; |
| 72164 | 72172 | } |
| 72165 | 72173 | sqlite3BtreeClearCursor(pCur); |
| 72166 | 72174 | } |
| 72167 | | - rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->pPage, |
| 72175 | + rc = getAndInitPage(pCur->pBt, pCur->pgnoRoot, &pCur->pPage, |
| 72168 | 72176 | 0, pCur->curPagerFlags); |
| 72169 | 72177 | if( rc!=SQLITE_OK ){ |
| 72170 | 72178 | pCur->eState = CURSOR_INVALID; |
| 72171 | 72179 | return rc; |
| 72172 | 72180 | } |
| | @@ -73803,16 +73811,10 @@ |
| 73803 | 73811 | data = pPage->aData; |
| 73804 | 73812 | ptr = &pPage->aCellIdx[2*idx]; |
| 73805 | 73813 | assert( pPage->pBt->usableSize > (u32)(ptr-data) ); |
| 73806 | 73814 | pc = get2byte(ptr); |
| 73807 | 73815 | hdr = pPage->hdrOffset; |
| 73808 | | -#if 0 /* Not required. Omit for efficiency */ |
| 73809 | | - if( pc<hdr+pPage->nCell*2 ){ |
| 73810 | | - *pRC = SQLITE_CORRUPT_BKPT; |
| 73811 | | - return; |
| 73812 | | - } |
| 73813 | | -#endif |
| 73814 | 73816 | testcase( pc==(u32)get2byte(&data[hdr+5]) ); |
| 73815 | 73817 | testcase( pc+sz==pPage->pBt->usableSize ); |
| 73816 | 73818 | if( pc+sz > pPage->pBt->usableSize ){ |
| 73817 | 73819 | *pRC = SQLITE_CORRUPT_BKPT; |
| 73818 | 73820 | return; |
| | @@ -80759,11 +80761,18 @@ |
| 80759 | 80761 | return 0; |
| 80760 | 80762 | } |
| 80761 | 80763 | #endif |
| 80762 | 80764 | |
| 80763 | 80765 | /* |
| 80764 | | -** Swap all content between two VDBE structures. |
| 80766 | +** Swap byte-code between two VDBE structures. |
| 80767 | +** |
| 80768 | +** This happens after pB was previously run and returned |
| 80769 | +** SQLITE_SCHEMA. The statement was then reprepared in pA. |
| 80770 | +** This routine transfers the new bytecode in pA over to pB |
| 80771 | +** so that pB can be run again. The old pB byte code is |
| 80772 | +** moved back to pA so that it will be cleaned up when pA is |
| 80773 | +** finalized. |
| 80765 | 80774 | */ |
| 80766 | 80775 | SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){ |
| 80767 | 80776 | Vdbe tmp, *pTmp; |
| 80768 | 80777 | char *zTmp; |
| 80769 | 80778 | assert( pA->db==pB->db ); |
| | @@ -81450,12 +81459,12 @@ |
| 81450 | 81459 | Parse *pParse = p->pParse; |
| 81451 | 81460 | int *aLabel = pParse->aLabel; |
| 81452 | 81461 | p->readOnly = 1; |
| 81453 | 81462 | p->bIsReader = 0; |
| 81454 | 81463 | pOp = &p->aOp[p->nOp-1]; |
| 81455 | | - while(1){ |
| 81456 | | - |
| 81464 | + assert( p->aOp[0].opcode==OP_Init ); |
| 81465 | + while( 1 /* Loop termates when it reaches the OP_Init opcode */ ){ |
| 81457 | 81466 | /* Only JUMP opcodes and the short list of special opcodes in the switch |
| 81458 | 81467 | ** below need to be considered. The mkopcodeh.tcl generator script groups |
| 81459 | 81468 | ** all these opcodes together near the front of the opcode list. Skip |
| 81460 | 81469 | ** any opcode that does not need processing by virtual of the fact that |
| 81461 | 81470 | ** it is larger than SQLITE_MX_JUMP_OPCODE, as a performance optimization. |
| | @@ -81480,10 +81489,14 @@ |
| 81480 | 81489 | case OP_JournalMode: { |
| 81481 | 81490 | p->readOnly = 0; |
| 81482 | 81491 | p->bIsReader = 1; |
| 81483 | 81492 | break; |
| 81484 | 81493 | } |
| 81494 | + case OP_Init: { |
| 81495 | + assert( pOp->p2>=0 ); |
| 81496 | + goto resolve_p2_values_loop_exit; |
| 81497 | + } |
| 81485 | 81498 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 81486 | 81499 | case OP_VUpdate: { |
| 81487 | 81500 | if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; |
| 81488 | 81501 | break; |
| 81489 | 81502 | } |
| | @@ -81512,13 +81525,14 @@ |
| 81512 | 81525 | /* The mkopcodeh.tcl script has so arranged things that the only |
| 81513 | 81526 | ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to |
| 81514 | 81527 | ** have non-negative values for P2. */ |
| 81515 | 81528 | assert( (sqlite3OpcodeProperty[pOp->opcode]&OPFLG_JUMP)==0 || pOp->p2>=0); |
| 81516 | 81529 | } |
| 81517 | | - if( pOp==p->aOp ) break; |
| 81530 | + assert( pOp>p->aOp ); |
| 81518 | 81531 | pOp--; |
| 81519 | 81532 | } |
| 81533 | +resolve_p2_values_loop_exit: |
| 81520 | 81534 | if( aLabel ){ |
| 81521 | 81535 | sqlite3DbFreeNN(p->db, pParse->aLabel); |
| 81522 | 81536 | pParse->aLabel = 0; |
| 81523 | 81537 | } |
| 81524 | 81538 | pParse->nLabel = 0; |
| | @@ -86040,11 +86054,13 @@ |
| 86040 | 86054 | Vdbe *v = (Vdbe*)pStmt; |
| 86041 | 86055 | sqlite3 *db = v->db; |
| 86042 | 86056 | if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT; |
| 86043 | 86057 | sqlite3_mutex_enter(db->mutex); |
| 86044 | 86058 | checkProfileCallback(db, v); |
| 86045 | | - rc = sqlite3VdbeFinalize(v); |
| 86059 | + assert( v->eVdbeState>=VDBE_READY_STATE ); |
| 86060 | + rc = sqlite3VdbeReset(v); |
| 86061 | + sqlite3VdbeDelete(v); |
| 86046 | 86062 | rc = sqlite3ApiExit(db, rc); |
| 86047 | 86063 | sqlite3LeaveMutexAndCloseZombie(db); |
| 86048 | 86064 | } |
| 86049 | 86065 | return rc; |
| 86050 | 86066 | } |
| | @@ -90933,15 +90949,18 @@ |
| 90933 | 90949 | ** |
| 90934 | 90950 | ** Check the cursor P1 to see if it is currently pointing at a NULL row. |
| 90935 | 90951 | ** If it is, then set register P3 to NULL and jump immediately to P2. |
| 90936 | 90952 | ** If P1 is not on a NULL row, then fall through without making any |
| 90937 | 90953 | ** changes. |
| 90954 | +** |
| 90955 | +** If P1 is not an open cursor, then this opcode is a no-op. |
| 90938 | 90956 | */ |
| 90939 | 90957 | case OP_IfNullRow: { /* jump */ |
| 90958 | + VdbeCursor *pC; |
| 90940 | 90959 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 90941 | | - assert( p->apCsr[pOp->p1]!=0 ); |
| 90942 | | - if( p->apCsr[pOp->p1]->nullRow ){ |
| 90960 | + pC = p->apCsr[pOp->p1]; |
| 90961 | + if( ALWAYS(pC) && pC->nullRow ){ |
| 90943 | 90962 | sqlite3VdbeMemSetNull(aMem + pOp->p3); |
| 90944 | 90963 | goto jump_to_p2; |
| 90945 | 90964 | } |
| 90946 | 90965 | break; |
| 90947 | 90966 | } |
| | @@ -101759,11 +101778,11 @@ |
| 101759 | 101778 | for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){ |
| 101760 | 101779 | u8 hCol; |
| 101761 | 101780 | pTab = pItem->pTab; |
| 101762 | 101781 | assert( pTab!=0 && pTab->zName!=0 ); |
| 101763 | 101782 | assert( pTab->nCol>0 || pParse->nErr ); |
| 101764 | | - assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); |
| 101783 | + assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); |
| 101765 | 101784 | if( pItem->fg.isNestedFrom ){ |
| 101766 | 101785 | /* In this case, pItem is a subquery that has been formed from a |
| 101767 | 101786 | ** parenthesized subset of the FROM clause terms. Example: |
| 101768 | 101787 | ** .... FROM t1 LEFT JOIN (t2 RIGHT JOIN t3 USING(x)) USING(y) ... |
| 101769 | 101788 | ** \_________________________/ |
| | @@ -115449,12 +115468,10 @@ |
| 115449 | 115468 | pParse->nested++; |
| 115450 | 115469 | memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ); |
| 115451 | 115470 | memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ); |
| 115452 | 115471 | db->mDbFlags |= DBFLAG_PreferBuiltin; |
| 115453 | 115472 | sqlite3RunParser(pParse, zSql); |
| 115454 | | - sqlite3DbFree(db, pParse->zErrMsg); |
| 115455 | | - pParse->zErrMsg = 0; |
| 115456 | 115473 | db->mDbFlags = savedDbFlags; |
| 115457 | 115474 | sqlite3DbFree(db, zSql); |
| 115458 | 115475 | memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ); |
| 115459 | 115476 | pParse->nested--; |
| 115460 | 115477 | } |
| | @@ -135851,11 +135868,11 @@ |
| 135851 | 135868 | /* |
| 135852 | 135869 | ** Mark a subquery result column as having been used. |
| 135853 | 135870 | */ |
| 135854 | 135871 | SQLITE_PRIVATE void sqlite3SrcItemColumnUsed(SrcItem *pItem, int iCol){ |
| 135855 | 135872 | assert( pItem!=0 ); |
| 135856 | | - assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); |
| 135873 | + assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); |
| 135857 | 135874 | if( pItem->fg.isNestedFrom ){ |
| 135858 | 135875 | ExprList *pResults; |
| 135859 | 135876 | assert( pItem->pSelect!=0 ); |
| 135860 | 135877 | pResults = pItem->pSelect->pEList; |
| 135861 | 135878 | assert( pResults!=0 ); |
| | @@ -137347,13 +137364,10 @@ |
| 137347 | 137364 | |
| 137348 | 137365 | /* |
| 137349 | 137366 | ** Return a pointer to a string containing the 'declaration type' of the |
| 137350 | 137367 | ** expression pExpr. The string may be treated as static by the caller. |
| 137351 | 137368 | ** |
| 137352 | | -** Also try to estimate the size of the returned value and return that |
| 137353 | | -** result in *pEstWidth. |
| 137354 | | -** |
| 137355 | 137369 | ** The declaration type is the exact datatype definition extracted from the |
| 137356 | 137370 | ** original CREATE TABLE statement if the expression is a column. The |
| 137357 | 137371 | ** declaration type for a ROWID field is INTEGER. Exactly when an expression |
| 137358 | 137372 | ** is considered a column can be complex in the presence of subqueries. The |
| 137359 | 137373 | ** result-set expression in all of the following SELECT statements is |
| | @@ -139595,11 +139609,12 @@ |
| 139595 | 139609 | ** |
| 139596 | 139610 | ** (3) If the subquery is the right operand of a LEFT JOIN then |
| 139597 | 139611 | ** (3a) the subquery may not be a join and |
| 139598 | 139612 | ** (3b) the FROM clause of the subquery may not contain a virtual |
| 139599 | 139613 | ** table and |
| 139600 | | -** (3c) the outer query may not be an aggregate. |
| 139614 | +** (3c) The outer query may not have a GROUP BY. (This limitation is |
| 139615 | +** due to how TK_IF_NULL_ROW works. FIX ME!) |
| 139601 | 139616 | ** (3d) the outer query may not be DISTINCT. |
| 139602 | 139617 | ** See also (26) for restrictions on RIGHT JOIN. |
| 139603 | 139618 | ** |
| 139604 | 139619 | ** (4) The subquery can not be DISTINCT. |
| 139605 | 139620 | ** |
| | @@ -139649,10 +139664,13 @@ |
| 139649 | 139664 | ** (17d) the outer query may not be |
| 139650 | 139665 | ** (17d1) aggregate, or |
| 139651 | 139666 | ** (17d2) DISTINCT |
| 139652 | 139667 | ** (17e) the subquery may not contain window functions, and |
| 139653 | 139668 | ** (17f) the subquery must not be the RHS of a LEFT JOIN. |
| 139669 | +** (17g) either the subquery is the first element of the outer |
| 139670 | +** query or there are no RIGHT or FULL JOINs in any arm |
| 139671 | +** of the subquery. (This is a duplicate of condition (27b).) |
| 139654 | 139672 | ** |
| 139655 | 139673 | ** The parent and sub-query may contain WHERE clauses. Subject to |
| 139656 | 139674 | ** rules (11), (13) and (14), they may also contain ORDER BY, |
| 139657 | 139675 | ** LIMIT and OFFSET clauses. The subquery cannot use any compound |
| 139658 | 139676 | ** operator other than UNION ALL because all the other compound |
| | @@ -139700,11 +139718,15 @@ |
| 139700 | 139718 | ** |
| 139701 | 139719 | ** (26) The subquery may not be the right operand of a RIGHT JOIN. |
| 139702 | 139720 | ** See also (3) for restrictions on LEFT JOIN. |
| 139703 | 139721 | ** |
| 139704 | 139722 | ** (27) The subquery may not contain a FULL or RIGHT JOIN unless it |
| 139705 | | -** is the first element of the parent query. |
| 139723 | +** is the first element of the parent query. This must be the |
| 139724 | +** the case if: |
| 139725 | +** (27a) the subquery is not compound query, and |
| 139726 | +** (27b) the subquery is a compound query and the RIGHT JOIN occurs |
| 139727 | +** in any arm of the compound query. (See also (17g).) |
| 139706 | 139728 | ** |
| 139707 | 139729 | ** (28) The subquery is not a MATERIALIZED CTE. |
| 139708 | 139730 | ** |
| 139709 | 139731 | ** (29) Either the subquery is not the right-hand operand of a join with an |
| 139710 | 139732 | ** ON or USING clause nor the right-hand operand of a NATURAL JOIN, or |
| | @@ -139800,22 +139822,17 @@ |
| 139800 | 139822 | ** |
| 139801 | 139823 | ** (t1 LEFT OUTER JOIN t2) JOIN t3 |
| 139802 | 139824 | ** |
| 139803 | 139825 | ** which is not at all the same thing. |
| 139804 | 139826 | ** |
| 139805 | | - ** If the subquery is the right operand of a LEFT JOIN, then the outer |
| 139806 | | - ** query cannot be an aggregate. (3c) This is an artifact of the way |
| 139807 | | - ** aggregates are processed - there is no mechanism to determine if |
| 139808 | | - ** the LEFT JOIN table should be all-NULL. |
| 139809 | | - ** |
| 139810 | 139827 | ** See also tickets #306, #350, and #3300. |
| 139811 | 139828 | */ |
| 139812 | 139829 | if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){ |
| 139813 | 139830 | if( pSubSrc->nSrc>1 /* (3a) */ |
| 139814 | | - || isAgg /* (3c) */ |
| 139815 | 139831 | || IsVirtual(pSubSrc->a[0].pTab) /* (3b) */ |
| 139816 | 139832 | || (p->selFlags & SF_Distinct)!=0 /* (3d) */ |
| 139833 | + || (p->pGroupBy!=0) /* (3c) */ |
| 139817 | 139834 | || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */ |
| 139818 | 139835 | ){ |
| 139819 | 139836 | return 0; |
| 139820 | 139837 | } |
| 139821 | 139838 | isOuterJoin = 1; |
| | @@ -139830,11 +139847,11 @@ |
| 139830 | 139847 | } |
| 139831 | 139848 | #endif |
| 139832 | 139849 | |
| 139833 | 139850 | assert( pSubSrc->nSrc>0 ); /* True by restriction (7) */ |
| 139834 | 139851 | if( iFrom>0 && (pSubSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ |
| 139835 | | - return 0; /* Restriction (27) */ |
| 139852 | + return 0; /* Restriction (27a) */ |
| 139836 | 139853 | } |
| 139837 | 139854 | if( pSubitem->fg.isCte && pSubitem->u2.pCteUse->eM10d==M10d_Yes ){ |
| 139838 | 139855 | return 0; /* (28) */ |
| 139839 | 139856 | } |
| 139840 | 139857 | |
| | @@ -139850,11 +139867,11 @@ |
| 139850 | 139867 | ** |
| 139851 | 139868 | ** (29b) The subquery itself must not be the right operand of a |
| 139852 | 139869 | ** NATURAL join or a join that as an ON or USING clause. |
| 139853 | 139870 | ** |
| 139854 | 139871 | ** These conditions are sufficient to keep an EP_OuterON from being |
| 139855 | | - ** flattened into an EP_InnerON. Restrictions (3a) and (27) prevent |
| 139872 | + ** flattened into an EP_InnerON. Restrictions (3a) and (27a) prevent |
| 139856 | 139873 | ** an EP_InnerON from being flattened into an EP_OuterON. |
| 139857 | 139874 | */ |
| 139858 | 139875 | if( pSubSrc->nSrc>=2 |
| 139859 | 139876 | && (pSubSrc->a[pSubSrc->nSrc-1].fg.jointype & JT_OUTER)!=0 |
| 139860 | 139877 | ){ |
| | @@ -139891,10 +139908,16 @@ |
| 139891 | 139908 | #ifndef SQLITE_OMIT_WINDOWFUNC |
| 139892 | 139909 | || pSub1->pWin /* (17e) */ |
| 139893 | 139910 | #endif |
| 139894 | 139911 | ){ |
| 139895 | 139912 | return 0; |
| 139913 | + } |
| 139914 | + if( iFrom>0 && (pSub1->pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ |
| 139915 | + /* Without this restriction, the JT_LTORJ flag would end up being |
| 139916 | + ** omitted on left-hand tables of the right join that is being |
| 139917 | + ** flattened. */ |
| 139918 | + return 0; /* Restrictions (17g), (27b) */ |
| 139896 | 139919 | } |
| 139897 | 139920 | testcase( pSub1->pSrc->nSrc>1 ); |
| 139898 | 139921 | } |
| 139899 | 139922 | |
| 139900 | 139923 | /* Restriction (18). */ |
| | @@ -140724,10 +140747,11 @@ |
| 140724 | 140747 | if( p->pWhere |
| 140725 | 140748 | || p->pEList->nExpr!=1 |
| 140726 | 140749 | || p->pSrc->nSrc!=1 |
| 140727 | 140750 | || p->pSrc->a[0].pSelect |
| 140728 | 140751 | || pAggInfo->nFunc!=1 |
| 140752 | + || p->pHaving |
| 140729 | 140753 | ){ |
| 140730 | 140754 | return 0; |
| 140731 | 140755 | } |
| 140732 | 140756 | pTab = p->pSrc->a[0].pTab; |
| 140733 | 140757 | assert( pTab!=0 ); |
| | @@ -141425,11 +141449,11 @@ |
| 141425 | 141449 | |
| 141426 | 141450 | if( (zTabName = pFrom->zAlias)==0 ){ |
| 141427 | 141451 | zTabName = pTab->zName; |
| 141428 | 141452 | } |
| 141429 | 141453 | if( db->mallocFailed ) break; |
| 141430 | | - assert( pFrom->fg.isNestedFrom == IsNestedFrom(pFrom->pSelect) ); |
| 141454 | + assert( (int)pFrom->fg.isNestedFrom == IsNestedFrom(pFrom->pSelect) ); |
| 141431 | 141455 | if( pFrom->fg.isNestedFrom ){ |
| 141432 | 141456 | assert( pFrom->pSelect!=0 ); |
| 141433 | 141457 | pNestedFrom = pFrom->pSelect->pEList; |
| 141434 | 141458 | assert( pNestedFrom!=0 ); |
| 141435 | 141459 | assert( pNestedFrom->nExpr==pTab->nCol ); |
| | @@ -142354,11 +142378,13 @@ |
| 142354 | 142378 | && (p->selFlags & SF_OrderByReqd)==0 /* Condition (3) and (4) */ |
| 142355 | 142379 | && OptimizationEnabled(db, SQLITE_OmitOrderBy) |
| 142356 | 142380 | ){ |
| 142357 | 142381 | SELECTTRACE(0x100,pParse,p, |
| 142358 | 142382 | ("omit superfluous ORDER BY on %r FROM-clause subquery\n",i+1)); |
| 142359 | | - sqlite3ExprListDelete(db, pSub->pOrderBy); |
| 142383 | + sqlite3ParserAddCleanup(pParse, |
| 142384 | + (void(*)(sqlite3*,void*))sqlite3ExprListDelete, |
| 142385 | + pSub->pOrderBy); |
| 142360 | 142386 | pSub->pOrderBy = 0; |
| 142361 | 142387 | } |
| 142362 | 142388 | |
| 142363 | 142389 | /* If the outer query contains a "complex" result set (that is, |
| 142364 | 142390 | ** if the result set of the outer query uses functions or subqueries) |
| | @@ -155354,11 +155380,11 @@ |
| 155354 | 155380 | #ifndef SQLITE_DEBUG |
| 155355 | 155381 | UNUSED_PARAMETER( pParse ); |
| 155356 | 155382 | #endif |
| 155357 | 155383 | assert( pRec!=0 ); |
| 155358 | 155384 | assert( pIdx->nSample>0 ); |
| 155359 | | - assert( pRec->nField>0 && pRec->nField<=pIdx->nSampleCol ); |
| 155385 | + assert( pRec->nField>0 ); |
| 155360 | 155386 | |
| 155361 | 155387 | /* Do a binary search to find the first sample greater than or equal |
| 155362 | 155388 | ** to pRec. If pRec contains a single field, the set of samples to search |
| 155363 | 155389 | ** is simply the aSample[] array. If the samples in aSample[] contain more |
| 155364 | 155390 | ** than one fields, all fields following the first are ignored. |
| | @@ -155400,11 +155426,11 @@ |
| 155400 | 155426 | ** appears that it should be 1 field in size. However, that would make it |
| 155401 | 155427 | ** smaller than sample 1, so the binary search would not work. As a result, |
| 155402 | 155428 | ** it is extended to two fields. The duplicates that this creates do not |
| 155403 | 155429 | ** cause any problems. |
| 155404 | 155430 | */ |
| 155405 | | - nField = pRec->nField; |
| 155431 | + nField = MIN(pRec->nField, pIdx->nSample); |
| 155406 | 155432 | iCol = 0; |
| 155407 | 155433 | iSample = pIdx->nSample * nField; |
| 155408 | 155434 | do{ |
| 155409 | 155435 | int iSamp; /* Index in aSample[] of test sample */ |
| 155410 | 155436 | int n; /* Number of fields in test sample */ |
| | @@ -156117,16 +156143,22 @@ |
| 156117 | 156143 | } |
| 156118 | 156144 | } |
| 156119 | 156145 | } |
| 156120 | 156146 | |
| 156121 | 156147 | /* |
| 156122 | | -** Deallocate internal memory used by a WhereLoop object |
| 156148 | +** Deallocate internal memory used by a WhereLoop object. Leave the |
| 156149 | +** object in an initialized state, as if it had been newly allocated. |
| 156123 | 156150 | */ |
| 156124 | 156151 | static void whereLoopClear(sqlite3 *db, WhereLoop *p){ |
| 156125 | | - if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFreeNN(db, p->aLTerm); |
| 156152 | + if( p->aLTerm!=p->aLTermSpace ){ |
| 156153 | + sqlite3DbFreeNN(db, p->aLTerm); |
| 156154 | + p->aLTerm = p->aLTermSpace; |
| 156155 | + p->nLSlot = ArraySize(p->aLTermSpace); |
| 156156 | + } |
| 156126 | 156157 | whereLoopClearUnion(db, p); |
| 156127 | | - whereLoopInit(p); |
| 156158 | + p->nLTerm = 0; |
| 156159 | + p->wsFlags = 0; |
| 156128 | 156160 | } |
| 156129 | 156161 | |
| 156130 | 156162 | /* |
| 156131 | 156163 | ** Increase the memory allocation for pLoop->aLTerm[] to be at least n. |
| 156132 | 156164 | */ |
| | @@ -156146,11 +156178,13 @@ |
| 156146 | 156178 | /* |
| 156147 | 156179 | ** Transfer content from the second pLoop into the first. |
| 156148 | 156180 | */ |
| 156149 | 156181 | static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){ |
| 156150 | 156182 | whereLoopClearUnion(db, pTo); |
| 156151 | | - if( whereLoopResize(db, pTo, pFrom->nLTerm) ){ |
| 156183 | + if( pFrom->nLTerm > pTo->nLSlot |
| 156184 | + && whereLoopResize(db, pTo, pFrom->nLTerm) |
| 156185 | + ){ |
| 156152 | 156186 | memset(pTo, 0, WHERE_LOOP_XFER_SZ); |
| 156153 | 156187 | return SQLITE_NOMEM_BKPT; |
| 156154 | 156188 | } |
| 156155 | 156189 | memcpy(pTo, pFrom, WHERE_LOOP_XFER_SZ); |
| 156156 | 156190 | memcpy(pTo->aLTerm, pFrom->aLTerm, pTo->nLTerm*sizeof(pTo->aLTerm[0])); |
| | @@ -156799,11 +156833,15 @@ |
| 156799 | 156833 | pNew->wsFlags = saved_wsFlags; |
| 156800 | 156834 | pNew->u.btree.nEq = saved_nEq; |
| 156801 | 156835 | pNew->u.btree.nBtm = saved_nBtm; |
| 156802 | 156836 | pNew->u.btree.nTop = saved_nTop; |
| 156803 | 156837 | pNew->nLTerm = saved_nLTerm; |
| 156804 | | - if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ |
| 156838 | + if( pNew->nLTerm>=pNew->nLSlot |
| 156839 | + && whereLoopResize(db, pNew, pNew->nLTerm+1) |
| 156840 | + ){ |
| 156841 | + break; /* OOM while trying to enlarge the pNew->aLTerm array */ |
| 156842 | + } |
| 156805 | 156843 | pNew->aLTerm[pNew->nLTerm++] = pTerm; |
| 156806 | 156844 | pNew->prereq = (saved_prereq | pTerm->prereqRight) & ~pNew->maskSelf; |
| 156807 | 156845 | |
| 156808 | 156846 | assert( nInMul==0 |
| 156809 | 156847 | || (pNew->wsFlags & WHERE_COLUMN_NULL)!=0 |
| | @@ -156892,42 +156930,43 @@ |
| 156892 | 156930 | } |
| 156893 | 156931 | } |
| 156894 | 156932 | if( scan.iEquiv>1 ) pNew->wsFlags |= WHERE_TRANSCONS; |
| 156895 | 156933 | }else if( eOp & WO_ISNULL ){ |
| 156896 | 156934 | pNew->wsFlags |= WHERE_COLUMN_NULL; |
| 156897 | | - }else if( eOp & (WO_GT|WO_GE) ){ |
| 156898 | | - testcase( eOp & WO_GT ); |
| 156899 | | - testcase( eOp & WO_GE ); |
| 156900 | | - pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT; |
| 156901 | | - pNew->u.btree.nBtm = whereRangeVectorLen( |
| 156902 | | - pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm |
| 156903 | | - ); |
| 156904 | | - pBtm = pTerm; |
| 156905 | | - pTop = 0; |
| 156906 | | - if( pTerm->wtFlags & TERM_LIKEOPT ){ |
| 156907 | | - /* Range constraints that come from the LIKE optimization are |
| 156908 | | - ** always used in pairs. */ |
| 156909 | | - pTop = &pTerm[1]; |
| 156910 | | - assert( (pTop-(pTerm->pWC->a))<pTerm->pWC->nTerm ); |
| 156911 | | - assert( pTop->wtFlags & TERM_LIKEOPT ); |
| 156912 | | - assert( pTop->eOperator==WO_LT ); |
| 156913 | | - if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ |
| 156914 | | - pNew->aLTerm[pNew->nLTerm++] = pTop; |
| 156915 | | - pNew->wsFlags |= WHERE_TOP_LIMIT; |
| 156916 | | - pNew->u.btree.nTop = 1; |
| 156917 | | - } |
| 156918 | | - }else{ |
| 156919 | | - assert( eOp & (WO_LT|WO_LE) ); |
| 156920 | | - testcase( eOp & WO_LT ); |
| 156921 | | - testcase( eOp & WO_LE ); |
| 156922 | | - pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT; |
| 156923 | | - pNew->u.btree.nTop = whereRangeVectorLen( |
| 156924 | | - pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm |
| 156925 | | - ); |
| 156926 | | - pTop = pTerm; |
| 156927 | | - pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ? |
| 156928 | | - pNew->aLTerm[pNew->nLTerm-2] : 0; |
| 156935 | + }else{ |
| 156936 | + int nVecLen = whereRangeVectorLen( |
| 156937 | + pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm |
| 156938 | + ); |
| 156939 | + if( eOp & (WO_GT|WO_GE) ){ |
| 156940 | + testcase( eOp & WO_GT ); |
| 156941 | + testcase( eOp & WO_GE ); |
| 156942 | + pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT; |
| 156943 | + pNew->u.btree.nBtm = nVecLen; |
| 156944 | + pBtm = pTerm; |
| 156945 | + pTop = 0; |
| 156946 | + if( pTerm->wtFlags & TERM_LIKEOPT ){ |
| 156947 | + /* Range constraints that come from the LIKE optimization are |
| 156948 | + ** always used in pairs. */ |
| 156949 | + pTop = &pTerm[1]; |
| 156950 | + assert( (pTop-(pTerm->pWC->a))<pTerm->pWC->nTerm ); |
| 156951 | + assert( pTop->wtFlags & TERM_LIKEOPT ); |
| 156952 | + assert( pTop->eOperator==WO_LT ); |
| 156953 | + if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ |
| 156954 | + pNew->aLTerm[pNew->nLTerm++] = pTop; |
| 156955 | + pNew->wsFlags |= WHERE_TOP_LIMIT; |
| 156956 | + pNew->u.btree.nTop = 1; |
| 156957 | + } |
| 156958 | + }else{ |
| 156959 | + assert( eOp & (WO_LT|WO_LE) ); |
| 156960 | + testcase( eOp & WO_LT ); |
| 156961 | + testcase( eOp & WO_LE ); |
| 156962 | + pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT; |
| 156963 | + pNew->u.btree.nTop = nVecLen; |
| 156964 | + pTop = pTerm; |
| 156965 | + pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ? |
| 156966 | + pNew->aLTerm[pNew->nLTerm-2] : 0; |
| 156967 | + } |
| 156929 | 156968 | } |
| 156930 | 156969 | |
| 156931 | 156970 | /* At this point pNew->nOut is set to the number of rows expected to |
| 156932 | 156971 | ** be visited by the index scan before considering term pTerm, or the |
| 156933 | 156972 | ** values of nIn and nInMul. In other words, assuming that all |
| | @@ -158089,16 +158128,23 @@ |
| 158089 | 158128 | SrcItem *pItem; |
| 158090 | 158129 | SrcItem *pEnd = &pTabList->a[pWInfo->nLevel]; |
| 158091 | 158130 | sqlite3 *db = pWInfo->pParse->db; |
| 158092 | 158131 | int rc = SQLITE_OK; |
| 158093 | 158132 | int bFirstPastRJ = 0; |
| 158133 | + int hasRightJoin = 0; |
| 158094 | 158134 | WhereLoop *pNew; |
| 158095 | 158135 | |
| 158096 | 158136 | |
| 158097 | 158137 | /* Loop over the tables in the join, from left to right */ |
| 158098 | 158138 | pNew = pBuilder->pNew; |
| 158099 | | - whereLoopInit(pNew); |
| 158139 | + |
| 158140 | + /* Verify that pNew has already been initialized */ |
| 158141 | + assert( pNew->nLTerm==0 ); |
| 158142 | + assert( pNew->wsFlags==0 ); |
| 158143 | + assert( pNew->nLSlot>=ArraySize(pNew->aLTermSpace) ); |
| 158144 | + assert( pNew->aLTerm!=0 ); |
| 158145 | + |
| 158100 | 158146 | pBuilder->iPlanLimit = SQLITE_QUERY_PLANNER_LIMIT; |
| 158101 | 158147 | for(iTab=0, pItem=pTabList->a; pItem<pEnd; iTab++, pItem++){ |
| 158102 | 158148 | Bitmask mUnusable = 0; |
| 158103 | 158149 | pNew->iTab = iTab; |
| 158104 | 158150 | pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR; |
| | @@ -158109,19 +158155,20 @@ |
| 158109 | 158155 | /* Add prerequisites to prevent reordering of FROM clause terms |
| 158110 | 158156 | ** across CROSS joins and outer joins. The bFirstPastRJ boolean |
| 158111 | 158157 | ** prevents the right operand of a RIGHT JOIN from being swapped with |
| 158112 | 158158 | ** other elements even further to the right. |
| 158113 | 158159 | ** |
| 158114 | | - ** The JT_LTORJ term prevents any FROM-clause term reordering for terms |
| 158115 | | - ** to the left of a RIGHT JOIN. This is conservative. Relaxing this |
| 158116 | | - ** constraint somewhat to prevent terms from crossing from the right |
| 158117 | | - ** side of a LEFT JOIN over to the left side when they are on the |
| 158118 | | - ** left side of a RIGHT JOIN would be sufficient for all known failure |
| 158119 | | - ** cases. FIX ME: Implement this optimization. |
| 158160 | + ** The JT_LTORJ case and the hasRightJoin flag work together to |
| 158161 | + ** prevent FROM-clause terms from moving from the right side of |
| 158162 | + ** a LEFT JOIN over to the left side of that join if the LEFT JOIN |
| 158163 | + ** is itself on the left side of a RIGHT JOIN. |
| 158120 | 158164 | */ |
| 158165 | + if( pItem->fg.jointype & JT_LTORJ ) hasRightJoin = 1; |
| 158121 | 158166 | mPrereq |= mPrior; |
| 158122 | 158167 | bFirstPastRJ = (pItem->fg.jointype & JT_RIGHT)!=0; |
| 158168 | + }else if( !hasRightJoin ){ |
| 158169 | + mPrereq = 0; |
| 158123 | 158170 | } |
| 158124 | 158171 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 158125 | 158172 | if( IsVirtual(pItem->pTab) ){ |
| 158126 | 158173 | SrcItem *p; |
| 158127 | 158174 | for(p=&pItem[1]; p<pEnd; p++){ |
| | @@ -158690,13 +158737,13 @@ |
| 158690 | 158737 | for(ii=0, pFrom=aFrom; ii<nFrom; ii++, pFrom++){ |
| 158691 | 158738 | for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ |
| 158692 | 158739 | LogEst nOut; /* Rows visited by (pFrom+pWLoop) */ |
| 158693 | 158740 | LogEst rCost; /* Cost of path (pFrom+pWLoop) */ |
| 158694 | 158741 | LogEst rUnsorted; /* Unsorted cost of (pFrom+pWLoop) */ |
| 158695 | | - i8 isOrdered = pFrom->isOrdered; /* isOrdered for (pFrom+pWLoop) */ |
| 158742 | + i8 isOrdered; /* isOrdered for (pFrom+pWLoop) */ |
| 158696 | 158743 | Bitmask maskNew; /* Mask of src visited by (..) */ |
| 158697 | | - Bitmask revMask = 0; /* Mask of rev-order loops for (..) */ |
| 158744 | + Bitmask revMask; /* Mask of rev-order loops for (..) */ |
| 158698 | 158745 | |
| 158699 | 158746 | if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue; |
| 158700 | 158747 | if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue; |
| 158701 | 158748 | if( (pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 && pFrom->nRow<3 ){ |
| 158702 | 158749 | /* Do not use an automatic index if the this loop is expected |
| | @@ -158711,11 +158758,13 @@ |
| 158711 | 158758 | ** Compute its cost */ |
| 158712 | 158759 | rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow); |
| 158713 | 158760 | rUnsorted = sqlite3LogEstAdd(rUnsorted, pFrom->rUnsorted); |
| 158714 | 158761 | nOut = pFrom->nRow + pWLoop->nOut; |
| 158715 | 158762 | maskNew = pFrom->maskLoop | pWLoop->maskSelf; |
| 158763 | + isOrdered = pFrom->isOrdered; |
| 158716 | 158764 | if( isOrdered<0 ){ |
| 158765 | + revMask = 0; |
| 158717 | 158766 | isOrdered = wherePathSatisfiesOrderBy(pWInfo, |
| 158718 | 158767 | pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags, |
| 158719 | 158768 | iLoop, pWLoop, &revMask); |
| 158720 | 158769 | }else{ |
| 158721 | 158770 | revMask = pFrom->revLoop; |
| | @@ -169958,10 +170007,11 @@ |
| 169958 | 170007 | while( 1 ){ |
| 169959 | 170008 | n = sqlite3GetToken((u8*)zSql, &tokenType); |
| 169960 | 170009 | mxSqlLen -= n; |
| 169961 | 170010 | if( mxSqlLen<0 ){ |
| 169962 | 170011 | pParse->rc = SQLITE_TOOBIG; |
| 170012 | + pParse->nErr++; |
| 169963 | 170013 | break; |
| 169964 | 170014 | } |
| 169965 | 170015 | #ifndef SQLITE_OMIT_WINDOWFUNC |
| 169966 | 170016 | if( tokenType>=TK_WINDOW ){ |
| 169967 | 170017 | assert( tokenType==TK_SPACE || tokenType==TK_OVER || tokenType==TK_FILTER |
| | @@ -174698,12 +174748,15 @@ |
| 174698 | 174748 | sqlite3ShowUpsert(0); |
| 174699 | 174749 | sqlite3ShowTriggerStep(0); |
| 174700 | 174750 | sqlite3ShowTriggerStepList(0); |
| 174701 | 174751 | sqlite3ShowTrigger(0); |
| 174702 | 174752 | sqlite3ShowTriggerList(0); |
| 174753 | +#ifndef SQLITE_OMIT_WINDOWFUNC |
| 174703 | 174754 | sqlite3ShowWindow(0); |
| 174704 | 174755 | sqlite3ShowWinFunc(0); |
| 174756 | +#endif |
| 174757 | + sqlite3ShowSelect(0); |
| 174705 | 174758 | } |
| 174706 | 174759 | #endif |
| 174707 | 174760 | break; |
| 174708 | 174761 | } |
| 174709 | 174762 | |
| | @@ -181033,12 +181086,11 @@ |
| 181033 | 181086 | static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){ |
| 181034 | 181087 | int iToken; /* Used to iterate through phrase tokens */ |
| 181035 | 181088 | char *aPoslist = 0; /* Position list for deferred tokens */ |
| 181036 | 181089 | int nPoslist = 0; /* Number of bytes in aPoslist */ |
| 181037 | 181090 | int iPrev = -1; /* Token number of previous deferred token */ |
| 181038 | | - |
| 181039 | | - assert( pPhrase->doclist.bFreeList==0 ); |
| 181091 | + char *aFree = (pPhrase->doclist.bFreeList ? pPhrase->doclist.pList : 0); |
| 181040 | 181092 | |
| 181041 | 181093 | for(iToken=0; iToken<pPhrase->nToken; iToken++){ |
| 181042 | 181094 | Fts3PhraseToken *pToken = &pPhrase->aToken[iToken]; |
| 181043 | 181095 | Fts3DeferredToken *pDeferred = pToken->pDeferred; |
| 181044 | 181096 | |
| | @@ -181048,10 +181100,11 @@ |
| 181048 | 181100 | int rc = sqlite3Fts3DeferredTokenList(pDeferred, &pList, &nList); |
| 181049 | 181101 | if( rc!=SQLITE_OK ) return rc; |
| 181050 | 181102 | |
| 181051 | 181103 | if( pList==0 ){ |
| 181052 | 181104 | sqlite3_free(aPoslist); |
| 181105 | + sqlite3_free(aFree); |
| 181053 | 181106 | pPhrase->doclist.pList = 0; |
| 181054 | 181107 | pPhrase->doclist.nList = 0; |
| 181055 | 181108 | return SQLITE_OK; |
| 181056 | 181109 | |
| 181057 | 181110 | }else if( aPoslist==0 ){ |
| | @@ -181068,10 +181121,11 @@ |
| 181068 | 181121 | sqlite3_free(aPoslist); |
| 181069 | 181122 | aPoslist = pList; |
| 181070 | 181123 | nPoslist = (int)(aOut - aPoslist); |
| 181071 | 181124 | if( nPoslist==0 ){ |
| 181072 | 181125 | sqlite3_free(aPoslist); |
| 181126 | + sqlite3_free(aFree); |
| 181073 | 181127 | pPhrase->doclist.pList = 0; |
| 181074 | 181128 | pPhrase->doclist.nList = 0; |
| 181075 | 181129 | return SQLITE_OK; |
| 181076 | 181130 | } |
| 181077 | 181131 | } |
| | @@ -181107,10 +181161,11 @@ |
| 181107 | 181161 | sqlite3_free(aPoslist); |
| 181108 | 181162 | return SQLITE_NOMEM; |
| 181109 | 181163 | } |
| 181110 | 181164 | |
| 181111 | 181165 | pPhrase->doclist.pList = aOut; |
| 181166 | + assert( p1 && p2 ); |
| 181112 | 181167 | if( fts3PoslistPhraseMerge(&aOut, nDistance, 0, 1, &p1, &p2) ){ |
| 181113 | 181168 | pPhrase->doclist.bFreeList = 1; |
| 181114 | 181169 | pPhrase->doclist.nList = (int)(aOut - pPhrase->doclist.pList); |
| 181115 | 181170 | }else{ |
| 181116 | 181171 | sqlite3_free(aOut); |
| | @@ -181119,10 +181174,11 @@ |
| 181119 | 181174 | } |
| 181120 | 181175 | sqlite3_free(aPoslist); |
| 181121 | 181176 | } |
| 181122 | 181177 | } |
| 181123 | 181178 | |
| 181179 | + if( pPhrase->doclist.pList!=aFree ) sqlite3_free(aFree); |
| 181124 | 181180 | return SQLITE_OK; |
| 181125 | 181181 | } |
| 181126 | 181182 | #endif /* SQLITE_DISABLE_FTS4_DEFERRED */ |
| 181127 | 181183 | |
| 181128 | 181184 | /* |
| | @@ -182293,15 +182349,14 @@ |
| 182293 | 182349 | ); |
| 182294 | 182350 | break; |
| 182295 | 182351 | |
| 182296 | 182352 | default: { |
| 182297 | 182353 | #ifndef SQLITE_DISABLE_FTS4_DEFERRED |
| 182298 | | - if( pCsr->pDeferred |
| 182299 | | - && (pExpr->iDocid==pCsr->iPrevId || pExpr->bDeferred) |
| 182300 | | - ){ |
| 182354 | + if( pCsr->pDeferred && (pExpr->bDeferred || ( |
| 182355 | + pExpr->iDocid==pCsr->iPrevId && pExpr->pPhrase->doclist.pList |
| 182356 | + ))){ |
| 182301 | 182357 | Fts3Phrase *pPhrase = pExpr->pPhrase; |
| 182302 | | - assert( pExpr->bDeferred || pPhrase->doclist.bFreeList==0 ); |
| 182303 | 182358 | if( pExpr->bDeferred ){ |
| 182304 | 182359 | fts3EvalInvalidatePoslist(pPhrase); |
| 182305 | 182360 | } |
| 182306 | 182361 | *pRc = fts3EvalDeferredPhrase(pCsr, pPhrase); |
| 182307 | 182362 | bHit = (pPhrase->doclist.pList!=0); |
| | @@ -212484,15 +212539,16 @@ |
| 212484 | 212539 | */ |
| 212485 | 212540 | static int dbpageBegin(sqlite3_vtab *pVtab){ |
| 212486 | 212541 | DbpageTable *pTab = (DbpageTable *)pVtab; |
| 212487 | 212542 | sqlite3 *db = pTab->db; |
| 212488 | 212543 | int i; |
| 212489 | | - for(i=0; i<db->nDb; i++){ |
| 212544 | + int rc = SQLITE_OK; |
| 212545 | + for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ |
| 212490 | 212546 | Btree *pBt = db->aDb[i].pBt; |
| 212491 | | - if( pBt ) sqlite3BtreeBeginTrans(pBt, 1, 0); |
| 212547 | + if( pBt ) rc = sqlite3BtreeBeginTrans(pBt, 1, 0); |
| 212492 | 212548 | } |
| 212493 | | - return SQLITE_OK; |
| 212549 | + return rc; |
| 212494 | 212550 | } |
| 212495 | 212551 | |
| 212496 | 212552 | |
| 212497 | 212553 | /* |
| 212498 | 212554 | ** Invoke this routine to register the "dbpage" virtual table module |
| | @@ -236615,11 +236671,11 @@ |
| 236615 | 236671 | int nArg, /* Number of args */ |
| 236616 | 236672 | sqlite3_value **apUnused /* Function arguments */ |
| 236617 | 236673 | ){ |
| 236618 | 236674 | assert( nArg==0 ); |
| 236619 | 236675 | UNUSED_PARAM2(nArg, apUnused); |
| 236620 | | - sqlite3_result_text(pCtx, "fts5: 2022-06-25 14:57:57 14e166f40dbfa6e055543f8301525f2ca2e96a02a57269818b9e69e162e98918", -1, SQLITE_TRANSIENT); |
| 236676 | + sqlite3_result_text(pCtx, "fts5: 2022-07-18 19:32:30 22d280a5cd395abbedcfffbac3d3b3a614c327be25763ca380c1338a2a7bd33a", -1, SQLITE_TRANSIENT); |
| 236621 | 236677 | } |
| 236622 | 236678 | |
| 236623 | 236679 | /* |
| 236624 | 236680 | ** Return true if zName is the extension on one of the shadow tables used |
| 236625 | 236681 | ** by this module. |
| | @@ -241286,10 +241342,20 @@ |
| 241286 | 241342 | /* #include <assert.h> */ |
| 241287 | 241343 | /* #include <string.h> */ |
| 241288 | 241344 | |
| 241289 | 241345 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 241290 | 241346 | |
| 241347 | + |
| 241348 | +#define STMT_NUM_INTEGER_COLUMN 10 |
| 241349 | +typedef struct StmtRow StmtRow; |
| 241350 | +struct StmtRow { |
| 241351 | + sqlite3_int64 iRowid; /* Rowid value */ |
| 241352 | + char *zSql; /* column "sql" */ |
| 241353 | + int aCol[STMT_NUM_INTEGER_COLUMN+1]; /* all other column values */ |
| 241354 | + StmtRow *pNext; /* Next row to return */ |
| 241355 | +}; |
| 241356 | + |
| 241291 | 241357 | /* stmt_vtab is a subclass of sqlite3_vtab which will |
| 241292 | 241358 | ** serve as the underlying representation of a stmt virtual table |
| 241293 | 241359 | */ |
| 241294 | 241360 | typedef struct stmt_vtab stmt_vtab; |
| 241295 | 241361 | struct stmt_vtab { |
| | @@ -241303,12 +241369,11 @@ |
| 241303 | 241369 | */ |
| 241304 | 241370 | typedef struct stmt_cursor stmt_cursor; |
| 241305 | 241371 | struct stmt_cursor { |
| 241306 | 241372 | sqlite3_vtab_cursor base; /* Base class - must be first */ |
| 241307 | 241373 | sqlite3 *db; /* Database connection for this cursor */ |
| 241308 | | - sqlite3_stmt *pStmt; /* Statement cursor is currently pointing at */ |
| 241309 | | - sqlite3_int64 iRowid; /* The rowid */ |
| 241374 | + StmtRow *pRow; /* Current row */ |
| 241310 | 241375 | }; |
| 241311 | 241376 | |
| 241312 | 241377 | /* |
| 241313 | 241378 | ** The stmtConnect() method is invoked to create a new |
| 241314 | 241379 | ** stmt_vtab that describes the stmt virtual table. |
| | @@ -241348,11 +241413,11 @@ |
| 241348 | 241413 | |
| 241349 | 241414 | rc = sqlite3_declare_vtab(db, |
| 241350 | 241415 | "CREATE TABLE x(sql,ncol,ro,busy,nscan,nsort,naidx,nstep," |
| 241351 | 241416 | "reprep,run,mem)"); |
| 241352 | 241417 | if( rc==SQLITE_OK ){ |
| 241353 | | - pNew = sqlite3_malloc( sizeof(*pNew) ); |
| 241418 | + pNew = sqlite3_malloc64( sizeof(*pNew) ); |
| 241354 | 241419 | *ppVtab = (sqlite3_vtab*)pNew; |
| 241355 | 241420 | if( pNew==0 ) return SQLITE_NOMEM; |
| 241356 | 241421 | memset(pNew, 0, sizeof(*pNew)); |
| 241357 | 241422 | pNew->db = db; |
| 241358 | 241423 | } |
| | @@ -241370,22 +241435,33 @@ |
| 241370 | 241435 | /* |
| 241371 | 241436 | ** Constructor for a new stmt_cursor object. |
| 241372 | 241437 | */ |
| 241373 | 241438 | static int stmtOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ |
| 241374 | 241439 | stmt_cursor *pCur; |
| 241375 | | - pCur = sqlite3_malloc( sizeof(*pCur) ); |
| 241440 | + pCur = sqlite3_malloc64( sizeof(*pCur) ); |
| 241376 | 241441 | if( pCur==0 ) return SQLITE_NOMEM; |
| 241377 | 241442 | memset(pCur, 0, sizeof(*pCur)); |
| 241378 | 241443 | pCur->db = ((stmt_vtab*)p)->db; |
| 241379 | 241444 | *ppCursor = &pCur->base; |
| 241380 | 241445 | return SQLITE_OK; |
| 241381 | 241446 | } |
| 241447 | + |
| 241448 | +static void stmtCsrReset(stmt_cursor *pCur){ |
| 241449 | + StmtRow *pRow = 0; |
| 241450 | + StmtRow *pNext = 0; |
| 241451 | + for(pRow=pCur->pRow; pRow; pRow=pNext){ |
| 241452 | + pNext = pRow->pNext; |
| 241453 | + sqlite3_free(pRow); |
| 241454 | + } |
| 241455 | + pCur->pRow = 0; |
| 241456 | +} |
| 241382 | 241457 | |
| 241383 | 241458 | /* |
| 241384 | 241459 | ** Destructor for a stmt_cursor. |
| 241385 | 241460 | */ |
| 241386 | 241461 | static int stmtClose(sqlite3_vtab_cursor *cur){ |
| 241462 | + stmtCsrReset((stmt_cursor*)cur); |
| 241387 | 241463 | sqlite3_free(cur); |
| 241388 | 241464 | return SQLITE_OK; |
| 241389 | 241465 | } |
| 241390 | 241466 | |
| 241391 | 241467 | |
| | @@ -241392,12 +241468,13 @@ |
| 241392 | 241468 | /* |
| 241393 | 241469 | ** Advance a stmt_cursor to its next row of output. |
| 241394 | 241470 | */ |
| 241395 | 241471 | static int stmtNext(sqlite3_vtab_cursor *cur){ |
| 241396 | 241472 | stmt_cursor *pCur = (stmt_cursor*)cur; |
| 241397 | | - pCur->iRowid++; |
| 241398 | | - pCur->pStmt = sqlite3_next_stmt(pCur->db, pCur->pStmt); |
| 241473 | + StmtRow *pNext = pCur->pRow->pNext; |
| 241474 | + sqlite3_free(pCur->pRow); |
| 241475 | + pCur->pRow = pNext; |
| 241399 | 241476 | return SQLITE_OK; |
| 241400 | 241477 | } |
| 241401 | 241478 | |
| 241402 | 241479 | /* |
| 241403 | 241480 | ** Return values of columns for the row at which the stmt_cursor |
| | @@ -241407,43 +241484,15 @@ |
| 241407 | 241484 | sqlite3_vtab_cursor *cur, /* The cursor */ |
| 241408 | 241485 | sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ |
| 241409 | 241486 | int i /* Which column to return */ |
| 241410 | 241487 | ){ |
| 241411 | 241488 | stmt_cursor *pCur = (stmt_cursor*)cur; |
| 241412 | | - switch( i ){ |
| 241413 | | - case STMT_COLUMN_SQL: { |
| 241414 | | - sqlite3_result_text(ctx, sqlite3_sql(pCur->pStmt), -1, SQLITE_TRANSIENT); |
| 241415 | | - break; |
| 241416 | | - } |
| 241417 | | - case STMT_COLUMN_NCOL: { |
| 241418 | | - sqlite3_result_int(ctx, sqlite3_column_count(pCur->pStmt)); |
| 241419 | | - break; |
| 241420 | | - } |
| 241421 | | - case STMT_COLUMN_RO: { |
| 241422 | | - sqlite3_result_int(ctx, sqlite3_stmt_readonly(pCur->pStmt)); |
| 241423 | | - break; |
| 241424 | | - } |
| 241425 | | - case STMT_COLUMN_BUSY: { |
| 241426 | | - sqlite3_result_int(ctx, sqlite3_stmt_busy(pCur->pStmt)); |
| 241427 | | - break; |
| 241428 | | - } |
| 241429 | | - default: { |
| 241430 | | - assert( i==STMT_COLUMN_MEM ); |
| 241431 | | - i = SQLITE_STMTSTATUS_MEMUSED + |
| 241432 | | - STMT_COLUMN_NSCAN - SQLITE_STMTSTATUS_FULLSCAN_STEP; |
| 241433 | | - /* Fall thru */ |
| 241434 | | - } |
| 241435 | | - case STMT_COLUMN_NSCAN: |
| 241436 | | - case STMT_COLUMN_NSORT: |
| 241437 | | - case STMT_COLUMN_NAIDX: |
| 241438 | | - case STMT_COLUMN_NSTEP: |
| 241439 | | - case STMT_COLUMN_REPREP: |
| 241440 | | - case STMT_COLUMN_RUN: { |
| 241441 | | - sqlite3_result_int(ctx, sqlite3_stmt_status(pCur->pStmt, |
| 241442 | | - i-STMT_COLUMN_NSCAN+SQLITE_STMTSTATUS_FULLSCAN_STEP, 0)); |
| 241443 | | - break; |
| 241444 | | - } |
| 241489 | + StmtRow *pRow = pCur->pRow; |
| 241490 | + if( i==STMT_COLUMN_SQL ){ |
| 241491 | + sqlite3_result_text(ctx, pRow->zSql, -1, SQLITE_TRANSIENT); |
| 241492 | + }else{ |
| 241493 | + sqlite3_result_int(ctx, pRow->aCol[i]); |
| 241445 | 241494 | } |
| 241446 | 241495 | return SQLITE_OK; |
| 241447 | 241496 | } |
| 241448 | 241497 | |
| 241449 | 241498 | /* |
| | @@ -241450,21 +241499,21 @@ |
| 241450 | 241499 | ** Return the rowid for the current row. In this implementation, the |
| 241451 | 241500 | ** rowid is the same as the output value. |
| 241452 | 241501 | */ |
| 241453 | 241502 | static int stmtRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ |
| 241454 | 241503 | stmt_cursor *pCur = (stmt_cursor*)cur; |
| 241455 | | - *pRowid = pCur->iRowid; |
| 241504 | + *pRowid = pCur->pRow->iRowid; |
| 241456 | 241505 | return SQLITE_OK; |
| 241457 | 241506 | } |
| 241458 | 241507 | |
| 241459 | 241508 | /* |
| 241460 | 241509 | ** Return TRUE if the cursor has been moved off of the last |
| 241461 | 241510 | ** row of output. |
| 241462 | 241511 | */ |
| 241463 | 241512 | static int stmtEof(sqlite3_vtab_cursor *cur){ |
| 241464 | 241513 | stmt_cursor *pCur = (stmt_cursor*)cur; |
| 241465 | | - return pCur->pStmt==0; |
| 241514 | + return pCur->pRow==0; |
| 241466 | 241515 | } |
| 241467 | 241516 | |
| 241468 | 241517 | /* |
| 241469 | 241518 | ** This method is called to "rewind" the stmt_cursor object back |
| 241470 | 241519 | ** to the first row of output. This method is always called at least |
| | @@ -241475,13 +241524,57 @@ |
| 241475 | 241524 | sqlite3_vtab_cursor *pVtabCursor, |
| 241476 | 241525 | int idxNum, const char *idxStr, |
| 241477 | 241526 | int argc, sqlite3_value **argv |
| 241478 | 241527 | ){ |
| 241479 | 241528 | stmt_cursor *pCur = (stmt_cursor *)pVtabCursor; |
| 241480 | | - pCur->pStmt = 0; |
| 241481 | | - pCur->iRowid = 0; |
| 241482 | | - return stmtNext(pVtabCursor); |
| 241529 | + sqlite3_stmt *p = 0; |
| 241530 | + sqlite3_int64 iRowid = 1; |
| 241531 | + StmtRow **ppRow = 0; |
| 241532 | + |
| 241533 | + stmtCsrReset(pCur); |
| 241534 | + ppRow = &pCur->pRow; |
| 241535 | + for(p=sqlite3_next_stmt(pCur->db, 0); p; p=sqlite3_next_stmt(pCur->db, p)){ |
| 241536 | + const char *zSql = sqlite3_sql(p); |
| 241537 | + sqlite3_int64 nSql = zSql ? strlen(zSql)+1 : 0; |
| 241538 | + StmtRow *pNew = (StmtRow*)sqlite3_malloc64(sizeof(StmtRow) + nSql); |
| 241539 | + |
| 241540 | + if( pNew==0 ) return SQLITE_NOMEM; |
| 241541 | + memset(pNew, 0, sizeof(StmtRow)); |
| 241542 | + if( zSql ){ |
| 241543 | + pNew->zSql = (char*)&pNew[1]; |
| 241544 | + memcpy(pNew->zSql, zSql, nSql); |
| 241545 | + } |
| 241546 | + pNew->aCol[STMT_COLUMN_NCOL] = sqlite3_column_count(p); |
| 241547 | + pNew->aCol[STMT_COLUMN_RO] = sqlite3_stmt_readonly(p); |
| 241548 | + pNew->aCol[STMT_COLUMN_BUSY] = sqlite3_stmt_busy(p); |
| 241549 | + pNew->aCol[STMT_COLUMN_NSCAN] = sqlite3_stmt_status( |
| 241550 | + p, SQLITE_STMTSTATUS_FULLSCAN_STEP, 0 |
| 241551 | + ); |
| 241552 | + pNew->aCol[STMT_COLUMN_NSORT] = sqlite3_stmt_status( |
| 241553 | + p, SQLITE_STMTSTATUS_SORT, 0 |
| 241554 | + ); |
| 241555 | + pNew->aCol[STMT_COLUMN_NAIDX] = sqlite3_stmt_status( |
| 241556 | + p, SQLITE_STMTSTATUS_AUTOINDEX, 0 |
| 241557 | + ); |
| 241558 | + pNew->aCol[STMT_COLUMN_NSTEP] = sqlite3_stmt_status( |
| 241559 | + p, SQLITE_STMTSTATUS_VM_STEP, 0 |
| 241560 | + ); |
| 241561 | + pNew->aCol[STMT_COLUMN_REPREP] = sqlite3_stmt_status( |
| 241562 | + p, SQLITE_STMTSTATUS_REPREPARE, 0 |
| 241563 | + ); |
| 241564 | + pNew->aCol[STMT_COLUMN_RUN] = sqlite3_stmt_status( |
| 241565 | + p, SQLITE_STMTSTATUS_RUN, 0 |
| 241566 | + ); |
| 241567 | + pNew->aCol[STMT_COLUMN_MEM] = sqlite3_stmt_status( |
| 241568 | + p, SQLITE_STMTSTATUS_MEMUSED, 0 |
| 241569 | + ); |
| 241570 | + pNew->iRowid = iRowid++; |
| 241571 | + *ppRow = pNew; |
| 241572 | + ppRow = &pNew->pNext; |
| 241573 | + } |
| 241574 | + |
| 241575 | + return SQLITE_OK; |
| 241483 | 241576 | } |
| 241484 | 241577 | |
| 241485 | 241578 | /* |
| 241486 | 241579 | ** SQLite will invoke this method one or more times while planning a query |
| 241487 | 241580 | ** that uses the stmt virtual table. This routine needs to create |
| 241488 | 241581 | |