mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Add logic to do test coverage measurements on the VDBE code.
FossilOrigin-Name: ce184c7bb16988641d37c908d9b3042456d4be3d
This commit is contained in:
48
manifest
48
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Add\sa\stest\scase\sfor\sOP_SoftNull.
|
C Add\slogic\sto\sdo\stest\scoverage\smeasurements\son\sthe\sVDBE\scode.
|
||||||
D 2014-02-17T15:40:19.609
|
D 2014-02-17T22:40:43.958
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
|
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@@ -156,8 +156,8 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
|
|||||||
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||||
F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494
|
F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494
|
||||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||||
F src/alter.c d5348d0f86a5fc8fb3987727402f023953c021cf
|
F src/alter.c 829d67a359b7c5d37120be994af2c0eac730070c
|
||||||
F src/analyze.c 3ec444402a5d9ac1018ac8c549f8e82ac23d4122
|
F src/analyze.c 69761e1677142d180a9f55250dee2952f45e4793
|
||||||
F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52
|
F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52
|
||||||
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
|
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
|
||||||
F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53
|
F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53
|
||||||
@@ -166,26 +166,26 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
|
|||||||
F src/btree.c b945df4f0114b4cc71006acc2fbb1333fb33a200
|
F src/btree.c b945df4f0114b4cc71006acc2fbb1333fb33a200
|
||||||
F src/btree.h 9e0f97c01b972f779eb7655cfb4f8727fd6dc26f
|
F src/btree.h 9e0f97c01b972f779eb7655cfb4f8727fd6dc26f
|
||||||
F src/btreeInt.h 0be66063468a520e4d66b80c7a1dc26d04ee6ea4
|
F src/btreeInt.h 0be66063468a520e4d66b80c7a1dc26d04ee6ea4
|
||||||
F src/build.c 13b9d82181d95af7b00ec8a8e1304bac096432d4
|
F src/build.c 00ce613bc2256e525c9195cb10d0df7bcc48d1f0
|
||||||
F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98
|
F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98
|
||||||
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
||||||
F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd
|
F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd
|
||||||
F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
|
F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
|
||||||
F src/delete.c 57a09d3d576dd15cd54d945b7b0b478bac71f379
|
F src/delete.c a00bf893bd39868c51020eba1fc5182eb36bfeb7
|
||||||
F src/expr.c 90bba0ca6ec97d6857458f08a8ad2820130e13cf
|
F src/expr.c d1a8ccbf7e4dac6198674d33853e8ed01072eca4
|
||||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||||
F src/fkey.c b3da26dfcd53a68e1b7162a84e0bf70e54092647
|
F src/fkey.c 3cd6ce998404fb1b7203d886d6fdff71cf3c8846
|
||||||
F src/func.c f4499b39d66b71825514334ce67b32ff14bd19f5
|
F src/func.c f4499b39d66b71825514334ce67b32ff14bd19f5
|
||||||
F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486
|
F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486
|
||||||
F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd
|
F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd
|
||||||
F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
|
F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
|
||||||
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
||||||
F src/insert.c ddc56dc855069ddf530127a346ddc2e67f0396e6
|
F src/insert.c 5d5e1d78f74804739b424c92346bdc26c146dfa4
|
||||||
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
||||||
F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
|
F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
|
||||||
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
|
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
|
||||||
F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303
|
F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303
|
||||||
F src/main.c 07225af6a00be0b7f34ac52e60f99cf5cbb2a475
|
F src/main.c e054917b1beb3081b0f23e8bdd3d6c0e12933dd3
|
||||||
F src/malloc.c 0203ebce9152c6a0e5de520140b8ba65187350be
|
F src/malloc.c 0203ebce9152c6a0e5de520140b8ba65187350be
|
||||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||||
F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b
|
F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b
|
||||||
@@ -210,18 +210,18 @@ F src/parse.y cce844ccb80b5f969b04c25100c8d94338488efb
|
|||||||
F src/pcache.c d8eafac28290d4bb80332005435db44991d07fc2
|
F src/pcache.c d8eafac28290d4bb80332005435db44991d07fc2
|
||||||
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
|
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
|
||||||
F src/pcache1.c 102e6f5a2fbc646154463eb856d1fd716867b64c
|
F src/pcache1.c 102e6f5a2fbc646154463eb856d1fd716867b64c
|
||||||
F src/pragma.c 769d08f10b7848dbd1950d0723bfcb12fb22b7f3
|
F src/pragma.c 2635d6bf8b54003ebefd773df2f50258cece2bec
|
||||||
F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337
|
F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337
|
||||||
F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269
|
F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269
|
||||||
F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
|
F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
|
||||||
F src/resolve.c ca8b99d894164435f5c55cb304c1b8121705c51e
|
F src/resolve.c ca8b99d894164435f5c55cb304c1b8121705c51e
|
||||||
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
|
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
|
||||||
F src/select.c ebec4d3fad7fd5aa33cd69e2f50e9c109285dc73
|
F src/select.c 618b53bd4553bd7a9ef95069396f12a8f28489e7
|
||||||
F src/shell.c 3dd86bf73ccd079f0e32ef5069600586085e8239
|
F src/shell.c 3dd86bf73ccd079f0e32ef5069600586085e8239
|
||||||
F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b
|
F src/sqlite.h.in a2ef671f92747a5a1c8a47bad5c585a8dd9eca80
|
||||||
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
|
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
|
||||||
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
|
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
|
||||||
F src/sqliteInt.h c5ba0868bddac9fdb0df4686ab43150fefb27da5
|
F src/sqliteInt.h 004bd50575a05eefba7228c2d0fee432a53200de
|
||||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||||
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
|
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
|
||||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||||
@@ -272,17 +272,17 @@ F src/test_vfs.c e72f555ef7a59080f898fcf1a233deb9eb704ea9
|
|||||||
F src/test_vfstrace.c 3a0ab304682fecbceb689e7d9b904211fde11d78
|
F src/test_vfstrace.c 3a0ab304682fecbceb689e7d9b904211fde11d78
|
||||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||||
F src/tokenize.c 6da2de6e12218ccb0aea5184b56727d011f4bee7
|
F src/tokenize.c 6da2de6e12218ccb0aea5184b56727d011f4bee7
|
||||||
F src/trigger.c a417d386e214f0abd2e0f756b834b4d9f4d3368a
|
F src/trigger.c a80036fcbd992729adc7cd34a875d59a71fa10cc
|
||||||
F src/update.c b126167ee39470b6148fa3f89182e7c855dc15d0
|
F src/update.c 16d6555a32298da18ce6e2a00637c462d9e3ac97
|
||||||
F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
|
F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
|
||||||
F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf
|
F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf
|
||||||
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
|
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
|
||||||
F src/vdbe.c e3ba6ad0111dbd4234fef5e119dbe30d0abb3cf1
|
F src/vdbe.c 392f03b25152eb44565a78b8b809743c97e5852b
|
||||||
F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26
|
F src/vdbe.h f429f5e5e14b02acbdffb2b2e8ba6e865e66e320
|
||||||
F src/vdbeInt.h 5286af9067cabdb8ba57b87c0c988a931be6c6c8
|
F src/vdbeInt.h 5286af9067cabdb8ba57b87c0c988a931be6c6c8
|
||||||
F src/vdbeapi.c 5bc41aaea448a7fc250902c418f1795859be3820
|
F src/vdbeapi.c 5bc41aaea448a7fc250902c418f1795859be3820
|
||||||
F src/vdbeaux.c 9098973ff22c6fdfd68d061e11c2e64f65eea2d1
|
F src/vdbeaux.c 0e01d6fda149c689039caadb8c89b20abb58e21d
|
||||||
F src/vdbeblob.c 9542e116c1db5ed813977581d506c176e117c0ec
|
F src/vdbeblob.c d939997de046b8fcc607cfee4248f3d33dbcca50
|
||||||
F src/vdbemem.c 06603e8e9d2f3247b68c6bbe4bd37fb6721b5bda
|
F src/vdbemem.c 06603e8e9d2f3247b68c6bbe4bd37fb6721b5bda
|
||||||
F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147
|
F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147
|
||||||
F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767
|
F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767
|
||||||
@@ -290,7 +290,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
|
|||||||
F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8
|
F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8
|
||||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||||
F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45
|
F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45
|
||||||
F src/where.c 7d9c988741c7d0e4a57774ae4b56e59675c4014a
|
F src/where.c 7825dce3f92d7c7de9329505deefe176cbd5ba43
|
||||||
F src/whereInt.h 921f935af8b684ffb49705610bda7284db1db138
|
F src/whereInt.h 921f935af8b684ffb49705610bda7284db1db138
|
||||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||||
@@ -1151,7 +1151,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
|
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
|
||||||
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
|
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
|
||||||
P 2914e4191121004a3f564b1fbf1c235dcc595503
|
P f29d194e03d6bcc78bf883b77e591dbccada02f0
|
||||||
R b009af851099e49da0fb1800028a0b8c
|
R 3842d7f2fc20472907a26e6db9a0b24a
|
||||||
U drh
|
U drh
|
||||||
Z ba859408f13b87421335d53499aa861e
|
Z 8a746710251048df8d65813e18590ec6
|
||||||
|
@@ -1 +1 @@
|
|||||||
f29d194e03d6bcc78bf883b77e591dbccada02f0
|
ce184c7bb16988641d37c908d9b3042456d4be3d
|
@@ -604,7 +604,7 @@ void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){
|
|||||||
sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT);
|
sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT);
|
||||||
sqlite3VdbeUsesBtree(v, iDb);
|
sqlite3VdbeUsesBtree(v, iDb);
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2);
|
sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2);
|
||||||
j1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1);
|
j1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, r2);
|
sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, r2);
|
||||||
sqlite3VdbeJumpHere(v, j1);
|
sqlite3VdbeJumpHere(v, j1);
|
||||||
sqlite3ReleaseTempReg(pParse, r1);
|
sqlite3ReleaseTempReg(pParse, r1);
|
||||||
|
@@ -1077,6 +1077,7 @@ static void analyzeOneTable(
|
|||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
|
addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
|
||||||
|
VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng);
|
sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng);
|
||||||
addrGotoChng0 = sqlite3VdbeAddOp0(v, OP_Goto);
|
addrGotoChng0 = sqlite3VdbeAddOp0(v, OP_Goto);
|
||||||
|
|
||||||
@@ -1098,6 +1099,7 @@ static void analyzeOneTable(
|
|||||||
aGotoChng[i] =
|
aGotoChng[i] =
|
||||||
sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ);
|
sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ);
|
||||||
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
|
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
|
||||||
|
VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, nCol, regChng);
|
sqlite3VdbeAddOp2(v, OP_Integer, nCol, regChng);
|
||||||
aGotoChng[nCol] = sqlite3VdbeAddOp0(v, OP_Goto);
|
aGotoChng[nCol] = sqlite3VdbeAddOp0(v, OP_Goto);
|
||||||
@@ -1144,7 +1146,7 @@ static void analyzeOneTable(
|
|||||||
sqlite3VdbeAddOp3(v, OP_Function, 1, regStat4, regTemp);
|
sqlite3VdbeAddOp3(v, OP_Function, 1, regStat4, regTemp);
|
||||||
sqlite3VdbeChangeP4(v, -1, (char*)&statPushFuncdef, P4_FUNCDEF);
|
sqlite3VdbeChangeP4(v, -1, (char*)&statPushFuncdef, P4_FUNCDEF);
|
||||||
sqlite3VdbeChangeP5(v, 2+IsStat34);
|
sqlite3VdbeChangeP5(v, 2+IsStat34);
|
||||||
sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow);
|
sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
|
||||||
|
|
||||||
/* Add the entry to the stat1 table. */
|
/* Add the entry to the stat1 table. */
|
||||||
callStatGet(v, regStat4, STAT_GET_STAT1, regStat1);
|
callStatGet(v, regStat4, STAT_GET_STAT1, regStat1);
|
||||||
@@ -1171,10 +1173,12 @@ static void analyzeOneTable(
|
|||||||
addrNext = sqlite3VdbeCurrentAddr(v);
|
addrNext = sqlite3VdbeCurrentAddr(v);
|
||||||
callStatGet(v, regStat4, STAT_GET_ROWID, regSampleRowid);
|
callStatGet(v, regStat4, STAT_GET_ROWID, regSampleRowid);
|
||||||
addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid);
|
addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid);
|
||||||
|
VdbeCoverage(v);
|
||||||
callStatGet(v, regStat4, STAT_GET_NEQ, regEq);
|
callStatGet(v, regStat4, STAT_GET_NEQ, regEq);
|
||||||
callStatGet(v, regStat4, STAT_GET_NLT, regLt);
|
callStatGet(v, regStat4, STAT_GET_NLT, regLt);
|
||||||
callStatGet(v, regStat4, STAT_GET_NDLT, regDLt);
|
callStatGet(v, regStat4, STAT_GET_NDLT, regDLt);
|
||||||
sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
|
sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
|
||||||
|
VdbeCoverage(v);
|
||||||
#ifdef SQLITE_ENABLE_STAT3
|
#ifdef SQLITE_ENABLE_STAT3
|
||||||
sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur,
|
sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur,
|
||||||
pIdx->aiColumn[0], regSample);
|
pIdx->aiColumn[0], regSample);
|
||||||
@@ -1205,7 +1209,7 @@ static void analyzeOneTable(
|
|||||||
if( pOnlyIdx==0 && needTableCnt ){
|
if( pOnlyIdx==0 && needTableCnt ){
|
||||||
VdbeComment((v, "%s", pTab->zName));
|
VdbeComment((v, "%s", pTab->zName));
|
||||||
sqlite3VdbeAddOp2(v, OP_Count, iTabCur, regStat1);
|
sqlite3VdbeAddOp2(v, OP_Count, iTabCur, regStat1);
|
||||||
jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1);
|
jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname);
|
sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname);
|
||||||
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "aaa", 0);
|
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "aaa", 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
|
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
|
||||||
|
12
src/build.c
12
src/build.c
@@ -948,7 +948,7 @@ void sqlite3StartTable(
|
|||||||
reg3 = ++pParse->nMem;
|
reg3 = ++pParse->nMem;
|
||||||
sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT);
|
sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT);
|
||||||
sqlite3VdbeUsesBtree(v, iDb);
|
sqlite3VdbeUsesBtree(v, iDb);
|
||||||
j1 = sqlite3VdbeAddOp1(v, OP_If, reg3);
|
j1 = sqlite3VdbeAddOp1(v, OP_If, reg3); VdbeCoverage(v);
|
||||||
fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ?
|
fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ?
|
||||||
1 : SQLITE_MAX_FILE_FORMAT;
|
1 : SQLITE_MAX_FILE_FORMAT;
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, fileFormat, reg3);
|
sqlite3VdbeAddOp2(v, OP_Integer, fileFormat, reg3);
|
||||||
@@ -2675,27 +2675,27 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
|
|||||||
/* Open the table. Loop through all rows of the table, inserting index
|
/* Open the table. Loop through all rows of the table, inserting index
|
||||||
** records into the sorter. */
|
** records into the sorter. */
|
||||||
sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
|
sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
|
||||||
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
|
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); VdbeCoverage(v);
|
||||||
regRecord = sqlite3GetTempReg(pParse);
|
regRecord = sqlite3GetTempReg(pParse);
|
||||||
|
|
||||||
sqlite3GenerateIndexKey(pParse,pIndex,iTab,regRecord,0,&iPartIdxLabel,0,0);
|
sqlite3GenerateIndexKey(pParse,pIndex,iTab,regRecord,0,&iPartIdxLabel,0,0);
|
||||||
sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
|
sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
|
||||||
sqlite3VdbeResolveLabel(v, iPartIdxLabel);
|
sqlite3VdbeResolveLabel(v, iPartIdxLabel);
|
||||||
sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
|
sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); VdbeCoverage(v);
|
||||||
sqlite3VdbeJumpHere(v, addr1);
|
sqlite3VdbeJumpHere(v, addr1);
|
||||||
if( memRootPage<0 ) sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb);
|
if( memRootPage<0 ) sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb);
|
||||||
sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb,
|
sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb,
|
||||||
(char *)pKey, P4_KEYINFO);
|
(char *)pKey, P4_KEYINFO);
|
||||||
sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));
|
sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));
|
||||||
|
|
||||||
addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0);
|
addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v);
|
||||||
assert( pKey!=0 || db->mallocFailed || pParse->nErr );
|
assert( pKey!=0 || db->mallocFailed || pParse->nErr );
|
||||||
if( pIndex->onError!=OE_None && pKey!=0 ){
|
if( pIndex->onError!=OE_None && pKey!=0 ){
|
||||||
int j2 = sqlite3VdbeCurrentAddr(v) + 3;
|
int j2 = sqlite3VdbeCurrentAddr(v) + 3;
|
||||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, j2);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, j2);
|
||||||
addr2 = sqlite3VdbeCurrentAddr(v);
|
addr2 = sqlite3VdbeCurrentAddr(v);
|
||||||
sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord,
|
sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord,
|
||||||
pKey->nField - pIndex->nKeyCol);
|
pKey->nField - pIndex->nKeyCol); VdbeCoverage(v);
|
||||||
sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
|
sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
|
||||||
}else{
|
}else{
|
||||||
addr2 = sqlite3VdbeCurrentAddr(v);
|
addr2 = sqlite3VdbeCurrentAddr(v);
|
||||||
@@ -2704,7 +2704,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
|
|||||||
sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1);
|
sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1);
|
||||||
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
|
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
|
||||||
sqlite3ReleaseTempReg(pParse, regRecord);
|
sqlite3ReleaseTempReg(pParse, regRecord);
|
||||||
sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2);
|
sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v);
|
||||||
sqlite3VdbeJumpHere(v, addr1);
|
sqlite3VdbeJumpHere(v, addr1);
|
||||||
|
|
||||||
sqlite3VdbeAddOp1(v, OP_Close, iTab);
|
sqlite3VdbeAddOp1(v, OP_Close, iTab);
|
||||||
|
12
src/delete.c
12
src/delete.c
@@ -481,13 +481,15 @@ void sqlite3DeleteFrom(
|
|||||||
if( aToOpen[iDataCur-iTabCur] ){
|
if( aToOpen[iDataCur-iTabCur] ){
|
||||||
assert( pPk!=0 );
|
assert( pPk!=0 );
|
||||||
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
|
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
|
||||||
|
VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
}else if( pPk ){
|
}else if( pPk ){
|
||||||
addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur);
|
addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_RowKey, iEphCur, iKey);
|
sqlite3VdbeAddOp2(v, OP_RowKey, iEphCur, iKey);
|
||||||
assert( nKey==0 ); /* OP_Found will use a composite key */
|
assert( nKey==0 ); /* OP_Found will use a composite key */
|
||||||
}else{
|
}else{
|
||||||
addrLoop = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey);
|
addrLoop = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey);
|
||||||
|
VdbeCoverage(v);
|
||||||
assert( nKey==1 );
|
assert( nKey==1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -511,7 +513,7 @@ void sqlite3DeleteFrom(
|
|||||||
if( okOnePass ){
|
if( okOnePass ){
|
||||||
sqlite3VdbeResolveLabel(v, addrBypass);
|
sqlite3VdbeResolveLabel(v, addrBypass);
|
||||||
}else if( pPk ){
|
}else if( pPk ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1);
|
sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); VdbeCoverage(v);
|
||||||
sqlite3VdbeJumpHere(v, addrLoop);
|
sqlite3VdbeJumpHere(v, addrLoop);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrLoop);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrLoop);
|
||||||
@@ -609,7 +611,10 @@ void sqlite3GenerateRowDelete(
|
|||||||
** not attempt to delete it or fire any DELETE triggers. */
|
** not attempt to delete it or fire any DELETE triggers. */
|
||||||
iLabel = sqlite3VdbeMakeLabel(v);
|
iLabel = sqlite3VdbeMakeLabel(v);
|
||||||
opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
|
opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
|
||||||
if( !bNoSeek ) sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
|
if( !bNoSeek ){
|
||||||
|
sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
|
||||||
|
VdbeCoverage(v);
|
||||||
|
}
|
||||||
|
|
||||||
/* If there are any triggers to fire, allocate a range of registers to
|
/* If there are any triggers to fire, allocate a range of registers to
|
||||||
** use for the old.* references in the triggers. */
|
** use for the old.* references in the triggers. */
|
||||||
@@ -651,6 +656,7 @@ void sqlite3GenerateRowDelete(
|
|||||||
*/
|
*/
|
||||||
if( addrStart<sqlite3VdbeCurrentAddr(v) ){
|
if( addrStart<sqlite3VdbeCurrentAddr(v) ){
|
||||||
sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
|
sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
|
||||||
|
VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do FK processing. This call checks that any FK constraints that
|
/* Do FK processing. This call checks that any FK constraints that
|
||||||
|
46
src/expr.c
46
src/expr.c
@@ -1383,7 +1383,7 @@ void sqlite3ExprCodeIsNullJump(
|
|||||||
int iDest /* Jump here if the value is null */
|
int iDest /* Jump here if the value is null */
|
||||||
){
|
){
|
||||||
if( sqlite3ExprCanBeNull(pExpr) ){
|
if( sqlite3ExprCanBeNull(pExpr) ){
|
||||||
sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iDest);
|
sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iDest); VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1486,7 +1486,9 @@ static int isCandidateForInOpt(Select *p){
|
|||||||
*/
|
*/
|
||||||
int sqlite3CodeOnce(Parse *pParse){
|
int sqlite3CodeOnce(Parse *pParse){
|
||||||
Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */
|
Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */
|
||||||
return sqlite3VdbeAddOp1(v, OP_Once, pParse->nOnce++);
|
int addr = sqlite3VdbeAddOp1(v, OP_Once, pParse->nOnce++);
|
||||||
|
VdbeCoverage(v);
|
||||||
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1837,6 +1839,7 @@ int sqlite3CodeSubselect(
|
|||||||
if( isRowid ){
|
if( isRowid ){
|
||||||
sqlite3VdbeAddOp2(v, OP_MustBeInt, r3,
|
sqlite3VdbeAddOp2(v, OP_MustBeInt, r3,
|
||||||
sqlite3VdbeCurrentAddr(v)+2);
|
sqlite3VdbeCurrentAddr(v)+2);
|
||||||
|
VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3);
|
sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
|
sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
|
||||||
@@ -1960,10 +1963,11 @@ static void sqlite3ExprCodeIN(
|
|||||||
if( destIfNull==destIfFalse ){
|
if( destIfNull==destIfFalse ){
|
||||||
/* Shortcut for the common case where the false and NULL outcomes are
|
/* Shortcut for the common case where the false and NULL outcomes are
|
||||||
** the same. */
|
** the same. */
|
||||||
sqlite3VdbeAddOp2(v, OP_IsNull, r1, destIfNull);
|
sqlite3VdbeAddOp2(v, OP_IsNull, r1, destIfNull); VdbeCoverage(v);
|
||||||
}else{
|
}else{
|
||||||
int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1);
|
int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse);
|
sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse);
|
||||||
|
VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull);
|
||||||
sqlite3VdbeJumpHere(v, addr1);
|
sqlite3VdbeJumpHere(v, addr1);
|
||||||
}
|
}
|
||||||
@@ -1971,8 +1975,9 @@ static void sqlite3ExprCodeIN(
|
|||||||
if( eType==IN_INDEX_ROWID ){
|
if( eType==IN_INDEX_ROWID ){
|
||||||
/* In this case, the RHS is the ROWID of table b-tree
|
/* In this case, the RHS is the ROWID of table b-tree
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp2(v, OP_MustBeInt, r1, destIfFalse);
|
sqlite3VdbeAddOp2(v, OP_MustBeInt, r1, destIfFalse); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp3(v, OP_NotExists, pExpr->iTable, destIfFalse, r1);
|
sqlite3VdbeAddOp3(v, OP_NotExists, pExpr->iTable, destIfFalse, r1);
|
||||||
|
VdbeCoverage(v);
|
||||||
}else{
|
}else{
|
||||||
/* In this case, the RHS is an index b-tree.
|
/* In this case, the RHS is an index b-tree.
|
||||||
*/
|
*/
|
||||||
@@ -1993,7 +1998,7 @@ static void sqlite3ExprCodeIN(
|
|||||||
** for this particular IN operator.
|
** for this particular IN operator.
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse, r1, 1);
|
sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse, r1, 1);
|
||||||
|
VdbeCoverage(v);
|
||||||
}else{
|
}else{
|
||||||
/* In this branch, the RHS of the IN might contain a NULL and
|
/* In this branch, the RHS of the IN might contain a NULL and
|
||||||
** the presence of a NULL on the RHS makes a difference in the
|
** the presence of a NULL on the RHS makes a difference in the
|
||||||
@@ -2006,6 +2011,7 @@ static void sqlite3ExprCodeIN(
|
|||||||
** over all of the code that follows.
|
** over all of the code that follows.
|
||||||
*/
|
*/
|
||||||
j1 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, r1, 1);
|
j1 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, r1, 1);
|
||||||
|
VdbeCoverage(v);
|
||||||
|
|
||||||
/* Here we begin generating code that runs if the LHS is not
|
/* Here we begin generating code that runs if the LHS is not
|
||||||
** contained within the RHS. Generate additional code that
|
** contained within the RHS. Generate additional code that
|
||||||
@@ -2013,8 +2019,9 @@ static void sqlite3ExprCodeIN(
|
|||||||
** jump to destIfNull. If there are no NULLs in the RHS then
|
** jump to destIfNull. If there are no NULLs in the RHS then
|
||||||
** jump to destIfFalse.
|
** jump to destIfFalse.
|
||||||
*/
|
*/
|
||||||
j2 = sqlite3VdbeAddOp1(v, OP_NotNull, rRhsHasNull);
|
j2 = sqlite3VdbeAddOp1(v, OP_NotNull, rRhsHasNull); VdbeCoverage(v);
|
||||||
j3 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, rRhsHasNull, 1);
|
j3 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, rRhsHasNull, 1);
|
||||||
|
VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, -1, rRhsHasNull);
|
sqlite3VdbeAddOp2(v, OP_Integer, -1, rRhsHasNull);
|
||||||
sqlite3VdbeJumpHere(v, j3);
|
sqlite3VdbeJumpHere(v, j3);
|
||||||
sqlite3VdbeAddOp2(v, OP_AddImm, rRhsHasNull, 1);
|
sqlite3VdbeAddOp2(v, OP_AddImm, rRhsHasNull, 1);
|
||||||
@@ -2023,7 +2030,7 @@ static void sqlite3ExprCodeIN(
|
|||||||
/* Jump to the appropriate target depending on whether or not
|
/* Jump to the appropriate target depending on whether or not
|
||||||
** the RHS contains a NULL
|
** the RHS contains a NULL
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp2(v, OP_If, rRhsHasNull, destIfNull);
|
sqlite3VdbeAddOp2(v, OP_If, rRhsHasNull, destIfNull); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse);
|
||||||
|
|
||||||
/* The OP_Found at the top of this branch jumps here when true,
|
/* The OP_Found at the top of this branch jumps here when true,
|
||||||
@@ -2560,7 +2567,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
|||||||
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
|
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
|
||||||
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
|
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
|
||||||
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
|
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
|
||||||
r1, r2, inReg, SQLITE_STOREP2);
|
r1, r2, inReg, SQLITE_STOREP2); VdbeCoverage(v);
|
||||||
testcase( regFree1==0 );
|
testcase( regFree1==0 );
|
||||||
testcase( regFree2==0 );
|
testcase( regFree2==0 );
|
||||||
break;
|
break;
|
||||||
@@ -2574,6 +2581,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
|||||||
op = (op==TK_IS) ? TK_EQ : TK_NE;
|
op = (op==TK_IS) ? TK_EQ : TK_NE;
|
||||||
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
|
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
|
||||||
r1, r2, inReg, SQLITE_STOREP2 | SQLITE_NULLEQ);
|
r1, r2, inReg, SQLITE_STOREP2 | SQLITE_NULLEQ);
|
||||||
|
VdbeCoverage(v);
|
||||||
testcase( regFree1==0 );
|
testcase( regFree1==0 );
|
||||||
testcase( regFree2==0 );
|
testcase( regFree2==0 );
|
||||||
break;
|
break;
|
||||||
@@ -2663,7 +2671,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
|||||||
sqlite3VdbeAddOp2(v, OP_Integer, 1, target);
|
sqlite3VdbeAddOp2(v, OP_Integer, 1, target);
|
||||||
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
|
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
|
||||||
testcase( regFree1==0 );
|
testcase( regFree1==0 );
|
||||||
addr = sqlite3VdbeAddOp1(v, op, r1);
|
addr = sqlite3VdbeAddOp1(v, op, r1); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_AddImm, target, -1);
|
sqlite3VdbeAddOp2(v, OP_AddImm, target, -1);
|
||||||
sqlite3VdbeJumpHere(v, addr);
|
sqlite3VdbeJumpHere(v, addr);
|
||||||
break;
|
break;
|
||||||
@@ -2715,6 +2723,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
|||||||
sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target);
|
sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target);
|
||||||
for(i=1; i<nFarg; i++){
|
for(i=1; i<nFarg; i++){
|
||||||
sqlite3VdbeAddOp2(v, OP_NotNull, target, endCoalesce);
|
sqlite3VdbeAddOp2(v, OP_NotNull, target, endCoalesce);
|
||||||
|
VdbeCoverage(v);
|
||||||
sqlite3ExprCacheRemove(pParse, target, 1);
|
sqlite3ExprCacheRemove(pParse, target, 1);
|
||||||
sqlite3ExprCachePush(pParse);
|
sqlite3ExprCachePush(pParse);
|
||||||
sqlite3ExprCode(pParse, pFarg->a[i].pExpr, target);
|
sqlite3ExprCode(pParse, pFarg->a[i].pExpr, target);
|
||||||
@@ -2853,12 +2862,14 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
|||||||
r4 = sqlite3GetTempReg(pParse);
|
r4 = sqlite3GetTempReg(pParse);
|
||||||
codeCompare(pParse, pLeft, pRight, OP_Ge,
|
codeCompare(pParse, pLeft, pRight, OP_Ge,
|
||||||
r1, r2, r3, SQLITE_STOREP2);
|
r1, r2, r3, SQLITE_STOREP2);
|
||||||
|
VdbeCoverage(v);
|
||||||
pLItem++;
|
pLItem++;
|
||||||
pRight = pLItem->pExpr;
|
pRight = pLItem->pExpr;
|
||||||
sqlite3ReleaseTempReg(pParse, regFree2);
|
sqlite3ReleaseTempReg(pParse, regFree2);
|
||||||
r2 = sqlite3ExprCodeTemp(pParse, pRight, ®Free2);
|
r2 = sqlite3ExprCodeTemp(pParse, pRight, ®Free2);
|
||||||
testcase( regFree2==0 );
|
testcase( regFree2==0 );
|
||||||
codeCompare(pParse, pLeft, pRight, OP_Le, r1, r2, r4, SQLITE_STOREP2);
|
codeCompare(pParse, pLeft, pRight, OP_Le, r1, r2, r4, SQLITE_STOREP2);
|
||||||
|
VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp3(v, OP_And, r3, r4, target);
|
sqlite3VdbeAddOp3(v, OP_And, r3, r4, target);
|
||||||
sqlite3ReleaseTempReg(pParse, r3);
|
sqlite3ReleaseTempReg(pParse, r3);
|
||||||
sqlite3ReleaseTempReg(pParse, r4);
|
sqlite3ReleaseTempReg(pParse, r4);
|
||||||
@@ -3025,6 +3036,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
|||||||
if( pExpr->affinity==OE_Ignore ){
|
if( pExpr->affinity==OE_Ignore ){
|
||||||
sqlite3VdbeAddOp4(
|
sqlite3VdbeAddOp4(
|
||||||
v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
|
v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
|
||||||
|
VdbeCoverage(v);
|
||||||
}else{
|
}else{
|
||||||
sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_TRIGGER,
|
sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_TRIGGER,
|
||||||
pExpr->affinity, pExpr->u.zToken, 0, 0);
|
pExpr->affinity, pExpr->u.zToken, 0, 0);
|
||||||
@@ -3613,7 +3625,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
|||||||
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
|
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
|
||||||
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
|
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
|
||||||
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
|
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
|
||||||
r1, r2, dest, jumpIfNull);
|
r1, r2, dest, jumpIfNull); VdbeCoverage(v);
|
||||||
testcase( regFree1==0 );
|
testcase( regFree1==0 );
|
||||||
testcase( regFree2==0 );
|
testcase( regFree2==0 );
|
||||||
break;
|
break;
|
||||||
@@ -3626,7 +3638,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
|||||||
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
|
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
|
||||||
op = (op==TK_IS) ? TK_EQ : TK_NE;
|
op = (op==TK_IS) ? TK_EQ : TK_NE;
|
||||||
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
|
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
|
||||||
r1, r2, dest, SQLITE_NULLEQ);
|
r1, r2, dest, SQLITE_NULLEQ); VdbeCoverage(v);
|
||||||
testcase( regFree1==0 );
|
testcase( regFree1==0 );
|
||||||
testcase( regFree2==0 );
|
testcase( regFree2==0 );
|
||||||
break;
|
break;
|
||||||
@@ -3638,7 +3650,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
|||||||
testcase( op==TK_ISNULL );
|
testcase( op==TK_ISNULL );
|
||||||
testcase( op==TK_NOTNULL );
|
testcase( op==TK_NOTNULL );
|
||||||
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
|
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
|
||||||
sqlite3VdbeAddOp2(v, op, r1, dest);
|
sqlite3VdbeAddOp2(v, op, r1, dest); VdbeCoverage(v);
|
||||||
testcase( regFree1==0 );
|
testcase( regFree1==0 );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -3665,6 +3677,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
|||||||
}else{
|
}else{
|
||||||
r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1);
|
r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1);
|
||||||
sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0);
|
sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0);
|
||||||
|
VdbeCoverage(v);
|
||||||
testcase( regFree1==0 );
|
testcase( regFree1==0 );
|
||||||
testcase( jumpIfNull==0 );
|
testcase( jumpIfNull==0 );
|
||||||
}
|
}
|
||||||
@@ -3766,7 +3779,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
|||||||
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
|
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
|
||||||
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
|
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
|
||||||
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
|
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
|
||||||
r1, r2, dest, jumpIfNull);
|
r1, r2, dest, jumpIfNull); VdbeCoverage(v);
|
||||||
testcase( regFree1==0 );
|
testcase( regFree1==0 );
|
||||||
testcase( regFree2==0 );
|
testcase( regFree2==0 );
|
||||||
break;
|
break;
|
||||||
@@ -3779,7 +3792,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
|||||||
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
|
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
|
||||||
op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ;
|
op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ;
|
||||||
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
|
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
|
||||||
r1, r2, dest, SQLITE_NULLEQ);
|
r1, r2, dest, SQLITE_NULLEQ); VdbeCoverage(v);
|
||||||
testcase( regFree1==0 );
|
testcase( regFree1==0 );
|
||||||
testcase( regFree2==0 );
|
testcase( regFree2==0 );
|
||||||
break;
|
break;
|
||||||
@@ -3789,7 +3802,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
|||||||
testcase( op==TK_ISNULL );
|
testcase( op==TK_ISNULL );
|
||||||
testcase( op==TK_NOTNULL );
|
testcase( op==TK_NOTNULL );
|
||||||
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
|
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
|
||||||
sqlite3VdbeAddOp2(v, op, r1, dest);
|
sqlite3VdbeAddOp2(v, op, r1, dest); VdbeCoverage(v);
|
||||||
testcase( regFree1==0 );
|
testcase( regFree1==0 );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -3818,6 +3831,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
|||||||
}else{
|
}else{
|
||||||
r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1);
|
r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1);
|
||||||
sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0);
|
sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0);
|
||||||
|
VdbeCoverage(v);
|
||||||
testcase( regFree1==0 );
|
testcase( regFree1==0 );
|
||||||
testcase( jumpIfNull==0 );
|
testcase( jumpIfNull==0 );
|
||||||
}
|
}
|
||||||
|
18
src/fkey.c
18
src/fkey.c
@@ -340,10 +340,11 @@ static void fkLookupParent(
|
|||||||
** search for a matching row in the parent table. */
|
** search for a matching row in the parent table. */
|
||||||
if( nIncr<0 ){
|
if( nIncr<0 ){
|
||||||
sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, iOk);
|
sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, iOk);
|
||||||
|
VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
for(i=0; i<pFKey->nCol; i++){
|
for(i=0; i<pFKey->nCol; i++){
|
||||||
int iReg = aiCol[i] + regData + 1;
|
int iReg = aiCol[i] + regData + 1;
|
||||||
sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk);
|
sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk); VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( isIgnore==0 ){
|
if( isIgnore==0 ){
|
||||||
@@ -360,17 +361,18 @@ static void fkLookupParent(
|
|||||||
** will have INTEGER affinity applied to it, which may not be correct. */
|
** will have INTEGER affinity applied to it, which may not be correct. */
|
||||||
sqlite3VdbeAddOp2(v, OP_SCopy, aiCol[0]+1+regData, regTemp);
|
sqlite3VdbeAddOp2(v, OP_SCopy, aiCol[0]+1+regData, regTemp);
|
||||||
iMustBeInt = sqlite3VdbeAddOp2(v, OP_MustBeInt, regTemp, 0);
|
iMustBeInt = sqlite3VdbeAddOp2(v, OP_MustBeInt, regTemp, 0);
|
||||||
|
VdbeCoverage(v);
|
||||||
|
|
||||||
/* If the parent table is the same as the child table, and we are about
|
/* If the parent table is the same as the child table, and we are about
|
||||||
** to increment the constraint-counter (i.e. this is an INSERT operation),
|
** to increment the constraint-counter (i.e. this is an INSERT operation),
|
||||||
** then check if the row being inserted matches itself. If so, do not
|
** then check if the row being inserted matches itself. If so, do not
|
||||||
** increment the constraint-counter. */
|
** increment the constraint-counter. */
|
||||||
if( pTab==pFKey->pFrom && nIncr==1 ){
|
if( pTab==pFKey->pFrom && nIncr==1 ){
|
||||||
sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp);
|
sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp); VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
|
sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
|
||||||
sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp);
|
sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
|
||||||
sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
|
sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
|
||||||
sqlite3VdbeJumpHere(v, iMustBeInt);
|
sqlite3VdbeJumpHere(v, iMustBeInt);
|
||||||
@@ -406,7 +408,7 @@ static void fkLookupParent(
|
|||||||
/* The parent key is a composite key that includes the IPK column */
|
/* The parent key is a composite key that includes the IPK column */
|
||||||
iParent = regData;
|
iParent = regData;
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent);
|
sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent); VdbeCoverage(v);
|
||||||
sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
|
sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
|
||||||
@@ -414,7 +416,7 @@ static void fkLookupParent(
|
|||||||
|
|
||||||
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTemp, nCol, regRec,
|
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTemp, nCol, regRec,
|
||||||
sqlite3IndexAffinityStr(v,pIdx), nCol);
|
sqlite3IndexAffinityStr(v,pIdx), nCol);
|
||||||
sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0);
|
sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0); VdbeCoverage(v);
|
||||||
|
|
||||||
sqlite3ReleaseTempReg(pParse, regRec);
|
sqlite3ReleaseTempReg(pParse, regRec);
|
||||||
sqlite3ReleaseTempRange(pParse, regTemp, nCol);
|
sqlite3ReleaseTempRange(pParse, regTemp, nCol);
|
||||||
@@ -552,6 +554,7 @@ static void fkScanChildren(
|
|||||||
|
|
||||||
if( nIncr<0 ){
|
if( nIncr<0 ){
|
||||||
iFkIfZero = sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, 0);
|
iFkIfZero = sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, 0);
|
||||||
|
VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create an Expr object representing an SQL expression like:
|
/* Create an Expr object representing an SQL expression like:
|
||||||
@@ -714,7 +717,7 @@ void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){
|
|||||||
}
|
}
|
||||||
if( !p ) return;
|
if( !p ) return;
|
||||||
iSkip = sqlite3VdbeMakeLabel(v);
|
iSkip = sqlite3VdbeMakeLabel(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip);
|
sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip); VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
pParse->disableTriggers = 1;
|
pParse->disableTriggers = 1;
|
||||||
@@ -732,6 +735,7 @@ void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){
|
|||||||
*/
|
*/
|
||||||
if( (db->flags & SQLITE_DeferFKs)==0 ){
|
if( (db->flags & SQLITE_DeferFKs)==0 ){
|
||||||
sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2);
|
sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2);
|
||||||
|
VdbeCoverage(v);
|
||||||
sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
|
sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
|
||||||
OE_Abort, 0, P4_STATIC, P5_ConstraintFK);
|
OE_Abort, 0, P4_STATIC, P5_ConstraintFK);
|
||||||
}
|
}
|
||||||
@@ -891,7 +895,7 @@ void sqlite3FkCheck(
|
|||||||
int iJump = sqlite3VdbeCurrentAddr(v) + pFKey->nCol + 1;
|
int iJump = sqlite3VdbeCurrentAddr(v) + pFKey->nCol + 1;
|
||||||
for(i=0; i<pFKey->nCol; i++){
|
for(i=0; i<pFKey->nCol; i++){
|
||||||
int iReg = pFKey->aCol[i].iFrom + regOld + 1;
|
int iReg = pFKey->aCol[i].iFrom + regOld + 1;
|
||||||
sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iJump);
|
sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iJump); VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, -1);
|
sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, -1);
|
||||||
}
|
}
|
||||||
|
54
src/insert.c
54
src/insert.c
@@ -262,14 +262,14 @@ void sqlite3AutoincrementBegin(Parse *pParse){
|
|||||||
sqlite3VdbeAddOp3(v, OP_Null, 0, memId, memId+1);
|
sqlite3VdbeAddOp3(v, OP_Null, 0, memId, memId+1);
|
||||||
addr = sqlite3VdbeCurrentAddr(v);
|
addr = sqlite3VdbeCurrentAddr(v);
|
||||||
sqlite3VdbeAddOp4(v, OP_String8, 0, memId-1, 0, p->pTab->zName, 0);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, memId-1, 0, p->pTab->zName, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_Rewind, 0, addr+9);
|
sqlite3VdbeAddOp2(v, OP_Rewind, 0, addr+9); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp3(v, OP_Column, 0, 0, memId);
|
sqlite3VdbeAddOp3(v, OP_Column, 0, 0, memId);
|
||||||
sqlite3VdbeAddOp3(v, OP_Ne, memId-1, addr+7, memId);
|
sqlite3VdbeAddOp3(v, OP_Ne, memId-1, addr+7, memId); VdbeCoverage(v);
|
||||||
sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
|
sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
|
||||||
sqlite3VdbeAddOp2(v, OP_Rowid, 0, memId+1);
|
sqlite3VdbeAddOp2(v, OP_Rowid, 0, memId+1);
|
||||||
sqlite3VdbeAddOp3(v, OP_Column, 0, 1, memId);
|
sqlite3VdbeAddOp3(v, OP_Column, 0, 1, memId);
|
||||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, addr+9);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, addr+9);
|
||||||
sqlite3VdbeAddOp2(v, OP_Next, 0, addr+2);
|
sqlite3VdbeAddOp2(v, OP_Next, 0, addr+2); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, memId);
|
sqlite3VdbeAddOp2(v, OP_Integer, 0, memId);
|
||||||
sqlite3VdbeAddOp0(v, OP_Close);
|
sqlite3VdbeAddOp0(v, OP_Close);
|
||||||
}
|
}
|
||||||
@@ -311,11 +311,11 @@ void sqlite3AutoincrementEnd(Parse *pParse){
|
|||||||
iRec = sqlite3GetTempReg(pParse);
|
iRec = sqlite3GetTempReg(pParse);
|
||||||
assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) );
|
assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) );
|
||||||
sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
|
sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
|
||||||
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1);
|
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1); VdbeCoverage(v);
|
||||||
j2 = sqlite3VdbeAddOp0(v, OP_Rewind);
|
j2 = sqlite3VdbeAddOp0(v, OP_Rewind); VdbeCoverage(v);
|
||||||
j3 = sqlite3VdbeAddOp3(v, OP_Column, 0, 0, iRec);
|
j3 = sqlite3VdbeAddOp3(v, OP_Column, 0, 0, iRec);
|
||||||
j4 = sqlite3VdbeAddOp3(v, OP_Eq, memId-1, 0, iRec);
|
j4 = sqlite3VdbeAddOp3(v, OP_Eq, memId-1, 0, iRec); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_Next, 0, j3);
|
sqlite3VdbeAddOp2(v, OP_Next, 0, j3); VdbeCoverage(v);
|
||||||
sqlite3VdbeJumpHere(v, j2);
|
sqlite3VdbeJumpHere(v, j2);
|
||||||
sqlite3VdbeAddOp2(v, OP_NewRowid, 0, memId+1);
|
sqlite3VdbeAddOp2(v, OP_NewRowid, 0, memId+1);
|
||||||
j5 = sqlite3VdbeAddOp0(v, OP_Goto);
|
j5 = sqlite3VdbeAddOp0(v, OP_Goto);
|
||||||
@@ -692,7 +692,7 @@ void sqlite3Insert(
|
|||||||
regRec = sqlite3GetTempReg(pParse);
|
regRec = sqlite3GetTempReg(pParse);
|
||||||
regTempRowid = sqlite3GetTempReg(pParse);
|
regTempRowid = sqlite3GetTempReg(pParse);
|
||||||
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn);
|
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn);
|
||||||
addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
|
addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec);
|
sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec);
|
||||||
sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid);
|
sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid);
|
||||||
sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid);
|
sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid);
|
||||||
@@ -777,7 +777,7 @@ void sqlite3Insert(
|
|||||||
** end loop
|
** end loop
|
||||||
** D: ...
|
** D: ...
|
||||||
*/
|
*/
|
||||||
addrInsTop = sqlite3VdbeAddOp1(v, OP_Rewind, srcTab);
|
addrInsTop = sqlite3VdbeAddOp1(v, OP_Rewind, srcTab); VdbeCoverage(v);
|
||||||
addrCont = sqlite3VdbeCurrentAddr(v);
|
addrCont = sqlite3VdbeCurrentAddr(v);
|
||||||
}else if( pSelect ){
|
}else if( pSelect ){
|
||||||
/* This block codes the top of loop only. The complete loop is the
|
/* This block codes the top of loop only. The complete loop is the
|
||||||
@@ -789,6 +789,7 @@ void sqlite3Insert(
|
|||||||
** D: ...
|
** D: ...
|
||||||
*/
|
*/
|
||||||
addrInsTop = addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
|
addrInsTop = addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
|
||||||
|
VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Run the BEFORE and INSTEAD OF triggers, if there are any
|
/* Run the BEFORE and INSTEAD OF triggers, if there are any
|
||||||
@@ -814,10 +815,10 @@ void sqlite3Insert(
|
|||||||
assert( pSelect==0 ); /* Otherwise useTempTable is true */
|
assert( pSelect==0 ); /* Otherwise useTempTable is true */
|
||||||
sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regCols);
|
sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regCols);
|
||||||
}
|
}
|
||||||
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols);
|
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
|
sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
|
||||||
sqlite3VdbeJumpHere(v, j1);
|
sqlite3VdbeJumpHere(v, j1);
|
||||||
sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols);
|
sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols); VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cannot have triggers on a virtual table. If it were possible,
|
/* Cannot have triggers on a virtual table. If it were possible,
|
||||||
@@ -892,14 +893,14 @@ void sqlite3Insert(
|
|||||||
if( !appendFlag ){
|
if( !appendFlag ){
|
||||||
int j1;
|
int j1;
|
||||||
if( !IsVirtual(pTab) ){
|
if( !IsVirtual(pTab) ){
|
||||||
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid);
|
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc);
|
sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc);
|
||||||
sqlite3VdbeJumpHere(v, j1);
|
sqlite3VdbeJumpHere(v, j1);
|
||||||
}else{
|
}else{
|
||||||
j1 = sqlite3VdbeCurrentAddr(v);
|
j1 = sqlite3VdbeCurrentAddr(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, j1+2);
|
sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, j1+2); VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid);
|
sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid); VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
}else if( IsVirtual(pTab) || withoutRowid ){
|
}else if( IsVirtual(pTab) || withoutRowid ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid);
|
sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid);
|
||||||
@@ -990,7 +991,7 @@ void sqlite3Insert(
|
|||||||
*/
|
*/
|
||||||
sqlite3VdbeResolveLabel(v, endOfLoop);
|
sqlite3VdbeResolveLabel(v, endOfLoop);
|
||||||
if( useTempTable ){
|
if( useTempTable ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Next, srcTab, addrCont);
|
sqlite3VdbeAddOp2(v, OP_Next, srcTab, addrCont); VdbeCoverage(v);
|
||||||
sqlite3VdbeJumpHere(v, addrInsTop);
|
sqlite3VdbeJumpHere(v, addrInsTop);
|
||||||
sqlite3VdbeAddOp1(v, OP_Close, srcTab);
|
sqlite3VdbeAddOp1(v, OP_Close, srcTab);
|
||||||
}else if( pSelect ){
|
}else if( pSelect ){
|
||||||
@@ -1212,15 +1213,17 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
sqlite3VdbeAddOp4(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError,
|
sqlite3VdbeAddOp4(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError,
|
||||||
regNewData+1+i, zMsg, P4_DYNAMIC);
|
regNewData+1+i, zMsg, P4_DYNAMIC);
|
||||||
sqlite3VdbeChangeP5(v, P5_ConstraintNotNull);
|
sqlite3VdbeChangeP5(v, P5_ConstraintNotNull);
|
||||||
|
VdbeCoverage(v);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OE_Ignore: {
|
case OE_Ignore: {
|
||||||
sqlite3VdbeAddOp2(v, OP_IsNull, regNewData+1+i, ignoreDest);
|
sqlite3VdbeAddOp2(v, OP_IsNull, regNewData+1+i, ignoreDest);
|
||||||
|
VdbeCoverage(v);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
assert( onError==OE_Replace );
|
assert( onError==OE_Replace );
|
||||||
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i);
|
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i); VdbeCoverage(v);
|
||||||
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i);
|
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i);
|
||||||
sqlite3VdbeJumpHere(v, j1);
|
sqlite3VdbeJumpHere(v, j1);
|
||||||
break;
|
break;
|
||||||
@@ -1272,6 +1275,7 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
** it might have changed. Skip the conflict logic below if the rowid
|
** it might have changed. Skip the conflict logic below if the rowid
|
||||||
** is unchanged. */
|
** is unchanged. */
|
||||||
sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData);
|
sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData);
|
||||||
|
VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the response to a rowid conflict is REPLACE but the response
|
/* If the response to a rowid conflict is REPLACE but the response
|
||||||
@@ -1291,6 +1295,7 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
/* Check to see if the new rowid already exists in the table. Skip
|
/* Check to see if the new rowid already exists in the table. Skip
|
||||||
** the following conflict logic if it does not. */
|
** the following conflict logic if it does not. */
|
||||||
sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData);
|
sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData);
|
||||||
|
VdbeCoverage(v);
|
||||||
|
|
||||||
/* Generate code that deals with a rowid collision */
|
/* Generate code that deals with a rowid collision */
|
||||||
switch( onError ){
|
switch( onError ){
|
||||||
@@ -1430,7 +1435,7 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
|
|
||||||
/* Check to see if the new index entry will be unique */
|
/* Check to see if the new index entry will be unique */
|
||||||
sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk,
|
sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk,
|
||||||
regIdx, pIdx->nKeyCol);
|
regIdx, pIdx->nKeyCol); VdbeCoverage(v);
|
||||||
|
|
||||||
/* Generate code to handle collisions */
|
/* Generate code to handle collisions */
|
||||||
regR = (pIdx==pPk) ? regIdx : sqlite3GetTempRange(pParse, nPkField);
|
regR = (pIdx==pPk) ? regIdx : sqlite3GetTempRange(pParse, nPkField);
|
||||||
@@ -1441,6 +1446,7 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
** is different from old-rowid */
|
** is different from old-rowid */
|
||||||
if( isUpdate ){
|
if( isUpdate ){
|
||||||
sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData);
|
sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData);
|
||||||
|
VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
int x;
|
int x;
|
||||||
@@ -1475,7 +1481,7 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
}
|
}
|
||||||
sqlite3VdbeAddOp4(v, op,
|
sqlite3VdbeAddOp4(v, op,
|
||||||
regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ
|
regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ
|
||||||
);
|
); VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1557,6 +1563,7 @@ void sqlite3CompleteInsertion(
|
|||||||
bAffinityDone = 1;
|
bAffinityDone = 1;
|
||||||
if( pIdx->pPartIdxWhere ){
|
if( pIdx->pPartIdxWhere ){
|
||||||
sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
|
sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
|
||||||
|
VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i]);
|
sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i]);
|
||||||
pik_flags = 0;
|
pik_flags = 0;
|
||||||
@@ -1940,16 +1947,17 @@ static int xferOptimization(
|
|||||||
**
|
**
|
||||||
** (3) onError is something other than OE_Abort and OE_Rollback.
|
** (3) onError is something other than OE_Abort and OE_Rollback.
|
||||||
*/
|
*/
|
||||||
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0);
|
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0); VdbeCoverage(v);
|
||||||
emptyDestTest = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
|
emptyDestTest = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
|
||||||
sqlite3VdbeJumpHere(v, addr1);
|
sqlite3VdbeJumpHere(v, addr1);
|
||||||
}
|
}
|
||||||
if( HasRowid(pSrc) ){
|
if( HasRowid(pSrc) ){
|
||||||
sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead);
|
sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead);
|
||||||
emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
|
emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
|
||||||
if( pDest->iPKey>=0 ){
|
if( pDest->iPKey>=0 ){
|
||||||
addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
|
addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
|
||||||
addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid);
|
addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid);
|
||||||
|
VdbeCoverage(v);
|
||||||
sqlite3RowidConstraint(pParse, onError, pDest);
|
sqlite3RowidConstraint(pParse, onError, pDest);
|
||||||
sqlite3VdbeJumpHere(v, addr2);
|
sqlite3VdbeJumpHere(v, addr2);
|
||||||
autoIncStep(pParse, regAutoinc, regRowid);
|
autoIncStep(pParse, regAutoinc, regRowid);
|
||||||
@@ -1963,7 +1971,7 @@ static int xferOptimization(
|
|||||||
sqlite3VdbeAddOp3(v, OP_Insert, iDest, regData, regRowid);
|
sqlite3VdbeAddOp3(v, OP_Insert, iDest, regData, regRowid);
|
||||||
sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND);
|
sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND);
|
||||||
sqlite3VdbeChangeP4(v, -1, pDest->zName, 0);
|
sqlite3VdbeChangeP4(v, -1, pDest->zName, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1);
|
sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
|
||||||
}else{
|
}else{
|
||||||
@@ -1982,10 +1990,10 @@ static int xferOptimization(
|
|||||||
sqlite3VdbeSetP4KeyInfo(pParse, pDestIdx);
|
sqlite3VdbeSetP4KeyInfo(pParse, pDestIdx);
|
||||||
sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR);
|
sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR);
|
||||||
VdbeComment((v, "%s", pDestIdx->zName));
|
VdbeComment((v, "%s", pDestIdx->zName));
|
||||||
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
|
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData);
|
sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData);
|
||||||
sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1);
|
sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1);
|
||||||
sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1);
|
sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v);
|
||||||
sqlite3VdbeJumpHere(v, addr1);
|
sqlite3VdbeJumpHere(v, addr1);
|
||||||
sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
|
||||||
|
15
src/main.c
15
src/main.c
@@ -3307,6 +3307,21 @@ int sqlite3_test_control(int op, ...){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, xCallback, ptr);
|
||||||
|
**
|
||||||
|
** Set the VDBE coverage callback function to xCallback with context
|
||||||
|
** pointer ptr.
|
||||||
|
*/
|
||||||
|
case SQLITE_TESTCTRL_VDBE_COVERAGE: {
|
||||||
|
#ifdef SQLITE_VDBE_COVERAGE
|
||||||
|
typedef void (*branch_callback)(void*,int,u8,u8);
|
||||||
|
sqlite3GlobalConfig.xVdbeBranch = va_arg(ap,branch_callback);
|
||||||
|
sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
#endif /* SQLITE_OMIT_BUILTIN_TEST */
|
#endif /* SQLITE_OMIT_BUILTIN_TEST */
|
||||||
|
46
src/pragma.c
46
src/pragma.c
@@ -824,6 +824,7 @@ void sqlite3Pragma(
|
|||||||
** size of historical compatibility.
|
** size of historical compatibility.
|
||||||
*/
|
*/
|
||||||
case PragTyp_DEFAULT_CACHE_SIZE: {
|
case PragTyp_DEFAULT_CACHE_SIZE: {
|
||||||
|
static const int iLn = __LINE__+2;
|
||||||
static const VdbeOpList getCacheSize[] = {
|
static const VdbeOpList getCacheSize[] = {
|
||||||
{ OP_Transaction, 0, 0, 0}, /* 0 */
|
{ OP_Transaction, 0, 0, 0}, /* 0 */
|
||||||
{ OP_ReadCookie, 0, 1, BTREE_DEFAULT_CACHE_SIZE}, /* 1 */
|
{ OP_ReadCookie, 0, 1, BTREE_DEFAULT_CACHE_SIZE}, /* 1 */
|
||||||
@@ -841,7 +842,7 @@ void sqlite3Pragma(
|
|||||||
sqlite3VdbeSetNumCols(v, 1);
|
sqlite3VdbeSetNumCols(v, 1);
|
||||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", SQLITE_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", SQLITE_STATIC);
|
||||||
pParse->nMem += 2;
|
pParse->nMem += 2;
|
||||||
addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
|
addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize,iLn);
|
||||||
sqlite3VdbeChangeP1(v, addr, iDb);
|
sqlite3VdbeChangeP1(v, addr, iDb);
|
||||||
sqlite3VdbeChangeP1(v, addr+1, iDb);
|
sqlite3VdbeChangeP1(v, addr+1, iDb);
|
||||||
sqlite3VdbeChangeP1(v, addr+6, SQLITE_DEFAULT_CACHE_SIZE);
|
sqlite3VdbeChangeP1(v, addr+6, SQLITE_DEFAULT_CACHE_SIZE);
|
||||||
@@ -1086,6 +1087,7 @@ void sqlite3Pragma(
|
|||||||
** file. Before writing to meta[6], check that meta[3] indicates
|
** file. Before writing to meta[6], check that meta[3] indicates
|
||||||
** that this really is an auto-vacuum capable database.
|
** that this really is an auto-vacuum capable database.
|
||||||
*/
|
*/
|
||||||
|
static const int iLn = __LINE__+2;
|
||||||
static const VdbeOpList setMeta6[] = {
|
static const VdbeOpList setMeta6[] = {
|
||||||
{ OP_Transaction, 0, 1, 0}, /* 0 */
|
{ OP_Transaction, 0, 1, 0}, /* 0 */
|
||||||
{ OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE},
|
{ OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE},
|
||||||
@@ -1095,7 +1097,7 @@ void sqlite3Pragma(
|
|||||||
{ OP_SetCookie, 0, BTREE_INCR_VACUUM, 1}, /* 5 */
|
{ OP_SetCookie, 0, BTREE_INCR_VACUUM, 1}, /* 5 */
|
||||||
};
|
};
|
||||||
int iAddr;
|
int iAddr;
|
||||||
iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6);
|
iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6, iLn);
|
||||||
sqlite3VdbeChangeP1(v, iAddr, iDb);
|
sqlite3VdbeChangeP1(v, iAddr, iDb);
|
||||||
sqlite3VdbeChangeP1(v, iAddr+1, iDb);
|
sqlite3VdbeChangeP1(v, iAddr+1, iDb);
|
||||||
sqlite3VdbeChangeP2(v, iAddr+2, iAddr+4);
|
sqlite3VdbeChangeP2(v, iAddr+2, iAddr+4);
|
||||||
@@ -1121,10 +1123,10 @@ void sqlite3Pragma(
|
|||||||
}
|
}
|
||||||
sqlite3BeginWriteOperation(pParse, 0, iDb);
|
sqlite3BeginWriteOperation(pParse, 0, iDb);
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1);
|
sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1);
|
||||||
addr = sqlite3VdbeAddOp1(v, OP_IncrVacuum, iDb);
|
addr = sqlite3VdbeAddOp1(v, OP_IncrVacuum, iDb); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp1(v, OP_ResultRow, 1);
|
sqlite3VdbeAddOp1(v, OP_ResultRow, 1);
|
||||||
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
|
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
|
||||||
sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr);
|
sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr); VdbeCoverage(v);
|
||||||
sqlite3VdbeJumpHere(v, addr);
|
sqlite3VdbeJumpHere(v, addr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1695,7 +1697,7 @@ void sqlite3Pragma(
|
|||||||
assert( pParse->nErr>0 || pFK==0 );
|
assert( pParse->nErr>0 || pFK==0 );
|
||||||
if( pFK ) break;
|
if( pFK ) break;
|
||||||
if( pParse->nTab<i ) pParse->nTab = i;
|
if( pParse->nTab<i ) pParse->nTab = i;
|
||||||
addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0);
|
addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0); VdbeCoverage(v);
|
||||||
for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
|
for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
|
||||||
pParent = sqlite3FindTable(db, pFK->zTo, zDb);
|
pParent = sqlite3FindTable(db, pFK->zTo, zDb);
|
||||||
pIdx = 0;
|
pIdx = 0;
|
||||||
@@ -1711,25 +1713,26 @@ void sqlite3Pragma(
|
|||||||
if( iKey!=pTab->iPKey ){
|
if( iKey!=pTab->iPKey ){
|
||||||
sqlite3VdbeAddOp3(v, OP_Column, 0, iKey, regRow);
|
sqlite3VdbeAddOp3(v, OP_Column, 0, iKey, regRow);
|
||||||
sqlite3ColumnDefault(v, pTab, iKey, regRow);
|
sqlite3ColumnDefault(v, pTab, iKey, regRow);
|
||||||
sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk);
|
sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_MustBeInt, regRow,
|
sqlite3VdbeAddOp2(v, OP_MustBeInt, regRow,
|
||||||
sqlite3VdbeCurrentAddr(v)+3);
|
sqlite3VdbeCurrentAddr(v)+3); VdbeCoverage(v);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow);
|
sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp3(v, OP_NotExists, i, 0, regRow);
|
sqlite3VdbeAddOp3(v, OP_NotExists, i, 0, regRow); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrOk);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrOk);
|
||||||
sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
|
sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
|
||||||
}else{
|
}else{
|
||||||
for(j=0; j<pFK->nCol; j++){
|
for(j=0; j<pFK->nCol; j++){
|
||||||
sqlite3ExprCodeGetColumnOfTable(v, pTab, 0,
|
sqlite3ExprCodeGetColumnOfTable(v, pTab, 0,
|
||||||
aiCols ? aiCols[j] : pFK->aCol[j].iFrom, regRow+j);
|
aiCols ? aiCols[j] : pFK->aCol[j].iFrom, regRow+j);
|
||||||
sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk);
|
sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
if( pParent ){
|
if( pParent ){
|
||||||
sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey,
|
sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey,
|
||||||
sqlite3IndexAffinityStr(v,pIdx), pFK->nCol);
|
sqlite3IndexAffinityStr(v,pIdx), pFK->nCol);
|
||||||
sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
|
sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
|
||||||
|
VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
|
sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
|
||||||
@@ -1740,7 +1743,7 @@ void sqlite3Pragma(
|
|||||||
sqlite3VdbeResolveLabel(v, addrOk);
|
sqlite3VdbeResolveLabel(v, addrOk);
|
||||||
sqlite3DbFree(db, aiCols);
|
sqlite3DbFree(db, aiCols);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1);
|
sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1); VdbeCoverage(v);
|
||||||
sqlite3VdbeJumpHere(v, addrTop);
|
sqlite3VdbeJumpHere(v, addrTop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1787,6 +1790,7 @@ void sqlite3Pragma(
|
|||||||
** messages have been generated, output OK. Otherwise output the
|
** messages have been generated, output OK. Otherwise output the
|
||||||
** error message
|
** error message
|
||||||
*/
|
*/
|
||||||
|
static const int iLn = __LINE__+2;
|
||||||
static const VdbeOpList endCode[] = {
|
static const VdbeOpList endCode[] = {
|
||||||
{ OP_AddImm, 1, 0, 0}, /* 0 */
|
{ OP_AddImm, 1, 0, 0}, /* 0 */
|
||||||
{ OP_IfNeg, 1, 0, 0}, /* 1 */
|
{ OP_IfNeg, 1, 0, 0}, /* 1 */
|
||||||
@@ -1835,6 +1839,7 @@ void sqlite3Pragma(
|
|||||||
|
|
||||||
sqlite3CodeVerifySchema(pParse, i);
|
sqlite3CodeVerifySchema(pParse, i);
|
||||||
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */
|
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */
|
||||||
|
VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
||||||
sqlite3VdbeJumpHere(v, addr);
|
sqlite3VdbeJumpHere(v, addr);
|
||||||
|
|
||||||
@@ -1866,7 +1871,7 @@ void sqlite3Pragma(
|
|||||||
/* Do the b-tree integrity checks */
|
/* Do the b-tree integrity checks */
|
||||||
sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1);
|
sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1);
|
||||||
sqlite3VdbeChangeP5(v, (u8)i);
|
sqlite3VdbeChangeP5(v, (u8)i);
|
||||||
addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2);
|
addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
|
||||||
sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName),
|
sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName),
|
||||||
P4_DYNAMIC);
|
P4_DYNAMIC);
|
||||||
@@ -1888,6 +1893,7 @@ void sqlite3Pragma(
|
|||||||
if( pTab->pIndex==0 ) continue;
|
if( pTab->pIndex==0 ) continue;
|
||||||
pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
|
pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
|
||||||
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */
|
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */
|
||||||
|
VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
||||||
sqlite3VdbeJumpHere(v, addr);
|
sqlite3VdbeJumpHere(v, addr);
|
||||||
sqlite3ExprCacheClear(pParse);
|
sqlite3ExprCacheClear(pParse);
|
||||||
@@ -1898,7 +1904,7 @@ void sqlite3Pragma(
|
|||||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */
|
sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */
|
||||||
}
|
}
|
||||||
pParse->nMem = MAX(pParse->nMem, 8+j);
|
pParse->nMem = MAX(pParse->nMem, 8+j);
|
||||||
sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0);
|
sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v);
|
||||||
loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1);
|
loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1);
|
||||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||||
int jmp2, jmp3, jmp4;
|
int jmp2, jmp3, jmp4;
|
||||||
@@ -1908,7 +1914,7 @@ void sqlite3Pragma(
|
|||||||
pPrior = pIdx;
|
pPrior = pIdx;
|
||||||
sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1); /* increment entry count */
|
sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1); /* increment entry count */
|
||||||
jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, 0, r1,
|
jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, 0, r1,
|
||||||
pIdx->nColumn);
|
pIdx->nColumn); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
|
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
|
||||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, "row ", P4_STATIC);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, "row ", P4_STATIC);
|
||||||
sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3);
|
sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3);
|
||||||
@@ -1918,13 +1924,13 @@ void sqlite3Pragma(
|
|||||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, pIdx->zName, P4_TRANSIENT);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, pIdx->zName, P4_TRANSIENT);
|
||||||
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
|
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
|
||||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
|
sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
|
||||||
jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1);
|
jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp0(v, OP_Halt);
|
sqlite3VdbeAddOp0(v, OP_Halt);
|
||||||
sqlite3VdbeJumpHere(v, jmp4);
|
sqlite3VdbeJumpHere(v, jmp4);
|
||||||
sqlite3VdbeJumpHere(v, jmp2);
|
sqlite3VdbeJumpHere(v, jmp2);
|
||||||
sqlite3VdbeResolveLabel(v, jmp3);
|
sqlite3VdbeResolveLabel(v, jmp3);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop);
|
sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
|
||||||
sqlite3VdbeJumpHere(v, loopTop-1);
|
sqlite3VdbeJumpHere(v, loopTop-1);
|
||||||
#ifndef SQLITE_OMIT_BTREECOUNT
|
#ifndef SQLITE_OMIT_BTREECOUNT
|
||||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0,
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0,
|
||||||
@@ -1932,10 +1938,10 @@ void sqlite3Pragma(
|
|||||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||||
if( pPk==pIdx ) continue;
|
if( pPk==pIdx ) continue;
|
||||||
addr = sqlite3VdbeCurrentAddr(v);
|
addr = sqlite3VdbeCurrentAddr(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2);
|
sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
|
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
|
||||||
sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3);
|
sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
|
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
|
||||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pIdx->zName, P4_TRANSIENT);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pIdx->zName, P4_TRANSIENT);
|
||||||
sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
|
sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
|
||||||
@@ -1944,7 +1950,7 @@ void sqlite3Pragma(
|
|||||||
#endif /* SQLITE_OMIT_BTREECOUNT */
|
#endif /* SQLITE_OMIT_BTREECOUNT */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode);
|
addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn);
|
||||||
sqlite3VdbeChangeP2(v, addr, -mxErr);
|
sqlite3VdbeChangeP2(v, addr, -mxErr);
|
||||||
sqlite3VdbeJumpHere(v, addr+1);
|
sqlite3VdbeJumpHere(v, addr+1);
|
||||||
sqlite3VdbeChangeP4(v, addr+2, "ok", P4_STATIC);
|
sqlite3VdbeChangeP4(v, addr+2, "ok", P4_STATIC);
|
||||||
@@ -2082,7 +2088,7 @@ void sqlite3Pragma(
|
|||||||
{ OP_Integer, 0, 1, 0}, /* 1 */
|
{ OP_Integer, 0, 1, 0}, /* 1 */
|
||||||
{ OP_SetCookie, 0, 0, 1}, /* 2 */
|
{ OP_SetCookie, 0, 0, 1}, /* 2 */
|
||||||
};
|
};
|
||||||
int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie);
|
int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie, 0);
|
||||||
sqlite3VdbeChangeP1(v, addr, iDb);
|
sqlite3VdbeChangeP1(v, addr, iDb);
|
||||||
sqlite3VdbeChangeP1(v, addr+1, sqlite3Atoi(zRight));
|
sqlite3VdbeChangeP1(v, addr+1, sqlite3Atoi(zRight));
|
||||||
sqlite3VdbeChangeP1(v, addr+2, iDb);
|
sqlite3VdbeChangeP1(v, addr+2, iDb);
|
||||||
@@ -2094,7 +2100,7 @@ void sqlite3Pragma(
|
|||||||
{ OP_ReadCookie, 0, 1, 0}, /* 1 */
|
{ OP_ReadCookie, 0, 1, 0}, /* 1 */
|
||||||
{ OP_ResultRow, 1, 1, 0}
|
{ OP_ResultRow, 1, 1, 0}
|
||||||
};
|
};
|
||||||
int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie);
|
int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie, 0);
|
||||||
sqlite3VdbeChangeP1(v, addr, iDb);
|
sqlite3VdbeChangeP1(v, addr, iDb);
|
||||||
sqlite3VdbeChangeP1(v, addr+1, iDb);
|
sqlite3VdbeChangeP1(v, addr+1, iDb);
|
||||||
sqlite3VdbeChangeP3(v, addr+1, iCookie);
|
sqlite3VdbeChangeP3(v, addr+1, iCookie);
|
||||||
|
81
src/select.c
81
src/select.c
@@ -455,7 +455,7 @@ static void pushOntoSorter(
|
|||||||
}else{
|
}else{
|
||||||
iLimit = pSelect->iLimit;
|
iLimit = pSelect->iLimit;
|
||||||
}
|
}
|
||||||
addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, iLimit);
|
addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, iLimit); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_AddImm, iLimit, -1);
|
sqlite3VdbeAddOp2(v, OP_AddImm, iLimit, -1);
|
||||||
addr2 = sqlite3VdbeAddOp0(v, OP_Goto);
|
addr2 = sqlite3VdbeAddOp0(v, OP_Goto);
|
||||||
sqlite3VdbeJumpHere(v, addr1);
|
sqlite3VdbeJumpHere(v, addr1);
|
||||||
@@ -476,7 +476,7 @@ static void codeOffset(
|
|||||||
if( iOffset>0 && iContinue!=0 ){
|
if( iOffset>0 && iContinue!=0 ){
|
||||||
int addr;
|
int addr;
|
||||||
sqlite3VdbeAddOp2(v, OP_AddImm, iOffset, -1);
|
sqlite3VdbeAddOp2(v, OP_AddImm, iOffset, -1);
|
||||||
addr = sqlite3VdbeAddOp1(v, OP_IfNeg, iOffset);
|
addr = sqlite3VdbeAddOp1(v, OP_IfNeg, iOffset); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, iContinue);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, iContinue);
|
||||||
VdbeComment((v, "skip OFFSET records"));
|
VdbeComment((v, "skip OFFSET records"));
|
||||||
sqlite3VdbeJumpHere(v, addr);
|
sqlite3VdbeJumpHere(v, addr);
|
||||||
@@ -504,7 +504,7 @@ static void codeDistinct(
|
|||||||
|
|
||||||
v = pParse->pVdbe;
|
v = pParse->pVdbe;
|
||||||
r1 = sqlite3GetTempReg(pParse);
|
r1 = sqlite3GetTempReg(pParse);
|
||||||
sqlite3VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N);
|
sqlite3VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1);
|
sqlite3VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1);
|
||||||
sqlite3VdbeAddOp2(v, OP_IdxInsert, iTab, r1);
|
sqlite3VdbeAddOp2(v, OP_IdxInsert, iTab, r1);
|
||||||
sqlite3ReleaseTempReg(pParse, r1);
|
sqlite3ReleaseTempReg(pParse, r1);
|
||||||
@@ -644,8 +644,10 @@ static void selectInnerLoop(
|
|||||||
CollSeq *pColl = sqlite3ExprCollSeq(pParse, pEList->a[i].pExpr);
|
CollSeq *pColl = sqlite3ExprCollSeq(pParse, pEList->a[i].pExpr);
|
||||||
if( i<nResultCol-1 ){
|
if( i<nResultCol-1 ){
|
||||||
sqlite3VdbeAddOp3(v, OP_Ne, regResult+i, iJump, regPrev+i);
|
sqlite3VdbeAddOp3(v, OP_Ne, regResult+i, iJump, regPrev+i);
|
||||||
|
VdbeCoverage(v);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp3(v, OP_Eq, regResult+i, iContinue, regPrev+i);
|
sqlite3VdbeAddOp3(v, OP_Eq, regResult+i, iContinue, regPrev+i);
|
||||||
|
VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
sqlite3VdbeChangeP4(v, -1, (const char *)pColl, P4_COLLSEQ);
|
sqlite3VdbeChangeP4(v, -1, (const char *)pColl, P4_COLLSEQ);
|
||||||
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
|
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
|
||||||
@@ -712,7 +714,7 @@ static void selectInnerLoop(
|
|||||||
** current row to the index and proceed with writing it to the
|
** current row to the index and proceed with writing it to the
|
||||||
** output table as well. */
|
** output table as well. */
|
||||||
int addr = sqlite3VdbeCurrentAddr(v) + 4;
|
int addr = sqlite3VdbeCurrentAddr(v) + 4;
|
||||||
sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, addr, r1, 0);
|
sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, addr, r1, 0); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r1);
|
sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r1);
|
||||||
assert( pOrderBy==0 );
|
assert( pOrderBy==0 );
|
||||||
}
|
}
|
||||||
@@ -823,6 +825,7 @@ static void selectInnerLoop(
|
|||||||
** added to the queue. Only add this new value if it has never before
|
** added to the queue. Only add this new value if it has never before
|
||||||
** been added */
|
** been added */
|
||||||
addrTest = sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, 0, r3, 0);
|
addrTest = sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, 0, r3, 0);
|
||||||
|
VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r3);
|
sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r3);
|
||||||
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
|
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
|
||||||
}
|
}
|
||||||
@@ -861,7 +864,7 @@ static void selectInnerLoop(
|
|||||||
** the output for us.
|
** the output for us.
|
||||||
*/
|
*/
|
||||||
if( pOrderBy==0 && p->iLimit ){
|
if( pOrderBy==0 && p->iLimit ){
|
||||||
sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1);
|
sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1080,12 +1083,13 @@ static void generateSortTail(
|
|||||||
int ptab2 = pParse->nTab++;
|
int ptab2 = pParse->nTab++;
|
||||||
sqlite3VdbeAddOp3(v, OP_OpenPseudo, ptab2, regSortOut, pOrderBy->nExpr+2);
|
sqlite3VdbeAddOp3(v, OP_OpenPseudo, ptab2, regSortOut, pOrderBy->nExpr+2);
|
||||||
addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
|
addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
|
||||||
|
VdbeCoverage(v);
|
||||||
codeOffset(v, p->iOffset, addrContinue);
|
codeOffset(v, p->iOffset, addrContinue);
|
||||||
sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut);
|
sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut);
|
||||||
sqlite3VdbeAddOp3(v, OP_Column, ptab2, pOrderBy->nExpr+1, regRow);
|
sqlite3VdbeAddOp3(v, OP_Column, ptab2, pOrderBy->nExpr+1, regRow);
|
||||||
sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
|
sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
|
||||||
}else{
|
}else{
|
||||||
addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak);
|
addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v);
|
||||||
codeOffset(v, p->iOffset, addrContinue);
|
codeOffset(v, p->iOffset, addrContinue);
|
||||||
sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr+1, regRow);
|
sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr+1, regRow);
|
||||||
}
|
}
|
||||||
@@ -1143,9 +1147,9 @@ static void generateSortTail(
|
|||||||
*/
|
*/
|
||||||
sqlite3VdbeResolveLabel(v, addrContinue);
|
sqlite3VdbeResolveLabel(v, addrContinue);
|
||||||
if( p->selFlags & SF_UseSorter ){
|
if( p->selFlags & SF_UseSorter ){
|
||||||
sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr);
|
sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr); VdbeCoverage(v);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp2(v, OP_Next, iTab, addr);
|
sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
sqlite3VdbeResolveLabel(v, addrBreak);
|
sqlite3VdbeResolveLabel(v, addrBreak);
|
||||||
if( eDest==SRT_Output || eDest==SRT_Coroutine ){
|
if( eDest==SRT_Output || eDest==SRT_Coroutine ){
|
||||||
@@ -1693,22 +1697,22 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
|
|||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
sqlite3ExprCode(pParse, p->pLimit, iLimit);
|
sqlite3ExprCode(pParse, p->pLimit, iLimit);
|
||||||
sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit);
|
sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeCoverage(v);
|
||||||
VdbeComment((v, "LIMIT counter"));
|
VdbeComment((v, "LIMIT counter"));
|
||||||
sqlite3VdbeAddOp2(v, OP_IfZero, iLimit, iBreak);
|
sqlite3VdbeAddOp2(v, OP_IfZero, iLimit, iBreak); VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
if( p->pOffset ){
|
if( p->pOffset ){
|
||||||
p->iOffset = iOffset = ++pParse->nMem;
|
p->iOffset = iOffset = ++pParse->nMem;
|
||||||
pParse->nMem++; /* Allocate an extra register for limit+offset */
|
pParse->nMem++; /* Allocate an extra register for limit+offset */
|
||||||
sqlite3ExprCode(pParse, p->pOffset, iOffset);
|
sqlite3ExprCode(pParse, p->pOffset, iOffset);
|
||||||
sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset);
|
sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v);
|
||||||
VdbeComment((v, "OFFSET counter"));
|
VdbeComment((v, "OFFSET counter"));
|
||||||
addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iOffset);
|
addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iOffset); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, iOffset);
|
sqlite3VdbeAddOp2(v, OP_Integer, 0, iOffset);
|
||||||
sqlite3VdbeJumpHere(v, addr1);
|
sqlite3VdbeJumpHere(v, addr1);
|
||||||
sqlite3VdbeAddOp3(v, OP_Add, iLimit, iOffset, iOffset+1);
|
sqlite3VdbeAddOp3(v, OP_Add, iLimit, iOffset, iOffset+1);
|
||||||
VdbeComment((v, "LIMIT+OFFSET"));
|
VdbeComment((v, "LIMIT+OFFSET"));
|
||||||
addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iLimit);
|
addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iLimit); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, -1, iOffset+1);
|
sqlite3VdbeAddOp2(v, OP_Integer, -1, iOffset+1);
|
||||||
sqlite3VdbeJumpHere(v, addr1);
|
sqlite3VdbeJumpHere(v, addr1);
|
||||||
}
|
}
|
||||||
@@ -1897,7 +1901,7 @@ static void generateWithRecursiveQuery(
|
|||||||
if( rc ) goto end_of_recursive_query;
|
if( rc ) goto end_of_recursive_query;
|
||||||
|
|
||||||
/* Find the next row in the Queue and output that row */
|
/* Find the next row in the Queue and output that row */
|
||||||
addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iQueue, addrBreak);
|
addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iQueue, addrBreak); VdbeCoverage(v);
|
||||||
|
|
||||||
/* Transfer the next row in Queue over to Current */
|
/* Transfer the next row in Queue over to Current */
|
||||||
sqlite3VdbeAddOp1(v, OP_NullRow, iCurrent); /* To reset column cache */
|
sqlite3VdbeAddOp1(v, OP_NullRow, iCurrent); /* To reset column cache */
|
||||||
@@ -1913,7 +1917,10 @@ static void generateWithRecursiveQuery(
|
|||||||
codeOffset(v, regOffset, addrCont);
|
codeOffset(v, regOffset, addrCont);
|
||||||
selectInnerLoop(pParse, p, p->pEList, iCurrent,
|
selectInnerLoop(pParse, p, p->pEList, iCurrent,
|
||||||
0, 0, pDest, addrCont, addrBreak);
|
0, 0, pDest, addrCont, addrBreak);
|
||||||
if( regLimit ) sqlite3VdbeAddOp3(v, OP_IfZero, regLimit, addrBreak, -1);
|
if( regLimit ){
|
||||||
|
sqlite3VdbeAddOp3(v, OP_IfZero, regLimit, addrBreak, -1);
|
||||||
|
VdbeCoverage(v);
|
||||||
|
}
|
||||||
sqlite3VdbeResolveLabel(v, addrCont);
|
sqlite3VdbeResolveLabel(v, addrCont);
|
||||||
|
|
||||||
/* Execute the recursive SELECT taking the single row in Current as
|
/* Execute the recursive SELECT taking the single row in Current as
|
||||||
@@ -2073,7 +2080,7 @@ static int multiSelect(
|
|||||||
p->iLimit = pPrior->iLimit;
|
p->iLimit = pPrior->iLimit;
|
||||||
p->iOffset = pPrior->iOffset;
|
p->iOffset = pPrior->iOffset;
|
||||||
if( p->iLimit ){
|
if( p->iLimit ){
|
||||||
addr = sqlite3VdbeAddOp1(v, OP_IfZero, p->iLimit);
|
addr = sqlite3VdbeAddOp1(v, OP_IfZero, p->iLimit); VdbeCoverage(v);
|
||||||
VdbeComment((v, "Jump ahead if LIMIT reached"));
|
VdbeComment((v, "Jump ahead if LIMIT reached"));
|
||||||
}
|
}
|
||||||
explainSetInteger(iSub2, pParse->iNextSelectId);
|
explainSetInteger(iSub2, pParse->iNextSelectId);
|
||||||
@@ -2180,12 +2187,12 @@ static int multiSelect(
|
|||||||
iBreak = sqlite3VdbeMakeLabel(v);
|
iBreak = sqlite3VdbeMakeLabel(v);
|
||||||
iCont = sqlite3VdbeMakeLabel(v);
|
iCont = sqlite3VdbeMakeLabel(v);
|
||||||
computeLimitRegisters(pParse, p, iBreak);
|
computeLimitRegisters(pParse, p, iBreak);
|
||||||
sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak);
|
sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v);
|
||||||
iStart = sqlite3VdbeCurrentAddr(v);
|
iStart = sqlite3VdbeCurrentAddr(v);
|
||||||
selectInnerLoop(pParse, p, p->pEList, unionTab,
|
selectInnerLoop(pParse, p, p->pEList, unionTab,
|
||||||
0, 0, &dest, iCont, iBreak);
|
0, 0, &dest, iCont, iBreak);
|
||||||
sqlite3VdbeResolveLabel(v, iCont);
|
sqlite3VdbeResolveLabel(v, iCont);
|
||||||
sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart);
|
sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v);
|
||||||
sqlite3VdbeResolveLabel(v, iBreak);
|
sqlite3VdbeResolveLabel(v, iBreak);
|
||||||
sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0);
|
||||||
}
|
}
|
||||||
@@ -2255,15 +2262,15 @@ static int multiSelect(
|
|||||||
iBreak = sqlite3VdbeMakeLabel(v);
|
iBreak = sqlite3VdbeMakeLabel(v);
|
||||||
iCont = sqlite3VdbeMakeLabel(v);
|
iCont = sqlite3VdbeMakeLabel(v);
|
||||||
computeLimitRegisters(pParse, p, iBreak);
|
computeLimitRegisters(pParse, p, iBreak);
|
||||||
sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak);
|
sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v);
|
||||||
r1 = sqlite3GetTempReg(pParse);
|
r1 = sqlite3GetTempReg(pParse);
|
||||||
iStart = sqlite3VdbeAddOp2(v, OP_RowKey, tab1, r1);
|
iStart = sqlite3VdbeAddOp2(v, OP_RowKey, tab1, r1);
|
||||||
sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0);
|
sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); VdbeCoverage(v);
|
||||||
sqlite3ReleaseTempReg(pParse, r1);
|
sqlite3ReleaseTempReg(pParse, r1);
|
||||||
selectInnerLoop(pParse, p, p->pEList, tab1,
|
selectInnerLoop(pParse, p, p->pEList, tab1,
|
||||||
0, 0, &dest, iCont, iBreak);
|
0, 0, &dest, iCont, iBreak);
|
||||||
sqlite3VdbeResolveLabel(v, iCont);
|
sqlite3VdbeResolveLabel(v, iCont);
|
||||||
sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart);
|
sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v);
|
||||||
sqlite3VdbeResolveLabel(v, iBreak);
|
sqlite3VdbeResolveLabel(v, iBreak);
|
||||||
sqlite3VdbeAddOp2(v, OP_Close, tab2, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, tab2, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_Close, tab1, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, tab1, 0);
|
||||||
@@ -2370,10 +2377,10 @@ static int generateOutputSubroutine(
|
|||||||
*/
|
*/
|
||||||
if( regPrev ){
|
if( regPrev ){
|
||||||
int j1, j2;
|
int j1, j2;
|
||||||
j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev);
|
j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); VdbeCoverage(v);
|
||||||
j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst,
|
j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst,
|
||||||
(char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
|
(char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
|
||||||
sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2);
|
sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2); VdbeCoverage(v);
|
||||||
sqlite3VdbeJumpHere(v, j1);
|
sqlite3VdbeJumpHere(v, j1);
|
||||||
sqlite3VdbeAddOp3(v, OP_Copy, pIn->iSdst, regPrev+1, pIn->nSdst-1);
|
sqlite3VdbeAddOp3(v, OP_Copy, pIn->iSdst, regPrev+1, pIn->nSdst-1);
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev);
|
sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev);
|
||||||
@@ -2474,7 +2481,7 @@ static int generateOutputSubroutine(
|
|||||||
/* Jump to the end of the loop if the LIMIT is reached.
|
/* Jump to the end of the loop if the LIMIT is reached.
|
||||||
*/
|
*/
|
||||||
if( p->iLimit ){
|
if( p->iLimit ){
|
||||||
sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1);
|
sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate the subroutine return
|
/* Generate the subroutine return
|
||||||
@@ -2790,6 +2797,7 @@ static int multiSelectOrderBy(
|
|||||||
VdbeNoopComment((v, "eof-A subroutine"));
|
VdbeNoopComment((v, "eof-A subroutine"));
|
||||||
addrEofA = sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
|
addrEofA = sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
|
||||||
addrEofA_noB = sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, labelEnd);
|
addrEofA_noB = sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, labelEnd);
|
||||||
|
VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofA);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofA);
|
||||||
p->nSelectRow += pPrior->nSelectRow;
|
p->nSelectRow += pPrior->nSelectRow;
|
||||||
}
|
}
|
||||||
@@ -2803,7 +2811,7 @@ static int multiSelectOrderBy(
|
|||||||
}else{
|
}else{
|
||||||
VdbeNoopComment((v, "eof-B subroutine"));
|
VdbeNoopComment((v, "eof-B subroutine"));
|
||||||
addrEofB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
|
addrEofB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
|
||||||
sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, labelEnd);
|
sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, labelEnd); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofB);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofB);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2811,7 +2819,7 @@ static int multiSelectOrderBy(
|
|||||||
*/
|
*/
|
||||||
VdbeNoopComment((v, "A-lt-B subroutine"));
|
VdbeNoopComment((v, "A-lt-B subroutine"));
|
||||||
addrAltB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
|
addrAltB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
|
||||||
sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA);
|
sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
|
||||||
|
|
||||||
/* Generate code to handle the case of A==B
|
/* Generate code to handle the case of A==B
|
||||||
@@ -2824,7 +2832,7 @@ static int multiSelectOrderBy(
|
|||||||
}else{
|
}else{
|
||||||
VdbeNoopComment((v, "A-eq-B subroutine"));
|
VdbeNoopComment((v, "A-eq-B subroutine"));
|
||||||
addrAeqB =
|
addrAeqB =
|
||||||
sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA);
|
sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2835,14 +2843,14 @@ static int multiSelectOrderBy(
|
|||||||
if( op==TK_ALL || op==TK_UNION ){
|
if( op==TK_ALL || op==TK_UNION ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
|
sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB);
|
sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
|
||||||
|
|
||||||
/* This code runs once to initialize everything.
|
/* This code runs once to initialize everything.
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeJumpHere(v, j1);
|
sqlite3VdbeJumpHere(v, j1);
|
||||||
sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA_noB);
|
sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA_noB); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB);
|
sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v);
|
||||||
|
|
||||||
/* Implement the main merge loop
|
/* Implement the main merge loop
|
||||||
*/
|
*/
|
||||||
@@ -2851,7 +2859,7 @@ static int multiSelectOrderBy(
|
|||||||
sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy,
|
sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy,
|
||||||
(char*)pKeyMerge, P4_KEYINFO);
|
(char*)pKeyMerge, P4_KEYINFO);
|
||||||
sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE);
|
sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE);
|
||||||
sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
|
sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB); VdbeCoverage(v);
|
||||||
|
|
||||||
/* Jump to the this point in order to terminate the query.
|
/* Jump to the this point in order to terminate the query.
|
||||||
*/
|
*/
|
||||||
@@ -4391,7 +4399,7 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
|
|||||||
** values to an OP_Copy.
|
** values to an OP_Copy.
|
||||||
*/
|
*/
|
||||||
if( regHit ){
|
if( regHit ){
|
||||||
addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit);
|
addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
sqlite3ExprCacheClear(pParse);
|
sqlite3ExprCacheClear(pParse);
|
||||||
for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
|
for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
|
||||||
@@ -4925,7 +4933,7 @@ int sqlite3Select(
|
|||||||
sortOut = sqlite3GetTempReg(pParse);
|
sortOut = sqlite3GetTempReg(pParse);
|
||||||
sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol);
|
sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol);
|
||||||
sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd);
|
sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd);
|
||||||
VdbeComment((v, "GROUP BY sort"));
|
VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v);
|
||||||
sAggInfo.useSortingIdx = 1;
|
sAggInfo.useSortingIdx = 1;
|
||||||
sqlite3ExprCacheClear(pParse);
|
sqlite3ExprCacheClear(pParse);
|
||||||
}
|
}
|
||||||
@@ -4952,7 +4960,7 @@ int sqlite3Select(
|
|||||||
sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr,
|
sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr,
|
||||||
(char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
|
(char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
|
||||||
j1 = sqlite3VdbeCurrentAddr(v);
|
j1 = sqlite3VdbeCurrentAddr(v);
|
||||||
sqlite3VdbeAddOp3(v, OP_Jump, j1+1, 0, j1+1);
|
sqlite3VdbeAddOp3(v, OP_Jump, j1+1, 0, j1+1); VdbeCoverage(v);
|
||||||
|
|
||||||
/* Generate code that runs whenever the GROUP BY changes.
|
/* Generate code that runs whenever the GROUP BY changes.
|
||||||
** Changes in the GROUP BY are detected by the previous code
|
** Changes in the GROUP BY are detected by the previous code
|
||||||
@@ -4966,7 +4974,7 @@ int sqlite3Select(
|
|||||||
sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr);
|
sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr);
|
||||||
sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow);
|
sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow);
|
||||||
VdbeComment((v, "output one row"));
|
VdbeComment((v, "output one row"));
|
||||||
sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd);
|
sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); VdbeCoverage(v);
|
||||||
VdbeComment((v, "check abort flag"));
|
VdbeComment((v, "check abort flag"));
|
||||||
sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
|
sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
|
||||||
VdbeComment((v, "reset accumulator"));
|
VdbeComment((v, "reset accumulator"));
|
||||||
@@ -4983,6 +4991,7 @@ int sqlite3Select(
|
|||||||
*/
|
*/
|
||||||
if( groupBySort ){
|
if( groupBySort ){
|
||||||
sqlite3VdbeAddOp2(v, OP_SorterNext, sAggInfo.sortingIdx, addrTopOfLoop);
|
sqlite3VdbeAddOp2(v, OP_SorterNext, sAggInfo.sortingIdx, addrTopOfLoop);
|
||||||
|
VdbeCoverage(v);
|
||||||
}else{
|
}else{
|
||||||
sqlite3WhereEnd(pWInfo);
|
sqlite3WhereEnd(pWInfo);
|
||||||
sqlite3VdbeChangeToNoop(v, addrSortingIdx);
|
sqlite3VdbeChangeToNoop(v, addrSortingIdx);
|
||||||
@@ -5010,7 +5019,7 @@ int sqlite3Select(
|
|||||||
sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
|
sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
|
||||||
sqlite3VdbeResolveLabel(v, addrOutputRow);
|
sqlite3VdbeResolveLabel(v, addrOutputRow);
|
||||||
addrOutputRow = sqlite3VdbeCurrentAddr(v);
|
addrOutputRow = sqlite3VdbeCurrentAddr(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2);
|
sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2); VdbeCoverage(v);
|
||||||
VdbeComment((v, "Groupby result generator entry point"));
|
VdbeComment((v, "Groupby result generator entry point"));
|
||||||
sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
|
sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
|
||||||
finalizeAggFunctions(pParse, &sAggInfo);
|
finalizeAggFunctions(pParse, &sAggInfo);
|
||||||
|
@@ -6117,7 +6117,8 @@ int sqlite3_test_control(int op, ...);
|
|||||||
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
|
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
|
||||||
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19
|
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19
|
||||||
#define SQLITE_TESTCTRL_NEVER_CORRUPT 20
|
#define SQLITE_TESTCTRL_NEVER_CORRUPT 20
|
||||||
#define SQLITE_TESTCTRL_LAST 20
|
#define SQLITE_TESTCTRL_VDBE_COVERAGE 21
|
||||||
|
#define SQLITE_TESTCTRL_LAST 21
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: SQLite Runtime Status
|
** CAPI3REF: SQLite Runtime Status
|
||||||
|
@@ -2657,6 +2657,13 @@ struct Sqlite3Config {
|
|||||||
void(*xSqllog)(void*,sqlite3*,const char*, int);
|
void(*xSqllog)(void*,sqlite3*,const char*, int);
|
||||||
void *pSqllogArg;
|
void *pSqllogArg;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef SQLITE_VDBE_COVERAGE
|
||||||
|
/* The following callback (if not NULL) is invoked on every VDBE branch
|
||||||
|
** operation. Set the callback using SQLITE_TESTCTRL_VDBE_COVERAGE.
|
||||||
|
*/
|
||||||
|
void (*xVdbeBranch)(void*,int iSrcLine,u8 eThis,u8 eMx); /* Callback */
|
||||||
|
void *pVdbeBranchArg; /* 1st argument */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -566,6 +566,7 @@ void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
|
|||||||
assert( pTable!=0 );
|
assert( pTable!=0 );
|
||||||
if( (v = sqlite3GetVdbe(pParse))!=0 ){
|
if( (v = sqlite3GetVdbe(pParse))!=0 ){
|
||||||
int base;
|
int base;
|
||||||
|
static const int iLn = __LINE__+2;
|
||||||
static const VdbeOpList dropTrigger[] = {
|
static const VdbeOpList dropTrigger[] = {
|
||||||
{ OP_Rewind, 0, ADDR(9), 0},
|
{ OP_Rewind, 0, ADDR(9), 0},
|
||||||
{ OP_String8, 0, 1, 0}, /* 1 */
|
{ OP_String8, 0, 1, 0}, /* 1 */
|
||||||
@@ -580,7 +581,7 @@ void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
|
|||||||
|
|
||||||
sqlite3BeginWriteOperation(pParse, 0, iDb);
|
sqlite3BeginWriteOperation(pParse, 0, iDb);
|
||||||
sqlite3OpenMasterTable(pParse, iDb);
|
sqlite3OpenMasterTable(pParse, iDb);
|
||||||
base = sqlite3VdbeAddOpList(v, ArraySize(dropTrigger), dropTrigger);
|
base = sqlite3VdbeAddOpList(v, ArraySize(dropTrigger), dropTrigger, iLn);
|
||||||
sqlite3VdbeChangeP4(v, base+1, pTrigger->zName, P4_TRANSIENT);
|
sqlite3VdbeChangeP4(v, base+1, pTrigger->zName, P4_TRANSIENT);
|
||||||
sqlite3VdbeChangeP4(v, base+4, "trigger", P4_STATIC);
|
sqlite3VdbeChangeP4(v, base+4, "trigger", P4_STATIC);
|
||||||
sqlite3ChangeCookie(pParse, iDb);
|
sqlite3ChangeCookie(pParse, iDb);
|
||||||
|
19
src/update.c
19
src/update.c
@@ -434,18 +434,23 @@ void sqlite3Update(
|
|||||||
if( aToOpen[iDataCur-iBaseCur] ){
|
if( aToOpen[iDataCur-iBaseCur] ){
|
||||||
assert( pPk!=0 );
|
assert( pPk!=0 );
|
||||||
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey);
|
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey);
|
||||||
|
VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
labelContinue = labelBreak;
|
labelContinue = labelBreak;
|
||||||
sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
|
sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
|
||||||
|
VdbeCoverage(v);
|
||||||
}else if( pPk ){
|
}else if( pPk ){
|
||||||
labelContinue = sqlite3VdbeMakeLabel(v);
|
labelContinue = sqlite3VdbeMakeLabel(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak);
|
sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v);
|
||||||
addrTop = sqlite3VdbeAddOp2(v, OP_RowKey, iEph, regKey);
|
addrTop = sqlite3VdbeAddOp2(v, OP_RowKey, iEph, regKey);
|
||||||
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0);
|
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0);
|
||||||
|
VdbeCoverage(v);
|
||||||
}else{
|
}else{
|
||||||
labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet, labelBreak,
|
labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet, labelBreak,
|
||||||
regOldRowid);
|
regOldRowid);
|
||||||
|
VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid);
|
sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid);
|
||||||
|
VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the record number will change, set register regNewRowid to
|
/* If the record number will change, set register regNewRowid to
|
||||||
@@ -455,7 +460,7 @@ void sqlite3Update(
|
|||||||
assert( chngKey || pTrigger || hasFK || regOldRowid==regNewRowid );
|
assert( chngKey || pTrigger || hasFK || regOldRowid==regNewRowid );
|
||||||
if( chngRowid ){
|
if( chngRowid ){
|
||||||
sqlite3ExprCode(pParse, pRowidExpr, regNewRowid);
|
sqlite3ExprCode(pParse, pRowidExpr, regNewRowid);
|
||||||
sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid);
|
sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid); VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute the old pre-UPDATE content of the row being changed, if that
|
/* Compute the old pre-UPDATE content of the row being changed, if that
|
||||||
@@ -536,8 +541,10 @@ void sqlite3Update(
|
|||||||
*/
|
*/
|
||||||
if( pPk ){
|
if( pPk ){
|
||||||
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue,regKey,nKey);
|
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue,regKey,nKey);
|
||||||
|
VdbeCoverage(v);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid);
|
sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid);
|
||||||
|
VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If it did not delete it, the row-trigger may still have modified
|
/* If it did not delete it, the row-trigger may still have modified
|
||||||
@@ -570,8 +577,10 @@ void sqlite3Update(
|
|||||||
if( bReplace || chngKey ){
|
if( bReplace || chngKey ){
|
||||||
if( pPk ){
|
if( pPk ){
|
||||||
j1 = sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, 0, regKey, nKey);
|
j1 = sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, 0, regKey, nKey);
|
||||||
|
VdbeCoverage(v);
|
||||||
}else{
|
}else{
|
||||||
j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, 0, regOldRowid);
|
j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, 0, regOldRowid);
|
||||||
|
VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx);
|
sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx);
|
||||||
@@ -616,7 +625,7 @@ void sqlite3Update(
|
|||||||
/* Nothing to do at end-of-loop for a single-pass */
|
/* Nothing to do at end-of-loop for a single-pass */
|
||||||
}else if( pPk ){
|
}else if( pPk ){
|
||||||
sqlite3VdbeResolveLabel(v, labelContinue);
|
sqlite3VdbeResolveLabel(v, labelContinue);
|
||||||
sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop);
|
sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop); VdbeCoverage(v);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, labelContinue);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, labelContinue);
|
||||||
}
|
}
|
||||||
@@ -745,7 +754,7 @@ static void updateVirtualTable(
|
|||||||
/* Generate code to scan the ephemeral table and call VUpdate. */
|
/* Generate code to scan the ephemeral table and call VUpdate. */
|
||||||
iReg = ++pParse->nMem;
|
iReg = ++pParse->nMem;
|
||||||
pParse->nMem += pTab->nCol+1;
|
pParse->nMem += pTab->nCol+1;
|
||||||
addr = sqlite3VdbeAddOp2(v, OP_Rewind, ephemTab, 0);
|
addr = sqlite3VdbeAddOp2(v, OP_Rewind, ephemTab, 0); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp3(v, OP_Column, ephemTab, 0, iReg);
|
sqlite3VdbeAddOp3(v, OP_Column, ephemTab, 0, iReg);
|
||||||
sqlite3VdbeAddOp3(v, OP_Column, ephemTab, (pRowid?1:0), iReg+1);
|
sqlite3VdbeAddOp3(v, OP_Column, ephemTab, (pRowid?1:0), iReg+1);
|
||||||
for(i=0; i<pTab->nCol; i++){
|
for(i=0; i<pTab->nCol; i++){
|
||||||
@@ -755,7 +764,7 @@ static void updateVirtualTable(
|
|||||||
sqlite3VdbeAddOp4(v, OP_VUpdate, 0, pTab->nCol+2, iReg, pVTab, P4_VTAB);
|
sqlite3VdbeAddOp4(v, OP_VUpdate, 0, pTab->nCol+2, iReg, pVTab, P4_VTAB);
|
||||||
sqlite3VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError);
|
sqlite3VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError);
|
||||||
sqlite3MayAbort(pParse);
|
sqlite3MayAbort(pParse);
|
||||||
sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1);
|
sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1); VdbeCoverage(v);
|
||||||
sqlite3VdbeJumpHere(v, addr);
|
sqlite3VdbeJumpHere(v, addr);
|
||||||
sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0);
|
||||||
|
|
||||||
|
68
src/vdbe.c
68
src/vdbe.c
@@ -107,6 +107,18 @@ int sqlite3_found_count = 0;
|
|||||||
# define UPDATE_MAX_BLOBSIZE(P)
|
# define UPDATE_MAX_BLOBSIZE(P)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Invoke the VDBE coverage callback, if defined
|
||||||
|
*/
|
||||||
|
#if !defined(SQLITE_VDBE_COVERAGE)
|
||||||
|
# define VdbeBranchTaken(I,M)
|
||||||
|
#else
|
||||||
|
# define VdbeBranchTaken(I,M) \
|
||||||
|
if( sqlite3GlobalConfig.xVdbeBranch!=0 ){ \
|
||||||
|
sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg, \
|
||||||
|
pOp->iSrcLine,(I),(M)); }
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Convert the given register into a string if it isn't one
|
** Convert the given register into a string if it isn't one
|
||||||
** already. Return non-zero if a malloc() fails.
|
** already. Return non-zero if a malloc() fails.
|
||||||
@@ -1638,6 +1650,7 @@ case OP_MustBeInt: { /* jump, in1 */
|
|||||||
pIn1 = &aMem[pOp->p1];
|
pIn1 = &aMem[pOp->p1];
|
||||||
if( (pIn1->flags & MEM_Int)==0 ){
|
if( (pIn1->flags & MEM_Int)==0 ){
|
||||||
applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
|
applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
|
||||||
|
VdbeBranchTaken((pIn1->flags&MEM_Int)==0, 2);
|
||||||
if( (pIn1->flags & MEM_Int)==0 ){
|
if( (pIn1->flags & MEM_Int)==0 ){
|
||||||
if( pOp->p2==0 ){
|
if( pOp->p2==0 ){
|
||||||
rc = SQLITE_MISMATCH;
|
rc = SQLITE_MISMATCH;
|
||||||
@@ -1891,12 +1904,15 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
|
|||||||
** then the result is always NULL.
|
** then the result is always NULL.
|
||||||
** The jump is taken if the SQLITE_JUMPIFNULL bit is set.
|
** The jump is taken if the SQLITE_JUMPIFNULL bit is set.
|
||||||
*/
|
*/
|
||||||
if( pOp->p5 & SQLITE_JUMPIFNULL ){
|
if( pOp->p5 & SQLITE_STOREP2 ){
|
||||||
pc = pOp->p2-1;
|
|
||||||
}else if( pOp->p5 & SQLITE_STOREP2 ){
|
|
||||||
pOut = &aMem[pOp->p2];
|
pOut = &aMem[pOp->p2];
|
||||||
MemSetTypeFlag(pOut, MEM_Null);
|
MemSetTypeFlag(pOut, MEM_Null);
|
||||||
REGISTER_TRACE(pOp->p2, pOut);
|
REGISTER_TRACE(pOp->p2, pOut);
|
||||||
|
}else{
|
||||||
|
VdbeBranchTaken((pOp->p5 & SQLITE_JUMPIFNULL)?2:3,4);
|
||||||
|
if( pOp->p5 & SQLITE_JUMPIFNULL ){
|
||||||
|
pc = pOp->p2-1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1929,10 +1945,12 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
|
|||||||
MemSetTypeFlag(pOut, MEM_Int);
|
MemSetTypeFlag(pOut, MEM_Int);
|
||||||
pOut->u.i = res;
|
pOut->u.i = res;
|
||||||
REGISTER_TRACE(pOp->p2, pOut);
|
REGISTER_TRACE(pOp->p2, pOut);
|
||||||
}else if( res ){
|
}else{
|
||||||
|
VdbeBranchTaken(res!=0, 4);
|
||||||
|
if( res ){
|
||||||
pc = pOp->p2-1;
|
pc = pOp->p2-1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/* Undo any changes made by applyAffinity() to the input registers. */
|
/* Undo any changes made by applyAffinity() to the input registers. */
|
||||||
pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (flags1&MEM_TypeMask);
|
pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (flags1&MEM_TypeMask);
|
||||||
pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (flags3&MEM_TypeMask);
|
pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (flags3&MEM_TypeMask);
|
||||||
@@ -2029,11 +2047,11 @@ case OP_Compare: {
|
|||||||
*/
|
*/
|
||||||
case OP_Jump: { /* jump */
|
case OP_Jump: { /* jump */
|
||||||
if( iCompare<0 ){
|
if( iCompare<0 ){
|
||||||
pc = pOp->p1 - 1;
|
pc = pOp->p1 - 1; VdbeBranchTaken(0,3);
|
||||||
}else if( iCompare==0 ){
|
}else if( iCompare==0 ){
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1; VdbeBranchTaken(1,3);
|
||||||
}else{
|
}else{
|
||||||
pc = pOp->p3 - 1;
|
pc = pOp->p3 - 1; VdbeBranchTaken(2,3);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2137,6 +2155,7 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */
|
|||||||
*/
|
*/
|
||||||
case OP_Once: { /* jump */
|
case OP_Once: { /* jump */
|
||||||
assert( pOp->p1<p->nOnceFlag );
|
assert( pOp->p1<p->nOnceFlag );
|
||||||
|
VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2);
|
||||||
if( p->aOnceFlag[pOp->p1] ){
|
if( p->aOnceFlag[pOp->p1] ){
|
||||||
pc = pOp->p2-1;
|
pc = pOp->p2-1;
|
||||||
}else{
|
}else{
|
||||||
@@ -2171,6 +2190,7 @@ case OP_IfNot: { /* jump, in1 */
|
|||||||
#endif
|
#endif
|
||||||
if( pOp->opcode==OP_IfNot ) c = !c;
|
if( pOp->opcode==OP_IfNot ) c = !c;
|
||||||
}
|
}
|
||||||
|
VdbeBranchTaken(c!=0, 2);
|
||||||
if( c ){
|
if( c ){
|
||||||
pc = pOp->p2-1;
|
pc = pOp->p2-1;
|
||||||
}
|
}
|
||||||
@@ -2184,6 +2204,7 @@ case OP_IfNot: { /* jump, in1 */
|
|||||||
*/
|
*/
|
||||||
case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */
|
case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */
|
||||||
pIn1 = &aMem[pOp->p1];
|
pIn1 = &aMem[pOp->p1];
|
||||||
|
VdbeBranchTaken( (pIn1->flags & MEM_Null)!=0, 2);
|
||||||
if( (pIn1->flags & MEM_Null)!=0 ){
|
if( (pIn1->flags & MEM_Null)!=0 ){
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
}
|
}
|
||||||
@@ -2197,6 +2218,7 @@ case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */
|
|||||||
*/
|
*/
|
||||||
case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */
|
case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */
|
||||||
pIn1 = &aMem[pOp->p1];
|
pIn1 = &aMem[pOp->p1];
|
||||||
|
VdbeBranchTaken( (pIn1->flags & MEM_Null)==0, 2);
|
||||||
if( (pIn1->flags & MEM_Null)==0 ){
|
if( (pIn1->flags & MEM_Null)==0 ){
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
}
|
}
|
||||||
@@ -3474,7 +3496,7 @@ case OP_SeekGT: { /* jump, in3 */
|
|||||||
if( (pIn3->flags & MEM_Real)==0 ){
|
if( (pIn3->flags & MEM_Real)==0 ){
|
||||||
/* If the P3 value cannot be converted into any kind of a number,
|
/* If the P3 value cannot be converted into any kind of a number,
|
||||||
** then the seek is not possible, so jump to P2 */
|
** then the seek is not possible, so jump to P2 */
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1; VdbeBranchTaken(1,2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3569,6 +3591,7 @@ case OP_SeekGT: { /* jump, in3 */
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert( pOp->p2>0 );
|
assert( pOp->p2>0 );
|
||||||
|
VdbeBranchTaken(res!=0,2);
|
||||||
if( res ){
|
if( res ){
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
}
|
}
|
||||||
@@ -3702,7 +3725,7 @@ case OP_Found: { /* jump, in3 */
|
|||||||
** conflict */
|
** conflict */
|
||||||
for(ii=0; ii<r.nField; ii++){
|
for(ii=0; ii<r.nField; ii++){
|
||||||
if( r.aMem[ii].flags & MEM_Null ){
|
if( r.aMem[ii].flags & MEM_Null ){
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1; VdbeBranchTaken(1,2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3720,8 +3743,10 @@ case OP_Found: { /* jump, in3 */
|
|||||||
pC->deferredMoveto = 0;
|
pC->deferredMoveto = 0;
|
||||||
pC->cacheStatus = CACHE_STALE;
|
pC->cacheStatus = CACHE_STALE;
|
||||||
if( pOp->opcode==OP_Found ){
|
if( pOp->opcode==OP_Found ){
|
||||||
|
VdbeBranchTaken(alreadyExists!=0,2);
|
||||||
if( alreadyExists ) pc = pOp->p2 - 1;
|
if( alreadyExists ) pc = pOp->p2 - 1;
|
||||||
}else{
|
}else{
|
||||||
|
VdbeBranchTaken(alreadyExists==0,2);
|
||||||
if( !alreadyExists ) pc = pOp->p2 - 1;
|
if( !alreadyExists ) pc = pOp->p2 - 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -3764,6 +3789,7 @@ case OP_NotExists: { /* jump, in3 */
|
|||||||
pC->nullRow = 0;
|
pC->nullRow = 0;
|
||||||
pC->cacheStatus = CACHE_STALE;
|
pC->cacheStatus = CACHE_STALE;
|
||||||
pC->deferredMoveto = 0;
|
pC->deferredMoveto = 0;
|
||||||
|
VdbeBranchTaken(res!=0,2);
|
||||||
if( res!=0 ){
|
if( res!=0 ){
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
assert( pC->rowidIsValid==0 );
|
assert( pC->rowidIsValid==0 );
|
||||||
@@ -4138,6 +4164,7 @@ case OP_SorterCompare: {
|
|||||||
pIn3 = &aMem[pOp->p3];
|
pIn3 = &aMem[pOp->p3];
|
||||||
nIgnore = pOp->p4.i;
|
nIgnore = pOp->p4.i;
|
||||||
rc = sqlite3VdbeSorterCompare(pC, pIn3, nIgnore, &res);
|
rc = sqlite3VdbeSorterCompare(pC, pIn3, nIgnore, &res);
|
||||||
|
VdbeBranchTaken(res!=0,2);
|
||||||
if( res ){
|
if( res ){
|
||||||
pc = pOp->p2-1;
|
pc = pOp->p2-1;
|
||||||
}
|
}
|
||||||
@@ -4337,8 +4364,9 @@ case OP_Last: { /* jump */
|
|||||||
pC->deferredMoveto = 0;
|
pC->deferredMoveto = 0;
|
||||||
pC->rowidIsValid = 0;
|
pC->rowidIsValid = 0;
|
||||||
pC->cacheStatus = CACHE_STALE;
|
pC->cacheStatus = CACHE_STALE;
|
||||||
if( pOp->p2>0 && res ){
|
if( pOp->p2>0 ){
|
||||||
pc = pOp->p2 - 1;
|
VdbeBranchTaken(res!=0,2);
|
||||||
|
if( res ) pc = pOp->p2 - 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -4395,6 +4423,7 @@ case OP_Rewind: { /* jump */
|
|||||||
}
|
}
|
||||||
pC->nullRow = (u8)res;
|
pC->nullRow = (u8)res;
|
||||||
assert( pOp->p2>0 && pOp->p2<p->nOp );
|
assert( pOp->p2>0 && pOp->p2<p->nOp );
|
||||||
|
VdbeBranchTaken(res!=0,2);
|
||||||
if( res ){
|
if( res ){
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
}
|
}
|
||||||
@@ -4485,6 +4514,7 @@ case OP_Next: /* jump */
|
|||||||
rc = pOp->p4.xAdvance(pC->pCursor, &res);
|
rc = pOp->p4.xAdvance(pC->pCursor, &res);
|
||||||
next_tail:
|
next_tail:
|
||||||
pC->cacheStatus = CACHE_STALE;
|
pC->cacheStatus = CACHE_STALE;
|
||||||
|
VdbeBranchTaken(res==0,2);
|
||||||
if( res==0 ){
|
if( res==0 ){
|
||||||
pC->nullRow = 0;
|
pC->nullRow = 0;
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
@@ -4710,6 +4740,7 @@ case OP_IdxGE: { /* jump */
|
|||||||
assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxGT );
|
assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxGT );
|
||||||
res++;
|
res++;
|
||||||
}
|
}
|
||||||
|
VdbeBranchTaken(res>0,2);
|
||||||
if( res>0 ){
|
if( res>0 ){
|
||||||
pc = pOp->p2 - 1 ;
|
pc = pOp->p2 - 1 ;
|
||||||
}
|
}
|
||||||
@@ -5071,9 +5102,11 @@ case OP_RowSetRead: { /* jump, in1, out3 */
|
|||||||
/* The boolean index is empty */
|
/* The boolean index is empty */
|
||||||
sqlite3VdbeMemSetNull(pIn1);
|
sqlite3VdbeMemSetNull(pIn1);
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
|
VdbeBranchTaken(1,2);
|
||||||
}else{
|
}else{
|
||||||
/* A value was pulled from the index */
|
/* A value was pulled from the index */
|
||||||
sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val);
|
sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val);
|
||||||
|
VdbeBranchTaken(0,2);
|
||||||
}
|
}
|
||||||
goto check_for_interrupt;
|
goto check_for_interrupt;
|
||||||
}
|
}
|
||||||
@@ -5125,6 +5158,7 @@ case OP_RowSetTest: { /* jump, in1, in3 */
|
|||||||
exists = sqlite3RowSetTest(pIn1->u.pRowSet,
|
exists = sqlite3RowSetTest(pIn1->u.pRowSet,
|
||||||
(u8)(iSet>=0 ? iSet & 0xf : 0xff),
|
(u8)(iSet>=0 ? iSet & 0xf : 0xff),
|
||||||
pIn3->u.i);
|
pIn3->u.i);
|
||||||
|
VdbeBranchTaken(exists!=0,2);
|
||||||
if( exists ){
|
if( exists ){
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
break;
|
break;
|
||||||
@@ -5317,8 +5351,10 @@ case OP_FkCounter: {
|
|||||||
*/
|
*/
|
||||||
case OP_FkIfZero: { /* jump */
|
case OP_FkIfZero: { /* jump */
|
||||||
if( pOp->p1 ){
|
if( pOp->p1 ){
|
||||||
|
VdbeBranchTaken(db->nDeferredCons==0 && db->nDeferredImmCons==0, 2);
|
||||||
if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1;
|
if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1;
|
||||||
}else{
|
}else{
|
||||||
|
VdbeBranchTaken(p->nFkConstraint==0 && db->nDeferredImmCons==0, 2);
|
||||||
if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1;
|
if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -5367,6 +5403,7 @@ case OP_MemMax: { /* in2 */
|
|||||||
case OP_IfPos: { /* jump, in1 */
|
case OP_IfPos: { /* jump, in1 */
|
||||||
pIn1 = &aMem[pOp->p1];
|
pIn1 = &aMem[pOp->p1];
|
||||||
assert( pIn1->flags&MEM_Int );
|
assert( pIn1->flags&MEM_Int );
|
||||||
|
VdbeBranchTaken( pIn1->u.i>0, 2);
|
||||||
if( pIn1->u.i>0 ){
|
if( pIn1->u.i>0 ){
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
}
|
}
|
||||||
@@ -5384,6 +5421,7 @@ case OP_IfPos: { /* jump, in1 */
|
|||||||
case OP_IfNeg: { /* jump, in1 */
|
case OP_IfNeg: { /* jump, in1 */
|
||||||
pIn1 = &aMem[pOp->p1];
|
pIn1 = &aMem[pOp->p1];
|
||||||
assert( pIn1->flags&MEM_Int );
|
assert( pIn1->flags&MEM_Int );
|
||||||
|
VdbeBranchTaken(pIn1->u.i<0, 2);
|
||||||
if( pIn1->u.i<0 ){
|
if( pIn1->u.i<0 ){
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
}
|
}
|
||||||
@@ -5403,6 +5441,7 @@ case OP_IfZero: { /* jump, in1 */
|
|||||||
pIn1 = &aMem[pOp->p1];
|
pIn1 = &aMem[pOp->p1];
|
||||||
assert( pIn1->flags&MEM_Int );
|
assert( pIn1->flags&MEM_Int );
|
||||||
pIn1->u.i += pOp->p3;
|
pIn1->u.i += pOp->p3;
|
||||||
|
VdbeBranchTaken(pIn1->u.i==0, 2);
|
||||||
if( pIn1->u.i==0 ){
|
if( pIn1->u.i==0 ){
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
}
|
}
|
||||||
@@ -5674,6 +5713,7 @@ case OP_IncrVacuum: { /* jump */
|
|||||||
assert( p->readOnly==0 );
|
assert( p->readOnly==0 );
|
||||||
pBt = db->aDb[pOp->p1].pBt;
|
pBt = db->aDb[pOp->p1].pBt;
|
||||||
rc = sqlite3BtreeIncrVacuum(pBt);
|
rc = sqlite3BtreeIncrVacuum(pBt);
|
||||||
|
VdbeBranchTaken(rc==SQLITE_DONE,2);
|
||||||
if( rc==SQLITE_DONE ){
|
if( rc==SQLITE_DONE ){
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
rc = SQLITE_OK;
|
rc = SQLITE_OK;
|
||||||
@@ -5880,7 +5920,7 @@ case OP_VFilter: { /* jump */
|
|||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
res = pModule->xEof(pVtabCursor);
|
res = pModule->xEof(pVtabCursor);
|
||||||
}
|
}
|
||||||
|
VdbeBranchTaken(res!=0,2);
|
||||||
if( res ){
|
if( res ){
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
}
|
}
|
||||||
@@ -5985,7 +6025,7 @@ case OP_VNext: { /* jump */
|
|||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
res = pModule->xEof(pCur->pVtabCursor);
|
res = pModule->xEof(pCur->pVtabCursor);
|
||||||
}
|
}
|
||||||
|
VdbeBranchTaken(!res,2);
|
||||||
if( !res ){
|
if( !res ){
|
||||||
/* If there is data, jump to P2 */
|
/* If there is data, jump to P2 */
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
|
15
src/vdbe.h
15
src/vdbe.h
@@ -68,6 +68,9 @@ struct VdbeOp {
|
|||||||
int cnt; /* Number of times this instruction was executed */
|
int cnt; /* Number of times this instruction was executed */
|
||||||
u64 cycles; /* Total time spent executing this instruction */
|
u64 cycles; /* Total time spent executing this instruction */
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef SQLITE_VDBE_COVERAGE
|
||||||
|
int iSrcLine; /* Source-code line that generated this opcode */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
typedef struct VdbeOp VdbeOp;
|
typedef struct VdbeOp VdbeOp;
|
||||||
|
|
||||||
@@ -167,7 +170,7 @@ int sqlite3VdbeAddOp2(Vdbe*,int,int,int);
|
|||||||
int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int);
|
int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int);
|
||||||
int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int);
|
int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int);
|
||||||
int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int);
|
int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int);
|
||||||
int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp);
|
int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno);
|
||||||
void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
|
void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
|
||||||
void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1);
|
void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1);
|
||||||
void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2);
|
void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2);
|
||||||
@@ -238,4 +241,14 @@ void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
|
|||||||
# define VdbeModuleComment(X)
|
# define VdbeModuleComment(X)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Set the Opcode.iSrcline field of the previous opcode */
|
||||||
|
#ifdef SQLITE_VDBE_COVERAGE
|
||||||
|
void sqlite3VdbeSetLineNumber(Vdbe*,int);
|
||||||
|
# define VdbeCoverage(v) sqlite3VdbeSetLineNumber(v,__LINE__)
|
||||||
|
# define VdbeCoverageIf(v,x) if(x)sqlite3VdbeSetLineNumber(v,__LINE__)
|
||||||
|
#else
|
||||||
|
# define VdbeCoverage(v)
|
||||||
|
# define VdbeCoverageIf(v,x)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -173,6 +173,9 @@ int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
|
|||||||
#ifdef VDBE_PROFILE
|
#ifdef VDBE_PROFILE
|
||||||
pOp->cycles = 0;
|
pOp->cycles = 0;
|
||||||
pOp->cnt = 0;
|
pOp->cnt = 0;
|
||||||
|
#endif
|
||||||
|
#ifdef SQLITE_VDBE_COVERAGE
|
||||||
|
pOp->iSrcLine = 0;
|
||||||
#endif
|
#endif
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@@ -535,7 +538,7 @@ VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){
|
|||||||
** Add a whole list of operations to the operation stack. Return the
|
** Add a whole list of operations to the operation stack. Return the
|
||||||
** address of the first operation added.
|
** address of the first operation added.
|
||||||
*/
|
*/
|
||||||
int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
|
int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp, int iLineno){
|
||||||
int addr;
|
int addr;
|
||||||
assert( p->magic==VDBE_MAGIC_INIT );
|
assert( p->magic==VDBE_MAGIC_INIT );
|
||||||
if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p) ){
|
if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p) ){
|
||||||
@@ -563,6 +566,11 @@ int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
|
|||||||
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
|
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||||
pOut->zComment = 0;
|
pOut->zComment = 0;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef SQLITE_VDBE_COVERAGE
|
||||||
|
pOut->iSrcLine = iLineno+i;
|
||||||
|
#else
|
||||||
|
(void)iLineno;
|
||||||
|
#endif
|
||||||
#ifdef SQLITE_DEBUG
|
#ifdef SQLITE_DEBUG
|
||||||
if( p->db->flags & SQLITE_VdbeAddopTrace ){
|
if( p->db->flags & SQLITE_VdbeAddopTrace ){
|
||||||
sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
|
sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
|
||||||
@@ -851,6 +859,15 @@ void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){
|
|||||||
}
|
}
|
||||||
#endif /* NDEBUG */
|
#endif /* NDEBUG */
|
||||||
|
|
||||||
|
#ifdef SQLITE_VDBE_COVERAGE
|
||||||
|
/*
|
||||||
|
** Set the value if the iSrcLine field for the previously coded instruction.
|
||||||
|
*/
|
||||||
|
void sqlite3VdbeSetLineNumber(Vdbe *v, int iLine){
|
||||||
|
sqlite3VdbeGetOp(v,-1)->iSrcLine = iLine;
|
||||||
|
}
|
||||||
|
#endif /* SQLITE_VDBE_COVERAGE */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Return the opcode for a given address. If the address is -1, then
|
** Return the opcode for a given address. If the address is -1, then
|
||||||
** return the most recently inserted opcode.
|
** return the most recently inserted opcode.
|
||||||
|
@@ -133,14 +133,13 @@ int sqlite3_blob_open(
|
|||||||
** which closes the b-tree cursor and (possibly) commits the
|
** which closes the b-tree cursor and (possibly) commits the
|
||||||
** transaction.
|
** transaction.
|
||||||
*/
|
*/
|
||||||
|
static const int iLn = __LINE__+4;
|
||||||
static const VdbeOpList openBlob[] = {
|
static const VdbeOpList openBlob[] = {
|
||||||
/* {OP_Transaction, 0, 0, 0}, // 0: Inserted separately */
|
/* {OP_Transaction, 0, 0, 0}, // 0: Inserted separately */
|
||||||
{OP_TableLock, 0, 0, 0}, /* 1: Acquire a read or write lock */
|
{OP_TableLock, 0, 0, 0}, /* 1: Acquire a read or write lock */
|
||||||
|
|
||||||
/* One of the following two instructions is replaced by an OP_Noop. */
|
/* One of the following two instructions is replaced by an OP_Noop. */
|
||||||
{OP_OpenRead, 0, 0, 0}, /* 2: Open cursor 0 for reading */
|
{OP_OpenRead, 0, 0, 0}, /* 2: Open cursor 0 for reading */
|
||||||
{OP_OpenWrite, 0, 0, 0}, /* 3: Open cursor 0 for read/write */
|
{OP_OpenWrite, 0, 0, 0}, /* 3: Open cursor 0 for read/write */
|
||||||
|
|
||||||
{OP_Variable, 1, 1, 1}, /* 4: Push the rowid to the stack */
|
{OP_Variable, 1, 1, 1}, /* 4: Push the rowid to the stack */
|
||||||
{OP_NotExists, 0, 10, 1}, /* 5: Seek the cursor */
|
{OP_NotExists, 0, 10, 1}, /* 5: Seek the cursor */
|
||||||
{OP_Column, 0, 0, 1}, /* 6 */
|
{OP_Column, 0, 0, 1}, /* 6 */
|
||||||
@@ -265,7 +264,7 @@ int sqlite3_blob_open(
|
|||||||
pTab->pSchema->schema_cookie,
|
pTab->pSchema->schema_cookie,
|
||||||
pTab->pSchema->iGeneration);
|
pTab->pSchema->iGeneration);
|
||||||
sqlite3VdbeChangeP5(v, 1);
|
sqlite3VdbeChangeP5(v, 1);
|
||||||
sqlite3VdbeAddOpList(v, sizeof(openBlob)/sizeof(VdbeOpList), openBlob);
|
sqlite3VdbeAddOpList(v, ArraySize(openBlob), openBlob, iLn);
|
||||||
|
|
||||||
/* Make sure a mutex is held on the table to be accessed */
|
/* Make sure a mutex is held on the table to be accessed */
|
||||||
sqlite3VdbeUsesBtree(v, iDb);
|
sqlite3VdbeUsesBtree(v, iDb);
|
||||||
|
38
src/where.c
38
src/where.c
@@ -1708,12 +1708,12 @@ static void constructAutomaticIndex(
|
|||||||
VdbeComment((v, "for %s", pTable->zName));
|
VdbeComment((v, "for %s", pTable->zName));
|
||||||
|
|
||||||
/* Fill the automatic index with content */
|
/* Fill the automatic index with content */
|
||||||
addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur);
|
addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);
|
||||||
regRecord = sqlite3GetTempReg(pParse);
|
regRecord = sqlite3GetTempReg(pParse);
|
||||||
sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0);
|
sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
|
sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
|
||||||
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
|
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
|
||||||
sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1);
|
sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
|
||||||
sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
|
sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
|
||||||
sqlite3VdbeJumpHere(v, addrTop);
|
sqlite3VdbeJumpHere(v, addrTop);
|
||||||
sqlite3ReleaseTempReg(pParse, regRecord);
|
sqlite3ReleaseTempReg(pParse, regRecord);
|
||||||
@@ -2388,7 +2388,7 @@ static int codeEqualityTerm(
|
|||||||
bRev = !bRev;
|
bRev = !bRev;
|
||||||
}
|
}
|
||||||
iTab = pX->iTable;
|
iTab = pX->iTable;
|
||||||
sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0);
|
sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0); VdbeCoverage(v);
|
||||||
assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
|
assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
|
||||||
pLoop->wsFlags |= WHERE_IN_ABLE;
|
pLoop->wsFlags |= WHERE_IN_ABLE;
|
||||||
if( pLevel->u.in.nIn==0 ){
|
if( pLevel->u.in.nIn==0 ){
|
||||||
@@ -2408,7 +2408,7 @@ static int codeEqualityTerm(
|
|||||||
pIn->addrInTop = sqlite3VdbeAddOp3(v, OP_Column, iTab, 0, iReg);
|
pIn->addrInTop = sqlite3VdbeAddOp3(v, OP_Column, iTab, 0, iReg);
|
||||||
}
|
}
|
||||||
pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen;
|
pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen;
|
||||||
sqlite3VdbeAddOp1(v, OP_IsNull, iReg);
|
sqlite3VdbeAddOp1(v, OP_IsNull, iReg); VdbeCoverage(v);
|
||||||
}else{
|
}else{
|
||||||
pLevel->u.in.nIn = 0;
|
pLevel->u.in.nIn = 0;
|
||||||
}
|
}
|
||||||
@@ -2502,11 +2502,11 @@ static int codeAllEqualityTerms(
|
|||||||
|
|
||||||
if( nSkip ){
|
if( nSkip ){
|
||||||
int iIdxCur = pLevel->iIdxCur;
|
int iIdxCur = pLevel->iIdxCur;
|
||||||
sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur);
|
sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur); VdbeCoverage(v);
|
||||||
VdbeComment((v, "begin skip-scan on %s", pIdx->zName));
|
VdbeComment((v, "begin skip-scan on %s", pIdx->zName));
|
||||||
j = sqlite3VdbeAddOp0(v, OP_Goto);
|
j = sqlite3VdbeAddOp0(v, OP_Goto);
|
||||||
pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT),
|
pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT),
|
||||||
iIdxCur, 0, regBase, nSkip);
|
iIdxCur, 0, regBase, nSkip); VdbeCoverage(v);
|
||||||
sqlite3VdbeJumpHere(v, j);
|
sqlite3VdbeJumpHere(v, j);
|
||||||
for(j=0; j<nSkip; j++){
|
for(j=0; j<nSkip; j++){
|
||||||
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, j, regBase+j);
|
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, j, regBase+j);
|
||||||
@@ -2787,6 +2787,7 @@ static Bitmask codeOneLoopStart(
|
|||||||
int regYield = pTabItem->regReturn;
|
int regYield = pTabItem->regReturn;
|
||||||
sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub);
|
sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub);
|
||||||
pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk);
|
pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk);
|
||||||
|
VdbeCoverage(v);
|
||||||
VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName));
|
VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName));
|
||||||
pLevel->op = OP_Goto;
|
pLevel->op = OP_Goto;
|
||||||
}else
|
}else
|
||||||
@@ -2819,6 +2820,7 @@ static Bitmask codeOneLoopStart(
|
|||||||
sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg,
|
sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg,
|
||||||
pLoop->u.vtab.idxStr,
|
pLoop->u.vtab.idxStr,
|
||||||
pLoop->u.vtab.needFree ? P4_MPRINTF : P4_STATIC);
|
pLoop->u.vtab.needFree ? P4_MPRINTF : P4_STATIC);
|
||||||
|
VdbeCoverage(v);
|
||||||
pLoop->u.vtab.needFree = 0;
|
pLoop->u.vtab.needFree = 0;
|
||||||
for(j=0; j<nConstraint && j<16; j++){
|
for(j=0; j<nConstraint && j<16; j++){
|
||||||
if( (pLoop->u.vtab.omitMask>>j)&1 ){
|
if( (pLoop->u.vtab.omitMask>>j)&1 ){
|
||||||
@@ -2850,8 +2852,9 @@ static Bitmask codeOneLoopStart(
|
|||||||
testcase( pTerm->wtFlags & TERM_VIRTUAL );
|
testcase( pTerm->wtFlags & TERM_VIRTUAL );
|
||||||
iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
|
iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
|
||||||
addrNxt = pLevel->addrNxt;
|
addrNxt = pLevel->addrNxt;
|
||||||
sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt);
|
sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt); VdbeCoverage(v);
|
||||||
sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg);
|
sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg);
|
||||||
|
VdbeCoverage(v);
|
||||||
sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1);
|
sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1);
|
||||||
sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
|
sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
|
||||||
VdbeComment((v, "pk"));
|
VdbeComment((v, "pk"));
|
||||||
@@ -2901,12 +2904,13 @@ static Bitmask codeOneLoopStart(
|
|||||||
testcase( pStart->leftCursor!=iCur ); /* transitive constraints */
|
testcase( pStart->leftCursor!=iCur ); /* transitive constraints */
|
||||||
r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
|
r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
|
||||||
sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1);
|
sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1);
|
||||||
VdbeComment((v, "pk"));
|
VdbeComment((v, "pk")); VdbeCoverage(v);
|
||||||
sqlite3ExprCacheAffinityChange(pParse, r1, 1);
|
sqlite3ExprCacheAffinityChange(pParse, r1, 1);
|
||||||
sqlite3ReleaseTempReg(pParse, rTemp);
|
sqlite3ReleaseTempReg(pParse, rTemp);
|
||||||
disableTerm(pLevel, pStart);
|
disableTerm(pLevel, pStart);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrBrk);
|
sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrBrk);
|
||||||
|
VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
if( pEnd ){
|
if( pEnd ){
|
||||||
Expr *pX;
|
Expr *pX;
|
||||||
@@ -2934,6 +2938,7 @@ static Bitmask codeOneLoopStart(
|
|||||||
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg);
|
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg);
|
||||||
sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
|
sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
|
||||||
sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg);
|
sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg);
|
||||||
|
VdbeCoverage(v);
|
||||||
sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL);
|
sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL);
|
||||||
}
|
}
|
||||||
}else if( pLoop->wsFlags & WHERE_INDEXED ){
|
}else if( pLoop->wsFlags & WHERE_INDEXED ){
|
||||||
@@ -3107,6 +3112,13 @@ static Bitmask codeOneLoopStart(
|
|||||||
testcase( op==OP_SeekLE );
|
testcase( op==OP_SeekLE );
|
||||||
testcase( op==OP_SeekLT );
|
testcase( op==OP_SeekLT );
|
||||||
sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
|
sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
|
||||||
|
VdbeCoverage(v);
|
||||||
|
VdbeCoverageIf(v, op==OP_Rewind);
|
||||||
|
VdbeCoverageIf(v, op==OP_Last);
|
||||||
|
VdbeCoverageIf(v, op==OP_SeekGT);
|
||||||
|
VdbeCoverageIf(v, op==OP_SeekGE);
|
||||||
|
VdbeCoverageIf(v, op==OP_SeekLE);
|
||||||
|
VdbeCoverageIf(v, op==OP_SeekLT);
|
||||||
|
|
||||||
/* Load the value for the inequality constraint at the end of the
|
/* Load the value for the inequality constraint at the end of the
|
||||||
** range (if any).
|
** range (if any).
|
||||||
@@ -3144,6 +3156,7 @@ static Bitmask codeOneLoopStart(
|
|||||||
testcase( op==OP_IdxLT );
|
testcase( op==OP_IdxLT );
|
||||||
testcase( op==OP_IdxLE );
|
testcase( op==OP_IdxLE );
|
||||||
sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
|
sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
|
||||||
|
VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Seek the table cursor, if required */
|
/* Seek the table cursor, if required */
|
||||||
@@ -3164,7 +3177,7 @@ static Bitmask codeOneLoopStart(
|
|||||||
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j);
|
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont,
|
sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont,
|
||||||
iRowidReg, pPk->nKeyCol);
|
iRowidReg, pPk->nKeyCol); VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Record the instruction used to terminate the loop. Disable
|
/* Record the instruction used to terminate the loop. Disable
|
||||||
@@ -3348,6 +3361,7 @@ static Bitmask codeOneLoopStart(
|
|||||||
regRowid, 0);
|
regRowid, 0);
|
||||||
sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset,
|
sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset,
|
||||||
sqlite3VdbeCurrentAddr(v)+2, r, iSet);
|
sqlite3VdbeCurrentAddr(v)+2, r, iSet);
|
||||||
|
VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody);
|
sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody);
|
||||||
|
|
||||||
@@ -3416,6 +3430,8 @@ static Bitmask codeOneLoopStart(
|
|||||||
pLevel->op = aStep[bRev];
|
pLevel->op = aStep[bRev];
|
||||||
pLevel->p1 = iCur;
|
pLevel->p1 = iCur;
|
||||||
pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
|
pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
|
||||||
|
VdbeCoverageIf(v, bRev);
|
||||||
|
VdbeCoverageIf(v, !bRev);
|
||||||
pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
|
pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5785,6 +5801,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
|||||||
if( pLevel->op!=OP_Noop ){
|
if( pLevel->op!=OP_Noop ){
|
||||||
sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3);
|
sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3);
|
||||||
sqlite3VdbeChangeP5(v, pLevel->p5);
|
sqlite3VdbeChangeP5(v, pLevel->p5);
|
||||||
|
VdbeCoverage(v);
|
||||||
}
|
}
|
||||||
if( pLoop->wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){
|
if( pLoop->wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){
|
||||||
struct InLoop *pIn;
|
struct InLoop *pIn;
|
||||||
@@ -5793,6 +5810,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
|||||||
for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){
|
for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){
|
||||||
sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
|
sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
|
||||||
sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop);
|
sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop);
|
||||||
|
VdbeCoverage(v);
|
||||||
sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
|
sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
|
||||||
}
|
}
|
||||||
sqlite3DbFree(db, pLevel->u.in.aInLoop);
|
sqlite3DbFree(db, pLevel->u.in.aInLoop);
|
||||||
@@ -5805,7 +5823,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
|||||||
sqlite3VdbeJumpHere(v, pLevel->addrSkip-2);
|
sqlite3VdbeJumpHere(v, pLevel->addrSkip-2);
|
||||||
}
|
}
|
||||||
if( pLevel->iLeftJoin ){
|
if( pLevel->iLeftJoin ){
|
||||||
addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin);
|
addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v);
|
||||||
assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
|
assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
|
||||||
|| (pLoop->wsFlags & WHERE_INDEXED)!=0 );
|
|| (pLoop->wsFlags & WHERE_INDEXED)!=0 );
|
||||||
if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 ){
|
if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 ){
|
||||||
|
Reference in New Issue
Block a user