| | @@ -16,11 +16,11 @@ |
| 16 | 16 | ** if you want a wrapper to interface SQLite with your choice of programming |
| 17 | 17 | ** language. The code for the "sqlite3" command-line shell is also in a |
| 18 | 18 | ** separate file. This file contains only code for the core SQLite library. |
| 19 | 19 | ** |
| 20 | 20 | ** The content in this amalgamation comes from Fossil check-in |
| 21 | | -** 0083d5169a46104a25355bdd9d5a2f4027b0 with changes in files: |
| 21 | +** 720387f8604f7cd997f1850ed62ce6ab3260 with changes in files: |
| 22 | 22 | ** |
| 23 | 23 | ** |
| 24 | 24 | */ |
| 25 | 25 | #ifndef SQLITE_AMALGAMATION |
| 26 | 26 | #define SQLITE_CORE 1 |
| | @@ -465,11 +465,11 @@ |
| 465 | 465 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 466 | 466 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 467 | 467 | */ |
| 468 | 468 | #define SQLITE_VERSION "3.51.0" |
| 469 | 469 | #define SQLITE_VERSION_NUMBER 3051000 |
| 470 | | -#define SQLITE_SOURCE_ID "2025-06-30 16:41:40 0083d5169a46104a25355bdd9d5a2f4027b049191ebda571dd228477ec217296" |
| 470 | +#define SQLITE_SOURCE_ID "2025-07-08 20:28:35 720387f8604f7cd997f1850ed62ce6ab32608155d7f02a89c695041caafc4067" |
| 471 | 471 | |
| 472 | 472 | /* |
| 473 | 473 | ** CAPI3REF: Run-Time Library Version Numbers |
| 474 | 474 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 475 | 475 | ** |
| | @@ -15565,10 +15565,11 @@ |
| 15565 | 15565 | ** 0x00010000 Beginning of DELETE/INSERT/UPDATE processing |
| 15566 | 15566 | ** 0x00020000 Transform DISTINCT into GROUP BY |
| 15567 | 15567 | ** 0x00040000 SELECT tree dump after all code has been generated |
| 15568 | 15568 | ** 0x00080000 NOT NULL strength reduction |
| 15569 | 15569 | ** 0x00100000 Pointers are all shown as zero |
| 15570 | +** 0x00200000 EXISTS-to-JOIN optimization |
| 15570 | 15571 | */ |
| 15571 | 15572 | |
| 15572 | 15573 | /* |
| 15573 | 15574 | ** Macros for "wheretrace" |
| 15574 | 15575 | */ |
| | @@ -16750,10 +16751,11 @@ |
| 16750 | 16751 | }; |
| 16751 | 16752 | |
| 16752 | 16753 | SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload, |
| 16753 | 16754 | int flags, int seekResult); |
| 16754 | 16755 | SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor*, int *pRes); |
| 16756 | +SQLITE_PRIVATE int sqlite3BtreeIsEmpty(BtCursor *pCur, int *pRes); |
| 16755 | 16757 | SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor*, int *pRes); |
| 16756 | 16758 | SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int flags); |
| 16757 | 16759 | SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*); |
| 16758 | 16760 | SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int flags); |
| 16759 | 16761 | SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor*); |
| | @@ -17083,76 +17085,76 @@ |
| 17083 | 17085 | #define OP_Last 32 /* jump0 */ |
| 17084 | 17086 | #define OP_IfSizeBetween 33 /* jump */ |
| 17085 | 17087 | #define OP_SorterSort 34 /* jump */ |
| 17086 | 17088 | #define OP_Sort 35 /* jump */ |
| 17087 | 17089 | #define OP_Rewind 36 /* jump0 */ |
| 17088 | | -#define OP_SorterNext 37 /* jump */ |
| 17089 | | -#define OP_Prev 38 /* jump */ |
| 17090 | | -#define OP_Next 39 /* jump */ |
| 17091 | | -#define OP_IdxLE 40 /* jump, synopsis: key=r[P3@P4] */ |
| 17092 | | -#define OP_IdxGT 41 /* jump, synopsis: key=r[P3@P4] */ |
| 17093 | | -#define OP_IdxLT 42 /* jump, synopsis: key=r[P3@P4] */ |
| 17090 | +#define OP_IfEmpty 37 /* jump, synopsis: if( empty(P1) ) goto P2 */ |
| 17091 | +#define OP_SorterNext 38 /* jump */ |
| 17092 | +#define OP_Prev 39 /* jump */ |
| 17093 | +#define OP_Next 40 /* jump */ |
| 17094 | +#define OP_IdxLE 41 /* jump, synopsis: key=r[P3@P4] */ |
| 17095 | +#define OP_IdxGT 42 /* jump, synopsis: key=r[P3@P4] */ |
| 17094 | 17096 | #define OP_Or 43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ |
| 17095 | 17097 | #define OP_And 44 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ |
| 17096 | | -#define OP_IdxGE 45 /* jump, synopsis: key=r[P3@P4] */ |
| 17097 | | -#define OP_RowSetRead 46 /* jump, synopsis: r[P3]=rowset(P1) */ |
| 17098 | | -#define OP_RowSetTest 47 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ |
| 17099 | | -#define OP_Program 48 /* jump0 */ |
| 17100 | | -#define OP_FkIfZero 49 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ |
| 17101 | | -#define OP_IfPos 50 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ |
| 17098 | +#define OP_IdxLT 45 /* jump, synopsis: key=r[P3@P4] */ |
| 17099 | +#define OP_IdxGE 46 /* jump, synopsis: key=r[P3@P4] */ |
| 17100 | +#define OP_RowSetRead 47 /* jump, synopsis: r[P3]=rowset(P1) */ |
| 17101 | +#define OP_RowSetTest 48 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ |
| 17102 | +#define OP_Program 49 /* jump0 */ |
| 17103 | +#define OP_FkIfZero 50 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ |
| 17102 | 17104 | #define OP_IsNull 51 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ |
| 17103 | 17105 | #define OP_NotNull 52 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ |
| 17104 | 17106 | #define OP_Ne 53 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */ |
| 17105 | 17107 | #define OP_Eq 54 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */ |
| 17106 | 17108 | #define OP_Gt 55 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */ |
| 17107 | 17109 | #define OP_Le 56 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */ |
| 17108 | 17110 | #define OP_Lt 57 /* jump, same as TK_LT, synopsis: IF r[P3]<r[P1] */ |
| 17109 | 17111 | #define OP_Ge 58 /* jump, same as TK_GE, synopsis: IF r[P3]>=r[P1] */ |
| 17110 | 17112 | #define OP_ElseEq 59 /* jump, same as TK_ESCAPE */ |
| 17111 | | -#define OP_IfNotZero 60 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ |
| 17112 | | -#define OP_DecrJumpZero 61 /* jump, synopsis: if (--r[P1])==0 goto P2 */ |
| 17113 | | -#define OP_IncrVacuum 62 /* jump */ |
| 17114 | | -#define OP_VNext 63 /* jump */ |
| 17115 | | -#define OP_Filter 64 /* jump, synopsis: if key(P3@P4) not in filter(P1) goto P2 */ |
| 17116 | | -#define OP_PureFunc 65 /* synopsis: r[P3]=func(r[P2@NP]) */ |
| 17117 | | -#define OP_Function 66 /* synopsis: r[P3]=func(r[P2@NP]) */ |
| 17118 | | -#define OP_Return 67 |
| 17119 | | -#define OP_EndCoroutine 68 |
| 17120 | | -#define OP_HaltIfNull 69 /* synopsis: if r[P3]=null halt */ |
| 17121 | | -#define OP_Halt 70 |
| 17122 | | -#define OP_Integer 71 /* synopsis: r[P2]=P1 */ |
| 17123 | | -#define OP_Int64 72 /* synopsis: r[P2]=P4 */ |
| 17124 | | -#define OP_String 73 /* synopsis: r[P2]='P4' (len=P1) */ |
| 17125 | | -#define OP_BeginSubrtn 74 /* synopsis: r[P2]=NULL */ |
| 17126 | | -#define OP_Null 75 /* synopsis: r[P2..P3]=NULL */ |
| 17127 | | -#define OP_SoftNull 76 /* synopsis: r[P1]=NULL */ |
| 17128 | | -#define OP_Blob 77 /* synopsis: r[P2]=P4 (len=P1) */ |
| 17129 | | -#define OP_Variable 78 /* synopsis: r[P2]=parameter(P1) */ |
| 17130 | | -#define OP_Move 79 /* synopsis: r[P2@P3]=r[P1@P3] */ |
| 17131 | | -#define OP_Copy 80 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ |
| 17132 | | -#define OP_SCopy 81 /* synopsis: r[P2]=r[P1] */ |
| 17133 | | -#define OP_IntCopy 82 /* synopsis: r[P2]=r[P1] */ |
| 17134 | | -#define OP_FkCheck 83 |
| 17135 | | -#define OP_ResultRow 84 /* synopsis: output=r[P1@P2] */ |
| 17136 | | -#define OP_CollSeq 85 |
| 17137 | | -#define OP_AddImm 86 /* synopsis: r[P1]=r[P1]+P2 */ |
| 17138 | | -#define OP_RealAffinity 87 |
| 17139 | | -#define OP_Cast 88 /* synopsis: affinity(r[P1]) */ |
| 17140 | | -#define OP_Permutation 89 |
| 17141 | | -#define OP_Compare 90 /* synopsis: r[P1@P3] <-> r[P2@P3] */ |
| 17142 | | -#define OP_IsTrue 91 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */ |
| 17143 | | -#define OP_ZeroOrNull 92 /* synopsis: r[P2] = 0 OR NULL */ |
| 17144 | | -#define OP_Offset 93 /* synopsis: r[P3] = sqlite_offset(P1) */ |
| 17145 | | -#define OP_Column 94 /* synopsis: r[P3]=PX cursor P1 column P2 */ |
| 17146 | | -#define OP_TypeCheck 95 /* synopsis: typecheck(r[P1@P2]) */ |
| 17147 | | -#define OP_Affinity 96 /* synopsis: affinity(r[P1@P2]) */ |
| 17148 | | -#define OP_MakeRecord 97 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ |
| 17149 | | -#define OP_Count 98 /* synopsis: r[P2]=count() */ |
| 17150 | | -#define OP_ReadCookie 99 |
| 17151 | | -#define OP_SetCookie 100 |
| 17152 | | -#define OP_ReopenIdx 101 /* synopsis: root=P2 iDb=P3 */ |
| 17153 | | -#define OP_OpenRead 102 /* synopsis: root=P2 iDb=P3 */ |
| 17113 | +#define OP_IfPos 60 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ |
| 17114 | +#define OP_IfNotZero 61 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ |
| 17115 | +#define OP_DecrJumpZero 62 /* jump, synopsis: if (--r[P1])==0 goto P2 */ |
| 17116 | +#define OP_IncrVacuum 63 /* jump */ |
| 17117 | +#define OP_VNext 64 /* jump */ |
| 17118 | +#define OP_Filter 65 /* jump, synopsis: if key(P3@P4) not in filter(P1) goto P2 */ |
| 17119 | +#define OP_PureFunc 66 /* synopsis: r[P3]=func(r[P2@NP]) */ |
| 17120 | +#define OP_Function 67 /* synopsis: r[P3]=func(r[P2@NP]) */ |
| 17121 | +#define OP_Return 68 |
| 17122 | +#define OP_EndCoroutine 69 |
| 17123 | +#define OP_HaltIfNull 70 /* synopsis: if r[P3]=null halt */ |
| 17124 | +#define OP_Halt 71 |
| 17125 | +#define OP_Integer 72 /* synopsis: r[P2]=P1 */ |
| 17126 | +#define OP_Int64 73 /* synopsis: r[P2]=P4 */ |
| 17127 | +#define OP_String 74 /* synopsis: r[P2]='P4' (len=P1) */ |
| 17128 | +#define OP_BeginSubrtn 75 /* synopsis: r[P2]=NULL */ |
| 17129 | +#define OP_Null 76 /* synopsis: r[P2..P3]=NULL */ |
| 17130 | +#define OP_SoftNull 77 /* synopsis: r[P1]=NULL */ |
| 17131 | +#define OP_Blob 78 /* synopsis: r[P2]=P4 (len=P1) */ |
| 17132 | +#define OP_Variable 79 /* synopsis: r[P2]=parameter(P1) */ |
| 17133 | +#define OP_Move 80 /* synopsis: r[P2@P3]=r[P1@P3] */ |
| 17134 | +#define OP_Copy 81 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ |
| 17135 | +#define OP_SCopy 82 /* synopsis: r[P2]=r[P1] */ |
| 17136 | +#define OP_IntCopy 83 /* synopsis: r[P2]=r[P1] */ |
| 17137 | +#define OP_FkCheck 84 |
| 17138 | +#define OP_ResultRow 85 /* synopsis: output=r[P1@P2] */ |
| 17139 | +#define OP_CollSeq 86 |
| 17140 | +#define OP_AddImm 87 /* synopsis: r[P1]=r[P1]+P2 */ |
| 17141 | +#define OP_RealAffinity 88 |
| 17142 | +#define OP_Cast 89 /* synopsis: affinity(r[P1]) */ |
| 17143 | +#define OP_Permutation 90 |
| 17144 | +#define OP_Compare 91 /* synopsis: r[P1@P3] <-> r[P2@P3] */ |
| 17145 | +#define OP_IsTrue 92 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */ |
| 17146 | +#define OP_ZeroOrNull 93 /* synopsis: r[P2] = 0 OR NULL */ |
| 17147 | +#define OP_Offset 94 /* synopsis: r[P3] = sqlite_offset(P1) */ |
| 17148 | +#define OP_Column 95 /* synopsis: r[P3]=PX cursor P1 column P2 */ |
| 17149 | +#define OP_TypeCheck 96 /* synopsis: typecheck(r[P1@P2]) */ |
| 17150 | +#define OP_Affinity 97 /* synopsis: affinity(r[P1@P2]) */ |
| 17151 | +#define OP_MakeRecord 98 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ |
| 17152 | +#define OP_Count 99 /* synopsis: r[P2]=count() */ |
| 17153 | +#define OP_ReadCookie 100 |
| 17154 | +#define OP_SetCookie 101 |
| 17155 | +#define OP_ReopenIdx 102 /* synopsis: root=P2 iDb=P3 */ |
| 17154 | 17156 | #define OP_BitAnd 103 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ |
| 17155 | 17157 | #define OP_BitOr 104 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ |
| 17156 | 17158 | #define OP_ShiftLeft 105 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */ |
| 17157 | 17159 | #define OP_ShiftRight 106 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */ |
| 17158 | 17160 | #define OP_Add 107 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ |
| | @@ -17159,87 +17161,88 @@ |
| 17159 | 17161 | #define OP_Subtract 108 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ |
| 17160 | 17162 | #define OP_Multiply 109 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ |
| 17161 | 17163 | #define OP_Divide 110 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ |
| 17162 | 17164 | #define OP_Remainder 111 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ |
| 17163 | 17165 | #define OP_Concat 112 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ |
| 17164 | | -#define OP_OpenWrite 113 /* synopsis: root=P2 iDb=P3 */ |
| 17165 | | -#define OP_OpenDup 114 |
| 17166 | +#define OP_OpenRead 113 /* synopsis: root=P2 iDb=P3 */ |
| 17167 | +#define OP_OpenWrite 114 /* synopsis: root=P2 iDb=P3 */ |
| 17166 | 17168 | #define OP_BitNot 115 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */ |
| 17167 | | -#define OP_OpenAutoindex 116 /* synopsis: nColumn=P2 */ |
| 17168 | | -#define OP_OpenEphemeral 117 /* synopsis: nColumn=P2 */ |
| 17169 | +#define OP_OpenDup 116 |
| 17170 | +#define OP_OpenAutoindex 117 /* synopsis: nColumn=P2 */ |
| 17169 | 17171 | #define OP_String8 118 /* same as TK_STRING, synopsis: r[P2]='P4' */ |
| 17170 | | -#define OP_SorterOpen 119 |
| 17171 | | -#define OP_SequenceTest 120 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ |
| 17172 | | -#define OP_OpenPseudo 121 /* synopsis: P3 columns in r[P2] */ |
| 17173 | | -#define OP_Close 122 |
| 17174 | | -#define OP_ColumnsUsed 123 |
| 17175 | | -#define OP_SeekScan 124 /* synopsis: Scan-ahead up to P1 rows */ |
| 17176 | | -#define OP_SeekHit 125 /* synopsis: set P2<=seekHit<=P3 */ |
| 17177 | | -#define OP_Sequence 126 /* synopsis: r[P2]=cursor[P1].ctr++ */ |
| 17178 | | -#define OP_NewRowid 127 /* synopsis: r[P2]=rowid */ |
| 17179 | | -#define OP_Insert 128 /* synopsis: intkey=r[P3] data=r[P2] */ |
| 17180 | | -#define OP_RowCell 129 |
| 17181 | | -#define OP_Delete 130 |
| 17182 | | -#define OP_ResetCount 131 |
| 17183 | | -#define OP_SorterCompare 132 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ |
| 17184 | | -#define OP_SorterData 133 /* synopsis: r[P2]=data */ |
| 17185 | | -#define OP_RowData 134 /* synopsis: r[P2]=data */ |
| 17186 | | -#define OP_Rowid 135 /* synopsis: r[P2]=PX rowid of P1 */ |
| 17187 | | -#define OP_NullRow 136 |
| 17188 | | -#define OP_SeekEnd 137 |
| 17189 | | -#define OP_IdxInsert 138 /* synopsis: key=r[P2] */ |
| 17190 | | -#define OP_SorterInsert 139 /* synopsis: key=r[P2] */ |
| 17191 | | -#define OP_IdxDelete 140 /* synopsis: key=r[P2@P3] */ |
| 17192 | | -#define OP_DeferredSeek 141 /* synopsis: Move P3 to P1.rowid if needed */ |
| 17193 | | -#define OP_IdxRowid 142 /* synopsis: r[P2]=rowid */ |
| 17194 | | -#define OP_FinishSeek 143 |
| 17195 | | -#define OP_Destroy 144 |
| 17196 | | -#define OP_Clear 145 |
| 17197 | | -#define OP_ResetSorter 146 |
| 17198 | | -#define OP_CreateBtree 147 /* synopsis: r[P2]=root iDb=P1 flags=P3 */ |
| 17199 | | -#define OP_SqlExec 148 |
| 17200 | | -#define OP_ParseSchema 149 |
| 17201 | | -#define OP_LoadAnalysis 150 |
| 17202 | | -#define OP_DropTable 151 |
| 17203 | | -#define OP_DropIndex 152 |
| 17204 | | -#define OP_DropTrigger 153 |
| 17172 | +#define OP_OpenEphemeral 119 /* synopsis: nColumn=P2 */ |
| 17173 | +#define OP_SorterOpen 120 |
| 17174 | +#define OP_SequenceTest 121 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ |
| 17175 | +#define OP_OpenPseudo 122 /* synopsis: P3 columns in r[P2] */ |
| 17176 | +#define OP_Close 123 |
| 17177 | +#define OP_ColumnsUsed 124 |
| 17178 | +#define OP_SeekScan 125 /* synopsis: Scan-ahead up to P1 rows */ |
| 17179 | +#define OP_SeekHit 126 /* synopsis: set P2<=seekHit<=P3 */ |
| 17180 | +#define OP_Sequence 127 /* synopsis: r[P2]=cursor[P1].ctr++ */ |
| 17181 | +#define OP_NewRowid 128 /* synopsis: r[P2]=rowid */ |
| 17182 | +#define OP_Insert 129 /* synopsis: intkey=r[P3] data=r[P2] */ |
| 17183 | +#define OP_RowCell 130 |
| 17184 | +#define OP_Delete 131 |
| 17185 | +#define OP_ResetCount 132 |
| 17186 | +#define OP_SorterCompare 133 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ |
| 17187 | +#define OP_SorterData 134 /* synopsis: r[P2]=data */ |
| 17188 | +#define OP_RowData 135 /* synopsis: r[P2]=data */ |
| 17189 | +#define OP_Rowid 136 /* synopsis: r[P2]=PX rowid of P1 */ |
| 17190 | +#define OP_NullRow 137 |
| 17191 | +#define OP_SeekEnd 138 |
| 17192 | +#define OP_IdxInsert 139 /* synopsis: key=r[P2] */ |
| 17193 | +#define OP_SorterInsert 140 /* synopsis: key=r[P2] */ |
| 17194 | +#define OP_IdxDelete 141 /* synopsis: key=r[P2@P3] */ |
| 17195 | +#define OP_DeferredSeek 142 /* synopsis: Move P3 to P1.rowid if needed */ |
| 17196 | +#define OP_IdxRowid 143 /* synopsis: r[P2]=rowid */ |
| 17197 | +#define OP_FinishSeek 144 |
| 17198 | +#define OP_Destroy 145 |
| 17199 | +#define OP_Clear 146 |
| 17200 | +#define OP_ResetSorter 147 |
| 17201 | +#define OP_CreateBtree 148 /* synopsis: r[P2]=root iDb=P1 flags=P3 */ |
| 17202 | +#define OP_SqlExec 149 |
| 17203 | +#define OP_ParseSchema 150 |
| 17204 | +#define OP_LoadAnalysis 151 |
| 17205 | +#define OP_DropTable 152 |
| 17206 | +#define OP_DropIndex 153 |
| 17205 | 17207 | #define OP_Real 154 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ |
| 17206 | | -#define OP_IntegrityCk 155 |
| 17207 | | -#define OP_RowSetAdd 156 /* synopsis: rowset(P1)=r[P2] */ |
| 17208 | | -#define OP_Param 157 |
| 17209 | | -#define OP_FkCounter 158 /* synopsis: fkctr[P1]+=P2 */ |
| 17210 | | -#define OP_MemMax 159 /* synopsis: r[P1]=max(r[P1],r[P2]) */ |
| 17211 | | -#define OP_OffsetLimit 160 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ |
| 17212 | | -#define OP_AggInverse 161 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */ |
| 17213 | | -#define OP_AggStep 162 /* synopsis: accum=r[P3] step(r[P2@P5]) */ |
| 17214 | | -#define OP_AggStep1 163 /* synopsis: accum=r[P3] step(r[P2@P5]) */ |
| 17215 | | -#define OP_AggValue 164 /* synopsis: r[P3]=value N=P2 */ |
| 17216 | | -#define OP_AggFinal 165 /* synopsis: accum=r[P1] N=P2 */ |
| 17217 | | -#define OP_Expire 166 |
| 17218 | | -#define OP_CursorLock 167 |
| 17219 | | -#define OP_CursorUnlock 168 |
| 17220 | | -#define OP_TableLock 169 /* synopsis: iDb=P1 root=P2 write=P3 */ |
| 17221 | | -#define OP_VBegin 170 |
| 17222 | | -#define OP_VCreate 171 |
| 17223 | | -#define OP_VDestroy 172 |
| 17224 | | -#define OP_VOpen 173 |
| 17225 | | -#define OP_VCheck 174 |
| 17226 | | -#define OP_VInitIn 175 /* synopsis: r[P2]=ValueList(P1,P3) */ |
| 17227 | | -#define OP_VColumn 176 /* synopsis: r[P3]=vcolumn(P2) */ |
| 17228 | | -#define OP_VRename 177 |
| 17229 | | -#define OP_Pagecount 178 |
| 17230 | | -#define OP_MaxPgcnt 179 |
| 17231 | | -#define OP_ClrSubtype 180 /* synopsis: r[P1].subtype = 0 */ |
| 17232 | | -#define OP_GetSubtype 181 /* synopsis: r[P2] = r[P1].subtype */ |
| 17233 | | -#define OP_SetSubtype 182 /* synopsis: r[P2].subtype = r[P1] */ |
| 17234 | | -#define OP_FilterAdd 183 /* synopsis: filter(P1) += key(P3@P4) */ |
| 17235 | | -#define OP_Trace 184 |
| 17236 | | -#define OP_CursorHint 185 |
| 17237 | | -#define OP_ReleaseReg 186 /* synopsis: release r[P1@P2] mask P3 */ |
| 17238 | | -#define OP_Noop 187 |
| 17239 | | -#define OP_Explain 188 |
| 17240 | | -#define OP_Abortable 189 |
| 17208 | +#define OP_DropTrigger 155 |
| 17209 | +#define OP_IntegrityCk 156 |
| 17210 | +#define OP_RowSetAdd 157 /* synopsis: rowset(P1)=r[P2] */ |
| 17211 | +#define OP_Param 158 |
| 17212 | +#define OP_FkCounter 159 /* synopsis: fkctr[P1]+=P2 */ |
| 17213 | +#define OP_MemMax 160 /* synopsis: r[P1]=max(r[P1],r[P2]) */ |
| 17214 | +#define OP_OffsetLimit 161 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ |
| 17215 | +#define OP_AggInverse 162 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */ |
| 17216 | +#define OP_AggStep 163 /* synopsis: accum=r[P3] step(r[P2@P5]) */ |
| 17217 | +#define OP_AggStep1 164 /* synopsis: accum=r[P3] step(r[P2@P5]) */ |
| 17218 | +#define OP_AggValue 165 /* synopsis: r[P3]=value N=P2 */ |
| 17219 | +#define OP_AggFinal 166 /* synopsis: accum=r[P1] N=P2 */ |
| 17220 | +#define OP_Expire 167 |
| 17221 | +#define OP_CursorLock 168 |
| 17222 | +#define OP_CursorUnlock 169 |
| 17223 | +#define OP_TableLock 170 /* synopsis: iDb=P1 root=P2 write=P3 */ |
| 17224 | +#define OP_VBegin 171 |
| 17225 | +#define OP_VCreate 172 |
| 17226 | +#define OP_VDestroy 173 |
| 17227 | +#define OP_VOpen 174 |
| 17228 | +#define OP_VCheck 175 |
| 17229 | +#define OP_VInitIn 176 /* synopsis: r[P2]=ValueList(P1,P3) */ |
| 17230 | +#define OP_VColumn 177 /* synopsis: r[P3]=vcolumn(P2) */ |
| 17231 | +#define OP_VRename 178 |
| 17232 | +#define OP_Pagecount 179 |
| 17233 | +#define OP_MaxPgcnt 180 |
| 17234 | +#define OP_ClrSubtype 181 /* synopsis: r[P1].subtype = 0 */ |
| 17235 | +#define OP_GetSubtype 182 /* synopsis: r[P2] = r[P1].subtype */ |
| 17236 | +#define OP_SetSubtype 183 /* synopsis: r[P2].subtype = r[P1] */ |
| 17237 | +#define OP_FilterAdd 184 /* synopsis: filter(P1) += key(P3@P4) */ |
| 17238 | +#define OP_Trace 185 |
| 17239 | +#define OP_CursorHint 186 |
| 17240 | +#define OP_ReleaseReg 187 /* synopsis: release r[P1@P2] mask P3 */ |
| 17241 | +#define OP_Noop 188 |
| 17242 | +#define OP_Explain 189 |
| 17243 | +#define OP_Abortable 190 |
| 17241 | 17244 | |
| 17242 | 17245 | /* Properties such as "out2" or "jump" that are specified in |
| 17243 | 17246 | ** comments following the "case" for each opcode in the vdbe.c |
| 17244 | 17247 | ** are encoded into bitvectors as follows: |
| 17245 | 17248 | */ |
| | @@ -17254,38 +17257,38 @@ |
| 17254 | 17257 | #define OPFLG_INITIALIZER {\ |
| 17255 | 17258 | /* 0 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x41, 0x00,\ |
| 17256 | 17259 | /* 8 */ 0x81, 0x01, 0x01, 0x81, 0x83, 0x83, 0x01, 0x01,\ |
| 17257 | 17260 | /* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0xc9, 0xc9, 0xc9,\ |
| 17258 | 17261 | /* 24 */ 0xc9, 0x01, 0x49, 0x49, 0x49, 0x49, 0xc9, 0x49,\ |
| 17259 | | -/* 32 */ 0xc1, 0x01, 0x41, 0x41, 0xc1, 0x01, 0x41, 0x41,\ |
| 17260 | | -/* 40 */ 0x41, 0x41, 0x41, 0x26, 0x26, 0x41, 0x23, 0x0b,\ |
| 17261 | | -/* 48 */ 0x81, 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b,\ |
| 17262 | | -/* 56 */ 0x0b, 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x41,\ |
| 17263 | | -/* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\ |
| 17264 | | -/* 72 */ 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10, 0x00,\ |
| 17265 | | -/* 80 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02,\ |
| 17266 | | -/* 88 */ 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x40, 0x00,\ |
| 17267 | | -/* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x40, 0x40, 0x26,\ |
| 17262 | +/* 32 */ 0xc1, 0x01, 0x41, 0x41, 0xc1, 0x01, 0x01, 0x41,\ |
| 17263 | +/* 40 */ 0x41, 0x41, 0x41, 0x26, 0x26, 0x41, 0x41, 0x23,\ |
| 17264 | +/* 48 */ 0x0b, 0x81, 0x01, 0x03, 0x03, 0x0b, 0x0b, 0x0b,\ |
| 17265 | +/* 56 */ 0x0b, 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x03, 0x01,\ |
| 17266 | +/* 64 */ 0x41, 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00,\ |
| 17267 | +/* 72 */ 0x10, 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10,\ |
| 17268 | +/* 80 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x02,\ |
| 17269 | +/* 88 */ 0x02, 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x40,\ |
| 17270 | +/* 96 */ 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x40, 0x26,\ |
| 17268 | 17271 | /* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\ |
| 17269 | | -/* 112 */ 0x26, 0x00, 0x40, 0x12, 0x40, 0x40, 0x10, 0x00,\ |
| 17270 | | -/* 120 */ 0x00, 0x00, 0x40, 0x00, 0x40, 0x40, 0x10, 0x10,\ |
| 17271 | | -/* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x50,\ |
| 17272 | | -/* 136 */ 0x00, 0x40, 0x04, 0x04, 0x00, 0x40, 0x50, 0x40,\ |
| 17273 | | -/* 144 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\ |
| 17274 | | -/* 152 */ 0x00, 0x00, 0x10, 0x00, 0x06, 0x10, 0x00, 0x04,\ |
| 17275 | | -/* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ |
| 17276 | | -/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x50,\ |
| 17277 | | -/* 176 */ 0x40, 0x00, 0x10, 0x10, 0x02, 0x12, 0x12, 0x00,\ |
| 17278 | | -/* 184 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,} |
| 17272 | +/* 112 */ 0x26, 0x40, 0x00, 0x12, 0x40, 0x40, 0x10, 0x40,\ |
| 17273 | +/* 120 */ 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x40, 0x10,\ |
| 17274 | +/* 128 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,\ |
| 17275 | +/* 136 */ 0x50, 0x00, 0x40, 0x04, 0x04, 0x00, 0x40, 0x50,\ |
| 17276 | +/* 144 */ 0x40, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\ |
| 17277 | +/* 152 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00,\ |
| 17278 | +/* 160 */ 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ |
| 17279 | +/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10,\ |
| 17280 | +/* 176 */ 0x50, 0x40, 0x00, 0x10, 0x10, 0x02, 0x12, 0x12,\ |
| 17281 | +/* 184 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,} |
| 17279 | 17282 | |
| 17280 | 17283 | /* The resolve3P2Values() routine is able to run faster if it knows |
| 17281 | 17284 | ** the value of the largest JUMP opcode. The smaller the maximum |
| 17282 | 17285 | ** JUMP opcode the better, so the mkopcodeh.tcl script that |
| 17283 | 17286 | ** generated this include file strives to group all JUMP opcodes |
| 17284 | 17287 | ** together near the beginning of the list. |
| 17285 | 17288 | */ |
| 17286 | | -#define SQLITE_MX_JUMP_OPCODE 64 /* Maximum JUMP opcode */ |
| 17289 | +#define SQLITE_MX_JUMP_OPCODE 65 /* Maximum JUMP opcode */ |
| 17287 | 17290 | |
| 17288 | 17291 | /************** End of opcodes.h *********************************************/ |
| 17289 | 17292 | /************** Continuing where we left off in vdbe.h ***********************/ |
| 17290 | 17293 | |
| 17291 | 17294 | /* |
| | @@ -18300,10 +18303,11 @@ |
| 18300 | 18303 | #define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */ |
| 18301 | 18304 | #define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */ |
| 18302 | 18305 | #define SQLITE_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */ |
| 18303 | 18306 | #define SQLITE_OrderBySubq 0x10000000 /* ORDER BY in subquery helps outer */ |
| 18304 | 18307 | #define SQLITE_StarQuery 0x20000000 /* Heurists for star queries */ |
| 18308 | +#define SQLITE_ExistsToJoin 0x40000000 /* The EXISTS-to-JOIN optimization */ |
| 18305 | 18309 | #define SQLITE_AllOpts 0xffffffff /* All optimizations */ |
| 18306 | 18310 | |
| 18307 | 18311 | /* |
| 18308 | 18312 | ** Macros for testing whether or not optimizations are enabled or disabled. |
| 18309 | 18313 | */ |
| | @@ -19182,11 +19186,10 @@ |
| 19182 | 19186 | unsigned isCovering:1; /* True if this is a covering index */ |
| 19183 | 19187 | unsigned noSkipScan:1; /* Do not try to use skip-scan if true */ |
| 19184 | 19188 | unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */ |
| 19185 | 19189 | unsigned bNoQuery:1; /* Do not use this index to optimize queries */ |
| 19186 | 19190 | unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */ |
| 19187 | | - unsigned bIdxRowid:1; /* One or more of the index keys is the ROWID */ |
| 19188 | 19191 | unsigned bHasVCol:1; /* Index references one or more VIRTUAL columns */ |
| 19189 | 19192 | unsigned bHasExpr:1; /* Index contains an expression, either a literal |
| 19190 | 19193 | ** expression, or a reference to a VIRTUAL column */ |
| 19191 | 19194 | #ifdef SQLITE_ENABLE_STAT4 |
| 19192 | 19195 | int nSample; /* Number of elements in aSample[] */ |
| | @@ -19744,10 +19747,11 @@ |
| 19744 | 19747 | unsigned isSynthUsing :1; /* u3.pUsing is synthesized from NATURAL */ |
| 19745 | 19748 | unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */ |
| 19746 | 19749 | unsigned rowidUsed :1; /* The ROWID of this table is referenced */ |
| 19747 | 19750 | unsigned fixedSchema :1; /* Uses u4.pSchema, not u4.zDatabase */ |
| 19748 | 19751 | unsigned hadSchema :1; /* Had u4.zDatabase before u4.pSchema */ |
| 19752 | + unsigned fromExists :1; /* Comes from WHERE EXISTS(...) */ |
| 19749 | 19753 | } fg; |
| 19750 | 19754 | int iCursor; /* The VDBE cursor number used to access this table */ |
| 19751 | 19755 | Bitmask colUsed; /* Bit N set if column N used. Details above for N>62 */ |
| 19752 | 19756 | union { |
| 19753 | 19757 | char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" clause */ |
| | @@ -20274,10 +20278,11 @@ |
| 20274 | 20278 | u8 mayAbort; /* True if statement may throw an ABORT exception */ |
| 20275 | 20279 | u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */ |
| 20276 | 20280 | u8 disableLookaside; /* Number of times lookaside has been disabled */ |
| 20277 | 20281 | u8 prepFlags; /* SQLITE_PREPARE_* flags */ |
| 20278 | 20282 | u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */ |
| 20283 | + u8 bHasExists; /* Has a correlated "EXISTS (SELECT ....)" expression */ |
| 20279 | 20284 | u8 mSubrtnSig; /* mini Bloom filter on available SubrtnSig.selId */ |
| 20280 | 20285 | u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */ |
| 20281 | 20286 | u8 bReturning; /* Coding a RETURNING trigger */ |
| 20282 | 20287 | u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ |
| 20283 | 20288 | u8 disableTriggers; /* True to disable triggers */ |
| | @@ -37721,76 +37726,76 @@ |
| 37721 | 37726 | /* 32 */ "Last" OpHelp(""), |
| 37722 | 37727 | /* 33 */ "IfSizeBetween" OpHelp(""), |
| 37723 | 37728 | /* 34 */ "SorterSort" OpHelp(""), |
| 37724 | 37729 | /* 35 */ "Sort" OpHelp(""), |
| 37725 | 37730 | /* 36 */ "Rewind" OpHelp(""), |
| 37726 | | - /* 37 */ "SorterNext" OpHelp(""), |
| 37727 | | - /* 38 */ "Prev" OpHelp(""), |
| 37728 | | - /* 39 */ "Next" OpHelp(""), |
| 37729 | | - /* 40 */ "IdxLE" OpHelp("key=r[P3@P4]"), |
| 37730 | | - /* 41 */ "IdxGT" OpHelp("key=r[P3@P4]"), |
| 37731 | | - /* 42 */ "IdxLT" OpHelp("key=r[P3@P4]"), |
| 37731 | + /* 37 */ "IfEmpty" OpHelp("if( empty(P1) ) goto P2"), |
| 37732 | + /* 38 */ "SorterNext" OpHelp(""), |
| 37733 | + /* 39 */ "Prev" OpHelp(""), |
| 37734 | + /* 40 */ "Next" OpHelp(""), |
| 37735 | + /* 41 */ "IdxLE" OpHelp("key=r[P3@P4]"), |
| 37736 | + /* 42 */ "IdxGT" OpHelp("key=r[P3@P4]"), |
| 37732 | 37737 | /* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), |
| 37733 | 37738 | /* 44 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), |
| 37734 | | - /* 45 */ "IdxGE" OpHelp("key=r[P3@P4]"), |
| 37735 | | - /* 46 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), |
| 37736 | | - /* 47 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), |
| 37737 | | - /* 48 */ "Program" OpHelp(""), |
| 37738 | | - /* 49 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), |
| 37739 | | - /* 50 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), |
| 37739 | + /* 45 */ "IdxLT" OpHelp("key=r[P3@P4]"), |
| 37740 | + /* 46 */ "IdxGE" OpHelp("key=r[P3@P4]"), |
| 37741 | + /* 47 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), |
| 37742 | + /* 48 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), |
| 37743 | + /* 49 */ "Program" OpHelp(""), |
| 37744 | + /* 50 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), |
| 37740 | 37745 | /* 51 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), |
| 37741 | 37746 | /* 52 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), |
| 37742 | 37747 | /* 53 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), |
| 37743 | 37748 | /* 54 */ "Eq" OpHelp("IF r[P3]==r[P1]"), |
| 37744 | 37749 | /* 55 */ "Gt" OpHelp("IF r[P3]>r[P1]"), |
| 37745 | 37750 | /* 56 */ "Le" OpHelp("IF r[P3]<=r[P1]"), |
| 37746 | 37751 | /* 57 */ "Lt" OpHelp("IF r[P3]<r[P1]"), |
| 37747 | 37752 | /* 58 */ "Ge" OpHelp("IF r[P3]>=r[P1]"), |
| 37748 | 37753 | /* 59 */ "ElseEq" OpHelp(""), |
| 37749 | | - /* 60 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), |
| 37750 | | - /* 61 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), |
| 37751 | | - /* 62 */ "IncrVacuum" OpHelp(""), |
| 37752 | | - /* 63 */ "VNext" OpHelp(""), |
| 37753 | | - /* 64 */ "Filter" OpHelp("if key(P3@P4) not in filter(P1) goto P2"), |
| 37754 | | - /* 65 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"), |
| 37755 | | - /* 66 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"), |
| 37756 | | - /* 67 */ "Return" OpHelp(""), |
| 37757 | | - /* 68 */ "EndCoroutine" OpHelp(""), |
| 37758 | | - /* 69 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), |
| 37759 | | - /* 70 */ "Halt" OpHelp(""), |
| 37760 | | - /* 71 */ "Integer" OpHelp("r[P2]=P1"), |
| 37761 | | - /* 72 */ "Int64" OpHelp("r[P2]=P4"), |
| 37762 | | - /* 73 */ "String" OpHelp("r[P2]='P4' (len=P1)"), |
| 37763 | | - /* 74 */ "BeginSubrtn" OpHelp("r[P2]=NULL"), |
| 37764 | | - /* 75 */ "Null" OpHelp("r[P2..P3]=NULL"), |
| 37765 | | - /* 76 */ "SoftNull" OpHelp("r[P1]=NULL"), |
| 37766 | | - /* 77 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), |
| 37767 | | - /* 78 */ "Variable" OpHelp("r[P2]=parameter(P1)"), |
| 37768 | | - /* 79 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), |
| 37769 | | - /* 80 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), |
| 37770 | | - /* 81 */ "SCopy" OpHelp("r[P2]=r[P1]"), |
| 37771 | | - /* 82 */ "IntCopy" OpHelp("r[P2]=r[P1]"), |
| 37772 | | - /* 83 */ "FkCheck" OpHelp(""), |
| 37773 | | - /* 84 */ "ResultRow" OpHelp("output=r[P1@P2]"), |
| 37774 | | - /* 85 */ "CollSeq" OpHelp(""), |
| 37775 | | - /* 86 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), |
| 37776 | | - /* 87 */ "RealAffinity" OpHelp(""), |
| 37777 | | - /* 88 */ "Cast" OpHelp("affinity(r[P1])"), |
| 37778 | | - /* 89 */ "Permutation" OpHelp(""), |
| 37779 | | - /* 90 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), |
| 37780 | | - /* 91 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"), |
| 37781 | | - /* 92 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"), |
| 37782 | | - /* 93 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"), |
| 37783 | | - /* 94 */ "Column" OpHelp("r[P3]=PX cursor P1 column P2"), |
| 37784 | | - /* 95 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"), |
| 37785 | | - /* 96 */ "Affinity" OpHelp("affinity(r[P1@P2])"), |
| 37786 | | - /* 97 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), |
| 37787 | | - /* 98 */ "Count" OpHelp("r[P2]=count()"), |
| 37788 | | - /* 99 */ "ReadCookie" OpHelp(""), |
| 37789 | | - /* 100 */ "SetCookie" OpHelp(""), |
| 37790 | | - /* 101 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), |
| 37791 | | - /* 102 */ "OpenRead" OpHelp("root=P2 iDb=P3"), |
| 37754 | + /* 60 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), |
| 37755 | + /* 61 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), |
| 37756 | + /* 62 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), |
| 37757 | + /* 63 */ "IncrVacuum" OpHelp(""), |
| 37758 | + /* 64 */ "VNext" OpHelp(""), |
| 37759 | + /* 65 */ "Filter" OpHelp("if key(P3@P4) not in filter(P1) goto P2"), |
| 37760 | + /* 66 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"), |
| 37761 | + /* 67 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"), |
| 37762 | + /* 68 */ "Return" OpHelp(""), |
| 37763 | + /* 69 */ "EndCoroutine" OpHelp(""), |
| 37764 | + /* 70 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), |
| 37765 | + /* 71 */ "Halt" OpHelp(""), |
| 37766 | + /* 72 */ "Integer" OpHelp("r[P2]=P1"), |
| 37767 | + /* 73 */ "Int64" OpHelp("r[P2]=P4"), |
| 37768 | + /* 74 */ "String" OpHelp("r[P2]='P4' (len=P1)"), |
| 37769 | + /* 75 */ "BeginSubrtn" OpHelp("r[P2]=NULL"), |
| 37770 | + /* 76 */ "Null" OpHelp("r[P2..P3]=NULL"), |
| 37771 | + /* 77 */ "SoftNull" OpHelp("r[P1]=NULL"), |
| 37772 | + /* 78 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), |
| 37773 | + /* 79 */ "Variable" OpHelp("r[P2]=parameter(P1)"), |
| 37774 | + /* 80 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), |
| 37775 | + /* 81 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), |
| 37776 | + /* 82 */ "SCopy" OpHelp("r[P2]=r[P1]"), |
| 37777 | + /* 83 */ "IntCopy" OpHelp("r[P2]=r[P1]"), |
| 37778 | + /* 84 */ "FkCheck" OpHelp(""), |
| 37779 | + /* 85 */ "ResultRow" OpHelp("output=r[P1@P2]"), |
| 37780 | + /* 86 */ "CollSeq" OpHelp(""), |
| 37781 | + /* 87 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), |
| 37782 | + /* 88 */ "RealAffinity" OpHelp(""), |
| 37783 | + /* 89 */ "Cast" OpHelp("affinity(r[P1])"), |
| 37784 | + /* 90 */ "Permutation" OpHelp(""), |
| 37785 | + /* 91 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), |
| 37786 | + /* 92 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"), |
| 37787 | + /* 93 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"), |
| 37788 | + /* 94 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"), |
| 37789 | + /* 95 */ "Column" OpHelp("r[P3]=PX cursor P1 column P2"), |
| 37790 | + /* 96 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"), |
| 37791 | + /* 97 */ "Affinity" OpHelp("affinity(r[P1@P2])"), |
| 37792 | + /* 98 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), |
| 37793 | + /* 99 */ "Count" OpHelp("r[P2]=count()"), |
| 37794 | + /* 100 */ "ReadCookie" OpHelp(""), |
| 37795 | + /* 101 */ "SetCookie" OpHelp(""), |
| 37796 | + /* 102 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), |
| 37792 | 37797 | /* 103 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), |
| 37793 | 37798 | /* 104 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), |
| 37794 | 37799 | /* 105 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"), |
| 37795 | 37800 | /* 106 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"), |
| 37796 | 37801 | /* 107 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), |
| | @@ -37797,87 +37802,88 @@ |
| 37797 | 37802 | /* 108 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), |
| 37798 | 37803 | /* 109 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), |
| 37799 | 37804 | /* 110 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), |
| 37800 | 37805 | /* 111 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), |
| 37801 | 37806 | /* 112 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), |
| 37802 | | - /* 113 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), |
| 37803 | | - /* 114 */ "OpenDup" OpHelp(""), |
| 37807 | + /* 113 */ "OpenRead" OpHelp("root=P2 iDb=P3"), |
| 37808 | + /* 114 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), |
| 37804 | 37809 | /* 115 */ "BitNot" OpHelp("r[P2]= ~r[P1]"), |
| 37805 | | - /* 116 */ "OpenAutoindex" OpHelp("nColumn=P2"), |
| 37806 | | - /* 117 */ "OpenEphemeral" OpHelp("nColumn=P2"), |
| 37810 | + /* 116 */ "OpenDup" OpHelp(""), |
| 37811 | + /* 117 */ "OpenAutoindex" OpHelp("nColumn=P2"), |
| 37807 | 37812 | /* 118 */ "String8" OpHelp("r[P2]='P4'"), |
| 37808 | | - /* 119 */ "SorterOpen" OpHelp(""), |
| 37809 | | - /* 120 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), |
| 37810 | | - /* 121 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), |
| 37811 | | - /* 122 */ "Close" OpHelp(""), |
| 37812 | | - /* 123 */ "ColumnsUsed" OpHelp(""), |
| 37813 | | - /* 124 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"), |
| 37814 | | - /* 125 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"), |
| 37815 | | - /* 126 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), |
| 37816 | | - /* 127 */ "NewRowid" OpHelp("r[P2]=rowid"), |
| 37817 | | - /* 128 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), |
| 37818 | | - /* 129 */ "RowCell" OpHelp(""), |
| 37819 | | - /* 130 */ "Delete" OpHelp(""), |
| 37820 | | - /* 131 */ "ResetCount" OpHelp(""), |
| 37821 | | - /* 132 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), |
| 37822 | | - /* 133 */ "SorterData" OpHelp("r[P2]=data"), |
| 37823 | | - /* 134 */ "RowData" OpHelp("r[P2]=data"), |
| 37824 | | - /* 135 */ "Rowid" OpHelp("r[P2]=PX rowid of P1"), |
| 37825 | | - /* 136 */ "NullRow" OpHelp(""), |
| 37826 | | - /* 137 */ "SeekEnd" OpHelp(""), |
| 37827 | | - /* 138 */ "IdxInsert" OpHelp("key=r[P2]"), |
| 37828 | | - /* 139 */ "SorterInsert" OpHelp("key=r[P2]"), |
| 37829 | | - /* 140 */ "IdxDelete" OpHelp("key=r[P2@P3]"), |
| 37830 | | - /* 141 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"), |
| 37831 | | - /* 142 */ "IdxRowid" OpHelp("r[P2]=rowid"), |
| 37832 | | - /* 143 */ "FinishSeek" OpHelp(""), |
| 37833 | | - /* 144 */ "Destroy" OpHelp(""), |
| 37834 | | - /* 145 */ "Clear" OpHelp(""), |
| 37835 | | - /* 146 */ "ResetSorter" OpHelp(""), |
| 37836 | | - /* 147 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"), |
| 37837 | | - /* 148 */ "SqlExec" OpHelp(""), |
| 37838 | | - /* 149 */ "ParseSchema" OpHelp(""), |
| 37839 | | - /* 150 */ "LoadAnalysis" OpHelp(""), |
| 37840 | | - /* 151 */ "DropTable" OpHelp(""), |
| 37841 | | - /* 152 */ "DropIndex" OpHelp(""), |
| 37842 | | - /* 153 */ "DropTrigger" OpHelp(""), |
| 37813 | + /* 119 */ "OpenEphemeral" OpHelp("nColumn=P2"), |
| 37814 | + /* 120 */ "SorterOpen" OpHelp(""), |
| 37815 | + /* 121 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), |
| 37816 | + /* 122 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), |
| 37817 | + /* 123 */ "Close" OpHelp(""), |
| 37818 | + /* 124 */ "ColumnsUsed" OpHelp(""), |
| 37819 | + /* 125 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"), |
| 37820 | + /* 126 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"), |
| 37821 | + /* 127 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), |
| 37822 | + /* 128 */ "NewRowid" OpHelp("r[P2]=rowid"), |
| 37823 | + /* 129 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), |
| 37824 | + /* 130 */ "RowCell" OpHelp(""), |
| 37825 | + /* 131 */ "Delete" OpHelp(""), |
| 37826 | + /* 132 */ "ResetCount" OpHelp(""), |
| 37827 | + /* 133 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), |
| 37828 | + /* 134 */ "SorterData" OpHelp("r[P2]=data"), |
| 37829 | + /* 135 */ "RowData" OpHelp("r[P2]=data"), |
| 37830 | + /* 136 */ "Rowid" OpHelp("r[P2]=PX rowid of P1"), |
| 37831 | + /* 137 */ "NullRow" OpHelp(""), |
| 37832 | + /* 138 */ "SeekEnd" OpHelp(""), |
| 37833 | + /* 139 */ "IdxInsert" OpHelp("key=r[P2]"), |
| 37834 | + /* 140 */ "SorterInsert" OpHelp("key=r[P2]"), |
| 37835 | + /* 141 */ "IdxDelete" OpHelp("key=r[P2@P3]"), |
| 37836 | + /* 142 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"), |
| 37837 | + /* 143 */ "IdxRowid" OpHelp("r[P2]=rowid"), |
| 37838 | + /* 144 */ "FinishSeek" OpHelp(""), |
| 37839 | + /* 145 */ "Destroy" OpHelp(""), |
| 37840 | + /* 146 */ "Clear" OpHelp(""), |
| 37841 | + /* 147 */ "ResetSorter" OpHelp(""), |
| 37842 | + /* 148 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"), |
| 37843 | + /* 149 */ "SqlExec" OpHelp(""), |
| 37844 | + /* 150 */ "ParseSchema" OpHelp(""), |
| 37845 | + /* 151 */ "LoadAnalysis" OpHelp(""), |
| 37846 | + /* 152 */ "DropTable" OpHelp(""), |
| 37847 | + /* 153 */ "DropIndex" OpHelp(""), |
| 37843 | 37848 | /* 154 */ "Real" OpHelp("r[P2]=P4"), |
| 37844 | | - /* 155 */ "IntegrityCk" OpHelp(""), |
| 37845 | | - /* 156 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), |
| 37846 | | - /* 157 */ "Param" OpHelp(""), |
| 37847 | | - /* 158 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), |
| 37848 | | - /* 159 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), |
| 37849 | | - /* 160 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), |
| 37850 | | - /* 161 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), |
| 37851 | | - /* 162 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), |
| 37852 | | - /* 163 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"), |
| 37853 | | - /* 164 */ "AggValue" OpHelp("r[P3]=value N=P2"), |
| 37854 | | - /* 165 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), |
| 37855 | | - /* 166 */ "Expire" OpHelp(""), |
| 37856 | | - /* 167 */ "CursorLock" OpHelp(""), |
| 37857 | | - /* 168 */ "CursorUnlock" OpHelp(""), |
| 37858 | | - /* 169 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), |
| 37859 | | - /* 170 */ "VBegin" OpHelp(""), |
| 37860 | | - /* 171 */ "VCreate" OpHelp(""), |
| 37861 | | - /* 172 */ "VDestroy" OpHelp(""), |
| 37862 | | - /* 173 */ "VOpen" OpHelp(""), |
| 37863 | | - /* 174 */ "VCheck" OpHelp(""), |
| 37864 | | - /* 175 */ "VInitIn" OpHelp("r[P2]=ValueList(P1,P3)"), |
| 37865 | | - /* 176 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), |
| 37866 | | - /* 177 */ "VRename" OpHelp(""), |
| 37867 | | - /* 178 */ "Pagecount" OpHelp(""), |
| 37868 | | - /* 179 */ "MaxPgcnt" OpHelp(""), |
| 37869 | | - /* 180 */ "ClrSubtype" OpHelp("r[P1].subtype = 0"), |
| 37870 | | - /* 181 */ "GetSubtype" OpHelp("r[P2] = r[P1].subtype"), |
| 37871 | | - /* 182 */ "SetSubtype" OpHelp("r[P2].subtype = r[P1]"), |
| 37872 | | - /* 183 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"), |
| 37873 | | - /* 184 */ "Trace" OpHelp(""), |
| 37874 | | - /* 185 */ "CursorHint" OpHelp(""), |
| 37875 | | - /* 186 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), |
| 37876 | | - /* 187 */ "Noop" OpHelp(""), |
| 37877 | | - /* 188 */ "Explain" OpHelp(""), |
| 37878 | | - /* 189 */ "Abortable" OpHelp(""), |
| 37849 | + /* 155 */ "DropTrigger" OpHelp(""), |
| 37850 | + /* 156 */ "IntegrityCk" OpHelp(""), |
| 37851 | + /* 157 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), |
| 37852 | + /* 158 */ "Param" OpHelp(""), |
| 37853 | + /* 159 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), |
| 37854 | + /* 160 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), |
| 37855 | + /* 161 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), |
| 37856 | + /* 162 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), |
| 37857 | + /* 163 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), |
| 37858 | + /* 164 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"), |
| 37859 | + /* 165 */ "AggValue" OpHelp("r[P3]=value N=P2"), |
| 37860 | + /* 166 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), |
| 37861 | + /* 167 */ "Expire" OpHelp(""), |
| 37862 | + /* 168 */ "CursorLock" OpHelp(""), |
| 37863 | + /* 169 */ "CursorUnlock" OpHelp(""), |
| 37864 | + /* 170 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), |
| 37865 | + /* 171 */ "VBegin" OpHelp(""), |
| 37866 | + /* 172 */ "VCreate" OpHelp(""), |
| 37867 | + /* 173 */ "VDestroy" OpHelp(""), |
| 37868 | + /* 174 */ "VOpen" OpHelp(""), |
| 37869 | + /* 175 */ "VCheck" OpHelp(""), |
| 37870 | + /* 176 */ "VInitIn" OpHelp("r[P2]=ValueList(P1,P3)"), |
| 37871 | + /* 177 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), |
| 37872 | + /* 178 */ "VRename" OpHelp(""), |
| 37873 | + /* 179 */ "Pagecount" OpHelp(""), |
| 37874 | + /* 180 */ "MaxPgcnt" OpHelp(""), |
| 37875 | + /* 181 */ "ClrSubtype" OpHelp("r[P1].subtype = 0"), |
| 37876 | + /* 182 */ "GetSubtype" OpHelp("r[P2] = r[P1].subtype"), |
| 37877 | + /* 183 */ "SetSubtype" OpHelp("r[P2].subtype = r[P1]"), |
| 37878 | + /* 184 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"), |
| 37879 | + /* 185 */ "Trace" OpHelp(""), |
| 37880 | + /* 186 */ "CursorHint" OpHelp(""), |
| 37881 | + /* 187 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), |
| 37882 | + /* 188 */ "Noop" OpHelp(""), |
| 37883 | + /* 189 */ "Explain" OpHelp(""), |
| 37884 | + /* 190 */ "Abortable" OpHelp(""), |
| 37879 | 37885 | }; |
| 37880 | 37886 | return azName[i]; |
| 37881 | 37887 | } |
| 37882 | 37888 | #endif |
| 37883 | 37889 | |
| | @@ -73586,14 +73592,14 @@ |
| 73586 | 73592 | u8 *pTmp; /* Temporary ptr into data[] */ |
| 73587 | 73593 | |
| 73588 | 73594 | assert( pPage->pBt!=0 ); |
| 73589 | 73595 | assert( sqlite3PagerIswriteable(pPage->pDbPage) ); |
| 73590 | 73596 | assert( CORRUPT_DB || iStart>=pPage->hdrOffset+6+pPage->childPtrSize ); |
| 73591 | | - assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize ); |
| 73597 | + assert( CORRUPT_DB || iEnd <= (int)pPage->pBt->usableSize ); |
| 73592 | 73598 | assert( sqlite3_mutex_held(pPage->pBt->mutex) ); |
| 73593 | 73599 | assert( iSize>=4 ); /* Minimum cell size is 4 */ |
| 73594 | | - assert( CORRUPT_DB || iStart<=pPage->pBt->usableSize-4 ); |
| 73600 | + assert( CORRUPT_DB || iStart<=(int)pPage->pBt->usableSize-4 ); |
| 73595 | 73601 | |
| 73596 | 73602 | /* The list of freeblocks must be in ascending order. Find the |
| 73597 | 73603 | ** spot on the list where iStart should be inserted. |
| 73598 | 73604 | */ |
| 73599 | 73605 | hdr = pPage->hdrOffset; |
| | @@ -77323,10 +77329,34 @@ |
| 77323 | 77329 | *pRes = 1; |
| 77324 | 77330 | rc = SQLITE_OK; |
| 77325 | 77331 | } |
| 77326 | 77332 | return rc; |
| 77327 | 77333 | } |
| 77334 | + |
| 77335 | +/* Set *pRes to 1 (true) if the BTree pointed to by cursor pCur contains zero |
| 77336 | +** rows of content. Set *pRes to 0 (false) if the table contains content. |
| 77337 | +** Return SQLITE_OK on success or some error code (ex: SQLITE_NOMEM) if |
| 77338 | +** something goes wrong. |
| 77339 | +*/ |
| 77340 | +SQLITE_PRIVATE int sqlite3BtreeIsEmpty(BtCursor *pCur, int *pRes){ |
| 77341 | + int rc; |
| 77342 | + |
| 77343 | + assert( cursorOwnsBtShared(pCur) ); |
| 77344 | + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); |
| 77345 | + if( pCur->eState==CURSOR_VALID ){ |
| 77346 | + *pRes = 0; |
| 77347 | + return SQLITE_OK; |
| 77348 | + } |
| 77349 | + rc = moveToRoot(pCur); |
| 77350 | + if( rc==SQLITE_EMPTY ){ |
| 77351 | + *pRes = 1; |
| 77352 | + rc = SQLITE_OK; |
| 77353 | + }else{ |
| 77354 | + *pRes = 0; |
| 77355 | + } |
| 77356 | + return rc; |
| 77357 | +} |
| 77328 | 77358 | |
| 77329 | 77359 | #ifdef SQLITE_DEBUG |
| 77330 | 77360 | /* The cursors is CURSOR_VALID and has BTCF_AtLast set. Verify that |
| 77331 | 77361 | ** this flags are true for a consistent database. |
| 77332 | 77362 | ** |
| | @@ -100850,10 +100880,36 @@ |
| 100850 | 100880 | VdbeBranchTaken(res!=0,2); |
| 100851 | 100881 | if( res ) goto jump_to_p2; |
| 100852 | 100882 | } |
| 100853 | 100883 | break; |
| 100854 | 100884 | } |
| 100885 | + |
| 100886 | +/* Opcode: IfEmpty P1 P2 * * * |
| 100887 | +** Synopsis: if( empty(P1) ) goto P2 |
| 100888 | +** |
| 100889 | +** Check to see if the b-tree table that cursor P1 references is empty |
| 100890 | +** and jump to P2 if it is. |
| 100891 | +*/ |
| 100892 | +case OP_IfEmpty: { /* jump */ |
| 100893 | + VdbeCursor *pC; |
| 100894 | + BtCursor *pCrsr; |
| 100895 | + int res; |
| 100896 | + |
| 100897 | + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 100898 | + assert( pOp->p2>=0 && pOp->p2<p->nOp ); |
| 100899 | + |
| 100900 | + pC = p->apCsr[pOp->p1]; |
| 100901 | + assert( pC!=0 ); |
| 100902 | + assert( pC->eCurType==CURTYPE_BTREE ); |
| 100903 | + pCrsr = pC->uc.pCursor; |
| 100904 | + assert( pCrsr ); |
| 100905 | + rc = sqlite3BtreeIsEmpty(pCrsr, &res); |
| 100906 | + if( rc ) goto abort_due_to_error; |
| 100907 | + VdbeBranchTaken(res!=0,2); |
| 100908 | + if( res ) goto jump_to_p2; |
| 100909 | + break; |
| 100910 | +} |
| 100855 | 100911 | |
| 100856 | 100912 | /* Opcode: Next P1 P2 P3 * P5 |
| 100857 | 100913 | ** |
| 100858 | 100914 | ** Advance cursor P1 so that it points to the next key/data pair in its |
| 100859 | 100915 | ** table or index. If there are no more key/value pairs then fall through |
| | @@ -102722,11 +102778,18 @@ |
| 102722 | 102778 | sqlite3_vtab_cursor *pVCur; |
| 102723 | 102779 | sqlite3_vtab *pVtab; |
| 102724 | 102780 | const sqlite3_module *pModule; |
| 102725 | 102781 | |
| 102726 | 102782 | assert( p->bIsReader ); |
| 102727 | | - pCur = 0; |
| 102783 | + pCur = p->apCsr[pOp->p1]; |
| 102784 | + if( pCur!=0 |
| 102785 | + && ALWAYS( pCur->eCurType==CURTYPE_VTAB ) |
| 102786 | + && ALWAYS( pCur->uc.pVCur->pVtab==pOp->p4.pVtab->pVtab ) |
| 102787 | + ){ |
| 102788 | + /* This opcode is a no-op if the cursor is already open */ |
| 102789 | + break; |
| 102790 | + } |
| 102728 | 102791 | pVCur = 0; |
| 102729 | 102792 | pVtab = pOp->p4.pVtab->pVtab; |
| 102730 | 102793 | if( pVtab==0 || NEVER(pVtab->pModule==0) ){ |
| 102731 | 102794 | rc = SQLITE_LOCKED; |
| 102732 | 102795 | goto abort_due_to_error; |
| | @@ -104125,11 +104188,11 @@ |
| 104125 | 104188 | void *z, |
| 104126 | 104189 | int n, |
| 104127 | 104190 | int iOffset, |
| 104128 | 104191 | int (*xCall)(BtCursor*, u32, u32, void*) |
| 104129 | 104192 | ){ |
| 104130 | | - int rc; |
| 104193 | + int rc = SQLITE_OK; |
| 104131 | 104194 | Incrblob *p = (Incrblob *)pBlob; |
| 104132 | 104195 | Vdbe *v; |
| 104133 | 104196 | sqlite3 *db; |
| 104134 | 104197 | |
| 104135 | 104198 | if( p==0 ) return SQLITE_MISUSE_BKPT; |
| | @@ -104165,21 +104228,36 @@ |
| 104165 | 104228 | ** same way as an SQLITE_DELETE (the SQLITE_DELETE code is actually |
| 104166 | 104229 | ** slightly more efficient). Since you cannot write to a PK column |
| 104167 | 104230 | ** using the incremental-blob API, this works. For the sessions module |
| 104168 | 104231 | ** anyhow. |
| 104169 | 104232 | */ |
| 104170 | | - sqlite3_int64 iKey; |
| 104171 | | - iKey = sqlite3BtreeIntegerKey(p->pCsr); |
| 104172 | | - assert( v->apCsr[0]!=0 ); |
| 104173 | | - assert( v->apCsr[0]->eCurType==CURTYPE_BTREE ); |
| 104174 | | - sqlite3VdbePreUpdateHook( |
| 104175 | | - v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1, p->iCol |
| 104176 | | - ); |
| 104177 | | - } |
| 104178 | | -#endif |
| 104179 | | - |
| 104233 | + if( sqlite3BtreeCursorIsValidNN(p->pCsr)==0 ){ |
| 104234 | + /* If the cursor is not currently valid, try to reseek it. This |
| 104235 | + ** always either fails or finds the correct row - the cursor will |
| 104236 | + ** have been marked permanently CURSOR_INVALID if the open row has |
| 104237 | + ** been deleted. */ |
| 104238 | + int bDiff = 0; |
| 104239 | + rc = sqlite3BtreeCursorRestore(p->pCsr, &bDiff); |
| 104240 | + assert( bDiff==0 || sqlite3BtreeCursorIsValidNN(p->pCsr)==0 ); |
| 104241 | + } |
| 104242 | + if( sqlite3BtreeCursorIsValidNN(p->pCsr) ){ |
| 104243 | + sqlite3_int64 iKey; |
| 104244 | + iKey = sqlite3BtreeIntegerKey(p->pCsr); |
| 104245 | + assert( v->apCsr[0]!=0 ); |
| 104246 | + assert( v->apCsr[0]->eCurType==CURTYPE_BTREE ); |
| 104247 | + sqlite3VdbePreUpdateHook( |
| 104248 | + v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1, p->iCol |
| 104249 | + ); |
| 104250 | + } |
| 104251 | + } |
| 104252 | + if( rc==SQLITE_OK ){ |
| 104253 | + rc = xCall(p->pCsr, iOffset+p->iOffset, n, z); |
| 104254 | + } |
| 104255 | +#else |
| 104180 | 104256 | rc = xCall(p->pCsr, iOffset+p->iOffset, n, z); |
| 104257 | +#endif |
| 104258 | + |
| 104181 | 104259 | sqlite3BtreeLeaveCursor(p->pCsr); |
| 104182 | 104260 | if( rc==SQLITE_ABORT ){ |
| 104183 | 104261 | sqlite3VdbeFinalize(v); |
| 104184 | 104262 | p->pStmt = 0; |
| 104185 | 104263 | }else{ |
| | @@ -109563,22 +109641,25 @@ |
| 109563 | 109641 | ** type of the function |
| 109564 | 109642 | */ |
| 109565 | 109643 | return WRC_Prune; |
| 109566 | 109644 | } |
| 109567 | 109645 | #ifndef SQLITE_OMIT_SUBQUERY |
| 109646 | + case TK_EXISTS: |
| 109568 | 109647 | case TK_SELECT: |
| 109569 | | - case TK_EXISTS: testcase( pExpr->op==TK_EXISTS ); |
| 109570 | 109648 | #endif |
| 109571 | 109649 | case TK_IN: { |
| 109572 | 109650 | testcase( pExpr->op==TK_IN ); |
| 109651 | + testcase( pExpr->op==TK_EXISTS ); |
| 109652 | + testcase( pExpr->op==TK_SELECT ); |
| 109573 | 109653 | if( ExprUseXSelect(pExpr) ){ |
| 109574 | 109654 | int nRef = pNC->nRef; |
| 109575 | 109655 | testcase( pNC->ncFlags & NC_IsCheck ); |
| 109576 | 109656 | testcase( pNC->ncFlags & NC_PartIdx ); |
| 109577 | 109657 | testcase( pNC->ncFlags & NC_IdxExpr ); |
| 109578 | 109658 | testcase( pNC->ncFlags & NC_GenCol ); |
| 109579 | 109659 | assert( pExpr->x.pSelect ); |
| 109660 | + if( pExpr->op==TK_EXISTS ) pParse->bHasExists = 1; |
| 109580 | 109661 | if( pNC->ncFlags & NC_SelfRef ){ |
| 109581 | 109662 | notValidImpl(pParse, pNC, "subqueries", pExpr, pExpr); |
| 109582 | 109663 | }else{ |
| 109583 | 109664 | sqlite3WalkSelect(pWalker, pExpr->x.pSelect); |
| 109584 | 109665 | } |
| | @@ -111660,11 +111741,11 @@ |
| 111660 | 111741 | return pRight; |
| 111661 | 111742 | }else if( pRight==0 ){ |
| 111662 | 111743 | return pLeft; |
| 111663 | 111744 | }else{ |
| 111664 | 111745 | u32 f = pLeft->flags | pRight->flags; |
| 111665 | | - if( (f&(EP_OuterON|EP_InnerON|EP_IsFalse))==EP_IsFalse |
| 111746 | + if( (f&(EP_OuterON|EP_InnerON|EP_IsFalse|EP_HasFunc))==EP_IsFalse |
| 111666 | 111747 | && !IN_RENAME_OBJECT |
| 111667 | 111748 | ){ |
| 111668 | 111749 | sqlite3ExprDeferredDelete(pParse, pLeft); |
| 111669 | 111750 | sqlite3ExprDeferredDelete(pParse, pRight); |
| 111670 | 111751 | return sqlite3Expr(db, TK_INTEGER, "0"); |
| | @@ -112940,12 +113021,15 @@ |
| 112940 | 113021 | ** then compute the right operand first and do an IsNull jump if the |
| 112941 | 113022 | ** right operand evalutes to NULL. |
| 112942 | 113023 | */ |
| 112943 | 113024 | if( exprEvalRhsFirst(pExpr) && sqlite3ExprCanBeNull(pExpr->pRight) ){ |
| 112944 | 113025 | r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, pFree2); |
| 112945 | | - addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, r2); VdbeCoverage(v); |
| 113026 | + addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, r2); |
| 113027 | + VdbeComment((v, "skip left operand")); |
| 113028 | + VdbeCoverage(v); |
| 112946 | 113029 | }else{ |
| 113030 | + r2 = 0; /* Silence a false-positive uninit-var warning in MSVC */ |
| 112947 | 113031 | addrIsNull = 0; |
| 112948 | 113032 | } |
| 112949 | 113033 | r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, pFree1); |
| 112950 | 113034 | if( addrIsNull==0 ){ |
| 112951 | 113035 | /* |
| | @@ -112955,11 +113039,13 @@ |
| 112955 | 113039 | ** operand. |
| 112956 | 113040 | */ |
| 112957 | 113041 | if( ExprHasProperty(pExpr->pRight, EP_Subquery) |
| 112958 | 113042 | && sqlite3ExprCanBeNull(pExpr->pLeft) |
| 112959 | 113043 | ){ |
| 112960 | | - addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, r1); VdbeCoverage(v); |
| 113044 | + addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, r1); |
| 113045 | + VdbeComment((v, "skip right operand")); |
| 113046 | + VdbeCoverage(v); |
| 112961 | 113047 | } |
| 112962 | 113048 | r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, pFree2); |
| 112963 | 113049 | } |
| 112964 | 113050 | *pR1 = r1; |
| 112965 | 113051 | *pR2 = r2; |
| | @@ -114408,21 +114494,27 @@ |
| 114408 | 114494 | dest.eDest = SRT_Exists; |
| 114409 | 114495 | sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm); |
| 114410 | 114496 | VdbeComment((v, "Init EXISTS result")); |
| 114411 | 114497 | } |
| 114412 | 114498 | if( pSel->pLimit ){ |
| 114413 | | - /* The subquery already has a limit. If the pre-existing limit is X |
| 114414 | | - ** then make the new limit X<>0 so that the new limit is either 1 or 0 */ |
| 114415 | | - sqlite3 *db = pParse->db; |
| 114416 | | - pLimit = sqlite3Expr(db, TK_INTEGER, "0"); |
| 114417 | | - if( pLimit ){ |
| 114418 | | - pLimit->affExpr = SQLITE_AFF_NUMERIC; |
| 114419 | | - pLimit = sqlite3PExpr(pParse, TK_NE, |
| 114420 | | - sqlite3ExprDup(db, pSel->pLimit->pLeft, 0), pLimit); |
| 114421 | | - } |
| 114422 | | - sqlite3ExprDeferredDelete(pParse, pSel->pLimit->pLeft); |
| 114423 | | - pSel->pLimit->pLeft = pLimit; |
| 114499 | + /* The subquery already has a limit. If the pre-existing limit X is |
| 114500 | + ** not already integer value 1 or 0, then make the new limit X<>0 so that |
| 114501 | + ** the new limit is either 1 or 0 */ |
| 114502 | + Expr *pLeft = pSel->pLimit->pLeft; |
| 114503 | + if( ExprHasProperty(pLeft, EP_IntValue)==0 |
| 114504 | + || (pLeft->u.iValue!=1 && pLeft->u.iValue!=0) |
| 114505 | + ){ |
| 114506 | + sqlite3 *db = pParse->db; |
| 114507 | + pLimit = sqlite3Expr(db, TK_INTEGER, "0"); |
| 114508 | + if( pLimit ){ |
| 114509 | + pLimit->affExpr = SQLITE_AFF_NUMERIC; |
| 114510 | + pLimit = sqlite3PExpr(pParse, TK_NE, |
| 114511 | + sqlite3ExprDup(db, pLeft, 0), pLimit); |
| 114512 | + } |
| 114513 | + sqlite3ExprDeferredDelete(pParse, pLeft); |
| 114514 | + pSel->pLimit->pLeft = pLimit; |
| 114515 | + } |
| 114424 | 114516 | }else{ |
| 114425 | 114517 | /* If there is no pre-existing limit add a limit of 1 */ |
| 114426 | 114518 | pLimit = sqlite3Expr(pParse->db, TK_INTEGER, "1"); |
| 114427 | 114519 | pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0); |
| 114428 | 114520 | } |
| | @@ -115628,10 +115720,11 @@ |
| 115628 | 115720 | testcase( regFree2==0 ); |
| 115629 | 115721 | if( addrIsNull ){ |
| 115630 | 115722 | sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2); |
| 115631 | 115723 | sqlite3VdbeJumpHere(v, addrIsNull); |
| 115632 | 115724 | sqlite3VdbeAddOp2(v, OP_Null, 0, target); |
| 115725 | + VdbeComment((v, "short-circut value")); |
| 115633 | 115726 | } |
| 115634 | 115727 | break; |
| 115635 | 115728 | } |
| 115636 | 115729 | case TK_UMINUS: { |
| 115637 | 115730 | Expr *pLeft = pExpr->pLeft; |
| | @@ -127518,11 +127611,10 @@ |
| 127518 | 127611 | }else{ |
| 127519 | 127612 | j = pCExpr->iColumn; |
| 127520 | 127613 | assert( j<=0x7fff ); |
| 127521 | 127614 | if( j<0 ){ |
| 127522 | 127615 | j = pTab->iPKey; |
| 127523 | | - pIndex->bIdxRowid = 1; |
| 127524 | 127616 | }else{ |
| 127525 | 127617 | if( pTab->aCol[j].notNull==0 ){ |
| 127526 | 127618 | pIndex->uniqNotNull = 0; |
| 127527 | 127619 | } |
| 127528 | 127620 | if( pTab->aCol[j].colFlags & COLFLAG_VIRTUAL ){ |
| | @@ -128437,20 +128529,26 @@ |
| 128437 | 128529 | ** Append the contents of SrcList p2 to SrcList p1 and return the resulting |
| 128438 | 128530 | ** SrcList. Or, if an error occurs, return NULL. In all cases, p1 and p2 |
| 128439 | 128531 | ** are deleted by this function. |
| 128440 | 128532 | */ |
| 128441 | 128533 | SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2){ |
| 128442 | | - assert( p1 && p1->nSrc==1 ); |
| 128534 | + assert( p1 ); |
| 128535 | + assert( p2 || pParse->nErr ); |
| 128536 | + assert( p2==0 || p2->nSrc>=1 ); |
| 128537 | + testcase( p1->nSrc==0 ); |
| 128443 | 128538 | if( p2 ){ |
| 128444 | | - SrcList *pNew = sqlite3SrcListEnlarge(pParse, p1, p2->nSrc, 1); |
| 128539 | + int nOld = p1->nSrc; |
| 128540 | + SrcList *pNew = sqlite3SrcListEnlarge(pParse, p1, p2->nSrc, nOld); |
| 128445 | 128541 | if( pNew==0 ){ |
| 128446 | 128542 | sqlite3SrcListDelete(pParse->db, p2); |
| 128447 | 128543 | }else{ |
| 128448 | 128544 | p1 = pNew; |
| 128449 | | - memcpy(&p1->a[1], p2->a, p2->nSrc*sizeof(SrcItem)); |
| 128545 | + memcpy(&p1->a[nOld], p2->a, p2->nSrc*sizeof(SrcItem)); |
| 128546 | + assert( nOld==1 || (p2->a[0].fg.jointype & JT_LTORJ)==0 ); |
| 128547 | + assert( p1->nSrc>=1 ); |
| 128548 | + p1->a[0].fg.jointype |= (JT_LTORJ & p2->a[0].fg.jointype); |
| 128450 | 128549 | sqlite3DbFree(pParse->db, p2); |
| 128451 | | - p1->a[0].fg.jointype |= (JT_LTORJ & p1->a[1].fg.jointype); |
| 128452 | 128550 | } |
| 128453 | 128551 | } |
| 128454 | 128552 | return p1; |
| 128455 | 128553 | } |
| 128456 | 128554 | |
| | @@ -145523,11 +145621,11 @@ |
| 145523 | 145621 | SrcList *pSrc, /* Array of tables to search */ |
| 145524 | 145622 | int iStart, /* First member of pSrc->a[] to check */ |
| 145525 | 145623 | int iEnd, /* Last member of pSrc->a[] to check */ |
| 145526 | 145624 | const char *zCol, /* Name of the column we are looking for */ |
| 145527 | 145625 | int *piTab, /* Write index of pSrc->a[] here */ |
| 145528 | | - int *piCol, /* Write index of pSrc->a[*piTab].pTab->aCol[] here */ |
| 145626 | + int *piCol, /* Write index of pSrc->a[*piTab].pSTab->aCol[] here */ |
| 145529 | 145627 | int bIgnoreHidden /* Ignore hidden columns */ |
| 145530 | 145628 | ){ |
| 145531 | 145629 | int i; /* For looping over tables in pSrc */ |
| 145532 | 145630 | int iCol; /* Index of column matching zCol */ |
| 145533 | 145631 | |
| | @@ -148175,11 +148273,13 @@ |
| 148175 | 148273 | int unionTab; /* Cursor number of the temp table holding result */ |
| 148176 | 148274 | u8 op = 0; /* One of the SRT_ operations to apply to self */ |
| 148177 | 148275 | int priorOp; /* The SRT_ operation to apply to prior selects */ |
| 148178 | 148276 | Expr *pLimit; /* Saved values of p->nLimit */ |
| 148179 | 148277 | int addr; |
| 148278 | + int emptyBypass = 0; /* IfEmpty opcode to bypass RHS */ |
| 148180 | 148279 | SelectDest uniondest; |
| 148280 | + |
| 148181 | 148281 | |
| 148182 | 148282 | testcase( p->op==TK_EXCEPT ); |
| 148183 | 148283 | testcase( p->op==TK_UNION ); |
| 148184 | 148284 | priorOp = SRT_Union; |
| 148185 | 148285 | if( dest.eDest==priorOp ){ |
| | @@ -148214,10 +148314,12 @@ |
| 148214 | 148314 | |
| 148215 | 148315 | /* Code the current SELECT statement |
| 148216 | 148316 | */ |
| 148217 | 148317 | if( p->op==TK_EXCEPT ){ |
| 148218 | 148318 | op = SRT_Except; |
| 148319 | + emptyBypass = sqlite3VdbeAddOp1(v, OP_IfEmpty, unionTab); |
| 148320 | + VdbeCoverage(v); |
| 148219 | 148321 | }else{ |
| 148220 | 148322 | assert( p->op==TK_UNION ); |
| 148221 | 148323 | op = SRT_Union; |
| 148222 | 148324 | } |
| 148223 | 148325 | p->pPrior = 0; |
| | @@ -148234,10 +148336,11 @@ |
| 148234 | 148336 | p->pPrior = pPrior; |
| 148235 | 148337 | p->pOrderBy = 0; |
| 148236 | 148338 | if( p->op==TK_UNION ){ |
| 148237 | 148339 | p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); |
| 148238 | 148340 | } |
| 148341 | + if( emptyBypass ) sqlite3VdbeJumpHere(v, emptyBypass); |
| 148239 | 148342 | sqlite3ExprDelete(db, p->pLimit); |
| 148240 | 148343 | p->pLimit = pLimit; |
| 148241 | 148344 | p->iLimit = 0; |
| 148242 | 148345 | p->iOffset = 0; |
| 148243 | 148346 | |
| | @@ -148267,10 +148370,11 @@ |
| 148267 | 148370 | int iCont, iBreak, iStart; |
| 148268 | 148371 | Expr *pLimit; |
| 148269 | 148372 | int addr; |
| 148270 | 148373 | SelectDest intersectdest; |
| 148271 | 148374 | int r1; |
| 148375 | + int emptyBypass; |
| 148272 | 148376 | |
| 148273 | 148377 | /* INTERSECT is different from the others since it requires |
| 148274 | 148378 | ** two temporary tables. Hence it has its own case. Begin |
| 148275 | 148379 | ** by allocating the tables we will need. |
| 148276 | 148380 | */ |
| | @@ -148290,10 +148394,11 @@ |
| 148290 | 148394 | TREETRACE(0x400, pParse, p, ("multiSelect INTERSECT left...\n")); |
| 148291 | 148395 | rc = sqlite3Select(pParse, pPrior, &intersectdest); |
| 148292 | 148396 | if( rc ){ |
| 148293 | 148397 | goto multi_select_end; |
| 148294 | 148398 | } |
| 148399 | + emptyBypass = sqlite3VdbeAddOp1(v, OP_IfEmpty, tab1); VdbeCoverage(v); |
| 148295 | 148400 | |
| 148296 | 148401 | /* Code the current SELECT into temporary table "tab2" |
| 148297 | 148402 | */ |
| 148298 | 148403 | addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0); |
| 148299 | 148404 | assert( p->addrOpenEphm[1] == -1 ); |
| | @@ -148321,11 +148426,11 @@ |
| 148321 | 148426 | if( rc ) break; |
| 148322 | 148427 | assert( p->pEList ); |
| 148323 | 148428 | iBreak = sqlite3VdbeMakeLabel(pParse); |
| 148324 | 148429 | iCont = sqlite3VdbeMakeLabel(pParse); |
| 148325 | 148430 | computeLimitRegisters(pParse, p, iBreak); |
| 148326 | | - sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v); |
| 148431 | + sqlite3VdbeAddOp1(v, OP_Rewind, tab1); |
| 148327 | 148432 | r1 = sqlite3GetTempReg(pParse); |
| 148328 | 148433 | iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1); |
| 148329 | 148434 | sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); |
| 148330 | 148435 | VdbeCoverage(v); |
| 148331 | 148436 | sqlite3ReleaseTempReg(pParse, r1); |
| | @@ -148333,10 +148438,11 @@ |
| 148333 | 148438 | 0, 0, &dest, iCont, iBreak); |
| 148334 | 148439 | sqlite3VdbeResolveLabel(v, iCont); |
| 148335 | 148440 | sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v); |
| 148336 | 148441 | sqlite3VdbeResolveLabel(v, iBreak); |
| 148337 | 148442 | sqlite3VdbeAddOp2(v, OP_Close, tab2, 0); |
| 148443 | + sqlite3VdbeJumpHere(v, emptyBypass); |
| 148338 | 148444 | sqlite3VdbeAddOp2(v, OP_Close, tab1, 0); |
| 148339 | 148445 | break; |
| 148340 | 148446 | } |
| 148341 | 148447 | } |
| 148342 | 148448 | |
| | @@ -149011,10 +149117,11 @@ |
| 149011 | 149117 | typedef struct SubstContext { |
| 149012 | 149118 | Parse *pParse; /* The parsing context */ |
| 149013 | 149119 | int iTable; /* Replace references to this table */ |
| 149014 | 149120 | int iNewTable; /* New table number */ |
| 149015 | 149121 | int isOuterJoin; /* Add TK_IF_NULL_ROW opcodes on each replacement */ |
| 149122 | + int nSelDepth; /* Depth of sub-query recursion. Top==1 */ |
| 149016 | 149123 | ExprList *pEList; /* Replacement expressions */ |
| 149017 | 149124 | ExprList *pCList; /* Collation sequences for replacement expr */ |
| 149018 | 149125 | } SubstContext; |
| 149019 | 149126 | |
| 149020 | 149127 | /* Forward Declarations */ |
| | @@ -149117,10 +149224,13 @@ |
| 149117 | 149224 | } |
| 149118 | 149225 | } |
| 149119 | 149226 | }else{ |
| 149120 | 149227 | if( pExpr->op==TK_IF_NULL_ROW && pExpr->iTable==pSubst->iTable ){ |
| 149121 | 149228 | pExpr->iTable = pSubst->iNewTable; |
| 149229 | + } |
| 149230 | + if( pExpr->op==TK_AGG_FUNCTION && pExpr->op2>=pSubst->nSelDepth ){ |
| 149231 | + pExpr->op2--; |
| 149122 | 149232 | } |
| 149123 | 149233 | pExpr->pLeft = substExpr(pSubst, pExpr->pLeft); |
| 149124 | 149234 | pExpr->pRight = substExpr(pSubst, pExpr->pRight); |
| 149125 | 149235 | if( ExprUseXSelect(pExpr) ){ |
| 149126 | 149236 | substSelect(pSubst, pExpr->x.pSelect, 1); |
| | @@ -149155,10 +149265,11 @@ |
| 149155 | 149265 | ){ |
| 149156 | 149266 | SrcList *pSrc; |
| 149157 | 149267 | SrcItem *pItem; |
| 149158 | 149268 | int i; |
| 149159 | 149269 | if( !p ) return; |
| 149270 | + pSubst->nSelDepth++; |
| 149160 | 149271 | do{ |
| 149161 | 149272 | substExprList(pSubst, p->pEList); |
| 149162 | 149273 | substExprList(pSubst, p->pGroupBy); |
| 149163 | 149274 | substExprList(pSubst, p->pOrderBy); |
| 149164 | 149275 | p->pHaving = substExpr(pSubst, p->pHaving); |
| | @@ -149172,10 +149283,11 @@ |
| 149172 | 149283 | if( pItem->fg.isTabFunc ){ |
| 149173 | 149284 | substExprList(pSubst, pItem->u1.pFuncArg); |
| 149174 | 149285 | } |
| 149175 | 149286 | } |
| 149176 | 149287 | }while( doPrior && (p = p->pPrior)!=0 ); |
| 149288 | + pSubst->nSelDepth--; |
| 149177 | 149289 | } |
| 149178 | 149290 | #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ |
| 149179 | 149291 | |
| 149180 | 149292 | #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) |
| 149181 | 149293 | /* |
| | @@ -149783,11 +149895,11 @@ |
| 149783 | 149895 | /* Defer deleting the Table object associated with the |
| 149784 | 149896 | ** subquery until code generation is |
| 149785 | 149897 | ** complete, since there may still exist Expr.pTab entries that |
| 149786 | 149898 | ** refer to the subquery even after flattening. Ticket #3346. |
| 149787 | 149899 | ** |
| 149788 | | - ** pSubitem->pTab is always non-NULL by test restrictions and tests above. |
| 149900 | + ** pSubitem->pSTab is always non-NULL by test restrictions and tests above. |
| 149789 | 149901 | */ |
| 149790 | 149902 | if( ALWAYS(pSubitem->pSTab!=0) ){ |
| 149791 | 149903 | Table *pTabToDel = pSubitem->pSTab; |
| 149792 | 149904 | if( pTabToDel->nTabRef==1 ){ |
| 149793 | 149905 | Parse *pToplevel = sqlite3ParseToplevel(pParse); |
| | @@ -149913,10 +150025,11 @@ |
| 149913 | 150025 | SubstContext x; |
| 149914 | 150026 | x.pParse = pParse; |
| 149915 | 150027 | x.iTable = iParent; |
| 149916 | 150028 | x.iNewTable = iNewParent; |
| 149917 | 150029 | x.isOuterJoin = isOuterJoin; |
| 150030 | + x.nSelDepth = 0; |
| 149918 | 150031 | x.pEList = pSub->pEList; |
| 149919 | 150032 | x.pCList = findLeftmostExprlist(pSub); |
| 149920 | 150033 | substSelect(&x, pParent, 0); |
| 149921 | 150034 | } |
| 149922 | 150035 | |
| | @@ -150498,10 +150611,11 @@ |
| 150498 | 150611 | unsetJoinExpr(pNew, -1, 1); |
| 150499 | 150612 | x.pParse = pParse; |
| 150500 | 150613 | x.iTable = pSrc->iCursor; |
| 150501 | 150614 | x.iNewTable = pSrc->iCursor; |
| 150502 | 150615 | x.isOuterJoin = 0; |
| 150616 | + x.nSelDepth = 0; |
| 150503 | 150617 | x.pEList = pSubq->pEList; |
| 150504 | 150618 | x.pCList = findLeftmostExprlist(pSubq); |
| 150505 | 150619 | pNew = substExpr(&x, pNew); |
| 150506 | 150620 | #ifndef SQLITE_OMIT_WINDOWFUNC |
| 150507 | 150621 | if( pSubq->pWin && 0==pushDownWindowCheck(pParse, pSubq, pNew) ){ |
| | @@ -150895,11 +151009,11 @@ |
| 150895 | 151009 | ** a WITH clause on the stack currently maintained by the parser (on the |
| 150896 | 151010 | ** pParse->pWith linked list). And if currently processing a CTE |
| 150897 | 151011 | ** CTE expression, through routine checks to see if the reference is |
| 150898 | 151012 | ** a recursive reference to the CTE. |
| 150899 | 151013 | ** |
| 150900 | | -** If pFrom matches a CTE according to either of these two above, pFrom->pTab |
| 151014 | +** If pFrom matches a CTE according to either of these two above, pFrom->pSTab |
| 150901 | 151015 | ** and other fields are populated accordingly. |
| 150902 | 151016 | ** |
| 150903 | 151017 | ** Return 0 if no match is found. |
| 150904 | 151018 | ** Return 1 if a match is found. |
| 150905 | 151019 | ** Return 2 if an error condition is detected. |
| | @@ -152521,10 +152635,86 @@ |
| 152521 | 152635 | pItem--; |
| 152522 | 152636 | if( pItem->fg.isSubquery ) return 0; /* (1c-i) */ |
| 152523 | 152637 | } |
| 152524 | 152638 | return 1; |
| 152525 | 152639 | } |
| 152640 | + |
| 152641 | +/* |
| 152642 | +** Argument pWhere is the WHERE clause belonging to SELECT statement p. This |
| 152643 | +** function attempts to transform expressions of the form: |
| 152644 | +** |
| 152645 | +** EXISTS (SELECT ...) |
| 152646 | +** |
| 152647 | +** into joins. For example, given |
| 152648 | +** |
| 152649 | +** CREATE TABLE sailors(sid INTEGER PRIMARY KEY, name TEXT); |
| 152650 | +** CREATE TABLE reserves(sid INT, day DATE, PRIMARY KEY(sid, day)); |
| 152651 | +** |
| 152652 | +** SELECT name FROM sailors AS S WHERE EXISTS ( |
| 152653 | +** SELECT * FROM reserves AS R WHERE S.sid = R.sid AND R.day = '2022-10-25' |
| 152654 | +** ); |
| 152655 | +** |
| 152656 | +** the SELECT statement may be transformed as follows: |
| 152657 | +** |
| 152658 | +** SELECT name FROM sailors AS S, reserves AS R |
| 152659 | +** WHERE S.sid = R.sid AND R.day = '2022-10-25'; |
| 152660 | +** |
| 152661 | +** **Approximately**. Really, we have to ensure that the FROM-clause term |
| 152662 | +** that was formerly inside the EXISTS is only executed once. This is handled |
| 152663 | +** by setting the SrcItem.fg.fromExists flag, which then causes code in |
| 152664 | +** the where.c file to exit the corresponding loop after the first successful |
| 152665 | +** match (if any). |
| 152666 | +*/ |
| 152667 | +static SQLITE_NOINLINE void existsToJoin( |
| 152668 | + Parse *pParse, /* Parsing context */ |
| 152669 | + Select *p, /* The SELECT statement being optimized */ |
| 152670 | + Expr *pWhere /* part of the WHERE clause currently being examined */ |
| 152671 | +){ |
| 152672 | + if( pWhere |
| 152673 | + && !ExprHasProperty(pWhere, EP_OuterON|EP_InnerON) |
| 152674 | + && p->pSrc->nSrc<BMS |
| 152675 | + && pParse->db->mallocFailed==0 |
| 152676 | + ){ |
| 152677 | + if( pWhere->op==TK_AND ){ |
| 152678 | + Expr *pRight = pWhere->pRight; |
| 152679 | + existsToJoin(pParse, p, pWhere->pLeft); |
| 152680 | + existsToJoin(pParse, p, pRight); |
| 152681 | + } |
| 152682 | + else if( pWhere->op==TK_EXISTS ){ |
| 152683 | + Select *pSub = pWhere->x.pSelect; |
| 152684 | + Expr *pSubWhere = pSub->pWhere; |
| 152685 | + if( pSub->pSrc->nSrc==1 |
| 152686 | + && (pSub->selFlags & SF_Aggregate)==0 |
| 152687 | + && !pSub->pSrc->a[0].fg.isSubquery |
| 152688 | + ){ |
| 152689 | + memset(pWhere, 0, sizeof(*pWhere)); |
| 152690 | + pWhere->op = TK_INTEGER; |
| 152691 | + pWhere->u.iValue = 1; |
| 152692 | + ExprSetProperty(pWhere, EP_IntValue); |
| 152693 | + |
| 152694 | + assert( p->pWhere!=0 ); |
| 152695 | + pSub->pSrc->a[0].fg.fromExists = 1; |
| 152696 | + pSub->pSrc->a[0].fg.jointype |= JT_CROSS; |
| 152697 | + p->pSrc = sqlite3SrcListAppendList(pParse, p->pSrc, pSub->pSrc); |
| 152698 | + if( pSubWhere ){ |
| 152699 | + p->pWhere = sqlite3PExpr(pParse, TK_AND, p->pWhere, pSubWhere); |
| 152700 | + pSub->pWhere = 0; |
| 152701 | + } |
| 152702 | + pSub->pSrc = 0; |
| 152703 | + sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pSub); |
| 152704 | +#if TREETRACE_ENABLED |
| 152705 | + if( sqlite3TreeTrace & 0x100000 ){ |
| 152706 | + TREETRACE(0x100000,pParse,p, |
| 152707 | + ("After EXISTS-to-JOIN optimization:\n")); |
| 152708 | + sqlite3TreeViewSelect(0, p, 0); |
| 152709 | + } |
| 152710 | +#endif |
| 152711 | + existsToJoin(pParse, p, pSubWhere); |
| 152712 | + } |
| 152713 | + } |
| 152714 | + } |
| 152715 | +} |
| 152526 | 152716 | |
| 152527 | 152717 | /* |
| 152528 | 152718 | ** Generate byte-code for the SELECT statement given in the p argument. |
| 152529 | 152719 | ** |
| 152530 | 152720 | ** The results are returned according to the SelectDest structure. |
| | @@ -152889,10 +153079,17 @@ |
| 152889 | 153079 | #endif |
| 152890 | 153080 | if( p->pNext==0 ) ExplainQueryPlanPop(pParse); |
| 152891 | 153081 | return rc; |
| 152892 | 153082 | } |
| 152893 | 153083 | #endif |
| 153084 | + |
| 153085 | + /* If there may be an "EXISTS (SELECT ...)" in the WHERE clause, attempt |
| 153086 | + ** to change it into a join. */ |
| 153087 | + if( pParse->bHasExists && OptimizationEnabled(db,SQLITE_ExistsToJoin) ){ |
| 153088 | + existsToJoin(pParse, p, p->pWhere); |
| 153089 | + pTabList = p->pSrc; |
| 153090 | + } |
| 152894 | 153091 | |
| 152895 | 153092 | /* Do the WHERE-clause constant propagation optimization if this is |
| 152896 | 153093 | ** a join. No need to spend time on this operation for non-join queries |
| 152897 | 153094 | ** as the equivalent optimization will be handled by query planner in |
| 152898 | 153095 | ** sqlite3WhereBegin(). tag-select-0330 |
| | @@ -153676,24 +153873,24 @@ |
| 153676 | 153873 | ** over to a0,a1,a2. It then calls the output subroutine |
| 153677 | 153874 | ** and resets the aggregate accumulator registers in preparation |
| 153678 | 153875 | ** for the next GROUP BY batch. |
| 153679 | 153876 | */ |
| 153680 | 153877 | sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); |
| 153681 | | - VdbeComment((v, "output one row")); |
| 153878 | + VdbeComment((v, "output one row of %d", p->selId)); |
| 153682 | 153879 | sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr); |
| 153683 | 153880 | sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); VdbeCoverage(v); |
| 153684 | 153881 | VdbeComment((v, "check abort flag")); |
| 153685 | 153882 | sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); |
| 153686 | | - VdbeComment((v, "reset accumulator")); |
| 153883 | + VdbeComment((v, "reset accumulator %d", p->selId)); |
| 153687 | 153884 | |
| 153688 | 153885 | /* Update the aggregate accumulators based on the content of |
| 153689 | 153886 | ** the current row |
| 153690 | 153887 | */ |
| 153691 | 153888 | sqlite3VdbeJumpHere(v, addr1); |
| 153692 | 153889 | updateAccumulator(pParse, iUseFlag, pAggInfo, eDist); |
| 153693 | 153890 | sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag); |
| 153694 | | - VdbeComment((v, "indicate data in accumulator")); |
| 153891 | + VdbeComment((v, "indicate data in accumulator %d", p->selId)); |
| 153695 | 153892 | |
| 153696 | 153893 | /* End of the loop |
| 153697 | 153894 | */ |
| 153698 | 153895 | if( groupBySort ){ |
| 153699 | 153896 | sqlite3VdbeAddOp2(v, OP_SorterNext, pAggInfo->sortingIdx,addrTopOfLoop); |
| | @@ -153706,11 +153903,11 @@ |
| 153706 | 153903 | sqlite3ExprListDelete(db, pDistinct); |
| 153707 | 153904 | |
| 153708 | 153905 | /* Output the final row of result |
| 153709 | 153906 | */ |
| 153710 | 153907 | sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); |
| 153711 | | - VdbeComment((v, "output final row")); |
| 153908 | + VdbeComment((v, "output final row of %d", p->selId)); |
| 153712 | 153909 | |
| 153713 | 153910 | /* Jump over the subroutines |
| 153714 | 153911 | */ |
| 153715 | 153912 | sqlite3VdbeGoto(v, addrEnd); |
| 153716 | 153913 | |
| | @@ -153727,26 +153924,26 @@ |
| 153727 | 153924 | sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); |
| 153728 | 153925 | sqlite3VdbeResolveLabel(v, addrOutputRow); |
| 153729 | 153926 | addrOutputRow = sqlite3VdbeCurrentAddr(v); |
| 153730 | 153927 | sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2); |
| 153731 | 153928 | VdbeCoverage(v); |
| 153732 | | - VdbeComment((v, "Groupby result generator entry point")); |
| 153929 | + VdbeComment((v, "Groupby result generator entry point %d", p->selId)); |
| 153733 | 153930 | sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); |
| 153734 | 153931 | finalizeAggFunctions(pParse, pAggInfo); |
| 153735 | 153932 | sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL); |
| 153736 | 153933 | selectInnerLoop(pParse, p, -1, &sSort, |
| 153737 | 153934 | &sDistinct, pDest, |
| 153738 | 153935 | addrOutputRow+1, addrSetAbort); |
| 153739 | 153936 | sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); |
| 153740 | | - VdbeComment((v, "end groupby result generator")); |
| 153937 | + VdbeComment((v, "end groupby result generator %d", p->selId)); |
| 153741 | 153938 | |
| 153742 | 153939 | /* Generate a subroutine that will reset the group-by accumulator |
| 153743 | 153940 | */ |
| 153744 | 153941 | sqlite3VdbeResolveLabel(v, addrReset); |
| 153745 | 153942 | resetAccumulator(pParse, pAggInfo); |
| 153746 | 153943 | sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag); |
| 153747 | | - VdbeComment((v, "indicate accumulator empty")); |
| 153944 | + VdbeComment((v, "indicate accumulator %d empty", p->selId)); |
| 153748 | 153945 | sqlite3VdbeAddOp1(v, OP_Return, regReset); |
| 153749 | 153946 | |
| 153750 | 153947 | if( distFlag!=0 && eDist!=WHERE_DISTINCT_NOOP ){ |
| 153751 | 153948 | struct AggInfo_func *pF = &pAggInfo->aFunc[0]; |
| 153752 | 153949 | fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr); |
| | @@ -159334,10 +159531,11 @@ |
| 159334 | 159531 | struct WhereLevel { |
| 159335 | 159532 | int iLeftJoin; /* Memory cell used to implement LEFT OUTER JOIN */ |
| 159336 | 159533 | int iTabCur; /* The VDBE cursor used to access the table */ |
| 159337 | 159534 | int iIdxCur; /* The VDBE cursor used to access pIdx */ |
| 159338 | 159535 | int addrBrk; /* Jump here to break out of the loop */ |
| 159536 | + int addrHalt; /* Abort the query due to empty table or similar */ |
| 159339 | 159537 | int addrNxt; /* Jump here to start the next IN combination */ |
| 159340 | 159538 | int addrSkip; /* Jump here for next iteration of skip-scan */ |
| 159341 | 159539 | int addrCont; /* Jump here to continue with the next loop cycle */ |
| 159342 | 159540 | int addrFirst; /* First instruction of interior of the loop */ |
| 159343 | 159541 | int addrBody; /* Beginning of the body of this loop */ |
| | @@ -160034,11 +160232,10 @@ |
| 160034 | 160232 | #if !defined(SQLITE_DEBUG) |
| 160035 | 160233 | if( sqlite3ParseToplevel(pParse)->explain==2 || IS_STMT_SCANSTATUS(pParse->db) ) |
| 160036 | 160234 | #endif |
| 160037 | 160235 | { |
| 160038 | 160236 | VdbeOp *pOp = sqlite3VdbeGetOp(pParse->pVdbe, addr); |
| 160039 | | - |
| 160040 | 160237 | SrcItem *pItem = &pTabList->a[pLevel->iFrom]; |
| 160041 | 160238 | sqlite3 *db = pParse->db; /* Database handle */ |
| 160042 | 160239 | int isSearch; /* True for a SEARCH. False for SCAN. */ |
| 160043 | 160240 | WhereLoop *pLoop; /* The controlling WhereLoop object */ |
| 160044 | 160241 | u32 flags; /* Flags that describe this loop */ |
| | @@ -160057,11 +160254,14 @@ |
| 160057 | 160254 | || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0)) |
| 160058 | 160255 | || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX)); |
| 160059 | 160256 | |
| 160060 | 160257 | sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH); |
| 160061 | 160258 | str.printfFlags = SQLITE_PRINTF_INTERNAL; |
| 160062 | | - sqlite3_str_appendf(&str, "%s %S", isSearch ? "SEARCH" : "SCAN", pItem); |
| 160259 | + sqlite3_str_appendf(&str, "%s %S%s", |
| 160260 | + isSearch ? "SEARCH" : "SCAN", |
| 160261 | + pItem, |
| 160262 | + pItem->fg.fromExists ? " EXISTS" : ""); |
| 160063 | 160263 | if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){ |
| 160064 | 160264 | const char *zFmt = 0; |
| 160065 | 160265 | Index *pIdx; |
| 160066 | 160266 | |
| 160067 | 160267 | assert( pLoop->u.btree.pIndex!=0 ); |
| | @@ -160506,11 +160706,13 @@ |
| 160506 | 160706 | for(i=iEq; i<pLoop->nLTerm; i++){ |
| 160507 | 160707 | if( pLoop->aLTerm[i]->pExpr==pX ){ |
| 160508 | 160708 | int iField; |
| 160509 | 160709 | assert( (pLoop->aLTerm[i]->eOperator & (WO_OR|WO_AND))==0 ); |
| 160510 | 160710 | iField = pLoop->aLTerm[i]->u.x.iField - 1; |
| 160511 | | - if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */ |
| 160711 | + if( NEVER(pOrigRhs->a[iField].pExpr==0) ){ |
| 160712 | + continue; /* Duplicate PK column */ |
| 160713 | + } |
| 160512 | 160714 | pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr); |
| 160513 | 160715 | pOrigRhs->a[iField].pExpr = 0; |
| 160514 | 160716 | if( pRhs ) pRhs->a[pRhs->nExpr-1].u.x.iOrderByCol = iField+1; |
| 160515 | 160717 | if( pOrigLhs ){ |
| 160516 | 160718 | assert( pOrigLhs->a[iField].pExpr!=0 ); |
| | @@ -160603,35 +160805,26 @@ |
| 160603 | 160805 | if( pLoop->aLTerm[i] && pLoop->aLTerm[i]->pExpr==pX ){ |
| 160604 | 160806 | disableTerm(pLevel, pTerm); |
| 160605 | 160807 | return; |
| 160606 | 160808 | } |
| 160607 | 160809 | } |
| 160608 | | - for(i=iEq;i<pLoop->nLTerm; i++){ |
| 160810 | + for(i=iEq; i<pLoop->nLTerm; i++){ |
| 160609 | 160811 | assert( pLoop->aLTerm[i]!=0 ); |
| 160610 | 160812 | if( pLoop->aLTerm[i]->pExpr==pX ) nEq++; |
| 160611 | 160813 | } |
| 160612 | 160814 | |
| 160613 | 160815 | iTab = 0; |
| 160614 | 160816 | if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){ |
| 160615 | 160817 | eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); |
| 160616 | 160818 | }else{ |
| 160617 | | - Expr *pExpr = pTerm->pExpr; |
| 160618 | | - if( pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){ |
| 160619 | | - sqlite3 *db = pParse->db; |
| 160620 | | - pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); |
| 160621 | | - if( !db->mallocFailed ){ |
| 160622 | | - aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); |
| 160623 | | - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab); |
| 160624 | | - pExpr->iTable = iTab; |
| 160625 | | - } |
| 160626 | | - sqlite3ExprDelete(db, pX); |
| 160627 | | - }else{ |
| 160628 | | - int n = sqlite3ExprVectorSize(pX->pLeft); |
| 160629 | | - aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*MAX(nEq,n)); |
| 160630 | | - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab); |
| 160631 | | - } |
| 160632 | | - pX = pExpr; |
| 160819 | + sqlite3 *db = pParse->db; |
| 160820 | + Expr *pXMod = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); |
| 160821 | + if( !db->mallocFailed ){ |
| 160822 | + aiMap = (int*)sqlite3DbMallocZero(db, sizeof(int)*nEq); |
| 160823 | + eType = sqlite3FindInIndex(pParse, pXMod, IN_INDEX_LOOP, 0, aiMap, &iTab); |
| 160824 | + } |
| 160825 | + sqlite3ExprDelete(db, pXMod); |
| 160633 | 160826 | } |
| 160634 | 160827 | |
| 160635 | 160828 | if( eType==IN_INDEX_INDEX_DESC ){ |
| 160636 | 160829 | testcase( bRev ); |
| 160637 | 160830 | bRev = !bRev; |
| | @@ -160657,11 +160850,11 @@ |
| 160657 | 160850 | sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn); |
| 160658 | 160851 | pIn = pLevel->u.in.aInLoop; |
| 160659 | 160852 | if( pIn ){ |
| 160660 | 160853 | int iMap = 0; /* Index in aiMap[] */ |
| 160661 | 160854 | pIn += i; |
| 160662 | | - for(i=iEq;i<pLoop->nLTerm; i++){ |
| 160855 | + for(i=iEq; i<pLoop->nLTerm; i++){ |
| 160663 | 160856 | if( pLoop->aLTerm[i]->pExpr==pX ){ |
| 160664 | 160857 | int iOut = iTarget + i - iEq; |
| 160665 | 160858 | if( eType==IN_INDEX_ROWID ){ |
| 160666 | 160859 | pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut); |
| 160667 | 160860 | }else{ |
| | @@ -161308,19 +161501,20 @@ |
| 161308 | 161501 | WhereInfo *pWInfo, /* Complete information about the WHERE clause */ |
| 161309 | 161502 | int iLevel, /* Which level of pWInfo->a[] should be coded */ |
| 161310 | 161503 | int addrNxt, /* Jump here to bypass inner loops */ |
| 161311 | 161504 | Bitmask notReady /* Loops that are not ready */ |
| 161312 | 161505 | ){ |
| 161506 | + int saved_addrBrk; |
| 161313 | 161507 | while( ++iLevel < pWInfo->nLevel ){ |
| 161314 | 161508 | WhereLevel *pLevel = &pWInfo->a[iLevel]; |
| 161315 | 161509 | WhereLoop *pLoop = pLevel->pWLoop; |
| 161316 | 161510 | if( pLevel->regFilter==0 ) continue; |
| 161317 | 161511 | if( pLevel->pWLoop->nSkip ) continue; |
| 161318 | 161512 | /* ,--- Because sqlite3ConstructBloomFilter() has will not have set |
| 161319 | 161513 | ** vvvvv--' pLevel->regFilter if this were true. */ |
| 161320 | 161514 | if( NEVER(pLoop->prereq & notReady) ) continue; |
| 161321 | | - assert( pLevel->addrBrk==0 ); |
| 161515 | + saved_addrBrk = pLevel->addrBrk; |
| 161322 | 161516 | pLevel->addrBrk = addrNxt; |
| 161323 | 161517 | if( pLoop->wsFlags & WHERE_IPK ){ |
| 161324 | 161518 | WhereTerm *pTerm = pLoop->aLTerm[0]; |
| 161325 | 161519 | int regRowid; |
| 161326 | 161520 | assert( pTerm!=0 ); |
| | @@ -161346,11 +161540,11 @@ |
| 161346 | 161540 | sqlite3VdbeAddOp4Int(pParse->pVdbe, OP_Filter, pLevel->regFilter, |
| 161347 | 161541 | addrNxt, r1, nEq); |
| 161348 | 161542 | VdbeCoverage(pParse->pVdbe); |
| 161349 | 161543 | } |
| 161350 | 161544 | pLevel->regFilter = 0; |
| 161351 | | - pLevel->addrBrk = 0; |
| 161545 | + pLevel->addrBrk = saved_addrBrk; |
| 161352 | 161546 | } |
| 161353 | 161547 | } |
| 161354 | 161548 | |
| 161355 | 161549 | /* |
| 161356 | 161550 | ** Loop pLoop is a WHERE_INDEXED level that uses at least one IN(...) |
| | @@ -161393,11 +161587,10 @@ |
| 161393 | 161587 | WhereClause *pWC; /* Decomposition of the entire WHERE clause */ |
| 161394 | 161588 | WhereTerm *pTerm; /* A WHERE clause term */ |
| 161395 | 161589 | sqlite3 *db; /* Database connection */ |
| 161396 | 161590 | SrcItem *pTabItem; /* FROM clause term being coded */ |
| 161397 | 161591 | int addrBrk; /* Jump here to break out of the loop */ |
| 161398 | | - int addrHalt; /* addrBrk for the outermost loop */ |
| 161399 | 161592 | int addrCont; /* Jump here to continue with next cycle */ |
| 161400 | 161593 | int iRowidReg = 0; /* Rowid is stored in this register, if not zero */ |
| 161401 | 161594 | int iReleaseReg = 0; /* Temp register to free before returning */ |
| 161402 | 161595 | Index *pIdx = 0; /* Index used by loop (if any) */ |
| 161403 | 161596 | int iLoop; /* Iteration of constraint generator loop */ |
| | @@ -161437,11 +161630,11 @@ |
| 161437 | 161630 | ** When there is an IN operator, we also have a "addrNxt" label that |
| 161438 | 161631 | ** means to continue with the next IN value combination. When |
| 161439 | 161632 | ** there are no IN operators in the constraints, the "addrNxt" label |
| 161440 | 161633 | ** is the same as "addrBrk". |
| 161441 | 161634 | */ |
| 161442 | | - addrBrk = pLevel->addrBrk = pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse); |
| 161635 | + addrBrk = pLevel->addrNxt = pLevel->addrBrk; |
| 161443 | 161636 | addrCont = pLevel->addrCont = sqlite3VdbeMakeLabel(pParse); |
| 161444 | 161637 | |
| 161445 | 161638 | /* If this is the right table of a LEFT OUTER JOIN, allocate and |
| 161446 | 161639 | ** initialize a memory cell that records if this table matches any |
| 161447 | 161640 | ** row of the left table of the join. |
| | @@ -161453,18 +161646,10 @@ |
| 161453 | 161646 | pLevel->iLeftJoin = ++pParse->nMem; |
| 161454 | 161647 | sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin); |
| 161455 | 161648 | VdbeComment((v, "init LEFT JOIN match flag")); |
| 161456 | 161649 | } |
| 161457 | 161650 | |
| 161458 | | - /* Compute a safe address to jump to if we discover that the table for |
| 161459 | | - ** this loop is empty and can never contribute content. */ |
| 161460 | | - for(j=iLevel; j>0; j--){ |
| 161461 | | - if( pWInfo->a[j].iLeftJoin ) break; |
| 161462 | | - if( pWInfo->a[j].pRJ ) break; |
| 161463 | | - } |
| 161464 | | - addrHalt = pWInfo->a[j].addrBrk; |
| 161465 | | - |
| 161466 | 161651 | /* Special case of a FROM clause subquery implemented as a co-routine */ |
| 161467 | 161652 | if( pTabItem->fg.viaCoroutine ){ |
| 161468 | 161653 | int regYield; |
| 161469 | 161654 | Subquery *pSubq; |
| 161470 | 161655 | assert( pTabItem->fg.isSubquery && pTabItem->u4.pSubq!=0 ); |
| | @@ -161699,11 +161884,11 @@ |
| 161699 | 161884 | VdbeCoverageIf(v, pX->op==TK_LE); |
| 161700 | 161885 | VdbeCoverageIf(v, pX->op==TK_LT); |
| 161701 | 161886 | VdbeCoverageIf(v, pX->op==TK_GE); |
| 161702 | 161887 | sqlite3ReleaseTempReg(pParse, rTemp); |
| 161703 | 161888 | }else{ |
| 161704 | | - sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrHalt); |
| 161889 | + sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, pLevel->addrHalt); |
| 161705 | 161890 | VdbeCoverageIf(v, bRev==0); |
| 161706 | 161891 | VdbeCoverageIf(v, bRev!=0); |
| 161707 | 161892 | } |
| 161708 | 161893 | if( pEnd ){ |
| 161709 | 161894 | Expr *pX; |
| | @@ -162494,11 +162679,11 @@ |
| 162494 | 162679 | pLevel->op = OP_Noop; |
| 162495 | 162680 | }else{ |
| 162496 | 162681 | codeCursorHint(pTabItem, pWInfo, pLevel, 0); |
| 162497 | 162682 | pLevel->op = aStep[bRev]; |
| 162498 | 162683 | pLevel->p1 = iCur; |
| 162499 | | - pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrHalt); |
| 162684 | + pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev],iCur,pLevel->addrHalt); |
| 162500 | 162685 | VdbeCoverageIf(v, bRev==0); |
| 162501 | 162686 | VdbeCoverageIf(v, bRev!=0); |
| 162502 | 162687 | pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; |
| 162503 | 162688 | } |
| 162504 | 162689 | } |
| | @@ -163805,11 +163990,11 @@ |
| 163805 | 163990 | if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; /* (1) */ |
| 163806 | 163991 | if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; /* (2) */ |
| 163807 | 163992 | if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* (3) */ |
| 163808 | 163993 | assert( pSrc!=0 ); |
| 163809 | 163994 | if( pExpr->op==TK_IS |
| 163810 | | - && pSrc->nSrc |
| 163995 | + && pSrc->nSrc>=2 |
| 163811 | 163996 | && (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 |
| 163812 | 163997 | ){ |
| 163813 | 163998 | return 0; /* (4) */ |
| 163814 | 163999 | } |
| 163815 | 164000 | aff1 = sqlite3ExprAffinity(pExpr->pLeft); |
| | @@ -164509,11 +164694,11 @@ |
| 164509 | 164694 | ** SELECT statement passed as the second argument. These terms are only |
| 164510 | 164695 | ** added if: |
| 164511 | 164696 | ** |
| 164512 | 164697 | ** 1. The SELECT statement has a LIMIT clause, and |
| 164513 | 164698 | ** 2. The SELECT statement is not an aggregate or DISTINCT query, and |
| 164514 | | -** 3. The SELECT statement has exactly one object in its from clause, and |
| 164699 | +** 3. The SELECT statement has exactly one object in its FROM clause, and |
| 164515 | 164700 | ** that object is a virtual table, and |
| 164516 | 164701 | ** 4. There are no terms in the WHERE clause that will not be passed |
| 164517 | 164702 | ** to the virtual table xBestIndex method. |
| 164518 | 164703 | ** 5. The ORDER BY clause, if any, will be made available to the xBestIndex |
| 164519 | 164704 | ** method. |
| | @@ -164546,12 +164731,26 @@ |
| 164546 | 164731 | ** pWC->a[] array. So this term can be ignored, as a LIMIT clause |
| 164547 | 164732 | ** will only be added if each of the child terms passes the |
| 164548 | 164733 | ** (leftCursor==iCsr) test below. */ |
| 164549 | 164734 | continue; |
| 164550 | 164735 | } |
| 164551 | | - if( pWC->a[ii].leftCursor!=iCsr ) return; |
| 164552 | | - if( pWC->a[ii].prereqRight!=0 ) return; |
| 164736 | + if( pWC->a[ii].leftCursor==iCsr && pWC->a[ii].prereqRight==0 ) continue; |
| 164737 | + |
| 164738 | + /* If this term has a parent with exactly one child, and the parent will |
| 164739 | + ** be passed through to xBestIndex, then this term can be ignored. */ |
| 164740 | + if( pWC->a[ii].iParent>=0 ){ |
| 164741 | + WhereTerm *pParent = &pWC->a[ pWC->a[ii].iParent ]; |
| 164742 | + if( pParent->leftCursor==iCsr |
| 164743 | + && pParent->prereqRight==0 |
| 164744 | + && pParent->nChild==1 |
| 164745 | + ){ |
| 164746 | + continue; |
| 164747 | + } |
| 164748 | + } |
| 164749 | + |
| 164750 | + /* This term will not be passed through. Do not add a LIMIT clause. */ |
| 164751 | + return; |
| 164553 | 164752 | } |
| 164554 | 164753 | |
| 164555 | 164754 | /* Check condition (5). Return early if it is not met. */ |
| 164556 | 164755 | if( pOrderBy ){ |
| 164557 | 164756 | for(ii=0; ii<pOrderBy->nExpr; ii++){ |
| | @@ -165986,11 +166185,13 @@ |
| 165986 | 166185 | sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSubq->addrFillSub); |
| 165987 | 166186 | addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield); |
| 165988 | 166187 | VdbeCoverage(v); |
| 165989 | 166188 | VdbeComment((v, "next row of %s", pSrc->pSTab->zName)); |
| 165990 | 166189 | }else{ |
| 165991 | | - addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v); |
| 166190 | + assert( pLevel->addrHalt ); |
| 166191 | + addrTop = sqlite3VdbeAddOp2(v, OP_Rewind,pLevel->iTabCur,pLevel->addrHalt); |
| 166192 | + VdbeCoverage(v); |
| 165992 | 166193 | } |
| 165993 | 166194 | if( pPartial ){ |
| 165994 | 166195 | iContinue = sqlite3VdbeMakeLabel(pParse); |
| 165995 | 166196 | sqlite3ExprIfFalse(pParse, pPartial, iContinue, SQLITE_JUMPIFNULL); |
| 165996 | 166197 | pLoop->wsFlags |= WHERE_PARTIALIDX; |
| | @@ -166014,15 +166215,18 @@ |
| 166014 | 166215 | assert( pLevel->iIdxCur>0 ); |
| 166015 | 166216 | translateColumnToCopy(pParse, addrTop, pLevel->iTabCur, |
| 166016 | 166217 | pSrc->u4.pSubq->regResult, pLevel->iIdxCur); |
| 166017 | 166218 | sqlite3VdbeGoto(v, addrTop); |
| 166018 | 166219 | pSrc->fg.viaCoroutine = 0; |
| 166220 | + sqlite3VdbeJumpHere(v, addrTop); |
| 166019 | 166221 | }else{ |
| 166020 | 166222 | sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v); |
| 166021 | 166223 | sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX); |
| 166224 | + if( (pSrc->fg.jointype & JT_LEFT)!=0 ){ |
| 166225 | + sqlite3VdbeJumpHere(v, addrTop); |
| 166226 | + } |
| 166022 | 166227 | } |
| 166023 | | - sqlite3VdbeJumpHere(v, addrTop); |
| 166024 | 166228 | sqlite3ReleaseTempReg(pParse, regRecord); |
| 166025 | 166229 | |
| 166026 | 166230 | /* Jump here when skipping the initialization */ |
| 166027 | 166231 | sqlite3VdbeJumpHere(v, addrInit); |
| 166028 | 166232 | sqlite3VdbeScanStatusRange(v, addrExp, addrExp, -1); |
| | @@ -168019,19 +168223,33 @@ |
| 168019 | 168223 | if( eOp & WO_IN ){ |
| 168020 | 168224 | Expr *pExpr = pTerm->pExpr; |
| 168021 | 168225 | if( ExprUseXSelect(pExpr) ){ |
| 168022 | 168226 | /* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */ |
| 168023 | 168227 | int i; |
| 168228 | + int bRedundant = 0; |
| 168024 | 168229 | nIn = 46; assert( 46==sqlite3LogEst(25) ); |
| 168025 | 168230 | |
| 168026 | 168231 | /* The expression may actually be of the form (x, y) IN (SELECT...). |
| 168027 | 168232 | ** In this case there is a separate term for each of (x) and (y). |
| 168028 | 168233 | ** However, the nIn multiplier should only be applied once, not once |
| 168029 | 168234 | ** for each such term. The following loop checks that pTerm is the |
| 168030 | 168235 | ** first such term in use, and sets nIn back to 0 if it is not. */ |
| 168031 | 168236 | for(i=0; i<pNew->nLTerm-1; i++){ |
| 168032 | | - if( pNew->aLTerm[i] && pNew->aLTerm[i]->pExpr==pExpr ) nIn = 0; |
| 168237 | + if( pNew->aLTerm[i] && pNew->aLTerm[i]->pExpr==pExpr ){ |
| 168238 | + nIn = 0; |
| 168239 | + if( pNew->aLTerm[i]->u.x.iField == pTerm->u.x.iField ){ |
| 168240 | + /* Detect when two or more columns of an index match the same |
| 168241 | + ** column of a vector IN operater, and avoid adding the column |
| 168242 | + ** to the WhereLoop more than once. See tag-20250707-01 |
| 168243 | + ** in test/rowvalue.test */ |
| 168244 | + bRedundant = 1; |
| 168245 | + } |
| 168246 | + } |
| 168247 | + } |
| 168248 | + if( bRedundant ){ |
| 168249 | + pNew->nLTerm--; |
| 168250 | + continue; |
| 168033 | 168251 | } |
| 168034 | 168252 | }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){ |
| 168035 | 168253 | /* "x IN (value, value, ...)" */ |
| 168036 | 168254 | nIn = sqlite3LogEst(pExpr->x.pList->nExpr); |
| 168037 | 168255 | } |
| | @@ -168259,11 +168477,11 @@ |
| 168259 | 168477 | } |
| 168260 | 168478 | |
| 168261 | 168479 | if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 |
| 168262 | 168480 | && pNew->u.btree.nEq<pProbe->nColumn |
| 168263 | 168481 | && (pNew->u.btree.nEq<pProbe->nKeyCol || |
| 168264 | | - (pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY && !pProbe->bIdxRowid)) |
| 168482 | + pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY) |
| 168265 | 168483 | ){ |
| 168266 | 168484 | if( pNew->u.btree.nEq>3 ){ |
| 168267 | 168485 | sqlite3ProgressCheck(pParse); |
| 168268 | 168486 | } |
| 168269 | 168487 | whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn); |
| | @@ -168298,10 +168516,11 @@ |
| 168298 | 168516 | && saved_nEq==pNew->nLTerm |
| 168299 | 168517 | && pProbe->noSkipScan==0 |
| 168300 | 168518 | && pProbe->hasStat1!=0 |
| 168301 | 168519 | && OptimizationEnabled(db, SQLITE_SkipScan) |
| 168302 | 168520 | && pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */ |
| 168521 | + && pSrc->fg.fromExists==0 |
| 168303 | 168522 | && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK |
| 168304 | 168523 | ){ |
| 168305 | 168524 | LogEst nIter; |
| 168306 | 168525 | pNew->u.btree.nEq++; |
| 168307 | 168526 | pNew->nSkip++; |
| | @@ -171855,10 +172074,18 @@ |
| 171855 | 172074 | |
| 171856 | 172075 | pTabItem = &pTabList->a[pLevel->iFrom]; |
| 171857 | 172076 | pTab = pTabItem->pSTab; |
| 171858 | 172077 | iDb = sqlite3SchemaToIndex(db, pTab->pSchema); |
| 171859 | 172078 | pLoop = pLevel->pWLoop; |
| 172079 | + pLevel->addrBrk = sqlite3VdbeMakeLabel(pParse); |
| 172080 | + if( ii==0 || (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){ |
| 172081 | + pLevel->addrHalt = pLevel->addrBrk; |
| 172082 | + }else if( pWInfo->a[ii-1].pRJ ){ |
| 172083 | + pLevel->addrHalt = pWInfo->a[ii-1].addrBrk; |
| 172084 | + }else{ |
| 172085 | + pLevel->addrHalt = pWInfo->a[ii-1].addrHalt; |
| 172086 | + } |
| 171860 | 172087 | if( (pTab->tabFlags & TF_Ephemeral)!=0 || IsView(pTab) ){ |
| 171861 | 172088 | /* Do nothing */ |
| 171862 | 172089 | }else |
| 171863 | 172090 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 171864 | 172091 | if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){ |
| | @@ -171906,10 +172133,17 @@ |
| 171906 | 172133 | } |
| 171907 | 172134 | #ifdef SQLITE_ENABLE_COLUMN_USED_MASK |
| 171908 | 172135 | sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, pTabItem->iCursor, 0, 0, |
| 171909 | 172136 | (const u8*)&pTabItem->colUsed, P4_INT64); |
| 171910 | 172137 | #endif |
| 172138 | + if( ii>=2 |
| 172139 | + && (pTabItem[0].fg.jointype & (JT_LTORJ|JT_LEFT))==0 |
| 172140 | + && pLevel->addrHalt==pWInfo->a[0].addrHalt |
| 172141 | + ){ |
| 172142 | + sqlite3VdbeAddOp2(v, OP_IfEmpty, pTabItem->iCursor, pWInfo->iBreak); |
| 172143 | + VdbeCoverage(v); |
| 172144 | + } |
| 171911 | 172145 | }else{ |
| 171912 | 172146 | sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); |
| 171913 | 172147 | } |
| 171914 | 172148 | if( pLoop->wsFlags & WHERE_INDEXED ){ |
| 171915 | 172149 | Index *pIx = pLoop->u.btree.pIndex; |
| | @@ -172162,10 +172396,13 @@ |
| 172162 | 172396 | VdbeCoverageIf(v, op==OP_SeekLT); |
| 172163 | 172397 | VdbeCoverageIf(v, op==OP_SeekGT); |
| 172164 | 172398 | sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2); |
| 172165 | 172399 | } |
| 172166 | 172400 | #endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */ |
| 172401 | + if( pTabList->a[pLevel->iFrom].fg.fromExists ){ |
| 172402 | + sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2); |
| 172403 | + } |
| 172167 | 172404 | /* The common case: Advance to the next row */ |
| 172168 | 172405 | if( pLevel->addrCont ) sqlite3VdbeResolveLabel(v, pLevel->addrCont); |
| 172169 | 172406 | sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3); |
| 172170 | 172407 | sqlite3VdbeChangeP5(v, pLevel->p5); |
| 172171 | 172408 | VdbeCoverage(v); |
| | @@ -180234,16 +180471,25 @@ |
| 180234 | 180471 | /* Expressions of the form |
| 180235 | 180472 | ** |
| 180236 | 180473 | ** expr1 IN () |
| 180237 | 180474 | ** expr1 NOT IN () |
| 180238 | 180475 | ** |
| 180239 | | - ** simplify to constants 0 (false) and 1 (true), respectively, |
| 180240 | | - ** regardless of the value of expr1. |
| 180476 | + ** simplify to constants 0 (false) and 1 (true), respectively. |
| 180477 | + ** |
| 180478 | + ** Except, do not apply this optimization if expr1 contains a function |
| 180479 | + ** because that function might be an aggregate (we don't know yet whether |
| 180480 | + ** it is or not) and if it is an aggregate, that could change the meaning |
| 180481 | + ** of the whole query. |
| 180241 | 180482 | */ |
| 180242 | | - sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy590); |
| 180243 | | - yymsp[-4].minor.yy590 = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy502 ? "true" : "false"); |
| 180244 | | - if( yymsp[-4].minor.yy590 ) sqlite3ExprIdToTrueFalse(yymsp[-4].minor.yy590); |
| 180483 | + Expr *pB = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy502 ? "true" : "false"); |
| 180484 | + if( pB ) sqlite3ExprIdToTrueFalse(pB); |
| 180485 | + if( !ExprHasProperty(yymsp[-4].minor.yy590, EP_HasFunc) ){ |
| 180486 | + sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy590); |
| 180487 | + yymsp[-4].minor.yy590 = pB; |
| 180488 | + }else{ |
| 180489 | + yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, yymsp[-3].minor.yy502 ? TK_OR : TK_AND, pB, yymsp[-4].minor.yy590); |
| 180490 | + } |
| 180245 | 180491 | }else{ |
| 180246 | 180492 | Expr *pRHS = yymsp[-1].minor.yy402->a[0].pExpr; |
| 180247 | 180493 | if( yymsp[-1].minor.yy402->nExpr==1 && sqlite3ExprIsConstant(pParse,pRHS) && yymsp[-4].minor.yy590->op!=TK_VECTOR ){ |
| 180248 | 180494 | yymsp[-1].minor.yy402->a[0].pExpr = 0; |
| 180249 | 180495 | sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy402); |
| | @@ -181845,11 +182091,11 @@ |
| 181845 | 182091 | static int getToken(const unsigned char **pz){ |
| 181846 | 182092 | const unsigned char *z = *pz; |
| 181847 | 182093 | int t; /* Token type to return */ |
| 181848 | 182094 | do { |
| 181849 | 182095 | z += sqlite3GetToken(z, &t); |
| 181850 | | - }while( t==TK_SPACE ); |
| 182096 | + }while( t==TK_SPACE || t==TK_COMMENT ); |
| 181851 | 182097 | if( t==TK_ID |
| 181852 | 182098 | || t==TK_STRING |
| 181853 | 182099 | || t==TK_JOIN_KW |
| 181854 | 182100 | || t==TK_WINDOW |
| 181855 | 182101 | || t==TK_OVER |
| | @@ -247032,22 +247278,24 @@ |
| 247032 | 247278 | if( pLast ){ |
| 247033 | 247279 | int iOff; |
| 247034 | 247280 | fts5DataRelease(pIter->pLeaf); |
| 247035 | 247281 | pIter->pLeaf = pLast; |
| 247036 | 247282 | pIter->iLeafPgno = pgnoLast; |
| 247037 | | - iOff = fts5LeafFirstRowidOff(pLast); |
| 247038 | | - if( iOff>pLast->szLeaf ){ |
| 247039 | | - FTS5_CORRUPT_ITER(p, pIter); |
| 247040 | | - return; |
| 247041 | | - } |
| 247042 | | - iOff += fts5GetVarint(&pLast->p[iOff], (u64*)&pIter->iRowid); |
| 247043 | | - pIter->iLeafOffset = iOff; |
| 247044 | | - |
| 247045 | | - if( fts5LeafIsTermless(pLast) ){ |
| 247046 | | - pIter->iEndofDoclist = pLast->nn+1; |
| 247047 | | - }else{ |
| 247048 | | - pIter->iEndofDoclist = fts5LeafFirstTermOff(pLast); |
| 247283 | + if( p->rc==SQLITE_OK ){ |
| 247284 | + iOff = fts5LeafFirstRowidOff(pLast); |
| 247285 | + if( iOff>pLast->szLeaf ){ |
| 247286 | + FTS5_CORRUPT_ITER(p, pIter); |
| 247287 | + return; |
| 247288 | + } |
| 247289 | + iOff += fts5GetVarint(&pLast->p[iOff], (u64*)&pIter->iRowid); |
| 247290 | + pIter->iLeafOffset = iOff; |
| 247291 | + |
| 247292 | + if( fts5LeafIsTermless(pLast) ){ |
| 247293 | + pIter->iEndofDoclist = pLast->nn+1; |
| 247294 | + }else{ |
| 247295 | + pIter->iEndofDoclist = fts5LeafFirstTermOff(pLast); |
| 247296 | + } |
| 247049 | 247297 | } |
| 247050 | 247298 | } |
| 247051 | 247299 | |
| 247052 | 247300 | fts5SegIterReverseInitPage(p, pIter); |
| 247053 | 247301 | } |
| | @@ -250396,11 +250644,11 @@ |
| 250396 | 250644 | } |
| 250397 | 250645 | assert( pStruct->aLevel[i].nMerge<=nThis ); |
| 250398 | 250646 | } |
| 250399 | 250647 | |
| 250400 | 250648 | nByte += (((i64)pStruct->nLevel)+1) * sizeof(Fts5StructureLevel); |
| 250401 | | - assert( nByte==SZ_FTS5STRUCTURE(pStruct->nLevel+2) ); |
| 250649 | + assert( nByte==(i64)SZ_FTS5STRUCTURE(pStruct->nLevel+2) ); |
| 250402 | 250650 | pNew = (Fts5Structure*)sqlite3Fts5MallocZero(&p->rc, nByte); |
| 250403 | 250651 | |
| 250404 | 250652 | if( pNew ){ |
| 250405 | 250653 | Fts5StructureLevel *pLvl; |
| 250406 | 250654 | nByte = nSeg * sizeof(Fts5StructureSegment); |
| | @@ -252835,23 +253083,31 @@ |
| 252835 | 253083 | } |
| 252836 | 253084 | |
| 252837 | 253085 | /* |
| 252838 | 253086 | ** This function is also purely an internal test. It does not contribute to |
| 252839 | 253087 | ** FTS functionality, or even the integrity-check, in any way. |
| 253088 | +** |
| 253089 | +** This function sets output variable (*pbFail) to true if the test fails. Or |
| 253090 | +** leaves it unchanged if the test succeeds. |
| 252840 | 253091 | */ |
| 252841 | 253092 | static void fts5TestTerm( |
| 252842 | 253093 | Fts5Index *p, |
| 252843 | 253094 | Fts5Buffer *pPrev, /* Previous term */ |
| 252844 | 253095 | const char *z, int n, /* Possibly new term to test */ |
| 252845 | 253096 | u64 expected, |
| 252846 | | - u64 *pCksum |
| 253097 | + u64 *pCksum, |
| 253098 | + int *pbFail |
| 252847 | 253099 | ){ |
| 252848 | 253100 | int rc = p->rc; |
| 252849 | 253101 | if( pPrev->n==0 ){ |
| 252850 | 253102 | fts5BufferSet(&rc, pPrev, n, (const u8*)z); |
| 252851 | 253103 | }else |
| 252852 | | - if( rc==SQLITE_OK && (pPrev->n!=n || memcmp(pPrev->p, z, n)) ){ |
| 253104 | + if( *pbFail==0 |
| 253105 | + && rc==SQLITE_OK |
| 253106 | + && (pPrev->n!=n || memcmp(pPrev->p, z, n)) |
| 253107 | + && (p->pHash==0 || p->pHash->nEntry==0) |
| 253108 | + ){ |
| 252853 | 253109 | u64 cksum3 = *pCksum; |
| 252854 | 253110 | const char *zTerm = (const char*)&pPrev->p[1]; /* term sans prefix-byte */ |
| 252855 | 253111 | int nTerm = pPrev->n-1; /* Size of zTerm in bytes */ |
| 252856 | 253112 | int iIdx = (pPrev->p[0] - FTS5_MAIN_PREFIX); |
| 252857 | 253113 | int flags = (iIdx==0 ? 0 : FTS5INDEX_QUERY_PREFIX); |
| | @@ -252897,20 +253153,20 @@ |
| 252897 | 253153 | |
| 252898 | 253154 | cksum3 ^= ck1; |
| 252899 | 253155 | fts5BufferSet(&rc, pPrev, n, (const u8*)z); |
| 252900 | 253156 | |
| 252901 | 253157 | if( rc==SQLITE_OK && cksum3!=expected ){ |
| 252902 | | - rc = FTS5_CORRUPT; |
| 253158 | + *pbFail = 1; |
| 252903 | 253159 | } |
| 252904 | 253160 | *pCksum = cksum3; |
| 252905 | 253161 | } |
| 252906 | 253162 | p->rc = rc; |
| 252907 | 253163 | } |
| 252908 | 253164 | |
| 252909 | 253165 | #else |
| 252910 | 253166 | # define fts5TestDlidxReverse(x,y,z) |
| 252911 | | -# define fts5TestTerm(u,v,w,x,y,z) |
| 253167 | +# define fts5TestTerm(t,u,v,w,x,y,z) |
| 252912 | 253168 | #endif |
| 252913 | 253169 | |
| 252914 | 253170 | /* |
| 252915 | 253171 | ** Check that: |
| 252916 | 253172 | ** |
| | @@ -253164,10 +253420,11 @@ |
| 253164 | 253420 | |
| 253165 | 253421 | #ifdef SQLITE_DEBUG |
| 253166 | 253422 | /* Used by extra internal tests only run if NDEBUG is not defined */ |
| 253167 | 253423 | u64 cksum3 = 0; /* Checksum based on contents of indexes */ |
| 253168 | 253424 | Fts5Buffer term = {0,0,0}; /* Buffer used to hold most recent term */ |
| 253425 | + int bTestFail = 0; |
| 253169 | 253426 | #endif |
| 253170 | 253427 | const int flags = FTS5INDEX_QUERY_NOOUTPUT; |
| 253171 | 253428 | |
| 253172 | 253429 | /* Load the FTS index structure */ |
| 253173 | 253430 | pStruct = fts5StructureRead(p); |
| | @@ -253206,11 +253463,11 @@ |
| 253206 | 253463 | int iOff = 0; /* Offset within poslist */ |
| 253207 | 253464 | i64 iRowid = fts5MultiIterRowid(pIter); |
| 253208 | 253465 | char *z = (char*)fts5MultiIterTerm(pIter, &n); |
| 253209 | 253466 | |
| 253210 | 253467 | /* If this is a new term, query for it. Update cksum3 with the results. */ |
| 253211 | | - fts5TestTerm(p, &term, z, n, cksum2, &cksum3); |
| 253468 | + fts5TestTerm(p, &term, z, n, cksum2, &cksum3, &bTestFail); |
| 253212 | 253469 | if( p->rc ) break; |
| 253213 | 253470 | |
| 253214 | 253471 | if( eDetail==FTS5_DETAIL_NONE ){ |
| 253215 | 253472 | if( 0==fts5MultiIterIsEmpty(p, pIter) ){ |
| 253216 | 253473 | cksum2 ^= sqlite3Fts5IndexEntryCksum(iRowid, 0, 0, -1, z, n); |
| | @@ -253224,24 +253481,30 @@ |
| 253224 | 253481 | int iTokOff = FTS5_POS2OFFSET(iPos); |
| 253225 | 253482 | cksum2 ^= sqlite3Fts5IndexEntryCksum(iRowid, iCol, iTokOff, -1, z, n); |
| 253226 | 253483 | } |
| 253227 | 253484 | } |
| 253228 | 253485 | } |
| 253229 | | - fts5TestTerm(p, &term, 0, 0, cksum2, &cksum3); |
| 253486 | + fts5TestTerm(p, &term, 0, 0, cksum2, &cksum3, &bTestFail); |
| 253230 | 253487 | |
| 253231 | 253488 | fts5MultiIterFree(pIter); |
| 253232 | 253489 | if( p->rc==SQLITE_OK && bUseCksum && cksum!=cksum2 ){ |
| 253233 | 253490 | p->rc = FTS5_CORRUPT; |
| 253234 | 253491 | sqlite3Fts5ConfigErrmsg(p->pConfig, |
| 253235 | 253492 | "fts5: checksum mismatch for table \"%s\"", p->pConfig->zName |
| 253236 | 253493 | ); |
| 253237 | 253494 | } |
| 253238 | | - |
| 253239 | | - fts5StructureRelease(pStruct); |
| 253240 | 253495 | #ifdef SQLITE_DEBUG |
| 253496 | + /* In SQLITE_DEBUG builds, expensive extra checks were run as part of |
| 253497 | + ** the integrity-check above. If no other errors were detected, but one |
| 253498 | + ** of these tests failed, set the result to SQLITE_CORRUPT_VTAB here. */ |
| 253499 | + if( p->rc==SQLITE_OK && bTestFail ){ |
| 253500 | + p->rc = FTS5_CORRUPT; |
| 253501 | + } |
| 253241 | 253502 | fts5BufferFree(&term); |
| 253242 | 253503 | #endif |
| 253504 | + |
| 253505 | + fts5StructureRelease(pStruct); |
| 253243 | 253506 | fts5BufferFree(&poslist); |
| 253244 | 253507 | return fts5IndexReturn(p); |
| 253245 | 253508 | } |
| 253246 | 253509 | |
| 253247 | 253510 | /************************************************************************* |
| | @@ -257648,11 +257911,11 @@ |
| 257648 | 257911 | int nArg, /* Number of args */ |
| 257649 | 257912 | sqlite3_value **apUnused /* Function arguments */ |
| 257650 | 257913 | ){ |
| 257651 | 257914 | assert( nArg==0 ); |
| 257652 | 257915 | UNUSED_PARAM2(nArg, apUnused); |
| 257653 | | - sqlite3_result_text(pCtx, "fts5: 2025-06-30 16:41:40 0083d5169a46104a25355bdd9d5a2f4027b049191ebda571dd228477ec217296", -1, SQLITE_TRANSIENT); |
| 257916 | + sqlite3_result_text(pCtx, "fts5: 2025-07-08 19:02:26 043ff54fb746c54bc6cfa6aa8c8a32c876c09d36163125916ad01024b98d447b", -1, SQLITE_TRANSIENT); |
| 257654 | 257917 | } |
| 257655 | 257918 | |
| 257656 | 257919 | /* |
| 257657 | 257920 | ** Implementation of fts5_locale(LOCALE, TEXT) function. |
| 257658 | 257921 | ** |
| 257659 | 257922 | |