| | @@ -381,11 +381,11 @@ |
| 381 | 381 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 382 | 382 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 383 | 383 | */ |
| 384 | 384 | #define SQLITE_VERSION "3.16.0" |
| 385 | 385 | #define SQLITE_VERSION_NUMBER 3016000 |
| 386 | | -#define SQLITE_SOURCE_ID "2016-12-08 19:04:36 b26df26e184ec6da4b5537526c10f42a293d09b5" |
| 386 | +#define SQLITE_SOURCE_ID "2016-12-23 16:05:22 2940661b8c014b94973e05c44f1b1f4f443dbdd3" |
| 387 | 387 | |
| 388 | 388 | /* |
| 389 | 389 | ** CAPI3REF: Run-Time Library Version Numbers |
| 390 | 390 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 391 | 391 | ** |
| | @@ -12076,10 +12076,18 @@ |
| 12076 | 12076 | typedef struct VtabCtx VtabCtx; |
| 12077 | 12077 | typedef struct Walker Walker; |
| 12078 | 12078 | typedef struct WhereInfo WhereInfo; |
| 12079 | 12079 | typedef struct With With; |
| 12080 | 12080 | |
| 12081 | +/* A VList object records a mapping between parameters/variables/wildcards |
| 12082 | +** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer |
| 12083 | +** variable number associated with that parameter. See the format description |
| 12084 | +** on the sqlite3VListAdd() routine for more information. A VList is really |
| 12085 | +** just an array of integers. |
| 12086 | +*/ |
| 12087 | +typedef int VList; |
| 12088 | + |
| 12081 | 12089 | /* |
| 12082 | 12090 | ** Defer sourcing vdbe.h and btree.h until after the "u8" and |
| 12083 | 12091 | ** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque |
| 12084 | 12092 | ** pointer types (i.e. FuncDef) defined above. |
| 12085 | 12093 | */ |
| | @@ -12693,11 +12701,11 @@ |
| 12693 | 12701 | #define OP_RowSetRead 62 /* synopsis: r[P3]=rowset(P1) */ |
| 12694 | 12702 | #define OP_RowSetTest 63 /* synopsis: if r[P3] in rowset(P1) goto P2 */ |
| 12695 | 12703 | #define OP_Program 64 |
| 12696 | 12704 | #define OP_FkIfZero 65 /* synopsis: if fkctr[P1]==0 goto P2 */ |
| 12697 | 12705 | #define OP_IfPos 66 /* synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ |
| 12698 | | -#define OP_IfNotZero 67 /* synopsis: if r[P1]!=0 then r[P1]-=P3, goto P2 */ |
| 12706 | +#define OP_IfNotZero 67 /* synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ |
| 12699 | 12707 | #define OP_DecrJumpZero 68 /* synopsis: if (--r[P1])==0 goto P2 */ |
| 12700 | 12708 | #define OP_IncrVacuum 69 |
| 12701 | 12709 | #define OP_VNext 70 |
| 12702 | 12710 | #define OP_Init 71 /* synopsis: Start at P2 */ |
| 12703 | 12711 | #define OP_Return 72 |
| | @@ -12901,11 +12909,11 @@ |
| 12901 | 12909 | SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); |
| 12902 | 12910 | |
| 12903 | 12911 | SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); |
| 12904 | 12912 | SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); |
| 12905 | 12913 | SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int); |
| 12906 | | -SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **); |
| 12914 | +SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*); |
| 12907 | 12915 | |
| 12908 | 12916 | typedef int (*RecordCompare)(int,const void*,UnpackedRecord*); |
| 12909 | 12917 | SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*); |
| 12910 | 12918 | |
| 12911 | 12919 | #ifndef SQLITE_OMIT_TRIGGER |
| | @@ -14506,13 +14514,13 @@ |
| 14506 | 14514 | FKey *pFKey; /* Linked list of all foreign keys in this table */ |
| 14507 | 14515 | char *zColAff; /* String defining the affinity of each column */ |
| 14508 | 14516 | ExprList *pCheck; /* All CHECK constraints */ |
| 14509 | 14517 | /* ... also used as column name list in a VIEW */ |
| 14510 | 14518 | int tnum; /* Root BTree page for this table */ |
| 14519 | + u32 nTabRef; /* Number of pointers to this Table */ |
| 14511 | 14520 | i16 iPKey; /* If not negative, use aCol[iPKey] as the rowid */ |
| 14512 | 14521 | i16 nCol; /* Number of columns in this table */ |
| 14513 | | - u16 nRef; /* Number of pointers to this Table */ |
| 14514 | 14522 | LogEst nRowLogEst; /* Estimated rows in table - from sqlite_stat1 table */ |
| 14515 | 14523 | LogEst szTabRow; /* Estimated size of each table row in bytes */ |
| 14516 | 14524 | #ifdef SQLITE_ENABLE_COSTMULT |
| 14517 | 14525 | LogEst costMult; /* Cost multiplier for using this table */ |
| 14518 | 14526 | #endif |
| | @@ -15657,11 +15665,10 @@ |
| 15657 | 15665 | ** first field in the recursive region. |
| 15658 | 15666 | ************************************************************************/ |
| 15659 | 15667 | |
| 15660 | 15668 | Token sLastToken; /* The last token parsed */ |
| 15661 | 15669 | ynVar nVar; /* Number of '?' variables seen in the SQL so far */ |
| 15662 | | - int nzVar; /* Number of available slots in azVar[] */ |
| 15663 | 15670 | u8 iPkSortOrder; /* ASC or DESC for INTEGER PRIMARY KEY */ |
| 15664 | 15671 | u8 explain; /* True if the EXPLAIN flag is found on the query */ |
| 15665 | 15672 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 15666 | 15673 | u8 declareVtab; /* True if inside sqlite3_declare_vtab() */ |
| 15667 | 15674 | int nVtabLock; /* Number of virtual tables to lock */ |
| | @@ -15669,11 +15676,11 @@ |
| 15669 | 15676 | int nHeight; /* Expression tree height of current sub-select */ |
| 15670 | 15677 | #ifndef SQLITE_OMIT_EXPLAIN |
| 15671 | 15678 | int iSelectId; /* ID of current select for EXPLAIN output */ |
| 15672 | 15679 | int iNextSelectId; /* Next available select ID for EXPLAIN output */ |
| 15673 | 15680 | #endif |
| 15674 | | - char **azVar; /* Pointers to names of parameters */ |
| 15681 | + VList *pVList; /* Mapping between variable names and numbers */ |
| 15675 | 15682 | Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */ |
| 15676 | 15683 | const char *zTail; /* All SQL text past the last semicolon parsed */ |
| 15677 | 15684 | Table *pNewTable; /* A table being constructed by CREATE TABLE */ |
| 15678 | 15685 | Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */ |
| 15679 | 15686 | const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */ |
| | @@ -16268,10 +16275,13 @@ |
| 16268 | 16275 | SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*); |
| 16269 | 16276 | SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*); |
| 16270 | 16277 | SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**); |
| 16271 | 16278 | SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**); |
| 16272 | 16279 | SQLITE_PRIVATE void sqlite3Pragma(Parse*,Token*,Token*,Token*,int); |
| 16280 | +#ifndef SQLITE_OMIT_VIRTUALTABLE |
| 16281 | +SQLITE_PRIVATE Module *sqlite3PragmaVtabRegister(sqlite3*,const char *zName); |
| 16282 | +#endif |
| 16273 | 16283 | SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3*); |
| 16274 | 16284 | SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3*,int); |
| 16275 | 16285 | SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3*); |
| 16276 | 16286 | SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3*); |
| 16277 | 16287 | SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3*,Table*); |
| | @@ -16566,10 +16576,13 @@ |
| 16566 | 16576 | #if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \ |
| 16567 | 16577 | defined(SQLITE_ENABLE_STAT3_OR_STAT4) || \ |
| 16568 | 16578 | defined(SQLITE_EXPLAIN_ESTIMATED_ROWS) |
| 16569 | 16579 | SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst); |
| 16570 | 16580 | #endif |
| 16581 | +SQLITE_PRIVATE VList *sqlite3VListAdd(sqlite3*,VList*,const char*,int,int); |
| 16582 | +SQLITE_PRIVATE const char *sqlite3VListNumToName(VList*,int); |
| 16583 | +SQLITE_PRIVATE int sqlite3VListNameToNum(VList*,const char*,int); |
| 16571 | 16584 | |
| 16572 | 16585 | /* |
| 16573 | 16586 | ** Routines to read and write variable-length integers. These used to |
| 16574 | 16587 | ** be defined locally, but now we use the varint routines in the util.c |
| 16575 | 16588 | ** file. |
| | @@ -16782,10 +16795,17 @@ |
| 16782 | 16795 | SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *); |
| 16783 | 16796 | SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3*); |
| 16784 | 16797 | SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *, int, int); |
| 16785 | 16798 | SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*); |
| 16786 | 16799 | SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3*, Table*); |
| 16800 | +SQLITE_PRIVATE Module *sqlite3VtabCreateModule( |
| 16801 | + sqlite3*, |
| 16802 | + const char*, |
| 16803 | + const sqlite3_module*, |
| 16804 | + void*, |
| 16805 | + void(*)(void*) |
| 16806 | + ); |
| 16787 | 16807 | # define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0) |
| 16788 | 16808 | #endif |
| 16789 | 16809 | SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse*,Module*); |
| 16790 | 16810 | SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3*,Module*); |
| 16791 | 16811 | SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*); |
| | @@ -17180,12 +17200,12 @@ |
| 17180 | 17200 | SQLITE_THREADSAFE==1, /* bFullMutex */ |
| 17181 | 17201 | SQLITE_USE_URI, /* bOpenUri */ |
| 17182 | 17202 | SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */ |
| 17183 | 17203 | 0x7ffffffe, /* mxStrlen */ |
| 17184 | 17204 | 0, /* neverCorrupt */ |
| 17185 | | - 128, /* szLookaside */ |
| 17186 | | - 500, /* nLookaside */ |
| 17205 | + 512, /* szLookaside */ |
| 17206 | + 125, /* nLookaside */ |
| 17187 | 17207 | SQLITE_STMTJRNL_SPILL, /* nStmtSpill */ |
| 17188 | 17208 | {0,0,0,0,0,0,0,0}, /* m */ |
| 17189 | 17209 | {0,0,0,0,0,0,0,0,0}, /* mutex */ |
| 17190 | 17210 | {0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */ |
| 17191 | 17211 | (void*)0, /* pHeap */ |
| | @@ -17832,64 +17852,64 @@ |
| 17832 | 17852 | ** * A virtual table |
| 17833 | 17853 | ** * A one-row "pseudotable" stored in a single register |
| 17834 | 17854 | */ |
| 17835 | 17855 | typedef struct VdbeCursor VdbeCursor; |
| 17836 | 17856 | struct VdbeCursor { |
| 17837 | | - u8 eCurType; /* One of the CURTYPE_* values above */ |
| 17838 | | - i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ |
| 17839 | | - u8 nullRow; /* True if pointing to a row with no data */ |
| 17840 | | - u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ |
| 17841 | | - u8 isTable; /* True for rowid tables. False for indexes */ |
| 17857 | + u8 eCurType; /* One of the CURTYPE_* values above */ |
| 17858 | + i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ |
| 17859 | + u8 nullRow; /* True if pointing to a row with no data */ |
| 17860 | + u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ |
| 17861 | + u8 isTable; /* True for rowid tables. False for indexes */ |
| 17842 | 17862 | #ifdef SQLITE_DEBUG |
| 17843 | | - u8 seekOp; /* Most recent seek operation on this cursor */ |
| 17844 | | - u8 wrFlag; /* The wrFlag argument to sqlite3BtreeCursor() */ |
| 17863 | + u8 seekOp; /* Most recent seek operation on this cursor */ |
| 17864 | + u8 wrFlag; /* The wrFlag argument to sqlite3BtreeCursor() */ |
| 17845 | 17865 | #endif |
| 17846 | | - Bool isEphemeral:1; /* True for an ephemeral table */ |
| 17847 | | - Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */ |
| 17848 | | - Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */ |
| 17849 | | - Pgno pgnoRoot; /* Root page of the open btree cursor */ |
| 17850 | | - i16 nField; /* Number of fields in the header */ |
| 17851 | | - u16 nHdrParsed; /* Number of header fields parsed so far */ |
| 17866 | + Bool isEphemeral:1; /* True for an ephemeral table */ |
| 17867 | + Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */ |
| 17868 | + Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */ |
| 17869 | + Btree *pBtx; /* Separate file holding temporary table */ |
| 17870 | + i64 seqCount; /* Sequence counter */ |
| 17871 | + int *aAltMap; /* Mapping from table to index column numbers */ |
| 17872 | + |
| 17873 | + /* Cached OP_Column parse information is only valid if cacheStatus matches |
| 17874 | + ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of |
| 17875 | + ** CACHE_STALE (0) and so setting cacheStatus=CACHE_STALE guarantees that |
| 17876 | + ** the cache is out of date. */ |
| 17877 | + u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ |
| 17878 | + int seekResult; /* Result of previous sqlite3BtreeMoveto() or 0 |
| 17879 | + ** if there have been no prior seeks on the cursor. */ |
| 17880 | + /* NB: seekResult does not distinguish between "no seeks have ever occurred |
| 17881 | + ** on this cursor" and "the most recent seek was an exact match". */ |
| 17882 | + |
| 17883 | + /* When a new VdbeCursor is allocated, only the fields above are zeroed. |
| 17884 | + ** The fields that follow are uninitialized, and must be individually |
| 17885 | + ** initialized prior to first use. */ |
| 17886 | + VdbeCursor *pAltCursor; /* Associated index cursor from which to read */ |
| 17852 | 17887 | union { |
| 17853 | 17888 | BtCursor *pCursor; /* CURTYPE_BTREE. Btree cursor */ |
| 17854 | 17889 | sqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB. Vtab cursor */ |
| 17855 | 17890 | int pseudoTableReg; /* CURTYPE_PSEUDO. Reg holding content. */ |
| 17856 | 17891 | VdbeSorter *pSorter; /* CURTYPE_SORTER. Sorter object */ |
| 17857 | 17892 | } uc; |
| 17858 | | - Btree *pBt; /* Separate file holding temporary table */ |
| 17859 | | - KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ |
| 17860 | | - int seekResult; /* Result of previous sqlite3BtreeMoveto() or 0 |
| 17861 | | - ** if there have been no prior seeks on the cursor. */ |
| 17862 | | - /* NB: seekResult does not distinguish between "no seeks have ever occurred |
| 17863 | | - ** on this cursor" and "the most recent seek was an exact match". */ |
| 17864 | | - i64 seqCount; /* Sequence counter */ |
| 17865 | | - i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ |
| 17866 | | - VdbeCursor *pAltCursor; /* Associated index cursor from which to read */ |
| 17867 | | - int *aAltMap; /* Mapping from table to index column numbers */ |
| 17893 | + KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ |
| 17894 | + u32 iHdrOffset; /* Offset to next unparsed byte of the header */ |
| 17895 | + Pgno pgnoRoot; /* Root page of the open btree cursor */ |
| 17896 | + i16 nField; /* Number of fields in the header */ |
| 17897 | + u16 nHdrParsed; /* Number of header fields parsed so far */ |
| 17898 | + i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ |
| 17899 | + u32 *aOffset; /* Pointer to aType[nField] */ |
| 17900 | + const u8 *aRow; /* Data for the current row, if all on one page */ |
| 17901 | + u32 payloadSize; /* Total number of bytes in the record */ |
| 17902 | + u32 szRow; /* Byte available in aRow */ |
| 17868 | 17903 | #ifdef SQLITE_ENABLE_COLUMN_USED_MASK |
| 17869 | | - u64 maskUsed; /* Mask of columns used by this cursor */ |
| 17904 | + u64 maskUsed; /* Mask of columns used by this cursor */ |
| 17870 | 17905 | #endif |
| 17871 | 17906 | |
| 17872 | | - /* Cached information about the header for the data record that the |
| 17873 | | - ** cursor is currently pointing to. Only valid if cacheStatus matches |
| 17874 | | - ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of |
| 17875 | | - ** CACHE_STALE and so setting cacheStatus=CACHE_STALE guarantees that |
| 17876 | | - ** the cache is out of date. |
| 17877 | | - ** |
| 17878 | | - ** aRow might point to (ephemeral) data for the current row, or it might |
| 17879 | | - ** be NULL. |
| 17880 | | - */ |
| 17881 | | - u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ |
| 17882 | | - u32 payloadSize; /* Total number of bytes in the record */ |
| 17883 | | - u32 szRow; /* Byte available in aRow */ |
| 17884 | | - u32 iHdrOffset; /* Offset to next unparsed byte of the header */ |
| 17885 | | - const u8 *aRow; /* Data for the current row, if all on one page */ |
| 17886 | | - u32 *aOffset; /* Pointer to aType[nField] */ |
| 17887 | | - u32 aType[1]; /* Type values for all entries in the record */ |
| 17888 | 17907 | /* 2*nField extra array elements allocated for aType[], beyond the one |
| 17889 | 17908 | ** static element declared in the structure. nField total array slots for |
| 17890 | 17909 | ** aType[] and nField+1 array slots for aOffset[] */ |
| 17910 | + u32 aType[1]; /* Type values record decode. MUST BE LAST */ |
| 17891 | 17911 | }; |
| 17892 | 17912 | |
| 17893 | 17913 | |
| 17894 | 17914 | /* |
| 17895 | 17915 | ** A value for VdbeCursor.cacheStatus that means the cache is always invalid. |
| | @@ -18105,11 +18125,10 @@ |
| 18105 | 18125 | struct Vdbe { |
| 18106 | 18126 | sqlite3 *db; /* The database connection that owns this statement */ |
| 18107 | 18127 | Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ |
| 18108 | 18128 | Parse *pParse; /* Parsing context used to create this Vdbe */ |
| 18109 | 18129 | ynVar nVar; /* Number of entries in aVar[] */ |
| 18110 | | - ynVar nzVar; /* Number of entries in azVar[] */ |
| 18111 | 18130 | u32 magic; /* Magic number for sanity checking */ |
| 18112 | 18131 | int nMem; /* Number of memory locations currently allocated */ |
| 18113 | 18132 | int nCursor; /* Number of slots in apCsr[] */ |
| 18114 | 18133 | u32 cacheCtr; /* VdbeCursor row cache generation counter */ |
| 18115 | 18134 | int pc; /* The program counter */ |
| | @@ -18130,11 +18149,11 @@ |
| 18130 | 18149 | Mem *aColName; /* Column names to return */ |
| 18131 | 18150 | Mem *pResultSet; /* Pointer to an array of results */ |
| 18132 | 18151 | char *zErrMsg; /* Error message written here */ |
| 18133 | 18152 | VdbeCursor **apCsr; /* One element of this array for each open cursor */ |
| 18134 | 18153 | Mem *aVar; /* Values for the OP_Variable opcode. */ |
| 18135 | | - char **azVar; /* Name of variables */ |
| 18154 | + VList *pVList; /* Name of variables */ |
| 18136 | 18155 | #ifndef SQLITE_OMIT_TRACE |
| 18137 | 18156 | i64 startTime; /* Time when query started - used for profiling */ |
| 18138 | 18157 | #endif |
| 18139 | 18158 | int nOp; /* Number of instructions in the program */ |
| 18140 | 18159 | #ifdef SQLITE_DEBUG |
| | @@ -28879,10 +28898,113 @@ |
| 28879 | 28898 | assert( x<=60 ); |
| 28880 | 28899 | #endif |
| 28881 | 28900 | return x>=3 ? (n+8)<<(x-3) : (n+8)>>(3-x); |
| 28882 | 28901 | } |
| 28883 | 28902 | #endif /* defined SCANSTAT or STAT4 or ESTIMATED_ROWS */ |
| 28903 | + |
| 28904 | +/* |
| 28905 | +** Add a new name/number pair to a VList. This might require that the |
| 28906 | +** VList object be reallocated, so return the new VList. If an OOM |
| 28907 | +** error occurs, the original VList returned and the |
| 28908 | +** db->mallocFailed flag is set. |
| 28909 | +** |
| 28910 | +** A VList is really just an array of integers. To destroy a VList, |
| 28911 | +** simply pass it to sqlite3DbFree(). |
| 28912 | +** |
| 28913 | +** The first integer is the number of integers allocated for the whole |
| 28914 | +** VList. The second integer is the number of integers actually used. |
| 28915 | +** Each name/number pair is encoded by subsequent groups of 3 or more |
| 28916 | +** integers. |
| 28917 | +** |
| 28918 | +** Each name/number pair starts with two integers which are the numeric |
| 28919 | +** value for the pair and the size of the name/number pair, respectively. |
| 28920 | +** The text name overlays one or more following integers. The text name |
| 28921 | +** is always zero-terminated. |
| 28922 | +** |
| 28923 | +** Conceptually: |
| 28924 | +** |
| 28925 | +** struct VList { |
| 28926 | +** int nAlloc; // Number of allocated slots |
| 28927 | +** int nUsed; // Number of used slots |
| 28928 | +** struct VListEntry { |
| 28929 | +** int iValue; // Value for this entry |
| 28930 | +** int nSlot; // Slots used by this entry |
| 28931 | +** // ... variable name goes here |
| 28932 | +** } a[0]; |
| 28933 | +** } |
| 28934 | +** |
| 28935 | +** During code generation, pointers to the variable names within the |
| 28936 | +** VList are taken. When that happens, nAlloc is set to zero as an |
| 28937 | +** indication that the VList may never again be enlarged, since the |
| 28938 | +** accompanying realloc() would invalidate the pointers. |
| 28939 | +*/ |
| 28940 | +SQLITE_PRIVATE VList *sqlite3VListAdd( |
| 28941 | + sqlite3 *db, /* The database connection used for malloc() */ |
| 28942 | + VList *pIn, /* The input VList. Might be NULL */ |
| 28943 | + const char *zName, /* Name of symbol to add */ |
| 28944 | + int nName, /* Bytes of text in zName */ |
| 28945 | + int iVal /* Value to associate with zName */ |
| 28946 | +){ |
| 28947 | + int nInt; /* number of sizeof(int) objects needed for zName */ |
| 28948 | + char *z; /* Pointer to where zName will be stored */ |
| 28949 | + int i; /* Index in pIn[] where zName is stored */ |
| 28950 | + |
| 28951 | + nInt = nName/4 + 3; |
| 28952 | + assert( pIn==0 || pIn[0]>=3 ); /* Verify ok to add new elements */ |
| 28953 | + if( pIn==0 || pIn[1]+nInt > pIn[0] ){ |
| 28954 | + /* Enlarge the allocation */ |
| 28955 | + int nAlloc = (pIn ? pIn[0]*2 : 10) + nInt; |
| 28956 | + VList *pOut = sqlite3DbRealloc(db, pIn, nAlloc*sizeof(int)); |
| 28957 | + if( pOut==0 ) return pIn; |
| 28958 | + if( pIn==0 ) pOut[1] = 2; |
| 28959 | + pIn = pOut; |
| 28960 | + pIn[0] = nAlloc; |
| 28961 | + } |
| 28962 | + i = pIn[1]; |
| 28963 | + pIn[i] = iVal; |
| 28964 | + pIn[i+1] = nInt; |
| 28965 | + z = (char*)&pIn[i+2]; |
| 28966 | + pIn[1] = i+nInt; |
| 28967 | + assert( pIn[1]<=pIn[0] ); |
| 28968 | + memcpy(z, zName, nName); |
| 28969 | + z[nName] = 0; |
| 28970 | + return pIn; |
| 28971 | +} |
| 28972 | + |
| 28973 | +/* |
| 28974 | +** Return a pointer to the name of a variable in the given VList that |
| 28975 | +** has the value iVal. Or return a NULL if there is no such variable in |
| 28976 | +** the list |
| 28977 | +*/ |
| 28978 | +SQLITE_PRIVATE const char *sqlite3VListNumToName(VList *pIn, int iVal){ |
| 28979 | + int i, mx; |
| 28980 | + if( pIn==0 ) return 0; |
| 28981 | + mx = pIn[1]; |
| 28982 | + i = 2; |
| 28983 | + do{ |
| 28984 | + if( pIn[i]==iVal ) return (char*)&pIn[i+2]; |
| 28985 | + i += pIn[i+1]; |
| 28986 | + }while( i<mx ); |
| 28987 | + return 0; |
| 28988 | +} |
| 28989 | + |
| 28990 | +/* |
| 28991 | +** Return the number of the variable named zName, if it is in VList. |
| 28992 | +** or return 0 if there is no such variable. |
| 28993 | +*/ |
| 28994 | +SQLITE_PRIVATE int sqlite3VListNameToNum(VList *pIn, const char *zName, int nName){ |
| 28995 | + int i, mx; |
| 28996 | + if( pIn==0 ) return 0; |
| 28997 | + mx = pIn[1]; |
| 28998 | + i = 2; |
| 28999 | + do{ |
| 29000 | + const char *z = (const char*)&pIn[i+2]; |
| 29001 | + if( strncmp(z,zName,nName)==0 && z[nName]==0 ) return pIn[i]; |
| 29002 | + i += pIn[i+1]; |
| 29003 | + }while( i<mx ); |
| 29004 | + return 0; |
| 29005 | +} |
| 28884 | 29006 | |
| 28885 | 29007 | /************** End of util.c ************************************************/ |
| 28886 | 29008 | /************** Begin file hash.c ********************************************/ |
| 28887 | 29009 | /* |
| 28888 | 29010 | ** 2001 September 22 |
| | @@ -29235,11 +29357,11 @@ |
| 29235 | 29357 | /* 62 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), |
| 29236 | 29358 | /* 63 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), |
| 29237 | 29359 | /* 64 */ "Program" OpHelp(""), |
| 29238 | 29360 | /* 65 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), |
| 29239 | 29361 | /* 66 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), |
| 29240 | | - /* 67 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]-=P3, goto P2"), |
| 29362 | + /* 67 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), |
| 29241 | 29363 | /* 68 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), |
| 29242 | 29364 | /* 69 */ "IncrVacuum" OpHelp(""), |
| 29243 | 29365 | /* 70 */ "VNext" OpHelp(""), |
| 29244 | 29366 | /* 71 */ "Init" OpHelp("Start at P2"), |
| 29245 | 29367 | /* 72 */ "Return" OpHelp(""), |
| | @@ -43847,11 +43969,11 @@ |
| 43847 | 43969 | */ |
| 43848 | 43970 | #if SQLITE_DEBUG |
| 43849 | 43971 | SQLITE_PRIVATE int sqlite3PcachePageSanity(PgHdr *pPg){ |
| 43850 | 43972 | PCache *pCache; |
| 43851 | 43973 | assert( pPg!=0 ); |
| 43852 | | - assert( pPg->pgno>0 ); /* Page number is 1 or more */ |
| 43974 | + assert( pPg->pgno>0 || pPg->pPager==0 ); /* Page number is 1 or more */ |
| 43853 | 43975 | pCache = pPg->pCache; |
| 43854 | 43976 | assert( pCache!=0 ); /* Every page has an associated PCache */ |
| 43855 | 43977 | if( pPg->flags & PGHDR_CLEAN ){ |
| 43856 | 43978 | assert( (pPg->flags & PGHDR_DIRTY)==0 );/* Cannot be both CLEAN and DIRTY */ |
| 43857 | 43979 | assert( pCache->pDirty!=pPg ); /* CLEAN pages not on dirty list */ |
| | @@ -44023,10 +44145,16 @@ |
| 44023 | 44145 | /* |
| 44024 | 44146 | ** Create a new PCache object. Storage space to hold the object |
| 44025 | 44147 | ** has already been allocated and is passed in as the p pointer. |
| 44026 | 44148 | ** The caller discovers how much space needs to be allocated by |
| 44027 | 44149 | ** calling sqlite3PcacheSize(). |
| 44150 | +** |
| 44151 | +** szExtra is some extra space allocated for each page. The first |
| 44152 | +** 8 bytes of the extra space will be zeroed as the page is allocated, |
| 44153 | +** but remaining content will be uninitialized. Though it is opaque |
| 44154 | +** to this module, the extra space really ends up being the MemPage |
| 44155 | +** structure in the pager. |
| 44028 | 44156 | */ |
| 44029 | 44157 | SQLITE_PRIVATE int sqlite3PcacheOpen( |
| 44030 | 44158 | int szPage, /* Size of every page */ |
| 44031 | 44159 | int szExtra, /* Extra space associated with each page */ |
| 44032 | 44160 | int bPurgeable, /* True if pages are on backing store */ |
| | @@ -44035,10 +44163,11 @@ |
| 44035 | 44163 | PCache *p /* Preallocated space for the PCache */ |
| 44036 | 44164 | ){ |
| 44037 | 44165 | memset(p, 0, sizeof(PCache)); |
| 44038 | 44166 | p->szPage = 1; |
| 44039 | 44167 | p->szExtra = szExtra; |
| 44168 | + assert( szExtra>=8 ); /* First 8 bytes will be zeroed */ |
| 44040 | 44169 | p->bPurgeable = bPurgeable; |
| 44041 | 44170 | p->eCreate = 2; |
| 44042 | 44171 | p->xStress = xStress; |
| 44043 | 44172 | p->pStress = pStress; |
| 44044 | 44173 | p->szCache = 100; |
| | @@ -44104,11 +44233,10 @@ |
| 44104 | 44233 | sqlite3_pcache_page *pRes; |
| 44105 | 44234 | |
| 44106 | 44235 | assert( pCache!=0 ); |
| 44107 | 44236 | assert( pCache->pCache!=0 ); |
| 44108 | 44237 | assert( createFlag==3 || createFlag==0 ); |
| 44109 | | - assert( pgno>0 ); |
| 44110 | 44238 | assert( pCache->eCreate==((pCache->bPurgeable && pCache->pDirty) ? 1 : 2) ); |
| 44111 | 44239 | |
| 44112 | 44240 | /* eCreate defines what to do if the page does not exist. |
| 44113 | 44241 | ** 0 Do not allocate a new page. (createFlag==0) |
| 44114 | 44242 | ** 1 Allocate a new page if doing so is inexpensive. |
| | @@ -44204,11 +44332,11 @@ |
| 44204 | 44332 | assert( pPgHdr->pPage==0 ); |
| 44205 | 44333 | memset(&pPgHdr->pDirty, 0, sizeof(PgHdr) - offsetof(PgHdr,pDirty)); |
| 44206 | 44334 | pPgHdr->pPage = pPage; |
| 44207 | 44335 | pPgHdr->pData = pPage->pBuf; |
| 44208 | 44336 | pPgHdr->pExtra = (void *)&pPgHdr[1]; |
| 44209 | | - memset(pPgHdr->pExtra, 0, pCache->szExtra); |
| 44337 | + memset(pPgHdr->pExtra, 0, 8); |
| 44210 | 44338 | pPgHdr->pCache = pCache; |
| 44211 | 44339 | pPgHdr->pgno = pgno; |
| 44212 | 44340 | pPgHdr->flags = PGHDR_CLEAN; |
| 44213 | 44341 | return sqlite3PcacheFetchFinish(pCache,pgno,pPage); |
| 44214 | 44342 | } |
| | @@ -47221,10 +47349,11 @@ |
| 47221 | 47349 | int aStat[3]; /* Total cache hits, misses and writes */ |
| 47222 | 47350 | #ifdef SQLITE_TEST |
| 47223 | 47351 | int nRead; /* Database pages read */ |
| 47224 | 47352 | #endif |
| 47225 | 47353 | void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */ |
| 47354 | + int (*xGet)(Pager*,Pgno,DbPage**,int); /* Routine to fetch a patch */ |
| 47226 | 47355 | #ifdef SQLITE_HAS_CODEC |
| 47227 | 47356 | void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */ |
| 47228 | 47357 | void (*xCodecSizeChng)(void*,int,int); /* Notify of page size changes */ |
| 47229 | 47358 | void (*xCodecFree)(void*); /* Destructor for the codec */ |
| 47230 | 47359 | void *pCodec; /* First argument to xCodec... methods */ |
| | @@ -47546,10 +47675,37 @@ |
| 47546 | 47675 | ); |
| 47547 | 47676 | |
| 47548 | 47677 | return zRet; |
| 47549 | 47678 | } |
| 47550 | 47679 | #endif |
| 47680 | + |
| 47681 | +/* Forward references to the various page getters */ |
| 47682 | +static int getPageNormal(Pager*,Pgno,DbPage**,int); |
| 47683 | +static int getPageError(Pager*,Pgno,DbPage**,int); |
| 47684 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 47685 | +static int getPageMMap(Pager*,Pgno,DbPage**,int); |
| 47686 | +#endif |
| 47687 | + |
| 47688 | +/* |
| 47689 | +** Set the Pager.xGet method for the appropriate routine used to fetch |
| 47690 | +** content from the pager. |
| 47691 | +*/ |
| 47692 | +static void setGetterMethod(Pager *pPager){ |
| 47693 | + if( pPager->errCode ){ |
| 47694 | + pPager->xGet = getPageError; |
| 47695 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 47696 | + }else if( USEFETCH(pPager) |
| 47697 | +#ifdef SQLITE_HAS_CODEC |
| 47698 | + && pPager->xCodec==0 |
| 47699 | +#endif |
| 47700 | + ){ |
| 47701 | + pPager->xGet = getPageMMap; |
| 47702 | +#endif /* SQLITE_MAX_MMAP_SIZE>0 */ |
| 47703 | + }else{ |
| 47704 | + pPager->xGet = getPageNormal; |
| 47705 | + } |
| 47706 | +} |
| 47551 | 47707 | |
| 47552 | 47708 | /* |
| 47553 | 47709 | ** Return true if it is necessary to write page *pPg into the sub-journal. |
| 47554 | 47710 | ** A page needs to be written into the sub-journal if there exists one |
| 47555 | 47711 | ** or more open savepoints for which: |
| | @@ -48361,10 +48517,11 @@ |
| 48361 | 48517 | }else{ |
| 48362 | 48518 | pPager->eState = (isOpen(pPager->jfd) ? PAGER_OPEN : PAGER_READER); |
| 48363 | 48519 | } |
| 48364 | 48520 | if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0); |
| 48365 | 48521 | pPager->errCode = SQLITE_OK; |
| 48522 | + setGetterMethod(pPager); |
| 48366 | 48523 | } |
| 48367 | 48524 | |
| 48368 | 48525 | pPager->journalOff = 0; |
| 48369 | 48526 | pPager->journalHdr = 0; |
| 48370 | 48527 | pPager->setMaster = 0; |
| | @@ -48398,10 +48555,11 @@ |
| 48398 | 48555 | (pPager->errCode & 0xff)==SQLITE_IOERR |
| 48399 | 48556 | ); |
| 48400 | 48557 | if( rc2==SQLITE_FULL || rc2==SQLITE_IOERR ){ |
| 48401 | 48558 | pPager->errCode = rc; |
| 48402 | 48559 | pPager->eState = PAGER_ERROR; |
| 48560 | + setGetterMethod(pPager); |
| 48403 | 48561 | } |
| 48404 | 48562 | return rc; |
| 48405 | 48563 | } |
| 48406 | 48564 | |
| 48407 | 48565 | static int pager_truncate(Pager *pPager, Pgno nPage); |
| | @@ -48566,11 +48724,11 @@ |
| 48566 | 48724 | |
| 48567 | 48725 | sqlite3BitvecDestroy(pPager->pInJournal); |
| 48568 | 48726 | pPager->pInJournal = 0; |
| 48569 | 48727 | pPager->nRec = 0; |
| 48570 | 48728 | if( rc==SQLITE_OK ){ |
| 48571 | | - if( pagerFlushOnCommit(pPager, bCommit) ){ |
| 48729 | + if( MEMDB || pagerFlushOnCommit(pPager, bCommit) ){ |
| 48572 | 48730 | sqlite3PcacheCleanAll(pPager->pPCache); |
| 48573 | 48731 | }else{ |
| 48574 | 48732 | sqlite3PcacheClearWritable(pPager->pPCache); |
| 48575 | 48733 | } |
| 48576 | 48734 | sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize); |
| | @@ -49965,10 +50123,11 @@ |
| 49965 | 50123 | sqlite3_file *fd = pPager->fd; |
| 49966 | 50124 | if( isOpen(fd) && fd->pMethods->iVersion>=3 ){ |
| 49967 | 50125 | sqlite3_int64 sz; |
| 49968 | 50126 | sz = pPager->szMmap; |
| 49969 | 50127 | pPager->bUseFetch = (sz>0); |
| 50128 | + setGetterMethod(pPager); |
| 49970 | 50129 | sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz); |
| 49971 | 50130 | } |
| 49972 | 50131 | #endif |
| 49973 | 50132 | } |
| 49974 | 50133 | |
| | @@ -50483,11 +50642,12 @@ |
| 50483 | 50642 | |
| 50484 | 50643 | if( pPager->pMmapFreelist ){ |
| 50485 | 50644 | *ppPage = p = pPager->pMmapFreelist; |
| 50486 | 50645 | pPager->pMmapFreelist = p->pDirty; |
| 50487 | 50646 | p->pDirty = 0; |
| 50488 | | - memset(p->pExtra, 0, pPager->nExtra); |
| 50647 | + assert( pPager->nExtra>=8 ); |
| 50648 | + memset(p->pExtra, 0, 8); |
| 50489 | 50649 | }else{ |
| 50490 | 50650 | *ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra); |
| 50491 | 50651 | if( p==0 ){ |
| 50492 | 50652 | sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData); |
| 50493 | 50653 | return SQLITE_NOMEM_BKPT; |
| | @@ -51083,11 +51243,13 @@ |
| 51083 | 51243 | ** all information is held in cache. It is never written to disk. |
| 51084 | 51244 | ** This can be used to implement an in-memory database. |
| 51085 | 51245 | ** |
| 51086 | 51246 | ** The nExtra parameter specifies the number of bytes of space allocated |
| 51087 | 51247 | ** along with each page reference. This space is available to the user |
| 51088 | | -** via the sqlite3PagerGetExtra() API. |
| 51248 | +** via the sqlite3PagerGetExtra() API. When a new page is allocated, the |
| 51249 | +** first 8 bytes of this space are zeroed but the remainder is uninitialized. |
| 51250 | +** (The extra space is used by btree as the MemPage object.) |
| 51089 | 51251 | ** |
| 51090 | 51252 | ** The flags argument is used to specify properties that affect the |
| 51091 | 51253 | ** operation of the pager. It should be passed some bitwise combination |
| 51092 | 51254 | ** of the PAGER_* flags. |
| 51093 | 51255 | ** |
| | @@ -51313,12 +51475,12 @@ |
| 51313 | 51475 | testcase( rc!=SQLITE_OK ); |
| 51314 | 51476 | } |
| 51315 | 51477 | |
| 51316 | 51478 | /* Initialize the PCache object. */ |
| 51317 | 51479 | if( rc==SQLITE_OK ){ |
| 51318 | | - assert( nExtra<1000 ); |
| 51319 | 51480 | nExtra = ROUND8(nExtra); |
| 51481 | + assert( nExtra>=8 && nExtra<1000 ); |
| 51320 | 51482 | rc = sqlite3PcacheOpen(szPageDflt, nExtra, !memDb, |
| 51321 | 51483 | !memDb?pagerStress:0, (void *)pPager, pPager->pPCache); |
| 51322 | 51484 | } |
| 51323 | 51485 | |
| 51324 | 51486 | /* If an error occurred above, free the Pager structure and close the file. |
| | @@ -51379,10 +51541,11 @@ |
| 51379 | 51541 | pPager->journalMode = PAGER_JOURNALMODE_MEMORY; |
| 51380 | 51542 | } |
| 51381 | 51543 | /* pPager->xBusyHandler = 0; */ |
| 51382 | 51544 | /* pPager->pBusyHandlerArg = 0; */ |
| 51383 | 51545 | pPager->xReiniter = xReinit; |
| 51546 | + setGetterMethod(pPager); |
| 51384 | 51547 | /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */ |
| 51385 | 51548 | /* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */ |
| 51386 | 51549 | |
| 51387 | 51550 | *ppPager = pPager; |
| 51388 | 51551 | return SQLITE_OK; |
| | @@ -51792,14 +51955,21 @@ |
| 51792 | 51955 | pagerUnlockAndRollback(pPager); |
| 51793 | 51956 | } |
| 51794 | 51957 | } |
| 51795 | 51958 | |
| 51796 | 51959 | /* |
| 51797 | | -** Acquire a reference to page number pgno in pager pPager (a page |
| 51798 | | -** reference has type DbPage*). If the requested reference is |
| 51960 | +** The page getter methods each try to acquire a reference to a |
| 51961 | +** page with page number pgno. If the requested reference is |
| 51799 | 51962 | ** successfully obtained, it is copied to *ppPage and SQLITE_OK returned. |
| 51800 | 51963 | ** |
| 51964 | +** There are different implementations of the getter method depending |
| 51965 | +** on the current state of the pager. |
| 51966 | +** |
| 51967 | +** getPageNormal() -- The normal getter |
| 51968 | +** getPageError() -- Used if the pager is in an error state |
| 51969 | +** getPageMmap() -- Used if memory-mapped I/O is enabled |
| 51970 | +** |
| 51801 | 51971 | ** If the requested page is already in the cache, it is returned. |
| 51802 | 51972 | ** Otherwise, a new page object is allocated and populated with data |
| 51803 | 51973 | ** read from the database file. In some cases, the pcache module may |
| 51804 | 51974 | ** choose not to allocate a new page object and may reuse an existing |
| 51805 | 51975 | ** object with no outstanding references. |
| | @@ -51807,27 +51977,27 @@ |
| 51807 | 51977 | ** The extra data appended to a page is always initialized to zeros the |
| 51808 | 51978 | ** first time a page is loaded into memory. If the page requested is |
| 51809 | 51979 | ** already in the cache when this function is called, then the extra |
| 51810 | 51980 | ** data is left as it was when the page object was last used. |
| 51811 | 51981 | ** |
| 51812 | | -** If the database image is smaller than the requested page or if a |
| 51813 | | -** non-zero value is passed as the noContent parameter and the |
| 51982 | +** If the database image is smaller than the requested page or if |
| 51983 | +** the flags parameter contains the PAGER_GET_NOCONTENT bit and the |
| 51814 | 51984 | ** requested page is not already stored in the cache, then no |
| 51815 | 51985 | ** actual disk read occurs. In this case the memory image of the |
| 51816 | 51986 | ** page is initialized to all zeros. |
| 51817 | 51987 | ** |
| 51818 | | -** If noContent is true, it means that we do not care about the contents |
| 51819 | | -** of the page. This occurs in two scenarios: |
| 51988 | +** If PAGER_GET_NOCONTENT is true, it means that we do not care about |
| 51989 | +** the contents of the page. This occurs in two scenarios: |
| 51820 | 51990 | ** |
| 51821 | 51991 | ** a) When reading a free-list leaf page from the database, and |
| 51822 | 51992 | ** |
| 51823 | 51993 | ** b) When a savepoint is being rolled back and we need to load |
| 51824 | 51994 | ** a new page into the cache to be filled with the data read |
| 51825 | 51995 | ** from the savepoint journal. |
| 51826 | 51996 | ** |
| 51827 | | -** If noContent is true, then the data returned is zeroed instead of |
| 51828 | | -** being read from the database. Additionally, the bits corresponding |
| 51997 | +** If PAGER_GET_NOCONTENT is true, then the data returned is zeroed instead |
| 51998 | +** of being read from the database. Additionally, the bits corresponding |
| 51829 | 51999 | ** to pgno in Pager.pInJournal (bitvec of pages already written to the |
| 51830 | 52000 | ** journal file) and the PagerSavepoint.pInSavepoint bitvecs of any open |
| 51831 | 52001 | ** savepoints are set. This means if the page is made writable at any |
| 51832 | 52002 | ** point in the future, using a call to sqlite3PagerWrite(), its contents |
| 51833 | 52003 | ** will not be journaled. This saves IO. |
| | @@ -51841,129 +52011,63 @@ |
| 51841 | 52011 | ** just returns 0. This routine acquires a read-lock the first time it |
| 51842 | 52012 | ** has to go to disk, and could also playback an old journal if necessary. |
| 51843 | 52013 | ** Since Lookup() never goes to disk, it never has to deal with locks |
| 51844 | 52014 | ** or journal files. |
| 51845 | 52015 | */ |
| 51846 | | -SQLITE_PRIVATE int sqlite3PagerGet( |
| 52016 | +static int getPageNormal( |
| 51847 | 52017 | Pager *pPager, /* The pager open on the database file */ |
| 51848 | 52018 | Pgno pgno, /* Page number to fetch */ |
| 51849 | 52019 | DbPage **ppPage, /* Write a pointer to the page here */ |
| 51850 | 52020 | int flags /* PAGER_GET_XXX flags */ |
| 51851 | 52021 | ){ |
| 51852 | 52022 | int rc = SQLITE_OK; |
| 51853 | | - PgHdr *pPg = 0; |
| 51854 | | - u32 iFrame = 0; /* Frame to read from WAL file */ |
| 51855 | | - const int noContent = (flags & PAGER_GET_NOCONTENT); |
| 51856 | | - |
| 51857 | | - /* It is acceptable to use a read-only (mmap) page for any page except |
| 51858 | | - ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY |
| 51859 | | - ** flag was specified by the caller. And so long as the db is not a |
| 51860 | | - ** temporary or in-memory database. */ |
| 51861 | | - const int bMmapOk = (pgno>1 && USEFETCH(pPager) |
| 51862 | | - && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY)) |
| 51863 | | -#ifdef SQLITE_HAS_CODEC |
| 51864 | | - && pPager->xCodec==0 |
| 51865 | | -#endif |
| 51866 | | - ); |
| 51867 | | - |
| 51868 | | - /* Optimization note: Adding the "pgno<=1" term before "pgno==0" here |
| 51869 | | - ** allows the compiler optimizer to reuse the results of the "pgno>1" |
| 51870 | | - ** test in the previous statement, and avoid testing pgno==0 in the |
| 51871 | | - ** common case where pgno is large. */ |
| 51872 | | - if( pgno<=1 && pgno==0 ){ |
| 51873 | | - return SQLITE_CORRUPT_BKPT; |
| 51874 | | - } |
| 52023 | + PgHdr *pPg; |
| 52024 | + u8 noContent; /* True if PAGER_GET_NOCONTENT is set */ |
| 52025 | + sqlite3_pcache_page *pBase; |
| 52026 | + |
| 52027 | + assert( pPager->errCode==SQLITE_OK ); |
| 51875 | 52028 | assert( pPager->eState>=PAGER_READER ); |
| 51876 | 52029 | assert( assert_pager_state(pPager) ); |
| 51877 | | - assert( noContent==0 || bMmapOk==0 ); |
| 51878 | | - |
| 51879 | 52030 | assert( pPager->hasHeldSharedLock==1 ); |
| 51880 | 52031 | |
| 51881 | | - /* If the pager is in the error state, return an error immediately. |
| 51882 | | - ** Otherwise, request the page from the PCache layer. */ |
| 51883 | | - if( pPager->errCode!=SQLITE_OK ){ |
| 51884 | | - rc = pPager->errCode; |
| 51885 | | - }else{ |
| 51886 | | - if( bMmapOk && pagerUseWal(pPager) ){ |
| 51887 | | - rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); |
| 51888 | | - if( rc!=SQLITE_OK ) goto pager_acquire_err; |
| 51889 | | - } |
| 51890 | | - |
| 51891 | | - if( bMmapOk && iFrame==0 ){ |
| 51892 | | - void *pData = 0; |
| 51893 | | - |
| 51894 | | - rc = sqlite3OsFetch(pPager->fd, |
| 51895 | | - (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData |
| 51896 | | - ); |
| 51897 | | - |
| 51898 | | - if( rc==SQLITE_OK && pData ){ |
| 51899 | | - if( pPager->eState>PAGER_READER || pPager->tempFile ){ |
| 51900 | | - pPg = sqlite3PagerLookup(pPager, pgno); |
| 51901 | | - } |
| 51902 | | - if( pPg==0 ){ |
| 51903 | | - rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg); |
| 51904 | | - }else{ |
| 51905 | | - sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData); |
| 51906 | | - } |
| 51907 | | - if( pPg ){ |
| 51908 | | - assert( rc==SQLITE_OK ); |
| 51909 | | - *ppPage = pPg; |
| 51910 | | - return SQLITE_OK; |
| 51911 | | - } |
| 51912 | | - } |
| 51913 | | - if( rc!=SQLITE_OK ){ |
| 51914 | | - goto pager_acquire_err; |
| 51915 | | - } |
| 51916 | | - } |
| 51917 | | - |
| 51918 | | - { |
| 51919 | | - sqlite3_pcache_page *pBase; |
| 51920 | | - pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3); |
| 51921 | | - if( pBase==0 ){ |
| 51922 | | - rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase); |
| 51923 | | - if( rc!=SQLITE_OK ) goto pager_acquire_err; |
| 51924 | | - if( pBase==0 ){ |
| 51925 | | - pPg = *ppPage = 0; |
| 51926 | | - rc = SQLITE_NOMEM_BKPT; |
| 51927 | | - goto pager_acquire_err; |
| 51928 | | - } |
| 51929 | | - } |
| 51930 | | - pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase); |
| 51931 | | - assert( pPg!=0 ); |
| 51932 | | - } |
| 51933 | | - } |
| 51934 | | - |
| 51935 | | - if( rc!=SQLITE_OK ){ |
| 51936 | | - /* Either the call to sqlite3PcacheFetch() returned an error or the |
| 51937 | | - ** pager was already in the error-state when this function was called. |
| 51938 | | - ** Set pPg to 0 and jump to the exception handler. */ |
| 52032 | + pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3); |
| 52033 | + if( pBase==0 ){ |
| 51939 | 52034 | pPg = 0; |
| 51940 | | - goto pager_acquire_err; |
| 52035 | + rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase); |
| 52036 | + if( rc!=SQLITE_OK ) goto pager_acquire_err; |
| 52037 | + if( pBase==0 ){ |
| 52038 | + rc = SQLITE_NOMEM_BKPT; |
| 52039 | + goto pager_acquire_err; |
| 52040 | + } |
| 51941 | 52041 | } |
| 52042 | + pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase); |
| 51942 | 52043 | assert( pPg==(*ppPage) ); |
| 51943 | 52044 | assert( pPg->pgno==pgno ); |
| 51944 | 52045 | assert( pPg->pPager==pPager || pPg->pPager==0 ); |
| 51945 | 52046 | |
| 52047 | + noContent = (flags & PAGER_GET_NOCONTENT)!=0; |
| 51946 | 52048 | if( pPg->pPager && !noContent ){ |
| 51947 | 52049 | /* In this case the pcache already contains an initialized copy of |
| 51948 | 52050 | ** the page. Return without further ado. */ |
| 51949 | 52051 | assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) ); |
| 51950 | 52052 | pPager->aStat[PAGER_STAT_HIT]++; |
| 51951 | 52053 | return SQLITE_OK; |
| 51952 | 52054 | |
| 51953 | 52055 | }else{ |
| 51954 | 52056 | /* The pager cache has created a new page. Its content needs to |
| 51955 | | - ** be initialized. */ |
| 51956 | | - |
| 51957 | | - pPg->pPager = pPager; |
| 51958 | | - |
| 51959 | | - /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page |
| 51960 | | - ** number greater than this, or the unused locking-page, is requested. */ |
| 51961 | | - if( pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){ |
| 52057 | + ** be initialized. But first some error checks: |
| 52058 | + ** |
| 52059 | + ** (1) Minimum page number is 1 |
| 52060 | + ** (2) The maximum page number is 2^31 |
| 52061 | + ** (3) Never try to fetch the locking page |
| 52062 | + */ |
| 52063 | + if( pgno==0 || pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){ |
| 51962 | 52064 | rc = SQLITE_CORRUPT_BKPT; |
| 51963 | 52065 | goto pager_acquire_err; |
| 51964 | 52066 | } |
| 52067 | + |
| 52068 | + pPg->pPager = pPager; |
| 51965 | 52069 | |
| 51966 | 52070 | assert( !isOpen(pPager->fd) || !MEMDB ); |
| 51967 | 52071 | if( !isOpen(pPager->fd) || pPager->dbSize<pgno || noContent ){ |
| 51968 | 52072 | if( pgno>pPager->mxPgno ){ |
| 51969 | 52073 | rc = SQLITE_FULL; |
| | @@ -51986,11 +52090,12 @@ |
| 51986 | 52090 | sqlite3EndBenignMalloc(); |
| 51987 | 52091 | } |
| 51988 | 52092 | memset(pPg->pData, 0, pPager->pageSize); |
| 51989 | 52093 | IOTRACE(("ZERO %p %d\n", pPager, pgno)); |
| 51990 | 52094 | }else{ |
| 51991 | | - if( pagerUseWal(pPager) && bMmapOk==0 ){ |
| 52095 | + u32 iFrame = 0; /* Frame to read from WAL file */ |
| 52096 | + if( pagerUseWal(pPager) ){ |
| 51992 | 52097 | rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); |
| 51993 | 52098 | if( rc!=SQLITE_OK ) goto pager_acquire_err; |
| 51994 | 52099 | } |
| 51995 | 52100 | assert( pPg->pPager==pPager ); |
| 51996 | 52101 | pPager->aStat[PAGER_STAT_MISS]++; |
| | @@ -51999,22 +52104,119 @@ |
| 51999 | 52104 | goto pager_acquire_err; |
| 52000 | 52105 | } |
| 52001 | 52106 | } |
| 52002 | 52107 | pager_set_pagehash(pPg); |
| 52003 | 52108 | } |
| 52004 | | - |
| 52005 | 52109 | return SQLITE_OK; |
| 52006 | 52110 | |
| 52007 | 52111 | pager_acquire_err: |
| 52008 | 52112 | assert( rc!=SQLITE_OK ); |
| 52009 | 52113 | if( pPg ){ |
| 52010 | 52114 | sqlite3PcacheDrop(pPg); |
| 52011 | 52115 | } |
| 52012 | 52116 | pagerUnlockIfUnused(pPager); |
| 52117 | + *ppPage = 0; |
| 52118 | + return rc; |
| 52119 | +} |
| 52013 | 52120 | |
| 52121 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 52122 | +/* The page getter for when memory-mapped I/O is enabled */ |
| 52123 | +static int getPageMMap( |
| 52124 | + Pager *pPager, /* The pager open on the database file */ |
| 52125 | + Pgno pgno, /* Page number to fetch */ |
| 52126 | + DbPage **ppPage, /* Write a pointer to the page here */ |
| 52127 | + int flags /* PAGER_GET_XXX flags */ |
| 52128 | +){ |
| 52129 | + int rc = SQLITE_OK; |
| 52130 | + PgHdr *pPg = 0; |
| 52131 | + u32 iFrame = 0; /* Frame to read from WAL file */ |
| 52132 | + |
| 52133 | + /* It is acceptable to use a read-only (mmap) page for any page except |
| 52134 | + ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY |
| 52135 | + ** flag was specified by the caller. And so long as the db is not a |
| 52136 | + ** temporary or in-memory database. */ |
| 52137 | + const int bMmapOk = (pgno>1 |
| 52138 | + && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY)) |
| 52139 | + ); |
| 52140 | + |
| 52141 | + assert( USEFETCH(pPager) ); |
| 52142 | +#ifdef SQLITE_HAS_CODEC |
| 52143 | + assert( pPager->xCodec==0 ); |
| 52144 | +#endif |
| 52145 | + |
| 52146 | + /* Optimization note: Adding the "pgno<=1" term before "pgno==0" here |
| 52147 | + ** allows the compiler optimizer to reuse the results of the "pgno>1" |
| 52148 | + ** test in the previous statement, and avoid testing pgno==0 in the |
| 52149 | + ** common case where pgno is large. */ |
| 52150 | + if( pgno<=1 && pgno==0 ){ |
| 52151 | + return SQLITE_CORRUPT_BKPT; |
| 52152 | + } |
| 52153 | + assert( pPager->eState>=PAGER_READER ); |
| 52154 | + assert( assert_pager_state(pPager) ); |
| 52155 | + assert( pPager->hasHeldSharedLock==1 ); |
| 52156 | + assert( pPager->errCode==SQLITE_OK ); |
| 52157 | + |
| 52158 | + if( bMmapOk && pagerUseWal(pPager) ){ |
| 52159 | + rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); |
| 52160 | + if( rc!=SQLITE_OK ){ |
| 52161 | + *ppPage = 0; |
| 52162 | + return rc; |
| 52163 | + } |
| 52164 | + } |
| 52165 | + if( bMmapOk && iFrame==0 ){ |
| 52166 | + void *pData = 0; |
| 52167 | + rc = sqlite3OsFetch(pPager->fd, |
| 52168 | + (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData |
| 52169 | + ); |
| 52170 | + if( rc==SQLITE_OK && pData ){ |
| 52171 | + if( pPager->eState>PAGER_READER || pPager->tempFile ){ |
| 52172 | + pPg = sqlite3PagerLookup(pPager, pgno); |
| 52173 | + } |
| 52174 | + if( pPg==0 ){ |
| 52175 | + rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg); |
| 52176 | + }else{ |
| 52177 | + sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData); |
| 52178 | + } |
| 52179 | + if( pPg ){ |
| 52180 | + assert( rc==SQLITE_OK ); |
| 52181 | + *ppPage = pPg; |
| 52182 | + return SQLITE_OK; |
| 52183 | + } |
| 52184 | + } |
| 52185 | + if( rc!=SQLITE_OK ){ |
| 52186 | + *ppPage = 0; |
| 52187 | + return rc; |
| 52188 | + } |
| 52189 | + } |
| 52190 | + return getPageNormal(pPager, pgno, ppPage, flags); |
| 52191 | +} |
| 52192 | +#endif /* SQLITE_MAX_MMAP_SIZE>0 */ |
| 52193 | + |
| 52194 | +/* The page getter method for when the pager is an error state */ |
| 52195 | +static int getPageError( |
| 52196 | + Pager *pPager, /* The pager open on the database file */ |
| 52197 | + Pgno pgno, /* Page number to fetch */ |
| 52198 | + DbPage **ppPage, /* Write a pointer to the page here */ |
| 52199 | + int flags /* PAGER_GET_XXX flags */ |
| 52200 | +){ |
| 52201 | + UNUSED_PARAMETER(pgno); |
| 52202 | + UNUSED_PARAMETER(flags); |
| 52203 | + assert( pPager->errCode!=SQLITE_OK ); |
| 52014 | 52204 | *ppPage = 0; |
| 52015 | | - return rc; |
| 52205 | + return pPager->errCode; |
| 52206 | +} |
| 52207 | + |
| 52208 | + |
| 52209 | +/* Dispatch all page fetch requests to the appropriate getter method. |
| 52210 | +*/ |
| 52211 | +SQLITE_PRIVATE int sqlite3PagerGet( |
| 52212 | + Pager *pPager, /* The pager open on the database file */ |
| 52213 | + Pgno pgno, /* Page number to fetch */ |
| 52214 | + DbPage **ppPage, /* Write a pointer to the page here */ |
| 52215 | + int flags /* PAGER_GET_XXX flags */ |
| 52216 | +){ |
| 52217 | + return pPager->xGet(pPager, pgno, ppPage, flags); |
| 52016 | 52218 | } |
| 52017 | 52219 | |
| 52018 | 52220 | /* |
| 52019 | 52221 | ** Acquire a page if it is already in the in-memory cache. Do |
| 52020 | 52222 | ** not read the page from disk. Return a pointer to the page, |
| | @@ -52486,15 +52688,15 @@ |
| 52486 | 52688 | SQLITE_PRIVATE int sqlite3PagerWrite(PgHdr *pPg){ |
| 52487 | 52689 | Pager *pPager = pPg->pPager; |
| 52488 | 52690 | assert( (pPg->flags & PGHDR_MMAP)==0 ); |
| 52489 | 52691 | assert( pPager->eState>=PAGER_WRITER_LOCKED ); |
| 52490 | 52692 | assert( assert_pager_state(pPager) ); |
| 52491 | | - if( pPager->errCode ){ |
| 52492 | | - return pPager->errCode; |
| 52493 | | - }else if( (pPg->flags & PGHDR_WRITEABLE)!=0 && pPager->dbSize>=pPg->pgno ){ |
| 52693 | + if( (pPg->flags & PGHDR_WRITEABLE)!=0 && pPager->dbSize>=pPg->pgno ){ |
| 52494 | 52694 | if( pPager->nSavepoint ) return subjournalPageIfRequired(pPg); |
| 52495 | 52695 | return SQLITE_OK; |
| 52696 | + }else if( pPager->errCode ){ |
| 52697 | + return pPager->errCode; |
| 52496 | 52698 | }else if( pPager->sectorSize > (u32)pPager->pageSize ){ |
| 52497 | 52699 | assert( pPager->tempFile==0 ); |
| 52498 | 52700 | return pagerWriteLargeSector(pPg); |
| 52499 | 52701 | }else{ |
| 52500 | 52702 | return pager_write(pPg); |
| | @@ -52985,10 +53187,11 @@ |
| 52985 | 53187 | ** state to indicate that the contents of the cache may not be trusted. |
| 52986 | 53188 | ** Any active readers will get SQLITE_ABORT. |
| 52987 | 53189 | */ |
| 52988 | 53190 | pPager->errCode = SQLITE_ABORT; |
| 52989 | 53191 | pPager->eState = PAGER_ERROR; |
| 53192 | + setGetterMethod(pPager); |
| 52990 | 53193 | return rc; |
| 52991 | 53194 | } |
| 52992 | 53195 | }else{ |
| 52993 | 53196 | rc = pager_playback(pPager, 0); |
| 52994 | 53197 | } |
| | @@ -53246,10 +53449,11 @@ |
| 53246 | 53449 | pPager->journalMode==PAGER_JOURNALMODE_OFF |
| 53247 | 53450 | && pPager->eState>=PAGER_WRITER_CACHEMOD |
| 53248 | 53451 | ){ |
| 53249 | 53452 | pPager->errCode = SQLITE_ABORT; |
| 53250 | 53453 | pPager->eState = PAGER_ERROR; |
| 53454 | + setGetterMethod(pPager); |
| 53251 | 53455 | } |
| 53252 | 53456 | #endif |
| 53253 | 53457 | } |
| 53254 | 53458 | |
| 53255 | 53459 | return rc; |
| | @@ -53318,10 +53522,11 @@ |
| 53318 | 53522 | if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec); |
| 53319 | 53523 | pPager->xCodec = pPager->memDb ? 0 : xCodec; |
| 53320 | 53524 | pPager->xCodecSizeChng = xCodecSizeChng; |
| 53321 | 53525 | pPager->xCodecFree = xCodecFree; |
| 53322 | 53526 | pPager->pCodec = pCodec; |
| 53527 | + setGetterMethod(pPager); |
| 53323 | 53528 | pagerReportSize(pPager); |
| 53324 | 53529 | } |
| 53325 | 53530 | SQLITE_PRIVATE void *sqlite3PagerGetCodec(Pager *pPager){ |
| 53326 | 53531 | return pPager->pCodec; |
| 53327 | 53532 | } |
| | @@ -57790,59 +57995,53 @@ |
| 57790 | 57995 | #define PTF_ZERODATA 0x02 |
| 57791 | 57996 | #define PTF_LEAFDATA 0x04 |
| 57792 | 57997 | #define PTF_LEAF 0x08 |
| 57793 | 57998 | |
| 57794 | 57999 | /* |
| 57795 | | -** As each page of the file is loaded into memory, an instance of the following |
| 57796 | | -** structure is appended and initialized to zero. This structure stores |
| 57797 | | -** information about the page that is decoded from the raw file page. |
| 58000 | +** An instance of this object stores information about each a single database |
| 58001 | +** page that has been loaded into memory. The information in this object |
| 58002 | +** is derived from the raw on-disk page content. |
| 57798 | 58003 | ** |
| 57799 | | -** The pParent field points back to the parent page. This allows us to |
| 57800 | | -** walk up the BTree from any leaf to the root. Care must be taken to |
| 57801 | | -** unref() the parent page pointer when this page is no longer referenced. |
| 57802 | | -** The pageDestructor() routine handles that chore. |
| 58004 | +** As each database page is loaded into memory, the pager allocats an |
| 58005 | +** instance of this object and zeros the first 8 bytes. (This is the |
| 58006 | +** "extra" information associated with each page of the pager.) |
| 57803 | 58007 | ** |
| 57804 | 58008 | ** Access to all fields of this structure is controlled by the mutex |
| 57805 | 58009 | ** stored in MemPage.pBt->mutex. |
| 57806 | 58010 | */ |
| 57807 | 58011 | struct MemPage { |
| 57808 | 58012 | u8 isInit; /* True if previously initialized. MUST BE FIRST! */ |
| 57809 | | - u8 nOverflow; /* Number of overflow cell bodies in aCell[] */ |
| 58013 | + u8 bBusy; /* Prevent endless loops on corrupt database files */ |
| 57810 | 58014 | u8 intKey; /* True if table b-trees. False for index b-trees */ |
| 57811 | 58015 | u8 intKeyLeaf; /* True if the leaf of an intKey table */ |
| 58016 | + Pgno pgno; /* Page number for this page */ |
| 58017 | + /* Only the first 8 bytes (above) are zeroed by pager.c when a new page |
| 58018 | + ** is allocated. All fields that follow must be initialized before use */ |
| 57812 | 58019 | u8 leaf; /* True if a leaf page */ |
| 57813 | 58020 | u8 hdrOffset; /* 100 for page 1. 0 otherwise */ |
| 57814 | 58021 | u8 childPtrSize; /* 0 if leaf==1. 4 if leaf==0 */ |
| 57815 | 58022 | u8 max1bytePayload; /* min(maxLocal,127) */ |
| 57816 | | - u8 bBusy; /* Prevent endless loops on corrupt database files */ |
| 58023 | + u8 nOverflow; /* Number of overflow cell bodies in aCell[] */ |
| 57817 | 58024 | u16 maxLocal; /* Copy of BtShared.maxLocal or BtShared.maxLeaf */ |
| 57818 | 58025 | u16 minLocal; /* Copy of BtShared.minLocal or BtShared.minLeaf */ |
| 57819 | 58026 | u16 cellOffset; /* Index in aData of first cell pointer */ |
| 57820 | 58027 | u16 nFree; /* Number of free bytes on the page */ |
| 57821 | 58028 | u16 nCell; /* Number of cells on this page, local and ovfl */ |
| 57822 | 58029 | u16 maskPage; /* Mask for page offset */ |
| 57823 | | - u16 aiOvfl[5]; /* Insert the i-th overflow cell before the aiOvfl-th |
| 58030 | + u16 aiOvfl[4]; /* Insert the i-th overflow cell before the aiOvfl-th |
| 57824 | 58031 | ** non-overflow cell */ |
| 57825 | | - u8 *apOvfl[5]; /* Pointers to the body of overflow cells */ |
| 58032 | + u8 *apOvfl[4]; /* Pointers to the body of overflow cells */ |
| 57826 | 58033 | BtShared *pBt; /* Pointer to BtShared that this page is part of */ |
| 57827 | 58034 | u8 *aData; /* Pointer to disk image of the page data */ |
| 57828 | 58035 | u8 *aDataEnd; /* One byte past the end of usable data */ |
| 57829 | 58036 | u8 *aCellIdx; /* The cell index area */ |
| 57830 | 58037 | u8 *aDataOfst; /* Same as aData for leaves. aData+4 for interior */ |
| 57831 | 58038 | DbPage *pDbPage; /* Pager page handle */ |
| 57832 | 58039 | u16 (*xCellSize)(MemPage*,u8*); /* cellSizePtr method */ |
| 57833 | 58040 | void (*xParseCell)(MemPage*,u8*,CellInfo*); /* btreeParseCell method */ |
| 57834 | | - Pgno pgno; /* Page number for this page */ |
| 57835 | 58041 | }; |
| 57836 | 58042 | |
| 57837 | | -/* |
| 57838 | | -** The in-memory image of a disk page has the auxiliary information appended |
| 57839 | | -** to the end. EXTRA_SIZE is the number of bytes of space needed to hold |
| 57840 | | -** that extra information. |
| 57841 | | -*/ |
| 57842 | | -#define EXTRA_SIZE sizeof(MemPage) |
| 57843 | | - |
| 57844 | 58043 | /* |
| 57845 | 58044 | ** A linked list of the following structures is stored at BtShared.pLock. |
| 57846 | 58045 | ** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor |
| 57847 | 58046 | ** is opened on the table with root page BtShared.iTable. Locks are removed |
| 57848 | 58047 | ** from this list when a transaction is committed or rolled back, or when |
| | @@ -59288,30 +59487,27 @@ |
| 59288 | 59487 | int bias, /* Bias search to the high end */ |
| 59289 | 59488 | int *pRes /* Write search results here */ |
| 59290 | 59489 | ){ |
| 59291 | 59490 | int rc; /* Status code */ |
| 59292 | 59491 | UnpackedRecord *pIdxKey; /* Unpacked index key */ |
| 59293 | | - char aSpace[384]; /* Temp space for pIdxKey - to avoid a malloc */ |
| 59294 | | - char *pFree = 0; |
| 59295 | 59492 | |
| 59296 | 59493 | if( pKey ){ |
| 59297 | 59494 | assert( nKey==(i64)(int)nKey ); |
| 59298 | | - pIdxKey = sqlite3VdbeAllocUnpackedRecord( |
| 59299 | | - pCur->pKeyInfo, aSpace, sizeof(aSpace), &pFree |
| 59300 | | - ); |
| 59495 | + pIdxKey = sqlite3VdbeAllocUnpackedRecord(pCur->pKeyInfo); |
| 59301 | 59496 | if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT; |
| 59302 | 59497 | sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey); |
| 59303 | 59498 | if( pIdxKey->nField==0 ){ |
| 59304 | | - sqlite3DbFree(pCur->pKeyInfo->db, pFree); |
| 59305 | | - return SQLITE_CORRUPT_BKPT; |
| 59499 | + rc = SQLITE_CORRUPT_BKPT; |
| 59500 | + goto moveto_done; |
| 59306 | 59501 | } |
| 59307 | 59502 | }else{ |
| 59308 | 59503 | pIdxKey = 0; |
| 59309 | 59504 | } |
| 59310 | 59505 | rc = sqlite3BtreeMovetoUnpacked(pCur, pIdxKey, nKey, bias, pRes); |
| 59311 | | - if( pFree ){ |
| 59312 | | - sqlite3DbFree(pCur->pKeyInfo->db, pFree); |
| 59506 | +moveto_done: |
| 59507 | + if( pIdxKey ){ |
| 59508 | + sqlite3DbFree(pCur->pKeyInfo->db, pIdxKey); |
| 59313 | 59509 | } |
| 59314 | 59510 | return rc; |
| 59315 | 59511 | } |
| 59316 | 59512 | |
| 59317 | 59513 | /* |
| | @@ -60268,11 +60464,11 @@ |
| 60268 | 60464 | assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) ); |
| 60269 | 60465 | assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) ); |
| 60270 | 60466 | assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) ); |
| 60271 | 60467 | |
| 60272 | 60468 | if( !pPage->isInit ){ |
| 60273 | | - u16 pc; /* Address of a freeblock within pPage->aData[] */ |
| 60469 | + int pc; /* Address of a freeblock within pPage->aData[] */ |
| 60274 | 60470 | u8 hdr; /* Offset to beginning of page header */ |
| 60275 | 60471 | u8 *data; /* Equal to pPage->aData */ |
| 60276 | 60472 | BtShared *pBt; /* The main btree structure */ |
| 60277 | 60473 | int usableSize; /* Amount of usable space on each page */ |
| 60278 | 60474 | u16 cellOffset; /* Offset from start of page to first cell pointer */ |
| | @@ -60348,29 +60544,34 @@ |
| 60348 | 60544 | ** EVIDENCE-OF: R-23588-34450 The two-byte integer at offset 1 gives the |
| 60349 | 60545 | ** start of the first freeblock on the page, or is zero if there are no |
| 60350 | 60546 | ** freeblocks. */ |
| 60351 | 60547 | pc = get2byte(&data[hdr+1]); |
| 60352 | 60548 | nFree = data[hdr+7] + top; /* Init nFree to non-freeblock free space */ |
| 60353 | | - while( pc>0 ){ |
| 60354 | | - u16 next, size; |
| 60355 | | - if( pc<iCellFirst || pc>iCellLast ){ |
| 60549 | + if( pc>0 ){ |
| 60550 | + u32 next, size; |
| 60551 | + if( pc<iCellFirst ){ |
| 60356 | 60552 | /* EVIDENCE-OF: R-55530-52930 In a well-formed b-tree page, there will |
| 60357 | 60553 | ** always be at least one cell before the first freeblock. |
| 60358 | | - ** |
| 60359 | | - ** Or, the freeblock is off the end of the page |
| 60360 | 60554 | */ |
| 60361 | 60555 | return SQLITE_CORRUPT_BKPT; |
| 60362 | 60556 | } |
| 60363 | | - next = get2byte(&data[pc]); |
| 60364 | | - size = get2byte(&data[pc+2]); |
| 60365 | | - if( (next>0 && next<=pc+size+3) || pc+size>usableSize ){ |
| 60366 | | - /* Free blocks must be in ascending order. And the last byte of |
| 60367 | | - ** the free-block must lie on the database page. */ |
| 60368 | | - return SQLITE_CORRUPT_BKPT; |
| 60369 | | - } |
| 60370 | | - nFree = nFree + size; |
| 60371 | | - pc = next; |
| 60557 | + while( 1 ){ |
| 60558 | + if( pc>iCellLast ){ |
| 60559 | + return SQLITE_CORRUPT_BKPT; /* Freeblock off the end of the page */ |
| 60560 | + } |
| 60561 | + next = get2byte(&data[pc]); |
| 60562 | + size = get2byte(&data[pc+2]); |
| 60563 | + nFree = nFree + size; |
| 60564 | + if( next<=pc+size+3 ) break; |
| 60565 | + pc = next; |
| 60566 | + } |
| 60567 | + if( next>0 ){ |
| 60568 | + return SQLITE_CORRUPT_BKPT; /* Freeblock not in ascending order */ |
| 60569 | + } |
| 60570 | + if( pc+size>(unsigned int)usableSize ){ |
| 60571 | + return SQLITE_CORRUPT_BKPT; /* Last freeblock extends past page end */ |
| 60572 | + } |
| 60372 | 60573 | } |
| 60373 | 60574 | |
| 60374 | 60575 | /* At this point, nFree contains the sum of the offset to the start |
| 60375 | 60576 | ** of the cell-content area plus the number of free bytes within |
| 60376 | 60577 | ** the cell-content area. If this is greater than the usable-size |
| | @@ -60807,11 +61008,11 @@ |
| 60807 | 61008 | if( pBt==0 ){ |
| 60808 | 61009 | rc = SQLITE_NOMEM_BKPT; |
| 60809 | 61010 | goto btree_open_out; |
| 60810 | 61011 | } |
| 60811 | 61012 | rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename, |
| 60812 | | - EXTRA_SIZE, flags, vfsFlags, pageReinit); |
| 61013 | + sizeof(MemPage), flags, vfsFlags, pageReinit); |
| 60813 | 61014 | if( rc==SQLITE_OK ){ |
| 60814 | 61015 | sqlite3PagerSetMmapLimit(pBt->pPager, db->szMmap); |
| 60815 | 61016 | rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader); |
| 60816 | 61017 | } |
| 60817 | 61018 | if( rc!=SQLITE_OK ){ |
| | @@ -61816,18 +62017,15 @@ |
| 61816 | 62017 | static int setChildPtrmaps(MemPage *pPage){ |
| 61817 | 62018 | int i; /* Counter variable */ |
| 61818 | 62019 | int nCell; /* Number of cells in page pPage */ |
| 61819 | 62020 | int rc; /* Return code */ |
| 61820 | 62021 | BtShared *pBt = pPage->pBt; |
| 61821 | | - u8 isInitOrig = pPage->isInit; |
| 61822 | 62022 | Pgno pgno = pPage->pgno; |
| 61823 | 62023 | |
| 61824 | 62024 | assert( sqlite3_mutex_held(pPage->pBt->mutex) ); |
| 61825 | 62025 | rc = btreeInitPage(pPage); |
| 61826 | | - if( rc!=SQLITE_OK ){ |
| 61827 | | - goto set_child_ptrmaps_out; |
| 61828 | | - } |
| 62026 | + if( rc!=SQLITE_OK ) return rc; |
| 61829 | 62027 | nCell = pPage->nCell; |
| 61830 | 62028 | |
| 61831 | 62029 | for(i=0; i<nCell; i++){ |
| 61832 | 62030 | u8 *pCell = findCell(pPage, i); |
| 61833 | 62031 | |
| | @@ -61842,12 +62040,10 @@ |
| 61842 | 62040 | if( !pPage->leaf ){ |
| 61843 | 62041 | Pgno childPgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); |
| 61844 | 62042 | ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno, &rc); |
| 61845 | 62043 | } |
| 61846 | 62044 | |
| 61847 | | -set_child_ptrmaps_out: |
| 61848 | | - pPage->isInit = isInitOrig; |
| 61849 | 62045 | return rc; |
| 61850 | 62046 | } |
| 61851 | 62047 | |
| 61852 | 62048 | /* |
| 61853 | 62049 | ** Somewhere on pPage is a pointer to page iFrom. Modify this pointer so |
| | @@ -61871,11 +62067,10 @@ |
| 61871 | 62067 | if( get4byte(pPage->aData)!=iFrom ){ |
| 61872 | 62068 | return SQLITE_CORRUPT_BKPT; |
| 61873 | 62069 | } |
| 61874 | 62070 | put4byte(pPage->aData, iTo); |
| 61875 | 62071 | }else{ |
| 61876 | | - u8 isInitOrig = pPage->isInit; |
| 61877 | 62072 | int i; |
| 61878 | 62073 | int nCell; |
| 61879 | 62074 | int rc; |
| 61880 | 62075 | |
| 61881 | 62076 | rc = btreeInitPage(pPage); |
| | @@ -61907,12 +62102,10 @@ |
| 61907 | 62102 | get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){ |
| 61908 | 62103 | return SQLITE_CORRUPT_BKPT; |
| 61909 | 62104 | } |
| 61910 | 62105 | put4byte(&pPage->aData[pPage->hdrOffset+8], iTo); |
| 61911 | 62106 | } |
| 61912 | | - |
| 61913 | | - pPage->isInit = isInitOrig; |
| 61914 | 62107 | } |
| 61915 | 62108 | return SQLITE_OK; |
| 61916 | 62109 | } |
| 61917 | 62110 | |
| 61918 | 62111 | |
| | @@ -64521,34 +64714,32 @@ |
| 64521 | 64714 | ** overflow) into *pnSize. |
| 64522 | 64715 | */ |
| 64523 | 64716 | static int clearCell( |
| 64524 | 64717 | MemPage *pPage, /* The page that contains the Cell */ |
| 64525 | 64718 | unsigned char *pCell, /* First byte of the Cell */ |
| 64526 | | - u16 *pnSize /* Write the size of the Cell here */ |
| 64719 | + CellInfo *pInfo /* Size information about the cell */ |
| 64527 | 64720 | ){ |
| 64528 | 64721 | BtShared *pBt = pPage->pBt; |
| 64529 | | - CellInfo info; |
| 64530 | 64722 | Pgno ovflPgno; |
| 64531 | 64723 | int rc; |
| 64532 | 64724 | int nOvfl; |
| 64533 | 64725 | u32 ovflPageSize; |
| 64534 | 64726 | |
| 64535 | 64727 | assert( sqlite3_mutex_held(pPage->pBt->mutex) ); |
| 64536 | | - pPage->xParseCell(pPage, pCell, &info); |
| 64537 | | - *pnSize = info.nSize; |
| 64538 | | - if( info.nLocal==info.nPayload ){ |
| 64728 | + pPage->xParseCell(pPage, pCell, pInfo); |
| 64729 | + if( pInfo->nLocal==pInfo->nPayload ){ |
| 64539 | 64730 | return SQLITE_OK; /* No overflow pages. Return without doing anything */ |
| 64540 | 64731 | } |
| 64541 | | - if( pCell+info.nSize-1 > pPage->aData+pPage->maskPage ){ |
| 64732 | + if( pCell+pInfo->nSize-1 > pPage->aData+pPage->maskPage ){ |
| 64542 | 64733 | return SQLITE_CORRUPT_BKPT; /* Cell extends past end of page */ |
| 64543 | 64734 | } |
| 64544 | | - ovflPgno = get4byte(pCell + info.nSize - 4); |
| 64735 | + ovflPgno = get4byte(pCell + pInfo->nSize - 4); |
| 64545 | 64736 | assert( pBt->usableSize > 4 ); |
| 64546 | 64737 | ovflPageSize = pBt->usableSize - 4; |
| 64547 | | - nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize; |
| 64738 | + nOvfl = (pInfo->nPayload - pInfo->nLocal + ovflPageSize - 1)/ovflPageSize; |
| 64548 | 64739 | assert( nOvfl>0 || |
| 64549 | | - (CORRUPT_DB && (info.nPayload + ovflPageSize)<ovflPageSize) |
| 64740 | + (CORRUPT_DB && (pInfo->nPayload + ovflPageSize)<ovflPageSize) |
| 64550 | 64741 | ); |
| 64551 | 64742 | while( nOvfl-- ){ |
| 64552 | 64743 | Pgno iNext = 0; |
| 64553 | 64744 | MemPage *pOvfl = 0; |
| 64554 | 64745 | if( ovflPgno<2 || ovflPgno>btreePagecount(pBt) ){ |
| | @@ -64784,11 +64975,10 @@ |
| 64784 | 64975 | u8 *ptr; /* Used to move bytes around within data[] */ |
| 64785 | 64976 | int rc; /* The return code */ |
| 64786 | 64977 | int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */ |
| 64787 | 64978 | |
| 64788 | 64979 | if( *pRC ) return; |
| 64789 | | - |
| 64790 | 64980 | assert( idx>=0 && idx<pPage->nCell ); |
| 64791 | 64981 | assert( CORRUPT_DB || sz==cellSize(pPage, idx) ); |
| 64792 | 64982 | assert( sqlite3PagerIswriteable(pPage->pDbPage) ); |
| 64793 | 64983 | assert( sqlite3_mutex_held(pPage->pBt->mutex) ); |
| 64794 | 64984 | data = pPage->aData; |
| | @@ -64868,11 +65058,14 @@ |
| 64868 | 65058 | } |
| 64869 | 65059 | if( iChild ){ |
| 64870 | 65060 | put4byte(pCell, iChild); |
| 64871 | 65061 | } |
| 64872 | 65062 | j = pPage->nOverflow++; |
| 64873 | | - assert( j<(int)(sizeof(pPage->apOvfl)/sizeof(pPage->apOvfl[0])) ); |
| 65063 | + /* Comparison against ArraySize-1 since we hold back one extra slot |
| 65064 | + ** as a contingency. In other words, never need more than 3 overflow |
| 65065 | + ** slots but 4 are allocated, just to be safe. */ |
| 65066 | + assert( j < ArraySize(pPage->apOvfl)-1 ); |
| 64874 | 65067 | pPage->apOvfl[j] = pCell; |
| 64875 | 65068 | pPage->aiOvfl[j] = (u16)i; |
| 64876 | 65069 | |
| 64877 | 65070 | /* When multiple overflows occur, they are always sequential and in |
| 64878 | 65071 | ** sorted order. This invariants arise because multiple overflows can |
| | @@ -65608,11 +65801,11 @@ |
| 65608 | 65801 | goto balance_cleanup; |
| 65609 | 65802 | } |
| 65610 | 65803 | nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow; |
| 65611 | 65804 | if( (i--)==0 ) break; |
| 65612 | 65805 | |
| 65613 | | - if( i+nxDiv==pParent->aiOvfl[0] && pParent->nOverflow ){ |
| 65806 | + if( pParent->nOverflow && ALWAYS(i+nxDiv==pParent->aiOvfl[0]) ){ |
| 65614 | 65807 | apDiv[i] = pParent->apOvfl[0]; |
| 65615 | 65808 | pgno = get4byte(apDiv[i]); |
| 65616 | 65809 | szNew[i] = pParent->xCellSize(pParent, apDiv[i]); |
| 65617 | 65810 | pParent->nOverflow = 0; |
| 65618 | 65811 | }else{ |
| | @@ -66547,14 +66740,18 @@ |
| 66547 | 66740 | if( rc ) return rc; |
| 66548 | 66741 | } |
| 66549 | 66742 | }else if( loc==0 ){ |
| 66550 | 66743 | if( pX->nMem ){ |
| 66551 | 66744 | UnpackedRecord r; |
| 66552 | | - memset(&r, 0, sizeof(r)); |
| 66553 | 66745 | r.pKeyInfo = pCur->pKeyInfo; |
| 66554 | 66746 | r.aMem = pX->aMem; |
| 66555 | 66747 | r.nField = pX->nMem; |
| 66748 | + r.default_rc = 0; |
| 66749 | + r.errCode = 0; |
| 66750 | + r.r1 = 0; |
| 66751 | + r.r2 = 0; |
| 66752 | + r.eqSeen = 0; |
| 66556 | 66753 | rc = sqlite3BtreeMovetoUnpacked(pCur, &r, 0, appendBias, &loc); |
| 66557 | 66754 | }else{ |
| 66558 | 66755 | rc = btreeMoveto(pCur, pX->pKey, pX->nKey, appendBias, &loc); |
| 66559 | 66756 | } |
| 66560 | 66757 | if( rc ) return rc; |
| | @@ -66575,22 +66772,33 @@ |
| 66575 | 66772 | if( rc ) goto end_insert; |
| 66576 | 66773 | assert( szNew==pPage->xCellSize(pPage, newCell) ); |
| 66577 | 66774 | assert( szNew <= MX_CELL_SIZE(pBt) ); |
| 66578 | 66775 | idx = pCur->aiIdx[pCur->iPage]; |
| 66579 | 66776 | if( loc==0 ){ |
| 66580 | | - u16 szOld; |
| 66777 | + CellInfo info; |
| 66581 | 66778 | assert( idx<pPage->nCell ); |
| 66582 | 66779 | rc = sqlite3PagerWrite(pPage->pDbPage); |
| 66583 | 66780 | if( rc ){ |
| 66584 | 66781 | goto end_insert; |
| 66585 | 66782 | } |
| 66586 | 66783 | oldCell = findCell(pPage, idx); |
| 66587 | 66784 | if( !pPage->leaf ){ |
| 66588 | 66785 | memcpy(newCell, oldCell, 4); |
| 66589 | 66786 | } |
| 66590 | | - rc = clearCell(pPage, oldCell, &szOld); |
| 66591 | | - dropCell(pPage, idx, szOld, &rc); |
| 66787 | + rc = clearCell(pPage, oldCell, &info); |
| 66788 | + if( info.nSize==szNew && info.nLocal==info.nPayload ){ |
| 66789 | + /* Overwrite the old cell with the new if they are the same size. |
| 66790 | + ** We could also try to do this if the old cell is smaller, then add |
| 66791 | + ** the leftover space to the free list. But experiments show that |
| 66792 | + ** doing that is no faster then skipping this optimization and just |
| 66793 | + ** calling dropCell() and insertCell(). */ |
| 66794 | + assert( rc==SQLITE_OK ); /* clearCell never fails when nLocal==nPayload */ |
| 66795 | + if( oldCell+szNew > pPage->aDataEnd ) return SQLITE_CORRUPT_BKPT; |
| 66796 | + memcpy(oldCell, newCell, szNew); |
| 66797 | + return SQLITE_OK; |
| 66798 | + } |
| 66799 | + dropCell(pPage, idx, info.nSize, &rc); |
| 66592 | 66800 | if( rc ) goto end_insert; |
| 66593 | 66801 | }else if( loc<0 && pPage->nCell>0 ){ |
| 66594 | 66802 | assert( pPage->leaf ); |
| 66595 | 66803 | idx = ++pCur->aiIdx[pCur->iPage]; |
| 66596 | 66804 | }else{ |
| | @@ -66662,11 +66870,11 @@ |
| 66662 | 66870 | int rc; /* Return code */ |
| 66663 | 66871 | MemPage *pPage; /* Page to delete cell from */ |
| 66664 | 66872 | unsigned char *pCell; /* Pointer to cell to delete */ |
| 66665 | 66873 | int iCellIdx; /* Index of cell to delete */ |
| 66666 | 66874 | int iCellDepth; /* Depth of node containing pCell */ |
| 66667 | | - u16 szCell; /* Size of the cell being deleted */ |
| 66875 | + CellInfo info; /* Size of the cell being deleted */ |
| 66668 | 66876 | int bSkipnext = 0; /* Leaf cursor in SKIPNEXT state */ |
| 66669 | 66877 | u8 bPreserve = flags & BTREE_SAVEPOSITION; /* Keep cursor valid */ |
| 66670 | 66878 | |
| 66671 | 66879 | assert( cursorOwnsBtShared(pCur) ); |
| 66672 | 66880 | assert( pBt->inTransaction==TRANS_WRITE ); |
| | @@ -66734,12 +66942,12 @@ |
| 66734 | 66942 | /* Make the page containing the entry to be deleted writable. Then free any |
| 66735 | 66943 | ** overflow pages associated with the entry and finally remove the cell |
| 66736 | 66944 | ** itself from within the page. */ |
| 66737 | 66945 | rc = sqlite3PagerWrite(pPage->pDbPage); |
| 66738 | 66946 | if( rc ) return rc; |
| 66739 | | - rc = clearCell(pPage, pCell, &szCell); |
| 66740 | | - dropCell(pPage, iCellIdx, szCell, &rc); |
| 66947 | + rc = clearCell(pPage, pCell, &info); |
| 66948 | + dropCell(pPage, iCellIdx, info.nSize, &rc); |
| 66741 | 66949 | if( rc ) return rc; |
| 66742 | 66950 | |
| 66743 | 66951 | /* If the cell deleted was not located on a leaf page, then the cursor |
| 66744 | 66952 | ** is currently pointing to the largest entry in the sub-tree headed |
| 66745 | 66953 | ** by the child-page of the cell that was just deleted from an internal |
| | @@ -66985,11 +67193,11 @@ |
| 66985 | 67193 | MemPage *pPage; |
| 66986 | 67194 | int rc; |
| 66987 | 67195 | unsigned char *pCell; |
| 66988 | 67196 | int i; |
| 66989 | 67197 | int hdr; |
| 66990 | | - u16 szCell; |
| 67198 | + CellInfo info; |
| 66991 | 67199 | |
| 66992 | 67200 | assert( sqlite3_mutex_held(pBt->mutex) ); |
| 66993 | 67201 | if( pgno>btreePagecount(pBt) ){ |
| 66994 | 67202 | return SQLITE_CORRUPT_BKPT; |
| 66995 | 67203 | } |
| | @@ -67005,11 +67213,11 @@ |
| 67005 | 67213 | pCell = findCell(pPage, i); |
| 67006 | 67214 | if( !pPage->leaf ){ |
| 67007 | 67215 | rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange); |
| 67008 | 67216 | if( rc ) goto cleardatabasepage_out; |
| 67009 | 67217 | } |
| 67010 | | - rc = clearCell(pPage, pCell, &szCell); |
| 67218 | + rc = clearCell(pPage, pCell, &info); |
| 67011 | 67219 | if( rc ) goto cleardatabasepage_out; |
| 67012 | 67220 | } |
| 67013 | 67221 | if( !pPage->leaf ){ |
| 67014 | 67222 | rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), 1, pnChange); |
| 67015 | 67223 | if( rc ) goto cleardatabasepage_out; |
| | @@ -70379,10 +70587,11 @@ |
| 70379 | 70587 | sqlite3ValueApplyAffinity(pVal, affinity, enc); |
| 70380 | 70588 | } |
| 70381 | 70589 | }else if( op==TK_NULL ){ |
| 70382 | 70590 | pVal = valueNew(db, pCtx); |
| 70383 | 70591 | if( pVal==0 ) goto no_mem; |
| 70592 | + sqlite3VdbeMemNumerify(pVal); |
| 70384 | 70593 | } |
| 70385 | 70594 | #ifndef SQLITE_OMIT_BLOB_LITERAL |
| 70386 | 70595 | else if( op==TK_BLOB ){ |
| 70387 | 70596 | int nVal; |
| 70388 | 70597 | assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' ); |
| | @@ -72730,14 +72939,12 @@ |
| 72730 | 72939 | if( x.nNeeded==0 ) break; |
| 72731 | 72940 | x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded); |
| 72732 | 72941 | x.nFree = x.nNeeded; |
| 72733 | 72942 | }while( !db->mallocFailed ); |
| 72734 | 72943 | |
| 72735 | | - p->nzVar = pParse->nzVar; |
| 72736 | | - p->azVar = pParse->azVar; |
| 72737 | | - pParse->nzVar = 0; |
| 72738 | | - pParse->azVar = 0; |
| 72944 | + p->pVList = pParse->pVList; |
| 72945 | + pParse->pVList = 0; |
| 72739 | 72946 | p->explain = pParse->explain; |
| 72740 | 72947 | if( db->mallocFailed ){ |
| 72741 | 72948 | p->nVar = 0; |
| 72742 | 72949 | p->nCursor = 0; |
| 72743 | 72950 | p->nMem = 0; |
| | @@ -72761,19 +72968,19 @@ |
| 72761 | 72968 | */ |
| 72762 | 72969 | SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ |
| 72763 | 72970 | if( pCx==0 ){ |
| 72764 | 72971 | return; |
| 72765 | 72972 | } |
| 72766 | | - assert( pCx->pBt==0 || pCx->eCurType==CURTYPE_BTREE ); |
| 72973 | + assert( pCx->pBtx==0 || pCx->eCurType==CURTYPE_BTREE ); |
| 72767 | 72974 | switch( pCx->eCurType ){ |
| 72768 | 72975 | case CURTYPE_SORTER: { |
| 72769 | 72976 | sqlite3VdbeSorterClose(p->db, pCx); |
| 72770 | 72977 | break; |
| 72771 | 72978 | } |
| 72772 | 72979 | case CURTYPE_BTREE: { |
| 72773 | | - if( pCx->pBt ){ |
| 72774 | | - sqlite3BtreeClose(pCx->pBt); |
| 72980 | + if( pCx->pBtx ){ |
| 72981 | + sqlite3BtreeClose(pCx->pBtx); |
| 72775 | 72982 | /* The pCx->pCursor will be close automatically, if it exists, by |
| 72776 | 72983 | ** the call above. */ |
| 72777 | 72984 | }else{ |
| 72778 | 72985 | assert( pCx->uc.pCursor!=0 ); |
| 72779 | 72986 | sqlite3BtreeCloseCursor(pCx->uc.pCursor); |
| | @@ -73727,32 +73934,33 @@ |
| 73727 | 73934 | ** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with |
| 73728 | 73935 | ** the database connection and frees the object itself. |
| 73729 | 73936 | */ |
| 73730 | 73937 | SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ |
| 73731 | 73938 | SubProgram *pSub, *pNext; |
| 73732 | | - int i; |
| 73733 | 73939 | assert( p->db==0 || p->db==db ); |
| 73734 | 73940 | releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); |
| 73735 | 73941 | for(pSub=p->pProgram; pSub; pSub=pNext){ |
| 73736 | 73942 | pNext = pSub->pNext; |
| 73737 | 73943 | vdbeFreeOpArray(db, pSub->aOp, pSub->nOp); |
| 73738 | 73944 | sqlite3DbFree(db, pSub); |
| 73739 | 73945 | } |
| 73740 | 73946 | if( p->magic!=VDBE_MAGIC_INIT ){ |
| 73741 | 73947 | releaseMemArray(p->aVar, p->nVar); |
| 73742 | | - for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]); |
| 73743 | | - sqlite3DbFree(db, p->azVar); |
| 73948 | + sqlite3DbFree(db, p->pVList); |
| 73744 | 73949 | sqlite3DbFree(db, p->pFree); |
| 73745 | 73950 | } |
| 73746 | 73951 | vdbeFreeOpArray(db, p->aOp, p->nOp); |
| 73747 | 73952 | sqlite3DbFree(db, p->aColName); |
| 73748 | 73953 | sqlite3DbFree(db, p->zSql); |
| 73749 | 73954 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS |
| 73750 | | - for(i=0; i<p->nScan; i++){ |
| 73751 | | - sqlite3DbFree(db, p->aScan[i].zName); |
| 73955 | + { |
| 73956 | + int i; |
| 73957 | + for(i=0; i<p->nScan; i++){ |
| 73958 | + sqlite3DbFree(db, p->aScan[i].zName); |
| 73959 | + } |
| 73960 | + sqlite3DbFree(db, p->aScan); |
| 73752 | 73961 | } |
| 73753 | | - sqlite3DbFree(db, p->aScan); |
| 73754 | 73962 | #endif |
| 73755 | 73963 | } |
| 73756 | 73964 | |
| 73757 | 73965 | /* |
| 73758 | 73966 | ** Delete an entire VDBE. |
| | @@ -74249,34 +74457,17 @@ |
| 74249 | 74457 | ** before returning. |
| 74250 | 74458 | ** |
| 74251 | 74459 | ** If an OOM error occurs, NULL is returned. |
| 74252 | 74460 | */ |
| 74253 | 74461 | SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord( |
| 74254 | | - KeyInfo *pKeyInfo, /* Description of the record */ |
| 74255 | | - char *pSpace, /* Unaligned space available */ |
| 74256 | | - int szSpace, /* Size of pSpace[] in bytes */ |
| 74257 | | - char **ppFree /* OUT: Caller should free this pointer */ |
| 74462 | + KeyInfo *pKeyInfo /* Description of the record */ |
| 74258 | 74463 | ){ |
| 74259 | 74464 | UnpackedRecord *p; /* Unpacked record to return */ |
| 74260 | | - int nOff; /* Increment pSpace by nOff to align it */ |
| 74261 | 74465 | int nByte; /* Number of bytes required for *p */ |
| 74262 | | - |
| 74263 | | - /* We want to shift the pointer pSpace up such that it is 8-byte aligned. |
| 74264 | | - ** Thus, we need to calculate a value, nOff, between 0 and 7, to shift |
| 74265 | | - ** it by. If pSpace is already 8-byte aligned, nOff should be zero. |
| 74266 | | - */ |
| 74267 | | - nOff = (8 - (SQLITE_PTR_TO_INT(pSpace) & 7)) & 7; |
| 74268 | 74466 | nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nField+1); |
| 74269 | | - if( nByte>szSpace+nOff ){ |
| 74270 | | - p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); |
| 74271 | | - *ppFree = (char *)p; |
| 74272 | | - if( !p ) return 0; |
| 74273 | | - }else{ |
| 74274 | | - p = (UnpackedRecord*)&pSpace[nOff]; |
| 74275 | | - *ppFree = 0; |
| 74276 | | - } |
| 74277 | | - |
| 74467 | + p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); |
| 74468 | + if( !p ) return 0; |
| 74278 | 74469 | p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))]; |
| 74279 | 74470 | assert( pKeyInfo->aSortOrder!=0 ); |
| 74280 | 74471 | p->pKeyInfo = pKeyInfo; |
| 74281 | 74472 | p->nField = pKeyInfo->nField + 1; |
| 74282 | 74473 | return p; |
| | @@ -76890,35 +77081,22 @@ |
| 76890 | 77081 | ** |
| 76891 | 77082 | ** The result is always UTF-8. |
| 76892 | 77083 | */ |
| 76893 | 77084 | SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){ |
| 76894 | 77085 | Vdbe *p = (Vdbe*)pStmt; |
| 76895 | | - if( p==0 || i<1 || i>p->nzVar ){ |
| 76896 | | - return 0; |
| 76897 | | - } |
| 76898 | | - return p->azVar[i-1]; |
| 77086 | + if( p==0 ) return 0; |
| 77087 | + return sqlite3VListNumToName(p->pVList, i); |
| 76899 | 77088 | } |
| 76900 | 77089 | |
| 76901 | 77090 | /* |
| 76902 | 77091 | ** Given a wildcard parameter name, return the index of the variable |
| 76903 | 77092 | ** with that name. If there is no variable with the given name, |
| 76904 | 77093 | ** return 0. |
| 76905 | 77094 | */ |
| 76906 | 77095 | SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nName){ |
| 76907 | | - int i; |
| 76908 | | - if( p==0 ){ |
| 76909 | | - return 0; |
| 76910 | | - } |
| 76911 | | - if( zName ){ |
| 76912 | | - for(i=0; i<p->nzVar; i++){ |
| 76913 | | - const char *z = p->azVar[i]; |
| 76914 | | - if( z && strncmp(z,zName,nName)==0 && z[nName]==0 ){ |
| 76915 | | - return i+1; |
| 76916 | | - } |
| 76917 | | - } |
| 76918 | | - } |
| 76919 | | - return 0; |
| 77096 | + if( p==0 || zName==0 ) return 0; |
| 77097 | + return sqlite3VListNameToNum(p->pVList, zName, nName); |
| 76920 | 77098 | } |
| 76921 | 77099 | SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){ |
| 76922 | 77100 | return sqlite3VdbeParameterIndex((Vdbe*)pStmt, zName, sqlite3Strlen30(zName)); |
| 76923 | 77101 | } |
| 76924 | 77102 | |
| | @@ -77077,14 +77255,13 @@ |
| 77077 | 77255 | static UnpackedRecord *vdbeUnpackRecord( |
| 77078 | 77256 | KeyInfo *pKeyInfo, |
| 77079 | 77257 | int nKey, |
| 77080 | 77258 | const void *pKey |
| 77081 | 77259 | ){ |
| 77082 | | - char *dummy; /* Dummy argument for AllocUnpackedRecord() */ |
| 77083 | 77260 | UnpackedRecord *pRet; /* Return value */ |
| 77084 | 77261 | |
| 77085 | | - pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo, 0, 0, &dummy); |
| 77262 | + pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); |
| 77086 | 77263 | if( pRet ){ |
| 77087 | 77264 | memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nField+1)); |
| 77088 | 77265 | sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, pRet); |
| 77089 | 77266 | } |
| 77090 | 77267 | return pRet; |
| | @@ -77742,11 +77919,11 @@ |
| 77742 | 77919 | sqlite3VdbeFreeCursor(p, p->apCsr[iCur]); |
| 77743 | 77920 | p->apCsr[iCur] = 0; |
| 77744 | 77921 | } |
| 77745 | 77922 | if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){ |
| 77746 | 77923 | p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z; |
| 77747 | | - memset(pCx, 0, sizeof(VdbeCursor)); |
| 77924 | + memset(pCx, 0, offsetof(VdbeCursor,pAltCursor)); |
| 77748 | 77925 | pCx->eCurType = eCurType; |
| 77749 | 77926 | pCx->iDb = iDb; |
| 77750 | 77927 | pCx->nField = nField; |
| 77751 | 77928 | pCx->aOffset = &pCx->aType[nField]; |
| 77752 | 77929 | if( eCurType==CURTYPE_BTREE ){ |
| | @@ -78800,11 +78977,11 @@ |
| 78800 | 78977 | */ |
| 78801 | 78978 | case OP_Variable: { /* out2 */ |
| 78802 | 78979 | Mem *pVar; /* Value being transferred */ |
| 78803 | 78980 | |
| 78804 | 78981 | assert( pOp->p1>0 && pOp->p1<=p->nVar ); |
| 78805 | | - assert( pOp->p4.z==0 || pOp->p4.z==p->azVar[pOp->p1-1] ); |
| 78982 | + assert( pOp->p4.z==0 || pOp->p4.z==sqlite3VListNumToName(p->pVList,pOp->p1) ); |
| 78806 | 78983 | pVar = &p->aVar[pOp->p1 - 1]; |
| 78807 | 78984 | if( sqlite3VdbeMemTooBig(pVar) ){ |
| 78808 | 78985 | goto too_big; |
| 78809 | 78986 | } |
| 78810 | 78987 | pOut = out2Prerelease(p, pOp); |
| | @@ -81137,36 +81314,35 @@ |
| 81137 | 81314 | assert( pOp->p2>=0 ); |
| 81138 | 81315 | pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE); |
| 81139 | 81316 | if( pCx==0 ) goto no_mem; |
| 81140 | 81317 | pCx->nullRow = 1; |
| 81141 | 81318 | pCx->isEphemeral = 1; |
| 81142 | | - rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBt, |
| 81319 | + rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx, |
| 81143 | 81320 | BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); |
| 81144 | 81321 | if( rc==SQLITE_OK ){ |
| 81145 | | - rc = sqlite3BtreeBeginTrans(pCx->pBt, 1); |
| 81322 | + rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1); |
| 81146 | 81323 | } |
| 81147 | 81324 | if( rc==SQLITE_OK ){ |
| 81148 | 81325 | /* If a transient index is required, create it by calling |
| 81149 | 81326 | ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before |
| 81150 | 81327 | ** opening it. If a transient table is required, just use the |
| 81151 | 81328 | ** automatically created table with root-page 1 (an BLOB_INTKEY table). |
| 81152 | 81329 | */ |
| 81153 | | - if( (pKeyInfo = pOp->p4.pKeyInfo)!=0 ){ |
| 81330 | + if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){ |
| 81154 | 81331 | int pgno; |
| 81155 | 81332 | assert( pOp->p4type==P4_KEYINFO ); |
| 81156 | | - rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5); |
| 81333 | + rc = sqlite3BtreeCreateTable(pCx->pBtx, &pgno, BTREE_BLOBKEY | pOp->p5); |
| 81157 | 81334 | if( rc==SQLITE_OK ){ |
| 81158 | 81335 | assert( pgno==MASTER_ROOT+1 ); |
| 81159 | 81336 | assert( pKeyInfo->db==db ); |
| 81160 | 81337 | assert( pKeyInfo->enc==ENC(db) ); |
| 81161 | | - pCx->pKeyInfo = pKeyInfo; |
| 81162 | | - rc = sqlite3BtreeCursor(pCx->pBt, pgno, BTREE_WRCSR, |
| 81338 | + rc = sqlite3BtreeCursor(pCx->pBtx, pgno, BTREE_WRCSR, |
| 81163 | 81339 | pKeyInfo, pCx->uc.pCursor); |
| 81164 | 81340 | } |
| 81165 | 81341 | pCx->isTable = 0; |
| 81166 | 81342 | }else{ |
| 81167 | | - rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, BTREE_WRCSR, |
| 81343 | + rc = sqlite3BtreeCursor(pCx->pBtx, MASTER_ROOT, BTREE_WRCSR, |
| 81168 | 81344 | 0, pCx->uc.pCursor); |
| 81169 | 81345 | pCx->isTable = 1; |
| 81170 | 81346 | } |
| 81171 | 81347 | } |
| 81172 | 81348 | if( rc ) goto abort_due_to_error; |
| | @@ -81596,14 +81772,13 @@ |
| 81596 | 81772 | int alreadyExists; |
| 81597 | 81773 | int takeJump; |
| 81598 | 81774 | int ii; |
| 81599 | 81775 | VdbeCursor *pC; |
| 81600 | 81776 | int res; |
| 81601 | | - char *pFree; |
| 81777 | + UnpackedRecord *pFree; |
| 81602 | 81778 | UnpackedRecord *pIdxKey; |
| 81603 | 81779 | UnpackedRecord r; |
| 81604 | | - char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*4 + 7]; |
| 81605 | 81780 | |
| 81606 | 81781 | #ifdef SQLITE_TEST |
| 81607 | 81782 | if( pOp->opcode!=OP_NoConflict ) sqlite3_found_count++; |
| 81608 | 81783 | #endif |
| 81609 | 81784 | |
| | @@ -81616,11 +81791,10 @@ |
| 81616 | 81791 | #endif |
| 81617 | 81792 | pIn3 = &aMem[pOp->p3]; |
| 81618 | 81793 | assert( pC->eCurType==CURTYPE_BTREE ); |
| 81619 | 81794 | assert( pC->uc.pCursor!=0 ); |
| 81620 | 81795 | assert( pC->isTable==0 ); |
| 81621 | | - pFree = 0; |
| 81622 | 81796 | if( pOp->p4.i>0 ){ |
| 81623 | 81797 | r.pKeyInfo = pC->pKeyInfo; |
| 81624 | 81798 | r.nField = (u16)pOp->p4.i; |
| 81625 | 81799 | r.aMem = pIn3; |
| 81626 | 81800 | #ifdef SQLITE_DEBUG |
| | @@ -81629,14 +81803,13 @@ |
| 81629 | 81803 | assert( (r.aMem[ii].flags & MEM_Zero)==0 || r.aMem[ii].n==0 ); |
| 81630 | 81804 | if( ii ) REGISTER_TRACE(pOp->p3+ii, &r.aMem[ii]); |
| 81631 | 81805 | } |
| 81632 | 81806 | #endif |
| 81633 | 81807 | pIdxKey = &r; |
| 81808 | + pFree = 0; |
| 81634 | 81809 | }else{ |
| 81635 | | - pIdxKey = sqlite3VdbeAllocUnpackedRecord( |
| 81636 | | - pC->pKeyInfo, aTempRec, sizeof(aTempRec), &pFree |
| 81637 | | - ); |
| 81810 | + pFree = pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo); |
| 81638 | 81811 | if( pIdxKey==0 ) goto no_mem; |
| 81639 | 81812 | assert( pIn3->flags & MEM_Blob ); |
| 81640 | 81813 | (void)ExpandBlob(pIn3); |
| 81641 | 81814 | sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey); |
| 81642 | 81815 | } |
| | @@ -81652,11 +81825,11 @@ |
| 81652 | 81825 | break; |
| 81653 | 81826 | } |
| 81654 | 81827 | } |
| 81655 | 81828 | } |
| 81656 | 81829 | rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, pIdxKey, 0, 0, &res); |
| 81657 | | - sqlite3DbFree(db, pFree); |
| 81830 | + if( pFree ) sqlite3DbFree(db, pFree); |
| 81658 | 81831 | if( rc!=SQLITE_OK ){ |
| 81659 | 81832 | goto abort_due_to_error; |
| 81660 | 81833 | } |
| 81661 | 81834 | pC->seekResult = res; |
| 81662 | 81835 | alreadyExists = (res==0); |
| | @@ -82434,10 +82607,19 @@ |
| 82434 | 82607 | } |
| 82435 | 82608 | break; |
| 82436 | 82609 | } |
| 82437 | 82610 | |
| 82438 | 82611 | |
| 82612 | +/* Opcode: SorterSort P1 P2 * * * |
| 82613 | +** |
| 82614 | +** After all records have been inserted into the Sorter object |
| 82615 | +** identified by P1, invoke this opcode to actually do the sorting. |
| 82616 | +** Jump to P2 if there are no records to be sorted. |
| 82617 | +** |
| 82618 | +** This opcode is an alias for OP_Sort and OP_Rewind that is used |
| 82619 | +** for Sorter objects. |
| 82620 | +*/ |
| 82439 | 82621 | /* Opcode: Sort P1 P2 * * * |
| 82440 | 82622 | ** |
| 82441 | 82623 | ** This opcode does exactly the same thing as OP_Rewind except that |
| 82442 | 82624 | ** it increments an undocumented global variable used for testing. |
| 82443 | 82625 | ** |
| | @@ -82561,10 +82743,17 @@ |
| 82561 | 82743 | /* Opcode: PrevIfOpen P1 P2 P3 P4 P5 |
| 82562 | 82744 | ** |
| 82563 | 82745 | ** This opcode works just like Prev except that if cursor P1 is not |
| 82564 | 82746 | ** open it behaves a no-op. |
| 82565 | 82747 | */ |
| 82748 | +/* Opcode: SorterNext P1 P2 * * P5 |
| 82749 | +** |
| 82750 | +** This opcode works just like OP_Next except that P1 must be a |
| 82751 | +** sorter object for which the OP_SorterSort opcode has been |
| 82752 | +** invoked. This opcode advances the cursor to the next sorted |
| 82753 | +** record, or jumps to P2 if there are no more sorted records. |
| 82754 | +*/ |
| 82566 | 82755 | case OP_SorterNext: { /* jump */ |
| 82567 | 82756 | VdbeCursor *pC; |
| 82568 | 82757 | int res; |
| 82569 | 82758 | |
| 82570 | 82759 | pC = p->apCsr[pOp->p1]; |
| | @@ -83090,11 +83279,11 @@ |
| 83090 | 83279 | |
| 83091 | 83280 | iDb = pOp->p1; |
| 83092 | 83281 | assert( iDb>=0 && iDb<db->nDb ); |
| 83093 | 83282 | assert( DbHasProperty(db, iDb, DB_SchemaLoaded) ); |
| 83094 | 83283 | /* Used to be a conditional */ { |
| 83095 | | - zMaster = SCHEMA_TABLE(iDb); |
| 83284 | + zMaster = MASTER_NAME; |
| 83096 | 83285 | initData.db = db; |
| 83097 | 83286 | initData.iDb = pOp->p1; |
| 83098 | 83287 | initData.pzErrMsg = &p->zErrMsg; |
| 83099 | 83288 | zSql = sqlite3MPrintf(db, |
| 83100 | 83289 | "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid", |
| | @@ -83601,33 +83790,46 @@ |
| 83601 | 83790 | ** and r[P2] is set to -1. |
| 83602 | 83791 | ** |
| 83603 | 83792 | ** Otherwise, r[P2] is set to the sum of r[P1] and r[P3]. |
| 83604 | 83793 | */ |
| 83605 | 83794 | case OP_OffsetLimit: { /* in1, out2, in3 */ |
| 83795 | + i64 x; |
| 83606 | 83796 | pIn1 = &aMem[pOp->p1]; |
| 83607 | 83797 | pIn3 = &aMem[pOp->p3]; |
| 83608 | 83798 | pOut = out2Prerelease(p, pOp); |
| 83609 | 83799 | assert( pIn1->flags & MEM_Int ); |
| 83610 | 83800 | assert( pIn3->flags & MEM_Int ); |
| 83611 | | - pOut->u.i = pIn1->u.i<=0 ? -1 : pIn1->u.i+(pIn3->u.i>0?pIn3->u.i:0); |
| 83801 | + x = pIn1->u.i; |
| 83802 | + if( x<=0 || sqlite3AddInt64(&x, pIn3->u.i>0?pIn3->u.i:0) ){ |
| 83803 | + /* If the LIMIT is less than or equal to zero, loop forever. This |
| 83804 | + ** is documented. But also, if the LIMIT+OFFSET exceeds 2^63 then |
| 83805 | + ** also loop forever. This is undocumented. In fact, one could argue |
| 83806 | + ** that the loop should terminate. But assuming 1 billion iterations |
| 83807 | + ** per second (far exceeding the capabilities of any current hardware) |
| 83808 | + ** it would take nearly 300 years to actually reach the limit. So |
| 83809 | + ** looping forever is a reasonable approximation. */ |
| 83810 | + pOut->u.i = -1; |
| 83811 | + }else{ |
| 83812 | + pOut->u.i = x; |
| 83813 | + } |
| 83612 | 83814 | break; |
| 83613 | 83815 | } |
| 83614 | 83816 | |
| 83615 | | -/* Opcode: IfNotZero P1 P2 P3 * * |
| 83616 | | -** Synopsis: if r[P1]!=0 then r[P1]-=P3, goto P2 |
| 83817 | +/* Opcode: IfNotZero P1 P2 * * * |
| 83818 | +** Synopsis: if r[P1]!=0 then r[P1]--, goto P2 |
| 83617 | 83819 | ** |
| 83618 | 83820 | ** Register P1 must contain an integer. If the content of register P1 is |
| 83619 | | -** initially nonzero, then subtract P3 from the value in register P1 and |
| 83620 | | -** jump to P2. If register P1 is initially zero, leave it unchanged |
| 83621 | | -** and fall through. |
| 83821 | +** initially greater than zero, then decrement the value in register P1. |
| 83822 | +** If it is non-zero (negative or positive) and then also jump to P2. |
| 83823 | +** If register P1 is initially zero, leave it unchanged and fall through. |
| 83622 | 83824 | */ |
| 83623 | 83825 | case OP_IfNotZero: { /* jump, in1 */ |
| 83624 | 83826 | pIn1 = &aMem[pOp->p1]; |
| 83625 | 83827 | assert( pIn1->flags&MEM_Int ); |
| 83626 | 83828 | VdbeBranchTaken(pIn1->u.i<0, 2); |
| 83627 | 83829 | if( pIn1->u.i ){ |
| 83628 | | - pIn1->u.i -= pOp->p3; |
| 83830 | + if( pIn1->u.i>0 ) pIn1->u.i--; |
| 83629 | 83831 | goto jump_to_p2; |
| 83630 | 83832 | } |
| 83631 | 83833 | break; |
| 83632 | 83834 | } |
| 83633 | 83835 | |
| | @@ -86111,11 +86313,11 @@ |
| 86111 | 86313 | if( nWorker>=SORTER_MAX_MERGE_COUNT ){ |
| 86112 | 86314 | nWorker = SORTER_MAX_MERGE_COUNT-1; |
| 86113 | 86315 | } |
| 86114 | 86316 | #endif |
| 86115 | 86317 | |
| 86116 | | - assert( pCsr->pKeyInfo && pCsr->pBt==0 ); |
| 86318 | + assert( pCsr->pKeyInfo && pCsr->pBtx==0 ); |
| 86117 | 86319 | assert( pCsr->eCurType==CURTYPE_SORTER ); |
| 86118 | 86320 | szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nField-1)*sizeof(CollSeq*); |
| 86119 | 86321 | sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask); |
| 86120 | 86322 | |
| 86121 | 86323 | pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo); |
| | @@ -86479,16 +86681,12 @@ |
| 86479 | 86681 | ** structure at pTask->pUnpacked. Return SQLITE_OK if successful (or |
| 86480 | 86682 | ** if no allocation was required), or SQLITE_NOMEM otherwise. |
| 86481 | 86683 | */ |
| 86482 | 86684 | static int vdbeSortAllocUnpacked(SortSubtask *pTask){ |
| 86483 | 86685 | if( pTask->pUnpacked==0 ){ |
| 86484 | | - char *pFree; |
| 86485 | | - pTask->pUnpacked = sqlite3VdbeAllocUnpackedRecord( |
| 86486 | | - pTask->pSorter->pKeyInfo, 0, 0, &pFree |
| 86487 | | - ); |
| 86488 | | - assert( pTask->pUnpacked==(UnpackedRecord*)pFree ); |
| 86489 | | - if( pFree==0 ) return SQLITE_NOMEM_BKPT; |
| 86686 | + pTask->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pTask->pSorter->pKeyInfo); |
| 86687 | + if( pTask->pUnpacked==0 ) return SQLITE_NOMEM_BKPT; |
| 86490 | 86688 | pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nField; |
| 86491 | 86689 | pTask->pUnpacked->errCode = 0; |
| 86492 | 86690 | } |
| 86493 | 86691 | return SQLITE_OK; |
| 86494 | 86692 | } |
| | @@ -87885,13 +88083,11 @@ |
| 87885 | 88083 | assert( pCsr->eCurType==CURTYPE_SORTER ); |
| 87886 | 88084 | pSorter = pCsr->uc.pSorter; |
| 87887 | 88085 | r2 = pSorter->pUnpacked; |
| 87888 | 88086 | pKeyInfo = pCsr->pKeyInfo; |
| 87889 | 88087 | if( r2==0 ){ |
| 87890 | | - char *p; |
| 87891 | | - r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo,0,0,&p); |
| 87892 | | - assert( pSorter->pUnpacked==(UnpackedRecord*)p ); |
| 88088 | + r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); |
| 87893 | 88089 | if( r2==0 ) return SQLITE_NOMEM_BKPT; |
| 87894 | 88090 | r2->nField = nKeyCol; |
| 87895 | 88091 | } |
| 87896 | 88092 | assert( r2->nField==nKeyCol ); |
| 87897 | 88093 | |
| | @@ -90973,11 +91169,11 @@ |
| 90973 | 91169 | ** |
| 90974 | 91170 | ** Wildcards consisting of a single "?" are assigned the next sequential |
| 90975 | 91171 | ** variable number. |
| 90976 | 91172 | ** |
| 90977 | 91173 | ** Wildcards of the form "?nnn" are assigned the number "nnn". We make |
| 90978 | | -** sure "nnn" is not too be to avoid a denial of service attack when |
| 91174 | +** sure "nnn" is not too big to avoid a denial of service attack when |
| 90979 | 91175 | ** the SQL statement comes from an external source. |
| 90980 | 91176 | ** |
| 90981 | 91177 | ** Wildcards of the form ":aaa", "@aaa", or "$aaa" are assigned the same number |
| 90982 | 91178 | ** as the previous instance of the same wildcard. Or if this is the first |
| 90983 | 91179 | ** instance of the wildcard, the next sequential variable number is |
| | @@ -90984,10 +91180,11 @@ |
| 90984 | 91180 | ** assigned. |
| 90985 | 91181 | */ |
| 90986 | 91182 | SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){ |
| 90987 | 91183 | sqlite3 *db = pParse->db; |
| 90988 | 91184 | const char *z; |
| 91185 | + ynVar x; |
| 90989 | 91186 | |
| 90990 | 91187 | if( pExpr==0 ) return; |
| 90991 | 91188 | assert( !ExprHasProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) ); |
| 90992 | 91189 | z = pExpr->u.zToken; |
| 90993 | 91190 | assert( z!=0 ); |
| | @@ -90994,13 +91191,13 @@ |
| 90994 | 91191 | assert( z[0]!=0 ); |
| 90995 | 91192 | assert( n==sqlite3Strlen30(z) ); |
| 90996 | 91193 | if( z[1]==0 ){ |
| 90997 | 91194 | /* Wildcard of the form "?". Assign the next variable number */ |
| 90998 | 91195 | assert( z[0]=='?' ); |
| 90999 | | - pExpr->iColumn = (ynVar)(++pParse->nVar); |
| 91196 | + x = (ynVar)(++pParse->nVar); |
| 91000 | 91197 | }else{ |
| 91001 | | - ynVar x; |
| 91198 | + int doAdd = 0; |
| 91002 | 91199 | if( z[0]=='?' ){ |
| 91003 | 91200 | /* Wildcard of the form "?nnn". Convert "nnn" to an integer and |
| 91004 | 91201 | ** use it as the variable number */ |
| 91005 | 91202 | i64 i; |
| 91006 | 91203 | int bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8); |
| | @@ -91012,44 +91209,33 @@ |
| 91012 | 91209 | if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ |
| 91013 | 91210 | sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d", |
| 91014 | 91211 | db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]); |
| 91015 | 91212 | return; |
| 91016 | 91213 | } |
| 91017 | | - if( i>pParse->nVar ){ |
| 91018 | | - pParse->nVar = (int)i; |
| 91214 | + if( x>pParse->nVar ){ |
| 91215 | + pParse->nVar = (int)x; |
| 91216 | + doAdd = 1; |
| 91217 | + }else if( sqlite3VListNumToName(pParse->pVList, x)==0 ){ |
| 91218 | + doAdd = 1; |
| 91019 | 91219 | } |
| 91020 | 91220 | }else{ |
| 91021 | 91221 | /* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable |
| 91022 | 91222 | ** number as the prior appearance of the same name, or if the name |
| 91023 | 91223 | ** has never appeared before, reuse the same variable number |
| 91024 | 91224 | */ |
| 91025 | | - ynVar i; |
| 91026 | | - for(i=x=0; i<pParse->nzVar; i++){ |
| 91027 | | - if( pParse->azVar[i] && strcmp(pParse->azVar[i],z)==0 ){ |
| 91028 | | - x = (ynVar)i+1; |
| 91029 | | - break; |
| 91030 | | - } |
| 91031 | | - } |
| 91032 | | - if( x==0 ) x = (ynVar)(++pParse->nVar); |
| 91033 | | - } |
| 91034 | | - pExpr->iColumn = x; |
| 91035 | | - if( x>pParse->nzVar ){ |
| 91036 | | - char **a; |
| 91037 | | - a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0])); |
| 91038 | | - if( a==0 ){ |
| 91039 | | - assert( db->mallocFailed ); /* Error reported through mallocFailed */ |
| 91040 | | - return; |
| 91041 | | - } |
| 91042 | | - pParse->azVar = a; |
| 91043 | | - memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0])); |
| 91044 | | - pParse->nzVar = x; |
| 91045 | | - } |
| 91046 | | - if( pParse->azVar[x-1]==0 ){ |
| 91047 | | - pParse->azVar[x-1] = sqlite3DbStrNDup(db, z, n); |
| 91048 | | - } |
| 91049 | | - } |
| 91050 | | - if( pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ |
| 91225 | + x = (ynVar)sqlite3VListNameToNum(pParse->pVList, z, n); |
| 91226 | + if( x==0 ){ |
| 91227 | + x = (ynVar)(++pParse->nVar); |
| 91228 | + doAdd = 1; |
| 91229 | + } |
| 91230 | + } |
| 91231 | + if( doAdd ){ |
| 91232 | + pParse->pVList = sqlite3VListAdd(db, pParse->pVList, z, n, x); |
| 91233 | + } |
| 91234 | + } |
| 91235 | + pExpr->iColumn = x; |
| 91236 | + if( x>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ |
| 91051 | 91237 | sqlite3ErrorMsg(pParse, "too many SQL variables"); |
| 91052 | 91238 | } |
| 91053 | 91239 | } |
| 91054 | 91240 | |
| 91055 | 91241 | /* |
| | @@ -91404,11 +91590,11 @@ |
| 91404 | 91590 | pNewItem->u1.pFuncArg = |
| 91405 | 91591 | sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags); |
| 91406 | 91592 | } |
| 91407 | 91593 | pTab = pNewItem->pTab = pOldItem->pTab; |
| 91408 | 91594 | if( pTab ){ |
| 91409 | | - pTab->nRef++; |
| 91595 | + pTab->nTabRef++; |
| 91410 | 91596 | } |
| 91411 | 91597 | pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags); |
| 91412 | 91598 | pNewItem->pOn = sqlite3ExprDup(db, pOldItem->pOn, flags); |
| 91413 | 91599 | pNewItem->pUsing = sqlite3IdListDup(db, pOldItem->pUsing); |
| 91414 | 91600 | pNewItem->colUsed = pOldItem->colUsed; |
| | @@ -93469,13 +93655,14 @@ |
| 93469 | 93655 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); |
| 93470 | 93656 | assert( pExpr->u.zToken!=0 ); |
| 93471 | 93657 | assert( pExpr->u.zToken[0]!=0 ); |
| 93472 | 93658 | sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target); |
| 93473 | 93659 | if( pExpr->u.zToken[1]!=0 ){ |
| 93474 | | - assert( pExpr->u.zToken[0]=='?' |
| 93475 | | - || strcmp(pExpr->u.zToken, pParse->azVar[pExpr->iColumn-1])==0 ); |
| 93476 | | - sqlite3VdbeAppendP4(v, pParse->azVar[pExpr->iColumn-1], P4_STATIC); |
| 93660 | + const char *z = sqlite3VListNumToName(pParse->pVList, pExpr->iColumn); |
| 93661 | + assert( pExpr->u.zToken[0]=='?' || strcmp(pExpr->u.zToken, z)==0 ); |
| 93662 | + pParse->pVList[0] = 0; /* Indicate VList may no longer be enlarged */ |
| 93663 | + sqlite3VdbeAppendP4(v, (char*)z, P4_STATIC); |
| 93477 | 93664 | } |
| 93478 | 93665 | return target; |
| 93479 | 93666 | } |
| 93480 | 93667 | case TK_REGISTER: { |
| 93481 | 93668 | return pExpr->iTable; |
| | @@ -95596,11 +95783,11 @@ |
| 95596 | 95783 | ** for which the renamed table is the parent table. */ |
| 95597 | 95784 | if( (zWhere=whereForeignKeys(pParse, pTab))!=0 ){ |
| 95598 | 95785 | sqlite3NestedParse(pParse, |
| 95599 | 95786 | "UPDATE \"%w\".%s SET " |
| 95600 | 95787 | "sql = sqlite_rename_parent(sql, %Q, %Q) " |
| 95601 | | - "WHERE %s;", zDb, SCHEMA_TABLE(iDb), zTabName, zName, zWhere); |
| 95788 | + "WHERE %s;", zDb, MASTER_NAME, zTabName, zName, zWhere); |
| 95602 | 95789 | sqlite3DbFree(db, zWhere); |
| 95603 | 95790 | } |
| 95604 | 95791 | } |
| 95605 | 95792 | #endif |
| 95606 | 95793 | |
| | @@ -95620,11 +95807,11 @@ |
| 95620 | 95807 | "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN " |
| 95621 | 95808 | "'sqlite_autoindex_' || %Q || substr(name,%d+18) " |
| 95622 | 95809 | "ELSE name END " |
| 95623 | 95810 | "WHERE tbl_name=%Q COLLATE nocase AND " |
| 95624 | 95811 | "(type='table' OR type='index' OR type='trigger');", |
| 95625 | | - zDb, SCHEMA_TABLE(iDb), zName, zName, zName, |
| 95812 | + zDb, MASTER_NAME, zName, zName, zName, |
| 95626 | 95813 | #ifndef SQLITE_OMIT_TRIGGER |
| 95627 | 95814 | zName, |
| 95628 | 95815 | #endif |
| 95629 | 95816 | zName, nTabName, zTabName |
| 95630 | 95817 | ); |
| | @@ -95781,11 +95968,11 @@ |
| 95781 | 95968 | db->flags |= SQLITE_PreferBuiltin; |
| 95782 | 95969 | sqlite3NestedParse(pParse, |
| 95783 | 95970 | "UPDATE \"%w\".%s SET " |
| 95784 | 95971 | "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) " |
| 95785 | 95972 | "WHERE type = 'table' AND name = %Q", |
| 95786 | | - zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1, |
| 95973 | + zDb, MASTER_NAME, pNew->addColOffset, zCol, pNew->addColOffset+1, |
| 95787 | 95974 | zTab |
| 95788 | 95975 | ); |
| 95789 | 95976 | sqlite3DbFree(db, zCol); |
| 95790 | 95977 | db->flags = savedDbFlags; |
| 95791 | 95978 | } |
| | @@ -95865,11 +96052,11 @@ |
| 95865 | 96052 | ** prefix on their name. |
| 95866 | 96053 | */ |
| 95867 | 96054 | pNew = (Table*)sqlite3DbMallocZero(db, sizeof(Table)); |
| 95868 | 96055 | if( !pNew ) goto exit_begin_add_column; |
| 95869 | 96056 | pParse->pNewTable = pNew; |
| 95870 | | - pNew->nRef = 1; |
| 96057 | + pNew->nTabRef = 1; |
| 95871 | 96058 | pNew->nCol = pTab->nCol; |
| 95872 | 96059 | assert( pNew->nCol>0 ); |
| 95873 | 96060 | nAlloc = (((pNew->nCol-1)/8)*8)+8; |
| 95874 | 96061 | assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 ); |
| 95875 | 96062 | pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nAlloc); |
| | @@ -95885,11 +96072,11 @@ |
| 95885 | 96072 | pCol->zColl = 0; |
| 95886 | 96073 | pCol->pDflt = 0; |
| 95887 | 96074 | } |
| 95888 | 96075 | pNew->pSchema = db->aDb[iDb].pSchema; |
| 95889 | 96076 | pNew->addColOffset = pTab->addColOffset; |
| 95890 | | - pNew->nRef = 1; |
| 96077 | + pNew->nTabRef = 1; |
| 95891 | 96078 | |
| 95892 | 96079 | /* Begin a transaction and increment the schema cookie. */ |
| 95893 | 96080 | sqlite3BeginWriteOperation(pParse, 0, iDb); |
| 95894 | 96081 | v = sqlite3GetVdbe(pParse); |
| 95895 | 96082 | if( !v ) goto exit_begin_add_column; |
| | @@ -98672,14 +98859,14 @@ |
| 98672 | 98859 | /* |
| 98673 | 98860 | ** The TableLock structure is only used by the sqlite3TableLock() and |
| 98674 | 98861 | ** codeTableLocks() functions. |
| 98675 | 98862 | */ |
| 98676 | 98863 | struct TableLock { |
| 98677 | | - int iDb; /* The database containing the table to be locked */ |
| 98678 | | - int iTab; /* The root page of the table to be locked */ |
| 98679 | | - u8 isWriteLock; /* True for write lock. False for a read lock */ |
| 98680 | | - const char *zName; /* Name of the table */ |
| 98864 | + int iDb; /* The database containing the table to be locked */ |
| 98865 | + int iTab; /* The root page of the table to be locked */ |
| 98866 | + u8 isWriteLock; /* True for write lock. False for a read lock */ |
| 98867 | + const char *zLockName; /* Name of the table */ |
| 98681 | 98868 | }; |
| 98682 | 98869 | |
| 98683 | 98870 | /* |
| 98684 | 98871 | ** Record the fact that we want to lock a table at run-time. |
| 98685 | 98872 | ** |
| | @@ -98719,11 +98906,11 @@ |
| 98719 | 98906 | if( pToplevel->aTableLock ){ |
| 98720 | 98907 | p = &pToplevel->aTableLock[pToplevel->nTableLock++]; |
| 98721 | 98908 | p->iDb = iDb; |
| 98722 | 98909 | p->iTab = iTab; |
| 98723 | 98910 | p->isWriteLock = isWriteLock; |
| 98724 | | - p->zName = zName; |
| 98911 | + p->zLockName = zName; |
| 98725 | 98912 | }else{ |
| 98726 | 98913 | pToplevel->nTableLock = 0; |
| 98727 | 98914 | sqlite3OomFault(pToplevel->db); |
| 98728 | 98915 | } |
| 98729 | 98916 | } |
| | @@ -98741,11 +98928,11 @@ |
| 98741 | 98928 | |
| 98742 | 98929 | for(i=0; i<pParse->nTableLock; i++){ |
| 98743 | 98930 | TableLock *p = &pParse->aTableLock[i]; |
| 98744 | 98931 | int p1 = p->iDb; |
| 98745 | 98932 | sqlite3VdbeAddOp4(pVdbe, OP_TableLock, p1, p->iTab, p->isWriteLock, |
| 98746 | | - p->zName, P4_STATIC); |
| 98933 | + p->zLockName, P4_STATIC); |
| 98747 | 98934 | } |
| 98748 | 98935 | } |
| 98749 | 98936 | #else |
| 98750 | 98937 | #define codeTableLocks(x) |
| 98751 | 98938 | #endif |
| | @@ -98950,19 +99137,26 @@ |
| 98950 | 99137 | ** exists */ |
| 98951 | 99138 | if( db->auth.authLevel<UAUTH_Admin && sqlite3UserAuthTable(zName)!=0 ){ |
| 98952 | 99139 | return 0; |
| 98953 | 99140 | } |
| 98954 | 99141 | #endif |
| 98955 | | - for(i=OMIT_TEMPDB; i<db->nDb; i++){ |
| 98956 | | - int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ |
| 98957 | | - if( zDatabase==0 || sqlite3StrICmp(zDatabase, db->aDb[j].zDbSName)==0 ){ |
| 98958 | | - assert( sqlite3SchemaMutexHeld(db, j, 0) ); |
| 98959 | | - p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName); |
| 98960 | | - if( p ) break; |
| 98961 | | - } |
| 98962 | | - } |
| 98963 | | - return p; |
| 99142 | + while(1){ |
| 99143 | + for(i=OMIT_TEMPDB; i<db->nDb; i++){ |
| 99144 | + int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ |
| 99145 | + if( zDatabase==0 || sqlite3StrICmp(zDatabase, db->aDb[j].zDbSName)==0 ){ |
| 99146 | + assert( sqlite3SchemaMutexHeld(db, j, 0) ); |
| 99147 | + p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName); |
| 99148 | + if( p ) return p; |
| 99149 | + } |
| 99150 | + } |
| 99151 | + /* Not found. If the name we were looking for was temp.sqlite_master |
| 99152 | + ** then change the name to sqlite_temp_master and try again. */ |
| 99153 | + if( sqlite3StrICmp(zName, MASTER_NAME)!=0 ) break; |
| 99154 | + if( sqlite3_stricmp(zDatabase, db->aDb[1].zDbSName)!=0 ) break; |
| 99155 | + zName = TEMP_MASTER_NAME; |
| 99156 | + } |
| 99157 | + return 0; |
| 98964 | 99158 | } |
| 98965 | 99159 | |
| 98966 | 99160 | /* |
| 98967 | 99161 | ** Locate the in-memory structure that describes a particular database |
| 98968 | 99162 | ** table given the name of that table and (optionally) the name of the |
| | @@ -98994,10 +99188,13 @@ |
| 98994 | 99188 | if( sqlite3FindDbName(pParse->db, zDbase)<1 ){ |
| 98995 | 99189 | /* If zName is the not the name of a table in the schema created using |
| 98996 | 99190 | ** CREATE, then check to see if it is the name of an virtual table that |
| 98997 | 99191 | ** can be an eponymous virtual table. */ |
| 98998 | 99192 | Module *pMod = (Module*)sqlite3HashFind(&pParse->db->aModule, zName); |
| 99193 | + if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){ |
| 99194 | + pMod = sqlite3PragmaVtabRegister(pParse->db, zName); |
| 99195 | + } |
| 98999 | 99196 | if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){ |
| 99000 | 99197 | return pMod->pEpoTab; |
| 99001 | 99198 | } |
| 99002 | 99199 | } |
| 99003 | 99200 | #endif |
| | @@ -99276,11 +99473,11 @@ |
| 99276 | 99473 | assert( nLookaside==0 || nLookaside==db->lookaside.nOut ); |
| 99277 | 99474 | } |
| 99278 | 99475 | SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ |
| 99279 | 99476 | /* Do not delete the table until the reference count reaches zero. */ |
| 99280 | 99477 | if( !pTable ) return; |
| 99281 | | - if( ((!db || db->pnBytesFreed==0) && (--pTable->nRef)>0) ) return; |
| 99478 | + if( ((!db || db->pnBytesFreed==0) && (--pTable->nTabRef)>0) ) return; |
| 99282 | 99479 | deleteTable(db, pTable); |
| 99283 | 99480 | } |
| 99284 | 99481 | |
| 99285 | 99482 | |
| 99286 | 99483 | /* |
| | @@ -99330,11 +99527,11 @@ |
| 99330 | 99527 | ** Open the sqlite_master table stored in database number iDb for |
| 99331 | 99528 | ** writing. The table is opened using cursor 0. |
| 99332 | 99529 | */ |
| 99333 | 99530 | SQLITE_PRIVATE void sqlite3OpenMasterTable(Parse *p, int iDb){ |
| 99334 | 99531 | Vdbe *v = sqlite3GetVdbe(p); |
| 99335 | | - sqlite3TableLock(p, iDb, MASTER_ROOT, 1, SCHEMA_TABLE(iDb)); |
| 99532 | + sqlite3TableLock(p, iDb, MASTER_ROOT, 1, MASTER_NAME); |
| 99336 | 99533 | sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, MASTER_ROOT, iDb, 5); |
| 99337 | 99534 | if( p->nTab==0 ){ |
| 99338 | 99535 | p->nTab = 1; |
| 99339 | 99536 | } |
| 99340 | 99537 | } |
| | @@ -99567,11 +99764,11 @@ |
| 99567 | 99764 | goto begin_table_error; |
| 99568 | 99765 | } |
| 99569 | 99766 | pTable->zName = zName; |
| 99570 | 99767 | pTable->iPKey = -1; |
| 99571 | 99768 | pTable->pSchema = db->aDb[iDb].pSchema; |
| 99572 | | - pTable->nRef = 1; |
| 99769 | + pTable->nTabRef = 1; |
| 99573 | 99770 | pTable->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); |
| 99574 | 99771 | assert( pParse->pNewTable==0 ); |
| 99575 | 99772 | pParse->pNewTable = pTable; |
| 99576 | 99773 | |
| 99577 | 99774 | /* If this is the magic sqlite_sequence table used by autoincrement, |
| | @@ -100633,11 +100830,11 @@ |
| 100633 | 100830 | */ |
| 100634 | 100831 | sqlite3NestedParse(pParse, |
| 100635 | 100832 | "UPDATE %Q.%s " |
| 100636 | 100833 | "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q " |
| 100637 | 100834 | "WHERE rowid=#%d", |
| 100638 | | - db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), |
| 100835 | + db->aDb[iDb].zDbSName, MASTER_NAME, |
| 100639 | 100836 | zType, |
| 100640 | 100837 | p->zName, |
| 100641 | 100838 | p->zName, |
| 100642 | 100839 | pParse->regRoot, |
| 100643 | 100840 | zStmt, |
| | @@ -100970,11 +101167,11 @@ |
| 100970 | 101167 | ** is in register NNN. See grammar rules associated with the TK_REGISTER |
| 100971 | 101168 | ** token for additional information. |
| 100972 | 101169 | */ |
| 100973 | 101170 | sqlite3NestedParse(pParse, |
| 100974 | 101171 | "UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d", |
| 100975 | | - pParse->db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), iTable, r1, r1); |
| 101172 | + pParse->db->aDb[iDb].zDbSName, MASTER_NAME, iTable, r1, r1); |
| 100976 | 101173 | #endif |
| 100977 | 101174 | sqlite3ReleaseTempReg(pParse, r1); |
| 100978 | 101175 | } |
| 100979 | 101176 | |
| 100980 | 101177 | /* |
| | @@ -101113,11 +101310,11 @@ |
| 101113 | 101310 | ** created in the temp database that refers to a table in another |
| 101114 | 101311 | ** database. |
| 101115 | 101312 | */ |
| 101116 | 101313 | sqlite3NestedParse(pParse, |
| 101117 | 101314 | "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'", |
| 101118 | | - pDb->zDbSName, SCHEMA_TABLE(iDb), pTab->zName); |
| 101315 | + pDb->zDbSName, MASTER_NAME, pTab->zName); |
| 101119 | 101316 | if( !isView && !IsVirtual(pTab) ){ |
| 101120 | 101317 | destroyTable(pParse, pTab); |
| 101121 | 101318 | } |
| 101122 | 101319 | |
| 101123 | 101320 | /* Remove the table entry from SQLite's internal schema and modify |
| | @@ -102005,11 +102202,11 @@ |
| 102005 | 102202 | |
| 102006 | 102203 | /* Add an entry in sqlite_master for this index |
| 102007 | 102204 | */ |
| 102008 | 102205 | sqlite3NestedParse(pParse, |
| 102009 | 102206 | "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);", |
| 102010 | | - db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), |
| 102207 | + db->aDb[iDb].zDbSName, MASTER_NAME, |
| 102011 | 102208 | pIndex->zName, |
| 102012 | 102209 | pTab->zName, |
| 102013 | 102210 | iMem, |
| 102014 | 102211 | zStmt |
| 102015 | 102212 | ); |
| | @@ -102157,11 +102354,11 @@ |
| 102157 | 102354 | v = sqlite3GetVdbe(pParse); |
| 102158 | 102355 | if( v ){ |
| 102159 | 102356 | sqlite3BeginWriteOperation(pParse, 1, iDb); |
| 102160 | 102357 | sqlite3NestedParse(pParse, |
| 102161 | 102358 | "DELETE FROM %Q.%s WHERE name=%Q AND type='index'", |
| 102162 | | - db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), pIndex->zName |
| 102359 | + db->aDb[iDb].zDbSName, MASTER_NAME, pIndex->zName |
| 102163 | 102360 | ); |
| 102164 | 102361 | sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName); |
| 102165 | 102362 | sqlite3ChangeCookie(pParse, iDb); |
| 102166 | 102363 | destroyRootPage(pParse, pIndex->tnum, iDb); |
| 102167 | 102364 | sqlite3VdbeAddOp4(v, OP_DropIndex, iDb, 0, 0, pIndex->zName, 0); |
| | @@ -102300,11 +102497,11 @@ |
| 102300 | 102497 | assert( iStart<=pSrc->nSrc ); |
| 102301 | 102498 | |
| 102302 | 102499 | /* Allocate additional space if needed */ |
| 102303 | 102500 | if( (u32)pSrc->nSrc+nExtra>pSrc->nAlloc ){ |
| 102304 | 102501 | SrcList *pNew; |
| 102305 | | - int nAlloc = pSrc->nSrc+nExtra; |
| 102502 | + int nAlloc = pSrc->nSrc*2+nExtra; |
| 102306 | 102503 | int nGot; |
| 102307 | 102504 | pNew = sqlite3DbRealloc(db, pSrc, |
| 102308 | 102505 | sizeof(*pSrc) + (nAlloc-1)*sizeof(pSrc->a[0]) ); |
| 102309 | 102506 | if( pNew==0 ){ |
| 102310 | 102507 | assert( db->mallocFailed ); |
| | @@ -102378,13 +102575,16 @@ |
| 102378 | 102575 | assert( db!=0 ); |
| 102379 | 102576 | if( pList==0 ){ |
| 102380 | 102577 | pList = sqlite3DbMallocRawNN(db, sizeof(SrcList) ); |
| 102381 | 102578 | if( pList==0 ) return 0; |
| 102382 | 102579 | pList->nAlloc = 1; |
| 102383 | | - pList->nSrc = 0; |
| 102580 | + pList->nSrc = 1; |
| 102581 | + memset(&pList->a[0], 0, sizeof(pList->a[0])); |
| 102582 | + pList->a[0].iCursor = -1; |
| 102583 | + }else{ |
| 102584 | + pList = sqlite3SrcListEnlarge(db, pList, 1, pList->nSrc); |
| 102384 | 102585 | } |
| 102385 | | - pList = sqlite3SrcListEnlarge(db, pList, 1, pList->nSrc); |
| 102386 | 102586 | if( db->mallocFailed ){ |
| 102387 | 102587 | sqlite3SrcListDelete(db, pList); |
| 102388 | 102588 | return 0; |
| 102389 | 102589 | } |
| 102390 | 102590 | pItem = &pList->a[pList->nSrc-1]; |
| | @@ -103595,11 +103795,11 @@ |
| 103595 | 103795 | assert( pItem && pSrc->nSrc==1 ); |
| 103596 | 103796 | pTab = sqlite3LocateTableItem(pParse, 0, pItem); |
| 103597 | 103797 | sqlite3DeleteTable(pParse->db, pItem->pTab); |
| 103598 | 103798 | pItem->pTab = pTab; |
| 103599 | 103799 | if( pTab ){ |
| 103600 | | - pTab->nRef++; |
| 103800 | + pTab->nTabRef++; |
| 103601 | 103801 | } |
| 103602 | 103802 | if( sqlite3IndexedByLookup(pParse, pItem) ){ |
| 103603 | 103803 | pTab = 0; |
| 103604 | 103804 | } |
| 103605 | 103805 | return pTab; |
| | @@ -106544,11 +106744,11 @@ |
| 106544 | 106744 | if( !aiCol ) return 1; |
| 106545 | 106745 | *paiCol = aiCol; |
| 106546 | 106746 | } |
| 106547 | 106747 | |
| 106548 | 106748 | for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 106549 | | - if( pIdx->nKeyCol==nCol && IsUniqueIndex(pIdx) ){ |
| 106749 | + if( pIdx->nKeyCol==nCol && IsUniqueIndex(pIdx) && pIdx->pPartIdxWhere==0 ){ |
| 106550 | 106750 | /* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number |
| 106551 | 106751 | ** of columns. If each indexed column corresponds to a foreign key |
| 106552 | 106752 | ** column of pFKey, then this index is a winner. */ |
| 106553 | 106753 | |
| 106554 | 106754 | if( zKey==0 ){ |
| | @@ -107326,11 +107526,11 @@ |
| 107326 | 107526 | pSrc = sqlite3SrcListAppend(db, 0, 0, 0); |
| 107327 | 107527 | if( pSrc ){ |
| 107328 | 107528 | struct SrcList_item *pItem = pSrc->a; |
| 107329 | 107529 | pItem->pTab = pFKey->pFrom; |
| 107330 | 107530 | pItem->zName = pFKey->pFrom->zName; |
| 107331 | | - pItem->pTab->nRef++; |
| 107531 | + pItem->pTab->nTabRef++; |
| 107332 | 107532 | pItem->iCursor = pParse->nTab++; |
| 107333 | 107533 | |
| 107334 | 107534 | if( regNew!=0 ){ |
| 107335 | 107535 | fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1); |
| 107336 | 107536 | } |
| | @@ -111477,10 +111677,12 @@ |
| 111477 | 111677 | /* DO NOT EDIT! |
| 111478 | 111678 | ** This file is automatically generated by the script at |
| 111479 | 111679 | ** ../tool/mkpragmatab.tcl. To update the set of pragmas, edit |
| 111480 | 111680 | ** that script and rerun it. |
| 111481 | 111681 | */ |
| 111682 | + |
| 111683 | +/* The various pragma types */ |
| 111482 | 111684 | #define PragTyp_HEADER_VALUE 0 |
| 111483 | 111685 | #define PragTyp_AUTO_VACUUM 1 |
| 111484 | 111686 | #define PragTyp_FLAG 2 |
| 111485 | 111687 | #define PragTyp_BUSY_TIMEOUT 3 |
| 111486 | 111688 | #define PragTyp_CACHE_SIZE 4 |
| | @@ -111520,423 +111722,563 @@ |
| 111520 | 111722 | #define PragTyp_HEXKEY 38 |
| 111521 | 111723 | #define PragTyp_KEY 39 |
| 111522 | 111724 | #define PragTyp_REKEY 40 |
| 111523 | 111725 | #define PragTyp_LOCK_STATUS 41 |
| 111524 | 111726 | #define PragTyp_PARSER_TRACE 42 |
| 111525 | | -#define PragFlag_NeedSchema 0x01 |
| 111526 | | -#define PragFlag_ReadOnly 0x02 |
| 111527 | | -static const struct sPragmaNames { |
| 111528 | | - const char *const zName; /* Name of pragma */ |
| 111529 | | - u8 ePragTyp; /* PragTyp_XXX value */ |
| 111530 | | - u8 mPragFlag; /* Zero or more PragFlag_XXX values */ |
| 111531 | | - u32 iArg; /* Extra argument */ |
| 111532 | | -} aPragmaNames[] = { |
| 111533 | | -#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD) |
| 111534 | | - { /* zName: */ "activate_extensions", |
| 111535 | | - /* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS, |
| 111536 | | - /* ePragFlag: */ 0, |
| 111537 | | - /* iArg: */ 0 }, |
| 111538 | | -#endif |
| 111539 | | -#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) |
| 111540 | | - { /* zName: */ "application_id", |
| 111541 | | - /* ePragTyp: */ PragTyp_HEADER_VALUE, |
| 111542 | | - /* ePragFlag: */ 0, |
| 111543 | | - /* iArg: */ BTREE_APPLICATION_ID }, |
| 111544 | | -#endif |
| 111545 | | -#if !defined(SQLITE_OMIT_AUTOVACUUM) |
| 111546 | | - { /* zName: */ "auto_vacuum", |
| 111547 | | - /* ePragTyp: */ PragTyp_AUTO_VACUUM, |
| 111548 | | - /* ePragFlag: */ PragFlag_NeedSchema, |
| 111549 | | - /* iArg: */ 0 }, |
| 111550 | | -#endif |
| 111551 | | -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 111552 | | -#if !defined(SQLITE_OMIT_AUTOMATIC_INDEX) |
| 111553 | | - { /* zName: */ "automatic_index", |
| 111554 | | - /* ePragTyp: */ PragTyp_FLAG, |
| 111555 | | - /* ePragFlag: */ 0, |
| 111556 | | - /* iArg: */ SQLITE_AutoIndex }, |
| 111557 | | -#endif |
| 111558 | | -#endif |
| 111559 | | - { /* zName: */ "busy_timeout", |
| 111560 | | - /* ePragTyp: */ PragTyp_BUSY_TIMEOUT, |
| 111561 | | - /* ePragFlag: */ 0, |
| 111562 | | - /* iArg: */ 0 }, |
| 111563 | | -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 111564 | | - { /* zName: */ "cache_size", |
| 111565 | | - /* ePragTyp: */ PragTyp_CACHE_SIZE, |
| 111566 | | - /* ePragFlag: */ PragFlag_NeedSchema, |
| 111567 | | - /* iArg: */ 0 }, |
| 111568 | | -#endif |
| 111569 | | -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 111570 | | - { /* zName: */ "cache_spill", |
| 111571 | | - /* ePragTyp: */ PragTyp_CACHE_SPILL, |
| 111572 | | - /* ePragFlag: */ 0, |
| 111573 | | - /* iArg: */ 0 }, |
| 111574 | | -#endif |
| 111575 | | - { /* zName: */ "case_sensitive_like", |
| 111576 | | - /* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE, |
| 111577 | | - /* ePragFlag: */ 0, |
| 111578 | | - /* iArg: */ 0 }, |
| 111579 | | - { /* zName: */ "cell_size_check", |
| 111580 | | - /* ePragTyp: */ PragTyp_FLAG, |
| 111581 | | - /* ePragFlag: */ 0, |
| 111582 | | - /* iArg: */ SQLITE_CellSizeCk }, |
| 111583 | | -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 111584 | | - { /* zName: */ "checkpoint_fullfsync", |
| 111585 | | - /* ePragTyp: */ PragTyp_FLAG, |
| 111586 | | - /* ePragFlag: */ 0, |
| 111587 | | - /* iArg: */ SQLITE_CkptFullFSync }, |
| 111588 | | -#endif |
| 111589 | | -#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) |
| 111590 | | - { /* zName: */ "collation_list", |
| 111591 | | - /* ePragTyp: */ PragTyp_COLLATION_LIST, |
| 111592 | | - /* ePragFlag: */ 0, |
| 111593 | | - /* iArg: */ 0 }, |
| 111594 | | -#endif |
| 111595 | | -#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) |
| 111596 | | - { /* zName: */ "compile_options", |
| 111597 | | - /* ePragTyp: */ PragTyp_COMPILE_OPTIONS, |
| 111598 | | - /* ePragFlag: */ 0, |
| 111599 | | - /* iArg: */ 0 }, |
| 111600 | | -#endif |
| 111601 | | -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 111602 | | - { /* zName: */ "count_changes", |
| 111603 | | - /* ePragTyp: */ PragTyp_FLAG, |
| 111604 | | - /* ePragFlag: */ 0, |
| 111605 | | - /* iArg: */ SQLITE_CountRows }, |
| 111606 | | -#endif |
| 111607 | | -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN |
| 111608 | | - { /* zName: */ "data_store_directory", |
| 111609 | | - /* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY, |
| 111610 | | - /* ePragFlag: */ 0, |
| 111611 | | - /* iArg: */ 0 }, |
| 111612 | | -#endif |
| 111613 | | -#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) |
| 111614 | | - { /* zName: */ "data_version", |
| 111615 | | - /* ePragTyp: */ PragTyp_HEADER_VALUE, |
| 111616 | | - /* ePragFlag: */ PragFlag_ReadOnly, |
| 111617 | | - /* iArg: */ BTREE_DATA_VERSION }, |
| 111618 | | -#endif |
| 111619 | | -#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) |
| 111620 | | - { /* zName: */ "database_list", |
| 111621 | | - /* ePragTyp: */ PragTyp_DATABASE_LIST, |
| 111622 | | - /* ePragFlag: */ PragFlag_NeedSchema, |
| 111623 | | - /* iArg: */ 0 }, |
| 111624 | | -#endif |
| 111625 | | -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) |
| 111626 | | - { /* zName: */ "default_cache_size", |
| 111627 | | - /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE, |
| 111628 | | - /* ePragFlag: */ PragFlag_NeedSchema, |
| 111629 | | - /* iArg: */ 0 }, |
| 111630 | | -#endif |
| 111631 | | -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 111632 | | -#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) |
| 111633 | | - { /* zName: */ "defer_foreign_keys", |
| 111634 | | - /* ePragTyp: */ PragTyp_FLAG, |
| 111635 | | - /* ePragFlag: */ 0, |
| 111636 | | - /* iArg: */ SQLITE_DeferFKs }, |
| 111637 | | -#endif |
| 111638 | | -#endif |
| 111639 | | -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 111640 | | - { /* zName: */ "empty_result_callbacks", |
| 111641 | | - /* ePragTyp: */ PragTyp_FLAG, |
| 111642 | | - /* ePragFlag: */ 0, |
| 111643 | | - /* iArg: */ SQLITE_NullCallback }, |
| 111644 | | -#endif |
| 111645 | | -#if !defined(SQLITE_OMIT_UTF16) |
| 111646 | | - { /* zName: */ "encoding", |
| 111647 | | - /* ePragTyp: */ PragTyp_ENCODING, |
| 111648 | | - /* ePragFlag: */ 0, |
| 111649 | | - /* iArg: */ 0 }, |
| 111650 | | -#endif |
| 111651 | | -#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) |
| 111652 | | - { /* zName: */ "foreign_key_check", |
| 111653 | | - /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK, |
| 111654 | | - /* ePragFlag: */ PragFlag_NeedSchema, |
| 111655 | | - /* iArg: */ 0 }, |
| 111656 | | -#endif |
| 111657 | | -#if !defined(SQLITE_OMIT_FOREIGN_KEY) |
| 111658 | | - { /* zName: */ "foreign_key_list", |
| 111659 | | - /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST, |
| 111660 | | - /* ePragFlag: */ PragFlag_NeedSchema, |
| 111661 | | - /* iArg: */ 0 }, |
| 111662 | | -#endif |
| 111663 | | -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 111664 | | -#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) |
| 111665 | | - { /* zName: */ "foreign_keys", |
| 111666 | | - /* ePragTyp: */ PragTyp_FLAG, |
| 111667 | | - /* ePragFlag: */ 0, |
| 111668 | | - /* iArg: */ SQLITE_ForeignKeys }, |
| 111669 | | -#endif |
| 111670 | | -#endif |
| 111671 | | -#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) |
| 111672 | | - { /* zName: */ "freelist_count", |
| 111673 | | - /* ePragTyp: */ PragTyp_HEADER_VALUE, |
| 111674 | | - /* ePragFlag: */ PragFlag_ReadOnly, |
| 111675 | | - /* iArg: */ BTREE_FREE_PAGE_COUNT }, |
| 111676 | | -#endif |
| 111677 | | -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 111678 | | - { /* zName: */ "full_column_names", |
| 111679 | | - /* ePragTyp: */ PragTyp_FLAG, |
| 111680 | | - /* ePragFlag: */ 0, |
| 111681 | | - /* iArg: */ SQLITE_FullColNames }, |
| 111682 | | - { /* zName: */ "fullfsync", |
| 111683 | | - /* ePragTyp: */ PragTyp_FLAG, |
| 111684 | | - /* ePragFlag: */ 0, |
| 111685 | | - /* iArg: */ SQLITE_FullFSync }, |
| 111686 | | -#endif |
| 111687 | | -#if defined(SQLITE_HAS_CODEC) |
| 111688 | | - { /* zName: */ "hexkey", |
| 111689 | | - /* ePragTyp: */ PragTyp_HEXKEY, |
| 111690 | | - /* ePragFlag: */ 0, |
| 111691 | | - /* iArg: */ 0 }, |
| 111692 | | - { /* zName: */ "hexrekey", |
| 111693 | | - /* ePragTyp: */ PragTyp_HEXKEY, |
| 111694 | | - /* ePragFlag: */ 0, |
| 111695 | | - /* iArg: */ 0 }, |
| 111696 | | -#endif |
| 111697 | | -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 111698 | | -#if !defined(SQLITE_OMIT_CHECK) |
| 111699 | | - { /* zName: */ "ignore_check_constraints", |
| 111700 | | - /* ePragTyp: */ PragTyp_FLAG, |
| 111701 | | - /* ePragFlag: */ 0, |
| 111702 | | - /* iArg: */ SQLITE_IgnoreChecks }, |
| 111703 | | -#endif |
| 111704 | | -#endif |
| 111705 | | -#if !defined(SQLITE_OMIT_AUTOVACUUM) |
| 111706 | | - { /* zName: */ "incremental_vacuum", |
| 111707 | | - /* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM, |
| 111708 | | - /* ePragFlag: */ PragFlag_NeedSchema, |
| 111709 | | - /* iArg: */ 0 }, |
| 111710 | | -#endif |
| 111711 | | -#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) |
| 111712 | | - { /* zName: */ "index_info", |
| 111713 | | - /* ePragTyp: */ PragTyp_INDEX_INFO, |
| 111714 | | - /* ePragFlag: */ PragFlag_NeedSchema, |
| 111715 | | - /* iArg: */ 0 }, |
| 111716 | | - { /* zName: */ "index_list", |
| 111717 | | - /* ePragTyp: */ PragTyp_INDEX_LIST, |
| 111718 | | - /* ePragFlag: */ PragFlag_NeedSchema, |
| 111719 | | - /* iArg: */ 0 }, |
| 111720 | | - { /* zName: */ "index_xinfo", |
| 111721 | | - /* ePragTyp: */ PragTyp_INDEX_INFO, |
| 111722 | | - /* ePragFlag: */ PragFlag_NeedSchema, |
| 111723 | | - /* iArg: */ 1 }, |
| 111724 | | -#endif |
| 111725 | | -#if !defined(SQLITE_OMIT_INTEGRITY_CHECK) |
| 111726 | | - { /* zName: */ "integrity_check", |
| 111727 | | - /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, |
| 111728 | | - /* ePragFlag: */ PragFlag_NeedSchema, |
| 111729 | | - /* iArg: */ 0 }, |
| 111730 | | -#endif |
| 111731 | | -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 111732 | | - { /* zName: */ "journal_mode", |
| 111733 | | - /* ePragTyp: */ PragTyp_JOURNAL_MODE, |
| 111734 | | - /* ePragFlag: */ PragFlag_NeedSchema, |
| 111735 | | - /* iArg: */ 0 }, |
| 111736 | | - { /* zName: */ "journal_size_limit", |
| 111737 | | - /* ePragTyp: */ PragTyp_JOURNAL_SIZE_LIMIT, |
| 111738 | | - /* ePragFlag: */ 0, |
| 111739 | | - /* iArg: */ 0 }, |
| 111740 | | -#endif |
| 111741 | | -#if defined(SQLITE_HAS_CODEC) |
| 111742 | | - { /* zName: */ "key", |
| 111743 | | - /* ePragTyp: */ PragTyp_KEY, |
| 111744 | | - /* ePragFlag: */ 0, |
| 111745 | | - /* iArg: */ 0 }, |
| 111746 | | -#endif |
| 111747 | | -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 111748 | | - { /* zName: */ "legacy_file_format", |
| 111749 | | - /* ePragTyp: */ PragTyp_FLAG, |
| 111750 | | - /* ePragFlag: */ 0, |
| 111751 | | - /* iArg: */ SQLITE_LegacyFileFmt }, |
| 111752 | | -#endif |
| 111753 | | -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE |
| 111754 | | - { /* zName: */ "lock_proxy_file", |
| 111755 | | - /* ePragTyp: */ PragTyp_LOCK_PROXY_FILE, |
| 111756 | | - /* ePragFlag: */ 0, |
| 111757 | | - /* iArg: */ 0 }, |
| 111758 | | -#endif |
| 111759 | | -#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) |
| 111760 | | - { /* zName: */ "lock_status", |
| 111761 | | - /* ePragTyp: */ PragTyp_LOCK_STATUS, |
| 111762 | | - /* ePragFlag: */ 0, |
| 111763 | | - /* iArg: */ 0 }, |
| 111764 | | -#endif |
| 111765 | | -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 111766 | | - { /* zName: */ "locking_mode", |
| 111767 | | - /* ePragTyp: */ PragTyp_LOCKING_MODE, |
| 111768 | | - /* ePragFlag: */ 0, |
| 111769 | | - /* iArg: */ 0 }, |
| 111770 | | - { /* zName: */ "max_page_count", |
| 111771 | | - /* ePragTyp: */ PragTyp_PAGE_COUNT, |
| 111772 | | - /* ePragFlag: */ PragFlag_NeedSchema, |
| 111773 | | - /* iArg: */ 0 }, |
| 111774 | | - { /* zName: */ "mmap_size", |
| 111775 | | - /* ePragTyp: */ PragTyp_MMAP_SIZE, |
| 111776 | | - /* ePragFlag: */ 0, |
| 111777 | | - /* iArg: */ 0 }, |
| 111778 | | - { /* zName: */ "page_count", |
| 111779 | | - /* ePragTyp: */ PragTyp_PAGE_COUNT, |
| 111780 | | - /* ePragFlag: */ PragFlag_NeedSchema, |
| 111781 | | - /* iArg: */ 0 }, |
| 111782 | | - { /* zName: */ "page_size", |
| 111783 | | - /* ePragTyp: */ PragTyp_PAGE_SIZE, |
| 111784 | | - /* ePragFlag: */ 0, |
| 111785 | | - /* iArg: */ 0 }, |
| 111786 | | -#endif |
| 111787 | | -#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_PARSER_TRACE) |
| 111788 | | - { /* zName: */ "parser_trace", |
| 111789 | | - /* ePragTyp: */ PragTyp_PARSER_TRACE, |
| 111790 | | - /* ePragFlag: */ 0, |
| 111791 | | - /* iArg: */ 0 }, |
| 111792 | | -#endif |
| 111793 | | -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 111794 | | - { /* zName: */ "query_only", |
| 111795 | | - /* ePragTyp: */ PragTyp_FLAG, |
| 111796 | | - /* ePragFlag: */ 0, |
| 111797 | | - /* iArg: */ SQLITE_QueryOnly }, |
| 111798 | | -#endif |
| 111799 | | -#if !defined(SQLITE_OMIT_INTEGRITY_CHECK) |
| 111800 | | - { /* zName: */ "quick_check", |
| 111801 | | - /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, |
| 111802 | | - /* ePragFlag: */ PragFlag_NeedSchema, |
| 111803 | | - /* iArg: */ 0 }, |
| 111804 | | -#endif |
| 111805 | | -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 111806 | | - { /* zName: */ "read_uncommitted", |
| 111807 | | - /* ePragTyp: */ PragTyp_FLAG, |
| 111808 | | - /* ePragFlag: */ 0, |
| 111809 | | - /* iArg: */ SQLITE_ReadUncommitted }, |
| 111810 | | - { /* zName: */ "recursive_triggers", |
| 111811 | | - /* ePragTyp: */ PragTyp_FLAG, |
| 111812 | | - /* ePragFlag: */ 0, |
| 111813 | | - /* iArg: */ SQLITE_RecTriggers }, |
| 111814 | | -#endif |
| 111815 | | -#if defined(SQLITE_HAS_CODEC) |
| 111816 | | - { /* zName: */ "rekey", |
| 111817 | | - /* ePragTyp: */ PragTyp_REKEY, |
| 111818 | | - /* ePragFlag: */ 0, |
| 111819 | | - /* iArg: */ 0 }, |
| 111820 | | -#endif |
| 111821 | | -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 111822 | | - { /* zName: */ "reverse_unordered_selects", |
| 111823 | | - /* ePragTyp: */ PragTyp_FLAG, |
| 111824 | | - /* ePragFlag: */ 0, |
| 111825 | | - /* iArg: */ SQLITE_ReverseOrder }, |
| 111826 | | -#endif |
| 111827 | | -#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) |
| 111828 | | - { /* zName: */ "schema_version", |
| 111829 | | - /* ePragTyp: */ PragTyp_HEADER_VALUE, |
| 111830 | | - /* ePragFlag: */ 0, |
| 111831 | | - /* iArg: */ BTREE_SCHEMA_VERSION }, |
| 111832 | | -#endif |
| 111833 | | -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 111834 | | - { /* zName: */ "secure_delete", |
| 111835 | | - /* ePragTyp: */ PragTyp_SECURE_DELETE, |
| 111836 | | - /* ePragFlag: */ 0, |
| 111837 | | - /* iArg: */ 0 }, |
| 111838 | | -#endif |
| 111839 | | -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 111840 | | - { /* zName: */ "short_column_names", |
| 111841 | | - /* ePragTyp: */ PragTyp_FLAG, |
| 111842 | | - /* ePragFlag: */ 0, |
| 111843 | | - /* iArg: */ SQLITE_ShortColNames }, |
| 111844 | | -#endif |
| 111845 | | - { /* zName: */ "shrink_memory", |
| 111846 | | - /* ePragTyp: */ PragTyp_SHRINK_MEMORY, |
| 111847 | | - /* ePragFlag: */ 0, |
| 111848 | | - /* iArg: */ 0 }, |
| 111849 | | - { /* zName: */ "soft_heap_limit", |
| 111850 | | - /* ePragTyp: */ PragTyp_SOFT_HEAP_LIMIT, |
| 111851 | | - /* ePragFlag: */ 0, |
| 111852 | | - /* iArg: */ 0 }, |
| 111853 | | -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 111854 | | -#if defined(SQLITE_DEBUG) |
| 111855 | | - { /* zName: */ "sql_trace", |
| 111856 | | - /* ePragTyp: */ PragTyp_FLAG, |
| 111857 | | - /* ePragFlag: */ 0, |
| 111858 | | - /* iArg: */ SQLITE_SqlTrace }, |
| 111859 | | -#endif |
| 111860 | | -#endif |
| 111861 | | -#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) |
| 111862 | | - { /* zName: */ "stats", |
| 111863 | | - /* ePragTyp: */ PragTyp_STATS, |
| 111864 | | - /* ePragFlag: */ PragFlag_NeedSchema, |
| 111865 | | - /* iArg: */ 0 }, |
| 111866 | | -#endif |
| 111867 | | -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 111868 | | - { /* zName: */ "synchronous", |
| 111869 | | - /* ePragTyp: */ PragTyp_SYNCHRONOUS, |
| 111870 | | - /* ePragFlag: */ PragFlag_NeedSchema, |
| 111871 | | - /* iArg: */ 0 }, |
| 111872 | | -#endif |
| 111873 | | -#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) |
| 111874 | | - { /* zName: */ "table_info", |
| 111875 | | - /* ePragTyp: */ PragTyp_TABLE_INFO, |
| 111876 | | - /* ePragFlag: */ PragFlag_NeedSchema, |
| 111877 | | - /* iArg: */ 0 }, |
| 111878 | | -#endif |
| 111879 | | -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 111880 | | - { /* zName: */ "temp_store", |
| 111881 | | - /* ePragTyp: */ PragTyp_TEMP_STORE, |
| 111882 | | - /* ePragFlag: */ 0, |
| 111883 | | - /* iArg: */ 0 }, |
| 111884 | | - { /* zName: */ "temp_store_directory", |
| 111885 | | - /* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY, |
| 111886 | | - /* ePragFlag: */ 0, |
| 111887 | | - /* iArg: */ 0 }, |
| 111888 | | -#endif |
| 111889 | | - { /* zName: */ "threads", |
| 111890 | | - /* ePragTyp: */ PragTyp_THREADS, |
| 111891 | | - /* ePragFlag: */ 0, |
| 111892 | | - /* iArg: */ 0 }, |
| 111893 | | -#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) |
| 111894 | | - { /* zName: */ "user_version", |
| 111895 | | - /* ePragTyp: */ PragTyp_HEADER_VALUE, |
| 111896 | | - /* ePragFlag: */ 0, |
| 111897 | | - /* iArg: */ BTREE_USER_VERSION }, |
| 111898 | | -#endif |
| 111899 | | -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 111900 | | -#if defined(SQLITE_DEBUG) |
| 111901 | | - { /* zName: */ "vdbe_addoptrace", |
| 111902 | | - /* ePragTyp: */ PragTyp_FLAG, |
| 111903 | | - /* ePragFlag: */ 0, |
| 111904 | | - /* iArg: */ SQLITE_VdbeAddopTrace }, |
| 111905 | | - { /* zName: */ "vdbe_debug", |
| 111906 | | - /* ePragTyp: */ PragTyp_FLAG, |
| 111907 | | - /* ePragFlag: */ 0, |
| 111908 | | - /* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace }, |
| 111909 | | - { /* zName: */ "vdbe_eqp", |
| 111910 | | - /* ePragTyp: */ PragTyp_FLAG, |
| 111911 | | - /* ePragFlag: */ 0, |
| 111912 | | - /* iArg: */ SQLITE_VdbeEQP }, |
| 111913 | | - { /* zName: */ "vdbe_listing", |
| 111914 | | - /* ePragTyp: */ PragTyp_FLAG, |
| 111915 | | - /* ePragFlag: */ 0, |
| 111916 | | - /* iArg: */ SQLITE_VdbeListing }, |
| 111917 | | - { /* zName: */ "vdbe_trace", |
| 111918 | | - /* ePragTyp: */ PragTyp_FLAG, |
| 111919 | | - /* ePragFlag: */ 0, |
| 111920 | | - /* iArg: */ SQLITE_VdbeTrace }, |
| 111921 | | -#endif |
| 111922 | | -#endif |
| 111923 | | -#if !defined(SQLITE_OMIT_WAL) |
| 111924 | | - { /* zName: */ "wal_autocheckpoint", |
| 111925 | | - /* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT, |
| 111926 | | - /* ePragFlag: */ 0, |
| 111927 | | - /* iArg: */ 0 }, |
| 111928 | | - { /* zName: */ "wal_checkpoint", |
| 111929 | | - /* ePragTyp: */ PragTyp_WAL_CHECKPOINT, |
| 111930 | | - /* ePragFlag: */ PragFlag_NeedSchema, |
| 111931 | | - /* iArg: */ 0 }, |
| 111932 | | -#endif |
| 111933 | | -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 111934 | | - { /* zName: */ "writable_schema", |
| 111935 | | - /* ePragTyp: */ PragTyp_FLAG, |
| 111936 | | - /* ePragFlag: */ 0, |
| 111937 | | - /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode }, |
| 111727 | + |
| 111728 | +/* Property flags associated with various pragma. */ |
| 111729 | +#define PragFlg_NeedSchema 0x01 /* Force schema load before running */ |
| 111730 | +#define PragFlg_NoColumns 0x02 /* OP_ResultRow called with zero columns */ |
| 111731 | +#define PragFlg_ReadOnly 0x04 /* Read-only HEADER_VALUE */ |
| 111732 | +#define PragFlg_Result0 0x08 /* Acts as query when no argument */ |
| 111733 | +#define PragFlg_Result1 0x10 /* Acts as query when has one argument */ |
| 111734 | +#define PragFlg_SchemaOpt 0x20 /* Schema restricts name search if present */ |
| 111735 | +#define PragFlg_SchemaReq 0x40 /* Schema required - "main" is default */ |
| 111736 | + |
| 111737 | +/* Names of columns for pragmas that return multi-column result |
| 111738 | +** or that return single-column results where the name of the |
| 111739 | +** result column is different from the name of the pragma |
| 111740 | +*/ |
| 111741 | +static const char *const pragCName[] = { |
| 111742 | + /* 0 */ "cache_size", /* Used by: default_cache_size */ |
| 111743 | + /* 1 */ "cid", /* Used by: table_info */ |
| 111744 | + /* 2 */ "name", |
| 111745 | + /* 3 */ "type", |
| 111746 | + /* 4 */ "notnull", |
| 111747 | + /* 5 */ "dflt_value", |
| 111748 | + /* 6 */ "pk", |
| 111749 | + /* 7 */ "table", /* Used by: stats */ |
| 111750 | + /* 8 */ "index", |
| 111751 | + /* 9 */ "width", |
| 111752 | + /* 10 */ "height", |
| 111753 | + /* 11 */ "seqno", /* Used by: index_info */ |
| 111754 | + /* 12 */ "cid", |
| 111755 | + /* 13 */ "name", |
| 111756 | + /* 14 */ "seqno", /* Used by: index_xinfo */ |
| 111757 | + /* 15 */ "cid", |
| 111758 | + /* 16 */ "name", |
| 111759 | + /* 17 */ "desc", |
| 111760 | + /* 18 */ "coll", |
| 111761 | + /* 19 */ "key", |
| 111762 | + /* 20 */ "seq", /* Used by: index_list */ |
| 111763 | + /* 21 */ "name", |
| 111764 | + /* 22 */ "unique", |
| 111765 | + /* 23 */ "origin", |
| 111766 | + /* 24 */ "partial", |
| 111767 | + /* 25 */ "seq", /* Used by: database_list */ |
| 111768 | + /* 26 */ "name", |
| 111769 | + /* 27 */ "file", |
| 111770 | + /* 28 */ "seq", /* Used by: collation_list */ |
| 111771 | + /* 29 */ "name", |
| 111772 | + /* 30 */ "id", /* Used by: foreign_key_list */ |
| 111773 | + /* 31 */ "seq", |
| 111774 | + /* 32 */ "table", |
| 111775 | + /* 33 */ "from", |
| 111776 | + /* 34 */ "to", |
| 111777 | + /* 35 */ "on_update", |
| 111778 | + /* 36 */ "on_delete", |
| 111779 | + /* 37 */ "match", |
| 111780 | + /* 38 */ "table", /* Used by: foreign_key_check */ |
| 111781 | + /* 39 */ "rowid", |
| 111782 | + /* 40 */ "parent", |
| 111783 | + /* 41 */ "fkid", |
| 111784 | + /* 42 */ "busy", /* Used by: wal_checkpoint */ |
| 111785 | + /* 43 */ "log", |
| 111786 | + /* 44 */ "checkpointed", |
| 111787 | + /* 45 */ "timeout", /* Used by: busy_timeout */ |
| 111788 | + /* 46 */ "database", /* Used by: lock_status */ |
| 111789 | + /* 47 */ "status", |
| 111790 | +}; |
| 111791 | + |
| 111792 | +/* Definitions of all built-in pragmas */ |
| 111793 | +typedef struct PragmaName { |
| 111794 | + const char *const zName; /* Name of pragma */ |
| 111795 | + u8 ePragTyp; /* PragTyp_XXX value */ |
| 111796 | + u8 mPragFlg; /* Zero or more PragFlg_XXX values */ |
| 111797 | + u8 iPragCName; /* Start of column names in pragCName[] */ |
| 111798 | + u8 nPragCName; /* Num of col names. 0 means use pragma name */ |
| 111799 | + u32 iArg; /* Extra argument */ |
| 111800 | +} PragmaName; |
| 111801 | +static const PragmaName aPragmaName[] = { |
| 111802 | +#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD) |
| 111803 | + {/* zName: */ "activate_extensions", |
| 111804 | + /* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS, |
| 111805 | + /* ePragFlg: */ 0, |
| 111806 | + /* ColNames: */ 0, 0, |
| 111807 | + /* iArg: */ 0 }, |
| 111808 | +#endif |
| 111809 | +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) |
| 111810 | + {/* zName: */ "application_id", |
| 111811 | + /* ePragTyp: */ PragTyp_HEADER_VALUE, |
| 111812 | + /* ePragFlg: */ PragFlg_Result0, |
| 111813 | + /* ColNames: */ 0, 0, |
| 111814 | + /* iArg: */ BTREE_APPLICATION_ID }, |
| 111815 | +#endif |
| 111816 | +#if !defined(SQLITE_OMIT_AUTOVACUUM) |
| 111817 | + {/* zName: */ "auto_vacuum", |
| 111818 | + /* ePragTyp: */ PragTyp_AUTO_VACUUM, |
| 111819 | + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, |
| 111820 | + /* ColNames: */ 0, 0, |
| 111821 | + /* iArg: */ 0 }, |
| 111822 | +#endif |
| 111823 | +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 111824 | +#if !defined(SQLITE_OMIT_AUTOMATIC_INDEX) |
| 111825 | + {/* zName: */ "automatic_index", |
| 111826 | + /* ePragTyp: */ PragTyp_FLAG, |
| 111827 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, |
| 111828 | + /* ColNames: */ 0, 0, |
| 111829 | + /* iArg: */ SQLITE_AutoIndex }, |
| 111830 | +#endif |
| 111831 | +#endif |
| 111832 | + {/* zName: */ "busy_timeout", |
| 111833 | + /* ePragTyp: */ PragTyp_BUSY_TIMEOUT, |
| 111834 | + /* ePragFlg: */ PragFlg_Result0, |
| 111835 | + /* ColNames: */ 45, 1, |
| 111836 | + /* iArg: */ 0 }, |
| 111837 | +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 111838 | + {/* zName: */ "cache_size", |
| 111839 | + /* ePragTyp: */ PragTyp_CACHE_SIZE, |
| 111840 | + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, |
| 111841 | + /* ColNames: */ 0, 0, |
| 111842 | + /* iArg: */ 0 }, |
| 111843 | +#endif |
| 111844 | +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 111845 | + {/* zName: */ "cache_spill", |
| 111846 | + /* ePragTyp: */ PragTyp_CACHE_SPILL, |
| 111847 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq, |
| 111848 | + /* ColNames: */ 0, 0, |
| 111849 | + /* iArg: */ 0 }, |
| 111850 | +#endif |
| 111851 | + {/* zName: */ "case_sensitive_like", |
| 111852 | + /* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE, |
| 111853 | + /* ePragFlg: */ 0, |
| 111854 | + /* ColNames: */ 0, 0, |
| 111855 | + /* iArg: */ 0 }, |
| 111856 | + {/* zName: */ "cell_size_check", |
| 111857 | + /* ePragTyp: */ PragTyp_FLAG, |
| 111858 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, |
| 111859 | + /* ColNames: */ 0, 0, |
| 111860 | + /* iArg: */ SQLITE_CellSizeCk }, |
| 111861 | +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 111862 | + {/* zName: */ "checkpoint_fullfsync", |
| 111863 | + /* ePragTyp: */ PragTyp_FLAG, |
| 111864 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, |
| 111865 | + /* ColNames: */ 0, 0, |
| 111866 | + /* iArg: */ SQLITE_CkptFullFSync }, |
| 111867 | +#endif |
| 111868 | +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) |
| 111869 | + {/* zName: */ "collation_list", |
| 111870 | + /* ePragTyp: */ PragTyp_COLLATION_LIST, |
| 111871 | + /* ePragFlg: */ PragFlg_Result0, |
| 111872 | + /* ColNames: */ 28, 2, |
| 111873 | + /* iArg: */ 0 }, |
| 111874 | +#endif |
| 111875 | +#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) |
| 111876 | + {/* zName: */ "compile_options", |
| 111877 | + /* ePragTyp: */ PragTyp_COMPILE_OPTIONS, |
| 111878 | + /* ePragFlg: */ PragFlg_Result0, |
| 111879 | + /* ColNames: */ 0, 0, |
| 111880 | + /* iArg: */ 0 }, |
| 111881 | +#endif |
| 111882 | +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 111883 | + {/* zName: */ "count_changes", |
| 111884 | + /* ePragTyp: */ PragTyp_FLAG, |
| 111885 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, |
| 111886 | + /* ColNames: */ 0, 0, |
| 111887 | + /* iArg: */ SQLITE_CountRows }, |
| 111888 | +#endif |
| 111889 | +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN |
| 111890 | + {/* zName: */ "data_store_directory", |
| 111891 | + /* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY, |
| 111892 | + /* ePragFlg: */ 0, |
| 111893 | + /* ColNames: */ 0, 0, |
| 111894 | + /* iArg: */ 0 }, |
| 111895 | +#endif |
| 111896 | +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) |
| 111897 | + {/* zName: */ "data_version", |
| 111898 | + /* ePragTyp: */ PragTyp_HEADER_VALUE, |
| 111899 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_ReadOnly, |
| 111900 | + /* ColNames: */ 0, 0, |
| 111901 | + /* iArg: */ BTREE_DATA_VERSION }, |
| 111902 | +#endif |
| 111903 | +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) |
| 111904 | + {/* zName: */ "database_list", |
| 111905 | + /* ePragTyp: */ PragTyp_DATABASE_LIST, |
| 111906 | + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0, |
| 111907 | + /* ColNames: */ 25, 3, |
| 111908 | + /* iArg: */ 0 }, |
| 111909 | +#endif |
| 111910 | +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) |
| 111911 | + {/* zName: */ "default_cache_size", |
| 111912 | + /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE, |
| 111913 | + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, |
| 111914 | + /* ColNames: */ 0, 1, |
| 111915 | + /* iArg: */ 0 }, |
| 111916 | +#endif |
| 111917 | +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 111918 | +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) |
| 111919 | + {/* zName: */ "defer_foreign_keys", |
| 111920 | + /* ePragTyp: */ PragTyp_FLAG, |
| 111921 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, |
| 111922 | + /* ColNames: */ 0, 0, |
| 111923 | + /* iArg: */ SQLITE_DeferFKs }, |
| 111924 | +#endif |
| 111925 | +#endif |
| 111926 | +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 111927 | + {/* zName: */ "empty_result_callbacks", |
| 111928 | + /* ePragTyp: */ PragTyp_FLAG, |
| 111929 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, |
| 111930 | + /* ColNames: */ 0, 0, |
| 111931 | + /* iArg: */ SQLITE_NullCallback }, |
| 111932 | +#endif |
| 111933 | +#if !defined(SQLITE_OMIT_UTF16) |
| 111934 | + {/* zName: */ "encoding", |
| 111935 | + /* ePragTyp: */ PragTyp_ENCODING, |
| 111936 | + /* ePragFlg: */ PragFlg_Result0, |
| 111937 | + /* ColNames: */ 0, 0, |
| 111938 | + /* iArg: */ 0 }, |
| 111939 | +#endif |
| 111940 | +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) |
| 111941 | + {/* zName: */ "foreign_key_check", |
| 111942 | + /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK, |
| 111943 | + /* ePragFlg: */ PragFlg_NeedSchema, |
| 111944 | + /* ColNames: */ 38, 4, |
| 111945 | + /* iArg: */ 0 }, |
| 111946 | +#endif |
| 111947 | +#if !defined(SQLITE_OMIT_FOREIGN_KEY) |
| 111948 | + {/* zName: */ "foreign_key_list", |
| 111949 | + /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST, |
| 111950 | + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, |
| 111951 | + /* ColNames: */ 30, 8, |
| 111952 | + /* iArg: */ 0 }, |
| 111953 | +#endif |
| 111954 | +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 111955 | +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) |
| 111956 | + {/* zName: */ "foreign_keys", |
| 111957 | + /* ePragTyp: */ PragTyp_FLAG, |
| 111958 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, |
| 111959 | + /* ColNames: */ 0, 0, |
| 111960 | + /* iArg: */ SQLITE_ForeignKeys }, |
| 111961 | +#endif |
| 111962 | +#endif |
| 111963 | +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) |
| 111964 | + {/* zName: */ "freelist_count", |
| 111965 | + /* ePragTyp: */ PragTyp_HEADER_VALUE, |
| 111966 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_ReadOnly, |
| 111967 | + /* ColNames: */ 0, 0, |
| 111968 | + /* iArg: */ BTREE_FREE_PAGE_COUNT }, |
| 111969 | +#endif |
| 111970 | +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 111971 | + {/* zName: */ "full_column_names", |
| 111972 | + /* ePragTyp: */ PragTyp_FLAG, |
| 111973 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, |
| 111974 | + /* ColNames: */ 0, 0, |
| 111975 | + /* iArg: */ SQLITE_FullColNames }, |
| 111976 | + {/* zName: */ "fullfsync", |
| 111977 | + /* ePragTyp: */ PragTyp_FLAG, |
| 111978 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, |
| 111979 | + /* ColNames: */ 0, 0, |
| 111980 | + /* iArg: */ SQLITE_FullFSync }, |
| 111981 | +#endif |
| 111982 | +#if defined(SQLITE_HAS_CODEC) |
| 111983 | + {/* zName: */ "hexkey", |
| 111984 | + /* ePragTyp: */ PragTyp_HEXKEY, |
| 111985 | + /* ePragFlg: */ 0, |
| 111986 | + /* ColNames: */ 0, 0, |
| 111987 | + /* iArg: */ 0 }, |
| 111988 | + {/* zName: */ "hexrekey", |
| 111989 | + /* ePragTyp: */ PragTyp_HEXKEY, |
| 111990 | + /* ePragFlg: */ 0, |
| 111991 | + /* ColNames: */ 0, 0, |
| 111992 | + /* iArg: */ 0 }, |
| 111993 | +#endif |
| 111994 | +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 111995 | +#if !defined(SQLITE_OMIT_CHECK) |
| 111996 | + {/* zName: */ "ignore_check_constraints", |
| 111997 | + /* ePragTyp: */ PragTyp_FLAG, |
| 111998 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, |
| 111999 | + /* ColNames: */ 0, 0, |
| 112000 | + /* iArg: */ SQLITE_IgnoreChecks }, |
| 112001 | +#endif |
| 112002 | +#endif |
| 112003 | +#if !defined(SQLITE_OMIT_AUTOVACUUM) |
| 112004 | + {/* zName: */ "incremental_vacuum", |
| 112005 | + /* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM, |
| 112006 | + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_NoColumns, |
| 112007 | + /* ColNames: */ 0, 0, |
| 112008 | + /* iArg: */ 0 }, |
| 112009 | +#endif |
| 112010 | +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) |
| 112011 | + {/* zName: */ "index_info", |
| 112012 | + /* ePragTyp: */ PragTyp_INDEX_INFO, |
| 112013 | + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, |
| 112014 | + /* ColNames: */ 11, 3, |
| 112015 | + /* iArg: */ 0 }, |
| 112016 | + {/* zName: */ "index_list", |
| 112017 | + /* ePragTyp: */ PragTyp_INDEX_LIST, |
| 112018 | + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, |
| 112019 | + /* ColNames: */ 20, 5, |
| 112020 | + /* iArg: */ 0 }, |
| 112021 | + {/* zName: */ "index_xinfo", |
| 112022 | + /* ePragTyp: */ PragTyp_INDEX_INFO, |
| 112023 | + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, |
| 112024 | + /* ColNames: */ 14, 6, |
| 112025 | + /* iArg: */ 1 }, |
| 112026 | +#endif |
| 112027 | +#if !defined(SQLITE_OMIT_INTEGRITY_CHECK) |
| 112028 | + {/* zName: */ "integrity_check", |
| 112029 | + /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, |
| 112030 | + /* ePragFlg: */ PragFlg_NeedSchema, |
| 112031 | + /* ColNames: */ 0, 0, |
| 112032 | + /* iArg: */ 0 }, |
| 112033 | +#endif |
| 112034 | +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 112035 | + {/* zName: */ "journal_mode", |
| 112036 | + /* ePragTyp: */ PragTyp_JOURNAL_MODE, |
| 112037 | + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, |
| 112038 | + /* ColNames: */ 0, 0, |
| 112039 | + /* iArg: */ 0 }, |
| 112040 | + {/* zName: */ "journal_size_limit", |
| 112041 | + /* ePragTyp: */ PragTyp_JOURNAL_SIZE_LIMIT, |
| 112042 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq, |
| 112043 | + /* ColNames: */ 0, 0, |
| 112044 | + /* iArg: */ 0 }, |
| 112045 | +#endif |
| 112046 | +#if defined(SQLITE_HAS_CODEC) |
| 112047 | + {/* zName: */ "key", |
| 112048 | + /* ePragTyp: */ PragTyp_KEY, |
| 112049 | + /* ePragFlg: */ 0, |
| 112050 | + /* ColNames: */ 0, 0, |
| 112051 | + /* iArg: */ 0 }, |
| 112052 | +#endif |
| 112053 | +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 112054 | + {/* zName: */ "legacy_file_format", |
| 112055 | + /* ePragTyp: */ PragTyp_FLAG, |
| 112056 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, |
| 112057 | + /* ColNames: */ 0, 0, |
| 112058 | + /* iArg: */ SQLITE_LegacyFileFmt }, |
| 112059 | +#endif |
| 112060 | +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE |
| 112061 | + {/* zName: */ "lock_proxy_file", |
| 112062 | + /* ePragTyp: */ PragTyp_LOCK_PROXY_FILE, |
| 112063 | + /* ePragFlg: */ 0, |
| 112064 | + /* ColNames: */ 0, 0, |
| 112065 | + /* iArg: */ 0 }, |
| 112066 | +#endif |
| 112067 | +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) |
| 112068 | + {/* zName: */ "lock_status", |
| 112069 | + /* ePragTyp: */ PragTyp_LOCK_STATUS, |
| 112070 | + /* ePragFlg: */ PragFlg_Result0, |
| 112071 | + /* ColNames: */ 46, 2, |
| 112072 | + /* iArg: */ 0 }, |
| 112073 | +#endif |
| 112074 | +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 112075 | + {/* zName: */ "locking_mode", |
| 112076 | + /* ePragTyp: */ PragTyp_LOCKING_MODE, |
| 112077 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq, |
| 112078 | + /* ColNames: */ 0, 0, |
| 112079 | + /* iArg: */ 0 }, |
| 112080 | + {/* zName: */ "max_page_count", |
| 112081 | + /* ePragTyp: */ PragTyp_PAGE_COUNT, |
| 112082 | + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, |
| 112083 | + /* ColNames: */ 0, 0, |
| 112084 | + /* iArg: */ 0 }, |
| 112085 | + {/* zName: */ "mmap_size", |
| 112086 | + /* ePragTyp: */ PragTyp_MMAP_SIZE, |
| 112087 | + /* ePragFlg: */ 0, |
| 112088 | + /* ColNames: */ 0, 0, |
| 112089 | + /* iArg: */ 0 }, |
| 112090 | + {/* zName: */ "page_count", |
| 112091 | + /* ePragTyp: */ PragTyp_PAGE_COUNT, |
| 112092 | + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, |
| 112093 | + /* ColNames: */ 0, 0, |
| 112094 | + /* iArg: */ 0 }, |
| 112095 | + {/* zName: */ "page_size", |
| 112096 | + /* ePragTyp: */ PragTyp_PAGE_SIZE, |
| 112097 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq, |
| 112098 | + /* ColNames: */ 0, 0, |
| 112099 | + /* iArg: */ 0 }, |
| 112100 | +#endif |
| 112101 | +#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_PARSER_TRACE) |
| 112102 | + {/* zName: */ "parser_trace", |
| 112103 | + /* ePragTyp: */ PragTyp_PARSER_TRACE, |
| 112104 | + /* ePragFlg: */ 0, |
| 112105 | + /* ColNames: */ 0, 0, |
| 112106 | + /* iArg: */ 0 }, |
| 112107 | +#endif |
| 112108 | +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 112109 | + {/* zName: */ "query_only", |
| 112110 | + /* ePragTyp: */ PragTyp_FLAG, |
| 112111 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, |
| 112112 | + /* ColNames: */ 0, 0, |
| 112113 | + /* iArg: */ SQLITE_QueryOnly }, |
| 112114 | +#endif |
| 112115 | +#if !defined(SQLITE_OMIT_INTEGRITY_CHECK) |
| 112116 | + {/* zName: */ "quick_check", |
| 112117 | + /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, |
| 112118 | + /* ePragFlg: */ PragFlg_NeedSchema, |
| 112119 | + /* ColNames: */ 0, 0, |
| 112120 | + /* iArg: */ 0 }, |
| 112121 | +#endif |
| 112122 | +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 112123 | + {/* zName: */ "read_uncommitted", |
| 112124 | + /* ePragTyp: */ PragTyp_FLAG, |
| 112125 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, |
| 112126 | + /* ColNames: */ 0, 0, |
| 112127 | + /* iArg: */ SQLITE_ReadUncommitted }, |
| 112128 | + {/* zName: */ "recursive_triggers", |
| 112129 | + /* ePragTyp: */ PragTyp_FLAG, |
| 112130 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, |
| 112131 | + /* ColNames: */ 0, 0, |
| 112132 | + /* iArg: */ SQLITE_RecTriggers }, |
| 112133 | +#endif |
| 112134 | +#if defined(SQLITE_HAS_CODEC) |
| 112135 | + {/* zName: */ "rekey", |
| 112136 | + /* ePragTyp: */ PragTyp_REKEY, |
| 112137 | + /* ePragFlg: */ 0, |
| 112138 | + /* ColNames: */ 0, 0, |
| 112139 | + /* iArg: */ 0 }, |
| 112140 | +#endif |
| 112141 | +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 112142 | + {/* zName: */ "reverse_unordered_selects", |
| 112143 | + /* ePragTyp: */ PragTyp_FLAG, |
| 112144 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, |
| 112145 | + /* ColNames: */ 0, 0, |
| 112146 | + /* iArg: */ SQLITE_ReverseOrder }, |
| 112147 | +#endif |
| 112148 | +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) |
| 112149 | + {/* zName: */ "schema_version", |
| 112150 | + /* ePragTyp: */ PragTyp_HEADER_VALUE, |
| 112151 | + /* ePragFlg: */ PragFlg_Result0, |
| 112152 | + /* ColNames: */ 0, 0, |
| 112153 | + /* iArg: */ BTREE_SCHEMA_VERSION }, |
| 112154 | +#endif |
| 112155 | +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 112156 | + {/* zName: */ "secure_delete", |
| 112157 | + /* ePragTyp: */ PragTyp_SECURE_DELETE, |
| 112158 | + /* ePragFlg: */ PragFlg_Result0, |
| 112159 | + /* ColNames: */ 0, 0, |
| 112160 | + /* iArg: */ 0 }, |
| 112161 | +#endif |
| 112162 | +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 112163 | + {/* zName: */ "short_column_names", |
| 112164 | + /* ePragTyp: */ PragTyp_FLAG, |
| 112165 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, |
| 112166 | + /* ColNames: */ 0, 0, |
| 112167 | + /* iArg: */ SQLITE_ShortColNames }, |
| 112168 | +#endif |
| 112169 | + {/* zName: */ "shrink_memory", |
| 112170 | + /* ePragTyp: */ PragTyp_SHRINK_MEMORY, |
| 112171 | + /* ePragFlg: */ 0, |
| 112172 | + /* ColNames: */ 0, 0, |
| 112173 | + /* iArg: */ 0 }, |
| 112174 | + {/* zName: */ "soft_heap_limit", |
| 112175 | + /* ePragTyp: */ PragTyp_SOFT_HEAP_LIMIT, |
| 112176 | + /* ePragFlg: */ PragFlg_Result0, |
| 112177 | + /* ColNames: */ 0, 0, |
| 112178 | + /* iArg: */ 0 }, |
| 112179 | +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 112180 | +#if defined(SQLITE_DEBUG) |
| 112181 | + {/* zName: */ "sql_trace", |
| 112182 | + /* ePragTyp: */ PragTyp_FLAG, |
| 112183 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, |
| 112184 | + /* ColNames: */ 0, 0, |
| 112185 | + /* iArg: */ SQLITE_SqlTrace }, |
| 112186 | +#endif |
| 112187 | +#endif |
| 112188 | +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) |
| 112189 | + {/* zName: */ "stats", |
| 112190 | + /* ePragTyp: */ PragTyp_STATS, |
| 112191 | + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, |
| 112192 | + /* ColNames: */ 7, 4, |
| 112193 | + /* iArg: */ 0 }, |
| 112194 | +#endif |
| 112195 | +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 112196 | + {/* zName: */ "synchronous", |
| 112197 | + /* ePragTyp: */ PragTyp_SYNCHRONOUS, |
| 112198 | + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, |
| 112199 | + /* ColNames: */ 0, 0, |
| 112200 | + /* iArg: */ 0 }, |
| 112201 | +#endif |
| 112202 | +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) |
| 112203 | + {/* zName: */ "table_info", |
| 112204 | + /* ePragTyp: */ PragTyp_TABLE_INFO, |
| 112205 | + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, |
| 112206 | + /* ColNames: */ 1, 6, |
| 112207 | + /* iArg: */ 0 }, |
| 112208 | +#endif |
| 112209 | +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 112210 | + {/* zName: */ "temp_store", |
| 112211 | + /* ePragTyp: */ PragTyp_TEMP_STORE, |
| 112212 | + /* ePragFlg: */ PragFlg_Result0, |
| 112213 | + /* ColNames: */ 0, 0, |
| 112214 | + /* iArg: */ 0 }, |
| 112215 | + {/* zName: */ "temp_store_directory", |
| 112216 | + /* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY, |
| 112217 | + /* ePragFlg: */ 0, |
| 112218 | + /* ColNames: */ 0, 0, |
| 112219 | + /* iArg: */ 0 }, |
| 112220 | +#endif |
| 112221 | + {/* zName: */ "threads", |
| 112222 | + /* ePragTyp: */ PragTyp_THREADS, |
| 112223 | + /* ePragFlg: */ PragFlg_Result0, |
| 112224 | + /* ColNames: */ 0, 0, |
| 112225 | + /* iArg: */ 0 }, |
| 112226 | +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) |
| 112227 | + {/* zName: */ "user_version", |
| 112228 | + /* ePragTyp: */ PragTyp_HEADER_VALUE, |
| 112229 | + /* ePragFlg: */ PragFlg_Result0, |
| 112230 | + /* ColNames: */ 0, 0, |
| 112231 | + /* iArg: */ BTREE_USER_VERSION }, |
| 112232 | +#endif |
| 112233 | +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 112234 | +#if defined(SQLITE_DEBUG) |
| 112235 | + {/* zName: */ "vdbe_addoptrace", |
| 112236 | + /* ePragTyp: */ PragTyp_FLAG, |
| 112237 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, |
| 112238 | + /* ColNames: */ 0, 0, |
| 112239 | + /* iArg: */ SQLITE_VdbeAddopTrace }, |
| 112240 | + {/* zName: */ "vdbe_debug", |
| 112241 | + /* ePragTyp: */ PragTyp_FLAG, |
| 112242 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, |
| 112243 | + /* ColNames: */ 0, 0, |
| 112244 | + /* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace }, |
| 112245 | + {/* zName: */ "vdbe_eqp", |
| 112246 | + /* ePragTyp: */ PragTyp_FLAG, |
| 112247 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, |
| 112248 | + /* ColNames: */ 0, 0, |
| 112249 | + /* iArg: */ SQLITE_VdbeEQP }, |
| 112250 | + {/* zName: */ "vdbe_listing", |
| 112251 | + /* ePragTyp: */ PragTyp_FLAG, |
| 112252 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, |
| 112253 | + /* ColNames: */ 0, 0, |
| 112254 | + /* iArg: */ SQLITE_VdbeListing }, |
| 112255 | + {/* zName: */ "vdbe_trace", |
| 112256 | + /* ePragTyp: */ PragTyp_FLAG, |
| 112257 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, |
| 112258 | + /* ColNames: */ 0, 0, |
| 112259 | + /* iArg: */ SQLITE_VdbeTrace }, |
| 112260 | +#endif |
| 112261 | +#endif |
| 112262 | +#if !defined(SQLITE_OMIT_WAL) |
| 112263 | + {/* zName: */ "wal_autocheckpoint", |
| 112264 | + /* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT, |
| 112265 | + /* ePragFlg: */ 0, |
| 112266 | + /* ColNames: */ 0, 0, |
| 112267 | + /* iArg: */ 0 }, |
| 112268 | + {/* zName: */ "wal_checkpoint", |
| 112269 | + /* ePragTyp: */ PragTyp_WAL_CHECKPOINT, |
| 112270 | + /* ePragFlg: */ PragFlg_NeedSchema, |
| 112271 | + /* ColNames: */ 42, 3, |
| 112272 | + /* iArg: */ 0 }, |
| 112273 | +#endif |
| 112274 | +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 112275 | + {/* zName: */ "writable_schema", |
| 112276 | + /* ePragTyp: */ PragTyp_FLAG, |
| 112277 | + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, |
| 112278 | + /* ColNames: */ 0, 0, |
| 112279 | + /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode }, |
| 111938 | 112280 | #endif |
| 111939 | 112281 | }; |
| 111940 | 112282 | /* Number of pragmas: 60 on by default, 73 total. */ |
| 111941 | 112283 | |
| 111942 | 112284 | /************** End of pragma.h **********************************************/ |
| | @@ -112073,47 +112415,45 @@ |
| 112073 | 112415 | return SQLITE_OK; |
| 112074 | 112416 | } |
| 112075 | 112417 | #endif /* SQLITE_PAGER_PRAGMAS */ |
| 112076 | 112418 | |
| 112077 | 112419 | /* |
| 112078 | | -** Set the names of the first N columns to the values in azCol[] |
| 112420 | +** Set result column names for a pragma. |
| 112079 | 112421 | */ |
| 112080 | | -static void setAllColumnNames( |
| 112081 | | - Vdbe *v, /* The query under construction */ |
| 112082 | | - int N, /* Number of columns */ |
| 112083 | | - const char **azCol /* Names of columns */ |
| 112422 | +static void setPragmaResultColumnNames( |
| 112423 | + Vdbe *v, /* The query under construction */ |
| 112424 | + const PragmaName *pPragma /* The pragma */ |
| 112084 | 112425 | ){ |
| 112085 | | - int i; |
| 112086 | | - sqlite3VdbeSetNumCols(v, N); |
| 112087 | | - for(i=0; i<N; i++){ |
| 112088 | | - sqlite3VdbeSetColName(v, i, COLNAME_NAME, azCol[i], SQLITE_STATIC); |
| 112089 | | - } |
| 112090 | | -} |
| 112091 | | -static void setOneColumnName(Vdbe *v, const char *z){ |
| 112092 | | - setAllColumnNames(v, 1, &z); |
| 112426 | + u8 n = pPragma->nPragCName; |
| 112427 | + sqlite3VdbeSetNumCols(v, n==0 ? 1 : n); |
| 112428 | + if( n==0 ){ |
| 112429 | + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, pPragma->zName, SQLITE_STATIC); |
| 112430 | + }else{ |
| 112431 | + int i, j; |
| 112432 | + for(i=0, j=pPragma->iPragCName; i<n; i++, j++){ |
| 112433 | + sqlite3VdbeSetColName(v, i, COLNAME_NAME, pragCName[j], SQLITE_STATIC); |
| 112434 | + } |
| 112435 | + } |
| 112093 | 112436 | } |
| 112094 | 112437 | |
| 112095 | 112438 | /* |
| 112096 | 112439 | ** Generate code to return a single integer value. |
| 112097 | 112440 | */ |
| 112098 | | -static void returnSingleInt(Vdbe *v, const char *zLabel, i64 value){ |
| 112441 | +static void returnSingleInt(Vdbe *v, i64 value){ |
| 112099 | 112442 | sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, 1, 0, (const u8*)&value, P4_INT64); |
| 112100 | | - setOneColumnName(v, zLabel); |
| 112101 | 112443 | sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); |
| 112102 | 112444 | } |
| 112103 | 112445 | |
| 112104 | 112446 | /* |
| 112105 | 112447 | ** Generate code to return a single text value. |
| 112106 | 112448 | */ |
| 112107 | 112449 | static void returnSingleText( |
| 112108 | 112450 | Vdbe *v, /* Prepared statement under construction */ |
| 112109 | | - const char *zLabel, /* Name of the result column */ |
| 112110 | 112451 | const char *zValue /* Value to be returned */ |
| 112111 | 112452 | ){ |
| 112112 | 112453 | if( zValue ){ |
| 112113 | 112454 | sqlite3VdbeLoadString(v, 1, (const char*)zValue); |
| 112114 | | - setOneColumnName(v, zLabel); |
| 112115 | 112455 | sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); |
| 112116 | 112456 | } |
| 112117 | 112457 | } |
| 112118 | 112458 | |
| 112119 | 112459 | |
| | @@ -112186,10 +112526,30 @@ |
| 112186 | 112526 | assert( eMode>=0 && eMode<=ArraySize(azModeName) ); |
| 112187 | 112527 | |
| 112188 | 112528 | if( eMode==ArraySize(azModeName) ) return 0; |
| 112189 | 112529 | return azModeName[eMode]; |
| 112190 | 112530 | } |
| 112531 | + |
| 112532 | +/* |
| 112533 | +** Locate a pragma in the aPragmaName[] array. |
| 112534 | +*/ |
| 112535 | +static const PragmaName *pragmaLocate(const char *zName){ |
| 112536 | + int upr, lwr, mid, rc; |
| 112537 | + lwr = 0; |
| 112538 | + upr = ArraySize(aPragmaName)-1; |
| 112539 | + while( lwr<=upr ){ |
| 112540 | + mid = (lwr+upr)/2; |
| 112541 | + rc = sqlite3_stricmp(zName, aPragmaName[mid].zName); |
| 112542 | + if( rc==0 ) break; |
| 112543 | + if( rc<0 ){ |
| 112544 | + upr = mid - 1; |
| 112545 | + }else{ |
| 112546 | + lwr = mid + 1; |
| 112547 | + } |
| 112548 | + } |
| 112549 | + return lwr>upr ? 0 : &aPragmaName[mid]; |
| 112550 | +} |
| 112191 | 112551 | |
| 112192 | 112552 | /* |
| 112193 | 112553 | ** Process a pragma statement. |
| 112194 | 112554 | ** |
| 112195 | 112555 | ** Pragmas are of this form: |
| | @@ -112215,16 +112575,15 @@ |
| 112215 | 112575 | char *zRight = 0; /* Nul-terminated UTF-8 string <value>, or NULL */ |
| 112216 | 112576 | const char *zDb = 0; /* The database name */ |
| 112217 | 112577 | Token *pId; /* Pointer to <id> token */ |
| 112218 | 112578 | char *aFcntl[4]; /* Argument to SQLITE_FCNTL_PRAGMA */ |
| 112219 | 112579 | int iDb; /* Database index for <database> */ |
| 112220 | | - int lwr, upr, mid = 0; /* Binary search bounds */ |
| 112221 | 112580 | int rc; /* return value form SQLITE_FCNTL_PRAGMA */ |
| 112222 | 112581 | sqlite3 *db = pParse->db; /* The database connection */ |
| 112223 | 112582 | Db *pDb; /* The specific database being pragmaed */ |
| 112224 | 112583 | Vdbe *v = sqlite3GetVdbe(pParse); /* Prepared statement */ |
| 112225 | | - const struct sPragmaNames *pPragma; |
| 112584 | + const PragmaName *pPragma; /* The pragma */ |
| 112226 | 112585 | |
| 112227 | 112586 | if( v==0 ) return; |
| 112228 | 112587 | sqlite3VdbeRunOnlyOnce(v); |
| 112229 | 112588 | pParse->nMem = 2; |
| 112230 | 112589 | |
| | @@ -112275,11 +112634,13 @@ |
| 112275 | 112634 | aFcntl[2] = zRight; |
| 112276 | 112635 | aFcntl[3] = 0; |
| 112277 | 112636 | db->busyHandler.nBusy = 0; |
| 112278 | 112637 | rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl); |
| 112279 | 112638 | if( rc==SQLITE_OK ){ |
| 112280 | | - returnSingleText(v, "result", aFcntl[0]); |
| 112639 | + sqlite3VdbeSetNumCols(v, 1); |
| 112640 | + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, aFcntl[0], SQLITE_TRANSIENT); |
| 112641 | + returnSingleText(v, aFcntl[0]); |
| 112281 | 112642 | sqlite3_free(aFcntl[0]); |
| 112282 | 112643 | goto pragma_out; |
| 112283 | 112644 | } |
| 112284 | 112645 | if( rc!=SQLITE_NOTFOUND ){ |
| 112285 | 112646 | if( aFcntl[0] ){ |
| | @@ -112290,29 +112651,22 @@ |
| 112290 | 112651 | pParse->rc = rc; |
| 112291 | 112652 | goto pragma_out; |
| 112292 | 112653 | } |
| 112293 | 112654 | |
| 112294 | 112655 | /* Locate the pragma in the lookup table */ |
| 112295 | | - lwr = 0; |
| 112296 | | - upr = ArraySize(aPragmaNames)-1; |
| 112297 | | - while( lwr<=upr ){ |
| 112298 | | - mid = (lwr+upr)/2; |
| 112299 | | - rc = sqlite3_stricmp(zLeft, aPragmaNames[mid].zName); |
| 112300 | | - if( rc==0 ) break; |
| 112301 | | - if( rc<0 ){ |
| 112302 | | - upr = mid - 1; |
| 112303 | | - }else{ |
| 112304 | | - lwr = mid + 1; |
| 112305 | | - } |
| 112306 | | - } |
| 112307 | | - if( lwr>upr ) goto pragma_out; |
| 112308 | | - pPragma = &aPragmaNames[mid]; |
| 112656 | + pPragma = pragmaLocate(zLeft); |
| 112657 | + if( pPragma==0 ) goto pragma_out; |
| 112309 | 112658 | |
| 112310 | 112659 | /* Make sure the database schema is loaded if the pragma requires that */ |
| 112311 | | - if( (pPragma->mPragFlag & PragFlag_NeedSchema)!=0 ){ |
| 112660 | + if( (pPragma->mPragFlg & PragFlg_NeedSchema)!=0 ){ |
| 112312 | 112661 | if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 112313 | 112662 | } |
| 112663 | + |
| 112664 | + /* Register the result column names for pragmas that return results */ |
| 112665 | + if( (pPragma->mPragFlg & PragFlg_NoColumns)==0 ){ |
| 112666 | + setPragmaResultColumnNames(v, pPragma); |
| 112667 | + } |
| 112314 | 112668 | |
| 112315 | 112669 | /* Jump to the appropriate pragma handler */ |
| 112316 | 112670 | switch( pPragma->ePragTyp ){ |
| 112317 | 112671 | |
| 112318 | 112672 | #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) |
| | @@ -112346,11 +112700,10 @@ |
| 112346 | 112700 | { OP_ResultRow, 1, 1, 0}, |
| 112347 | 112701 | }; |
| 112348 | 112702 | VdbeOp *aOp; |
| 112349 | 112703 | sqlite3VdbeUsesBtree(v, iDb); |
| 112350 | 112704 | if( !zRight ){ |
| 112351 | | - setOneColumnName(v, "cache_size"); |
| 112352 | 112705 | pParse->nMem += 2; |
| 112353 | 112706 | sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(getCacheSize)); |
| 112354 | 112707 | aOp = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize, iLn); |
| 112355 | 112708 | if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; |
| 112356 | 112709 | aOp[0].p1 = iDb; |
| | @@ -112381,11 +112734,11 @@ |
| 112381 | 112734 | case PragTyp_PAGE_SIZE: { |
| 112382 | 112735 | Btree *pBt = pDb->pBt; |
| 112383 | 112736 | assert( pBt!=0 ); |
| 112384 | 112737 | if( !zRight ){ |
| 112385 | 112738 | int size = ALWAYS(pBt) ? sqlite3BtreeGetPageSize(pBt) : 0; |
| 112386 | | - returnSingleInt(v, "page_size", size); |
| 112739 | + returnSingleInt(v, size); |
| 112387 | 112740 | }else{ |
| 112388 | 112741 | /* Malloc may fail when setting the page-size, as there is an internal |
| 112389 | 112742 | ** buffer that the pager module resizes using sqlite3_realloc(). |
| 112390 | 112743 | */ |
| 112391 | 112744 | db->nextPagesize = sqlite3Atoi(zRight); |
| | @@ -112416,11 +112769,11 @@ |
| 112416 | 112769 | for(ii=0; ii<db->nDb; ii++){ |
| 112417 | 112770 | sqlite3BtreeSecureDelete(db->aDb[ii].pBt, b); |
| 112418 | 112771 | } |
| 112419 | 112772 | } |
| 112420 | 112773 | b = sqlite3BtreeSecureDelete(pBt, b); |
| 112421 | | - returnSingleInt(v, "secure_delete", b); |
| 112774 | + returnSingleInt(v, b); |
| 112422 | 112775 | break; |
| 112423 | 112776 | } |
| 112424 | 112777 | |
| 112425 | 112778 | /* |
| 112426 | 112779 | ** PRAGMA [schema.]max_page_count |
| | @@ -112448,12 +112801,10 @@ |
| 112448 | 112801 | }else{ |
| 112449 | 112802 | sqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg, |
| 112450 | 112803 | sqlite3AbsInt32(sqlite3Atoi(zRight))); |
| 112451 | 112804 | } |
| 112452 | 112805 | sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1); |
| 112453 | | - sqlite3VdbeSetNumCols(v, 1); |
| 112454 | | - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT); |
| 112455 | 112806 | break; |
| 112456 | 112807 | } |
| 112457 | 112808 | |
| 112458 | 112809 | /* |
| 112459 | 112810 | ** PRAGMA [schema.]locking_mode |
| | @@ -112495,11 +112846,11 @@ |
| 112495 | 112846 | assert( eMode==PAGER_LOCKINGMODE_NORMAL |
| 112496 | 112847 | || eMode==PAGER_LOCKINGMODE_EXCLUSIVE ); |
| 112497 | 112848 | if( eMode==PAGER_LOCKINGMODE_EXCLUSIVE ){ |
| 112498 | 112849 | zRet = "exclusive"; |
| 112499 | 112850 | } |
| 112500 | | - returnSingleText(v, "locking_mode", zRet); |
| 112851 | + returnSingleText(v, zRet); |
| 112501 | 112852 | break; |
| 112502 | 112853 | } |
| 112503 | 112854 | |
| 112504 | 112855 | /* |
| 112505 | 112856 | ** PRAGMA [schema.]journal_mode |
| | @@ -112508,11 +112859,10 @@ |
| 112508 | 112859 | */ |
| 112509 | 112860 | case PragTyp_JOURNAL_MODE: { |
| 112510 | 112861 | int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */ |
| 112511 | 112862 | int ii; /* Loop counter */ |
| 112512 | 112863 | |
| 112513 | | - setOneColumnName(v, "journal_mode"); |
| 112514 | 112864 | if( zRight==0 ){ |
| 112515 | 112865 | /* If there is no "=MODE" part of the pragma, do a query for the |
| 112516 | 112866 | ** current mode */ |
| 112517 | 112867 | eMode = PAGER_JOURNALMODE_QUERY; |
| 112518 | 112868 | }else{ |
| | @@ -112554,11 +112904,11 @@ |
| 112554 | 112904 | if( zRight ){ |
| 112555 | 112905 | sqlite3DecOrHexToI64(zRight, &iLimit); |
| 112556 | 112906 | if( iLimit<-1 ) iLimit = -1; |
| 112557 | 112907 | } |
| 112558 | 112908 | iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); |
| 112559 | | - returnSingleInt(v, "journal_size_limit", iLimit); |
| 112909 | + returnSingleInt(v, iLimit); |
| 112560 | 112910 | break; |
| 112561 | 112911 | } |
| 112562 | 112912 | |
| 112563 | 112913 | #endif /* SQLITE_OMIT_PAGER_PRAGMAS */ |
| 112564 | 112914 | |
| | @@ -112572,11 +112922,11 @@ |
| 112572 | 112922 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| 112573 | 112923 | case PragTyp_AUTO_VACUUM: { |
| 112574 | 112924 | Btree *pBt = pDb->pBt; |
| 112575 | 112925 | assert( pBt!=0 ); |
| 112576 | 112926 | if( !zRight ){ |
| 112577 | | - returnSingleInt(v, "auto_vacuum", sqlite3BtreeGetAutoVacuum(pBt)); |
| 112927 | + returnSingleInt(v, sqlite3BtreeGetAutoVacuum(pBt)); |
| 112578 | 112928 | }else{ |
| 112579 | 112929 | int eAuto = getAutoVacuum(zRight); |
| 112580 | 112930 | assert( eAuto>=0 && eAuto<=2 ); |
| 112581 | 112931 | db->nextAutovac = (u8)eAuto; |
| 112582 | 112932 | /* Call SetAutoVacuum() to set initialize the internal auto and |
| | @@ -112651,11 +113001,11 @@ |
| 112651 | 113001 | ** of memory. |
| 112652 | 113002 | */ |
| 112653 | 113003 | case PragTyp_CACHE_SIZE: { |
| 112654 | 113004 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 112655 | 113005 | if( !zRight ){ |
| 112656 | | - returnSingleInt(v, "cache_size", pDb->pSchema->cache_size); |
| 113006 | + returnSingleInt(v, pDb->pSchema->cache_size); |
| 112657 | 113007 | }else{ |
| 112658 | 113008 | int size = sqlite3Atoi(zRight); |
| 112659 | 113009 | pDb->pSchema->cache_size = size; |
| 112660 | 113010 | sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); |
| 112661 | 113011 | } |
| | @@ -112685,11 +113035,11 @@ |
| 112685 | 113035 | ** not just the schema specified. |
| 112686 | 113036 | */ |
| 112687 | 113037 | case PragTyp_CACHE_SPILL: { |
| 112688 | 113038 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 112689 | 113039 | if( !zRight ){ |
| 112690 | | - returnSingleInt(v, "cache_spill", |
| 113040 | + returnSingleInt(v, |
| 112691 | 113041 | (db->flags & SQLITE_CacheSpill)==0 ? 0 : |
| 112692 | 113042 | sqlite3BtreeSetSpillSize(pDb->pBt,0)); |
| 112693 | 113043 | }else{ |
| 112694 | 113044 | int size = 1; |
| 112695 | 113045 | if( sqlite3GetInt32(zRight, &size) ){ |
| | @@ -112739,11 +113089,11 @@ |
| 112739 | 113089 | #else |
| 112740 | 113090 | sz = 0; |
| 112741 | 113091 | rc = SQLITE_OK; |
| 112742 | 113092 | #endif |
| 112743 | 113093 | if( rc==SQLITE_OK ){ |
| 112744 | | - returnSingleInt(v, "mmap_size", sz); |
| 113094 | + returnSingleInt(v, sz); |
| 112745 | 113095 | }else if( rc!=SQLITE_NOTFOUND ){ |
| 112746 | 113096 | pParse->nErr++; |
| 112747 | 113097 | pParse->rc = rc; |
| 112748 | 113098 | } |
| 112749 | 113099 | break; |
| | @@ -112760,11 +113110,11 @@ |
| 112760 | 113110 | ** Note that it is possible for the library compile-time options to |
| 112761 | 113111 | ** override this setting |
| 112762 | 113112 | */ |
| 112763 | 113113 | case PragTyp_TEMP_STORE: { |
| 112764 | 113114 | if( !zRight ){ |
| 112765 | | - returnSingleInt(v, "temp_store", db->temp_store); |
| 113115 | + returnSingleInt(v, db->temp_store); |
| 112766 | 113116 | }else{ |
| 112767 | 113117 | changeTempStorage(pParse, zRight); |
| 112768 | 113118 | } |
| 112769 | 113119 | break; |
| 112770 | 113120 | } |
| | @@ -112779,11 +113129,11 @@ |
| 112779 | 113129 | ** If temporary directory is changed, then invalidateTempStorage. |
| 112780 | 113130 | ** |
| 112781 | 113131 | */ |
| 112782 | 113132 | case PragTyp_TEMP_STORE_DIRECTORY: { |
| 112783 | 113133 | if( !zRight ){ |
| 112784 | | - returnSingleText(v, "temp_store_directory", sqlite3_temp_directory); |
| 113134 | + returnSingleText(v, sqlite3_temp_directory); |
| 112785 | 113135 | }else{ |
| 112786 | 113136 | #ifndef SQLITE_OMIT_WSD |
| 112787 | 113137 | if( zRight[0] ){ |
| 112788 | 113138 | int res; |
| 112789 | 113139 | rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res); |
| | @@ -112823,11 +113173,11 @@ |
| 112823 | 113173 | ** by this setting, regardless of its value. |
| 112824 | 113174 | ** |
| 112825 | 113175 | */ |
| 112826 | 113176 | case PragTyp_DATA_STORE_DIRECTORY: { |
| 112827 | 113177 | if( !zRight ){ |
| 112828 | | - returnSingleText(v, "data_store_directory", sqlite3_data_directory); |
| 113178 | + returnSingleText(v, sqlite3_data_directory); |
| 112829 | 113179 | }else{ |
| 112830 | 113180 | #ifndef SQLITE_OMIT_WSD |
| 112831 | 113181 | if( zRight[0] ){ |
| 112832 | 113182 | int res; |
| 112833 | 113183 | rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res); |
| | @@ -112862,11 +113212,11 @@ |
| 112862 | 113212 | Pager *pPager = sqlite3BtreePager(pDb->pBt); |
| 112863 | 113213 | char *proxy_file_path = NULL; |
| 112864 | 113214 | sqlite3_file *pFile = sqlite3PagerFile(pPager); |
| 112865 | 113215 | sqlite3OsFileControlHint(pFile, SQLITE_GET_LOCKPROXYFILE, |
| 112866 | 113216 | &proxy_file_path); |
| 112867 | | - returnSingleText(v, "lock_proxy_file", proxy_file_path); |
| 113217 | + returnSingleText(v, proxy_file_path); |
| 112868 | 113218 | }else{ |
| 112869 | 113219 | Pager *pPager = sqlite3BtreePager(pDb->pBt); |
| 112870 | 113220 | sqlite3_file *pFile = sqlite3PagerFile(pPager); |
| 112871 | 113221 | int res; |
| 112872 | 113222 | if( zRight[0] ){ |
| | @@ -112894,11 +113244,11 @@ |
| 112894 | 113244 | ** default value will be restored the next time the database is |
| 112895 | 113245 | ** opened. |
| 112896 | 113246 | */ |
| 112897 | 113247 | case PragTyp_SYNCHRONOUS: { |
| 112898 | 113248 | if( !zRight ){ |
| 112899 | | - returnSingleInt(v, "synchronous", pDb->safety_level-1); |
| 113249 | + returnSingleInt(v, pDb->safety_level-1); |
| 112900 | 113250 | }else{ |
| 112901 | 113251 | if( !db->autoCommit ){ |
| 112902 | 113252 | sqlite3ErrorMsg(pParse, |
| 112903 | 113253 | "Safety level may not be changed inside a transaction"); |
| 112904 | 113254 | }else{ |
| | @@ -112914,11 +113264,12 @@ |
| 112914 | 113264 | #endif /* SQLITE_OMIT_PAGER_PRAGMAS */ |
| 112915 | 113265 | |
| 112916 | 113266 | #ifndef SQLITE_OMIT_FLAG_PRAGMAS |
| 112917 | 113267 | case PragTyp_FLAG: { |
| 112918 | 113268 | if( zRight==0 ){ |
| 112919 | | - returnSingleInt(v, pPragma->zName, (db->flags & pPragma->iArg)!=0 ); |
| 113269 | + setPragmaResultColumnNames(v, pPragma); |
| 113270 | + returnSingleInt(v, (db->flags & pPragma->iArg)!=0 ); |
| 112920 | 113271 | }else{ |
| 112921 | 113272 | int mask = pPragma->iArg; /* Mask of bits to set or clear. */ |
| 112922 | 113273 | if( db->autoCommit==0 ){ |
| 112923 | 113274 | /* Foreign key support may not be enabled or disabled while not |
| 112924 | 113275 | ** in auto-commit mode. */ |
| | @@ -112964,20 +113315,16 @@ |
| 112964 | 113315 | */ |
| 112965 | 113316 | case PragTyp_TABLE_INFO: if( zRight ){ |
| 112966 | 113317 | Table *pTab; |
| 112967 | 113318 | pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb); |
| 112968 | 113319 | if( pTab ){ |
| 112969 | | - static const char *azCol[] = { |
| 112970 | | - "cid", "name", "type", "notnull", "dflt_value", "pk" |
| 112971 | | - }; |
| 112972 | 113320 | int i, k; |
| 112973 | 113321 | int nHidden = 0; |
| 112974 | 113322 | Column *pCol; |
| 112975 | 113323 | Index *pPk = sqlite3PrimaryKeyIndex(pTab); |
| 112976 | 113324 | pParse->nMem = 6; |
| 112977 | 113325 | sqlite3CodeVerifySchema(pParse, iDb); |
| 112978 | | - setAllColumnNames(v, 6, azCol); assert( 6==ArraySize(azCol) ); |
| 112979 | 113326 | sqlite3ViewGetColumnNames(pParse, pTab); |
| 112980 | 113327 | for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){ |
| 112981 | 113328 | if( IsHiddenColumn(pCol) ){ |
| 112982 | 113329 | nHidden++; |
| 112983 | 113330 | continue; |
| | @@ -113002,17 +113349,14 @@ |
| 113002 | 113349 | } |
| 113003 | 113350 | } |
| 113004 | 113351 | break; |
| 113005 | 113352 | |
| 113006 | 113353 | case PragTyp_STATS: { |
| 113007 | | - static const char *azCol[] = { "table", "index", "width", "height" }; |
| 113008 | 113354 | Index *pIdx; |
| 113009 | 113355 | HashElem *i; |
| 113010 | | - v = sqlite3GetVdbe(pParse); |
| 113011 | 113356 | pParse->nMem = 4; |
| 113012 | 113357 | sqlite3CodeVerifySchema(pParse, iDb); |
| 113013 | | - setAllColumnNames(v, 4, azCol); assert( 4==ArraySize(azCol) ); |
| 113014 | 113358 | for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){ |
| 113015 | 113359 | Table *pTab = sqliteHashData(i); |
| 113016 | 113360 | sqlite3VdbeMultiLoad(v, 1, "ssii", |
| 113017 | 113361 | pTab->zName, |
| 113018 | 113362 | 0, |
| | @@ -113033,13 +113377,10 @@ |
| 113033 | 113377 | case PragTyp_INDEX_INFO: if( zRight ){ |
| 113034 | 113378 | Index *pIdx; |
| 113035 | 113379 | Table *pTab; |
| 113036 | 113380 | pIdx = sqlite3FindIndex(db, zRight, zDb); |
| 113037 | 113381 | if( pIdx ){ |
| 113038 | | - static const char *azCol[] = { |
| 113039 | | - "seqno", "cid", "name", "desc", "coll", "key" |
| 113040 | | - }; |
| 113041 | 113382 | int i; |
| 113042 | 113383 | int mx; |
| 113043 | 113384 | if( pPragma->iArg ){ |
| 113044 | 113385 | /* PRAGMA index_xinfo (newer version with more rows and columns) */ |
| 113045 | 113386 | mx = pIdx->nColumn; |
| | @@ -113049,12 +113390,11 @@ |
| 113049 | 113390 | mx = pIdx->nKeyCol; |
| 113050 | 113391 | pParse->nMem = 3; |
| 113051 | 113392 | } |
| 113052 | 113393 | pTab = pIdx->pTable; |
| 113053 | 113394 | sqlite3CodeVerifySchema(pParse, iDb); |
| 113054 | | - assert( pParse->nMem<=ArraySize(azCol) ); |
| 113055 | | - setAllColumnNames(v, pParse->nMem, azCol); |
| 113395 | + assert( pParse->nMem<=pPragma->nPragCName ); |
| 113056 | 113396 | for(i=0; i<mx; i++){ |
| 113057 | 113397 | i16 cnum = pIdx->aiColumn[i]; |
| 113058 | 113398 | sqlite3VdbeMultiLoad(v, 1, "iis", i, cnum, |
| 113059 | 113399 | cnum<0 ? 0 : pTab->aCol[cnum].zName); |
| 113060 | 113400 | if( pPragma->iArg ){ |
| | @@ -113073,17 +113413,12 @@ |
| 113073 | 113413 | Index *pIdx; |
| 113074 | 113414 | Table *pTab; |
| 113075 | 113415 | int i; |
| 113076 | 113416 | pTab = sqlite3FindTable(db, zRight, zDb); |
| 113077 | 113417 | if( pTab ){ |
| 113078 | | - static const char *azCol[] = { |
| 113079 | | - "seq", "name", "unique", "origin", "partial" |
| 113080 | | - }; |
| 113081 | | - v = sqlite3GetVdbe(pParse); |
| 113082 | 113418 | pParse->nMem = 5; |
| 113083 | 113419 | sqlite3CodeVerifySchema(pParse, iDb); |
| 113084 | | - setAllColumnNames(v, 5, azCol); assert( 5==ArraySize(azCol) ); |
| 113085 | 113420 | for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){ |
| 113086 | 113421 | const char *azOrigin[] = { "c", "u", "pk" }; |
| 113087 | 113422 | sqlite3VdbeMultiLoad(v, 1, "isisi", |
| 113088 | 113423 | i, |
| 113089 | 113424 | pIdx->zName, |
| | @@ -113095,14 +113430,12 @@ |
| 113095 | 113430 | } |
| 113096 | 113431 | } |
| 113097 | 113432 | break; |
| 113098 | 113433 | |
| 113099 | 113434 | case PragTyp_DATABASE_LIST: { |
| 113100 | | - static const char *azCol[] = { "seq", "name", "file" }; |
| 113101 | 113435 | int i; |
| 113102 | 113436 | pParse->nMem = 3; |
| 113103 | | - setAllColumnNames(v, 3, azCol); assert( 3==ArraySize(azCol) ); |
| 113104 | 113437 | for(i=0; i<db->nDb; i++){ |
| 113105 | 113438 | if( db->aDb[i].pBt==0 ) continue; |
| 113106 | 113439 | assert( db->aDb[i].zDbSName!=0 ); |
| 113107 | 113440 | sqlite3VdbeMultiLoad(v, 1, "iss", |
| 113108 | 113441 | i, |
| | @@ -113112,15 +113445,13 @@ |
| 113112 | 113445 | } |
| 113113 | 113446 | } |
| 113114 | 113447 | break; |
| 113115 | 113448 | |
| 113116 | 113449 | case PragTyp_COLLATION_LIST: { |
| 113117 | | - static const char *azCol[] = { "seq", "name" }; |
| 113118 | 113450 | int i = 0; |
| 113119 | 113451 | HashElem *p; |
| 113120 | 113452 | pParse->nMem = 2; |
| 113121 | | - setAllColumnNames(v, 2, azCol); assert( 2==ArraySize(azCol) ); |
| 113122 | 113453 | for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){ |
| 113123 | 113454 | CollSeq *pColl = (CollSeq *)sqliteHashData(p); |
| 113124 | 113455 | sqlite3VdbeMultiLoad(v, 1, "is", i++, pColl->zName); |
| 113125 | 113456 | sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2); |
| 113126 | 113457 | } |
| | @@ -113132,21 +113463,15 @@ |
| 113132 | 113463 | case PragTyp_FOREIGN_KEY_LIST: if( zRight ){ |
| 113133 | 113464 | FKey *pFK; |
| 113134 | 113465 | Table *pTab; |
| 113135 | 113466 | pTab = sqlite3FindTable(db, zRight, zDb); |
| 113136 | 113467 | if( pTab ){ |
| 113137 | | - v = sqlite3GetVdbe(pParse); |
| 113138 | 113468 | pFK = pTab->pFKey; |
| 113139 | 113469 | if( pFK ){ |
| 113140 | | - static const char *azCol[] = { |
| 113141 | | - "id", "seq", "table", "from", "to", "on_update", "on_delete", |
| 113142 | | - "match" |
| 113143 | | - }; |
| 113144 | 113470 | int i = 0; |
| 113145 | 113471 | pParse->nMem = 8; |
| 113146 | 113472 | sqlite3CodeVerifySchema(pParse, iDb); |
| 113147 | | - setAllColumnNames(v, 8, azCol); assert( 8==ArraySize(azCol) ); |
| 113148 | 113473 | while(pFK){ |
| 113149 | 113474 | int j; |
| 113150 | 113475 | for(j=0; j<pFK->nCol; j++){ |
| 113151 | 113476 | sqlite3VdbeMultiLoad(v, 1, "iissssss", |
| 113152 | 113477 | i, |
| | @@ -113183,18 +113508,15 @@ |
| 113183 | 113508 | int regKey; /* Register to hold key for checking the FK */ |
| 113184 | 113509 | int regRow; /* Registers to hold a row from pTab */ |
| 113185 | 113510 | int addrTop; /* Top of a loop checking foreign keys */ |
| 113186 | 113511 | int addrOk; /* Jump here if the key is OK */ |
| 113187 | 113512 | int *aiCols; /* child to parent column mapping */ |
| 113188 | | - static const char *azCol[] = { "table", "rowid", "parent", "fkid" }; |
| 113189 | 113513 | |
| 113190 | 113514 | regResult = pParse->nMem+1; |
| 113191 | 113515 | pParse->nMem += 4; |
| 113192 | 113516 | regKey = ++pParse->nMem; |
| 113193 | 113517 | regRow = ++pParse->nMem; |
| 113194 | | - v = sqlite3GetVdbe(pParse); |
| 113195 | | - setAllColumnNames(v, 4, azCol); assert( 4==ArraySize(azCol) ); |
| 113196 | 113518 | sqlite3CodeVerifySchema(pParse, iDb); |
| 113197 | 113519 | k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash); |
| 113198 | 113520 | while( k ){ |
| 113199 | 113521 | if( zRight ){ |
| 113200 | 113522 | pTab = sqlite3LocateTable(pParse, 0, zRight, zDb); |
| | @@ -113329,11 +113651,10 @@ |
| 113329 | 113651 | assert( iDb==0 || pId2->z ); |
| 113330 | 113652 | if( pId2->z==0 ) iDb = -1; |
| 113331 | 113653 | |
| 113332 | 113654 | /* Initialize the VDBE program */ |
| 113333 | 113655 | pParse->nMem = 6; |
| 113334 | | - setOneColumnName(v, "integrity_check"); |
| 113335 | 113656 | |
| 113336 | 113657 | /* Set the maximum error count */ |
| 113337 | 113658 | mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; |
| 113338 | 113659 | if( zRight ){ |
| 113339 | 113660 | sqlite3GetInt32(zRight, &mxErr); |
| | @@ -113581,11 +113902,11 @@ |
| 113581 | 113902 | if( !zRight ){ /* "PRAGMA encoding" */ |
| 113582 | 113903 | if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 113583 | 113904 | assert( encnames[SQLITE_UTF8].enc==SQLITE_UTF8 ); |
| 113584 | 113905 | assert( encnames[SQLITE_UTF16LE].enc==SQLITE_UTF16LE ); |
| 113585 | 113906 | assert( encnames[SQLITE_UTF16BE].enc==SQLITE_UTF16BE ); |
| 113586 | | - returnSingleText(v, "encoding", encnames[ENC(pParse->db)].zName); |
| 113907 | + returnSingleText(v, encnames[ENC(pParse->db)].zName); |
| 113587 | 113908 | }else{ /* "PRAGMA encoding = XXX" */ |
| 113588 | 113909 | /* Only change the value of sqlite.enc if the database handle is not |
| 113589 | 113910 | ** initialized. If the main database exists, the new sqlite.enc value |
| 113590 | 113911 | ** will be overwritten when the schema is next loaded. If it does not |
| 113591 | 113912 | ** already exists, it will be created to use the new encoding value. |
| | @@ -113644,11 +113965,11 @@ |
| 113644 | 113965 | ** applications for any purpose. |
| 113645 | 113966 | */ |
| 113646 | 113967 | case PragTyp_HEADER_VALUE: { |
| 113647 | 113968 | int iCookie = pPragma->iArg; /* Which cookie to read or write */ |
| 113648 | 113969 | sqlite3VdbeUsesBtree(v, iDb); |
| 113649 | | - if( zRight && (pPragma->mPragFlag & PragFlag_ReadOnly)==0 ){ |
| 113970 | + if( zRight && (pPragma->mPragFlg & PragFlg_ReadOnly)==0 ){ |
| 113650 | 113971 | /* Write the specified cookie value */ |
| 113651 | 113972 | static const VdbeOpList setCookie[] = { |
| 113652 | 113973 | { OP_Transaction, 0, 1, 0}, /* 0 */ |
| 113653 | 113974 | { OP_SetCookie, 0, 0, 0}, /* 1 */ |
| 113654 | 113975 | }; |
| | @@ -113672,12 +113993,10 @@ |
| 113672 | 113993 | aOp = sqlite3VdbeAddOpList(v, ArraySize(readCookie),readCookie,0); |
| 113673 | 113994 | if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; |
| 113674 | 113995 | aOp[0].p1 = iDb; |
| 113675 | 113996 | aOp[1].p1 = iDb; |
| 113676 | 113997 | aOp[1].p3 = iCookie; |
| 113677 | | - sqlite3VdbeSetNumCols(v, 1); |
| 113678 | | - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT); |
| 113679 | 113998 | sqlite3VdbeReusable(v); |
| 113680 | 113999 | } |
| 113681 | 114000 | } |
| 113682 | 114001 | break; |
| 113683 | 114002 | #endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */ |
| | @@ -113691,11 +114010,10 @@ |
| 113691 | 114010 | */ |
| 113692 | 114011 | case PragTyp_COMPILE_OPTIONS: { |
| 113693 | 114012 | int i = 0; |
| 113694 | 114013 | const char *zOpt; |
| 113695 | 114014 | pParse->nMem = 1; |
| 113696 | | - setOneColumnName(v, "compile_option"); |
| 113697 | 114015 | while( (zOpt = sqlite3_compileoption_get(i++))!=0 ){ |
| 113698 | 114016 | sqlite3VdbeLoadString(v, 1, zOpt); |
| 113699 | 114017 | sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); |
| 113700 | 114018 | } |
| 113701 | 114019 | sqlite3VdbeReusable(v); |
| | @@ -113708,11 +114026,10 @@ |
| 113708 | 114026 | ** PRAGMA [schema.]wal_checkpoint = passive|full|restart|truncate |
| 113709 | 114027 | ** |
| 113710 | 114028 | ** Checkpoint the database. |
| 113711 | 114029 | */ |
| 113712 | 114030 | case PragTyp_WAL_CHECKPOINT: { |
| 113713 | | - static const char *azCol[] = { "busy", "log", "checkpointed" }; |
| 113714 | 114031 | int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED); |
| 113715 | 114032 | int eMode = SQLITE_CHECKPOINT_PASSIVE; |
| 113716 | 114033 | if( zRight ){ |
| 113717 | 114034 | if( sqlite3StrICmp(zRight, "full")==0 ){ |
| 113718 | 114035 | eMode = SQLITE_CHECKPOINT_FULL; |
| | @@ -113720,11 +114037,10 @@ |
| 113720 | 114037 | eMode = SQLITE_CHECKPOINT_RESTART; |
| 113721 | 114038 | }else if( sqlite3StrICmp(zRight, "truncate")==0 ){ |
| 113722 | 114039 | eMode = SQLITE_CHECKPOINT_TRUNCATE; |
| 113723 | 114040 | } |
| 113724 | 114041 | } |
| 113725 | | - setAllColumnNames(v, 3, azCol); assert( 3==ArraySize(azCol) ); |
| 113726 | 114042 | pParse->nMem = 3; |
| 113727 | 114043 | sqlite3VdbeAddOp3(v, OP_Checkpoint, iBt, eMode, 1); |
| 113728 | 114044 | sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); |
| 113729 | 114045 | } |
| 113730 | 114046 | break; |
| | @@ -113739,11 +114055,11 @@ |
| 113739 | 114055 | */ |
| 113740 | 114056 | case PragTyp_WAL_AUTOCHECKPOINT: { |
| 113741 | 114057 | if( zRight ){ |
| 113742 | 114058 | sqlite3_wal_autocheckpoint(db, sqlite3Atoi(zRight)); |
| 113743 | 114059 | } |
| 113744 | | - returnSingleInt(v, "wal_autocheckpoint", |
| 114060 | + returnSingleInt(v, |
| 113745 | 114061 | db->xWalCallback==sqlite3WalDefaultHook ? |
| 113746 | 114062 | SQLITE_PTR_TO_INT(db->pWalArg) : 0); |
| 113747 | 114063 | } |
| 113748 | 114064 | break; |
| 113749 | 114065 | #endif |
| | @@ -113772,11 +114088,11 @@ |
| 113772 | 114088 | /*case PragTyp_BUSY_TIMEOUT*/ default: { |
| 113773 | 114089 | assert( pPragma->ePragTyp==PragTyp_BUSY_TIMEOUT ); |
| 113774 | 114090 | if( zRight ){ |
| 113775 | 114091 | sqlite3_busy_timeout(db, sqlite3Atoi(zRight)); |
| 113776 | 114092 | } |
| 113777 | | - returnSingleInt(v, "timeout", db->busyTimeout); |
| 114093 | + returnSingleInt(v, db->busyTimeout); |
| 113778 | 114094 | break; |
| 113779 | 114095 | } |
| 113780 | 114096 | |
| 113781 | 114097 | /* |
| 113782 | 114098 | ** PRAGMA soft_heap_limit |
| | @@ -113792,11 +114108,11 @@ |
| 113792 | 114108 | case PragTyp_SOFT_HEAP_LIMIT: { |
| 113793 | 114109 | sqlite3_int64 N; |
| 113794 | 114110 | if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){ |
| 113795 | 114111 | sqlite3_soft_heap_limit64(N); |
| 113796 | 114112 | } |
| 113797 | | - returnSingleInt(v, "soft_heap_limit", sqlite3_soft_heap_limit64(-1)); |
| 114113 | + returnSingleInt(v, sqlite3_soft_heap_limit64(-1)); |
| 113798 | 114114 | break; |
| 113799 | 114115 | } |
| 113800 | 114116 | |
| 113801 | 114117 | /* |
| 113802 | 114118 | ** PRAGMA threads |
| | @@ -113811,12 +114127,11 @@ |
| 113811 | 114127 | && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK |
| 113812 | 114128 | && N>=0 |
| 113813 | 114129 | ){ |
| 113814 | 114130 | sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff)); |
| 113815 | 114131 | } |
| 113816 | | - returnSingleInt(v, "threads", |
| 113817 | | - sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1)); |
| 114132 | + returnSingleInt(v, sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1)); |
| 113818 | 114133 | break; |
| 113819 | 114134 | } |
| 113820 | 114135 | |
| 113821 | 114136 | #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) |
| 113822 | 114137 | /* |
| | @@ -113824,13 +114139,11 @@ |
| 113824 | 114139 | */ |
| 113825 | 114140 | case PragTyp_LOCK_STATUS: { |
| 113826 | 114141 | static const char *const azLockName[] = { |
| 113827 | 114142 | "unlocked", "shared", "reserved", "pending", "exclusive" |
| 113828 | 114143 | }; |
| 113829 | | - static const char *azCol[] = { "database", "status" }; |
| 113830 | 114144 | int i; |
| 113831 | | - setAllColumnNames(v, 2, azCol); assert( 2==ArraySize(azCol) ); |
| 113832 | 114145 | pParse->nMem = 2; |
| 113833 | 114146 | for(i=0; i<db->nDb; i++){ |
| 113834 | 114147 | Btree *pBt; |
| 113835 | 114148 | const char *zState = "unknown"; |
| 113836 | 114149 | int j; |
| | @@ -113896,10 +114209,316 @@ |
| 113896 | 114209 | |
| 113897 | 114210 | pragma_out: |
| 113898 | 114211 | sqlite3DbFree(db, zLeft); |
| 113899 | 114212 | sqlite3DbFree(db, zRight); |
| 113900 | 114213 | } |
| 114214 | +#ifndef SQLITE_OMIT_VIRTUALTABLE |
| 114215 | +/***************************************************************************** |
| 114216 | +** Implementation of an eponymous virtual table that runs a pragma. |
| 114217 | +** |
| 114218 | +*/ |
| 114219 | +typedef struct PragmaVtab PragmaVtab; |
| 114220 | +typedef struct PragmaVtabCursor PragmaVtabCursor; |
| 114221 | +struct PragmaVtab { |
| 114222 | + sqlite3_vtab base; /* Base class. Must be first */ |
| 114223 | + sqlite3 *db; /* The database connection to which it belongs */ |
| 114224 | + const PragmaName *pName; /* Name of the pragma */ |
| 114225 | + u8 nHidden; /* Number of hidden columns */ |
| 114226 | + u8 iHidden; /* Index of the first hidden column */ |
| 114227 | +}; |
| 114228 | +struct PragmaVtabCursor { |
| 114229 | + sqlite3_vtab_cursor base; /* Base class. Must be first */ |
| 114230 | + sqlite3_stmt *pPragma; /* The pragma statement to run */ |
| 114231 | + sqlite_int64 iRowid; /* Current rowid */ |
| 114232 | + char *azArg[2]; /* Value of the argument and schema */ |
| 114233 | +}; |
| 114234 | + |
| 114235 | +/* |
| 114236 | +** Pragma virtual table module xConnect method. |
| 114237 | +*/ |
| 114238 | +static int pragmaVtabConnect( |
| 114239 | + sqlite3 *db, |
| 114240 | + void *pAux, |
| 114241 | + int argc, const char *const*argv, |
| 114242 | + sqlite3_vtab **ppVtab, |
| 114243 | + char **pzErr |
| 114244 | +){ |
| 114245 | + const PragmaName *pPragma = (const PragmaName*)pAux; |
| 114246 | + PragmaVtab *pTab = 0; |
| 114247 | + int rc; |
| 114248 | + int i, j; |
| 114249 | + char cSep = '('; |
| 114250 | + StrAccum acc; |
| 114251 | + char zBuf[200]; |
| 114252 | + |
| 114253 | + UNUSED_PARAMETER(argc); |
| 114254 | + UNUSED_PARAMETER(argv); |
| 114255 | + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); |
| 114256 | + sqlite3StrAccumAppendAll(&acc, "CREATE TABLE x"); |
| 114257 | + for(i=0, j=pPragma->iPragCName; i<pPragma->nPragCName; i++, j++){ |
| 114258 | + sqlite3XPrintf(&acc, "%c\"%s\"", cSep, pragCName[j]); |
| 114259 | + cSep = ','; |
| 114260 | + } |
| 114261 | + if( i==0 ){ |
| 114262 | + sqlite3XPrintf(&acc, "(\"%s\"", pPragma->zName); |
| 114263 | + cSep = ','; |
| 114264 | + i++; |
| 114265 | + } |
| 114266 | + j = 0; |
| 114267 | + if( pPragma->mPragFlg & PragFlg_Result1 ){ |
| 114268 | + sqlite3StrAccumAppendAll(&acc, ",arg HIDDEN"); |
| 114269 | + j++; |
| 114270 | + } |
| 114271 | + if( pPragma->mPragFlg & (PragFlg_SchemaOpt|PragFlg_SchemaReq) ){ |
| 114272 | + sqlite3StrAccumAppendAll(&acc, ",schema HIDDEN"); |
| 114273 | + j++; |
| 114274 | + } |
| 114275 | + sqlite3StrAccumAppend(&acc, ")", 1); |
| 114276 | + sqlite3StrAccumFinish(&acc); |
| 114277 | + assert( strlen(zBuf) < sizeof(zBuf)-1 ); |
| 114278 | + rc = sqlite3_declare_vtab(db, zBuf); |
| 114279 | + if( rc==SQLITE_OK ){ |
| 114280 | + pTab = (PragmaVtab*)sqlite3_malloc(sizeof(PragmaVtab)); |
| 114281 | + if( pTab==0 ){ |
| 114282 | + rc = SQLITE_NOMEM; |
| 114283 | + }else{ |
| 114284 | + memset(pTab, 0, sizeof(PragmaVtab)); |
| 114285 | + pTab->pName = pPragma; |
| 114286 | + pTab->db = db; |
| 114287 | + pTab->iHidden = i; |
| 114288 | + pTab->nHidden = j; |
| 114289 | + } |
| 114290 | + }else{ |
| 114291 | + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); |
| 114292 | + } |
| 114293 | + |
| 114294 | + *ppVtab = (sqlite3_vtab*)pTab; |
| 114295 | + return rc; |
| 114296 | +} |
| 114297 | + |
| 114298 | +/* |
| 114299 | +** Pragma virtual table module xDisconnect method. |
| 114300 | +*/ |
| 114301 | +static int pragmaVtabDisconnect(sqlite3_vtab *pVtab){ |
| 114302 | + PragmaVtab *pTab = (PragmaVtab*)pVtab; |
| 114303 | + sqlite3_free(pTab); |
| 114304 | + return SQLITE_OK; |
| 114305 | +} |
| 114306 | + |
| 114307 | +/* Figure out the best index to use to search a pragma virtual table. |
| 114308 | +** |
| 114309 | +** There are not really any index choices. But we want to encourage the |
| 114310 | +** query planner to give == constraints on as many hidden parameters as |
| 114311 | +** possible, and especially on the first hidden parameter. So return a |
| 114312 | +** high cost if hidden parameters are unconstrained. |
| 114313 | +*/ |
| 114314 | +static int pragmaVtabBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ |
| 114315 | + PragmaVtab *pTab = (PragmaVtab*)tab; |
| 114316 | + const struct sqlite3_index_constraint *pConstraint; |
| 114317 | + int i, j; |
| 114318 | + int seen[2]; |
| 114319 | + |
| 114320 | + pIdxInfo->estimatedCost = (double)1; |
| 114321 | + if( pTab->nHidden==0 ){ return SQLITE_OK; } |
| 114322 | + pConstraint = pIdxInfo->aConstraint; |
| 114323 | + seen[0] = 0; |
| 114324 | + seen[1] = 0; |
| 114325 | + for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){ |
| 114326 | + if( pConstraint->usable==0 ) continue; |
| 114327 | + if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; |
| 114328 | + if( pConstraint->iColumn < pTab->iHidden ) continue; |
| 114329 | + j = pConstraint->iColumn - pTab->iHidden; |
| 114330 | + assert( j < 2 ); |
| 114331 | + seen[j] = i+1; |
| 114332 | + } |
| 114333 | + if( seen[0]==0 ){ |
| 114334 | + pIdxInfo->estimatedCost = (double)2147483647; |
| 114335 | + pIdxInfo->estimatedRows = 2147483647; |
| 114336 | + return SQLITE_OK; |
| 114337 | + } |
| 114338 | + j = seen[0]-1; |
| 114339 | + pIdxInfo->aConstraintUsage[j].argvIndex = 1; |
| 114340 | + pIdxInfo->aConstraintUsage[j].omit = 1; |
| 114341 | + if( seen[1]==0 ) return SQLITE_OK; |
| 114342 | + pIdxInfo->estimatedCost = (double)20; |
| 114343 | + pIdxInfo->estimatedRows = 20; |
| 114344 | + j = seen[1]-1; |
| 114345 | + pIdxInfo->aConstraintUsage[j].argvIndex = 2; |
| 114346 | + pIdxInfo->aConstraintUsage[j].omit = 1; |
| 114347 | + return SQLITE_OK; |
| 114348 | +} |
| 114349 | + |
| 114350 | +/* Create a new cursor for the pragma virtual table */ |
| 114351 | +static int pragmaVtabOpen(sqlite3_vtab *pVtab, sqlite3_vtab_cursor **ppCursor){ |
| 114352 | + PragmaVtabCursor *pCsr; |
| 114353 | + pCsr = (PragmaVtabCursor*)sqlite3_malloc(sizeof(*pCsr)); |
| 114354 | + if( pCsr==0 ) return SQLITE_NOMEM; |
| 114355 | + memset(pCsr, 0, sizeof(PragmaVtabCursor)); |
| 114356 | + pCsr->base.pVtab = pVtab; |
| 114357 | + *ppCursor = &pCsr->base; |
| 114358 | + return SQLITE_OK; |
| 114359 | +} |
| 114360 | + |
| 114361 | +/* Clear all content from pragma virtual table cursor. */ |
| 114362 | +static void pragmaVtabCursorClear(PragmaVtabCursor *pCsr){ |
| 114363 | + int i; |
| 114364 | + sqlite3_finalize(pCsr->pPragma); |
| 114365 | + pCsr->pPragma = 0; |
| 114366 | + for(i=0; i<ArraySize(pCsr->azArg); i++){ |
| 114367 | + sqlite3_free(pCsr->azArg[i]); |
| 114368 | + pCsr->azArg[i] = 0; |
| 114369 | + } |
| 114370 | +} |
| 114371 | + |
| 114372 | +/* Close a pragma virtual table cursor */ |
| 114373 | +static int pragmaVtabClose(sqlite3_vtab_cursor *cur){ |
| 114374 | + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)cur; |
| 114375 | + pragmaVtabCursorClear(pCsr); |
| 114376 | + sqlite3_free(pCsr); |
| 114377 | + return SQLITE_OK; |
| 114378 | +} |
| 114379 | + |
| 114380 | +/* Advance the pragma virtual table cursor to the next row */ |
| 114381 | +static int pragmaVtabNext(sqlite3_vtab_cursor *pVtabCursor){ |
| 114382 | + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; |
| 114383 | + int rc = SQLITE_OK; |
| 114384 | + |
| 114385 | + /* Increment the xRowid value */ |
| 114386 | + pCsr->iRowid++; |
| 114387 | + assert( pCsr->pPragma ); |
| 114388 | + if( SQLITE_ROW!=sqlite3_step(pCsr->pPragma) ){ |
| 114389 | + rc = sqlite3_finalize(pCsr->pPragma); |
| 114390 | + pCsr->pPragma = 0; |
| 114391 | + pragmaVtabCursorClear(pCsr); |
| 114392 | + } |
| 114393 | + return rc; |
| 114394 | +} |
| 114395 | + |
| 114396 | +/* |
| 114397 | +** Pragma virtual table module xFilter method. |
| 114398 | +*/ |
| 114399 | +static int pragmaVtabFilter( |
| 114400 | + sqlite3_vtab_cursor *pVtabCursor, |
| 114401 | + int idxNum, const char *idxStr, |
| 114402 | + int argc, sqlite3_value **argv |
| 114403 | +){ |
| 114404 | + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; |
| 114405 | + PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab); |
| 114406 | + int rc; |
| 114407 | + int i, j; |
| 114408 | + StrAccum acc; |
| 114409 | + char *zSql; |
| 114410 | + |
| 114411 | + UNUSED_PARAMETER(idxNum); |
| 114412 | + UNUSED_PARAMETER(idxStr); |
| 114413 | + pragmaVtabCursorClear(pCsr); |
| 114414 | + j = (pTab->pName->mPragFlg & PragFlg_Result1)!=0 ? 0 : 1; |
| 114415 | + for(i=0; i<argc; i++, j++){ |
| 114416 | + assert( j<ArraySize(pCsr->azArg) ); |
| 114417 | + pCsr->azArg[j] = sqlite3_mprintf("%s", sqlite3_value_text(argv[i])); |
| 114418 | + if( pCsr->azArg[j]==0 ){ |
| 114419 | + return SQLITE_NOMEM; |
| 114420 | + } |
| 114421 | + } |
| 114422 | + sqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_LIMIT_SQL_LENGTH]); |
| 114423 | + sqlite3StrAccumAppendAll(&acc, "PRAGMA "); |
| 114424 | + if( pCsr->azArg[1] ){ |
| 114425 | + sqlite3XPrintf(&acc, "%Q.", pCsr->azArg[1]); |
| 114426 | + } |
| 114427 | + sqlite3StrAccumAppendAll(&acc, pTab->pName->zName); |
| 114428 | + if( pCsr->azArg[0] ){ |
| 114429 | + sqlite3XPrintf(&acc, "=%Q", pCsr->azArg[0]); |
| 114430 | + } |
| 114431 | + zSql = sqlite3StrAccumFinish(&acc); |
| 114432 | + if( zSql==0 ) return SQLITE_NOMEM; |
| 114433 | + rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pPragma, 0); |
| 114434 | + sqlite3_free(zSql); |
| 114435 | + if( rc!=SQLITE_OK ){ |
| 114436 | + pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db)); |
| 114437 | + return rc; |
| 114438 | + } |
| 114439 | + return pragmaVtabNext(pVtabCursor); |
| 114440 | +} |
| 114441 | + |
| 114442 | +/* |
| 114443 | +** Pragma virtual table module xEof method. |
| 114444 | +*/ |
| 114445 | +static int pragmaVtabEof(sqlite3_vtab_cursor *pVtabCursor){ |
| 114446 | + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; |
| 114447 | + return (pCsr->pPragma==0); |
| 114448 | +} |
| 114449 | + |
| 114450 | +/* The xColumn method simply returns the corresponding column from |
| 114451 | +** the PRAGMA. |
| 114452 | +*/ |
| 114453 | +static int pragmaVtabColumn( |
| 114454 | + sqlite3_vtab_cursor *pVtabCursor, |
| 114455 | + sqlite3_context *ctx, |
| 114456 | + int i |
| 114457 | +){ |
| 114458 | + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; |
| 114459 | + PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab); |
| 114460 | + if( i<pTab->iHidden ){ |
| 114461 | + sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pPragma, i)); |
| 114462 | + }else{ |
| 114463 | + sqlite3_result_text(ctx, pCsr->azArg[i-pTab->iHidden],-1,SQLITE_TRANSIENT); |
| 114464 | + } |
| 114465 | + return SQLITE_OK; |
| 114466 | +} |
| 114467 | + |
| 114468 | +/* |
| 114469 | +** Pragma virtual table module xRowid method. |
| 114470 | +*/ |
| 114471 | +static int pragmaVtabRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *p){ |
| 114472 | + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; |
| 114473 | + *p = pCsr->iRowid; |
| 114474 | + return SQLITE_OK; |
| 114475 | +} |
| 114476 | + |
| 114477 | +/* The pragma virtual table object */ |
| 114478 | +static const sqlite3_module pragmaVtabModule = { |
| 114479 | + 0, /* iVersion */ |
| 114480 | + 0, /* xCreate - create a table */ |
| 114481 | + pragmaVtabConnect, /* xConnect - connect to an existing table */ |
| 114482 | + pragmaVtabBestIndex, /* xBestIndex - Determine search strategy */ |
| 114483 | + pragmaVtabDisconnect, /* xDisconnect - Disconnect from a table */ |
| 114484 | + 0, /* xDestroy - Drop a table */ |
| 114485 | + pragmaVtabOpen, /* xOpen - open a cursor */ |
| 114486 | + pragmaVtabClose, /* xClose - close a cursor */ |
| 114487 | + pragmaVtabFilter, /* xFilter - configure scan constraints */ |
| 114488 | + pragmaVtabNext, /* xNext - advance a cursor */ |
| 114489 | + pragmaVtabEof, /* xEof */ |
| 114490 | + pragmaVtabColumn, /* xColumn - read data */ |
| 114491 | + pragmaVtabRowid, /* xRowid - read data */ |
| 114492 | + 0, /* xUpdate - write data */ |
| 114493 | + 0, /* xBegin - begin transaction */ |
| 114494 | + 0, /* xSync - sync transaction */ |
| 114495 | + 0, /* xCommit - commit transaction */ |
| 114496 | + 0, /* xRollback - rollback transaction */ |
| 114497 | + 0, /* xFindFunction - function overloading */ |
| 114498 | + 0, /* xRename - rename the table */ |
| 114499 | + 0, /* xSavepoint */ |
| 114500 | + 0, /* xRelease */ |
| 114501 | + 0 /* xRollbackTo */ |
| 114502 | +}; |
| 114503 | + |
| 114504 | +/* |
| 114505 | +** Check to see if zTabName is really the name of a pragma. If it is, |
| 114506 | +** then register an eponymous virtual table for that pragma and return |
| 114507 | +** a pointer to the Module object for the new virtual table. |
| 114508 | +*/ |
| 114509 | +SQLITE_PRIVATE Module *sqlite3PragmaVtabRegister(sqlite3 *db, const char *zName){ |
| 114510 | + const PragmaName *pName; |
| 114511 | + assert( sqlite3_strnicmp(zName, "pragma_", 7)==0 ); |
| 114512 | + pName = pragmaLocate(zName+7); |
| 114513 | + if( pName==0 ) return 0; |
| 114514 | + if( (pName->mPragFlg & (PragFlg_Result0|PragFlg_Result1))==0 ) return 0; |
| 114515 | + assert( sqlite3HashFind(&db->aModule, zName)==0 ); |
| 114516 | + return sqlite3VtabCreateModule(db, zName, &pragmaVtabModule, (void*)pName, 0); |
| 114517 | +} |
| 114518 | + |
| 114519 | +#endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 113901 | 114520 | |
| 113902 | 114521 | #endif /* SQLITE_OMIT_PRAGMA */ |
| 113903 | 114522 | |
| 113904 | 114523 | /************** End of pragma.c **********************************************/ |
| 113905 | 114524 | /************** Begin file prepare.c *****************************************/ |
| | @@ -115354,11 +115973,11 @@ |
| 115354 | 115973 | int r1 = 0; |
| 115355 | 115974 | /* Fill the sorter until it contains LIMIT+OFFSET entries. (The iLimit |
| 115356 | 115975 | ** register is initialized with value of LIMIT+OFFSET.) After the sorter |
| 115357 | 115976 | ** fills up, delete the least entry in the sorter after each insert. |
| 115358 | 115977 | ** Thus we never hold more than the LIMIT+OFFSET rows in memory at once */ |
| 115359 | | - addr = sqlite3VdbeAddOp3(v, OP_IfNotZero, iLimit, 0, 1); VdbeCoverage(v); |
| 115978 | + addr = sqlite3VdbeAddOp1(v, OP_IfNotZero, iLimit); VdbeCoverage(v); |
| 115360 | 115979 | sqlite3VdbeAddOp1(v, OP_Last, pSort->iECursor); |
| 115361 | 115980 | if( pSort->bOrderedInnerLoop ){ |
| 115362 | 115981 | r1 = ++pParse->nMem; |
| 115363 | 115982 | sqlite3VdbeAddOp3(v, OP_Column, pSort->iECursor, nExpr, r1); |
| 115364 | 115983 | VdbeComment((v, "seq")); |
| | @@ -116564,11 +117183,11 @@ |
| 116564 | 117183 | return 0; |
| 116565 | 117184 | } |
| 116566 | 117185 | /* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside |
| 116567 | 117186 | ** is disabled */ |
| 116568 | 117187 | assert( db->lookaside.bDisable ); |
| 116569 | | - pTab->nRef = 1; |
| 117188 | + pTab->nTabRef = 1; |
| 116570 | 117189 | pTab->zName = 0; |
| 116571 | 117190 | pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); |
| 116572 | 117191 | sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); |
| 116573 | 117192 | sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSelect); |
| 116574 | 117193 | pTab->iPKey = -1; |
| | @@ -116795,10 +117414,11 @@ |
| 116795 | 117414 | /* Obtain authorization to do a recursive query */ |
| 116796 | 117415 | if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return; |
| 116797 | 117416 | |
| 116798 | 117417 | /* Process the LIMIT and OFFSET clauses, if they exist */ |
| 116799 | 117418 | addrBreak = sqlite3VdbeMakeLabel(v); |
| 117419 | + p->nSelectRow = 320; /* 4 billion rows */ |
| 116800 | 117420 | computeLimitRegisters(pParse, p, addrBreak); |
| 116801 | 117421 | pLimit = p->pLimit; |
| 116802 | 117422 | pOffset = p->pOffset; |
| 116803 | 117423 | regLimit = p->iLimit; |
| 116804 | 117424 | regOffset = p->iOffset; |
| | @@ -118377,16 +118997,16 @@ |
| 118377 | 118997 | ** |
| 118378 | 118998 | ** pSubitem->pTab is always non-NULL by test restrictions and tests above. |
| 118379 | 118999 | */ |
| 118380 | 119000 | if( ALWAYS(pSubitem->pTab!=0) ){ |
| 118381 | 119001 | Table *pTabToDel = pSubitem->pTab; |
| 118382 | | - if( pTabToDel->nRef==1 ){ |
| 119002 | + if( pTabToDel->nTabRef==1 ){ |
| 118383 | 119003 | Parse *pToplevel = sqlite3ParseToplevel(pParse); |
| 118384 | 119004 | pTabToDel->pNextZombie = pToplevel->pZombieTab; |
| 118385 | 119005 | pToplevel->pZombieTab = pTabToDel; |
| 118386 | 119006 | }else{ |
| 118387 | | - pTabToDel->nRef--; |
| 119007 | + pTabToDel->nTabRef--; |
| 118388 | 119008 | } |
| 118389 | 119009 | pSubitem->pTab = 0; |
| 118390 | 119010 | } |
| 118391 | 119011 | |
| 118392 | 119012 | /* The following loop runs once for each term in a compound-subquery |
| | @@ -118901,11 +119521,11 @@ |
| 118901 | 119521 | if( cannotBeFunction(pParse, pFrom) ) return SQLITE_ERROR; |
| 118902 | 119522 | |
| 118903 | 119523 | assert( pFrom->pTab==0 ); |
| 118904 | 119524 | pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); |
| 118905 | 119525 | if( pTab==0 ) return WRC_Abort; |
| 118906 | | - pTab->nRef = 1; |
| 119526 | + pTab->nTabRef = 1; |
| 118907 | 119527 | pTab->zName = sqlite3DbStrDup(db, pCte->zName); |
| 118908 | 119528 | pTab->iPKey = -1; |
| 118909 | 119529 | pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); |
| 118910 | 119530 | pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid; |
| 118911 | 119531 | pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0); |
| | @@ -118924,24 +119544,24 @@ |
| 118924 | 119544 | && pItem->zName!=0 |
| 118925 | 119545 | && 0==sqlite3StrICmp(pItem->zName, pCte->zName) |
| 118926 | 119546 | ){ |
| 118927 | 119547 | pItem->pTab = pTab; |
| 118928 | 119548 | pItem->fg.isRecursive = 1; |
| 118929 | | - pTab->nRef++; |
| 119549 | + pTab->nTabRef++; |
| 118930 | 119550 | pSel->selFlags |= SF_Recursive; |
| 118931 | 119551 | } |
| 118932 | 119552 | } |
| 118933 | 119553 | } |
| 118934 | 119554 | |
| 118935 | 119555 | /* Only one recursive reference is permitted. */ |
| 118936 | | - if( pTab->nRef>2 ){ |
| 119556 | + if( pTab->nTabRef>2 ){ |
| 118937 | 119557 | sqlite3ErrorMsg( |
| 118938 | 119558 | pParse, "multiple references to recursive table: %s", pCte->zName |
| 118939 | 119559 | ); |
| 118940 | 119560 | return SQLITE_ERROR; |
| 118941 | 119561 | } |
| 118942 | | - assert( pTab->nRef==1 || ((pSel->selFlags&SF_Recursive) && pTab->nRef==2 )); |
| 119562 | + assert( pTab->nTabRef==1 || ((pSel->selFlags&SF_Recursive) && pTab->nTabRef==2 )); |
| 118943 | 119563 | |
| 118944 | 119564 | pCte->zCteErr = "circular reference: %s"; |
| 118945 | 119565 | pSavedWith = pParse->pWith; |
| 118946 | 119566 | pParse->pWith = pWith; |
| 118947 | 119567 | sqlite3WalkSelect(pWalker, bMayRecursive ? pSel->pPrior : pSel); |
| | @@ -119070,11 +119690,11 @@ |
| 119070 | 119690 | assert( pSel!=0 ); |
| 119071 | 119691 | assert( pFrom->pTab==0 ); |
| 119072 | 119692 | if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort; |
| 119073 | 119693 | pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); |
| 119074 | 119694 | if( pTab==0 ) return WRC_Abort; |
| 119075 | | - pTab->nRef = 1; |
| 119695 | + pTab->nTabRef = 1; |
| 119076 | 119696 | pTab->zName = sqlite3MPrintf(db, "sqlite_sq_%p", (void*)pTab); |
| 119077 | 119697 | while( pSel->pPrior ){ pSel = pSel->pPrior; } |
| 119078 | 119698 | sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol); |
| 119079 | 119699 | pTab->iPKey = -1; |
| 119080 | 119700 | pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); |
| | @@ -119083,17 +119703,17 @@ |
| 119083 | 119703 | }else{ |
| 119084 | 119704 | /* An ordinary table or view name in the FROM clause */ |
| 119085 | 119705 | assert( pFrom->pTab==0 ); |
| 119086 | 119706 | pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom); |
| 119087 | 119707 | if( pTab==0 ) return WRC_Abort; |
| 119088 | | - if( pTab->nRef==0xffff ){ |
| 119708 | + if( pTab->nTabRef>=0xffff ){ |
| 119089 | 119709 | sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535", |
| 119090 | 119710 | pTab->zName); |
| 119091 | 119711 | pFrom->pTab = 0; |
| 119092 | 119712 | return WRC_Abort; |
| 119093 | 119713 | } |
| 119094 | | - pTab->nRef++; |
| 119714 | + pTab->nTabRef++; |
| 119095 | 119715 | if( !IsVirtual(pTab) && cannotBeFunction(pParse, pFrom) ){ |
| 119096 | 119716 | return WRC_Abort; |
| 119097 | 119717 | } |
| 119098 | 119718 | #if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE) |
| 119099 | 119719 | if( IsVirtual(pTab) || pTab->pSelect ){ |
| | @@ -119928,11 +120548,13 @@ |
| 119928 | 120548 | } |
| 119929 | 120549 | |
| 119930 | 120550 | /* Set the limiter. |
| 119931 | 120551 | */ |
| 119932 | 120552 | iEnd = sqlite3VdbeMakeLabel(v); |
| 119933 | | - p->nSelectRow = 320; /* 4 billion rows */ |
| 120553 | + if( (p->selFlags & SF_FixedLimit)==0 ){ |
| 120554 | + p->nSelectRow = 320; /* 4 billion rows */ |
| 120555 | + } |
| 119934 | 120556 | computeLimitRegisters(pParse, p, iEnd); |
| 119935 | 120557 | if( p->iLimit==0 && sSort.addrSortIndex>=0 ){ |
| 119936 | 120558 | sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen); |
| 119937 | 120559 | sSort.sortFlags |= SORTFLAG_UseSorter; |
| 119938 | 120560 | } |
| | @@ -120989,11 +121611,11 @@ |
| 120989 | 121611 | if( v==0 ) goto triggerfinish_cleanup; |
| 120990 | 121612 | sqlite3BeginWriteOperation(pParse, 0, iDb); |
| 120991 | 121613 | z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n); |
| 120992 | 121614 | sqlite3NestedParse(pParse, |
| 120993 | 121615 | "INSERT INTO %Q.%s VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')", |
| 120994 | | - db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), zName, |
| 121616 | + db->aDb[iDb].zDbSName, MASTER_NAME, zName, |
| 120995 | 121617 | pTrig->table, z); |
| 120996 | 121618 | sqlite3DbFree(db, z); |
| 120997 | 121619 | sqlite3ChangeCookie(pParse, iDb); |
| 120998 | 121620 | sqlite3VdbeAddParseSchemaOp(v, iDb, |
| 120999 | 121621 | sqlite3MPrintf(db, "type='trigger' AND name='%q'", zName)); |
| | @@ -121240,11 +121862,11 @@ |
| 121240 | 121862 | */ |
| 121241 | 121863 | assert( pTable!=0 ); |
| 121242 | 121864 | if( (v = sqlite3GetVdbe(pParse))!=0 ){ |
| 121243 | 121865 | sqlite3NestedParse(pParse, |
| 121244 | 121866 | "DELETE FROM %Q.%s WHERE name=%Q AND type='trigger'", |
| 121245 | | - db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), pTrigger->zName |
| 121867 | + db->aDb[iDb].zDbSName, MASTER_NAME, pTrigger->zName |
| 121246 | 121868 | ); |
| 121247 | 121869 | sqlite3ChangeCookie(pParse, iDb); |
| 121248 | 121870 | sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0); |
| 121249 | 121871 | } |
| 121250 | 121872 | } |
| | @@ -122990,10 +123612,45 @@ |
| 122990 | 123612 | VTable *pVTable; /* The virtual table being constructed */ |
| 122991 | 123613 | Table *pTab; /* The Table object to which the virtual table belongs */ |
| 122992 | 123614 | VtabCtx *pPrior; /* Parent context (if any) */ |
| 122993 | 123615 | int bDeclared; /* True after sqlite3_declare_vtab() is called */ |
| 122994 | 123616 | }; |
| 123617 | + |
| 123618 | +/* |
| 123619 | +** Construct and install a Module object for a virtual table. When this |
| 123620 | +** routine is called, it is guaranteed that all appropriate locks are held |
| 123621 | +** and the module is not already part of the connection. |
| 123622 | +*/ |
| 123623 | +SQLITE_PRIVATE Module *sqlite3VtabCreateModule( |
| 123624 | + sqlite3 *db, /* Database in which module is registered */ |
| 123625 | + const char *zName, /* Name assigned to this module */ |
| 123626 | + const sqlite3_module *pModule, /* The definition of the module */ |
| 123627 | + void *pAux, /* Context pointer for xCreate/xConnect */ |
| 123628 | + void (*xDestroy)(void *) /* Module destructor function */ |
| 123629 | +){ |
| 123630 | + Module *pMod; |
| 123631 | + int nName = sqlite3Strlen30(zName); |
| 123632 | + pMod = (Module *)sqlite3DbMallocRawNN(db, sizeof(Module) + nName + 1); |
| 123633 | + if( pMod ){ |
| 123634 | + Module *pDel; |
| 123635 | + char *zCopy = (char *)(&pMod[1]); |
| 123636 | + memcpy(zCopy, zName, nName+1); |
| 123637 | + pMod->zName = zCopy; |
| 123638 | + pMod->pModule = pModule; |
| 123639 | + pMod->pAux = pAux; |
| 123640 | + pMod->xDestroy = xDestroy; |
| 123641 | + pMod->pEpoTab = 0; |
| 123642 | + pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod); |
| 123643 | + assert( pDel==0 || pDel==pMod ); |
| 123644 | + if( pDel ){ |
| 123645 | + sqlite3OomFault(db); |
| 123646 | + sqlite3DbFree(db, pDel); |
| 123647 | + pMod = 0; |
| 123648 | + } |
| 123649 | + } |
| 123650 | + return pMod; |
| 123651 | +} |
| 122995 | 123652 | |
| 122996 | 123653 | /* |
| 122997 | 123654 | ** The actual function that does the work of creating a new module. |
| 122998 | 123655 | ** This function implements the sqlite3_create_module() and |
| 122999 | 123656 | ** sqlite3_create_module_v2() interfaces. |
| | @@ -123004,39 +123661,19 @@ |
| 123004 | 123661 | const sqlite3_module *pModule, /* The definition of the module */ |
| 123005 | 123662 | void *pAux, /* Context pointer for xCreate/xConnect */ |
| 123006 | 123663 | void (*xDestroy)(void *) /* Module destructor function */ |
| 123007 | 123664 | ){ |
| 123008 | 123665 | int rc = SQLITE_OK; |
| 123009 | | - int nName; |
| 123010 | 123666 | |
| 123011 | 123667 | sqlite3_mutex_enter(db->mutex); |
| 123012 | | - nName = sqlite3Strlen30(zName); |
| 123013 | 123668 | if( sqlite3HashFind(&db->aModule, zName) ){ |
| 123014 | 123669 | rc = SQLITE_MISUSE_BKPT; |
| 123015 | 123670 | }else{ |
| 123016 | | - Module *pMod; |
| 123017 | | - pMod = (Module *)sqlite3DbMallocRawNN(db, sizeof(Module) + nName + 1); |
| 123018 | | - if( pMod ){ |
| 123019 | | - Module *pDel; |
| 123020 | | - char *zCopy = (char *)(&pMod[1]); |
| 123021 | | - memcpy(zCopy, zName, nName+1); |
| 123022 | | - pMod->zName = zCopy; |
| 123023 | | - pMod->pModule = pModule; |
| 123024 | | - pMod->pAux = pAux; |
| 123025 | | - pMod->xDestroy = xDestroy; |
| 123026 | | - pMod->pEpoTab = 0; |
| 123027 | | - pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod); |
| 123028 | | - assert( pDel==0 || pDel==pMod ); |
| 123029 | | - if( pDel ){ |
| 123030 | | - sqlite3OomFault(db); |
| 123031 | | - sqlite3DbFree(db, pDel); |
| 123032 | | - } |
| 123033 | | - } |
| 123671 | + (void)sqlite3VtabCreateModule(db, zName, pModule, pAux, xDestroy); |
| 123034 | 123672 | } |
| 123035 | 123673 | rc = sqlite3ApiExit(db, rc); |
| 123036 | 123674 | if( rc!=SQLITE_OK && xDestroy ) xDestroy(pAux); |
| 123037 | | - |
| 123038 | 123675 | sqlite3_mutex_leave(db->mutex); |
| 123039 | 123676 | return rc; |
| 123040 | 123677 | } |
| 123041 | 123678 | |
| 123042 | 123679 | |
| | @@ -123371,11 +124008,11 @@ |
| 123371 | 124008 | iDb = sqlite3SchemaToIndex(db, pTab->pSchema); |
| 123372 | 124009 | sqlite3NestedParse(pParse, |
| 123373 | 124010 | "UPDATE %Q.%s " |
| 123374 | 124011 | "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q " |
| 123375 | 124012 | "WHERE rowid=#%d", |
| 123376 | | - db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), |
| 124013 | + db->aDb[iDb].zDbSName, MASTER_NAME, |
| 123377 | 124014 | pTab->zName, |
| 123378 | 124015 | pTab->zName, |
| 123379 | 124016 | zStmt, |
| 123380 | 124017 | pParse->regRowid |
| 123381 | 124018 | ); |
| | @@ -124096,11 +124733,11 @@ |
| 124096 | 124733 | if( pTab->zName==0 ){ |
| 124097 | 124734 | sqlite3DbFree(db, pTab); |
| 124098 | 124735 | return 0; |
| 124099 | 124736 | } |
| 124100 | 124737 | pMod->pEpoTab = pTab; |
| 124101 | | - pTab->nRef = 1; |
| 124738 | + pTab->nTabRef = 1; |
| 124102 | 124739 | pTab->pSchema = db->aDb[0].pSchema; |
| 124103 | 124740 | pTab->tabFlags |= TF_Virtual; |
| 124104 | 124741 | pTab->nModuleArg = 0; |
| 124105 | 124742 | pTab->iPKey = -1; |
| 124106 | 124743 | addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName)); |
| | @@ -137042,17 +137679,17 @@ |
| 137042 | 137679 | /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */ |
| 137043 | 137680 | /* 0x */ 27, 27, 27, 27, 27, 7, 27, 27, 27, 27, 27, 27, 7, 7, 27, 27, |
| 137044 | 137681 | /* 1x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, |
| 137045 | 137682 | /* 2x */ 27, 27, 27, 27, 27, 7, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, |
| 137046 | 137683 | /* 3x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, |
| 137047 | | -/* 4x */ 7, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 12, 17, 20, 10, |
| 137684 | +/* 4x */ 7, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, 12, 17, 20, 10, |
| 137048 | 137685 | /* 5x */ 24, 27, 27, 27, 27, 27, 27, 27, 27, 27, 15, 4, 21, 18, 19, 27, |
| 137049 | | -/* 6x */ 11, 16, 27, 27, 27, 27, 27, 27, 27, 27, 27, 23, 22, 1, 13, 7, |
| 137686 | +/* 6x */ 11, 16, 27, 27, 27, 27, 27, 27, 27, 27, 27, 23, 22, 1, 13, 6, |
| 137050 | 137687 | /* 7x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 8, 5, 5, 5, 8, 14, 8, |
| 137051 | 137688 | /* 8x */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, |
| 137052 | 137689 | /* 9x */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, |
| 137053 | | -/* 9x */ 25, 1, 1, 1, 1, 1, 1, 0, 1, 1, 27, 27, 27, 27, 27, 27, |
| 137690 | +/* Ax */ 27, 25, 1, 1, 1, 1, 1, 0, 1, 1, 27, 27, 27, 27, 27, 27, |
| 137054 | 137691 | /* Bx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 9, 27, 27, 27, 27, 27, |
| 137055 | 137692 | /* Cx */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, |
| 137056 | 137693 | /* Dx */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, |
| 137057 | 137694 | /* Ex */ 27, 27, 1, 1, 1, 1, 1, 0, 1, 1, 27, 27, 27, 27, 27, 27, |
| 137058 | 137695 | /* Fx */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 27, 27, 27, 27, 27, 27, |
| | @@ -137750,12 +138387,11 @@ |
| 137750 | 138387 | return SQLITE_NOMEM_BKPT; |
| 137751 | 138388 | } |
| 137752 | 138389 | assert( pParse->pNewTable==0 ); |
| 137753 | 138390 | assert( pParse->pNewTrigger==0 ); |
| 137754 | 138391 | assert( pParse->nVar==0 ); |
| 137755 | | - assert( pParse->nzVar==0 ); |
| 137756 | | - assert( pParse->azVar==0 ); |
| 138392 | + assert( pParse->pVList==0 ); |
| 137757 | 138393 | while( 1 ){ |
| 137758 | 138394 | assert( i>=0 ); |
| 137759 | 138395 | if( zSql[i]!=0 ){ |
| 137760 | 138396 | pParse->sLastToken.z = &zSql[i]; |
| 137761 | 138397 | pParse->sLastToken.n = sqlite3GetToken((u8*)&zSql[i],&tokenType); |
| | @@ -137838,12 +138474,11 @@ |
| 137838 | 138474 | sqlite3DeleteTable(db, pParse->pNewTable); |
| 137839 | 138475 | } |
| 137840 | 138476 | |
| 137841 | 138477 | if( pParse->pWithToFree ) sqlite3WithDelete(db, pParse->pWithToFree); |
| 137842 | 138478 | sqlite3DeleteTrigger(db, pParse->pNewTrigger); |
| 137843 | | - for(i=pParse->nzVar-1; i>=0; i--) sqlite3DbFree(db, pParse->azVar[i]); |
| 137844 | | - sqlite3DbFree(db, pParse->azVar); |
| 138479 | + sqlite3DbFree(db, pParse->pVList); |
| 137845 | 138480 | while( pParse->pAinc ){ |
| 137846 | 138481 | AutoincInfo *p = pParse->pAinc; |
| 137847 | 138482 | pParse->pAinc = p->pNext; |
| 137848 | 138483 | sqlite3DbFree(db, p); |
| 137849 | 138484 | } |
| | @@ -185122,11 +185757,14 @@ |
| 185122 | 185757 | p->bDesc = bDesc; |
| 185123 | 185758 | rc = fts5ExprNodeFirst(p, pRoot); |
| 185124 | 185759 | |
| 185125 | 185760 | /* If not at EOF but the current rowid occurs earlier than iFirst in |
| 185126 | 185761 | ** the iteration order, move to document iFirst or later. */ |
| 185127 | | - if( pRoot->bEof==0 && fts5RowidCmp(p, pRoot->iRowid, iFirst)<0 ){ |
| 185762 | + if( rc==SQLITE_OK |
| 185763 | + && 0==pRoot->bEof |
| 185764 | + && fts5RowidCmp(p, pRoot->iRowid, iFirst)<0 |
| 185765 | + ){ |
| 185128 | 185766 | rc = fts5ExprNodeNext(p, pRoot, 1, iFirst); |
| 185129 | 185767 | } |
| 185130 | 185768 | |
| 185131 | 185769 | /* If the iterator is not at a real match, skip forward until it is. */ |
| 185132 | 185770 | while( pRoot->bNomatch ){ |
| | @@ -196116,11 +196754,11 @@ |
| 196116 | 196754 | int nArg, /* Number of args */ |
| 196117 | 196755 | sqlite3_value **apUnused /* Function arguments */ |
| 196118 | 196756 | ){ |
| 196119 | 196757 | assert( nArg==0 ); |
| 196120 | 196758 | UNUSED_PARAM2(nArg, apUnused); |
| 196121 | | - sqlite3_result_text(pCtx, "fts5: 2016-12-08 19:04:36 b26df26e184ec6da4b5537526c10f42a293d09b5", -1, SQLITE_TRANSIENT); |
| 196759 | + sqlite3_result_text(pCtx, "fts5: 2016-12-23 16:05:22 2940661b8c014b94973e05c44f1b1f4f443dbdd3", -1, SQLITE_TRANSIENT); |
| 196122 | 196760 | } |
| 196123 | 196761 | |
| 196124 | 196762 | static int fts5Init(sqlite3 *db){ |
| 196125 | 196763 | static const sqlite3_module fts5Mod = { |
| 196126 | 196764 | /* iVersion */ 2, |
| 196127 | 196765 | |