| | @@ -1,8 +1,8 @@ |
| 1 | 1 | /****************************************************************************** |
| 2 | 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | | -** version 3.7.17. By combining all the individual C code files into this |
| 3 | +** version 3.8.0. By combining all the individual C code files into this |
| 4 | 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | 6 | ** possible if the files were compiled separately. Performance improvements |
| 7 | 7 | ** of 5% or more are commonly seen when SQLite is compiled as a single |
| 8 | 8 | ** translation unit. |
| | @@ -668,13 +668,13 @@ |
| 668 | 668 | ** |
| 669 | 669 | ** See also: [sqlite3_libversion()], |
| 670 | 670 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 671 | 671 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 672 | 672 | */ |
| 673 | | -#define SQLITE_VERSION "3.7.17" |
| 674 | | -#define SQLITE_VERSION_NUMBER 3007017 |
| 675 | | -#define SQLITE_SOURCE_ID "2013-06-20 14:17:39 d94db3fd921890ab1d6414ab629410ae50779686" |
| 673 | +#define SQLITE_VERSION "3.8.0" |
| 674 | +#define SQLITE_VERSION_NUMBER 3008000 |
| 675 | +#define SQLITE_SOURCE_ID "2013-07-09 03:04:32 52a49cbc1621094b2fe2b021209b768d29e0426b" |
| 676 | 676 | |
| 677 | 677 | /* |
| 678 | 678 | ** CAPI3REF: Run-Time Library Version Numbers |
| 679 | 679 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 680 | 680 | ** |
| | @@ -1041,10 +1041,11 @@ |
| 1041 | 1041 | #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) |
| 1042 | 1042 | #define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8)) |
| 1043 | 1043 | #define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8)) |
| 1044 | 1044 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) |
| 1045 | 1045 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) |
| 1046 | +#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) |
| 1046 | 1047 | #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) |
| 1047 | 1048 | #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) |
| 1048 | 1049 | #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) |
| 1049 | 1050 | #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) |
| 1050 | 1051 | #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) |
| | @@ -1060,10 +1061,11 @@ |
| 1060 | 1061 | #define SQLITE_CONSTRAINT_TRIGGER (SQLITE_CONSTRAINT | (7<<8)) |
| 1061 | 1062 | #define SQLITE_CONSTRAINT_UNIQUE (SQLITE_CONSTRAINT | (8<<8)) |
| 1062 | 1063 | #define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8)) |
| 1063 | 1064 | #define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8)) |
| 1064 | 1065 | #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8)) |
| 1066 | +#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8)) |
| 1065 | 1067 | |
| 1066 | 1068 | /* |
| 1067 | 1069 | ** CAPI3REF: Flags For File Open Operations |
| 1068 | 1070 | ** |
| 1069 | 1071 | ** These bit values are intended for use in the |
| | @@ -6869,15 +6871,25 @@ |
| 6869 | 6871 | ** <dd>^This is the number of rows inserted into transient indices that |
| 6870 | 6872 | ** were created automatically in order to help joins run faster. |
| 6871 | 6873 | ** A non-zero value in this counter may indicate an opportunity to |
| 6872 | 6874 | ** improvement performance by adding permanent indices that do not |
| 6873 | 6875 | ** need to be reinitialized each time the statement is run.</dd> |
| 6876 | +** |
| 6877 | +** [[SQLITE_STMTSTATUS_VM_STEP]] <dt>SQLITE_STMTSTATUS_VM_STEP</dt> |
| 6878 | +** <dd>^This is the number of virtual machine operations executed |
| 6879 | +** by the prepared statement if that number is less than or equal |
| 6880 | +** to 2147483647. The number of virtual machine operations can be |
| 6881 | +** used as a proxy for the total work done by the prepared statement. |
| 6882 | +** If the number of virtual machine operations exceeds 2147483647 |
| 6883 | +** then the value returned by this statement status code is undefined. |
| 6884 | +** </dd> |
| 6874 | 6885 | ** </dl> |
| 6875 | 6886 | */ |
| 6876 | 6887 | #define SQLITE_STMTSTATUS_FULLSCAN_STEP 1 |
| 6877 | 6888 | #define SQLITE_STMTSTATUS_SORT 2 |
| 6878 | 6889 | #define SQLITE_STMTSTATUS_AUTOINDEX 3 |
| 6890 | +#define SQLITE_STMTSTATUS_VM_STEP 4 |
| 6879 | 6891 | |
| 6880 | 6892 | /* |
| 6881 | 6893 | ** CAPI3REF: Custom Page Cache Object |
| 6882 | 6894 | ** |
| 6883 | 6895 | ** The sqlite3_pcache type is opaque. It is implemented by |
| | @@ -10066,13 +10078,14 @@ |
| 10066 | 10078 | int newTnum; /* Rootpage of table being initialized */ |
| 10067 | 10079 | u8 iDb; /* Which db file is being initialized */ |
| 10068 | 10080 | u8 busy; /* TRUE if currently initializing */ |
| 10069 | 10081 | u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */ |
| 10070 | 10082 | } init; |
| 10071 | | - int activeVdbeCnt; /* Number of VDBEs currently executing */ |
| 10072 | | - int writeVdbeCnt; /* Number of active VDBEs that are writing */ |
| 10073 | | - int vdbeExecCnt; /* Number of nested calls to VdbeExec() */ |
| 10083 | + int nVdbeActive; /* Number of VDBEs currently running */ |
| 10084 | + int nVdbeRead; /* Number of active VDBEs that read or write */ |
| 10085 | + int nVdbeWrite; /* Number of active VDBEs that read and write */ |
| 10086 | + int nVdbeExec; /* Number of nested calls to VdbeExec() */ |
| 10074 | 10087 | int nExtension; /* Number of loaded extensions */ |
| 10075 | 10088 | void **aExtension; /* Array of shared library handles */ |
| 10076 | 10089 | void (*xTrace)(void*,const char*); /* Trace function */ |
| 10077 | 10090 | void *pTraceArg; /* Argument to the trace function */ |
| 10078 | 10091 | void (*xProfile)(void*,const char*,u64); /* Profiling function */ |
| | @@ -10193,10 +10206,12 @@ |
| 10193 | 10206 | #define SQLITE_DistinctOpt 0x0020 /* DISTINCT using indexes */ |
| 10194 | 10207 | #define SQLITE_CoverIdxScan 0x0040 /* Covering index scans */ |
| 10195 | 10208 | #define SQLITE_OrderByIdxJoin 0x0080 /* ORDER BY of joins via index */ |
| 10196 | 10209 | #define SQLITE_SubqCoroutine 0x0100 /* Evaluate subqueries as coroutines */ |
| 10197 | 10210 | #define SQLITE_Transitive 0x0200 /* Transitive constraints */ |
| 10211 | +#define SQLITE_OmitNoopJoin 0x0400 /* Omit unused tables in joins */ |
| 10212 | +#define SQLITE_Stat3 0x0800 /* Use the SQLITE_STAT3 table */ |
| 10198 | 10213 | #define SQLITE_AllOpts 0xffff /* All optimizations */ |
| 10199 | 10214 | |
| 10200 | 10215 | /* |
| 10201 | 10216 | ** Macros for testing whether or not optimizations are enabled or disabled. |
| 10202 | 10217 | */ |
| | @@ -11143,10 +11158,11 @@ |
| 11143 | 11158 | #define WHERE_FORCE_TABLE 0x0020 /* Do not use an index-only search */ |
| 11144 | 11159 | #define WHERE_ONETABLE_ONLY 0x0040 /* Only code the 1st table in pTabList */ |
| 11145 | 11160 | #define WHERE_AND_ONLY 0x0080 /* Don't use indices for OR terms */ |
| 11146 | 11161 | #define WHERE_GROUPBY 0x0100 /* pOrderBy is really a GROUP BY */ |
| 11147 | 11162 | #define WHERE_DISTINCTBY 0x0200 /* pOrderby is really a DISTINCT clause */ |
| 11163 | +#define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */ |
| 11148 | 11164 | |
| 11149 | 11165 | /* Allowed return values from sqlite3WhereIsDistinct() |
| 11150 | 11166 | */ |
| 11151 | 11167 | #define WHERE_DISTINCT_NOOP 0 /* DISTINCT keyword not used */ |
| 11152 | 11168 | #define WHERE_DISTINCT_UNIQUE 1 /* No duplicates */ |
| | @@ -13500,18 +13516,19 @@ |
| 13500 | 13516 | bft inVtabMethod:2; /* See comments above */ |
| 13501 | 13517 | bft changeCntOn:1; /* True to update the change-counter */ |
| 13502 | 13518 | bft expired:1; /* True if the VM needs to be recompiled */ |
| 13503 | 13519 | bft runOnlyOnce:1; /* Automatically expire on reset */ |
| 13504 | 13520 | bft usesStmtJournal:1; /* True if uses a statement journal */ |
| 13505 | | - bft readOnly:1; /* True for read-only statements */ |
| 13521 | + bft readOnly:1; /* True for statements that do not write */ |
| 13522 | + bft bIsReader:1; /* True for statements that read */ |
| 13506 | 13523 | bft isPrepareV2:1; /* True if prepared with prepare_v2() */ |
| 13507 | 13524 | bft doingRerun:1; /* True if rerunning after an auto-reprepare */ |
| 13508 | 13525 | int nChange; /* Number of db changes made since last reset */ |
| 13509 | 13526 | yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */ |
| 13510 | 13527 | yDbMask lockMask; /* Subset of btreeMask that requires a lock */ |
| 13511 | 13528 | int iStatement; /* Statement number (or 0 if has not opened stmt) */ |
| 13512 | | - int aCounter[3]; /* Counters used by sqlite3_stmt_status() */ |
| 13529 | + int aCounter[4]; /* Counters used by sqlite3_stmt_status() */ |
| 13513 | 13530 | #ifndef SQLITE_OMIT_TRACE |
| 13514 | 13531 | i64 startTime; /* Time when query started - used for profiling */ |
| 13515 | 13532 | #endif |
| 13516 | 13533 | i64 nFkConstraint; /* Number of imm. FK constraints this VM */ |
| 13517 | 13534 | i64 nStmtDefCons; /* Number of def. constraints when stmt started */ |
| | @@ -19937,12 +19954,12 @@ |
| 19937 | 19954 | if( xtype==etEXP ){ |
| 19938 | 19955 | e2 = 0; |
| 19939 | 19956 | }else{ |
| 19940 | 19957 | e2 = exp; |
| 19941 | 19958 | } |
| 19942 | | - if( e2+precision+width > etBUFSIZE - 15 ){ |
| 19943 | | - bufpt = zExtra = sqlite3Malloc( e2+precision+width+15 ); |
| 19959 | + if( MAX(e2,0)+precision+width > etBUFSIZE - 15 ){ |
| 19960 | + bufpt = zExtra = sqlite3Malloc( MAX(e2,0)+precision+width+15 ); |
| 19944 | 19961 | if( bufpt==0 ){ |
| 19945 | 19962 | pAccum->mallocFailed = 1; |
| 19946 | 19963 | return; |
| 19947 | 19964 | } |
| 19948 | 19965 | } |
| | @@ -40058,10 +40075,11 @@ |
| 40058 | 40075 | assert( !MEMDB ); |
| 40059 | 40076 | pager_reset(pPager); |
| 40060 | 40077 | pPager->changeCountDone = pPager->tempFile; |
| 40061 | 40078 | pPager->eState = PAGER_OPEN; |
| 40062 | 40079 | pPager->errCode = SQLITE_OK; |
| 40080 | + if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0); |
| 40063 | 40081 | } |
| 40064 | 40082 | |
| 40065 | 40083 | pPager->journalOff = 0; |
| 40066 | 40084 | pPager->journalHdr = 0; |
| 40067 | 40085 | pPager->setMaster = 0; |
| | @@ -41624,14 +41642,14 @@ |
| 41624 | 41642 | ** Invoke SQLITE_FCNTL_MMAP_SIZE based on the current value of szMmap. |
| 41625 | 41643 | */ |
| 41626 | 41644 | static void pagerFixMaplimit(Pager *pPager){ |
| 41627 | 41645 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 41628 | 41646 | sqlite3_file *fd = pPager->fd; |
| 41629 | | - if( isOpen(fd) ){ |
| 41647 | + if( isOpen(fd) && fd->pMethods->iVersion>=3 ){ |
| 41630 | 41648 | sqlite3_int64 sz; |
| 41631 | | - pPager->bUseFetch = (fd->pMethods->iVersion>=3) && pPager->szMmap>0; |
| 41632 | 41649 | sz = pPager->szMmap; |
| 41650 | + pPager->bUseFetch = (sz>0); |
| 41633 | 41651 | sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz); |
| 41634 | 41652 | } |
| 41635 | 41653 | #endif |
| 41636 | 41654 | } |
| 41637 | 41655 | |
| | @@ -47879,11 +47897,11 @@ |
| 47879 | 47897 | ** the write is disallowed. |
| 47880 | 47898 | */ |
| 47881 | 47899 | if( memcmp(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr))!=0 ){ |
| 47882 | 47900 | walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); |
| 47883 | 47901 | pWal->writeLock = 0; |
| 47884 | | - rc = SQLITE_BUSY; |
| 47902 | + rc = SQLITE_BUSY_SNAPSHOT; |
| 47885 | 47903 | } |
| 47886 | 47904 | |
| 47887 | 47905 | return rc; |
| 47888 | 47906 | } |
| 47889 | 47907 | |
| | @@ -52739,16 +52757,17 @@ |
| 52739 | 52757 | ** This function is called from both BtreeCommitPhaseTwo() and BtreeRollback() |
| 52740 | 52758 | ** at the conclusion of a transaction. |
| 52741 | 52759 | */ |
| 52742 | 52760 | static void btreeEndTransaction(Btree *p){ |
| 52743 | 52761 | BtShared *pBt = p->pBt; |
| 52762 | + sqlite3 *db = p->db; |
| 52744 | 52763 | assert( sqlite3BtreeHoldsMutex(p) ); |
| 52745 | 52764 | |
| 52746 | 52765 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| 52747 | 52766 | pBt->bDoTruncate = 0; |
| 52748 | 52767 | #endif |
| 52749 | | - if( p->inTrans>TRANS_NONE && p->db->activeVdbeCnt>1 ){ |
| 52768 | + if( p->inTrans>TRANS_NONE && db->nVdbeRead>1 ){ |
| 52750 | 52769 | /* If there are other active statements that belong to this database |
| 52751 | 52770 | ** handle, downgrade to a read-only transaction. The other statements |
| 52752 | 52771 | ** may still be reading from the database. */ |
| 52753 | 52772 | downgradeAllSharedCacheTableLocks(p); |
| 52754 | 52773 | p->inTrans = TRANS_READ; |
| | @@ -60265,18 +60284,30 @@ |
| 60265 | 60284 | int i; |
| 60266 | 60285 | int nMaxArgs = *pMaxFuncArgs; |
| 60267 | 60286 | Op *pOp; |
| 60268 | 60287 | int *aLabel = p->aLabel; |
| 60269 | 60288 | p->readOnly = 1; |
| 60289 | + p->bIsReader = 0; |
| 60270 | 60290 | for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){ |
| 60271 | 60291 | u8 opcode = pOp->opcode; |
| 60272 | 60292 | |
| 60273 | 60293 | pOp->opflags = sqlite3OpcodeProperty[opcode]; |
| 60274 | 60294 | if( opcode==OP_Function || opcode==OP_AggStep ){ |
| 60275 | 60295 | if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5; |
| 60276 | | - }else if( (opcode==OP_Transaction && pOp->p2!=0) || opcode==OP_Vacuum ){ |
| 60296 | + }else if( opcode==OP_Transaction ){ |
| 60297 | + if( pOp->p2!=0 ) p->readOnly = 0; |
| 60298 | + p->bIsReader = 1; |
| 60299 | + }else if( opcode==OP_AutoCommit || opcode==OP_Savepoint ){ |
| 60300 | + p->bIsReader = 1; |
| 60301 | + }else if( opcode==OP_Vacuum |
| 60302 | + || opcode==OP_JournalMode |
| 60303 | +#ifndef SQLITE_OMIT_WAL |
| 60304 | + || opcode==OP_Checkpoint |
| 60305 | +#endif |
| 60306 | + ){ |
| 60277 | 60307 | p->readOnly = 0; |
| 60308 | + p->bIsReader = 1; |
| 60278 | 60309 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 60279 | 60310 | }else if( opcode==OP_VUpdate ){ |
| 60280 | 60311 | if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; |
| 60281 | 60312 | }else if( opcode==OP_VFilter ){ |
| 60282 | 60313 | int n; |
| | @@ -60298,12 +60329,12 @@ |
| 60298 | 60329 | pOp->p2 = aLabel[-1-pOp->p2]; |
| 60299 | 60330 | } |
| 60300 | 60331 | } |
| 60301 | 60332 | sqlite3DbFree(p->db, p->aLabel); |
| 60302 | 60333 | p->aLabel = 0; |
| 60303 | | - |
| 60304 | 60334 | *pMaxFuncArgs = nMaxArgs; |
| 60335 | + assert( p->bIsReader!=0 || p->btreeMask==0 ); |
| 60305 | 60336 | } |
| 60306 | 60337 | |
| 60307 | 60338 | /* |
| 60308 | 60339 | ** Return the address of the next instruction to be inserted. |
| 60309 | 60340 | */ |
| | @@ -61825,11 +61856,11 @@ |
| 61825 | 61856 | |
| 61826 | 61857 | return rc; |
| 61827 | 61858 | } |
| 61828 | 61859 | |
| 61829 | 61860 | /* |
| 61830 | | -** This routine checks that the sqlite3.activeVdbeCnt count variable |
| 61861 | +** This routine checks that the sqlite3.nVdbeActive count variable |
| 61831 | 61862 | ** matches the number of vdbe's in the list sqlite3.pVdbe that are |
| 61832 | 61863 | ** currently active. An assertion fails if the two counts do not match. |
| 61833 | 61864 | ** This is an internal self-check only - it is not an essential processing |
| 61834 | 61865 | ** step. |
| 61835 | 61866 | ** |
| | @@ -61838,20 +61869,23 @@ |
| 61838 | 61869 | #ifndef NDEBUG |
| 61839 | 61870 | static void checkActiveVdbeCnt(sqlite3 *db){ |
| 61840 | 61871 | Vdbe *p; |
| 61841 | 61872 | int cnt = 0; |
| 61842 | 61873 | int nWrite = 0; |
| 61874 | + int nRead = 0; |
| 61843 | 61875 | p = db->pVdbe; |
| 61844 | 61876 | while( p ){ |
| 61845 | 61877 | if( p->magic==VDBE_MAGIC_RUN && p->pc>=0 ){ |
| 61846 | 61878 | cnt++; |
| 61847 | 61879 | if( p->readOnly==0 ) nWrite++; |
| 61880 | + if( p->bIsReader ) nRead++; |
| 61848 | 61881 | } |
| 61849 | 61882 | p = p->pNext; |
| 61850 | 61883 | } |
| 61851 | | - assert( cnt==db->activeVdbeCnt ); |
| 61852 | | - assert( nWrite==db->writeVdbeCnt ); |
| 61884 | + assert( cnt==db->nVdbeActive ); |
| 61885 | + assert( nWrite==db->nVdbeWrite ); |
| 61886 | + assert( nRead==db->nVdbeRead ); |
| 61853 | 61887 | } |
| 61854 | 61888 | #else |
| 61855 | 61889 | #define checkActiveVdbeCnt(x) |
| 61856 | 61890 | #endif |
| 61857 | 61891 | |
| | @@ -61983,12 +62017,13 @@ |
| 61983 | 62017 | if( p->magic!=VDBE_MAGIC_RUN ){ |
| 61984 | 62018 | return SQLITE_OK; |
| 61985 | 62019 | } |
| 61986 | 62020 | checkActiveVdbeCnt(db); |
| 61987 | 62021 | |
| 61988 | | - /* No commit or rollback needed if the program never started */ |
| 61989 | | - if( p->pc>=0 ){ |
| 62022 | + /* No commit or rollback needed if the program never started or if the |
| 62023 | + ** SQL statement does not read or write a database file. */ |
| 62024 | + if( p->pc>=0 && p->bIsReader ){ |
| 61990 | 62025 | int mrc; /* Primary error code from p->rc */ |
| 61991 | 62026 | int eStatementOp = 0; |
| 61992 | 62027 | int isSpecialError; /* Set to true if a 'special' error */ |
| 61993 | 62028 | |
| 61994 | 62029 | /* Lock all btrees used by the statement */ |
| | @@ -62037,11 +62072,11 @@ |
| 62037 | 62072 | ** Note: This block also runs if one of the special errors handled |
| 62038 | 62073 | ** above has occurred. |
| 62039 | 62074 | */ |
| 62040 | 62075 | if( !sqlite3VtabInSync(db) |
| 62041 | 62076 | && db->autoCommit |
| 62042 | | - && db->writeVdbeCnt==(p->readOnly==0) |
| 62077 | + && db->nVdbeWrite==(p->readOnly==0) |
| 62043 | 62078 | ){ |
| 62044 | 62079 | if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){ |
| 62045 | 62080 | rc = sqlite3VdbeCheckFk(p, 1); |
| 62046 | 62081 | if( rc!=SQLITE_OK ){ |
| 62047 | 62082 | if( NEVER(p->readOnly) ){ |
| | @@ -62118,15 +62153,16 @@ |
| 62118 | 62153 | sqlite3VdbeLeave(p); |
| 62119 | 62154 | } |
| 62120 | 62155 | |
| 62121 | 62156 | /* We have successfully halted and closed the VM. Record this fact. */ |
| 62122 | 62157 | if( p->pc>=0 ){ |
| 62123 | | - db->activeVdbeCnt--; |
| 62124 | | - if( !p->readOnly ){ |
| 62125 | | - db->writeVdbeCnt--; |
| 62126 | | - } |
| 62127 | | - assert( db->activeVdbeCnt>=db->writeVdbeCnt ); |
| 62158 | + db->nVdbeActive--; |
| 62159 | + if( !p->readOnly ) db->nVdbeWrite--; |
| 62160 | + if( p->bIsReader ) db->nVdbeRead--; |
| 62161 | + assert( db->nVdbeActive>=db->nVdbeRead ); |
| 62162 | + assert( db->nVdbeRead>=db->nVdbeWrite ); |
| 62163 | + assert( db->nVdbeWrite>=0 ); |
| 62128 | 62164 | } |
| 62129 | 62165 | p->magic = VDBE_MAGIC_HALT; |
| 62130 | 62166 | checkActiveVdbeCnt(db); |
| 62131 | 62167 | if( p->db->mallocFailed ){ |
| 62132 | 62168 | p->rc = SQLITE_NOMEM; |
| | @@ -62138,11 +62174,11 @@ |
| 62138 | 62174 | */ |
| 62139 | 62175 | if( db->autoCommit ){ |
| 62140 | 62176 | sqlite3ConnectionUnlocked(db); |
| 62141 | 62177 | } |
| 62142 | 62178 | |
| 62143 | | - assert( db->activeVdbeCnt>0 || db->autoCommit==0 || db->nStatement==0 ); |
| 62179 | + assert( db->nVdbeActive>0 || db->autoCommit==0 || db->nStatement==0 ); |
| 62144 | 62180 | return (p->rc==SQLITE_BUSY ? SQLITE_BUSY : SQLITE_OK); |
| 62145 | 62181 | } |
| 62146 | 62182 | |
| 62147 | 62183 | |
| 62148 | 62184 | /* |
| | @@ -63496,35 +63532,36 @@ |
| 63496 | 63532 | if( p->pc<0 ){ |
| 63497 | 63533 | /* If there are no other statements currently running, then |
| 63498 | 63534 | ** reset the interrupt flag. This prevents a call to sqlite3_interrupt |
| 63499 | 63535 | ** from interrupting a statement that has not yet started. |
| 63500 | 63536 | */ |
| 63501 | | - if( db->activeVdbeCnt==0 ){ |
| 63537 | + if( db->nVdbeActive==0 ){ |
| 63502 | 63538 | db->u1.isInterrupted = 0; |
| 63503 | 63539 | } |
| 63504 | 63540 | |
| 63505 | | - assert( db->writeVdbeCnt>0 || db->autoCommit==0 || db->nDeferredCons==0 ); |
| 63541 | + assert( db->nVdbeWrite>0 || db->autoCommit==0 || db->nDeferredCons==0 ); |
| 63506 | 63542 | |
| 63507 | 63543 | #ifndef SQLITE_OMIT_TRACE |
| 63508 | 63544 | if( db->xProfile && !db->init.busy ){ |
| 63509 | 63545 | sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime); |
| 63510 | 63546 | } |
| 63511 | 63547 | #endif |
| 63512 | 63548 | |
| 63513 | | - db->activeVdbeCnt++; |
| 63514 | | - if( p->readOnly==0 ) db->writeVdbeCnt++; |
| 63549 | + db->nVdbeActive++; |
| 63550 | + if( p->readOnly==0 ) db->nVdbeWrite++; |
| 63551 | + if( p->bIsReader ) db->nVdbeRead++; |
| 63515 | 63552 | p->pc = 0; |
| 63516 | 63553 | } |
| 63517 | 63554 | #ifndef SQLITE_OMIT_EXPLAIN |
| 63518 | 63555 | if( p->explain ){ |
| 63519 | 63556 | rc = sqlite3VdbeList(p); |
| 63520 | 63557 | }else |
| 63521 | 63558 | #endif /* SQLITE_OMIT_EXPLAIN */ |
| 63522 | 63559 | { |
| 63523 | | - db->vdbeExecCnt++; |
| 63560 | + db->nVdbeExec++; |
| 63524 | 63561 | rc = sqlite3VdbeExec(p); |
| 63525 | | - db->vdbeExecCnt--; |
| 63562 | + db->nVdbeExec--; |
| 63526 | 63563 | } |
| 63527 | 63564 | |
| 63528 | 63565 | #ifndef SQLITE_OMIT_TRACE |
| 63529 | 63566 | /* Invoke the profile callback if there is one |
| 63530 | 63567 | */ |
| | @@ -64457,13 +64494,13 @@ |
| 64457 | 64494 | return nTotal; |
| 64458 | 64495 | } |
| 64459 | 64496 | |
| 64460 | 64497 | /* |
| 64461 | 64498 | ** This function returns a pointer to a nul-terminated string in memory |
| 64462 | | -** obtained from sqlite3DbMalloc(). If sqlite3.vdbeExecCnt is 1, then the |
| 64499 | +** obtained from sqlite3DbMalloc(). If sqlite3.nVdbeExec is 1, then the |
| 64463 | 64500 | ** string contains a copy of zRawSql but with host parameters expanded to |
| 64464 | | -** their current bindings. Or, if sqlite3.vdbeExecCnt is greater than 1, |
| 64501 | +** their current bindings. Or, if sqlite3.nVdbeExec is greater than 1, |
| 64465 | 64502 | ** then the returned string holds a copy of zRawSql with "-- " prepended |
| 64466 | 64503 | ** to each line of text. |
| 64467 | 64504 | ** |
| 64468 | 64505 | ** If the SQLITE_TRACE_SIZE_LIMIT macro is defined to an integer, then |
| 64469 | 64506 | ** then long strings and blobs are truncated to that many bytes. This |
| | @@ -64497,11 +64534,11 @@ |
| 64497 | 64534 | |
| 64498 | 64535 | db = p->db; |
| 64499 | 64536 | sqlite3StrAccumInit(&out, zBase, sizeof(zBase), |
| 64500 | 64537 | db->aLimit[SQLITE_LIMIT_LENGTH]); |
| 64501 | 64538 | out.db = db; |
| 64502 | | - if( db->vdbeExecCnt>1 ){ |
| 64539 | + if( db->nVdbeExec>1 ){ |
| 64503 | 64540 | while( *zRawSql ){ |
| 64504 | 64541 | const char *zStart = zRawSql; |
| 64505 | 64542 | while( *(zRawSql++)!='\n' && *zRawSql ); |
| 64506 | 64543 | sqlite3StrAccumAppend(&out, "-- ", 3); |
| 64507 | 64544 | sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart)); |
| | @@ -65351,16 +65388,17 @@ |
| 65351 | 65388 | u8 encoding = ENC(db); /* The database encoding */ |
| 65352 | 65389 | #ifndef SQLITE_OMIT_PROGRESS_CALLBACK |
| 65353 | 65390 | int checkProgress; /* True if progress callbacks are enabled */ |
| 65354 | 65391 | int nProgressOps = 0; /* Opcodes executed since progress callback. */ |
| 65355 | 65392 | #endif |
| 65393 | + int iCompare = 0; /* Result of last OP_Compare operation */ |
| 65394 | + unsigned nVmStep = 0; /* Number of virtual machine steps */ |
| 65356 | 65395 | Mem *aMem = p->aMem; /* Copy of p->aMem */ |
| 65357 | 65396 | Mem *pIn1 = 0; /* 1st input operand */ |
| 65358 | 65397 | Mem *pIn2 = 0; /* 2nd input operand */ |
| 65359 | 65398 | Mem *pIn3 = 0; /* 3rd input operand */ |
| 65360 | 65399 | Mem *pOut = 0; /* Output operand */ |
| 65361 | | - int iCompare = 0; /* Result of last OP_Compare operation */ |
| 65362 | 65400 | int *aPermute = 0; /* Permutation of columns for OP_Compare */ |
| 65363 | 65401 | i64 lastRowid = db->lastRowid; /* Saved value of the last insert ROWID */ |
| 65364 | 65402 | #ifdef VDBE_PROFILE |
| 65365 | 65403 | u64 start; /* CPU clock count at start of opcode */ |
| 65366 | 65404 | int origPc; /* Program counter at start of opcode */ |
| | @@ -65802,10 +65840,11 @@ |
| 65802 | 65840 | /* This happens if a malloc() inside a call to sqlite3_column_text() or |
| 65803 | 65841 | ** sqlite3_column_text16() failed. */ |
| 65804 | 65842 | goto no_mem; |
| 65805 | 65843 | } |
| 65806 | 65844 | assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY ); |
| 65845 | + assert( p->bIsReader || p->readOnly!=0 ); |
| 65807 | 65846 | p->rc = SQLITE_OK; |
| 65808 | 65847 | assert( p->explain==0 ); |
| 65809 | 65848 | p->pResultSet = 0; |
| 65810 | 65849 | db->busyHandler.nBusy = 0; |
| 65811 | 65850 | CHECK_FOR_INTERRUPT; |
| | @@ -65830,10 +65869,11 @@ |
| 65830 | 65869 | if( db->mallocFailed ) goto no_mem; |
| 65831 | 65870 | #ifdef VDBE_PROFILE |
| 65832 | 65871 | origPc = pc; |
| 65833 | 65872 | start = sqlite3Hwtime(); |
| 65834 | 65873 | #endif |
| 65874 | + nVmStep++; |
| 65835 | 65875 | pOp = &aOp[pc]; |
| 65836 | 65876 | |
| 65837 | 65877 | /* Only allow tracing if SQLITE_DEBUG is defined. |
| 65838 | 65878 | */ |
| 65839 | 65879 | #ifdef SQLITE_DEBUG |
| | @@ -67945,13 +67985,14 @@ |
| 67945 | 67985 | */ |
| 67946 | 67986 | assert( db->pSavepoint==0 || db->autoCommit==0 ); |
| 67947 | 67987 | assert( u.as.p1==SAVEPOINT_BEGIN||u.as.p1==SAVEPOINT_RELEASE||u.as.p1==SAVEPOINT_ROLLBACK ); |
| 67948 | 67988 | assert( db->pSavepoint || db->isTransactionSavepoint==0 ); |
| 67949 | 67989 | assert( checkSavepointCount(db) ); |
| 67990 | + assert( p->bIsReader ); |
| 67950 | 67991 | |
| 67951 | 67992 | if( u.as.p1==SAVEPOINT_BEGIN ){ |
| 67952 | | - if( db->writeVdbeCnt>0 ){ |
| 67993 | + if( db->nVdbeWrite>0 ){ |
| 67953 | 67994 | /* A new savepoint cannot be created if there are active write |
| 67954 | 67995 | ** statements (i.e. open read/write incremental blob handles). |
| 67955 | 67996 | */ |
| 67956 | 67997 | sqlite3SetString(&p->zErrMsg, db, "cannot open savepoint - " |
| 67957 | 67998 | "SQL statements in progress"); |
| | @@ -68004,11 +68045,11 @@ |
| 68004 | 68045 | u.as.iSavepoint++; |
| 68005 | 68046 | } |
| 68006 | 68047 | if( !u.as.pSavepoint ){ |
| 68007 | 68048 | sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", u.as.zName); |
| 68008 | 68049 | rc = SQLITE_ERROR; |
| 68009 | | - }else if( db->writeVdbeCnt>0 && u.as.p1==SAVEPOINT_RELEASE ){ |
| 68050 | + }else if( db->nVdbeWrite>0 && u.as.p1==SAVEPOINT_RELEASE ){ |
| 68010 | 68051 | /* It is not possible to release (commit) a savepoint if there are |
| 68011 | 68052 | ** active write statements. |
| 68012 | 68053 | */ |
| 68013 | 68054 | sqlite3SetString(&p->zErrMsg, db, |
| 68014 | 68055 | "cannot release savepoint - SQL statements in progress" |
| | @@ -68107,24 +68148,25 @@ |
| 68107 | 68148 | u.at.desiredAutoCommit = pOp->p1; |
| 68108 | 68149 | u.at.iRollback = pOp->p2; |
| 68109 | 68150 | u.at.turnOnAC = u.at.desiredAutoCommit && !db->autoCommit; |
| 68110 | 68151 | assert( u.at.desiredAutoCommit==1 || u.at.desiredAutoCommit==0 ); |
| 68111 | 68152 | assert( u.at.desiredAutoCommit==1 || u.at.iRollback==0 ); |
| 68112 | | - assert( db->activeVdbeCnt>0 ); /* At least this one VM is active */ |
| 68153 | + assert( db->nVdbeActive>0 ); /* At least this one VM is active */ |
| 68154 | + assert( p->bIsReader ); |
| 68113 | 68155 | |
| 68114 | 68156 | #if 0 |
| 68115 | | - if( u.at.turnOnAC && u.at.iRollback && db->activeVdbeCnt>1 ){ |
| 68157 | + if( u.at.turnOnAC && u.at.iRollback && db->nVdbeActive>1 ){ |
| 68116 | 68158 | /* If this instruction implements a ROLLBACK and other VMs are |
| 68117 | 68159 | ** still running, and a transaction is active, return an error indicating |
| 68118 | 68160 | ** that the other VMs must complete first. |
| 68119 | 68161 | */ |
| 68120 | 68162 | sqlite3SetString(&p->zErrMsg, db, "cannot rollback transaction - " |
| 68121 | 68163 | "SQL statements in progress"); |
| 68122 | 68164 | rc = SQLITE_BUSY; |
| 68123 | 68165 | }else |
| 68124 | 68166 | #endif |
| 68125 | | - if( u.at.turnOnAC && !u.at.iRollback && db->writeVdbeCnt>0 ){ |
| 68167 | + if( u.at.turnOnAC && !u.at.iRollback && db->nVdbeWrite>0 ){ |
| 68126 | 68168 | /* If this instruction implements a COMMIT and other VMs are writing |
| 68127 | 68169 | ** return an error indicating that the other VMs must complete first. |
| 68128 | 68170 | */ |
| 68129 | 68171 | sqlite3SetString(&p->zErrMsg, db, "cannot commit transaction - " |
| 68130 | 68172 | "SQL statements in progress"); |
| | @@ -68198,10 +68240,12 @@ |
| 68198 | 68240 | case OP_Transaction: { |
| 68199 | 68241 | #if 0 /* local variables moved into u.au */ |
| 68200 | 68242 | Btree *pBt; |
| 68201 | 68243 | #endif /* local variables moved into u.au */ |
| 68202 | 68244 | |
| 68245 | + assert( p->bIsReader ); |
| 68246 | + assert( p->readOnly==0 || pOp->p2==0 ); |
| 68203 | 68247 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 68204 | 68248 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 68205 | 68249 | u.au.pBt = db->aDb[pOp->p1].pBt; |
| 68206 | 68250 | |
| 68207 | 68251 | if( u.au.pBt ){ |
| | @@ -68214,11 +68258,11 @@ |
| 68214 | 68258 | if( rc!=SQLITE_OK ){ |
| 68215 | 68259 | goto abort_due_to_error; |
| 68216 | 68260 | } |
| 68217 | 68261 | |
| 68218 | 68262 | if( pOp->p2 && p->usesStmtJournal |
| 68219 | | - && (db->autoCommit==0 || db->activeVdbeCnt>1) |
| 68263 | + && (db->autoCommit==0 || db->nVdbeRead>1) |
| 68220 | 68264 | ){ |
| 68221 | 68265 | assert( sqlite3BtreeIsInTrans(u.au.pBt) ); |
| 68222 | 68266 | if( p->iStatement==0 ){ |
| 68223 | 68267 | assert( db->nStatement>=0 && db->nSavepoint>=0 ); |
| 68224 | 68268 | db->nStatement++; |
| | @@ -68256,10 +68300,11 @@ |
| 68256 | 68300 | int iMeta; |
| 68257 | 68301 | int iDb; |
| 68258 | 68302 | int iCookie; |
| 68259 | 68303 | #endif /* local variables moved into u.av */ |
| 68260 | 68304 | |
| 68305 | + assert( p->bIsReader ); |
| 68261 | 68306 | u.av.iDb = pOp->p1; |
| 68262 | 68307 | u.av.iCookie = pOp->p3; |
| 68263 | 68308 | assert( pOp->p3<SQLITE_N_BTREE_META ); |
| 68264 | 68309 | assert( u.av.iDb>=0 && u.av.iDb<db->nDb ); |
| 68265 | 68310 | assert( db->aDb[u.av.iDb].pBt!=0 ); |
| | @@ -68285,10 +68330,11 @@ |
| 68285 | 68330 | Db *pDb; |
| 68286 | 68331 | #endif /* local variables moved into u.aw */ |
| 68287 | 68332 | assert( pOp->p2<SQLITE_N_BTREE_META ); |
| 68288 | 68333 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 68289 | 68334 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 68335 | + assert( p->readOnly==0 ); |
| 68290 | 68336 | u.aw.pDb = &db->aDb[pOp->p1]; |
| 68291 | 68337 | assert( u.aw.pDb->pBt!=0 ); |
| 68292 | 68338 | assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); |
| 68293 | 68339 | pIn3 = &aMem[pOp->p3]; |
| 68294 | 68340 | sqlite3VdbeMemIntegerify(pIn3); |
| | @@ -68337,10 +68383,11 @@ |
| 68337 | 68383 | #endif /* local variables moved into u.ax */ |
| 68338 | 68384 | |
| 68339 | 68385 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 68340 | 68386 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 68341 | 68387 | assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); |
| 68388 | + assert( p->bIsReader ); |
| 68342 | 68389 | u.ax.pBt = db->aDb[pOp->p1].pBt; |
| 68343 | 68390 | if( u.ax.pBt ){ |
| 68344 | 68391 | sqlite3BtreeGetMeta(u.ax.pBt, BTREE_SCHEMA_VERSION, (u32 *)&u.ax.iMeta); |
| 68345 | 68392 | u.ax.iGen = db->aDb[pOp->p1].pSchema->iGeneration; |
| 68346 | 68393 | }else{ |
| | @@ -68434,10 +68481,12 @@ |
| 68434 | 68481 | Db *pDb; |
| 68435 | 68482 | #endif /* local variables moved into u.ay */ |
| 68436 | 68483 | |
| 68437 | 68484 | assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 ); |
| 68438 | 68485 | assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 ); |
| 68486 | + assert( p->bIsReader ); |
| 68487 | + assert( pOp->opcode==OP_OpenRead || p->readOnly==0 ); |
| 68439 | 68488 | |
| 68440 | 68489 | if( p->expired ){ |
| 68441 | 68490 | rc = SQLITE_ABORT; |
| 68442 | 68491 | break; |
| 68443 | 68492 | } |
| | @@ -70052,19 +70101,22 @@ |
| 70052 | 70101 | int iCnt; |
| 70053 | 70102 | Vdbe *pVdbe; |
| 70054 | 70103 | int iDb; |
| 70055 | 70104 | #endif /* local variables moved into u.bw */ |
| 70056 | 70105 | |
| 70106 | + assert( p->readOnly==0 ); |
| 70057 | 70107 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 70058 | 70108 | u.bw.iCnt = 0; |
| 70059 | 70109 | for(u.bw.pVdbe=db->pVdbe; u.bw.pVdbe; u.bw.pVdbe = u.bw.pVdbe->pNext){ |
| 70060 | | - if( u.bw.pVdbe->magic==VDBE_MAGIC_RUN && u.bw.pVdbe->inVtabMethod<2 && u.bw.pVdbe->pc>=0 ){ |
| 70110 | + if( u.bw.pVdbe->magic==VDBE_MAGIC_RUN && u.bw.pVdbe->bIsReader |
| 70111 | + && u.bw.pVdbe->inVtabMethod<2 && u.bw.pVdbe->pc>=0 |
| 70112 | + ){ |
| 70061 | 70113 | u.bw.iCnt++; |
| 70062 | 70114 | } |
| 70063 | 70115 | } |
| 70064 | 70116 | #else |
| 70065 | | - u.bw.iCnt = db->activeVdbeCnt; |
| 70117 | + u.bw.iCnt = db->nVdbeRead; |
| 70066 | 70118 | #endif |
| 70067 | 70119 | pOut->flags = MEM_Null; |
| 70068 | 70120 | if( u.bw.iCnt>1 ){ |
| 70069 | 70121 | rc = SQLITE_LOCKED; |
| 70070 | 70122 | p->errorAction = OE_Abort; |
| | @@ -70109,10 +70161,11 @@ |
| 70109 | 70161 | #if 0 /* local variables moved into u.bx */ |
| 70110 | 70162 | int nChange; |
| 70111 | 70163 | #endif /* local variables moved into u.bx */ |
| 70112 | 70164 | |
| 70113 | 70165 | u.bx.nChange = 0; |
| 70166 | + assert( p->readOnly==0 ); |
| 70114 | 70167 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 ); |
| 70115 | 70168 | rc = sqlite3BtreeClearTable( |
| 70116 | 70169 | db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bx.nChange : 0) |
| 70117 | 70170 | ); |
| 70118 | 70171 | if( pOp->p3 ){ |
| | @@ -70157,10 +70210,11 @@ |
| 70157 | 70210 | #endif /* local variables moved into u.by */ |
| 70158 | 70211 | |
| 70159 | 70212 | u.by.pgno = 0; |
| 70160 | 70213 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 70161 | 70214 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 70215 | + assert( p->readOnly==0 ); |
| 70162 | 70216 | u.by.pDb = &db->aDb[pOp->p1]; |
| 70163 | 70217 | assert( u.by.pDb->pBt!=0 ); |
| 70164 | 70218 | if( pOp->opcode==OP_CreateTable ){ |
| 70165 | 70219 | /* u.by.flags = BTREE_INTKEY; */ |
| 70166 | 70220 | u.by.flags = BTREE_INTKEY; |
| | @@ -70309,10 +70363,11 @@ |
| 70309 | 70363 | int nErr; /* Number of errors reported */ |
| 70310 | 70364 | char *z; /* Text of the error report */ |
| 70311 | 70365 | Mem *pnErr; /* Register keeping track of errors remaining */ |
| 70312 | 70366 | #endif /* local variables moved into u.ca */ |
| 70313 | 70367 | |
| 70368 | + assert( p->bIsReader ); |
| 70314 | 70369 | u.ca.nRoot = pOp->p2; |
| 70315 | 70370 | assert( u.ca.nRoot>0 ); |
| 70316 | 70371 | u.ca.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.ca.nRoot+1) ); |
| 70317 | 70372 | if( u.ca.aRoot==0 ) goto no_mem; |
| 70318 | 70373 | assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| | @@ -70830,10 +70885,11 @@ |
| 70830 | 70885 | int i; /* Loop counter */ |
| 70831 | 70886 | int aRes[3]; /* Results */ |
| 70832 | 70887 | Mem *pMem; /* Write results here */ |
| 70833 | 70888 | #endif /* local variables moved into u.ci */ |
| 70834 | 70889 | |
| 70890 | + assert( p->readOnly==0 ); |
| 70835 | 70891 | u.ci.aRes[0] = 0; |
| 70836 | 70892 | u.ci.aRes[1] = u.ci.aRes[2] = -1; |
| 70837 | 70893 | assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE |
| 70838 | 70894 | || pOp->p2==SQLITE_CHECKPOINT_FULL |
| 70839 | 70895 | || pOp->p2==SQLITE_CHECKPOINT_RESTART |
| | @@ -70881,10 +70937,11 @@ |
| 70881 | 70937 | || u.cj.eNew==PAGER_JOURNALMODE_MEMORY |
| 70882 | 70938 | || u.cj.eNew==PAGER_JOURNALMODE_WAL |
| 70883 | 70939 | || u.cj.eNew==PAGER_JOURNALMODE_QUERY |
| 70884 | 70940 | ); |
| 70885 | 70941 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 70942 | + assert( p->readOnly==0 ); |
| 70886 | 70943 | |
| 70887 | 70944 | u.cj.pBt = db->aDb[pOp->p1].pBt; |
| 70888 | 70945 | u.cj.pPager = sqlite3BtreePager(u.cj.pBt); |
| 70889 | 70946 | u.cj.eOld = sqlite3PagerGetJournalMode(u.cj.pPager); |
| 70890 | 70947 | if( u.cj.eNew==PAGER_JOURNALMODE_QUERY ) u.cj.eNew = u.cj.eOld; |
| | @@ -70904,11 +70961,11 @@ |
| 70904 | 70961 | } |
| 70905 | 70962 | |
| 70906 | 70963 | if( (u.cj.eNew!=u.cj.eOld) |
| 70907 | 70964 | && (u.cj.eOld==PAGER_JOURNALMODE_WAL || u.cj.eNew==PAGER_JOURNALMODE_WAL) |
| 70908 | 70965 | ){ |
| 70909 | | - if( !db->autoCommit || db->activeVdbeCnt>1 ){ |
| 70966 | + if( !db->autoCommit || db->nVdbeRead>1 ){ |
| 70910 | 70967 | rc = SQLITE_ERROR; |
| 70911 | 70968 | sqlite3SetString(&p->zErrMsg, db, |
| 70912 | 70969 | "cannot change %s wal mode from within a transaction", |
| 70913 | 70970 | (u.cj.eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of") |
| 70914 | 70971 | ); |
| | @@ -70963,10 +71020,11 @@ |
| 70963 | 71020 | ** Vacuum the entire database. This opcode will cause other virtual |
| 70964 | 71021 | ** machines to be created and run. It may not be called from within |
| 70965 | 71022 | ** a transaction. |
| 70966 | 71023 | */ |
| 70967 | 71024 | case OP_Vacuum: { |
| 71025 | + assert( p->readOnly==0 ); |
| 70968 | 71026 | rc = sqlite3RunVacuum(&p->zErrMsg, db); |
| 70969 | 71027 | break; |
| 70970 | 71028 | } |
| 70971 | 71029 | #endif |
| 70972 | 71030 | |
| | @@ -70982,10 +71040,11 @@ |
| 70982 | 71040 | Btree *pBt; |
| 70983 | 71041 | #endif /* local variables moved into u.ck */ |
| 70984 | 71042 | |
| 70985 | 71043 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 70986 | 71044 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 71045 | + assert( p->readOnly==0 ); |
| 70987 | 71046 | u.ck.pBt = db->aDb[pOp->p1].pBt; |
| 70988 | 71047 | rc = sqlite3BtreeIncrVacuum(u.ck.pBt); |
| 70989 | 71048 | if( rc==SQLITE_DONE ){ |
| 70990 | 71049 | pc = pOp->p2 - 1; |
| 70991 | 71050 | rc = SQLITE_OK; |
| | @@ -71104,10 +71163,11 @@ |
| 71104 | 71163 | sqlite3_vtab_cursor *pVtabCursor; |
| 71105 | 71164 | sqlite3_vtab *pVtab; |
| 71106 | 71165 | sqlite3_module *pModule; |
| 71107 | 71166 | #endif /* local variables moved into u.cm */ |
| 71108 | 71167 | |
| 71168 | + assert( p->bIsReader ); |
| 71109 | 71169 | u.cm.pCur = 0; |
| 71110 | 71170 | u.cm.pVtabCursor = 0; |
| 71111 | 71171 | u.cm.pVtab = pOp->p4.pVtab->pVtab; |
| 71112 | 71172 | u.cm.pModule = (sqlite3_module *)u.cm.pVtab->pModule; |
| 71113 | 71173 | assert(u.cm.pVtab && u.cm.pModule); |
| | @@ -71328,10 +71388,11 @@ |
| 71328 | 71388 | |
| 71329 | 71389 | u.cq.pVtab = pOp->p4.pVtab->pVtab; |
| 71330 | 71390 | u.cq.pName = &aMem[pOp->p1]; |
| 71331 | 71391 | assert( u.cq.pVtab->pModule->xRename ); |
| 71332 | 71392 | assert( memIsValid(u.cq.pName) ); |
| 71393 | + assert( p->readOnly==0 ); |
| 71333 | 71394 | REGISTER_TRACE(pOp->p1, u.cq.pName); |
| 71334 | 71395 | assert( u.cq.pName->flags & MEM_Str ); |
| 71335 | 71396 | testcase( u.cq.pName->enc==SQLITE_UTF8 ); |
| 71336 | 71397 | testcase( u.cq.pName->enc==SQLITE_UTF16BE ); |
| 71337 | 71398 | testcase( u.cq.pName->enc==SQLITE_UTF16LE ); |
| | @@ -71381,10 +71442,11 @@ |
| 71381 | 71442 | #endif /* local variables moved into u.cr */ |
| 71382 | 71443 | |
| 71383 | 71444 | assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback |
| 71384 | 71445 | || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace |
| 71385 | 71446 | ); |
| 71447 | + assert( p->readOnly==0 ); |
| 71386 | 71448 | u.cr.pVtab = pOp->p4.pVtab->pVtab; |
| 71387 | 71449 | u.cr.pModule = (sqlite3_module *)u.cr.pVtab->pModule; |
| 71388 | 71450 | u.cr.nArg = pOp->p2; |
| 71389 | 71451 | assert( pOp->p4type==P4_VTAB ); |
| 71390 | 71452 | if( ALWAYS(u.cr.pModule->xUpdate) ){ |
| | @@ -71566,10 +71628,11 @@ |
| 71566 | 71628 | /* This is the only way out of this procedure. We have to |
| 71567 | 71629 | ** release the mutexes on btrees that were acquired at the |
| 71568 | 71630 | ** top. */ |
| 71569 | 71631 | vdbe_return: |
| 71570 | 71632 | db->lastRowid = lastRowid; |
| 71633 | + p->aCounter[SQLITE_STMTSTATUS_VM_STEP-1] += (int)nVmStep; |
| 71571 | 71634 | sqlite3VdbeLeave(p); |
| 71572 | 71635 | return rc; |
| 71573 | 71636 | |
| 71574 | 71637 | /* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH |
| 71575 | 71638 | ** is encountered. |
| | @@ -76044,10 +76107,11 @@ |
| 76044 | 76107 | pItem->pExpr = sqlite3ExprDup(db, pOldExpr, flags); |
| 76045 | 76108 | pItem->zName = sqlite3DbStrDup(db, pOldItem->zName); |
| 76046 | 76109 | pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan); |
| 76047 | 76110 | pItem->sortOrder = pOldItem->sortOrder; |
| 76048 | 76111 | pItem->done = 0; |
| 76112 | + pItem->bSpanIsTab = pOldItem->bSpanIsTab; |
| 76049 | 76113 | pItem->iOrderByCol = pOldItem->iOrderByCol; |
| 76050 | 76114 | pItem->iAlias = pOldItem->iAlias; |
| 76051 | 76115 | } |
| 76052 | 76116 | return pNew; |
| 76053 | 76117 | } |
| | @@ -100236,19 +100300,20 @@ |
| 100236 | 100300 | sDistinct.eTnctType = WHERE_DISTINCT_NOOP; |
| 100237 | 100301 | } |
| 100238 | 100302 | |
| 100239 | 100303 | if( !isAgg && pGroupBy==0 ){ |
| 100240 | 100304 | /* No aggregate functions and no GROUP BY clause */ |
| 100241 | | - ExprList *pDist = (sDistinct.isTnct ? p->pEList : 0); |
| 100305 | + u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0); |
| 100242 | 100306 | |
| 100243 | 100307 | /* Begin the database scan. */ |
| 100244 | | - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pOrderBy, pDist, 0,0); |
| 100308 | + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pOrderBy, p->pEList, |
| 100309 | + wctrlFlags, 0); |
| 100245 | 100310 | if( pWInfo==0 ) goto select_end; |
| 100246 | 100311 | if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){ |
| 100247 | 100312 | p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo); |
| 100248 | 100313 | } |
| 100249 | | - if( sqlite3WhereIsDistinct(pWInfo) ){ |
| 100314 | + if( sDistinct.isTnct && sqlite3WhereIsDistinct(pWInfo) ){ |
| 100250 | 100315 | sDistinct.eTnctType = sqlite3WhereIsDistinct(pWInfo); |
| 100251 | 100316 | } |
| 100252 | 100317 | if( pOrderBy && sqlite3WhereIsOrdered(pWInfo) ) pOrderBy = 0; |
| 100253 | 100318 | |
| 100254 | 100319 | /* If sorting index that was created by a prior OP_OpenEphemeral |
| | @@ -102940,11 +103005,11 @@ |
| 102940 | 103005 | |
| 102941 | 103006 | if( !db->autoCommit ){ |
| 102942 | 103007 | sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction"); |
| 102943 | 103008 | return SQLITE_ERROR; |
| 102944 | 103009 | } |
| 102945 | | - if( db->activeVdbeCnt>1 ){ |
| 103010 | + if( db->nVdbeActive>1 ){ |
| 102946 | 103011 | sqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress"); |
| 102947 | 103012 | return SQLITE_ERROR; |
| 102948 | 103013 | } |
| 102949 | 103014 | |
| 102950 | 103015 | /* Save the current value of the database flags so that it can be |
| | @@ -104440,11 +104505,11 @@ |
| 104440 | 104505 | |
| 104441 | 104506 | /* |
| 104442 | 104507 | ** Each instance of this object holds a sequence of WhereLoop objects |
| 104443 | 104508 | ** that implement some or all of a query plan. |
| 104444 | 104509 | ** |
| 104445 | | -** Think of each WhereLoop objects as a node in a graph, which arcs |
| 104510 | +** Think of each WhereLoop object as a node in a graph with arcs |
| 104446 | 104511 | ** showing dependences and costs for travelling between nodes. (That is |
| 104447 | 104512 | ** not a completely accurate description because WhereLoop costs are a |
| 104448 | 104513 | ** vector, not a scalar, and because dependences are many-to-one, not |
| 104449 | 104514 | ** one-to-one as are graph nodes. But it is a useful visualization aid.) |
| 104450 | 104515 | ** Then a WherePath object is a path through the graph that visits some |
| | @@ -104664,23 +104729,23 @@ |
| 104664 | 104729 | */ |
| 104665 | 104730 | struct WhereInfo { |
| 104666 | 104731 | Parse *pParse; /* Parsing and code generating context */ |
| 104667 | 104732 | SrcList *pTabList; /* List of tables in the join */ |
| 104668 | 104733 | ExprList *pOrderBy; /* The ORDER BY clause or NULL */ |
| 104669 | | - ExprList *pDistinct; /* DISTINCT ON values, or NULL */ |
| 104734 | + ExprList *pResultSet; /* Result set. DISTINCT operates on these */ |
| 104670 | 104735 | WhereLoop *pLoops; /* List of all WhereLoop objects */ |
| 104671 | 104736 | Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ |
| 104672 | 104737 | WhereCost nRowOut; /* Estimated number of output rows */ |
| 104673 | 104738 | u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */ |
| 104674 | 104739 | u8 bOBSat; /* ORDER BY satisfied by indices */ |
| 104675 | 104740 | u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE/DELETE */ |
| 104676 | 104741 | u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */ |
| 104677 | 104742 | u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */ |
| 104743 | + u8 nLevel; /* Number of nested loop */ |
| 104678 | 104744 | int iTop; /* The very beginning of the WHERE loop */ |
| 104679 | 104745 | int iContinue; /* Jump here to continue with next record */ |
| 104680 | 104746 | int iBreak; /* Jump here to break out of the loop */ |
| 104681 | | - int nLevel; /* Number of nested loop */ |
| 104682 | 104747 | int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */ |
| 104683 | 104748 | WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */ |
| 104684 | 104749 | WhereClause sWC; /* Decomposition of the WHERE clause */ |
| 104685 | 104750 | WhereLevel a[1]; /* Information about each nest loop in WHERE */ |
| 104686 | 104751 | }; |
| | @@ -104710,11 +104775,11 @@ |
| 104710 | 104775 | /* |
| 104711 | 104776 | ** These are definitions of bits in the WhereLoop.wsFlags field. |
| 104712 | 104777 | ** The particular combination of bits in each WhereLoop help to |
| 104713 | 104778 | ** determine the algorithm that WhereLoop represents. |
| 104714 | 104779 | */ |
| 104715 | | -#define WHERE_COLUMN_EQ 0x00000001 /* x=EXPR or x IN (...) or x IS NULL */ |
| 104780 | +#define WHERE_COLUMN_EQ 0x00000001 /* x=EXPR */ |
| 104716 | 104781 | #define WHERE_COLUMN_RANGE 0x00000002 /* x<EXPR and/or x>EXPR */ |
| 104717 | 104782 | #define WHERE_COLUMN_IN 0x00000004 /* x IN (...) */ |
| 104718 | 104783 | #define WHERE_COLUMN_NULL 0x00000008 /* x IS NULL */ |
| 104719 | 104784 | #define WHERE_CONSTRAINT 0x0000000f /* Any of the WHERE_COLUMN_xxx values */ |
| 104720 | 104785 | #define WHERE_TOP_LIMIT 0x00000010 /* x<EXPR or x<=EXPR constraint */ |
| | @@ -104725,11 +104790,11 @@ |
| 104725 | 104790 | #define WHERE_INDEXED 0x00000200 /* WhereLoop.u.btree.pIndex is valid */ |
| 104726 | 104791 | #define WHERE_VIRTUALTABLE 0x00000400 /* WhereLoop.u.vtab is valid */ |
| 104727 | 104792 | #define WHERE_IN_ABLE 0x00000800 /* Able to support an IN operator */ |
| 104728 | 104793 | #define WHERE_ONEROW 0x00001000 /* Selects no more than one row */ |
| 104729 | 104794 | #define WHERE_MULTI_OR 0x00002000 /* OR using multiple indices */ |
| 104730 | | -#define WHERE_TEMP_INDEX 0x00004000 /* Uses an ephemeral index */ |
| 104795 | +#define WHERE_AUTO_INDEX 0x00004000 /* Uses an ephemeral index */ |
| 104731 | 104796 | |
| 104732 | 104797 | |
| 104733 | 104798 | /* Convert a WhereCost value (10 times log2(X)) into its integer value X. |
| 104734 | 104799 | ** A rough approximation is used. The value returned is not exact. |
| 104735 | 104800 | */ |
| | @@ -105103,11 +105168,11 @@ |
| 105103 | 105168 | /* |
| 105104 | 105169 | ** Advance to the next WhereTerm that matches according to the criteria |
| 105105 | 105170 | ** established when the pScan object was initialized by whereScanInit(). |
| 105106 | 105171 | ** Return NULL if there are no more matching WhereTerms. |
| 105107 | 105172 | */ |
| 105108 | | -WhereTerm *whereScanNext(WhereScan *pScan){ |
| 105173 | +static WhereTerm *whereScanNext(WhereScan *pScan){ |
| 105109 | 105174 | int iCur; /* The cursor on the LHS of the term */ |
| 105110 | 105175 | int iColumn; /* The column on the LHS of the term. -1 for IPK */ |
| 105111 | 105176 | Expr *pX; /* An expression being tested */ |
| 105112 | 105177 | WhereClause *pWC; /* Shorthand for pScan->pWC */ |
| 105113 | 105178 | WhereTerm *pTerm; /* The term being tested */ |
| | @@ -105190,11 +105255,11 @@ |
| 105190 | 105255 | ** but is enough to handle most commonly occurring SQL statements. |
| 105191 | 105256 | ** |
| 105192 | 105257 | ** If X is not the INTEGER PRIMARY KEY then X must be compatible with |
| 105193 | 105258 | ** index pIdx. |
| 105194 | 105259 | */ |
| 105195 | | -WhereTerm *whereScanInit( |
| 105260 | +static WhereTerm *whereScanInit( |
| 105196 | 105261 | WhereScan *pScan, /* The WhereScan object being initialized */ |
| 105197 | 105262 | WhereClause *pWC, /* The WHERE clause to be scanned */ |
| 105198 | 105263 | int iCur, /* Cursor to scan for */ |
| 105199 | 105264 | int iColumn, /* Column to scan for */ |
| 105200 | 105265 | u32 opMask, /* Operator(s) to scan for */ |
| | @@ -106019,10 +106084,11 @@ |
| 106019 | 106084 | ** the start of the loop will prevent any results from being returned. |
| 106020 | 106085 | */ |
| 106021 | 106086 | if( pExpr->op==TK_NOTNULL |
| 106022 | 106087 | && pExpr->pLeft->op==TK_COLUMN |
| 106023 | 106088 | && pExpr->pLeft->iColumn>=0 |
| 106089 | + && OptimizationEnabled(db, SQLITE_Stat3) |
| 106024 | 106090 | ){ |
| 106025 | 106091 | Expr *pNewExpr; |
| 106026 | 106092 | Expr *pLeft = pExpr->pLeft; |
| 106027 | 106093 | int idxNew; |
| 106028 | 106094 | WhereTerm *pNewTerm; |
| | @@ -106322,10 +106388,11 @@ |
| 106322 | 106388 | int mxBitCol; /* Maximum column in pSrc->colUsed */ |
| 106323 | 106389 | CollSeq *pColl; /* Collating sequence to on a column */ |
| 106324 | 106390 | WhereLoop *pLoop; /* The Loop object */ |
| 106325 | 106391 | Bitmask idxCols; /* Bitmap of columns used for indexing */ |
| 106326 | 106392 | Bitmask extraCols; /* Bitmap of additional columns */ |
| 106393 | + u8 sentWarning = 0; /* True if a warnning has been issued */ |
| 106327 | 106394 | |
| 106328 | 106395 | /* Generate code to skip over the creation and initialization of the |
| 106329 | 106396 | ** transient index on 2nd and subsequent iterations of the loop. */ |
| 106330 | 106397 | v = pParse->pVdbe; |
| 106331 | 106398 | assert( v!=0 ); |
| | @@ -106342,10 +106409,16 @@ |
| 106342 | 106409 | if( termCanDriveIndex(pTerm, pSrc, notReady) ){ |
| 106343 | 106410 | int iCol = pTerm->u.leftColumn; |
| 106344 | 106411 | Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol); |
| 106345 | 106412 | testcase( iCol==BMS ); |
| 106346 | 106413 | testcase( iCol==BMS-1 ); |
| 106414 | + if( !sentWarning ){ |
| 106415 | + sqlite3_log(SQLITE_WARNING_AUTOINDEX, |
| 106416 | + "automatic index on %s(%s)", pTable->zName, |
| 106417 | + pTable->aCol[iCol].zName); |
| 106418 | + sentWarning = 1; |
| 106419 | + } |
| 106347 | 106420 | if( (idxCols & cMask)==0 ){ |
| 106348 | 106421 | if( whereLoopResize(pParse->db, pLoop, nColumn+1) ) return; |
| 106349 | 106422 | pLoop->aLTerm[nColumn++] = pTerm; |
| 106350 | 106423 | idxCols |= cMask; |
| 106351 | 106424 | } |
| | @@ -106352,11 +106425,11 @@ |
| 106352 | 106425 | } |
| 106353 | 106426 | } |
| 106354 | 106427 | assert( nColumn>0 ); |
| 106355 | 106428 | pLoop->u.btree.nEq = pLoop->nLTerm = nColumn; |
| 106356 | 106429 | pLoop->wsFlags = WHERE_COLUMN_EQ | WHERE_IDX_ONLY | WHERE_INDEXED |
| 106357 | | - | WHERE_TEMP_INDEX; |
| 106430 | + | WHERE_AUTO_INDEX; |
| 106358 | 106431 | |
| 106359 | 106432 | /* Count the number of additional columns needed to create a |
| 106360 | 106433 | ** covering index. A "covering index" is an index that contains all |
| 106361 | 106434 | ** columns that are needed by the query. With a covering index, the |
| 106362 | 106435 | ** original table never needs to be accessed. Automatic indices must |
| | @@ -106690,13 +106763,14 @@ |
| 106690 | 106763 | z = (const u8 *)sqlite3_value_blob(pVal); |
| 106691 | 106764 | pColl = db->pDfltColl; |
| 106692 | 106765 | assert( pColl->enc==SQLITE_UTF8 ); |
| 106693 | 106766 | }else{ |
| 106694 | 106767 | pColl = sqlite3GetCollSeq(pParse, SQLITE_UTF8, 0, *pIdx->azColl); |
| 106695 | | - if( pColl==0 ){ |
| 106696 | | - return SQLITE_ERROR; |
| 106697 | | - } |
| 106768 | + /* If the collating sequence was unavailable, we should have failed |
| 106769 | + ** long ago and never reached this point. But we'll check just to |
| 106770 | + ** be doubly sure. */ |
| 106771 | + if( NEVER(pColl==0) ) return SQLITE_ERROR; |
| 106698 | 106772 | z = (const u8 *)sqlite3ValueText(pVal, pColl->enc); |
| 106699 | 106773 | if( !z ){ |
| 106700 | 106774 | return SQLITE_NOMEM; |
| 106701 | 106775 | } |
| 106702 | 106776 | assert( z && pColl && pColl->xCmp ); |
| | @@ -106851,11 +106925,11 @@ |
| 106851 | 106925 | ){ |
| 106852 | 106926 | int rc = SQLITE_OK; |
| 106853 | 106927 | |
| 106854 | 106928 | #ifdef SQLITE_ENABLE_STAT3 |
| 106855 | 106929 | |
| 106856 | | - if( nEq==0 && p->nSample ){ |
| 106930 | + if( nEq==0 && p->nSample && OptimizationEnabled(pParse->db, SQLITE_Stat3) ){ |
| 106857 | 106931 | sqlite3_value *pRangeVal; |
| 106858 | 106932 | tRowcnt iLower = 0; |
| 106859 | 106933 | tRowcnt iUpper = p->aiRowEst[0]; |
| 106860 | 106934 | tRowcnt a[2]; |
| 106861 | 106935 | u8 aff = p->pTable->aCol[p->aiColumn[0]].affinity; |
| | @@ -107397,17 +107471,16 @@ |
| 107397 | 107471 | } |
| 107398 | 107472 | if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 |
| 107399 | 107473 | && ALWAYS(pLoop->u.btree.pIndex!=0) |
| 107400 | 107474 | ){ |
| 107401 | 107475 | char *zWhere = explainIndexRange(db, pLoop, pItem->pTab); |
| 107402 | | - zMsg = sqlite3MAppendf(db, zMsg, "%s USING %s%sINDEX%s%s%s", zMsg, |
| 107403 | | - ((flags & WHERE_TEMP_INDEX)?"AUTOMATIC ":""), |
| 107404 | | - ((flags & WHERE_IDX_ONLY)?"COVERING ":""), |
| 107405 | | - ((flags & WHERE_TEMP_INDEX)?"":" "), |
| 107406 | | - ((flags & WHERE_TEMP_INDEX)?"": pLoop->u.btree.pIndex->zName), |
| 107407 | | - zWhere |
| 107408 | | - ); |
| 107476 | + zMsg = sqlite3MAppendf(db, zMsg, |
| 107477 | + ((flags & WHERE_AUTO_INDEX) ? |
| 107478 | + "%s USING AUTOMATIC %sINDEX%.0s%s" : |
| 107479 | + "%s USING %sINDEX %s%s"), |
| 107480 | + zMsg, ((flags & WHERE_IDX_ONLY) ? "COVERING " : ""), |
| 107481 | + pLoop->u.btree.pIndex->zName, zWhere); |
| 107409 | 107482 | sqlite3DbFree(db, zWhere); |
| 107410 | 107483 | }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){ |
| 107411 | 107484 | zMsg = sqlite3MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg); |
| 107412 | 107485 | |
| 107413 | 107486 | if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){ |
| | @@ -107608,14 +107681,15 @@ |
| 107608 | 107681 | }; |
| 107609 | 107682 | assert( TK_LE==TK_GT+1 ); /* Make sure the ordering.. */ |
| 107610 | 107683 | assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */ |
| 107611 | 107684 | assert( TK_GE==TK_GT+3 ); /* ... is correcct. */ |
| 107612 | 107685 | |
| 107686 | + assert( (pStart->wtFlags & TERM_VNULL)==0 ); |
| 107613 | 107687 | testcase( pStart->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */ |
| 107614 | 107688 | pX = pStart->pExpr; |
| 107615 | 107689 | assert( pX!=0 ); |
| 107616 | | - assert( pStart->leftCursor==iCur ); |
| 107690 | + testcase( pStart->leftCursor!=iCur ); /* transitive constraints */ |
| 107617 | 107691 | r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp); |
| 107618 | 107692 | sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1); |
| 107619 | 107693 | VdbeComment((v, "pk")); |
| 107620 | 107694 | sqlite3ExprCacheAffinityChange(pParse, r1, 1); |
| 107621 | 107695 | sqlite3ReleaseTempReg(pParse, rTemp); |
| | @@ -107625,11 +107699,12 @@ |
| 107625 | 107699 | } |
| 107626 | 107700 | if( pEnd ){ |
| 107627 | 107701 | Expr *pX; |
| 107628 | 107702 | pX = pEnd->pExpr; |
| 107629 | 107703 | assert( pX!=0 ); |
| 107630 | | - assert( pEnd->leftCursor==iCur ); |
| 107704 | + assert( (pEnd->wtFlags & TERM_VNULL)==0 ); |
| 107705 | + testcase( pEnd->leftCursor!=iCur ); /* Transitive constraints */ |
| 107631 | 107706 | testcase( pEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */ |
| 107632 | 107707 | memEndValue = ++pParse->nMem; |
| 107633 | 107708 | sqlite3ExprCode(pParse, pX->pRight, memEndValue); |
| 107634 | 107709 | if( pX->op==TK_LT || pX->op==TK_GT ){ |
| 107635 | 107710 | testOp = bRev ? OP_Le : OP_Ge; |
| | @@ -108074,11 +108149,11 @@ |
| 108074 | 108149 | ** terms, set pCov to the candidate covering index. Otherwise, set |
| 108075 | 108150 | ** pCov to NULL to indicate that no candidate covering index will |
| 108076 | 108151 | ** be available. |
| 108077 | 108152 | */ |
| 108078 | 108153 | pSubLoop = pSubWInfo->a[0].pWLoop; |
| 108079 | | - assert( (pSubLoop->wsFlags & WHERE_TEMP_INDEX)==0 ); |
| 108154 | + assert( (pSubLoop->wsFlags & WHERE_AUTO_INDEX)==0 ); |
| 108080 | 108155 | if( (pSubLoop->wsFlags & WHERE_INDEXED)!=0 |
| 108081 | 108156 | && (ii==0 || pSubLoop->u.btree.pIndex==pCov) |
| 108082 | 108157 | ){ |
| 108083 | 108158 | assert( pSubWInfo->a[0].iIdxCur==iCovCur ); |
| 108084 | 108159 | pCov = pSubLoop->u.btree.pIndex; |
| | @@ -108160,10 +108235,11 @@ |
| 108160 | 108235 | WhereTerm *pAlt; |
| 108161 | 108236 | Expr sEq; |
| 108162 | 108237 | if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; |
| 108163 | 108238 | if( pTerm->eOperator!=(WO_EQUIV|WO_EQ) ) continue; |
| 108164 | 108239 | if( pTerm->leftCursor!=iCur ) continue; |
| 108240 | + if( pLevel->iLeftJoin ) continue; |
| 108165 | 108241 | pE = pTerm->pExpr; |
| 108166 | 108242 | assert( !ExprHasProperty(pE, EP_FromJoin) ); |
| 108167 | 108243 | assert( (pTerm->prereqRight & newNotReady)!=0 ); |
| 108168 | 108244 | pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady, WO_EQ|WO_IN, 0); |
| 108169 | 108245 | if( pAlt==0 ) continue; |
| | @@ -108208,13 +108284,13 @@ |
| 108208 | 108284 | */ |
| 108209 | 108285 | static void whereLoopPrint(WhereLoop *p, SrcList *pTabList){ |
| 108210 | 108286 | int nb = 1+(pTabList->nSrc+7)/8; |
| 108211 | 108287 | struct SrcList_item *pItem = pTabList->a + p->iTab; |
| 108212 | 108288 | Table *pTab = pItem->pTab; |
| 108213 | | - sqlite3DebugPrintf("%c %2d.%0*llx.%0*llx", p->cId, |
| 108289 | + sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, |
| 108214 | 108290 | p->iTab, nb, p->maskSelf, nb, p->prereq); |
| 108215 | | - sqlite3DebugPrintf(" %8s", |
| 108291 | + sqlite3DebugPrintf(" %12s", |
| 108216 | 108292 | pItem->zAlias ? pItem->zAlias : pTab->zName); |
| 108217 | 108293 | if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){ |
| 108218 | 108294 | if( p->u.btree.pIndex ){ |
| 108219 | 108295 | const char *zName = p->u.btree.pIndex->zName; |
| 108220 | 108296 | if( zName==0 ) zName = "ipk"; |
| | @@ -108221,26 +108297,26 @@ |
| 108221 | 108297 | if( strncmp(zName, "sqlite_autoindex_", 17)==0 ){ |
| 108222 | 108298 | int i = sqlite3Strlen30(zName) - 1; |
| 108223 | 108299 | while( zName[i]!='_' ) i--; |
| 108224 | 108300 | zName += i; |
| 108225 | 108301 | } |
| 108226 | | - sqlite3DebugPrintf(".%-12s %2d", zName, p->u.btree.nEq); |
| 108302 | + sqlite3DebugPrintf(".%-16s %2d", zName, p->u.btree.nEq); |
| 108227 | 108303 | }else{ |
| 108228 | | - sqlite3DebugPrintf("%16s",""); |
| 108304 | + sqlite3DebugPrintf("%20s",""); |
| 108229 | 108305 | } |
| 108230 | 108306 | }else{ |
| 108231 | 108307 | char *z; |
| 108232 | 108308 | if( p->u.vtab.idxStr ){ |
| 108233 | 108309 | z = sqlite3_mprintf("(%d,\"%s\",%x)", |
| 108234 | 108310 | p->u.vtab.idxNum, p->u.vtab.idxStr, p->u.vtab.omitMask); |
| 108235 | 108311 | }else{ |
| 108236 | 108312 | z = sqlite3_mprintf("(%d,%x)", p->u.vtab.idxNum, p->u.vtab.omitMask); |
| 108237 | 108313 | } |
| 108238 | | - sqlite3DebugPrintf(" %-15s", z); |
| 108314 | + sqlite3DebugPrintf(" %-19s", z); |
| 108239 | 108315 | sqlite3_free(z); |
| 108240 | 108316 | } |
| 108241 | | - sqlite3DebugPrintf(" fg %05x N %d", p->wsFlags, p->nLTerm); |
| 108317 | + sqlite3DebugPrintf(" f %04x N %d", p->wsFlags, p->nLTerm); |
| 108242 | 108318 | sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut); |
| 108243 | 108319 | } |
| 108244 | 108320 | #endif |
| 108245 | 108321 | |
| 108246 | 108322 | /* |
| | @@ -108256,16 +108332,16 @@ |
| 108256 | 108332 | |
| 108257 | 108333 | /* |
| 108258 | 108334 | ** Clear the WhereLoop.u union. Leave WhereLoop.pLTerm intact. |
| 108259 | 108335 | */ |
| 108260 | 108336 | static void whereLoopClearUnion(sqlite3 *db, WhereLoop *p){ |
| 108261 | | - if( p->wsFlags & (WHERE_VIRTUALTABLE|WHERE_TEMP_INDEX) ){ |
| 108337 | + if( p->wsFlags & (WHERE_VIRTUALTABLE|WHERE_AUTO_INDEX) ){ |
| 108262 | 108338 | if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 && p->u.vtab.needFree ){ |
| 108263 | 108339 | sqlite3_free(p->u.vtab.idxStr); |
| 108264 | 108340 | p->u.vtab.needFree = 0; |
| 108265 | 108341 | p->u.vtab.idxStr = 0; |
| 108266 | | - }else if( (p->wsFlags & WHERE_TEMP_INDEX)!=0 && p->u.btree.pIndex!=0 ){ |
| 108342 | + }else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){ |
| 108267 | 108343 | sqlite3DbFree(db, p->u.btree.pIndex->zColAff); |
| 108268 | 108344 | sqlite3DbFree(db, p->u.btree.pIndex); |
| 108269 | 108345 | p->u.btree.pIndex = 0; |
| 108270 | 108346 | } |
| 108271 | 108347 | } |
| | @@ -108304,11 +108380,11 @@ |
| 108304 | 108380 | whereLoopClearUnion(db, pTo); |
| 108305 | 108381 | memcpy(pTo, pFrom, WHERE_LOOP_XFER_SZ); |
| 108306 | 108382 | memcpy(pTo->aLTerm, pFrom->aLTerm, pTo->nLTerm*sizeof(pTo->aLTerm[0])); |
| 108307 | 108383 | if( pFrom->wsFlags & WHERE_VIRTUALTABLE ){ |
| 108308 | 108384 | pFrom->u.vtab.needFree = 0; |
| 108309 | | - }else if( (pFrom->wsFlags & WHERE_TEMP_INDEX)!=0 ){ |
| 108385 | + }else if( (pFrom->wsFlags & WHERE_AUTO_INDEX)!=0 ){ |
| 108310 | 108386 | pFrom->u.btree.pIndex = 0; |
| 108311 | 108387 | } |
| 108312 | 108388 | return SQLITE_OK; |
| 108313 | 108389 | } |
| 108314 | 108390 | |
| | @@ -108554,10 +108630,15 @@ |
| 108554 | 108630 | pNew->rSetup = 0; |
| 108555 | 108631 | rLogSize = estLog(whereCost(pProbe->aiRowEst[0])); |
| 108556 | 108632 | for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){ |
| 108557 | 108633 | int nIn = 0; |
| 108558 | 108634 | if( pTerm->prereqRight & pNew->maskSelf ) continue; |
| 108635 | +#ifdef SQLITE_ENABLE_STAT3 |
| 108636 | + if( (pTerm->wtFlags & TERM_VNULL)!=0 && pSrc->pTab->aCol[iCol].notNull ){ |
| 108637 | + continue; /* skip IS NOT NULL constraints on a NOT NULL column */ |
| 108638 | + } |
| 108639 | +#endif |
| 108559 | 108640 | pNew->wsFlags = saved_wsFlags; |
| 108560 | 108641 | pNew->u.btree.nEq = saved_nEq; |
| 108561 | 108642 | pNew->nLTerm = saved_nLTerm; |
| 108562 | 108643 | if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ |
| 108563 | 108644 | pNew->aLTerm[pNew->nLTerm++] = pTerm; |
| | @@ -108616,11 +108697,12 @@ |
| 108616 | 108697 | whereRangeScanEst(pParse, pProbe, pNew->u.btree.nEq, |
| 108617 | 108698 | pBtm, pTop, &rDiv); |
| 108618 | 108699 | pNew->nOut = saved_nOut>rDiv+10 ? saved_nOut - rDiv : 10; |
| 108619 | 108700 | } |
| 108620 | 108701 | #ifdef SQLITE_ENABLE_STAT3 |
| 108621 | | - if( pNew->u.btree.nEq==1 && pProbe->nSample ){ |
| 108702 | + if( pNew->u.btree.nEq==1 && pProbe->nSample |
| 108703 | + && OptimizationEnabled(db, SQLITE_Stat3) ){ |
| 108622 | 108704 | tRowcnt nOut = 0; |
| 108623 | 108705 | if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))!=0 ){ |
| 108624 | 108706 | testcase( pTerm->eOperator & WO_EQ ); |
| 108625 | 108707 | testcase( pTerm->eOperator & WO_ISNULL ); |
| 108626 | 108708 | rc = whereEqualScanEst(pParse, pProbe, pTerm->pExpr->pRight, &nOut); |
| | @@ -108700,11 +108782,11 @@ |
| 108700 | 108782 | return m; |
| 108701 | 108783 | } |
| 108702 | 108784 | |
| 108703 | 108785 | |
| 108704 | 108786 | /* |
| 108705 | | -** Add all WhereLoop objects a single table of the join were the table |
| 108787 | +** Add all WhereLoop objects for a single table of the join where the table |
| 108706 | 108788 | ** is idenfied by pBuilder->pNew->iTab. That table is guaranteed to be |
| 108707 | 108789 | ** a b-tree table, not a virtual table. |
| 108708 | 108790 | */ |
| 108709 | 108791 | static int whereLoopAddBtree( |
| 108710 | 108792 | WhereLoopBuilder *pBuilder, /* WHERE clause information */ |
| | @@ -108776,17 +108858,20 @@ |
| 108776 | 108858 | pNew->u.btree.nEq = 1; |
| 108777 | 108859 | pNew->u.btree.pIndex = 0; |
| 108778 | 108860 | pNew->nLTerm = 1; |
| 108779 | 108861 | pNew->aLTerm[0] = pTerm; |
| 108780 | 108862 | /* TUNING: One-time cost for computing the automatic index is |
| 108781 | | - ** approximately 6*N*log2(N) where N is the number of rows in |
| 108863 | + ** approximately 7*N*log2(N) where N is the number of rows in |
| 108782 | 108864 | ** the table being indexed. */ |
| 108783 | | - pNew->rSetup = rLogSize + rSize + 26; assert( 26==whereCost(6) ); |
| 108784 | | - /* TUNING: Each index lookup yields 10 rows in the table */ |
| 108785 | | - pNew->nOut = 33; assert( 33==whereCost(10) ); |
| 108865 | + pNew->rSetup = rLogSize + rSize + 28; assert( 28==whereCost(7) ); |
| 108866 | + /* TUNING: Each index lookup yields 20 rows in the table. This |
| 108867 | + ** is more than the usual guess of 10 rows, since we have no way |
| 108868 | + ** of knowning how selective the index will ultimately be. It would |
| 108869 | + ** not be unreasonable to make this value much larger. */ |
| 108870 | + pNew->nOut = 43; assert( 43==whereCost(20) ); |
| 108786 | 108871 | pNew->rRun = whereCostAdd(rLogSize,pNew->nOut); |
| 108787 | | - pNew->wsFlags = WHERE_TEMP_INDEX; |
| 108872 | + pNew->wsFlags = WHERE_AUTO_INDEX; |
| 108788 | 108873 | pNew->prereq = mExtra | pTerm->prereqRight; |
| 108789 | 108874 | rc = whereLoopInsert(pBuilder, pNew); |
| 108790 | 108875 | } |
| 108791 | 108876 | } |
| 108792 | 108877 | } |
| | @@ -109161,16 +109246,23 @@ |
| 109161 | 109246 | } |
| 109162 | 109247 | |
| 109163 | 109248 | /* |
| 109164 | 109249 | ** Examine a WherePath (with the addition of the extra WhereLoop of the 5th |
| 109165 | 109250 | ** parameters) to see if it outputs rows in the requested ORDER BY |
| 109166 | | -** (or GROUP BY) without requiring a separate source operation. Return: |
| 109251 | +** (or GROUP BY) without requiring a separate sort operation. Return: |
| 109167 | 109252 | ** |
| 109168 | 109253 | ** 0: ORDER BY is not satisfied. Sorting required |
| 109169 | 109254 | ** 1: ORDER BY is satisfied. Omit sorting |
| 109170 | 109255 | ** -1: Unknown at this time |
| 109171 | 109256 | ** |
| 109257 | +** Note that processing for WHERE_GROUPBY and WHERE_DISTINCTBY is not as |
| 109258 | +** strict. With GROUP BY and DISTINCT the only requirement is that |
| 109259 | +** equivalent rows appear immediately adjacent to one another. GROUP BY |
| 109260 | +** and DISTINT do not require rows to appear in any particular order as long |
| 109261 | +** as equivelent rows are grouped together. Thus for GROUP BY and DISTINCT |
| 109262 | +** the pOrderBy terms can be matched in any order. With ORDER BY, the |
| 109263 | +** pOrderBy terms must be matched in strict left-to-right order. |
| 109172 | 109264 | */ |
| 109173 | 109265 | static int wherePathSatisfiesOrderBy( |
| 109174 | 109266 | WhereInfo *pWInfo, /* The WHERE clause */ |
| 109175 | 109267 | ExprList *pOrderBy, /* ORDER BY or GROUP BY or DISTINCT clause to check */ |
| 109176 | 109268 | WherePath *pPath, /* The WherePath to check */ |
| | @@ -109414,11 +109506,11 @@ |
| 109414 | 109506 | } |
| 109415 | 109507 | #endif |
| 109416 | 109508 | |
| 109417 | 109509 | |
| 109418 | 109510 | /* |
| 109419 | | -** Given the list of WhereLoop objects on pWInfo->pLoops, this routine |
| 109511 | +** Given the list of WhereLoop objects at pWInfo->pLoops, this routine |
| 109420 | 109512 | ** attempts to find the lowest cost path that visits each WhereLoop |
| 109421 | 109513 | ** once. This path is then loaded into the pWInfo->a[].pWLoop fields. |
| 109422 | 109514 | ** |
| 109423 | 109515 | ** Assume that the total number of output rows that will need to be sorted |
| 109424 | 109516 | ** will be nRowEst (in the 10*log2 representation). Or, ignore sorting |
| | @@ -109650,16 +109742,17 @@ |
| 109650 | 109742 | WhereLevel *pLevel = pWInfo->a + iLoop; |
| 109651 | 109743 | pLevel->pWLoop = pWLoop = pFrom->aLoop[iLoop]; |
| 109652 | 109744 | pLevel->iFrom = pWLoop->iTab; |
| 109653 | 109745 | pLevel->iTabCur = pWInfo->pTabList->a[pLevel->iFrom].iCursor; |
| 109654 | 109746 | } |
| 109655 | | - if( (pWInfo->wctrlFlags & WHERE_DISTINCTBY)==0 |
| 109656 | | - && pWInfo->pDistinct |
| 109747 | + if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)!=0 |
| 109748 | + && (pWInfo->wctrlFlags & WHERE_DISTINCTBY)==0 |
| 109749 | + && pWInfo->eDistinct==WHERE_DISTINCT_NOOP |
| 109657 | 109750 | && nRowEst |
| 109658 | 109751 | ){ |
| 109659 | 109752 | Bitmask notUsed; |
| 109660 | | - int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pDistinct, pFrom, |
| 109753 | + int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pResultSet, pFrom, |
| 109661 | 109754 | WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], ¬Used); |
| 109662 | 109755 | if( rc==1 ) pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; |
| 109663 | 109756 | } |
| 109664 | 109757 | if( pFrom->isOrdered ){ |
| 109665 | 109758 | if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){ |
| | @@ -109744,11 +109837,13 @@ |
| 109744 | 109837 | pWInfo->a[0].pWLoop = pLoop; |
| 109745 | 109838 | pLoop->maskSelf = getMask(&pWInfo->sMaskSet, iCur); |
| 109746 | 109839 | pWInfo->a[0].iTabCur = iCur; |
| 109747 | 109840 | pWInfo->nRowOut = 1; |
| 109748 | 109841 | if( pWInfo->pOrderBy ) pWInfo->bOBSat = 1; |
| 109749 | | - if( pWInfo->pDistinct ) pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; |
| 109842 | + if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){ |
| 109843 | + pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; |
| 109844 | + } |
| 109750 | 109845 | #ifdef SQLITE_DEBUG |
| 109751 | 109846 | pLoop->cId = '0'; |
| 109752 | 109847 | #endif |
| 109753 | 109848 | return 1; |
| 109754 | 109849 | } |
| | @@ -109828,20 +109923,21 @@ |
| 109828 | 109923 | ** fi |
| 109829 | 109924 | ** end |
| 109830 | 109925 | ** |
| 109831 | 109926 | ** ORDER BY CLAUSE PROCESSING |
| 109832 | 109927 | ** |
| 109833 | | -** pOrderBy is a pointer to the ORDER BY clause of a SELECT statement, |
| 109928 | +** pOrderBy is a pointer to the ORDER BY clause (or the GROUP BY clause |
| 109929 | +** if the WHERE_GROUPBY flag is set in wctrlFlags) of a SELECT statement |
| 109834 | 109930 | ** if there is one. If there is no ORDER BY clause or if this routine |
| 109835 | 109931 | ** is called from an UPDATE or DELETE statement, then pOrderBy is NULL. |
| 109836 | 109932 | */ |
| 109837 | 109933 | SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( |
| 109838 | 109934 | Parse *pParse, /* The parser context */ |
| 109839 | | - SrcList *pTabList, /* A list of all tables to be scanned */ |
| 109935 | + SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */ |
| 109840 | 109936 | Expr *pWhere, /* The WHERE clause */ |
| 109841 | 109937 | ExprList *pOrderBy, /* An ORDER BY clause, or NULL */ |
| 109842 | | - ExprList *pDistinct, /* The select-list for DISTINCT queries - or NULL */ |
| 109938 | + ExprList *pResultSet, /* Result set of the query */ |
| 109843 | 109939 | u16 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */ |
| 109844 | 109940 | int iIdxCur /* If WHERE_ONETABLE_ONLY is set, index cursor number */ |
| 109845 | 109941 | ){ |
| 109846 | 109942 | int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */ |
| 109847 | 109943 | int nTabList; /* Number of elements in pTabList */ |
| | @@ -109849,18 +109945,26 @@ |
| 109849 | 109945 | Vdbe *v = pParse->pVdbe; /* The virtual database engine */ |
| 109850 | 109946 | Bitmask notReady; /* Cursors that are not yet positioned */ |
| 109851 | 109947 | WhereLoopBuilder sWLB; /* The WhereLoop builder */ |
| 109852 | 109948 | WhereMaskSet *pMaskSet; /* The expression mask set */ |
| 109853 | 109949 | WhereLevel *pLevel; /* A single level in pWInfo->a[] */ |
| 109950 | + WhereLoop *pLoop; /* Pointer to a single WhereLoop object */ |
| 109854 | 109951 | int ii; /* Loop counter */ |
| 109855 | 109952 | sqlite3 *db; /* Database connection */ |
| 109856 | 109953 | int rc; /* Return code */ |
| 109857 | 109954 | |
| 109858 | 109955 | |
| 109859 | 109956 | /* Variable initialization */ |
| 109957 | + db = pParse->db; |
| 109860 | 109958 | memset(&sWLB, 0, sizeof(sWLB)); |
| 109861 | 109959 | sWLB.pOrderBy = pOrderBy; |
| 109960 | + |
| 109961 | + /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via |
| 109962 | + ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */ |
| 109963 | + if( OptimizationDisabled(db, SQLITE_DistinctOpt) ){ |
| 109964 | + wctrlFlags &= ~WHERE_WANT_DISTINCT; |
| 109965 | + } |
| 109862 | 109966 | |
| 109863 | 109967 | /* The number of tables in the FROM clause is limited by the number of |
| 109864 | 109968 | ** bits in a Bitmask |
| 109865 | 109969 | */ |
| 109866 | 109970 | testcase( pTabList->nSrc==BMS ); |
| | @@ -109881,11 +109985,10 @@ |
| 109881 | 109985 | ** struct, the contents of WhereInfo.a[], the WhereClause structure |
| 109882 | 109986 | ** and the WhereMaskSet structure. Since WhereClause contains an 8-byte |
| 109883 | 109987 | ** field (type Bitmask) it must be aligned on an 8-byte boundary on |
| 109884 | 109988 | ** some architectures. Hence the ROUND8() below. |
| 109885 | 109989 | */ |
| 109886 | | - db = pParse->db; |
| 109887 | 109990 | nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel)); |
| 109888 | 109991 | pWInfo = sqlite3DbMallocZero(db, nByteWInfo + sizeof(WhereLoop)); |
| 109889 | 109992 | if( db->mallocFailed ){ |
| 109890 | 109993 | sqlite3DbFree(db, pWInfo); |
| 109891 | 109994 | pWInfo = 0; |
| | @@ -109893,11 +109996,11 @@ |
| 109893 | 109996 | } |
| 109894 | 109997 | pWInfo->nLevel = nTabList; |
| 109895 | 109998 | pWInfo->pParse = pParse; |
| 109896 | 109999 | pWInfo->pTabList = pTabList; |
| 109897 | 110000 | pWInfo->pOrderBy = pOrderBy; |
| 109898 | | - pWInfo->pDistinct = pDistinct; |
| 110001 | + pWInfo->pResultSet = pResultSet; |
| 109899 | 110002 | pWInfo->iBreak = sqlite3VdbeMakeLabel(v); |
| 109900 | 110003 | pWInfo->wctrlFlags = wctrlFlags; |
| 109901 | 110004 | pWInfo->savedNQueryLoop = pParse->nQueryLoop; |
| 109902 | 110005 | pMaskSet = &pWInfo->sMaskSet; |
| 109903 | 110006 | sWLB.pWInfo = pWInfo; |
| | @@ -109906,21 +110009,18 @@ |
| 109906 | 110009 | whereLoopInit(sWLB.pNew); |
| 109907 | 110010 | #ifdef SQLITE_DEBUG |
| 109908 | 110011 | sWLB.pNew->cId = '*'; |
| 109909 | 110012 | #endif |
| 109910 | 110013 | |
| 109911 | | - /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via |
| 109912 | | - ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */ |
| 109913 | | - if( OptimizationDisabled(db, SQLITE_DistinctOpt) ) pDistinct = 0; |
| 109914 | | - |
| 109915 | 110014 | /* Split the WHERE clause into separate subexpressions where each |
| 109916 | 110015 | ** subexpression is separated by an AND operator. |
| 109917 | 110016 | */ |
| 109918 | 110017 | initMaskSet(pMaskSet); |
| 109919 | 110018 | whereClauseInit(&pWInfo->sWC, pWInfo); |
| 109920 | 110019 | sqlite3ExprCodeConstants(pParse, pWhere); |
| 109921 | 110020 | whereSplit(&pWInfo->sWC, pWhere, TK_AND); /* IMP: R-15842-53296 */ |
| 110021 | + sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */ |
| 109922 | 110022 | |
| 109923 | 110023 | /* Special case: a WHERE clause that is constant. Evaluate the |
| 109924 | 110024 | ** expression and either jump over all of the code or fall thru. |
| 109925 | 110025 | */ |
| 109926 | 110026 | if( pWhere && (nTabList==0 || sqlite3ExprIsConstantNotJoin(pWhere)) ){ |
| | @@ -109930,11 +110030,13 @@ |
| 109930 | 110030 | |
| 109931 | 110031 | /* Special case: No FROM clause |
| 109932 | 110032 | */ |
| 109933 | 110033 | if( nTabList==0 ){ |
| 109934 | 110034 | if( pOrderBy ) pWInfo->bOBSat = 1; |
| 109935 | | - if( pDistinct ) pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; |
| 110035 | + if( wctrlFlags & WHERE_WANT_DISTINCT ){ |
| 110036 | + pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; |
| 110037 | + } |
| 109936 | 110038 | } |
| 109937 | 110039 | |
| 109938 | 110040 | /* Assign a bit from the bitmask to every term in the FROM clause. |
| 109939 | 110041 | ** |
| 109940 | 110042 | ** When assigning bitmask values to FROM clause cursors, it must be |
| | @@ -109977,11 +110079,11 @@ |
| 109977 | 110079 | |
| 109978 | 110080 | /* If the ORDER BY (or GROUP BY) clause contains references to general |
| 109979 | 110081 | ** expressions, then we won't be able to satisfy it using indices, so |
| 109980 | 110082 | ** go ahead and disable it now. |
| 109981 | 110083 | */ |
| 109982 | | - if( pOrderBy && pDistinct ){ |
| 110084 | + if( pOrderBy && (wctrlFlags & WHERE_WANT_DISTINCT)!=0 ){ |
| 109983 | 110085 | for(ii=0; ii<pOrderBy->nExpr; ii++){ |
| 109984 | 110086 | Expr *pExpr = sqlite3ExprSkipCollate(pOrderBy->a[ii].pExpr); |
| 109985 | 110087 | if( pExpr->op!=TK_COLUMN ){ |
| 109986 | 110088 | pWInfo->pOrderBy = pOrderBy = 0; |
| 109987 | 110089 | break; |
| | @@ -109989,21 +110091,18 @@ |
| 109989 | 110091 | break; |
| 109990 | 110092 | } |
| 109991 | 110093 | } |
| 109992 | 110094 | } |
| 109993 | 110095 | |
| 109994 | | - /* Check if the DISTINCT qualifier, if there is one, is redundant. |
| 109995 | | - ** If it is, then set pDistinct to NULL and WhereInfo.eDistinct to |
| 109996 | | - ** WHERE_DISTINCT_UNIQUE to tell the caller to ignore the DISTINCT. |
| 109997 | | - */ |
| 109998 | | - if( pDistinct ){ |
| 109999 | | - if( isDistinctRedundant(pParse,pTabList,&pWInfo->sWC,pDistinct) ){ |
| 110000 | | - pDistinct = 0; |
| 110096 | + if( wctrlFlags & WHERE_WANT_DISTINCT ){ |
| 110097 | + if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){ |
| 110098 | + /* The DISTINCT marking is pointless. Ignore it. */ |
| 110001 | 110099 | pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; |
| 110002 | 110100 | }else if( pOrderBy==0 ){ |
| 110101 | + /* Try to ORDER BY the result set to make distinct processing easier */ |
| 110003 | 110102 | pWInfo->wctrlFlags |= WHERE_DISTINCTBY; |
| 110004 | | - pWInfo->pOrderBy = pDistinct; |
| 110103 | + pWInfo->pOrderBy = pResultSet; |
| 110005 | 110104 | } |
| 110006 | 110105 | } |
| 110007 | 110106 | |
| 110008 | 110107 | /* Construct the WhereLoop objects */ |
| 110009 | 110108 | WHERETRACE(0xffff,("*** Optimizer Start ***\n")); |
| | @@ -110013,15 +110112,15 @@ |
| 110013 | 110112 | |
| 110014 | 110113 | /* Display all of the WhereLoop objects if wheretrace is enabled */ |
| 110015 | 110114 | #ifdef WHERETRACE_ENABLED |
| 110016 | 110115 | if( sqlite3WhereTrace ){ |
| 110017 | 110116 | WhereLoop *p; |
| 110018 | | - int i = 0; |
| 110117 | + int i; |
| 110019 | 110118 | static char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz" |
| 110020 | 110119 | "ABCDEFGHIJKLMNOPQRSTUVWYXZ"; |
| 110021 | | - for(p=pWInfo->pLoops; p; p=p->pNextLoop){ |
| 110022 | | - p->cId = zLabel[(i++)%sizeof(zLabel)]; |
| 110120 | + for(p=pWInfo->pLoops, i=0; p; p=p->pNextLoop, i++){ |
| 110121 | + p->cId = zLabel[i%sizeof(zLabel)]; |
| 110023 | 110122 | whereLoopPrint(p, pTabList); |
| 110024 | 110123 | } |
| 110025 | 110124 | } |
| 110026 | 110125 | #endif |
| 110027 | 110126 | |
| | @@ -110058,15 +110157,46 @@ |
| 110058 | 110157 | sqlite3DebugPrintf(" DISTINCT=unordered"); |
| 110059 | 110158 | break; |
| 110060 | 110159 | } |
| 110061 | 110160 | } |
| 110062 | 110161 | sqlite3DebugPrintf("\n"); |
| 110063 | | - for(ii=0; ii<nTabList; ii++){ |
| 110162 | + for(ii=0; ii<pWInfo->nLevel; ii++){ |
| 110064 | 110163 | whereLoopPrint(pWInfo->a[ii].pWLoop, pTabList); |
| 110065 | 110164 | } |
| 110066 | 110165 | } |
| 110067 | 110166 | #endif |
| 110167 | + /* Attempt to omit tables from the join that do not effect the result */ |
| 110168 | + if( pWInfo->nLevel>=2 |
| 110169 | + && pResultSet!=0 |
| 110170 | + && OptimizationEnabled(db, SQLITE_OmitNoopJoin) |
| 110171 | + ){ |
| 110172 | + Bitmask tabUsed = exprListTableUsage(pMaskSet, pResultSet); |
| 110173 | + if( pOrderBy ) tabUsed |= exprListTableUsage(pMaskSet, pOrderBy); |
| 110174 | + while( pWInfo->nLevel>=2 ){ |
| 110175 | + WhereTerm *pTerm, *pEnd; |
| 110176 | + pLoop = pWInfo->a[pWInfo->nLevel-1].pWLoop; |
| 110177 | + if( (pWInfo->pTabList->a[pLoop->iTab].jointype & JT_LEFT)==0 ) break; |
| 110178 | + if( (wctrlFlags & WHERE_WANT_DISTINCT)==0 |
| 110179 | + && (pLoop->wsFlags & WHERE_ONEROW)==0 |
| 110180 | + ){ |
| 110181 | + break; |
| 110182 | + } |
| 110183 | + if( (tabUsed & pLoop->maskSelf)!=0 ) break; |
| 110184 | + pEnd = sWLB.pWC->a + sWLB.pWC->nTerm; |
| 110185 | + for(pTerm=sWLB.pWC->a; pTerm<pEnd; pTerm++){ |
| 110186 | + if( (pTerm->prereqAll & pLoop->maskSelf)!=0 |
| 110187 | + && !ExprHasProperty(pTerm->pExpr, EP_FromJoin) |
| 110188 | + ){ |
| 110189 | + break; |
| 110190 | + } |
| 110191 | + } |
| 110192 | + if( pTerm<pEnd ) break; |
| 110193 | + WHERETRACE(0xffff, ("-> drop loop %c not used\n", pLoop->cId)); |
| 110194 | + pWInfo->nLevel--; |
| 110195 | + nTabList--; |
| 110196 | + } |
| 110197 | + } |
| 110068 | 110198 | WHERETRACE(0xffff,("*** Optimizer Finished ***\n")); |
| 110069 | 110199 | pWInfo->pParse->nQueryLoop += pWInfo->nRowOut; |
| 110070 | 110200 | |
| 110071 | 110201 | /* If the caller is an UPDATE or DELETE statement that is requesting |
| 110072 | 110202 | ** to use a one-pass algorithm, determine if this is appropriate. |
| | @@ -110081,17 +110211,15 @@ |
| 110081 | 110211 | } |
| 110082 | 110212 | |
| 110083 | 110213 | /* Open all tables in the pTabList and any indices selected for |
| 110084 | 110214 | ** searching those tables. |
| 110085 | 110215 | */ |
| 110086 | | - sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */ |
| 110087 | 110216 | notReady = ~(Bitmask)0; |
| 110088 | 110217 | for(ii=0, pLevel=pWInfo->a; ii<nTabList; ii++, pLevel++){ |
| 110089 | 110218 | Table *pTab; /* Table to open */ |
| 110090 | 110219 | int iDb; /* Index of database containing table/index */ |
| 110091 | 110220 | struct SrcList_item *pTabItem; |
| 110092 | | - WhereLoop *pLoop; |
| 110093 | 110221 | |
| 110094 | 110222 | pTabItem = &pTabList->a[pLevel->iFrom]; |
| 110095 | 110223 | pTab = pTabItem->pTab; |
| 110096 | 110224 | iDb = sqlite3SchemaToIndex(db, pTab->pSchema); |
| 110097 | 110225 | pLoop = pLevel->pWLoop; |
| | @@ -110123,11 +110251,11 @@ |
| 110123 | 110251 | } |
| 110124 | 110252 | }else{ |
| 110125 | 110253 | sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); |
| 110126 | 110254 | } |
| 110127 | 110255 | #ifndef SQLITE_OMIT_AUTOMATIC_INDEX |
| 110128 | | - if( (pLoop->wsFlags & WHERE_TEMP_INDEX)!=0 ){ |
| 110256 | + if( (pLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){ |
| 110129 | 110257 | constructAutomaticIndex(pParse, &pWInfo->sWC, pTabItem, notReady, pLevel); |
| 110130 | 110258 | }else |
| 110131 | 110259 | #endif |
| 110132 | 110260 | if( pLoop->wsFlags & WHERE_INDEXED ){ |
| 110133 | 110261 | Index *pIx = pLoop->u.btree.pIndex; |
| | @@ -110231,11 +110359,11 @@ |
| 110231 | 110359 | */ |
| 110232 | 110360 | sqlite3VdbeResolveLabel(v, pWInfo->iBreak); |
| 110233 | 110361 | |
| 110234 | 110362 | /* Close all of the cursors that were opened by sqlite3WhereBegin. |
| 110235 | 110363 | */ |
| 110236 | | - assert( pWInfo->nLevel==1 || pWInfo->nLevel==pTabList->nSrc ); |
| 110364 | + assert( pWInfo->nLevel<=pTabList->nSrc ); |
| 110237 | 110365 | for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){ |
| 110238 | 110366 | Index *pIdx = 0; |
| 110239 | 110367 | struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom]; |
| 110240 | 110368 | Table *pTab = pTabItem->pTab; |
| 110241 | 110369 | assert( pTab!=0 ); |
| | @@ -110246,11 +110374,11 @@ |
| 110246 | 110374 | ){ |
| 110247 | 110375 | int ws = pLoop->wsFlags; |
| 110248 | 110376 | if( !pWInfo->okOnePass && (ws & WHERE_IDX_ONLY)==0 ){ |
| 110249 | 110377 | sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor); |
| 110250 | 110378 | } |
| 110251 | | - if( (ws & WHERE_INDEXED)!=0 && (ws & (WHERE_IPK|WHERE_TEMP_INDEX))==0 ){ |
| 110379 | + if( (ws & WHERE_INDEXED)!=0 && (ws & (WHERE_IPK|WHERE_AUTO_INDEX))==0 ){ |
| 110252 | 110380 | sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur); |
| 110253 | 110381 | } |
| 110254 | 110382 | } |
| 110255 | 110383 | |
| 110256 | 110384 | /* If this scan uses an index, make VDBE code substitutions to read data |
| | @@ -114457,11 +114585,11 @@ |
| 114457 | 114585 | sqlite3 *db = pParse->db; /* The database connection */ |
| 114458 | 114586 | int mxSqlLen; /* Max length of an SQL string */ |
| 114459 | 114587 | |
| 114460 | 114588 | |
| 114461 | 114589 | mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; |
| 114462 | | - if( db->activeVdbeCnt==0 ){ |
| 114590 | + if( db->nVdbeActive==0 ){ |
| 114463 | 114591 | db->u1.isInterrupted = 0; |
| 114464 | 114592 | } |
| 114465 | 114593 | pParse->rc = SQLITE_OK; |
| 114466 | 114594 | pParse->zTail = zSql; |
| 114467 | 114595 | i = 0; |
| | @@ -116025,10 +116153,11 @@ |
| 116025 | 116153 | case SQLITE_PERM: zName = "SQLITE_PERM"; break; |
| 116026 | 116154 | case SQLITE_ABORT: zName = "SQLITE_ABORT"; break; |
| 116027 | 116155 | case SQLITE_ABORT_ROLLBACK: zName = "SQLITE_ABORT_ROLLBACK"; break; |
| 116028 | 116156 | case SQLITE_BUSY: zName = "SQLITE_BUSY"; break; |
| 116029 | 116157 | case SQLITE_BUSY_RECOVERY: zName = "SQLITE_BUSY_RECOVERY"; break; |
| 116158 | + case SQLITE_BUSY_SNAPSHOT: zName = "SQLITE_BUSY_SNAPSHOT"; break; |
| 116030 | 116159 | case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break; |
| 116031 | 116160 | case SQLITE_LOCKED_SHAREDCACHE: zName = "SQLITE_LOCKED_SHAREDCACHE";break; |
| 116032 | 116161 | case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break; |
| 116033 | 116162 | case SQLITE_READONLY: zName = "SQLITE_READONLY"; break; |
| 116034 | 116163 | case SQLITE_READONLY_RECOVERY: zName = "SQLITE_READONLY_RECOVERY"; break; |
| | @@ -116098,10 +116227,11 @@ |
| 116098 | 116227 | case SQLITE_NOTICE: zName = "SQLITE_NOTICE"; break; |
| 116099 | 116228 | case SQLITE_NOTICE_RECOVER_WAL: zName = "SQLITE_NOTICE_RECOVER_WAL";break; |
| 116100 | 116229 | case SQLITE_NOTICE_RECOVER_ROLLBACK: |
| 116101 | 116230 | zName = "SQLITE_NOTICE_RECOVER_ROLLBACK"; break; |
| 116102 | 116231 | case SQLITE_WARNING: zName = "SQLITE_WARNING"; break; |
| 116232 | + case SQLITE_WARNING_AUTOINDEX: zName = "SQLITE_WARNING_AUTOINDEX"; break; |
| 116103 | 116233 | case SQLITE_DONE: zName = "SQLITE_DONE"; break; |
| 116104 | 116234 | } |
| 116105 | 116235 | } |
| 116106 | 116236 | if( zName==0 ){ |
| 116107 | 116237 | static char zBuf[50]; |
| | @@ -116356,11 +116486,11 @@ |
| 116356 | 116486 | ** is being overridden/deleted but there are no active VMs, allow the |
| 116357 | 116487 | ** operation to continue but invalidate all precompiled statements. |
| 116358 | 116488 | */ |
| 116359 | 116489 | p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0); |
| 116360 | 116490 | if( p && p->iPrefEnc==enc && p->nArg==nArg ){ |
| 116361 | | - if( db->activeVdbeCnt ){ |
| 116491 | + if( db->nVdbeActive ){ |
| 116362 | 116492 | sqlite3Error(db, SQLITE_BUSY, |
| 116363 | 116493 | "unable to delete/modify user-function due to active statements"); |
| 116364 | 116494 | assert( !db->mallocFailed ); |
| 116365 | 116495 | return SQLITE_BUSY; |
| 116366 | 116496 | }else{ |
| | @@ -116937,11 +117067,11 @@ |
| 116937 | 117067 | ** sequence. If so, and there are active VMs, return busy. If there |
| 116938 | 117068 | ** are no active VMs, invalidate any pre-compiled statements. |
| 116939 | 117069 | */ |
| 116940 | 117070 | pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 0); |
| 116941 | 117071 | if( pColl && pColl->xCmp ){ |
| 116942 | | - if( db->activeVdbeCnt ){ |
| 117072 | + if( db->nVdbeActive ){ |
| 116943 | 117073 | sqlite3Error(db, SQLITE_BUSY, |
| 116944 | 117074 | "unable to delete/modify collation sequence due to active statements"); |
| 116945 | 117075 | return SQLITE_BUSY; |
| 116946 | 117076 | } |
| 116947 | 117077 | sqlite3ExpirePreparedStatements(db); |
| | @@ -117412,11 +117542,14 @@ |
| 117412 | 117542 | memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); |
| 117413 | 117543 | db->autoCommit = 1; |
| 117414 | 117544 | db->nextAutovac = -1; |
| 117415 | 117545 | db->szMmap = sqlite3GlobalConfig.szMmap; |
| 117416 | 117546 | db->nextPagesize = 0; |
| 117417 | | - db->flags |= SQLITE_ShortColNames | SQLITE_AutoIndex | SQLITE_EnableTrigger |
| 117547 | + db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger |
| 117548 | +#if !defined(SQLITE_DEAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX |
| 117549 | + | SQLITE_AutoIndex |
| 117550 | +#endif |
| 117418 | 117551 | #if SQLITE_DEFAULT_FILE_FORMAT<4 |
| 117419 | 117552 | | SQLITE_LegacyFileFmt |
| 117420 | 117553 | #endif |
| 117421 | 117554 | #ifdef SQLITE_ENABLE_LOAD_EXTENSION |
| 117422 | 117555 | | SQLITE_LoadExtension |
| | @@ -119407,10 +119540,11 @@ |
| 119407 | 119540 | sqlite3 *db; /* The database connection */ |
| 119408 | 119541 | const char *zDb; /* logical database name */ |
| 119409 | 119542 | const char *zName; /* virtual table name */ |
| 119410 | 119543 | int nColumn; /* number of named columns in virtual table */ |
| 119411 | 119544 | char **azColumn; /* column names. malloced */ |
| 119545 | + u8 *abNotindexed; /* True for 'notindexed' columns */ |
| 119412 | 119546 | sqlite3_tokenizer *pTokenizer; /* tokenizer for inserts and queries */ |
| 119413 | 119547 | char *zContentTbl; /* content=xxx option, or NULL */ |
| 119414 | 119548 | char *zLanguageid; /* languageid=xxx option, or NULL */ |
| 119415 | 119549 | u8 bAutoincrmerge; /* True if automerge=1 */ |
| 119416 | 119550 | u32 nLeafAdd; /* Number of leaf blocks added this trans */ |
| | @@ -119634,11 +119768,10 @@ |
| 119634 | 119768 | sqlite3_int64, sqlite3_int64, const char *, int, Fts3SegReader**); |
| 119635 | 119769 | SQLITE_PRIVATE int sqlite3Fts3SegReaderPending( |
| 119636 | 119770 | Fts3Table*,int,const char*,int,int,Fts3SegReader**); |
| 119637 | 119771 | SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3SegReader *); |
| 119638 | 119772 | SQLITE_PRIVATE int sqlite3Fts3AllSegdirs(Fts3Table*, int, int, int, sqlite3_stmt **); |
| 119639 | | -SQLITE_PRIVATE int sqlite3Fts3ReadLock(Fts3Table *); |
| 119640 | 119773 | SQLITE_PRIVATE int sqlite3Fts3ReadBlock(Fts3Table*, sqlite3_int64, char **, int*, int*); |
| 119641 | 119774 | |
| 119642 | 119775 | SQLITE_PRIVATE int sqlite3Fts3SelectDoctotal(Fts3Table *, sqlite3_stmt **); |
| 119643 | 119776 | SQLITE_PRIVATE int sqlite3Fts3SelectDocsize(Fts3Table *, sqlite3_int64, sqlite3_stmt **); |
| 119644 | 119777 | |
| | @@ -120567,22 +120700,34 @@ |
| 120567 | 120700 | char *zPrefix = 0; /* Prefix parameter value (or NULL) */ |
| 120568 | 120701 | char *zCompress = 0; /* compress=? parameter (or NULL) */ |
| 120569 | 120702 | char *zUncompress = 0; /* uncompress=? parameter (or NULL) */ |
| 120570 | 120703 | char *zContent = 0; /* content=? parameter (or NULL) */ |
| 120571 | 120704 | char *zLanguageid = 0; /* languageid=? parameter (or NULL) */ |
| 120705 | + char **azNotindexed = 0; /* The set of notindexed= columns */ |
| 120706 | + int nNotindexed = 0; /* Size of azNotindexed[] array */ |
| 120572 | 120707 | |
| 120573 | 120708 | assert( strlen(argv[0])==4 ); |
| 120574 | 120709 | assert( (sqlite3_strnicmp(argv[0], "fts4", 4)==0 && isFts4) |
| 120575 | 120710 | || (sqlite3_strnicmp(argv[0], "fts3", 4)==0 && !isFts4) |
| 120576 | 120711 | ); |
| 120577 | 120712 | |
| 120578 | 120713 | nDb = (int)strlen(argv[1]) + 1; |
| 120579 | 120714 | nName = (int)strlen(argv[2]) + 1; |
| 120580 | 120715 | |
| 120581 | | - aCol = (const char **)sqlite3_malloc(sizeof(const char *) * (argc-2) ); |
| 120582 | | - if( !aCol ) return SQLITE_NOMEM; |
| 120583 | | - memset((void *)aCol, 0, sizeof(const char *) * (argc-2)); |
| 120716 | + nByte = sizeof(const char *) * (argc-2); |
| 120717 | + aCol = (const char **)sqlite3_malloc(nByte); |
| 120718 | + if( aCol ){ |
| 120719 | + memset((void*)aCol, 0, nByte); |
| 120720 | + azNotindexed = (char **)sqlite3_malloc(nByte); |
| 120721 | + } |
| 120722 | + if( azNotindexed ){ |
| 120723 | + memset(azNotindexed, 0, nByte); |
| 120724 | + } |
| 120725 | + if( !aCol || !azNotindexed ){ |
| 120726 | + rc = SQLITE_NOMEM; |
| 120727 | + goto fts3_init_out; |
| 120728 | + } |
| 120584 | 120729 | |
| 120585 | 120730 | /* Loop through all of the arguments passed by the user to the FTS3/4 |
| 120586 | 120731 | ** module (i.e. all the column names and special arguments). This loop |
| 120587 | 120732 | ** does the following: |
| 120588 | 120733 | ** |
| | @@ -120617,11 +120762,12 @@ |
| 120617 | 120762 | { "prefix", 6 }, /* 1 -> PREFIX */ |
| 120618 | 120763 | { "compress", 8 }, /* 2 -> COMPRESS */ |
| 120619 | 120764 | { "uncompress", 10 }, /* 3 -> UNCOMPRESS */ |
| 120620 | 120765 | { "order", 5 }, /* 4 -> ORDER */ |
| 120621 | 120766 | { "content", 7 }, /* 5 -> CONTENT */ |
| 120622 | | - { "languageid", 10 } /* 6 -> LANGUAGEID */ |
| 120767 | + { "languageid", 10 }, /* 6 -> LANGUAGEID */ |
| 120768 | + { "notindexed", 10 } /* 7 -> NOTINDEXED */ |
| 120623 | 120769 | }; |
| 120624 | 120770 | |
| 120625 | 120771 | int iOpt; |
| 120626 | 120772 | if( !zVal ){ |
| 120627 | 120773 | rc = SQLITE_NOMEM; |
| | @@ -120683,10 +120829,15 @@ |
| 120683 | 120829 | assert( iOpt==6 ); |
| 120684 | 120830 | sqlite3_free(zLanguageid); |
| 120685 | 120831 | zLanguageid = zVal; |
| 120686 | 120832 | zVal = 0; |
| 120687 | 120833 | break; |
| 120834 | + |
| 120835 | + case 7: /* NOTINDEXED */ |
| 120836 | + azNotindexed[nNotindexed++] = zVal; |
| 120837 | + zVal = 0; |
| 120838 | + break; |
| 120688 | 120839 | } |
| 120689 | 120840 | } |
| 120690 | 120841 | sqlite3_free(zVal); |
| 120691 | 120842 | } |
| 120692 | 120843 | } |
| | @@ -120754,10 +120905,11 @@ |
| 120754 | 120905 | |
| 120755 | 120906 | /* Allocate and populate the Fts3Table structure. */ |
| 120756 | 120907 | nByte = sizeof(Fts3Table) + /* Fts3Table */ |
| 120757 | 120908 | nCol * sizeof(char *) + /* azColumn */ |
| 120758 | 120909 | nIndex * sizeof(struct Fts3Index) + /* aIndex */ |
| 120910 | + nCol * sizeof(u8) + /* abNotindexed */ |
| 120759 | 120911 | nName + /* zName */ |
| 120760 | 120912 | nDb + /* zDb */ |
| 120761 | 120913 | nString; /* Space for azColumn strings */ |
| 120762 | 120914 | p = (Fts3Table*)sqlite3_malloc(nByte); |
| 120763 | 120915 | if( p==0 ){ |
| | @@ -120787,13 +120939,14 @@ |
| 120787 | 120939 | memcpy(p->aIndex, aIndex, sizeof(struct Fts3Index) * nIndex); |
| 120788 | 120940 | p->nIndex = nIndex; |
| 120789 | 120941 | for(i=0; i<nIndex; i++){ |
| 120790 | 120942 | fts3HashInit(&p->aIndex[i].hPending, FTS3_HASH_STRING, 1); |
| 120791 | 120943 | } |
| 120944 | + p->abNotindexed = (u8 *)&p->aIndex[nIndex]; |
| 120792 | 120945 | |
| 120793 | 120946 | /* Fill in the zName and zDb fields of the vtab structure. */ |
| 120794 | | - zCsr = (char *)&p->aIndex[nIndex]; |
| 120947 | + zCsr = (char *)&p->abNotindexed[nCol]; |
| 120795 | 120948 | p->zName = zCsr; |
| 120796 | 120949 | memcpy(zCsr, argv[2], nName); |
| 120797 | 120950 | zCsr += nName; |
| 120798 | 120951 | p->zDb = zCsr; |
| 120799 | 120952 | memcpy(zCsr, argv[1], nDb); |
| | @@ -120810,11 +120963,30 @@ |
| 120810 | 120963 | p->azColumn[iCol] = zCsr; |
| 120811 | 120964 | zCsr += n+1; |
| 120812 | 120965 | assert( zCsr <= &((char *)p)[nByte] ); |
| 120813 | 120966 | } |
| 120814 | 120967 | |
| 120815 | | - if( (zCompress==0)!=(zUncompress==0) ){ |
| 120968 | + /* Fill in the abNotindexed array */ |
| 120969 | + for(iCol=0; iCol<nCol; iCol++){ |
| 120970 | + int n = (int)strlen(p->azColumn[iCol]); |
| 120971 | + for(i=0; i<nNotindexed; i++){ |
| 120972 | + char *zNot = azNotindexed[i]; |
| 120973 | + if( zNot && 0==sqlite3_strnicmp(p->azColumn[iCol], zNot, n) ){ |
| 120974 | + p->abNotindexed[iCol] = 1; |
| 120975 | + sqlite3_free(zNot); |
| 120976 | + azNotindexed[i] = 0; |
| 120977 | + } |
| 120978 | + } |
| 120979 | + } |
| 120980 | + for(i=0; i<nNotindexed; i++){ |
| 120981 | + if( azNotindexed[i] ){ |
| 120982 | + *pzErr = sqlite3_mprintf("no such column: %s", azNotindexed[i]); |
| 120983 | + rc = SQLITE_ERROR; |
| 120984 | + } |
| 120985 | + } |
| 120986 | + |
| 120987 | + if( rc==SQLITE_OK && (zCompress==0)!=(zUncompress==0) ){ |
| 120816 | 120988 | char const *zMiss = (zCompress==0 ? "compress" : "uncompress"); |
| 120817 | 120989 | rc = SQLITE_ERROR; |
| 120818 | 120990 | *pzErr = sqlite3_mprintf("missing %s parameter in fts4 constructor", zMiss); |
| 120819 | 120991 | } |
| 120820 | 120992 | p->zReadExprlist = fts3ReadExprList(p, zUncompress, &rc); |
| | @@ -120851,11 +121023,13 @@ |
| 120851 | 121023 | sqlite3_free(aIndex); |
| 120852 | 121024 | sqlite3_free(zCompress); |
| 120853 | 121025 | sqlite3_free(zUncompress); |
| 120854 | 121026 | sqlite3_free(zContent); |
| 120855 | 121027 | sqlite3_free(zLanguageid); |
| 121028 | + for(i=0; i<nNotindexed; i++) sqlite3_free(azNotindexed[i]); |
| 120856 | 121029 | sqlite3_free((void *)aCol); |
| 121030 | + sqlite3_free((void *)azNotindexed); |
| 120857 | 121031 | if( rc!=SQLITE_OK ){ |
| 120858 | 121032 | if( p ){ |
| 120859 | 121033 | fts3DisconnectMethod((sqlite3_vtab *)p); |
| 120860 | 121034 | }else if( pTokenizer ){ |
| 120861 | 121035 | pTokenizer->pModule->xDestroy(pTokenizer); |
| | @@ -129717,16 +129891,19 @@ |
| 129717 | 129891 | sqlite3_value **apVal, |
| 129718 | 129892 | u32 *aSz |
| 129719 | 129893 | ){ |
| 129720 | 129894 | int i; /* Iterator variable */ |
| 129721 | 129895 | for(i=2; i<p->nColumn+2; i++){ |
| 129722 | | - const char *zText = (const char *)sqlite3_value_text(apVal[i]); |
| 129723 | | - int rc = fts3PendingTermsAdd(p, iLangid, zText, i-2, &aSz[i-2]); |
| 129724 | | - if( rc!=SQLITE_OK ){ |
| 129725 | | - return rc; |
| 129896 | + int iCol = i-2; |
| 129897 | + if( p->abNotindexed[iCol]==0 ){ |
| 129898 | + const char *zText = (const char *)sqlite3_value_text(apVal[i]); |
| 129899 | + int rc = fts3PendingTermsAdd(p, iLangid, zText, iCol, &aSz[iCol]); |
| 129900 | + if( rc!=SQLITE_OK ){ |
| 129901 | + return rc; |
| 129902 | + } |
| 129903 | + aSz[p->nColumn] += sqlite3_value_bytes(apVal[i]); |
| 129726 | 129904 | } |
| 129727 | | - aSz[p->nColumn] += sqlite3_value_bytes(apVal[i]); |
| 129728 | 129905 | } |
| 129729 | 129906 | return SQLITE_OK; |
| 129730 | 129907 | } |
| 129731 | 129908 | |
| 129732 | 129909 | /* |
| | @@ -129869,13 +130046,16 @@ |
| 129869 | 130046 | if( SQLITE_ROW==sqlite3_step(pSelect) ){ |
| 129870 | 130047 | int i; |
| 129871 | 130048 | int iLangid = langidFromSelect(p, pSelect); |
| 129872 | 130049 | rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pSelect, 0)); |
| 129873 | 130050 | for(i=1; rc==SQLITE_OK && i<=p->nColumn; i++){ |
| 129874 | | - const char *zText = (const char *)sqlite3_column_text(pSelect, i); |
| 129875 | | - rc = fts3PendingTermsAdd(p, iLangid, zText, -1, &aSz[i-1]); |
| 129876 | | - aSz[p->nColumn] += sqlite3_column_bytes(pSelect, i); |
| 130051 | + int iCol = i-1; |
| 130052 | + if( p->abNotindexed[iCol]==0 ){ |
| 130053 | + const char *zText = (const char *)sqlite3_column_text(pSelect, i); |
| 130054 | + rc = fts3PendingTermsAdd(p, iLangid, zText, -1, &aSz[iCol]); |
| 130055 | + aSz[p->nColumn] += sqlite3_column_bytes(pSelect, i); |
| 130056 | + } |
| 129877 | 130057 | } |
| 129878 | 130058 | if( rc!=SQLITE_OK ){ |
| 129879 | 130059 | sqlite3_reset(pSelect); |
| 129880 | 130060 | *pRC = rc; |
| 129881 | 130061 | return; |
| | @@ -132113,13 +132293,15 @@ |
| 132113 | 132293 | int iCol; |
| 132114 | 132294 | int iLangid = langidFromSelect(p, pStmt); |
| 132115 | 132295 | rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pStmt, 0)); |
| 132116 | 132296 | memset(aSz, 0, sizeof(aSz[0]) * (p->nColumn+1)); |
| 132117 | 132297 | for(iCol=0; rc==SQLITE_OK && iCol<p->nColumn; iCol++){ |
| 132118 | | - const char *z = (const char *) sqlite3_column_text(pStmt, iCol+1); |
| 132119 | | - rc = fts3PendingTermsAdd(p, iLangid, z, iCol, &aSz[iCol]); |
| 132120 | | - aSz[p->nColumn] += sqlite3_column_bytes(pStmt, iCol+1); |
| 132298 | + if( p->abNotindexed[iCol]==0 ){ |
| 132299 | + const char *z = (const char *) sqlite3_column_text(pStmt, iCol+1); |
| 132300 | + rc = fts3PendingTermsAdd(p, iLangid, z, iCol, &aSz[iCol]); |
| 132301 | + aSz[p->nColumn] += sqlite3_column_bytes(pStmt, iCol+1); |
| 132302 | + } |
| 132121 | 132303 | } |
| 132122 | 132304 | if( p->bHasDocsize ){ |
| 132123 | 132305 | fts3InsertDocsize(&rc, p, aSz); |
| 132124 | 132306 | } |
| 132125 | 132307 | if( rc!=SQLITE_OK ){ |
| | @@ -133918,39 +134100,41 @@ |
| 133918 | 134100 | |
| 133919 | 134101 | assert( pCsr->isRequireSeek==0 ); |
| 133920 | 134102 | iDocid = sqlite3_column_int64(pCsr->pStmt, 0); |
| 133921 | 134103 | |
| 133922 | 134104 | for(i=0; i<p->nColumn && rc==SQLITE_OK; i++){ |
| 133923 | | - const char *zText = (const char *)sqlite3_column_text(pCsr->pStmt, i+1); |
| 133924 | | - sqlite3_tokenizer_cursor *pTC = 0; |
| 133925 | | - |
| 133926 | | - rc = sqlite3Fts3OpenTokenizer(pT, pCsr->iLangid, zText, -1, &pTC); |
| 133927 | | - while( rc==SQLITE_OK ){ |
| 133928 | | - char const *zToken; /* Buffer containing token */ |
| 133929 | | - int nToken = 0; /* Number of bytes in token */ |
| 133930 | | - int iDum1 = 0, iDum2 = 0; /* Dummy variables */ |
| 133931 | | - int iPos = 0; /* Position of token in zText */ |
| 133932 | | - |
| 133933 | | - rc = pModule->xNext(pTC, &zToken, &nToken, &iDum1, &iDum2, &iPos); |
| 133934 | | - for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){ |
| 133935 | | - Fts3PhraseToken *pPT = pDef->pToken; |
| 133936 | | - if( (pDef->iCol>=p->nColumn || pDef->iCol==i) |
| 133937 | | - && (pPT->bFirst==0 || iPos==0) |
| 133938 | | - && (pPT->n==nToken || (pPT->isPrefix && pPT->n<nToken)) |
| 133939 | | - && (0==memcmp(zToken, pPT->z, pPT->n)) |
| 133940 | | - ){ |
| 133941 | | - fts3PendingListAppend(&pDef->pList, iDocid, i, iPos, &rc); |
| 133942 | | - } |
| 133943 | | - } |
| 133944 | | - } |
| 133945 | | - if( pTC ) pModule->xClose(pTC); |
| 133946 | | - if( rc==SQLITE_DONE ) rc = SQLITE_OK; |
| 133947 | | - } |
| 133948 | | - |
| 133949 | | - for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){ |
| 133950 | | - if( pDef->pList ){ |
| 133951 | | - rc = fts3PendingListAppendVarint(&pDef->pList, 0); |
| 134105 | + if( p->abNotindexed[i]==0 ){ |
| 134106 | + const char *zText = (const char *)sqlite3_column_text(pCsr->pStmt, i+1); |
| 134107 | + sqlite3_tokenizer_cursor *pTC = 0; |
| 134108 | + |
| 134109 | + rc = sqlite3Fts3OpenTokenizer(pT, pCsr->iLangid, zText, -1, &pTC); |
| 134110 | + while( rc==SQLITE_OK ){ |
| 134111 | + char const *zToken; /* Buffer containing token */ |
| 134112 | + int nToken = 0; /* Number of bytes in token */ |
| 134113 | + int iDum1 = 0, iDum2 = 0; /* Dummy variables */ |
| 134114 | + int iPos = 0; /* Position of token in zText */ |
| 134115 | + |
| 134116 | + rc = pModule->xNext(pTC, &zToken, &nToken, &iDum1, &iDum2, &iPos); |
| 134117 | + for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){ |
| 134118 | + Fts3PhraseToken *pPT = pDef->pToken; |
| 134119 | + if( (pDef->iCol>=p->nColumn || pDef->iCol==i) |
| 134120 | + && (pPT->bFirst==0 || iPos==0) |
| 134121 | + && (pPT->n==nToken || (pPT->isPrefix && pPT->n<nToken)) |
| 134122 | + && (0==memcmp(zToken, pPT->z, pPT->n)) |
| 134123 | + ){ |
| 134124 | + fts3PendingListAppend(&pDef->pList, iDocid, i, iPos, &rc); |
| 134125 | + } |
| 134126 | + } |
| 134127 | + } |
| 134128 | + if( pTC ) pModule->xClose(pTC); |
| 134129 | + if( rc==SQLITE_DONE ) rc = SQLITE_OK; |
| 134130 | + } |
| 134131 | + |
| 134132 | + for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){ |
| 134133 | + if( pDef->pList ){ |
| 134134 | + rc = fts3PendingListAppendVarint(&pDef->pList, 0); |
| 134135 | + } |
| 133952 | 134136 | } |
| 133953 | 134137 | } |
| 133954 | 134138 | } |
| 133955 | 134139 | |
| 133956 | 134140 | return rc; |
| 133957 | 134141 | |