Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3cbb1995f3 | |||
| 968067d282 | |||
| d8b7200b84 | |||
| 30776acd74 | |||
| 9a63f09204 | |||
| c06bbceb9c | |||
| ae7045cd53 | |||
| d7175ebeaf | |||
| 2fcc1590c4 | |||
| c232aca184 | |||
| 6bebbb6a2d | |||
| 94c4553f48 | |||
| 1f47b2aaa5 | |||
| 57ad53ada4 | |||
| b94664711b | |||
| 6d51243979 | |||
| 7fdaca40b7 | |||
| 2a3489ae82 | |||
| 5fba856bbf | |||
| 052153994b | |||
| c844fac64d | |||
| a3c79ae7cd | |||
| f87f9c240f | |||
| a74480a217 | |||
| 19dbfa8adc |
@@ -499,6 +499,10 @@ dbhash$(EXE): $(TOP)/tool/dbhash.c sqlite3.c sqlite3.h
|
||||
$(TCCX) -o dbhash$(EXE) -DSQLITE_THREADSAFE=0 \
|
||||
$(TOP)/tool/dbhash.c sqlite3.c $(TLIBS) $(THREADLIB)
|
||||
|
||||
faststat1$(EXE): $(TOP)/tool/faststat1.c sqlite3.c sqlite3.h
|
||||
$(TCCX) -o faststat1$(EXE) -DSQLITE_THREADSAFE=0 \
|
||||
$(TOP)/tool/faststat1.c sqlite3.c $(TLIBS) $(THREADLIB)
|
||||
|
||||
scrub$(EXE): $(TOP)/ext/misc/scrub.c sqlite3.o
|
||||
$(TCC) -I. -DSCRUB_STANDALONE -o scrub$(EXE) $(TOP)/ext/misc/scrub.c sqlite3.o $(THREADLIB)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
C Fix\sa\sproblem\scausing\sthe\splanner\sto\sgenerate\ssub-optimal\splans\sfor\ssome\squeries\nthat\suse\srecursive\sWITH\ssub-queries\swith\sLIMIT\sclauses.
|
||||
D 2016-12-16T15:05:40.539
|
||||
C Experimental\smerge\sof\sthe\sest_count_pragma\sand\sthe\spragma-as-vtab\sbranches.
|
||||
D 2016-12-16T16:49:11.848
|
||||
F Makefile.in c194b58fe00c370a48ac6ae6945e92a7781db1c8
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da
|
||||
@@ -312,7 +312,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
||||
F main.mk bd1149fdb5543e432a8530a0ea7642613a655bc1
|
||||
F main.mk 2476a37aa8a70a69efe54a004351f8ae7844f751
|
||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||
@@ -331,10 +331,10 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792
|
||||
F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b
|
||||
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
|
||||
F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73
|
||||
F src/btree.c b2055dff0b94e03eaad48a760984a2d8e39244e6
|
||||
F src/btree.h 2349a588abcd7e0c04f984e15c5c777b61637583
|
||||
F src/btree.c 7892be7e019565f6e5d2df6bda94befa7d91c9a0
|
||||
F src/btree.h 14931e081909f9b75009b0b5c5ead6b074204705
|
||||
F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e
|
||||
F src/build.c 854ec3a222d2872df5351339f7af4002e64fdd1a
|
||||
F src/build.c d814cb158ca2ef75c525e4c3f0d47b5666e53c95
|
||||
F src/callback.c 2e76147783386374bf01b227f752c81ec872d730
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a
|
||||
@@ -377,12 +377,12 @@ F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c 81fe2bb847df537694ec39e28e8b3dc221c64a7d
|
||||
F src/pager.h d1e944291030351f362a0a7da9b5c3e34e603e39
|
||||
F src/parse.y 29153738a7322054359320eb00b5a4cd44389f20
|
||||
F src/parse.y 5280d00e80f0fb118437ffc3ffc14c69ca0c87cd
|
||||
F src/pcache.c 51070ec9b8251bbf9c6ea3d35fd96a458752929e
|
||||
F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490
|
||||
F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953
|
||||
F src/pragma.c d932ba278654617cdd281f88a790a3185fca7c44
|
||||
F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c
|
||||
F src/pragma.c 850bee0057697e817c337c8141e12f74c64eb8f4
|
||||
F src/pragma.h e2636093e33f5cc0feffc7ead45ce1268a5524e9
|
||||
F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a
|
||||
F src/printf.c f94da4935d1dd25420ac50c6745db1deb35e07c1
|
||||
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
||||
@@ -393,7 +393,7 @@ F src/shell.c f1c7fde7a83421e6ed620df41d200674a2327e65
|
||||
F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae
|
||||
F src/sqliteInt.h 657a892d885253768c82f1e04e8053468b13cb6a
|
||||
F src/sqliteInt.h 9f4111b5743fdb9d6dea6da81485abc94abf01ac
|
||||
F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
|
||||
F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
|
||||
F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9
|
||||
@@ -455,7 +455,7 @@ F src/update.c 1da7c462110bffed442a42884cb0d528c1db46d8
|
||||
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
|
||||
F src/util.c e68e8ced7328f22d2cf7b4c898c394a0de34cdf1
|
||||
F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16
|
||||
F src/vdbe.c 64c3426893e1660bde7446c242468926555e3650
|
||||
F src/vdbe.c accfa7875623a5efa6108c75581e6588a342a643
|
||||
F src/vdbe.h 0c74f6305fb43b9b282dacaff102272370e327d4
|
||||
F src/vdbeInt.h 42e498dbe96475dbb3fda3d85d8fd2a87eff60a2
|
||||
F src/vdbeapi.c ea4e2dc2213cc6bd7bee375a29a9b51c31b93ae0
|
||||
@@ -464,7 +464,7 @@ F src/vdbeblob.c f4f98ea672b242f807c08c92c7faaa79e5091b65
|
||||
F src/vdbemem.c d3fd85b7b7ef3eb75de29c6d7e1d10d3ca78b4fd
|
||||
F src/vdbesort.c bb34eed4fb52e11ac037dccea4ee3190594c7f9e
|
||||
F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834
|
||||
F src/vtab.c fd64fd37aad1e47e3e887f0e171099ddddc7e3cb
|
||||
F src/vtab.c c4bbe0f870f52036553f8098aee0703997f0577a
|
||||
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344
|
||||
F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71
|
||||
@@ -1438,7 +1438,7 @@ F test/with1.test cef099a491eac9874f2c28bd2dc86394fb3e47b3
|
||||
F test/with2.test 2b40da883658eb74ad8ad06afabe11a408e7fb87
|
||||
F test/with3.test e71604a0e53cba82bc04c703987cb1d6751ec0b6
|
||||
F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64
|
||||
F test/without_rowid1.test 1a7b9bd51b899928d327052df9741d2fe8dbe701
|
||||
F test/without_rowid1.test eaac24556ed2dfaf84d8a32fac46229bd61b1015
|
||||
F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
|
||||
F test/without_rowid3.test 2724c787a51a5dce09d078453a758117b4b728f1
|
||||
F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a
|
||||
@@ -1458,6 +1458,7 @@ F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2
|
||||
F tool/dbhash.c a06228aa21ebc4e6ea8daa486601d938499238a5
|
||||
F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2
|
||||
F tool/fast_vacuum.c 5ba0d6f5963a0a63bdc42840f678bad75b2ebce1
|
||||
F tool/faststat1.c 67637f03dced49951f1021bfdc95aa9ffadbe871
|
||||
F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439
|
||||
F tool/fuzzershell.c d5c870a07452caa5c70a8e49d6c64e403558686d
|
||||
F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4
|
||||
@@ -1474,7 +1475,7 @@ F tool/mkmsvcmin.tcl 2f12f7fa8858bbe61cf81820a2da96c79ed1ca8d
|
||||
F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
|
||||
F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3
|
||||
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
|
||||
F tool/mkpragmatab.tcl f0d5bb266d1d388cf86fce5ba01a891e95d72d41
|
||||
F tool/mkpragmatab.tcl c4e9c6b70e54e5720a81eeccfb4d739a566be217
|
||||
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
|
||||
F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb
|
||||
F tool/mksqlite3c.tcl 06b2e6a0f21cc0a5d70fbbd136b3e0a96470645e
|
||||
@@ -1536,7 +1537,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 8d646905b830d5bb29092e103ac5cb499b3c7e5a
|
||||
R 147fd014e993bf990284d024622f7825
|
||||
U dan
|
||||
Z ececc9941f2e958f0280d3f055b0e66d
|
||||
P 546821e29edb0282a4b1d8f49512e36027a6bf6d 74a0ca1f152d6d8454787557c6e990efe0e47a50
|
||||
R 04f447c00e247ed4618fbb5b48ddcec6
|
||||
T *branch * est-count-pragma-vtab
|
||||
T *sym-est-count-pragma-vtab *
|
||||
T -sym-pragma-as-vtab *
|
||||
U drh
|
||||
Z f94f7d33b2ad68dbdfa8be480e10347f
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
053a149cc8244a7f85137129cfcb8622efe90306
|
||||
4b73ee33f31281886256663a0e4a6397d3c8efc5
|
||||
+67
@@ -5036,6 +5036,73 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Move the cursor pCur to a location within its b-tree that is
|
||||
** approximately the x/1e9*nRow entry in the table, assuming the
|
||||
** table contains nRow entries. So, in other words, if x==0 move
|
||||
** to the first entry and if x=1e9 move to the last entry and if
|
||||
** x=5e8 move to the middle entry. The final landing spot is
|
||||
** approximate.
|
||||
**
|
||||
** Write an estimate of the number of entries in the b-tree into
|
||||
** the *pnRowEst variable.
|
||||
**
|
||||
** This routine works by first moving the cursor to the root of the
|
||||
** b-tree, then following pointers down to a leaf, selecting a pointer
|
||||
** according to x.
|
||||
**
|
||||
** The estimated number of entries is found by multiplying the number of
|
||||
** entries on the leaf page by the number of pointers at each layer of
|
||||
** non-leaf pages.
|
||||
**
|
||||
** Return SQLITE_OK on success or an error code if problems are encountered.
|
||||
*/
|
||||
int sqlite3BtreeMovetoProportional(
|
||||
BtCursor *pCur, /* Cursor to reposition */
|
||||
u32 x, /* approximate location to position the cursor */
|
||||
sqlite3_uint64 *pnRowEst /* Write estimated entry count here */
|
||||
){
|
||||
sqlite3_uint64 n = 1;
|
||||
int rc;
|
||||
Pgno chldPg;
|
||||
u32 mx = 1000000000;
|
||||
u32 perChild;
|
||||
u16 rx;
|
||||
MemPage *pPage;
|
||||
rc = moveToRoot(pCur);
|
||||
if( rc ) return rc;
|
||||
pPage = pCur->apPage[0];
|
||||
while( !pPage->leaf ){
|
||||
perChild = (mx+pPage->nCell)/(pPage->nCell+1);
|
||||
if( perChild<1 ) perChild = 1;
|
||||
rx = x/perChild;
|
||||
x %= perChild;
|
||||
mx = perChild;
|
||||
if( rx>=pPage->nCell ){
|
||||
chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]);
|
||||
}else{
|
||||
chldPg = get4byte(findCell(pPage,rx));
|
||||
}
|
||||
n *= pPage->nCell+1;
|
||||
pCur->aiIdx[pCur->iPage] = rx;
|
||||
rc = moveToChild(pCur, chldPg);
|
||||
if( rc ) return rc;
|
||||
pPage = pCur->apPage[pCur->iPage];
|
||||
}
|
||||
*pnRowEst = n*pPage->nCell;
|
||||
if( pPage->nCell==0 ){
|
||||
rx = 0;
|
||||
}else{
|
||||
perChild = mx/pPage->nCell;
|
||||
if( perChild<1 ) perChild = 1;
|
||||
rx = x/perChild;
|
||||
if( rx>=pPage->nCell ) rx = pPage->nCell-1;
|
||||
}
|
||||
pCur->aiIdx[pCur->iPage] = rx;
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/* Move the cursor so that it points to an entry near the key
|
||||
** specified by pIdxKey or intKey. Return a success code.
|
||||
**
|
||||
|
||||
@@ -238,6 +238,7 @@ void sqlite3BtreeCursorHint(BtCursor*, int, ...);
|
||||
#endif
|
||||
|
||||
int sqlite3BtreeCloseCursor(BtCursor*);
|
||||
int sqlite3BtreeMovetoProportional(BtCursor*,u32,u64*);
|
||||
int sqlite3BtreeMovetoUnpacked(
|
||||
BtCursor*,
|
||||
UnpackedRecord *pUnKey,
|
||||
|
||||
+21
-6
@@ -320,8 +320,7 @@ Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
|
||||
/* Not found. If the name we were looking for was temp.sqlite_master
|
||||
** then change the name to sqlite_temp_master and try again. */
|
||||
if( sqlite3StrICmp(zName, MASTER_NAME)!=0 ) break;
|
||||
if( zDatabase==0 ) break;
|
||||
if( sqlite3StrICmp(zDatabase, db->aDb[1].zDbSName)!=0 ) break;
|
||||
if( sqlite3_stricmp(zDatabase, db->aDb[1].zDbSName)!=0 ) break;
|
||||
zName = TEMP_MASTER_NAME;
|
||||
}
|
||||
return 0;
|
||||
@@ -360,6 +359,9 @@ Table *sqlite3LocateTable(
|
||||
** CREATE, then check to see if it is the name of an virtual table that
|
||||
** can be an eponymous virtual table. */
|
||||
Module *pMod = (Module*)sqlite3HashFind(&pParse->db->aModule, zName);
|
||||
if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
|
||||
pMod = sqlite3PragmaVtabRegister(pParse->db, zName);
|
||||
}
|
||||
if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
|
||||
return pMod->pEpoTab;
|
||||
}
|
||||
@@ -3582,12 +3584,21 @@ void *sqlite3ArrayAllocate(
|
||||
** need be.
|
||||
**
|
||||
** A new IdList is returned, or NULL if malloc() fails.
|
||||
**
|
||||
** The zName must have been obtained from sqlite3DbMalloc(). This routine
|
||||
** accepts ownership of the zName string and will ensure that it is freed
|
||||
** when no longer in use.
|
||||
*/
|
||||
IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pToken){
|
||||
IdList *sqlite3IdListAppend(
|
||||
Parse *pParse, /* Parsing context */
|
||||
IdList *pList, /* ID list to append to */
|
||||
char *zName /* Token to append */
|
||||
){
|
||||
int i;
|
||||
sqlite3 *db = pParse->db;
|
||||
if( pList==0 ){
|
||||
pList = sqlite3DbMallocZero(db, sizeof(IdList) );
|
||||
if( pList==0 ) return 0;
|
||||
if( pList==0 ) goto id_list_append_fail;
|
||||
}
|
||||
pList->a = sqlite3ArrayAllocate(
|
||||
db,
|
||||
@@ -3598,10 +3609,14 @@ IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pToken){
|
||||
);
|
||||
if( i<0 ){
|
||||
sqlite3IdListDelete(db, pList);
|
||||
return 0;
|
||||
goto id_list_append_fail;
|
||||
}
|
||||
pList->a[i].zName = sqlite3NameFromToken(db, pToken);
|
||||
pList->a[i].zName = zName;
|
||||
return pList;
|
||||
|
||||
id_list_append_fail:
|
||||
sqlite3DbFree(db, zName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+35
-22
@@ -204,11 +204,15 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);}
|
||||
%left COLLATE.
|
||||
%right BITNOT.
|
||||
|
||||
// An IDENTIFIER can be a generic identifier, or one of several
|
||||
// An "id" can be a generic identifier, or one of several
|
||||
// keywords. Any non-standard keyword can also be an identifier.
|
||||
//
|
||||
%token_class id ID|INDEXED.
|
||||
|
||||
// A "number" can be either an integer or a floating point value
|
||||
%token_class number INTEGER|FLOAT.
|
||||
|
||||
|
||||
// The following directive causes tokens ABORT, AFTER, ASC, etc. to
|
||||
// fallback to ID if they will not parse as their original value.
|
||||
// This obviates the need for the "id" nonterminal.
|
||||
@@ -254,8 +258,8 @@ typetoken(A) ::= typename(A) LP signed COMMA signed RP(Y). {
|
||||
%type typename {Token}
|
||||
typename(A) ::= ids(A).
|
||||
typename(A) ::= typename(A) ids(Y). {A.n=Y.n+(int)(Y.z-A.z);}
|
||||
signed ::= plus_num.
|
||||
signed ::= minus_num.
|
||||
signed ::= PLUS|MINUS number.
|
||||
signed ::= number.
|
||||
|
||||
// "carglist" is a list of additional constraints that come after the
|
||||
// column name and column type in a CREATE TABLE statement.
|
||||
@@ -807,12 +811,13 @@ insert_cmd(A) ::= REPLACE. {A = OE_Replace;}
|
||||
%type idlist {IdList*}
|
||||
%destructor idlist {sqlite3IdListDelete(pParse->db, $$);}
|
||||
|
||||
idlist_opt(A) ::= . {A = 0;}
|
||||
idlist_opt(A) ::= . {A = 0;}
|
||||
idlist_opt(A) ::= LP idlist(X) RP. {A = X;}
|
||||
idlist(A) ::= idlist(A) COMMA nm(Y).
|
||||
{A = sqlite3IdListAppend(pParse->db,A,&Y);}
|
||||
{A = sqlite3IdListAppend(pParse,A,sqlite3NameFromToken(pParse->db,&Y));}
|
||||
idlist(A) ::= nm(Y).
|
||||
{A = sqlite3IdListAppend(pParse->db,0,&Y); /*A-overwrites-Y*/}
|
||||
{A = sqlite3IdListAppend(pParse,0,sqlite3NameFromToken(pParse->db,&Y));
|
||||
/*A-overwrites-Y*/}
|
||||
|
||||
/////////////////////////// Expression Processing /////////////////////////////
|
||||
//
|
||||
@@ -1325,24 +1330,32 @@ cmd ::= VACUUM nm(X). {sqlite3Vacuum(pParse,&X);}
|
||||
///////////////////////////// The PRAGMA command /////////////////////////////
|
||||
//
|
||||
%ifndef SQLITE_OMIT_PRAGMA
|
||||
cmd ::= PRAGMA nm(X) dbnm(Z). {sqlite3Pragma(pParse,&X,&Z,0,0);}
|
||||
cmd ::= PRAGMA nm(X) dbnm(Z) EQ nmnum(Y). {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
|
||||
cmd ::= PRAGMA nm(X) dbnm(Z) LP nmnum(Y) RP. {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
|
||||
cmd ::= PRAGMA nm(X) dbnm(Z) EQ minus_num(Y).
|
||||
{sqlite3Pragma(pParse,&X,&Z,&Y,1);}
|
||||
cmd ::= PRAGMA nm(X) dbnm(Z) LP minus_num(Y) RP.
|
||||
{sqlite3Pragma(pParse,&X,&Z,&Y,1);}
|
||||
cmd ::= PRAGMA nm(X) dbnm(Z). {sqlite3Pragma(pParse,&X,&Z,0);}
|
||||
cmd ::= PRAGMA nm(X) dbnm(Z) EQ pragma_arglist(Y).
|
||||
{sqlite3Pragma(pParse,&X,&Z,Y);}
|
||||
cmd ::= PRAGMA nm(X) dbnm(Z) LP pragma_arglist(Y) RP.
|
||||
{sqlite3Pragma(pParse,&X,&Z,Y);}
|
||||
|
||||
%type pragma_arglist {IdList*}
|
||||
%destructor pragma_arglist {sqlite3IdListDelete(pParse->db,$$);}
|
||||
|
||||
pragma_arglist(A) ::= pragma_arg(X).
|
||||
{ A = sqlite3IdListAppend(pParse,0,X)/*A-overwrites-X*/; }
|
||||
pragma_arglist(A) ::= pragma_arglist(A) COMMA pragma_arg(Y).
|
||||
{ A = sqlite3IdListAppend(pParse,A,Y); }
|
||||
|
||||
%type pragma_arg {char*}
|
||||
%destructor pragma_arg {sqlite3DbFree(pParse->db,$$);}
|
||||
pragma_arg(A) ::= number(X).
|
||||
{A = sqlite3NameFromToken(pParse->db,&X);/*A-overwrites-X*/}
|
||||
pragma_arg(A) ::= nm(X).
|
||||
{A = sqlite3NameFromToken(pParse->db,&X);/*A-overwrites-X*/}
|
||||
pragma_arg(A) ::= ON|DELETE|DEFAULT(X).
|
||||
{A = sqlite3NameFromToken(pParse->db,&X);/*A-overwrites-X*/}
|
||||
pragma_arg(A) ::= PLUS number(X). {A = sqlite3NameFromToken(pParse->db,&X);}
|
||||
pragma_arg(A) ::= MINUS number(X). {A = sqlite3MPrintf(pParse->db,"-%T",&X);}
|
||||
|
||||
nmnum(A) ::= plus_num(A).
|
||||
nmnum(A) ::= nm(A).
|
||||
nmnum(A) ::= ON(A).
|
||||
nmnum(A) ::= DELETE(A).
|
||||
nmnum(A) ::= DEFAULT(A).
|
||||
%endif SQLITE_OMIT_PRAGMA
|
||||
%token_class number INTEGER|FLOAT.
|
||||
plus_num(A) ::= PLUS number(X). {A = X;}
|
||||
plus_num(A) ::= number(A).
|
||||
minus_num(A) ::= MINUS number(X). {A = X;}
|
||||
//////////////////////////// The CREATE TRIGGER command /////////////////////
|
||||
|
||||
%ifndef SQLITE_OMIT_TRIGGER
|
||||
|
||||
+508
-113
@@ -163,29 +163,29 @@ static int changeTempStorage(Parse *pParse, const char *zStorageType){
|
||||
#endif /* SQLITE_PAGER_PRAGMAS */
|
||||
|
||||
/*
|
||||
** Set the names of the first N columns to the values in azCol[]
|
||||
** Set result column names for a pragma.
|
||||
*/
|
||||
static void setAllColumnNames(
|
||||
Vdbe *v, /* The query under construction */
|
||||
int N, /* Number of columns */
|
||||
const char **azCol /* Names of columns */
|
||||
static void setPragmaResultColumnNames(
|
||||
Vdbe *v, /* The query under construction */
|
||||
const PragmaName *pPragma /* The pragma */
|
||||
){
|
||||
int i;
|
||||
sqlite3VdbeSetNumCols(v, N);
|
||||
for(i=0; i<N; i++){
|
||||
sqlite3VdbeSetColName(v, i, COLNAME_NAME, azCol[i], SQLITE_STATIC);
|
||||
u8 n = pPragma->nPragCName;
|
||||
sqlite3VdbeSetNumCols(v, n==0 ? 1 : n);
|
||||
if( n==0 ){
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, pPragma->zName, SQLITE_STATIC);
|
||||
}else{
|
||||
int i, j;
|
||||
for(i=0, j=pPragma->iPragCName; i<n; i++, j++){
|
||||
sqlite3VdbeSetColName(v, i, COLNAME_NAME, pragCName[j], SQLITE_STATIC);
|
||||
}
|
||||
}
|
||||
}
|
||||
static void setOneColumnName(Vdbe *v, const char *z){
|
||||
setAllColumnNames(v, 1, &z);
|
||||
}
|
||||
|
||||
/*
|
||||
** Generate code to return a single integer value.
|
||||
*/
|
||||
static void returnSingleInt(Vdbe *v, const char *zLabel, i64 value){
|
||||
static void returnSingleInt(Vdbe *v, i64 value){
|
||||
sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, 1, 0, (const u8*)&value, P4_INT64);
|
||||
setOneColumnName(v, zLabel);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
|
||||
}
|
||||
|
||||
@@ -194,12 +194,10 @@ static void returnSingleInt(Vdbe *v, const char *zLabel, i64 value){
|
||||
*/
|
||||
static void returnSingleText(
|
||||
Vdbe *v, /* Prepared statement under construction */
|
||||
const char *zLabel, /* Name of the result column */
|
||||
const char *zValue /* Value to be returned */
|
||||
){
|
||||
if( zValue ){
|
||||
sqlite3VdbeLoadString(v, 1, (const char*)zValue);
|
||||
setOneColumnName(v, zLabel);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
|
||||
}
|
||||
}
|
||||
@@ -277,16 +275,32 @@ const char *sqlite3JournalModename(int eMode){
|
||||
return azModeName[eMode];
|
||||
}
|
||||
|
||||
/*
|
||||
** Locate a pragma in the aPragmaName[] array.
|
||||
*/
|
||||
static const PragmaName *pragmaLocate(const char *zName){
|
||||
int upr, lwr, mid, rc;
|
||||
lwr = 0;
|
||||
upr = ArraySize(aPragmaName)-1;
|
||||
while( lwr<=upr ){
|
||||
mid = (lwr+upr)/2;
|
||||
rc = sqlite3_stricmp(zName, aPragmaName[mid].zName);
|
||||
if( rc==0 ) break;
|
||||
if( rc<0 ){
|
||||
upr = mid - 1;
|
||||
}else{
|
||||
lwr = mid + 1;
|
||||
}
|
||||
}
|
||||
return lwr>upr ? 0 : &aPragmaName[mid];
|
||||
}
|
||||
|
||||
/*
|
||||
** Process a pragma statement.
|
||||
**
|
||||
** Pragmas are of this form:
|
||||
**
|
||||
** PRAGMA [schema.]id [= value]
|
||||
**
|
||||
** The identifier might also be a string. The value is a string, and
|
||||
** identifier, or a number. If minusFlag is true, then the value is
|
||||
** a number that was preceded by a minus sign.
|
||||
** PRAGMA [schema.]id [= value-list]
|
||||
**
|
||||
** If the left side is "database.id" then pId1 is the database name
|
||||
** and pId2 is the id. If the left side is just "id" then pId1 is the
|
||||
@@ -296,8 +310,7 @@ void sqlite3Pragma(
|
||||
Parse *pParse,
|
||||
Token *pId1, /* First part of [schema.]id field */
|
||||
Token *pId2, /* Second part of [schema.]id field, or NULL */
|
||||
Token *pValue, /* Token for <value>, or NULL */
|
||||
int minusFlag /* True if a '-' sign preceded <value> */
|
||||
IdList *pValues /* The value-list arguments. NULL if omitted */
|
||||
){
|
||||
char *zLeft = 0; /* Nul-terminated UTF-8 string <id> */
|
||||
char *zRight = 0; /* Nul-terminated UTF-8 string <value>, or NULL */
|
||||
@@ -305,21 +318,20 @@ void sqlite3Pragma(
|
||||
Token *pId; /* Pointer to <id> token */
|
||||
char *aFcntl[4]; /* Argument to SQLITE_FCNTL_PRAGMA */
|
||||
int iDb; /* Database index for <database> */
|
||||
int lwr, upr, mid = 0; /* Binary search bounds */
|
||||
int rc; /* return value form SQLITE_FCNTL_PRAGMA */
|
||||
sqlite3 *db = pParse->db; /* The database connection */
|
||||
Db *pDb; /* The specific database being pragmaed */
|
||||
Vdbe *v = sqlite3GetVdbe(pParse); /* Prepared statement */
|
||||
const struct sPragmaNames *pPragma;
|
||||
const PragmaName *pPragma; /* The pragma */
|
||||
|
||||
if( v==0 ) return;
|
||||
if( v==0 ) goto pragma_out;
|
||||
sqlite3VdbeRunOnlyOnce(v);
|
||||
pParse->nMem = 2;
|
||||
|
||||
/* Interpret the [schema.] part of the pragma statement. iDb is the
|
||||
** index of the database this pragma is being applied to in db.aDb[]. */
|
||||
iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId);
|
||||
if( iDb<0 ) return;
|
||||
if( iDb<0 ) goto pragma_out;
|
||||
pDb = &db->aDb[iDb];
|
||||
|
||||
/* If the temp database has been explicitly named as part of the
|
||||
@@ -330,12 +342,8 @@ void sqlite3Pragma(
|
||||
}
|
||||
|
||||
zLeft = sqlite3NameFromToken(db, pId);
|
||||
if( !zLeft ) return;
|
||||
if( minusFlag ){
|
||||
zRight = sqlite3MPrintf(db, "-%T", pValue);
|
||||
}else{
|
||||
zRight = sqlite3NameFromToken(db, pValue);
|
||||
}
|
||||
if( !zLeft ) goto pragma_out;
|
||||
if( pValues ) zRight = pValues->a[0].zName;
|
||||
|
||||
assert( pId2 );
|
||||
zDb = pId2->n>0 ? pDb->zDbSName : 0;
|
||||
@@ -365,7 +373,9 @@ void sqlite3Pragma(
|
||||
db->busyHandler.nBusy = 0;
|
||||
rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
|
||||
if( rc==SQLITE_OK ){
|
||||
returnSingleText(v, "result", aFcntl[0]);
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, aFcntl[0], SQLITE_TRANSIENT);
|
||||
returnSingleText(v, aFcntl[0]);
|
||||
sqlite3_free(aFcntl[0]);
|
||||
goto pragma_out;
|
||||
}
|
||||
@@ -380,26 +390,19 @@ void sqlite3Pragma(
|
||||
}
|
||||
|
||||
/* Locate the pragma in the lookup table */
|
||||
lwr = 0;
|
||||
upr = ArraySize(aPragmaNames)-1;
|
||||
while( lwr<=upr ){
|
||||
mid = (lwr+upr)/2;
|
||||
rc = sqlite3_stricmp(zLeft, aPragmaNames[mid].zName);
|
||||
if( rc==0 ) break;
|
||||
if( rc<0 ){
|
||||
upr = mid - 1;
|
||||
}else{
|
||||
lwr = mid + 1;
|
||||
}
|
||||
}
|
||||
if( lwr>upr ) goto pragma_out;
|
||||
pPragma = &aPragmaNames[mid];
|
||||
pPragma = pragmaLocate(zLeft);
|
||||
if( pPragma==0 ) goto pragma_out;
|
||||
|
||||
/* Make sure the database schema is loaded if the pragma requires that */
|
||||
if( (pPragma->mPragFlag & PragFlag_NeedSchema)!=0 ){
|
||||
if( (pPragma->mPragFlg & PragFlg_NeedSchema)!=0 ){
|
||||
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
||||
}
|
||||
|
||||
/* Register the result column names for pragmas that return results */
|
||||
if( (pPragma->mPragFlg & PragFlg_NoColumns)==0 ){
|
||||
setPragmaResultColumnNames(v, pPragma);
|
||||
}
|
||||
|
||||
/* Jump to the appropriate pragma handler */
|
||||
switch( pPragma->ePragTyp ){
|
||||
|
||||
@@ -436,7 +439,6 @@ void sqlite3Pragma(
|
||||
VdbeOp *aOp;
|
||||
sqlite3VdbeUsesBtree(v, iDb);
|
||||
if( !zRight ){
|
||||
setOneColumnName(v, "cache_size");
|
||||
pParse->nMem += 2;
|
||||
sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(getCacheSize));
|
||||
aOp = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize, iLn);
|
||||
@@ -471,7 +473,7 @@ void sqlite3Pragma(
|
||||
assert( pBt!=0 );
|
||||
if( !zRight ){
|
||||
int size = ALWAYS(pBt) ? sqlite3BtreeGetPageSize(pBt) : 0;
|
||||
returnSingleInt(v, "page_size", size);
|
||||
returnSingleInt(v, size);
|
||||
}else{
|
||||
/* Malloc may fail when setting the page-size, as there is an internal
|
||||
** buffer that the pager module resizes using sqlite3_realloc().
|
||||
@@ -506,7 +508,7 @@ void sqlite3Pragma(
|
||||
}
|
||||
}
|
||||
b = sqlite3BtreeSecureDelete(pBt, b);
|
||||
returnSingleInt(v, "secure_delete", b);
|
||||
returnSingleInt(v, b);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -538,8 +540,6 @@ void sqlite3Pragma(
|
||||
sqlite3AbsInt32(sqlite3Atoi(zRight)));
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1);
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -585,7 +585,7 @@ void sqlite3Pragma(
|
||||
if( eMode==PAGER_LOCKINGMODE_EXCLUSIVE ){
|
||||
zRet = "exclusive";
|
||||
}
|
||||
returnSingleText(v, "locking_mode", zRet);
|
||||
returnSingleText(v, zRet);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -598,7 +598,6 @@ void sqlite3Pragma(
|
||||
int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */
|
||||
int ii; /* Loop counter */
|
||||
|
||||
setOneColumnName(v, "journal_mode");
|
||||
if( zRight==0 ){
|
||||
/* If there is no "=MODE" part of the pragma, do a query for the
|
||||
** current mode */
|
||||
@@ -644,7 +643,7 @@ void sqlite3Pragma(
|
||||
if( iLimit<-1 ) iLimit = -1;
|
||||
}
|
||||
iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit);
|
||||
returnSingleInt(v, "journal_size_limit", iLimit);
|
||||
returnSingleInt(v, iLimit);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -662,7 +661,7 @@ void sqlite3Pragma(
|
||||
Btree *pBt = pDb->pBt;
|
||||
assert( pBt!=0 );
|
||||
if( !zRight ){
|
||||
returnSingleInt(v, "auto_vacuum", sqlite3BtreeGetAutoVacuum(pBt));
|
||||
returnSingleInt(v, sqlite3BtreeGetAutoVacuum(pBt));
|
||||
}else{
|
||||
int eAuto = getAutoVacuum(zRight);
|
||||
assert( eAuto>=0 && eAuto<=2 );
|
||||
@@ -741,7 +740,7 @@ void sqlite3Pragma(
|
||||
case PragTyp_CACHE_SIZE: {
|
||||
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
|
||||
if( !zRight ){
|
||||
returnSingleInt(v, "cache_size", pDb->pSchema->cache_size);
|
||||
returnSingleInt(v, pDb->pSchema->cache_size);
|
||||
}else{
|
||||
int size = sqlite3Atoi(zRight);
|
||||
pDb->pSchema->cache_size = size;
|
||||
@@ -775,7 +774,7 @@ void sqlite3Pragma(
|
||||
case PragTyp_CACHE_SPILL: {
|
||||
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
|
||||
if( !zRight ){
|
||||
returnSingleInt(v, "cache_spill",
|
||||
returnSingleInt(v,
|
||||
(db->flags & SQLITE_CacheSpill)==0 ? 0 :
|
||||
sqlite3BtreeSetSpillSize(pDb->pBt,0));
|
||||
}else{
|
||||
@@ -829,7 +828,7 @@ void sqlite3Pragma(
|
||||
rc = SQLITE_OK;
|
||||
#endif
|
||||
if( rc==SQLITE_OK ){
|
||||
returnSingleInt(v, "mmap_size", sz);
|
||||
returnSingleInt(v, sz);
|
||||
}else if( rc!=SQLITE_NOTFOUND ){
|
||||
pParse->nErr++;
|
||||
pParse->rc = rc;
|
||||
@@ -850,7 +849,7 @@ void sqlite3Pragma(
|
||||
*/
|
||||
case PragTyp_TEMP_STORE: {
|
||||
if( !zRight ){
|
||||
returnSingleInt(v, "temp_store", db->temp_store);
|
||||
returnSingleInt(v, db->temp_store);
|
||||
}else{
|
||||
changeTempStorage(pParse, zRight);
|
||||
}
|
||||
@@ -869,7 +868,7 @@ void sqlite3Pragma(
|
||||
*/
|
||||
case PragTyp_TEMP_STORE_DIRECTORY: {
|
||||
if( !zRight ){
|
||||
returnSingleText(v, "temp_store_directory", sqlite3_temp_directory);
|
||||
returnSingleText(v, sqlite3_temp_directory);
|
||||
}else{
|
||||
#ifndef SQLITE_OMIT_WSD
|
||||
if( zRight[0] ){
|
||||
@@ -913,7 +912,7 @@ void sqlite3Pragma(
|
||||
*/
|
||||
case PragTyp_DATA_STORE_DIRECTORY: {
|
||||
if( !zRight ){
|
||||
returnSingleText(v, "data_store_directory", sqlite3_data_directory);
|
||||
returnSingleText(v, sqlite3_data_directory);
|
||||
}else{
|
||||
#ifndef SQLITE_OMIT_WSD
|
||||
if( zRight[0] ){
|
||||
@@ -952,7 +951,7 @@ void sqlite3Pragma(
|
||||
sqlite3_file *pFile = sqlite3PagerFile(pPager);
|
||||
sqlite3OsFileControlHint(pFile, SQLITE_GET_LOCKPROXYFILE,
|
||||
&proxy_file_path);
|
||||
returnSingleText(v, "lock_proxy_file", proxy_file_path);
|
||||
returnSingleText(v, proxy_file_path);
|
||||
}else{
|
||||
Pager *pPager = sqlite3BtreePager(pDb->pBt);
|
||||
sqlite3_file *pFile = sqlite3PagerFile(pPager);
|
||||
@@ -984,7 +983,7 @@ void sqlite3Pragma(
|
||||
*/
|
||||
case PragTyp_SYNCHRONOUS: {
|
||||
if( !zRight ){
|
||||
returnSingleInt(v, "synchronous", pDb->safety_level-1);
|
||||
returnSingleInt(v, pDb->safety_level-1);
|
||||
}else{
|
||||
if( !db->autoCommit ){
|
||||
sqlite3ErrorMsg(pParse,
|
||||
@@ -1004,7 +1003,8 @@ void sqlite3Pragma(
|
||||
#ifndef SQLITE_OMIT_FLAG_PRAGMAS
|
||||
case PragTyp_FLAG: {
|
||||
if( zRight==0 ){
|
||||
returnSingleInt(v, pPragma->zName, (db->flags & pPragma->iArg)!=0 );
|
||||
setPragmaResultColumnNames(v, pPragma);
|
||||
returnSingleInt(v, (db->flags & pPragma->iArg)!=0 );
|
||||
}else{
|
||||
int mask = pPragma->iArg; /* Mask of bits to set or clear. */
|
||||
if( db->autoCommit==0 ){
|
||||
@@ -1054,16 +1054,12 @@ void sqlite3Pragma(
|
||||
Table *pTab;
|
||||
pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb);
|
||||
if( pTab ){
|
||||
static const char *azCol[] = {
|
||||
"cid", "name", "type", "notnull", "dflt_value", "pk"
|
||||
};
|
||||
int i, k;
|
||||
int nHidden = 0;
|
||||
Column *pCol;
|
||||
Index *pPk = sqlite3PrimaryKeyIndex(pTab);
|
||||
pParse->nMem = 6;
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
setAllColumnNames(v, 6, azCol); assert( 6==ArraySize(azCol) );
|
||||
sqlite3ViewGetColumnNames(pParse, pTab);
|
||||
for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
|
||||
if( IsHiddenColumn(pCol) ){
|
||||
@@ -1092,13 +1088,10 @@ void sqlite3Pragma(
|
||||
break;
|
||||
|
||||
case PragTyp_STATS: {
|
||||
static const char *azCol[] = { "table", "index", "width", "height" };
|
||||
Index *pIdx;
|
||||
HashElem *i;
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
pParse->nMem = 4;
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
setAllColumnNames(v, 4, azCol); assert( 4==ArraySize(azCol) );
|
||||
for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){
|
||||
Table *pTab = sqliteHashData(i);
|
||||
sqlite3VdbeMultiLoad(v, 1, "ssii",
|
||||
@@ -1122,10 +1115,11 @@ void sqlite3Pragma(
|
||||
Index *pIdx;
|
||||
Table *pTab;
|
||||
pIdx = sqlite3FindIndex(db, zRight, zDb);
|
||||
if( pIdx==0 ){
|
||||
pTab = sqlite3FindTable(db, zRight, zDb);
|
||||
if( pTab && !HasRowid(pTab) ) pIdx = sqlite3PrimaryKeyIndex(pTab);
|
||||
}
|
||||
if( pIdx ){
|
||||
static const char *azCol[] = {
|
||||
"seqno", "cid", "name", "desc", "coll", "key"
|
||||
};
|
||||
int i;
|
||||
int mx;
|
||||
if( pPragma->iArg ){
|
||||
@@ -1139,8 +1133,7 @@ void sqlite3Pragma(
|
||||
}
|
||||
pTab = pIdx->pTable;
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
assert( pParse->nMem<=ArraySize(azCol) );
|
||||
setAllColumnNames(v, pParse->nMem, azCol);
|
||||
assert( pParse->nMem<=pPragma->nPragCName );
|
||||
for(i=0; i<mx; i++){
|
||||
i16 cnum = pIdx->aiColumn[i];
|
||||
sqlite3VdbeMultiLoad(v, 1, "iis", i, cnum,
|
||||
@@ -1163,13 +1156,8 @@ void sqlite3Pragma(
|
||||
int i;
|
||||
pTab = sqlite3FindTable(db, zRight, zDb);
|
||||
if( pTab ){
|
||||
static const char *azCol[] = {
|
||||
"seq", "name", "unique", "origin", "partial"
|
||||
};
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
pParse->nMem = 5;
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
setAllColumnNames(v, 5, azCol); assert( 5==ArraySize(azCol) );
|
||||
for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){
|
||||
const char *azOrigin[] = { "c", "u", "pk" };
|
||||
sqlite3VdbeMultiLoad(v, 1, "isisi",
|
||||
@@ -1185,10 +1173,8 @@ void sqlite3Pragma(
|
||||
break;
|
||||
|
||||
case PragTyp_DATABASE_LIST: {
|
||||
static const char *azCol[] = { "seq", "name", "file" };
|
||||
int i;
|
||||
pParse->nMem = 3;
|
||||
setAllColumnNames(v, 3, azCol); assert( 3==ArraySize(azCol) );
|
||||
for(i=0; i<db->nDb; i++){
|
||||
if( db->aDb[i].pBt==0 ) continue;
|
||||
assert( db->aDb[i].zDbSName!=0 );
|
||||
@@ -1202,11 +1188,9 @@ void sqlite3Pragma(
|
||||
break;
|
||||
|
||||
case PragTyp_COLLATION_LIST: {
|
||||
static const char *azCol[] = { "seq", "name" };
|
||||
int i = 0;
|
||||
HashElem *p;
|
||||
pParse->nMem = 2;
|
||||
setAllColumnNames(v, 2, azCol); assert( 2==ArraySize(azCol) );
|
||||
for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){
|
||||
CollSeq *pColl = (CollSeq *)sqliteHashData(p);
|
||||
sqlite3VdbeMultiLoad(v, 1, "is", i++, pColl->zName);
|
||||
@@ -1222,17 +1206,11 @@ void sqlite3Pragma(
|
||||
Table *pTab;
|
||||
pTab = sqlite3FindTable(db, zRight, zDb);
|
||||
if( pTab ){
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
pFK = pTab->pFKey;
|
||||
if( pFK ){
|
||||
static const char *azCol[] = {
|
||||
"id", "seq", "table", "from", "to", "on_update", "on_delete",
|
||||
"match"
|
||||
};
|
||||
int i = 0;
|
||||
pParse->nMem = 8;
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
setAllColumnNames(v, 8, azCol); assert( 8==ArraySize(azCol) );
|
||||
while(pFK){
|
||||
int j;
|
||||
for(j=0; j<pFK->nCol; j++){
|
||||
@@ -1273,14 +1251,11 @@ void sqlite3Pragma(
|
||||
int addrTop; /* Top of a loop checking foreign keys */
|
||||
int addrOk; /* Jump here if the key is OK */
|
||||
int *aiCols; /* child to parent column mapping */
|
||||
static const char *azCol[] = { "table", "rowid", "parent", "fkid" };
|
||||
|
||||
regResult = pParse->nMem+1;
|
||||
pParse->nMem += 4;
|
||||
regKey = ++pParse->nMem;
|
||||
regRow = ++pParse->nMem;
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
setAllColumnNames(v, 4, azCol); assert( 4==ArraySize(azCol) );
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash);
|
||||
while( k ){
|
||||
@@ -1390,6 +1365,133 @@ void sqlite3Pragma(
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
** PRAGMA est_row_cnt(<table-or-index>,<fraction>);
|
||||
**
|
||||
** Seek in <table-or-index> through the first <fraction> of rows and
|
||||
** estimate the total number of rows based on the path back up to the
|
||||
** root.
|
||||
*/
|
||||
case PragTyp_EST_COUNT: {
|
||||
Index *pIdx;
|
||||
Table *pTab = 0;
|
||||
Pgno iRoot = 0;
|
||||
const char *zName = 0;
|
||||
int regResult;
|
||||
double r;
|
||||
if( (pIdx = sqlite3FindIndex(db, zRight, zDb))!=0 ){
|
||||
iRoot = pIdx->tnum;
|
||||
zName = pIdx->zName;
|
||||
}else if( (pTab = sqlite3FindTable(db, zRight, zDb))!=0 ){
|
||||
zName = pTab->zName;
|
||||
if( HasRowid(pTab) ){
|
||||
iRoot = pTab->tnum;
|
||||
}else{
|
||||
pIdx = sqlite3PrimaryKeyIndex(pTab);
|
||||
iRoot = pIdx->tnum;
|
||||
}
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
sqlite3TableLock(pParse, iDb, iRoot, 0, zName);
|
||||
regResult = ++pParse->nMem;
|
||||
if( pValues->nId>=2 ){
|
||||
const char *z = pValues->a[1].zName;
|
||||
sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
|
||||
}else{
|
||||
r = 0.5;
|
||||
}
|
||||
if( r<0.0 ) r = 0.0;
|
||||
if( r>1.0 ) r = 1.0;
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
pParse->nTab++;
|
||||
sqlite3VdbeAddOp4Int(v, OP_OpenRead, 0, iRoot, iDb, 1);
|
||||
if( pIdx ) sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
|
||||
sqlite3VdbeAddOp3(v, OP_EstRowCnt, 0, regResult, (int)(r*1000000000));
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
** PRAGMA btree_sample(<table-or-index>,<fraction>,<limit>);
|
||||
**
|
||||
** Seek in <table-or-index> through the first <fraction> of rows and
|
||||
** then begin returning rows, one by one. A max of <limit> rows will
|
||||
** be returned.
|
||||
*/
|
||||
case PragTyp_BTREE_SAMPLE: {
|
||||
Index *pIdx;
|
||||
Table *pTab = 0;
|
||||
Pgno iRoot = 0;
|
||||
Pgno iLock = 0;
|
||||
int nCol = 0;
|
||||
const char *zName = 0;
|
||||
int iLimit = 10;
|
||||
int i;
|
||||
int regResult;
|
||||
int regLimit;
|
||||
int addrTop;
|
||||
int addrJmp;
|
||||
int addrSkip;
|
||||
double r;
|
||||
if( (pIdx = sqlite3FindIndex(db, zRight, zDb))!=0 ){
|
||||
iRoot = pIdx->tnum;
|
||||
iLock = pIdx->pTable->tnum;
|
||||
zName = pIdx->zName;
|
||||
nCol = pIdx->nColumn;
|
||||
}else if( (pTab = sqlite3FindTable(db, zRight, zDb))!=0 ){
|
||||
zName = pTab->zName;
|
||||
if( HasRowid(pTab) ){
|
||||
iLock = iRoot = pTab->tnum;
|
||||
nCol = pTab->nCol;
|
||||
}else{
|
||||
pIdx = sqlite3PrimaryKeyIndex(pTab);
|
||||
iLock = iRoot = pIdx->tnum;
|
||||
nCol = pIdx->nColumn;
|
||||
}
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
sqlite3VdbeSetNumCols(v, nCol);
|
||||
for(i=0; i<nCol; i++){
|
||||
char zCol[30];
|
||||
sqlite3_snprintf(sizeof(zCol),zCol,"c%06d",i);
|
||||
sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, SQLITE_TRANSIENT);
|
||||
}
|
||||
if( pValues->nId>=2 ){
|
||||
const char *z = pValues->a[1].zName;
|
||||
sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
|
||||
}else{
|
||||
r = 0.5;
|
||||
}
|
||||
if( r<0.0 ) r = 0.0;
|
||||
if( r>1.0 ) r = 1.0;
|
||||
if( pValues->nId>=3 ){
|
||||
iLimit = sqlite3Atoi(pValues->a[2].zName);
|
||||
}
|
||||
pParse->nTab++;
|
||||
sqlite3TableLock(pParse, iDb, iLock, 0, zName);
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
sqlite3VdbeAddOp4Int(v, OP_OpenRead, 0, iRoot, iDb, nCol);
|
||||
if( pIdx ) sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
|
||||
regLimit = ++pParse->nMem;
|
||||
regResult = pParse->nMem+1;
|
||||
pParse->nMem += nCol;
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, iLimit, regLimit);
|
||||
addrSkip = sqlite3VdbeAddOp1(v, OP_Rewind, 0); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp3(v, OP_EstRowCnt, 0, regResult, (int)(r*1000000000));
|
||||
addrTop = sqlite3VdbeCurrentAddr(v);
|
||||
for(i=0; i<nCol; i++){
|
||||
sqlite3VdbeAddOp3(v, OP_Column, 0, i, regResult+i);
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nCol);
|
||||
addrJmp = sqlite3VdbeAddOp1(v, OP_DecrJumpZero, regLimit); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop); VdbeCoverage(v);
|
||||
sqlite3VdbeJumpHere(v, addrJmp);
|
||||
sqlite3VdbeJumpHere(v, addrSkip);
|
||||
}
|
||||
break;
|
||||
|
||||
#ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX
|
||||
# define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100
|
||||
#endif
|
||||
@@ -1419,7 +1521,6 @@ void sqlite3Pragma(
|
||||
|
||||
/* Initialize the VDBE program */
|
||||
pParse->nMem = 6;
|
||||
setOneColumnName(v, "integrity_check");
|
||||
|
||||
/* Set the maximum error count */
|
||||
mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
|
||||
@@ -1671,7 +1772,7 @@ void sqlite3Pragma(
|
||||
assert( encnames[SQLITE_UTF8].enc==SQLITE_UTF8 );
|
||||
assert( encnames[SQLITE_UTF16LE].enc==SQLITE_UTF16LE );
|
||||
assert( encnames[SQLITE_UTF16BE].enc==SQLITE_UTF16BE );
|
||||
returnSingleText(v, "encoding", encnames[ENC(pParse->db)].zName);
|
||||
returnSingleText(v, encnames[ENC(pParse->db)].zName);
|
||||
}else{ /* "PRAGMA encoding = XXX" */
|
||||
/* Only change the value of sqlite.enc if the database handle is not
|
||||
** initialized. If the main database exists, the new sqlite.enc value
|
||||
@@ -1734,7 +1835,7 @@ void sqlite3Pragma(
|
||||
case PragTyp_HEADER_VALUE: {
|
||||
int iCookie = pPragma->iArg; /* Which cookie to read or write */
|
||||
sqlite3VdbeUsesBtree(v, iDb);
|
||||
if( zRight && (pPragma->mPragFlag & PragFlag_ReadOnly)==0 ){
|
||||
if( zRight && (pPragma->mPragFlg & PragFlg_ReadOnly)==0 ){
|
||||
/* Write the specified cookie value */
|
||||
static const VdbeOpList setCookie[] = {
|
||||
{ OP_Transaction, 0, 1, 0}, /* 0 */
|
||||
@@ -1762,8 +1863,6 @@ void sqlite3Pragma(
|
||||
aOp[0].p1 = iDb;
|
||||
aOp[1].p1 = iDb;
|
||||
aOp[1].p3 = iCookie;
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT);
|
||||
sqlite3VdbeReusable(v);
|
||||
}
|
||||
}
|
||||
@@ -1781,7 +1880,6 @@ void sqlite3Pragma(
|
||||
int i = 0;
|
||||
const char *zOpt;
|
||||
pParse->nMem = 1;
|
||||
setOneColumnName(v, "compile_option");
|
||||
while( (zOpt = sqlite3_compileoption_get(i++))!=0 ){
|
||||
sqlite3VdbeLoadString(v, 1, zOpt);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
|
||||
@@ -1798,7 +1896,6 @@ void sqlite3Pragma(
|
||||
** Checkpoint the database.
|
||||
*/
|
||||
case PragTyp_WAL_CHECKPOINT: {
|
||||
static const char *azCol[] = { "busy", "log", "checkpointed" };
|
||||
int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED);
|
||||
int eMode = SQLITE_CHECKPOINT_PASSIVE;
|
||||
if( zRight ){
|
||||
@@ -1810,7 +1907,6 @@ void sqlite3Pragma(
|
||||
eMode = SQLITE_CHECKPOINT_TRUNCATE;
|
||||
}
|
||||
}
|
||||
setAllColumnNames(v, 3, azCol); assert( 3==ArraySize(azCol) );
|
||||
pParse->nMem = 3;
|
||||
sqlite3VdbeAddOp3(v, OP_Checkpoint, iBt, eMode, 1);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
|
||||
@@ -1829,7 +1925,7 @@ void sqlite3Pragma(
|
||||
if( zRight ){
|
||||
sqlite3_wal_autocheckpoint(db, sqlite3Atoi(zRight));
|
||||
}
|
||||
returnSingleInt(v, "wal_autocheckpoint",
|
||||
returnSingleInt(v,
|
||||
db->xWalCallback==sqlite3WalDefaultHook ?
|
||||
SQLITE_PTR_TO_INT(db->pWalArg) : 0);
|
||||
}
|
||||
@@ -1862,7 +1958,7 @@ void sqlite3Pragma(
|
||||
if( zRight ){
|
||||
sqlite3_busy_timeout(db, sqlite3Atoi(zRight));
|
||||
}
|
||||
returnSingleInt(v, "timeout", db->busyTimeout);
|
||||
returnSingleInt(v, db->busyTimeout);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1882,7 +1978,7 @@ void sqlite3Pragma(
|
||||
if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){
|
||||
sqlite3_soft_heap_limit64(N);
|
||||
}
|
||||
returnSingleInt(v, "soft_heap_limit", sqlite3_soft_heap_limit64(-1));
|
||||
returnSingleInt(v, sqlite3_soft_heap_limit64(-1));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1901,8 +1997,7 @@ void sqlite3Pragma(
|
||||
){
|
||||
sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff));
|
||||
}
|
||||
returnSingleInt(v, "threads",
|
||||
sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1));
|
||||
returnSingleInt(v, sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1914,9 +2009,7 @@ void sqlite3Pragma(
|
||||
static const char *const azLockName[] = {
|
||||
"unlocked", "shared", "reserved", "pending", "exclusive"
|
||||
};
|
||||
static const char *azCol[] = { "database", "status" };
|
||||
int i;
|
||||
setAllColumnNames(v, 2, azCol); assert( 2==ArraySize(azCol) );
|
||||
pParse->nMem = 2;
|
||||
for(i=0; i<db->nDb; i++){
|
||||
Btree *pBt;
|
||||
@@ -1984,7 +2077,309 @@ void sqlite3Pragma(
|
||||
|
||||
pragma_out:
|
||||
sqlite3DbFree(db, zLeft);
|
||||
sqlite3DbFree(db, zRight);
|
||||
sqlite3IdListDelete(db, pValues);
|
||||
}
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
/*****************************************************************************
|
||||
** Implementation of an eponymous virtual table that runs a pragma.
|
||||
**
|
||||
*/
|
||||
typedef struct PragmaVtab PragmaVtab;
|
||||
typedef struct PragmaVtabCursor PragmaVtabCursor;
|
||||
struct PragmaVtab {
|
||||
sqlite3_vtab base; /* Base class. Must be first */
|
||||
sqlite3 *db; /* The database connection to which it belongs */
|
||||
const PragmaName *pName; /* Name of the pragma */
|
||||
u8 nHidden; /* Number of hidden columns */
|
||||
u8 iHidden; /* Index of the first hidden column */
|
||||
};
|
||||
struct PragmaVtabCursor {
|
||||
sqlite3_vtab_cursor base; /* Base class. Must be first */
|
||||
sqlite3_stmt *pPragma; /* The pragma statement to run */
|
||||
sqlite_int64 iRowid; /* Current rowid */
|
||||
char *azArg[2]; /* Value of the argument and schema */
|
||||
};
|
||||
|
||||
/*
|
||||
** Pragma virtual table module xConnect method.
|
||||
*/
|
||||
static int pragmaVtabConnect(
|
||||
sqlite3 *db,
|
||||
void *pAux,
|
||||
int argc, const char *const*argv,
|
||||
sqlite3_vtab **ppVtab,
|
||||
char **pzErr
|
||||
){
|
||||
const PragmaName *pPragma = (const PragmaName*)pAux;
|
||||
PragmaVtab *pTab = 0;
|
||||
int rc;
|
||||
int i, j;
|
||||
char cSep = '(';
|
||||
StrAccum acc;
|
||||
char zBuf[200];
|
||||
|
||||
sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
|
||||
sqlite3StrAccumAppendAll(&acc, "CREATE TABLE x");
|
||||
for(i=0, j=pPragma->iPragCName; i<pPragma->nPragCName; i++, j++){
|
||||
sqlite3XPrintf(&acc, "%c\"%s\"", cSep, pragCName[j]);
|
||||
cSep = ',';
|
||||
}
|
||||
if( i==0 ){
|
||||
sqlite3XPrintf(&acc, "(\"%s\"", pPragma->zName);
|
||||
cSep = ',';
|
||||
i++;
|
||||
}
|
||||
j = 0;
|
||||
if( pPragma->mPragFlg & PragFlg_Result1 ){
|
||||
sqlite3StrAccumAppendAll(&acc, ",arg HIDDEN");
|
||||
j++;
|
||||
}
|
||||
if( pPragma->mPragFlg & (PragFlg_SchemaOpt|PragFlg_SchemaReq) ){
|
||||
sqlite3StrAccumAppendAll(&acc, ",schema HIDDEN");
|
||||
j++;
|
||||
}
|
||||
sqlite3StrAccumAppend(&acc, ")", 1);
|
||||
sqlite3StrAccumFinish(&acc);
|
||||
assert( strlen(zBuf) < sizeof(zBuf)-1 );
|
||||
rc = sqlite3_declare_vtab(db, zBuf);
|
||||
if( rc==SQLITE_OK ){
|
||||
pTab = (PragmaVtab*)sqlite3_malloc(sizeof(PragmaVtab));
|
||||
if( pTab==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
memset(pTab, 0, sizeof(PragmaVtab));
|
||||
pTab->pName = pPragma;
|
||||
pTab->db = db;
|
||||
pTab->iHidden = i;
|
||||
pTab->nHidden = j;
|
||||
}
|
||||
}else{
|
||||
*pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
|
||||
}
|
||||
|
||||
*ppVtab = (sqlite3_vtab*)pTab;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Pragma virtual table module xDisconnect method.
|
||||
*/
|
||||
static int pragmaVtabDisconnect(sqlite3_vtab *pVtab){
|
||||
PragmaVtab *pTab = (PragmaVtab*)pVtab;
|
||||
sqlite3_free(pTab);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/* Figure out the best index to use to search a pragma virtual table.
|
||||
**
|
||||
** There are not really any index choices. But we want to encourage the
|
||||
** query planner to give == constraints on as many hidden parameters as
|
||||
** possible, and especially on the first hidden parameter. So return a
|
||||
** high cost if hidden parameters are unconstrained.
|
||||
*/
|
||||
static int pragmaVtabBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
||||
PragmaVtab *pTab = (PragmaVtab*)tab;
|
||||
const struct sqlite3_index_constraint *pConstraint;
|
||||
int i, j;
|
||||
int seen[2];
|
||||
|
||||
pIdxInfo->estimatedCost = (double)1;
|
||||
if( pTab->nHidden==0 ){ return SQLITE_OK; }
|
||||
pConstraint = pIdxInfo->aConstraint;
|
||||
seen[0] = 0;
|
||||
seen[1] = 0;
|
||||
for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
|
||||
if( pConstraint->usable==0 ) continue;
|
||||
if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
|
||||
if( pConstraint->iColumn < pTab->iHidden ) continue;
|
||||
j = pConstraint->iColumn - pTab->iHidden;
|
||||
assert( j < 2 );
|
||||
seen[j] = i+1;
|
||||
}
|
||||
if( seen[0]==0 ){
|
||||
pIdxInfo->estimatedCost = (double)2147483647;
|
||||
pIdxInfo->estimatedRows = 2147483647;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
j = seen[0]-1;
|
||||
pIdxInfo->aConstraintUsage[j].argvIndex = 1;
|
||||
pIdxInfo->aConstraintUsage[j].omit = 1;
|
||||
if( seen[1]==0 ) return SQLITE_OK;
|
||||
pIdxInfo->estimatedCost = (double)20;
|
||||
pIdxInfo->estimatedRows = 20;
|
||||
j = seen[1]-1;
|
||||
pIdxInfo->aConstraintUsage[j].argvIndex = 2;
|
||||
pIdxInfo->aConstraintUsage[j].omit = 1;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/* Create a new cursor for the pragma virtual table */
|
||||
static int pragmaVtabOpen(sqlite3_vtab *pVtab, sqlite3_vtab_cursor **ppCursor){
|
||||
PragmaVtabCursor *pCsr;
|
||||
pCsr = (PragmaVtabCursor*)sqlite3_malloc(sizeof(*pCsr));
|
||||
if( pCsr==0 ) return SQLITE_NOMEM;
|
||||
memset(pCsr, 0, sizeof(PragmaVtabCursor));
|
||||
pCsr->base.pVtab = pVtab;
|
||||
*ppCursor = &pCsr->base;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/* Clear all content from pragma virtual table cursor. */
|
||||
static void pragmaVtabCursorClear(PragmaVtabCursor *pCsr){
|
||||
int i;
|
||||
sqlite3_finalize(pCsr->pPragma);
|
||||
pCsr->pPragma = 0;
|
||||
for(i=0; i<ArraySize(pCsr->azArg); i++){
|
||||
sqlite3_free(pCsr->azArg[i]);
|
||||
pCsr->azArg[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Close a pragma virtual table cursor */
|
||||
static int pragmaVtabClose(sqlite3_vtab_cursor *cur){
|
||||
PragmaVtabCursor *pCsr = (PragmaVtabCursor*)cur;
|
||||
pragmaVtabCursorClear(pCsr);
|
||||
sqlite3_free(pCsr);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/* Advance the pragma virtual table cursor to the next row */
|
||||
static int pragmaVtabNext(sqlite3_vtab_cursor *pVtabCursor){
|
||||
PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
/* Increment the xRowid value */
|
||||
pCsr->iRowid++;
|
||||
assert( pCsr->pPragma );
|
||||
if( SQLITE_ROW!=sqlite3_step(pCsr->pPragma) ){
|
||||
rc = sqlite3_finalize(pCsr->pPragma);
|
||||
pCsr->pPragma = 0;
|
||||
pragmaVtabCursorClear(pCsr);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Pragma virtual table module xFilter method.
|
||||
*/
|
||||
static int pragmaVtabFilter(
|
||||
sqlite3_vtab_cursor *pVtabCursor,
|
||||
int idxNum, const char *idxStr,
|
||||
int argc, sqlite3_value **argv
|
||||
){
|
||||
PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
|
||||
PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab);
|
||||
int rc;
|
||||
int i, j;
|
||||
StrAccum acc;
|
||||
char *zSql;
|
||||
|
||||
pragmaVtabCursorClear(pCsr);
|
||||
j = (pTab->pName->mPragFlg & PragFlg_Result1)!=0 ? 0 : 1;
|
||||
for(i=0; i<argc; i++, j++){
|
||||
assert( j<ArraySize(pCsr->azArg) );
|
||||
pCsr->azArg[j] = sqlite3_mprintf("%s", sqlite3_value_text(argv[i]));
|
||||
if( pCsr->azArg[j]==0 ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
}
|
||||
sqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_LIMIT_SQL_LENGTH]);
|
||||
sqlite3StrAccumAppendAll(&acc, "PRAGMA ");
|
||||
if( pCsr->azArg[1] ){
|
||||
sqlite3XPrintf(&acc, "%Q.", pCsr->azArg[1]);
|
||||
}
|
||||
sqlite3StrAccumAppendAll(&acc, pTab->pName->zName);
|
||||
if( pCsr->azArg[0] ){
|
||||
sqlite3XPrintf(&acc, "=%Q", pCsr->azArg[0]);
|
||||
}
|
||||
zSql = sqlite3StrAccumFinish(&acc);
|
||||
if( zSql==0 ) return SQLITE_NOMEM;
|
||||
rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pPragma, 0);
|
||||
sqlite3_free(zSql);
|
||||
if( rc!=SQLITE_OK ){
|
||||
pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db));
|
||||
return rc;
|
||||
}
|
||||
return pragmaVtabNext(pVtabCursor);
|
||||
}
|
||||
|
||||
/*
|
||||
** Pragma virtual table module xEof method.
|
||||
*/
|
||||
static int pragmaVtabEof(sqlite3_vtab_cursor *pVtabCursor){
|
||||
PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
|
||||
return (pCsr->pPragma==0);
|
||||
}
|
||||
|
||||
/* The xColumn method simply returns the corresponding column from
|
||||
** the PRAGMA.
|
||||
*/
|
||||
static int pragmaVtabColumn(
|
||||
sqlite3_vtab_cursor *pVtabCursor,
|
||||
sqlite3_context *ctx,
|
||||
int i
|
||||
){
|
||||
PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
|
||||
PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab);
|
||||
if( i<pTab->iHidden ){
|
||||
sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pPragma, i));
|
||||
}else{
|
||||
sqlite3_result_text(ctx, pCsr->azArg[i-pTab->iHidden],-1,SQLITE_TRANSIENT);
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Pragma virtual table module xRowid method.
|
||||
*/
|
||||
static int pragmaVtabRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *p){
|
||||
PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
|
||||
*p = pCsr->iRowid;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/* The pragma virtual table object */
|
||||
static const sqlite3_module pragmaVtabModule = {
|
||||
0, /* iVersion */
|
||||
0, /* xCreate - create a table */
|
||||
pragmaVtabConnect, /* xConnect - connect to an existing table */
|
||||
pragmaVtabBestIndex, /* xBestIndex - Determine search strategy */
|
||||
pragmaVtabDisconnect, /* xDisconnect - Disconnect from a table */
|
||||
0, /* xDestroy - Drop a table */
|
||||
pragmaVtabOpen, /* xOpen - open a cursor */
|
||||
pragmaVtabClose, /* xClose - close a cursor */
|
||||
pragmaVtabFilter, /* xFilter - configure scan constraints */
|
||||
pragmaVtabNext, /* xNext - advance a cursor */
|
||||
pragmaVtabEof, /* xEof */
|
||||
pragmaVtabColumn, /* xColumn - read data */
|
||||
pragmaVtabRowid, /* xRowid - read data */
|
||||
0, /* xUpdate - write data */
|
||||
0, /* xBegin - begin transaction */
|
||||
0, /* xSync - sync transaction */
|
||||
0, /* xCommit - commit transaction */
|
||||
0, /* xRollback - rollback transaction */
|
||||
0, /* xFindFunction - function overloading */
|
||||
0, /* xRename - rename the table */
|
||||
0, /* xSavepoint */
|
||||
0, /* xRelease */
|
||||
0 /* xRollbackTo */
|
||||
};
|
||||
|
||||
/*
|
||||
** Check to see if zTabName is really the name of a pragma. If it is,
|
||||
** then register an eponymous virtual table for that pragma and return
|
||||
** a pointer to the Module object for the new virtual table.
|
||||
*/
|
||||
Module *sqlite3PragmaVtabRegister(sqlite3 *db, const char *zName){
|
||||
const PragmaName *pName;
|
||||
assert( sqlite3_strnicmp(zName, "pragma_", 7)==0 );
|
||||
pName = pragmaLocate(zName+7);
|
||||
if( pName==0 ) return 0;
|
||||
if( (pName->mPragFlg & (PragFlg_Result0|PragFlg_Result1))==0 ) return 0;
|
||||
assert( sqlite3HashFind(&db->aModule, zName)==0 );
|
||||
return sqlite3VtabCreateModule(db, zName, &pragmaVtabModule, (void*)pName, 0);
|
||||
}
|
||||
|
||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||
|
||||
#endif /* SQLITE_OMIT_PRAGMA */
|
||||
|
||||
+495
-341
@@ -3,462 +3,616 @@
|
||||
** ../tool/mkpragmatab.tcl. To update the set of pragmas, edit
|
||||
** that script and rerun it.
|
||||
*/
|
||||
|
||||
/* The various pragma types */
|
||||
#define PragTyp_HEADER_VALUE 0
|
||||
#define PragTyp_AUTO_VACUUM 1
|
||||
#define PragTyp_FLAG 2
|
||||
#define PragTyp_BUSY_TIMEOUT 3
|
||||
#define PragTyp_CACHE_SIZE 4
|
||||
#define PragTyp_CACHE_SPILL 5
|
||||
#define PragTyp_CASE_SENSITIVE_LIKE 6
|
||||
#define PragTyp_COLLATION_LIST 7
|
||||
#define PragTyp_COMPILE_OPTIONS 8
|
||||
#define PragTyp_DATA_STORE_DIRECTORY 9
|
||||
#define PragTyp_DATABASE_LIST 10
|
||||
#define PragTyp_DEFAULT_CACHE_SIZE 11
|
||||
#define PragTyp_ENCODING 12
|
||||
#define PragTyp_FOREIGN_KEY_CHECK 13
|
||||
#define PragTyp_FOREIGN_KEY_LIST 14
|
||||
#define PragTyp_INCREMENTAL_VACUUM 15
|
||||
#define PragTyp_INDEX_INFO 16
|
||||
#define PragTyp_INDEX_LIST 17
|
||||
#define PragTyp_INTEGRITY_CHECK 18
|
||||
#define PragTyp_JOURNAL_MODE 19
|
||||
#define PragTyp_JOURNAL_SIZE_LIMIT 20
|
||||
#define PragTyp_LOCK_PROXY_FILE 21
|
||||
#define PragTyp_LOCKING_MODE 22
|
||||
#define PragTyp_PAGE_COUNT 23
|
||||
#define PragTyp_MMAP_SIZE 24
|
||||
#define PragTyp_PAGE_SIZE 25
|
||||
#define PragTyp_SECURE_DELETE 26
|
||||
#define PragTyp_SHRINK_MEMORY 27
|
||||
#define PragTyp_SOFT_HEAP_LIMIT 28
|
||||
#define PragTyp_STATS 29
|
||||
#define PragTyp_SYNCHRONOUS 30
|
||||
#define PragTyp_TABLE_INFO 31
|
||||
#define PragTyp_TEMP_STORE 32
|
||||
#define PragTyp_TEMP_STORE_DIRECTORY 33
|
||||
#define PragTyp_THREADS 34
|
||||
#define PragTyp_WAL_AUTOCHECKPOINT 35
|
||||
#define PragTyp_WAL_CHECKPOINT 36
|
||||
#define PragTyp_ACTIVATE_EXTENSIONS 37
|
||||
#define PragTyp_HEXKEY 38
|
||||
#define PragTyp_KEY 39
|
||||
#define PragTyp_REKEY 40
|
||||
#define PragTyp_LOCK_STATUS 41
|
||||
#define PragTyp_PARSER_TRACE 42
|
||||
#define PragFlag_NeedSchema 0x01
|
||||
#define PragFlag_ReadOnly 0x02
|
||||
static const struct sPragmaNames {
|
||||
const char *const zName; /* Name of pragma */
|
||||
u8 ePragTyp; /* PragTyp_XXX value */
|
||||
u8 mPragFlag; /* Zero or more PragFlag_XXX values */
|
||||
u32 iArg; /* Extra argument */
|
||||
} aPragmaNames[] = {
|
||||
#define PragTyp_BTREE_SAMPLE 3
|
||||
#define PragTyp_BUSY_TIMEOUT 4
|
||||
#define PragTyp_CACHE_SIZE 5
|
||||
#define PragTyp_CACHE_SPILL 6
|
||||
#define PragTyp_CASE_SENSITIVE_LIKE 7
|
||||
#define PragTyp_COLLATION_LIST 8
|
||||
#define PragTyp_COMPILE_OPTIONS 9
|
||||
#define PragTyp_DATA_STORE_DIRECTORY 10
|
||||
#define PragTyp_DATABASE_LIST 11
|
||||
#define PragTyp_DEFAULT_CACHE_SIZE 12
|
||||
#define PragTyp_ENCODING 13
|
||||
#define PragTyp_EST_COUNT 14
|
||||
#define PragTyp_FOREIGN_KEY_CHECK 15
|
||||
#define PragTyp_FOREIGN_KEY_LIST 16
|
||||
#define PragTyp_INCREMENTAL_VACUUM 17
|
||||
#define PragTyp_INDEX_INFO 18
|
||||
#define PragTyp_INDEX_LIST 19
|
||||
#define PragTyp_INTEGRITY_CHECK 20
|
||||
#define PragTyp_JOURNAL_MODE 21
|
||||
#define PragTyp_JOURNAL_SIZE_LIMIT 22
|
||||
#define PragTyp_LOCK_PROXY_FILE 23
|
||||
#define PragTyp_LOCKING_MODE 24
|
||||
#define PragTyp_PAGE_COUNT 25
|
||||
#define PragTyp_MMAP_SIZE 26
|
||||
#define PragTyp_PAGE_SIZE 27
|
||||
#define PragTyp_SECURE_DELETE 28
|
||||
#define PragTyp_SHRINK_MEMORY 29
|
||||
#define PragTyp_SOFT_HEAP_LIMIT 30
|
||||
#define PragTyp_STATS 31
|
||||
#define PragTyp_SYNCHRONOUS 32
|
||||
#define PragTyp_TABLE_INFO 33
|
||||
#define PragTyp_TEMP_STORE 34
|
||||
#define PragTyp_TEMP_STORE_DIRECTORY 35
|
||||
#define PragTyp_THREADS 36
|
||||
#define PragTyp_WAL_AUTOCHECKPOINT 37
|
||||
#define PragTyp_WAL_CHECKPOINT 38
|
||||
#define PragTyp_ACTIVATE_EXTENSIONS 39
|
||||
#define PragTyp_HEXKEY 40
|
||||
#define PragTyp_KEY 41
|
||||
#define PragTyp_REKEY 42
|
||||
#define PragTyp_LOCK_STATUS 43
|
||||
#define PragTyp_PARSER_TRACE 44
|
||||
|
||||
/* Property flags associated with various pragma. */
|
||||
#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
|
||||
#define PragFlg_NoColumns 0x02 /* OP_ResultRow called with zero columns */
|
||||
#define PragFlg_ReadOnly 0x04 /* Read-only HEADER_VALUE */
|
||||
#define PragFlg_Result0 0x08 /* Acts as query when no argument */
|
||||
#define PragFlg_Result1 0x10 /* Acts as query when has one argument */
|
||||
#define PragFlg_SchemaOpt 0x20 /* Schema restricts name search if present */
|
||||
#define PragFlg_SchemaReq 0x40 /* Schema required - "main" is default */
|
||||
|
||||
/* Names of columns for pragmas that return multi-column result
|
||||
** or that return single-column results where the name of the
|
||||
** result column is different from the name of the pragma
|
||||
*/
|
||||
static const char *const pragCName[] = {
|
||||
/* 0 */ "cache_size", /* Used by: default_cache_size */
|
||||
/* 1 */ "cid", /* Used by: table_info */
|
||||
/* 2 */ "name",
|
||||
/* 3 */ "type",
|
||||
/* 4 */ "notnull",
|
||||
/* 5 */ "dflt_value",
|
||||
/* 6 */ "pk",
|
||||
/* 7 */ "table", /* Used by: stats */
|
||||
/* 8 */ "index",
|
||||
/* 9 */ "width",
|
||||
/* 10 */ "height",
|
||||
/* 11 */ "seqno", /* Used by: index_info */
|
||||
/* 12 */ "cid",
|
||||
/* 13 */ "name",
|
||||
/* 14 */ "seqno", /* Used by: index_xinfo */
|
||||
/* 15 */ "cid",
|
||||
/* 16 */ "name",
|
||||
/* 17 */ "desc",
|
||||
/* 18 */ "coll",
|
||||
/* 19 */ "key",
|
||||
/* 20 */ "seq", /* Used by: index_list */
|
||||
/* 21 */ "name",
|
||||
/* 22 */ "unique",
|
||||
/* 23 */ "origin",
|
||||
/* 24 */ "partial",
|
||||
/* 25 */ "seq", /* Used by: database_list */
|
||||
/* 26 */ "name",
|
||||
/* 27 */ "file",
|
||||
/* 28 */ "seq", /* Used by: collation_list */
|
||||
/* 29 */ "name",
|
||||
/* 30 */ "id", /* Used by: foreign_key_list */
|
||||
/* 31 */ "seq",
|
||||
/* 32 */ "table",
|
||||
/* 33 */ "from",
|
||||
/* 34 */ "to",
|
||||
/* 35 */ "on_update",
|
||||
/* 36 */ "on_delete",
|
||||
/* 37 */ "match",
|
||||
/* 38 */ "table", /* Used by: foreign_key_check */
|
||||
/* 39 */ "rowid",
|
||||
/* 40 */ "parent",
|
||||
/* 41 */ "fkid",
|
||||
/* 42 */ "busy", /* Used by: wal_checkpoint */
|
||||
/* 43 */ "log",
|
||||
/* 44 */ "checkpointed",
|
||||
/* 45 */ "timeout", /* Used by: busy_timeout */
|
||||
/* 46 */ "database", /* Used by: lock_status */
|
||||
/* 47 */ "status",
|
||||
};
|
||||
|
||||
/* Definitions of all built-in pragmas */
|
||||
typedef struct PragmaName {
|
||||
const char *const zName; /* Name of pragma */
|
||||
u8 ePragTyp; /* PragTyp_XXX value */
|
||||
u8 mPragFlg; /* Zero or more PragFlg_XXX values */
|
||||
u8 iPragCName; /* Start of column names in pragCName[] */
|
||||
u8 nPragCName; /* Num of col names. 0 means use pragma name */
|
||||
u32 iArg; /* Extra argument */
|
||||
} PragmaName;
|
||||
static const PragmaName aPragmaName[] = {
|
||||
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
|
||||
{ /* zName: */ "activate_extensions",
|
||||
/* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "activate_extensions",
|
||||
/* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS,
|
||||
/* ePragFlg: */ 0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "application_id",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ BTREE_APPLICATION_ID },
|
||||
{/* zName: */ "application_id",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ BTREE_APPLICATION_ID },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_AUTOVACUUM)
|
||||
{ /* zName: */ "auto_vacuum",
|
||||
/* ePragTyp: */ PragTyp_AUTO_VACUUM,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "auto_vacuum",
|
||||
/* ePragTyp: */ PragTyp_AUTO_VACUUM,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_AUTOMATIC_INDEX)
|
||||
{ /* zName: */ "automatic_index",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_AutoIndex },
|
||||
{/* zName: */ "automatic_index",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_AutoIndex },
|
||||
#endif
|
||||
#endif
|
||||
{ /* zName: */ "busy_timeout",
|
||||
/* ePragTyp: */ PragTyp_BUSY_TIMEOUT,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "btree_sample",
|
||||
/* ePragTyp: */ PragTyp_BTREE_SAMPLE,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "busy_timeout",
|
||||
/* ePragTyp: */ PragTyp_BUSY_TIMEOUT,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
/* ColNames: */ 45, 1,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "cache_size",
|
||||
/* ePragTyp: */ PragTyp_CACHE_SIZE,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "cache_size",
|
||||
/* ePragTyp: */ PragTyp_CACHE_SIZE,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "cache_spill",
|
||||
/* ePragTyp: */ PragTyp_CACHE_SPILL,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "cache_spill",
|
||||
/* ePragTyp: */ PragTyp_CACHE_SPILL,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
{ /* zName: */ "case_sensitive_like",
|
||||
/* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "cell_size_check",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_CellSizeCk },
|
||||
{/* zName: */ "case_sensitive_like",
|
||||
/* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE,
|
||||
/* ePragFlg: */ 0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "cell_size_check",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_CellSizeCk },
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "checkpoint_fullfsync",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_CkptFullFSync },
|
||||
{/* zName: */ "checkpoint_fullfsync",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_CkptFullFSync },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "collation_list",
|
||||
/* ePragTyp: */ PragTyp_COLLATION_LIST,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "collation_list",
|
||||
/* ePragTyp: */ PragTyp_COLLATION_LIST,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
/* ColNames: */ 28, 2,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
|
||||
{ /* zName: */ "compile_options",
|
||||
/* ePragTyp: */ PragTyp_COMPILE_OPTIONS,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "compile_options",
|
||||
/* ePragTyp: */ PragTyp_COMPILE_OPTIONS,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "count_changes",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_CountRows },
|
||||
{/* zName: */ "count_changes",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_CountRows },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN
|
||||
{ /* zName: */ "data_store_directory",
|
||||
/* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "data_store_directory",
|
||||
/* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY,
|
||||
/* ePragFlg: */ 0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "data_version",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ PragFlag_ReadOnly,
|
||||
/* iArg: */ BTREE_DATA_VERSION },
|
||||
{/* zName: */ "data_version",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_ReadOnly,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ BTREE_DATA_VERSION },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "database_list",
|
||||
/* ePragTyp: */ PragTyp_DATABASE_LIST,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "database_list",
|
||||
/* ePragTyp: */ PragTyp_DATABASE_LIST,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
|
||||
/* ColNames: */ 25, 3,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
|
||||
{ /* zName: */ "default_cache_size",
|
||||
/* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "default_cache_size",
|
||||
/* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
|
||||
/* ColNames: */ 0, 1,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
|
||||
{ /* zName: */ "defer_foreign_keys",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_DeferFKs },
|
||||
{/* zName: */ "defer_foreign_keys",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_DeferFKs },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "empty_result_callbacks",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_NullCallback },
|
||||
{/* zName: */ "empty_result_callbacks",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_NullCallback },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_UTF16)
|
||||
{ /* zName: */ "encoding",
|
||||
/* ePragTyp: */ PragTyp_ENCODING,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "encoding",
|
||||
/* ePragTyp: */ PragTyp_ENCODING,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
{/* zName: */ "est_count",
|
||||
/* ePragTyp: */ PragTyp_EST_COUNT,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
|
||||
{ /* zName: */ "foreign_key_check",
|
||||
/* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "foreign_key_check",
|
||||
/* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema,
|
||||
/* ColNames: */ 38, 4,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY)
|
||||
{ /* zName: */ "foreign_key_list",
|
||||
/* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "foreign_key_list",
|
||||
/* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
|
||||
/* ColNames: */ 30, 8,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
|
||||
{ /* zName: */ "foreign_keys",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_ForeignKeys },
|
||||
{/* zName: */ "foreign_keys",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_ForeignKeys },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "freelist_count",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ PragFlag_ReadOnly,
|
||||
/* iArg: */ BTREE_FREE_PAGE_COUNT },
|
||||
{/* zName: */ "freelist_count",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_ReadOnly,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ BTREE_FREE_PAGE_COUNT },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "full_column_names",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_FullColNames },
|
||||
{ /* zName: */ "fullfsync",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_FullFSync },
|
||||
{/* zName: */ "full_column_names",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_FullColNames },
|
||||
{/* zName: */ "fullfsync",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_FullFSync },
|
||||
#endif
|
||||
#if defined(SQLITE_HAS_CODEC)
|
||||
{ /* zName: */ "hexkey",
|
||||
/* ePragTyp: */ PragTyp_HEXKEY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "hexrekey",
|
||||
/* ePragTyp: */ PragTyp_HEXKEY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "hexkey",
|
||||
/* ePragTyp: */ PragTyp_HEXKEY,
|
||||
/* ePragFlg: */ 0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "hexrekey",
|
||||
/* ePragTyp: */ PragTyp_HEXKEY,
|
||||
/* ePragFlg: */ 0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_CHECK)
|
||||
{ /* zName: */ "ignore_check_constraints",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_IgnoreChecks },
|
||||
{/* zName: */ "ignore_check_constraints",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_IgnoreChecks },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_AUTOVACUUM)
|
||||
{ /* zName: */ "incremental_vacuum",
|
||||
/* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "incremental_vacuum",
|
||||
/* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_NoColumns,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "index_info",
|
||||
/* ePragTyp: */ PragTyp_INDEX_INFO,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "index_list",
|
||||
/* ePragTyp: */ PragTyp_INDEX_LIST,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "index_xinfo",
|
||||
/* ePragTyp: */ PragTyp_INDEX_INFO,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 1 },
|
||||
{/* zName: */ "index_info",
|
||||
/* ePragTyp: */ PragTyp_INDEX_INFO,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
|
||||
/* ColNames: */ 11, 3,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "index_list",
|
||||
/* ePragTyp: */ PragTyp_INDEX_LIST,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
|
||||
/* ColNames: */ 20, 5,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "index_xinfo",
|
||||
/* ePragTyp: */ PragTyp_INDEX_INFO,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
|
||||
/* ColNames: */ 14, 6,
|
||||
/* iArg: */ 1 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
|
||||
{ /* zName: */ "integrity_check",
|
||||
/* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "integrity_check",
|
||||
/* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "journal_mode",
|
||||
/* ePragTyp: */ PragTyp_JOURNAL_MODE,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "journal_size_limit",
|
||||
/* ePragTyp: */ PragTyp_JOURNAL_SIZE_LIMIT,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "journal_mode",
|
||||
/* ePragTyp: */ PragTyp_JOURNAL_MODE,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "journal_size_limit",
|
||||
/* ePragTyp: */ PragTyp_JOURNAL_SIZE_LIMIT,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if defined(SQLITE_HAS_CODEC)
|
||||
{ /* zName: */ "key",
|
||||
/* ePragTyp: */ PragTyp_KEY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "key",
|
||||
/* ePragTyp: */ PragTyp_KEY,
|
||||
/* ePragFlg: */ 0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "legacy_file_format",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_LegacyFileFmt },
|
||||
{/* zName: */ "legacy_file_format",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_LegacyFileFmt },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE
|
||||
{ /* zName: */ "lock_proxy_file",
|
||||
/* ePragTyp: */ PragTyp_LOCK_PROXY_FILE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "lock_proxy_file",
|
||||
/* ePragTyp: */ PragTyp_LOCK_PROXY_FILE,
|
||||
/* ePragFlg: */ 0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
||||
{ /* zName: */ "lock_status",
|
||||
/* ePragTyp: */ PragTyp_LOCK_STATUS,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "lock_status",
|
||||
/* ePragTyp: */ PragTyp_LOCK_STATUS,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
/* ColNames: */ 46, 2,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "locking_mode",
|
||||
/* ePragTyp: */ PragTyp_LOCKING_MODE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "max_page_count",
|
||||
/* ePragTyp: */ PragTyp_PAGE_COUNT,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "mmap_size",
|
||||
/* ePragTyp: */ PragTyp_MMAP_SIZE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "page_count",
|
||||
/* ePragTyp: */ PragTyp_PAGE_COUNT,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "page_size",
|
||||
/* ePragTyp: */ PragTyp_PAGE_SIZE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "locking_mode",
|
||||
/* ePragTyp: */ PragTyp_LOCKING_MODE,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "max_page_count",
|
||||
/* ePragTyp: */ PragTyp_PAGE_COUNT,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "mmap_size",
|
||||
/* ePragTyp: */ PragTyp_MMAP_SIZE,
|
||||
/* ePragFlg: */ 0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "page_count",
|
||||
/* ePragTyp: */ PragTyp_PAGE_COUNT,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "page_size",
|
||||
/* ePragTyp: */ PragTyp_PAGE_SIZE,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_PARSER_TRACE)
|
||||
{ /* zName: */ "parser_trace",
|
||||
/* ePragTyp: */ PragTyp_PARSER_TRACE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "parser_trace",
|
||||
/* ePragTyp: */ PragTyp_PARSER_TRACE,
|
||||
/* ePragFlg: */ 0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "query_only",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_QueryOnly },
|
||||
{/* zName: */ "query_only",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_QueryOnly },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
|
||||
{ /* zName: */ "quick_check",
|
||||
/* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "quick_check",
|
||||
/* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "read_uncommitted",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_ReadUncommitted },
|
||||
{ /* zName: */ "recursive_triggers",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_RecTriggers },
|
||||
{/* zName: */ "read_uncommitted",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_ReadUncommitted },
|
||||
{/* zName: */ "recursive_triggers",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_RecTriggers },
|
||||
#endif
|
||||
#if defined(SQLITE_HAS_CODEC)
|
||||
{ /* zName: */ "rekey",
|
||||
/* ePragTyp: */ PragTyp_REKEY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "rekey",
|
||||
/* ePragTyp: */ PragTyp_REKEY,
|
||||
/* ePragFlg: */ 0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "reverse_unordered_selects",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_ReverseOrder },
|
||||
{/* zName: */ "reverse_unordered_selects",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_ReverseOrder },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "schema_version",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ BTREE_SCHEMA_VERSION },
|
||||
{/* zName: */ "schema_version",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ BTREE_SCHEMA_VERSION },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "secure_delete",
|
||||
/* ePragTyp: */ PragTyp_SECURE_DELETE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "secure_delete",
|
||||
/* ePragTyp: */ PragTyp_SECURE_DELETE,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "short_column_names",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_ShortColNames },
|
||||
{/* zName: */ "short_column_names",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_ShortColNames },
|
||||
#endif
|
||||
{ /* zName: */ "shrink_memory",
|
||||
/* ePragTyp: */ PragTyp_SHRINK_MEMORY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "soft_heap_limit",
|
||||
/* ePragTyp: */ PragTyp_SOFT_HEAP_LIMIT,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "shrink_memory",
|
||||
/* ePragTyp: */ PragTyp_SHRINK_MEMORY,
|
||||
/* ePragFlg: */ 0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "soft_heap_limit",
|
||||
/* ePragTyp: */ PragTyp_SOFT_HEAP_LIMIT,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if defined(SQLITE_DEBUG)
|
||||
{ /* zName: */ "sql_trace",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_SqlTrace },
|
||||
{/* zName: */ "sql_trace",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_SqlTrace },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "stats",
|
||||
/* ePragTyp: */ PragTyp_STATS,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "stats",
|
||||
/* ePragTyp: */ PragTyp_STATS,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
|
||||
/* ColNames: */ 7, 4,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "synchronous",
|
||||
/* ePragTyp: */ PragTyp_SYNCHRONOUS,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "synchronous",
|
||||
/* ePragTyp: */ PragTyp_SYNCHRONOUS,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{ /* zName: */ "table_info",
|
||||
/* ePragTyp: */ PragTyp_TABLE_INFO,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "table_info",
|
||||
/* ePragTyp: */ PragTyp_TABLE_INFO,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
|
||||
/* ColNames: */ 1, 6,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{ /* zName: */ "temp_store",
|
||||
/* ePragTyp: */ PragTyp_TEMP_STORE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "temp_store_directory",
|
||||
/* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "temp_store",
|
||||
/* ePragTyp: */ PragTyp_TEMP_STORE,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "temp_store_directory",
|
||||
/* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY,
|
||||
/* ePragFlg: */ 0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
{ /* zName: */ "threads",
|
||||
/* ePragTyp: */ PragTyp_THREADS,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "threads",
|
||||
/* ePragTyp: */ PragTyp_THREADS,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{ /* zName: */ "user_version",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ BTREE_USER_VERSION },
|
||||
{/* zName: */ "user_version",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ BTREE_USER_VERSION },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if defined(SQLITE_DEBUG)
|
||||
{ /* zName: */ "vdbe_addoptrace",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_VdbeAddopTrace },
|
||||
{ /* zName: */ "vdbe_debug",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace },
|
||||
{ /* zName: */ "vdbe_eqp",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_VdbeEQP },
|
||||
{ /* zName: */ "vdbe_listing",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_VdbeListing },
|
||||
{ /* zName: */ "vdbe_trace",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_VdbeTrace },
|
||||
{/* zName: */ "vdbe_addoptrace",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_VdbeAddopTrace },
|
||||
{/* zName: */ "vdbe_debug",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace },
|
||||
{/* zName: */ "vdbe_eqp",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_VdbeEQP },
|
||||
{/* zName: */ "vdbe_listing",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_VdbeListing },
|
||||
{/* zName: */ "vdbe_trace",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_VdbeTrace },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_WAL)
|
||||
{ /* zName: */ "wal_autocheckpoint",
|
||||
/* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ 0 },
|
||||
{ /* zName: */ "wal_checkpoint",
|
||||
/* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
|
||||
/* ePragFlag: */ PragFlag_NeedSchema,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "wal_autocheckpoint",
|
||||
/* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT,
|
||||
/* ePragFlg: */ 0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "wal_checkpoint",
|
||||
/* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema,
|
||||
/* ColNames: */ 42, 3,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
{ /* zName: */ "writable_schema",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlag: */ 0,
|
||||
/* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
|
||||
{/* zName: */ "writable_schema",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
|
||||
#endif
|
||||
};
|
||||
/* Number of pragmas: 60 on by default, 73 total. */
|
||||
/* Number of pragmas: 62 on by default, 75 total. */
|
||||
|
||||
+12
-2
@@ -3562,7 +3562,10 @@ void sqlite3ExprListDelete(sqlite3*, ExprList*);
|
||||
u32 sqlite3ExprListFlags(const ExprList*);
|
||||
int sqlite3Init(sqlite3*, char**);
|
||||
int sqlite3InitCallback(void*, int, char**, char**);
|
||||
void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
|
||||
void sqlite3Pragma(Parse*,Token*,Token*,IdList*);
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
Module *sqlite3PragmaVtabRegister(sqlite3*,const char *zName);
|
||||
#endif
|
||||
void sqlite3ResetAllSchemasOfConnection(sqlite3*);
|
||||
void sqlite3ResetOneSchema(sqlite3*,int);
|
||||
void sqlite3CollapseDatabaseArray(sqlite3*);
|
||||
@@ -3637,7 +3640,7 @@ void sqlite3DeleteTable(sqlite3*, Table*);
|
||||
#endif
|
||||
void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int);
|
||||
void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*);
|
||||
IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*);
|
||||
IdList *sqlite3IdListAppend(Parse*, IdList*, char*);
|
||||
int sqlite3IdListIndex(IdList*,const char*);
|
||||
SrcList *sqlite3SrcListEnlarge(sqlite3*, SrcList*, int, int);
|
||||
SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*);
|
||||
@@ -4077,6 +4080,13 @@ void sqlite3AutoLoadExtensions(sqlite3*);
|
||||
int sqlite3VtabSavepoint(sqlite3 *, int, int);
|
||||
void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*);
|
||||
VTable *sqlite3GetVTable(sqlite3*, Table*);
|
||||
Module *sqlite3VtabCreateModule(
|
||||
sqlite3*,
|
||||
const char*,
|
||||
const sqlite3_module*,
|
||||
void*,
|
||||
void(*)(void*)
|
||||
);
|
||||
# define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
|
||||
#endif
|
||||
int sqlite3VtabEponymousTableInit(Parse*,Module*);
|
||||
|
||||
+28
@@ -4887,6 +4887,34 @@ case OP_Rewind: { /* jump */
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** Opcode: EstRowCnt P1 P2 P3 * * *
|
||||
**
|
||||
** Estimate the number of entries in btree for cursor P1 do a proportional
|
||||
** seek to of P3. Store the result as a floating point value in P2.
|
||||
*/
|
||||
case OP_EstRowCnt: { /* out2 */
|
||||
VdbeCursor *pC;
|
||||
BtCursor *pCrsr;
|
||||
int rc;
|
||||
sqlite3_uint64 n = 0;
|
||||
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||
pC = p->apCsr[pOp->p1];
|
||||
assert( pC->eCurType==CURTYPE_BTREE );
|
||||
pCrsr = pC->uc.pCursor;
|
||||
assert( pCrsr );
|
||||
rc = sqlite3BtreeMovetoProportional(pCrsr, pOp->p3, &n);
|
||||
if( rc ) goto abort_due_to_error;
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
pOut->flags = MEM_Real;
|
||||
pOut->u.r = n;
|
||||
pC->nullRow = 0;
|
||||
pC->deferredMoveto = 0;
|
||||
pC->cacheStatus = CACHE_STALE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: Next P1 P2 P3 P4 P5
|
||||
**
|
||||
** Advance cursor P1 so that it points to the next key/data pair in its
|
||||
|
||||
+36
-21
@@ -28,6 +28,41 @@ struct VtabCtx {
|
||||
int bDeclared; /* True after sqlite3_declare_vtab() is called */
|
||||
};
|
||||
|
||||
/*
|
||||
** Construct and install a Module object for a virtual table. When this
|
||||
** routine is called, it is guaranteed that all appropriate locks are held
|
||||
** and the module is not already part of the connection.
|
||||
*/
|
||||
Module *sqlite3VtabCreateModule(
|
||||
sqlite3 *db, /* Database in which module is registered */
|
||||
const char *zName, /* Name assigned to this module */
|
||||
const sqlite3_module *pModule, /* The definition of the module */
|
||||
void *pAux, /* Context pointer for xCreate/xConnect */
|
||||
void (*xDestroy)(void *) /* Module destructor function */
|
||||
){
|
||||
Module *pMod;
|
||||
int nName = sqlite3Strlen30(zName);
|
||||
pMod = (Module *)sqlite3DbMallocRawNN(db, sizeof(Module) + nName + 1);
|
||||
if( pMod ){
|
||||
Module *pDel;
|
||||
char *zCopy = (char *)(&pMod[1]);
|
||||
memcpy(zCopy, zName, nName+1);
|
||||
pMod->zName = zCopy;
|
||||
pMod->pModule = pModule;
|
||||
pMod->pAux = pAux;
|
||||
pMod->xDestroy = xDestroy;
|
||||
pMod->pEpoTab = 0;
|
||||
pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod);
|
||||
assert( pDel==0 || pDel==pMod );
|
||||
if( pDel ){
|
||||
sqlite3OomFault(db);
|
||||
sqlite3DbFree(db, pDel);
|
||||
pMod = 0;
|
||||
}
|
||||
}
|
||||
return pMod;
|
||||
}
|
||||
|
||||
/*
|
||||
** The actual function that does the work of creating a new module.
|
||||
** This function implements the sqlite3_create_module() and
|
||||
@@ -41,35 +76,15 @@ static int createModule(
|
||||
void (*xDestroy)(void *) /* Module destructor function */
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
int nName;
|
||||
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
nName = sqlite3Strlen30(zName);
|
||||
if( sqlite3HashFind(&db->aModule, zName) ){
|
||||
rc = SQLITE_MISUSE_BKPT;
|
||||
}else{
|
||||
Module *pMod;
|
||||
pMod = (Module *)sqlite3DbMallocRawNN(db, sizeof(Module) + nName + 1);
|
||||
if( pMod ){
|
||||
Module *pDel;
|
||||
char *zCopy = (char *)(&pMod[1]);
|
||||
memcpy(zCopy, zName, nName+1);
|
||||
pMod->zName = zCopy;
|
||||
pMod->pModule = pModule;
|
||||
pMod->pAux = pAux;
|
||||
pMod->xDestroy = xDestroy;
|
||||
pMod->pEpoTab = 0;
|
||||
pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod);
|
||||
assert( pDel==0 || pDel==pMod );
|
||||
if( pDel ){
|
||||
sqlite3OomFault(db);
|
||||
sqlite3DbFree(db, pDel);
|
||||
}
|
||||
}
|
||||
(void)sqlite3VtabCreateModule(db, zName, pModule, pAux, xDestroy);
|
||||
}
|
||||
rc = sqlite3ApiExit(db, rc);
|
||||
if( rc!=SQLITE_OK && xDestroy ) xDestroy(pAux);
|
||||
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -328,5 +328,24 @@ do_catchsql_test 7.3 {
|
||||
) WITHOUT ROWID;
|
||||
} {1 {no such column: rowid}}
|
||||
|
||||
# The PRAGMA index_info and index_xinfo pragmas work on
|
||||
# WITHOUT ROWID tables too, but not on rowid tables.
|
||||
#
|
||||
do_execsql_test 8.1 {
|
||||
CREATE TABLE t80a(a TEXT, b INT, c BLOB, PRIMARY KEY(c,b));
|
||||
PRAGMA index_info(t80a);
|
||||
} {}
|
||||
do_execsql_test 8.2 {
|
||||
PRAGMA index_xinfo(t80a);
|
||||
} {}
|
||||
do_execsql_test 8.3 {
|
||||
CREATE TABLE t80b(a TEXT, b INT, c BLOB, PRIMARY KEY(c,b)) WITHOUT ROWID;
|
||||
PRAGMA index_info(t80b);
|
||||
} {0 2 c 1 1 b}
|
||||
do_execsql_test 8.4 {
|
||||
PRAGMA index_xinfo(t80b);
|
||||
} {0 2 c 0 BINARY 1 1 1 b 0 BINARY 1 2 0 a 0 BINARY 0}
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,354 @@
|
||||
/*
|
||||
** 2016-10-24
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
**
|
||||
** This is a utility program that uses the est_count and btree_sample
|
||||
** pragmas to try to approximate the content of the sqlite_stat1 table
|
||||
** without doing a full table scan.
|
||||
**
|
||||
** To compile, simply link against SQLite.
|
||||
**
|
||||
** See the showHelp() routine below for a brief description of how to
|
||||
** run the utility.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "sqlite3.h"
|
||||
|
||||
/*
|
||||
** All global variables are gathered into the "g" singleton.
|
||||
*/
|
||||
struct GlobalVars {
|
||||
const char *zArgv0; /* Name of program */
|
||||
unsigned fDebug; /* Debug flags */
|
||||
sqlite3 *db; /* The database connection */
|
||||
} g;
|
||||
|
||||
/*
|
||||
** Allowed values for g.fDebug
|
||||
*/
|
||||
#define DEBUG_NONE 0
|
||||
|
||||
|
||||
/*
|
||||
** Print an error resulting from faulting command-line arguments and
|
||||
** abort the program.
|
||||
*/
|
||||
static void cmdlineError(const char *zFormat, ...){
|
||||
va_list ap;
|
||||
fprintf(stderr, "%s: ", g.zArgv0);
|
||||
va_start(ap, zFormat);
|
||||
vfprintf(stderr, zFormat, ap);
|
||||
va_end(ap);
|
||||
fprintf(stderr, "\n\"%s --help\" for more help\n", g.zArgv0);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
** Print an error message for an error that occurs at runtime, then
|
||||
** abort the program.
|
||||
*/
|
||||
static void runtimeError(const char *zFormat, ...){
|
||||
va_list ap;
|
||||
fprintf(stderr, "%s: ", g.zArgv0);
|
||||
va_start(ap, zFormat);
|
||||
vfprintf(stderr, zFormat, ap);
|
||||
va_end(ap);
|
||||
fprintf(stderr, "\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the current time in milliseconds since the julian epoch.
|
||||
*/
|
||||
static sqlite3_int64 currentTime(void){
|
||||
sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
|
||||
sqlite3_int64 x = 0;
|
||||
(void)pVfs->xCurrentTimeInt64(pVfs, &x);
|
||||
return x;
|
||||
}
|
||||
|
||||
/*
|
||||
** Prepare a new SQL statement. Print an error and abort if anything
|
||||
** goes wrong.
|
||||
*/
|
||||
static sqlite3_stmt *db_vprepare(const char *zFormat, va_list ap){
|
||||
char *zSql;
|
||||
int rc;
|
||||
sqlite3_stmt *pStmt;
|
||||
|
||||
zSql = sqlite3_vmprintf(zFormat, ap);
|
||||
if( zSql==0 ) runtimeError("out of memory");
|
||||
rc = sqlite3_prepare_v2(g.db, zSql, -1, &pStmt, 0);
|
||||
if( rc ){
|
||||
runtimeError("SQL statement error: %s\n\"%s\"", sqlite3_errmsg(g.db),
|
||||
zSql);
|
||||
}
|
||||
sqlite3_free(zSql);
|
||||
return pStmt;
|
||||
}
|
||||
static sqlite3_stmt *db_prepare(const char *zFormat, ...){
|
||||
va_list ap;
|
||||
sqlite3_stmt *pStmt;
|
||||
va_start(ap, zFormat);
|
||||
pStmt = db_vprepare(zFormat, ap);
|
||||
va_end(ap);
|
||||
return pStmt;
|
||||
}
|
||||
|
||||
/*
|
||||
** Estimate the number of rows in the given table or index.
|
||||
*/
|
||||
static sqlite3_int64 estEntryCount(const char *zTabIdx){
|
||||
double sum = 0.0;
|
||||
int i;
|
||||
int n = 0;
|
||||
sqlite3_stmt *pStmt;
|
||||
# define N_CNT_SAMPLE 10
|
||||
for(i=0; i<=N_CNT_SAMPLE; i++){
|
||||
pStmt = db_prepare("PRAGMA est_count(\"%w\",%g)",
|
||||
zTabIdx, ((double)i)/(double)(N_CNT_SAMPLE));
|
||||
if( sqlite3_step(pStmt)==SQLITE_ROW ){
|
||||
sum += sqlite3_column_double(pStmt, 0);
|
||||
n++;
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
}
|
||||
return n==0 ? 0 : (sqlite3_int64)(sum/n);
|
||||
}
|
||||
|
||||
/*
|
||||
** Compare the i-th column of pStmt against pValue. Return true if they
|
||||
** are different.
|
||||
*/
|
||||
static int columnNotEqual(sqlite3_stmt *pStmt, int i, sqlite3_value *pValue){
|
||||
int n1, n2, n;
|
||||
if( sqlite3_column_type(pStmt,i)!=sqlite3_value_type(pValue) ) return 1;
|
||||
switch( sqlite3_column_type(pStmt,i) ){
|
||||
case SQLITE_NULL:
|
||||
return 0; /* Nulls compare equal to one another in this context */
|
||||
|
||||
case SQLITE_INTEGER:
|
||||
return sqlite3_column_int64(pStmt,i)!=sqlite3_value_int64(pValue);
|
||||
|
||||
case SQLITE_FLOAT:
|
||||
return sqlite3_column_double(pStmt,i)!=sqlite3_value_double(pValue);
|
||||
|
||||
case SQLITE_BLOB:
|
||||
n1 = sqlite3_column_bytes(pStmt,i);
|
||||
n2 = sqlite3_value_bytes(pValue);
|
||||
n = n1<n2 ? n1 : n2;
|
||||
if( memcmp(sqlite3_column_blob(pStmt,i), sqlite3_value_blob(pValue),n) ){
|
||||
return 1;
|
||||
}
|
||||
return n1!=n2;
|
||||
|
||||
case SQLITE_TEXT:
|
||||
n1 = sqlite3_column_bytes(pStmt,i);
|
||||
n2 = sqlite3_value_bytes(pValue);
|
||||
n = n1<n2 ? n1 : n2;
|
||||
if( memcmp(sqlite3_column_text(pStmt,i), sqlite3_value_text(pValue),n) ){
|
||||
return 1;
|
||||
}
|
||||
return n1!=n2;
|
||||
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** Stat1 for an index. Return non-zero if an entry was created.
|
||||
*/
|
||||
static int analyzeIndex(const char *zTab, const char *zIdx){
|
||||
sqlite3_int64 n = estEntryCount(zIdx);
|
||||
sqlite3_stmt *pStmt;
|
||||
sqlite3_uint64 *aCnt;
|
||||
sqlite3_value **apValue;
|
||||
int nCol = 0;
|
||||
int nByte;
|
||||
int i, j, k;
|
||||
int iLimit;
|
||||
int nRow = 0;
|
||||
char *zRes;
|
||||
int szRes;
|
||||
int rc;
|
||||
|
||||
# define N_SPAN 5
|
||||
if( n==0 ) return 0;
|
||||
pStmt = db_prepare("PRAGMA index_xinfo=\"%w\"", zIdx);
|
||||
while( sqlite3_step(pStmt)==SQLITE_ROW ){
|
||||
const char *zColl = (const char*)sqlite3_column_text(pStmt,4);
|
||||
if( sqlite3_stricmp(zColl,"binary")!=0 ){
|
||||
printf("-- cannot analyze index \"%s\" because column \"%s\" uses"
|
||||
" collating sequence \"%s\".\n",
|
||||
zIdx, sqlite3_column_text(pStmt, 2), zColl);
|
||||
sqlite3_finalize(pStmt);
|
||||
return 0;
|
||||
}
|
||||
if( sqlite3_column_int(pStmt, 5)==0 ) break;
|
||||
nCol++;
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
if( nCol==0 ) return 0;
|
||||
nByte = (sizeof(aCnt[0]) + sizeof(apValue[0]))*nCol + 30*(nCol+1);
|
||||
aCnt = sqlite3_malloc( nByte );
|
||||
if( aCnt==0 ){
|
||||
runtimeError("out of memory");
|
||||
}
|
||||
memset(aCnt, 0, nByte);
|
||||
apValue = (sqlite3_value**)&aCnt[nCol];
|
||||
zRes = (char*)&apValue[nCol];
|
||||
szRes = 30*(nCol+1);
|
||||
|
||||
iLimit = n>10000 ? 100 : 20000;
|
||||
pStmt = db_prepare("PRAGMA btree_sample(\"%w\",0.0,%lld)",
|
||||
zIdx, n*2);
|
||||
for(i=0; i<=N_SPAN; i++){
|
||||
k = 0;
|
||||
while( k<iLimit && (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
|
||||
int iFirst;
|
||||
for(iFirst=0; iFirst<nCol; iFirst++){
|
||||
if( apValue[iFirst]==0 ) break;
|
||||
if( columnNotEqual(pStmt, iFirst, apValue[iFirst]) ) break;
|
||||
}
|
||||
for(j=iFirst; j<nCol; j++){
|
||||
aCnt[j]++;
|
||||
sqlite3_value_free(apValue[j]);
|
||||
apValue[j] = sqlite3_value_dup(sqlite3_column_value(pStmt,j));
|
||||
}
|
||||
if( k==0 && iFirst==nCol ){
|
||||
nRow += n/(N_SPAN+1) - iLimit;
|
||||
}
|
||||
nRow++;
|
||||
k++;
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
if( rc!=SQLITE_ROW || i==N_SPAN-1 ) break;
|
||||
pStmt = db_prepare("PRAGMA btree_sample(\"%w\",%g,%lld)",
|
||||
zIdx, ((double)i)/(double)N_SPAN, n*2);
|
||||
}
|
||||
for(j=0; j<nCol; j++) sqlite3_value_free(apValue[j]);
|
||||
sqlite3_snprintf(szRes, zRes, "%lld", n);
|
||||
k = (int)strlen(zRes);
|
||||
for(j=0; j<nCol; j++){
|
||||
sqlite3_snprintf(szRes-k, zRes+k, " %d", (nRow+aCnt[j]-1)/aCnt[j]);
|
||||
k += (int)strlen(zRes+k);
|
||||
}
|
||||
printf("INSERT INTO sqlite_stat1 VALUES('%s','%s','%s');\n",
|
||||
zTab, zIdx, zRes);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** Stat1 for a table.
|
||||
*/
|
||||
static void analyzeTable(const char *zTab){
|
||||
sqlite3_int64 n = estEntryCount(zTab);
|
||||
sqlite3_stmt *pStmt;
|
||||
int nIndex = 0;
|
||||
int isWithoutRowid = 0;
|
||||
if( n==0 ){
|
||||
printf("-- empty table: %s\n", zTab);
|
||||
return;
|
||||
}
|
||||
if( analyzeIndex(zTab,zTab) ){
|
||||
isWithoutRowid = 1;
|
||||
nIndex++;
|
||||
}
|
||||
pStmt = db_prepare("PRAGMA index_list(\"%w\")", zTab);
|
||||
while( sqlite3_step(pStmt)==SQLITE_ROW ){
|
||||
if( sqlite3_column_text(pStmt,3)[0]=='p' && isWithoutRowid ) continue;
|
||||
if( sqlite3_column_int(pStmt,4)==0 ) nIndex++;
|
||||
analyzeIndex(zTab, (const char*)sqlite3_column_text(pStmt,1));
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
if( nIndex==0 ){
|
||||
printf("INSERT INTO sqlite_stat1 VALUES('%s',NULL,'%lld');\n", zTab, n);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Print sketchy documentation for this utility program
|
||||
*/
|
||||
static void showHelp(void){
|
||||
printf("Usage: %s [options] DBFILE\n", g.zArgv0);
|
||||
printf(
|
||||
"Generate an approximate sqlite_stat1 table for the database in the DBFILE\n"
|
||||
"file. Write the result to standard output.\n"
|
||||
"Options:\n"
|
||||
" (none yet....)\n"
|
||||
);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
const char *zDb = 0;
|
||||
int i;
|
||||
int rc;
|
||||
char *zErrMsg = 0;
|
||||
sqlite3_stmt *pStmt;
|
||||
sqlite3_int64 iStart, iTotal;
|
||||
|
||||
g.zArgv0 = argv[0];
|
||||
sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
|
||||
iStart = currentTime();
|
||||
for(i=1; i<argc; i++){
|
||||
const char *z = argv[i];
|
||||
if( z[0]=='-' ){
|
||||
z++;
|
||||
if( z[0]=='-' ) z++;
|
||||
if( strcmp(z,"debug")==0 ){
|
||||
if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]);
|
||||
g.fDebug = strtol(argv[++i], 0, 0);
|
||||
}else
|
||||
if( strcmp(z,"help")==0 ){
|
||||
showHelp();
|
||||
return 0;
|
||||
}else
|
||||
{
|
||||
cmdlineError("unknown option: %s", argv[i]);
|
||||
}
|
||||
}else if( zDb==0 ){
|
||||
zDb = argv[i];
|
||||
}else{
|
||||
cmdlineError("unknown argument: %s", argv[i]);
|
||||
}
|
||||
}
|
||||
if( zDb==0 ){
|
||||
cmdlineError("database filename required");
|
||||
}
|
||||
rc = sqlite3_open_v2(zDb, &g.db, SQLITE_OPEN_READONLY, 0);
|
||||
if( rc ){
|
||||
cmdlineError("cannot open database file \"%s\"", zDb);
|
||||
}
|
||||
rc = sqlite3_exec(g.db, "SELECT * FROM sqlite_master", 0, 0, &zErrMsg);
|
||||
if( rc || zErrMsg ){
|
||||
cmdlineError("\"%s\" does not appear to be a valid SQLite database", zDb);
|
||||
}
|
||||
printf("ANALYZE sqlite_master;\nDELETE FROM sqlite_stat1;\n");
|
||||
pStmt = db_prepare("SELECT name FROM sqlite_master"
|
||||
" WHERE type='table' AND rootpage>0"
|
||||
" AND name NOT LIKE 'sqlite_%%'"
|
||||
" ORDER BY name");
|
||||
while( sqlite3_step(pStmt)==SQLITE_ROW ){
|
||||
const char *zName = (const char*)sqlite3_column_text(pStmt, 0);
|
||||
analyzeTable(zName);
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
printf("ANALYZE sqlite_master;\n");
|
||||
sqlite3_close(g.db);
|
||||
iTotal = currentTime() - iStart;
|
||||
printf("-- elapsed time: %lld.%03lld seconds\n", iTotal/1000, iTotal%1000);
|
||||
return 0;
|
||||
}
|
||||
+128
-30
@@ -10,6 +10,15 @@
|
||||
# new pragma in ../src/pragma.c.
|
||||
#
|
||||
|
||||
# Flag meanings:
|
||||
set flagMeaning(NeedSchema) {Force schema load before running}
|
||||
set flagMeaning(ReadOnly) {Read-only HEADER_VALUE}
|
||||
set flagMeaning(Result0) {Acts as query when no argument}
|
||||
set flagMeaning(Result1) {Acts as query when has one argument}
|
||||
set flagMeaning(SchemaReq) {Schema required - "main" is default}
|
||||
set flagMeaning(SchemaOpt) {Schema restricts name search if present}
|
||||
set flagMeaning(NoColumns) {OP_ResultRow called with zero columns}
|
||||
|
||||
set pragma_def {
|
||||
NAME: full_column_names
|
||||
TYPE: FLAG
|
||||
@@ -47,6 +56,7 @@ set pragma_def {
|
||||
IF: !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
|
||||
NAME: cache_spill
|
||||
FLAG: Result0 SchemaReq
|
||||
IF: !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
|
||||
NAME: reverse_unordered_selects
|
||||
@@ -139,50 +149,56 @@ set pragma_def {
|
||||
ARG: SQLITE_CellSizeCk
|
||||
|
||||
NAME: default_cache_size
|
||||
FLAG: NeedSchema
|
||||
FLAG: NeedSchema Result0 SchemaReq
|
||||
COLS: cache_size
|
||||
IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
|
||||
|
||||
NAME: page_size
|
||||
FLAG: Result0 SchemaReq
|
||||
IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
|
||||
NAME: secure_delete
|
||||
FLAG: Result0
|
||||
IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
|
||||
NAME: page_count
|
||||
FLAG: NeedSchema
|
||||
FLAG: NeedSchema Result0 SchemaReq
|
||||
IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
|
||||
NAME: max_page_count
|
||||
TYPE: PAGE_COUNT
|
||||
FLAG: NeedSchema
|
||||
FLAG: NeedSchema Result0 SchemaReq
|
||||
IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
|
||||
NAME: locking_mode
|
||||
FLAG: Result0 SchemaReq
|
||||
IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
|
||||
NAME: journal_mode
|
||||
FLAG: NeedSchema
|
||||
FLAG: NeedSchema Result0 SchemaReq
|
||||
IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
|
||||
NAME: journal_size_limit
|
||||
FLAG: Result0 SchemaReq
|
||||
IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
|
||||
NAME: cache_size
|
||||
FLAG: NeedSchema
|
||||
FLAG: NeedSchema Result0 SchemaReq
|
||||
IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
|
||||
NAME: mmap_size
|
||||
IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
|
||||
NAME: auto_vacuum
|
||||
FLAG: NeedSchema
|
||||
FLAG: NeedSchema Result0 SchemaReq
|
||||
IF: !defined(SQLITE_OMIT_AUTOVACUUM)
|
||||
|
||||
NAME: incremental_vacuum
|
||||
FLAG: NeedSchema
|
||||
FLAG: NeedSchema NoColumns
|
||||
IF: !defined(SQLITE_OMIT_AUTOVACUUM)
|
||||
|
||||
NAME: temp_store
|
||||
FLAG: Result0
|
||||
IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
|
||||
NAME: temp_store_directory
|
||||
@@ -195,46 +211,56 @@ set pragma_def {
|
||||
IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE
|
||||
|
||||
NAME: synchronous
|
||||
FLAG: NeedSchema
|
||||
FLAG: NeedSchema Result0 SchemaReq
|
||||
IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
|
||||
NAME: table_info
|
||||
FLAG: NeedSchema
|
||||
FLAG: NeedSchema Result1 SchemaOpt
|
||||
COLS: cid name type notnull dflt_value pk
|
||||
IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
|
||||
NAME: stats
|
||||
FLAG: NeedSchema
|
||||
FLAG: NeedSchema Result0 SchemaReq
|
||||
COLS: table index width height
|
||||
IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
|
||||
NAME: index_info
|
||||
TYPE: INDEX_INFO
|
||||
ARG: 0
|
||||
FLAG: NeedSchema
|
||||
FLAG: NeedSchema Result1 SchemaOpt
|
||||
COLS: seqno cid name
|
||||
IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
|
||||
NAME: index_xinfo
|
||||
TYPE: INDEX_INFO
|
||||
ARG: 1
|
||||
FLAG: NeedSchema
|
||||
FLAG: NeedSchema Result1 SchemaOpt
|
||||
COLS: seqno cid name desc coll key
|
||||
IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
|
||||
NAME: index_list
|
||||
FLAG: NeedSchema
|
||||
FLAG: NeedSchema Result1 SchemaOpt
|
||||
COLS: seq name unique origin partial
|
||||
IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
|
||||
NAME: database_list
|
||||
FLAG: NeedSchema
|
||||
FLAG: NeedSchema Result0
|
||||
COLS: seq name file
|
||||
IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
|
||||
NAME: collation_list
|
||||
FLAG: Result0
|
||||
COLS: seq name
|
||||
IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
|
||||
NAME: foreign_key_list
|
||||
FLAG: NeedSchema
|
||||
FLAG: NeedSchema Result1 SchemaOpt
|
||||
COLS: id seq table from to on_update on_delete match
|
||||
IF: !defined(SQLITE_OMIT_FOREIGN_KEY)
|
||||
|
||||
NAME: foreign_key_check
|
||||
FLAG: NeedSchema
|
||||
COLS: table rowid parent fkid
|
||||
IF: !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
|
||||
|
||||
NAME: parser_trace
|
||||
@@ -251,7 +277,14 @@ set pragma_def {
|
||||
FLAG: NeedSchema
|
||||
IF: !defined(SQLITE_OMIT_INTEGRITY_CHECK)
|
||||
|
||||
NAME: est_count
|
||||
FLAG: NeedSchema
|
||||
|
||||
NAME: btree_sample
|
||||
FLAG: NeedSchema
|
||||
|
||||
NAME: encoding
|
||||
FLAG: Result0
|
||||
IF: !defined(SQLITE_OMIT_UTF16)
|
||||
|
||||
NAME: schema_version
|
||||
@@ -282,10 +315,12 @@ set pragma_def {
|
||||
IF: !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
|
||||
NAME: compile_options
|
||||
FLAG: Result0
|
||||
IF: !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
|
||||
|
||||
NAME: wal_checkpoint
|
||||
FLAG: NeedSchema
|
||||
COLS: busy log checkpointed
|
||||
IF: !defined(SQLITE_OMIT_WAL)
|
||||
|
||||
NAME: wal_autocheckpoint
|
||||
@@ -294,8 +329,12 @@ set pragma_def {
|
||||
NAME: shrink_memory
|
||||
|
||||
NAME: busy_timeout
|
||||
FLAG: Result0
|
||||
COLS: timeout
|
||||
|
||||
NAME: lock_status
|
||||
FLAG: Result0
|
||||
COLS: database status
|
||||
IF: defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
||||
|
||||
NAME: key
|
||||
@@ -315,8 +354,10 @@ set pragma_def {
|
||||
IF: defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
|
||||
|
||||
NAME: soft_heap_limit
|
||||
FLAG: Result0
|
||||
|
||||
NAME: threads
|
||||
FLAG: Result0
|
||||
}
|
||||
|
||||
# Open the output file
|
||||
@@ -336,15 +377,29 @@ set name {}
|
||||
set type {}
|
||||
set if {}
|
||||
set flags {}
|
||||
set cols {}
|
||||
set cols_list {}
|
||||
set arg 0
|
||||
proc record_one {} {
|
||||
global name type if arg allbyname typebyif flags
|
||||
global name type if arg allbyname typebyif flags cols allcols
|
||||
global cols_list colUsedBy
|
||||
if {$name==""} return
|
||||
set allbyname($name) [list $type $arg $if $flags]
|
||||
if {$cols!=""} {
|
||||
if {![info exists allcols($cols)]} {
|
||||
lappend cols_list $cols
|
||||
set allcols($cols) [llength $cols_list]
|
||||
}
|
||||
set cx $allcols($cols)
|
||||
lappend colUsedBy($cols) $name
|
||||
} else {
|
||||
set cx 0
|
||||
}
|
||||
set allbyname($name) [list $type $arg $if $flags $cx]
|
||||
set name {}
|
||||
set type {}
|
||||
set if {}
|
||||
set flags {}
|
||||
set cols {}
|
||||
set arg 0
|
||||
}
|
||||
foreach line [split $pragma_def \n] {
|
||||
@@ -358,8 +413,16 @@ foreach line [split $pragma_def \n] {
|
||||
set type [string toupper $val]
|
||||
} elseif {$id=="TYPE"} {
|
||||
set type $val
|
||||
if {$type=="FLAG"} {
|
||||
lappend flags Result0 NoColumns
|
||||
}
|
||||
if {$type=="HEADER_VALUE"} {
|
||||
lappend flags Result0
|
||||
}
|
||||
} elseif {$id=="ARG"} {
|
||||
set arg $val
|
||||
} elseif {$id=="COLS"} {
|
||||
set cols $val
|
||||
} elseif {$id=="IF"} {
|
||||
lappend if $val
|
||||
} elseif {$id=="FLAG"} {
|
||||
@@ -378,6 +441,7 @@ set allnames [lsort [array names allbyname]]
|
||||
# omit in default builds (defined(SQLITE_DEBUG) and defined(SQLITE_HAS_CODEC))
|
||||
# at the end.
|
||||
#
|
||||
puts $fd "\n/* The various pragma types */"
|
||||
set pnum 0
|
||||
foreach name $allnames {
|
||||
set type [lindex $allbyname($name) 0]
|
||||
@@ -407,25 +471,58 @@ foreach name $allnames {
|
||||
|
||||
# Generate #defines for flags
|
||||
#
|
||||
puts $fd "\n/* Property flags associated with various pragma. */"
|
||||
set fv 1
|
||||
foreach f [lsort [array names allflags]] {
|
||||
puts $fd [format {#define PragFlag_%-20s 0x%02x} $f $fv]
|
||||
puts $fd [format {#define PragFlg_%-10s 0x%02x /* %s */} \
|
||||
$f $fv $flagMeaning($f)]
|
||||
set fv [expr {$fv*2}]
|
||||
}
|
||||
|
||||
# Generate the array of column names used by pragmas that act like
|
||||
# queries.
|
||||
#
|
||||
puts $fd "\n/* Names of columns for pragmas that return multi-column result"
|
||||
puts $fd "** or that return single-column results where the name of the"
|
||||
puts $fd "** result column is different from the name of the pragma\n*/"
|
||||
puts $fd "static const char *const pragCName\[\] = {"
|
||||
set offset 0
|
||||
foreach cols $cols_list {
|
||||
set cols_offset($allcols($cols)) $offset
|
||||
set ub " /* Used by: $colUsedBy($cols) */"
|
||||
foreach c $cols {
|
||||
puts $fd [format " /* %3d */ %-14s%s" $offset \"$c\", $ub]
|
||||
set ub ""
|
||||
incr offset
|
||||
}
|
||||
}
|
||||
puts $fd "\175;"
|
||||
|
||||
# Generate the lookup table
|
||||
#
|
||||
puts $fd "static const struct sPragmaNames \173"
|
||||
puts $fd " const char *const zName; /* Name of pragma */"
|
||||
puts $fd " u8 ePragTyp; /* PragTyp_XXX value */"
|
||||
puts $fd " u8 mPragFlag; /* Zero or more PragFlag_XXX values */"
|
||||
puts $fd " u32 iArg; /* Extra argument */"
|
||||
puts $fd "\175 aPragmaNames\[\] = \173"
|
||||
puts $fd "\n/* Definitions of all built-in pragmas */"
|
||||
puts $fd "typedef struct PragmaName \173"
|
||||
puts $fd " const char *const zName; /* Name of pragma */"
|
||||
puts $fd " u8 ePragTyp; /* PragTyp_XXX value */"
|
||||
puts $fd " u8 mPragFlg; /* Zero or more PragFlg_XXX values */"
|
||||
puts $fd { u8 iPragCName; /* Start of column names in pragCName[] */}
|
||||
puts $fd " u8 nPragCName; \
|
||||
/* Num of col names. 0 means use pragma name */"
|
||||
puts $fd " u32 iArg; /* Extra argument */"
|
||||
puts $fd "\175 PragmaName;"
|
||||
puts $fd "static const PragmaName aPragmaName\[\] = \173"
|
||||
|
||||
set current_if {}
|
||||
set spacer [format { %26s } {}]
|
||||
foreach name $allnames {
|
||||
foreach {type arg if flag} $allbyname($name) break
|
||||
foreach {type arg if flag cx} $allbyname($name) break
|
||||
if {$cx==0} {
|
||||
set cy 0
|
||||
set nx 0
|
||||
} else {
|
||||
set cy $cols_offset($cx)
|
||||
set nx [llength [lindex $cols_list [expr {$cx-1}]]]
|
||||
}
|
||||
if {$if!=$current_if} {
|
||||
if {$current_if!=""} {
|
||||
foreach this_if $current_if {
|
||||
@@ -443,12 +540,13 @@ foreach name $allnames {
|
||||
if {$flag==""} {
|
||||
set flagx "0"
|
||||
} else {
|
||||
set flagx PragFlag_[join $flag {|PragFlag_}]
|
||||
set flagx PragFlg_[join $flag {|PragFlg_}]
|
||||
}
|
||||
puts $fd " \173 /* zName: */ \"$name\","
|
||||
puts $fd " /* ePragTyp: */ PragTyp_$type,"
|
||||
puts $fd " /* ePragFlag: */ $flagx,"
|
||||
puts $fd " /* iArg: */ $arg \175,"
|
||||
puts $fd " \173/* zName: */ \"$name\","
|
||||
puts $fd " /* ePragTyp: */ PragTyp_$type,"
|
||||
puts $fd " /* ePragFlg: */ $flagx,"
|
||||
puts $fd " /* ColNames: */ $cy, $nx,"
|
||||
puts $fd " /* iArg: */ $arg \175,"
|
||||
}
|
||||
if {$current_if!=""} {
|
||||
foreach this_if $current_if {
|
||||
|
||||
Reference in New Issue
Block a user