mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Merge enhancements from trunk.
FossilOrigin-Name: 25ee3000e94d60d8c1d7b980f416dcc33eb11105
This commit is contained in:
50
manifest
50
manifest
@@ -1,5 +1,5 @@
|
||||
C Merge\senhancements\sfrom\strunk.
|
||||
D 2015-09-01T18:31:19.659
|
||||
D 2015-09-03T14:39:33.829
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in f85066ce844a28b671aaeeff320921cd0ce36239
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@@ -272,38 +272,38 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
|
||||
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F src/alter.c 48e14b8aea28dc58baafe3cfcb8889c086b7744a
|
||||
F src/analyze.c f89727c36f997bd2bf6c5e546c2f51dc94e6f2a4
|
||||
F src/alter.c 4911e1f18fc11b60edbc6410643e938762969a6a
|
||||
F src/analyze.c e4ad1495090d6b7bf58b927e1267fc211ad5e7da
|
||||
F src/attach.c e944d0052b577703b9b83aac1638452ff42a8395
|
||||
F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
|
||||
F src/backup.c 4d9134dc988a87838c06056c89c0e8c4700a0452
|
||||
F src/bitvec.c d1f21d7d91690747881f03940584f4cc548c9d3d
|
||||
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
|
||||
F src/btree.c b8083a37c09df6a30af497086d7ba05c1526d359
|
||||
F src/btree.c 3d759d9943ee2ce422a2bb1f7810e7447a907e97
|
||||
F src/btree.h 6310645beddbd3eef89fa9b6d1062065976a93c8
|
||||
F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0
|
||||
F src/build.c 511b02138eddc3cf68dab1016da4998260093e9f
|
||||
F src/build.c 6c3a8a9b21402a6be98126f7d86b76527e68ca67
|
||||
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
|
||||
F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
|
||||
F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b
|
||||
F src/date.c 8ec787fed4929d8ccdf6b1bc360fccc3e1d2ca58
|
||||
F src/dbstat.c f402e77e25089c6003d0c60b3233b9b3947d599a
|
||||
F src/delete.c 813be7b5659d7658c8a71b5ae194b45c8f739c8b
|
||||
F src/expr.c 6814e926d92b8e99ed422193341b89f5cb8d0f87
|
||||
F src/delete.c 5b4835982c31f12b256dc4d814363a11e7ef34cf
|
||||
F src/expr.c 3783aa19150be01a2ae92e1eb429c84a2313c8fc
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c 3ce33dd49f12c72376cec9adc7a4d8e7111cedcc
|
||||
F src/fkey.c 83e1baba999bed3144ea5a2143fc922edf51135f
|
||||
F src/func.c 824bea430d3a2b7dbc62806ad54da8fdb8ed9e3f
|
||||
F src/global.c 508e4087f7b41d688e4762dcf4d4fe28cfbc87f9
|
||||
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
|
||||
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
|
||||
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
||||
F src/insert.c c31b9253f0d40425d012701ba6e7e4b28c1676ea
|
||||
F src/insert.c bcff4a416177ed90faa8dba65f0266ddad2aeb76
|
||||
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
||||
F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
|
||||
F src/lempar.c 92bafa308607dd985ca389a788cd9e0a2b608712
|
||||
F src/loadext.c dfcee8c7c032cd0fd55af3e0fc1fcfb01e426df2
|
||||
F src/main.c e17fcffae4306a9b8334faf3bac80d7396850b54
|
||||
F src/malloc.c 19461e159bccf0e2cf06a50e867963d0a7b124a8
|
||||
F src/malloc.c 021012e28a81ffdabf4c30ec3df6ce1f6cc93f1d
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c abe6ee469b6c5a35c7f22bfeb9c9bac664a1c987
|
||||
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
|
||||
@@ -321,7 +321,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8
|
||||
F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf
|
||||
F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e
|
||||
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
|
||||
F src/os_unix.c 388c023582b17890f10c980b30ec1922b471753b
|
||||
F src/os_unix.c 76f493ed71c4154338049dee1bf6e47f69c74a55
|
||||
F src/os_win.c 40b3af7a47eb1107d0d69e592bec345a3b7b798a
|
||||
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
||||
F src/pager.c aa916ca28606ccf4b6877dfc2b643ccbca86589f
|
||||
@@ -329,15 +329,15 @@ F src/pager.h 6d435f563b3f7fcae4b84433b76a6ac2730036e2
|
||||
F src/parse.y f599aa5e871a493330d567ced93de696f61f48f7
|
||||
F src/pcache.c cde06aa50962595e412d497e22fd2e07878ba1f0
|
||||
F src/pcache.h 9968603796240cdf83da7e7bef76edf90619cea9
|
||||
F src/pcache1.c a3fe31b17e841ec70beee72a2c960e9c787a8857
|
||||
F src/pragma.c a239d2c8c6d87d589927547f234b0f6259c69f62
|
||||
F src/pcache1.c b31af9dbc83b9c68e87d681b8453a9605f28e734
|
||||
F src/pragma.c d71b813e67bf03f3116b9dd5164fbfd81ec673a2
|
||||
F src/pragma.h 631a91c8b0e6ca8f051a1d8a4a0da4150e04620a
|
||||
F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1
|
||||
F src/printf.c 2bc439ff20a4aad0e0ad50a37a67b5eae7d20edc
|
||||
F src/printf.c 0c4bcdd1c2e2521024f0a69cb5eb334f86b3652a
|
||||
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||
F src/resolve.c f2ef256786a6435efddd64a632fea89c8be62215
|
||||
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
||||
F src/select.c 3f588e05027cdb1a0b27ed305038d1449657b31d
|
||||
F src/select.c bb99c37242673405683992085a0fcff380b70575
|
||||
F src/shell.c bbe2bab590b7dd04dd8f9119d4473cb8c52906e3
|
||||
F src/sqlite.h.in 378bebc8fe6a88bade25e5f23b7e6123fdc64b00
|
||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||
@@ -396,27 +396,27 @@ F src/threads.c 6bbcc9fe50c917864d48287b4792d46d6e873481
|
||||
F src/tokenize.c 57cb3720f53f84d811def2069c2b169b6be539a5
|
||||
F src/treeview.c 46036cbbceada0836833531b2d963edbca3d9cfa
|
||||
F src/trigger.c 322f23aad694e8f31d384dcfa386d52a48d3c52f
|
||||
F src/update.c adc8b4b2b6fd2cca2e0d2b803e0cf6956aa3a030
|
||||
F src/update.c 795fba8ebadeb194285b0a73a07f7ad5ae4d0410
|
||||
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
|
||||
F src/util.c bc9dd64b5db544218b871b66243871c202b2781f
|
||||
F src/util.c fc612367108b74573c5fd13a85d0a23027f438bd
|
||||
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
|
||||
F src/vdbe.c 9d85fa72a73f7f07789d76602f724be63e998ddc
|
||||
F src/vdbe.h 529bb4a7bedcd28dccba5abb3927e3c5cb70a832
|
||||
F src/vdbe.h efb7a8c1459e31f3ea4377824c6a7e4cb5068637
|
||||
F src/vdbeInt.h 7258d75fc2dad0bccdef14d7d8d2fd50fd1bf2d2
|
||||
F src/vdbeapi.c bda74ef4b5103d7b4a4be36f936d3cf2b56a7d6f
|
||||
F src/vdbeaux.c 2262c5a674a30279f666061dd6b86f147df0d4b5
|
||||
F src/vdbeaux.c 7dccd114c9ee5f801709daecee36464fe6ce71af
|
||||
F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90
|
||||
F src/vdbemem.c ae38a0d35ae71cf604381a887c170466ba518090
|
||||
F src/vdbesort.c f5009e7a35e3065635d8918b9a31f498a499976b
|
||||
F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0
|
||||
F src/vtab.c d31174e4c8f592febab3fa7f69e18320b4fd657a
|
||||
F src/vtab.c 2ecfe020c10e0a0c7b078203fdba2fae844744bc
|
||||
F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
|
||||
F src/wal.c 8cd07f1f99e1a81346db1c9da879bef6c6f97cf6
|
||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||
F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba
|
||||
F src/where.c 5efdfbfade7392dbe0849b41af3550bc5de0a923
|
||||
F src/where.c 6055bee2f4aff2934ea1965c25c4d1f6368dc0eb
|
||||
F src/whereInt.h 901c17c1e3c82745ad9b85b4471543fa59c980e9
|
||||
F src/wherecode.c a9b88cb2973947a11ca80d04f2db30d46f8d6853
|
||||
F src/wherecode.c 93fa794fcd1aba23454cc15bca2b617bca21ec0a
|
||||
F src/whereexpr.c 1a308d1ee5144890d21ea9cf70d49bc96a83432b
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
|
||||
@@ -1381,7 +1381,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P b9927c876c1d4e146cb6a603d82cd2489594084d 1da60c3dda4254620052a83c853c2d2b6dd5009f
|
||||
R 3e1b1bd77195e09164f187ec59686181
|
||||
P 29570a604806e2a60a8eef7eaf1dce022d2a7004 847387ec8e6fef283899578fb232b2c23b00ee5b
|
||||
R af53d4591486f700f0b5e9bcc7196ecf
|
||||
U drh
|
||||
Z 804082d677813b1dfe48fd23d37aae84
|
||||
Z 6458a4b1081b59ccab00b014bcb486e3
|
||||
|
@@ -1 +1 @@
|
||||
29570a604806e2a60a8eef7eaf1dce022d2a7004
|
||||
25ee3000e94d60d8c1d7b980f416dcc33eb11105
|
@@ -491,7 +491,7 @@ void sqlite3AlterRenameTable(
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
if( pVTab ){
|
||||
int i = ++pParse->nMem;
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, i, 0, zName, 0);
|
||||
sqlite3VdbeLoadString(v, i, zName);
|
||||
sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB);
|
||||
sqlite3MayAbort(pParse);
|
||||
}
|
||||
|
@@ -1014,7 +1014,7 @@ static void analyzeOneTable(
|
||||
iIdxCur = iTab++;
|
||||
pParse->nTab = MAX(pParse->nTab, iTab);
|
||||
sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0);
|
||||
sqlite3VdbeLoadString(v, regTabname, pTab->zName);
|
||||
|
||||
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||
int nCol; /* Number of columns in pIdx. "N" */
|
||||
@@ -1036,7 +1036,7 @@ static void analyzeOneTable(
|
||||
}
|
||||
|
||||
/* Populate the register containing the index name. */
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, zIdxName, 0);
|
||||
sqlite3VdbeLoadString(v, regIdxname, zIdxName);
|
||||
VdbeComment((v, "Analysis for %s.%s", pTab->zName, zIdxName));
|
||||
|
||||
/*
|
||||
@@ -1150,7 +1150,7 @@ static void analyzeOneTable(
|
||||
VdbeCoverage(v);
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, nColTest, regChng);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, endDistinctTest);
|
||||
sqlite3VdbeGoto(v, endDistinctTest);
|
||||
|
||||
|
||||
/*
|
||||
|
@@ -8721,7 +8721,6 @@ static void checkAppendMsg(
|
||||
...
|
||||
){
|
||||
va_list ap;
|
||||
char zBuf[200];
|
||||
if( !pCheck->mxErr ) return;
|
||||
pCheck->mxErr--;
|
||||
pCheck->nErr++;
|
||||
@@ -8730,8 +8729,7 @@ static void checkAppendMsg(
|
||||
sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1);
|
||||
}
|
||||
if( pCheck->zPfx ){
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf, pCheck->zPfx, pCheck->v1, pCheck->v2);
|
||||
sqlite3StrAccumAppendAll(&pCheck->errMsg, zBuf);
|
||||
sqlite3XPrintf(&pCheck->errMsg, 0, pCheck->zPfx, pCheck->v1, pCheck->v2);
|
||||
}
|
||||
sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap);
|
||||
va_end(ap);
|
||||
|
10
src/build.c
10
src/build.c
@@ -221,7 +221,7 @@ void sqlite3FinishCoding(Parse *pParse){
|
||||
}
|
||||
|
||||
/* Finally, jump back to the beginning of the executable code. */
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, 1);
|
||||
sqlite3VdbeGoto(v, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1690,7 +1690,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
|
||||
*/
|
||||
if( pParse->addrCrTab ){
|
||||
assert( v );
|
||||
sqlite3VdbeGetOp(v, pParse->addrCrTab)->opcode = OP_CreateIndex;
|
||||
sqlite3VdbeChangeOpcode(v, pParse->addrCrTab, OP_CreateIndex);
|
||||
}
|
||||
|
||||
/* Locate the PRIMARY KEY index. Or, if this table was originally
|
||||
@@ -1719,7 +1719,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
|
||||
** a database schema). */
|
||||
if( v ){
|
||||
assert( db->init.busy==0 );
|
||||
sqlite3VdbeGetOp(v, pPk->tnum)->opcode = OP_Goto;
|
||||
sqlite3VdbeChangeOpcode(v, pPk->tnum, OP_Goto);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1963,7 +1963,7 @@ void sqlite3EndTable(
|
||||
sqlite3TableAffinity(v, p, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_NewRowid, 1, regRowid);
|
||||
sqlite3VdbeAddOp3(v, OP_Insert, 1, regRec, regRowid);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrInsLoop);
|
||||
sqlite3VdbeGoto(v, addrInsLoop);
|
||||
sqlite3VdbeJumpHere(v, addrInsLoop);
|
||||
sqlite3VdbeAddOp1(v, OP_Close, 1);
|
||||
}
|
||||
@@ -2792,7 +2792,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
|
||||
assert( pKey!=0 || db->mallocFailed || pParse->nErr );
|
||||
if( IsUniqueIndex(pIndex) && pKey!=0 ){
|
||||
int j2 = sqlite3VdbeCurrentAddr(v) + 3;
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, j2);
|
||||
sqlite3VdbeGoto(v, j2);
|
||||
addr2 = sqlite3VdbeCurrentAddr(v);
|
||||
sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord,
|
||||
pIndex->nKeyCol); VdbeCoverage(v);
|
||||
|
@@ -456,7 +456,7 @@ void sqlite3DeleteFrom(
|
||||
if( okOnePass ){
|
||||
/* Bypass the delete logic below if the WHERE loop found zero rows */
|
||||
addrBypass = sqlite3VdbeMakeLabel(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrBypass);
|
||||
sqlite3VdbeGoto(v, addrBypass);
|
||||
sqlite3VdbeJumpHere(v, addrDelete);
|
||||
}
|
||||
|
||||
@@ -518,7 +518,7 @@ void sqlite3DeleteFrom(
|
||||
sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); VdbeCoverage(v);
|
||||
sqlite3VdbeJumpHere(v, addrLoop);
|
||||
}else{
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrLoop);
|
||||
sqlite3VdbeGoto(v, addrLoop);
|
||||
sqlite3VdbeJumpHere(v, addrLoop);
|
||||
}
|
||||
|
||||
|
16
src/expr.c
16
src/expr.c
@@ -2161,7 +2161,7 @@ static void sqlite3ExprCodeIN(
|
||||
}
|
||||
if( regCkNull ){
|
||||
sqlite3VdbeAddOp2(v, OP_IsNull, regCkNull, destIfNull); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse);
|
||||
sqlite3VdbeGoto(v, destIfFalse);
|
||||
}
|
||||
sqlite3VdbeResolveLabel(v, labelOk);
|
||||
sqlite3ReleaseTempReg(pParse, regCkNull);
|
||||
@@ -2179,7 +2179,7 @@ static void sqlite3ExprCodeIN(
|
||||
int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse);
|
||||
VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull);
|
||||
sqlite3VdbeGoto(v, destIfNull);
|
||||
sqlite3VdbeJumpHere(v, addr1);
|
||||
}
|
||||
}
|
||||
@@ -2229,7 +2229,7 @@ static void sqlite3ExprCodeIN(
|
||||
VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_IsNull, rRhsHasNull, destIfNull);
|
||||
VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse);
|
||||
sqlite3VdbeGoto(v, destIfFalse);
|
||||
sqlite3VdbeJumpHere(v, j1);
|
||||
}
|
||||
}
|
||||
@@ -2655,7 +2655,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
#endif
|
||||
case TK_STRING: {
|
||||
assert( !ExprHasProperty(pExpr, EP_IntValue) );
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, target, 0, pExpr->u.zToken, 0);
|
||||
sqlite3VdbeLoadString(v, target, pExpr->u.zToken);
|
||||
break;
|
||||
}
|
||||
case TK_NULL: {
|
||||
@@ -3152,7 +3152,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL);
|
||||
testcase( aListelem[i+1].pExpr->op==TK_COLUMN );
|
||||
sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, endLabel);
|
||||
sqlite3VdbeGoto(v, endLabel);
|
||||
sqlite3ExprCachePop(pParse);
|
||||
sqlite3VdbeResolveLabel(v, nextCase);
|
||||
}
|
||||
@@ -3542,14 +3542,14 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
||||
int destIfFalse = sqlite3VdbeMakeLabel(v);
|
||||
int destIfNull = jumpIfNull ? dest : destIfFalse;
|
||||
sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, dest);
|
||||
sqlite3VdbeGoto(v, dest);
|
||||
sqlite3VdbeResolveLabel(v, destIfFalse);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default: {
|
||||
if( exprAlwaysTrue(pExpr) ){
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, dest);
|
||||
sqlite3VdbeGoto(v, dest);
|
||||
}else if( exprAlwaysFalse(pExpr) ){
|
||||
/* No-op */
|
||||
}else{
|
||||
@@ -3705,7 +3705,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
||||
#endif
|
||||
default: {
|
||||
if( exprAlwaysFalse(pExpr) ){
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, dest);
|
||||
sqlite3VdbeGoto(v, dest);
|
||||
}else if( exprAlwaysTrue(pExpr) ){
|
||||
/* no-op */
|
||||
}else{
|
||||
|
@@ -374,7 +374,7 @@ static void fkLookupParent(
|
||||
|
||||
sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
|
||||
sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
|
||||
sqlite3VdbeGoto(v, iOk);
|
||||
sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
|
||||
sqlite3VdbeJumpHere(v, iMustBeInt);
|
||||
sqlite3ReleaseTempReg(pParse, regTemp);
|
||||
@@ -412,7 +412,7 @@ static void fkLookupParent(
|
||||
sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent); VdbeCoverage(v);
|
||||
sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
|
||||
sqlite3VdbeGoto(v, iOk);
|
||||
}
|
||||
|
||||
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTemp, nCol, regRec,
|
||||
|
18
src/insert.c
18
src/insert.c
@@ -259,14 +259,14 @@ void sqlite3AutoincrementBegin(Parse *pParse){
|
||||
sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead);
|
||||
sqlite3VdbeAddOp3(v, OP_Null, 0, memId, memId+1);
|
||||
addr = sqlite3VdbeCurrentAddr(v);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, memId-1, 0, p->pTab->zName, 0);
|
||||
sqlite3VdbeLoadString(v, memId-1, p->pTab->zName);
|
||||
sqlite3VdbeAddOp2(v, OP_Rewind, 0, addr+9); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp3(v, OP_Column, 0, 0, memId);
|
||||
sqlite3VdbeAddOp3(v, OP_Ne, memId-1, addr+7, memId); VdbeCoverage(v);
|
||||
sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
|
||||
sqlite3VdbeAddOp2(v, OP_Rowid, 0, memId+1);
|
||||
sqlite3VdbeAddOp3(v, OP_Column, 0, 1, memId);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, addr+9);
|
||||
sqlite3VdbeGoto(v, addr+9);
|
||||
sqlite3VdbeAddOp2(v, OP_Next, 0, addr+2); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, memId);
|
||||
sqlite3VdbeAddOp0(v, OP_Close);
|
||||
@@ -690,7 +690,7 @@ void sqlite3Insert(
|
||||
sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec);
|
||||
sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid);
|
||||
sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrL);
|
||||
sqlite3VdbeGoto(v, addrL);
|
||||
sqlite3VdbeJumpHere(v, addrL);
|
||||
sqlite3ReleaseTempReg(pParse, regRec);
|
||||
sqlite3ReleaseTempReg(pParse, regTempRowid);
|
||||
@@ -991,7 +991,7 @@ void sqlite3Insert(
|
||||
sqlite3VdbeJumpHere(v, addrInsTop);
|
||||
sqlite3VdbeAddOp1(v, OP_Close, srcTab);
|
||||
}else if( pSelect ){
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrCont);
|
||||
sqlite3VdbeGoto(v, addrCont);
|
||||
sqlite3VdbeJumpHere(v, addrInsTop);
|
||||
}
|
||||
|
||||
@@ -1238,7 +1238,7 @@ void sqlite3GenerateConstraintChecks(
|
||||
int allOk = sqlite3VdbeMakeLabel(v);
|
||||
sqlite3ExprIfTrue(pParse, pCheck->a[i].pExpr, allOk, SQLITE_JUMPIFNULL);
|
||||
if( onError==OE_Ignore ){
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
|
||||
sqlite3VdbeGoto(v, ignoreDest);
|
||||
}else{
|
||||
char *zName = pCheck->a[i].zName;
|
||||
if( zName==0 ) zName = pTab->zName;
|
||||
@@ -1346,7 +1346,7 @@ void sqlite3GenerateConstraintChecks(
|
||||
}
|
||||
case OE_Ignore: {
|
||||
/*assert( seenReplace==0 );*/
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
|
||||
sqlite3VdbeGoto(v, ignoreDest);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1499,7 +1499,7 @@ void sqlite3GenerateConstraintChecks(
|
||||
break;
|
||||
}
|
||||
case OE_Ignore: {
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
|
||||
sqlite3VdbeGoto(v, ignoreDest);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -1520,7 +1520,7 @@ void sqlite3GenerateConstraintChecks(
|
||||
if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField);
|
||||
}
|
||||
if( ipkTop ){
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, ipkTop+1);
|
||||
sqlite3VdbeGoto(v, ipkTop+1);
|
||||
sqlite3VdbeJumpHere(v, ipkBottom);
|
||||
}
|
||||
|
||||
@@ -1966,7 +1966,7 @@ static int xferOptimization(
|
||||
** (3) onError is something other than OE_Abort and OE_Rollback.
|
||||
*/
|
||||
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0); VdbeCoverage(v);
|
||||
emptyDestTest = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
|
||||
emptyDestTest = sqlite3VdbeAddOp0(v, OP_Goto);
|
||||
sqlite3VdbeJumpHere(v, addr1);
|
||||
}
|
||||
if( HasRowid(pSrc) ){
|
||||
|
154
src/malloc.c
154
src/malloc.c
@@ -45,16 +45,7 @@ typedef struct ScratchFreeslot {
|
||||
*/
|
||||
static SQLITE_WSD struct Mem0Global {
|
||||
sqlite3_mutex *mutex; /* Mutex to serialize access */
|
||||
|
||||
/*
|
||||
** The alarm callback and its arguments. The mem0.mutex lock will
|
||||
** be held while the callback is running. Recursive calls into
|
||||
** the memory subsystem are allowed, but no new callbacks will be
|
||||
** issued.
|
||||
*/
|
||||
sqlite3_int64 alarmThreshold;
|
||||
void (*alarmCallback)(void*, sqlite3_int64,int);
|
||||
void *alarmArg;
|
||||
sqlite3_int64 alarmThreshold; /* The soft heap limit */
|
||||
|
||||
/*
|
||||
** Pointers to the end of sqlite3GlobalConfig.pScratch memory
|
||||
@@ -71,7 +62,7 @@ static SQLITE_WSD struct Mem0Global {
|
||||
** sqlite3_soft_heap_limit() setting.
|
||||
*/
|
||||
int nearlyFull;
|
||||
} mem0 = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
} mem0 = { 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
#define mem0 GLOBAL(struct Mem0Global, mem0)
|
||||
|
||||
@@ -83,49 +74,59 @@ sqlite3_mutex *sqlite3MallocMutex(void){
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine runs when the memory allocator sees that the
|
||||
** total memory allocation is about to exceed the soft heap
|
||||
** limit.
|
||||
** Return the amount of memory currently in use.
|
||||
*/
|
||||
static void softHeapLimitEnforcer(
|
||||
void *NotUsed,
|
||||
sqlite3_int64 NotUsed2,
|
||||
int allocSize
|
||||
){
|
||||
UNUSED_PARAMETER2(NotUsed, NotUsed2);
|
||||
sqlite3_release_memory(allocSize);
|
||||
static sqlite3_int64 memInUse(void){
|
||||
assert( sqlite3_mutex_held(mem0.mutex) );
|
||||
return sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
|
||||
}
|
||||
|
||||
/*
|
||||
** Change the alarm callback
|
||||
** Called when the soft heap limit is exceeded for an allocation
|
||||
** of nBytes.
|
||||
*/
|
||||
static int sqlite3MemoryAlarm(
|
||||
void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
|
||||
void *pArg,
|
||||
sqlite3_int64 iThreshold
|
||||
){
|
||||
sqlite3_int64 nUsed;
|
||||
sqlite3_mutex_enter(mem0.mutex);
|
||||
mem0.alarmCallback = xCallback;
|
||||
mem0.alarmArg = pArg;
|
||||
mem0.alarmThreshold = iThreshold;
|
||||
nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
|
||||
mem0.nearlyFull = (iThreshold>0 && iThreshold<=nUsed);
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
static void sqlite3HeapLimitExceeded(int nByte){
|
||||
sqlite3_int64 excess = memInUse() + nByte - mem0.alarmThreshold;
|
||||
sqlite3_mutex_leave(mem0.mutex);
|
||||
return SQLITE_OK;
|
||||
sqlite3_release_memory((int)(excess & 0x7fffffff));
|
||||
sqlite3_mutex_enter(mem0.mutex);
|
||||
}
|
||||
#else
|
||||
# define sqlite3HeapLimitExceeded(X) /* no-op */
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Check to see if increasing the total memory usage by nNew bytes
|
||||
** will exceed the soft heap limit.
|
||||
**
|
||||
** If the soft heap limit is exceeded, set the mem0.nearlyFull flag
|
||||
** and invoke sqlite3HeapLimitExceeded() to try to free up some
|
||||
** memory.
|
||||
*/
|
||||
static void sqlite3CheckSoftHeapLimit(int nNew){
|
||||
assert( sqlite3_mutex_held(mem0.mutex) );
|
||||
if( mem0.alarmThreshold>0 ){
|
||||
if( mem0.alarmThreshold-nNew >= memInUse() ){
|
||||
mem0.nearlyFull = 1;
|
||||
sqlite3HeapLimitExceeded(nNew);
|
||||
}else{
|
||||
mem0.nearlyFull = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
/*
|
||||
** Deprecated external interface. Internal/core SQLite code
|
||||
** should call sqlite3MemoryAlarm.
|
||||
** Deprecated external interface. First deprecated 2007-11-05. Changed
|
||||
** into a no-op on 2015-09-02.
|
||||
*/
|
||||
int sqlite3_memory_alarm(
|
||||
void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
|
||||
void *pArg,
|
||||
sqlite3_int64 iThreshold
|
||||
){
|
||||
return sqlite3MemoryAlarm(xCallback, pArg, iThreshold);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -135,22 +136,20 @@ int sqlite3_memory_alarm(
|
||||
*/
|
||||
sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){
|
||||
sqlite3_int64 priorLimit;
|
||||
sqlite3_int64 excess;
|
||||
#ifndef SQLITE_OMIT_AUTOINIT
|
||||
int rc = sqlite3_initialize();
|
||||
if( rc ) return -1;
|
||||
#endif
|
||||
sqlite3_mutex_enter(mem0.mutex);
|
||||
priorLimit = mem0.alarmThreshold;
|
||||
sqlite3_mutex_leave(mem0.mutex);
|
||||
if( n<0 ) return priorLimit;
|
||||
if( n>0 ){
|
||||
sqlite3MemoryAlarm(softHeapLimitEnforcer, 0, n);
|
||||
}else{
|
||||
sqlite3MemoryAlarm(0, 0, 0);
|
||||
mem0.alarmThreshold = n;
|
||||
sqlite3CheckSoftHeapLimit(0);
|
||||
}else if( n==0 ){
|
||||
mem0.alarmThreshold = 0;
|
||||
mem0.nearlyFull = 0;
|
||||
}
|
||||
excess = sqlite3_memory_used() - n;
|
||||
if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff));
|
||||
sqlite3_mutex_leave(mem0.mutex);
|
||||
return priorLimit;
|
||||
}
|
||||
void sqlite3_soft_heap_limit(int n){
|
||||
@@ -241,25 +240,6 @@ sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
|
||||
return mx;
|
||||
}
|
||||
|
||||
/*
|
||||
** Trigger the alarm
|
||||
*/
|
||||
static void sqlite3MallocAlarm(int nByte){
|
||||
void (*xCallback)(void*,sqlite3_int64,int);
|
||||
sqlite3_int64 nowUsed;
|
||||
void *pArg;
|
||||
if( mem0.alarmCallback==0 ) return;
|
||||
xCallback = mem0.alarmCallback;
|
||||
nowUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
|
||||
pArg = mem0.alarmArg;
|
||||
mem0.alarmCallback = 0;
|
||||
sqlite3_mutex_leave(mem0.mutex);
|
||||
xCallback(pArg, nowUsed, nByte);
|
||||
sqlite3_mutex_enter(mem0.mutex);
|
||||
mem0.alarmCallback = xCallback;
|
||||
mem0.alarmArg = pArg;
|
||||
}
|
||||
|
||||
/*
|
||||
** Do a memory allocation with statistics and alarms. Assume the
|
||||
** lock is already held.
|
||||
@@ -270,19 +250,11 @@ static int mallocWithAlarm(int n, void **pp){
|
||||
assert( sqlite3_mutex_held(mem0.mutex) );
|
||||
nFull = sqlite3GlobalConfig.m.xRoundup(n);
|
||||
sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n);
|
||||
if( mem0.alarmCallback!=0 ){
|
||||
sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
|
||||
if( nUsed >= mem0.alarmThreshold - nFull ){
|
||||
mem0.nearlyFull = 1;
|
||||
sqlite3MallocAlarm(nFull);
|
||||
}else{
|
||||
mem0.nearlyFull = 0;
|
||||
}
|
||||
}
|
||||
sqlite3CheckSoftHeapLimit(nFull);
|
||||
p = sqlite3GlobalConfig.m.xMalloc(nFull);
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
if( p==0 && mem0.alarmCallback ){
|
||||
sqlite3MallocAlarm(nFull);
|
||||
if( p==0 && mem0.alarmThreshold ){
|
||||
sqlite3HeapLimitExceeded(nFull);
|
||||
p = sqlite3GlobalConfig.m.xMalloc(nFull);
|
||||
}
|
||||
#endif
|
||||
@@ -456,19 +428,20 @@ int sqlite3MallocSize(void *p){
|
||||
return sqlite3GlobalConfig.m.xSize(p);
|
||||
}
|
||||
int sqlite3DbMallocSize(sqlite3 *db, void *p){
|
||||
if( db==0 ){
|
||||
assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
|
||||
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
|
||||
return sqlite3MallocSize(p);
|
||||
}else{
|
||||
assert( sqlite3_mutex_held(db->mutex) );
|
||||
if( isLookaside(db, p) ){
|
||||
return db->lookaside.sz;
|
||||
if( db==0 || !isLookaside(db,p) ){
|
||||
#if SQLITE_DEBUG
|
||||
if( db==0 ){
|
||||
assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
|
||||
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
|
||||
}else{
|
||||
assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
|
||||
assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
|
||||
return sqlite3GlobalConfig.m.xSize(p);
|
||||
}
|
||||
#endif
|
||||
return sqlite3GlobalConfig.m.xSize(p);
|
||||
}else{
|
||||
assert( sqlite3_mutex_held(db->mutex) );
|
||||
return db->lookaside.sz;
|
||||
}
|
||||
}
|
||||
sqlite3_uint64 sqlite3_msize(void *p){
|
||||
@@ -564,15 +537,14 @@ void *sqlite3Realloc(void *pOld, u64 nBytes){
|
||||
sqlite3_mutex_enter(mem0.mutex);
|
||||
sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes);
|
||||
nDiff = nNew - nOld;
|
||||
if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >=
|
||||
mem0.alarmThreshold-nDiff ){
|
||||
sqlite3MallocAlarm(nDiff);
|
||||
}
|
||||
sqlite3CheckSoftHeapLimit(nDiff);
|
||||
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
|
||||
if( pNew==0 && mem0.alarmCallback ){
|
||||
sqlite3MallocAlarm((int)nBytes);
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
if( pNew==0 && mem0.alarmThreshold ){
|
||||
sqlite3HeapLimitExceeded((int)nBytes);
|
||||
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
|
||||
}
|
||||
#endif
|
||||
if( pNew ){
|
||||
nNew = sqlite3MallocSize(pNew);
|
||||
sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
|
||||
|
@@ -3146,7 +3146,6 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
|
||||
TIMER_START;
|
||||
assert( cnt==(cnt&0x1ffff) );
|
||||
assert( id->h>2 );
|
||||
cnt &= 0x1ffff;
|
||||
do{
|
||||
#if defined(USE_PREAD)
|
||||
got = osPread(id->h, pBuf, cnt, offset);
|
||||
@@ -3363,8 +3362,8 @@ static int unixWrite(
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
while( amt>0 && (wrote = seekAndWrite(pFile, offset, pBuf, amt))>0 ){
|
||||
|
||||
while( (wrote = seekAndWrite(pFile, offset, pBuf, amt))<amt && wrote>0 ){
|
||||
amt -= wrote;
|
||||
offset += wrote;
|
||||
pBuf = &((char*)pBuf)[wrote];
|
||||
@@ -3372,7 +3371,7 @@ static int unixWrite(
|
||||
SimulateIOError(( wrote=(-1), amt=1 ));
|
||||
SimulateDiskfullError(( wrote=0, amt=1 ));
|
||||
|
||||
if( amt>0 ){
|
||||
if( amt>wrote ){
|
||||
if( wrote<0 && pFile->lastErrno!=ENOSPC ){
|
||||
/* lastErrno set by seekAndWrite */
|
||||
return SQLITE_IOERR_WRITE;
|
||||
|
@@ -392,7 +392,7 @@ static int pcache1MemSize(void *p){
|
||||
/*
|
||||
** Allocate a new page object initially associated with cache pCache.
|
||||
*/
|
||||
static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
|
||||
static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){
|
||||
PgHdr1 *p = 0;
|
||||
void *pPg;
|
||||
|
||||
@@ -410,6 +410,7 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
|
||||
assert( pCache->pGroup==&pcache1.grp );
|
||||
pcache1LeaveMutex(pCache->pGroup);
|
||||
#endif
|
||||
if( benignMalloc ) sqlite3BeginBenignMalloc();
|
||||
#ifdef SQLITE_PCACHE_SEPARATE_HEADER
|
||||
pPg = pcache1Alloc(pCache->szPage);
|
||||
p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra);
|
||||
@@ -422,6 +423,7 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
|
||||
pPg = pcache1Alloc(pCache->szAlloc);
|
||||
p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
|
||||
#endif
|
||||
if( benignMalloc ) sqlite3EndBenignMalloc();
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
pcache1EnterMutex(pCache->pGroup);
|
||||
#endif
|
||||
@@ -867,9 +869,7 @@ static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2(
|
||||
** attempt to allocate a new one.
|
||||
*/
|
||||
if( !pPage ){
|
||||
if( createFlag==1 ){ sqlite3BeginBenignMalloc(); }
|
||||
pPage = pcache1AllocPage(pCache);
|
||||
if( createFlag==1 ){ sqlite3EndBenignMalloc(); }
|
||||
pPage = pcache1AllocPage(pCache, createFlag==1);
|
||||
}
|
||||
|
||||
if( pPage ){
|
||||
|
348
src/pragma.c
348
src/pragma.c
@@ -159,20 +159,46 @@ static int changeTempStorage(Parse *pParse, const char *zStorageType){
|
||||
}
|
||||
#endif /* SQLITE_PAGER_PRAGMAS */
|
||||
|
||||
/*
|
||||
** Set the names of the first N columns to the values in azCol[]
|
||||
*/
|
||||
static void setAllColumnNames(
|
||||
Vdbe *v, /* The query under construction */
|
||||
int N, /* Number of columns */
|
||||
const char **azCol /* Names of columns */
|
||||
){
|
||||
int i;
|
||||
sqlite3VdbeSetNumCols(v, N);
|
||||
for(i=0; i<N; i++){
|
||||
sqlite3VdbeSetColName(v, i, COLNAME_NAME, azCol[i], SQLITE_STATIC);
|
||||
}
|
||||
}
|
||||
static void setOneColumnName(Vdbe *v, const char *z){
|
||||
setAllColumnNames(v, 1, &z);
|
||||
}
|
||||
|
||||
/*
|
||||
** Generate code to return a single integer value.
|
||||
*/
|
||||
static void returnSingleInt(Parse *pParse, const char *zLabel, i64 value){
|
||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||
int nMem = ++pParse->nMem;
|
||||
i64 *pI64 = sqlite3DbMallocRaw(pParse->db, sizeof(value));
|
||||
if( pI64 ){
|
||||
memcpy(pI64, &value, sizeof(value));
|
||||
static void returnSingleInt(Vdbe *v, const char *zLabel, i64 value){
|
||||
sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, 1, 0, (const u8*)&value, P4_INT64);
|
||||
setOneColumnName(v, zLabel);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
** Generate code to return a single text value.
|
||||
*/
|
||||
static void returnSingleText(
|
||||
Vdbe *v, /* Prepared statement under construction */
|
||||
const char *zLabel, /* Name of the result column */
|
||||
const char *zValue /* Value to be returned */
|
||||
){
|
||||
if( zValue ){
|
||||
sqlite3VdbeLoadString(v, 1, (const char*)zValue);
|
||||
setOneColumnName(v, zLabel);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
|
||||
}
|
||||
sqlite3VdbeAddOp4(v, OP_Int64, 0, nMem, 0, (char*)pI64, P4_INT64);
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, nMem, 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -336,14 +362,8 @@ void sqlite3Pragma(
|
||||
db->busyHandler.nBusy = 0;
|
||||
rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
|
||||
if( rc==SQLITE_OK ){
|
||||
if( aFcntl[0] ){
|
||||
int nMem = ++pParse->nMem;
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, nMem, 0, aFcntl[0], 0);
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "result", SQLITE_STATIC);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, nMem, 1);
|
||||
sqlite3_free(aFcntl[0]);
|
||||
}
|
||||
returnSingleText(v, "result", aFcntl[0]);
|
||||
sqlite3_free(aFcntl[0]);
|
||||
goto pragma_out;
|
||||
}
|
||||
if( rc!=SQLITE_NOTFOUND ){
|
||||
@@ -413,8 +433,7 @@ void sqlite3Pragma(
|
||||
int addr;
|
||||
sqlite3VdbeUsesBtree(v, iDb);
|
||||
if( !zRight ){
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", SQLITE_STATIC);
|
||||
setOneColumnName(v, "cache_size");
|
||||
pParse->nMem += 2;
|
||||
addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize,iLn);
|
||||
sqlite3VdbeChangeP1(v, addr, iDb);
|
||||
@@ -448,7 +467,7 @@ void sqlite3Pragma(
|
||||
assert( pBt!=0 );
|
||||
if( !zRight ){
|
||||
int size = ALWAYS(pBt) ? sqlite3BtreeGetPageSize(pBt) : 0;
|
||||
returnSingleInt(pParse, "page_size", size);
|
||||
returnSingleInt(v, "page_size", size);
|
||||
}else{
|
||||
/* Malloc may fail when setting the page-size, as there is an internal
|
||||
** buffer that the pager module resizes using sqlite3_realloc().
|
||||
@@ -483,7 +502,7 @@ void sqlite3Pragma(
|
||||
}
|
||||
}
|
||||
b = sqlite3BtreeSecureDelete(pBt, b);
|
||||
returnSingleInt(pParse, "secure_delete", b);
|
||||
returnSingleInt(v, "secure_delete", b);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -562,10 +581,7 @@ void sqlite3Pragma(
|
||||
if( eMode==PAGER_LOCKINGMODE_EXCLUSIVE ){
|
||||
zRet = "exclusive";
|
||||
}
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "locking_mode", SQLITE_STATIC);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, zRet, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
|
||||
returnSingleText(v, "locking_mode", zRet);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -578,9 +594,7 @@ void sqlite3Pragma(
|
||||
int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */
|
||||
int ii; /* Loop counter */
|
||||
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", SQLITE_STATIC);
|
||||
|
||||
setOneColumnName(v, "journal_mode");
|
||||
if( zRight==0 ){
|
||||
/* If there is no "=MODE" part of the pragma, do a query for the
|
||||
** current mode */
|
||||
@@ -626,7 +640,7 @@ void sqlite3Pragma(
|
||||
if( iLimit<-1 ) iLimit = -1;
|
||||
}
|
||||
iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit);
|
||||
returnSingleInt(pParse, "journal_size_limit", iLimit);
|
||||
returnSingleInt(v, "journal_size_limit", iLimit);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -644,7 +658,7 @@ void sqlite3Pragma(
|
||||
Btree *pBt = pDb->pBt;
|
||||
assert( pBt!=0 );
|
||||
if( !zRight ){
|
||||
returnSingleInt(pParse, "auto_vacuum", sqlite3BtreeGetAutoVacuum(pBt));
|
||||
returnSingleInt(v, "auto_vacuum", sqlite3BtreeGetAutoVacuum(pBt));
|
||||
}else{
|
||||
int eAuto = getAutoVacuum(zRight);
|
||||
assert( eAuto>=0 && eAuto<=2 );
|
||||
@@ -722,7 +736,7 @@ void sqlite3Pragma(
|
||||
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
|
||||
if( !zRight ){
|
||||
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
||||
returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size);
|
||||
returnSingleInt(v, "cache_size", pDb->pSchema->cache_size);
|
||||
}else{
|
||||
int size = sqlite3Atoi(zRight);
|
||||
pDb->pSchema->cache_size = size;
|
||||
@@ -768,7 +782,7 @@ void sqlite3Pragma(
|
||||
rc = SQLITE_OK;
|
||||
#endif
|
||||
if( rc==SQLITE_OK ){
|
||||
returnSingleInt(pParse, "mmap_size", sz);
|
||||
returnSingleInt(v, "mmap_size", sz);
|
||||
}else if( rc!=SQLITE_NOTFOUND ){
|
||||
pParse->nErr++;
|
||||
pParse->rc = rc;
|
||||
@@ -789,7 +803,7 @@ void sqlite3Pragma(
|
||||
*/
|
||||
case PragTyp_TEMP_STORE: {
|
||||
if( !zRight ){
|
||||
returnSingleInt(pParse, "temp_store", db->temp_store);
|
||||
returnSingleInt(v, "temp_store", db->temp_store);
|
||||
}else{
|
||||
changeTempStorage(pParse, zRight);
|
||||
}
|
||||
@@ -808,13 +822,7 @@ void sqlite3Pragma(
|
||||
*/
|
||||
case PragTyp_TEMP_STORE_DIRECTORY: {
|
||||
if( !zRight ){
|
||||
if( sqlite3_temp_directory ){
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME,
|
||||
"temp_store_directory", SQLITE_STATIC);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, sqlite3_temp_directory, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
|
||||
}
|
||||
returnSingleText(v, "temp_store_directory", sqlite3_temp_directory);
|
||||
}else{
|
||||
#ifndef SQLITE_OMIT_WSD
|
||||
if( zRight[0] ){
|
||||
@@ -858,13 +866,7 @@ void sqlite3Pragma(
|
||||
*/
|
||||
case PragTyp_DATA_STORE_DIRECTORY: {
|
||||
if( !zRight ){
|
||||
if( sqlite3_data_directory ){
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME,
|
||||
"data_store_directory", SQLITE_STATIC);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, sqlite3_data_directory, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
|
||||
}
|
||||
returnSingleText(v, "data_store_directory", sqlite3_data_directory);
|
||||
}else{
|
||||
#ifndef SQLITE_OMIT_WSD
|
||||
if( zRight[0] ){
|
||||
@@ -903,14 +905,7 @@ void sqlite3Pragma(
|
||||
sqlite3_file *pFile = sqlite3PagerFile(pPager);
|
||||
sqlite3OsFileControlHint(pFile, SQLITE_GET_LOCKPROXYFILE,
|
||||
&proxy_file_path);
|
||||
|
||||
if( proxy_file_path ){
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME,
|
||||
"lock_proxy_file", SQLITE_STATIC);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, proxy_file_path, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
|
||||
}
|
||||
returnSingleText(v, "lock_proxy_file", proxy_file_path);
|
||||
}else{
|
||||
Pager *pPager = sqlite3BtreePager(pDb->pBt);
|
||||
sqlite3_file *pFile = sqlite3PagerFile(pPager);
|
||||
@@ -942,7 +937,7 @@ void sqlite3Pragma(
|
||||
*/
|
||||
case PragTyp_SYNCHRONOUS: {
|
||||
if( !zRight ){
|
||||
returnSingleInt(pParse, "synchronous", pDb->safety_level-1);
|
||||
returnSingleInt(v, "synchronous", pDb->safety_level-1);
|
||||
}else{
|
||||
if( !db->autoCommit ){
|
||||
sqlite3ErrorMsg(pParse,
|
||||
@@ -961,7 +956,7 @@ void sqlite3Pragma(
|
||||
#ifndef SQLITE_OMIT_FLAG_PRAGMAS
|
||||
case PragTyp_FLAG: {
|
||||
if( zRight==0 ){
|
||||
returnSingleInt(pParse, pPragma->zName, (db->flags & pPragma->iArg)!=0 );
|
||||
returnSingleInt(v, pPragma->zName, (db->flags & pPragma->iArg)!=0 );
|
||||
}else{
|
||||
int mask = pPragma->iArg; /* Mask of bits to set or clear. */
|
||||
if( db->autoCommit==0 ){
|
||||
@@ -1011,35 +1006,22 @@ void sqlite3Pragma(
|
||||
Table *pTab;
|
||||
pTab = sqlite3FindTable(db, zRight, zDb);
|
||||
if( pTab ){
|
||||
static const char *azCol[] = {
|
||||
"cid", "name", "type", "notnull", "dflt_value", "pk"
|
||||
};
|
||||
int i, k;
|
||||
int nHidden = 0;
|
||||
Column *pCol;
|
||||
Index *pPk = sqlite3PrimaryKeyIndex(pTab);
|
||||
sqlite3VdbeSetNumCols(v, 6);
|
||||
pParse->nMem = 6;
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "type", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "notnull", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "dflt_value", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "pk", SQLITE_STATIC);
|
||||
setAllColumnNames(v, 6, azCol); assert( 6==ArraySize(azCol) );
|
||||
sqlite3ViewGetColumnNames(pParse, pTab);
|
||||
for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
|
||||
if( IsHiddenColumn(pCol) ){
|
||||
nHidden++;
|
||||
continue;
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, i-nHidden, 1);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pCol->zName, 0);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
|
||||
pCol->zType ? pCol->zType : "", 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, (pCol->notNull ? 1 : 0), 4);
|
||||
if( pCol->zDflt ){
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, (char*)pCol->zDflt, 0);
|
||||
}else{
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, 5);
|
||||
}
|
||||
if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){
|
||||
k = 0;
|
||||
}else if( pPk==0 ){
|
||||
@@ -1047,7 +1029,13 @@ void sqlite3Pragma(
|
||||
}else{
|
||||
for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, k, 6);
|
||||
sqlite3VdbeMultiLoad(v, 1, "issisi",
|
||||
i-nHidden,
|
||||
pCol->zName,
|
||||
pCol->zType ? pCol->zType : "",
|
||||
pCol->notNull ? 1 : 0,
|
||||
pCol->zDflt,
|
||||
k);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);
|
||||
}
|
||||
}
|
||||
@@ -1055,31 +1043,26 @@ void sqlite3Pragma(
|
||||
break;
|
||||
|
||||
case PragTyp_STATS: {
|
||||
static const char *azCol[] = { "table", "index", "width", "height" };
|
||||
Index *pIdx;
|
||||
HashElem *i;
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
sqlite3VdbeSetNumCols(v, 4);
|
||||
pParse->nMem = 4;
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "table", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "index", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "width", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "height", SQLITE_STATIC);
|
||||
setAllColumnNames(v, 4, azCol); assert( 4==ArraySize(azCol) );
|
||||
for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){
|
||||
Table *pTab = sqliteHashData(i);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, pTab->zName, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, 2);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer,
|
||||
(int)sqlite3LogEstToInt(pTab->szTabRow), 3);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer,
|
||||
(int)sqlite3LogEstToInt(pTab->nRowLogEst), 4);
|
||||
sqlite3VdbeMultiLoad(v, 1, "ssii",
|
||||
pTab->zName,
|
||||
0,
|
||||
(int)sqlite3LogEstToInt(pTab->szTabRow),
|
||||
(int)sqlite3LogEstToInt(pTab->nRowLogEst));
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
|
||||
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer,
|
||||
(int)sqlite3LogEstToInt(pIdx->szIdxRow), 3);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer,
|
||||
(int)sqlite3LogEstToInt(pIdx->aiRowLogEst[0]), 4);
|
||||
sqlite3VdbeMultiLoad(v, 2, "sii",
|
||||
pIdx->zName,
|
||||
(int)sqlite3LogEstToInt(pIdx->szIdxRow),
|
||||
(int)sqlite3LogEstToInt(pIdx->aiRowLogEst[0]));
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
|
||||
}
|
||||
}
|
||||
@@ -1091,6 +1074,9 @@ void sqlite3Pragma(
|
||||
Table *pTab;
|
||||
pIdx = sqlite3FindIndex(db, zRight, zDb);
|
||||
if( pIdx ){
|
||||
static const char *azCol[] = {
|
||||
"seqno", "cid", "name", "desc", "coll", "key"
|
||||
};
|
||||
int i;
|
||||
int mx;
|
||||
if( pPragma->iArg ){
|
||||
@@ -1103,29 +1089,18 @@ void sqlite3Pragma(
|
||||
pParse->nMem = 3;
|
||||
}
|
||||
pTab = pIdx->pTable;
|
||||
sqlite3VdbeSetNumCols(v, pParse->nMem);
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", SQLITE_STATIC);
|
||||
if( pPragma->iArg ){
|
||||
sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "desc", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "coll", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "key", SQLITE_STATIC);
|
||||
}
|
||||
assert( pParse->nMem<=ArraySize(azCol) );
|
||||
setAllColumnNames(v, pParse->nMem, azCol);
|
||||
for(i=0; i<mx; i++){
|
||||
i16 cnum = pIdx->aiColumn[i];
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, cnum, 2);
|
||||
if( cnum<0 ){
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, 3);
|
||||
}else{
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pTab->aCol[cnum].zName, 0);
|
||||
}
|
||||
sqlite3VdbeMultiLoad(v, 1, "iis", i, cnum,
|
||||
cnum<0 ? 0 : pTab->aCol[cnum].zName);
|
||||
if( pPragma->iArg ){
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->aSortOrder[i], 4);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, pIdx->azColl[i], 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, i<pIdx->nKeyCol, 6);
|
||||
sqlite3VdbeMultiLoad(v, 4, "isi",
|
||||
pIdx->aSortOrder[i],
|
||||
pIdx->azColl[i],
|
||||
i<pIdx->nKeyCol);
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, pParse->nMem);
|
||||
}
|
||||
@@ -1139,22 +1114,21 @@ void sqlite3Pragma(
|
||||
int i;
|
||||
pTab = sqlite3FindTable(db, zRight, zDb);
|
||||
if( pTab ){
|
||||
static const char *azCol[] = {
|
||||
"seq", "name", "unique", "origin", "partial"
|
||||
};
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
sqlite3VdbeSetNumCols(v, 5);
|
||||
pParse->nMem = 5;
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "origin", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "partial", SQLITE_STATIC);
|
||||
setAllColumnNames(v, 5, azCol); assert( 5==ArraySize(azCol) );
|
||||
for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){
|
||||
const char *azOrigin[] = { "c", "u", "pk" };
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, IsUniqueIndex(pIdx), 3);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, azOrigin[pIdx->idxType], 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->pPartIdxWhere!=0, 5);
|
||||
sqlite3VdbeMultiLoad(v, 1, "isisi",
|
||||
i,
|
||||
pIdx->zName,
|
||||
IsUniqueIndex(pIdx),
|
||||
azOrigin[pIdx->idxType],
|
||||
pIdx->pPartIdxWhere!=0);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5);
|
||||
}
|
||||
}
|
||||
@@ -1162,35 +1136,31 @@ void sqlite3Pragma(
|
||||
break;
|
||||
|
||||
case PragTyp_DATABASE_LIST: {
|
||||
static const char *azCol[] = { "seq", "name", "file" };
|
||||
int i;
|
||||
sqlite3VdbeSetNumCols(v, 3);
|
||||
pParse->nMem = 3;
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "file", SQLITE_STATIC);
|
||||
setAllColumnNames(v, 3, azCol); assert( 3==ArraySize(azCol) );
|
||||
for(i=0; i<db->nDb; i++){
|
||||
if( db->aDb[i].pBt==0 ) continue;
|
||||
assert( db->aDb[i].zName!=0 );
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, db->aDb[i].zName, 0);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
|
||||
sqlite3BtreeGetFilename(db->aDb[i].pBt), 0);
|
||||
sqlite3VdbeMultiLoad(v, 1, "iss",
|
||||
i,
|
||||
db->aDb[i].zName,
|
||||
sqlite3BtreeGetFilename(db->aDb[i].pBt));
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PragTyp_COLLATION_LIST: {
|
||||
static const char *azCol[] = { "seq", "name" };
|
||||
int i = 0;
|
||||
HashElem *p;
|
||||
sqlite3VdbeSetNumCols(v, 2);
|
||||
pParse->nMem = 2;
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
|
||||
setAllColumnNames(v, 2, azCol); assert( 2==ArraySize(azCol) );
|
||||
for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){
|
||||
CollSeq *pColl = (CollSeq *)sqliteHashData(p);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, i++, 1);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pColl->zName, 0);
|
||||
sqlite3VdbeMultiLoad(v, 1, "is", i++, pColl->zName);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2);
|
||||
}
|
||||
}
|
||||
@@ -1206,33 +1176,26 @@ void sqlite3Pragma(
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
pFK = pTab->pFKey;
|
||||
if( pFK ){
|
||||
static const char *azCol[] = {
|
||||
"id", "seq", "table", "from", "to", "on_update", "on_delete",
|
||||
"match"
|
||||
};
|
||||
int i = 0;
|
||||
sqlite3VdbeSetNumCols(v, 8);
|
||||
pParse->nMem = 8;
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "id", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "seq", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "table", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "from", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "to", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "on_update", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 6, COLNAME_NAME, "on_delete", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 7, COLNAME_NAME, "match", SQLITE_STATIC);
|
||||
setAllColumnNames(v, 8, azCol); assert( 8==ArraySize(azCol) );
|
||||
while(pFK){
|
||||
int j;
|
||||
for(j=0; j<pFK->nCol; j++){
|
||||
char *zCol = pFK->aCol[j].zCol;
|
||||
char *zOnDelete = (char *)actionName(pFK->aAction[0]);
|
||||
char *zOnUpdate = (char *)actionName(pFK->aAction[1]);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, j, 2);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pFK->zTo, 0);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0,
|
||||
pTab->aCol[pFK->aCol[j].iFrom].zName, 0);
|
||||
sqlite3VdbeAddOp4(v, zCol ? OP_String8 : OP_Null, 0, 5, 0, zCol, 0);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 6, 0, zOnUpdate, 0);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 7, 0, zOnDelete, 0);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 8, 0, "NONE", 0);
|
||||
sqlite3VdbeMultiLoad(v, 1, "iissssss",
|
||||
i,
|
||||
j,
|
||||
pFK->zTo,
|
||||
pTab->aCol[pFK->aCol[j].iFrom].zName,
|
||||
pFK->aCol[j].zCol,
|
||||
actionName(pFK->aAction[1]), /* ON UPDATE */
|
||||
actionName(pFK->aAction[0]), /* ON DELETE */
|
||||
"NONE");
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 8);
|
||||
}
|
||||
++i;
|
||||
@@ -1261,17 +1224,14 @@ void sqlite3Pragma(
|
||||
int addrTop; /* Top of a loop checking foreign keys */
|
||||
int addrOk; /* Jump here if the key is OK */
|
||||
int *aiCols; /* child to parent column mapping */
|
||||
static const char *azCol[] = { "table", "rowid", "parent", "fkid" };
|
||||
|
||||
regResult = pParse->nMem+1;
|
||||
pParse->nMem += 4;
|
||||
regKey = ++pParse->nMem;
|
||||
regRow = ++pParse->nMem;
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
sqlite3VdbeSetNumCols(v, 4);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "table", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "rowid", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "parent", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "fkid", SQLITE_STATIC);
|
||||
setAllColumnNames(v, 4, azCol); assert( 4==ArraySize(azCol) );
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash);
|
||||
while( k ){
|
||||
@@ -1286,8 +1246,7 @@ void sqlite3Pragma(
|
||||
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
|
||||
if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow;
|
||||
sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, regResult, 0, pTab->zName,
|
||||
P4_TRANSIENT);
|
||||
sqlite3VdbeLoadString(v, regResult, pTab->zName);
|
||||
for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
|
||||
pParent = sqlite3FindTable(db, pFK->zTo, zDb);
|
||||
if( pParent==0 ) continue;
|
||||
@@ -1332,7 +1291,7 @@ void sqlite3Pragma(
|
||||
sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow);
|
||||
}
|
||||
sqlite3VdbeAddOp3(v, OP_NotExists, i, 0, regRow); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrOk);
|
||||
sqlite3VdbeGoto(v, addrOk);
|
||||
sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
|
||||
}else{
|
||||
for(j=0; j<pFK->nCol; j++){
|
||||
@@ -1348,9 +1307,7 @@ void sqlite3Pragma(
|
||||
}
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, regResult+2, 0,
|
||||
pFK->zTo, P4_TRANSIENT);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, i-1, regResult+3);
|
||||
sqlite3VdbeMultiLoad(v, regResult+2, "si", pFK->zTo, i-1);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 4);
|
||||
sqlite3VdbeResolveLabel(v, addrOk);
|
||||
sqlite3DbFree(db, aiCols);
|
||||
@@ -1426,8 +1383,7 @@ void sqlite3Pragma(
|
||||
|
||||
/* Initialize the VDBE program */
|
||||
pParse->nMem = 6;
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", SQLITE_STATIC);
|
||||
setOneColumnName(v, "integrity_check");
|
||||
|
||||
/* Set the maximum error count */
|
||||
mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
|
||||
@@ -1549,13 +1505,11 @@ void sqlite3Pragma(
|
||||
jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1,
|
||||
pIdx->nColumn); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, "row ", P4_STATIC);
|
||||
sqlite3VdbeLoadString(v, 3, "row ");
|
||||
sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0,
|
||||
" missing from index ", P4_STATIC);
|
||||
sqlite3VdbeLoadString(v, 4, " missing from index ");
|
||||
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
|
||||
jmp5 = sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0,
|
||||
pIdx->zName, P4_TRANSIENT);
|
||||
jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName);
|
||||
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
|
||||
jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v);
|
||||
@@ -1576,14 +1530,13 @@ void sqlite3Pragma(
|
||||
VdbeCoverage(v);
|
||||
}
|
||||
jmp6 = sqlite3VdbeAddOp1(v, OP_Next, iIdxCur+j); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, uniqOk);
|
||||
sqlite3VdbeGoto(v, uniqOk);
|
||||
sqlite3VdbeJumpHere(v, jmp6);
|
||||
sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1,
|
||||
pIdx->nKeyCol); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
|
||||
"non-unique entry in index ", P4_STATIC);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, jmp5);
|
||||
sqlite3VdbeLoadString(v, 3, "non-unique entry in index ");
|
||||
sqlite3VdbeGoto(v, jmp5);
|
||||
sqlite3VdbeResolveLabel(v, uniqOk);
|
||||
}
|
||||
sqlite3VdbeJumpHere(v, jmp4);
|
||||
@@ -1592,8 +1545,7 @@ void sqlite3Pragma(
|
||||
sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
|
||||
sqlite3VdbeJumpHere(v, loopTop-1);
|
||||
#ifndef SQLITE_OMIT_BTREECOUNT
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0,
|
||||
"wrong # of entries in index ", P4_STATIC);
|
||||
sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
|
||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||
if( pPk==pIdx ) continue;
|
||||
addr = sqlite3VdbeCurrentAddr(v);
|
||||
@@ -1603,7 +1555,7 @@ void sqlite3Pragma(
|
||||
sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); VdbeCoverage(v);
|
||||
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
|
||||
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pIdx->zName, P4_TRANSIENT);
|
||||
sqlite3VdbeLoadString(v, 3, pIdx->zName);
|
||||
sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1);
|
||||
}
|
||||
@@ -1659,14 +1611,10 @@ void sqlite3Pragma(
|
||||
const struct EncName *pEnc;
|
||||
if( !zRight ){ /* "PRAGMA encoding" */
|
||||
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "encoding", SQLITE_STATIC);
|
||||
sqlite3VdbeAddOp2(v, OP_String8, 0, 1);
|
||||
assert( encnames[SQLITE_UTF8].enc==SQLITE_UTF8 );
|
||||
assert( encnames[SQLITE_UTF16LE].enc==SQLITE_UTF16LE );
|
||||
assert( encnames[SQLITE_UTF16BE].enc==SQLITE_UTF16BE );
|
||||
sqlite3VdbeChangeP4(v, -1, encnames[ENC(pParse->db)].zName, P4_STATIC);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
|
||||
returnSingleText(v, "encoding", encnames[ENC(pParse->db)].zName);
|
||||
}else{ /* "PRAGMA encoding = XXX" */
|
||||
/* Only change the value of sqlite.enc if the database handle is not
|
||||
** initialized. If the main database exists, the new sqlite.enc value
|
||||
@@ -1767,11 +1715,10 @@ void sqlite3Pragma(
|
||||
case PragTyp_COMPILE_OPTIONS: {
|
||||
int i = 0;
|
||||
const char *zOpt;
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
pParse->nMem = 1;
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "compile_option", SQLITE_STATIC);
|
||||
setOneColumnName(v, "compile_option");
|
||||
while( (zOpt = sqlite3_compileoption_get(i++))!=0 ){
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, zOpt, 0);
|
||||
sqlite3VdbeLoadString(v, 1, zOpt);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
|
||||
}
|
||||
}
|
||||
@@ -1785,6 +1732,7 @@ void sqlite3Pragma(
|
||||
** Checkpoint the database.
|
||||
*/
|
||||
case PragTyp_WAL_CHECKPOINT: {
|
||||
static const char *azCol[] = { "busy", "log", "checkpointed" };
|
||||
int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED);
|
||||
int eMode = SQLITE_CHECKPOINT_PASSIVE;
|
||||
if( zRight ){
|
||||
@@ -1796,12 +1744,8 @@ void sqlite3Pragma(
|
||||
eMode = SQLITE_CHECKPOINT_TRUNCATE;
|
||||
}
|
||||
}
|
||||
sqlite3VdbeSetNumCols(v, 3);
|
||||
setAllColumnNames(v, 3, azCol); assert( 3==ArraySize(azCol) );
|
||||
pParse->nMem = 3;
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "busy", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "log", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "checkpointed", SQLITE_STATIC);
|
||||
|
||||
sqlite3VdbeAddOp3(v, OP_Checkpoint, iBt, eMode, 1);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
|
||||
}
|
||||
@@ -1819,7 +1763,7 @@ void sqlite3Pragma(
|
||||
if( zRight ){
|
||||
sqlite3_wal_autocheckpoint(db, sqlite3Atoi(zRight));
|
||||
}
|
||||
returnSingleInt(pParse, "wal_autocheckpoint",
|
||||
returnSingleInt(v, "wal_autocheckpoint",
|
||||
db->xWalCallback==sqlite3WalDefaultHook ?
|
||||
SQLITE_PTR_TO_INT(db->pWalArg) : 0);
|
||||
}
|
||||
@@ -1852,7 +1796,7 @@ void sqlite3Pragma(
|
||||
if( zRight ){
|
||||
sqlite3_busy_timeout(db, sqlite3Atoi(zRight));
|
||||
}
|
||||
returnSingleInt(pParse, "timeout", db->busyTimeout);
|
||||
returnSingleInt(v, "timeout", db->busyTimeout);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1872,7 +1816,7 @@ void sqlite3Pragma(
|
||||
if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){
|
||||
sqlite3_soft_heap_limit64(N);
|
||||
}
|
||||
returnSingleInt(pParse, "soft_heap_limit", sqlite3_soft_heap_limit64(-1));
|
||||
returnSingleInt(v, "soft_heap_limit", sqlite3_soft_heap_limit64(-1));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1891,7 +1835,7 @@ void sqlite3Pragma(
|
||||
){
|
||||
sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff));
|
||||
}
|
||||
returnSingleInt(pParse, "threads",
|
||||
returnSingleInt(v, "threads",
|
||||
sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1));
|
||||
break;
|
||||
}
|
||||
@@ -1904,17 +1848,15 @@ void sqlite3Pragma(
|
||||
static const char *const azLockName[] = {
|
||||
"unlocked", "shared", "reserved", "pending", "exclusive"
|
||||
};
|
||||
static const char *azCol[] = { "database", "status" };
|
||||
int i;
|
||||
sqlite3VdbeSetNumCols(v, 2);
|
||||
setAllColumnNames(v, 2, azCol); assert( 2==ArraySize(azCol) );
|
||||
pParse->nMem = 2;
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "database", SQLITE_STATIC);
|
||||
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "status", SQLITE_STATIC);
|
||||
for(i=0; i<db->nDb; i++){
|
||||
Btree *pBt;
|
||||
const char *zState = "unknown";
|
||||
int j;
|
||||
if( db->aDb[i].zName==0 ) continue;
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, db->aDb[i].zName, P4_STATIC);
|
||||
pBt = db->aDb[i].pBt;
|
||||
if( pBt==0 || sqlite3BtreePager(pBt)==0 ){
|
||||
zState = "closed";
|
||||
@@ -1922,7 +1864,7 @@ void sqlite3Pragma(
|
||||
SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){
|
||||
zState = azLockName[j];
|
||||
}
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, zState, P4_STATIC);
|
||||
sqlite3VdbeMultiLoad(v, 1, "ss", db->aDb[i].zName, zState);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2);
|
||||
}
|
||||
break;
|
||||
|
29
src/printf.c
29
src/printf.c
@@ -468,21 +468,16 @@ void sqlite3VXPrintf(
|
||||
if( realvalue>0.0 ){
|
||||
LONGDOUBLE_TYPE scale = 1.0;
|
||||
while( realvalue>=1e100*scale && exp<=350 ){ scale *= 1e100;exp+=100;}
|
||||
while( realvalue>=1e64*scale && exp<=350 ){ scale *= 1e64; exp+=64; }
|
||||
while( realvalue>=1e8*scale && exp<=350 ){ scale *= 1e8; exp+=8; }
|
||||
while( realvalue>=1e10*scale && exp<=350 ){ scale *= 1e10; exp+=10; }
|
||||
while( realvalue>=10.0*scale && exp<=350 ){ scale *= 10.0; exp++; }
|
||||
realvalue /= scale;
|
||||
while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; }
|
||||
while( realvalue<1.0 ){ realvalue *= 10.0; exp--; }
|
||||
if( exp>350 ){
|
||||
if( prefix=='-' ){
|
||||
bufpt = "-Inf";
|
||||
}else if( prefix=='+' ){
|
||||
bufpt = "+Inf";
|
||||
}else{
|
||||
bufpt = "Inf";
|
||||
}
|
||||
length = sqlite3Strlen30(bufpt);
|
||||
bufpt = buf;
|
||||
buf[0] = prefix;
|
||||
memcpy(buf+(prefix!=0),"Inf",4);
|
||||
length = 3+(prefix!=0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -631,12 +626,13 @@ void sqlite3VXPrintf(
|
||||
case etDYNSTRING:
|
||||
if( bArgList ){
|
||||
bufpt = getTextArg(pArgList);
|
||||
xtype = etSTRING;
|
||||
}else{
|
||||
bufpt = va_arg(ap,char*);
|
||||
}
|
||||
if( bufpt==0 ){
|
||||
bufpt = "";
|
||||
}else if( xtype==etDYNSTRING && !bArgList ){
|
||||
}else if( xtype==etDYNSTRING ){
|
||||
zExtra = bufpt;
|
||||
}
|
||||
if( precision>=0 ){
|
||||
@@ -645,9 +641,9 @@ void sqlite3VXPrintf(
|
||||
length = sqlite3Strlen30(bufpt);
|
||||
}
|
||||
break;
|
||||
case etSQLESCAPE:
|
||||
case etSQLESCAPE2:
|
||||
case etSQLESCAPE3: {
|
||||
case etSQLESCAPE: /* Escape ' characters */
|
||||
case etSQLESCAPE2: /* Escape ' and enclose in '...' */
|
||||
case etSQLESCAPE3: { /* Escape " characters */
|
||||
int i, j, k, n, isnull;
|
||||
int needQuote;
|
||||
char ch;
|
||||
@@ -666,7 +662,7 @@ void sqlite3VXPrintf(
|
||||
if( ch==q ) n++;
|
||||
}
|
||||
needQuote = !isnull && xtype==etSQLESCAPE2;
|
||||
n += i + 1 + needQuote*2;
|
||||
n += i + 3;
|
||||
if( n>etBUFSIZE ){
|
||||
bufpt = zExtra = sqlite3Malloc( n );
|
||||
if( bufpt==0 ){
|
||||
@@ -1062,7 +1058,8 @@ void sqlite3DebugPrintf(const char *zFormat, ...){
|
||||
|
||||
|
||||
/*
|
||||
** variable-argument wrapper around sqlite3VXPrintf().
|
||||
** variable-argument wrapper around sqlite3VXPrintf(). The bFlags argument
|
||||
** can contain the bit SQLITE_PRINTF_INTERNAL enable internal formats.
|
||||
*/
|
||||
void sqlite3XPrintf(StrAccum *p, u32 bFlags, const char *zFormat, ...){
|
||||
va_list ap;
|
||||
|
24
src/select.c
24
src/select.c
@@ -597,7 +597,7 @@ static void codeOffset(
|
||||
if( iOffset>0 ){
|
||||
int addr;
|
||||
addr = sqlite3VdbeAddOp3(v, OP_IfNeg, iOffset, 0, -1); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, iContinue);
|
||||
sqlite3VdbeGoto(v, iContinue);
|
||||
VdbeComment((v, "skip OFFSET records"));
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
}
|
||||
@@ -1206,7 +1206,7 @@ static void generateSortTail(
|
||||
|
||||
if( pSort->labelBkOut ){
|
||||
sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrBreak);
|
||||
sqlite3VdbeGoto(v, addrBreak);
|
||||
sqlite3VdbeResolveLabel(v, pSort->labelBkOut);
|
||||
}
|
||||
iTab = pSort->iECursor;
|
||||
@@ -1834,7 +1834,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit);
|
||||
VdbeComment((v, "LIMIT counter"));
|
||||
if( n==0 ){
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak);
|
||||
sqlite3VdbeGoto(v, iBreak);
|
||||
}else if( n>=0 && p->nSelectRow>(u64)n ){
|
||||
p->nSelectRow = n;
|
||||
}
|
||||
@@ -2082,7 +2082,7 @@ static void generateWithRecursiveQuery(
|
||||
}
|
||||
|
||||
/* Keep running the loop until the Queue is empty */
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
|
||||
sqlite3VdbeGoto(v, addrTop);
|
||||
sqlite3VdbeResolveLabel(v, addrBreak);
|
||||
|
||||
end_of_recursive_query:
|
||||
@@ -2991,7 +2991,7 @@ static int multiSelectOrderBy(
|
||||
addrEofA = sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
|
||||
addrEofA_noB = sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, labelEnd);
|
||||
VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofA);
|
||||
sqlite3VdbeGoto(v, addrEofA);
|
||||
p->nSelectRow += pPrior->nSelectRow;
|
||||
}
|
||||
|
||||
@@ -3005,7 +3005,7 @@ static int multiSelectOrderBy(
|
||||
VdbeNoopComment((v, "eof-B subroutine"));
|
||||
addrEofB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
|
||||
sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, labelEnd); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofB);
|
||||
sqlite3VdbeGoto(v, addrEofB);
|
||||
}
|
||||
|
||||
/* Generate code to handle the case of A<B
|
||||
@@ -3013,7 +3013,7 @@ static int multiSelectOrderBy(
|
||||
VdbeNoopComment((v, "A-lt-B subroutine"));
|
||||
addrAltB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
|
||||
sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
|
||||
sqlite3VdbeGoto(v, labelCmpr);
|
||||
|
||||
/* Generate code to handle the case of A==B
|
||||
*/
|
||||
@@ -3026,7 +3026,7 @@ static int multiSelectOrderBy(
|
||||
VdbeNoopComment((v, "A-eq-B subroutine"));
|
||||
addrAeqB =
|
||||
sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
|
||||
sqlite3VdbeGoto(v, labelCmpr);
|
||||
}
|
||||
|
||||
/* Generate code to handle the case of A>B
|
||||
@@ -3037,7 +3037,7 @@ static int multiSelectOrderBy(
|
||||
sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
|
||||
sqlite3VdbeGoto(v, labelCmpr);
|
||||
|
||||
/* This code runs once to initialize everything.
|
||||
*/
|
||||
@@ -5075,7 +5075,7 @@ int sqlite3Select(
|
||||
p->nSelectRow = LARGEST_INT64;
|
||||
computeLimitRegisters(pParse, p, iEnd);
|
||||
if( p->iLimit==0 && sSort.addrSortIndex>=0 ){
|
||||
sqlite3VdbeGetOp(v, sSort.addrSortIndex)->opcode = OP_SorterOpen;
|
||||
sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen);
|
||||
sSort.sortFlags |= SORTFLAG_UseSorter;
|
||||
}
|
||||
|
||||
@@ -5403,7 +5403,7 @@ int sqlite3Select(
|
||||
|
||||
/* Jump over the subroutines
|
||||
*/
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEnd);
|
||||
sqlite3VdbeGoto(v, addrEnd);
|
||||
|
||||
/* Generate a subroutine that outputs a single row of the result
|
||||
** set. This subroutine first looks at the iUseFlag. If iUseFlag
|
||||
@@ -5557,7 +5557,7 @@ int sqlite3Select(
|
||||
updateAccumulator(pParse, &sAggInfo);
|
||||
assert( pMinMax==0 || pMinMax->nExpr==1 );
|
||||
if( sqlite3WhereIsOrdered(pWInfo)>0 ){
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3WhereBreakLabel(pWInfo));
|
||||
sqlite3VdbeGoto(v, sqlite3WhereBreakLabel(pWInfo));
|
||||
VdbeComment((v, "%s() by index",
|
||||
(flag==WHERE_ORDERBY_MIN?"min":"max")));
|
||||
}
|
||||
|
@@ -627,7 +627,7 @@ void sqlite3Update(
|
||||
sqlite3VdbeResolveLabel(v, labelContinue);
|
||||
sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop); VdbeCoverage(v);
|
||||
}else{
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, labelContinue);
|
||||
sqlite3VdbeGoto(v, labelContinue);
|
||||
}
|
||||
sqlite3VdbeResolveLabel(v, labelBreak);
|
||||
|
||||
|
@@ -1065,11 +1065,8 @@ u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){
|
||||
** 64-bit integer.
|
||||
*/
|
||||
int sqlite3VarintLen(u64 v){
|
||||
int i = 0;
|
||||
do{
|
||||
i++;
|
||||
v >>= 7;
|
||||
}while( v!=0 && ALWAYS(i<9) );
|
||||
int i;
|
||||
for(i=1; (v >>= 7)!=0; i++){ assert( i<9 ); }
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@@ -173,12 +173,16 @@ Vdbe *sqlite3VdbeCreate(Parse*);
|
||||
int sqlite3VdbeAddOp0(Vdbe*,int);
|
||||
int sqlite3VdbeAddOp1(Vdbe*,int,int);
|
||||
int sqlite3VdbeAddOp2(Vdbe*,int,int,int);
|
||||
int sqlite3VdbeGoto(Vdbe*,int);
|
||||
int sqlite3VdbeLoadString(Vdbe*,int,const char*);
|
||||
void sqlite3VdbeMultiLoad(Vdbe*,int,const char*,...);
|
||||
int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int);
|
||||
int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int);
|
||||
int sqlite3VdbeAddOp4Dup8(Vdbe*,int,int,int,int,const u8*,int);
|
||||
int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int);
|
||||
int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno);
|
||||
void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
|
||||
void sqlite3VdbeChangeOpcode(Vdbe*, u32 addr, u8);
|
||||
void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1);
|
||||
void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2);
|
||||
void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3);
|
||||
|
166
src/vdbeaux.c
166
src/vdbeaux.c
@@ -68,7 +68,7 @@ void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){
|
||||
*/
|
||||
const char *sqlite3_sql(sqlite3_stmt *pStmt){
|
||||
Vdbe *p = (Vdbe *)pStmt;
|
||||
return (p && p->isPrepareV2) ? p->zSql : 0;
|
||||
return p ? p->zSql : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -215,6 +215,44 @@ int sqlite3VdbeAddOp2(Vdbe *p, int op, int p1, int p2){
|
||||
return sqlite3VdbeAddOp3(p, op, p1, p2, 0);
|
||||
}
|
||||
|
||||
/* Generate code for an unconditional jump to instruction iDest
|
||||
*/
|
||||
int sqlite3VdbeGoto(Vdbe *p, int iDest){
|
||||
return sqlite3VdbeAddOp3(p, OP_Goto, 0, iDest, 0);
|
||||
}
|
||||
|
||||
/* Generate code to cause the string zStr to be loaded into
|
||||
** register iDest
|
||||
*/
|
||||
int sqlite3VdbeLoadString(Vdbe *p, int iDest, const char *zStr){
|
||||
return sqlite3VdbeAddOp4(p, OP_String8, 0, iDest, 0, zStr, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
** Generate code that initializes multiple registers to string or integer
|
||||
** constants. The registers begin with iDest and increase consecutively.
|
||||
** One register is initialized for each characgter in zTypes[]. For each
|
||||
** "s" character in zTypes[], the register is a string if the argument is
|
||||
** not NULL, or OP_Null if the value is a null pointer. For each "i" character
|
||||
** in zTypes[], the register is initialized to an integer.
|
||||
*/
|
||||
void sqlite3VdbeMultiLoad(Vdbe *p, int iDest, const char *zTypes, ...){
|
||||
va_list ap;
|
||||
int i;
|
||||
char c;
|
||||
va_start(ap, zTypes);
|
||||
for(i=0; (c = zTypes[i])!=0; i++){
|
||||
if( c=='s' ){
|
||||
const char *z = va_arg(ap, const char*);
|
||||
int addr = sqlite3VdbeAddOp2(p, z==0 ? OP_Null : OP_String8, 0, iDest++);
|
||||
if( z ) sqlite3VdbeChangeP4(p, addr, z, 0);
|
||||
}else{
|
||||
assert( c=='i' );
|
||||
sqlite3VdbeAddOp2(p, OP_Integer, va_arg(ap, int), iDest++);
|
||||
}
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/*
|
||||
** Add an opcode that includes the p4 value as a pointer.
|
||||
@@ -234,7 +272,8 @@ int sqlite3VdbeAddOp4(
|
||||
}
|
||||
|
||||
/*
|
||||
** Add an opcode that includes the p4 value with a P4_INT64 type.
|
||||
** Add an opcode that includes the p4 value with a P4_INT64 or
|
||||
** P4_REAL type.
|
||||
*/
|
||||
int sqlite3VdbeAddOp4Dup8(
|
||||
Vdbe *p, /* Add the opcode to this VM */
|
||||
@@ -319,7 +358,8 @@ void sqlite3VdbeResolveLabel(Vdbe *v, int x){
|
||||
int j = -1-x;
|
||||
assert( v->magic==VDBE_MAGIC_INIT );
|
||||
assert( j<p->nLabel );
|
||||
if( ALWAYS(j>=0) && p->aLabel ){
|
||||
assert( j>=0 );
|
||||
if( p->aLabel ){
|
||||
p->aLabel[j] = v->nOp;
|
||||
}
|
||||
p->iFixedOp = v->nOp - 1;
|
||||
@@ -463,17 +503,21 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
|
||||
#endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */
|
||||
|
||||
/*
|
||||
** Loop through the program looking for P2 values that are negative
|
||||
** on jump instructions. Each such value is a label. Resolve the
|
||||
** label by setting the P2 value to its correct non-zero value.
|
||||
** This routine is called after all opcodes have been inserted. It loops
|
||||
** through all the opcodes and fixes up some details.
|
||||
**
|
||||
** This routine is called once after all opcodes have been inserted.
|
||||
** (1) For each jump instruction with a negative P2 value (a label)
|
||||
** resolve the P2 value to an actual address.
|
||||
**
|
||||
** Variable *pMaxFuncArgs is set to the maximum value of any P2 argument
|
||||
** to an OP_Function, OP_AggStep or OP_VFilter opcode. This is used by
|
||||
** sqlite3VdbeMakeReady() to size the Vdbe.apArg[] array.
|
||||
** (2) Compute the maximum number of arguments used by any SQL function
|
||||
** and store that value in *pMaxFuncArgs.
|
||||
**
|
||||
** The Op.opflags field is set on all opcodes.
|
||||
** (3) Update the Vdbe.readOnly and Vdbe.bIsReader flags to accurately
|
||||
** indicate what the prepared statement actually does.
|
||||
**
|
||||
** (4) Initialize the p4.xAdvance pointer on opcodes that use it.
|
||||
**
|
||||
** (5) Reclaim the memory allocated for storing labels.
|
||||
*/
|
||||
static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
|
||||
int i;
|
||||
@@ -586,46 +630,44 @@ VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){
|
||||
** address of the first operation added.
|
||||
*/
|
||||
int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp, int iLineno){
|
||||
int addr;
|
||||
int addr, i;
|
||||
VdbeOp *pOut;
|
||||
assert( nOp>0 );
|
||||
assert( p->magic==VDBE_MAGIC_INIT );
|
||||
if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p, nOp) ){
|
||||
return 0;
|
||||
}
|
||||
addr = p->nOp;
|
||||
if( ALWAYS(nOp>0) ){
|
||||
int i;
|
||||
VdbeOpList const *pIn = aOp;
|
||||
for(i=0; i<nOp; i++, pIn++){
|
||||
int p2 = pIn->p2;
|
||||
VdbeOp *pOut = &p->aOp[i+addr];
|
||||
pOut->opcode = pIn->opcode;
|
||||
pOut->p1 = pIn->p1;
|
||||
if( p2<0 ){
|
||||
assert( sqlite3OpcodeProperty[pOut->opcode] & OPFLG_JUMP );
|
||||
pOut->p2 = addr + ADDR(p2);
|
||||
}else{
|
||||
pOut->p2 = p2;
|
||||
}
|
||||
pOut->p3 = pIn->p3;
|
||||
pOut->p4type = P4_NOTUSED;
|
||||
pOut->p4.p = 0;
|
||||
pOut->p5 = 0;
|
||||
pOut = &p->aOp[addr];
|
||||
for(i=0; i<nOp; i++, aOp++, pOut++){
|
||||
int p2 = aOp->p2;
|
||||
pOut->opcode = aOp->opcode;
|
||||
pOut->p1 = aOp->p1;
|
||||
if( p2<0 ){
|
||||
assert( sqlite3OpcodeProperty[pOut->opcode] & OPFLG_JUMP );
|
||||
pOut->p2 = addr + ADDR(p2);
|
||||
}else{
|
||||
pOut->p2 = p2;
|
||||
}
|
||||
pOut->p3 = aOp->p3;
|
||||
pOut->p4type = P4_NOTUSED;
|
||||
pOut->p4.p = 0;
|
||||
pOut->p5 = 0;
|
||||
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||
pOut->zComment = 0;
|
||||
pOut->zComment = 0;
|
||||
#endif
|
||||
#ifdef SQLITE_VDBE_COVERAGE
|
||||
pOut->iSrcLine = iLineno+i;
|
||||
pOut->iSrcLine = iLineno+i;
|
||||
#else
|
||||
(void)iLineno;
|
||||
(void)iLineno;
|
||||
#endif
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( p->db->flags & SQLITE_VdbeAddopTrace ){
|
||||
sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
|
||||
}
|
||||
#endif
|
||||
if( p->db->flags & SQLITE_VdbeAddopTrace ){
|
||||
sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
|
||||
}
|
||||
p->nOp += nOp;
|
||||
#endif
|
||||
}
|
||||
p->nOp += nOp;
|
||||
return addr;
|
||||
}
|
||||
|
||||
@@ -658,49 +700,23 @@ void sqlite3VdbeScanStatus(
|
||||
|
||||
|
||||
/*
|
||||
** Change the value of the P1 operand for a specific instruction.
|
||||
** This routine is useful when a large program is loaded from a
|
||||
** static array using sqlite3VdbeAddOpList but we want to make a
|
||||
** few minor changes to the program.
|
||||
** Change the value of the opcode, or P1, P2, P3, or P5 operands
|
||||
** for a specific instruction.
|
||||
*/
|
||||
void sqlite3VdbeChangeOpcode(Vdbe *p, u32 addr, u8 iNewOpcode){
|
||||
sqlite3VdbeGetOp(p,addr)->opcode = iNewOpcode;
|
||||
}
|
||||
void sqlite3VdbeChangeP1(Vdbe *p, u32 addr, int val){
|
||||
assert( p!=0 );
|
||||
if( ((u32)p->nOp)>addr ){
|
||||
p->aOp[addr].p1 = val;
|
||||
}
|
||||
sqlite3VdbeGetOp(p,addr)->p1 = val;
|
||||
}
|
||||
|
||||
/*
|
||||
** Change the value of the P2 operand for a specific instruction.
|
||||
** This routine is useful for setting a jump destination.
|
||||
*/
|
||||
void sqlite3VdbeChangeP2(Vdbe *p, u32 addr, int val){
|
||||
assert( p!=0 );
|
||||
if( ((u32)p->nOp)>addr ){
|
||||
p->aOp[addr].p2 = val;
|
||||
}
|
||||
sqlite3VdbeGetOp(p,addr)->p2 = val;
|
||||
}
|
||||
|
||||
/*
|
||||
** Change the value of the P3 operand for a specific instruction.
|
||||
*/
|
||||
void sqlite3VdbeChangeP3(Vdbe *p, u32 addr, int val){
|
||||
assert( p!=0 );
|
||||
if( ((u32)p->nOp)>addr ){
|
||||
p->aOp[addr].p3 = val;
|
||||
}
|
||||
sqlite3VdbeGetOp(p,addr)->p3 = val;
|
||||
}
|
||||
|
||||
/*
|
||||
** Change the value of the P5 operand for the most recently
|
||||
** added operation.
|
||||
*/
|
||||
void sqlite3VdbeChangeP5(Vdbe *p, u8 val){
|
||||
assert( p!=0 );
|
||||
if( p->aOp ){
|
||||
assert( p->nOp>0 );
|
||||
p->aOp[p->nOp-1].p5 = val;
|
||||
}
|
||||
void sqlite3VdbeChangeP5(Vdbe *p, u8 p5){
|
||||
sqlite3VdbeGetOp(p,-1)->p5 = p5;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -708,8 +724,8 @@ void sqlite3VdbeChangeP5(Vdbe *p, u8 val){
|
||||
** the address of the next instruction to be coded.
|
||||
*/
|
||||
void sqlite3VdbeJumpHere(Vdbe *p, int addr){
|
||||
sqlite3VdbeChangeP2(p, addr, p->nOp);
|
||||
p->pParse->iFixedOp = p->nOp - 1;
|
||||
sqlite3VdbeChangeP2(p, addr, p->nOp);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -423,7 +423,7 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
|
||||
sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere);
|
||||
|
||||
iReg = ++pParse->nMem;
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, iReg, 0, pTab->zName, 0);
|
||||
sqlite3VdbeLoadString(v, iReg, pTab->zName);
|
||||
sqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg);
|
||||
}
|
||||
|
||||
|
@@ -728,7 +728,7 @@ static void constructAutomaticIndex(
|
||||
if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
|
||||
if( pTabItem->fg.viaCoroutine ){
|
||||
translateColumnToCopy(v, addrTop, pLevel->iTabCur, pTabItem->regResult);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
|
||||
sqlite3VdbeGoto(v, addrTop);
|
||||
pTabItem->fg.viaCoroutine = 0;
|
||||
}else{
|
||||
sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
|
||||
@@ -4389,7 +4389,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
||||
}
|
||||
sqlite3VdbeResolveLabel(v, pLevel->addrBrk);
|
||||
if( pLevel->addrSkip ){
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrSkip);
|
||||
sqlite3VdbeGoto(v, pLevel->addrSkip);
|
||||
VdbeComment((v, "next skip-scan on %s", pLoop->u.btree.pIndex->zName));
|
||||
sqlite3VdbeJumpHere(v, pLevel->addrSkip);
|
||||
sqlite3VdbeJumpHere(v, pLevel->addrSkip-2);
|
||||
@@ -4417,7 +4417,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
||||
if( pLevel->op==OP_Return ){
|
||||
sqlite3VdbeAddOp2(v, OP_Gosub, pLevel->p1, pLevel->addrFirst);
|
||||
}else{
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrFirst);
|
||||
sqlite3VdbeGoto(v, pLevel->addrFirst);
|
||||
}
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
}
|
||||
|
@@ -67,12 +67,8 @@ static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop, Table *pTab){
|
||||
sqlite3StrAccumAppend(pStr, " (", 2);
|
||||
for(i=0; i<nEq; i++){
|
||||
char *z = aiColumn[i] < 0 ? "rowid" : aCol[aiColumn[i]].zName;
|
||||
if( i>=nSkip ){
|
||||
explainAppendTerm(pStr, i, z, "=");
|
||||
}else{
|
||||
if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5);
|
||||
sqlite3XPrintf(pStr, 0, "ANY(%s)", z);
|
||||
}
|
||||
if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5);
|
||||
sqlite3XPrintf(pStr, 0, i>=nSkip ? "%s=?" : "ANY(%s)", z);
|
||||
}
|
||||
|
||||
j = i;
|
||||
@@ -165,19 +161,18 @@ int sqlite3WhereExplainOneScan(
|
||||
explainIndexRange(&str, pLoop, pItem->pTab);
|
||||
}
|
||||
}else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
|
||||
const char *zRange;
|
||||
const char *zRangeOp;
|
||||
if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){
|
||||
zRange = "(rowid=?)";
|
||||
zRangeOp = "=";
|
||||
}else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
|
||||
zRange = "(rowid>? AND rowid<?)";
|
||||
zRangeOp = ">? AND rowid<";
|
||||
}else if( flags&WHERE_BTM_LIMIT ){
|
||||
zRange = "(rowid>?)";
|
||||
zRangeOp = ">";
|
||||
}else{
|
||||
assert( flags&WHERE_TOP_LIMIT);
|
||||
zRange = "(rowid<?)";
|
||||
zRangeOp = "<";
|
||||
}
|
||||
sqlite3StrAccumAppendAll(&str, " USING INTEGER PRIMARY KEY ");
|
||||
sqlite3StrAccumAppendAll(&str, zRange);
|
||||
sqlite3XPrintf(&str, 0, " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp);
|
||||
}
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
|
||||
@@ -1530,7 +1525,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
sqlite3ExprDelete(db, pAndExpr);
|
||||
}
|
||||
sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk);
|
||||
sqlite3VdbeGoto(v, pLevel->addrBrk);
|
||||
sqlite3VdbeResolveLabel(v, iLoopBody);
|
||||
|
||||
if( pWInfo->nLevel>1 ) sqlite3StackFree(db, pOrTab);
|
||||
|
Reference in New Issue
Block a user