Fossil SCM
Update the built-in SQLite to the latest 3.8.6 beta from upstream.
Commit
f05e0025708d0328ce51633aa9a550ad33f6e98c
Parent
b6a5023faefffef…
2 files changed
+353
-204
+1
-1
+353
-204
| --- src/sqlite3.c | ||
| +++ src/sqlite3.c | ||
| @@ -222,11 +222,11 @@ | ||
| 222 | 222 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 223 | 223 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 224 | 224 | */ |
| 225 | 225 | #define SQLITE_VERSION "3.8.6" |
| 226 | 226 | #define SQLITE_VERSION_NUMBER 3008006 |
| 227 | -#define SQLITE_SOURCE_ID "2014-07-31 18:54:01 1e5489faff093d6a8e538061e45532f9050e9459" | |
| 227 | +#define SQLITE_SOURCE_ID "2014-08-06 00:29:06 0ad1ed8ef0b5fb5d8db44479373b2b93d8fcfd66" | |
| 228 | 228 | |
| 229 | 229 | /* |
| 230 | 230 | ** CAPI3REF: Run-Time Library Version Numbers |
| 231 | 231 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 232 | 232 | ** |
| @@ -9407,11 +9407,11 @@ | ||
| 9407 | 9407 | #define OP_FkCounter 131 /* synopsis: fkctr[P1]+=P2 */ |
| 9408 | 9408 | #define OP_FkIfZero 132 /* synopsis: if fkctr[P1]==0 goto P2 */ |
| 9409 | 9409 | #define OP_Real 133 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ |
| 9410 | 9410 | #define OP_MemMax 134 /* synopsis: r[P1]=max(r[P1],r[P2]) */ |
| 9411 | 9411 | #define OP_IfPos 135 /* synopsis: if r[P1]>0 goto P2 */ |
| 9412 | -#define OP_IfNeg 136 /* synopsis: if r[P1]<0 goto P2 */ | |
| 9412 | +#define OP_IfNeg 136 /* synopsis: r[P1]+=P3, if r[P1]<0 goto P2 */ | |
| 9413 | 9413 | #define OP_IfZero 137 /* synopsis: r[P1]+=P3, if r[P1]==0 goto P2 */ |
| 9414 | 9414 | #define OP_AggFinal 138 /* synopsis: accum=r[P1] N=P2 */ |
| 9415 | 9415 | #define OP_IncrVacuum 139 |
| 9416 | 9416 | #define OP_Expire 140 |
| 9417 | 9417 | #define OP_TableLock 141 /* synopsis: iDb=P1 root=P2 write=P3 */ |
| @@ -10370,22 +10370,22 @@ | ||
| 10370 | 10370 | Hash trigHash; /* All triggers indexed by name */ |
| 10371 | 10371 | Hash fkeyHash; /* All foreign keys by referenced table name */ |
| 10372 | 10372 | Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */ |
| 10373 | 10373 | u8 file_format; /* Schema format version for this file */ |
| 10374 | 10374 | u8 enc; /* Text encoding used by this database */ |
| 10375 | - u16 flags; /* Flags associated with this schema */ | |
| 10375 | + u16 schemaFlags; /* Flags associated with this schema */ | |
| 10376 | 10376 | int cache_size; /* Number of pages to use in the cache */ |
| 10377 | 10377 | }; |
| 10378 | 10378 | |
| 10379 | 10379 | /* |
| 10380 | 10380 | ** These macros can be used to test, set, or clear bits in the |
| 10381 | 10381 | ** Db.pSchema->flags field. |
| 10382 | 10382 | */ |
| 10383 | -#define DbHasProperty(D,I,P) (((D)->aDb[I].pSchema->flags&(P))==(P)) | |
| 10384 | -#define DbHasAnyProperty(D,I,P) (((D)->aDb[I].pSchema->flags&(P))!=0) | |
| 10385 | -#define DbSetProperty(D,I,P) (D)->aDb[I].pSchema->flags|=(P) | |
| 10386 | -#define DbClearProperty(D,I,P) (D)->aDb[I].pSchema->flags&=~(P) | |
| 10383 | +#define DbHasProperty(D,I,P) (((D)->aDb[I].pSchema->schemaFlags&(P))==(P)) | |
| 10384 | +#define DbHasAnyProperty(D,I,P) (((D)->aDb[I].pSchema->schemaFlags&(P))!=0) | |
| 10385 | +#define DbSetProperty(D,I,P) (D)->aDb[I].pSchema->schemaFlags|=(P) | |
| 10386 | +#define DbClearProperty(D,I,P) (D)->aDb[I].pSchema->schemaFlags&=~(P) | |
| 10387 | 10387 | |
| 10388 | 10388 | /* |
| 10389 | 10389 | ** Allowed values for the DB.pSchema->flags field. |
| 10390 | 10390 | ** |
| 10391 | 10391 | ** The DB_SchemaLoaded flag is set after the database schema has been |
| @@ -11214,10 +11214,13 @@ | ||
| 11214 | 11214 | #define SQLITE_IDXTYPE_PRIMARYKEY 2 /* Is the PRIMARY KEY for the table */ |
| 11215 | 11215 | |
| 11216 | 11216 | /* Return true if index X is a PRIMARY KEY index */ |
| 11217 | 11217 | #define IsPrimaryKeyIndex(X) ((X)->idxType==SQLITE_IDXTYPE_PRIMARYKEY) |
| 11218 | 11218 | |
| 11219 | +/* Return true if index X is a UNIQUE index */ | |
| 11220 | +#define IsUniqueIndex(X) ((X)->onError!=OE_None) | |
| 11221 | + | |
| 11219 | 11222 | /* |
| 11220 | 11223 | ** Each sample stored in the sqlite_stat3 table is represented in memory |
| 11221 | 11224 | ** using a structure of this type. See documentation at the top of the |
| 11222 | 11225 | ** analyze.c source file for additional information. |
| 11223 | 11226 | */ |
| @@ -13082,15 +13085,25 @@ | ||
| 13082 | 13085 | #else |
| 13083 | 13086 | #define sqlite3BeginBenignMalloc() |
| 13084 | 13087 | #define sqlite3EndBenignMalloc() |
| 13085 | 13088 | #endif |
| 13086 | 13089 | |
| 13087 | -#define IN_INDEX_ROWID 1 | |
| 13088 | -#define IN_INDEX_EPH 2 | |
| 13089 | -#define IN_INDEX_INDEX_ASC 3 | |
| 13090 | -#define IN_INDEX_INDEX_DESC 4 | |
| 13091 | -SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, int*); | |
| 13090 | +/* | |
| 13091 | +** Allowed return values from sqlite3FindInIndex() | |
| 13092 | +*/ | |
| 13093 | +#define IN_INDEX_ROWID 1 /* Search the rowid of the table */ | |
| 13094 | +#define IN_INDEX_EPH 2 /* Search an ephemeral b-tree */ | |
| 13095 | +#define IN_INDEX_INDEX_ASC 3 /* Existing index ASCENDING */ | |
| 13096 | +#define IN_INDEX_INDEX_DESC 4 /* Existing index DESCENDING */ | |
| 13097 | +#define IN_INDEX_NOOP 5 /* No table available. Use comparisons */ | |
| 13098 | +/* | |
| 13099 | +** Allowed flags for the 3rd parameter to sqlite3FindInIndex(). | |
| 13100 | +*/ | |
| 13101 | +#define IN_INDEX_NOOP_OK 0x0001 /* OK to return IN_INDEX_NOOP */ | |
| 13102 | +#define IN_INDEX_MEMBERSHIP 0x0002 /* IN operator used for membership test */ | |
| 13103 | +#define IN_INDEX_LOOP 0x0004 /* IN operator used as a loop */ | |
| 13104 | +SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*); | |
| 13092 | 13105 | |
| 13093 | 13106 | #ifdef SQLITE_ENABLE_ATOMIC_WRITE |
| 13094 | 13107 | SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int); |
| 13095 | 13108 | SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *); |
| 13096 | 13109 | SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *); |
| @@ -24039,11 +24052,11 @@ | ||
| 24039 | 24052 | /* 131 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), |
| 24040 | 24053 | /* 132 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), |
| 24041 | 24054 | /* 133 */ "Real" OpHelp("r[P2]=P4"), |
| 24042 | 24055 | /* 134 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), |
| 24043 | 24056 | /* 135 */ "IfPos" OpHelp("if r[P1]>0 goto P2"), |
| 24044 | - /* 136 */ "IfNeg" OpHelp("if r[P1]<0 goto P2"), | |
| 24057 | + /* 136 */ "IfNeg" OpHelp("r[P1]+=P3, if r[P1]<0 goto P2"), | |
| 24045 | 24058 | /* 137 */ "IfZero" OpHelp("r[P1]+=P3, if r[P1]==0 goto P2"), |
| 24046 | 24059 | /* 138 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), |
| 24047 | 24060 | /* 139 */ "IncrVacuum" OpHelp(""), |
| 24048 | 24061 | /* 140 */ "Expire" OpHelp(""), |
| 24049 | 24062 | /* 141 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), |
| @@ -51693,11 +51706,11 @@ | ||
| 51693 | 51706 | /* If the client is reading or writing an index and the schema is |
| 51694 | 51707 | ** not loaded, then it is too difficult to actually check to see if |
| 51695 | 51708 | ** the correct locks are held. So do not bother - just return true. |
| 51696 | 51709 | ** This case does not come up very often anyhow. |
| 51697 | 51710 | */ |
| 51698 | - if( isIndex && (!pSchema || (pSchema->flags&DB_SchemaLoaded)==0) ){ | |
| 51711 | + if( isIndex && (!pSchema || (pSchema->schemaFlags&DB_SchemaLoaded)==0) ){ | |
| 51699 | 51712 | return 1; |
| 51700 | 51713 | } |
| 51701 | 51714 | |
| 51702 | 51715 | /* Figure out the root-page that the lock should be held on. For table |
| 51703 | 51716 | ** b-trees, this is just the root page of the b-tree being read or |
| @@ -67993,10 +68006,16 @@ | ||
| 67993 | 68006 | ** |
| 67994 | 68007 | ** M is an integer, 2 or 3, that indices how many different ways the |
| 67995 | 68008 | ** branch can go. It is usually 2. "I" is the direction the branch |
| 67996 | 68009 | ** goes. 0 means falls through. 1 means branch is taken. 2 means the |
| 67997 | 68010 | ** second alternative branch is taken. |
| 68011 | +** | |
| 68012 | +** iSrcLine is the source code line (from the __LINE__ macro) that | |
| 68013 | +** generated the VDBE instruction. This instrumentation assumes that all | |
| 68014 | +** source code is in a single file (the amalgamation). Special values 1 | |
| 68015 | +** and 2 for the iSrcLine parameter mean that this particular branch is | |
| 68016 | +** always taken or never taken, respectively. | |
| 67998 | 68017 | */ |
| 67999 | 68018 | #if !defined(SQLITE_VDBE_COVERAGE) |
| 68000 | 68019 | # define VdbeBranchTaken(I,M) |
| 68001 | 68020 | #else |
| 68002 | 68021 | # define VdbeBranchTaken(I,M) vdbeTakeBranch(pOp->iSrcLine,I,M) |
| @@ -68756,11 +68775,11 @@ | ||
| 68756 | 68775 | break; |
| 68757 | 68776 | } |
| 68758 | 68777 | |
| 68759 | 68778 | /* Opcode: EndCoroutine P1 * * * * |
| 68760 | 68779 | ** |
| 68761 | -** The instruction at the address in register P1 is an Yield. | |
| 68780 | +** The instruction at the address in register P1 is a Yield. | |
| 68762 | 68781 | ** Jump to the P2 parameter of that Yield. |
| 68763 | 68782 | ** After the jump, register P1 becomes undefined. |
| 68764 | 68783 | ** |
| 68765 | 68784 | ** See also: InitCoroutine |
| 68766 | 68785 | */ |
| @@ -68949,11 +68968,11 @@ | ||
| 68949 | 68968 | |
| 68950 | 68969 | /* Opcode: String8 * P2 * P4 * |
| 68951 | 68970 | ** Synopsis: r[P2]='P4' |
| 68952 | 68971 | ** |
| 68953 | 68972 | ** P4 points to a nul terminated UTF-8 string. This opcode is transformed |
| 68954 | -** into an OP_String before it is executed for the first time. During | |
| 68973 | +** into a String before it is executed for the first time. During | |
| 68955 | 68974 | ** this transformation, the length of string P4 is computed and stored |
| 68956 | 68975 | ** as the P1 parameter. |
| 68957 | 68976 | */ |
| 68958 | 68977 | case OP_String8: { /* same as TK_STRING, out2-prerelease */ |
| 68959 | 68978 | assert( pOp->p4.z!=0 ); |
| @@ -70195,17 +70214,17 @@ | ||
| 70195 | 70214 | |
| 70196 | 70215 | /* Opcode: If P1 P2 P3 * * |
| 70197 | 70216 | ** |
| 70198 | 70217 | ** Jump to P2 if the value in register P1 is true. The value |
| 70199 | 70218 | ** is considered true if it is numeric and non-zero. If the value |
| 70200 | -** in P1 is NULL then take the jump if P3 is non-zero. | |
| 70219 | +** in P1 is NULL then take the jump if and only if P3 is non-zero. | |
| 70201 | 70220 | */ |
| 70202 | 70221 | /* Opcode: IfNot P1 P2 P3 * * |
| 70203 | 70222 | ** |
| 70204 | 70223 | ** Jump to P2 if the value in register P1 is False. The value |
| 70205 | 70224 | ** is considered false if it has a numeric value of zero. If the value |
| 70206 | -** in P1 is NULL then take the jump if P3 is zero. | |
| 70225 | +** in P1 is NULL then take the jump if and only if P3 is non-zero. | |
| 70207 | 70226 | */ |
| 70208 | 70227 | case OP_If: /* jump, in1 */ |
| 70209 | 70228 | case OP_IfNot: { /* jump, in1 */ |
| 70210 | 70229 | int c; |
| 70211 | 70230 | pIn1 = &aMem[pOp->p1]; |
| @@ -71473,11 +71492,11 @@ | ||
| 71473 | 71492 | ** Reposition cursor P1 so that it points to the smallest entry that |
| 71474 | 71493 | ** is greater than or equal to the key value. If there are no records |
| 71475 | 71494 | ** greater than or equal to the key and P2 is not zero, then jump to P2. |
| 71476 | 71495 | ** |
| 71477 | 71496 | ** This opcode leaves the cursor configured to move in forward order, |
| 71478 | -** from the begining toward the end. In other words, the cursor is | |
| 71497 | +** from the beginning toward the end. In other words, the cursor is | |
| 71479 | 71498 | ** configured to use Next, not Prev. |
| 71480 | 71499 | ** |
| 71481 | 71500 | ** See also: Found, NotFound, SeekLt, SeekGt, SeekLe |
| 71482 | 71501 | */ |
| 71483 | 71502 | /* Opcode: SeekGT P1 P2 P3 P4 * |
| @@ -71713,13 +71732,13 @@ | ||
| 71713 | 71732 | ** |
| 71714 | 71733 | ** Cursor P1 is on an index btree. If the record identified by P3 and P4 |
| 71715 | 71734 | ** is a prefix of any entry in P1 then a jump is made to P2 and |
| 71716 | 71735 | ** P1 is left pointing at the matching entry. |
| 71717 | 71736 | ** |
| 71718 | -** This operation leaves the cursor in a state where it cannot be | |
| 71719 | -** advanced in either direction. In other words, the Next and Prev | |
| 71720 | -** opcodes do not work after this operation. | |
| 71737 | +** This operation leaves the cursor in a state where it can be | |
| 71738 | +** advanced in the forward direction. The Next instruction will work, | |
| 71739 | +** but not the Prev instruction. | |
| 71721 | 71740 | ** |
| 71722 | 71741 | ** See also: NotFound, NoConflict, NotExists. SeekGe |
| 71723 | 71742 | */ |
| 71724 | 71743 | /* Opcode: NotFound P1 P2 P3 P4 * |
| 71725 | 71744 | ** Synopsis: key=r[P3@P4] |
| @@ -71782,11 +71801,11 @@ | ||
| 71782 | 71801 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 71783 | 71802 | assert( pOp->p4type==P4_INT32 ); |
| 71784 | 71803 | pC = p->apCsr[pOp->p1]; |
| 71785 | 71804 | assert( pC!=0 ); |
| 71786 | 71805 | #ifdef SQLITE_DEBUG |
| 71787 | - pC->seekOp = 0; | |
| 71806 | + pC->seekOp = pOp->opcode; | |
| 71788 | 71807 | #endif |
| 71789 | 71808 | pIn3 = &aMem[pOp->p3]; |
| 71790 | 71809 | assert( pC->pCursor!=0 ); |
| 71791 | 71810 | assert( pC->isTable==0 ); |
| 71792 | 71811 | pFree = 0; /* Not needed. Only used to suppress a compiler warning. */ |
| @@ -72177,11 +72196,11 @@ | ||
| 72177 | 72196 | ** Delete the record at which the P1 cursor is currently pointing. |
| 72178 | 72197 | ** |
| 72179 | 72198 | ** The cursor will be left pointing at either the next or the previous |
| 72180 | 72199 | ** record in the table. If it is left pointing at the next record, then |
| 72181 | 72200 | ** the next Next instruction will be a no-op. Hence it is OK to delete |
| 72182 | -** a record from within an Next loop. | |
| 72201 | +** a record from within a Next loop. | |
| 72183 | 72202 | ** |
| 72184 | 72203 | ** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is |
| 72185 | 72204 | ** incremented (otherwise not). |
| 72186 | 72205 | ** |
| 72187 | 72206 | ** P1 must not be pseudo-table. It has to be a real table with |
| @@ -72240,11 +72259,11 @@ | ||
| 72240 | 72259 | |
| 72241 | 72260 | /* Opcode: SorterCompare P1 P2 P3 P4 |
| 72242 | 72261 | ** Synopsis: if key(P1)!=trim(r[P3],P4) goto P2 |
| 72243 | 72262 | ** |
| 72244 | 72263 | ** P1 is a sorter cursor. This instruction compares a prefix of the |
| 72245 | -** the record blob in register P3 against a prefix of the entry that | |
| 72264 | +** record blob in register P3 against a prefix of the entry that | |
| 72246 | 72265 | ** the sorter cursor currently points to. Only the first P4 fields |
| 72247 | 72266 | ** of r[P3] and the sorter record are compared. |
| 72248 | 72267 | ** |
| 72249 | 72268 | ** If either P3 or the sorter contains a NULL in one of their significant |
| 72250 | 72269 | ** fields (not counting the P4 fields at the end which are ignored) then |
| @@ -72639,11 +72658,11 @@ | ||
| 72639 | 72658 | |
| 72640 | 72659 | /* The Next opcode is only used after SeekGT, SeekGE, and Rewind. |
| 72641 | 72660 | ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */ |
| 72642 | 72661 | assert( pOp->opcode!=OP_Next || pOp->opcode!=OP_NextIfOpen |
| 72643 | 72662 | || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE |
| 72644 | - || pC->seekOp==OP_Rewind ); | |
| 72663 | + || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found); | |
| 72645 | 72664 | assert( pOp->opcode!=OP_Prev || pOp->opcode!=OP_PrevIfOpen |
| 72646 | 72665 | || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE |
| 72647 | 72666 | || pC->seekOp==OP_Last ); |
| 72648 | 72667 | |
| 72649 | 72668 | rc = pOp->p4.xAdvance(pC->pCursor, &res); |
| @@ -73566,21 +73585,20 @@ | ||
| 73566 | 73585 | pc = pOp->p2 - 1; |
| 73567 | 73586 | } |
| 73568 | 73587 | break; |
| 73569 | 73588 | } |
| 73570 | 73589 | |
| 73571 | -/* Opcode: IfNeg P1 P2 * * * | |
| 73572 | -** Synopsis: if r[P1]<0 goto P2 | |
| 73590 | +/* Opcode: IfNeg P1 P2 P3 * * | |
| 73591 | +** Synopsis: r[P1]+=P3, if r[P1]<0 goto P2 | |
| 73573 | 73592 | ** |
| 73574 | -** If the value of register P1 is less than zero, jump to P2. | |
| 73575 | -** | |
| 73576 | -** It is illegal to use this instruction on a register that does | |
| 73577 | -** not contain an integer. An assertion fault will result if you try. | |
| 73593 | +** Register P1 must contain an integer. Add literal P3 to the value in | |
| 73594 | +** register P1 then if the value of register P1 is less than zero, jump to P2. | |
| 73578 | 73595 | */ |
| 73579 | 73596 | case OP_IfNeg: { /* jump, in1 */ |
| 73580 | 73597 | pIn1 = &aMem[pOp->p1]; |
| 73581 | 73598 | assert( pIn1->flags&MEM_Int ); |
| 73599 | + pIn1->u.i += pOp->p3; | |
| 73582 | 73600 | VdbeBranchTaken(pIn1->u.i<0, 2); |
| 73583 | 73601 | if( pIn1->u.i<0 ){ |
| 73584 | 73602 | pc = pOp->p2 - 1; |
| 73585 | 73603 | } |
| 73586 | 73604 | break; |
| @@ -73589,13 +73607,10 @@ | ||
| 73589 | 73607 | /* Opcode: IfZero P1 P2 P3 * * |
| 73590 | 73608 | ** Synopsis: r[P1]+=P3, if r[P1]==0 goto P2 |
| 73591 | 73609 | ** |
| 73592 | 73610 | ** The register P1 must contain an integer. Add literal P3 to the |
| 73593 | 73611 | ** value in register P1. If the result is exactly 0, jump to P2. |
| 73594 | -** | |
| 73595 | -** It is illegal to use this instruction on a register that does | |
| 73596 | -** not contain an integer. An assertion fault will result if you try. | |
| 73597 | 73612 | */ |
| 73598 | 73613 | case OP_IfZero: { /* jump, in1 */ |
| 73599 | 73614 | pIn1 = &aMem[pOp->p1]; |
| 73600 | 73615 | assert( pIn1->flags&MEM_Int ); |
| 73601 | 73616 | pIn1->u.i += pOp->p3; |
| @@ -79563,10 +79578,13 @@ | ||
| 79563 | 79578 | case TK_INTEGER: |
| 79564 | 79579 | case TK_STRING: |
| 79565 | 79580 | case TK_FLOAT: |
| 79566 | 79581 | case TK_BLOB: |
| 79567 | 79582 | return 0; |
| 79583 | + case TK_COLUMN: | |
| 79584 | + assert( p->pTab!=0 ); | |
| 79585 | + return p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0; | |
| 79568 | 79586 | default: |
| 79569 | 79587 | return 1; |
| 79570 | 79588 | } |
| 79571 | 79589 | } |
| 79572 | 79590 | |
| @@ -79670,83 +79688,124 @@ | ||
| 79670 | 79688 | SQLITE_PRIVATE int sqlite3CodeOnce(Parse *pParse){ |
| 79671 | 79689 | Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ |
| 79672 | 79690 | return sqlite3VdbeAddOp1(v, OP_Once, pParse->nOnce++); |
| 79673 | 79691 | } |
| 79674 | 79692 | |
| 79693 | +/* | |
| 79694 | +** Generate code that checks the left-most column of index table iCur to see if | |
| 79695 | +** it contains any NULL entries. Cause the register at regHasNull to be set | |
| 79696 | +** to a non-NULL value if iCur contains no NULLs. Cause register regHasNull | |
| 79697 | +** to be set to NULL if iCur contains one or more NULL values. | |
| 79698 | +*/ | |
| 79699 | +static void sqlite3SetHasNullFlag(Vdbe *v, int iCur, int regHasNull){ | |
| 79700 | + int j1; | |
| 79701 | + sqlite3VdbeAddOp2(v, OP_Integer, 0, regHasNull); | |
| 79702 | + j1 = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v); | |
| 79703 | + sqlite3VdbeAddOp3(v, OP_Column, iCur, 0, regHasNull); | |
| 79704 | + sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); | |
| 79705 | + VdbeComment((v, "first_entry_in(%d)", iCur)); | |
| 79706 | + sqlite3VdbeJumpHere(v, j1); | |
| 79707 | +} | |
| 79708 | + | |
| 79709 | + | |
| 79710 | +#ifndef SQLITE_OMIT_SUBQUERY | |
| 79711 | +/* | |
| 79712 | +** The argument is an IN operator with a list (not a subquery) on the | |
| 79713 | +** right-hand side. Return TRUE if that list is constant. | |
| 79714 | +*/ | |
| 79715 | +static int sqlite3InRhsIsConstant(Expr *pIn){ | |
| 79716 | + Expr *pLHS; | |
| 79717 | + int res; | |
| 79718 | + assert( !ExprHasProperty(pIn, EP_xIsSelect) ); | |
| 79719 | + pLHS = pIn->pLeft; | |
| 79720 | + pIn->pLeft = 0; | |
| 79721 | + res = sqlite3ExprIsConstant(pIn); | |
| 79722 | + pIn->pLeft = pLHS; | |
| 79723 | + return res; | |
| 79724 | +} | |
| 79725 | +#endif | |
| 79726 | + | |
| 79675 | 79727 | /* |
| 79676 | 79728 | ** This function is used by the implementation of the IN (...) operator. |
| 79677 | 79729 | ** The pX parameter is the expression on the RHS of the IN operator, which |
| 79678 | 79730 | ** might be either a list of expressions or a subquery. |
| 79679 | 79731 | ** |
| 79680 | 79732 | ** The job of this routine is to find or create a b-tree object that can |
| 79681 | 79733 | ** be used either to test for membership in the RHS set or to iterate through |
| 79682 | 79734 | ** all members of the RHS set, skipping duplicates. |
| 79683 | 79735 | ** |
| 79684 | -** A cursor is opened on the b-tree object that the RHS of the IN operator | |
| 79736 | +** A cursor is opened on the b-tree object that is the RHS of the IN operator | |
| 79685 | 79737 | ** and pX->iTable is set to the index of that cursor. |
| 79686 | 79738 | ** |
| 79687 | 79739 | ** The returned value of this function indicates the b-tree type, as follows: |
| 79688 | 79740 | ** |
| 79689 | 79741 | ** IN_INDEX_ROWID - The cursor was opened on a database table. |
| 79690 | 79742 | ** IN_INDEX_INDEX_ASC - The cursor was opened on an ascending index. |
| 79691 | 79743 | ** IN_INDEX_INDEX_DESC - The cursor was opened on a descending index. |
| 79692 | 79744 | ** IN_INDEX_EPH - The cursor was opened on a specially created and |
| 79693 | 79745 | ** populated epheremal table. |
| 79746 | +** IN_INDEX_NOOP - No cursor was allocated. The IN operator must be | |
| 79747 | +** implemented as a sequence of comparisons. | |
| 79694 | 79748 | ** |
| 79695 | 79749 | ** An existing b-tree might be used if the RHS expression pX is a simple |
| 79696 | 79750 | ** subquery such as: |
| 79697 | 79751 | ** |
| 79698 | 79752 | ** SELECT <column> FROM <table> |
| 79699 | 79753 | ** |
| 79700 | 79754 | ** If the RHS of the IN operator is a list or a more complex subquery, then |
| 79701 | 79755 | ** an ephemeral table might need to be generated from the RHS and then |
| 79702 | 79756 | ** pX->iTable made to point to the ephermeral table instead of an |
| 79703 | -** existing table. | |
| 79757 | +** existing table. | |
| 79704 | 79758 | ** |
| 79705 | -** If the prNotFound parameter is 0, then the b-tree will be used to iterate | |
| 79706 | -** through the set members, skipping any duplicates. In this case an | |
| 79707 | -** epheremal table must be used unless the selected <column> is guaranteed | |
| 79759 | +** The inFlags parameter must contain exactly one of the bits | |
| 79760 | +** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP. If inFlags contains | |
| 79761 | +** IN_INDEX_MEMBERSHIP, then the generated table will be used for a | |
| 79762 | +** fast membership test. When the IN_INDEX_LOOP bit is set, the | |
| 79763 | +** IN index will be used to loop over all values of the RHS of the | |
| 79764 | +** IN operator. | |
| 79765 | +** | |
| 79766 | +** When IN_INDEX_LOOP is used (and the b-tree will be used to iterate | |
| 79767 | +** through the set members) then the b-tree must not contain duplicates. | |
| 79768 | +** An epheremal table must be used unless the selected <column> is guaranteed | |
| 79708 | 79769 | ** to be unique - either because it is an INTEGER PRIMARY KEY or it |
| 79709 | 79770 | ** has a UNIQUE constraint or UNIQUE index. |
| 79710 | 79771 | ** |
| 79711 | -** If the prNotFound parameter is not 0, then the b-tree will be used | |
| 79712 | -** for fast set membership tests. In this case an epheremal table must | |
| 79772 | +** When IN_INDEX_MEMBERSHIP is used (and the b-tree will be used | |
| 79773 | +** for fast set membership tests) then an epheremal table must | |
| 79713 | 79774 | ** be used unless <column> is an INTEGER PRIMARY KEY or an index can |
| 79714 | 79775 | ** be found with <column> as its left-most column. |
| 79776 | +** | |
| 79777 | +** If the IN_INDEX_NOOP_OK and IN_INDEX_MEMBERSHIP are both set and | |
| 79778 | +** if the RHS of the IN operator is a list (not a subquery) then this | |
| 79779 | +** routine might decide that creating an ephemeral b-tree for membership | |
| 79780 | +** testing is too expensive and return IN_INDEX_NOOP. In that case, the | |
| 79781 | +** calling routine should implement the IN operator using a sequence | |
| 79782 | +** of Eq or Ne comparison operations. | |
| 79715 | 79783 | ** |
| 79716 | 79784 | ** When the b-tree is being used for membership tests, the calling function |
| 79717 | -** needs to know whether or not the structure contains an SQL NULL | |
| 79718 | -** value in order to correctly evaluate expressions like "X IN (Y, Z)". | |
| 79719 | -** If there is any chance that the (...) might contain a NULL value at | |
| 79785 | +** might need to know whether or not the RHS side of the IN operator | |
| 79786 | +** contains a NULL. If prRhsHasNull is not a NULL pointer and | |
| 79787 | +** if there is any chance that the (...) might contain a NULL value at | |
| 79720 | 79788 | ** runtime, then a register is allocated and the register number written |
| 79721 | -** to *prNotFound. If there is no chance that the (...) contains a | |
| 79722 | -** NULL value, then *prNotFound is left unchanged. | |
| 79723 | -** | |
| 79724 | -** If a register is allocated and its location stored in *prNotFound, then | |
| 79725 | -** its initial value is NULL. If the (...) does not remain constant | |
| 79726 | -** for the duration of the query (i.e. the SELECT within the (...) | |
| 79727 | -** is a correlated subquery) then the value of the allocated register is | |
| 79728 | -** reset to NULL each time the subquery is rerun. This allows the | |
| 79729 | -** caller to use vdbe code equivalent to the following: | |
| 79730 | -** | |
| 79731 | -** if( register==NULL ){ | |
| 79732 | -** has_null = <test if data structure contains null> | |
| 79733 | -** register = 1 | |
| 79734 | -** } | |
| 79735 | -** | |
| 79736 | -** in order to avoid running the <test if data structure contains null> | |
| 79737 | -** test more often than is necessary. | |
| 79789 | +** to *prRhsHasNull. If there is no chance that the (...) contains a | |
| 79790 | +** NULL value, then *prRhsHasNull is left unchanged. | |
| 79791 | +** | |
| 79792 | +** If a register is allocated and its location stored in *prRhsHasNull, then | |
| 79793 | +** the value in that register will be NULL if the b-tree contains one or more | |
| 79794 | +** NULL values, and it will be some non-NULL value if the b-tree contains no | |
| 79795 | +** NULL values. | |
| 79738 | 79796 | */ |
| 79739 | 79797 | #ifndef SQLITE_OMIT_SUBQUERY |
| 79740 | -SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ | |
| 79798 | +SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int *prRhsHasNull){ | |
| 79741 | 79799 | Select *p; /* SELECT to the right of IN operator */ |
| 79742 | 79800 | int eType = 0; /* Type of RHS table. IN_INDEX_* */ |
| 79743 | 79801 | int iTab = pParse->nTab++; /* Cursor of the RHS table */ |
| 79744 | - int mustBeUnique = (prNotFound==0); /* True if RHS must be unique */ | |
| 79802 | + int mustBeUnique; /* True if RHS must be unique */ | |
| 79745 | 79803 | Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ |
| 79746 | 79804 | |
| 79747 | 79805 | assert( pX->op==TK_IN ); |
| 79806 | + mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0; | |
| 79748 | 79807 | |
| 79749 | 79808 | /* Check to see if an existing table or index can be used to |
| 79750 | 79809 | ** satisfy the query. This is preferable to generating a new |
| 79751 | 79810 | ** ephemeral table. |
| 79752 | 79811 | */ |
| @@ -79799,44 +79858,59 @@ | ||
| 79799 | 79858 | int affinity_ok = sqlite3IndexAffinityOk(pX, pTab->aCol[iCol].affinity); |
| 79800 | 79859 | |
| 79801 | 79860 | for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){ |
| 79802 | 79861 | if( (pIdx->aiColumn[0]==iCol) |
| 79803 | 79862 | && sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq |
| 79804 | - && (!mustBeUnique || (pIdx->nKeyCol==1 && pIdx->onError!=OE_None)) | |
| 79863 | + && (!mustBeUnique || (pIdx->nKeyCol==1 && IsUniqueIndex(pIdx))) | |
| 79805 | 79864 | ){ |
| 79806 | 79865 | int iAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v); |
| 79807 | 79866 | sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb); |
| 79808 | 79867 | sqlite3VdbeSetP4KeyInfo(pParse, pIdx); |
| 79809 | 79868 | VdbeComment((v, "%s", pIdx->zName)); |
| 79810 | 79869 | assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 ); |
| 79811 | 79870 | eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0]; |
| 79812 | 79871 | |
| 79813 | - if( prNotFound && !pTab->aCol[iCol].notNull ){ | |
| 79814 | - *prNotFound = ++pParse->nMem; | |
| 79815 | - sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound); | |
| 79872 | + if( prRhsHasNull && !pTab->aCol[iCol].notNull ){ | |
| 79873 | + *prRhsHasNull = ++pParse->nMem; | |
| 79874 | + sqlite3SetHasNullFlag(v, iTab, *prRhsHasNull); | |
| 79816 | 79875 | } |
| 79817 | 79876 | sqlite3VdbeJumpHere(v, iAddr); |
| 79818 | 79877 | } |
| 79819 | 79878 | } |
| 79820 | 79879 | } |
| 79821 | 79880 | } |
| 79881 | + | |
| 79882 | + /* If no preexisting index is available for the IN clause | |
| 79883 | + ** and IN_INDEX_NOOP is an allowed reply | |
| 79884 | + ** and the RHS of the IN operator is a list, not a subquery | |
| 79885 | + ** and the RHS is not contant or has two or fewer terms, | |
| 79886 | + ** then it is not worth creating an ephermeral table to evaluate | |
| 79887 | + ** the IN operator so return IN_INDEX_NOOP. | |
| 79888 | + */ | |
| 79889 | + if( eType==0 | |
| 79890 | + && (inFlags & IN_INDEX_NOOP_OK) | |
| 79891 | + && !ExprHasProperty(pX, EP_xIsSelect) | |
| 79892 | + && (!sqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2) | |
| 79893 | + ){ | |
| 79894 | + eType = IN_INDEX_NOOP; | |
| 79895 | + } | |
| 79896 | + | |
| 79822 | 79897 | |
| 79823 | 79898 | if( eType==0 ){ |
| 79824 | 79899 | /* Could not find an existing table or index to use as the RHS b-tree. |
| 79825 | 79900 | ** We will have to generate an ephemeral table to do the job. |
| 79826 | 79901 | */ |
| 79827 | 79902 | u32 savedNQueryLoop = pParse->nQueryLoop; |
| 79828 | 79903 | int rMayHaveNull = 0; |
| 79829 | 79904 | eType = IN_INDEX_EPH; |
| 79830 | - if( prNotFound ){ | |
| 79831 | - *prNotFound = rMayHaveNull = ++pParse->nMem; | |
| 79832 | - sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound); | |
| 79833 | - }else{ | |
| 79905 | + if( inFlags & IN_INDEX_LOOP ){ | |
| 79834 | 79906 | pParse->nQueryLoop = 0; |
| 79835 | 79907 | if( pX->pLeft->iColumn<0 && !ExprHasProperty(pX, EP_xIsSelect) ){ |
| 79836 | 79908 | eType = IN_INDEX_ROWID; |
| 79837 | 79909 | } |
| 79910 | + }else if( prRhsHasNull ){ | |
| 79911 | + *prRhsHasNull = rMayHaveNull = ++pParse->nMem; | |
| 79838 | 79912 | } |
| 79839 | 79913 | sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID); |
| 79840 | 79914 | pParse->nQueryLoop = savedNQueryLoop; |
| 79841 | 79915 | }else{ |
| 79842 | 79916 | pX->iTable = iTab; |
| @@ -79863,31 +79937,25 @@ | ||
| 79863 | 79937 | ** intkey B-Tree to store the set of IN(...) values instead of the usual |
| 79864 | 79938 | ** (slower) variable length keys B-Tree. |
| 79865 | 79939 | ** |
| 79866 | 79940 | ** If rMayHaveNull is non-zero, that means that the operation is an IN |
| 79867 | 79941 | ** (not a SELECT or EXISTS) and that the RHS might contains NULLs. |
| 79868 | -** Furthermore, the IN is in a WHERE clause and that we really want | |
| 79869 | -** to iterate over the RHS of the IN operator in order to quickly locate | |
| 79870 | -** all corresponding LHS elements. All this routine does is initialize | |
| 79871 | -** the register given by rMayHaveNull to NULL. Calling routines will take | |
| 79872 | -** care of changing this register value to non-NULL if the RHS is NULL-free. | |
| 79873 | -** | |
| 79874 | -** If rMayHaveNull is zero, that means that the subquery is being used | |
| 79875 | -** for membership testing only. There is no need to initialize any | |
| 79876 | -** registers to indicate the presence or absence of NULLs on the RHS. | |
| 79942 | +** All this routine does is initialize the register given by rMayHaveNull | |
| 79943 | +** to NULL. Calling routines will take care of changing this register | |
| 79944 | +** value to non-NULL if the RHS is NULL-free. | |
| 79877 | 79945 | ** |
| 79878 | 79946 | ** For a SELECT or EXISTS operator, return the register that holds the |
| 79879 | 79947 | ** result. For IN operators or if an error occurs, the return value is 0. |
| 79880 | 79948 | */ |
| 79881 | 79949 | #ifndef SQLITE_OMIT_SUBQUERY |
| 79882 | 79950 | SQLITE_PRIVATE int sqlite3CodeSubselect( |
| 79883 | 79951 | Parse *pParse, /* Parsing context */ |
| 79884 | 79952 | Expr *pExpr, /* The IN, SELECT, or EXISTS operator */ |
| 79885 | - int rMayHaveNull, /* Register that records whether NULLs exist in RHS */ | |
| 79953 | + int rHasNullFlag, /* Register that records whether NULLs exist in RHS */ | |
| 79886 | 79954 | int isRowid /* If true, LHS of IN operator is a rowid */ |
| 79887 | 79955 | ){ |
| 79888 | - int testAddr = -1; /* One-time test address */ | |
| 79956 | + int jmpIfDynamic = -1; /* One-time test address */ | |
| 79889 | 79957 | int rReg = 0; /* Register storing resulting */ |
| 79890 | 79958 | Vdbe *v = sqlite3GetVdbe(pParse); |
| 79891 | 79959 | if( NEVER(v==0) ) return 0; |
| 79892 | 79960 | sqlite3ExprCachePush(pParse); |
| 79893 | 79961 | |
| @@ -79900,17 +79968,17 @@ | ||
| 79900 | 79968 | ** |
| 79901 | 79969 | ** If all of the above are false, then we can run this code just once |
| 79902 | 79970 | ** save the results, and reuse the same result on subsequent invocations. |
| 79903 | 79971 | */ |
| 79904 | 79972 | if( !ExprHasProperty(pExpr, EP_VarSelect) ){ |
| 79905 | - testAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v); | |
| 79973 | + jmpIfDynamic = sqlite3CodeOnce(pParse); VdbeCoverage(v); | |
| 79906 | 79974 | } |
| 79907 | 79975 | |
| 79908 | 79976 | #ifndef SQLITE_OMIT_EXPLAIN |
| 79909 | 79977 | if( pParse->explain==2 ){ |
| 79910 | 79978 | char *zMsg = sqlite3MPrintf( |
| 79911 | - pParse->db, "EXECUTE %s%s SUBQUERY %d", testAddr>=0?"":"CORRELATED ", | |
| 79979 | + pParse->db, "EXECUTE %s%s SUBQUERY %d", jmpIfDynamic>=0?"":"CORRELATED ", | |
| 79912 | 79980 | pExpr->op==TK_IN?"LIST":"SCALAR", pParse->iNextSelectId |
| 79913 | 79981 | ); |
| 79914 | 79982 | sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC); |
| 79915 | 79983 | } |
| 79916 | 79984 | #endif |
| @@ -79920,14 +79988,10 @@ | ||
| 79920 | 79988 | char affinity; /* Affinity of the LHS of the IN */ |
| 79921 | 79989 | int addr; /* Address of OP_OpenEphemeral instruction */ |
| 79922 | 79990 | Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */ |
| 79923 | 79991 | KeyInfo *pKeyInfo = 0; /* Key information */ |
| 79924 | 79992 | |
| 79925 | - if( rMayHaveNull ){ | |
| 79926 | - sqlite3VdbeAddOp2(v, OP_Null, 0, rMayHaveNull); | |
| 79927 | - } | |
| 79928 | - | |
| 79929 | 79993 | affinity = sqlite3ExprAffinity(pLeft); |
| 79930 | 79994 | |
| 79931 | 79995 | /* Whether this is an 'x IN(SELECT...)' or an 'x IN(<exprlist>)' |
| 79932 | 79996 | ** expression it is handled the same way. An ephemeral table is |
| 79933 | 79997 | ** filled with single-field index keys representing the results |
| @@ -79996,23 +80060,23 @@ | ||
| 79996 | 80060 | } |
| 79997 | 80061 | |
| 79998 | 80062 | /* Loop through each expression in <exprlist>. */ |
| 79999 | 80063 | r1 = sqlite3GetTempReg(pParse); |
| 80000 | 80064 | r2 = sqlite3GetTempReg(pParse); |
| 80001 | - sqlite3VdbeAddOp2(v, OP_Null, 0, r2); | |
| 80065 | + if( isRowid ) sqlite3VdbeAddOp2(v, OP_Null, 0, r2); | |
| 80002 | 80066 | for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){ |
| 80003 | 80067 | Expr *pE2 = pItem->pExpr; |
| 80004 | 80068 | int iValToIns; |
| 80005 | 80069 | |
| 80006 | 80070 | /* If the expression is not constant then we will need to |
| 80007 | 80071 | ** disable the test that was generated above that makes sure |
| 80008 | 80072 | ** this code only executes once. Because for a non-constant |
| 80009 | 80073 | ** expression we need to rerun this code each time. |
| 80010 | 80074 | */ |
| 80011 | - if( testAddr>=0 && !sqlite3ExprIsConstant(pE2) ){ | |
| 80012 | - sqlite3VdbeChangeToNoop(v, testAddr); | |
| 80013 | - testAddr = -1; | |
| 80075 | + if( jmpIfDynamic>=0 && !sqlite3ExprIsConstant(pE2) ){ | |
| 80076 | + sqlite3VdbeChangeToNoop(v, jmpIfDynamic); | |
| 80077 | + jmpIfDynamic = -1; | |
| 80014 | 80078 | } |
| 80015 | 80079 | |
| 80016 | 80080 | /* Evaluate the expression and insert it into the temp table */ |
| 80017 | 80081 | if( isRowid && sqlite3ExprIsInteger(pE2, &iValToIns) ){ |
| 80018 | 80082 | sqlite3VdbeAddOp3(v, OP_InsertInt, pExpr->iTable, r2, iValToIns); |
| @@ -80078,12 +80142,16 @@ | ||
| 80078 | 80142 | ExprSetVVAProperty(pExpr, EP_NoReduce); |
| 80079 | 80143 | break; |
| 80080 | 80144 | } |
| 80081 | 80145 | } |
| 80082 | 80146 | |
| 80083 | - if( testAddr>=0 ){ | |
| 80084 | - sqlite3VdbeJumpHere(v, testAddr); | |
| 80147 | + if( rHasNullFlag ){ | |
| 80148 | + sqlite3SetHasNullFlag(v, pExpr->iTable, rHasNullFlag); | |
| 80149 | + } | |
| 80150 | + | |
| 80151 | + if( jmpIfDynamic>=0 ){ | |
| 80152 | + sqlite3VdbeJumpHere(v, jmpIfDynamic); | |
| 80085 | 80153 | } |
| 80086 | 80154 | sqlite3ExprCachePop(pParse); |
| 80087 | 80155 | |
| 80088 | 80156 | return rReg; |
| 80089 | 80157 | } |
| @@ -80100,11 +80168,11 @@ | ||
| 80100 | 80168 | ** is an array of zero or more values. The expression is true if the LHS is |
| 80101 | 80169 | ** contained within the RHS. The value of the expression is unknown (NULL) |
| 80102 | 80170 | ** if the LHS is NULL or if the LHS is not contained within the RHS and the |
| 80103 | 80171 | ** RHS contains one or more NULL values. |
| 80104 | 80172 | ** |
| 80105 | -** This routine generates code will jump to destIfFalse if the LHS is not | |
| 80173 | +** This routine generates code that jumps to destIfFalse if the LHS is not | |
| 80106 | 80174 | ** contained within the RHS. If due to NULLs we cannot determine if the LHS |
| 80107 | 80175 | ** is contained in the RHS then jump to destIfNull. If the LHS is contained |
| 80108 | 80176 | ** within the RHS then fall through. |
| 80109 | 80177 | */ |
| 80110 | 80178 | static void sqlite3ExprCodeIN( |
| @@ -80123,11 +80191,13 @@ | ||
| 80123 | 80191 | ** pExpr->iTable will contains the values that make up the RHS. |
| 80124 | 80192 | */ |
| 80125 | 80193 | v = pParse->pVdbe; |
| 80126 | 80194 | assert( v!=0 ); /* OOM detected prior to this routine */ |
| 80127 | 80195 | VdbeNoopComment((v, "begin IN expr")); |
| 80128 | - eType = sqlite3FindInIndex(pParse, pExpr, &rRhsHasNull); | |
| 80196 | + eType = sqlite3FindInIndex(pParse, pExpr, | |
| 80197 | + IN_INDEX_MEMBERSHIP | IN_INDEX_NOOP_OK, | |
| 80198 | + destIfFalse==destIfNull ? 0 : &rRhsHasNull); | |
| 80129 | 80199 | |
| 80130 | 80200 | /* Figure out the affinity to use to create a key from the results |
| 80131 | 80201 | ** of the expression. affinityStr stores a static string suitable for |
| 80132 | 80202 | ** P4 of OP_MakeRecord. |
| 80133 | 80203 | */ |
| @@ -80137,86 +80207,118 @@ | ||
| 80137 | 80207 | */ |
| 80138 | 80208 | sqlite3ExprCachePush(pParse); |
| 80139 | 80209 | r1 = sqlite3GetTempReg(pParse); |
| 80140 | 80210 | sqlite3ExprCode(pParse, pExpr->pLeft, r1); |
| 80141 | 80211 | |
| 80142 | - /* If the LHS is NULL, then the result is either false or NULL depending | |
| 80143 | - ** on whether the RHS is empty or not, respectively. | |
| 80144 | - */ | |
| 80145 | - if( destIfNull==destIfFalse ){ | |
| 80146 | - /* Shortcut for the common case where the false and NULL outcomes are | |
| 80147 | - ** the same. */ | |
| 80148 | - sqlite3VdbeAddOp2(v, OP_IsNull, r1, destIfNull); VdbeCoverage(v); | |
| 80149 | - }else{ | |
| 80150 | - int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); VdbeCoverage(v); | |
| 80151 | - sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse); | |
| 80152 | - VdbeCoverage(v); | |
| 80153 | - sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull); | |
| 80154 | - sqlite3VdbeJumpHere(v, addr1); | |
| 80155 | - } | |
| 80156 | - | |
| 80157 | - if( eType==IN_INDEX_ROWID ){ | |
| 80158 | - /* In this case, the RHS is the ROWID of table b-tree | |
| 80159 | - */ | |
| 80160 | - sqlite3VdbeAddOp2(v, OP_MustBeInt, r1, destIfFalse); VdbeCoverage(v); | |
| 80161 | - sqlite3VdbeAddOp3(v, OP_NotExists, pExpr->iTable, destIfFalse, r1); | |
| 80162 | - VdbeCoverage(v); | |
| 80163 | - }else{ | |
| 80164 | - /* In this case, the RHS is an index b-tree. | |
| 80165 | - */ | |
| 80166 | - sqlite3VdbeAddOp4(v, OP_Affinity, r1, 1, 0, &affinity, 1); | |
| 80167 | - | |
| 80168 | - /* If the set membership test fails, then the result of the | |
| 80169 | - ** "x IN (...)" expression must be either 0 or NULL. If the set | |
| 80170 | - ** contains no NULL values, then the result is 0. If the set | |
| 80171 | - ** contains one or more NULL values, then the result of the | |
| 80172 | - ** expression is also NULL. | |
| 80173 | - */ | |
| 80174 | - if( rRhsHasNull==0 || destIfFalse==destIfNull ){ | |
| 80175 | - /* This branch runs if it is known at compile time that the RHS | |
| 80176 | - ** cannot contain NULL values. This happens as the result | |
| 80177 | - ** of a "NOT NULL" constraint in the database schema. | |
| 80178 | - ** | |
| 80179 | - ** Also run this branch if NULL is equivalent to FALSE | |
| 80180 | - ** for this particular IN operator. | |
| 80181 | - */ | |
| 80182 | - sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse, r1, 1); | |
| 80183 | - VdbeCoverage(v); | |
| 80184 | - }else{ | |
| 80185 | - /* In this branch, the RHS of the IN might contain a NULL and | |
| 80186 | - ** the presence of a NULL on the RHS makes a difference in the | |
| 80187 | - ** outcome. | |
| 80188 | - */ | |
| 80189 | - int j1, j2; | |
| 80190 | - | |
| 80191 | - /* First check to see if the LHS is contained in the RHS. If so, | |
| 80192 | - ** then the presence of NULLs in the RHS does not matter, so jump | |
| 80193 | - ** over all of the code that follows. | |
| 80194 | - */ | |
| 80195 | - j1 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, r1, 1); | |
| 80196 | - VdbeCoverage(v); | |
| 80197 | - | |
| 80198 | - /* Here we begin generating code that runs if the LHS is not | |
| 80199 | - ** contained within the RHS. Generate additional code that | |
| 80200 | - ** tests the RHS for NULLs. If the RHS contains a NULL then | |
| 80201 | - ** jump to destIfNull. If there are no NULLs in the RHS then | |
| 80202 | - ** jump to destIfFalse. | |
| 80203 | - */ | |
| 80204 | - sqlite3VdbeAddOp2(v, OP_If, rRhsHasNull, destIfNull); VdbeCoverage(v); | |
| 80205 | - sqlite3VdbeAddOp2(v, OP_IfNot, rRhsHasNull, destIfFalse); VdbeCoverage(v); | |
| 80206 | - j2 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, rRhsHasNull, 1); | |
| 80207 | - VdbeCoverage(v); | |
| 80208 | - sqlite3VdbeAddOp2(v, OP_Integer, 0, rRhsHasNull); | |
| 80212 | + /* If sqlite3FindInIndex() did not find or create an index that is | |
| 80213 | + ** suitable for evaluating the IN operator, then evaluate using a | |
| 80214 | + ** sequence of comparisons. | |
| 80215 | + */ | |
| 80216 | + if( eType==IN_INDEX_NOOP ){ | |
| 80217 | + ExprList *pList = pExpr->x.pList; | |
| 80218 | + CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft); | |
| 80219 | + int labelOk = sqlite3VdbeMakeLabel(v); | |
| 80220 | + int r2, regToFree; | |
| 80221 | + int regCkNull = 0; | |
| 80222 | + int ii; | |
| 80223 | + assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); | |
| 80224 | + if( destIfNull!=destIfFalse ){ | |
| 80225 | + regCkNull = sqlite3GetTempReg(pParse); | |
| 80226 | + sqlite3VdbeAddOp3(v, OP_BitAnd, r1, r1, regCkNull); | |
| 80227 | + } | |
| 80228 | + for(ii=0; ii<pList->nExpr; ii++){ | |
| 80229 | + r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, ®ToFree); | |
| 80230 | + if( regCkNull && sqlite3ExprCanBeNull(pList->a[ii].pExpr) ){ | |
| 80231 | + sqlite3VdbeAddOp3(v, OP_BitAnd, regCkNull, r2, regCkNull); | |
| 80232 | + } | |
| 80233 | + if( ii<pList->nExpr-1 || destIfNull!=destIfFalse ){ | |
| 80234 | + sqlite3VdbeAddOp4(v, OP_Eq, r1, labelOk, r2, | |
| 80235 | + (void*)pColl, P4_COLLSEQ); | |
| 80236 | + VdbeCoverageIf(v, ii<pList->nExpr-1); | |
| 80237 | + VdbeCoverageIf(v, ii==pList->nExpr-1); | |
| 80238 | + sqlite3VdbeChangeP5(v, affinity); | |
| 80239 | + }else{ | |
| 80240 | + assert( destIfNull==destIfFalse ); | |
| 80241 | + sqlite3VdbeAddOp4(v, OP_Ne, r1, destIfFalse, r2, | |
| 80242 | + (void*)pColl, P4_COLLSEQ); VdbeCoverage(v); | |
| 80243 | + sqlite3VdbeChangeP5(v, affinity | SQLITE_JUMPIFNULL); | |
| 80244 | + } | |
| 80245 | + sqlite3ReleaseTempReg(pParse, regToFree); | |
| 80246 | + } | |
| 80247 | + if( regCkNull ){ | |
| 80248 | + sqlite3VdbeAddOp2(v, OP_IsNull, regCkNull, destIfNull); VdbeCoverage(v); | |
| 80209 | 80249 | sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse); |
| 80210 | - sqlite3VdbeJumpHere(v, j2); | |
| 80211 | - sqlite3VdbeAddOp2(v, OP_Integer, 1, rRhsHasNull); | |
| 80212 | - sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull); | |
| 80213 | - | |
| 80214 | - /* The OP_Found at the top of this branch jumps here when true, | |
| 80215 | - ** causing the overall IN expression evaluation to fall through. | |
| 80250 | + } | |
| 80251 | + sqlite3VdbeResolveLabel(v, labelOk); | |
| 80252 | + sqlite3ReleaseTempReg(pParse, regCkNull); | |
| 80253 | + }else{ | |
| 80254 | + | |
| 80255 | + /* If the LHS is NULL, then the result is either false or NULL depending | |
| 80256 | + ** on whether the RHS is empty or not, respectively. | |
| 80257 | + */ | |
| 80258 | + if( sqlite3ExprCanBeNull(pExpr->pLeft) ){ | |
| 80259 | + if( destIfNull==destIfFalse ){ | |
| 80260 | + /* Shortcut for the common case where the false and NULL outcomes are | |
| 80261 | + ** the same. */ | |
| 80262 | + sqlite3VdbeAddOp2(v, OP_IsNull, r1, destIfNull); VdbeCoverage(v); | |
| 80263 | + }else{ | |
| 80264 | + int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); VdbeCoverage(v); | |
| 80265 | + sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse); | |
| 80266 | + VdbeCoverage(v); | |
| 80267 | + sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull); | |
| 80268 | + sqlite3VdbeJumpHere(v, addr1); | |
| 80269 | + } | |
| 80270 | + } | |
| 80271 | + | |
| 80272 | + if( eType==IN_INDEX_ROWID ){ | |
| 80273 | + /* In this case, the RHS is the ROWID of table b-tree | |
| 80216 | 80274 | */ |
| 80217 | - sqlite3VdbeJumpHere(v, j1); | |
| 80275 | + sqlite3VdbeAddOp2(v, OP_MustBeInt, r1, destIfFalse); VdbeCoverage(v); | |
| 80276 | + sqlite3VdbeAddOp3(v, OP_NotExists, pExpr->iTable, destIfFalse, r1); | |
| 80277 | + VdbeCoverage(v); | |
| 80278 | + }else{ | |
| 80279 | + /* In this case, the RHS is an index b-tree. | |
| 80280 | + */ | |
| 80281 | + sqlite3VdbeAddOp4(v, OP_Affinity, r1, 1, 0, &affinity, 1); | |
| 80282 | + | |
| 80283 | + /* If the set membership test fails, then the result of the | |
| 80284 | + ** "x IN (...)" expression must be either 0 or NULL. If the set | |
| 80285 | + ** contains no NULL values, then the result is 0. If the set | |
| 80286 | + ** contains one or more NULL values, then the result of the | |
| 80287 | + ** expression is also NULL. | |
| 80288 | + */ | |
| 80289 | + assert( destIfFalse!=destIfNull || rRhsHasNull==0 ); | |
| 80290 | + if( rRhsHasNull==0 ){ | |
| 80291 | + /* This branch runs if it is known at compile time that the RHS | |
| 80292 | + ** cannot contain NULL values. This happens as the result | |
| 80293 | + ** of a "NOT NULL" constraint in the database schema. | |
| 80294 | + ** | |
| 80295 | + ** Also run this branch if NULL is equivalent to FALSE | |
| 80296 | + ** for this particular IN operator. | |
| 80297 | + */ | |
| 80298 | + sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse, r1, 1); | |
| 80299 | + VdbeCoverage(v); | |
| 80300 | + }else{ | |
| 80301 | + /* In this branch, the RHS of the IN might contain a NULL and | |
| 80302 | + ** the presence of a NULL on the RHS makes a difference in the | |
| 80303 | + ** outcome. | |
| 80304 | + */ | |
| 80305 | + int j1; | |
| 80306 | + | |
| 80307 | + /* First check to see if the LHS is contained in the RHS. If so, | |
| 80308 | + ** then the answer is TRUE the presence of NULLs in the RHS does | |
| 80309 | + ** not matter. If the LHS is not contained in the RHS, then the | |
| 80310 | + ** answer is NULL if the RHS contains NULLs and the answer is | |
| 80311 | + ** FALSE if the RHS is NULL-free. | |
| 80312 | + */ | |
| 80313 | + j1 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, r1, 1); | |
| 80314 | + VdbeCoverage(v); | |
| 80315 | + sqlite3VdbeAddOp2(v, OP_IsNull, rRhsHasNull, destIfNull); | |
| 80316 | + VdbeCoverage(v); | |
| 80317 | + sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse); | |
| 80318 | + sqlite3VdbeJumpHere(v, j1); | |
| 80319 | + } | |
| 80218 | 80320 | } |
| 80219 | 80321 | } |
| 80220 | 80322 | sqlite3ReleaseTempReg(pParse, r1); |
| 80221 | 80323 | sqlite3ExprCachePop(pParse); |
| 80222 | 80324 | VdbeComment((v, "end IN expr")); |
| @@ -80836,11 +80938,11 @@ | ||
| 80836 | 80938 | r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); |
| 80837 | 80939 | testcase( regFree1==0 ); |
| 80838 | 80940 | addr = sqlite3VdbeAddOp1(v, op, r1); |
| 80839 | 80941 | VdbeCoverageIf(v, op==TK_ISNULL); |
| 80840 | 80942 | VdbeCoverageIf(v, op==TK_NOTNULL); |
| 80841 | - sqlite3VdbeAddOp2(v, OP_AddImm, target, -1); | |
| 80943 | + sqlite3VdbeAddOp2(v, OP_Integer, 0, target); | |
| 80842 | 80944 | sqlite3VdbeJumpHere(v, addr); |
| 80843 | 80945 | break; |
| 80844 | 80946 | } |
| 80845 | 80947 | case TK_AGG_FUNCTION: { |
| 80846 | 80948 | AggInfo *pInfo = pExpr->pAggInfo; |
| @@ -80872,11 +80974,11 @@ | ||
| 80872 | 80974 | nFarg = pFarg ? pFarg->nExpr : 0; |
| 80873 | 80975 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); |
| 80874 | 80976 | zId = pExpr->u.zToken; |
| 80875 | 80977 | nId = sqlite3Strlen30(zId); |
| 80876 | 80978 | pDef = sqlite3FindFunction(db, zId, nId, nFarg, enc, 0); |
| 80877 | - if( pDef==0 ){ | |
| 80979 | + if( pDef==0 || pDef->xFunc==0 ){ | |
| 80878 | 80980 | sqlite3ErrorMsg(pParse, "unknown function: %.*s()", nId, zId); |
| 80879 | 80981 | break; |
| 80880 | 80982 | } |
| 80881 | 80983 | |
| 80882 | 80984 | /* Attempt a direct implementation of the built-in COALESCE() and |
| @@ -84421,11 +84523,11 @@ | ||
| 84421 | 84523 | ** regChng = N |
| 84422 | 84524 | ** goto endDistinctTest |
| 84423 | 84525 | */ |
| 84424 | 84526 | sqlite3VdbeAddOp0(v, OP_Goto); |
| 84425 | 84527 | addrNextRow = sqlite3VdbeCurrentAddr(v); |
| 84426 | - if( nColTest==1 && pIdx->nKeyCol==1 && pIdx->onError!=OE_None ){ | |
| 84528 | + if( nColTest==1 && pIdx->nKeyCol==1 && IsUniqueIndex(pIdx) ){ | |
| 84427 | 84529 | /* For a single-column UNIQUE index, once we have found a non-NULL |
| 84428 | 84530 | ** row, we know that all the rest will be distinct, so skip |
| 84429 | 84531 | ** subsequent distinctness tests. */ |
| 84430 | 84532 | sqlite3VdbeAddOp2(v, OP_NotNull, regPrev, endDistinctTest); |
| 84431 | 84533 | VdbeCoverage(v); |
| @@ -88103,11 +88205,11 @@ | ||
| 88103 | 88205 | pTable->aCol = pSelTab->aCol; |
| 88104 | 88206 | pSelTab->nCol = 0; |
| 88105 | 88207 | pSelTab->aCol = 0; |
| 88106 | 88208 | sqlite3DeleteTable(db, pSelTab); |
| 88107 | 88209 | assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) ); |
| 88108 | - pTable->pSchema->flags |= DB_UnresetViews; | |
| 88210 | + pTable->pSchema->schemaFlags |= DB_UnresetViews; | |
| 88109 | 88211 | }else{ |
| 88110 | 88212 | pTable->nCol = 0; |
| 88111 | 88213 | nErr++; |
| 88112 | 88214 | } |
| 88113 | 88215 | sqlite3SelectDelete(db, pSel); |
| @@ -88680,11 +88782,11 @@ | ||
| 88680 | 88782 | (char *)pKey, P4_KEYINFO); |
| 88681 | 88783 | sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0)); |
| 88682 | 88784 | |
| 88683 | 88785 | addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v); |
| 88684 | 88786 | assert( pKey!=0 || db->mallocFailed || pParse->nErr ); |
| 88685 | - if( pIndex->onError!=OE_None && pKey!=0 ){ | |
| 88787 | + if( IsUniqueIndex(pIndex) && pKey!=0 ){ | |
| 88686 | 88788 | int j2 = sqlite3VdbeCurrentAddr(v) + 3; |
| 88687 | 88789 | sqlite3VdbeAddOp2(v, OP_Goto, 0, j2); |
| 88688 | 88790 | addr2 = sqlite3VdbeCurrentAddr(v); |
| 88689 | 88791 | sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord, |
| 88690 | 88792 | pIndex->nKeyCol); VdbeCoverage(v); |
| @@ -89077,13 +89179,13 @@ | ||
| 89077 | 89179 | ** considered distinct and both result in separate indices. |
| 89078 | 89180 | */ |
| 89079 | 89181 | Index *pIdx; |
| 89080 | 89182 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 89081 | 89183 | int k; |
| 89082 | - assert( pIdx->onError!=OE_None ); | |
| 89184 | + assert( IsUniqueIndex(pIdx) ); | |
| 89083 | 89185 | assert( pIdx->idxType!=SQLITE_IDXTYPE_APPDEF ); |
| 89084 | - assert( pIndex->onError!=OE_None ); | |
| 89186 | + assert( IsUniqueIndex(pIndex) ); | |
| 89085 | 89187 | |
| 89086 | 89188 | if( pIdx->nKeyCol!=pIndex->nKeyCol ) continue; |
| 89087 | 89189 | for(k=0; k<pIdx->nKeyCol; k++){ |
| 89088 | 89190 | const char *z1; |
| 89089 | 89191 | const char *z2; |
| @@ -89270,11 +89372,11 @@ | ||
| 89270 | 89372 | for(i=nCopy+1; i<=pIdx->nKeyCol; i++){ |
| 89271 | 89373 | a[i] = 23; assert( 23==sqlite3LogEst(5) ); |
| 89272 | 89374 | } |
| 89273 | 89375 | |
| 89274 | 89376 | assert( 0==sqlite3LogEst(1) ); |
| 89275 | - if( pIdx->onError!=OE_None ) a[pIdx->nKeyCol] = 0; | |
| 89377 | + if( IsUniqueIndex(pIdx) ) a[pIdx->nKeyCol] = 0; | |
| 89276 | 89378 | } |
| 89277 | 89379 | |
| 89278 | 89380 | /* |
| 89279 | 89381 | ** This routine will drop an existing named index. This routine |
| 89280 | 89382 | ** implements the DROP INDEX statement. |
| @@ -90682,13 +90784,13 @@ | ||
| 90682 | 90784 | sqlite3DeleteTable(0, pTab); |
| 90683 | 90785 | } |
| 90684 | 90786 | sqlite3HashClear(&temp1); |
| 90685 | 90787 | sqlite3HashClear(&pSchema->fkeyHash); |
| 90686 | 90788 | pSchema->pSeqTab = 0; |
| 90687 | - if( pSchema->flags & DB_SchemaLoaded ){ | |
| 90789 | + if( pSchema->schemaFlags & DB_SchemaLoaded ){ | |
| 90688 | 90790 | pSchema->iGeneration++; |
| 90689 | - pSchema->flags &= ~DB_SchemaLoaded; | |
| 90791 | + pSchema->schemaFlags &= ~DB_SchemaLoaded; | |
| 90690 | 90792 | } |
| 90691 | 90793 | } |
| 90692 | 90794 | |
| 90693 | 90795 | /* |
| 90694 | 90796 | ** Find and return the schema associated with a BTree. Create |
| @@ -93530,11 +93632,11 @@ | ||
| 93530 | 93632 | if( !aiCol ) return 1; |
| 93531 | 93633 | *paiCol = aiCol; |
| 93532 | 93634 | } |
| 93533 | 93635 | |
| 93534 | 93636 | for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 93535 | - if( pIdx->nKeyCol==nCol && pIdx->onError!=OE_None ){ | |
| 93637 | + if( pIdx->nKeyCol==nCol && IsUniqueIndex(pIdx) ){ | |
| 93536 | 93638 | /* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number |
| 93537 | 93639 | ** of columns. If each indexed column corresponds to a foreign key |
| 93538 | 93640 | ** column of pFKey, then this index is a winner. */ |
| 93539 | 93641 | |
| 93540 | 93642 | if( zKey==0 ){ |
| @@ -96556,11 +96658,11 @@ | ||
| 96556 | 96658 | ){ |
| 96557 | 96659 | return 0; /* Default values must be the same for all columns */ |
| 96558 | 96660 | } |
| 96559 | 96661 | } |
| 96560 | 96662 | for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){ |
| 96561 | - if( pDestIdx->onError!=OE_None ){ | |
| 96663 | + if( IsUniqueIndex(pDestIdx) ){ | |
| 96562 | 96664 | destHasUniqueIdx = 1; |
| 96563 | 96665 | } |
| 96564 | 96666 | for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){ |
| 96565 | 96667 | if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break; |
| 96566 | 96668 | } |
| @@ -99627,11 +99729,11 @@ | ||
| 99627 | 99729 | sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC); |
| 99628 | 99730 | sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC); |
| 99629 | 99731 | for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){ |
| 99630 | 99732 | sqlite3VdbeAddOp2(v, OP_Integer, i, 1); |
| 99631 | 99733 | sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0); |
| 99632 | - sqlite3VdbeAddOp2(v, OP_Integer, pIdx->onError!=OE_None, 3); | |
| 99734 | + sqlite3VdbeAddOp2(v, OP_Integer, IsUniqueIndex(pIdx), 3); | |
| 99633 | 99735 | sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); |
| 99634 | 99736 | } |
| 99635 | 99737 | } |
| 99636 | 99738 | } |
| 99637 | 99739 | break; |
| @@ -99877,13 +99979,12 @@ | ||
| 99877 | 99979 | ** messages have been generated, output OK. Otherwise output the |
| 99878 | 99980 | ** error message |
| 99879 | 99981 | */ |
| 99880 | 99982 | static const int iLn = VDBE_OFFSET_LINENO(2); |
| 99881 | 99983 | static const VdbeOpList endCode[] = { |
| 99882 | - { OP_AddImm, 1, 0, 0}, /* 0 */ | |
| 99883 | - { OP_IfNeg, 1, 0, 0}, /* 1 */ | |
| 99884 | - { OP_String8, 0, 3, 0}, /* 2 */ | |
| 99984 | + { OP_IfNeg, 1, 0, 0}, /* 0 */ | |
| 99985 | + { OP_String8, 0, 3, 0}, /* 1 */ | |
| 99885 | 99986 | { OP_ResultRow, 3, 1, 0}, |
| 99886 | 99987 | }; |
| 99887 | 99988 | |
| 99888 | 99989 | int isQuick = (sqlite3Tolower(zLeft[0])=='q'); |
| 99889 | 99990 | |
| @@ -99991,32 +100092,80 @@ | ||
| 99991 | 100092 | sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */ |
| 99992 | 100093 | } |
| 99993 | 100094 | pParse->nMem = MAX(pParse->nMem, 8+j); |
| 99994 | 100095 | sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v); |
| 99995 | 100096 | loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1); |
| 100097 | + /* Verify that all NOT NULL columns really are NOT NULL */ | |
| 100098 | + for(j=0; j<pTab->nCol; j++){ | |
| 100099 | + char *zErr; | |
| 100100 | + int jmp2, jmp3; | |
| 100101 | + if( j==pTab->iPKey ) continue; | |
| 100102 | + if( pTab->aCol[j].notNull==0 ) continue; | |
| 100103 | + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); | |
| 100104 | + sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); | |
| 100105 | + jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v); | |
| 100106 | + sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */ | |
| 100107 | + zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName, | |
| 100108 | + pTab->aCol[j].zName); | |
| 100109 | + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); | |
| 100110 | + sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); | |
| 100111 | + jmp3 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v); | |
| 100112 | + sqlite3VdbeAddOp0(v, OP_Halt); | |
| 100113 | + sqlite3VdbeJumpHere(v, jmp2); | |
| 100114 | + sqlite3VdbeJumpHere(v, jmp3); | |
| 100115 | + } | |
| 100116 | + /* Validate index entries for the current row */ | |
| 99996 | 100117 | for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ |
| 99997 | - int jmp2, jmp3, jmp4; | |
| 100118 | + int jmp2, jmp3, jmp4, jmp5; | |
| 100119 | + int ckUniq = sqlite3VdbeMakeLabel(v); | |
| 99998 | 100120 | if( pPk==pIdx ) continue; |
| 99999 | 100121 | r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3, |
| 100000 | 100122 | pPrior, r1); |
| 100001 | 100123 | pPrior = pIdx; |
| 100002 | 100124 | sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1); /* increment entry count */ |
| 100003 | - jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, 0, r1, | |
| 100125 | + /* Verify that an index entry exists for the current table row */ | |
| 100126 | + jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1, | |
| 100004 | 100127 | pIdx->nColumn); VdbeCoverage(v); |
| 100005 | 100128 | sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */ |
| 100006 | 100129 | sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, "row ", P4_STATIC); |
| 100007 | 100130 | sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); |
| 100008 | - sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, " missing from index ", | |
| 100009 | - P4_STATIC); | |
| 100131 | + sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, | |
| 100132 | + " missing from index ", P4_STATIC); | |
| 100010 | 100133 | sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); |
| 100011 | - sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, pIdx->zName, P4_TRANSIENT); | |
| 100134 | + jmp5 = sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, | |
| 100135 | + pIdx->zName, P4_TRANSIENT); | |
| 100012 | 100136 | sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); |
| 100013 | 100137 | sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); |
| 100014 | 100138 | jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v); |
| 100015 | 100139 | sqlite3VdbeAddOp0(v, OP_Halt); |
| 100016 | - sqlite3VdbeJumpHere(v, jmp4); | |
| 100017 | 100140 | sqlite3VdbeJumpHere(v, jmp2); |
| 100141 | + /* For UNIQUE indexes, verify that only one entry exists with the | |
| 100142 | + ** current key. The entry is unique if (1) any column is NULL | |
| 100143 | + ** or (2) the next entry has a different key */ | |
| 100144 | + if( IsUniqueIndex(pIdx) ){ | |
| 100145 | + int uniqOk = sqlite3VdbeMakeLabel(v); | |
| 100146 | + int jmp6; | |
| 100147 | + int kk; | |
| 100148 | + for(kk=0; kk<pIdx->nKeyCol; kk++){ | |
| 100149 | + int iCol = pIdx->aiColumn[kk]; | |
| 100150 | + assert( iCol>=0 && iCol<pTab->nCol ); | |
| 100151 | + if( pTab->aCol[iCol].notNull ) continue; | |
| 100152 | + sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk); | |
| 100153 | + VdbeCoverage(v); | |
| 100154 | + } | |
| 100155 | + jmp6 = sqlite3VdbeAddOp1(v, OP_Next, iIdxCur+j); VdbeCoverage(v); | |
| 100156 | + sqlite3VdbeAddOp2(v, OP_Goto, 0, uniqOk); | |
| 100157 | + sqlite3VdbeJumpHere(v, jmp6); | |
| 100158 | + sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1, | |
| 100159 | + pIdx->nKeyCol); VdbeCoverage(v); | |
| 100160 | + sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */ | |
| 100161 | + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, | |
| 100162 | + "non-unique entry in index ", P4_STATIC); | |
| 100163 | + sqlite3VdbeAddOp2(v, OP_Goto, 0, jmp5); | |
| 100164 | + sqlite3VdbeResolveLabel(v, uniqOk); | |
| 100165 | + } | |
| 100166 | + sqlite3VdbeJumpHere(v, jmp4); | |
| 100018 | 100167 | sqlite3ResolvePartIdxLabel(pParse, jmp3); |
| 100019 | 100168 | } |
| 100020 | 100169 | sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v); |
| 100021 | 100170 | sqlite3VdbeJumpHere(v, loopTop-1); |
| 100022 | 100171 | #ifndef SQLITE_OMIT_BTREECOUNT |
| @@ -100037,13 +100186,13 @@ | ||
| 100037 | 100186 | } |
| 100038 | 100187 | #endif /* SQLITE_OMIT_BTREECOUNT */ |
| 100039 | 100188 | } |
| 100040 | 100189 | } |
| 100041 | 100190 | addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn); |
| 100042 | - sqlite3VdbeChangeP2(v, addr, -mxErr); | |
| 100043 | - sqlite3VdbeJumpHere(v, addr+1); | |
| 100044 | - sqlite3VdbeChangeP4(v, addr+2, "ok", P4_STATIC); | |
| 100191 | + sqlite3VdbeChangeP3(v, addr, -mxErr); | |
| 100192 | + sqlite3VdbeJumpHere(v, addr); | |
| 100193 | + sqlite3VdbeChangeP4(v, addr+1, "ok", P4_STATIC); | |
| 100045 | 100194 | } |
| 100046 | 100195 | break; |
| 100047 | 100196 | #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ |
| 100048 | 100197 | |
| 100049 | 100198 | #ifndef SQLITE_OMIT_UTF16 |
| @@ -101825,12 +101974,11 @@ | ||
| 101825 | 101974 | int iOffset, /* Register holding the offset counter */ |
| 101826 | 101975 | int iContinue /* Jump here to skip the current record */ |
| 101827 | 101976 | ){ |
| 101828 | 101977 | if( iOffset>0 ){ |
| 101829 | 101978 | int addr; |
| 101830 | - sqlite3VdbeAddOp2(v, OP_AddImm, iOffset, -1); | |
| 101831 | - addr = sqlite3VdbeAddOp1(v, OP_IfNeg, iOffset); VdbeCoverage(v); | |
| 101979 | + addr = sqlite3VdbeAddOp3(v, OP_IfNeg, iOffset, 0, -1); VdbeCoverage(v); | |
| 101832 | 101980 | sqlite3VdbeAddOp2(v, OP_Goto, 0, iContinue); |
| 101833 | 101981 | VdbeComment((v, "skip OFFSET records")); |
| 101834 | 101982 | sqlite3VdbeJumpHere(v, addr); |
| 101835 | 101983 | } |
| 101836 | 101984 | } |
| @@ -108458,11 +108606,12 @@ | ||
| 108458 | 108606 | sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey); |
| 108459 | 108607 | VdbeCoverageNeverTaken(v); |
| 108460 | 108608 | } |
| 108461 | 108609 | labelContinue = labelBreak; |
| 108462 | 108610 | sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak); |
| 108463 | - VdbeCoverage(v); | |
| 108611 | + VdbeCoverageIf(v, pPk==0); | |
| 108612 | + VdbeCoverageIf(v, pPk!=0); | |
| 108464 | 108613 | }else if( pPk ){ |
| 108465 | 108614 | labelContinue = sqlite3VdbeMakeLabel(v); |
| 108466 | 108615 | sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v); |
| 108467 | 108616 | addrTop = sqlite3VdbeAddOp2(v, OP_RowKey, iEph, regKey); |
| 108468 | 108617 | sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0); |
| @@ -112198,11 +112347,11 @@ | ||
| 112198 | 112347 | ** |
| 112199 | 112348 | ** 3. All of those index columns for which the WHERE clause does not |
| 112200 | 112349 | ** contain a "col=X" term are subject to a NOT NULL constraint. |
| 112201 | 112350 | */ |
| 112202 | 112351 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 112203 | - if( pIdx->onError==OE_None ) continue; | |
| 112352 | + if( !IsUniqueIndex(pIdx) ) continue; | |
| 112204 | 112353 | for(i=0; i<pIdx->nKeyCol; i++){ |
| 112205 | 112354 | i16 iCol = pIdx->aiColumn[i]; |
| 112206 | 112355 | if( 0==findTerm(pWC, iBase, iCol, ~(Bitmask)0, WO_EQ, pIdx) ){ |
| 112207 | 112356 | int iIdxCol = findIndexCol(pParse, pDistinct, iBase, pIdx, i); |
| 112208 | 112357 | if( iIdxCol<0 || pTab->aCol[iCol].notNull==0 ){ |
| @@ -113250,11 +113399,11 @@ | ||
| 113250 | 113399 | testcase( bRev ); |
| 113251 | 113400 | bRev = !bRev; |
| 113252 | 113401 | } |
| 113253 | 113402 | assert( pX->op==TK_IN ); |
| 113254 | 113403 | iReg = iTarget; |
| 113255 | - eType = sqlite3FindInIndex(pParse, pX, 0); | |
| 113404 | + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0); | |
| 113256 | 113405 | if( eType==IN_INDEX_INDEX_DESC ){ |
| 113257 | 113406 | testcase( bRev ); |
| 113258 | 113407 | bRev = !bRev; |
| 113259 | 113408 | } |
| 113260 | 113409 | iTab = pX->iTable; |
| @@ -115104,11 +115253,11 @@ | ||
| 115104 | 115253 | ** changes "x IN (?)" into "x=?". */ |
| 115105 | 115254 | |
| 115106 | 115255 | }else if( eOp & (WO_EQ) ){ |
| 115107 | 115256 | pNew->wsFlags |= WHERE_COLUMN_EQ; |
| 115108 | 115257 | if( iCol<0 || (nInMul==0 && pNew->u.btree.nEq==pProbe->nKeyCol-1) ){ |
| 115109 | - if( iCol>=0 && pProbe->onError==OE_None ){ | |
| 115258 | + if( iCol>=0 && !IsUniqueIndex(pProbe) ){ | |
| 115110 | 115259 | pNew->wsFlags |= WHERE_UNQ_WANTED; |
| 115111 | 115260 | }else{ |
| 115112 | 115261 | pNew->wsFlags |= WHERE_ONEROW; |
| 115113 | 115262 | } |
| 115114 | 115263 | } |
| @@ -115959,11 +116108,11 @@ | ||
| 115959 | 116108 | }else{ |
| 115960 | 116109 | nKeyCol = pIndex->nKeyCol; |
| 115961 | 116110 | nColumn = pIndex->nColumn; |
| 115962 | 116111 | assert( nColumn==nKeyCol+1 || !HasRowid(pIndex->pTable) ); |
| 115963 | 116112 | assert( pIndex->aiColumn[nColumn-1]==(-1) || !HasRowid(pIndex->pTable)); |
| 115964 | - isOrderDistinct = pIndex->onError!=OE_None; | |
| 116113 | + isOrderDistinct = IsUniqueIndex(pIndex); | |
| 115965 | 116114 | } |
| 115966 | 116115 | |
| 115967 | 116116 | /* Loop through all columns of the index and deal with the ones |
| 115968 | 116117 | ** that are not constrained by == or IN. |
| 115969 | 116118 | */ |
| @@ -116474,11 +116623,11 @@ | ||
| 116474 | 116623 | pLoop->rRun = 33; /* 33==sqlite3LogEst(10) */ |
| 116475 | 116624 | }else{ |
| 116476 | 116625 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 116477 | 116626 | assert( pLoop->aLTermSpace==pLoop->aLTerm ); |
| 116478 | 116627 | assert( ArraySize(pLoop->aLTermSpace)==4 ); |
| 116479 | - if( pIdx->onError==OE_None | |
| 116628 | + if( !IsUniqueIndex(pIdx) | |
| 116480 | 116629 | || pIdx->pPartIdxWhere!=0 |
| 116481 | 116630 | || pIdx->nKeyCol>ArraySize(pLoop->aLTermSpace) |
| 116482 | 116631 | ) continue; |
| 116483 | 116632 | for(j=0; j<pIdx->nKeyCol; j++){ |
| 116484 | 116633 | pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, WO_EQ, pIdx); |
| 116485 | 116634 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -222,11 +222,11 @@ | |
| 222 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 223 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 224 | */ |
| 225 | #define SQLITE_VERSION "3.8.6" |
| 226 | #define SQLITE_VERSION_NUMBER 3008006 |
| 227 | #define SQLITE_SOURCE_ID "2014-07-31 18:54:01 1e5489faff093d6a8e538061e45532f9050e9459" |
| 228 | |
| 229 | /* |
| 230 | ** CAPI3REF: Run-Time Library Version Numbers |
| 231 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 232 | ** |
| @@ -9407,11 +9407,11 @@ | |
| 9407 | #define OP_FkCounter 131 /* synopsis: fkctr[P1]+=P2 */ |
| 9408 | #define OP_FkIfZero 132 /* synopsis: if fkctr[P1]==0 goto P2 */ |
| 9409 | #define OP_Real 133 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ |
| 9410 | #define OP_MemMax 134 /* synopsis: r[P1]=max(r[P1],r[P2]) */ |
| 9411 | #define OP_IfPos 135 /* synopsis: if r[P1]>0 goto P2 */ |
| 9412 | #define OP_IfNeg 136 /* synopsis: if r[P1]<0 goto P2 */ |
| 9413 | #define OP_IfZero 137 /* synopsis: r[P1]+=P3, if r[P1]==0 goto P2 */ |
| 9414 | #define OP_AggFinal 138 /* synopsis: accum=r[P1] N=P2 */ |
| 9415 | #define OP_IncrVacuum 139 |
| 9416 | #define OP_Expire 140 |
| 9417 | #define OP_TableLock 141 /* synopsis: iDb=P1 root=P2 write=P3 */ |
| @@ -10370,22 +10370,22 @@ | |
| 10370 | Hash trigHash; /* All triggers indexed by name */ |
| 10371 | Hash fkeyHash; /* All foreign keys by referenced table name */ |
| 10372 | Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */ |
| 10373 | u8 file_format; /* Schema format version for this file */ |
| 10374 | u8 enc; /* Text encoding used by this database */ |
| 10375 | u16 flags; /* Flags associated with this schema */ |
| 10376 | int cache_size; /* Number of pages to use in the cache */ |
| 10377 | }; |
| 10378 | |
| 10379 | /* |
| 10380 | ** These macros can be used to test, set, or clear bits in the |
| 10381 | ** Db.pSchema->flags field. |
| 10382 | */ |
| 10383 | #define DbHasProperty(D,I,P) (((D)->aDb[I].pSchema->flags&(P))==(P)) |
| 10384 | #define DbHasAnyProperty(D,I,P) (((D)->aDb[I].pSchema->flags&(P))!=0) |
| 10385 | #define DbSetProperty(D,I,P) (D)->aDb[I].pSchema->flags|=(P) |
| 10386 | #define DbClearProperty(D,I,P) (D)->aDb[I].pSchema->flags&=~(P) |
| 10387 | |
| 10388 | /* |
| 10389 | ** Allowed values for the DB.pSchema->flags field. |
| 10390 | ** |
| 10391 | ** The DB_SchemaLoaded flag is set after the database schema has been |
| @@ -11214,10 +11214,13 @@ | |
| 11214 | #define SQLITE_IDXTYPE_PRIMARYKEY 2 /* Is the PRIMARY KEY for the table */ |
| 11215 | |
| 11216 | /* Return true if index X is a PRIMARY KEY index */ |
| 11217 | #define IsPrimaryKeyIndex(X) ((X)->idxType==SQLITE_IDXTYPE_PRIMARYKEY) |
| 11218 | |
| 11219 | /* |
| 11220 | ** Each sample stored in the sqlite_stat3 table is represented in memory |
| 11221 | ** using a structure of this type. See documentation at the top of the |
| 11222 | ** analyze.c source file for additional information. |
| 11223 | */ |
| @@ -13082,15 +13085,25 @@ | |
| 13082 | #else |
| 13083 | #define sqlite3BeginBenignMalloc() |
| 13084 | #define sqlite3EndBenignMalloc() |
| 13085 | #endif |
| 13086 | |
| 13087 | #define IN_INDEX_ROWID 1 |
| 13088 | #define IN_INDEX_EPH 2 |
| 13089 | #define IN_INDEX_INDEX_ASC 3 |
| 13090 | #define IN_INDEX_INDEX_DESC 4 |
| 13091 | SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, int*); |
| 13092 | |
| 13093 | #ifdef SQLITE_ENABLE_ATOMIC_WRITE |
| 13094 | SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int); |
| 13095 | SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *); |
| 13096 | SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *); |
| @@ -24039,11 +24052,11 @@ | |
| 24039 | /* 131 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), |
| 24040 | /* 132 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), |
| 24041 | /* 133 */ "Real" OpHelp("r[P2]=P4"), |
| 24042 | /* 134 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), |
| 24043 | /* 135 */ "IfPos" OpHelp("if r[P1]>0 goto P2"), |
| 24044 | /* 136 */ "IfNeg" OpHelp("if r[P1]<0 goto P2"), |
| 24045 | /* 137 */ "IfZero" OpHelp("r[P1]+=P3, if r[P1]==0 goto P2"), |
| 24046 | /* 138 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), |
| 24047 | /* 139 */ "IncrVacuum" OpHelp(""), |
| 24048 | /* 140 */ "Expire" OpHelp(""), |
| 24049 | /* 141 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), |
| @@ -51693,11 +51706,11 @@ | |
| 51693 | /* If the client is reading or writing an index and the schema is |
| 51694 | ** not loaded, then it is too difficult to actually check to see if |
| 51695 | ** the correct locks are held. So do not bother - just return true. |
| 51696 | ** This case does not come up very often anyhow. |
| 51697 | */ |
| 51698 | if( isIndex && (!pSchema || (pSchema->flags&DB_SchemaLoaded)==0) ){ |
| 51699 | return 1; |
| 51700 | } |
| 51701 | |
| 51702 | /* Figure out the root-page that the lock should be held on. For table |
| 51703 | ** b-trees, this is just the root page of the b-tree being read or |
| @@ -67993,10 +68006,16 @@ | |
| 67993 | ** |
| 67994 | ** M is an integer, 2 or 3, that indices how many different ways the |
| 67995 | ** branch can go. It is usually 2. "I" is the direction the branch |
| 67996 | ** goes. 0 means falls through. 1 means branch is taken. 2 means the |
| 67997 | ** second alternative branch is taken. |
| 67998 | */ |
| 67999 | #if !defined(SQLITE_VDBE_COVERAGE) |
| 68000 | # define VdbeBranchTaken(I,M) |
| 68001 | #else |
| 68002 | # define VdbeBranchTaken(I,M) vdbeTakeBranch(pOp->iSrcLine,I,M) |
| @@ -68756,11 +68775,11 @@ | |
| 68756 | break; |
| 68757 | } |
| 68758 | |
| 68759 | /* Opcode: EndCoroutine P1 * * * * |
| 68760 | ** |
| 68761 | ** The instruction at the address in register P1 is an Yield. |
| 68762 | ** Jump to the P2 parameter of that Yield. |
| 68763 | ** After the jump, register P1 becomes undefined. |
| 68764 | ** |
| 68765 | ** See also: InitCoroutine |
| 68766 | */ |
| @@ -68949,11 +68968,11 @@ | |
| 68949 | |
| 68950 | /* Opcode: String8 * P2 * P4 * |
| 68951 | ** Synopsis: r[P2]='P4' |
| 68952 | ** |
| 68953 | ** P4 points to a nul terminated UTF-8 string. This opcode is transformed |
| 68954 | ** into an OP_String before it is executed for the first time. During |
| 68955 | ** this transformation, the length of string P4 is computed and stored |
| 68956 | ** as the P1 parameter. |
| 68957 | */ |
| 68958 | case OP_String8: { /* same as TK_STRING, out2-prerelease */ |
| 68959 | assert( pOp->p4.z!=0 ); |
| @@ -70195,17 +70214,17 @@ | |
| 70195 | |
| 70196 | /* Opcode: If P1 P2 P3 * * |
| 70197 | ** |
| 70198 | ** Jump to P2 if the value in register P1 is true. The value |
| 70199 | ** is considered true if it is numeric and non-zero. If the value |
| 70200 | ** in P1 is NULL then take the jump if P3 is non-zero. |
| 70201 | */ |
| 70202 | /* Opcode: IfNot P1 P2 P3 * * |
| 70203 | ** |
| 70204 | ** Jump to P2 if the value in register P1 is False. The value |
| 70205 | ** is considered false if it has a numeric value of zero. If the value |
| 70206 | ** in P1 is NULL then take the jump if P3 is zero. |
| 70207 | */ |
| 70208 | case OP_If: /* jump, in1 */ |
| 70209 | case OP_IfNot: { /* jump, in1 */ |
| 70210 | int c; |
| 70211 | pIn1 = &aMem[pOp->p1]; |
| @@ -71473,11 +71492,11 @@ | |
| 71473 | ** Reposition cursor P1 so that it points to the smallest entry that |
| 71474 | ** is greater than or equal to the key value. If there are no records |
| 71475 | ** greater than or equal to the key and P2 is not zero, then jump to P2. |
| 71476 | ** |
| 71477 | ** This opcode leaves the cursor configured to move in forward order, |
| 71478 | ** from the begining toward the end. In other words, the cursor is |
| 71479 | ** configured to use Next, not Prev. |
| 71480 | ** |
| 71481 | ** See also: Found, NotFound, SeekLt, SeekGt, SeekLe |
| 71482 | */ |
| 71483 | /* Opcode: SeekGT P1 P2 P3 P4 * |
| @@ -71713,13 +71732,13 @@ | |
| 71713 | ** |
| 71714 | ** Cursor P1 is on an index btree. If the record identified by P3 and P4 |
| 71715 | ** is a prefix of any entry in P1 then a jump is made to P2 and |
| 71716 | ** P1 is left pointing at the matching entry. |
| 71717 | ** |
| 71718 | ** This operation leaves the cursor in a state where it cannot be |
| 71719 | ** advanced in either direction. In other words, the Next and Prev |
| 71720 | ** opcodes do not work after this operation. |
| 71721 | ** |
| 71722 | ** See also: NotFound, NoConflict, NotExists. SeekGe |
| 71723 | */ |
| 71724 | /* Opcode: NotFound P1 P2 P3 P4 * |
| 71725 | ** Synopsis: key=r[P3@P4] |
| @@ -71782,11 +71801,11 @@ | |
| 71782 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 71783 | assert( pOp->p4type==P4_INT32 ); |
| 71784 | pC = p->apCsr[pOp->p1]; |
| 71785 | assert( pC!=0 ); |
| 71786 | #ifdef SQLITE_DEBUG |
| 71787 | pC->seekOp = 0; |
| 71788 | #endif |
| 71789 | pIn3 = &aMem[pOp->p3]; |
| 71790 | assert( pC->pCursor!=0 ); |
| 71791 | assert( pC->isTable==0 ); |
| 71792 | pFree = 0; /* Not needed. Only used to suppress a compiler warning. */ |
| @@ -72177,11 +72196,11 @@ | |
| 72177 | ** Delete the record at which the P1 cursor is currently pointing. |
| 72178 | ** |
| 72179 | ** The cursor will be left pointing at either the next or the previous |
| 72180 | ** record in the table. If it is left pointing at the next record, then |
| 72181 | ** the next Next instruction will be a no-op. Hence it is OK to delete |
| 72182 | ** a record from within an Next loop. |
| 72183 | ** |
| 72184 | ** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is |
| 72185 | ** incremented (otherwise not). |
| 72186 | ** |
| 72187 | ** P1 must not be pseudo-table. It has to be a real table with |
| @@ -72240,11 +72259,11 @@ | |
| 72240 | |
| 72241 | /* Opcode: SorterCompare P1 P2 P3 P4 |
| 72242 | ** Synopsis: if key(P1)!=trim(r[P3],P4) goto P2 |
| 72243 | ** |
| 72244 | ** P1 is a sorter cursor. This instruction compares a prefix of the |
| 72245 | ** the record blob in register P3 against a prefix of the entry that |
| 72246 | ** the sorter cursor currently points to. Only the first P4 fields |
| 72247 | ** of r[P3] and the sorter record are compared. |
| 72248 | ** |
| 72249 | ** If either P3 or the sorter contains a NULL in one of their significant |
| 72250 | ** fields (not counting the P4 fields at the end which are ignored) then |
| @@ -72639,11 +72658,11 @@ | |
| 72639 | |
| 72640 | /* The Next opcode is only used after SeekGT, SeekGE, and Rewind. |
| 72641 | ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */ |
| 72642 | assert( pOp->opcode!=OP_Next || pOp->opcode!=OP_NextIfOpen |
| 72643 | || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE |
| 72644 | || pC->seekOp==OP_Rewind ); |
| 72645 | assert( pOp->opcode!=OP_Prev || pOp->opcode!=OP_PrevIfOpen |
| 72646 | || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE |
| 72647 | || pC->seekOp==OP_Last ); |
| 72648 | |
| 72649 | rc = pOp->p4.xAdvance(pC->pCursor, &res); |
| @@ -73566,21 +73585,20 @@ | |
| 73566 | pc = pOp->p2 - 1; |
| 73567 | } |
| 73568 | break; |
| 73569 | } |
| 73570 | |
| 73571 | /* Opcode: IfNeg P1 P2 * * * |
| 73572 | ** Synopsis: if r[P1]<0 goto P2 |
| 73573 | ** |
| 73574 | ** If the value of register P1 is less than zero, jump to P2. |
| 73575 | ** |
| 73576 | ** It is illegal to use this instruction on a register that does |
| 73577 | ** not contain an integer. An assertion fault will result if you try. |
| 73578 | */ |
| 73579 | case OP_IfNeg: { /* jump, in1 */ |
| 73580 | pIn1 = &aMem[pOp->p1]; |
| 73581 | assert( pIn1->flags&MEM_Int ); |
| 73582 | VdbeBranchTaken(pIn1->u.i<0, 2); |
| 73583 | if( pIn1->u.i<0 ){ |
| 73584 | pc = pOp->p2 - 1; |
| 73585 | } |
| 73586 | break; |
| @@ -73589,13 +73607,10 @@ | |
| 73589 | /* Opcode: IfZero P1 P2 P3 * * |
| 73590 | ** Synopsis: r[P1]+=P3, if r[P1]==0 goto P2 |
| 73591 | ** |
| 73592 | ** The register P1 must contain an integer. Add literal P3 to the |
| 73593 | ** value in register P1. If the result is exactly 0, jump to P2. |
| 73594 | ** |
| 73595 | ** It is illegal to use this instruction on a register that does |
| 73596 | ** not contain an integer. An assertion fault will result if you try. |
| 73597 | */ |
| 73598 | case OP_IfZero: { /* jump, in1 */ |
| 73599 | pIn1 = &aMem[pOp->p1]; |
| 73600 | assert( pIn1->flags&MEM_Int ); |
| 73601 | pIn1->u.i += pOp->p3; |
| @@ -79563,10 +79578,13 @@ | |
| 79563 | case TK_INTEGER: |
| 79564 | case TK_STRING: |
| 79565 | case TK_FLOAT: |
| 79566 | case TK_BLOB: |
| 79567 | return 0; |
| 79568 | default: |
| 79569 | return 1; |
| 79570 | } |
| 79571 | } |
| 79572 | |
| @@ -79670,83 +79688,124 @@ | |
| 79670 | SQLITE_PRIVATE int sqlite3CodeOnce(Parse *pParse){ |
| 79671 | Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ |
| 79672 | return sqlite3VdbeAddOp1(v, OP_Once, pParse->nOnce++); |
| 79673 | } |
| 79674 | |
| 79675 | /* |
| 79676 | ** This function is used by the implementation of the IN (...) operator. |
| 79677 | ** The pX parameter is the expression on the RHS of the IN operator, which |
| 79678 | ** might be either a list of expressions or a subquery. |
| 79679 | ** |
| 79680 | ** The job of this routine is to find or create a b-tree object that can |
| 79681 | ** be used either to test for membership in the RHS set or to iterate through |
| 79682 | ** all members of the RHS set, skipping duplicates. |
| 79683 | ** |
| 79684 | ** A cursor is opened on the b-tree object that the RHS of the IN operator |
| 79685 | ** and pX->iTable is set to the index of that cursor. |
| 79686 | ** |
| 79687 | ** The returned value of this function indicates the b-tree type, as follows: |
| 79688 | ** |
| 79689 | ** IN_INDEX_ROWID - The cursor was opened on a database table. |
| 79690 | ** IN_INDEX_INDEX_ASC - The cursor was opened on an ascending index. |
| 79691 | ** IN_INDEX_INDEX_DESC - The cursor was opened on a descending index. |
| 79692 | ** IN_INDEX_EPH - The cursor was opened on a specially created and |
| 79693 | ** populated epheremal table. |
| 79694 | ** |
| 79695 | ** An existing b-tree might be used if the RHS expression pX is a simple |
| 79696 | ** subquery such as: |
| 79697 | ** |
| 79698 | ** SELECT <column> FROM <table> |
| 79699 | ** |
| 79700 | ** If the RHS of the IN operator is a list or a more complex subquery, then |
| 79701 | ** an ephemeral table might need to be generated from the RHS and then |
| 79702 | ** pX->iTable made to point to the ephermeral table instead of an |
| 79703 | ** existing table. |
| 79704 | ** |
| 79705 | ** If the prNotFound parameter is 0, then the b-tree will be used to iterate |
| 79706 | ** through the set members, skipping any duplicates. In this case an |
| 79707 | ** epheremal table must be used unless the selected <column> is guaranteed |
| 79708 | ** to be unique - either because it is an INTEGER PRIMARY KEY or it |
| 79709 | ** has a UNIQUE constraint or UNIQUE index. |
| 79710 | ** |
| 79711 | ** If the prNotFound parameter is not 0, then the b-tree will be used |
| 79712 | ** for fast set membership tests. In this case an epheremal table must |
| 79713 | ** be used unless <column> is an INTEGER PRIMARY KEY or an index can |
| 79714 | ** be found with <column> as its left-most column. |
| 79715 | ** |
| 79716 | ** When the b-tree is being used for membership tests, the calling function |
| 79717 | ** needs to know whether or not the structure contains an SQL NULL |
| 79718 | ** value in order to correctly evaluate expressions like "X IN (Y, Z)". |
| 79719 | ** If there is any chance that the (...) might contain a NULL value at |
| 79720 | ** runtime, then a register is allocated and the register number written |
| 79721 | ** to *prNotFound. If there is no chance that the (...) contains a |
| 79722 | ** NULL value, then *prNotFound is left unchanged. |
| 79723 | ** |
| 79724 | ** If a register is allocated and its location stored in *prNotFound, then |
| 79725 | ** its initial value is NULL. If the (...) does not remain constant |
| 79726 | ** for the duration of the query (i.e. the SELECT within the (...) |
| 79727 | ** is a correlated subquery) then the value of the allocated register is |
| 79728 | ** reset to NULL each time the subquery is rerun. This allows the |
| 79729 | ** caller to use vdbe code equivalent to the following: |
| 79730 | ** |
| 79731 | ** if( register==NULL ){ |
| 79732 | ** has_null = <test if data structure contains null> |
| 79733 | ** register = 1 |
| 79734 | ** } |
| 79735 | ** |
| 79736 | ** in order to avoid running the <test if data structure contains null> |
| 79737 | ** test more often than is necessary. |
| 79738 | */ |
| 79739 | #ifndef SQLITE_OMIT_SUBQUERY |
| 79740 | SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ |
| 79741 | Select *p; /* SELECT to the right of IN operator */ |
| 79742 | int eType = 0; /* Type of RHS table. IN_INDEX_* */ |
| 79743 | int iTab = pParse->nTab++; /* Cursor of the RHS table */ |
| 79744 | int mustBeUnique = (prNotFound==0); /* True if RHS must be unique */ |
| 79745 | Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ |
| 79746 | |
| 79747 | assert( pX->op==TK_IN ); |
| 79748 | |
| 79749 | /* Check to see if an existing table or index can be used to |
| 79750 | ** satisfy the query. This is preferable to generating a new |
| 79751 | ** ephemeral table. |
| 79752 | */ |
| @@ -79799,44 +79858,59 @@ | |
| 79799 | int affinity_ok = sqlite3IndexAffinityOk(pX, pTab->aCol[iCol].affinity); |
| 79800 | |
| 79801 | for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){ |
| 79802 | if( (pIdx->aiColumn[0]==iCol) |
| 79803 | && sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq |
| 79804 | && (!mustBeUnique || (pIdx->nKeyCol==1 && pIdx->onError!=OE_None)) |
| 79805 | ){ |
| 79806 | int iAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v); |
| 79807 | sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb); |
| 79808 | sqlite3VdbeSetP4KeyInfo(pParse, pIdx); |
| 79809 | VdbeComment((v, "%s", pIdx->zName)); |
| 79810 | assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 ); |
| 79811 | eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0]; |
| 79812 | |
| 79813 | if( prNotFound && !pTab->aCol[iCol].notNull ){ |
| 79814 | *prNotFound = ++pParse->nMem; |
| 79815 | sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound); |
| 79816 | } |
| 79817 | sqlite3VdbeJumpHere(v, iAddr); |
| 79818 | } |
| 79819 | } |
| 79820 | } |
| 79821 | } |
| 79822 | |
| 79823 | if( eType==0 ){ |
| 79824 | /* Could not find an existing table or index to use as the RHS b-tree. |
| 79825 | ** We will have to generate an ephemeral table to do the job. |
| 79826 | */ |
| 79827 | u32 savedNQueryLoop = pParse->nQueryLoop; |
| 79828 | int rMayHaveNull = 0; |
| 79829 | eType = IN_INDEX_EPH; |
| 79830 | if( prNotFound ){ |
| 79831 | *prNotFound = rMayHaveNull = ++pParse->nMem; |
| 79832 | sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound); |
| 79833 | }else{ |
| 79834 | pParse->nQueryLoop = 0; |
| 79835 | if( pX->pLeft->iColumn<0 && !ExprHasProperty(pX, EP_xIsSelect) ){ |
| 79836 | eType = IN_INDEX_ROWID; |
| 79837 | } |
| 79838 | } |
| 79839 | sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID); |
| 79840 | pParse->nQueryLoop = savedNQueryLoop; |
| 79841 | }else{ |
| 79842 | pX->iTable = iTab; |
| @@ -79863,31 +79937,25 @@ | |
| 79863 | ** intkey B-Tree to store the set of IN(...) values instead of the usual |
| 79864 | ** (slower) variable length keys B-Tree. |
| 79865 | ** |
| 79866 | ** If rMayHaveNull is non-zero, that means that the operation is an IN |
| 79867 | ** (not a SELECT or EXISTS) and that the RHS might contains NULLs. |
| 79868 | ** Furthermore, the IN is in a WHERE clause and that we really want |
| 79869 | ** to iterate over the RHS of the IN operator in order to quickly locate |
| 79870 | ** all corresponding LHS elements. All this routine does is initialize |
| 79871 | ** the register given by rMayHaveNull to NULL. Calling routines will take |
| 79872 | ** care of changing this register value to non-NULL if the RHS is NULL-free. |
| 79873 | ** |
| 79874 | ** If rMayHaveNull is zero, that means that the subquery is being used |
| 79875 | ** for membership testing only. There is no need to initialize any |
| 79876 | ** registers to indicate the presence or absence of NULLs on the RHS. |
| 79877 | ** |
| 79878 | ** For a SELECT or EXISTS operator, return the register that holds the |
| 79879 | ** result. For IN operators or if an error occurs, the return value is 0. |
| 79880 | */ |
| 79881 | #ifndef SQLITE_OMIT_SUBQUERY |
| 79882 | SQLITE_PRIVATE int sqlite3CodeSubselect( |
| 79883 | Parse *pParse, /* Parsing context */ |
| 79884 | Expr *pExpr, /* The IN, SELECT, or EXISTS operator */ |
| 79885 | int rMayHaveNull, /* Register that records whether NULLs exist in RHS */ |
| 79886 | int isRowid /* If true, LHS of IN operator is a rowid */ |
| 79887 | ){ |
| 79888 | int testAddr = -1; /* One-time test address */ |
| 79889 | int rReg = 0; /* Register storing resulting */ |
| 79890 | Vdbe *v = sqlite3GetVdbe(pParse); |
| 79891 | if( NEVER(v==0) ) return 0; |
| 79892 | sqlite3ExprCachePush(pParse); |
| 79893 | |
| @@ -79900,17 +79968,17 @@ | |
| 79900 | ** |
| 79901 | ** If all of the above are false, then we can run this code just once |
| 79902 | ** save the results, and reuse the same result on subsequent invocations. |
| 79903 | */ |
| 79904 | if( !ExprHasProperty(pExpr, EP_VarSelect) ){ |
| 79905 | testAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v); |
| 79906 | } |
| 79907 | |
| 79908 | #ifndef SQLITE_OMIT_EXPLAIN |
| 79909 | if( pParse->explain==2 ){ |
| 79910 | char *zMsg = sqlite3MPrintf( |
| 79911 | pParse->db, "EXECUTE %s%s SUBQUERY %d", testAddr>=0?"":"CORRELATED ", |
| 79912 | pExpr->op==TK_IN?"LIST":"SCALAR", pParse->iNextSelectId |
| 79913 | ); |
| 79914 | sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC); |
| 79915 | } |
| 79916 | #endif |
| @@ -79920,14 +79988,10 @@ | |
| 79920 | char affinity; /* Affinity of the LHS of the IN */ |
| 79921 | int addr; /* Address of OP_OpenEphemeral instruction */ |
| 79922 | Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */ |
| 79923 | KeyInfo *pKeyInfo = 0; /* Key information */ |
| 79924 | |
| 79925 | if( rMayHaveNull ){ |
| 79926 | sqlite3VdbeAddOp2(v, OP_Null, 0, rMayHaveNull); |
| 79927 | } |
| 79928 | |
| 79929 | affinity = sqlite3ExprAffinity(pLeft); |
| 79930 | |
| 79931 | /* Whether this is an 'x IN(SELECT...)' or an 'x IN(<exprlist>)' |
| 79932 | ** expression it is handled the same way. An ephemeral table is |
| 79933 | ** filled with single-field index keys representing the results |
| @@ -79996,23 +80060,23 @@ | |
| 79996 | } |
| 79997 | |
| 79998 | /* Loop through each expression in <exprlist>. */ |
| 79999 | r1 = sqlite3GetTempReg(pParse); |
| 80000 | r2 = sqlite3GetTempReg(pParse); |
| 80001 | sqlite3VdbeAddOp2(v, OP_Null, 0, r2); |
| 80002 | for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){ |
| 80003 | Expr *pE2 = pItem->pExpr; |
| 80004 | int iValToIns; |
| 80005 | |
| 80006 | /* If the expression is not constant then we will need to |
| 80007 | ** disable the test that was generated above that makes sure |
| 80008 | ** this code only executes once. Because for a non-constant |
| 80009 | ** expression we need to rerun this code each time. |
| 80010 | */ |
| 80011 | if( testAddr>=0 && !sqlite3ExprIsConstant(pE2) ){ |
| 80012 | sqlite3VdbeChangeToNoop(v, testAddr); |
| 80013 | testAddr = -1; |
| 80014 | } |
| 80015 | |
| 80016 | /* Evaluate the expression and insert it into the temp table */ |
| 80017 | if( isRowid && sqlite3ExprIsInteger(pE2, &iValToIns) ){ |
| 80018 | sqlite3VdbeAddOp3(v, OP_InsertInt, pExpr->iTable, r2, iValToIns); |
| @@ -80078,12 +80142,16 @@ | |
| 80078 | ExprSetVVAProperty(pExpr, EP_NoReduce); |
| 80079 | break; |
| 80080 | } |
| 80081 | } |
| 80082 | |
| 80083 | if( testAddr>=0 ){ |
| 80084 | sqlite3VdbeJumpHere(v, testAddr); |
| 80085 | } |
| 80086 | sqlite3ExprCachePop(pParse); |
| 80087 | |
| 80088 | return rReg; |
| 80089 | } |
| @@ -80100,11 +80168,11 @@ | |
| 80100 | ** is an array of zero or more values. The expression is true if the LHS is |
| 80101 | ** contained within the RHS. The value of the expression is unknown (NULL) |
| 80102 | ** if the LHS is NULL or if the LHS is not contained within the RHS and the |
| 80103 | ** RHS contains one or more NULL values. |
| 80104 | ** |
| 80105 | ** This routine generates code will jump to destIfFalse if the LHS is not |
| 80106 | ** contained within the RHS. If due to NULLs we cannot determine if the LHS |
| 80107 | ** is contained in the RHS then jump to destIfNull. If the LHS is contained |
| 80108 | ** within the RHS then fall through. |
| 80109 | */ |
| 80110 | static void sqlite3ExprCodeIN( |
| @@ -80123,11 +80191,13 @@ | |
| 80123 | ** pExpr->iTable will contains the values that make up the RHS. |
| 80124 | */ |
| 80125 | v = pParse->pVdbe; |
| 80126 | assert( v!=0 ); /* OOM detected prior to this routine */ |
| 80127 | VdbeNoopComment((v, "begin IN expr")); |
| 80128 | eType = sqlite3FindInIndex(pParse, pExpr, &rRhsHasNull); |
| 80129 | |
| 80130 | /* Figure out the affinity to use to create a key from the results |
| 80131 | ** of the expression. affinityStr stores a static string suitable for |
| 80132 | ** P4 of OP_MakeRecord. |
| 80133 | */ |
| @@ -80137,86 +80207,118 @@ | |
| 80137 | */ |
| 80138 | sqlite3ExprCachePush(pParse); |
| 80139 | r1 = sqlite3GetTempReg(pParse); |
| 80140 | sqlite3ExprCode(pParse, pExpr->pLeft, r1); |
| 80141 | |
| 80142 | /* If the LHS is NULL, then the result is either false or NULL depending |
| 80143 | ** on whether the RHS is empty or not, respectively. |
| 80144 | */ |
| 80145 | if( destIfNull==destIfFalse ){ |
| 80146 | /* Shortcut for the common case where the false and NULL outcomes are |
| 80147 | ** the same. */ |
| 80148 | sqlite3VdbeAddOp2(v, OP_IsNull, r1, destIfNull); VdbeCoverage(v); |
| 80149 | }else{ |
| 80150 | int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); VdbeCoverage(v); |
| 80151 | sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse); |
| 80152 | VdbeCoverage(v); |
| 80153 | sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull); |
| 80154 | sqlite3VdbeJumpHere(v, addr1); |
| 80155 | } |
| 80156 | |
| 80157 | if( eType==IN_INDEX_ROWID ){ |
| 80158 | /* In this case, the RHS is the ROWID of table b-tree |
| 80159 | */ |
| 80160 | sqlite3VdbeAddOp2(v, OP_MustBeInt, r1, destIfFalse); VdbeCoverage(v); |
| 80161 | sqlite3VdbeAddOp3(v, OP_NotExists, pExpr->iTable, destIfFalse, r1); |
| 80162 | VdbeCoverage(v); |
| 80163 | }else{ |
| 80164 | /* In this case, the RHS is an index b-tree. |
| 80165 | */ |
| 80166 | sqlite3VdbeAddOp4(v, OP_Affinity, r1, 1, 0, &affinity, 1); |
| 80167 | |
| 80168 | /* If the set membership test fails, then the result of the |
| 80169 | ** "x IN (...)" expression must be either 0 or NULL. If the set |
| 80170 | ** contains no NULL values, then the result is 0. If the set |
| 80171 | ** contains one or more NULL values, then the result of the |
| 80172 | ** expression is also NULL. |
| 80173 | */ |
| 80174 | if( rRhsHasNull==0 || destIfFalse==destIfNull ){ |
| 80175 | /* This branch runs if it is known at compile time that the RHS |
| 80176 | ** cannot contain NULL values. This happens as the result |
| 80177 | ** of a "NOT NULL" constraint in the database schema. |
| 80178 | ** |
| 80179 | ** Also run this branch if NULL is equivalent to FALSE |
| 80180 | ** for this particular IN operator. |
| 80181 | */ |
| 80182 | sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse, r1, 1); |
| 80183 | VdbeCoverage(v); |
| 80184 | }else{ |
| 80185 | /* In this branch, the RHS of the IN might contain a NULL and |
| 80186 | ** the presence of a NULL on the RHS makes a difference in the |
| 80187 | ** outcome. |
| 80188 | */ |
| 80189 | int j1, j2; |
| 80190 | |
| 80191 | /* First check to see if the LHS is contained in the RHS. If so, |
| 80192 | ** then the presence of NULLs in the RHS does not matter, so jump |
| 80193 | ** over all of the code that follows. |
| 80194 | */ |
| 80195 | j1 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, r1, 1); |
| 80196 | VdbeCoverage(v); |
| 80197 | |
| 80198 | /* Here we begin generating code that runs if the LHS is not |
| 80199 | ** contained within the RHS. Generate additional code that |
| 80200 | ** tests the RHS for NULLs. If the RHS contains a NULL then |
| 80201 | ** jump to destIfNull. If there are no NULLs in the RHS then |
| 80202 | ** jump to destIfFalse. |
| 80203 | */ |
| 80204 | sqlite3VdbeAddOp2(v, OP_If, rRhsHasNull, destIfNull); VdbeCoverage(v); |
| 80205 | sqlite3VdbeAddOp2(v, OP_IfNot, rRhsHasNull, destIfFalse); VdbeCoverage(v); |
| 80206 | j2 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, rRhsHasNull, 1); |
| 80207 | VdbeCoverage(v); |
| 80208 | sqlite3VdbeAddOp2(v, OP_Integer, 0, rRhsHasNull); |
| 80209 | sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse); |
| 80210 | sqlite3VdbeJumpHere(v, j2); |
| 80211 | sqlite3VdbeAddOp2(v, OP_Integer, 1, rRhsHasNull); |
| 80212 | sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull); |
| 80213 | |
| 80214 | /* The OP_Found at the top of this branch jumps here when true, |
| 80215 | ** causing the overall IN expression evaluation to fall through. |
| 80216 | */ |
| 80217 | sqlite3VdbeJumpHere(v, j1); |
| 80218 | } |
| 80219 | } |
| 80220 | sqlite3ReleaseTempReg(pParse, r1); |
| 80221 | sqlite3ExprCachePop(pParse); |
| 80222 | VdbeComment((v, "end IN expr")); |
| @@ -80836,11 +80938,11 @@ | |
| 80836 | r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); |
| 80837 | testcase( regFree1==0 ); |
| 80838 | addr = sqlite3VdbeAddOp1(v, op, r1); |
| 80839 | VdbeCoverageIf(v, op==TK_ISNULL); |
| 80840 | VdbeCoverageIf(v, op==TK_NOTNULL); |
| 80841 | sqlite3VdbeAddOp2(v, OP_AddImm, target, -1); |
| 80842 | sqlite3VdbeJumpHere(v, addr); |
| 80843 | break; |
| 80844 | } |
| 80845 | case TK_AGG_FUNCTION: { |
| 80846 | AggInfo *pInfo = pExpr->pAggInfo; |
| @@ -80872,11 +80974,11 @@ | |
| 80872 | nFarg = pFarg ? pFarg->nExpr : 0; |
| 80873 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); |
| 80874 | zId = pExpr->u.zToken; |
| 80875 | nId = sqlite3Strlen30(zId); |
| 80876 | pDef = sqlite3FindFunction(db, zId, nId, nFarg, enc, 0); |
| 80877 | if( pDef==0 ){ |
| 80878 | sqlite3ErrorMsg(pParse, "unknown function: %.*s()", nId, zId); |
| 80879 | break; |
| 80880 | } |
| 80881 | |
| 80882 | /* Attempt a direct implementation of the built-in COALESCE() and |
| @@ -84421,11 +84523,11 @@ | |
| 84421 | ** regChng = N |
| 84422 | ** goto endDistinctTest |
| 84423 | */ |
| 84424 | sqlite3VdbeAddOp0(v, OP_Goto); |
| 84425 | addrNextRow = sqlite3VdbeCurrentAddr(v); |
| 84426 | if( nColTest==1 && pIdx->nKeyCol==1 && pIdx->onError!=OE_None ){ |
| 84427 | /* For a single-column UNIQUE index, once we have found a non-NULL |
| 84428 | ** row, we know that all the rest will be distinct, so skip |
| 84429 | ** subsequent distinctness tests. */ |
| 84430 | sqlite3VdbeAddOp2(v, OP_NotNull, regPrev, endDistinctTest); |
| 84431 | VdbeCoverage(v); |
| @@ -88103,11 +88205,11 @@ | |
| 88103 | pTable->aCol = pSelTab->aCol; |
| 88104 | pSelTab->nCol = 0; |
| 88105 | pSelTab->aCol = 0; |
| 88106 | sqlite3DeleteTable(db, pSelTab); |
| 88107 | assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) ); |
| 88108 | pTable->pSchema->flags |= DB_UnresetViews; |
| 88109 | }else{ |
| 88110 | pTable->nCol = 0; |
| 88111 | nErr++; |
| 88112 | } |
| 88113 | sqlite3SelectDelete(db, pSel); |
| @@ -88680,11 +88782,11 @@ | |
| 88680 | (char *)pKey, P4_KEYINFO); |
| 88681 | sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0)); |
| 88682 | |
| 88683 | addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v); |
| 88684 | assert( pKey!=0 || db->mallocFailed || pParse->nErr ); |
| 88685 | if( pIndex->onError!=OE_None && pKey!=0 ){ |
| 88686 | int j2 = sqlite3VdbeCurrentAddr(v) + 3; |
| 88687 | sqlite3VdbeAddOp2(v, OP_Goto, 0, j2); |
| 88688 | addr2 = sqlite3VdbeCurrentAddr(v); |
| 88689 | sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord, |
| 88690 | pIndex->nKeyCol); VdbeCoverage(v); |
| @@ -89077,13 +89179,13 @@ | |
| 89077 | ** considered distinct and both result in separate indices. |
| 89078 | */ |
| 89079 | Index *pIdx; |
| 89080 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 89081 | int k; |
| 89082 | assert( pIdx->onError!=OE_None ); |
| 89083 | assert( pIdx->idxType!=SQLITE_IDXTYPE_APPDEF ); |
| 89084 | assert( pIndex->onError!=OE_None ); |
| 89085 | |
| 89086 | if( pIdx->nKeyCol!=pIndex->nKeyCol ) continue; |
| 89087 | for(k=0; k<pIdx->nKeyCol; k++){ |
| 89088 | const char *z1; |
| 89089 | const char *z2; |
| @@ -89270,11 +89372,11 @@ | |
| 89270 | for(i=nCopy+1; i<=pIdx->nKeyCol; i++){ |
| 89271 | a[i] = 23; assert( 23==sqlite3LogEst(5) ); |
| 89272 | } |
| 89273 | |
| 89274 | assert( 0==sqlite3LogEst(1) ); |
| 89275 | if( pIdx->onError!=OE_None ) a[pIdx->nKeyCol] = 0; |
| 89276 | } |
| 89277 | |
| 89278 | /* |
| 89279 | ** This routine will drop an existing named index. This routine |
| 89280 | ** implements the DROP INDEX statement. |
| @@ -90682,13 +90784,13 @@ | |
| 90682 | sqlite3DeleteTable(0, pTab); |
| 90683 | } |
| 90684 | sqlite3HashClear(&temp1); |
| 90685 | sqlite3HashClear(&pSchema->fkeyHash); |
| 90686 | pSchema->pSeqTab = 0; |
| 90687 | if( pSchema->flags & DB_SchemaLoaded ){ |
| 90688 | pSchema->iGeneration++; |
| 90689 | pSchema->flags &= ~DB_SchemaLoaded; |
| 90690 | } |
| 90691 | } |
| 90692 | |
| 90693 | /* |
| 90694 | ** Find and return the schema associated with a BTree. Create |
| @@ -93530,11 +93632,11 @@ | |
| 93530 | if( !aiCol ) return 1; |
| 93531 | *paiCol = aiCol; |
| 93532 | } |
| 93533 | |
| 93534 | for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 93535 | if( pIdx->nKeyCol==nCol && pIdx->onError!=OE_None ){ |
| 93536 | /* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number |
| 93537 | ** of columns. If each indexed column corresponds to a foreign key |
| 93538 | ** column of pFKey, then this index is a winner. */ |
| 93539 | |
| 93540 | if( zKey==0 ){ |
| @@ -96556,11 +96658,11 @@ | |
| 96556 | ){ |
| 96557 | return 0; /* Default values must be the same for all columns */ |
| 96558 | } |
| 96559 | } |
| 96560 | for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){ |
| 96561 | if( pDestIdx->onError!=OE_None ){ |
| 96562 | destHasUniqueIdx = 1; |
| 96563 | } |
| 96564 | for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){ |
| 96565 | if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break; |
| 96566 | } |
| @@ -99627,11 +99729,11 @@ | |
| 99627 | sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC); |
| 99628 | sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC); |
| 99629 | for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){ |
| 99630 | sqlite3VdbeAddOp2(v, OP_Integer, i, 1); |
| 99631 | sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0); |
| 99632 | sqlite3VdbeAddOp2(v, OP_Integer, pIdx->onError!=OE_None, 3); |
| 99633 | sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); |
| 99634 | } |
| 99635 | } |
| 99636 | } |
| 99637 | break; |
| @@ -99877,13 +99979,12 @@ | |
| 99877 | ** messages have been generated, output OK. Otherwise output the |
| 99878 | ** error message |
| 99879 | */ |
| 99880 | static const int iLn = VDBE_OFFSET_LINENO(2); |
| 99881 | static const VdbeOpList endCode[] = { |
| 99882 | { OP_AddImm, 1, 0, 0}, /* 0 */ |
| 99883 | { OP_IfNeg, 1, 0, 0}, /* 1 */ |
| 99884 | { OP_String8, 0, 3, 0}, /* 2 */ |
| 99885 | { OP_ResultRow, 3, 1, 0}, |
| 99886 | }; |
| 99887 | |
| 99888 | int isQuick = (sqlite3Tolower(zLeft[0])=='q'); |
| 99889 | |
| @@ -99991,32 +100092,80 @@ | |
| 99991 | sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */ |
| 99992 | } |
| 99993 | pParse->nMem = MAX(pParse->nMem, 8+j); |
| 99994 | sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v); |
| 99995 | loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1); |
| 99996 | for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ |
| 99997 | int jmp2, jmp3, jmp4; |
| 99998 | if( pPk==pIdx ) continue; |
| 99999 | r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3, |
| 100000 | pPrior, r1); |
| 100001 | pPrior = pIdx; |
| 100002 | sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1); /* increment entry count */ |
| 100003 | jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, 0, r1, |
| 100004 | pIdx->nColumn); VdbeCoverage(v); |
| 100005 | sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */ |
| 100006 | sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, "row ", P4_STATIC); |
| 100007 | sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); |
| 100008 | sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, " missing from index ", |
| 100009 | P4_STATIC); |
| 100010 | sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); |
| 100011 | sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, pIdx->zName, P4_TRANSIENT); |
| 100012 | sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); |
| 100013 | sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); |
| 100014 | jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v); |
| 100015 | sqlite3VdbeAddOp0(v, OP_Halt); |
| 100016 | sqlite3VdbeJumpHere(v, jmp4); |
| 100017 | sqlite3VdbeJumpHere(v, jmp2); |
| 100018 | sqlite3ResolvePartIdxLabel(pParse, jmp3); |
| 100019 | } |
| 100020 | sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v); |
| 100021 | sqlite3VdbeJumpHere(v, loopTop-1); |
| 100022 | #ifndef SQLITE_OMIT_BTREECOUNT |
| @@ -100037,13 +100186,13 @@ | |
| 100037 | } |
| 100038 | #endif /* SQLITE_OMIT_BTREECOUNT */ |
| 100039 | } |
| 100040 | } |
| 100041 | addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn); |
| 100042 | sqlite3VdbeChangeP2(v, addr, -mxErr); |
| 100043 | sqlite3VdbeJumpHere(v, addr+1); |
| 100044 | sqlite3VdbeChangeP4(v, addr+2, "ok", P4_STATIC); |
| 100045 | } |
| 100046 | break; |
| 100047 | #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ |
| 100048 | |
| 100049 | #ifndef SQLITE_OMIT_UTF16 |
| @@ -101825,12 +101974,11 @@ | |
| 101825 | int iOffset, /* Register holding the offset counter */ |
| 101826 | int iContinue /* Jump here to skip the current record */ |
| 101827 | ){ |
| 101828 | if( iOffset>0 ){ |
| 101829 | int addr; |
| 101830 | sqlite3VdbeAddOp2(v, OP_AddImm, iOffset, -1); |
| 101831 | addr = sqlite3VdbeAddOp1(v, OP_IfNeg, iOffset); VdbeCoverage(v); |
| 101832 | sqlite3VdbeAddOp2(v, OP_Goto, 0, iContinue); |
| 101833 | VdbeComment((v, "skip OFFSET records")); |
| 101834 | sqlite3VdbeJumpHere(v, addr); |
| 101835 | } |
| 101836 | } |
| @@ -108458,11 +108606,12 @@ | |
| 108458 | sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey); |
| 108459 | VdbeCoverageNeverTaken(v); |
| 108460 | } |
| 108461 | labelContinue = labelBreak; |
| 108462 | sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak); |
| 108463 | VdbeCoverage(v); |
| 108464 | }else if( pPk ){ |
| 108465 | labelContinue = sqlite3VdbeMakeLabel(v); |
| 108466 | sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v); |
| 108467 | addrTop = sqlite3VdbeAddOp2(v, OP_RowKey, iEph, regKey); |
| 108468 | sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0); |
| @@ -112198,11 +112347,11 @@ | |
| 112198 | ** |
| 112199 | ** 3. All of those index columns for which the WHERE clause does not |
| 112200 | ** contain a "col=X" term are subject to a NOT NULL constraint. |
| 112201 | */ |
| 112202 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 112203 | if( pIdx->onError==OE_None ) continue; |
| 112204 | for(i=0; i<pIdx->nKeyCol; i++){ |
| 112205 | i16 iCol = pIdx->aiColumn[i]; |
| 112206 | if( 0==findTerm(pWC, iBase, iCol, ~(Bitmask)0, WO_EQ, pIdx) ){ |
| 112207 | int iIdxCol = findIndexCol(pParse, pDistinct, iBase, pIdx, i); |
| 112208 | if( iIdxCol<0 || pTab->aCol[iCol].notNull==0 ){ |
| @@ -113250,11 +113399,11 @@ | |
| 113250 | testcase( bRev ); |
| 113251 | bRev = !bRev; |
| 113252 | } |
| 113253 | assert( pX->op==TK_IN ); |
| 113254 | iReg = iTarget; |
| 113255 | eType = sqlite3FindInIndex(pParse, pX, 0); |
| 113256 | if( eType==IN_INDEX_INDEX_DESC ){ |
| 113257 | testcase( bRev ); |
| 113258 | bRev = !bRev; |
| 113259 | } |
| 113260 | iTab = pX->iTable; |
| @@ -115104,11 +115253,11 @@ | |
| 115104 | ** changes "x IN (?)" into "x=?". */ |
| 115105 | |
| 115106 | }else if( eOp & (WO_EQ) ){ |
| 115107 | pNew->wsFlags |= WHERE_COLUMN_EQ; |
| 115108 | if( iCol<0 || (nInMul==0 && pNew->u.btree.nEq==pProbe->nKeyCol-1) ){ |
| 115109 | if( iCol>=0 && pProbe->onError==OE_None ){ |
| 115110 | pNew->wsFlags |= WHERE_UNQ_WANTED; |
| 115111 | }else{ |
| 115112 | pNew->wsFlags |= WHERE_ONEROW; |
| 115113 | } |
| 115114 | } |
| @@ -115959,11 +116108,11 @@ | |
| 115959 | }else{ |
| 115960 | nKeyCol = pIndex->nKeyCol; |
| 115961 | nColumn = pIndex->nColumn; |
| 115962 | assert( nColumn==nKeyCol+1 || !HasRowid(pIndex->pTable) ); |
| 115963 | assert( pIndex->aiColumn[nColumn-1]==(-1) || !HasRowid(pIndex->pTable)); |
| 115964 | isOrderDistinct = pIndex->onError!=OE_None; |
| 115965 | } |
| 115966 | |
| 115967 | /* Loop through all columns of the index and deal with the ones |
| 115968 | ** that are not constrained by == or IN. |
| 115969 | */ |
| @@ -116474,11 +116623,11 @@ | |
| 116474 | pLoop->rRun = 33; /* 33==sqlite3LogEst(10) */ |
| 116475 | }else{ |
| 116476 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 116477 | assert( pLoop->aLTermSpace==pLoop->aLTerm ); |
| 116478 | assert( ArraySize(pLoop->aLTermSpace)==4 ); |
| 116479 | if( pIdx->onError==OE_None |
| 116480 | || pIdx->pPartIdxWhere!=0 |
| 116481 | || pIdx->nKeyCol>ArraySize(pLoop->aLTermSpace) |
| 116482 | ) continue; |
| 116483 | for(j=0; j<pIdx->nKeyCol; j++){ |
| 116484 | pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, WO_EQ, pIdx); |
| 116485 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -222,11 +222,11 @@ | |
| 222 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 223 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 224 | */ |
| 225 | #define SQLITE_VERSION "3.8.6" |
| 226 | #define SQLITE_VERSION_NUMBER 3008006 |
| 227 | #define SQLITE_SOURCE_ID "2014-08-06 00:29:06 0ad1ed8ef0b5fb5d8db44479373b2b93d8fcfd66" |
| 228 | |
| 229 | /* |
| 230 | ** CAPI3REF: Run-Time Library Version Numbers |
| 231 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 232 | ** |
| @@ -9407,11 +9407,11 @@ | |
| 9407 | #define OP_FkCounter 131 /* synopsis: fkctr[P1]+=P2 */ |
| 9408 | #define OP_FkIfZero 132 /* synopsis: if fkctr[P1]==0 goto P2 */ |
| 9409 | #define OP_Real 133 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ |
| 9410 | #define OP_MemMax 134 /* synopsis: r[P1]=max(r[P1],r[P2]) */ |
| 9411 | #define OP_IfPos 135 /* synopsis: if r[P1]>0 goto P2 */ |
| 9412 | #define OP_IfNeg 136 /* synopsis: r[P1]+=P3, if r[P1]<0 goto P2 */ |
| 9413 | #define OP_IfZero 137 /* synopsis: r[P1]+=P3, if r[P1]==0 goto P2 */ |
| 9414 | #define OP_AggFinal 138 /* synopsis: accum=r[P1] N=P2 */ |
| 9415 | #define OP_IncrVacuum 139 |
| 9416 | #define OP_Expire 140 |
| 9417 | #define OP_TableLock 141 /* synopsis: iDb=P1 root=P2 write=P3 */ |
| @@ -10370,22 +10370,22 @@ | |
| 10370 | Hash trigHash; /* All triggers indexed by name */ |
| 10371 | Hash fkeyHash; /* All foreign keys by referenced table name */ |
| 10372 | Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */ |
| 10373 | u8 file_format; /* Schema format version for this file */ |
| 10374 | u8 enc; /* Text encoding used by this database */ |
| 10375 | u16 schemaFlags; /* Flags associated with this schema */ |
| 10376 | int cache_size; /* Number of pages to use in the cache */ |
| 10377 | }; |
| 10378 | |
| 10379 | /* |
| 10380 | ** These macros can be used to test, set, or clear bits in the |
| 10381 | ** Db.pSchema->flags field. |
| 10382 | */ |
| 10383 | #define DbHasProperty(D,I,P) (((D)->aDb[I].pSchema->schemaFlags&(P))==(P)) |
| 10384 | #define DbHasAnyProperty(D,I,P) (((D)->aDb[I].pSchema->schemaFlags&(P))!=0) |
| 10385 | #define DbSetProperty(D,I,P) (D)->aDb[I].pSchema->schemaFlags|=(P) |
| 10386 | #define DbClearProperty(D,I,P) (D)->aDb[I].pSchema->schemaFlags&=~(P) |
| 10387 | |
| 10388 | /* |
| 10389 | ** Allowed values for the DB.pSchema->flags field. |
| 10390 | ** |
| 10391 | ** The DB_SchemaLoaded flag is set after the database schema has been |
| @@ -11214,10 +11214,13 @@ | |
| 11214 | #define SQLITE_IDXTYPE_PRIMARYKEY 2 /* Is the PRIMARY KEY for the table */ |
| 11215 | |
| 11216 | /* Return true if index X is a PRIMARY KEY index */ |
| 11217 | #define IsPrimaryKeyIndex(X) ((X)->idxType==SQLITE_IDXTYPE_PRIMARYKEY) |
| 11218 | |
| 11219 | /* Return true if index X is a UNIQUE index */ |
| 11220 | #define IsUniqueIndex(X) ((X)->onError!=OE_None) |
| 11221 | |
| 11222 | /* |
| 11223 | ** Each sample stored in the sqlite_stat3 table is represented in memory |
| 11224 | ** using a structure of this type. See documentation at the top of the |
| 11225 | ** analyze.c source file for additional information. |
| 11226 | */ |
| @@ -13082,15 +13085,25 @@ | |
| 13085 | #else |
| 13086 | #define sqlite3BeginBenignMalloc() |
| 13087 | #define sqlite3EndBenignMalloc() |
| 13088 | #endif |
| 13089 | |
| 13090 | /* |
| 13091 | ** Allowed return values from sqlite3FindInIndex() |
| 13092 | */ |
| 13093 | #define IN_INDEX_ROWID 1 /* Search the rowid of the table */ |
| 13094 | #define IN_INDEX_EPH 2 /* Search an ephemeral b-tree */ |
| 13095 | #define IN_INDEX_INDEX_ASC 3 /* Existing index ASCENDING */ |
| 13096 | #define IN_INDEX_INDEX_DESC 4 /* Existing index DESCENDING */ |
| 13097 | #define IN_INDEX_NOOP 5 /* No table available. Use comparisons */ |
| 13098 | /* |
| 13099 | ** Allowed flags for the 3rd parameter to sqlite3FindInIndex(). |
| 13100 | */ |
| 13101 | #define IN_INDEX_NOOP_OK 0x0001 /* OK to return IN_INDEX_NOOP */ |
| 13102 | #define IN_INDEX_MEMBERSHIP 0x0002 /* IN operator used for membership test */ |
| 13103 | #define IN_INDEX_LOOP 0x0004 /* IN operator used as a loop */ |
| 13104 | SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*); |
| 13105 | |
| 13106 | #ifdef SQLITE_ENABLE_ATOMIC_WRITE |
| 13107 | SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int); |
| 13108 | SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *); |
| 13109 | SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *); |
| @@ -24039,11 +24052,11 @@ | |
| 24052 | /* 131 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), |
| 24053 | /* 132 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), |
| 24054 | /* 133 */ "Real" OpHelp("r[P2]=P4"), |
| 24055 | /* 134 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), |
| 24056 | /* 135 */ "IfPos" OpHelp("if r[P1]>0 goto P2"), |
| 24057 | /* 136 */ "IfNeg" OpHelp("r[P1]+=P3, if r[P1]<0 goto P2"), |
| 24058 | /* 137 */ "IfZero" OpHelp("r[P1]+=P3, if r[P1]==0 goto P2"), |
| 24059 | /* 138 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), |
| 24060 | /* 139 */ "IncrVacuum" OpHelp(""), |
| 24061 | /* 140 */ "Expire" OpHelp(""), |
| 24062 | /* 141 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), |
| @@ -51693,11 +51706,11 @@ | |
| 51706 | /* If the client is reading or writing an index and the schema is |
| 51707 | ** not loaded, then it is too difficult to actually check to see if |
| 51708 | ** the correct locks are held. So do not bother - just return true. |
| 51709 | ** This case does not come up very often anyhow. |
| 51710 | */ |
| 51711 | if( isIndex && (!pSchema || (pSchema->schemaFlags&DB_SchemaLoaded)==0) ){ |
| 51712 | return 1; |
| 51713 | } |
| 51714 | |
| 51715 | /* Figure out the root-page that the lock should be held on. For table |
| 51716 | ** b-trees, this is just the root page of the b-tree being read or |
| @@ -67993,10 +68006,16 @@ | |
| 68006 | ** |
| 68007 | ** M is an integer, 2 or 3, that indices how many different ways the |
| 68008 | ** branch can go. It is usually 2. "I" is the direction the branch |
| 68009 | ** goes. 0 means falls through. 1 means branch is taken. 2 means the |
| 68010 | ** second alternative branch is taken. |
| 68011 | ** |
| 68012 | ** iSrcLine is the source code line (from the __LINE__ macro) that |
| 68013 | ** generated the VDBE instruction. This instrumentation assumes that all |
| 68014 | ** source code is in a single file (the amalgamation). Special values 1 |
| 68015 | ** and 2 for the iSrcLine parameter mean that this particular branch is |
| 68016 | ** always taken or never taken, respectively. |
| 68017 | */ |
| 68018 | #if !defined(SQLITE_VDBE_COVERAGE) |
| 68019 | # define VdbeBranchTaken(I,M) |
| 68020 | #else |
| 68021 | # define VdbeBranchTaken(I,M) vdbeTakeBranch(pOp->iSrcLine,I,M) |
| @@ -68756,11 +68775,11 @@ | |
| 68775 | break; |
| 68776 | } |
| 68777 | |
| 68778 | /* Opcode: EndCoroutine P1 * * * * |
| 68779 | ** |
| 68780 | ** The instruction at the address in register P1 is a Yield. |
| 68781 | ** Jump to the P2 parameter of that Yield. |
| 68782 | ** After the jump, register P1 becomes undefined. |
| 68783 | ** |
| 68784 | ** See also: InitCoroutine |
| 68785 | */ |
| @@ -68949,11 +68968,11 @@ | |
| 68968 | |
| 68969 | /* Opcode: String8 * P2 * P4 * |
| 68970 | ** Synopsis: r[P2]='P4' |
| 68971 | ** |
| 68972 | ** P4 points to a nul terminated UTF-8 string. This opcode is transformed |
| 68973 | ** into a String before it is executed for the first time. During |
| 68974 | ** this transformation, the length of string P4 is computed and stored |
| 68975 | ** as the P1 parameter. |
| 68976 | */ |
| 68977 | case OP_String8: { /* same as TK_STRING, out2-prerelease */ |
| 68978 | assert( pOp->p4.z!=0 ); |
| @@ -70195,17 +70214,17 @@ | |
| 70214 | |
| 70215 | /* Opcode: If P1 P2 P3 * * |
| 70216 | ** |
| 70217 | ** Jump to P2 if the value in register P1 is true. The value |
| 70218 | ** is considered true if it is numeric and non-zero. If the value |
| 70219 | ** in P1 is NULL then take the jump if and only if P3 is non-zero. |
| 70220 | */ |
| 70221 | /* Opcode: IfNot P1 P2 P3 * * |
| 70222 | ** |
| 70223 | ** Jump to P2 if the value in register P1 is False. The value |
| 70224 | ** is considered false if it has a numeric value of zero. If the value |
| 70225 | ** in P1 is NULL then take the jump if and only if P3 is non-zero. |
| 70226 | */ |
| 70227 | case OP_If: /* jump, in1 */ |
| 70228 | case OP_IfNot: { /* jump, in1 */ |
| 70229 | int c; |
| 70230 | pIn1 = &aMem[pOp->p1]; |
| @@ -71473,11 +71492,11 @@ | |
| 71492 | ** Reposition cursor P1 so that it points to the smallest entry that |
| 71493 | ** is greater than or equal to the key value. If there are no records |
| 71494 | ** greater than or equal to the key and P2 is not zero, then jump to P2. |
| 71495 | ** |
| 71496 | ** This opcode leaves the cursor configured to move in forward order, |
| 71497 | ** from the beginning toward the end. In other words, the cursor is |
| 71498 | ** configured to use Next, not Prev. |
| 71499 | ** |
| 71500 | ** See also: Found, NotFound, SeekLt, SeekGt, SeekLe |
| 71501 | */ |
| 71502 | /* Opcode: SeekGT P1 P2 P3 P4 * |
| @@ -71713,13 +71732,13 @@ | |
| 71732 | ** |
| 71733 | ** Cursor P1 is on an index btree. If the record identified by P3 and P4 |
| 71734 | ** is a prefix of any entry in P1 then a jump is made to P2 and |
| 71735 | ** P1 is left pointing at the matching entry. |
| 71736 | ** |
| 71737 | ** This operation leaves the cursor in a state where it can be |
| 71738 | ** advanced in the forward direction. The Next instruction will work, |
| 71739 | ** but not the Prev instruction. |
| 71740 | ** |
| 71741 | ** See also: NotFound, NoConflict, NotExists. SeekGe |
| 71742 | */ |
| 71743 | /* Opcode: NotFound P1 P2 P3 P4 * |
| 71744 | ** Synopsis: key=r[P3@P4] |
| @@ -71782,11 +71801,11 @@ | |
| 71801 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 71802 | assert( pOp->p4type==P4_INT32 ); |
| 71803 | pC = p->apCsr[pOp->p1]; |
| 71804 | assert( pC!=0 ); |
| 71805 | #ifdef SQLITE_DEBUG |
| 71806 | pC->seekOp = pOp->opcode; |
| 71807 | #endif |
| 71808 | pIn3 = &aMem[pOp->p3]; |
| 71809 | assert( pC->pCursor!=0 ); |
| 71810 | assert( pC->isTable==0 ); |
| 71811 | pFree = 0; /* Not needed. Only used to suppress a compiler warning. */ |
| @@ -72177,11 +72196,11 @@ | |
| 72196 | ** Delete the record at which the P1 cursor is currently pointing. |
| 72197 | ** |
| 72198 | ** The cursor will be left pointing at either the next or the previous |
| 72199 | ** record in the table. If it is left pointing at the next record, then |
| 72200 | ** the next Next instruction will be a no-op. Hence it is OK to delete |
| 72201 | ** a record from within a Next loop. |
| 72202 | ** |
| 72203 | ** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is |
| 72204 | ** incremented (otherwise not). |
| 72205 | ** |
| 72206 | ** P1 must not be pseudo-table. It has to be a real table with |
| @@ -72240,11 +72259,11 @@ | |
| 72259 | |
| 72260 | /* Opcode: SorterCompare P1 P2 P3 P4 |
| 72261 | ** Synopsis: if key(P1)!=trim(r[P3],P4) goto P2 |
| 72262 | ** |
| 72263 | ** P1 is a sorter cursor. This instruction compares a prefix of the |
| 72264 | ** record blob in register P3 against a prefix of the entry that |
| 72265 | ** the sorter cursor currently points to. Only the first P4 fields |
| 72266 | ** of r[P3] and the sorter record are compared. |
| 72267 | ** |
| 72268 | ** If either P3 or the sorter contains a NULL in one of their significant |
| 72269 | ** fields (not counting the P4 fields at the end which are ignored) then |
| @@ -72639,11 +72658,11 @@ | |
| 72658 | |
| 72659 | /* The Next opcode is only used after SeekGT, SeekGE, and Rewind. |
| 72660 | ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */ |
| 72661 | assert( pOp->opcode!=OP_Next || pOp->opcode!=OP_NextIfOpen |
| 72662 | || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE |
| 72663 | || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found); |
| 72664 | assert( pOp->opcode!=OP_Prev || pOp->opcode!=OP_PrevIfOpen |
| 72665 | || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE |
| 72666 | || pC->seekOp==OP_Last ); |
| 72667 | |
| 72668 | rc = pOp->p4.xAdvance(pC->pCursor, &res); |
| @@ -73566,21 +73585,20 @@ | |
| 73585 | pc = pOp->p2 - 1; |
| 73586 | } |
| 73587 | break; |
| 73588 | } |
| 73589 | |
| 73590 | /* Opcode: IfNeg P1 P2 P3 * * |
| 73591 | ** Synopsis: r[P1]+=P3, if r[P1]<0 goto P2 |
| 73592 | ** |
| 73593 | ** Register P1 must contain an integer. Add literal P3 to the value in |
| 73594 | ** register P1 then if the value of register P1 is less than zero, jump to P2. |
| 73595 | */ |
| 73596 | case OP_IfNeg: { /* jump, in1 */ |
| 73597 | pIn1 = &aMem[pOp->p1]; |
| 73598 | assert( pIn1->flags&MEM_Int ); |
| 73599 | pIn1->u.i += pOp->p3; |
| 73600 | VdbeBranchTaken(pIn1->u.i<0, 2); |
| 73601 | if( pIn1->u.i<0 ){ |
| 73602 | pc = pOp->p2 - 1; |
| 73603 | } |
| 73604 | break; |
| @@ -73589,13 +73607,10 @@ | |
| 73607 | /* Opcode: IfZero P1 P2 P3 * * |
| 73608 | ** Synopsis: r[P1]+=P3, if r[P1]==0 goto P2 |
| 73609 | ** |
| 73610 | ** The register P1 must contain an integer. Add literal P3 to the |
| 73611 | ** value in register P1. If the result is exactly 0, jump to P2. |
| 73612 | */ |
| 73613 | case OP_IfZero: { /* jump, in1 */ |
| 73614 | pIn1 = &aMem[pOp->p1]; |
| 73615 | assert( pIn1->flags&MEM_Int ); |
| 73616 | pIn1->u.i += pOp->p3; |
| @@ -79563,10 +79578,13 @@ | |
| 79578 | case TK_INTEGER: |
| 79579 | case TK_STRING: |
| 79580 | case TK_FLOAT: |
| 79581 | case TK_BLOB: |
| 79582 | return 0; |
| 79583 | case TK_COLUMN: |
| 79584 | assert( p->pTab!=0 ); |
| 79585 | return p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0; |
| 79586 | default: |
| 79587 | return 1; |
| 79588 | } |
| 79589 | } |
| 79590 | |
| @@ -79670,83 +79688,124 @@ | |
| 79688 | SQLITE_PRIVATE int sqlite3CodeOnce(Parse *pParse){ |
| 79689 | Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ |
| 79690 | return sqlite3VdbeAddOp1(v, OP_Once, pParse->nOnce++); |
| 79691 | } |
| 79692 | |
| 79693 | /* |
| 79694 | ** Generate code that checks the left-most column of index table iCur to see if |
| 79695 | ** it contains any NULL entries. Cause the register at regHasNull to be set |
| 79696 | ** to a non-NULL value if iCur contains no NULLs. Cause register regHasNull |
| 79697 | ** to be set to NULL if iCur contains one or more NULL values. |
| 79698 | */ |
| 79699 | static void sqlite3SetHasNullFlag(Vdbe *v, int iCur, int regHasNull){ |
| 79700 | int j1; |
| 79701 | sqlite3VdbeAddOp2(v, OP_Integer, 0, regHasNull); |
| 79702 | j1 = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v); |
| 79703 | sqlite3VdbeAddOp3(v, OP_Column, iCur, 0, regHasNull); |
| 79704 | sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); |
| 79705 | VdbeComment((v, "first_entry_in(%d)", iCur)); |
| 79706 | sqlite3VdbeJumpHere(v, j1); |
| 79707 | } |
| 79708 | |
| 79709 | |
| 79710 | #ifndef SQLITE_OMIT_SUBQUERY |
| 79711 | /* |
| 79712 | ** The argument is an IN operator with a list (not a subquery) on the |
| 79713 | ** right-hand side. Return TRUE if that list is constant. |
| 79714 | */ |
| 79715 | static int sqlite3InRhsIsConstant(Expr *pIn){ |
| 79716 | Expr *pLHS; |
| 79717 | int res; |
| 79718 | assert( !ExprHasProperty(pIn, EP_xIsSelect) ); |
| 79719 | pLHS = pIn->pLeft; |
| 79720 | pIn->pLeft = 0; |
| 79721 | res = sqlite3ExprIsConstant(pIn); |
| 79722 | pIn->pLeft = pLHS; |
| 79723 | return res; |
| 79724 | } |
| 79725 | #endif |
| 79726 | |
| 79727 | /* |
| 79728 | ** This function is used by the implementation of the IN (...) operator. |
| 79729 | ** The pX parameter is the expression on the RHS of the IN operator, which |
| 79730 | ** might be either a list of expressions or a subquery. |
| 79731 | ** |
| 79732 | ** The job of this routine is to find or create a b-tree object that can |
| 79733 | ** be used either to test for membership in the RHS set or to iterate through |
| 79734 | ** all members of the RHS set, skipping duplicates. |
| 79735 | ** |
| 79736 | ** A cursor is opened on the b-tree object that is the RHS of the IN operator |
| 79737 | ** and pX->iTable is set to the index of that cursor. |
| 79738 | ** |
| 79739 | ** The returned value of this function indicates the b-tree type, as follows: |
| 79740 | ** |
| 79741 | ** IN_INDEX_ROWID - The cursor was opened on a database table. |
| 79742 | ** IN_INDEX_INDEX_ASC - The cursor was opened on an ascending index. |
| 79743 | ** IN_INDEX_INDEX_DESC - The cursor was opened on a descending index. |
| 79744 | ** IN_INDEX_EPH - The cursor was opened on a specially created and |
| 79745 | ** populated epheremal table. |
| 79746 | ** IN_INDEX_NOOP - No cursor was allocated. The IN operator must be |
| 79747 | ** implemented as a sequence of comparisons. |
| 79748 | ** |
| 79749 | ** An existing b-tree might be used if the RHS expression pX is a simple |
| 79750 | ** subquery such as: |
| 79751 | ** |
| 79752 | ** SELECT <column> FROM <table> |
| 79753 | ** |
| 79754 | ** If the RHS of the IN operator is a list or a more complex subquery, then |
| 79755 | ** an ephemeral table might need to be generated from the RHS and then |
| 79756 | ** pX->iTable made to point to the ephermeral table instead of an |
| 79757 | ** existing table. |
| 79758 | ** |
| 79759 | ** The inFlags parameter must contain exactly one of the bits |
| 79760 | ** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP. If inFlags contains |
| 79761 | ** IN_INDEX_MEMBERSHIP, then the generated table will be used for a |
| 79762 | ** fast membership test. When the IN_INDEX_LOOP bit is set, the |
| 79763 | ** IN index will be used to loop over all values of the RHS of the |
| 79764 | ** IN operator. |
| 79765 | ** |
| 79766 | ** When IN_INDEX_LOOP is used (and the b-tree will be used to iterate |
| 79767 | ** through the set members) then the b-tree must not contain duplicates. |
| 79768 | ** An epheremal table must be used unless the selected <column> is guaranteed |
| 79769 | ** to be unique - either because it is an INTEGER PRIMARY KEY or it |
| 79770 | ** has a UNIQUE constraint or UNIQUE index. |
| 79771 | ** |
| 79772 | ** When IN_INDEX_MEMBERSHIP is used (and the b-tree will be used |
| 79773 | ** for fast set membership tests) then an epheremal table must |
| 79774 | ** be used unless <column> is an INTEGER PRIMARY KEY or an index can |
| 79775 | ** be found with <column> as its left-most column. |
| 79776 | ** |
| 79777 | ** If the IN_INDEX_NOOP_OK and IN_INDEX_MEMBERSHIP are both set and |
| 79778 | ** if the RHS of the IN operator is a list (not a subquery) then this |
| 79779 | ** routine might decide that creating an ephemeral b-tree for membership |
| 79780 | ** testing is too expensive and return IN_INDEX_NOOP. In that case, the |
| 79781 | ** calling routine should implement the IN operator using a sequence |
| 79782 | ** of Eq or Ne comparison operations. |
| 79783 | ** |
| 79784 | ** When the b-tree is being used for membership tests, the calling function |
| 79785 | ** might need to know whether or not the RHS side of the IN operator |
| 79786 | ** contains a NULL. If prRhsHasNull is not a NULL pointer and |
| 79787 | ** if there is any chance that the (...) might contain a NULL value at |
| 79788 | ** runtime, then a register is allocated and the register number written |
| 79789 | ** to *prRhsHasNull. If there is no chance that the (...) contains a |
| 79790 | ** NULL value, then *prRhsHasNull is left unchanged. |
| 79791 | ** |
| 79792 | ** If a register is allocated and its location stored in *prRhsHasNull, then |
| 79793 | ** the value in that register will be NULL if the b-tree contains one or more |
| 79794 | ** NULL values, and it will be some non-NULL value if the b-tree contains no |
| 79795 | ** NULL values. |
| 79796 | */ |
| 79797 | #ifndef SQLITE_OMIT_SUBQUERY |
| 79798 | SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int *prRhsHasNull){ |
| 79799 | Select *p; /* SELECT to the right of IN operator */ |
| 79800 | int eType = 0; /* Type of RHS table. IN_INDEX_* */ |
| 79801 | int iTab = pParse->nTab++; /* Cursor of the RHS table */ |
| 79802 | int mustBeUnique; /* True if RHS must be unique */ |
| 79803 | Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ |
| 79804 | |
| 79805 | assert( pX->op==TK_IN ); |
| 79806 | mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0; |
| 79807 | |
| 79808 | /* Check to see if an existing table or index can be used to |
| 79809 | ** satisfy the query. This is preferable to generating a new |
| 79810 | ** ephemeral table. |
| 79811 | */ |
| @@ -79799,44 +79858,59 @@ | |
| 79858 | int affinity_ok = sqlite3IndexAffinityOk(pX, pTab->aCol[iCol].affinity); |
| 79859 | |
| 79860 | for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){ |
| 79861 | if( (pIdx->aiColumn[0]==iCol) |
| 79862 | && sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq |
| 79863 | && (!mustBeUnique || (pIdx->nKeyCol==1 && IsUniqueIndex(pIdx))) |
| 79864 | ){ |
| 79865 | int iAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v); |
| 79866 | sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb); |
| 79867 | sqlite3VdbeSetP4KeyInfo(pParse, pIdx); |
| 79868 | VdbeComment((v, "%s", pIdx->zName)); |
| 79869 | assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 ); |
| 79870 | eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0]; |
| 79871 | |
| 79872 | if( prRhsHasNull && !pTab->aCol[iCol].notNull ){ |
| 79873 | *prRhsHasNull = ++pParse->nMem; |
| 79874 | sqlite3SetHasNullFlag(v, iTab, *prRhsHasNull); |
| 79875 | } |
| 79876 | sqlite3VdbeJumpHere(v, iAddr); |
| 79877 | } |
| 79878 | } |
| 79879 | } |
| 79880 | } |
| 79881 | |
| 79882 | /* If no preexisting index is available for the IN clause |
| 79883 | ** and IN_INDEX_NOOP is an allowed reply |
| 79884 | ** and the RHS of the IN operator is a list, not a subquery |
| 79885 | ** and the RHS is not contant or has two or fewer terms, |
| 79886 | ** then it is not worth creating an ephermeral table to evaluate |
| 79887 | ** the IN operator so return IN_INDEX_NOOP. |
| 79888 | */ |
| 79889 | if( eType==0 |
| 79890 | && (inFlags & IN_INDEX_NOOP_OK) |
| 79891 | && !ExprHasProperty(pX, EP_xIsSelect) |
| 79892 | && (!sqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2) |
| 79893 | ){ |
| 79894 | eType = IN_INDEX_NOOP; |
| 79895 | } |
| 79896 | |
| 79897 | |
| 79898 | if( eType==0 ){ |
| 79899 | /* Could not find an existing table or index to use as the RHS b-tree. |
| 79900 | ** We will have to generate an ephemeral table to do the job. |
| 79901 | */ |
| 79902 | u32 savedNQueryLoop = pParse->nQueryLoop; |
| 79903 | int rMayHaveNull = 0; |
| 79904 | eType = IN_INDEX_EPH; |
| 79905 | if( inFlags & IN_INDEX_LOOP ){ |
| 79906 | pParse->nQueryLoop = 0; |
| 79907 | if( pX->pLeft->iColumn<0 && !ExprHasProperty(pX, EP_xIsSelect) ){ |
| 79908 | eType = IN_INDEX_ROWID; |
| 79909 | } |
| 79910 | }else if( prRhsHasNull ){ |
| 79911 | *prRhsHasNull = rMayHaveNull = ++pParse->nMem; |
| 79912 | } |
| 79913 | sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID); |
| 79914 | pParse->nQueryLoop = savedNQueryLoop; |
| 79915 | }else{ |
| 79916 | pX->iTable = iTab; |
| @@ -79863,31 +79937,25 @@ | |
| 79937 | ** intkey B-Tree to store the set of IN(...) values instead of the usual |
| 79938 | ** (slower) variable length keys B-Tree. |
| 79939 | ** |
| 79940 | ** If rMayHaveNull is non-zero, that means that the operation is an IN |
| 79941 | ** (not a SELECT or EXISTS) and that the RHS might contains NULLs. |
| 79942 | ** All this routine does is initialize the register given by rMayHaveNull |
| 79943 | ** to NULL. Calling routines will take care of changing this register |
| 79944 | ** value to non-NULL if the RHS is NULL-free. |
| 79945 | ** |
| 79946 | ** For a SELECT or EXISTS operator, return the register that holds the |
| 79947 | ** result. For IN operators or if an error occurs, the return value is 0. |
| 79948 | */ |
| 79949 | #ifndef SQLITE_OMIT_SUBQUERY |
| 79950 | SQLITE_PRIVATE int sqlite3CodeSubselect( |
| 79951 | Parse *pParse, /* Parsing context */ |
| 79952 | Expr *pExpr, /* The IN, SELECT, or EXISTS operator */ |
| 79953 | int rHasNullFlag, /* Register that records whether NULLs exist in RHS */ |
| 79954 | int isRowid /* If true, LHS of IN operator is a rowid */ |
| 79955 | ){ |
| 79956 | int jmpIfDynamic = -1; /* One-time test address */ |
| 79957 | int rReg = 0; /* Register storing resulting */ |
| 79958 | Vdbe *v = sqlite3GetVdbe(pParse); |
| 79959 | if( NEVER(v==0) ) return 0; |
| 79960 | sqlite3ExprCachePush(pParse); |
| 79961 | |
| @@ -79900,17 +79968,17 @@ | |
| 79968 | ** |
| 79969 | ** If all of the above are false, then we can run this code just once |
| 79970 | ** save the results, and reuse the same result on subsequent invocations. |
| 79971 | */ |
| 79972 | if( !ExprHasProperty(pExpr, EP_VarSelect) ){ |
| 79973 | jmpIfDynamic = sqlite3CodeOnce(pParse); VdbeCoverage(v); |
| 79974 | } |
| 79975 | |
| 79976 | #ifndef SQLITE_OMIT_EXPLAIN |
| 79977 | if( pParse->explain==2 ){ |
| 79978 | char *zMsg = sqlite3MPrintf( |
| 79979 | pParse->db, "EXECUTE %s%s SUBQUERY %d", jmpIfDynamic>=0?"":"CORRELATED ", |
| 79980 | pExpr->op==TK_IN?"LIST":"SCALAR", pParse->iNextSelectId |
| 79981 | ); |
| 79982 | sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC); |
| 79983 | } |
| 79984 | #endif |
| @@ -79920,14 +79988,10 @@ | |
| 79988 | char affinity; /* Affinity of the LHS of the IN */ |
| 79989 | int addr; /* Address of OP_OpenEphemeral instruction */ |
| 79990 | Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */ |
| 79991 | KeyInfo *pKeyInfo = 0; /* Key information */ |
| 79992 | |
| 79993 | affinity = sqlite3ExprAffinity(pLeft); |
| 79994 | |
| 79995 | /* Whether this is an 'x IN(SELECT...)' or an 'x IN(<exprlist>)' |
| 79996 | ** expression it is handled the same way. An ephemeral table is |
| 79997 | ** filled with single-field index keys representing the results |
| @@ -79996,23 +80060,23 @@ | |
| 80060 | } |
| 80061 | |
| 80062 | /* Loop through each expression in <exprlist>. */ |
| 80063 | r1 = sqlite3GetTempReg(pParse); |
| 80064 | r2 = sqlite3GetTempReg(pParse); |
| 80065 | if( isRowid ) sqlite3VdbeAddOp2(v, OP_Null, 0, r2); |
| 80066 | for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){ |
| 80067 | Expr *pE2 = pItem->pExpr; |
| 80068 | int iValToIns; |
| 80069 | |
| 80070 | /* If the expression is not constant then we will need to |
| 80071 | ** disable the test that was generated above that makes sure |
| 80072 | ** this code only executes once. Because for a non-constant |
| 80073 | ** expression we need to rerun this code each time. |
| 80074 | */ |
| 80075 | if( jmpIfDynamic>=0 && !sqlite3ExprIsConstant(pE2) ){ |
| 80076 | sqlite3VdbeChangeToNoop(v, jmpIfDynamic); |
| 80077 | jmpIfDynamic = -1; |
| 80078 | } |
| 80079 | |
| 80080 | /* Evaluate the expression and insert it into the temp table */ |
| 80081 | if( isRowid && sqlite3ExprIsInteger(pE2, &iValToIns) ){ |
| 80082 | sqlite3VdbeAddOp3(v, OP_InsertInt, pExpr->iTable, r2, iValToIns); |
| @@ -80078,12 +80142,16 @@ | |
| 80142 | ExprSetVVAProperty(pExpr, EP_NoReduce); |
| 80143 | break; |
| 80144 | } |
| 80145 | } |
| 80146 | |
| 80147 | if( rHasNullFlag ){ |
| 80148 | sqlite3SetHasNullFlag(v, pExpr->iTable, rHasNullFlag); |
| 80149 | } |
| 80150 | |
| 80151 | if( jmpIfDynamic>=0 ){ |
| 80152 | sqlite3VdbeJumpHere(v, jmpIfDynamic); |
| 80153 | } |
| 80154 | sqlite3ExprCachePop(pParse); |
| 80155 | |
| 80156 | return rReg; |
| 80157 | } |
| @@ -80100,11 +80168,11 @@ | |
| 80168 | ** is an array of zero or more values. The expression is true if the LHS is |
| 80169 | ** contained within the RHS. The value of the expression is unknown (NULL) |
| 80170 | ** if the LHS is NULL or if the LHS is not contained within the RHS and the |
| 80171 | ** RHS contains one or more NULL values. |
| 80172 | ** |
| 80173 | ** This routine generates code that jumps to destIfFalse if the LHS is not |
| 80174 | ** contained within the RHS. If due to NULLs we cannot determine if the LHS |
| 80175 | ** is contained in the RHS then jump to destIfNull. If the LHS is contained |
| 80176 | ** within the RHS then fall through. |
| 80177 | */ |
| 80178 | static void sqlite3ExprCodeIN( |
| @@ -80123,11 +80191,13 @@ | |
| 80191 | ** pExpr->iTable will contains the values that make up the RHS. |
| 80192 | */ |
| 80193 | v = pParse->pVdbe; |
| 80194 | assert( v!=0 ); /* OOM detected prior to this routine */ |
| 80195 | VdbeNoopComment((v, "begin IN expr")); |
| 80196 | eType = sqlite3FindInIndex(pParse, pExpr, |
| 80197 | IN_INDEX_MEMBERSHIP | IN_INDEX_NOOP_OK, |
| 80198 | destIfFalse==destIfNull ? 0 : &rRhsHasNull); |
| 80199 | |
| 80200 | /* Figure out the affinity to use to create a key from the results |
| 80201 | ** of the expression. affinityStr stores a static string suitable for |
| 80202 | ** P4 of OP_MakeRecord. |
| 80203 | */ |
| @@ -80137,86 +80207,118 @@ | |
| 80207 | */ |
| 80208 | sqlite3ExprCachePush(pParse); |
| 80209 | r1 = sqlite3GetTempReg(pParse); |
| 80210 | sqlite3ExprCode(pParse, pExpr->pLeft, r1); |
| 80211 | |
| 80212 | /* If sqlite3FindInIndex() did not find or create an index that is |
| 80213 | ** suitable for evaluating the IN operator, then evaluate using a |
| 80214 | ** sequence of comparisons. |
| 80215 | */ |
| 80216 | if( eType==IN_INDEX_NOOP ){ |
| 80217 | ExprList *pList = pExpr->x.pList; |
| 80218 | CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft); |
| 80219 | int labelOk = sqlite3VdbeMakeLabel(v); |
| 80220 | int r2, regToFree; |
| 80221 | int regCkNull = 0; |
| 80222 | int ii; |
| 80223 | assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); |
| 80224 | if( destIfNull!=destIfFalse ){ |
| 80225 | regCkNull = sqlite3GetTempReg(pParse); |
| 80226 | sqlite3VdbeAddOp3(v, OP_BitAnd, r1, r1, regCkNull); |
| 80227 | } |
| 80228 | for(ii=0; ii<pList->nExpr; ii++){ |
| 80229 | r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, ®ToFree); |
| 80230 | if( regCkNull && sqlite3ExprCanBeNull(pList->a[ii].pExpr) ){ |
| 80231 | sqlite3VdbeAddOp3(v, OP_BitAnd, regCkNull, r2, regCkNull); |
| 80232 | } |
| 80233 | if( ii<pList->nExpr-1 || destIfNull!=destIfFalse ){ |
| 80234 | sqlite3VdbeAddOp4(v, OP_Eq, r1, labelOk, r2, |
| 80235 | (void*)pColl, P4_COLLSEQ); |
| 80236 | VdbeCoverageIf(v, ii<pList->nExpr-1); |
| 80237 | VdbeCoverageIf(v, ii==pList->nExpr-1); |
| 80238 | sqlite3VdbeChangeP5(v, affinity); |
| 80239 | }else{ |
| 80240 | assert( destIfNull==destIfFalse ); |
| 80241 | sqlite3VdbeAddOp4(v, OP_Ne, r1, destIfFalse, r2, |
| 80242 | (void*)pColl, P4_COLLSEQ); VdbeCoverage(v); |
| 80243 | sqlite3VdbeChangeP5(v, affinity | SQLITE_JUMPIFNULL); |
| 80244 | } |
| 80245 | sqlite3ReleaseTempReg(pParse, regToFree); |
| 80246 | } |
| 80247 | if( regCkNull ){ |
| 80248 | sqlite3VdbeAddOp2(v, OP_IsNull, regCkNull, destIfNull); VdbeCoverage(v); |
| 80249 | sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse); |
| 80250 | } |
| 80251 | sqlite3VdbeResolveLabel(v, labelOk); |
| 80252 | sqlite3ReleaseTempReg(pParse, regCkNull); |
| 80253 | }else{ |
| 80254 | |
| 80255 | /* If the LHS is NULL, then the result is either false or NULL depending |
| 80256 | ** on whether the RHS is empty or not, respectively. |
| 80257 | */ |
| 80258 | if( sqlite3ExprCanBeNull(pExpr->pLeft) ){ |
| 80259 | if( destIfNull==destIfFalse ){ |
| 80260 | /* Shortcut for the common case where the false and NULL outcomes are |
| 80261 | ** the same. */ |
| 80262 | sqlite3VdbeAddOp2(v, OP_IsNull, r1, destIfNull); VdbeCoverage(v); |
| 80263 | }else{ |
| 80264 | int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); VdbeCoverage(v); |
| 80265 | sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse); |
| 80266 | VdbeCoverage(v); |
| 80267 | sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull); |
| 80268 | sqlite3VdbeJumpHere(v, addr1); |
| 80269 | } |
| 80270 | } |
| 80271 | |
| 80272 | if( eType==IN_INDEX_ROWID ){ |
| 80273 | /* In this case, the RHS is the ROWID of table b-tree |
| 80274 | */ |
| 80275 | sqlite3VdbeAddOp2(v, OP_MustBeInt, r1, destIfFalse); VdbeCoverage(v); |
| 80276 | sqlite3VdbeAddOp3(v, OP_NotExists, pExpr->iTable, destIfFalse, r1); |
| 80277 | VdbeCoverage(v); |
| 80278 | }else{ |
| 80279 | /* In this case, the RHS is an index b-tree. |
| 80280 | */ |
| 80281 | sqlite3VdbeAddOp4(v, OP_Affinity, r1, 1, 0, &affinity, 1); |
| 80282 | |
| 80283 | /* If the set membership test fails, then the result of the |
| 80284 | ** "x IN (...)" expression must be either 0 or NULL. If the set |
| 80285 | ** contains no NULL values, then the result is 0. If the set |
| 80286 | ** contains one or more NULL values, then the result of the |
| 80287 | ** expression is also NULL. |
| 80288 | */ |
| 80289 | assert( destIfFalse!=destIfNull || rRhsHasNull==0 ); |
| 80290 | if( rRhsHasNull==0 ){ |
| 80291 | /* This branch runs if it is known at compile time that the RHS |
| 80292 | ** cannot contain NULL values. This happens as the result |
| 80293 | ** of a "NOT NULL" constraint in the database schema. |
| 80294 | ** |
| 80295 | ** Also run this branch if NULL is equivalent to FALSE |
| 80296 | ** for this particular IN operator. |
| 80297 | */ |
| 80298 | sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse, r1, 1); |
| 80299 | VdbeCoverage(v); |
| 80300 | }else{ |
| 80301 | /* In this branch, the RHS of the IN might contain a NULL and |
| 80302 | ** the presence of a NULL on the RHS makes a difference in the |
| 80303 | ** outcome. |
| 80304 | */ |
| 80305 | int j1; |
| 80306 | |
| 80307 | /* First check to see if the LHS is contained in the RHS. If so, |
| 80308 | ** then the answer is TRUE the presence of NULLs in the RHS does |
| 80309 | ** not matter. If the LHS is not contained in the RHS, then the |
| 80310 | ** answer is NULL if the RHS contains NULLs and the answer is |
| 80311 | ** FALSE if the RHS is NULL-free. |
| 80312 | */ |
| 80313 | j1 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, r1, 1); |
| 80314 | VdbeCoverage(v); |
| 80315 | sqlite3VdbeAddOp2(v, OP_IsNull, rRhsHasNull, destIfNull); |
| 80316 | VdbeCoverage(v); |
| 80317 | sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse); |
| 80318 | sqlite3VdbeJumpHere(v, j1); |
| 80319 | } |
| 80320 | } |
| 80321 | } |
| 80322 | sqlite3ReleaseTempReg(pParse, r1); |
| 80323 | sqlite3ExprCachePop(pParse); |
| 80324 | VdbeComment((v, "end IN expr")); |
| @@ -80836,11 +80938,11 @@ | |
| 80938 | r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); |
| 80939 | testcase( regFree1==0 ); |
| 80940 | addr = sqlite3VdbeAddOp1(v, op, r1); |
| 80941 | VdbeCoverageIf(v, op==TK_ISNULL); |
| 80942 | VdbeCoverageIf(v, op==TK_NOTNULL); |
| 80943 | sqlite3VdbeAddOp2(v, OP_Integer, 0, target); |
| 80944 | sqlite3VdbeJumpHere(v, addr); |
| 80945 | break; |
| 80946 | } |
| 80947 | case TK_AGG_FUNCTION: { |
| 80948 | AggInfo *pInfo = pExpr->pAggInfo; |
| @@ -80872,11 +80974,11 @@ | |
| 80974 | nFarg = pFarg ? pFarg->nExpr : 0; |
| 80975 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); |
| 80976 | zId = pExpr->u.zToken; |
| 80977 | nId = sqlite3Strlen30(zId); |
| 80978 | pDef = sqlite3FindFunction(db, zId, nId, nFarg, enc, 0); |
| 80979 | if( pDef==0 || pDef->xFunc==0 ){ |
| 80980 | sqlite3ErrorMsg(pParse, "unknown function: %.*s()", nId, zId); |
| 80981 | break; |
| 80982 | } |
| 80983 | |
| 80984 | /* Attempt a direct implementation of the built-in COALESCE() and |
| @@ -84421,11 +84523,11 @@ | |
| 84523 | ** regChng = N |
| 84524 | ** goto endDistinctTest |
| 84525 | */ |
| 84526 | sqlite3VdbeAddOp0(v, OP_Goto); |
| 84527 | addrNextRow = sqlite3VdbeCurrentAddr(v); |
| 84528 | if( nColTest==1 && pIdx->nKeyCol==1 && IsUniqueIndex(pIdx) ){ |
| 84529 | /* For a single-column UNIQUE index, once we have found a non-NULL |
| 84530 | ** row, we know that all the rest will be distinct, so skip |
| 84531 | ** subsequent distinctness tests. */ |
| 84532 | sqlite3VdbeAddOp2(v, OP_NotNull, regPrev, endDistinctTest); |
| 84533 | VdbeCoverage(v); |
| @@ -88103,11 +88205,11 @@ | |
| 88205 | pTable->aCol = pSelTab->aCol; |
| 88206 | pSelTab->nCol = 0; |
| 88207 | pSelTab->aCol = 0; |
| 88208 | sqlite3DeleteTable(db, pSelTab); |
| 88209 | assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) ); |
| 88210 | pTable->pSchema->schemaFlags |= DB_UnresetViews; |
| 88211 | }else{ |
| 88212 | pTable->nCol = 0; |
| 88213 | nErr++; |
| 88214 | } |
| 88215 | sqlite3SelectDelete(db, pSel); |
| @@ -88680,11 +88782,11 @@ | |
| 88782 | (char *)pKey, P4_KEYINFO); |
| 88783 | sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0)); |
| 88784 | |
| 88785 | addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v); |
| 88786 | assert( pKey!=0 || db->mallocFailed || pParse->nErr ); |
| 88787 | if( IsUniqueIndex(pIndex) && pKey!=0 ){ |
| 88788 | int j2 = sqlite3VdbeCurrentAddr(v) + 3; |
| 88789 | sqlite3VdbeAddOp2(v, OP_Goto, 0, j2); |
| 88790 | addr2 = sqlite3VdbeCurrentAddr(v); |
| 88791 | sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord, |
| 88792 | pIndex->nKeyCol); VdbeCoverage(v); |
| @@ -89077,13 +89179,13 @@ | |
| 89179 | ** considered distinct and both result in separate indices. |
| 89180 | */ |
| 89181 | Index *pIdx; |
| 89182 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 89183 | int k; |
| 89184 | assert( IsUniqueIndex(pIdx) ); |
| 89185 | assert( pIdx->idxType!=SQLITE_IDXTYPE_APPDEF ); |
| 89186 | assert( IsUniqueIndex(pIndex) ); |
| 89187 | |
| 89188 | if( pIdx->nKeyCol!=pIndex->nKeyCol ) continue; |
| 89189 | for(k=0; k<pIdx->nKeyCol; k++){ |
| 89190 | const char *z1; |
| 89191 | const char *z2; |
| @@ -89270,11 +89372,11 @@ | |
| 89372 | for(i=nCopy+1; i<=pIdx->nKeyCol; i++){ |
| 89373 | a[i] = 23; assert( 23==sqlite3LogEst(5) ); |
| 89374 | } |
| 89375 | |
| 89376 | assert( 0==sqlite3LogEst(1) ); |
| 89377 | if( IsUniqueIndex(pIdx) ) a[pIdx->nKeyCol] = 0; |
| 89378 | } |
| 89379 | |
| 89380 | /* |
| 89381 | ** This routine will drop an existing named index. This routine |
| 89382 | ** implements the DROP INDEX statement. |
| @@ -90682,13 +90784,13 @@ | |
| 90784 | sqlite3DeleteTable(0, pTab); |
| 90785 | } |
| 90786 | sqlite3HashClear(&temp1); |
| 90787 | sqlite3HashClear(&pSchema->fkeyHash); |
| 90788 | pSchema->pSeqTab = 0; |
| 90789 | if( pSchema->schemaFlags & DB_SchemaLoaded ){ |
| 90790 | pSchema->iGeneration++; |
| 90791 | pSchema->schemaFlags &= ~DB_SchemaLoaded; |
| 90792 | } |
| 90793 | } |
| 90794 | |
| 90795 | /* |
| 90796 | ** Find and return the schema associated with a BTree. Create |
| @@ -93530,11 +93632,11 @@ | |
| 93632 | if( !aiCol ) return 1; |
| 93633 | *paiCol = aiCol; |
| 93634 | } |
| 93635 | |
| 93636 | for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 93637 | if( pIdx->nKeyCol==nCol && IsUniqueIndex(pIdx) ){ |
| 93638 | /* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number |
| 93639 | ** of columns. If each indexed column corresponds to a foreign key |
| 93640 | ** column of pFKey, then this index is a winner. */ |
| 93641 | |
| 93642 | if( zKey==0 ){ |
| @@ -96556,11 +96658,11 @@ | |
| 96658 | ){ |
| 96659 | return 0; /* Default values must be the same for all columns */ |
| 96660 | } |
| 96661 | } |
| 96662 | for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){ |
| 96663 | if( IsUniqueIndex(pDestIdx) ){ |
| 96664 | destHasUniqueIdx = 1; |
| 96665 | } |
| 96666 | for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){ |
| 96667 | if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break; |
| 96668 | } |
| @@ -99627,11 +99729,11 @@ | |
| 99729 | sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC); |
| 99730 | sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC); |
| 99731 | for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){ |
| 99732 | sqlite3VdbeAddOp2(v, OP_Integer, i, 1); |
| 99733 | sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0); |
| 99734 | sqlite3VdbeAddOp2(v, OP_Integer, IsUniqueIndex(pIdx), 3); |
| 99735 | sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); |
| 99736 | } |
| 99737 | } |
| 99738 | } |
| 99739 | break; |
| @@ -99877,13 +99979,12 @@ | |
| 99979 | ** messages have been generated, output OK. Otherwise output the |
| 99980 | ** error message |
| 99981 | */ |
| 99982 | static const int iLn = VDBE_OFFSET_LINENO(2); |
| 99983 | static const VdbeOpList endCode[] = { |
| 99984 | { OP_IfNeg, 1, 0, 0}, /* 0 */ |
| 99985 | { OP_String8, 0, 3, 0}, /* 1 */ |
| 99986 | { OP_ResultRow, 3, 1, 0}, |
| 99987 | }; |
| 99988 | |
| 99989 | int isQuick = (sqlite3Tolower(zLeft[0])=='q'); |
| 99990 | |
| @@ -99991,32 +100092,80 @@ | |
| 100092 | sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */ |
| 100093 | } |
| 100094 | pParse->nMem = MAX(pParse->nMem, 8+j); |
| 100095 | sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v); |
| 100096 | loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1); |
| 100097 | /* Verify that all NOT NULL columns really are NOT NULL */ |
| 100098 | for(j=0; j<pTab->nCol; j++){ |
| 100099 | char *zErr; |
| 100100 | int jmp2, jmp3; |
| 100101 | if( j==pTab->iPKey ) continue; |
| 100102 | if( pTab->aCol[j].notNull==0 ) continue; |
| 100103 | sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); |
| 100104 | sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); |
| 100105 | jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v); |
| 100106 | sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */ |
| 100107 | zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName, |
| 100108 | pTab->aCol[j].zName); |
| 100109 | sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); |
| 100110 | sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); |
| 100111 | jmp3 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v); |
| 100112 | sqlite3VdbeAddOp0(v, OP_Halt); |
| 100113 | sqlite3VdbeJumpHere(v, jmp2); |
| 100114 | sqlite3VdbeJumpHere(v, jmp3); |
| 100115 | } |
| 100116 | /* Validate index entries for the current row */ |
| 100117 | for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ |
| 100118 | int jmp2, jmp3, jmp4, jmp5; |
| 100119 | int ckUniq = sqlite3VdbeMakeLabel(v); |
| 100120 | if( pPk==pIdx ) continue; |
| 100121 | r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3, |
| 100122 | pPrior, r1); |
| 100123 | pPrior = pIdx; |
| 100124 | sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1); /* increment entry count */ |
| 100125 | /* Verify that an index entry exists for the current table row */ |
| 100126 | jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1, |
| 100127 | pIdx->nColumn); VdbeCoverage(v); |
| 100128 | sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */ |
| 100129 | sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, "row ", P4_STATIC); |
| 100130 | sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); |
| 100131 | sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, |
| 100132 | " missing from index ", P4_STATIC); |
| 100133 | sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); |
| 100134 | jmp5 = sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, |
| 100135 | pIdx->zName, P4_TRANSIENT); |
| 100136 | sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); |
| 100137 | sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); |
| 100138 | jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v); |
| 100139 | sqlite3VdbeAddOp0(v, OP_Halt); |
| 100140 | sqlite3VdbeJumpHere(v, jmp2); |
| 100141 | /* For UNIQUE indexes, verify that only one entry exists with the |
| 100142 | ** current key. The entry is unique if (1) any column is NULL |
| 100143 | ** or (2) the next entry has a different key */ |
| 100144 | if( IsUniqueIndex(pIdx) ){ |
| 100145 | int uniqOk = sqlite3VdbeMakeLabel(v); |
| 100146 | int jmp6; |
| 100147 | int kk; |
| 100148 | for(kk=0; kk<pIdx->nKeyCol; kk++){ |
| 100149 | int iCol = pIdx->aiColumn[kk]; |
| 100150 | assert( iCol>=0 && iCol<pTab->nCol ); |
| 100151 | if( pTab->aCol[iCol].notNull ) continue; |
| 100152 | sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk); |
| 100153 | VdbeCoverage(v); |
| 100154 | } |
| 100155 | jmp6 = sqlite3VdbeAddOp1(v, OP_Next, iIdxCur+j); VdbeCoverage(v); |
| 100156 | sqlite3VdbeAddOp2(v, OP_Goto, 0, uniqOk); |
| 100157 | sqlite3VdbeJumpHere(v, jmp6); |
| 100158 | sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1, |
| 100159 | pIdx->nKeyCol); VdbeCoverage(v); |
| 100160 | sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */ |
| 100161 | sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, |
| 100162 | "non-unique entry in index ", P4_STATIC); |
| 100163 | sqlite3VdbeAddOp2(v, OP_Goto, 0, jmp5); |
| 100164 | sqlite3VdbeResolveLabel(v, uniqOk); |
| 100165 | } |
| 100166 | sqlite3VdbeJumpHere(v, jmp4); |
| 100167 | sqlite3ResolvePartIdxLabel(pParse, jmp3); |
| 100168 | } |
| 100169 | sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v); |
| 100170 | sqlite3VdbeJumpHere(v, loopTop-1); |
| 100171 | #ifndef SQLITE_OMIT_BTREECOUNT |
| @@ -100037,13 +100186,13 @@ | |
| 100186 | } |
| 100187 | #endif /* SQLITE_OMIT_BTREECOUNT */ |
| 100188 | } |
| 100189 | } |
| 100190 | addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn); |
| 100191 | sqlite3VdbeChangeP3(v, addr, -mxErr); |
| 100192 | sqlite3VdbeJumpHere(v, addr); |
| 100193 | sqlite3VdbeChangeP4(v, addr+1, "ok", P4_STATIC); |
| 100194 | } |
| 100195 | break; |
| 100196 | #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ |
| 100197 | |
| 100198 | #ifndef SQLITE_OMIT_UTF16 |
| @@ -101825,12 +101974,11 @@ | |
| 101974 | int iOffset, /* Register holding the offset counter */ |
| 101975 | int iContinue /* Jump here to skip the current record */ |
| 101976 | ){ |
| 101977 | if( iOffset>0 ){ |
| 101978 | int addr; |
| 101979 | addr = sqlite3VdbeAddOp3(v, OP_IfNeg, iOffset, 0, -1); VdbeCoverage(v); |
| 101980 | sqlite3VdbeAddOp2(v, OP_Goto, 0, iContinue); |
| 101981 | VdbeComment((v, "skip OFFSET records")); |
| 101982 | sqlite3VdbeJumpHere(v, addr); |
| 101983 | } |
| 101984 | } |
| @@ -108458,11 +108606,12 @@ | |
| 108606 | sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey); |
| 108607 | VdbeCoverageNeverTaken(v); |
| 108608 | } |
| 108609 | labelContinue = labelBreak; |
| 108610 | sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak); |
| 108611 | VdbeCoverageIf(v, pPk==0); |
| 108612 | VdbeCoverageIf(v, pPk!=0); |
| 108613 | }else if( pPk ){ |
| 108614 | labelContinue = sqlite3VdbeMakeLabel(v); |
| 108615 | sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v); |
| 108616 | addrTop = sqlite3VdbeAddOp2(v, OP_RowKey, iEph, regKey); |
| 108617 | sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0); |
| @@ -112198,11 +112347,11 @@ | |
| 112347 | ** |
| 112348 | ** 3. All of those index columns for which the WHERE clause does not |
| 112349 | ** contain a "col=X" term are subject to a NOT NULL constraint. |
| 112350 | */ |
| 112351 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 112352 | if( !IsUniqueIndex(pIdx) ) continue; |
| 112353 | for(i=0; i<pIdx->nKeyCol; i++){ |
| 112354 | i16 iCol = pIdx->aiColumn[i]; |
| 112355 | if( 0==findTerm(pWC, iBase, iCol, ~(Bitmask)0, WO_EQ, pIdx) ){ |
| 112356 | int iIdxCol = findIndexCol(pParse, pDistinct, iBase, pIdx, i); |
| 112357 | if( iIdxCol<0 || pTab->aCol[iCol].notNull==0 ){ |
| @@ -113250,11 +113399,11 @@ | |
| 113399 | testcase( bRev ); |
| 113400 | bRev = !bRev; |
| 113401 | } |
| 113402 | assert( pX->op==TK_IN ); |
| 113403 | iReg = iTarget; |
| 113404 | eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0); |
| 113405 | if( eType==IN_INDEX_INDEX_DESC ){ |
| 113406 | testcase( bRev ); |
| 113407 | bRev = !bRev; |
| 113408 | } |
| 113409 | iTab = pX->iTable; |
| @@ -115104,11 +115253,11 @@ | |
| 115253 | ** changes "x IN (?)" into "x=?". */ |
| 115254 | |
| 115255 | }else if( eOp & (WO_EQ) ){ |
| 115256 | pNew->wsFlags |= WHERE_COLUMN_EQ; |
| 115257 | if( iCol<0 || (nInMul==0 && pNew->u.btree.nEq==pProbe->nKeyCol-1) ){ |
| 115258 | if( iCol>=0 && !IsUniqueIndex(pProbe) ){ |
| 115259 | pNew->wsFlags |= WHERE_UNQ_WANTED; |
| 115260 | }else{ |
| 115261 | pNew->wsFlags |= WHERE_ONEROW; |
| 115262 | } |
| 115263 | } |
| @@ -115959,11 +116108,11 @@ | |
| 116108 | }else{ |
| 116109 | nKeyCol = pIndex->nKeyCol; |
| 116110 | nColumn = pIndex->nColumn; |
| 116111 | assert( nColumn==nKeyCol+1 || !HasRowid(pIndex->pTable) ); |
| 116112 | assert( pIndex->aiColumn[nColumn-1]==(-1) || !HasRowid(pIndex->pTable)); |
| 116113 | isOrderDistinct = IsUniqueIndex(pIndex); |
| 116114 | } |
| 116115 | |
| 116116 | /* Loop through all columns of the index and deal with the ones |
| 116117 | ** that are not constrained by == or IN. |
| 116118 | */ |
| @@ -116474,11 +116623,11 @@ | |
| 116623 | pLoop->rRun = 33; /* 33==sqlite3LogEst(10) */ |
| 116624 | }else{ |
| 116625 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 116626 | assert( pLoop->aLTermSpace==pLoop->aLTerm ); |
| 116627 | assert( ArraySize(pLoop->aLTermSpace)==4 ); |
| 116628 | if( !IsUniqueIndex(pIdx) |
| 116629 | || pIdx->pPartIdxWhere!=0 |
| 116630 | || pIdx->nKeyCol>ArraySize(pLoop->aLTermSpace) |
| 116631 | ) continue; |
| 116632 | for(j=0; j<pIdx->nKeyCol; j++){ |
| 116633 | pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, WO_EQ, pIdx); |
| 116634 |
+1
-1
| --- src/sqlite3.h | ||
| +++ src/sqlite3.h | ||
| @@ -107,11 +107,11 @@ | ||
| 107 | 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | 109 | */ |
| 110 | 110 | #define SQLITE_VERSION "3.8.6" |
| 111 | 111 | #define SQLITE_VERSION_NUMBER 3008006 |
| 112 | -#define SQLITE_SOURCE_ID "2014-07-31 18:54:01 1e5489faff093d6a8e538061e45532f9050e9459" | |
| 112 | +#define SQLITE_SOURCE_ID "2014-08-06 00:29:06 0ad1ed8ef0b5fb5d8db44479373b2b93d8fcfd66" | |
| 113 | 113 | |
| 114 | 114 | /* |
| 115 | 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | 117 | ** |
| 118 | 118 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -107,11 +107,11 @@ | |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.8.6" |
| 111 | #define SQLITE_VERSION_NUMBER 3008006 |
| 112 | #define SQLITE_SOURCE_ID "2014-07-31 18:54:01 1e5489faff093d6a8e538061e45532f9050e9459" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| 118 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -107,11 +107,11 @@ | |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.8.6" |
| 111 | #define SQLITE_VERSION_NUMBER 3008006 |
| 112 | #define SQLITE_SOURCE_ID "2014-08-06 00:29:06 0ad1ed8ef0b5fb5d8db44479373b2b93d8fcfd66" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| 118 |