Pull all the latest trunk changes into the sessions branch.
FossilOrigin-Name: 361fb66a799f4f253e61ca94d999accde2c75b2c
This commit is contained in:
commit
fdf1795618
@ -33,6 +33,9 @@
|
||||
/* Define to 1 if you have the `localtime_s' function. */
|
||||
#undef HAVE_LOCALTIME_S
|
||||
|
||||
/* Define to 1 if you have the <malloc.h> header file. */
|
||||
#undef HAVE_MALLOC_H
|
||||
|
||||
/* Define to 1 if you have the `malloc_usable_size' function. */
|
||||
#undef HAVE_MALLOC_USABLE_SIZE
|
||||
|
||||
|
@ -122,7 +122,7 @@ AC_CHECK_TYPES([int8_t, int16_t, int32_t, int64_t, intptr_t, uint8_t,
|
||||
|
||||
#########
|
||||
# Check for needed/wanted headers
|
||||
AC_CHECK_HEADERS([sys/types.h stdlib.h stdint.h inttypes.h])
|
||||
AC_CHECK_HEADERS([sys/types.h stdlib.h stdint.h inttypes.h malloc.h])
|
||||
|
||||
#########
|
||||
# Figure out whether or not we have these functions
|
||||
|
@ -944,7 +944,7 @@ static int asyncFileControl(sqlite3_file *id, int op, void *pArg){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
}
|
||||
return SQLITE_ERROR;
|
||||
return SQLITE_NOTFOUND;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1044,15 +1044,18 @@ static int asyncOpen(
|
||||
char *z;
|
||||
int isAsyncOpen = doAsynchronousOpen(flags);
|
||||
|
||||
/* If zName is NULL, then the upper layer is requesting an anonymous file */
|
||||
/* If zName is NULL, then the upper layer is requesting an anonymous file.
|
||||
** Otherwise, allocate enough space to make a copy of the file name (along
|
||||
** with the second nul-terminator byte required by xOpen).
|
||||
*/
|
||||
if( zName ){
|
||||
nName = (int)strlen(zName)+1;
|
||||
nName = (int)strlen(zName);
|
||||
}
|
||||
|
||||
nByte = (
|
||||
sizeof(AsyncFileData) + /* AsyncFileData structure */
|
||||
2 * pVfs->szOsFile + /* AsyncFileData.pBaseRead and pBaseWrite */
|
||||
nName /* AsyncFileData.zName */
|
||||
nName + 2 /* AsyncFileData.zName */
|
||||
);
|
||||
z = sqlite3_malloc(nByte);
|
||||
if( !z ){
|
||||
|
@ -2600,7 +2600,9 @@ static int fts3SegReaderCursor(
|
||||
}
|
||||
|
||||
rc = sqlite3Fts3SegReaderNew(pCsr->nSegment+1,
|
||||
iStartBlock, iLeavesEndBlock, iEndBlock, zRoot, nRoot, &pSeg
|
||||
(isPrefix==0 && isScan==0),
|
||||
iStartBlock, iLeavesEndBlock,
|
||||
iEndBlock, zRoot, nRoot, &pSeg
|
||||
);
|
||||
if( rc!=SQLITE_OK ) goto finished;
|
||||
rc = fts3SegReaderCursorAppend(pCsr, pSeg);
|
||||
|
@ -401,7 +401,7 @@ int sqlite3Fts3UpdateMethod(sqlite3_vtab*,int,sqlite3_value**,sqlite3_int64*);
|
||||
int sqlite3Fts3PendingTermsFlush(Fts3Table *);
|
||||
void sqlite3Fts3PendingTermsClear(Fts3Table *);
|
||||
int sqlite3Fts3Optimize(Fts3Table *);
|
||||
int sqlite3Fts3SegReaderNew(int, sqlite3_int64,
|
||||
int sqlite3Fts3SegReaderNew(int, int, sqlite3_int64,
|
||||
sqlite3_int64, sqlite3_int64, const char *, int, Fts3SegReader**);
|
||||
int sqlite3Fts3SegReaderPending(
|
||||
Fts3Table*,int,const char*,int,int,Fts3SegReader**);
|
||||
|
@ -110,6 +110,7 @@ struct Fts3DeferredToken {
|
||||
*/
|
||||
struct Fts3SegReader {
|
||||
int iIdx; /* Index within level, or 0x7FFFFFFF for PT */
|
||||
int bLookup; /* True for a lookup only */
|
||||
|
||||
sqlite3_int64 iStartBlock; /* Rowid of first leaf block to traverse */
|
||||
sqlite3_int64 iLeafEndBlock; /* Rowid of final leaf block to traverse */
|
||||
@ -1088,6 +1089,18 @@ static int fts3SegReaderRequire(Fts3SegReader *pReader, char *pFrom, int nByte){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Set an Fts3SegReader cursor to point at EOF.
|
||||
*/
|
||||
static void fts3SegReaderSetEof(Fts3SegReader *pSeg){
|
||||
if( !fts3SegReaderIsRootOnly(pSeg) ){
|
||||
sqlite3_free(pSeg->aNode);
|
||||
sqlite3_blob_close(pSeg->pBlob);
|
||||
pSeg->pBlob = 0;
|
||||
}
|
||||
pSeg->aNode = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Move the iterator passed as the first argument to the next term in the
|
||||
** segment. If successful, SQLITE_OK is returned. If there is no next term,
|
||||
@ -1127,12 +1140,7 @@ static int fts3SegReaderNext(
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
if( !fts3SegReaderIsRootOnly(pReader) ){
|
||||
sqlite3_free(pReader->aNode);
|
||||
sqlite3_blob_close(pReader->pBlob);
|
||||
pReader->pBlob = 0;
|
||||
}
|
||||
pReader->aNode = 0;
|
||||
fts3SegReaderSetEof(pReader);
|
||||
|
||||
/* If iCurrentBlock>=iLeafEndBlock, this is an EOF condition. All leaf
|
||||
** blocks have already been traversed. */
|
||||
@ -1379,6 +1387,7 @@ void sqlite3Fts3SegReaderFree(Fts3SegReader *pReader){
|
||||
*/
|
||||
int sqlite3Fts3SegReaderNew(
|
||||
int iAge, /* Segment "age". */
|
||||
int bLookup, /* True for a lookup only */
|
||||
sqlite3_int64 iStartLeaf, /* First leaf to traverse */
|
||||
sqlite3_int64 iEndLeaf, /* Final leaf to traverse */
|
||||
sqlite3_int64 iEndBlock, /* Final block of segment */
|
||||
@ -1400,6 +1409,7 @@ int sqlite3Fts3SegReaderNew(
|
||||
}
|
||||
memset(pReader, 0, sizeof(Fts3SegReader));
|
||||
pReader->iIdx = iAge;
|
||||
pReader->bLookup = bLookup;
|
||||
pReader->iStartBlock = iStartLeaf;
|
||||
pReader->iLeafEndBlock = iEndLeaf;
|
||||
pReader->iEndBlock = iEndBlock;
|
||||
@ -2402,11 +2412,16 @@ static int fts3SegReaderStart(
|
||||
** b-tree leaf nodes contain more than one term.
|
||||
*/
|
||||
for(i=0; pCsr->bRestart==0 && i<pCsr->nSegment; i++){
|
||||
int res = 0;
|
||||
Fts3SegReader *pSeg = pCsr->apSegment[i];
|
||||
do {
|
||||
int rc = fts3SegReaderNext(p, pSeg, 0);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
}while( zTerm && fts3SegReaderTermCmp(pSeg, zTerm, nTerm)<0 );
|
||||
}while( zTerm && (res = fts3SegReaderTermCmp(pSeg, zTerm, nTerm))<0 );
|
||||
|
||||
if( pSeg->bLookup && res!=0 ){
|
||||
fts3SegReaderSetEof(pSeg);
|
||||
}
|
||||
}
|
||||
fts3SegReaderSort(pCsr->apSegment, nSeg, nSeg, fts3SegReaderCmp);
|
||||
|
||||
@ -2527,7 +2542,12 @@ int sqlite3Fts3SegReaderStep(
|
||||
** forward. Then sort the list in order of current term again.
|
||||
*/
|
||||
for(i=0; i<pCsr->nAdvance; i++){
|
||||
rc = fts3SegReaderNext(p, apSegment[i], 0);
|
||||
Fts3SegReader *pSeg = apSegment[i];
|
||||
if( pSeg->bLookup ){
|
||||
fts3SegReaderSetEof(pSeg);
|
||||
}else{
|
||||
rc = fts3SegReaderNext(p, pSeg, 0);
|
||||
}
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
}
|
||||
fts3SegReaderSort(apSegment, nSegment, pCsr->nAdvance, fts3SegReaderCmp);
|
||||
|
118
manifest
118
manifest
@ -1,12 +1,12 @@
|
||||
C Support\sbuilding\swith\sSQLITE_ENABLE_SESSION\sunder\sMSVC.
|
||||
D 2012-01-16T12:33:36.900
|
||||
C Pull\sall\sthe\slatest\strunk\schanges\sinto\sthe\ssessions\sbranch.
|
||||
D 2012-02-10T17:54:52.604
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 3f79a373e57c3b92dabf76f40b065e719d31ac34
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
F Makefile.msc 340b6d1bb4553c389d6837aa437d7c25dc03f980
|
||||
F Makefile.vxworks 1deb39c8bb047296c30161ffa10c1b5423e632f9
|
||||
F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6
|
||||
F VERSION af03cd6400f9d71d38bdb7a9d66a1aefdc2f3e0d
|
||||
F VERSION bb4c2a86abe53ea3c1d6ea515b69a426040e2414
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
F addopcodes.awk 17dc593f791f874d2c23a0f9360850ded0286531
|
||||
F art/2005osaward.gif 0d1851b2a7c1c9d0ccce545f3e14bca42d7fd248
|
||||
@ -21,17 +21,17 @@ F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
|
||||
F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
|
||||
F art/src_logo.gif 9341ef09f0e53cd44c0c9b6fc3c16f7f3d6c2ad9
|
||||
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
|
||||
F config.h.in 31cc8c4943f56e60c4aa4fba929c9d4c70e418b4
|
||||
F config.h.in 0921066a13130082764ab4ab6456f7b5bebe56de
|
||||
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
|
||||
F configure cdfb8a907ded1f8e75b6967e3e3bd35718884aff x
|
||||
F configure.ac 75323bdac56fb0e69f6a3fc5b23f24359550b9d9
|
||||
F configure 4ee31677412c454d0978a64872faf3ec36ff94ca x
|
||||
F configure.ac 9ee886c21c095b3272137b1553ae416c8b8c8557
|
||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/lemon.html 3091574143dd3415669b6745843ff8d011d33549
|
||||
F doc/pager-invariants.txt 870107036470d7c419e93768676fae2f8749cf9e
|
||||
F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a
|
||||
F ext/README.txt 913a7bd3f4837ab14d7e063304181787658b14e1
|
||||
F ext/async/README.txt 0c541f418b14b415212264cbaaf51c924ec62e5b
|
||||
F ext/async/sqlite3async.c a7c6078c82c0bac3b7bea95bc52d5ce7ed58083a
|
||||
F ext/async/sqlite3async.c 733a9f21b1066f44ff07b9c0da973b1e483d1e0c
|
||||
F ext/async/sqlite3async.h a21e1252deb14a2c211f0e165c4b9122a8f1f344
|
||||
F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e
|
||||
F ext/fts1/ft_hash.c 3927bd880e65329bdc6f506555b228b28924921b
|
||||
@ -63,9 +63,9 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51
|
||||
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
|
||||
F ext/fts3/README.tokenizers 998756696647400de63d5ba60e9655036cb966e9
|
||||
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
|
||||
F ext/fts3/fts3.c bd570b99f1f65b17d587361a421d7f2f28082aa0
|
||||
F ext/fts3/fts3.c 4cf7b8e5bbb6667f5d7818fa0bf064fbbb72b086
|
||||
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
|
||||
F ext/fts3/fts3Int.h def7a900f98c5ab5fa4772e922bfa219d5097f05
|
||||
F ext/fts3/fts3Int.h ce958a6fa92a95462853aa3acc0b69bcda39102f
|
||||
F ext/fts3/fts3_aux.c 0ebfa7b86cf8ff6a0861605fcc63b83ec1b70691
|
||||
F ext/fts3/fts3_expr.c f5df26bddf46a5916b2a5f80c4027996e92b7b15
|
||||
F ext/fts3/fts3_hash.c 8dd2d06b66c72c628c2732555a32bc0943114914
|
||||
@ -78,7 +78,7 @@ F ext/fts3/fts3_test.c 24fa13f330db011500acb95590da9eee24951894
|
||||
F ext/fts3/fts3_tokenizer.c 9ff7ec66ae3c5c0340fa081958e64f395c71a106
|
||||
F ext/fts3/fts3_tokenizer.h 13ffd9fcb397fec32a05ef5cd9e0fa659bf3dbd3
|
||||
F ext/fts3/fts3_tokenizer1.c 0dde8f307b8045565cf63797ba9acfaff1c50c68
|
||||
F ext/fts3/fts3_write.c fdf0c99830360146ec7128150271c8c014a8fef7
|
||||
F ext/fts3/fts3_write.c 1721187a4dec29ef9ae648ad8478da741085af18
|
||||
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
|
||||
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
|
||||
F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9
|
||||
@ -130,26 +130,26 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
|
||||
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
|
||||
F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
|
||||
F src/alter.c ac80a0f31189f8b4a524ebf661e47e84536ee7f5
|
||||
F src/alter.c 149cc80d9257971b0bff34e58fb2263e01998289
|
||||
F src/analyze.c f32ff304da413851eefa562b04e61ff6cb88248b
|
||||
F src/attach.c 12c6957996908edc31c96d7c68d4942c2474405f
|
||||
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
|
||||
F src/backup.c e9538bad2d4a4fcd4308f1aed7cb18a0fbc968f9
|
||||
F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef
|
||||
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
|
||||
F src/btree.c a65816cc000bdd421772986e64c88c9035331332
|
||||
F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce
|
||||
F src/btreeInt.h 6c9960645c431c9456ca56498f43a2b3bf1fa8c2
|
||||
F src/build.c 8e2a4dedad860fed982270ef43968505f35ec57f
|
||||
F src/btree.c bb0132a725b4d5ed077924399c4f6d4b9390a721
|
||||
F src/btree.h 46e9f04672f1390255bc56865a3238b384d0f2d5
|
||||
F src/btreeInt.h 26d8ca625b141927fe6620c1d2cf58eaf494ca0c
|
||||
F src/build.c c4d36e527f457f9992a6663365871dfa7c5094b8
|
||||
F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a
|
||||
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
||||
F src/ctime.c a9c26822515f81ec21588cbb482ca6724be02e33
|
||||
F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
|
||||
F src/delete.c c6796c89280de6cbad73089adb4cdd01a4d4a1a7
|
||||
F src/expr.c 537591e95eac74af783e4eb033954fb218cf398e
|
||||
F src/expr.c 00675123e0beec98f999aa4594d2cbe1fec33c1b
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5
|
||||
F src/func.c 6261ce00aad9c63cd5b4219249b05683979060e9
|
||||
F src/func.c d7925f33a8ce2207f86dea5cfb1a4379413312fe
|
||||
F src/global.c 4cfdca5cb0edd33c4d021baec4ede958cb2c793b
|
||||
F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af
|
||||
F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970
|
||||
@ -159,10 +159,10 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e
|
||||
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
|
||||
F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416
|
||||
F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d
|
||||
F src/main.c 11e7d9ea1930f361ff58262752e4241dc371ecd7
|
||||
F src/main.c 166f9571341f7084172f87e1931f0833778576eb
|
||||
F src/malloc.c 15afac5e59b6584efe072e9933aefb4230e74f97
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c 7998e7003a3047e323c849a26dda004debc04d03
|
||||
F src/mem1.c c953f3bfc8fcd31d4de2078697caefeb1dcfd7ff
|
||||
F src/mem2.c e307323e86b5da1853d7111b68fd6b84ad6f09cf
|
||||
F src/mem3.c 61c9d47b792908c532ca3a62b999cf21795c6534
|
||||
F src/mem5.c c2c63b7067570b00bf33d751c39af24182316f7f
|
||||
@ -175,37 +175,37 @@ F src/mutex_unix.c c3a4e00f96ba068a8dbef34084465979aaf369cc
|
||||
F src/mutex_w32.c 5e54f3ba275bcb5d00248b8c23107df2e2f73e33
|
||||
F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
|
||||
F src/os.c e1acdc09ff3ac2412945cca9766e2dcf4675f31c
|
||||
F src/os.h a2219c3b05ce31230bb000fdc4f1a542b33ee649
|
||||
F src/os.h 59beba555b65a450bd1d804220532971d4299f60
|
||||
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
|
||||
F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440
|
||||
F src/os_unix.c 657672fab2580a84116c140b36ee3d6b6fc75b4e
|
||||
F src/os_unix.c d509b369ed376c77bc547961844a105d3907e4fa
|
||||
F src/os_win.c 5ac061ae1326a71500cee578ed0fd9113b4f6a37
|
||||
F src/pager.c 4d58c983d9f4d34bc2d48e4280361ccaeecd03c5
|
||||
F src/pager.h 5cd760857707529b403837d813d86b68938d6183
|
||||
F src/parse.y fabb2e7047417d840e6fdb3ef0988a86849a08ba
|
||||
F src/pager.c 2d892f7b901a8867a33bc21742086165a3a99af8
|
||||
F src/pager.h a435da8421dc7844b7f9c7f37b636c160c50208a
|
||||
F src/parse.y 1ddd71ae55f4b7cbb2672526ea4de023de0f519e
|
||||
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
|
||||
F src/pcache.h b1d8775a9bddf44e65edb0d20bfc57a4982f840f
|
||||
F src/pcache1.c 281822d22265245b19f908cb3f5df725f7e11b06
|
||||
F src/pragma.c fb979b7b5103ad0db1b72bcf349c83f5dec62574
|
||||
F src/pcache.h 1b5dcc3dc8103d03e625b177023ee67764fa6b7c
|
||||
F src/pcache1.c b30b1c35908346ecc43d8d9d17f2ddf6817f8f60
|
||||
F src/pragma.c 350f59843f4ec4fca5dc63d497caf6433096bbdd
|
||||
F src/prepare.c ec4989f7f480544bdc4192fe663470d2a2d7d61e
|
||||
F src/printf.c 7ffb4ebb8b341f67e049695ba031da717b3d2699
|
||||
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
||||
F src/resolve.c 3d3e80a98f203ac6b9329e9621e29eda85ddfd40
|
||||
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
|
||||
F src/select.c a1d075db66a0ea42807353501b62997969e5be79
|
||||
F src/shell.c aa4183d4a5243d8110b1d3d77faa4aea7e9c9c2d
|
||||
F src/sqlite.h.in 132b3140f29469dc1222a43fd9451c1785c80a51
|
||||
F src/select.c 232283a2e60d91cbd9a5ddf2f6f7ecf53d590075
|
||||
F src/shell.c aa28f117033ba3e44b5eaaf2ad572222bcdfd66e
|
||||
F src/sqlite.h.in e805ca92bb66d958423dfcef12879e16bf547209
|
||||
F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
|
||||
F src/sqliteInt.h 701b38210f369a802853894309af5185b44061b4
|
||||
F src/sqliteInt.h b62e6f8dfc335f78e89721d54172fa12909e8f2e
|
||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||
F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a
|
||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||
F src/tclsqlite.c 47d088f383a106b2914ac970586fdab66c1bd169
|
||||
F src/test1.c 1b1e514e85ffe7152b02cba38bd0a1ce8cd56113
|
||||
F src/test1.c 328cbe4a4ee6d10d67ece2a7adaa2770569fae0f
|
||||
F src/test2.c 711555927f1f7e8db9aab86b512bc6934a774abe
|
||||
F src/test3.c 91d3f1a09cfae3533ef17d8b484a160f3d1f1a21
|
||||
F src/test4.c d1e5a5e904d4b444cf572391fdcb017638e36ff7
|
||||
F src/test5.c e1a19845625144caf038031234a12185e40d315c
|
||||
F src/test5.c a6d1ac55ac054d0b2b8f37b5e655b6c92645a013
|
||||
F src/test6.c cf6ab27a59e1ab64b011bb251ba600131e803e59
|
||||
F src/test7.c 2e0781754905c8adc3268d8f0967e7633af58843
|
||||
F src/test8.c 99f70341d6ec480313775127f4cd14b4a47db557
|
||||
@ -225,7 +225,7 @@ F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99
|
||||
F src/test_intarray.h 489edb9068bb926583445cb02589344961054207
|
||||
F src/test_journal.c a6a6baf343f79b942331f13378d045e7e270ae64
|
||||
F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e
|
||||
F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5
|
||||
F src/test_malloc.c cfe25d74333892ababde61196821a889b4756dee
|
||||
F src/test_multiplex.c afab2c9d292677ab31e0dd4b3dde2420fb655c5f
|
||||
F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d
|
||||
F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e
|
||||
@ -241,7 +241,7 @@ F src/test_stat.c 80271ad7d776a79babe0e025bb3a1bfcd3a3cfb1
|
||||
F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd
|
||||
F src/test_syscall.c a992d8c80ea91fbf21fb2dd570db40e77dd7e6ae
|
||||
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
|
||||
F src/test_thread.c 35022393dd54d147b998b6b7f7e945b01114d666
|
||||
F src/test_thread.c e286f2173563f2a1747c24bcda6b9d030bf4f4e4
|
||||
F src/test_vfs.c 07157a0bbfe161cb5e32cad2079abd26cd611c4b
|
||||
F src/test_vfstrace.c 065c7270a614254b2c68fbc7ba8d1fb1d5cbc823
|
||||
F src/test_wholenumber.c 6129adfbe7c7444f2e60cc785927f3aa74e12290
|
||||
@ -252,16 +252,16 @@ F src/update.c 89de085a0bf4da448472029d0420a2b1cf1824ee
|
||||
F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84
|
||||
F src/util.c 9e07bd67dfafe9c75b1da78c87ba030cebbb5388
|
||||
F src/vacuum.c 0c0ba2242355c6048d65e2b333abe0f7c06348fa
|
||||
F src/vdbe.c 502f3deb63c24fbb3fe6b88a10c984ec897f5b7b
|
||||
F src/vdbe.c a24b861d9de4e26220c4656b6db22103b7e5f39f
|
||||
F src/vdbe.h 87b8ff40de3f55dbcdc33029416862f517c37a2f
|
||||
F src/vdbeInt.h 1aa78a0c2d6e4fdc4b9b8ff29192e98182d25afa
|
||||
F src/vdbeInt.h f1956902b06b4f05ce965aafab6fe220a5477f9c
|
||||
F src/vdbeapi.c 2fc381f651738feb2495cb001cf2114dea596cc3
|
||||
F src/vdbeaux.c ca1eada4b21723a67c510c0f456217c03ad15e48
|
||||
F src/vdbeaux.c b7c245fe73ed15090cf626f1250dcb7cdcfb1bd6
|
||||
F src/vdbeblob.c 11248c6362389569764682eb0f59ce910f3cc381
|
||||
F src/vdbemem.c 4f7d25d5ea2e2040254095b8f6de07f8dbbadf80
|
||||
F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790
|
||||
F src/vdbemem.c fb0ac964ccbcd94f595eb993c05bfd9c52468a4a
|
||||
F src/vdbesort.c b25814d385895544ebc8118245c8311ded7f81c9
|
||||
F src/vdbetrace.c d6e50e04e1ec498150e519058f617d91b8f5c843
|
||||
F src/vtab.c e9318d88feac85be8e27ee783ac8f5397933fc8a
|
||||
F src/vtab.c ab90fb600a3f5e4b7c48d22a4cdb2d6b23239847
|
||||
F src/wal.c 5f7bcc0610af759953defd769eacebfd98a22bc8
|
||||
F src/wal.h eaa00b9a403ddda2b56d01b7afc19ef600f9363f
|
||||
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
|
||||
@ -270,7 +270,7 @@ F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
|
||||
F test/all.test 52fc8dee494092031a556911d404ca30a749a30b
|
||||
F test/alter.test 66f5818f9848c4f22de022a345fae25bcd30f8fb
|
||||
F test/alter.test 57d96ec9b320bd07af77567034488dcb6642c748
|
||||
F test/alter2.test 7ea05c7d92ac99349a802ef7ada17294dd647060
|
||||
F test/alter3.test 49c9d9fba2b8fcdce2dedeca97bbf1f369cc548d
|
||||
F test/alter4.test b2debc14d8cbe4c1d12ccd6a41eef88a8c1f15d5
|
||||
@ -301,7 +301,7 @@ F test/autovacuum.test fcaf4616ae5bb18098db1cb36262565e5c841c3c
|
||||
F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4
|
||||
F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85
|
||||
F test/backcompat.test 71eeb75ea567c060774c4e8db4b0e703f21c7677
|
||||
F test/backup.test 6970614b002b056ae5bab5b76559905e02b6f0b2
|
||||
F test/backup.test 717346db953e9e435c2a94916e4af177330d60d3
|
||||
F test/backup2.test 34986ef926ea522911a51dfdb2f8e99b7b75ebcf
|
||||
F test/backup_ioerr.test 40d208bc9224b666ee3ed423f49bc9062a36a9d0
|
||||
F test/backup_malloc.test 7162d604ec2b4683c4b3799a48657fb8b5e2d450
|
||||
@ -386,7 +386,7 @@ F test/descidx1.test 533dcbda614b0463b0ea029527fd27e5a9ab2d66
|
||||
F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d
|
||||
F test/descidx3.test fe720e8b37d59f4cef808b0bf4e1b391c2e56b6f
|
||||
F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
|
||||
F test/distinct.test df5b11ad606439129c88720a86787bc9ca181f31
|
||||
F test/distinct.test 76908ed038c5186ffb8acf5954ed64e22056f311
|
||||
F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
|
||||
F test/e_createtable.test 48598b15e8fe6554d301e7b65a10c9851f177e84
|
||||
F test/e_delete.test ec168cd4b08d681e6d5847f462203755ad647532
|
||||
@ -398,7 +398,7 @@ F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459
|
||||
F test/e_insert.test 234242b71855af8e8a9b1e141c3533f6d43d8645
|
||||
F test/e_reindex.test dfedfc32c5a282b0596c6537cbcd4217fbb1a216
|
||||
F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6
|
||||
F test/e_select.test 6f488c22851c1c280ed74e16a9a1430706a3a8cb
|
||||
F test/e_select.test 99202f99a9a3273c6fb0d2e7592b98faeb6c206e
|
||||
F test/e_select2.test 5c3d3da19c7b3e90ae444579db2b70098599ab92
|
||||
F test/e_update.test dba988a4d079156549a40854074ba4890b0a4577
|
||||
F test/e_uri.test 6f35b491f80dac005c8144f38b2dfb4d96483596
|
||||
@ -477,7 +477,7 @@ F test/fts3am.test 218aa6ba0dfc50c7c16b2022aac5c6be593d08d8
|
||||
F test/fts3an.test a49ccadc07a2f7d646ec1b81bc09da2d85a85b18
|
||||
F test/fts3ao.test e7b80272efcced57d1d087a9da5c690dd7c21fd9
|
||||
F test/fts3atoken.test 402ef2f7c2fb4b3d4fa0587df6441c1447e799b3
|
||||
F test/fts3auto.test c1a30b37002b7c764a96937fbc71065b73d69494
|
||||
F test/fts3auto.test 868a2afea308d7d8b45ef29fcf022644a9e6d662
|
||||
F test/fts3aux1.test 0b02743955d56fc0d4d66236a26177bd1b726de0
|
||||
F test/fts3b.test e93bbb653e52afde110ad53bbd793f14fe7a8984
|
||||
F test/fts3c.test fc723a9cf10b397fdfc2b32e73c53c8b1ec02958
|
||||
@ -500,13 +500,14 @@ F test/fts3malloc.test b86ea33db9e8c58c0c2f8027a9fcadaf6a1568be
|
||||
F test/fts3matchinfo.test 6507fe1c342e542300d65ea637d4110eccf894e6
|
||||
F test/fts3near.test 2e318ee434d32babd27c167142e2b94ddbab4844
|
||||
F test/fts3prefix.test b36d4f00b128a51e7b386cc013a874246d9d7dc1
|
||||
F test/fts3prefix2.test 477ca96e67f60745b7ac931cfa6e9b080c562da5
|
||||
F test/fts3query.test ef79d31fdb355d094baec1c1b24b60439a1fb8a2
|
||||
F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0
|
||||
F test/fts3shared.test 8bb266521d7c5495c0ae522bb4d376ad5387d4a2
|
||||
F test/fts3snippet.test 8e956051221a34c7daeb504f023cb54d5fa5a8b2
|
||||
F test/fts3sort.test 95be0b19d7e41c44b29014f13ea8bddd495fd659
|
||||
F test/fts4aa.test 6e7f90420b837b2c685f3bcbe84c868492d40a68
|
||||
F test/fts4content.test 2624253c7e5a32d0c0d51f776dcd4526f0a51097
|
||||
F test/fts4content.test 17b2360f7d1a9a7e5aa8022783f5c5731b6dfd4f
|
||||
F test/func.test 6c5ce11e3a0021ca3c0649234e2d4454c89110ca
|
||||
F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
|
||||
F test/func3.test 001021e5b88bd02a3b365a5c5fd8f6f49d39744a
|
||||
@ -537,7 +538,7 @@ F test/index4.test 2983216eb8c86ee62d9ed7cb206b5cc3331c0026
|
||||
F test/indexedby.test be501e381b82b2f8ab406309ba7aac46e221f4ad
|
||||
F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
|
||||
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
|
||||
F test/insert.test aef273dd1cee84cc92407469e6bd1b3cdcb76908
|
||||
F test/insert.test d540650825c98d8082d32f786c611d70e1c21a80
|
||||
F test/insert2.test 4f3a04d168c728ed5ec2c88842e772606c7ce435
|
||||
F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30
|
||||
F test/insert4.test 87f6798f31d60c4e177622fcc3663367e6ecbd90
|
||||
@ -612,13 +613,14 @@ F test/memsubsys2.test 3a1c1a9de48e5726faa85108b02459fae8cb9ee9
|
||||
F test/minmax.test 722d80816f7e096bf2c04f4111f1a6c1ba65453d
|
||||
F test/minmax2.test 33504c01a03bd99226144e4b03f7631a274d66e0
|
||||
F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354
|
||||
F test/minmax4.test c1fa9505fd135007fdb1fb699334fb3d4ea7952e
|
||||
F test/misc1.test 55cb2bfbf4a8cd61f4be1effc30426ad41696bff
|
||||
F test/misc2.test 00d7de54eda90e237fc9a38b9e5ccc769ebf6d4d
|
||||
F test/misc3.test fe55130a43e444ee75e2156ff75dc96e964b5738
|
||||
F test/misc4.test 9c078510fbfff05a9869a0b6d8b86a623ad2c4f6
|
||||
F test/misc5.test 528468b26d03303b1f047146e5eefc941b9069f5
|
||||
F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91
|
||||
F test/misc7.test eafaa41b9133d7a2ded4641bbe5f340731d35a52
|
||||
F test/misc7.test 6743b810884ef64ae14c07ad1f9f858c40c06100
|
||||
F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054
|
||||
F test/multiplex.test e08cc7177bd6d85990ee1d71100bb6c684c02256
|
||||
F test/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a
|
||||
@ -633,7 +635,7 @@ F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347
|
||||
F test/null.test a8b09b8ed87852742343b33441a9240022108993
|
||||
F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394
|
||||
F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3
|
||||
F test/pager1.test 9e9f5f1c6d4df4831dbff213b1262ef94bf72118
|
||||
F test/pager1.test efef0bb4035d7180ec58308f1d449475e4670b48
|
||||
F test/pager2.test 745b911dde3d1f24ae0870bd433dfa83d7c658c1
|
||||
F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f
|
||||
F test/pagerfault.test 452f2cc23e3bfcfa935f4442aec1da4fe1dc0442
|
||||
@ -850,7 +852,7 @@ F test/tkt3793.test d90ffd75c52413908d15e1c44fc2ea9c80fcc449
|
||||
F test/tkt3810.test 90fa0635dfa7da9680c8cd3513350a49b3a8ae12
|
||||
F test/tkt3824.test 150aa00bb6220672e5f0eb14dc8eaa36750425f0
|
||||
F test/tkt3832.test 2300d10d57562b89875b72148338ac3e14f8847d
|
||||
F test/tkt3838.test d8490365a1c473d214f7878007e543410cbb715f
|
||||
F test/tkt3838.test 292e72489101cd1320d7278dc111c173ebf334d4
|
||||
F test/tkt3841.test 4659845bc53f809a5932c61c6ce8c5bb9d6b947f
|
||||
F test/tkt3871.test 43ecbc8d90dc83908e2a454aef345acc9d160c6f
|
||||
F test/tkt3879.test 2ad5bef2c87e9991ce941e054c31abe26ef7fb90
|
||||
@ -868,7 +870,7 @@ F test/trace2.test 962175290996d5f06dc4402ca218bbfc7df4cb20
|
||||
F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6
|
||||
F test/trans2.test d5337e61de45e66b1fcbf9db833fa8c82e624b22
|
||||
F test/trans3.test d728abaa318ca364dc370e06576aa7e5fbed7e97
|
||||
F test/trigger1.test 38c657eaf9907344c9e0bcb16af94a452c6babde
|
||||
F test/trigger1.test 38524d80ac26c232d23ecec4b037eb60fb67eedd
|
||||
F test/trigger2.test 834187beafd1db383af0c659cfa49b0576832816
|
||||
F test/trigger3.test d2c60d8be271c355d61727411e753181e877230a
|
||||
F test/trigger4.test 74700b76ebf3947b2f7a92405141eb2cf2a5d359
|
||||
@ -898,7 +900,7 @@ F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9
|
||||
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
|
||||
F test/veryquick.test 7701bb609fe8bf6535514e8b849a309e8f00573b
|
||||
F test/view.test b182a67ec43f490b156b5a710827a341be83dd17
|
||||
F test/vtab1.test 12fbb309ce830c4064e44f275eb02a65c2780076
|
||||
F test/vtab1.test 17d0db1096b603a357f943a9dcbdc3e30c6f04f2
|
||||
F test/vtab2.test 7bcffc050da5c68f4f312e49e443063e2d391c0d
|
||||
F test/vtab3.test baad99fd27217f5d6db10660522e0b7192446de1
|
||||
F test/vtab4.test 942f8b8280b3ea8a41dae20e7822d065ca1cb275
|
||||
@ -981,7 +983,7 @@ F tool/shell1.test 20dfe7099cf2afe37aecd69afb7678d14f7a0abf
|
||||
F tool/shell2.test 5dc76b8005b465f420fed8241621da7513060ff3
|
||||
F tool/shell3.test 4fad469e8003938426355afdf34155f08c587836
|
||||
F tool/shell4.test 35f9c3d452b4e76d5013c63e1fd07478a62f14ce
|
||||
F tool/shell5.test 62bfaf9267296da1b91e4b1c03e44e7b393f6a94
|
||||
F tool/shell5.test 0e987fb8d40638bb5c90163cb58cbe3e07dbed56
|
||||
F tool/showdb.c 43e913d954684c2f5007dcab46d1a1308852a0ad
|
||||
F tool/showjournal.c b62cecaab86a4053d944c276bb5232e4d17ece02
|
||||
F tool/showwal.c f09e5a80a293919290ec85a6a37c85a5ddcf37d9
|
||||
@ -1000,7 +1002,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
|
||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||
F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
|
||||
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
||||
P 01c84fd391a0ca1f5245c7eff0644d0cc6cff86b
|
||||
R 88d7ca9f3f2aa524ac3a66d4c2e7567b
|
||||
U mistachkin
|
||||
Z 171e4d9c94c739b476f164aff1375bac
|
||||
P 2845654d425164de143e82b9fdb255d81a01af56 92131195d0c24c0116992db51ed5d8316626ba57
|
||||
R f655afae9aef18c1ea6dcf2304669fd0
|
||||
U drh
|
||||
Z 91074916592f2b739d5ac72d0cab45cc
|
||||
|
@ -1 +1 @@
|
||||
2845654d425164de143e82b9fdb255d81a01af56
|
||||
361fb66a799f4f253e61ca94d999accde2c75b2c
|
@ -530,7 +530,7 @@ void sqlite3AlterRenameTable(
|
||||
"WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN "
|
||||
"'sqlite_autoindex_' || %Q || substr(name,%d+18) "
|
||||
"ELSE name END "
|
||||
"WHERE tbl_name=%Q AND "
|
||||
"WHERE tbl_name=%Q COLLATE nocase AND "
|
||||
"(type='table' OR type='index' OR type='trigger');",
|
||||
zDb, SCHEMA_TABLE(iDb), zName, zName, zName,
|
||||
#ifndef SQLITE_OMIT_TRIGGER
|
||||
|
52
src/btree.c
52
src/btree.c
@ -870,12 +870,10 @@ static u8 *findOverflowCell(MemPage *pPage, int iCell){
|
||||
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
|
||||
for(i=pPage->nOverflow-1; i>=0; i--){
|
||||
int k;
|
||||
struct _OvflCell *pOvfl;
|
||||
pOvfl = &pPage->aOvfl[i];
|
||||
k = pOvfl->idx;
|
||||
k = pPage->aiOvfl[i];
|
||||
if( k<=iCell ){
|
||||
if( k==iCell ){
|
||||
return pOvfl->pCell;
|
||||
return pPage->apOvfl[i];
|
||||
}
|
||||
iCell--;
|
||||
}
|
||||
@ -1689,11 +1687,8 @@ static int btreeInvokeBusyHandler(void *pArg){
|
||||
** If zFilename is ":memory:" then an in-memory database is created
|
||||
** that is automatically destroyed when it is closed.
|
||||
**
|
||||
** The "flags" parameter is a bitmask that might contain bits
|
||||
** BTREE_OMIT_JOURNAL and/or BTREE_NO_READLOCK. The BTREE_NO_READLOCK
|
||||
** bit is also set if the SQLITE_NoReadlock flags is set in db->flags.
|
||||
** These flags are passed through into sqlite3PagerOpen() and must
|
||||
** be the same values as PAGER_OMIT_JOURNAL and PAGER_NO_READLOCK.
|
||||
** The "flags" parameter is a bitmask that might contain bits like
|
||||
** BTREE_OMIT_JOURNAL and/or BTREE_MEMORY.
|
||||
**
|
||||
** If the database is already opened in the same database connection
|
||||
** and we are in shared cache mode, then the open will fail with an
|
||||
@ -1740,9 +1735,6 @@ int sqlite3BtreeOpen(
|
||||
/* A BTREE_SINGLE database is always a temporary and/or ephemeral */
|
||||
assert( (flags & BTREE_SINGLE)==0 || isTempDb );
|
||||
|
||||
if( db->flags & SQLITE_NoReadlock ){
|
||||
flags |= BTREE_NO_READLOCK;
|
||||
}
|
||||
if( isMemdb ){
|
||||
flags |= BTREE_MEMORY;
|
||||
}
|
||||
@ -5527,7 +5519,7 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){
|
||||
** If the cell content will fit on the page, then put it there. If it
|
||||
** will not fit, then make a copy of the cell content into pTemp if
|
||||
** pTemp is not null. Regardless of pTemp, allocate a new entry
|
||||
** in pPage->aOvfl[] and make it point to the cell content (either
|
||||
** in pPage->apOvfl[] and make it point to the cell content (either
|
||||
** in pTemp or the original pCell) and also record its index.
|
||||
** Allocating a new entry in pPage->aCell[] implies that
|
||||
** pPage->nOverflow is incremented.
|
||||
@ -5561,7 +5553,8 @@ static void insertCell(
|
||||
|
||||
assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
|
||||
assert( pPage->nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=10921 );
|
||||
assert( pPage->nOverflow<=ArraySize(pPage->aOvfl) );
|
||||
assert( pPage->nOverflow<=ArraySize(pPage->apOvfl) );
|
||||
assert( ArraySize(pPage->apOvfl)==ArraySize(pPage->aiOvfl) );
|
||||
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
|
||||
/* The cell should normally be sized correctly. However, when moving a
|
||||
** malformed cell from a leaf page to an interior page, if the cell size
|
||||
@ -5578,9 +5571,9 @@ static void insertCell(
|
||||
put4byte(pCell, iChild);
|
||||
}
|
||||
j = pPage->nOverflow++;
|
||||
assert( j<(int)(sizeof(pPage->aOvfl)/sizeof(pPage->aOvfl[0])) );
|
||||
pPage->aOvfl[j].pCell = pCell;
|
||||
pPage->aOvfl[j].idx = (u16)i;
|
||||
assert( j<(int)(sizeof(pPage->apOvfl)/sizeof(pPage->apOvfl[0])) );
|
||||
pPage->apOvfl[j] = pCell;
|
||||
pPage->aiOvfl[j] = (u16)i;
|
||||
}else{
|
||||
int rc = sqlite3PagerWrite(pPage->pDbPage);
|
||||
if( rc!=SQLITE_OK ){
|
||||
@ -5728,7 +5721,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
|
||||
if( rc==SQLITE_OK ){
|
||||
|
||||
u8 *pOut = &pSpace[4];
|
||||
u8 *pCell = pPage->aOvfl[0].pCell;
|
||||
u8 *pCell = pPage->apOvfl[0];
|
||||
u16 szCell = cellSizePtr(pPage, pCell);
|
||||
u8 *pStop;
|
||||
|
||||
@ -5838,7 +5831,7 @@ static int ptrmapCheckPages(MemPage **apPage, int nPage){
|
||||
** map entries are also updated so that the parent page is page pTo.
|
||||
**
|
||||
** If pFrom is currently carrying any overflow cells (entries in the
|
||||
** MemPage.aOvfl[] array), they are not copied to pTo.
|
||||
** MemPage.apOvfl[] array), they are not copied to pTo.
|
||||
**
|
||||
** Before returning, page pTo is reinitialized using btreeInitPage().
|
||||
**
|
||||
@ -5975,7 +5968,7 @@ static int balance_nonroot(
|
||||
** is called (indirectly) from sqlite3BtreeDelete().
|
||||
*/
|
||||
assert( pParent->nOverflow==0 || pParent->nOverflow==1 );
|
||||
assert( pParent->nOverflow==0 || pParent->aOvfl[0].idx==iParentIdx );
|
||||
assert( pParent->nOverflow==0 || pParent->aiOvfl[0]==iParentIdx );
|
||||
|
||||
if( !aOvflSpace ){
|
||||
return SQLITE_NOMEM;
|
||||
@ -6022,8 +6015,8 @@ static int balance_nonroot(
|
||||
nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow;
|
||||
if( (i--)==0 ) break;
|
||||
|
||||
if( i+nxDiv==pParent->aOvfl[0].idx && pParent->nOverflow ){
|
||||
apDiv[i] = pParent->aOvfl[0].pCell;
|
||||
if( i+nxDiv==pParent->aiOvfl[0] && pParent->nOverflow ){
|
||||
apDiv[i] = pParent->apOvfl[0];
|
||||
pgno = get4byte(apDiv[i]);
|
||||
szNew[i] = cellSizePtr(pParent, apDiv[i]);
|
||||
pParent->nOverflow = 0;
|
||||
@ -6464,7 +6457,7 @@ static int balance_nonroot(
|
||||
MemPage *pOld = apCopy[0];
|
||||
int nOverflow = pOld->nOverflow;
|
||||
int iNextOld = pOld->nCell + nOverflow;
|
||||
int iOverflow = (nOverflow ? pOld->aOvfl[0].idx : -1);
|
||||
int iOverflow = (nOverflow ? pOld->aiOvfl[0] : -1);
|
||||
j = 0; /* Current 'old' sibling page */
|
||||
k = 0; /* Current 'new' sibling page */
|
||||
for(i=0; i<nCell; i++){
|
||||
@ -6478,14 +6471,14 @@ static int balance_nonroot(
|
||||
iNextOld = i + !leafData + pOld->nCell + pOld->nOverflow;
|
||||
if( pOld->nOverflow ){
|
||||
nOverflow = pOld->nOverflow;
|
||||
iOverflow = i + !leafData + pOld->aOvfl[0].idx;
|
||||
iOverflow = i + !leafData + pOld->aiOvfl[0];
|
||||
}
|
||||
isDivider = !leafData;
|
||||
}
|
||||
|
||||
assert(nOverflow>0 || iOverflow<i );
|
||||
assert(nOverflow<2 || pOld->aOvfl[0].idx==pOld->aOvfl[1].idx-1);
|
||||
assert(nOverflow<3 || pOld->aOvfl[1].idx==pOld->aOvfl[2].idx-1);
|
||||
assert(nOverflow<2 || pOld->aiOvfl[0]==pOld->aiOvfl[1]-1);
|
||||
assert(nOverflow<3 || pOld->aiOvfl[1]==pOld->aiOvfl[2]-1);
|
||||
if( i==iOverflow ){
|
||||
isDivider = 1;
|
||||
if( (--nOverflow)>0 ){
|
||||
@ -6606,7 +6599,10 @@ static int balance_deeper(MemPage *pRoot, MemPage **ppChild){
|
||||
TRACE(("BALANCE: copy root %d into %d\n", pRoot->pgno, pChild->pgno));
|
||||
|
||||
/* Copy the overflow cells from pRoot to pChild */
|
||||
memcpy(pChild->aOvfl, pRoot->aOvfl, pRoot->nOverflow*sizeof(pRoot->aOvfl[0]));
|
||||
memcpy(pChild->aiOvfl, pRoot->aiOvfl,
|
||||
pRoot->nOverflow*sizeof(pRoot->aiOvfl[0]));
|
||||
memcpy(pChild->apOvfl, pRoot->apOvfl,
|
||||
pRoot->nOverflow*sizeof(pRoot->apOvfl[0]));
|
||||
pChild->nOverflow = pRoot->nOverflow;
|
||||
|
||||
/* Zero the contents of pRoot. Then install pChild as the right-child. */
|
||||
@ -6669,7 +6665,7 @@ static int balance(BtCursor *pCur){
|
||||
#ifndef SQLITE_OMIT_QUICKBALANCE
|
||||
if( pPage->hasData
|
||||
&& pPage->nOverflow==1
|
||||
&& pPage->aOvfl[0].idx==pPage->nCell
|
||||
&& pPage->aiOvfl[0]==pPage->nCell
|
||||
&& pParent->pgno!=1
|
||||
&& pParent->nCell==iIdx
|
||||
){
|
||||
|
@ -57,10 +57,9 @@ int sqlite3BtreeOpen(
|
||||
** pager.h.
|
||||
*/
|
||||
#define BTREE_OMIT_JOURNAL 1 /* Do not create or use a rollback journal */
|
||||
#define BTREE_NO_READLOCK 2 /* Omit readlocks on readonly files */
|
||||
#define BTREE_MEMORY 4 /* This is an in-memory DB */
|
||||
#define BTREE_SINGLE 8 /* The file contains at most 1 b-tree */
|
||||
#define BTREE_UNORDERED 16 /* Use of a hash implementation is OK */
|
||||
#define BTREE_MEMORY 2 /* This is an in-memory DB */
|
||||
#define BTREE_SINGLE 4 /* The file contains at most 1 b-tree */
|
||||
#define BTREE_UNORDERED 8 /* Use of a hash implementation is OK */
|
||||
|
||||
int sqlite3BtreeClose(Btree*);
|
||||
int sqlite3BtreeSetCacheSize(Btree*,int);
|
||||
|
@ -284,10 +284,9 @@ struct MemPage {
|
||||
u16 nFree; /* Number of free bytes on the page */
|
||||
u16 nCell; /* Number of cells on this page, local and ovfl */
|
||||
u16 maskPage; /* Mask for page offset */
|
||||
struct _OvflCell { /* Cells that will not fit on aData[] */
|
||||
u8 *pCell; /* Pointers to the body of the overflow cell */
|
||||
u16 idx; /* Insert this cell before idx-th non-overflow cell */
|
||||
} aOvfl[5];
|
||||
u16 aiOvfl[5]; /* Insert the i-th overflow cell before the aiOvfl-th
|
||||
** non-overflow cell */
|
||||
u8 *apOvfl[5]; /* Pointers to the body of overflow cells */
|
||||
BtShared *pBt; /* Pointer to BtShared that this page is part of */
|
||||
u8 *aData; /* Pointer to disk image of the page data */
|
||||
u8 *aDataEnd; /* One byte past the end of usable data */
|
||||
@ -495,6 +494,9 @@ struct BtCursor {
|
||||
BtShared *pBt; /* The BtShared this cursor points to */
|
||||
BtCursor *pNext, *pPrev; /* Forms a linked list of all cursors */
|
||||
struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */
|
||||
#ifndef SQLITE_OMIT_INCRBLOB
|
||||
Pgno *aOverflow; /* Cache of overflow page locations */
|
||||
#endif
|
||||
Pgno pgnoRoot; /* The root page of this tree */
|
||||
sqlite3_int64 cachedRowid; /* Next rowid cache. 0 means not valid */
|
||||
CellInfo info; /* A parse of the cell we are pointing at */
|
||||
@ -506,7 +508,6 @@ struct BtCursor {
|
||||
u8 validNKey; /* True if info.nKey is valid */
|
||||
u8 eState; /* One of the CURSOR_XXX constants (see below) */
|
||||
#ifndef SQLITE_OMIT_INCRBLOB
|
||||
Pgno *aOverflow; /* Cache of overflow page locations */
|
||||
u8 isIncrblobHandle; /* True if this cursor is an incr. io handle */
|
||||
#endif
|
||||
i16 iPage; /* Index of current page in apPage */
|
||||
@ -635,8 +636,8 @@ typedef struct IntegrityCk IntegrityCk;
|
||||
struct IntegrityCk {
|
||||
BtShared *pBt; /* The tree being checked out */
|
||||
Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */
|
||||
Pgno nPage; /* Number of pages in the database */
|
||||
int *anRef; /* Number of times each page is referenced */
|
||||
Pgno nPage; /* Number of pages in the database */
|
||||
int mxErr; /* Stop accumulating errors when this reaches zero */
|
||||
int nErr; /* Number of messages written to zErrMsg so far */
|
||||
int mallocFailed; /* A memory allocation error has occurred */
|
||||
|
20
src/build.c
20
src/build.c
@ -1638,7 +1638,6 @@ void sqlite3EndTable(
|
||||
return;
|
||||
}
|
||||
pParse->pNewTable = 0;
|
||||
db->nTable++;
|
||||
db->flags |= SQLITE_InternChanges;
|
||||
|
||||
#ifndef SQLITE_OMIT_ALTERTABLE
|
||||
@ -3059,27 +3058,23 @@ void *sqlite3ArrayAllocate(
|
||||
sqlite3 *db, /* Connection to notify of malloc failures */
|
||||
void *pArray, /* Array of objects. Might be reallocated */
|
||||
int szEntry, /* Size of each object in the array */
|
||||
int initSize, /* Suggested initial allocation, in elements */
|
||||
int *pnEntry, /* Number of objects currently in use */
|
||||
int *pnAlloc, /* Current size of the allocation, in elements */
|
||||
int *pIdx /* Write the index of a new slot here */
|
||||
){
|
||||
char *z;
|
||||
if( *pnEntry >= *pnAlloc ){
|
||||
void *pNew;
|
||||
int newSize;
|
||||
newSize = (*pnAlloc)*2 + initSize;
|
||||
pNew = sqlite3DbRealloc(db, pArray, newSize*szEntry);
|
||||
int n = *pnEntry;
|
||||
if( (n & (n-1))==0 ){
|
||||
int sz = (n==0) ? 1 : 2*n;
|
||||
void *pNew = sqlite3DbRealloc(db, pArray, sz*szEntry);
|
||||
if( pNew==0 ){
|
||||
*pIdx = -1;
|
||||
return pArray;
|
||||
}
|
||||
*pnAlloc = sqlite3DbMallocSize(db, pNew)/szEntry;
|
||||
pArray = pNew;
|
||||
}
|
||||
z = (char*)pArray;
|
||||
memset(&z[*pnEntry * szEntry], 0, szEntry);
|
||||
*pIdx = *pnEntry;
|
||||
memset(&z[n * szEntry], 0, szEntry);
|
||||
*pIdx = n;
|
||||
++*pnEntry;
|
||||
return pArray;
|
||||
}
|
||||
@ -3095,15 +3090,12 @@ IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pToken){
|
||||
if( pList==0 ){
|
||||
pList = sqlite3DbMallocZero(db, sizeof(IdList) );
|
||||
if( pList==0 ) return 0;
|
||||
pList->nAlloc = 0;
|
||||
}
|
||||
pList->a = sqlite3ArrayAllocate(
|
||||
db,
|
||||
pList->a,
|
||||
sizeof(pList->a[0]),
|
||||
5,
|
||||
&pList->nId,
|
||||
&pList->nAlloc,
|
||||
&i
|
||||
);
|
||||
if( i<0 ){
|
||||
|
28
src/expr.c
28
src/expr.c
@ -856,8 +856,9 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){
|
||||
pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) );
|
||||
if( pNew==0 ) return 0;
|
||||
pNew->iECursor = 0;
|
||||
pNew->nExpr = pNew->nAlloc = p->nExpr;
|
||||
pNew->a = pItem = sqlite3DbMallocRaw(db, p->nExpr*sizeof(p->a[0]) );
|
||||
pNew->nExpr = i = p->nExpr;
|
||||
if( (flags & EXPRDUP_REDUCE)==0 ) for(i=1; i<p->nExpr; i+=i){}
|
||||
pNew->a = pItem = sqlite3DbMallocRaw(db, i*sizeof(p->a[0]) );
|
||||
if( pItem==0 ){
|
||||
sqlite3DbFree(db, pNew);
|
||||
return 0;
|
||||
@ -925,12 +926,15 @@ IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){
|
||||
if( p==0 ) return 0;
|
||||
pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) );
|
||||
if( pNew==0 ) return 0;
|
||||
pNew->nId = pNew->nAlloc = p->nId;
|
||||
pNew->nId = p->nId;
|
||||
pNew->a = sqlite3DbMallocRaw(db, p->nId*sizeof(p->a[0]) );
|
||||
if( pNew->a==0 ){
|
||||
sqlite3DbFree(db, pNew);
|
||||
return 0;
|
||||
}
|
||||
/* Note that because the size of the allocation for p->a[] is not
|
||||
** necessarily a power of two, sqlite3IdListAppend() may not be called
|
||||
** on the duplicate created by this function. */
|
||||
for(i=0; i<p->nId; i++){
|
||||
struct IdList_item *pNewItem = &pNew->a[i];
|
||||
struct IdList_item *pOldItem = &p->a[i];
|
||||
@ -992,17 +996,16 @@ ExprList *sqlite3ExprListAppend(
|
||||
if( pList==0 ){
|
||||
goto no_mem;
|
||||
}
|
||||
assert( pList->nAlloc==0 );
|
||||
}
|
||||
if( pList->nAlloc<=pList->nExpr ){
|
||||
pList->a = sqlite3DbMallocRaw(db, sizeof(pList->a[0]));
|
||||
if( pList->a==0 ) goto no_mem;
|
||||
}else if( (pList->nExpr & (pList->nExpr-1))==0 ){
|
||||
struct ExprList_item *a;
|
||||
int n = pList->nAlloc*2 + 4;
|
||||
a = sqlite3DbRealloc(db, pList->a, n*sizeof(pList->a[0]));
|
||||
assert( pList->nExpr>0 );
|
||||
a = sqlite3DbRealloc(db, pList->a, pList->nExpr*2*sizeof(pList->a[0]));
|
||||
if( a==0 ){
|
||||
goto no_mem;
|
||||
}
|
||||
pList->a = a;
|
||||
pList->nAlloc = sqlite3DbMallocSize(db, a)/sizeof(a[0]);
|
||||
}
|
||||
assert( pList->a!=0 );
|
||||
if( 1 ){
|
||||
@ -1093,8 +1096,7 @@ void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
|
||||
int i;
|
||||
struct ExprList_item *pItem;
|
||||
if( pList==0 ) return;
|
||||
assert( pList->a!=0 || (pList->nExpr==0 && pList->nAlloc==0) );
|
||||
assert( pList->nExpr<=pList->nAlloc );
|
||||
assert( pList->a!=0 || pList->nExpr==0 );
|
||||
for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
|
||||
sqlite3ExprDelete(db, pItem->pExpr);
|
||||
sqlite3DbFree(db, pItem->zName);
|
||||
@ -3775,9 +3777,7 @@ static int addAggInfoColumn(sqlite3 *db, AggInfo *pInfo){
|
||||
db,
|
||||
pInfo->aCol,
|
||||
sizeof(pInfo->aCol[0]),
|
||||
3,
|
||||
&pInfo->nColumn,
|
||||
&pInfo->nColumnAlloc,
|
||||
&i
|
||||
);
|
||||
return i;
|
||||
@ -3793,9 +3793,7 @@ static int addAggInfoFunc(sqlite3 *db, AggInfo *pInfo){
|
||||
db,
|
||||
pInfo->aFunc,
|
||||
sizeof(pInfo->aFunc[0]),
|
||||
3,
|
||||
&pInfo->nFunc,
|
||||
&pInfo->nFuncAlloc,
|
||||
&i
|
||||
);
|
||||
return i;
|
||||
|
17
src/func.c
17
src/func.c
@ -28,6 +28,14 @@ static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){
|
||||
return context->pColl;
|
||||
}
|
||||
|
||||
/*
|
||||
** Indicate that the accumulator load should be skipped on this
|
||||
** iteration of the aggregate loop.
|
||||
*/
|
||||
static void sqlite3SkipAccumulatorLoad(sqlite3_context *context){
|
||||
context->skipFlag = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** Implementation of the non-aggregate min() and max() functions
|
||||
*/
|
||||
@ -1334,11 +1342,12 @@ static void minmaxStep(
|
||||
Mem *pBest;
|
||||
UNUSED_PARAMETER(NotUsed);
|
||||
|
||||
if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
|
||||
pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest));
|
||||
if( !pBest ) return;
|
||||
|
||||
if( pBest->flags ){
|
||||
if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
|
||||
if( pBest->flags ) sqlite3SkipAccumulatorLoad(context);
|
||||
}else if( pBest->flags ){
|
||||
int max;
|
||||
int cmp;
|
||||
CollSeq *pColl = sqlite3GetFuncCollSeq(context);
|
||||
@ -1354,6 +1363,8 @@ static void minmaxStep(
|
||||
cmp = sqlite3MemCompare(pBest, pArg, pColl);
|
||||
if( (max && cmp<0) || (!max && cmp>0) ){
|
||||
sqlite3VdbeMemCopy(pBest, pArg);
|
||||
}else{
|
||||
sqlite3SkipAccumulatorLoad(context);
|
||||
}
|
||||
}else{
|
||||
sqlite3VdbeMemCopy(pBest, pArg);
|
||||
@ -1363,7 +1374,7 @@ static void minMaxFinalize(sqlite3_context *context){
|
||||
sqlite3_value *pRes;
|
||||
pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0);
|
||||
if( pRes ){
|
||||
if( ALWAYS(pRes->flags) ){
|
||||
if( pRes->flags ){
|
||||
sqlite3_result_value(context, pRes);
|
||||
}
|
||||
sqlite3VdbeMemRelease(pRes);
|
||||
|
@ -3016,7 +3016,8 @@ const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){
|
||||
*/
|
||||
int sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){
|
||||
const char *z = sqlite3_uri_parameter(zFilename, zParam);
|
||||
return z ? sqlite3GetBoolean(z) : (bDflt!=0);
|
||||
bDflt = bDflt!=0;
|
||||
return z ? sqlite3GetBoolean(z, bDflt) : bDflt;
|
||||
}
|
||||
|
||||
/*
|
||||
|
59
src/mem1.c
59
src/mem1.c
@ -15,7 +15,35 @@
|
||||
** to obtain the memory it needs.
|
||||
**
|
||||
** This file contains implementations of the low-level memory allocation
|
||||
** routines specified in the sqlite3_mem_methods object.
|
||||
** routines specified in the sqlite3_mem_methods object. The content of
|
||||
** this file is only used if SQLITE_SYSTEM_MALLOC is defined. The
|
||||
** SQLITE_SYSTEM_MALLOC macro is defined automatically if neither the
|
||||
** SQLITE_MEMDEBUG nor the SQLITE_WIN32_MALLOC macros are defined. The
|
||||
** default configuration is to use memory allocation routines in this
|
||||
** file.
|
||||
**
|
||||
** C-preprocessor macro summary:
|
||||
**
|
||||
** HAVE_MALLOC_USABLE_SIZE The configure script sets this symbol if
|
||||
** the malloc_usable_size() interface exists
|
||||
** on the target platform. Or, this symbol
|
||||
** can be set manually, if desired.
|
||||
** If an equivalent interface exists by
|
||||
** a different name, using a separate -D
|
||||
** option to rename it. This symbol will
|
||||
** be enabled automatically on windows
|
||||
** systems, and malloc_usable_size() will
|
||||
** be redefined to _msize(), unless the
|
||||
** SQLITE_WITHOUT_MSIZE macro is defined.
|
||||
**
|
||||
** SQLITE_WITHOUT_ZONEMALLOC Some older macs lack support for the zone
|
||||
** memory allocator. Set this symbol to enable
|
||||
** building on older macs.
|
||||
**
|
||||
** SQLITE_WITHOUT_MSIZE Set this symbol to disable the use of
|
||||
** _msize() on windows systems. This might
|
||||
** be necessary when compiling for Delphi,
|
||||
** for example.
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -27,17 +55,21 @@
|
||||
#ifdef SQLITE_SYSTEM_MALLOC
|
||||
|
||||
/*
|
||||
** Windows systems have malloc_usable_size() but it is called _msize()
|
||||
** Windows systems have malloc_usable_size() but it is called _msize().
|
||||
** The use of _msize() is automatic, but can be disabled by compiling
|
||||
** with -DSQLITE_WITHOUT_MSIZE
|
||||
*/
|
||||
#if !defined(HAVE_MALLOC_USABLE_SIZE) && SQLITE_OS_WIN
|
||||
#if !defined(HAVE_MALLOC_USABLE_SIZE) && SQLITE_OS_WIN \
|
||||
&& !defined(SQLITE_WITHOUT_MSIZE)
|
||||
# define HAVE_MALLOC_USABLE_SIZE 1
|
||||
# define malloc_usable_size _msize
|
||||
# define SQLITE_MALLOCSIZE _msize
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC)
|
||||
|
||||
/*
|
||||
** Use the zone allocator available on apple products
|
||||
** Use the zone allocator available on apple products unless the
|
||||
** SQLITE_WITHOUT_ZONEMALLOC symbol is defined.
|
||||
*/
|
||||
#include <sys/sysctl.h>
|
||||
#include <malloc/malloc.h>
|
||||
@ -52,17 +84,22 @@ static malloc_zone_t* _sqliteZone_;
|
||||
#else /* if not __APPLE__ */
|
||||
|
||||
/*
|
||||
** Use standard C library malloc and free on non-Apple systems.
|
||||
** Use standard C library malloc and free on non-Apple systems.
|
||||
** Also used by Apple systems if SQLITE_WITHOUT_ZONEMALLOC is defined.
|
||||
*/
|
||||
#define SQLITE_MALLOC(x) malloc(x)
|
||||
#define SQLITE_FREE(x) free(x)
|
||||
#define SQLITE_REALLOC(x,y) realloc((x),(y))
|
||||
|
||||
#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLOC_USABLE_SIZE)
|
||||
# include <malloc.h> /* Needed for malloc_usable_size on linux */
|
||||
#endif
|
||||
#ifdef HAVE_MALLOC_USABLE_SIZE
|
||||
#include <malloc.h>
|
||||
#define SQLITE_MALLOCSIZE(x) malloc_usable_size(x)
|
||||
# ifndef SQLITE_MALLOCSIZE
|
||||
# define SQLITE_MALLOCSIZE(x) malloc_usable_size(x)
|
||||
# endif
|
||||
#else
|
||||
#undef SQLITE_MALLOCSIZE
|
||||
# undef SQLITE_MALLOCSIZE
|
||||
#endif
|
||||
|
||||
#endif /* __APPLE__ or not __APPLE__ */
|
||||
@ -184,7 +221,7 @@ static int sqlite3MemRoundup(int n){
|
||||
** Initialize this module.
|
||||
*/
|
||||
static int sqlite3MemInit(void *NotUsed){
|
||||
#if defined(__APPLE__)
|
||||
#if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC)
|
||||
int cpuCount;
|
||||
size_t len;
|
||||
if( _sqliteZone_ ){
|
||||
|
18
src/os.h
18
src/os.h
@ -91,11 +91,23 @@
|
||||
|
||||
/*
|
||||
** Determine if we are dealing with Windows NT.
|
||||
**
|
||||
** We ought to be able to determine if we are compiling for win98 or winNT
|
||||
** using the _WIN32_WINNT macro as follows:
|
||||
**
|
||||
** #if defined(_WIN32_WINNT)
|
||||
** # define SQLITE_OS_WINNT 1
|
||||
** #else
|
||||
** # define SQLITE_OS_WINNT 0
|
||||
** #endif
|
||||
**
|
||||
** However, vs2005 does not set _WIN32_WINNT by default, as it ought to,
|
||||
** so the above test does not work. We'll just assume that everything is
|
||||
** winNT unless the programmer explicitly says otherwise by setting
|
||||
** SQLITE_OS_WINNT to 0.
|
||||
*/
|
||||
#if defined(_WIN32_WINNT)
|
||||
#if SQLITE_OS_WIN && !defined(SQLITE_OS_WINNT)
|
||||
# define SQLITE_OS_WINNT 1
|
||||
#else
|
||||
# define SQLITE_OS_WINNT 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -5413,7 +5413,7 @@ static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){
|
||||
memset(zBuf, 0, nBuf);
|
||||
#if !defined(SQLITE_TEST)
|
||||
{
|
||||
int pid, fd;
|
||||
int pid, fd, got;
|
||||
fd = robust_open("/dev/urandom", O_RDONLY, 0);
|
||||
if( fd<0 ){
|
||||
time_t t;
|
||||
@ -5424,7 +5424,7 @@ static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){
|
||||
assert( sizeof(t)+sizeof(pid)<=(size_t)nBuf );
|
||||
nBuf = sizeof(t) + sizeof(pid);
|
||||
}else{
|
||||
do{ nBuf = osRead(fd, zBuf, nBuf); }while( nBuf<0 && errno==EINTR );
|
||||
do{ got = osRead(fd, zBuf, nBuf); }while( got<0 && errno==EINTR );
|
||||
robust_close(0, fd, __LINE__);
|
||||
}
|
||||
}
|
||||
|
24
src/pager.c
24
src/pager.c
@ -612,7 +612,6 @@ struct Pager {
|
||||
u8 exclusiveMode; /* Boolean. True if locking_mode==EXCLUSIVE */
|
||||
u8 journalMode; /* One of the PAGER_JOURNALMODE_* values */
|
||||
u8 useJournal; /* Use a rollback journal on this file */
|
||||
u8 noReadlock; /* Do not bother to obtain readlocks */
|
||||
u8 noSync; /* Do not sync the journal if true */
|
||||
u8 fullSync; /* Do extra syncs of the journal for robustness */
|
||||
u8 ckptSyncFlags; /* SYNC_NORMAL or SYNC_FULL for checkpoint */
|
||||
@ -860,7 +859,7 @@ static int assert_pager_state(Pager *p){
|
||||
case PAGER_READER:
|
||||
assert( pPager->errCode==SQLITE_OK );
|
||||
assert( p->eLock!=UNKNOWN_LOCK );
|
||||
assert( p->eLock>=SHARED_LOCK || p->noReadlock );
|
||||
assert( p->eLock>=SHARED_LOCK );
|
||||
break;
|
||||
|
||||
case PAGER_WRITER_LOCKED:
|
||||
@ -3069,7 +3068,7 @@ static int pagerPagecount(Pager *pPager, Pgno *pnPage){
|
||||
** contains no valid committed transactions.
|
||||
*/
|
||||
assert( pPager->eState==PAGER_OPEN );
|
||||
assert( pPager->eLock>=SHARED_LOCK || pPager->noReadlock );
|
||||
assert( pPager->eLock>=SHARED_LOCK );
|
||||
nPage = sqlite3WalDbsize(pPager->pWal);
|
||||
|
||||
/* If the database size was not available from the WAL sub-system,
|
||||
@ -3124,7 +3123,7 @@ static int pagerPagecount(Pager *pPager, Pgno *pnPage){
|
||||
static int pagerOpenWalIfPresent(Pager *pPager){
|
||||
int rc = SQLITE_OK;
|
||||
assert( pPager->eState==PAGER_OPEN );
|
||||
assert( pPager->eLock>=SHARED_LOCK || pPager->noReadlock );
|
||||
assert( pPager->eLock>=SHARED_LOCK );
|
||||
|
||||
if( !pPager->tempFile ){
|
||||
int isWal; /* True if WAL file exists */
|
||||
@ -4287,7 +4286,7 @@ static int pagerStress(void *p, PgHdr *pPg){
|
||||
**
|
||||
** The flags argument is used to specify properties that affect the
|
||||
** operation of the pager. It should be passed some bitwise combination
|
||||
** of the PAGER_OMIT_JOURNAL and PAGER_NO_READLOCK flags.
|
||||
** of the PAGER_* flags.
|
||||
**
|
||||
** The vfsFlags parameter is a bitmask to pass to the flags parameter
|
||||
** of the xOpen() method of the supplied VFS when opening files.
|
||||
@ -4318,7 +4317,6 @@ int sqlite3PagerOpen(
|
||||
char *zPathname = 0; /* Full path to database file */
|
||||
int nPathname = 0; /* Number of bytes in zPathname */
|
||||
int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */
|
||||
int noReadlock = (flags & PAGER_NO_READLOCK)!=0; /* True to omit read-lock */
|
||||
int pcacheSize = sqlite3PcacheSize(); /* Bytes to allocate for PCache */
|
||||
u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */
|
||||
const char *zUri = 0; /* URI args to copy */
|
||||
@ -4525,7 +4523,6 @@ int sqlite3PagerOpen(
|
||||
IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename))
|
||||
|
||||
pPager->useJournal = (u8)useJournal;
|
||||
pPager->noReadlock = (noReadlock && readOnly) ?1:0;
|
||||
/* pPager->stmtOpen = 0; */
|
||||
/* pPager->stmtInUse = 0; */
|
||||
/* pPager->nRef = 0; */
|
||||
@ -4747,14 +4744,11 @@ int sqlite3PagerSharedLock(Pager *pPager){
|
||||
int bHotJournal = 1; /* True if there exists a hot journal-file */
|
||||
|
||||
assert( !MEMDB );
|
||||
assert( pPager->noReadlock==0 || pPager->readOnly );
|
||||
|
||||
if( pPager->noReadlock==0 ){
|
||||
rc = pager_wait_on_lock(pPager, SHARED_LOCK);
|
||||
if( rc!=SQLITE_OK ){
|
||||
assert( pPager->eLock==NO_LOCK || pPager->eLock==UNKNOWN_LOCK );
|
||||
goto failed;
|
||||
}
|
||||
rc = pager_wait_on_lock(pPager, SHARED_LOCK);
|
||||
if( rc!=SQLITE_OK ){
|
||||
assert( pPager->eLock==NO_LOCK || pPager->eLock==UNKNOWN_LOCK );
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* If a journal file exists, and there is no RESERVED lock on the
|
||||
@ -6762,7 +6756,7 @@ static int pagerOpenWal(Pager *pPager){
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
assert( pPager->pWal==0 && pPager->tempFile==0 );
|
||||
assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK || pPager->noReadlock);
|
||||
assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK );
|
||||
|
||||
/* If the pager is already in exclusive-mode, the WAL module will use
|
||||
** heap-memory for the wal-index instead of the VFS shared-memory
|
||||
|
@ -58,8 +58,7 @@ typedef struct PgHdr DbPage;
|
||||
** NOTE: These values must match the corresponding BTREE_ values in btree.h.
|
||||
*/
|
||||
#define PAGER_OMIT_JOURNAL 0x0001 /* Do not use a rollback journal */
|
||||
#define PAGER_NO_READLOCK 0x0002 /* Omit readlocks on readonly files */
|
||||
#define PAGER_MEMORY 0x0004 /* In-memory database */
|
||||
#define PAGER_MEMORY 0x0002 /* In-memory database */
|
||||
|
||||
/*
|
||||
** Valid values for the second argument to sqlite3PagerLockingMode().
|
||||
|
84
src/parse.y
84
src/parse.y
@ -94,6 +94,14 @@ struct TrigEvent { int a; IdList * b; };
|
||||
*/
|
||||
struct AttachKey { int type; Token key; };
|
||||
|
||||
/*
|
||||
** One or more VALUES claues
|
||||
*/
|
||||
struct ValueList {
|
||||
ExprList *pList;
|
||||
Select *pSelect;
|
||||
};
|
||||
|
||||
} // end %include
|
||||
|
||||
// Input is a single SQL command
|
||||
@ -573,20 +581,17 @@ using_opt(U) ::= . {U = 0;}
|
||||
%destructor orderby_opt {sqlite3ExprListDelete(pParse->db, $$);}
|
||||
%type sortlist {ExprList*}
|
||||
%destructor sortlist {sqlite3ExprListDelete(pParse->db, $$);}
|
||||
%type sortitem {Expr*}
|
||||
%destructor sortitem {sqlite3ExprDelete(pParse->db, $$);}
|
||||
|
||||
orderby_opt(A) ::= . {A = 0;}
|
||||
orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;}
|
||||
sortlist(A) ::= sortlist(X) COMMA sortitem(Y) sortorder(Z). {
|
||||
A = sqlite3ExprListAppend(pParse,X,Y);
|
||||
sortlist(A) ::= sortlist(X) COMMA expr(Y) sortorder(Z). {
|
||||
A = sqlite3ExprListAppend(pParse,X,Y.pExpr);
|
||||
if( A ) A->a[A->nExpr-1].sortOrder = (u8)Z;
|
||||
}
|
||||
sortlist(A) ::= sortitem(Y) sortorder(Z). {
|
||||
A = sqlite3ExprListAppend(pParse,0,Y);
|
||||
sortlist(A) ::= expr(Y) sortorder(Z). {
|
||||
A = sqlite3ExprListAppend(pParse,0,Y.pExpr);
|
||||
if( A && ALWAYS(A->a) ) A->a[0].sortOrder = (u8)Z;
|
||||
}
|
||||
sortitem(A) ::= expr(X). {A = X.pExpr;}
|
||||
|
||||
%type sortorder {int}
|
||||
|
||||
@ -679,9 +684,8 @@ setlist(A) ::= nm(X) EQ expr(Y). {
|
||||
|
||||
////////////////////////// The INSERT command /////////////////////////////////
|
||||
//
|
||||
cmd ::= insert_cmd(R) INTO fullname(X) inscollist_opt(F)
|
||||
VALUES LP itemlist(Y) RP.
|
||||
{sqlite3Insert(pParse, X, Y, 0, F, R);}
|
||||
cmd ::= insert_cmd(R) INTO fullname(X) inscollist_opt(F) valuelist(Y).
|
||||
{sqlite3Insert(pParse, X, Y.pList, Y.pSelect, F, R);}
|
||||
cmd ::= insert_cmd(R) INTO fullname(X) inscollist_opt(F) select(S).
|
||||
{sqlite3Insert(pParse, X, 0, S, F, R);}
|
||||
cmd ::= insert_cmd(R) INTO fullname(X) inscollist_opt(F) DEFAULT VALUES.
|
||||
@ -691,14 +695,46 @@ cmd ::= insert_cmd(R) INTO fullname(X) inscollist_opt(F) DEFAULT VALUES.
|
||||
insert_cmd(A) ::= INSERT orconf(R). {A = R;}
|
||||
insert_cmd(A) ::= REPLACE. {A = OE_Replace;}
|
||||
|
||||
// A ValueList is either a single VALUES clause or a comma-separated list
|
||||
// of VALUES clauses. If it is a single VALUES clause then the
|
||||
// ValueList.pList field points to the expression list of that clause.
|
||||
// If it is a list of VALUES clauses, then those clauses are transformed
|
||||
// into a set of SELECT statements without FROM clauses and connected by
|
||||
// UNION ALL and the ValueList.pSelect points to the right-most SELECT in
|
||||
// that compound.
|
||||
%type valuelist {struct ValueList}
|
||||
%destructor valuelist {
|
||||
sqlite3ExprListDelete(pParse->db, $$.pList);
|
||||
sqlite3SelectDelete(pParse->db, $$.pSelect);
|
||||
}
|
||||
valuelist(A) ::= VALUES LP nexprlist(X) RP. {
|
||||
A.pList = X;
|
||||
A.pSelect = 0;
|
||||
}
|
||||
|
||||
%type itemlist {ExprList*}
|
||||
%destructor itemlist {sqlite3ExprListDelete(pParse->db, $$);}
|
||||
|
||||
itemlist(A) ::= itemlist(X) COMMA expr(Y).
|
||||
{A = sqlite3ExprListAppend(pParse,X,Y.pExpr);}
|
||||
itemlist(A) ::= expr(X).
|
||||
{A = sqlite3ExprListAppend(pParse,0,X.pExpr);}
|
||||
// Since a list of VALUEs is inplemented as a compound SELECT, we have
|
||||
// to disable the value list option if compound SELECTs are disabled.
|
||||
%ifndef SQLITE_OMIT_COMPOUND_SELECT
|
||||
valuelist(A) ::= valuelist(X) COMMA LP exprlist(Y) RP. {
|
||||
Select *pRight = sqlite3SelectNew(pParse, Y, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
if( X.pList ){
|
||||
X.pSelect = sqlite3SelectNew(pParse, X.pList, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
X.pList = 0;
|
||||
}
|
||||
A.pList = 0;
|
||||
if( X.pSelect==0 || pRight==0 ){
|
||||
sqlite3SelectDelete(pParse->db, pRight);
|
||||
sqlite3SelectDelete(pParse->db, X.pSelect);
|
||||
A.pSelect = 0;
|
||||
}else{
|
||||
pRight->op = TK_ALL;
|
||||
pRight->pPrior = X.pSelect;
|
||||
pRight->selFlags |= SF_Values;
|
||||
pRight->pPrior->selFlags |= SF_Values;
|
||||
A.pSelect = pRight;
|
||||
}
|
||||
}
|
||||
%endif SQLITE_OMIT_COMPOUND_SELECT
|
||||
|
||||
%type inscollist_opt {IdList*}
|
||||
%destructor inscollist_opt {sqlite3IdListDelete(pParse->db, $$);}
|
||||
@ -1163,11 +1199,10 @@ nmnum(A) ::= ON(X). {A = X;}
|
||||
nmnum(A) ::= DELETE(X). {A = X;}
|
||||
nmnum(A) ::= DEFAULT(X). {A = X;}
|
||||
%endif SQLITE_OMIT_PRAGMA
|
||||
plus_num(A) ::= plus_opt number(X). {A = X;}
|
||||
plus_num(A) ::= PLUS number(X). {A = X;}
|
||||
plus_num(A) ::= number(X). {A = X;}
|
||||
minus_num(A) ::= MINUS number(X). {A = X;}
|
||||
number(A) ::= INTEGER|FLOAT(X). {A = X;}
|
||||
plus_opt ::= PLUS.
|
||||
plus_opt ::= .
|
||||
|
||||
//////////////////////////// The CREATE TRIGGER command /////////////////////
|
||||
|
||||
@ -1261,8 +1296,8 @@ trigger_cmd(A) ::=
|
||||
|
||||
// INSERT
|
||||
trigger_cmd(A) ::=
|
||||
insert_cmd(R) INTO trnm(X) inscollist_opt(F) VALUES LP itemlist(Y) RP.
|
||||
{A = sqlite3TriggerInsertStep(pParse->db, &X, F, Y, 0, R);}
|
||||
insert_cmd(R) INTO trnm(X) inscollist_opt(F) valuelist(Y).
|
||||
{A = sqlite3TriggerInsertStep(pParse->db, &X, F, Y.pList, Y.pSelect, R);}
|
||||
|
||||
trigger_cmd(A) ::= insert_cmd(R) INTO trnm(X) inscollist_opt(F) select(S).
|
||||
{A = sqlite3TriggerInsertStep(pParse->db, &X, F, 0, S, R);}
|
||||
@ -1356,8 +1391,9 @@ kwcolumn_opt ::= COLUMNKW.
|
||||
%ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
cmd ::= create_vtab. {sqlite3VtabFinishParse(pParse,0);}
|
||||
cmd ::= create_vtab LP vtabarglist RP(X). {sqlite3VtabFinishParse(pParse,&X);}
|
||||
create_vtab ::= createkw VIRTUAL TABLE nm(X) dbnm(Y) USING nm(Z). {
|
||||
sqlite3VtabBeginParse(pParse, &X, &Y, &Z);
|
||||
create_vtab ::= createkw VIRTUAL TABLE ifnotexists(E)
|
||||
nm(X) dbnm(Y) USING nm(Z). {
|
||||
sqlite3VtabBeginParse(pParse, &X, &Y, &Z, E);
|
||||
}
|
||||
vtabarglist ::= vtabarg.
|
||||
vtabarglist ::= vtabarglist COMMA vtabarg.
|
||||
|
@ -27,8 +27,8 @@ struct PgHdr {
|
||||
void *pData; /* Page data */
|
||||
void *pExtra; /* Extra content */
|
||||
PgHdr *pDirty; /* Transient list of dirty pages */
|
||||
Pgno pgno; /* Page number for this page */
|
||||
Pager *pPager; /* The pager this page is part of */
|
||||
Pgno pgno; /* Page number for this page */
|
||||
#ifdef SQLITE_CHECK_PAGES
|
||||
u32 pageHash; /* Hash of page content */
|
||||
#endif
|
||||
|
@ -76,6 +76,7 @@ struct PCache1 {
|
||||
unsigned int nMin; /* Minimum number of pages reserved */
|
||||
unsigned int nMax; /* Configured "cache_size" value */
|
||||
unsigned int n90pct; /* nMax*9/10 */
|
||||
unsigned int iMaxKey; /* Largest key seen since xTruncate() */
|
||||
|
||||
/* Hash table of all pages. The following variables may only be accessed
|
||||
** when the accessor is holding the PGroup mutex.
|
||||
@ -84,8 +85,6 @@ struct PCache1 {
|
||||
unsigned int nPage; /* Total number of pages in apHash */
|
||||
unsigned int nHash; /* Number of slots in apHash[] */
|
||||
PgHdr1 **apHash; /* Hash table for fast lookup by key */
|
||||
|
||||
unsigned int iMaxKey; /* Largest key seen since xTruncate() */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -129,8 +128,8 @@ static SQLITE_WSD struct PCacheGlobal {
|
||||
void *pStart, *pEnd; /* Bounds of pagecache malloc range */
|
||||
/* Above requires no mutex. Use mutex below for variable that follow. */
|
||||
sqlite3_mutex *mutex; /* Mutex for accessing the following: */
|
||||
int nFreeSlot; /* Number of unused pcache slots */
|
||||
PgFreeslot *pFree; /* Free page blocks */
|
||||
int nFreeSlot; /* Number of unused pcache slots */
|
||||
/* The following value requires a mutex to change. We skip the mutex on
|
||||
** reading because (1) most platforms read a 32-bit integer atomically and
|
||||
** (2) even if an incorrect value is read, no great harm is done since this
|
||||
|
24
src/pragma.c
24
src/pragma.c
@ -16,14 +16,15 @@
|
||||
/*
|
||||
** Interpret the given string as a safety level. Return 0 for OFF,
|
||||
** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or
|
||||
** unrecognized string argument.
|
||||
** unrecognized string argument. The FULL option is disallowed
|
||||
** if the omitFull parameter it 1.
|
||||
**
|
||||
** Note that the values returned are one less that the values that
|
||||
** should be passed into sqlite3BtreeSetSafetyLevel(). The is done
|
||||
** to support legacy SQL code. The safety level used to be boolean
|
||||
** and older scripts may have used numbers 0 for OFF and 1 for ON.
|
||||
*/
|
||||
static u8 getSafetyLevel(const char *z){
|
||||
static u8 getSafetyLevel(const char *z, int omitFull, int dflt){
|
||||
/* 123456789 123456789 */
|
||||
static const char zText[] = "onoffalseyestruefull";
|
||||
static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16};
|
||||
@ -34,19 +35,19 @@ static u8 getSafetyLevel(const char *z){
|
||||
return (u8)sqlite3Atoi(z);
|
||||
}
|
||||
n = sqlite3Strlen30(z);
|
||||
for(i=0; i<ArraySize(iLength); i++){
|
||||
for(i=0; i<ArraySize(iLength)-omitFull; i++){
|
||||
if( iLength[i]==n && sqlite3StrNICmp(&zText[iOffset[i]],z,n)==0 ){
|
||||
return iValue[i];
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
return dflt;
|
||||
}
|
||||
|
||||
/*
|
||||
** Interpret the given string as a boolean value.
|
||||
*/
|
||||
u8 sqlite3GetBoolean(const char *z){
|
||||
return getSafetyLevel(z)&1;
|
||||
u8 sqlite3GetBoolean(const char *z, int dflt){
|
||||
return getSafetyLevel(z,1,dflt)!=0;
|
||||
}
|
||||
|
||||
/* The sqlite3GetBoolean() function is used by other modules but the
|
||||
@ -189,7 +190,6 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
|
||||
#endif
|
||||
/* The following is VERY experimental */
|
||||
{ "writable_schema", SQLITE_WriteSchema|SQLITE_RecoveryMode },
|
||||
{ "omit_readlock", SQLITE_NoReadlock },
|
||||
|
||||
/* TODO: Maybe it shouldn't be possible to change the ReadUncommitted
|
||||
** flag if there are any active statements. */
|
||||
@ -221,7 +221,7 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
|
||||
mask &= ~(SQLITE_ForeignKeys);
|
||||
}
|
||||
|
||||
if( sqlite3GetBoolean(zRight) ){
|
||||
if( sqlite3GetBoolean(zRight, 0) ){
|
||||
db->flags |= mask;
|
||||
}else{
|
||||
db->flags &= ~mask;
|
||||
@ -437,7 +437,7 @@ void sqlite3Pragma(
|
||||
int b = -1;
|
||||
assert( pBt!=0 );
|
||||
if( zRight ){
|
||||
b = sqlite3GetBoolean(zRight);
|
||||
b = sqlite3GetBoolean(zRight, 0);
|
||||
}
|
||||
if( pId2->n==0 && b>=0 ){
|
||||
int ii;
|
||||
@ -842,7 +842,7 @@ void sqlite3Pragma(
|
||||
sqlite3ErrorMsg(pParse,
|
||||
"Safety level may not be changed inside a transaction");
|
||||
}else{
|
||||
pDb->safety_level = getSafetyLevel(zRight)+1;
|
||||
pDb->safety_level = getSafetyLevel(zRight,0,1)+1;
|
||||
}
|
||||
}
|
||||
}else
|
||||
@ -1041,7 +1041,7 @@ void sqlite3Pragma(
|
||||
#ifndef NDEBUG
|
||||
if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){
|
||||
if( zRight ){
|
||||
if( sqlite3GetBoolean(zRight) ){
|
||||
if( sqlite3GetBoolean(zRight, 0) ){
|
||||
sqlite3ParserTrace(stderr, "parser: ");
|
||||
}else{
|
||||
sqlite3ParserTrace(0, 0);
|
||||
@ -1055,7 +1055,7 @@ void sqlite3Pragma(
|
||||
*/
|
||||
if( sqlite3StrICmp(zLeft, "case_sensitive_like")==0 ){
|
||||
if( zRight ){
|
||||
sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight));
|
||||
sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight, 0));
|
||||
}
|
||||
}else
|
||||
|
||||
|
24
src/select.c
24
src/select.c
@ -73,6 +73,7 @@ Select *sqlite3SelectNew(
|
||||
pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ALL,0));
|
||||
}
|
||||
pNew->pEList = pEList;
|
||||
if( pSrc==0 ) pSrc = sqlite3DbMallocZero(db, sizeof(*pSrc));
|
||||
pNew->pSrc = pSrc;
|
||||
pNew->pWhere = pWhere;
|
||||
pNew->pGroupBy = pGroupBy;
|
||||
@ -1611,8 +1612,12 @@ static int multiSelect(
|
||||
*/
|
||||
assert( p->pEList && pPrior->pEList );
|
||||
if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
|
||||
sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
|
||||
" do not have the same number of result columns", selectOpName(p->op));
|
||||
if( p->selFlags & SF_Values ){
|
||||
sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms");
|
||||
}else{
|
||||
sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
|
||||
" do not have the same number of result columns", selectOpName(p->op));
|
||||
}
|
||||
rc = 1;
|
||||
goto multi_select_end;
|
||||
}
|
||||
@ -2228,7 +2233,7 @@ static int multiSelectOrderBy(
|
||||
pNew->flags |= EP_IntValue;
|
||||
pNew->u.iValue = i;
|
||||
pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
|
||||
pOrderBy->a[nOrderBy++].iOrderByCol = (u16)i;
|
||||
if( pOrderBy ) pOrderBy->a[nOrderBy++].iOrderByCol = (u16)i;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3591,6 +3596,8 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){
|
||||
static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
|
||||
Vdbe *v = pParse->pVdbe;
|
||||
int i;
|
||||
int regHit = 0;
|
||||
int addrHitTest = 0;
|
||||
struct AggInfo_func *pF;
|
||||
struct AggInfo_col *pC;
|
||||
|
||||
@ -3626,7 +3633,8 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
|
||||
if( !pColl ){
|
||||
pColl = pParse->db->pDfltColl;
|
||||
}
|
||||
sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
|
||||
if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem;
|
||||
sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ);
|
||||
}
|
||||
sqlite3VdbeAddOp4(v, OP_AggStep, 0, regAgg, pF->iMem,
|
||||
(void*)pF->pFunc, P4_FUNCDEF);
|
||||
@ -3649,12 +3657,18 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
|
||||
** Another solution would be to change the OP_SCopy used to copy cached
|
||||
** values to an OP_Copy.
|
||||
*/
|
||||
if( regHit ){
|
||||
addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit);
|
||||
}
|
||||
sqlite3ExprCacheClear(pParse);
|
||||
for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
|
||||
sqlite3ExprCode(pParse, pC->pExpr, pC->iMem);
|
||||
}
|
||||
pAggInfo->directMode = 0;
|
||||
sqlite3ExprCacheClear(pParse);
|
||||
if( addrHitTest ){
|
||||
sqlite3VdbeJumpHere(v, addrHitTest);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4595,4 +4609,4 @@ void sqlite3ExplainSelect(Vdbe *pVdbe, Select *p){
|
||||
|
||||
/* End of the structure debug printing code
|
||||
*****************************************************************************/
|
||||
#endif /* defined(SQLITE_TEST) || defined(SQLITE_DEBUG) */
|
||||
#endif /* defined(SQLITE_ENABLE_TREE_EXPLAIN) */
|
||||
|
138
src/shell.c
138
src/shell.c
@ -57,7 +57,7 @@
|
||||
# include <readline/history.h>
|
||||
#endif
|
||||
#if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1)
|
||||
# define readline(p) local_getline(p,stdin)
|
||||
# define readline(p) local_getline(p,stdin,0)
|
||||
# define add_history(X)
|
||||
# define read_history(X)
|
||||
# define write_history(X)
|
||||
@ -334,10 +334,11 @@ static void shellstaticFunc(
|
||||
** The interface is like "readline" but no command-line editing
|
||||
** is done.
|
||||
*/
|
||||
static char *local_getline(char *zPrompt, FILE *in){
|
||||
static char *local_getline(char *zPrompt, FILE *in, int csvFlag){
|
||||
char *zLine;
|
||||
int nLine;
|
||||
int n;
|
||||
int inQuote = 0;
|
||||
|
||||
if( zPrompt && *zPrompt ){
|
||||
printf("%s",zPrompt);
|
||||
@ -361,8 +362,11 @@ static char *local_getline(char *zPrompt, FILE *in){
|
||||
zLine[n] = 0;
|
||||
break;
|
||||
}
|
||||
while( zLine[n] ){ n++; }
|
||||
if( n>0 && zLine[n-1]=='\n' ){
|
||||
while( zLine[n] ){
|
||||
if( zLine[n]=='"' ) inQuote = !inQuote;
|
||||
n++;
|
||||
}
|
||||
if( n>0 && zLine[n-1]=='\n' && (!inQuote || !csvFlag) ){
|
||||
n--;
|
||||
if( n>0 && zLine[n-1]=='\r' ) n--;
|
||||
zLine[n] = 0;
|
||||
@ -383,7 +387,7 @@ static char *one_input_line(const char *zPrior, FILE *in){
|
||||
char *zPrompt;
|
||||
char *zResult;
|
||||
if( in!=0 ){
|
||||
return local_getline(0, in);
|
||||
return local_getline(0, in, 0);
|
||||
}
|
||||
if( zPrior && zPrior[0] ){
|
||||
zPrompt = continuePrompt;
|
||||
@ -614,8 +618,7 @@ static const char needCsvQuote[] = {
|
||||
/*
|
||||
** Output a single term of CSV. Actually, p->separator is used for
|
||||
** the separator, which may or may not be a comma. p->nullvalue is
|
||||
** the null value. Strings are quoted using ANSI-C rules. Numbers
|
||||
** appear outside of quotes.
|
||||
** the null value. Strings are quoted if necessary.
|
||||
*/
|
||||
static void output_csv(struct callback_data *p, const char *z, int bSep){
|
||||
FILE *out = p->out;
|
||||
@ -934,11 +937,14 @@ static char *appendText(char *zIn, char const *zAppend, char quote){
|
||||
|
||||
|
||||
/*
|
||||
** Execute a query statement that has a single result column. Print
|
||||
** that result column on a line by itself with a semicolon terminator.
|
||||
** Execute a query statement that will generate SQL output. Print
|
||||
** the result columns, comma-separated, on a line and then add a
|
||||
** semicolon terminator to the end of that line.
|
||||
**
|
||||
** This is used, for example, to show the schema of the database by
|
||||
** querying the SQLITE_MASTER table.
|
||||
** If the number of columns is 1 and that column contains text "--"
|
||||
** then write the semicolon on a separate line. That way, if a
|
||||
** "--" comment occurs at the end of the statement, the comment
|
||||
** won't consume the semicolon terminator.
|
||||
*/
|
||||
static int run_table_dump_query(
|
||||
struct callback_data *p, /* Query context */
|
||||
@ -947,6 +953,9 @@ static int run_table_dump_query(
|
||||
){
|
||||
sqlite3_stmt *pSelect;
|
||||
int rc;
|
||||
int nResult;
|
||||
int i;
|
||||
const char *z;
|
||||
rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0);
|
||||
if( rc!=SQLITE_OK || !pSelect ){
|
||||
fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
|
||||
@ -954,12 +963,24 @@ static int run_table_dump_query(
|
||||
return rc;
|
||||
}
|
||||
rc = sqlite3_step(pSelect);
|
||||
nResult = sqlite3_column_count(pSelect);
|
||||
while( rc==SQLITE_ROW ){
|
||||
if( zFirstRow ){
|
||||
fprintf(p->out, "%s", zFirstRow);
|
||||
zFirstRow = 0;
|
||||
}
|
||||
fprintf(p->out, "%s;\n", sqlite3_column_text(pSelect, 0));
|
||||
z = (const char*)sqlite3_column_text(pSelect, 0);
|
||||
fprintf(p->out, "%s", z);
|
||||
for(i=1; i<nResult; i++){
|
||||
fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
|
||||
}
|
||||
if( z==0 ) z = "";
|
||||
while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
|
||||
if( z[0] ){
|
||||
fprintf(p->out, "\n;\n");
|
||||
}else{
|
||||
fprintf(p->out, ";\n");
|
||||
}
|
||||
rc = sqlite3_step(pSelect);
|
||||
}
|
||||
rc = sqlite3_finalize(pSelect);
|
||||
@ -1266,6 +1287,7 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
|
||||
char *zTableInfo = 0;
|
||||
char *zTmp = 0;
|
||||
int nRow = 0;
|
||||
int kk;
|
||||
|
||||
zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
|
||||
zTableInfo = appendText(zTableInfo, zTable, '"');
|
||||
@ -1278,7 +1300,12 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
|
||||
}
|
||||
|
||||
zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
|
||||
zTmp = appendText(zTmp, zTable, '"');
|
||||
if( !isalpha(zTable[0]) ){
|
||||
kk = 0;
|
||||
}else{
|
||||
for(kk=1; isalnum(zTable[kk]); kk++){}
|
||||
}
|
||||
zTmp = appendText(zTmp, zTable, zTable[kk] ? '"' : 0);
|
||||
if( zTmp ){
|
||||
zSelect = appendText(zSelect, zTmp, '\'');
|
||||
}
|
||||
@ -1290,7 +1317,7 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
|
||||
zSelect = appendText(zSelect, zText, '"');
|
||||
rc = sqlite3_step(pTableInfo);
|
||||
if( rc==SQLITE_ROW ){
|
||||
zSelect = appendText(zSelect, ") || ',' || ", 0);
|
||||
zSelect = appendText(zSelect, "), ", 0);
|
||||
}else{
|
||||
zSelect = appendText(zSelect, ") ", 0);
|
||||
}
|
||||
@ -1769,12 +1796,15 @@ static int do_meta_command(char *zLine, struct callback_data *p){
|
||||
}
|
||||
sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
|
||||
zCommit = "COMMIT";
|
||||
while( (zLine = local_getline(0, in))!=0 ){
|
||||
char *z;
|
||||
while( (zLine = local_getline(0, in, 1))!=0 ){
|
||||
char *z, c;
|
||||
int inQuote = 0;
|
||||
lineno++;
|
||||
azCol[0] = zLine;
|
||||
for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
|
||||
if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
|
||||
for(i=0, z=zLine; (c = *z)!=0; z++){
|
||||
if( c=='"' ) inQuote = !inQuote;
|
||||
if( c=='\n' ) lineno++;
|
||||
if( !inQuote && c==p->separator[0] && strncmp(z,p->separator,nSep)==0 ){
|
||||
*z = 0;
|
||||
i++;
|
||||
if( i<nCol ){
|
||||
@ -1794,6 +1824,14 @@ static int do_meta_command(char *zLine, struct callback_data *p){
|
||||
break; /* from while */
|
||||
}
|
||||
for(i=0; i<nCol; i++){
|
||||
if( azCol[i][0]=='"' ){
|
||||
int k;
|
||||
for(z=azCol[i], j=1, k=0; z[j]; j++){
|
||||
if( z[j]=='"' ){ j++; if( z[j]==0 ) break; }
|
||||
z[k++] = z[j];
|
||||
}
|
||||
z[k] = 0;
|
||||
}
|
||||
sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
|
||||
}
|
||||
sqlite3_step(pStmt);
|
||||
@ -2666,29 +2704,30 @@ static int process_sqliterc(
|
||||
** Show available command line options
|
||||
*/
|
||||
static const char zOptions[] =
|
||||
" -help show this message\n"
|
||||
" -init filename read/process named file\n"
|
||||
" -echo print commands before execution\n"
|
||||
" -[no]header turn headers on or off\n"
|
||||
" -bail stop after hitting an error\n"
|
||||
" -interactive force interactive I/O\n"
|
||||
" -batch force batch I/O\n"
|
||||
" -column set output mode to 'column'\n"
|
||||
" -cmd command run \"command\" before reading stdin\n"
|
||||
" -csv set output mode to 'csv'\n"
|
||||
" -echo print commands before execution\n"
|
||||
" -init filename read/process named file\n"
|
||||
" -[no]header turn headers on or off\n"
|
||||
" -help show this message\n"
|
||||
" -html set output mode to HTML\n"
|
||||
" -interactive force interactive I/O\n"
|
||||
" -line set output mode to 'line'\n"
|
||||
" -list set output mode to 'list'\n"
|
||||
#ifdef SQLITE_ENABLE_MULTIPLEX
|
||||
" -multiplex enable the multiplexor VFS\n"
|
||||
#endif
|
||||
" -nullvalue 'text' set text string for NULL values\n"
|
||||
" -separator 'x' set output field separator (|)\n"
|
||||
" -stats print memory stats before each finalize\n"
|
||||
" -nullvalue 'text' set text string for NULL values\n"
|
||||
" -version show SQLite version\n"
|
||||
" -vfs NAME use NAME as the default VFS\n"
|
||||
#ifdef SQLITE_ENABLE_VFSTRACE
|
||||
" -vfstrace enable tracing of all VFS calls\n"
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_MULTIPLEX
|
||||
" -multiplex enable the multiplexor VFS\n"
|
||||
#endif
|
||||
;
|
||||
static void usage(int showDetail){
|
||||
fprintf(stderr,
|
||||
@ -2751,19 +2790,22 @@ int main(int argc, char **argv){
|
||||
char *z;
|
||||
if( argv[i][0]!='-' ) break;
|
||||
z = argv[i];
|
||||
if( z[0]=='-' && z[1]=='-' ) z++;
|
||||
if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
|
||||
if( z[1]=='-' ) z++;
|
||||
if( strcmp(z,"-separator")==0
|
||||
|| strcmp(z,"-nullvalue")==0
|
||||
|| strcmp(z,"-cmd")==0
|
||||
){
|
||||
i++;
|
||||
}else if( strcmp(argv[i],"-init")==0 ){
|
||||
}else if( strcmp(z,"-init")==0 ){
|
||||
i++;
|
||||
zInitFile = argv[i];
|
||||
/* Need to check for batch mode here to so we can avoid printing
|
||||
** informational messages (like from process_sqliterc) before
|
||||
** we do the actual processing of arguments later in a second pass.
|
||||
*/
|
||||
}else if( strcmp(argv[i],"-batch")==0 ){
|
||||
}else if( strcmp(z,"-batch")==0 ){
|
||||
stdin_is_interactive = 0;
|
||||
}else if( strcmp(argv[i],"-heap")==0 ){
|
||||
}else if( strcmp(z,"-heap")==0 ){
|
||||
#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
|
||||
int j, c;
|
||||
const char *zSize;
|
||||
@ -2780,7 +2822,7 @@ int main(int argc, char **argv){
|
||||
sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_VFSTRACE
|
||||
}else if( strcmp(argv[i],"-vfstrace")==0 ){
|
||||
}else if( strcmp(z,"-vfstrace")==0 ){
|
||||
extern int vfstrace_register(
|
||||
const char *zTraceName,
|
||||
const char *zOldVfsName,
|
||||
@ -2791,11 +2833,11 @@ int main(int argc, char **argv){
|
||||
vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_MULTIPLEX
|
||||
}else if( strcmp(argv[i],"-multiplex")==0 ){
|
||||
}else if( strcmp(z,"-multiplex")==0 ){
|
||||
extern int sqlite3_multiple_initialize(const char*,int);
|
||||
sqlite3_multiplex_initialize(0, 1);
|
||||
#endif
|
||||
}else if( strcmp(argv[i],"-vfs")==0 ){
|
||||
}else if( strcmp(z,"-vfs")==0 ){
|
||||
sqlite3_vfs *pVfs = sqlite3_vfs_find(argv[++i]);
|
||||
if( pVfs ){
|
||||
sqlite3_vfs_register(pVfs, 1);
|
||||
@ -2877,7 +2919,8 @@ int main(int argc, char **argv){
|
||||
}else if( strcmp(z,"-separator")==0 ){
|
||||
i++;
|
||||
if(i>=argc){
|
||||
fprintf(stderr,"%s: Error: missing argument for option: %s\n", Argv0, z);
|
||||
fprintf(stderr,"%s: Error: missing argument for option: %s\n",
|
||||
Argv0, z);
|
||||
fprintf(stderr,"Use -help for a list of options.\n");
|
||||
return 1;
|
||||
}
|
||||
@ -2886,7 +2929,8 @@ int main(int argc, char **argv){
|
||||
}else if( strcmp(z,"-nullvalue")==0 ){
|
||||
i++;
|
||||
if(i>=argc){
|
||||
fprintf(stderr,"%s: Error: missing argument for option: %s\n", Argv0, z);
|
||||
fprintf(stderr,"%s: Error: missing argument for option: %s\n",
|
||||
Argv0, z);
|
||||
fprintf(stderr,"Use -help for a list of options.\n");
|
||||
return 1;
|
||||
}
|
||||
@ -2921,8 +2965,26 @@ int main(int argc, char **argv){
|
||||
}else if( strcmp(z,"-multiplex")==0 ){
|
||||
i++;
|
||||
#endif
|
||||
}else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
|
||||
}else if( strcmp(z,"-help")==0 ){
|
||||
usage(1);
|
||||
}else if( strcmp(z,"-cmd")==0 ){
|
||||
if( i==argc-1 ) break;
|
||||
i++;
|
||||
z = argv[i];
|
||||
if( z[0]=='.' ){
|
||||
rc = do_meta_command(z, &data);
|
||||
if( rc && bail_on_error ) return rc;
|
||||
}else{
|
||||
open_db(&data);
|
||||
rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
|
||||
if( zErrMsg!=0 ){
|
||||
fprintf(stderr,"Error: %s\n", zErrMsg);
|
||||
if( bail_on_error ) return rc!=0 ? rc : 1;
|
||||
}else if( rc!=0 ){
|
||||
fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
|
||||
if( bail_on_error ) return rc;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
|
||||
fprintf(stderr,"Use -help for a list of options.\n");
|
||||
|
@ -2639,9 +2639,14 @@ int sqlite3_open_v2(
|
||||
**
|
||||
** The sqlite3_uri_boolean(F,P,B) routine assumes that P is a boolean
|
||||
** parameter and returns true (1) or false (0) according to the value
|
||||
** of P. The value of P is true if it is "yes" or "true" or "on" or
|
||||
** a non-zero number and is false otherwise. If P is not a query parameter
|
||||
** on F then sqlite3_uri_boolean(F,P,B) returns (B!=0).
|
||||
** of P. The sqlite3_uri_boolean(F,P,B) routine returns true (1) if the
|
||||
** value of query parameter P is one of "yes", "true", or "on" in any
|
||||
** case or if the value begins with a non-zero number. The
|
||||
** sqlite3_uri_boolean(F,P,B) routines returns false (0) if the value of
|
||||
** query parameter P is one of "no", "false", or "off" in any case or
|
||||
** if the value begins with a numeric zero. If P is not a query
|
||||
** parameter on F or if the value of P is does not match any of the
|
||||
** above, then sqlite3_uri_boolean(F,P,B) returns (B!=0).
|
||||
**
|
||||
** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a
|
||||
** 64-bit signed integer and returns that integer, or D if P does not
|
||||
|
169
src/sqliteInt.h
169
src/sqliteInt.h
@ -561,9 +561,13 @@ struct BusyHandler {
|
||||
|
||||
/*
|
||||
** The following value as a destructor means to use sqlite3DbFree().
|
||||
** This is an internal extension to SQLITE_STATIC and SQLITE_TRANSIENT.
|
||||
** The sqlite3DbFree() routine requires two parameters instead of the
|
||||
** one parameter that destructors normally want. So we have to introduce
|
||||
** this magic value that the code knows to handle differently. Any
|
||||
** pointer will work here as long as it is distinct from SQLITE_STATIC
|
||||
** and SQLITE_TRANSIENT.
|
||||
*/
|
||||
#define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3DbFree)
|
||||
#define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3MallocSize)
|
||||
|
||||
/*
|
||||
** When SQLITE_OMIT_WSD is defined, it means that the target platform does
|
||||
@ -794,35 +798,16 @@ struct FuncDefHash {
|
||||
|
||||
/*
|
||||
** Each database connection is an instance of the following structure.
|
||||
**
|
||||
** The sqlite.lastRowid records the last insert rowid generated by an
|
||||
** insert statement. Inserts on views do not affect its value. Each
|
||||
** trigger has its own context, so that lastRowid can be updated inside
|
||||
** triggers as usual. The previous value will be restored once the trigger
|
||||
** exits. Upon entering a before or instead of trigger, lastRowid is no
|
||||
** longer (since after version 2.8.12) reset to -1.
|
||||
**
|
||||
** The sqlite.nChange does not count changes within triggers and keeps no
|
||||
** context. It is reset at start of sqlite3_exec.
|
||||
** The sqlite.lsChange represents the number of changes made by the last
|
||||
** insert, update, or delete statement. It remains constant throughout the
|
||||
** length of a statement and is then updated by OP_SetCounts. It keeps a
|
||||
** context stack just like lastRowid so that the count of changes
|
||||
** within a trigger is not seen outside the trigger. Changes to views do not
|
||||
** affect the value of lsChange.
|
||||
** The sqlite.csChange keeps track of the number of current changes (since
|
||||
** the last statement) and is used to update sqlite_lsChange.
|
||||
**
|
||||
** The member variables sqlite.errCode, sqlite.zErrMsg and sqlite.zErrMsg16
|
||||
** store the most recent error code and, if applicable, string. The
|
||||
** internal function sqlite3Error() is used to set these variables
|
||||
** consistently.
|
||||
*/
|
||||
struct sqlite3 {
|
||||
sqlite3_vfs *pVfs; /* OS Interface */
|
||||
int nDb; /* Number of backends currently in use */
|
||||
struct Vdbe *pVdbe; /* List of active virtual machines */
|
||||
CollSeq *pDfltColl; /* The default collating sequence (BINARY) */
|
||||
sqlite3_mutex *mutex; /* Connection mutex */
|
||||
Db *aDb; /* All backends */
|
||||
int nDb; /* Number of backends currently in use */
|
||||
int flags; /* Miscellaneous flags. See below */
|
||||
i64 lastRowid; /* ROWID of most recent insert (see above) */
|
||||
unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */
|
||||
int errCode; /* Most recent error code (SQLITE_*) */
|
||||
int errMask; /* & result codes with this before returning */
|
||||
@ -833,27 +818,23 @@ struct sqlite3 {
|
||||
signed char nextAutovac; /* Autovac setting after VACUUM if >=0 */
|
||||
u8 suppressErr; /* Do not issue error messages if true */
|
||||
u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */
|
||||
u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */
|
||||
int nextPagesize; /* Pagesize after VACUUM if >0 */
|
||||
int nTable; /* Number of tables in the database */
|
||||
CollSeq *pDfltColl; /* The default collating sequence (BINARY) */
|
||||
i64 lastRowid; /* ROWID of most recent insert (see above) */
|
||||
u32 magic; /* Magic number for detect library misuse */
|
||||
int nChange; /* Value returned by sqlite3_changes() */
|
||||
int nTotalChange; /* Value returned by sqlite3_total_changes() */
|
||||
sqlite3_mutex *mutex; /* Connection mutex */
|
||||
int aLimit[SQLITE_N_LIMIT]; /* Limits */
|
||||
struct sqlite3InitInfo { /* Information used during initialization */
|
||||
int iDb; /* When back is being initialized */
|
||||
int newTnum; /* Rootpage of table being initialized */
|
||||
u8 iDb; /* Which db file is being initialized */
|
||||
u8 busy; /* TRUE if currently initializing */
|
||||
u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */
|
||||
} init;
|
||||
int nExtension; /* Number of loaded extensions */
|
||||
void **aExtension; /* Array of shared library handles */
|
||||
struct Vdbe *pVdbe; /* List of active virtual machines */
|
||||
int activeVdbeCnt; /* Number of VDBEs currently executing */
|
||||
int writeVdbeCnt; /* Number of active VDBEs that are writing */
|
||||
int vdbeExecCnt; /* Number of nested calls to VdbeExec() */
|
||||
int nExtension; /* Number of loaded extensions */
|
||||
void **aExtension; /* Array of shared library handles */
|
||||
void (*xTrace)(void*,const char*); /* Trace function */
|
||||
void *pTraceArg; /* Argument to the trace function */
|
||||
void (*xProfile)(void*,const char*,u64); /* Profiling function */
|
||||
@ -897,21 +878,20 @@ struct sqlite3 {
|
||||
int nProgressOps; /* Number of opcodes for progress callback */
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
int nVTrans; /* Allocated size of aVTrans */
|
||||
Hash aModule; /* populated by sqlite3_create_module() */
|
||||
VtabCtx *pVtabCtx; /* Context for active vtab connect/create */
|
||||
VTable **aVTrans; /* Virtual tables with open transactions */
|
||||
int nVTrans; /* Allocated size of aVTrans */
|
||||
VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */
|
||||
#endif
|
||||
FuncDefHash aFunc; /* Hash table of connection functions */
|
||||
Hash aCollSeq; /* All collating sequences */
|
||||
BusyHandler busyHandler; /* Busy callback */
|
||||
int busyTimeout; /* Busy handler timeout, in msec */
|
||||
Db aDbStatic[2]; /* Static space for the 2 default backends */
|
||||
Savepoint *pSavepoint; /* List of active savepoints */
|
||||
int busyTimeout; /* Busy handler timeout, in msec */
|
||||
int nSavepoint; /* Number of non-transaction savepoints */
|
||||
int nStatement; /* Number of nested statement-transactions */
|
||||
u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */
|
||||
i64 nDeferredCons; /* Net deferred constraints this transaction. */
|
||||
int *pnBytesFreed; /* If not NULL, increment this in DbFree() */
|
||||
|
||||
@ -954,8 +934,7 @@ struct sqlite3 {
|
||||
#define SQLITE_SqlTrace 0x00004000 /* Debug print SQL as it executes */
|
||||
#define SQLITE_VdbeListing 0x00008000 /* Debug listings of VDBE programs */
|
||||
#define SQLITE_WriteSchema 0x00010000 /* OK to update SQLITE_MASTER */
|
||||
#define SQLITE_NoReadlock 0x00020000 /* Readlocks are omitted when
|
||||
** accessing read-only databases */
|
||||
/* 0x00020000 Unused */
|
||||
#define SQLITE_IgnoreChecks 0x00040000 /* Do not enforce check constraints */
|
||||
#define SQLITE_ReadUncommitted 0x0080000 /* For shared-cache mode */
|
||||
#define SQLITE_LegacyFileFmt 0x00100000 /* Create new databases in format 1 */
|
||||
@ -1044,7 +1023,6 @@ struct FuncDestructor {
|
||||
#define SQLITE_FUNC_CASE 0x02 /* Case-sensitive LIKE-type function */
|
||||
#define SQLITE_FUNC_EPHEM 0x04 /* Ephemeral. Delete with VDBE */
|
||||
#define SQLITE_FUNC_NEEDCOLL 0x08 /* sqlite3GetFuncCollSeq() might be called */
|
||||
#define SQLITE_FUNC_PRIVATE 0x10 /* Allowed for internal use only */
|
||||
#define SQLITE_FUNC_COUNT 0x20 /* Built-in count(*) aggregate */
|
||||
#define SQLITE_FUNC_COALESCE 0x40 /* Built-in coalesce() or ifnull() function */
|
||||
|
||||
@ -1327,8 +1305,6 @@ struct Table {
|
||||
#define TF_HasPrimaryKey 0x04 /* Table has a primary key */
|
||||
#define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */
|
||||
#define TF_Virtual 0x10 /* Is a virtual table */
|
||||
#define TF_NeedMetadata 0x20 /* aCol[].zType and aCol[].pColl missing */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
@ -1490,19 +1466,19 @@ struct UnpackedRecord {
|
||||
*/
|
||||
struct Index {
|
||||
char *zName; /* Name of this index */
|
||||
int nColumn; /* Number of columns in the table used by this index */
|
||||
int *aiColumn; /* Which columns are used by this index. 1st is 0 */
|
||||
tRowcnt *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */
|
||||
Table *pTable; /* The SQL table being indexed */
|
||||
int tnum; /* Page containing root of this index in database file */
|
||||
u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
|
||||
u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */
|
||||
u8 bUnordered; /* Use this index for == or IN queries only */
|
||||
char *zColAff; /* String defining the affinity of each column */
|
||||
Index *pNext; /* The next index associated with the same table */
|
||||
Schema *pSchema; /* Schema containing this index */
|
||||
u8 *aSortOrder; /* Array of size Index.nColumn. True==DESC, False==ASC */
|
||||
char **azColl; /* Array of collation sequence names for index */
|
||||
int nColumn; /* Number of columns in the table used by this index */
|
||||
int tnum; /* Page containing root of this index in database file */
|
||||
u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
|
||||
u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */
|
||||
u8 bUnordered; /* Use this index for == or IN queries only */
|
||||
#ifdef SQLITE_ENABLE_STAT3
|
||||
int nSample; /* Number of elements in aSample[] */
|
||||
tRowcnt avgEq; /* Average nEq value for key values not in aSample */
|
||||
@ -1561,8 +1537,8 @@ struct AggInfo {
|
||||
** than the source table */
|
||||
int sortingIdx; /* Cursor number of the sorting index */
|
||||
int sortingIdxPTab; /* Cursor number of pseudo-table */
|
||||
ExprList *pGroupBy; /* The group by clause */
|
||||
int nSortingColumn; /* Number of columns in the sorting index */
|
||||
ExprList *pGroupBy; /* The group by clause */
|
||||
struct AggInfo_col { /* For each column used in source tables */
|
||||
Table *pTab; /* Source table */
|
||||
int iTable; /* Cursor number of the source table */
|
||||
@ -1572,7 +1548,6 @@ struct AggInfo {
|
||||
Expr *pExpr; /* The original expression */
|
||||
} *aCol;
|
||||
int nColumn; /* Number of used entries in aCol[] */
|
||||
int nColumnAlloc; /* Number of slots allocated for aCol[] */
|
||||
int nAccumulator; /* Number of columns that show through to the output.
|
||||
** Additional columns are used only as parameters to
|
||||
** aggregate functions */
|
||||
@ -1583,7 +1558,6 @@ struct AggInfo {
|
||||
int iDistinct; /* Ephemeral table used to enforce DISTINCT */
|
||||
} *aFunc;
|
||||
int nFunc; /* Number of entries in aFunc[] */
|
||||
int nFuncAlloc; /* Number of slots allocated for aFunc[] */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1780,9 +1754,8 @@ struct Expr {
|
||||
*/
|
||||
struct ExprList {
|
||||
int nExpr; /* Number of expressions on the list */
|
||||
int nAlloc; /* Number of entries allocated below */
|
||||
int iECursor; /* VDBE Cursor associated with this ExprList */
|
||||
struct ExprList_item {
|
||||
struct ExprList_item { /* For each expression in the list */
|
||||
Expr *pExpr; /* The list of expressions */
|
||||
char *zName; /* Token associated with this expression */
|
||||
char *zSpan; /* Original text of the expression */
|
||||
@ -1790,7 +1763,7 @@ struct ExprList {
|
||||
u8 done; /* A flag to indicate when processing is finished */
|
||||
u16 iOrderByCol; /* For ORDER BY, column number in result set */
|
||||
u16 iAlias; /* Index into Parse.aAlias[] for zName */
|
||||
} *a; /* One entry for each expression */
|
||||
} *a; /* Alloc a power of two greater or equal to nExpr */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1825,7 +1798,6 @@ struct IdList {
|
||||
int idx; /* Index in some Table.aCol[] of a column named zName */
|
||||
} *a;
|
||||
int nId; /* Number of identifiers on the list */
|
||||
int nAlloc; /* Number of entries allocated for a[] below */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -2069,6 +2041,9 @@ struct Select {
|
||||
u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
|
||||
char affinity; /* MakeRecord with this affinity for SRT_Set */
|
||||
u16 selFlags; /* Various SF_* values */
|
||||
int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */
|
||||
int addrOpenEphm[3]; /* OP_OpenEphem opcodes related to this select */
|
||||
double nSelectRow; /* Estimated number of result rows */
|
||||
SrcList *pSrc; /* The FROM clause */
|
||||
Expr *pWhere; /* The WHERE clause */
|
||||
ExprList *pGroupBy; /* The GROUP BY clause */
|
||||
@ -2079,9 +2054,6 @@ struct Select {
|
||||
Select *pRightmost; /* Right-most select in a compound select statement */
|
||||
Expr *pLimit; /* LIMIT expression. NULL means not used. */
|
||||
Expr *pOffset; /* OFFSET expression. NULL means not used. */
|
||||
int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */
|
||||
int addrOpenEphm[3]; /* OP_OpenEphem opcodes related to this select */
|
||||
double nSelectRow; /* Estimated number of result rows */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -2095,6 +2067,7 @@ struct Select {
|
||||
#define SF_Expanded 0x10 /* sqlite3SelectExpand() called on this */
|
||||
#define SF_HasTypeInfo 0x20 /* FROM subqueries have Table metadata */
|
||||
#define SF_UseSorter 0x40 /* Sort using a sorter */
|
||||
#define SF_Values 0x80 /* Synthesized from VALUES clause */
|
||||
|
||||
|
||||
/*
|
||||
@ -2172,10 +2145,10 @@ struct AutoincInfo {
|
||||
*/
|
||||
struct TriggerPrg {
|
||||
Trigger *pTrigger; /* Trigger this program was coded from */
|
||||
int orconf; /* Default ON CONFLICT policy */
|
||||
SubProgram *pProgram; /* Program implementing pTrigger/orconf */
|
||||
u32 aColmask[2]; /* Masks of old.*, new.* columns accessed */
|
||||
TriggerPrg *pNext; /* Next entry in Parse.pTriggerPrg list */
|
||||
SubProgram *pProgram; /* Program implementing pTrigger/orconf */
|
||||
int orconf; /* Default ON CONFLICT policy */
|
||||
u32 aColmask[2]; /* Masks of old.*, new.* columns accessed */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -2205,14 +2178,18 @@ struct TriggerPrg {
|
||||
*/
|
||||
struct Parse {
|
||||
sqlite3 *db; /* The main database structure */
|
||||
int rc; /* Return code from execution */
|
||||
char *zErrMsg; /* An error message */
|
||||
Vdbe *pVdbe; /* An engine for executing database bytecode */
|
||||
int rc; /* Return code from execution */
|
||||
u8 colNamesSet; /* TRUE after OP_ColumnName has been issued to pVdbe */
|
||||
u8 checkSchema; /* Causes schema cookie check after an error */
|
||||
u8 nested; /* Number of nested calls to the parser/code generator */
|
||||
u8 nTempReg; /* Number of temporary registers in aTempReg[] */
|
||||
u8 nTempInUse; /* Number of aTempReg[] currently checked out */
|
||||
u8 nColCache; /* Number of entries in aColCache[] */
|
||||
u8 iColCache; /* Next entry in aColCache[] to replace */
|
||||
u8 isMultiWrite; /* True if statement may modify/insert multiple rows */
|
||||
u8 mayAbort; /* True if statement may throw an ABORT exception */
|
||||
int aTempReg[8]; /* Holding area for temporary registers */
|
||||
int nRangeReg; /* Size of the temporary register block */
|
||||
int iRangeReg; /* First register in temporary register block */
|
||||
@ -2224,8 +2201,6 @@ struct Parse {
|
||||
int ckBase; /* Base register of data during check constraints */
|
||||
int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
|
||||
int iCacheCnt; /* Counter used to generate aColCache[].lru values */
|
||||
u8 nColCache; /* Number of entries in aColCache[] */
|
||||
u8 iColCache; /* Next entry in aColCache[] to replace */
|
||||
struct yColCache {
|
||||
int iTable; /* Table cursor number */
|
||||
int iColumn; /* Table column number */
|
||||
@ -2236,61 +2211,63 @@ struct Parse {
|
||||
} aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */
|
||||
yDbMask writeMask; /* Start a write transaction on these databases */
|
||||
yDbMask cookieMask; /* Bitmask of schema verified databases */
|
||||
u8 isMultiWrite; /* True if statement may affect/insert multiple rows */
|
||||
u8 mayAbort; /* True if statement may throw an ABORT exception */
|
||||
int cookieGoto; /* Address of OP_Goto to cookie verifier subroutine */
|
||||
int cookieValue[SQLITE_MAX_ATTACHED+2]; /* Values of cookies to verify */
|
||||
int regRowid; /* Register holding rowid of CREATE TABLE entry */
|
||||
int regRoot; /* Register holding root page number for new objects */
|
||||
int nMaxArg; /* Max args passed to user function by sub-program */
|
||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||
int nTableLock; /* Number of locks in aTableLock */
|
||||
TableLock *aTableLock; /* Required table locks for shared-cache mode */
|
||||
#endif
|
||||
int regRowid; /* Register holding rowid of CREATE TABLE entry */
|
||||
int regRoot; /* Register holding root page number for new objects */
|
||||
AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */
|
||||
int nMaxArg; /* Max args passed to user function by sub-program */
|
||||
|
||||
/* Information used while coding trigger programs. */
|
||||
Parse *pToplevel; /* Parse structure for main program (or NULL) */
|
||||
Table *pTriggerTab; /* Table triggers are being coded for */
|
||||
double nQueryLoop; /* Estimated number of iterations of a query */
|
||||
u32 oldmask; /* Mask of old.* columns referenced */
|
||||
u32 newmask; /* Mask of new.* columns referenced */
|
||||
u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */
|
||||
u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */
|
||||
u8 disableTriggers; /* True to disable triggers */
|
||||
double nQueryLoop; /* Estimated number of iterations of a query */
|
||||
|
||||
/* Above is constant between recursions. Below is reset before and after
|
||||
** each recursion */
|
||||
|
||||
int nVar; /* Number of '?' variables seen in the SQL so far */
|
||||
int nzVar; /* Number of available slots in azVar[] */
|
||||
char **azVar; /* Pointers to names of parameters */
|
||||
Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */
|
||||
int nAlias; /* Number of aliased result set columns */
|
||||
int *aAlias; /* Register used to hold aliased result */
|
||||
u8 explain; /* True if the EXPLAIN flag is found on the query */
|
||||
Token sNameToken; /* Token with unqualified schema object name */
|
||||
Token sLastToken; /* The last token parsed */
|
||||
const char *zTail; /* All SQL text past the last semicolon parsed */
|
||||
Table *pNewTable; /* A table being constructed by CREATE TABLE */
|
||||
int nVar; /* Number of '?' variables seen in the SQL so far */
|
||||
int nzVar; /* Number of available slots in azVar[] */
|
||||
u8 explain; /* True if the EXPLAIN flag is found on the query */
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
u8 declareVtab; /* True if inside sqlite3_declare_vtab() */
|
||||
int nVtabLock; /* Number of virtual tables to lock */
|
||||
#endif
|
||||
int nAlias; /* Number of aliased result set columns */
|
||||
int nHeight; /* Expression tree height of current sub-select */
|
||||
#ifndef SQLITE_OMIT_EXPLAIN
|
||||
int iSelectId; /* ID of current select for EXPLAIN output */
|
||||
int iNextSelectId; /* Next available select ID for EXPLAIN output */
|
||||
#endif
|
||||
char **azVar; /* Pointers to names of parameters */
|
||||
Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */
|
||||
int *aAlias; /* Register used to hold aliased result */
|
||||
const char *zTail; /* All SQL text past the last semicolon parsed */
|
||||
Table *pNewTable; /* A table being constructed by CREATE TABLE */
|
||||
Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */
|
||||
const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
|
||||
Token sNameToken; /* Token with unqualified schema object name */
|
||||
Token sLastToken; /* The last token parsed */
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
Token sArg; /* Complete text of a module argument */
|
||||
u8 declareVtab; /* True if inside sqlite3_declare_vtab() */
|
||||
int nVtabLock; /* Number of virtual tables to lock */
|
||||
Table **apVtabLock; /* Pointer to virtual tables needing locking */
|
||||
#endif
|
||||
int nHeight; /* Expression tree height of current sub-select */
|
||||
Table *pZombieTab; /* List of Table objects to delete after code gen */
|
||||
TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */
|
||||
|
||||
#ifndef SQLITE_OMIT_EXPLAIN
|
||||
int iSelectId;
|
||||
int iNextSelectId;
|
||||
Token sArg; /* Complete text of a module argument */
|
||||
Table **apVtabLock; /* Pointer to virtual tables needing locking */
|
||||
#endif
|
||||
Table *pZombieTab; /* List of Table objects to delete after code gen */
|
||||
TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */
|
||||
};
|
||||
|
||||
/*
|
||||
** Return true if currently inside an sqlite3_declare_vtab() call.
|
||||
*/
|
||||
#ifdef SQLITE_OMIT_VIRTUALTABLE
|
||||
#define IN_DECLARE_VTAB 0
|
||||
#else
|
||||
@ -2442,8 +2419,8 @@ struct StrAccum {
|
||||
*/
|
||||
typedef struct {
|
||||
sqlite3 *db; /* The database being initialized */
|
||||
int iDb; /* 0 for main database. 1 for TEMP, 2.. for ATTACHed */
|
||||
char **pzErrMsg; /* Error message stored here */
|
||||
int iDb; /* 0 for main database. 1 for TEMP, 2.. for ATTACHed */
|
||||
int rc; /* Result code stored here */
|
||||
} InitData;
|
||||
|
||||
@ -2768,7 +2745,7 @@ void sqlite3DeleteTable(sqlite3*, Table*);
|
||||
# define sqlite3AutoincrementEnd(X)
|
||||
#endif
|
||||
void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int);
|
||||
void *sqlite3ArrayAllocate(sqlite3*,void*,int,int,int*,int*,int*);
|
||||
void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*);
|
||||
IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*);
|
||||
int sqlite3IdListIndex(IdList*,const char*);
|
||||
SrcList *sqlite3SrcListEnlarge(sqlite3*, SrcList*, int, int);
|
||||
@ -3006,7 +2983,7 @@ void sqlite3FileSuffix3(const char*, char*);
|
||||
#else
|
||||
# define sqlite3FileSuffix3(X,Y)
|
||||
#endif
|
||||
u8 sqlite3GetBoolean(const char *z);
|
||||
u8 sqlite3GetBoolean(const char *z,int);
|
||||
|
||||
const void *sqlite3ValueText(sqlite3_value*, u8);
|
||||
int sqlite3ValueBytes(sqlite3_value*, u8);
|
||||
@ -3132,7 +3109,7 @@ void sqlite3AutoLoadExtensions(sqlite3*);
|
||||
# define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
|
||||
#endif
|
||||
void sqlite3VtabMakeWritable(Parse*,Table*);
|
||||
void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*);
|
||||
void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int);
|
||||
void sqlite3VtabFinishParse(Parse*, Token*);
|
||||
void sqlite3VtabArgInit(Parse*);
|
||||
void sqlite3VtabArgExtend(Parse*, Token*);
|
||||
|
19
src/test1.c
19
src/test1.c
@ -668,6 +668,7 @@ static int test_key(
|
||||
int argc, /* Number of arguments */
|
||||
char **argv /* Text of each argument */
|
||||
){
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
sqlite3 *db;
|
||||
const char *zKey;
|
||||
int nKey;
|
||||
@ -679,7 +680,6 @@ static int test_key(
|
||||
if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
|
||||
zKey = argv[2];
|
||||
nKey = strlen(zKey);
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
sqlite3_key(db, zKey, nKey);
|
||||
#endif
|
||||
return TCL_OK;
|
||||
@ -696,6 +696,7 @@ static int test_rekey(
|
||||
int argc, /* Number of arguments */
|
||||
char **argv /* Text of each argument */
|
||||
){
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
sqlite3 *db;
|
||||
const char *zKey;
|
||||
int nKey;
|
||||
@ -707,7 +708,6 @@ static int test_rekey(
|
||||
if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
|
||||
zKey = argv[2];
|
||||
nKey = strlen(zKey);
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
sqlite3_rekey(db, zKey, nKey);
|
||||
#endif
|
||||
return TCL_OK;
|
||||
@ -2369,7 +2369,6 @@ static int uses_stmt_journal(
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
sqlite3_stmt *pStmt;
|
||||
int rc;
|
||||
|
||||
if( objc!=2 ){
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||
@ -2378,7 +2377,7 @@ static int uses_stmt_journal(
|
||||
}
|
||||
|
||||
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
|
||||
rc = sqlite3_stmt_readonly(pStmt);
|
||||
sqlite3_stmt_readonly(pStmt);
|
||||
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(((Vdbe *)pStmt)->usesStmtJournal));
|
||||
return TCL_OK;
|
||||
}
|
||||
@ -3858,7 +3857,6 @@ static int test_open(
|
||||
){
|
||||
const char *zFilename;
|
||||
sqlite3 *db;
|
||||
int rc;
|
||||
char zBuf[100];
|
||||
|
||||
if( objc!=3 && objc!=2 && objc!=1 ){
|
||||
@ -3868,7 +3866,7 @@ static int test_open(
|
||||
}
|
||||
|
||||
zFilename = objc>1 ? Tcl_GetString(objv[1]) : 0;
|
||||
rc = sqlite3_open(zFilename, &db);
|
||||
sqlite3_open(zFilename, &db);
|
||||
|
||||
if( sqlite3TestMakePointerStr(interp, zBuf, db) ) return TCL_ERROR;
|
||||
Tcl_AppendResult(interp, zBuf, 0);
|
||||
@ -3957,7 +3955,6 @@ static int test_open16(
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
const void *zFilename;
|
||||
sqlite3 *db;
|
||||
int rc;
|
||||
char zBuf[100];
|
||||
|
||||
if( objc!=3 ){
|
||||
@ -3967,7 +3964,7 @@ static int test_open16(
|
||||
}
|
||||
|
||||
zFilename = Tcl_GetByteArrayFromObj(objv[1], 0);
|
||||
rc = sqlite3_open16(zFilename, &db);
|
||||
sqlite3_open16(zFilename, &db);
|
||||
|
||||
if( sqlite3TestMakePointerStr(interp, zBuf, db) ) return TCL_ERROR;
|
||||
Tcl_AppendResult(interp, zBuf, 0);
|
||||
@ -5114,8 +5111,6 @@ static int file_control_lockproxy_test(
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
sqlite3 *db;
|
||||
const char *zPwd;
|
||||
int nPwd;
|
||||
|
||||
if( objc!=3 ){
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||
@ -5125,7 +5120,6 @@ static int file_control_lockproxy_test(
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
zPwd = Tcl_GetStringFromObj(objv[2], &nPwd);
|
||||
|
||||
#if !defined(SQLITE_ENABLE_LOCKING_STYLE)
|
||||
# if defined(__APPLE__)
|
||||
@ -5138,8 +5132,11 @@ static int file_control_lockproxy_test(
|
||||
{
|
||||
char *testPath;
|
||||
int rc;
|
||||
int nPwd;
|
||||
const char *zPwd;
|
||||
char proxyPath[400];
|
||||
|
||||
zPwd = Tcl_GetStringFromObj(objv[2], &nPwd);
|
||||
if( sizeof(proxyPath)<nPwd+20 ){
|
||||
Tcl_AppendResult(interp, "PWD too big", (void*)0);
|
||||
return TCL_ERROR;
|
||||
|
@ -64,7 +64,6 @@ static int test_value_overhead(
|
||||
int repeat_count;
|
||||
int i;
|
||||
Mem val;
|
||||
const char *zVal;
|
||||
|
||||
if( objc!=3 ){
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||
@ -82,7 +81,7 @@ static int test_value_overhead(
|
||||
|
||||
for(i=0; i<repeat_count; i++){
|
||||
if( do_calls ){
|
||||
zVal = (char*)sqlite3_value_text(&val);
|
||||
sqlite3_value_text(&val);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -713,14 +713,14 @@ static int test_memdebug_settitle(
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
const char *zTitle;
|
||||
if( objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "TITLE");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
zTitle = Tcl_GetString(objv[1]);
|
||||
#ifdef SQLITE_MEMDEBUG
|
||||
{
|
||||
const char *zTitle;
|
||||
zTitle = Tcl_GetString(objv[1]);
|
||||
extern int sqlite3MemdebugSettitle(const char*);
|
||||
sqlite3MemdebugSettitle(zTitle);
|
||||
}
|
||||
@ -1033,7 +1033,6 @@ static int test_config_lookaside(
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
int rc;
|
||||
int sz, cnt;
|
||||
Tcl_Obj *pRet;
|
||||
if( objc!=3 ){
|
||||
@ -1049,7 +1048,7 @@ static int test_config_lookaside(
|
||||
Tcl_ListObjAppendElement(
|
||||
interp, pRet, Tcl_NewIntObj(sqlite3GlobalConfig.nLookaside)
|
||||
);
|
||||
rc = sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, cnt);
|
||||
sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, cnt);
|
||||
Tcl_SetObjResult(interp, pRet);
|
||||
return TCL_OK;
|
||||
}
|
||||
@ -1106,7 +1105,6 @@ static int test_config_heap(
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
static char *zBuf; /* Use this memory */
|
||||
static int szBuf; /* Bytes allocated for zBuf */
|
||||
int nByte; /* Size of buffer to pass to sqlite3_config() */
|
||||
int nMinAlloc; /* Size of minimum allocation */
|
||||
int rc; /* Return code of sqlite3_config() */
|
||||
@ -1124,11 +1122,9 @@ static int test_config_heap(
|
||||
if( nByte==0 ){
|
||||
free( zBuf );
|
||||
zBuf = 0;
|
||||
szBuf = 0;
|
||||
rc = sqlite3_config(SQLITE_CONFIG_HEAP, (void*)0, 0, 0);
|
||||
}else{
|
||||
zBuf = realloc(zBuf, nByte);
|
||||
szBuf = nByte;
|
||||
rc = sqlite3_config(SQLITE_CONFIG_HEAP, zBuf, nByte, nMinAlloc);
|
||||
}
|
||||
|
||||
|
@ -273,7 +273,6 @@ static int sqlthread_open(
|
||||
|
||||
const char *zFilename;
|
||||
sqlite3 *db;
|
||||
int rc;
|
||||
char zBuf[100];
|
||||
extern void Md5_Register(sqlite3*);
|
||||
|
||||
@ -281,11 +280,12 @@ static int sqlthread_open(
|
||||
UNUSED_PARAMETER(objc);
|
||||
|
||||
zFilename = Tcl_GetString(objv[2]);
|
||||
rc = sqlite3_open(zFilename, &db);
|
||||
sqlite3_open(zFilename, &db);
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
if( db && objc>=4 ){
|
||||
const char *zKey;
|
||||
int nKey;
|
||||
int rc;
|
||||
zKey = Tcl_GetStringFromObj(objv[3], &nKey);
|
||||
rc = sqlite3_key(db, zKey, nKey);
|
||||
if( rc!=SQLITE_OK ){
|
||||
|
19
src/vdbe.c
19
src/vdbe.c
@ -1341,19 +1341,26 @@ arithmetic_result_is_null:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: CollSeq * * P4
|
||||
/* Opcode: CollSeq P1 * * P4
|
||||
**
|
||||
** P4 is a pointer to a CollSeq struct. If the next call to a user function
|
||||
** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will
|
||||
** be returned. This is used by the built-in min(), max() and nullif()
|
||||
** functions.
|
||||
**
|
||||
** If P1 is not zero, then it is a register that a subsequent min() or
|
||||
** max() aggregate will set to 1 if the current row is not the minimum or
|
||||
** maximum. The P1 register is initialized to 0 by this instruction.
|
||||
**
|
||||
** The interface used by the implementation of the aforementioned functions
|
||||
** to retrieve the collation sequence set by this opcode is not available
|
||||
** publicly, only to user functions defined in func.c.
|
||||
*/
|
||||
case OP_CollSeq: {
|
||||
assert( pOp->p4type==P4_COLLSEQ );
|
||||
if( pOp->p1 ){
|
||||
sqlite3VdbeMemSetInt64(&aMem[pOp->p1], 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2863,7 +2870,7 @@ case OP_AutoCommit: {
|
||||
** throw an ABORT exception), a statement transaction may also be opened.
|
||||
** More specifically, a statement transaction is opened iff the database
|
||||
** connection is currently not in autocommit mode, or if there are other
|
||||
** active statements. A statement transaction allows the affects of this
|
||||
** active statements. A statement transaction allows the changes made by this
|
||||
** VDBE to be rolled back after an error without having to roll back the
|
||||
** entire transaction. If no error is encountered, the statement transaction
|
||||
** will automatically commit when the VDBE halts.
|
||||
@ -4885,6 +4892,7 @@ case OP_ParseSchema: {
|
||||
db->init.busy = 0;
|
||||
}
|
||||
}
|
||||
if( rc ) sqlite3ResetInternalSchema(db, -1);
|
||||
if( rc==SQLITE_NOMEM ){
|
||||
goto no_mem;
|
||||
}
|
||||
@ -5219,7 +5227,6 @@ case OP_Program: { /* jump */
|
||||
p->nOp = pProgram->nOp;
|
||||
p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor];
|
||||
p->nOnceFlag = pProgram->nOnce;
|
||||
p->nOp = pProgram->nOp;
|
||||
pc = -1;
|
||||
memset(p->aOnceFlag, 0, p->nOnceFlag);
|
||||
|
||||
@ -5408,6 +5415,7 @@ case OP_AggStep: {
|
||||
ctx.s.db = db;
|
||||
ctx.isError = 0;
|
||||
ctx.pColl = 0;
|
||||
ctx.skipFlag = 0;
|
||||
if( ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
|
||||
assert( pOp>p->aOp );
|
||||
assert( pOp[-1].p4type==P4_COLLSEQ );
|
||||
@ -5419,6 +5427,11 @@ case OP_AggStep: {
|
||||
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s));
|
||||
rc = ctx.isError;
|
||||
}
|
||||
if( ctx.skipFlag ){
|
||||
assert( pOp[-1].opcode==OP_CollSeq );
|
||||
i = pOp[-1].p1;
|
||||
if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1);
|
||||
}
|
||||
|
||||
sqlite3VdbeMemRelease(&ctx.s);
|
||||
|
||||
|
@ -115,21 +115,21 @@ typedef struct VdbeCursor VdbeCursor;
|
||||
typedef struct VdbeFrame VdbeFrame;
|
||||
struct VdbeFrame {
|
||||
Vdbe *v; /* VM this frame belongs to */
|
||||
int pc; /* Program Counter in parent (calling) frame */
|
||||
VdbeFrame *pParent; /* Parent of this frame, or NULL if parent is main */
|
||||
Op *aOp; /* Program instructions for parent frame */
|
||||
int nOp; /* Size of aOp array */
|
||||
Mem *aMem; /* Array of memory cells for parent frame */
|
||||
int nMem; /* Number of entries in aMem */
|
||||
u8 *aOnceFlag; /* Array of OP_Once flags for parent frame */
|
||||
int nOnceFlag; /* Number of entries in aOnceFlag */
|
||||
VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */
|
||||
u16 nCursor; /* Number of entries in apCsr */
|
||||
void *token; /* Copy of SubProgram.token */
|
||||
i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */
|
||||
u16 nCursor; /* Number of entries in apCsr */
|
||||
int pc; /* Program Counter in parent (calling) frame */
|
||||
int nOp; /* Size of aOp array */
|
||||
int nMem; /* Number of entries in aMem */
|
||||
int nOnceFlag; /* Number of entries in aOnceFlag */
|
||||
int nChildMem; /* Number of memory cells for child frame */
|
||||
int nChildCsr; /* Number of cursors for child frame */
|
||||
i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */
|
||||
int nChange; /* Statement changes (Vdbe.nChanges) */
|
||||
VdbeFrame *pParent; /* Parent of this frame, or NULL if parent is main */
|
||||
};
|
||||
|
||||
#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
|
||||
@ -256,8 +256,9 @@ struct sqlite3_context {
|
||||
VdbeFunc *pVdbeFunc; /* Auxilary data, if created. */
|
||||
Mem s; /* The return value is stored here */
|
||||
Mem *pMem; /* Memory cell used to store aggregate context */
|
||||
int isError; /* Error code returned by the function. */
|
||||
CollSeq *pColl; /* Collating sequence */
|
||||
int isError; /* Error code returned by the function. */
|
||||
int skipFlag; /* Skip skip accumulator loading if true */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -298,7 +299,6 @@ struct Vdbe {
|
||||
int nOp; /* Number of instructions in the program */
|
||||
int nOpAlloc; /* Number of slots allocated for aOp[] */
|
||||
int nLabel; /* Number of labels used */
|
||||
int nLabelAlloc; /* Number of slots allocated in aLabel[] */
|
||||
int *aLabel; /* Space to hold the labels */
|
||||
u16 nResColumn; /* Number of columns in one row of the result set */
|
||||
u16 nCursor; /* Number of slots in apCsr[] */
|
||||
|
@ -241,14 +241,11 @@ int sqlite3VdbeAddOp4Int(
|
||||
** Zero is returned if a malloc() fails.
|
||||
*/
|
||||
int sqlite3VdbeMakeLabel(Vdbe *p){
|
||||
int i;
|
||||
i = p->nLabel++;
|
||||
int i = p->nLabel++;
|
||||
assert( p->magic==VDBE_MAGIC_INIT );
|
||||
if( i>=p->nLabelAlloc ){
|
||||
int n = p->nLabelAlloc*2 + 5;
|
||||
p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel,
|
||||
n*sizeof(p->aLabel[0]));
|
||||
p->nLabelAlloc = sqlite3DbMallocSize(p->db, p->aLabel)/sizeof(p->aLabel[0]);
|
||||
if( (i & (i-1))==0 ){
|
||||
p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel,
|
||||
(i*2+1)*sizeof(p->aLabel[0]));
|
||||
}
|
||||
if( p->aLabel ){
|
||||
p->aLabel[i] = -1;
|
||||
@ -2293,12 +2290,6 @@ int sqlite3VdbeHalt(Vdbe *p){
|
||||
}
|
||||
p->nChange = 0;
|
||||
}
|
||||
|
||||
/* Rollback or commit any schema changes that occurred. */
|
||||
if( p->rc!=SQLITE_OK && db->flags&SQLITE_InternChanges ){
|
||||
sqlite3ResetInternalSchema(db, -1);
|
||||
db->flags = (db->flags | SQLITE_InternChanges);
|
||||
}
|
||||
|
||||
/* Release the locks */
|
||||
sqlite3VdbeLeave(p);
|
||||
|
@ -92,6 +92,7 @@ int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve){
|
||||
memcpy(pMem->zMalloc, pMem->z, pMem->n);
|
||||
}
|
||||
if( pMem->flags&MEM_Dyn && pMem->xDel ){
|
||||
assert( pMem->xDel!=SQLITE_DYNAMIC );
|
||||
pMem->xDel((void *)(pMem->z));
|
||||
}
|
||||
|
||||
@ -271,6 +272,7 @@ void sqlite3VdbeMemReleaseExternal(Mem *p){
|
||||
sqlite3VdbeMemRelease(p);
|
||||
}else if( p->flags&MEM_Dyn && p->xDel ){
|
||||
assert( (p->flags&MEM_RowSet)==0 );
|
||||
assert( p->xDel!=SQLITE_DYNAMIC );
|
||||
p->xDel((void *)p->z);
|
||||
p->xDel = 0;
|
||||
}else if( p->flags&MEM_RowSet ){
|
||||
@ -413,8 +415,14 @@ void sqlite3VdbeIntegerAffinity(Mem *pMem){
|
||||
** true and could be omitted. But we leave it in because other
|
||||
** architectures might behave differently.
|
||||
*/
|
||||
if( pMem->r==(double)pMem->u.i && pMem->u.i>SMALLEST_INT64
|
||||
&& ALWAYS(pMem->u.i<LARGEST_INT64) ){
|
||||
if( pMem->r==(double)pMem->u.i
|
||||
&& pMem->u.i>SMALLEST_INT64
|
||||
#if defined(__i486__) || defined(__x86_64__)
|
||||
&& ALWAYS(pMem->u.i<LARGEST_INT64)
|
||||
#else
|
||||
&& pMem->u.i<LARGEST_INT64
|
||||
#endif
|
||||
){
|
||||
pMem->flags |= MEM_Int;
|
||||
}
|
||||
}
|
||||
|
@ -93,17 +93,17 @@ typedef struct SorterRecord SorterRecord;
|
||||
** being merged (rounded up to the next power of 2).
|
||||
*/
|
||||
struct VdbeSorter {
|
||||
int nInMemory; /* Current size of pRecord list as PMA */
|
||||
int nTree; /* Used size of aTree/aIter (power of 2) */
|
||||
VdbeSorterIter *aIter; /* Array of iterators to merge */
|
||||
int *aTree; /* Current state of incremental merge */
|
||||
i64 iWriteOff; /* Current write offset within file pTemp1 */
|
||||
i64 iReadOff; /* Current read offset within file pTemp1 */
|
||||
sqlite3_file *pTemp1; /* PMA file 1 */
|
||||
int nInMemory; /* Current size of pRecord list as PMA */
|
||||
int nTree; /* Used size of aTree/aIter (power of 2) */
|
||||
int nPMA; /* Number of PMAs stored in pTemp1 */
|
||||
SorterRecord *pRecord; /* Head of in-memory record list */
|
||||
int mnPmaSize; /* Minimum PMA size, in bytes */
|
||||
int mxPmaSize; /* Maximum PMA size, in bytes. 0==no limit */
|
||||
VdbeSorterIter *aIter; /* Array of iterators to merge */
|
||||
int *aTree; /* Current state of incremental merge */
|
||||
sqlite3_file *pTemp1; /* PMA file 1 */
|
||||
SorterRecord *pRecord; /* Head of in-memory record list */
|
||||
UnpackedRecord *pUnpacked; /* Used to unpack keys */
|
||||
};
|
||||
|
||||
@ -114,10 +114,10 @@ struct VdbeSorter {
|
||||
struct VdbeSorterIter {
|
||||
i64 iReadOff; /* Current read offset */
|
||||
i64 iEof; /* 1 byte past EOF for this iterator */
|
||||
sqlite3_file *pFile; /* File iterator is reading from */
|
||||
int nAlloc; /* Bytes of space at aAlloc */
|
||||
u8 *aAlloc; /* Allocated space */
|
||||
int nKey; /* Number of bytes in key */
|
||||
sqlite3_file *pFile; /* File iterator is reading from */
|
||||
u8 *aAlloc; /* Allocated space */
|
||||
u8 *aKey; /* Pointer to current key */
|
||||
};
|
||||
|
||||
|
@ -278,13 +278,14 @@ void sqlite3VtabBeginParse(
|
||||
Parse *pParse, /* Parsing context */
|
||||
Token *pName1, /* Name of new table, or database name */
|
||||
Token *pName2, /* Name of new table or NULL */
|
||||
Token *pModuleName /* Name of the module for the virtual table */
|
||||
Token *pModuleName, /* Name of the module for the virtual table */
|
||||
int ifNotExists /* No error if the table already exists */
|
||||
){
|
||||
int iDb; /* The database the table is being created in */
|
||||
Table *pTable; /* The new virtual table */
|
||||
sqlite3 *db; /* Database connection */
|
||||
|
||||
sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, 0);
|
||||
sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, ifNotExists);
|
||||
pTable = pParse->pNewTable;
|
||||
if( pTable==0 ) return;
|
||||
assert( 0==pTable->pIndex );
|
||||
@ -319,7 +320,7 @@ void sqlite3VtabBeginParse(
|
||||
** virtual table currently under construction in pParse->pTable.
|
||||
*/
|
||||
static void addArgumentToVtab(Parse *pParse){
|
||||
if( pParse->sArg.z && ALWAYS(pParse->pNewTable) ){
|
||||
if( pParse->sArg.z && pParse->pNewTable ){
|
||||
const char *z = (const char*)pParse->sArg.z;
|
||||
int n = pParse->sArg.n;
|
||||
sqlite3 *db = pParse->db;
|
||||
|
@ -349,7 +349,8 @@ db func trigfunc trigfunc
|
||||
do_test alter-3.1.0 {
|
||||
execsql {
|
||||
CREATE TABLE t6(a, b, c);
|
||||
CREATE TRIGGER trig1 AFTER INSERT ON t6 BEGIN
|
||||
-- Different case for the table name in the trigger.
|
||||
CREATE TRIGGER trig1 AFTER INSERT ON T6 BEGIN
|
||||
SELECT trigfunc('trig1', new.a, new.b, new.c);
|
||||
END;
|
||||
}
|
||||
|
@ -463,7 +463,7 @@ do_test backup-4.5.3 {
|
||||
db close
|
||||
db2 close
|
||||
#
|
||||
# End of backup-5.* tests.
|
||||
# End of backup-4.* tests.
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
|
@ -46,8 +46,8 @@ proc do_temptables_test {tn sql temptables} {
|
||||
set ret ""
|
||||
db eval "EXPLAIN [set sql]" {
|
||||
if {$opcode == "OpenEphemeral" || $opcode == "SorterOpen"} {
|
||||
if {$p5 != "10" && $p5!="00"} { error "p5 = $p5" }
|
||||
if {$p5 == "10"} {
|
||||
if {$p5 != "08" && $p5!="00"} { error "p5 = $p5" }
|
||||
if {$p5 == "08"} {
|
||||
lappend ret hash
|
||||
} else {
|
||||
lappend ret btree
|
||||
|
@ -800,7 +800,7 @@ do_select_tests e_select-4.1 {
|
||||
|
||||
6 "SELECT count(*), * FROM z1" {6 63 born -26}
|
||||
7 "SELECT max(a), * FROM z1" {63 63 born -26}
|
||||
8 "SELECT *, min(a) FROM z1" {63 born -26 -5}
|
||||
8 "SELECT *, min(a) FROM z1" {-5 {} 75 -5}
|
||||
|
||||
9 "SELECT *,* FROM z1,z2 LIMIT 1" {
|
||||
51.65 -59.58 belfries {} 21 51.65 -59.58 belfries {} 21
|
||||
|
@ -573,10 +573,10 @@ set chunkconfig [fts3_configure_incr_load 1 1]
|
||||
foreach {tn create pending} {
|
||||
1 "fts4(a, b)" 1
|
||||
2 "fts4(a, b, order=ASC, prefix=1)" 1
|
||||
3 "fts4(a, b, order=ASC, prefix=1,3)" 0
|
||||
4 "fts4(a, b, order=DESC, prefix=2,4)" 0
|
||||
5 "fts4(a, b, order=DESC, prefix=1)" 0
|
||||
6 "fts4(a, b, order=ASC, prefix=1,3)" 0
|
||||
3 "fts4(a, b, order=ASC, prefix=\"1,3\")" 0
|
||||
4 "fts4(a, b, order=DESC, prefix=\"2,4\")" 0
|
||||
5 "fts4(a, b, order=DESC, prefix=\"1\")" 0
|
||||
6 "fts4(a, b, order=ASC, prefix=\"1,3\")" 0
|
||||
} {
|
||||
|
||||
execsql [subst {
|
||||
|
62
test/fts3prefix2.test
Normal file
62
test/fts3prefix2.test
Normal file
@ -0,0 +1,62 @@
|
||||
# 2012 January 25
|
||||
#
|
||||
# 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 file implements regression tests for SQLite library. The
|
||||
# focus of this script is testing the FTS3 module.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix fts3prefix2
|
||||
|
||||
ifcapable !fts3 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 { PRAGMA page_size = 512 }
|
||||
do_execsql_test 1.1 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts4(x, prefix="2,3");
|
||||
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES('T TX T TX T TX T TX T TX');
|
||||
INSERT INTO t1 SELECT * FROM t1; -- 2
|
||||
INSERT INTO t1 SELECT * FROM t1; -- 4
|
||||
INSERT INTO t1 SELECT * FROM t1; -- 8
|
||||
INSERT INTO t1 SELECT * FROM t1; -- 16
|
||||
INSERT INTO t1 SELECT * FROM t1; -- 32
|
||||
INSERT INTO t1 SELECT * FROM t1; -- 64
|
||||
INSERT INTO t1 SELECT * FROM t1; -- 128
|
||||
INSERT INTO t1 SELECT * FROM t1; -- 256
|
||||
INSERT INTO t1 SELECT * FROM t1; -- 512
|
||||
INSERT INTO t1 SELECT * FROM t1; -- 1024
|
||||
INSERT INTO t1 SELECT * FROM t1; -- 2048
|
||||
COMMIT;
|
||||
}
|
||||
|
||||
do_execsql_test 1.2 {
|
||||
INSERT INTO t1 SELECT * FROM t1 LIMIT 10;
|
||||
INSERT INTO t1 SELECT * FROM t1 LIMIT 10;
|
||||
INSERT INTO t1 SELECT * FROM t1 LIMIT 10;
|
||||
DELETE FROM t1 WHERE docid > 5;
|
||||
}
|
||||
|
||||
do_execsql_test 1.3 {
|
||||
SELECT * FROM t1 WHERE t1 MATCH 'T*';
|
||||
} {
|
||||
{T TX T TX T TX T TX T TX}
|
||||
{T TX T TX T TX T TX T TX}
|
||||
{T TX T TX T TX T TX T TX}
|
||||
{T TX T TX T TX T TX T TX}
|
||||
{T TX T TX T TX T TX T TX}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
@ -43,6 +43,9 @@ ifcapable !fts3 {
|
||||
# exist, the FTS table can still be used for INSERT and some
|
||||
# SELECT statements.
|
||||
#
|
||||
# 8.* - Test that if the content=xxx and prefix options are used together,
|
||||
# the 'rebuild' command still works.
|
||||
#
|
||||
|
||||
do_execsql_test 1.1.1 {
|
||||
CREATE TABLE t1(a, b, c);
|
||||
@ -498,4 +501,25 @@ do_catchsql_test 7.2.4 {
|
||||
SELECT * FROM ft9 WHERE ft9 MATCH 'N';
|
||||
} {1 {SQL logic error or missing database}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test cases 8.*
|
||||
#
|
||||
do_execsql_test 8.1 {
|
||||
CREATE TABLE t10(a, b);
|
||||
INSERT INTO t10 VALUES(
|
||||
'abasia abasic abask', 'Abassin abastardize abatable');
|
||||
INSERT INTO t10 VALUES(
|
||||
'abate abatement abater', 'abatis abatised abaton');
|
||||
INSERT INTO t10 VALUES(
|
||||
'abator abattoir Abatua', 'abature abave abaxial');
|
||||
|
||||
CREATE VIRTUAL TABLE ft10 USING fts4(content=t10, prefix="2,4", a, b);
|
||||
}
|
||||
|
||||
do_execsql_test 8.2 { SELECT * FROM ft10 WHERE a MATCH 'ab*'; }
|
||||
do_execsql_test 8.3 { INSERT INTO ft10(ft10) VALUES('rebuild'); }
|
||||
do_execsql_test 8.4 { SELECT rowid FROM ft10 WHERE a MATCH 'ab*'; } {1 2 3}
|
||||
do_execsql_test 8.5 { SELECT rowid FROM ft10 WHERE b MATCH 'abav*'; } {3}
|
||||
do_execsql_test 8.6 { SELECT rowid FROM ft10 WHERE ft10 MATCH 'abas*'; } {1}
|
||||
|
||||
finish_test
|
||||
|
@ -386,6 +386,21 @@ do_test insert-9.2 {
|
||||
}
|
||||
} {1 1 2 2 3 3 12 101 13 102 16 103}
|
||||
|
||||
# Multiple VALUES clauses
|
||||
#
|
||||
do_test insert-10.1 {
|
||||
execsql {
|
||||
CREATE TABLE t10(a,b,c);
|
||||
INSERT INTO t10 VALUES(1,2,3), (4,5,6), (7,8,9);
|
||||
SELECT * FROM t10;
|
||||
}
|
||||
} {1 2 3 4 5 6 7 8 9}
|
||||
do_test insert-10.2 {
|
||||
catchsql {
|
||||
INSERT INTO t10 VALUES(11,12,13), (14,15);
|
||||
}
|
||||
} {1 {all VALUES must have the same number of terms}}
|
||||
|
||||
integrity_check insert-99.0
|
||||
|
||||
finish_test
|
||||
|
145
test/minmax4.test
Normal file
145
test/minmax4.test
Normal file
@ -0,0 +1,145 @@
|
||||
# 2012 February 02
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# Test for queries of the form:
|
||||
#
|
||||
# SELECT p, max(q) FROM t1;
|
||||
#
|
||||
# Demonstration that the value returned for p is on the same row as
|
||||
# the maximum q.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
do_test minmax4-1.1 {
|
||||
db eval {
|
||||
CREATE TABLE t1(p,q);
|
||||
SELECT p, max(q) FROM t1;
|
||||
}
|
||||
} {{} {}}
|
||||
do_test minmax4-1.2 {
|
||||
db eval {
|
||||
SELECT p, min(q) FROM t1;
|
||||
}
|
||||
} {{} {}}
|
||||
do_test minmax4-1.3 {
|
||||
db eval {
|
||||
INSERT INTO t1 VALUES(1,2);
|
||||
SELECT p, max(q) FROM t1;
|
||||
}
|
||||
} {1 2}
|
||||
do_test minmax4-1.4 {
|
||||
db eval {
|
||||
SELECT p, min(q) FROM t1;
|
||||
}
|
||||
} {1 2}
|
||||
do_test minmax4-1.5 {
|
||||
db eval {
|
||||
INSERT INTO t1 VALUES(3,4);
|
||||
SELECT p, max(q) FROM t1;
|
||||
}
|
||||
} {3 4}
|
||||
do_test minmax4-1.6 {
|
||||
db eval {
|
||||
SELECT p, min(q) FROM t1;
|
||||
}
|
||||
} {1 2}
|
||||
do_test minmax4-1.7 {
|
||||
db eval {
|
||||
INSERT INTO t1 VALUES(5,0);
|
||||
SELECT p, max(q) FROM t1;
|
||||
}
|
||||
} {3 4}
|
||||
do_test minmax4-1.8 {
|
||||
db eval {
|
||||
SELECT p, min(q) FROM t1;
|
||||
}
|
||||
} {5 0}
|
||||
do_test minmax4-1.9 {
|
||||
db eval {
|
||||
INSERT INTO t1 VALUES(6,1);
|
||||
SELECT p, max(q) FROM t1;
|
||||
}
|
||||
} {3 4}
|
||||
do_test minmax4-1.10 {
|
||||
db eval {
|
||||
SELECT p, min(q) FROM t1;
|
||||
}
|
||||
} {5 0}
|
||||
do_test minmax4-1.11 {
|
||||
db eval {
|
||||
INSERT INTO t1 VALUES(7,NULL);
|
||||
SELECT p, max(q) FROM t1;
|
||||
}
|
||||
} {3 4}
|
||||
do_test minmax4-1.12 {
|
||||
db eval {
|
||||
SELECT p, min(q) FROM t1;
|
||||
}
|
||||
} {5 0}
|
||||
do_test minmax4-1.13 {
|
||||
db eval {
|
||||
DELETE FROM t1 WHERE q IS NOT NULL;
|
||||
SELECT p, max(q) FROM t1;
|
||||
}
|
||||
} {7 {}}
|
||||
do_test minmax4-1.14 {
|
||||
db eval {
|
||||
SELECT p, min(q) FROM t1;
|
||||
}
|
||||
} {7 {}}
|
||||
|
||||
do_test minmax4-2.1 {
|
||||
db eval {
|
||||
CREATE TABLE t2(a,b,c);
|
||||
INSERT INTO t2 VALUES
|
||||
(1,null,2),
|
||||
(1,2,3),
|
||||
(1,1,4),
|
||||
(2,3,5);
|
||||
SELECT a, max(b), c FROM t2 GROUP BY a ORDER BY a;
|
||||
}
|
||||
} {1 2 3 2 3 5}
|
||||
do_test minmax4-2.2 {
|
||||
db eval {
|
||||
SELECT a, min(b), c FROM t2 GROUP BY a ORDER BY a;
|
||||
}
|
||||
} {1 1 4 2 3 5}
|
||||
do_test minmax4-2.3 {
|
||||
db eval {
|
||||
SELECT a, min(b), avg(b), count(b), c FROM t2 GROUP BY a ORDER BY a DESC;
|
||||
}
|
||||
} {2 3 3.0 1 5 1 1 1.5 2 4}
|
||||
do_test minmax4-2.4 {
|
||||
db eval {
|
||||
SELECT a, min(b), max(b), c FROM t2 GROUP BY a ORDER BY a;
|
||||
}
|
||||
} {1 1 2 3 2 3 3 5}
|
||||
do_test minmax4-2.5 {
|
||||
db eval {
|
||||
SELECT a, max(b), min(b), c FROM t2 GROUP BY a ORDER BY a;
|
||||
}
|
||||
} {1 2 1 4 2 3 3 5}
|
||||
do_test minmax4-2.6 {
|
||||
db eval {
|
||||
SELECT a, max(b), b, max(c), c FROM t2 GROUP BY a ORDER BY a;
|
||||
}
|
||||
} {1 2 1 4 4 2 3 3 5 5}
|
||||
do_test minmax4-2.7 {
|
||||
db eval {
|
||||
SELECT a, min(b), b, min(c), c FROM t2 GROUP BY a ORDER BY a;
|
||||
}
|
||||
} {1 1 {} 2 2 2 3 3 5 5}
|
||||
|
||||
|
||||
|
||||
finish_test
|
@ -151,6 +151,12 @@ db2 close
|
||||
# Test that nothing goes horribly wrong when attaching a database
|
||||
# after the omit_readlock pragma has been exercised.
|
||||
#
|
||||
# Note: The PRAGMA omit_readlock was an early hack to disable the
|
||||
# fcntl() calls for read-only databases so that read-only databases could
|
||||
# be read on broken NFS systems. That pragma has now been removed.
|
||||
# (Use the unix-none VFS as a replacement, if needed.) But these tests
|
||||
# do not really depend on omit_readlock, so we left them in place.
|
||||
#
|
||||
do_test misc7-7.1 {
|
||||
forcedelete test2.db
|
||||
forcedelete test2.db-journal
|
||||
|
@ -54,6 +54,8 @@ do_not_use_codec
|
||||
# pager1-16.*: Varying sqlite3_vfs.mxPathname
|
||||
#
|
||||
# pager1-17.*: Tests related to "PRAGMA omit_readlock"
|
||||
# (The omit_readlock pragma has been removed and so have
|
||||
# these tests.)
|
||||
#
|
||||
# pager1-18.*: Test that the pager layer responds correctly if the b-tree
|
||||
# requests an invalid page number (due to db corruption).
|
||||
@ -1708,75 +1710,6 @@ for {set ii [expr $::file_len-5]} {$ii < [expr $::file_len+20]} {incr ii} {
|
||||
tv delete
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test "PRAGMA omit_readlock".
|
||||
#
|
||||
# pager1-17.$tn.1.*: Test that if a second connection has an open
|
||||
# read-transaction, it is not usually possible to write
|
||||
# the database.
|
||||
#
|
||||
# pager1-17.$tn.2.*: Test that if the second connection was opened with
|
||||
# the SQLITE_OPEN_READONLY flag, and
|
||||
# "PRAGMA omit_readlock = 1" is executed before attaching
|
||||
# the database and opening a read-transaction on it, it is
|
||||
# possible to write the db.
|
||||
#
|
||||
# pager1-17.$tn.3.*: Test that if the second connection was *not* opened with
|
||||
# the SQLITE_OPEN_READONLY flag, executing
|
||||
# "PRAGMA omit_readlock = 1" has no effect.
|
||||
#
|
||||
do_multiclient_test tn {
|
||||
do_test pager1-17.$tn.1.1 {
|
||||
sql1 {
|
||||
CREATE TABLE t1(a, b);
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
}
|
||||
sql2 {
|
||||
BEGIN;
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {1 2}
|
||||
do_test pager1-17.$tn.1.2 {
|
||||
csql1 { INSERT INTO t1 VALUES(3, 4) }
|
||||
} {1 {database is locked}}
|
||||
do_test pager1-17.$tn.1.3 {
|
||||
sql2 { COMMIT }
|
||||
sql1 { INSERT INTO t1 VALUES(3, 4) }
|
||||
} {}
|
||||
|
||||
do_test pager1-17.$tn.2.1 {
|
||||
code2 {
|
||||
db2 close
|
||||
sqlite3 db2 :memory: -readonly 1
|
||||
}
|
||||
sql2 {
|
||||
PRAGMA omit_readlock = 1;
|
||||
ATTACH 'test.db' AS two;
|
||||
BEGIN;
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {1 2 3 4}
|
||||
do_test pager1-17.$tn.2.2 { sql1 "INSERT INTO t1 VALUES(5, 6)" } {}
|
||||
do_test pager1-17.$tn.2.3 { sql2 "SELECT * FROM t1" } {1 2 3 4}
|
||||
do_test pager1-17.$tn.2.4 { sql2 "COMMIT ; SELECT * FROM t1" } {1 2 3 4 5 6}
|
||||
|
||||
do_test pager1-17.$tn.3.1 {
|
||||
code2 {
|
||||
db2 close
|
||||
sqlite3 db2 :memory:
|
||||
}
|
||||
sql2 {
|
||||
PRAGMA omit_readlock = 1;
|
||||
ATTACH 'test.db' AS two;
|
||||
BEGIN;
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {1 2 3 4 5 6}
|
||||
do_test pager1-17.$tn.3.2 {
|
||||
csql1 { INSERT INTO t1 VALUES(3, 4) }
|
||||
} {1 {database is locked}}
|
||||
do_test pager1-17.$tn.3.3 { sql2 COMMIT } {}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test the pagers response to the b-tree layer requesting illegal page
|
||||
|
@ -38,4 +38,21 @@ do_realnum_test tkt3838-1.1 {
|
||||
}
|
||||
} {2 999 9e+99 xyzzy}
|
||||
|
||||
ifcapable trigger {
|
||||
do_test tkt3838-1.2 {
|
||||
db eval {
|
||||
CREATE TABLE log(y);
|
||||
CREATE TRIGGER r1 AFTER INSERT ON T1 BEGIN
|
||||
INSERT INTO log VALUES(new.x);
|
||||
END;
|
||||
INSERT INTO t1(x) VALUES(123);
|
||||
ALTER TABLE T1 RENAME TO XYZ2;
|
||||
INSERT INTO xyz2(x) VALUES(456);
|
||||
ALTER TABLE xyz2 RENAME TO pqr3;
|
||||
INSERT INTO pqr3(x) VALUES(789);
|
||||
SELECT * FROM log;
|
||||
}
|
||||
} {123 456 789}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
@ -290,9 +290,21 @@ ifcapable tempdb {
|
||||
SELECT * FROM t2;
|
||||
}
|
||||
} {1 {no such table: main.t2}}
|
||||
do_test trigger-3.6 {
|
||||
do_test trigger-3.6.1 {
|
||||
catchsql {
|
||||
DROP TRIGGER r1;
|
||||
CREATE TEMP TRIGGER r1 AFTER INSERT ON t1 BEGIN
|
||||
INSERT INTO t2 VALUES(NEW.a,NEW.b), (NEW.b*100, NEW.a*100);
|
||||
END;
|
||||
INSERT INTO t1 VALUES(1,2);
|
||||
SELECT * FROM t2;
|
||||
}
|
||||
} {0 {1 2 200 100}}
|
||||
do_test trigger-3.6.2 {
|
||||
catchsql {
|
||||
DROP TRIGGER r1;
|
||||
DELETE FROM t1;
|
||||
DELETE FROM t2;
|
||||
CREATE TEMP TRIGGER r1 AFTER INSERT ON t1 BEGIN
|
||||
INSERT INTO t2 VALUES(NEW.a,NEW.b);
|
||||
END;
|
||||
|
@ -51,7 +51,7 @@ ifcapable !vtab||!schema_pragmas {
|
||||
|
||||
# We cannot create a virtual table if the module has not been registered.
|
||||
#
|
||||
do_test vtab1-1.1 {
|
||||
do_test vtab1-1.1.1 {
|
||||
explain {
|
||||
CREATE VIRTUAL TABLE t1 USING echo;
|
||||
}
|
||||
@ -59,6 +59,11 @@ do_test vtab1-1.1 {
|
||||
CREATE VIRTUAL TABLE t1 USING echo;
|
||||
}
|
||||
} {1 {no such module: echo}}
|
||||
do_test vtab1-1.1.2 {
|
||||
catchsql {
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS t1 USING echo;
|
||||
}
|
||||
} {1 {no such module: echo}}
|
||||
do_test vtab1-1.2 {
|
||||
execsql {
|
||||
SELECT name FROM sqlite_master ORDER BY 1
|
||||
@ -75,11 +80,16 @@ register_echo_module [sqlite3_connection_pointer db]
|
||||
# The "echo" module does not invoke sqlite3_declare_vtab() if it is
|
||||
# passed zero arguments.
|
||||
#
|
||||
do_test vtab1-1.3 {
|
||||
do_test vtab1-1.3.1 {
|
||||
catchsql {
|
||||
CREATE VIRTUAL TABLE t1 USING echo;
|
||||
}
|
||||
} {1 {vtable constructor did not declare schema: t1}}
|
||||
do_test vtab1-1.3.2 {
|
||||
catchsql {
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS t1 USING echo;
|
||||
}
|
||||
} {1 {vtable constructor did not declare schema: t1}}
|
||||
do_test vtab1-1.4 {
|
||||
execsql {
|
||||
SELECT name FROM sqlite_master ORDER BY 1
|
||||
@ -90,11 +100,16 @@ do_test vtab1-1.4 {
|
||||
# the virtual table if it is passed an argument that does not correspond
|
||||
# to an existing real table in the same database.
|
||||
#
|
||||
do_test vtab1-1.5 {
|
||||
do_test vtab1-1.5.1 {
|
||||
catchsql {
|
||||
CREATE VIRTUAL TABLE t1 USING echo(no_such_table);
|
||||
}
|
||||
} {1 {vtable constructor failed: t1}}
|
||||
do_test vtab1-1.5.2 {
|
||||
catchsql {
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS t1 USING echo(no_such_table);
|
||||
}
|
||||
} {1 {vtable constructor failed: t1}}
|
||||
do_test vtab1-1.6 {
|
||||
execsql {
|
||||
SELECT name FROM sqlite_master ORDER BY 1
|
||||
@ -128,17 +143,27 @@ do_test vtab-1.2152.4 {
|
||||
# select an illegal table-name (i.e a reserved name or the name of a
|
||||
# table that already exists).
|
||||
#
|
||||
do_test vtab1-1.7 {
|
||||
do_test vtab1-1.7.1 {
|
||||
catchsql {
|
||||
CREATE VIRTUAL TABLE sqlite_master USING echo;
|
||||
}
|
||||
} {1 {object name reserved for internal use: sqlite_master}}
|
||||
do_test vtab1-1.8 {
|
||||
do_test vtab1-1.7.2 {
|
||||
catchsql {
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS sqlite_master USING echo;
|
||||
}
|
||||
} {1 {object name reserved for internal use: sqlite_master}}
|
||||
do_test vtab1-1.8.1 {
|
||||
catchsql {
|
||||
CREATE TABLE treal(a, b, c);
|
||||
CREATE VIRTUAL TABLE treal USING echo(treal);
|
||||
}
|
||||
} {1 {table treal already exists}}
|
||||
do_test vtab1-1.8.2 {
|
||||
catchsql {
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS treal USING echo(treal);
|
||||
}
|
||||
} {0 {}}
|
||||
do_test vtab1-1.9 {
|
||||
execsql {
|
||||
DROP TABLE treal;
|
||||
|
@ -194,7 +194,7 @@ SELECT COUNT(*) FROM t1;}]
|
||||
|
||||
do_test shell5-1.4.10.2 {
|
||||
catchcmd "test.db" {SELECT b FROM t1 WHERE a='7';}
|
||||
} {0 {"Now is the time for all good men to come to the aid of their country."}}
|
||||
} {0 {Now is the time for all good men to come to the aid of their country.}}
|
||||
|
||||
# check importing very long field
|
||||
do_test shell5-1.5.1 {
|
||||
|
Loading…
Reference in New Issue
Block a user