mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Refactoring the VM. The P3 parameter is changed to P4. A P5 parameter is
added (though not currently used.) Add routines sqlite3VdbeAddOpX() where X is one of 0, 1, 2, 3, or 4. (CVS 4660) FossilOrigin-Name: 027875e4d4c4bd7686dc880c6917a968049b2fec
This commit is contained in:
52
manifest
52
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Add\soperands\sp4\sand\sp5\sto\sthe\sVdbeOp\sstructure.\s(CVS\s4659)
|
C Refactoring\sthe\sVM.\s\sThe\sP3\sparameter\sis\schanged\sto\sP4.\s\sA\sP5\sparameter\sis\nadded\s(though\snot\scurrently\sused.)\s\sAdd\sroutines\ssqlite3VdbeAddOpX()\swhere\nX\sis\sone\sof\s0,\s1,\s2,\s3,\sor\s4.\s(CVS\s4660)
|
||||||
D 2008-01-02T17:25:55
|
D 2008-01-03T00:01:24
|
||||||
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
||||||
F Makefile.in 30789bf70614bad659351660d76b8e533f3340e9
|
F Makefile.in 30789bf70614bad659351660d76b8e533f3340e9
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@@ -78,25 +78,25 @@ F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2
|
|||||||
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
|
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
|
||||||
F sqlite3.def a96c1d0d39362b763d2ddba220a32da41a15c4b4
|
F sqlite3.def a96c1d0d39362b763d2ddba220a32da41a15c4b4
|
||||||
F sqlite3.pc.in abed4664817e1cd500f2276142c71958087c16bc
|
F sqlite3.pc.in abed4664817e1cd500f2276142c71958087c16bc
|
||||||
F src/alter.c 23d18ec53ef27fcb5e5ae9ca050217231ae15a0d
|
F src/alter.c b58ed3becc77885e2aec6754c689255534f2734c
|
||||||
F src/analyze.c 40806c79cf2cd4fd0f6396d3d283fa05711439d1
|
F src/analyze.c 09e55b6bd3fe6a05fac7f471d21da344e9a0a92b
|
||||||
F src/attach.c 95658e74e3e0d1cbdb8658817516d4d1467fc13d
|
F src/attach.c 4b214b411237531491e1186211e005e4de73630d
|
||||||
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
|
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
|
||||||
F src/btmutex.c 5d39da37c9d1282f3c6f9967afae6a34ee36b7ff
|
F src/btmutex.c 5d39da37c9d1282f3c6f9967afae6a34ee36b7ff
|
||||||
F src/btree.c 5164b32950cfd41f2c5c31e8ff82c4a499918aef
|
F src/btree.c 5164b32950cfd41f2c5c31e8ff82c4a499918aef
|
||||||
F src/btree.h 19dcf5ad23c17b98855da548e9a8e3eb4429d5eb
|
F src/btree.h 19dcf5ad23c17b98855da548e9a8e3eb4429d5eb
|
||||||
F src/btreeInt.h 1c5a9da165718ef7de81e35ce9ab5d9ba9283f76
|
F src/btreeInt.h 1c5a9da165718ef7de81e35ce9ab5d9ba9283f76
|
||||||
F src/build.c 640c2a2a22baa16622c0aa74ae948a3643c1d6d6
|
F src/build.c 043c36a387e5bb73b14209b7a0cfeb1f7892d3a2
|
||||||
F src/callback.c 77b302b0d41468dcda78c70e706e5b84577f0fa0
|
F src/callback.c 77b302b0d41468dcda78c70e706e5b84577f0fa0
|
||||||
F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131
|
F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131
|
||||||
F src/date.c 49c5a6d2de6c12000905b4d36868b07d3011bbf6
|
F src/date.c 49c5a6d2de6c12000905b4d36868b07d3011bbf6
|
||||||
F src/delete.c 0114a9582305e2348bed4bc94ffa3e603da489ff
|
F src/delete.c 4d3e382146a1753b7de27c0554fc366cffef8b16
|
||||||
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
|
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
|
||||||
F src/expr.c c5c784ffdd8e55d6e9730fbaebe482a34136ab60
|
F src/expr.c 4bfb33eeef12c373ecf477aef199ec9e114b09dc
|
||||||
F src/func.c 996071cf0af9d967e58b69fce1909555059ebc7d
|
F src/func.c 996071cf0af9d967e58b69fce1909555059ebc7d
|
||||||
F src/hash.c 45a7005aac044b6c86bd7e49c44bc15d30006d6c
|
F src/hash.c 45a7005aac044b6c86bd7e49c44bc15d30006d6c
|
||||||
F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53
|
F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53
|
||||||
F src/insert.c 5b8061104f91f74f96427e7b7962ed623ccf73df
|
F src/insert.c 6c8bbffdfaf74dfd558dafe6109a4d17533502a8
|
||||||
F src/journal.c 807bed7a158979ac8d63953e1774e8d85bff65e2
|
F src/journal.c 807bed7a158979ac8d63953e1774e8d85bff65e2
|
||||||
F src/legacy.c 4ac53191fad2e3c4d59bde1228879b2dc5a96d66
|
F src/legacy.c 4ac53191fad2e3c4d59bde1228879b2dc5a96d66
|
||||||
F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35
|
F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35
|
||||||
@@ -127,16 +127,16 @@ F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
|||||||
F src/pager.c 0cb6ccea4b9615627d61d7c4417cedc45776d429
|
F src/pager.c 0cb6ccea4b9615627d61d7c4417cedc45776d429
|
||||||
F src/pager.h f504f7ae84060fee0416a853e368d3d113c3d6fa
|
F src/pager.h f504f7ae84060fee0416a853e368d3d113c3d6fa
|
||||||
F src/parse.y 2ae06e8d3190faace49c5b82e7cea1fc60d084a1
|
F src/parse.y 2ae06e8d3190faace49c5b82e7cea1fc60d084a1
|
||||||
F src/pragma.c 4a7f377a509eb14e35b09d4bf7b808ef647aad0b
|
F src/pragma.c 036e49b88c4f5079a8d9d536a7cc2928583f163f
|
||||||
F src/prepare.c 7aeba7851773fbe3950a26b35d3389bef0eb1c62
|
F src/prepare.c 31ce0903040ec6f71da10c74869e10137890d981
|
||||||
F src/printf.c eb27822ba2eec669161409ca31279a24c26ac910
|
F src/printf.c eb27822ba2eec669161409ca31279a24c26ac910
|
||||||
F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da
|
F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da
|
||||||
F src/select.c cc4064f931c32139f97b43572180a99eff08e759
|
F src/select.c fb57c9f49f5a117a1680dd4dd517e1e8631baf68
|
||||||
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
||||||
F src/shell.c 77895a54c2082157e169c857a2e244525ec25af7
|
F src/shell.c 77895a54c2082157e169c857a2e244525ec25af7
|
||||||
F src/sqlite.h.in 2a7e3776534bbe6ff2cdc058f3abebe91e7e429f
|
F src/sqlite.h.in 2a7e3776534bbe6ff2cdc058f3abebe91e7e429f
|
||||||
F src/sqlite3ext.h a93f59cdee3638dc0c9c086f80df743a4e68c3cb
|
F src/sqlite3ext.h a93f59cdee3638dc0c9c086f80df743a4e68c3cb
|
||||||
F src/sqliteInt.h dc0f9180d4aa50fce261d7ae7387952e02752165
|
F src/sqliteInt.h 2e30ff7e6ee65743d38447f00ef873ce058be7be
|
||||||
F src/sqliteLimit.h ee4430f88f69bf63527967bb35ca52af7b0ccb1e
|
F src/sqliteLimit.h ee4430f88f69bf63527967bb35ca52af7b0ccb1e
|
||||||
F src/table.c 1aeb9eab57b4235db86fe15a35dec76fb445a9c4
|
F src/table.c 1aeb9eab57b4235db86fe15a35dec76fb445a9c4
|
||||||
F src/tclsqlite.c 9923abeffc9b3d7dad58e92b319661521f60debf
|
F src/tclsqlite.c 9923abeffc9b3d7dad58e92b319661521f60debf
|
||||||
@@ -157,27 +157,27 @@ F src/test_hexio.c 1a1cd8324d57585ea86b922f609fa1fbaaf9662d
|
|||||||
F src/test_loadext.c 22065d601a18878e5542191001f0eaa5d77c0ed8
|
F src/test_loadext.c 22065d601a18878e5542191001f0eaa5d77c0ed8
|
||||||
F src/test_malloc.c 72ceed192f7b229db34a2869ff9285b41a5cb796
|
F src/test_malloc.c 72ceed192f7b229db34a2869ff9285b41a5cb796
|
||||||
F src/test_md5.c c107c96637123239c3518b5fbe97a79130f4d32e
|
F src/test_md5.c c107c96637123239c3518b5fbe97a79130f4d32e
|
||||||
F src/test_onefile.c d877baba46837587345933376c00c656f58d6fb6
|
F src/test_onefile.c 54282b6796d55d7acc489be83b89b8715e7d3756
|
||||||
F src/test_schema.c 12c9de7661d6294eec2d57afbb52e2af1128084f
|
F src/test_schema.c 12c9de7661d6294eec2d57afbb52e2af1128084f
|
||||||
F src/test_server.c a6ece6c835e7eae835054124e09e947e422b1ac5
|
F src/test_server.c a6ece6c835e7eae835054124e09e947e422b1ac5
|
||||||
F src/test_tclvar.c b2d1115e4d489179d3f029e765211b2ad527ba59
|
F src/test_tclvar.c b2d1115e4d489179d3f029e765211b2ad527ba59
|
||||||
F src/test_thread.c e297dd41db0b249646e69f97d36ec13e56e8b730
|
F src/test_thread.c e297dd41db0b249646e69f97d36ec13e56e8b730
|
||||||
F src/tokenize.c a4e04438c11fed2c67ec47fe3edbef9cca2d1b48
|
F src/tokenize.c a4e04438c11fed2c67ec47fe3edbef9cca2d1b48
|
||||||
F src/trigger.c 907b819d87eb3a15d1372ecd81e4ca969f5bcf1a
|
F src/trigger.c 3267e5d6e3c1e8b688db5844278d71acc0f00996
|
||||||
F src/update.c 608ecf1f508442d8b05cc258a0573e6fe3573b8b
|
F src/update.c 39ac597c81b1d7d0396d5571d620bfa694f21151
|
||||||
F src/utf.c ef4b7d83bae533b76c3e1bf635b113fdad86a736
|
F src/utf.c ef4b7d83bae533b76c3e1bf635b113fdad86a736
|
||||||
F src/util.c 05f31144bbd3f1a24f4139ae029c42545cb72624
|
F src/util.c 05f31144bbd3f1a24f4139ae029c42545cb72624
|
||||||
F src/vacuum.c 25ffbd766f25bca099ead1c1e11f5528c86102b8
|
F src/vacuum.c 3f34f278809bf3eb0b62ec46ff779e9c385b28f0
|
||||||
F src/vdbe.c 85e44649ad750d4c249751693ca93b4f57737b0f
|
F src/vdbe.c fd5f6fc98eda1c1664cb1bfd09479ec3fb642139
|
||||||
F src/vdbe.h 5c9ed634212361091bfc92ca689374d211f384b7
|
F src/vdbe.h c50dd0ad14ae4a2cc0b69f61263dcc732274d231
|
||||||
F src/vdbeInt.h 2985f1369273e635898cf5952237efcb3fdb21f3
|
F src/vdbeInt.h 2985f1369273e635898cf5952237efcb3fdb21f3
|
||||||
F src/vdbeapi.c 4acfaab3e10c99eb66c5332979d7b14a1c3505ae
|
F src/vdbeapi.c bf615ff2cf2b121f1609cbadd4f52720289733b5
|
||||||
F src/vdbeaux.c 9c2ce05e86502ac3dd148ed13535886e82678e04
|
F src/vdbeaux.c 5601e73eaf893c14effb0b2fd921128b605d83c3
|
||||||
F src/vdbeblob.c 82f51cdf9b0c0af729732fde48c824e498c0a1ca
|
F src/vdbeblob.c 82f51cdf9b0c0af729732fde48c824e498c0a1ca
|
||||||
F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6
|
F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6
|
||||||
F src/vdbemem.c 123994fcd344993d2fb050a83b91b341bbbd08b4
|
F src/vdbemem.c 123994fcd344993d2fb050a83b91b341bbbd08b4
|
||||||
F src/vtab.c f819d55ef638d45e09ce00009d435da8bf16f528
|
F src/vtab.c 03014b2bfa8096ecac5fcdc80d34cd76e06af52a
|
||||||
F src/where.c 49901aac9ad568c9c92f914150e91c1663f3978d
|
F src/where.c 09edd04e2c6eeb6dcb6f634eef4a1d062d103988
|
||||||
F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617
|
F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617
|
||||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||||
F test/all.test ee350b9ab15b175fc0a8fb51bf2141ed3a3b9cba
|
F test/all.test ee350b9ab15b175fc0a8fb51bf2141ed3a3b9cba
|
||||||
@@ -603,7 +603,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
|
|||||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||||
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
||||||
P fbd17a8976cc9b4dd7c7c903d8beade9a7ef095f
|
P ad528735e41ce2ec2e680b12e562d4ddb6650985
|
||||||
R 959deef8458a4ade4a9b18649b5cc232
|
R ace653b10b899d3bff1e4800e5ac3a83
|
||||||
U drh
|
U drh
|
||||||
Z 63670bfa755df999b8dac508860cddb8
|
Z fe84d7f6c2377b705fae1be2a7ddde3c
|
||||||
|
@@ -1 +1 @@
|
|||||||
ad528735e41ce2ec2e680b12e562d4ddb6650985
|
027875e4d4c4bd7686dc880c6917a968049b2fec
|
14
src/alter.c
14
src/alter.c
@@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that used to generate VDBE code
|
** This file contains C code routines that used to generate VDBE code
|
||||||
** that implements the ALTER TABLE command.
|
** that implements the ALTER TABLE command.
|
||||||
**
|
**
|
||||||
** $Id: alter.c,v 1.35 2007/12/13 21:54:11 drh Exp $
|
** $Id: alter.c,v 1.36 2008/01/03 00:01:24 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -243,24 +243,24 @@ static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){
|
|||||||
for(pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext){
|
for(pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext){
|
||||||
int iTrigDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
|
int iTrigDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
|
||||||
assert( iTrigDb==iDb || iTrigDb==1 );
|
assert( iTrigDb==iDb || iTrigDb==1 );
|
||||||
sqlite3VdbeOp3(v, OP_DropTrigger, iTrigDb, 0, pTrig->name, 0);
|
sqlite3VdbeAddOp4(v, OP_DropTrigger, iTrigDb, 0, 0, pTrig->name, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Drop the table and index from the internal schema */
|
/* Drop the table and index from the internal schema */
|
||||||
sqlite3VdbeOp3(v, OP_DropTable, iDb, 0, pTab->zName, 0);
|
sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);
|
||||||
|
|
||||||
/* Reload the table, index and permanent trigger schemas. */
|
/* Reload the table, index and permanent trigger schemas. */
|
||||||
zWhere = sqlite3MPrintf(pParse->db, "tbl_name=%Q", zName);
|
zWhere = sqlite3MPrintf(pParse->db, "tbl_name=%Q", zName);
|
||||||
if( !zWhere ) return;
|
if( !zWhere ) return;
|
||||||
sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, zWhere, P3_DYNAMIC);
|
sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC);
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_TRIGGER
|
#ifndef SQLITE_OMIT_TRIGGER
|
||||||
/* Now, if the table is not stored in the temp database, reload any temp
|
/* Now, if the table is not stored in the temp database, reload any temp
|
||||||
** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined.
|
** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined.
|
||||||
*/
|
*/
|
||||||
if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
|
if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
|
||||||
sqlite3VdbeOp3(v, OP_ParseSchema, 1, 0, zWhere, P3_DYNAMIC);
|
sqlite3VdbeAddOp4(v, OP_ParseSchema, 1, 0, 0, zWhere, P4_DYNAMIC);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -362,8 +362,8 @@ void sqlite3AlterRenameTable(
|
|||||||
*/
|
*/
|
||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
if( isVirtualRename ){
|
if( isVirtualRename ){
|
||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, zName, 0);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, zName, 0);
|
||||||
sqlite3VdbeOp3(v, OP_VRename, 0, 0, (const char*)pTab->pVtab, P3_VTAB);
|
sqlite3VdbeAddOp4(v, OP_VRename, 0, 0, 0,(const char*)pTab->pVtab, P4_VTAB);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** This file contains code associated with the ANALYZE command.
|
** This file contains code associated with the ANALYZE command.
|
||||||
**
|
**
|
||||||
** @(#) $Id: analyze.c,v 1.26 2008/01/02 14:28:13 drh Exp $
|
** @(#) $Id: analyze.c,v 1.27 2008/01/03 00:01:24 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef SQLITE_OMIT_ANALYZE
|
#ifndef SQLITE_OMIT_ANALYZE
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
@@ -61,7 +61,7 @@ static void openStatTable(
|
|||||||
}else{
|
}else{
|
||||||
/* The sqlite_stat1 table already exists. Delete all rows. */
|
/* The sqlite_stat1 table already exists. Delete all rows. */
|
||||||
iRootPage = pStat->tnum;
|
iRootPage = pStat->tnum;
|
||||||
sqlite3VdbeAddOp(v, OP_Clear, pStat->tnum, iDb);
|
sqlite3VdbeAddOp2(v, OP_Clear, pStat->tnum, iDb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open the sqlite_stat1 table for writing. Unless it was created
|
/* Open the sqlite_stat1 table for writing. Unless it was created
|
||||||
@@ -72,9 +72,9 @@ static void openStatTable(
|
|||||||
if( iRootPage>0 ){
|
if( iRootPage>0 ){
|
||||||
sqlite3TableLock(pParse, iDb, iRootPage, 1, "sqlite_stat1");
|
sqlite3TableLock(pParse, iDb, iRootPage, 1, "sqlite_stat1");
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
|
sqlite3VdbeAddOp1(v, OP_Integer, iDb);
|
||||||
sqlite3VdbeAddOp(v, OP_OpenWrite, iStatCur, iRootPage);
|
sqlite3VdbeAddOp2(v, OP_OpenWrite, iStatCur, iRootPage);
|
||||||
sqlite3VdbeAddOp(v, OP_SetNumColumns, iStatCur, 3);
|
sqlite3VdbeAddOp2(v, OP_SetNumColumns, iStatCur, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -122,15 +122,15 @@ static void analyzeOneTable(
|
|||||||
/* Open a cursor to the index to be analyzed
|
/* Open a cursor to the index to be analyzed
|
||||||
*/
|
*/
|
||||||
assert( iDb==sqlite3SchemaToIndex(pParse->db, pIdx->pSchema) );
|
assert( iDb==sqlite3SchemaToIndex(pParse->db, pIdx->pSchema) );
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
|
sqlite3VdbeAddOp1(v, OP_Integer, iDb);
|
||||||
VdbeComment((v, "%s", pIdx->zName));
|
VdbeComment((v, "%s", pIdx->zName));
|
||||||
sqlite3VdbeOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum,
|
sqlite3VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIdx->tnum, 0,
|
||||||
(char *)pKey, P3_KEYINFO_HANDOFF);
|
(char *)pKey, P4_KEYINFO_HANDOFF);
|
||||||
nCol = pIdx->nColumn;
|
nCol = pIdx->nColumn;
|
||||||
if( iMem+nCol*2>=pParse->nMem ){
|
if( iMem+nCol*2>=pParse->nMem ){
|
||||||
pParse->nMem = iMem+nCol*2+1;
|
pParse->nMem = iMem+nCol*2+1;
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_SetNumColumns, iIdxCur, nCol+1);
|
sqlite3VdbeAddOp2(v, OP_SetNumColumns, iIdxCur, nCol+1);
|
||||||
|
|
||||||
/* Memory cells are used as follows:
|
/* Memory cells are used as follows:
|
||||||
**
|
**
|
||||||
@@ -146,33 +146,33 @@ static void analyzeOneTable(
|
|||||||
** are initialized to NULL.
|
** are initialized to NULL.
|
||||||
*/
|
*/
|
||||||
for(i=0; i<=nCol; i++){
|
for(i=0; i<=nCol; i++){
|
||||||
sqlite3VdbeAddOp(v, OP_MemInt, 0, iMem+i);
|
sqlite3VdbeAddOp2(v, OP_MemInt, 0, iMem+i);
|
||||||
}
|
}
|
||||||
for(i=0; i<nCol; i++){
|
for(i=0; i<nCol; i++){
|
||||||
sqlite3VdbeAddOp(v, OP_MemNull, 0, iMem+nCol+i+1);
|
sqlite3VdbeAddOp2(v, OP_MemNull, 0, iMem+nCol+i+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do the analysis.
|
/* Do the analysis.
|
||||||
*/
|
*/
|
||||||
endOfLoop = sqlite3VdbeMakeLabel(v);
|
endOfLoop = sqlite3VdbeMakeLabel(v);
|
||||||
sqlite3VdbeAddOp(v, OP_Rewind, iIdxCur, endOfLoop);
|
sqlite3VdbeAddOp2(v, OP_Rewind, iIdxCur, endOfLoop);
|
||||||
topOfLoop = sqlite3VdbeCurrentAddr(v);
|
topOfLoop = sqlite3VdbeCurrentAddr(v);
|
||||||
sqlite3VdbeAddOp(v, OP_MemIncr, 1, iMem);
|
sqlite3VdbeAddOp2(v, OP_MemIncr, 1, iMem);
|
||||||
for(i=0; i<nCol; i++){
|
for(i=0; i<nCol; i++){
|
||||||
sqlite3VdbeAddOp(v, OP_Column, iIdxCur, i);
|
sqlite3VdbeAddOp2(v, OP_Column, iIdxCur, i);
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, iMem+nCol+i+1, 0);
|
sqlite3VdbeAddOp1(v, OP_MemLoad, iMem+nCol+i+1);
|
||||||
sqlite3VdbeAddOp(v, OP_Ne, 0x100, 0);
|
sqlite3VdbeAddOp1(v, OP_Ne, 0x100);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, endOfLoop);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, endOfLoop);
|
||||||
for(i=0; i<nCol; i++){
|
for(i=0; i<nCol; i++){
|
||||||
addr = sqlite3VdbeAddOp(v, OP_MemIncr, 1, iMem+i+1);
|
addr = sqlite3VdbeAddOp2(v, OP_MemIncr, 1, iMem+i+1);
|
||||||
sqlite3VdbeChangeP2(v, topOfLoop + 3*i + 3, addr);
|
sqlite3VdbeChangeP2(v, topOfLoop + 3*i + 3, addr);
|
||||||
sqlite3VdbeAddOp(v, OP_Column, iIdxCur, i);
|
sqlite3VdbeAddOp2(v, OP_Column, iIdxCur, i);
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, iMem+nCol+i+1, 1);
|
sqlite3VdbeAddOp2(v, OP_MemStore, iMem+nCol+i+1, 1);
|
||||||
}
|
}
|
||||||
sqlite3VdbeResolveLabel(v, endOfLoop);
|
sqlite3VdbeResolveLabel(v, endOfLoop);
|
||||||
sqlite3VdbeAddOp(v, OP_Next, iIdxCur, topOfLoop);
|
sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, topOfLoop);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, iIdxCur, 0);
|
sqlite3VdbeAddOp1(v, OP_Close, iIdxCur);
|
||||||
|
|
||||||
/* Store the results.
|
/* Store the results.
|
||||||
**
|
**
|
||||||
@@ -192,29 +192,29 @@ static void analyzeOneTable(
|
|||||||
** If K>0 then it is always the case the D>0 so division by zero
|
** If K>0 then it is always the case the D>0 so division by zero
|
||||||
** is never possible.
|
** is never possible.
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, iMem, 0);
|
sqlite3VdbeAddOp1(v, OP_MemLoad, iMem);
|
||||||
addr = sqlite3VdbeAddOp(v, OP_IfNot, 0, 0);
|
addr = sqlite3VdbeAddOp0(v, OP_IfNot);
|
||||||
sqlite3VdbeAddOp(v, OP_NewRowid, iStatCur, 0);
|
sqlite3VdbeAddOp1(v, OP_NewRowid, iStatCur);
|
||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0);
|
||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, pIdx->zName, 0);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pIdx->zName, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, iMem, 0);
|
sqlite3VdbeAddOp1(v, OP_MemLoad, iMem);
|
||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, " ", 0);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, " ", 0);
|
||||||
for(i=0; i<nCol; i++){
|
for(i=0; i<nCol; i++){
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, iMem, 0);
|
sqlite3VdbeAddOp1(v, OP_MemLoad, iMem);
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, iMem+i+1, 0);
|
sqlite3VdbeAddOp1(v, OP_MemLoad, iMem+i+1);
|
||||||
sqlite3VdbeAddOp(v, OP_Add, 0, 0);
|
sqlite3VdbeAddOp0(v, OP_Add);
|
||||||
sqlite3VdbeAddOp(v, OP_AddImm, -1, 0);
|
sqlite3VdbeAddOp1(v, OP_AddImm, -1);
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, iMem+i+1, 0);
|
sqlite3VdbeAddOp1(v, OP_MemLoad, iMem+i+1);
|
||||||
sqlite3VdbeAddOp(v, OP_Divide, 0, 0);
|
sqlite3VdbeAddOp0(v, OP_Divide);
|
||||||
sqlite3VdbeAddOp(v, OP_ToInt, 0, 0);
|
sqlite3VdbeAddOp0(v, OP_ToInt);
|
||||||
if( i==nCol-1 ){
|
if( i==nCol-1 ){
|
||||||
sqlite3VdbeAddOp(v, OP_Concat, nCol*2-1, 0);
|
sqlite3VdbeAddOp1(v, OP_Concat, nCol*2-1);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
|
sqlite3VdbeAddOp1(v, OP_Dup, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3VdbeOp3(v, OP_MakeRecord, 3, 0, "aaa", 0);
|
sqlite3VdbeAddOp4(v, OP_MakeRecord, 3, 0, 0, "aaa", 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Insert, iStatCur, OPFLAG_APPEND);
|
sqlite3VdbeAddOp2(v, OP_Insert, iStatCur, OPFLAG_APPEND);
|
||||||
sqlite3VdbeJumpHere(v, addr);
|
sqlite3VdbeJumpHere(v, addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -226,7 +226,7 @@ static void analyzeOneTable(
|
|||||||
static void loadAnalysis(Parse *pParse, int iDb){
|
static void loadAnalysis(Parse *pParse, int iDb){
|
||||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||||
if( v ){
|
if( v ){
|
||||||
sqlite3VdbeAddOp(v, OP_LoadAnalysis, iDb, 0);
|
sqlite3VdbeAddOp1(v, OP_LoadAnalysis, iDb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** This file contains code used to implement the ATTACH and DETACH commands.
|
** This file contains code used to implement the ATTACH and DETACH commands.
|
||||||
**
|
**
|
||||||
** $Id: attach.c,v 1.64 2007/12/27 15:12:17 danielk1977 Exp $
|
** $Id: attach.c,v 1.65 2008/01/03 00:01:24 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -332,15 +332,15 @@ static void codeAttach(
|
|||||||
|
|
||||||
assert( v || db->mallocFailed );
|
assert( v || db->mallocFailed );
|
||||||
if( v ){
|
if( v ){
|
||||||
sqlite3VdbeAddOp(v, OP_Function, 0, nFunc);
|
sqlite3VdbeAddOp2(v, OP_Function, 0, nFunc);
|
||||||
pFunc = sqlite3FindFunction(db, zFunc, strlen(zFunc), nFunc, SQLITE_UTF8,0);
|
pFunc = sqlite3FindFunction(db, zFunc, strlen(zFunc), nFunc, SQLITE_UTF8,0);
|
||||||
sqlite3VdbeChangeP3(v, -1, (char *)pFunc, P3_FUNCDEF);
|
sqlite3VdbeChangeP4(v, -1, (char *)pFunc, P4_FUNCDEF);
|
||||||
|
|
||||||
/* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this
|
/* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this
|
||||||
** statement only). For DETACH, set it to false (expire all existing
|
** statement only). For DETACH, set it to false (expire all existing
|
||||||
** statements).
|
** statements).
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp(v, OP_Expire, (type==SQLITE_ATTACH), 0);
|
sqlite3VdbeAddOp1(v, OP_Expire, (type==SQLITE_ATTACH));
|
||||||
}
|
}
|
||||||
|
|
||||||
attach_end:
|
attach_end:
|
||||||
|
146
src/build.c
146
src/build.c
@@ -22,7 +22,7 @@
|
|||||||
** COMMIT
|
** COMMIT
|
||||||
** ROLLBACK
|
** ROLLBACK
|
||||||
**
|
**
|
||||||
** $Id: build.c,v 1.452 2008/01/02 16:27:10 danielk1977 Exp $
|
** $Id: build.c,v 1.453 2008/01/03 00:01:24 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -114,7 +114,7 @@ static void codeTableLocks(Parse *pParse){
|
|||||||
if( p->isWriteLock ){
|
if( p->isWriteLock ){
|
||||||
p1 = -1*(p1+1);
|
p1 = -1*(p1+1);
|
||||||
}
|
}
|
||||||
sqlite3VdbeOp3(pVdbe, OP_TableLock, p1, p->iTab, p->zName, P3_STATIC);
|
sqlite3VdbeAddOp4(pVdbe, OP_TableLock, p1, p->iTab, 0, p->zName, P4_STATIC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@@ -150,7 +150,7 @@ void sqlite3FinishCoding(Parse *pParse){
|
|||||||
*/
|
*/
|
||||||
v = sqlite3GetVdbe(pParse);
|
v = sqlite3GetVdbe(pParse);
|
||||||
if( v ){
|
if( v ){
|
||||||
sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
|
sqlite3VdbeAddOp0(v, OP_Halt);
|
||||||
|
|
||||||
/* The cookie mask contains one bit for each database file open.
|
/* The cookie mask contains one bit for each database file open.
|
||||||
** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are
|
** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are
|
||||||
@@ -165,13 +165,13 @@ void sqlite3FinishCoding(Parse *pParse){
|
|||||||
for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){
|
for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){
|
||||||
if( (mask & pParse->cookieMask)==0 ) continue;
|
if( (mask & pParse->cookieMask)==0 ) continue;
|
||||||
sqlite3VdbeUsesBtree(v, iDb);
|
sqlite3VdbeUsesBtree(v, iDb);
|
||||||
sqlite3VdbeAddOp(v, OP_Transaction, iDb, (mask & pParse->writeMask)!=0);
|
sqlite3VdbeAddOp2(v,OP_Transaction, iDb, (mask & pParse->writeMask)!=0);
|
||||||
sqlite3VdbeAddOp(v, OP_VerifyCookie, iDb, pParse->cookieValue[iDb]);
|
sqlite3VdbeAddOp2(v,OP_VerifyCookie, iDb, pParse->cookieValue[iDb]);
|
||||||
}
|
}
|
||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
if( pParse->pVirtualLock ){
|
if( pParse->pVirtualLock ){
|
||||||
char *vtab = (char *)pParse->pVirtualLock->pVtab;
|
char *vtab = (char *)pParse->pVirtualLock->pVtab;
|
||||||
sqlite3VdbeOp3(v, OP_VBegin, 0, 0, vtab, P3_VTAB);
|
sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -180,17 +180,18 @@ void sqlite3FinishCoding(Parse *pParse){
|
|||||||
** shared-cache feature is enabled.
|
** shared-cache feature is enabled.
|
||||||
*/
|
*/
|
||||||
codeTableLocks(pParse);
|
codeTableLocks(pParse);
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->cookieGoto);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, pParse->cookieGoto);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_TRACE
|
#ifndef SQLITE_OMIT_TRACE
|
||||||
/* Add a No-op that contains the complete text of the compiled SQL
|
/* Add a No-op that contains the complete text of the compiled SQL
|
||||||
** statement as its P3 argument. This does not change the functionality
|
** statement as its P4 argument. This does not change the functionality
|
||||||
** of the program.
|
** of the program.
|
||||||
**
|
**
|
||||||
** This is used to implement sqlite3_trace().
|
** This is used to implement sqlite3_trace().
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeOp3(v, OP_Noop, 0, 0, pParse->zSql, pParse->zTail-pParse->zSql);
|
sqlite3VdbeAddOp4(v, OP_Noop, 0, 0, 0,
|
||||||
|
pParse->zSql, pParse->zTail-pParse->zSql);
|
||||||
#endif /* SQLITE_OMIT_TRACE */
|
#endif /* SQLITE_OMIT_TRACE */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -599,9 +600,9 @@ char *sqlite3NameFromToken(sqlite3 *db, Token *pName){
|
|||||||
void sqlite3OpenMasterTable(Parse *p, int iDb){
|
void sqlite3OpenMasterTable(Parse *p, int iDb){
|
||||||
Vdbe *v = sqlite3GetVdbe(p);
|
Vdbe *v = sqlite3GetVdbe(p);
|
||||||
sqlite3TableLock(p, iDb, MASTER_ROOT, 1, SCHEMA_TABLE(iDb));
|
sqlite3TableLock(p, iDb, MASTER_ROOT, 1, SCHEMA_TABLE(iDb));
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
|
sqlite3VdbeAddOp1(v, OP_Integer, iDb);
|
||||||
sqlite3VdbeAddOp(v, OP_OpenWrite, 0, MASTER_ROOT);
|
sqlite3VdbeAddOp2(v, OP_OpenWrite, 0, MASTER_ROOT);
|
||||||
sqlite3VdbeAddOp(v, OP_SetNumColumns, 0, 5); /* sqlite_master has 5 columns */
|
sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, 5); /* sqlite_master has 5 columns */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -844,23 +845,23 @@ void sqlite3StartTable(
|
|||||||
|
|
||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
if( isVirtual ){
|
if( isVirtual ){
|
||||||
sqlite3VdbeAddOp(v, OP_VBegin, 0, 0);
|
sqlite3VdbeAddOp0(v, OP_VBegin);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If the file format and encoding in the database have not been set,
|
/* If the file format and encoding in the database have not been set,
|
||||||
** set them now.
|
** set them now.
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1); /* file_format */
|
sqlite3VdbeAddOp2(v, OP_ReadCookie, iDb, 1); /* file_format */
|
||||||
sqlite3VdbeUsesBtree(v, iDb);
|
sqlite3VdbeUsesBtree(v, iDb);
|
||||||
lbl = sqlite3VdbeMakeLabel(v);
|
lbl = sqlite3VdbeMakeLabel(v);
|
||||||
sqlite3VdbeAddOp(v, OP_If, 0, lbl);
|
sqlite3VdbeAddOp2(v, OP_If, 0, lbl);
|
||||||
fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ?
|
fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ?
|
||||||
1 : SQLITE_MAX_FILE_FORMAT;
|
1 : SQLITE_MAX_FILE_FORMAT;
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, fileFormat, 0);
|
sqlite3VdbeAddOp1(v, OP_Integer, fileFormat);
|
||||||
sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1);
|
sqlite3VdbeAddOp2(v, OP_SetCookie, iDb, 1);
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, ENC(db), 0);
|
sqlite3VdbeAddOp1(v, OP_Integer, ENC(db));
|
||||||
sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 4);
|
sqlite3VdbeAddOp2(v, OP_SetCookie, iDb, 4);
|
||||||
sqlite3VdbeResolveLabel(v, lbl);
|
sqlite3VdbeResolveLabel(v, lbl);
|
||||||
|
|
||||||
/* This just creates a place-holder record in the sqlite_master table.
|
/* This just creates a place-holder record in the sqlite_master table.
|
||||||
@@ -873,19 +874,19 @@ void sqlite3StartTable(
|
|||||||
*/
|
*/
|
||||||
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
|
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
|
||||||
if( isView || isVirtual ){
|
if( isView || isVirtual ){
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
|
sqlite3VdbeAddOp0(v, OP_Integer);
|
||||||
}else
|
}else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
sqlite3VdbeAddOp(v, OP_CreateTable, iDb, 0);
|
sqlite3VdbeAddOp1(v, OP_CreateTable, iDb);
|
||||||
}
|
}
|
||||||
sqlite3OpenMasterTable(pParse, iDb);
|
sqlite3OpenMasterTable(pParse, iDb);
|
||||||
sqlite3VdbeAddOp(v, OP_NewRowid, 0, 0);
|
sqlite3VdbeAddOp0(v, OP_NewRowid);
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
|
sqlite3VdbeAddOp0(v, OP_Dup);
|
||||||
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
sqlite3VdbeAddOp0(v, OP_Null);
|
||||||
sqlite3VdbeAddOp(v, OP_Insert, 0, OPFLAG_APPEND);
|
sqlite3VdbeAddOp2(v, OP_Insert, 0, OPFLAG_APPEND);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, 0, 0);
|
sqlite3VdbeAddOp0(v, OP_Close);
|
||||||
sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
|
sqlite3VdbeAddOp1(v, OP_Pull, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Normal (non-error) return. */
|
/* Normal (non-error) return. */
|
||||||
@@ -1275,8 +1276,8 @@ CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName){
|
|||||||
** 1 chance in 2^32. So we're safe enough.
|
** 1 chance in 2^32. So we're safe enough.
|
||||||
*/
|
*/
|
||||||
void sqlite3ChangeCookie(sqlite3 *db, Vdbe *v, int iDb){
|
void sqlite3ChangeCookie(sqlite3 *db, Vdbe *v, int iDb){
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, db->aDb[iDb].pSchema->schema_cookie+1, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, db->aDb[iDb].pSchema->schema_cookie+1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 0);
|
sqlite3VdbeAddOp2(v, OP_SetCookie, iDb, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1459,7 +1460,7 @@ void sqlite3EndTable(
|
|||||||
v = sqlite3GetVdbe(pParse);
|
v = sqlite3GetVdbe(pParse);
|
||||||
if( v==0 ) return;
|
if( v==0 ) return;
|
||||||
|
|
||||||
sqlite3VdbeAddOp(v, OP_Close, 0, 0);
|
sqlite3VdbeAddOp1(v, OP_Close, 0);
|
||||||
|
|
||||||
/* Create the rootpage for the new table and push it onto the stack.
|
/* Create the rootpage for the new table and push it onto the stack.
|
||||||
** A view has no rootpage, so just push a zero onto the stack for
|
** A view has no rootpage, so just push a zero onto the stack for
|
||||||
@@ -1493,12 +1494,12 @@ void sqlite3EndTable(
|
|||||||
if( pSelect ){
|
if( pSelect ){
|
||||||
SelectDest dest = {SRT_Table, 1, 0};
|
SelectDest dest = {SRT_Table, 1, 0};
|
||||||
Table *pSelTab;
|
Table *pSelTab;
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
|
sqlite3VdbeAddOp1(v, OP_Dup, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
|
sqlite3VdbeAddOp1(v, OP_Integer, iDb);
|
||||||
sqlite3VdbeAddOp(v, OP_OpenWrite, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_OpenWrite, 1, 0);
|
||||||
pParse->nTab = 2;
|
pParse->nTab = 2;
|
||||||
sqlite3Select(pParse, pSelect, &dest, 0, 0, 0, 0);
|
sqlite3Select(pParse, pSelect, &dest, 0, 0, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, 1, 0);
|
sqlite3VdbeAddOp1(v, OP_Close, 1);
|
||||||
if( pParse->nErr==0 ){
|
if( pParse->nErr==0 ){
|
||||||
pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSelect);
|
pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSelect);
|
||||||
if( pSelTab==0 ) return;
|
if( pSelTab==0 ) return;
|
||||||
@@ -1556,8 +1557,8 @@ void sqlite3EndTable(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Reparse everything to update our internal data structures */
|
/* Reparse everything to update our internal data structures */
|
||||||
sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0,
|
sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0,
|
||||||
sqlite3MPrintf(db, "tbl_name='%q'",p->zName), P3_DYNAMIC);
|
sqlite3MPrintf(db, "tbl_name='%q'",p->zName), P4_DYNAMIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1833,7 +1834,7 @@ void sqlite3RootPageMoved(Db *pDb, int iFrom, int iTo){
|
|||||||
*/
|
*/
|
||||||
static void destroyRootPage(Parse *pParse, int iTable, int iDb){
|
static void destroyRootPage(Parse *pParse, int iTable, int iDb){
|
||||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||||
sqlite3VdbeAddOp(v, OP_Destroy, iTable, iDb);
|
sqlite3VdbeAddOp2(v, OP_Destroy, iTable, iDb);
|
||||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||||
/* OP_Destroy pushes an integer onto the stack. If this integer
|
/* OP_Destroy pushes an integer onto the stack. If this integer
|
||||||
** is non-zero, then it is the root page number of a table moved to
|
** is non-zero, then it is the root page number of a table moved to
|
||||||
@@ -2006,7 +2007,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
|
|||||||
if( IsVirtual(pTab) ){
|
if( IsVirtual(pTab) ){
|
||||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||||
if( v ){
|
if( v ){
|
||||||
sqlite3VdbeAddOp(v, OP_VBegin, 0, 0);
|
sqlite3VdbeAddOp0(v, OP_VBegin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -2055,9 +2056,9 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
|
|||||||
** the schema cookie.
|
** the schema cookie.
|
||||||
*/
|
*/
|
||||||
if( IsVirtual(pTab) ){
|
if( IsVirtual(pTab) ){
|
||||||
sqlite3VdbeOp3(v, OP_VDestroy, iDb, 0, pTab->zName, 0);
|
sqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0);
|
||||||
}
|
}
|
||||||
sqlite3VdbeOp3(v, OP_DropTable, iDb, 0, pTab->zName, 0);
|
sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);
|
||||||
sqlite3ChangeCookie(db, v, iDb);
|
sqlite3ChangeCookie(db, v, iDb);
|
||||||
}
|
}
|
||||||
sqliteViewResetAll(db, iDb);
|
sqliteViewResetAll(db, iDb);
|
||||||
@@ -2236,34 +2237,35 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
|
|||||||
v = sqlite3GetVdbe(pParse);
|
v = sqlite3GetVdbe(pParse);
|
||||||
if( v==0 ) return;
|
if( v==0 ) return;
|
||||||
if( memRootPage>=0 ){
|
if( memRootPage>=0 ){
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, memRootPage, 0);
|
sqlite3VdbeAddOp1(v, OP_MemLoad, memRootPage);
|
||||||
tnum = 0;
|
tnum = 0;
|
||||||
}else{
|
}else{
|
||||||
tnum = pIndex->tnum;
|
tnum = pIndex->tnum;
|
||||||
sqlite3VdbeAddOp(v, OP_Clear, tnum, iDb);
|
sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
|
sqlite3VdbeAddOp1(v, OP_Integer, iDb);
|
||||||
pKey = sqlite3IndexKeyinfo(pParse, pIndex);
|
pKey = sqlite3IndexKeyinfo(pParse, pIndex);
|
||||||
sqlite3VdbeOp3(v, OP_OpenWrite, iIdx, tnum, (char *)pKey, P3_KEYINFO_HANDOFF);
|
sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, 0,
|
||||||
|
(char *)pKey, P4_KEYINFO_HANDOFF);
|
||||||
sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
|
sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
|
||||||
addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0);
|
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
|
||||||
sqlite3GenerateIndexKey(v, pIndex, iTab);
|
sqlite3GenerateIndexKey(v, pIndex, iTab);
|
||||||
if( pIndex->onError!=OE_None ){
|
if( pIndex->onError!=OE_None ){
|
||||||
int curaddr = sqlite3VdbeCurrentAddr(v);
|
int curaddr = sqlite3VdbeCurrentAddr(v);
|
||||||
int addr2 = curaddr+4;
|
int addr2 = curaddr+4;
|
||||||
sqlite3VdbeChangeP2(v, curaddr-1, addr2);
|
sqlite3VdbeChangeP2(v, curaddr-1, addr2);
|
||||||
sqlite3VdbeAddOp(v, OP_Rowid, iTab, 0);
|
sqlite3VdbeAddOp1(v, OP_Rowid, iTab);
|
||||||
sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
|
sqlite3VdbeAddOp1(v, OP_AddImm, 1);
|
||||||
sqlite3VdbeAddOp(v, OP_IsUnique, iIdx, addr2);
|
sqlite3VdbeAddOp2(v, OP_IsUnique, iIdx, addr2);
|
||||||
sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, OE_Abort,
|
sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, OE_Abort, 0,
|
||||||
"indexed columns are not unique", P3_STATIC);
|
"indexed columns are not unique", P4_STATIC);
|
||||||
assert( db->mallocFailed || addr2==sqlite3VdbeCurrentAddr(v) );
|
assert( db->mallocFailed || addr2==sqlite3VdbeCurrentAddr(v) );
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_IdxInsert, iIdx, 0);
|
sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Next, iTab, addr1+1);
|
sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
|
||||||
sqlite3VdbeJumpHere(v, addr1);
|
sqlite3VdbeJumpHere(v, addr1);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, iTab, 0);
|
sqlite3VdbeAddOp1(v, OP_Close, iTab);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, iIdx, 0);
|
sqlite3VdbeAddOp1(v, OP_Close, iIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2638,8 +2640,8 @@ void sqlite3CreateIndex(
|
|||||||
/* Create the rootpage for the index
|
/* Create the rootpage for the index
|
||||||
*/
|
*/
|
||||||
sqlite3BeginWriteOperation(pParse, 1, iDb);
|
sqlite3BeginWriteOperation(pParse, 1, iDb);
|
||||||
sqlite3VdbeAddOp(v, OP_CreateIndex, iDb, 0);
|
sqlite3VdbeAddOp1(v, OP_CreateIndex, iDb);
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, iMem, 0);
|
sqlite3VdbeAddOp2(v, OP_MemStore, iMem, 0);
|
||||||
|
|
||||||
/* Gather the complete text of the CREATE INDEX statement into
|
/* Gather the complete text of the CREATE INDEX statement into
|
||||||
** the zStmt variable
|
** the zStmt variable
|
||||||
@@ -2665,7 +2667,7 @@ void sqlite3CreateIndex(
|
|||||||
pTab->zName,
|
pTab->zName,
|
||||||
zStmt
|
zStmt
|
||||||
);
|
);
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
sqlite3VdbeAddOp1(v, OP_Pop, 1);
|
||||||
sqlite3_free(zStmt);
|
sqlite3_free(zStmt);
|
||||||
|
|
||||||
/* Fill the index with data and reparse the schema. Code an OP_Expire
|
/* Fill the index with data and reparse the schema. Code an OP_Expire
|
||||||
@@ -2674,9 +2676,9 @@ void sqlite3CreateIndex(
|
|||||||
if( pTblName ){
|
if( pTblName ){
|
||||||
sqlite3RefillIndex(pParse, pIndex, iMem);
|
sqlite3RefillIndex(pParse, pIndex, iMem);
|
||||||
sqlite3ChangeCookie(db, v, iDb);
|
sqlite3ChangeCookie(db, v, iDb);
|
||||||
sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0,
|
sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0,
|
||||||
sqlite3MPrintf(db, "name='%q'", pIndex->zName), P3_DYNAMIC);
|
sqlite3MPrintf(db, "name='%q'", pIndex->zName), P4_DYNAMIC);
|
||||||
sqlite3VdbeAddOp(v, OP_Expire, 0, 0);
|
sqlite3VdbeAddOp1(v, OP_Expire, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2720,12 +2722,12 @@ void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){
|
|||||||
Vdbe *v;
|
Vdbe *v;
|
||||||
v = sqlite3GetVdbe(pParse);
|
v = sqlite3GetVdbe(pParse);
|
||||||
if( v ){
|
if( v ){
|
||||||
sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1);
|
sqlite3VdbeAddOp2(v, OP_ReadCookie, iDb, 1);
|
||||||
sqlite3VdbeUsesBtree(v, iDb);
|
sqlite3VdbeUsesBtree(v, iDb);
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, minFormat, 0);
|
sqlite3VdbeAddOp1(v, OP_Integer, minFormat);
|
||||||
sqlite3VdbeAddOp(v, OP_Ge, 0, sqlite3VdbeCurrentAddr(v)+3);
|
sqlite3VdbeAddOp2(v, OP_Ge, 0, sqlite3VdbeCurrentAddr(v)+3);
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, minFormat, 0);
|
sqlite3VdbeAddOp1(v, OP_Integer, minFormat);
|
||||||
sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1);
|
sqlite3VdbeAddOp2(v, OP_SetCookie, iDb, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2822,7 +2824,7 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){
|
|||||||
);
|
);
|
||||||
sqlite3ChangeCookie(db, v, iDb);
|
sqlite3ChangeCookie(db, v, iDb);
|
||||||
destroyRootPage(pParse, pIndex->tnum, iDb);
|
destroyRootPage(pParse, pIndex->tnum, iDb);
|
||||||
sqlite3VdbeOp3(v, OP_DropIndex, iDb, 0, pIndex->zName, 0);
|
sqlite3VdbeAddOp4(v, OP_DropIndex, iDb, 0, 0, pIndex->zName, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
exit_drop_index:
|
exit_drop_index:
|
||||||
@@ -3118,11 +3120,11 @@ void sqlite3BeginTransaction(Parse *pParse, int type){
|
|||||||
if( !v ) return;
|
if( !v ) return;
|
||||||
if( type!=TK_DEFERRED ){
|
if( type!=TK_DEFERRED ){
|
||||||
for(i=0; i<db->nDb; i++){
|
for(i=0; i<db->nDb; i++){
|
||||||
sqlite3VdbeAddOp(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1);
|
sqlite3VdbeAddOp2(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1);
|
||||||
sqlite3VdbeUsesBtree(v, i);
|
sqlite3VdbeUsesBtree(v, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_AutoCommit, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_AutoCommit, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -3138,7 +3140,7 @@ void sqlite3CommitTransaction(Parse *pParse){
|
|||||||
|
|
||||||
v = sqlite3GetVdbe(pParse);
|
v = sqlite3GetVdbe(pParse);
|
||||||
if( v ){
|
if( v ){
|
||||||
sqlite3VdbeAddOp(v, OP_AutoCommit, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3155,7 +3157,7 @@ void sqlite3RollbackTransaction(Parse *pParse){
|
|||||||
|
|
||||||
v = sqlite3GetVdbe(pParse);
|
v = sqlite3GetVdbe(pParse);
|
||||||
if( v ){
|
if( v ){
|
||||||
sqlite3VdbeAddOp(v, OP_AutoCommit, 1, 1);
|
sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3227,7 +3229,7 @@ void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
|
|||||||
if( v==0 ) return; /* This only happens if there was a prior error */
|
if( v==0 ) return; /* This only happens if there was a prior error */
|
||||||
db = pParse->db;
|
db = pParse->db;
|
||||||
if( pParse->cookieGoto==0 ){
|
if( pParse->cookieGoto==0 ){
|
||||||
pParse->cookieGoto = sqlite3VdbeAddOp(v, OP_Goto, 0, 0)+1;
|
pParse->cookieGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0)+1;
|
||||||
}
|
}
|
||||||
if( iDb>=0 ){
|
if( iDb>=0 ){
|
||||||
assert( iDb<db->nDb );
|
assert( iDb<db->nDb );
|
||||||
@@ -3268,7 +3270,7 @@ void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){
|
|||||||
sqlite3CodeVerifySchema(pParse, iDb);
|
sqlite3CodeVerifySchema(pParse, iDb);
|
||||||
pParse->writeMask |= 1<<iDb;
|
pParse->writeMask |= 1<<iDb;
|
||||||
if( setStatement && pParse->nested==0 ){
|
if( setStatement && pParse->nested==0 ){
|
||||||
sqlite3VdbeAddOp(v, OP_Statement, iDb, 0);
|
sqlite3VdbeAddOp1(v, OP_Statement, iDb);
|
||||||
}
|
}
|
||||||
if( (OMIT_TEMPDB || iDb!=1) && pParse->db->aDb[1].pBt!=0 ){
|
if( (OMIT_TEMPDB || iDb!=1) && pParse->db->aDb[1].pBt!=0 ){
|
||||||
sqlite3BeginWriteOperation(pParse, setStatement, 1);
|
sqlite3BeginWriteOperation(pParse, setStatement, 1);
|
||||||
|
91
src/delete.c
91
src/delete.c
@@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** in order to generate code for DELETE FROM statements.
|
** in order to generate code for DELETE FROM statements.
|
||||||
**
|
**
|
||||||
** $Id: delete.c,v 1.139 2008/01/02 16:27:10 danielk1977 Exp $
|
** $Id: delete.c,v 1.140 2008/01/03 00:01:24 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -75,10 +75,10 @@ void sqlite3OpenTable(
|
|||||||
v = sqlite3GetVdbe(p);
|
v = sqlite3GetVdbe(p);
|
||||||
assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
|
assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
|
||||||
sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite), pTab->zName);
|
sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite), pTab->zName);
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
|
sqlite3VdbeAddOp1(v, OP_Integer, iDb);
|
||||||
VdbeComment((v, "%s", pTab->zName));
|
VdbeComment((v, "%s", pTab->zName));
|
||||||
sqlite3VdbeAddOp(v, opcode, iCur, pTab->tnum);
|
sqlite3VdbeAddOp2(v, opcode, iCur, pTab->tnum);
|
||||||
sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol);
|
sqlite3VdbeAddOp2(v, OP_SetNumColumns, iCur, pTab->nCol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -201,18 +201,18 @@ void sqlite3DeleteFrom(
|
|||||||
sqlite3BeginWriteOperation(pParse, triggers_exist, iDb);
|
sqlite3BeginWriteOperation(pParse, triggers_exist, iDb);
|
||||||
|
|
||||||
if( triggers_exist ){
|
if( triggers_exist ){
|
||||||
int iGoto = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
|
int iGoto = sqlite3VdbeAddOp0(v, OP_Goto);
|
||||||
addr = sqlite3VdbeMakeLabel(v);
|
addr = sqlite3VdbeMakeLabel(v);
|
||||||
iBeginBeforeTrigger = sqlite3VdbeCurrentAddr(v);
|
iBeginBeforeTrigger = sqlite3VdbeCurrentAddr(v);
|
||||||
(void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_BEFORE, pTab,
|
(void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_BEFORE, pTab,
|
||||||
-1, oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,
|
-1, oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,
|
||||||
addr, &old_col_mask, 0);
|
addr, &old_col_mask, 0);
|
||||||
iEndBeforeTrigger = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
|
iEndBeforeTrigger = sqlite3VdbeAddOp0(v, OP_Goto);
|
||||||
iBeginAfterTrigger = sqlite3VdbeCurrentAddr(v);
|
iBeginAfterTrigger = sqlite3VdbeCurrentAddr(v);
|
||||||
(void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_AFTER, pTab, -1,
|
(void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_AFTER, pTab, -1,
|
||||||
oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,
|
oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,
|
||||||
addr, &old_col_mask, 0);
|
addr, &old_col_mask, 0);
|
||||||
iEndAfterTrigger = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
|
iEndAfterTrigger = sqlite3VdbeAddOp0(v, OP_Goto);
|
||||||
sqlite3VdbeJumpHere(v, iGoto);
|
sqlite3VdbeJumpHere(v, iGoto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,7 +233,7 @@ void sqlite3DeleteFrom(
|
|||||||
*/
|
*/
|
||||||
if( db->flags & SQLITE_CountRows ){
|
if( db->flags & SQLITE_CountRows ){
|
||||||
memCnt = pParse->nMem++;
|
memCnt = pParse->nMem++;
|
||||||
sqlite3VdbeAddOp(v, OP_MemInt, 0, memCnt);
|
sqlite3VdbeAddOp2(v, OP_MemInt, 0, memCnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Special case: A DELETE without a WHERE clause deletes everything.
|
/* Special case: A DELETE without a WHERE clause deletes everything.
|
||||||
@@ -248,19 +248,19 @@ void sqlite3DeleteFrom(
|
|||||||
if( !isView ){
|
if( !isView ){
|
||||||
sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
|
sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_Rewind, iCur, sqlite3VdbeCurrentAddr(v)+2);
|
sqlite3VdbeAddOp2(v, OP_Rewind, iCur, sqlite3VdbeCurrentAddr(v)+2);
|
||||||
addr2 = sqlite3VdbeAddOp(v, OP_MemIncr, 1, memCnt);
|
addr2 = sqlite3VdbeAddOp2(v, OP_MemIncr, 1, memCnt);
|
||||||
sqlite3VdbeAddOp(v, OP_Next, iCur, addr2);
|
sqlite3VdbeAddOp2(v, OP_Next, iCur, addr2);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
sqlite3VdbeAddOp1(v, OP_Close, iCur);
|
||||||
}
|
}
|
||||||
if( !isView ){
|
if( !isView ){
|
||||||
sqlite3VdbeAddOp(v, OP_Clear, pTab->tnum, iDb);
|
sqlite3VdbeAddOp2(v, OP_Clear, pTab->tnum, iDb);
|
||||||
if( !pParse->nested ){
|
if( !pParse->nested ){
|
||||||
sqlite3VdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
|
sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC);
|
||||||
}
|
}
|
||||||
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||||
assert( pIdx->pSchema==pTab->pSchema );
|
assert( pIdx->pSchema==pTab->pSchema );
|
||||||
sqlite3VdbeAddOp(v, OP_Clear, pIdx->tnum, iDb);
|
sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -275,10 +275,10 @@ void sqlite3DeleteFrom(
|
|||||||
|
|
||||||
/* Remember the rowid of every item to be deleted.
|
/* Remember the rowid of every item to be deleted.
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp(v, IsVirtual(pTab) ? OP_VRowid : OP_Rowid, iCur, 0);
|
sqlite3VdbeAddOp1(v, IsVirtual(pTab) ? OP_VRowid : OP_Rowid, iCur);
|
||||||
sqlite3VdbeAddOp(v, OP_FifoWrite, 0, 0);
|
sqlite3VdbeAddOp0(v, OP_FifoWrite);
|
||||||
if( db->flags & SQLITE_CountRows ){
|
if( db->flags & SQLITE_CountRows ){
|
||||||
sqlite3VdbeAddOp(v, OP_MemIncr, 1, memCnt);
|
sqlite3VdbeAddOp2(v, OP_MemIncr, 1, memCnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* End the database scan loop.
|
/* End the database scan loop.
|
||||||
@@ -288,8 +288,8 @@ void sqlite3DeleteFrom(
|
|||||||
/* Open the pseudo-table used to store OLD if there are triggers.
|
/* Open the pseudo-table used to store OLD if there are triggers.
|
||||||
*/
|
*/
|
||||||
if( triggers_exist ){
|
if( triggers_exist ){
|
||||||
sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
|
sqlite3VdbeAddOp1(v, OP_OpenPseudo, oldIdx);
|
||||||
sqlite3VdbeAddOp(v, OP_SetNumColumns, oldIdx, pTab->nCol);
|
sqlite3VdbeAddOp2(v, OP_SetNumColumns, oldIdx, pTab->nCol);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete every item whose key was written to the list during the
|
/* Delete every item whose key was written to the list during the
|
||||||
@@ -311,29 +311,29 @@ void sqlite3DeleteFrom(
|
|||||||
if( triggers_exist ){
|
if( triggers_exist ){
|
||||||
sqlite3VdbeResolveLabel(v, addr);
|
sqlite3VdbeResolveLabel(v, addr);
|
||||||
}
|
}
|
||||||
addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, end);
|
addr = sqlite3VdbeAddOp2(v, OP_FifoRead, 0, end);
|
||||||
sqlite3VdbeAddOp(v, OP_StackDepth, -1, 0);
|
sqlite3VdbeAddOp1(v, OP_StackDepth, -1);
|
||||||
|
|
||||||
if( triggers_exist ){
|
if( triggers_exist ){
|
||||||
int mem1 = pParse->nMem++;
|
int mem1 = pParse->nMem++;
|
||||||
if( !isView ){
|
if( !isView ){
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, mem1, 0);
|
sqlite3VdbeAddOp1(v, OP_MemStore, mem1);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_NotExists, iCur, addr);
|
sqlite3VdbeAddOp2(v, OP_NotExists, iCur, addr);
|
||||||
sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
|
sqlite3VdbeAddOp1(v, OP_Rowid, iCur);
|
||||||
if( old_col_mask ){
|
if( old_col_mask ){
|
||||||
sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
|
sqlite3VdbeAddOp1(v, OP_RowData, iCur);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
sqlite3VdbeAddOp0(v, OP_Null);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_Insert, oldIdx, 0);
|
sqlite3VdbeAddOp1(v, OP_Insert, oldIdx);
|
||||||
|
|
||||||
/* Jump back and run the BEFORE triggers */
|
/* Jump back and run the BEFORE triggers */
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, iBeginBeforeTrigger);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginBeforeTrigger);
|
||||||
sqlite3VdbeJumpHere(v, iEndBeforeTrigger);
|
sqlite3VdbeJumpHere(v, iEndBeforeTrigger);
|
||||||
|
|
||||||
if( !isView ){
|
if( !isView ){
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, mem1, 0);
|
sqlite3VdbeAddOp1(v, OP_MemLoad, mem1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,7 +342,8 @@ void sqlite3DeleteFrom(
|
|||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
if( IsVirtual(pTab) ){
|
if( IsVirtual(pTab) ){
|
||||||
pParse->pVirtualLock = pTab;
|
pParse->pVirtualLock = pTab;
|
||||||
sqlite3VdbeOp3(v, OP_VUpdate, 0, 1, (const char*)pTab->pVtab, P3_VTAB);
|
sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, 0,
|
||||||
|
(const char*)pTab->pVtab, P4_VTAB);
|
||||||
}else
|
}else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
@@ -355,20 +356,20 @@ void sqlite3DeleteFrom(
|
|||||||
*/
|
*/
|
||||||
if( triggers_exist ){
|
if( triggers_exist ){
|
||||||
/* Jump back and run the AFTER triggers */
|
/* Jump back and run the AFTER triggers */
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, iBeginAfterTrigger);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginAfterTrigger);
|
||||||
sqlite3VdbeJumpHere(v, iEndAfterTrigger);
|
sqlite3VdbeJumpHere(v, iEndAfterTrigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* End of the delete loop */
|
/* End of the delete loop */
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, addr);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
|
||||||
sqlite3VdbeResolveLabel(v, end);
|
sqlite3VdbeResolveLabel(v, end);
|
||||||
|
|
||||||
/* Close the cursors after the loop if there are no row triggers */
|
/* Close the cursors after the loop if there are no row triggers */
|
||||||
if( !isView && !IsVirtual(pTab) ){
|
if( !isView && !IsVirtual(pTab) ){
|
||||||
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
|
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
|
||||||
sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);
|
sqlite3VdbeAddOp2(v, OP_Close, iCur + i, pIdx->tnum);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
sqlite3VdbeAddOp1(v, OP_Close, iCur);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -378,9 +379,9 @@ void sqlite3DeleteFrom(
|
|||||||
** invoke the callback function.
|
** invoke the callback function.
|
||||||
*/
|
*/
|
||||||
if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){
|
if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){
|
||||||
sqlite3VdbeAddOp(v, OP_ResultRow, memCnt, 1);
|
sqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1);
|
||||||
sqlite3VdbeSetNumCols(v, 1);
|
sqlite3VdbeSetNumCols(v, 1);
|
||||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", P4_STATIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete_from_cleanup:
|
delete_from_cleanup:
|
||||||
@@ -418,11 +419,11 @@ void sqlite3GenerateRowDelete(
|
|||||||
int count /* Increment the row change counter */
|
int count /* Increment the row change counter */
|
||||||
){
|
){
|
||||||
int addr;
|
int addr;
|
||||||
addr = sqlite3VdbeAddOp(v, OP_NotExists, iCur, 0);
|
addr = sqlite3VdbeAddOp1(v, OP_NotExists, iCur);
|
||||||
sqlite3GenerateRowIndexDelete(v, pTab, iCur, 0);
|
sqlite3GenerateRowIndexDelete(v, pTab, iCur, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0));
|
sqlite3VdbeAddOp2(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0));
|
||||||
if( count ){
|
if( count ){
|
||||||
sqlite3VdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
|
sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC);
|
||||||
}
|
}
|
||||||
sqlite3VdbeJumpHere(v, addr);
|
sqlite3VdbeJumpHere(v, addr);
|
||||||
}
|
}
|
||||||
@@ -455,7 +456,7 @@ void sqlite3GenerateRowIndexDelete(
|
|||||||
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
|
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
|
||||||
if( aIdxUsed!=0 && aIdxUsed[i-1]==0 ) continue;
|
if( aIdxUsed!=0 && aIdxUsed[i-1]==0 ) continue;
|
||||||
sqlite3GenerateIndexKey(v, pIdx, iCur);
|
sqlite3GenerateIndexKey(v, pIdx, iCur);
|
||||||
sqlite3VdbeAddOp(v, OP_IdxDelete, iCur+i, 0);
|
sqlite3VdbeAddOp1(v, OP_IdxDelete, iCur+i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -473,16 +474,16 @@ void sqlite3GenerateIndexKey(
|
|||||||
int j;
|
int j;
|
||||||
Table *pTab = pIdx->pTable;
|
Table *pTab = pIdx->pTable;
|
||||||
|
|
||||||
sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
|
sqlite3VdbeAddOp1(v, OP_Rowid, iCur);
|
||||||
for(j=0; j<pIdx->nColumn; j++){
|
for(j=0; j<pIdx->nColumn; j++){
|
||||||
int idx = pIdx->aiColumn[j];
|
int idx = pIdx->aiColumn[j];
|
||||||
if( idx==pTab->iPKey ){
|
if( idx==pTab->iPKey ){
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, j, 0);
|
sqlite3VdbeAddOp1(v, OP_Dup, j);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_Column, iCur, idx);
|
sqlite3VdbeAddOp2(v, OP_Column, iCur, idx);
|
||||||
sqlite3ColumnDefault(v, pTab, idx);
|
sqlite3ColumnDefault(v, pTab, idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_MakeIdxRec, pIdx->nColumn, 0);
|
sqlite3VdbeAddOp1(v, OP_MakeIdxRec, pIdx->nColumn);
|
||||||
sqlite3IndexAffinityStr(v, pIdx);
|
sqlite3IndexAffinityStr(v, pIdx);
|
||||||
}
|
}
|
||||||
|
177
src/expr.c
177
src/expr.c
@@ -12,7 +12,7 @@
|
|||||||
** This file contains routines used for analyzing expressions and
|
** This file contains routines used for analyzing expressions and
|
||||||
** for generating VDBE code that evaluates expressions in SQLite.
|
** for generating VDBE code that evaluates expressions in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: expr.c,v 1.324 2008/01/02 16:27:10 danielk1977 Exp $
|
** $Id: expr.c,v 1.325 2008/01/03 00:01:24 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -216,7 +216,8 @@ static int codeCompare(
|
|||||||
){
|
){
|
||||||
int p1 = binaryCompareP1(pLeft, pRight, jumpIfNull);
|
int p1 = binaryCompareP1(pLeft, pRight, jumpIfNull);
|
||||||
CollSeq *p3 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight);
|
CollSeq *p3 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight);
|
||||||
return sqlite3VdbeOp3(pParse->pVdbe, opcode, p1, dest, (void*)p3, P3_COLLSEQ);
|
return sqlite3VdbeAddOp4(pParse->pVdbe, opcode, p1, dest, 0,
|
||||||
|
(void*)p3, P4_COLLSEQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -307,8 +308,8 @@ Expr *sqlite3RegisterExpr(Parse *pParse, Token *pToken){
|
|||||||
}
|
}
|
||||||
depth = atoi((char*)&pToken->z[1]);
|
depth = atoi((char*)&pToken->z[1]);
|
||||||
p->iTable = pParse->nMem++;
|
p->iTable = pParse->nMem++;
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, depth, 0);
|
sqlite3VdbeAddOp1(v, OP_Dup, depth);
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, p->iTable, 1);
|
sqlite3VdbeAddOp2(v, OP_MemStore, p->iTable, 1);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1605,9 +1606,9 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int mustBeUnique){
|
|||||||
int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
|
int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
|
||||||
sqlite3VdbeUsesBtree(v, iDb);
|
sqlite3VdbeUsesBtree(v, iDb);
|
||||||
|
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, iMem, 0);
|
sqlite3VdbeAddOp1(v, OP_MemLoad, iMem);
|
||||||
iAddr = sqlite3VdbeAddOp(v, OP_If, 0, iMem);
|
iAddr = sqlite3VdbeAddOp2(v, OP_If, 0, iMem);
|
||||||
sqlite3VdbeAddOp(v, OP_MemInt, 1, iMem);
|
sqlite3VdbeAddOp2(v, OP_MemInt, 1, iMem);
|
||||||
|
|
||||||
sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
|
sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
|
||||||
eType = IN_INDEX_ROWID;
|
eType = IN_INDEX_ROWID;
|
||||||
@@ -1642,15 +1643,16 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int mustBeUnique){
|
|||||||
iDb = sqlite3SchemaToIndex(db, pIdx->pSchema);
|
iDb = sqlite3SchemaToIndex(db, pIdx->pSchema);
|
||||||
sqlite3VdbeUsesBtree(v, iDb);
|
sqlite3VdbeUsesBtree(v, iDb);
|
||||||
|
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, iMem, 0);
|
sqlite3VdbeAddOp1(v, OP_MemLoad, iMem);
|
||||||
iAddr = sqlite3VdbeAddOp(v, OP_If, 0, iMem);
|
iAddr = sqlite3VdbeAddOp2(v, OP_If, 0, iMem);
|
||||||
sqlite3VdbeAddOp(v, OP_MemInt, 1, iMem);
|
sqlite3VdbeAddOp2(v, OP_MemInt, 1, iMem);
|
||||||
|
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
|
sqlite3VdbeAddOp1(v, OP_Integer, iDb);
|
||||||
VdbeComment((v, "%s", pIdx->zName));
|
VdbeComment((v, "%s", pIdx->zName));
|
||||||
sqlite3VdbeOp3(v,OP_OpenRead,iTab,pIdx->tnum,pKey,P3_KEYINFO_HANDOFF);
|
sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, 0,
|
||||||
|
pKey,P4_KEYINFO_HANDOFF);
|
||||||
eType = IN_INDEX_INDEX;
|
eType = IN_INDEX_INDEX;
|
||||||
sqlite3VdbeAddOp(v, OP_SetNumColumns, iTab, pIdx->nColumn);
|
sqlite3VdbeAddOp2(v, OP_SetNumColumns, iTab, pIdx->nColumn);
|
||||||
|
|
||||||
sqlite3VdbeJumpHere(v, iAddr);
|
sqlite3VdbeJumpHere(v, iAddr);
|
||||||
}
|
}
|
||||||
@@ -1699,10 +1701,10 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
|||||||
*/
|
*/
|
||||||
if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->trigStack ){
|
if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->trigStack ){
|
||||||
int mem = pParse->nMem++;
|
int mem = pParse->nMem++;
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, mem, 0);
|
sqlite3VdbeAddOp1(v, OP_MemLoad, mem);
|
||||||
testAddr = sqlite3VdbeAddOp(v, OP_If, 0, 0);
|
testAddr = sqlite3VdbeAddOp0(v, OP_If);
|
||||||
assert( testAddr>0 || pParse->db->mallocFailed );
|
assert( testAddr>0 || pParse->db->mallocFailed );
|
||||||
sqlite3VdbeAddOp(v, OP_MemInt, 1, mem);
|
sqlite3VdbeAddOp2(v, OP_MemInt, 1, mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch( pExpr->op ){
|
switch( pExpr->op ){
|
||||||
@@ -1727,10 +1729,10 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
|||||||
** is used.
|
** is used.
|
||||||
*/
|
*/
|
||||||
pExpr->iTable = pParse->nTab++;
|
pExpr->iTable = pParse->nTab++;
|
||||||
addr = sqlite3VdbeAddOp(v, OP_OpenEphemeral, pExpr->iTable, 0);
|
addr = sqlite3VdbeAddOp1(v, OP_OpenEphemeral, pExpr->iTable);
|
||||||
memset(&keyInfo, 0, sizeof(keyInfo));
|
memset(&keyInfo, 0, sizeof(keyInfo));
|
||||||
keyInfo.nField = 1;
|
keyInfo.nField = 1;
|
||||||
sqlite3VdbeAddOp(v, OP_SetNumColumns, pExpr->iTable, 1);
|
sqlite3VdbeAddOp2(v, OP_SetNumColumns, pExpr->iTable, 1);
|
||||||
|
|
||||||
if( pExpr->pSelect ){
|
if( pExpr->pSelect ){
|
||||||
/* Case 1: expr IN (SELECT ...)
|
/* Case 1: expr IN (SELECT ...)
|
||||||
@@ -1784,11 +1786,11 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
|||||||
|
|
||||||
/* Evaluate the expression and insert it into the temp table */
|
/* Evaluate the expression and insert it into the temp table */
|
||||||
sqlite3ExprCode(pParse, pE2);
|
sqlite3ExprCode(pParse, pE2);
|
||||||
sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1);
|
sqlite3VdbeAddOp4(v, OP_MakeRecord, 1, 0, 0, &affinity, 1);
|
||||||
sqlite3VdbeAddOp(v, OP_IdxInsert, pExpr->iTable, 0);
|
sqlite3VdbeAddOp1(v, OP_IdxInsert, pExpr->iTable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3VdbeChangeP3(v, addr, (void *)&keyInfo, P3_KEYINFO);
|
sqlite3VdbeChangeP4(v, addr, (void *)&keyInfo, P4_KEYINFO);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1806,11 +1808,11 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
|||||||
dest.iParm = pParse->nMem++;
|
dest.iParm = pParse->nMem++;
|
||||||
if( pExpr->op==TK_SELECT ){
|
if( pExpr->op==TK_SELECT ){
|
||||||
dest.eDest = SRT_Mem;
|
dest.eDest = SRT_Mem;
|
||||||
sqlite3VdbeAddOp(v, OP_MemNull, 0, dest.iParm);
|
sqlite3VdbeAddOp2(v, OP_MemNull, 0, dest.iParm);
|
||||||
VdbeComment((v, "Init subquery result"));
|
VdbeComment((v, "Init subquery result"));
|
||||||
}else{
|
}else{
|
||||||
dest.eDest = SRT_Exists;
|
dest.eDest = SRT_Exists;
|
||||||
sqlite3VdbeAddOp(v, OP_MemInt, 0, dest.iParm);
|
sqlite3VdbeAddOp2(v, OP_MemInt, 0, dest.iParm);
|
||||||
VdbeComment((v, "Init EXISTS result"));
|
VdbeComment((v, "Init EXISTS result"));
|
||||||
}
|
}
|
||||||
sqlite3ExprDelete(pSel->pLimit);
|
sqlite3ExprDelete(pSel->pLimit);
|
||||||
@@ -1859,7 +1861,7 @@ static void codeReal(Vdbe *v, const char *z, int n, int negateFlag){
|
|||||||
sqlite3AtoF(z, &value);
|
sqlite3AtoF(z, &value);
|
||||||
if( negateFlag ) value = -value;
|
if( negateFlag ) value = -value;
|
||||||
zV = dup8bytes(v, (char*)&value);
|
zV = dup8bytes(v, (char*)&value);
|
||||||
sqlite3VdbeOp3(v, OP_Real, 0, 0, zV, P3_REAL);
|
sqlite3VdbeAddOp4(v, OP_Real, 0, 0, 0, zV, P4_REAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1879,14 +1881,14 @@ static void codeInteger(Vdbe *v, const char *z, int n, int negateFlag){
|
|||||||
assert( !isdigit(z[n]) );
|
assert( !isdigit(z[n]) );
|
||||||
if( sqlite3GetInt32(z, &i) ){
|
if( sqlite3GetInt32(z, &i) ){
|
||||||
if( negateFlag ) i = -i;
|
if( negateFlag ) i = -i;
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
|
sqlite3VdbeAddOp1(v, OP_Integer, i);
|
||||||
}else if( sqlite3FitsIn64Bits(z, negateFlag) ){
|
}else if( sqlite3FitsIn64Bits(z, negateFlag) ){
|
||||||
i64 value;
|
i64 value;
|
||||||
char *zV;
|
char *zV;
|
||||||
sqlite3Atoi64(z, &value);
|
sqlite3Atoi64(z, &value);
|
||||||
if( negateFlag ) value = -value;
|
if( negateFlag ) value = -value;
|
||||||
zV = dup8bytes(v, (char*)&value);
|
zV = dup8bytes(v, (char*)&value);
|
||||||
sqlite3VdbeOp3(v, OP_Int64, 0, 0, zV, P3_INT64);
|
sqlite3VdbeAddOp4(v, OP_Int64, 0, 0, 0, zV, P4_INT64);
|
||||||
}else{
|
}else{
|
||||||
codeReal(v, z, n, negateFlag);
|
codeReal(v, z, n, negateFlag);
|
||||||
}
|
}
|
||||||
@@ -1903,16 +1905,16 @@ static void codeInteger(Vdbe *v, const char *z, int n, int negateFlag){
|
|||||||
void sqlite3ExprCodeGetColumn(Vdbe *v, Table *pTab, int iColumn, int iTable){
|
void sqlite3ExprCodeGetColumn(Vdbe *v, Table *pTab, int iColumn, int iTable){
|
||||||
if( iColumn<0 ){
|
if( iColumn<0 ){
|
||||||
int op = (pTab && IsVirtual(pTab)) ? OP_VRowid : OP_Rowid;
|
int op = (pTab && IsVirtual(pTab)) ? OP_VRowid : OP_Rowid;
|
||||||
sqlite3VdbeAddOp(v, op, iTable, 0);
|
sqlite3VdbeAddOp1(v, op, iTable);
|
||||||
}else if( pTab==0 ){
|
}else if( pTab==0 ){
|
||||||
sqlite3VdbeAddOp(v, OP_Column, iTable, iColumn);
|
sqlite3VdbeAddOp2(v, OP_Column, iTable, iColumn);
|
||||||
}else{
|
}else{
|
||||||
int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;
|
int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;
|
||||||
sqlite3VdbeAddOp(v, op, iTable, iColumn);
|
sqlite3VdbeAddOp2(v, op, iTable, iColumn);
|
||||||
sqlite3ColumnDefault(v, pTab, iColumn);
|
sqlite3ColumnDefault(v, pTab, iColumn);
|
||||||
#ifndef SQLITE_OMIT_FLOATING_POINT
|
#ifndef SQLITE_OMIT_FLOATING_POINT
|
||||||
if( pTab->aCol[iColumn].affinity==SQLITE_AFF_REAL ){
|
if( pTab->aCol[iColumn].affinity==SQLITE_AFF_REAL ){
|
||||||
sqlite3VdbeAddOp(v, OP_RealAffinity, 0, 0);
|
sqlite3VdbeAddOp0(v, OP_RealAffinity);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -1935,7 +1937,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
|
|
||||||
if( v==0 ) return;
|
if( v==0 ) return;
|
||||||
if( pExpr==0 ){
|
if( pExpr==0 ){
|
||||||
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
sqlite3VdbeAddOp0(v, OP_Null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
op = pExpr->op;
|
op = pExpr->op;
|
||||||
@@ -1944,10 +1946,10 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
AggInfo *pAggInfo = pExpr->pAggInfo;
|
AggInfo *pAggInfo = pExpr->pAggInfo;
|
||||||
struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg];
|
struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg];
|
||||||
if( !pAggInfo->directMode ){
|
if( !pAggInfo->directMode ){
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, pCol->iMem, 0);
|
sqlite3VdbeAddOp1(v, OP_MemLoad, pCol->iMem);
|
||||||
break;
|
break;
|
||||||
}else if( pAggInfo->useSortingIdx ){
|
}else if( pAggInfo->useSortingIdx ){
|
||||||
sqlite3VdbeAddOp(v, OP_Column, pAggInfo->sortingIdx,
|
sqlite3VdbeAddOp2(v, OP_Column, pAggInfo->sortingIdx,
|
||||||
pCol->iSorterColumn);
|
pCol->iSorterColumn);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1957,7 +1959,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
if( pExpr->iTable<0 ){
|
if( pExpr->iTable<0 ){
|
||||||
/* This only happens when coding check constraints */
|
/* This only happens when coding check constraints */
|
||||||
assert( pParse->ckOffset>0 );
|
assert( pParse->ckOffset>0 );
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, pParse->ckOffset-pExpr->iColumn-1, 1);
|
sqlite3VdbeAddOp2(v, OP_Dup, pParse->ckOffset-pExpr->iColumn-1, 1);
|
||||||
}else{
|
}else{
|
||||||
sqlite3ExprCodeGetColumn(v, pExpr->pTab, pExpr->iColumn, pExpr->iTable);
|
sqlite3ExprCodeGetColumn(v, pExpr->pTab, pExpr->iColumn, pExpr->iTable);
|
||||||
}
|
}
|
||||||
@@ -1973,11 +1975,12 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
}
|
}
|
||||||
case TK_STRING: {
|
case TK_STRING: {
|
||||||
sqlite3DequoteExpr(pParse->db, pExpr);
|
sqlite3DequoteExpr(pParse->db, pExpr);
|
||||||
sqlite3VdbeOp3(v,OP_String8, 0, 0, (char*)pExpr->token.z, pExpr->token.n);
|
sqlite3VdbeAddOp4(v,OP_String8, 0, 0, 0,
|
||||||
|
(char*)pExpr->token.z, pExpr->token.n);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_NULL: {
|
case TK_NULL: {
|
||||||
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
sqlite3VdbeAddOp0(v, OP_Null);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifndef SQLITE_OMIT_BLOB_LITERAL
|
#ifndef SQLITE_OMIT_BLOB_LITERAL
|
||||||
@@ -1991,19 +1994,19 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
if( n==0 ){
|
if( n==0 ){
|
||||||
z = "";
|
z = "";
|
||||||
}
|
}
|
||||||
sqlite3VdbeOp3(v, op, 0, 0, z, n);
|
sqlite3VdbeAddOp4(v, op, 0, 0, 0, z, n);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
case TK_VARIABLE: {
|
case TK_VARIABLE: {
|
||||||
sqlite3VdbeAddOp(v, OP_Variable, pExpr->iTable, 0);
|
sqlite3VdbeAddOp1(v, OP_Variable, pExpr->iTable);
|
||||||
if( pExpr->token.n>1 ){
|
if( pExpr->token.n>1 ){
|
||||||
sqlite3VdbeChangeP3(v, -1, (char*)pExpr->token.z, pExpr->token.n);
|
sqlite3VdbeChangeP4(v, -1, (char*)pExpr->token.z, pExpr->token.n);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_REGISTER: {
|
case TK_REGISTER: {
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iTable, 0);
|
sqlite3VdbeAddOp1(v, OP_MemLoad, pExpr->iTable);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifndef SQLITE_OMIT_CAST
|
#ifndef SQLITE_OMIT_CAST
|
||||||
@@ -2018,7 +2021,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
assert( to_op==OP_ToNumeric || aff!=SQLITE_AFF_NUMERIC );
|
assert( to_op==OP_ToNumeric || aff!=SQLITE_AFF_NUMERIC );
|
||||||
assert( to_op==OP_ToInt || aff!=SQLITE_AFF_INTEGER );
|
assert( to_op==OP_ToInt || aff!=SQLITE_AFF_INTEGER );
|
||||||
assert( to_op==OP_ToReal || aff!=SQLITE_AFF_REAL );
|
assert( to_op==OP_ToReal || aff!=SQLITE_AFF_REAL );
|
||||||
sqlite3VdbeAddOp(v, to_op, 0, 0);
|
sqlite3VdbeAddOp0(v, to_op);
|
||||||
stackChng = 0;
|
stackChng = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2066,7 +2069,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
assert( TK_CONCAT==OP_Concat );
|
assert( TK_CONCAT==OP_Concat );
|
||||||
sqlite3ExprCode(pParse, pExpr->pLeft);
|
sqlite3ExprCode(pParse, pExpr->pLeft);
|
||||||
sqlite3ExprCode(pParse, pExpr->pRight);
|
sqlite3ExprCode(pParse, pExpr->pRight);
|
||||||
sqlite3VdbeAddOp(v, op, 0, 0);
|
sqlite3VdbeAddOp0(v, op);
|
||||||
stackChng = -1;
|
stackChng = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2089,7 +2092,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
assert( TK_BITNOT==OP_BitNot );
|
assert( TK_BITNOT==OP_BitNot );
|
||||||
assert( TK_NOT==OP_Not );
|
assert( TK_NOT==OP_Not );
|
||||||
sqlite3ExprCode(pParse, pExpr->pLeft);
|
sqlite3ExprCode(pParse, pExpr->pLeft);
|
||||||
sqlite3VdbeAddOp(v, op, 0, 0);
|
sqlite3VdbeAddOp0(v, op);
|
||||||
stackChng = 0;
|
stackChng = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2098,11 +2101,11 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
int dest;
|
int dest;
|
||||||
assert( TK_ISNULL==OP_IsNull );
|
assert( TK_ISNULL==OP_IsNull );
|
||||||
assert( TK_NOTNULL==OP_NotNull );
|
assert( TK_NOTNULL==OP_NotNull );
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
|
sqlite3VdbeAddOp1(v, OP_Integer, 1);
|
||||||
sqlite3ExprCode(pParse, pExpr->pLeft);
|
sqlite3ExprCode(pParse, pExpr->pLeft);
|
||||||
dest = sqlite3VdbeCurrentAddr(v) + 2;
|
dest = sqlite3VdbeCurrentAddr(v) + 2;
|
||||||
sqlite3VdbeAddOp(v, op, 1, dest);
|
sqlite3VdbeAddOp2(v, op, 1, dest);
|
||||||
sqlite3VdbeAddOp(v, OP_AddImm, -1, 0);
|
sqlite3VdbeAddOp1(v, OP_AddImm, -1);
|
||||||
stackChng = 0;
|
stackChng = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2112,7 +2115,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
sqlite3ErrorMsg(pParse, "misuse of aggregate: %T",
|
sqlite3ErrorMsg(pParse, "misuse of aggregate: %T",
|
||||||
&pExpr->span);
|
&pExpr->span);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, pInfo->aFunc[pExpr->iAgg].iMem, 0);
|
sqlite3VdbeAddOp1(v, OP_MemLoad, pInfo->aFunc[pExpr->iAgg].iMem);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2163,9 +2166,10 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
}
|
}
|
||||||
if( pDef->needCollSeq ){
|
if( pDef->needCollSeq ){
|
||||||
if( !pColl ) pColl = pParse->db->pDfltColl;
|
if( !pColl ) pColl = pParse->db->pDfltColl;
|
||||||
sqlite3VdbeOp3(v, OP_CollSeq, 0, 0, (char *)pColl, P3_COLLSEQ);
|
sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
|
||||||
}
|
}
|
||||||
sqlite3VdbeOp3(v, OP_Function, constMask, nExpr, (char*)pDef, P3_FUNCDEF);
|
sqlite3VdbeAddOp4(v, OP_Function, constMask, nExpr, 0,
|
||||||
|
(char*)pDef, P4_FUNCDEF);
|
||||||
stackChng = 1-nExpr;
|
stackChng = 1-nExpr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2175,7 +2179,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
if( pExpr->iColumn==0 ){
|
if( pExpr->iColumn==0 ){
|
||||||
sqlite3CodeSubselect(pParse, pExpr);
|
sqlite3CodeSubselect(pParse, pExpr);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0);
|
sqlite3VdbeAddOp1(v, OP_MemLoad, pExpr->iColumn);
|
||||||
VdbeComment((v, "load subquery result"));
|
VdbeComment((v, "load subquery result"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2190,11 +2194,11 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
|
|
||||||
/* Figure out the affinity to use to create a key from the results
|
/* Figure out the affinity to use to create a key from the results
|
||||||
** of the expression. affinityStr stores a static string suitable for
|
** of the expression. affinityStr stores a static string suitable for
|
||||||
** P3 of OP_MakeRecord.
|
** P4 of OP_MakeRecord.
|
||||||
*/
|
*/
|
||||||
affinity = comparisonAffinity(pExpr);
|
affinity = comparisonAffinity(pExpr);
|
||||||
|
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
|
sqlite3VdbeAddOp1(v, OP_Integer, 1);
|
||||||
pParse->ckOffset = (ckOffset ? (ckOffset+1) : 0);
|
pParse->ckOffset = (ckOffset ? (ckOffset+1) : 0);
|
||||||
|
|
||||||
/* Code the <expr> from "<expr> IN (...)". The temporary table
|
/* Code the <expr> from "<expr> IN (...)". The temporary table
|
||||||
@@ -2202,20 +2206,21 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
*/
|
*/
|
||||||
sqlite3ExprCode(pParse, pExpr->pLeft);
|
sqlite3ExprCode(pParse, pExpr->pLeft);
|
||||||
addr = sqlite3VdbeCurrentAddr(v);
|
addr = sqlite3VdbeCurrentAddr(v);
|
||||||
sqlite3VdbeAddOp(v, OP_NotNull, -1, addr+4); /* addr + 0 */
|
sqlite3VdbeAddOp2(v, OP_NotNull, -1, addr+4); /* addr + 0 */
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, 2, 0);
|
sqlite3VdbeAddOp1(v, OP_Pop, 2);
|
||||||
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
sqlite3VdbeAddOp0(v, OP_Null);
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, iLabel);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, iLabel);
|
||||||
if( eType==IN_INDEX_ROWID ){
|
if( eType==IN_INDEX_ROWID ){
|
||||||
int iAddr = sqlite3VdbeCurrentAddr(v)+3;
|
int iAddr = sqlite3VdbeCurrentAddr(v)+3;
|
||||||
sqlite3VdbeAddOp(v, OP_MustBeInt, 1, iAddr);
|
sqlite3VdbeAddOp2(v, OP_MustBeInt, 1, iAddr);
|
||||||
sqlite3VdbeAddOp(v, OP_NotExists, pExpr->iTable, iAddr);
|
sqlite3VdbeAddOp2(v, OP_NotExists, pExpr->iTable, iAddr);
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, pExpr->iTable, iLabel);
|
sqlite3VdbeAddOp2(v, OP_Goto, pExpr->iTable, iLabel);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1); /* addr + 4 */
|
sqlite3VdbeAddOp4(v, OP_MakeRecord, 1, 0, 0,
|
||||||
sqlite3VdbeAddOp(v, OP_Found, pExpr->iTable, iLabel);
|
&affinity, 1); /* addr + 4 */
|
||||||
|
sqlite3VdbeAddOp2(v, OP_Found, pExpr->iTable, iLabel);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_AddImm, -1, 0); /* addr + 6 */
|
sqlite3VdbeAddOp1(v, OP_AddImm, -1); /* addr + 6 */
|
||||||
sqlite3VdbeResolveLabel(v, iLabel);
|
sqlite3VdbeResolveLabel(v, iLabel);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -2226,15 +2231,15 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
struct ExprList_item *pLItem = pExpr->pList->a;
|
struct ExprList_item *pLItem = pExpr->pList->a;
|
||||||
Expr *pRight = pLItem->pExpr;
|
Expr *pRight = pLItem->pExpr;
|
||||||
sqlite3ExprCode(pParse, pLeft);
|
sqlite3ExprCode(pParse, pLeft);
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
|
sqlite3VdbeAddOp0(v, OP_Dup);
|
||||||
sqlite3ExprCode(pParse, pRight);
|
sqlite3ExprCode(pParse, pRight);
|
||||||
codeCompare(pParse, pLeft, pRight, OP_Ge, 0, 0);
|
codeCompare(pParse, pLeft, pRight, OP_Ge, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
|
sqlite3VdbeAddOp1(v, OP_Pull, 1);
|
||||||
pLItem++;
|
pLItem++;
|
||||||
pRight = pLItem->pExpr;
|
pRight = pLItem->pExpr;
|
||||||
sqlite3ExprCode(pParse, pRight);
|
sqlite3ExprCode(pParse, pRight);
|
||||||
codeCompare(pParse, pLeft, pRight, OP_Le, 0, 0);
|
codeCompare(pParse, pLeft, pRight, OP_Le, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_And, 0, 0);
|
sqlite3VdbeAddOp0(v, OP_And);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_UPLUS: {
|
case TK_UPLUS: {
|
||||||
@@ -2263,24 +2268,24 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
for(i=0; i<nExpr; i=i+2){
|
for(i=0; i<nExpr; i=i+2){
|
||||||
sqlite3ExprCode(pParse, aListelem[i].pExpr);
|
sqlite3ExprCode(pParse, aListelem[i].pExpr);
|
||||||
if( pExpr->pLeft ){
|
if( pExpr->pLeft ){
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, 1, 1);
|
sqlite3VdbeAddOp2(v, OP_Dup, 1, 1);
|
||||||
jumpInst = codeCompare(pParse, pExpr->pLeft, aListelem[i].pExpr,
|
jumpInst = codeCompare(pParse, pExpr->pLeft, aListelem[i].pExpr,
|
||||||
OP_Ne, 0, 1);
|
OP_Ne, 0, 1);
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
sqlite3VdbeAddOp1(v, OP_Pop, 1);
|
||||||
}else{
|
}else{
|
||||||
jumpInst = sqlite3VdbeAddOp(v, OP_IfNot, 1, 0);
|
jumpInst = sqlite3VdbeAddOp2(v, OP_IfNot, 1, 0);
|
||||||
}
|
}
|
||||||
sqlite3ExprCode(pParse, aListelem[i+1].pExpr);
|
sqlite3ExprCode(pParse, aListelem[i+1].pExpr);
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, expr_end_label);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, expr_end_label);
|
||||||
sqlite3VdbeJumpHere(v, jumpInst);
|
sqlite3VdbeJumpHere(v, jumpInst);
|
||||||
}
|
}
|
||||||
if( pExpr->pLeft ){
|
if( pExpr->pLeft ){
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
|
||||||
}
|
}
|
||||||
if( pExpr->pRight ){
|
if( pExpr->pRight ){
|
||||||
sqlite3ExprCode(pParse, pExpr->pRight);
|
sqlite3ExprCode(pParse, pExpr->pRight);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Null, 0, 0);
|
||||||
}
|
}
|
||||||
sqlite3VdbeResolveLabel(v, expr_end_label);
|
sqlite3VdbeResolveLabel(v, expr_end_label);
|
||||||
break;
|
break;
|
||||||
@@ -2297,12 +2302,12 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
pExpr->iColumn == OE_Abort ||
|
pExpr->iColumn == OE_Abort ||
|
||||||
pExpr->iColumn == OE_Fail );
|
pExpr->iColumn == OE_Fail );
|
||||||
sqlite3DequoteExpr(pParse->db, pExpr);
|
sqlite3DequoteExpr(pParse->db, pExpr);
|
||||||
sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, pExpr->iColumn,
|
sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, pExpr->iColumn, 0,
|
||||||
(char*)pExpr->token.z, pExpr->token.n);
|
(char*)pExpr->token.z, pExpr->token.n);
|
||||||
} else {
|
} else {
|
||||||
assert( pExpr->iColumn == OE_Ignore );
|
assert( pExpr->iColumn == OE_Ignore );
|
||||||
sqlite3VdbeAddOp(v, OP_ContextPop, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_ContextPop, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->trigStack->ignoreJump);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, pParse->trigStack->ignoreJump);
|
||||||
VdbeComment((v, "raise(IGNORE)"));
|
VdbeComment((v, "raise(IGNORE)"));
|
||||||
}
|
}
|
||||||
stackChng = 0;
|
stackChng = 0;
|
||||||
@@ -2340,7 +2345,7 @@ void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr){
|
|||||||
if( addr2>addr1+1
|
if( addr2>addr1+1
|
||||||
|| ((pOp = sqlite3VdbeGetOp(v, addr1))!=0 && pOp->opcode==OP_Function) ){
|
|| ((pOp = sqlite3VdbeGetOp(v, addr1))!=0 && pOp->opcode==OP_Function) ){
|
||||||
iMem = pExpr->iTable = pParse->nMem++;
|
iMem = pExpr->iTable = pParse->nMem++;
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, iMem, 0);
|
sqlite3VdbeAddOp2(v, OP_MemStore, iMem, 0);
|
||||||
pExpr->op = TK_REGISTER;
|
pExpr->op = TK_REGISTER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2362,7 +2367,7 @@ int sqlite3ExprIntoReg(Parse *pParse, Expr *pExpr, int target){
|
|||||||
if( target<0 ){
|
if( target<0 ){
|
||||||
target = pParse->nMem++;
|
target = pParse->nMem++;
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, target, 1);
|
sqlite3VdbeAddOp2(v, OP_MemStore, target, 1);
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2445,7 +2450,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
|||||||
assert( TK_ISNULL==OP_IsNull );
|
assert( TK_ISNULL==OP_IsNull );
|
||||||
assert( TK_NOTNULL==OP_NotNull );
|
assert( TK_NOTNULL==OP_NotNull );
|
||||||
sqlite3ExprCode(pParse, pExpr->pLeft);
|
sqlite3ExprCode(pParse, pExpr->pLeft);
|
||||||
sqlite3VdbeAddOp(v, op, 1, dest);
|
sqlite3VdbeAddOp2(v, op, 1, dest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_BETWEEN: {
|
case TK_BETWEEN: {
|
||||||
@@ -2459,7 +2464,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
|||||||
Expr *pLeft = pExpr->pLeft;
|
Expr *pLeft = pExpr->pLeft;
|
||||||
Expr *pRight = pExpr->pList->a[0].pExpr;
|
Expr *pRight = pExpr->pList->a[0].pExpr;
|
||||||
sqlite3ExprCode(pParse, pLeft);
|
sqlite3ExprCode(pParse, pLeft);
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Dup, 0, 0);
|
||||||
sqlite3ExprCode(pParse, pRight);
|
sqlite3ExprCode(pParse, pRight);
|
||||||
addr = codeCompare(pParse, pLeft, pRight, OP_Lt, 0, !jumpIfNull);
|
addr = codeCompare(pParse, pLeft, pRight, OP_Lt, 0, !jumpIfNull);
|
||||||
|
|
||||||
@@ -2467,14 +2472,14 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
|||||||
sqlite3ExprCode(pParse, pRight);
|
sqlite3ExprCode(pParse, pRight);
|
||||||
codeCompare(pParse, pLeft, pRight, OP_Le, dest, jumpIfNull);
|
codeCompare(pParse, pLeft, pRight, OP_Le, dest, jumpIfNull);
|
||||||
|
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
|
||||||
sqlite3VdbeJumpHere(v, addr);
|
sqlite3VdbeJumpHere(v, addr);
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
sqlite3ExprCode(pParse, pExpr);
|
sqlite3ExprCode(pParse, pExpr);
|
||||||
sqlite3VdbeAddOp(v, OP_If, jumpIfNull, dest);
|
sqlite3VdbeAddOp2(v, OP_If, jumpIfNull, dest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2557,7 +2562,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
|||||||
case TK_ISNULL:
|
case TK_ISNULL:
|
||||||
case TK_NOTNULL: {
|
case TK_NOTNULL: {
|
||||||
sqlite3ExprCode(pParse, pExpr->pLeft);
|
sqlite3ExprCode(pParse, pExpr->pLeft);
|
||||||
sqlite3VdbeAddOp(v, op, 1, dest);
|
sqlite3VdbeAddOp2(v, op, 1, dest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_BETWEEN: {
|
case TK_BETWEEN: {
|
||||||
@@ -2571,13 +2576,13 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
|||||||
Expr *pLeft = pExpr->pLeft;
|
Expr *pLeft = pExpr->pLeft;
|
||||||
Expr *pRight = pExpr->pList->a[0].pExpr;
|
Expr *pRight = pExpr->pList->a[0].pExpr;
|
||||||
sqlite3ExprCode(pParse, pLeft);
|
sqlite3ExprCode(pParse, pLeft);
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Dup, 0, 0);
|
||||||
sqlite3ExprCode(pParse, pRight);
|
sqlite3ExprCode(pParse, pRight);
|
||||||
addr = sqlite3VdbeCurrentAddr(v);
|
addr = sqlite3VdbeCurrentAddr(v);
|
||||||
codeCompare(pParse, pLeft, pRight, OP_Ge, addr+3, !jumpIfNull);
|
codeCompare(pParse, pLeft, pRight, OP_Ge, addr+3, !jumpIfNull);
|
||||||
|
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, dest);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, dest);
|
||||||
pRight = pExpr->pList->a[1].pExpr;
|
pRight = pExpr->pList->a[1].pExpr;
|
||||||
sqlite3ExprCode(pParse, pRight);
|
sqlite3ExprCode(pParse, pRight);
|
||||||
codeCompare(pParse, pLeft, pRight, OP_Gt, dest, jumpIfNull);
|
codeCompare(pParse, pLeft, pRight, OP_Gt, dest, jumpIfNull);
|
||||||
@@ -2585,7 +2590,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
|||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
sqlite3ExprCode(pParse, pExpr);
|
sqlite3ExprCode(pParse, pExpr);
|
||||||
sqlite3VdbeAddOp(v, OP_IfNot, jumpIfNull, dest);
|
sqlite3VdbeAddOp2(v, OP_IfNot, jumpIfNull, dest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
303
src/insert.c
303
src/insert.c
@@ -12,12 +12,12 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle INSERT statements in SQLite.
|
** to handle INSERT statements in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: insert.c,v 1.201 2008/01/02 16:27:10 danielk1977 Exp $
|
** $Id: insert.c,v 1.202 2008/01/03 00:01:24 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Set P3 of the most recently inserted opcode to a column affinity
|
** Set P4 of the most recently inserted opcode to a column affinity
|
||||||
** string for index pIdx. A column affinity string has one character
|
** string for index pIdx. A column affinity string has one character
|
||||||
** for each column in the table, according to the affinity of the column:
|
** for each column in the table, according to the affinity of the column:
|
||||||
**
|
**
|
||||||
@@ -52,11 +52,11 @@ void sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
|
|||||||
pIdx->zColAff[pIdx->nColumn] = '\0';
|
pIdx->zColAff[pIdx->nColumn] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3VdbeChangeP3(v, -1, pIdx->zColAff, 0);
|
sqlite3VdbeChangeP4(v, -1, pIdx->zColAff, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Set P3 of the most recently inserted opcode to a column affinity
|
** Set P4 of the most recently inserted opcode to a column affinity
|
||||||
** string for table pTab. A column affinity string has one character
|
** string for table pTab. A column affinity string has one character
|
||||||
** for each column indexed by the index, according to the affinity of the
|
** for each column indexed by the index, according to the affinity of the
|
||||||
** column:
|
** column:
|
||||||
@@ -95,7 +95,7 @@ void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){
|
|||||||
pTab->zColAff = zColAff;
|
pTab->zColAff = zColAff;
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3VdbeChangeP3(v, -1, pTab->zColAff, 0);
|
sqlite3VdbeChangeP4(v, -1, pTab->zColAff, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -129,9 +129,9 @@ static int readsTable(Vdbe *v, int iStartAddr, int iDb, Table *pTab){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
if( pOp->opcode==OP_VOpen && pOp->p3.p==(const char*)pTab->pVtab ){
|
if( pOp->opcode==OP_VOpen && pOp->p4.p==(const char*)pTab->pVtab ){
|
||||||
assert( pOp->p3.p!=0 );
|
assert( pOp->p4.p!=0 );
|
||||||
assert( pOp->p3type==P3_VTAB );
|
assert( pOp->p4type==P4_VTAB );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -171,17 +171,17 @@ static int autoIncBegin(
|
|||||||
memId = pParse->nMem+1;
|
memId = pParse->nMem+1;
|
||||||
pParse->nMem += 2;
|
pParse->nMem += 2;
|
||||||
sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenRead);
|
sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenRead);
|
||||||
sqlite3VdbeAddOp(v, OP_Rewind, iCur, addr+13);
|
sqlite3VdbeAddOp2(v, OP_Rewind, iCur, addr+13);
|
||||||
sqlite3VdbeAddOp(v, OP_Column, iCur, 0);
|
sqlite3VdbeAddOp2(v, OP_Column, iCur, 0);
|
||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Ne, 0x100, addr+12);
|
sqlite3VdbeAddOp2(v, OP_Ne, 0x100, addr+12);
|
||||||
sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
|
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, memId-1, 1);
|
sqlite3VdbeAddOp2(v, OP_MemStore, memId-1, 1);
|
||||||
sqlite3VdbeAddOp(v, OP_Column, iCur, 1);
|
sqlite3VdbeAddOp2(v, OP_Column, iCur, 1);
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, memId, 1);
|
sqlite3VdbeAddOp2(v, OP_MemStore, memId, 1);
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, addr+13);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, addr+13);
|
||||||
sqlite3VdbeAddOp(v, OP_Next, iCur, addr+4);
|
sqlite3VdbeAddOp2(v, OP_Next, iCur, addr+4);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
|
||||||
}
|
}
|
||||||
return memId;
|
return memId;
|
||||||
}
|
}
|
||||||
@@ -196,7 +196,7 @@ static int autoIncBegin(
|
|||||||
*/
|
*/
|
||||||
static void autoIncStep(Parse *pParse, int memId){
|
static void autoIncStep(Parse *pParse, int memId){
|
||||||
if( memId>0 ){
|
if( memId>0 ){
|
||||||
sqlite3VdbeAddOp(pParse->pVdbe, OP_MemMax, memId, 0);
|
sqlite3VdbeAddOp2(pParse->pVdbe, OP_MemMax, memId, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,15 +219,15 @@ static void autoIncEnd(
|
|||||||
assert( v );
|
assert( v );
|
||||||
addr = sqlite3VdbeCurrentAddr(v);
|
addr = sqlite3VdbeCurrentAddr(v);
|
||||||
sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
|
sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, memId-1, 0);
|
sqlite3VdbeAddOp2(v, OP_MemLoad, memId-1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_NotNull, -1, addr+7);
|
sqlite3VdbeAddOp2(v, OP_NotNull, -1, addr+7);
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_NewRowid, iCur, 0);
|
sqlite3VdbeAddOp2(v, OP_NewRowid, iCur, 0);
|
||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, memId, 0);
|
sqlite3VdbeAddOp2(v, OP_MemLoad, memId, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MakeRecord, 2, 0);
|
sqlite3VdbeAddOp2(v, OP_MakeRecord, 2, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Insert, iCur, OPFLAG_APPEND);
|
sqlite3VdbeAddOp2(v, OP_Insert, iCur, OPFLAG_APPEND);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@@ -478,7 +478,7 @@ void sqlite3Insert(
|
|||||||
*/
|
*/
|
||||||
SelectDest dest = {SRT_Subroutine, 0, 0};
|
SelectDest dest = {SRT_Subroutine, 0, 0};
|
||||||
int rc, iInitCode;
|
int rc, iInitCode;
|
||||||
iInitCode = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
|
iInitCode = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
|
||||||
iSelectLoop = sqlite3VdbeCurrentAddr(v);
|
iSelectLoop = sqlite3VdbeCurrentAddr(v);
|
||||||
iInsertBlock = sqlite3VdbeMakeLabel(v);
|
iInsertBlock = sqlite3VdbeMakeLabel(v);
|
||||||
dest.iParm = iInsertBlock;
|
dest.iParm = iInsertBlock;
|
||||||
@@ -490,7 +490,7 @@ void sqlite3Insert(
|
|||||||
}
|
}
|
||||||
|
|
||||||
iCleanup = sqlite3VdbeMakeLabel(v);
|
iCleanup = sqlite3VdbeMakeLabel(v);
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, iCleanup);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, iCleanup);
|
||||||
assert( pSelect->pEList );
|
assert( pSelect->pEList );
|
||||||
nColumn = pSelect->pEList->nExpr;
|
nColumn = pSelect->pEList->nExpr;
|
||||||
|
|
||||||
@@ -512,21 +512,21 @@ void sqlite3Insert(
|
|||||||
*/
|
*/
|
||||||
srcTab = pParse->nTab++;
|
srcTab = pParse->nTab++;
|
||||||
sqlite3VdbeResolveLabel(v, iInsertBlock);
|
sqlite3VdbeResolveLabel(v, iInsertBlock);
|
||||||
sqlite3VdbeAddOp(v, OP_StackDepth, -1, 0);
|
sqlite3VdbeAddOp2(v, OP_StackDepth, -1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
|
sqlite3VdbeAddOp2(v, OP_MakeRecord, nColumn, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_NewRowid, srcTab, 0);
|
sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Pull, 1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Insert, srcTab, OPFLAG_APPEND);
|
sqlite3VdbeAddOp2(v, OP_Insert, srcTab, OPFLAG_APPEND);
|
||||||
sqlite3VdbeAddOp(v, OP_Return, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
|
||||||
|
|
||||||
/* The following code runs first because the GOTO at the very top
|
/* The following code runs first because the GOTO at the very top
|
||||||
** of the program jumps to it. Create the temporary table, then jump
|
** of the program jumps to it. Create the temporary table, then jump
|
||||||
** back up and execute the SELECT code above.
|
** back up and execute the SELECT code above.
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeJumpHere(v, iInitCode);
|
sqlite3VdbeJumpHere(v, iInitCode);
|
||||||
sqlite3VdbeAddOp(v, OP_OpenEphemeral, srcTab, 0);
|
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_SetNumColumns, srcTab, nColumn);
|
sqlite3VdbeAddOp2(v, OP_SetNumColumns, srcTab, nColumn);
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, iSelectLoop);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, iSelectLoop);
|
||||||
sqlite3VdbeResolveLabel(v, iCleanup);
|
sqlite3VdbeResolveLabel(v, iCleanup);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeJumpHere(v, iInitCode);
|
sqlite3VdbeJumpHere(v, iInitCode);
|
||||||
@@ -616,15 +616,15 @@ void sqlite3Insert(
|
|||||||
/* Open the temp table for FOR EACH ROW triggers
|
/* Open the temp table for FOR EACH ROW triggers
|
||||||
*/
|
*/
|
||||||
if( triggers_exist ){
|
if( triggers_exist ){
|
||||||
sqlite3VdbeAddOp(v, OP_OpenPseudo, newIdx, 0);
|
sqlite3VdbeAddOp2(v, OP_OpenPseudo, newIdx, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_SetNumColumns, newIdx, pTab->nCol);
|
sqlite3VdbeAddOp2(v, OP_SetNumColumns, newIdx, pTab->nCol);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the count of rows to be inserted
|
/* Initialize the count of rows to be inserted
|
||||||
*/
|
*/
|
||||||
if( db->flags & SQLITE_CountRows ){
|
if( db->flags & SQLITE_CountRows ){
|
||||||
iCntMem = pParse->nMem++;
|
iCntMem = pParse->nMem++;
|
||||||
sqlite3VdbeAddOp(v, OP_MemInt, 0, iCntMem);
|
sqlite3VdbeAddOp2(v, OP_MemInt, 0, iCntMem);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this is not a view, open the table and and all indices */
|
/* If this is not a view, open the table and and all indices */
|
||||||
@@ -640,12 +640,12 @@ void sqlite3Insert(
|
|||||||
*/
|
*/
|
||||||
if( useTempTable ){
|
if( useTempTable ){
|
||||||
iBreak = sqlite3VdbeMakeLabel(v);
|
iBreak = sqlite3VdbeMakeLabel(v);
|
||||||
sqlite3VdbeAddOp(v, OP_Rewind, srcTab, iBreak);
|
sqlite3VdbeAddOp2(v, OP_Rewind, srcTab, iBreak);
|
||||||
iCont = sqlite3VdbeCurrentAddr(v);
|
iCont = sqlite3VdbeCurrentAddr(v);
|
||||||
}else if( pSelect ){
|
}else if( pSelect ){
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, iSelectLoop);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, iSelectLoop);
|
||||||
sqlite3VdbeResolveLabel(v, iInsertBlock);
|
sqlite3VdbeResolveLabel(v, iInsertBlock);
|
||||||
sqlite3VdbeAddOp(v, OP_StackDepth, -1, 0);
|
sqlite3VdbeAddOp2(v, OP_StackDepth, -1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Run the BEFORE and INSTEAD OF triggers, if there are any
|
/* Run the BEFORE and INSTEAD OF triggers, if there are any
|
||||||
@@ -660,16 +660,16 @@ void sqlite3Insert(
|
|||||||
** not happened yet) so we substitute a rowid of -1
|
** not happened yet) so we substitute a rowid of -1
|
||||||
*/
|
*/
|
||||||
if( keyColumn<0 ){
|
if( keyColumn<0 ){
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, -1, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, -1, 0);
|
||||||
}else if( useTempTable ){
|
}else if( useTempTable ){
|
||||||
sqlite3VdbeAddOp(v, OP_Column, srcTab, keyColumn);
|
sqlite3VdbeAddOp2(v, OP_Column, srcTab, keyColumn);
|
||||||
}else{
|
}else{
|
||||||
assert( pSelect==0 ); /* Otherwise useTempTable is true */
|
assert( pSelect==0 ); /* Otherwise useTempTable is true */
|
||||||
sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr);
|
sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr);
|
||||||
sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
|
sqlite3VdbeAddOp2(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, -1, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, -1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cannot have triggers on a virtual table. If it were possible,
|
/* Cannot have triggers on a virtual table. If it were possible,
|
||||||
@@ -690,13 +690,13 @@ void sqlite3Insert(
|
|||||||
if( pColumn && j>=pColumn->nId ){
|
if( pColumn && j>=pColumn->nId ){
|
||||||
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt);
|
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt);
|
||||||
}else if( useTempTable ){
|
}else if( useTempTable ){
|
||||||
sqlite3VdbeAddOp(v, OP_Column, srcTab, j);
|
sqlite3VdbeAddOp2(v, OP_Column, srcTab, j);
|
||||||
}else{
|
}else{
|
||||||
assert( pSelect==0 ); /* Otherwise useTempTable is true */
|
assert( pSelect==0 ); /* Otherwise useTempTable is true */
|
||||||
sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr);
|
sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
|
sqlite3VdbeAddOp2(v, OP_MakeRecord, pTab->nCol, 0);
|
||||||
|
|
||||||
/* If this is an INSERT on a view with an INSTEAD OF INSERT trigger,
|
/* If this is an INSERT on a view with an INSTEAD OF INSERT trigger,
|
||||||
** do not attempt any conversions before assembling the record.
|
** do not attempt any conversions before assembling the record.
|
||||||
@@ -706,7 +706,7 @@ void sqlite3Insert(
|
|||||||
if( !isView ){
|
if( !isView ){
|
||||||
sqlite3TableAffinityStr(v, pTab);
|
sqlite3TableAffinityStr(v, pTab);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0);
|
sqlite3VdbeAddOp2(v, OP_Insert, newIdx, 0);
|
||||||
|
|
||||||
/* Fire BEFORE or INSTEAD OF triggers */
|
/* Fire BEFORE or INSTEAD OF triggers */
|
||||||
if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TRIGGER_BEFORE, pTab,
|
if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TRIGGER_BEFORE, pTab,
|
||||||
@@ -723,13 +723,13 @@ void sqlite3Insert(
|
|||||||
if( !isView ){
|
if( !isView ){
|
||||||
if( IsVirtual(pTab) ){
|
if( IsVirtual(pTab) ){
|
||||||
/* The row that the VUpdate opcode will delete: none */
|
/* The row that the VUpdate opcode will delete: none */
|
||||||
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Null, 0, 0);
|
||||||
}
|
}
|
||||||
if( keyColumn>=0 ){
|
if( keyColumn>=0 ){
|
||||||
if( useTempTable ){
|
if( useTempTable ){
|
||||||
sqlite3VdbeAddOp(v, OP_Column, srcTab, keyColumn);
|
sqlite3VdbeAddOp2(v, OP_Column, srcTab, keyColumn);
|
||||||
}else if( pSelect ){
|
}else if( pSelect ){
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, nColumn - keyColumn - 1, 1);
|
sqlite3VdbeAddOp2(v, OP_Dup, nColumn - keyColumn - 1, 1);
|
||||||
}else{
|
}else{
|
||||||
VdbeOp *pOp;
|
VdbeOp *pOp;
|
||||||
sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr);
|
sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr);
|
||||||
@@ -745,15 +745,15 @@ void sqlite3Insert(
|
|||||||
** to generate a unique primary key value.
|
** to generate a unique primary key value.
|
||||||
*/
|
*/
|
||||||
if( !appendFlag ){
|
if( !appendFlag ){
|
||||||
sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
|
sqlite3VdbeAddOp2(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem);
|
sqlite3VdbeAddOp2(v, OP_NewRowid, base, counterMem);
|
||||||
sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0);
|
||||||
}
|
}
|
||||||
}else if( IsVirtual(pTab) ){
|
}else if( IsVirtual(pTab) ){
|
||||||
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Null, 0, 0);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem);
|
sqlite3VdbeAddOp2(v, OP_NewRowid, base, counterMem);
|
||||||
appendFlag = 1;
|
appendFlag = 1;
|
||||||
}
|
}
|
||||||
autoIncStep(pParse, counterMem);
|
autoIncStep(pParse, counterMem);
|
||||||
@@ -768,7 +768,7 @@ void sqlite3Insert(
|
|||||||
** Whenever this column is read, the record number will be substituted
|
** Whenever this column is read, the record number will be substituted
|
||||||
** in its place. So will fill this column with a NULL to avoid
|
** in its place. So will fill this column with a NULL to avoid
|
||||||
** taking up data space with information that will never be used. */
|
** taking up data space with information that will never be used. */
|
||||||
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Null, 0, 0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if( pColumn==0 ){
|
if( pColumn==0 ){
|
||||||
@@ -787,9 +787,9 @@ void sqlite3Insert(
|
|||||||
if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){
|
if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){
|
||||||
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt);
|
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt);
|
||||||
}else if( useTempTable ){
|
}else if( useTempTable ){
|
||||||
sqlite3VdbeAddOp(v, OP_Column, srcTab, j);
|
sqlite3VdbeAddOp2(v, OP_Column, srcTab, j);
|
||||||
}else if( pSelect ){
|
}else if( pSelect ){
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, i+nColumn-j+IsVirtual(pTab), 1);
|
sqlite3VdbeAddOp2(v, OP_Dup, i+nColumn-j+IsVirtual(pTab), 1);
|
||||||
}else{
|
}else{
|
||||||
sqlite3ExprCode(pParse, pList->a[j].pExpr);
|
sqlite3ExprCode(pParse, pList->a[j].pExpr);
|
||||||
}
|
}
|
||||||
@@ -801,8 +801,8 @@ void sqlite3Insert(
|
|||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
if( IsVirtual(pTab) ){
|
if( IsVirtual(pTab) ){
|
||||||
pParse->pVirtualLock = pTab;
|
pParse->pVirtualLock = pTab;
|
||||||
sqlite3VdbeOp3(v, OP_VUpdate, 1, pTab->nCol+2,
|
sqlite3VdbeAddOp4(v, OP_VUpdate, 1, pTab->nCol+2, 0,
|
||||||
(const char*)pTab->pVtab, P3_VTAB);
|
(const char*)pTab->pVtab, P4_VTAB);
|
||||||
}else
|
}else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
@@ -817,7 +817,7 @@ void sqlite3Insert(
|
|||||||
/* Update the count of rows that are inserted
|
/* Update the count of rows that are inserted
|
||||||
*/
|
*/
|
||||||
if( (db->flags & SQLITE_CountRows)!=0 ){
|
if( (db->flags & SQLITE_CountRows)!=0 ){
|
||||||
sqlite3VdbeAddOp(v, OP_MemIncr, 1, iCntMem);
|
sqlite3VdbeAddOp2(v, OP_MemIncr, 1, iCntMem);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( triggers_exist ){
|
if( triggers_exist ){
|
||||||
@@ -832,20 +832,20 @@ void sqlite3Insert(
|
|||||||
*/
|
*/
|
||||||
sqlite3VdbeResolveLabel(v, endOfLoop);
|
sqlite3VdbeResolveLabel(v, endOfLoop);
|
||||||
if( useTempTable ){
|
if( useTempTable ){
|
||||||
sqlite3VdbeAddOp(v, OP_Next, srcTab, iCont);
|
sqlite3VdbeAddOp2(v, OP_Next, srcTab, iCont);
|
||||||
sqlite3VdbeResolveLabel(v, iBreak);
|
sqlite3VdbeResolveLabel(v, iBreak);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, srcTab, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, srcTab, 0);
|
||||||
}else if( pSelect ){
|
}else if( pSelect ){
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0);
|
sqlite3VdbeAddOp2(v, OP_Pop, nColumn, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Return, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
|
||||||
sqlite3VdbeResolveLabel(v, iCleanup);
|
sqlite3VdbeResolveLabel(v, iCleanup);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !IsVirtual(pTab) && !isView ){
|
if( !IsVirtual(pTab) && !isView ){
|
||||||
/* Close all tables opened */
|
/* Close all tables opened */
|
||||||
sqlite3VdbeAddOp(v, OP_Close, base, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, base, 0);
|
||||||
for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
|
for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
|
||||||
sqlite3VdbeAddOp(v, OP_Close, idx+base, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, idx+base, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -861,9 +861,9 @@ void sqlite3Insert(
|
|||||||
** invoke the callback function.
|
** invoke the callback function.
|
||||||
*/
|
*/
|
||||||
if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){
|
if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){
|
||||||
sqlite3VdbeAddOp(v, OP_ResultRow, iCntMem, 1);
|
sqlite3VdbeAddOp2(v, OP_ResultRow, iCntMem, 1);
|
||||||
sqlite3VdbeSetNumCols(v, 1);
|
sqlite3VdbeSetNumCols(v, 1);
|
||||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", P4_STATIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
insert_cleanup:
|
insert_cleanup:
|
||||||
@@ -995,8 +995,8 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){
|
if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){
|
||||||
onError = OE_Abort;
|
onError = OE_Abort;
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, nCol-1-i, 1);
|
sqlite3VdbeAddOp2(v, OP_Dup, nCol-1-i, 1);
|
||||||
addr = sqlite3VdbeAddOp(v, OP_NotNull, 1, 0);
|
addr = sqlite3VdbeAddOp2(v, OP_NotNull, 1, 0);
|
||||||
assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
|
assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
|
||||||
|| onError==OE_Ignore || onError==OE_Replace );
|
|| onError==OE_Ignore || onError==OE_Replace );
|
||||||
switch( onError ){
|
switch( onError ){
|
||||||
@@ -1004,20 +1004,20 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
case OE_Abort:
|
case OE_Abort:
|
||||||
case OE_Fail: {
|
case OE_Fail: {
|
||||||
char *zMsg = 0;
|
char *zMsg = 0;
|
||||||
sqlite3VdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, onError);
|
sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_CONSTRAINT, onError);
|
||||||
sqlite3SetString(&zMsg, pTab->zName, ".", pTab->aCol[i].zName,
|
sqlite3SetString(&zMsg, pTab->zName, ".", pTab->aCol[i].zName,
|
||||||
" may not be NULL", (char*)0);
|
" may not be NULL", (char*)0);
|
||||||
sqlite3VdbeChangeP3(v, -1, zMsg, P3_DYNAMIC);
|
sqlite3VdbeChangeP4(v, -1, zMsg, P4_DYNAMIC);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OE_Ignore: {
|
case OE_Ignore: {
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRowids, 0);
|
sqlite3VdbeAddOp2(v, OP_Pop, nCol+1+hasTwoRowids, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OE_Replace: {
|
case OE_Replace: {
|
||||||
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt);
|
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt);
|
||||||
sqlite3VdbeAddOp(v, OP_Push, nCol-i, 0);
|
sqlite3VdbeAddOp2(v, OP_Push, nCol-i, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1036,10 +1036,10 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
pParse->ckOffset = 0;
|
pParse->ckOffset = 0;
|
||||||
onError = overrideError!=OE_Default ? overrideError : OE_Abort;
|
onError = overrideError!=OE_Default ? overrideError : OE_Abort;
|
||||||
if( onError==OE_Ignore ){
|
if( onError==OE_Ignore ){
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRowids, 0);
|
sqlite3VdbeAddOp2(v, OP_Pop, nCol+1+hasTwoRowids, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, onError);
|
sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_CONSTRAINT, onError);
|
||||||
}
|
}
|
||||||
sqlite3VdbeResolveLabel(v, allOk);
|
sqlite3VdbeResolveLabel(v, allOk);
|
||||||
}
|
}
|
||||||
@@ -1058,12 +1058,12 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( isUpdate ){
|
if( isUpdate ){
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, nCol+1, 1);
|
sqlite3VdbeAddOp2(v, OP_Dup, nCol+1, 1);
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, nCol+1, 1);
|
sqlite3VdbeAddOp2(v, OP_Dup, nCol+1, 1);
|
||||||
jumpInst1 = sqlite3VdbeAddOp(v, OP_Eq, 0, 0);
|
jumpInst1 = sqlite3VdbeAddOp2(v, OP_Eq, 0, 0);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, nCol, 1);
|
sqlite3VdbeAddOp2(v, OP_Dup, nCol, 1);
|
||||||
jumpInst2 = sqlite3VdbeAddOp(v, OP_NotExists, base, 0);
|
jumpInst2 = sqlite3VdbeAddOp2(v, OP_NotExists, base, 0);
|
||||||
switch( onError ){
|
switch( onError ){
|
||||||
default: {
|
default: {
|
||||||
onError = OE_Abort;
|
onError = OE_Abort;
|
||||||
@@ -1072,31 +1072,31 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
case OE_Rollback:
|
case OE_Rollback:
|
||||||
case OE_Abort:
|
case OE_Abort:
|
||||||
case OE_Fail: {
|
case OE_Fail: {
|
||||||
sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError,
|
sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0,
|
||||||
"PRIMARY KEY must be unique", P3_STATIC);
|
"PRIMARY KEY must be unique", P4_STATIC);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OE_Replace: {
|
case OE_Replace: {
|
||||||
sqlite3GenerateRowIndexDelete(v, pTab, base, 0);
|
sqlite3GenerateRowIndexDelete(v, pTab, base, 0);
|
||||||
if( isUpdate ){
|
if( isUpdate ){
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, nCol+hasTwoRowids, 1);
|
sqlite3VdbeAddOp2(v, OP_Dup, nCol+hasTwoRowids, 1);
|
||||||
sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
|
sqlite3VdbeAddOp2(v, OP_MoveGe, base, 0);
|
||||||
}
|
}
|
||||||
seenReplace = 1;
|
seenReplace = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OE_Ignore: {
|
case OE_Ignore: {
|
||||||
assert( seenReplace==0 );
|
assert( seenReplace==0 );
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRowids, 0);
|
sqlite3VdbeAddOp2(v, OP_Pop, nCol+1+hasTwoRowids, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3VdbeJumpHere(v, jumpInst2);
|
sqlite3VdbeJumpHere(v, jumpInst2);
|
||||||
if( isUpdate ){
|
if( isUpdate ){
|
||||||
sqlite3VdbeJumpHere(v, jumpInst1);
|
sqlite3VdbeJumpHere(v, jumpInst1);
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, nCol+1, 1);
|
sqlite3VdbeAddOp2(v, OP_Dup, nCol+1, 1);
|
||||||
sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
|
sqlite3VdbeAddOp2(v, OP_MoveGe, base, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1110,16 +1110,16 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
extra++;
|
extra++;
|
||||||
|
|
||||||
/* Create a key for accessing the index entry */
|
/* Create a key for accessing the index entry */
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, nCol+extra, 1);
|
sqlite3VdbeAddOp2(v, OP_Dup, nCol+extra, 1);
|
||||||
for(i=0; i<pIdx->nColumn; i++){
|
for(i=0; i<pIdx->nColumn; i++){
|
||||||
int idx = pIdx->aiColumn[i];
|
int idx = pIdx->aiColumn[i];
|
||||||
if( idx==pTab->iPKey ){
|
if( idx==pTab->iPKey ){
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, i+extra+nCol+1, 1);
|
sqlite3VdbeAddOp2(v, OP_Dup, i+extra+nCol+1, 1);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, i+extra+nCol-idx, 1);
|
sqlite3VdbeAddOp2(v, OP_Dup, i+extra+nCol-idx, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
jumpInst1 = sqlite3VdbeAddOp(v, OP_MakeIdxRec, pIdx->nColumn, 0);
|
jumpInst1 = sqlite3VdbeAddOp2(v, OP_MakeIdxRec, pIdx->nColumn, 0);
|
||||||
sqlite3IndexAffinityStr(v, pIdx);
|
sqlite3IndexAffinityStr(v, pIdx);
|
||||||
|
|
||||||
/* Find out what action to take in case there is an indexing conflict */
|
/* Find out what action to take in case there is an indexing conflict */
|
||||||
@@ -1137,8 +1137,8 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
|
|
||||||
|
|
||||||
/* Check to see if the new index entry will be unique */
|
/* Check to see if the new index entry will be unique */
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, extra+nCol+1+hasTwoRowids, 1);
|
sqlite3VdbeAddOp2(v, OP_Dup, extra+nCol+1+hasTwoRowids, 1);
|
||||||
jumpInst2 = sqlite3VdbeAddOp(v, OP_IsUnique, base+iCur+1, 0);
|
jumpInst2 = sqlite3VdbeAddOp2(v, OP_IsUnique, base+iCur+1, 0);
|
||||||
|
|
||||||
/* Generate code that executes if the new index entry is not unique */
|
/* Generate code that executes if the new index entry is not unique */
|
||||||
assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
|
assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
|
||||||
@@ -1170,20 +1170,20 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
}
|
}
|
||||||
sqlite3_snprintf(sizeof(zErrMsg)-n1, &zErrMsg[n1],
|
sqlite3_snprintf(sizeof(zErrMsg)-n1, &zErrMsg[n1],
|
||||||
pIdx->nColumn>1 ? " are not unique" : " is not unique");
|
pIdx->nColumn>1 ? " are not unique" : " is not unique");
|
||||||
sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError, zErrMsg, 0);
|
sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0, zErrMsg,0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OE_Ignore: {
|
case OE_Ignore: {
|
||||||
assert( seenReplace==0 );
|
assert( seenReplace==0 );
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, nCol+extra+3+hasTwoRowids, 0);
|
sqlite3VdbeAddOp2(v, OP_Pop, nCol+extra+3+hasTwoRowids, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OE_Replace: {
|
case OE_Replace: {
|
||||||
sqlite3GenerateRowDelete(pParse->db, v, pTab, base, 0);
|
sqlite3GenerateRowDelete(pParse->db, v, pTab, base, 0);
|
||||||
if( isUpdate ){
|
if( isUpdate ){
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, nCol+extra+1+hasTwoRowids, 1);
|
sqlite3VdbeAddOp2(v, OP_Dup, nCol+extra+1+hasTwoRowids, 1);
|
||||||
sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
|
sqlite3VdbeAddOp2(v, OP_MoveGe, base, 0);
|
||||||
}
|
}
|
||||||
seenReplace = 1;
|
seenReplace = 1;
|
||||||
break;
|
break;
|
||||||
@@ -1228,15 +1228,15 @@ void sqlite3CompleteInsertion(
|
|||||||
for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
|
for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
|
||||||
for(i=nIdx-1; i>=0; i--){
|
for(i=nIdx-1; i>=0; i--){
|
||||||
if( aIdxUsed && aIdxUsed[i]==0 ) continue;
|
if( aIdxUsed && aIdxUsed[i]==0 ) continue;
|
||||||
sqlite3VdbeAddOp(v, OP_IdxInsert, base+i+1, 0);
|
sqlite3VdbeAddOp2(v, OP_IdxInsert, base+i+1, 0);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
|
sqlite3VdbeAddOp2(v, OP_MakeRecord, pTab->nCol, 0);
|
||||||
sqlite3TableAffinityStr(v, pTab);
|
sqlite3TableAffinityStr(v, pTab);
|
||||||
#ifndef SQLITE_OMIT_TRIGGER
|
#ifndef SQLITE_OMIT_TRIGGER
|
||||||
if( newIdx>=0 ){
|
if( newIdx>=0 ){
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Dup, 1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Dup, 1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0);
|
sqlite3VdbeAddOp2(v, OP_Insert, newIdx, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if( pParse->nested ){
|
if( pParse->nested ){
|
||||||
@@ -1248,13 +1248,13 @@ void sqlite3CompleteInsertion(
|
|||||||
if( appendBias ){
|
if( appendBias ){
|
||||||
pik_flags |= OPFLAG_APPEND;
|
pik_flags |= OPFLAG_APPEND;
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_Insert, base, pik_flags);
|
sqlite3VdbeAddOp2(v, OP_Insert, base, pik_flags);
|
||||||
if( !pParse->nested ){
|
if( !pParse->nested ){
|
||||||
sqlite3VdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
|
sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( isUpdate && rowidChng ){
|
if( isUpdate && rowidChng ){
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1282,9 +1282,10 @@ void sqlite3OpenTableAndIndices(
|
|||||||
for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
||||||
KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
|
KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
|
||||||
assert( pIdx->pSchema==pTab->pSchema );
|
assert( pIdx->pSchema==pTab->pSchema );
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, iDb, 0);
|
||||||
VdbeComment((v, "%s", pIdx->zName));
|
VdbeComment((v, "%s", pIdx->zName));
|
||||||
sqlite3VdbeOp3(v, op, i+base, pIdx->tnum, (char*)pKey, P3_KEYINFO_HANDOFF);
|
sqlite3VdbeAddOp4(v, op, i+base, pIdx->tnum, 0,
|
||||||
|
(char*)pKey, P4_KEYINFO_HANDOFF);
|
||||||
}
|
}
|
||||||
if( pParse->nTab<=base+i ){
|
if( pParse->nTab<=base+i ){
|
||||||
pParse->nTab = base+i;
|
pParse->nTab = base+i;
|
||||||
@@ -1545,64 +1546,64 @@ static int xferOptimization(
|
|||||||
** insure that all entries in the union of DEST and SRC will be
|
** insure that all entries in the union of DEST and SRC will be
|
||||||
** unique.
|
** unique.
|
||||||
*/
|
*/
|
||||||
addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iDest, 0);
|
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0);
|
||||||
emptyDestTest = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
|
emptyDestTest = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
|
||||||
sqlite3VdbeJumpHere(v, addr1);
|
sqlite3VdbeJumpHere(v, addr1);
|
||||||
}else{
|
}else{
|
||||||
emptyDestTest = 0;
|
emptyDestTest = 0;
|
||||||
}
|
}
|
||||||
sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead);
|
sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead);
|
||||||
emptySrcTest = sqlite3VdbeAddOp(v, OP_Rewind, iSrc, 0);
|
emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
|
||||||
if( pDest->iPKey>=0 ){
|
if( pDest->iPKey>=0 ){
|
||||||
addr1 = sqlite3VdbeAddOp(v, OP_Rowid, iSrc, 0);
|
addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Dup, 0, 0);
|
||||||
addr2 = sqlite3VdbeAddOp(v, OP_NotExists, iDest, 0);
|
addr2 = sqlite3VdbeAddOp2(v, OP_NotExists, iDest, 0);
|
||||||
sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError,
|
sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0,
|
||||||
"PRIMARY KEY must be unique", P3_STATIC);
|
"PRIMARY KEY must be unique", P4_STATIC);
|
||||||
sqlite3VdbeJumpHere(v, addr2);
|
sqlite3VdbeJumpHere(v, addr2);
|
||||||
autoIncStep(pParse, counterMem);
|
autoIncStep(pParse, counterMem);
|
||||||
}else if( pDest->pIndex==0 ){
|
}else if( pDest->pIndex==0 ){
|
||||||
addr1 = sqlite3VdbeAddOp(v, OP_NewRowid, iDest, 0);
|
addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, 0);
|
||||||
}else{
|
}else{
|
||||||
addr1 = sqlite3VdbeAddOp(v, OP_Rowid, iSrc, 0);
|
addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, 0);
|
||||||
assert( pDest->autoInc==0 );
|
assert( pDest->autoInc==0 );
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_RowData, iSrc, 0);
|
sqlite3VdbeAddOp2(v, OP_RowData, iSrc, 0);
|
||||||
sqlite3VdbeOp3(v, OP_Insert, iDest,
|
sqlite3VdbeAddOp4(v, OP_Insert, iDest, 0,
|
||||||
OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND,
|
OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND,
|
||||||
pDest->zName, 0);
|
pDest->zName, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Next, iSrc, addr1);
|
sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1);
|
||||||
autoIncEnd(pParse, iDbDest, pDest, counterMem);
|
autoIncEnd(pParse, iDbDest, pDest, counterMem);
|
||||||
for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
|
for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
|
||||||
for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){
|
for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){
|
||||||
if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
|
if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
|
||||||
}
|
}
|
||||||
assert( pSrcIdx );
|
assert( pSrcIdx );
|
||||||
sqlite3VdbeAddOp(v, OP_Close, iSrc, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, iDest, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, iDbSrc, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, iDbSrc, 0);
|
||||||
pKey = sqlite3IndexKeyinfo(pParse, pSrcIdx);
|
pKey = sqlite3IndexKeyinfo(pParse, pSrcIdx);
|
||||||
VdbeComment((v, "%s", pSrcIdx->zName));
|
VdbeComment((v, "%s", pSrcIdx->zName));
|
||||||
sqlite3VdbeOp3(v, OP_OpenRead, iSrc, pSrcIdx->tnum,
|
sqlite3VdbeAddOp4(v, OP_OpenRead, iSrc, pSrcIdx->tnum, 0,
|
||||||
(char*)pKey, P3_KEYINFO_HANDOFF);
|
(char*)pKey, P4_KEYINFO_HANDOFF);
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, iDbDest, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, iDbDest, 0);
|
||||||
pKey = sqlite3IndexKeyinfo(pParse, pDestIdx);
|
pKey = sqlite3IndexKeyinfo(pParse, pDestIdx);
|
||||||
VdbeComment((v, "%s", pDestIdx->zName));
|
VdbeComment((v, "%s", pDestIdx->zName));
|
||||||
sqlite3VdbeOp3(v, OP_OpenWrite, iDest, pDestIdx->tnum,
|
sqlite3VdbeAddOp4(v, OP_OpenWrite, iDest, pDestIdx->tnum, 0,
|
||||||
(char*)pKey, P3_KEYINFO_HANDOFF);
|
(char*)pKey, P4_KEYINFO_HANDOFF);
|
||||||
addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iSrc, 0);
|
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_RowKey, iSrc, 0);
|
sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_IdxInsert, iDest, 1);
|
sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, 1);
|
||||||
sqlite3VdbeAddOp(v, OP_Next, iSrc, addr1+1);
|
sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1);
|
||||||
sqlite3VdbeJumpHere(v, addr1);
|
sqlite3VdbeJumpHere(v, addr1);
|
||||||
}
|
}
|
||||||
sqlite3VdbeJumpHere(v, emptySrcTest);
|
sqlite3VdbeJumpHere(v, emptySrcTest);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, iSrc, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, iDest, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
|
||||||
if( emptyDestTest ){
|
if( emptyDestTest ){
|
||||||
sqlite3VdbeAddOp(v, OP_Halt, SQLITE_OK, 0);
|
sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, 0);
|
||||||
sqlite3VdbeJumpHere(v, emptyDestTest);
|
sqlite3VdbeJumpHere(v, emptyDestTest);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, iDest, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}else{
|
}else{
|
||||||
return 1;
|
return 1;
|
||||||
|
218
src/pragma.c
218
src/pragma.c
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** This file contains code used to implement the PRAGMA command.
|
** This file contains code used to implement the PRAGMA command.
|
||||||
**
|
**
|
||||||
** $Id: pragma.c,v 1.154 2008/01/02 00:34:37 drh Exp $
|
** $Id: pragma.c,v 1.155 2008/01/03 00:01:24 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -148,12 +148,12 @@ static int changeTempStorage(Parse *pParse, const char *zStorageType){
|
|||||||
static void returnSingleInt(Parse *pParse, const char *zLabel, int value){
|
static void returnSingleInt(Parse *pParse, const char *zLabel, int value){
|
||||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||||
int mem = pParse->nMem++;
|
int mem = pParse->nMem++;
|
||||||
sqlite3VdbeAddOp(v, OP_MemInt, value, mem);
|
sqlite3VdbeAddOp2(v, OP_MemInt, value, mem);
|
||||||
if( pParse->explain==0 ){
|
if( pParse->explain==0 ){
|
||||||
sqlite3VdbeSetNumCols(v, 1);
|
sqlite3VdbeSetNumCols(v, 1);
|
||||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, P4_STATIC);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_ResultRow, mem, 1);
|
sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_FLAG_PRAGMAS
|
#ifndef SQLITE_OMIT_FLAG_PRAGMAS
|
||||||
@@ -210,7 +210,7 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
|
|||||||
** compiler (eg. count_changes). So add an opcode to expire all
|
** compiler (eg. count_changes). So add an opcode to expire all
|
||||||
** compiled SQL statements after modifying a pragma value.
|
** compiled SQL statements after modifying a pragma value.
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp(v, OP_Expire, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Expire, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,7 +311,7 @@ void sqlite3Pragma(
|
|||||||
sqlite3VdbeUsesBtree(v, iDb);
|
sqlite3VdbeUsesBtree(v, iDb);
|
||||||
if( !zRight ){
|
if( !zRight ){
|
||||||
sqlite3VdbeSetNumCols(v, 1);
|
sqlite3VdbeSetNumCols(v, 1);
|
||||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", P4_STATIC);
|
||||||
addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
|
addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
|
||||||
sqlite3VdbeChangeP1(v, addr, iDb);
|
sqlite3VdbeChangeP1(v, addr, iDb);
|
||||||
sqlite3VdbeChangeP1(v, addr+5, SQLITE_DEFAULT_CACHE_SIZE);
|
sqlite3VdbeChangeP1(v, addr+5, SQLITE_DEFAULT_CACHE_SIZE);
|
||||||
@@ -319,12 +319,12 @@ void sqlite3Pragma(
|
|||||||
int size = atoi(zRight);
|
int size = atoi(zRight);
|
||||||
if( size<0 ) size = -size;
|
if( size<0 ) size = -size;
|
||||||
sqlite3BeginWriteOperation(pParse, 0, iDb);
|
sqlite3BeginWriteOperation(pParse, 0, iDb);
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, size, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, size, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 2);
|
sqlite3VdbeAddOp2(v, OP_ReadCookie, iDb, 2);
|
||||||
addr = sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
|
addr = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Ge, 0, addr+3);
|
sqlite3VdbeAddOp2(v, OP_Ge, 0, addr+3);
|
||||||
sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Negative, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 2);
|
sqlite3VdbeAddOp2(v, OP_SetCookie, iDb, 2);
|
||||||
pDb->pSchema->cache_size = size;
|
pDb->pSchema->cache_size = size;
|
||||||
sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
|
sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
|
||||||
}
|
}
|
||||||
@@ -417,9 +417,9 @@ void sqlite3Pragma(
|
|||||||
zRet = "exclusive";
|
zRet = "exclusive";
|
||||||
}
|
}
|
||||||
sqlite3VdbeSetNumCols(v, 1);
|
sqlite3VdbeSetNumCols(v, 1);
|
||||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "locking_mode", P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "locking_mode", P4_STATIC);
|
||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, zRet, 0);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, zRet, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Callback, 1, 0);
|
||||||
}else
|
}else
|
||||||
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
|
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
|
||||||
|
|
||||||
@@ -492,11 +492,11 @@ void sqlite3Pragma(
|
|||||||
iLimit = 0x7fffffff;
|
iLimit = 0x7fffffff;
|
||||||
}
|
}
|
||||||
sqlite3BeginWriteOperation(pParse, 0, iDb);
|
sqlite3BeginWriteOperation(pParse, 0, iDb);
|
||||||
sqlite3VdbeAddOp(v, OP_MemInt, iLimit, 0);
|
sqlite3VdbeAddOp2(v, OP_MemInt, iLimit, 0);
|
||||||
addr = sqlite3VdbeAddOp(v, OP_IncrVacuum, iDb, 0);
|
addr = sqlite3VdbeAddOp2(v, OP_IncrVacuum, iDb, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Callback, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Callback, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MemIncr, -1, 0);
|
sqlite3VdbeAddOp2(v, OP_MemIncr, -1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_IfMemPos, 0, addr);
|
sqlite3VdbeAddOp2(v, OP_IfMemPos, 0, addr);
|
||||||
sqlite3VdbeJumpHere(v, addr);
|
sqlite3VdbeJumpHere(v, addr);
|
||||||
}else
|
}else
|
||||||
#endif
|
#endif
|
||||||
@@ -562,9 +562,9 @@ void sqlite3Pragma(
|
|||||||
if( sqlite3_temp_directory ){
|
if( sqlite3_temp_directory ){
|
||||||
sqlite3VdbeSetNumCols(v, 1);
|
sqlite3VdbeSetNumCols(v, 1);
|
||||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME,
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME,
|
||||||
"temp_store_directory", P3_STATIC);
|
"temp_store_directory", P4_STATIC);
|
||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, sqlite3_temp_directory, 0);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, sqlite3_temp_directory, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Callback, 1, 0);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
if( zRight[0]
|
if( zRight[0]
|
||||||
@@ -642,12 +642,12 @@ void sqlite3Pragma(
|
|||||||
int nHidden = 0;
|
int nHidden = 0;
|
||||||
Column *pCol;
|
Column *pCol;
|
||||||
sqlite3VdbeSetNumCols(v, 6);
|
sqlite3VdbeSetNumCols(v, 6);
|
||||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", P4_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC);
|
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P4_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "type", P3_STATIC);
|
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "type", P4_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "notnull", P3_STATIC);
|
sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "notnull", P4_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "dflt_value", P3_STATIC);
|
sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "dflt_value", P4_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "pk", P3_STATIC);
|
sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "pk", P4_STATIC);
|
||||||
sqlite3ViewGetColumnNames(pParse, pTab);
|
sqlite3ViewGetColumnNames(pParse, pTab);
|
||||||
for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
|
for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
|
||||||
const Token *pDflt;
|
const Token *pDflt;
|
||||||
@@ -655,18 +655,18 @@ void sqlite3Pragma(
|
|||||||
nHidden++;
|
nHidden++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, i-nHidden, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, i-nHidden, 0);
|
||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, pCol->zName, 0);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pCol->zName, 0);
|
||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0,
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0,
|
||||||
pCol->zType ? pCol->zType : "", 0);
|
pCol->zType ? pCol->zType : "", 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, pCol->notNull, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, pCol->notNull, 0);
|
||||||
if( pCol->pDflt && (pDflt = &pCol->pDflt->span)->z ){
|
if( pCol->pDflt && (pDflt = &pCol->pDflt->span)->z ){
|
||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, (char*)pDflt->z, pDflt->n);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, (char*)pDflt->z, pDflt->n);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Null, 0, 0);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, pCol->isPrimKey, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, pCol->isPrimKey, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Callback, 6, 0);
|
sqlite3VdbeAddOp2(v, OP_Callback, 6, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else
|
}else
|
||||||
@@ -680,16 +680,16 @@ void sqlite3Pragma(
|
|||||||
int i;
|
int i;
|
||||||
pTab = pIdx->pTable;
|
pTab = pIdx->pTable;
|
||||||
sqlite3VdbeSetNumCols(v, 3);
|
sqlite3VdbeSetNumCols(v, 3);
|
||||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", P4_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", P3_STATIC);
|
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", P4_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", P3_STATIC);
|
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", P4_STATIC);
|
||||||
for(i=0; i<pIdx->nColumn; i++){
|
for(i=0; i<pIdx->nColumn; i++){
|
||||||
int cnum = pIdx->aiColumn[i];
|
int cnum = pIdx->aiColumn[i];
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, i, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, cnum, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, cnum, 0);
|
||||||
assert( pTab->nCol>cnum );
|
assert( pTab->nCol>cnum );
|
||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->aCol[cnum].zName, 0);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->aCol[cnum].zName, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Callback, 3, 0);
|
sqlite3VdbeAddOp2(v, OP_Callback, 3, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else
|
}else
|
||||||
@@ -705,14 +705,14 @@ void sqlite3Pragma(
|
|||||||
if( pIdx ){
|
if( pIdx ){
|
||||||
int i = 0;
|
int i = 0;
|
||||||
sqlite3VdbeSetNumCols(v, 3);
|
sqlite3VdbeSetNumCols(v, 3);
|
||||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P4_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC);
|
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P4_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", P3_STATIC);
|
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", P4_STATIC);
|
||||||
while(pIdx){
|
while(pIdx){
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, i, 0);
|
||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, pIdx->zName, 0);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pIdx->zName, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, pIdx->onError!=OE_None, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->onError!=OE_None, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Callback, 3, 0);
|
sqlite3VdbeAddOp2(v, OP_Callback, 3, 0);
|
||||||
++i;
|
++i;
|
||||||
pIdx = pIdx->pNext;
|
pIdx = pIdx->pNext;
|
||||||
}
|
}
|
||||||
@@ -724,17 +724,17 @@ void sqlite3Pragma(
|
|||||||
int i;
|
int i;
|
||||||
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
||||||
sqlite3VdbeSetNumCols(v, 3);
|
sqlite3VdbeSetNumCols(v, 3);
|
||||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P4_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC);
|
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P4_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "file", P3_STATIC);
|
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "file", P4_STATIC);
|
||||||
for(i=0; i<db->nDb; i++){
|
for(i=0; i<db->nDb; i++){
|
||||||
if( db->aDb[i].pBt==0 ) continue;
|
if( db->aDb[i].pBt==0 ) continue;
|
||||||
assert( db->aDb[i].zName!=0 );
|
assert( db->aDb[i].zName!=0 );
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, i, 0);
|
||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, db->aDb[i].zName, 0);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, db->aDb[i].zName, 0);
|
||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0,
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0,
|
||||||
sqlite3BtreeGetFilename(db->aDb[i].pBt), 0);
|
sqlite3BtreeGetFilename(db->aDb[i].pBt), 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Callback, 3, 0);
|
sqlite3VdbeAddOp2(v, OP_Callback, 3, 0);
|
||||||
}
|
}
|
||||||
}else
|
}else
|
||||||
|
|
||||||
@@ -742,13 +742,13 @@ void sqlite3Pragma(
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
HashElem *p;
|
HashElem *p;
|
||||||
sqlite3VdbeSetNumCols(v, 2);
|
sqlite3VdbeSetNumCols(v, 2);
|
||||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P4_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC);
|
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P4_STATIC);
|
||||||
for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){
|
for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){
|
||||||
CollSeq *pColl = (CollSeq *)sqliteHashData(p);
|
CollSeq *pColl = (CollSeq *)sqliteHashData(p);
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, i++, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, i++, 0);
|
||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, pColl->zName, 0);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pColl->zName, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Callback, 2, 0);
|
sqlite3VdbeAddOp2(v, OP_Callback, 2, 0);
|
||||||
}
|
}
|
||||||
}else
|
}else
|
||||||
#endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */
|
#endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */
|
||||||
@@ -765,22 +765,22 @@ void sqlite3Pragma(
|
|||||||
if( pFK ){
|
if( pFK ){
|
||||||
int i = 0;
|
int i = 0;
|
||||||
sqlite3VdbeSetNumCols(v, 5);
|
sqlite3VdbeSetNumCols(v, 5);
|
||||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "id", P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "id", P4_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "seq", P3_STATIC);
|
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "seq", P4_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "table", P3_STATIC);
|
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "table", P4_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "from", P3_STATIC);
|
sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "from", P4_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "to", P3_STATIC);
|
sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "to", P4_STATIC);
|
||||||
while(pFK){
|
while(pFK){
|
||||||
int j;
|
int j;
|
||||||
for(j=0; j<pFK->nCol; j++){
|
for(j=0; j<pFK->nCol; j++){
|
||||||
char *zCol = pFK->aCol[j].zCol;
|
char *zCol = pFK->aCol[j].zCol;
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, i, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, j, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, j, 0);
|
||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, pFK->zTo, 0);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pFK->zTo, 0);
|
||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0,
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0,
|
||||||
pTab->aCol[pFK->aCol[j].iFrom].zName, 0);
|
pTab->aCol[pFK->aCol[j].iFrom].zName, 0);
|
||||||
sqlite3VdbeOp3(v, zCol ? OP_String8 : OP_Null, 0, 0, zCol, 0);
|
sqlite3VdbeAddOp4(v, zCol ? OP_String8 : OP_Null, 0, 0, 0, zCol, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Callback, 5, 0);
|
sqlite3VdbeAddOp2(v, OP_Callback, 5, 0);
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
pFK = pFK->pNextFrom;
|
pFK = pFK->pNextFrom;
|
||||||
@@ -842,7 +842,7 @@ void sqlite3Pragma(
|
|||||||
/* Initialize the VDBE program */
|
/* Initialize the VDBE program */
|
||||||
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
||||||
sqlite3VdbeSetNumCols(v, 1);
|
sqlite3VdbeSetNumCols(v, 1);
|
||||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", P4_STATIC);
|
||||||
|
|
||||||
/* Set the maximum error count */
|
/* Set the maximum error count */
|
||||||
mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
|
mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
|
||||||
@@ -852,7 +852,7 @@ void sqlite3Pragma(
|
|||||||
mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
|
mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_MemInt, mxErr, 0);
|
sqlite3VdbeAddOp2(v, OP_MemInt, mxErr, 0);
|
||||||
|
|
||||||
/* Do an integrity check on each database file */
|
/* Do an integrity check on each database file */
|
||||||
for(i=0; i<db->nDb; i++){
|
for(i=0; i<db->nDb; i++){
|
||||||
@@ -863,8 +863,8 @@ void sqlite3Pragma(
|
|||||||
if( OMIT_TEMPDB && i==1 ) continue;
|
if( OMIT_TEMPDB && i==1 ) continue;
|
||||||
|
|
||||||
sqlite3CodeVerifySchema(pParse, i);
|
sqlite3CodeVerifySchema(pParse, i);
|
||||||
addr = sqlite3VdbeAddOp(v, OP_IfMemPos, 0, 0);
|
addr = sqlite3VdbeAddOp2(v, OP_IfMemPos, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
||||||
sqlite3VdbeJumpHere(v, addr);
|
sqlite3VdbeJumpHere(v, addr);
|
||||||
|
|
||||||
/* Do an integrity check of the B-Tree
|
/* Do an integrity check of the B-Tree
|
||||||
@@ -873,22 +873,22 @@ void sqlite3Pragma(
|
|||||||
for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
|
for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
|
||||||
Table *pTab = sqliteHashData(x);
|
Table *pTab = sqliteHashData(x);
|
||||||
Index *pIdx;
|
Index *pIdx;
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, pTab->tnum, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, pTab->tnum, 0);
|
||||||
cnt++;
|
cnt++;
|
||||||
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, pIdx->tnum, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->tnum, 0);
|
||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( cnt==0 ) continue;
|
if( cnt==0 ) continue;
|
||||||
sqlite3VdbeAddOp(v, OP_IntegrityCk, 0, i);
|
sqlite3VdbeAddOp2(v, OP_IntegrityCk, 0, i);
|
||||||
addr = sqlite3VdbeAddOp(v, OP_IsNull, -1, 0);
|
addr = sqlite3VdbeAddOp2(v, OP_IsNull, -1, 0);
|
||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0,
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0,
|
||||||
sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName),
|
sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName),
|
||||||
P3_DYNAMIC);
|
P4_DYNAMIC);
|
||||||
sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Pull, 1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Concat, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Concat, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Callback, 1, 0);
|
||||||
sqlite3VdbeJumpHere(v, addr);
|
sqlite3VdbeJumpHere(v, addr);
|
||||||
|
|
||||||
/* Make sure all the indices are constructed correctly.
|
/* Make sure all the indices are constructed correctly.
|
||||||
@@ -899,13 +899,13 @@ void sqlite3Pragma(
|
|||||||
int loopTop;
|
int loopTop;
|
||||||
|
|
||||||
if( pTab->pIndex==0 ) continue;
|
if( pTab->pIndex==0 ) continue;
|
||||||
addr = sqlite3VdbeAddOp(v, OP_IfMemPos, 0, 0);
|
addr = sqlite3VdbeAddOp2(v, OP_IfMemPos, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
||||||
sqlite3VdbeJumpHere(v, addr);
|
sqlite3VdbeJumpHere(v, addr);
|
||||||
sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
|
sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
|
||||||
sqlite3VdbeAddOp(v, OP_MemInt, 0, 1);
|
sqlite3VdbeAddOp2(v, OP_MemInt, 0, 1);
|
||||||
loopTop = sqlite3VdbeAddOp(v, OP_Rewind, 1, 0);
|
loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MemIncr, 1, 1);
|
sqlite3VdbeAddOp2(v, OP_MemIncr, 1, 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;
|
int jmp2;
|
||||||
static const VdbeOpList idxErr[] = {
|
static const VdbeOpList idxErr[] = {
|
||||||
@@ -918,12 +918,12 @@ void sqlite3Pragma(
|
|||||||
{ OP_Callback, 1, 0, 0},
|
{ OP_Callback, 1, 0, 0},
|
||||||
};
|
};
|
||||||
sqlite3GenerateIndexKey(v, pIdx, 1);
|
sqlite3GenerateIndexKey(v, pIdx, 1);
|
||||||
jmp2 = sqlite3VdbeAddOp(v, OP_Found, j+2, 0);
|
jmp2 = sqlite3VdbeAddOp2(v, OP_Found, j+2, 0);
|
||||||
addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
|
addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
|
||||||
sqlite3VdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC);
|
sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_STATIC);
|
||||||
sqlite3VdbeJumpHere(v, jmp2);
|
sqlite3VdbeJumpHere(v, jmp2);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_Next, 1, loopTop+1);
|
sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop+1);
|
||||||
sqlite3VdbeJumpHere(v, loopTop);
|
sqlite3VdbeJumpHere(v, loopTop);
|
||||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||||
static const VdbeOpList cntIdx[] = {
|
static const VdbeOpList cntIdx[] = {
|
||||||
@@ -941,8 +941,8 @@ void sqlite3Pragma(
|
|||||||
{ OP_Callback, 1, 0, 0},
|
{ OP_Callback, 1, 0, 0},
|
||||||
};
|
};
|
||||||
if( pIdx->tnum==0 ) continue;
|
if( pIdx->tnum==0 ) continue;
|
||||||
addr = sqlite3VdbeAddOp(v, OP_IfMemPos, 0, 0);
|
addr = sqlite3VdbeAddOp2(v, OP_IfMemPos, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
||||||
sqlite3VdbeJumpHere(v, addr);
|
sqlite3VdbeJumpHere(v, addr);
|
||||||
addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
|
addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
|
||||||
sqlite3VdbeChangeP1(v, addr+1, j+2);
|
sqlite3VdbeChangeP1(v, addr+1, j+2);
|
||||||
@@ -950,7 +950,7 @@ void sqlite3Pragma(
|
|||||||
sqlite3VdbeChangeP1(v, addr+3, j+2);
|
sqlite3VdbeChangeP1(v, addr+3, j+2);
|
||||||
sqlite3VdbeChangeP2(v, addr+3, addr+2);
|
sqlite3VdbeChangeP2(v, addr+3, addr+2);
|
||||||
sqlite3VdbeJumpHere(v, addr+6);
|
sqlite3VdbeJumpHere(v, addr+6);
|
||||||
sqlite3VdbeChangeP3(v, addr+9, pIdx->zName, P3_STATIC);
|
sqlite3VdbeChangeP4(v, addr+9, pIdx->zName, P4_STATIC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1002,15 +1002,15 @@ void sqlite3Pragma(
|
|||||||
if( !zRight ){ /* "PRAGMA encoding" */
|
if( !zRight ){ /* "PRAGMA encoding" */
|
||||||
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
||||||
sqlite3VdbeSetNumCols(v, 1);
|
sqlite3VdbeSetNumCols(v, 1);
|
||||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "encoding", P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "encoding", P4_STATIC);
|
||||||
sqlite3VdbeAddOp(v, OP_String8, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_String8, 0, 0);
|
||||||
for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
|
for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
|
||||||
if( pEnc->enc==ENC(pParse->db) ){
|
if( pEnc->enc==ENC(pParse->db) ){
|
||||||
sqlite3VdbeChangeP3(v, -1, pEnc->zName, P3_STATIC);
|
sqlite3VdbeChangeP4(v, -1, pEnc->zName, P4_STATIC);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Callback, 1, 0);
|
||||||
}else{ /* "PRAGMA encoding = XXX" */
|
}else{ /* "PRAGMA encoding = XXX" */
|
||||||
/* Only change the value of sqlite.enc if the database handle is not
|
/* Only change the value of sqlite.enc if the database handle is not
|
||||||
** initialized. If the main database exists, the new sqlite.enc value
|
** initialized. If the main database exists, the new sqlite.enc value
|
||||||
@@ -1104,7 +1104,7 @@ void sqlite3Pragma(
|
|||||||
sqlite3VdbeChangeP1(v, addr, iDb);
|
sqlite3VdbeChangeP1(v, addr, iDb);
|
||||||
sqlite3VdbeChangeP2(v, addr, iCookie);
|
sqlite3VdbeChangeP2(v, addr, iCookie);
|
||||||
sqlite3VdbeSetNumCols(v, 1);
|
sqlite3VdbeSetNumCols(v, 1);
|
||||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, P3_TRANSIENT);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, P4_TRANSIENT);
|
||||||
}
|
}
|
||||||
}else
|
}else
|
||||||
#endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */
|
#endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */
|
||||||
@@ -1120,15 +1120,15 @@ void sqlite3Pragma(
|
|||||||
int i;
|
int i;
|
||||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||||
sqlite3VdbeSetNumCols(v, 2);
|
sqlite3VdbeSetNumCols(v, 2);
|
||||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "database", P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "database", P4_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "status", P3_STATIC);
|
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "status", P4_STATIC);
|
||||||
for(i=0; i<db->nDb; i++){
|
for(i=0; i<db->nDb; i++){
|
||||||
Btree *pBt;
|
Btree *pBt;
|
||||||
Pager *pPager;
|
Pager *pPager;
|
||||||
const char *zState = "unknown";
|
const char *zState = "unknown";
|
||||||
int j;
|
int j;
|
||||||
if( db->aDb[i].zName==0 ) continue;
|
if( db->aDb[i].zName==0 ) continue;
|
||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, db->aDb[i].zName, P3_STATIC);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, db->aDb[i].zName, P4_STATIC);
|
||||||
pBt = db->aDb[i].pBt;
|
pBt = db->aDb[i].pBt;
|
||||||
if( pBt==0 || (pPager = sqlite3BtreePager(pBt))==0 ){
|
if( pBt==0 || (pPager = sqlite3BtreePager(pBt))==0 ){
|
||||||
zState = "closed";
|
zState = "closed";
|
||||||
@@ -1136,8 +1136,8 @@ void sqlite3Pragma(
|
|||||||
SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){
|
SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){
|
||||||
zState = azLockName[j];
|
zState = azLockName[j];
|
||||||
}
|
}
|
||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, zState, P3_STATIC);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, zState, P4_STATIC);
|
||||||
sqlite3VdbeAddOp(v, OP_Callback, 2, 0);
|
sqlite3VdbeAddOp2(v, OP_Callback, 2, 0);
|
||||||
}
|
}
|
||||||
}else
|
}else
|
||||||
#endif
|
#endif
|
||||||
@@ -1182,7 +1182,7 @@ void sqlite3Pragma(
|
|||||||
** the VDBE implementing the pragma to expire. Most (all?) pragmas
|
** the VDBE implementing the pragma to expire. Most (all?) pragmas
|
||||||
** are only valid for a single execution.
|
** are only valid for a single execution.
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp(v, OP_Expire, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Expire, 1, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Reset the safety level, in case the fullfsync flag or synchronous
|
** Reset the safety level, in case the fullfsync flag or synchronous
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
** interface, and routines that contribute to loading the database schema
|
** interface, and routines that contribute to loading the database schema
|
||||||
** from disk.
|
** from disk.
|
||||||
**
|
**
|
||||||
** $Id: prepare.c,v 1.68 2007/12/27 15:12:17 danielk1977 Exp $
|
** $Id: prepare.c,v 1.69 2008/01/03 00:01:24 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -568,16 +568,16 @@ int sqlite3Prepare(
|
|||||||
if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
|
if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
|
||||||
if( sParse.explain==2 ){
|
if( sParse.explain==2 ){
|
||||||
sqlite3VdbeSetNumCols(sParse.pVdbe, 3);
|
sqlite3VdbeSetNumCols(sParse.pVdbe, 3);
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "order", P3_STATIC);
|
sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "order", P4_STATIC);
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "from", P3_STATIC);
|
sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "from", P4_STATIC);
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "detail", P3_STATIC);
|
sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "detail", P4_STATIC);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeSetNumCols(sParse.pVdbe, 5);
|
sqlite3VdbeSetNumCols(sParse.pVdbe, 5);
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "addr", P3_STATIC);
|
sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "addr", P4_STATIC);
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "opcode", P3_STATIC);
|
sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "opcode", P4_STATIC);
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "p1", P3_STATIC);
|
sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "p1", P4_STATIC);
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 3, COLNAME_NAME, "p2", P3_STATIC);
|
sqlite3VdbeSetColName(sParse.pVdbe, 3, COLNAME_NAME, "p2", P4_STATIC);
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 4, COLNAME_NAME, "p3", P3_STATIC);
|
sqlite3VdbeSetColName(sParse.pVdbe, 4, COLNAME_NAME, "p3", P4_STATIC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
337
src/select.c
337
src/select.c
@@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle SELECT statements in SQLite.
|
** to handle SELECT statements in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: select.c,v 1.377 2008/01/02 17:11:14 danielk1977 Exp $
|
** $Id: select.c,v 1.378 2008/01/03 00:01:25 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -388,18 +388,18 @@ static void pushOntoSorter(
|
|||||||
){
|
){
|
||||||
Vdbe *v = pParse->pVdbe;
|
Vdbe *v = pParse->pVdbe;
|
||||||
sqlite3ExprCodeExprList(pParse, pOrderBy);
|
sqlite3ExprCodeExprList(pParse, pOrderBy);
|
||||||
sqlite3VdbeAddOp(v, OP_Sequence, pOrderBy->iECursor, 0);
|
sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Pull, pOrderBy->nExpr + 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Pull, pOrderBy->nExpr + 1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MakeRecord, pOrderBy->nExpr + 2, 0);
|
sqlite3VdbeAddOp2(v, OP_MakeRecord, pOrderBy->nExpr + 2, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_IdxInsert, pOrderBy->iECursor, 0);
|
sqlite3VdbeAddOp2(v, OP_IdxInsert, pOrderBy->iECursor, 0);
|
||||||
if( pSelect->iLimit>=0 ){
|
if( pSelect->iLimit>=0 ){
|
||||||
int addr1, addr2;
|
int addr1, addr2;
|
||||||
addr1 = sqlite3VdbeAddOp(v, OP_IfMemZero, pSelect->iLimit+1, 0);
|
addr1 = sqlite3VdbeAddOp2(v, OP_IfMemZero, pSelect->iLimit+1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MemIncr, -1, pSelect->iLimit+1);
|
sqlite3VdbeAddOp2(v, OP_MemIncr, -1, pSelect->iLimit+1);
|
||||||
addr2 = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
|
addr2 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
|
||||||
sqlite3VdbeJumpHere(v, addr1);
|
sqlite3VdbeJumpHere(v, addr1);
|
||||||
sqlite3VdbeAddOp(v, OP_Last, pOrderBy->iECursor, 0);
|
sqlite3VdbeAddOp2(v, OP_Last, pOrderBy->iECursor, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Delete, pOrderBy->iECursor, 0);
|
sqlite3VdbeAddOp2(v, OP_Delete, pOrderBy->iECursor, 0);
|
||||||
sqlite3VdbeJumpHere(v, addr2);
|
sqlite3VdbeJumpHere(v, addr2);
|
||||||
pSelect->iLimit = -1;
|
pSelect->iLimit = -1;
|
||||||
}
|
}
|
||||||
@@ -416,12 +416,12 @@ static void codeOffset(
|
|||||||
){
|
){
|
||||||
if( p->iOffset>=0 && iContinue!=0 ){
|
if( p->iOffset>=0 && iContinue!=0 ){
|
||||||
int addr;
|
int addr;
|
||||||
sqlite3VdbeAddOp(v, OP_MemIncr, -1, p->iOffset);
|
sqlite3VdbeAddOp2(v, OP_MemIncr, -1, p->iOffset);
|
||||||
addr = sqlite3VdbeAddOp(v, OP_IfMemNeg, p->iOffset, 0);
|
addr = sqlite3VdbeAddOp2(v, OP_IfMemNeg, p->iOffset, 0);
|
||||||
if( nPop>0 ){
|
if( nPop>0 ){
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, nPop, 0);
|
sqlite3VdbeAddOp2(v, OP_Pop, nPop, 0);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(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);
|
||||||
}
|
}
|
||||||
@@ -442,12 +442,12 @@ static void codeDistinct_OLD(
|
|||||||
int addrRepeat, /* Jump to here if not distinct */
|
int addrRepeat, /* Jump to here if not distinct */
|
||||||
int N /* The top N elements of the stack must be distinct */
|
int N /* The top N elements of the stack must be distinct */
|
||||||
){
|
){
|
||||||
sqlite3VdbeAddOp(v, OP_MakeRecord, -N, 0);
|
sqlite3VdbeAddOp2(v, OP_MakeRecord, -N, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Distinct, iTab, sqlite3VdbeCurrentAddr(v)+3);
|
sqlite3VdbeAddOp2(v, OP_Distinct, iTab, sqlite3VdbeCurrentAddr(v)+3);
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, N+1, 0);
|
sqlite3VdbeAddOp2(v, OP_Pop, N+1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, addrRepeat);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrRepeat);
|
||||||
VdbeComment((v, "skip indistinct records"));
|
VdbeComment((v, "skip indistinct records"));
|
||||||
sqlite3VdbeAddOp(v, OP_IdxInsert, iTab, 0);
|
sqlite3VdbeAddOp2(v, OP_IdxInsert, iTab, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -465,12 +465,12 @@ static void codeDistinct(
|
|||||||
int addrRepeat, /* Jump to here if not distinct */
|
int addrRepeat, /* Jump to here if not distinct */
|
||||||
int iMem /* First element */
|
int iMem /* First element */
|
||||||
){
|
){
|
||||||
sqlite3VdbeAddOp(v, OP_RegMakeRec, iMem, 0);
|
sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Distinct, iTab, sqlite3VdbeCurrentAddr(v)+3);
|
sqlite3VdbeAddOp2(v, OP_Distinct, iTab, sqlite3VdbeCurrentAddr(v)+3);
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, addrRepeat);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrRepeat);
|
||||||
VdbeComment((v, "skip indistinct records"));
|
VdbeComment((v, "skip indistinct records"));
|
||||||
sqlite3VdbeAddOp(v, OP_IdxInsert, iTab, 0);
|
sqlite3VdbeAddOp2(v, OP_IdxInsert, iTab, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -543,10 +543,10 @@ static int selectInnerLoop(
|
|||||||
}
|
}
|
||||||
iMem = pParse->nMem;
|
iMem = pParse->nMem;
|
||||||
pParse->nMem += n+1;
|
pParse->nMem += n+1;
|
||||||
sqlite3VdbeAddOp(v, OP_MemInt, n, iMem);
|
sqlite3VdbeAddOp2(v, OP_MemInt, n, iMem);
|
||||||
if( nColumn>0 ){
|
if( nColumn>0 ){
|
||||||
for(i=0; i<nColumn; i++){
|
for(i=0; i<nColumn; i++){
|
||||||
sqlite3VdbeOp3Int(v, OP_Column, srcTab, i, iMem+i+1);
|
sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, iMem+i+1);
|
||||||
}
|
}
|
||||||
}else if( eDest!=SRT_Exists ){
|
}else if( eDest!=SRT_Exists ){
|
||||||
/* If the destination is an EXISTS(...) expression, the actual
|
/* If the destination is an EXISTS(...) expression, the actual
|
||||||
@@ -581,11 +581,11 @@ static int selectInnerLoop(
|
|||||||
*/
|
*/
|
||||||
#ifndef SQLITE_OMIT_COMPOUND_SELECT
|
#ifndef SQLITE_OMIT_COMPOUND_SELECT
|
||||||
case SRT_Union: {
|
case SRT_Union: {
|
||||||
sqlite3VdbeAddOp(v, OP_RegMakeRec, iMem, 0);
|
sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, 0);
|
||||||
if( aff ){
|
if( aff ){
|
||||||
sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC);
|
sqlite3VdbeChangeP4(v, -1, aff, P4_STATIC);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_IdxInsert, iParm, 0);
|
sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -595,10 +595,10 @@ static int selectInnerLoop(
|
|||||||
*/
|
*/
|
||||||
case SRT_Except: {
|
case SRT_Except: {
|
||||||
int addr;
|
int addr;
|
||||||
addr = sqlite3VdbeAddOp(v, OP_RegMakeRec, iMem, 0);
|
addr = sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, 0);
|
||||||
sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC);
|
sqlite3VdbeChangeP4(v, -1, aff, P4_STATIC);
|
||||||
sqlite3VdbeAddOp(v, OP_NotFound, iParm, addr+3);
|
sqlite3VdbeAddOp2(v, OP_NotFound, iParm, addr+3);
|
||||||
sqlite3VdbeAddOp(v, OP_Delete, iParm, 0);
|
sqlite3VdbeAddOp2(v, OP_Delete, iParm, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -607,13 +607,13 @@ static int selectInnerLoop(
|
|||||||
*/
|
*/
|
||||||
case SRT_Table:
|
case SRT_Table:
|
||||||
case SRT_EphemTab: {
|
case SRT_EphemTab: {
|
||||||
sqlite3VdbeAddOp(v, OP_RegMakeRec, iMem, 0);
|
sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, 0);
|
||||||
if( pOrderBy ){
|
if( pOrderBy ){
|
||||||
pushOntoSorter(pParse, pOrderBy, p);
|
pushOntoSorter(pParse, pOrderBy, p);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_NewRowid, iParm, 0);
|
sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Pull, 1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Insert, iParm, OPFLAG_APPEND);
|
sqlite3VdbeAddOp2(v, OP_Insert, iParm, OPFLAG_APPEND);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -627,18 +627,18 @@ static int selectInnerLoop(
|
|||||||
int addr2;
|
int addr2;
|
||||||
|
|
||||||
assert( nColumn==1 );
|
assert( nColumn==1 );
|
||||||
addr2 = sqlite3VdbeAddOp(v, OP_IfMemNull, iMem+1, 0);
|
addr2 = sqlite3VdbeAddOp2(v, OP_IfMemNull, iMem+1, 0);
|
||||||
p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affinity);
|
p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affinity);
|
||||||
if( pOrderBy ){
|
if( pOrderBy ){
|
||||||
/* At first glance you would think we could optimize out the
|
/* At first glance you would think we could optimize out the
|
||||||
** ORDER BY in this case since the order of entries in the set
|
** ORDER BY in this case since the order of entries in the set
|
||||||
** does not matter. But there might be a LIMIT clause, in which
|
** does not matter. But there might be a LIMIT clause, in which
|
||||||
** case the order does matter */
|
** case the order does matter */
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, iMem+1, 0);
|
sqlite3VdbeAddOp2(v, OP_MemLoad, iMem+1, 0);
|
||||||
pushOntoSorter(pParse, pOrderBy, p);
|
pushOntoSorter(pParse, pOrderBy, p);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeOp3(v, OP_RegMakeRec, iMem, 0, &p->affinity, 1);
|
sqlite3VdbeAddOp4(v, OP_RegMakeRec, iMem, 0, 0, &p->affinity, 1);
|
||||||
sqlite3VdbeAddOp(v, OP_IdxInsert, iParm, 0);
|
sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, 0);
|
||||||
}
|
}
|
||||||
sqlite3VdbeJumpHere(v, addr2);
|
sqlite3VdbeJumpHere(v, addr2);
|
||||||
break;
|
break;
|
||||||
@@ -647,7 +647,7 @@ static int selectInnerLoop(
|
|||||||
/* If any row exist in the result set, record that fact and abort.
|
/* If any row exist in the result set, record that fact and abort.
|
||||||
*/
|
*/
|
||||||
case SRT_Exists: {
|
case SRT_Exists: {
|
||||||
sqlite3VdbeAddOp(v, OP_MemInt, 1, iParm);
|
sqlite3VdbeAddOp2(v, OP_MemInt, 1, iParm);
|
||||||
/* The LIMIT clause will terminate the loop for us */
|
/* The LIMIT clause will terminate the loop for us */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -658,11 +658,11 @@ static int selectInnerLoop(
|
|||||||
*/
|
*/
|
||||||
case SRT_Mem: {
|
case SRT_Mem: {
|
||||||
assert( nColumn==1 );
|
assert( nColumn==1 );
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, iMem+1, 0);
|
sqlite3VdbeAddOp2(v, OP_MemLoad, iMem+1, 0);
|
||||||
if( pOrderBy ){
|
if( pOrderBy ){
|
||||||
pushOntoSorter(pParse, pOrderBy, p);
|
pushOntoSorter(pParse, pOrderBy, p);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
|
sqlite3VdbeAddOp2(v, OP_MemStore, iParm, 1);
|
||||||
/* The LIMIT clause will jump out of the loop for us */
|
/* The LIMIT clause will jump out of the loop for us */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -676,13 +676,13 @@ static int selectInnerLoop(
|
|||||||
case SRT_Subroutine:
|
case SRT_Subroutine:
|
||||||
case SRT_Callback: {
|
case SRT_Callback: {
|
||||||
if( pOrderBy ){
|
if( pOrderBy ){
|
||||||
sqlite3VdbeAddOp(v, OP_RegMakeRec, iMem, 0);
|
sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, 0);
|
||||||
pushOntoSorter(pParse, pOrderBy, p);
|
pushOntoSorter(pParse, pOrderBy, p);
|
||||||
}else if( eDest==SRT_Subroutine ){
|
}else if( eDest==SRT_Subroutine ){
|
||||||
for(i=0; i<nColumn; i++) sqlite3VdbeAddOp(v, OP_MemLoad, iMem+i+1, 0);
|
for(i=0; i<nColumn; i++) sqlite3VdbeAddOp2(v, OP_MemLoad, iMem+i+1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Gosub, 0, iParm);
|
sqlite3VdbeAddOp2(v, OP_Gosub, 0, iParm);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_ResultRow, iMem+1, nColumn);
|
sqlite3VdbeAddOp2(v, OP_ResultRow, iMem+1, nColumn);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -703,8 +703,8 @@ static int selectInnerLoop(
|
|||||||
/* 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>=0 && pOrderBy==0 ){
|
if( p->iLimit>=0 && pOrderBy==0 ){
|
||||||
sqlite3VdbeAddOp(v, OP_MemIncr, -1, p->iLimit);
|
sqlite3VdbeAddOp2(v, OP_MemIncr, -1, p->iLimit);
|
||||||
sqlite3VdbeAddOp(v, OP_IfMemZero, p->iLimit, iBreak);
|
sqlite3VdbeAddOp2(v, OP_IfMemZero, p->iLimit, iBreak);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -721,8 +721,8 @@ static int selectInnerLoop(
|
|||||||
**
|
**
|
||||||
** Space to hold the KeyInfo structure is obtain from malloc. The calling
|
** Space to hold the KeyInfo structure is obtain from malloc. The calling
|
||||||
** function is responsible for seeing that this structure is eventually
|
** function is responsible for seeing that this structure is eventually
|
||||||
** freed. Add the KeyInfo structure to the P3 field of an opcode using
|
** freed. Add the KeyInfo structure to the P4 field of an opcode using
|
||||||
** P3_KEYINFO_HANDOFF is the usual way of dealing with this.
|
** P4_KEYINFO_HANDOFF is the usual way of dealing with this.
|
||||||
*/
|
*/
|
||||||
static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){
|
static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){
|
||||||
sqlite3 *db = pParse->db;
|
sqlite3 *db = pParse->db;
|
||||||
@@ -777,36 +777,36 @@ static void generateSortTail(
|
|||||||
iTab = pOrderBy->iECursor;
|
iTab = pOrderBy->iECursor;
|
||||||
if( eDest==SRT_Callback || eDest==SRT_Subroutine ){
|
if( eDest==SRT_Callback || eDest==SRT_Subroutine ){
|
||||||
pseudoTab = pParse->nTab++;
|
pseudoTab = pParse->nTab++;
|
||||||
sqlite3VdbeAddOp(v, OP_OpenPseudo, pseudoTab, 0);
|
sqlite3VdbeAddOp2(v, OP_OpenPseudo, pseudoTab, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_SetNumColumns, pseudoTab, nColumn);
|
sqlite3VdbeAddOp2(v, OP_SetNumColumns, pseudoTab, nColumn);
|
||||||
}
|
}
|
||||||
addr = 1 + sqlite3VdbeAddOp(v, OP_Sort, iTab, brk);
|
addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, brk);
|
||||||
codeOffset(v, p, cont, 0);
|
codeOffset(v, p, cont, 0);
|
||||||
if( eDest==SRT_Callback || eDest==SRT_Subroutine ){
|
if( eDest==SRT_Callback || eDest==SRT_Subroutine ){
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, 1, 0);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_Column, iTab, pOrderBy->nExpr + 1);
|
sqlite3VdbeAddOp2(v, OP_Column, iTab, pOrderBy->nExpr + 1);
|
||||||
switch( eDest ){
|
switch( eDest ){
|
||||||
case SRT_Table:
|
case SRT_Table:
|
||||||
case SRT_EphemTab: {
|
case SRT_EphemTab: {
|
||||||
sqlite3VdbeAddOp(v, OP_NewRowid, iParm, 0);
|
sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Pull, 1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Insert, iParm, OPFLAG_APPEND);
|
sqlite3VdbeAddOp2(v, OP_Insert, iParm, OPFLAG_APPEND);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifndef SQLITE_OMIT_SUBQUERY
|
#ifndef SQLITE_OMIT_SUBQUERY
|
||||||
case SRT_Set: {
|
case SRT_Set: {
|
||||||
assert( nColumn==1 );
|
assert( nColumn==1 );
|
||||||
sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
|
sqlite3VdbeAddOp2(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+3);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+3);
|
||||||
sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &p->affinity, 1);
|
sqlite3VdbeAddOp4(v, OP_MakeRecord, 1, 0, 0, &p->affinity, 1);
|
||||||
sqlite3VdbeAddOp(v, OP_IdxInsert, iParm, 0);
|
sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SRT_Mem: {
|
case SRT_Mem: {
|
||||||
assert( nColumn==1 );
|
assert( nColumn==1 );
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
|
sqlite3VdbeAddOp2(v, OP_MemStore, iParm, 1);
|
||||||
/* The LIMIT clause will terminate the loop for us */
|
/* The LIMIT clause will terminate the loop for us */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -814,14 +814,14 @@ static void generateSortTail(
|
|||||||
case SRT_Callback:
|
case SRT_Callback:
|
||||||
case SRT_Subroutine: {
|
case SRT_Subroutine: {
|
||||||
int i;
|
int i;
|
||||||
sqlite3VdbeAddOp(v, OP_Insert, pseudoTab, 0);
|
sqlite3VdbeAddOp2(v, OP_Insert, pseudoTab, 0);
|
||||||
for(i=0; i<nColumn; i++){
|
for(i=0; i<nColumn; i++){
|
||||||
sqlite3VdbeAddOp(v, OP_Column, pseudoTab, i);
|
sqlite3VdbeAddOp2(v, OP_Column, pseudoTab, i);
|
||||||
}
|
}
|
||||||
if( eDest==SRT_Callback ){
|
if( eDest==SRT_Callback ){
|
||||||
sqlite3VdbeAddOp(v, OP_Callback, nColumn, 0);
|
sqlite3VdbeAddOp2(v, OP_Callback, nColumn, 0);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_Gosub, 0, iParm);
|
sqlite3VdbeAddOp2(v, OP_Gosub, 0, iParm);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -834,17 +834,17 @@ static void generateSortTail(
|
|||||||
/* Jump to the end of the loop when the LIMIT is reached
|
/* Jump to the end of the loop when the LIMIT is reached
|
||||||
*/
|
*/
|
||||||
if( p->iLimit>=0 ){
|
if( p->iLimit>=0 ){
|
||||||
sqlite3VdbeAddOp(v, OP_MemIncr, -1, p->iLimit);
|
sqlite3VdbeAddOp2(v, OP_MemIncr, -1, p->iLimit);
|
||||||
sqlite3VdbeAddOp(v, OP_IfMemZero, p->iLimit, brk);
|
sqlite3VdbeAddOp2(v, OP_IfMemZero, p->iLimit, brk);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The bottom of the loop
|
/* The bottom of the loop
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeResolveLabel(v, cont);
|
sqlite3VdbeResolveLabel(v, cont);
|
||||||
sqlite3VdbeAddOp(v, OP_Next, iTab, addr);
|
sqlite3VdbeAddOp2(v, OP_Next, iTab, addr);
|
||||||
sqlite3VdbeResolveLabel(v, brk);
|
sqlite3VdbeResolveLabel(v, brk);
|
||||||
if( eDest==SRT_Callback || eDest==SRT_Subroutine ){
|
if( eDest==SRT_Callback || eDest==SRT_Subroutine ){
|
||||||
sqlite3VdbeAddOp(v, OP_Close, pseudoTab, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, pseudoTab, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1007,10 +1007,10 @@ static void generateColumnTypes(
|
|||||||
** column specific strings, in case the schema is reset before this
|
** column specific strings, in case the schema is reset before this
|
||||||
** virtual machine is deleted.
|
** virtual machine is deleted.
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, P3_TRANSIENT);
|
sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, P4_TRANSIENT);
|
||||||
sqlite3VdbeSetColName(v, i, COLNAME_DATABASE, zOrigDb, P3_TRANSIENT);
|
sqlite3VdbeSetColName(v, i, COLNAME_DATABASE, zOrigDb, P4_TRANSIENT);
|
||||||
sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, P3_TRANSIENT);
|
sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, P4_TRANSIENT);
|
||||||
sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, P3_TRANSIENT);
|
sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, P4_TRANSIENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1074,7 +1074,7 @@ static void generateColumnNames(
|
|||||||
zTab = pTabList->a[j].zAlias;
|
zTab = pTabList->a[j].zAlias;
|
||||||
if( fullNames || zTab==0 ) zTab = pTab->zName;
|
if( fullNames || zTab==0 ) zTab = pTab->zName;
|
||||||
sqlite3SetString(&zName, zTab, ".", zCol, (char*)0);
|
sqlite3SetString(&zName, zTab, ".", zCol, (char*)0);
|
||||||
sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, P3_DYNAMIC);
|
sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, P4_DYNAMIC);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, strlen(zCol));
|
sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, strlen(zCol));
|
||||||
}
|
}
|
||||||
@@ -1751,35 +1751,35 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
|
|||||||
v = sqlite3GetVdbe(pParse);
|
v = sqlite3GetVdbe(pParse);
|
||||||
if( v==0 ) return;
|
if( v==0 ) return;
|
||||||
sqlite3ExprCode(pParse, p->pLimit);
|
sqlite3ExprCode(pParse, p->pLimit);
|
||||||
sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, iLimit, 1);
|
sqlite3VdbeAddOp2(v, OP_MemStore, iLimit, 1);
|
||||||
VdbeComment((v, "LIMIT counter"));
|
VdbeComment((v, "LIMIT counter"));
|
||||||
sqlite3VdbeAddOp(v, OP_IfMemZero, iLimit, iBreak);
|
sqlite3VdbeAddOp2(v, OP_IfMemZero, iLimit, iBreak);
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, iLimit, 0);
|
sqlite3VdbeAddOp2(v, OP_MemLoad, iLimit, 0);
|
||||||
}
|
}
|
||||||
if( p->pOffset ){
|
if( p->pOffset ){
|
||||||
p->iOffset = iOffset = pParse->nMem++;
|
p->iOffset = iOffset = pParse->nMem++;
|
||||||
v = sqlite3GetVdbe(pParse);
|
v = sqlite3GetVdbe(pParse);
|
||||||
if( v==0 ) return;
|
if( v==0 ) return;
|
||||||
sqlite3ExprCode(pParse, p->pOffset);
|
sqlite3ExprCode(pParse, p->pOffset);
|
||||||
sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, iOffset, p->pLimit==0);
|
sqlite3VdbeAddOp2(v, OP_MemStore, iOffset, p->pLimit==0);
|
||||||
VdbeComment((v, "OFFSET counter"));
|
VdbeComment((v, "OFFSET counter"));
|
||||||
addr1 = sqlite3VdbeAddOp(v, OP_IfMemPos, iOffset, 0);
|
addr1 = sqlite3VdbeAddOp2(v, OP_IfMemPos, iOffset, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
|
||||||
sqlite3VdbeJumpHere(v, addr1);
|
sqlite3VdbeJumpHere(v, addr1);
|
||||||
if( p->pLimit ){
|
if( p->pLimit ){
|
||||||
sqlite3VdbeAddOp(v, OP_Add, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Add, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( p->pLimit ){
|
if( p->pLimit ){
|
||||||
addr1 = sqlite3VdbeAddOp(v, OP_IfMemPos, iLimit, 0);
|
addr1 = sqlite3VdbeAddOp2(v, OP_IfMemPos, iLimit, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MemInt, -1, iLimit+1);
|
sqlite3VdbeAddOp2(v, OP_MemInt, -1, iLimit+1);
|
||||||
addr2 = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
|
addr2 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
|
||||||
sqlite3VdbeJumpHere(v, addr1);
|
sqlite3VdbeJumpHere(v, addr1);
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, iLimit+1, 1);
|
sqlite3VdbeAddOp2(v, OP_MemStore, iLimit+1, 1);
|
||||||
VdbeComment((v, "LIMIT+OFFSET"));
|
VdbeComment((v, "LIMIT+OFFSET"));
|
||||||
sqlite3VdbeJumpHere(v, addr2);
|
sqlite3VdbeJumpHere(v, addr2);
|
||||||
}
|
}
|
||||||
@@ -1793,7 +1793,7 @@ static void createSortingIndex(Parse *pParse, Select *p, ExprList *pOrderBy){
|
|||||||
int addr;
|
int addr;
|
||||||
assert( pOrderBy->iECursor==0 );
|
assert( pOrderBy->iECursor==0 );
|
||||||
pOrderBy->iECursor = pParse->nTab++;
|
pOrderBy->iECursor = pParse->nTab++;
|
||||||
addr = sqlite3VdbeAddOp(pParse->pVdbe, OP_OpenEphemeral,
|
addr = sqlite3VdbeAddOp2(pParse->pVdbe, OP_OpenEphemeral,
|
||||||
pOrderBy->iECursor, pOrderBy->nExpr+1);
|
pOrderBy->iECursor, pOrderBy->nExpr+1);
|
||||||
assert( p->addrOpenEphm[2] == -1 );
|
assert( p->addrOpenEphm[2] == -1 );
|
||||||
p->addrOpenEphm[2] = addr;
|
p->addrOpenEphm[2] = addr;
|
||||||
@@ -1909,7 +1909,7 @@ static int multiSelect(
|
|||||||
if( dest.eDest==SRT_EphemTab ){
|
if( dest.eDest==SRT_EphemTab ){
|
||||||
assert( p->pEList );
|
assert( p->pEList );
|
||||||
assert( nSetP2<sizeof(aSetP2)/sizeof(aSetP2[0]) );
|
assert( nSetP2<sizeof(aSetP2)/sizeof(aSetP2[0]) );
|
||||||
aSetP2[nSetP2++] = sqlite3VdbeAddOp(v, OP_OpenEphemeral, dest.iParm, 0);
|
aSetP2[nSetP2++] = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iParm, 0);
|
||||||
dest.eDest = SRT_Table;
|
dest.eDest = SRT_Table;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1933,7 +1933,7 @@ static int multiSelect(
|
|||||||
p->iLimit = pPrior->iLimit;
|
p->iLimit = pPrior->iLimit;
|
||||||
p->iOffset = pPrior->iOffset;
|
p->iOffset = pPrior->iOffset;
|
||||||
if( p->iLimit>=0 ){
|
if( p->iLimit>=0 ){
|
||||||
addr = sqlite3VdbeAddOp(v, OP_IfMemZero, p->iLimit, 0);
|
addr = sqlite3VdbeAddOp2(v, OP_IfMemZero, p->iLimit, 0);
|
||||||
VdbeComment((v, "Jump ahead if LIMIT reached"));
|
VdbeComment((v, "Jump ahead if LIMIT reached"));
|
||||||
}
|
}
|
||||||
rc = sqlite3Select(pParse, p, &dest, 0, 0, 0, aff);
|
rc = sqlite3Select(pParse, p, &dest, 0, 0, 0, aff);
|
||||||
@@ -1972,7 +1972,7 @@ static int multiSelect(
|
|||||||
rc = 1;
|
rc = 1;
|
||||||
goto multi_select_end;
|
goto multi_select_end;
|
||||||
}
|
}
|
||||||
addr = sqlite3VdbeAddOp(v, OP_OpenEphemeral, unionTab, 0);
|
addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0);
|
||||||
if( priorOp==SRT_Table ){
|
if( priorOp==SRT_Table ){
|
||||||
assert( nSetP2<sizeof(aSetP2)/sizeof(aSetP2[0]) );
|
assert( nSetP2<sizeof(aSetP2)/sizeof(aSetP2[0]) );
|
||||||
aSetP2[nSetP2++] = addr;
|
aSetP2[nSetP2++] = addr;
|
||||||
@@ -2040,7 +2040,7 @@ static int multiSelect(
|
|||||||
iBreak = sqlite3VdbeMakeLabel(v);
|
iBreak = sqlite3VdbeMakeLabel(v);
|
||||||
iCont = sqlite3VdbeMakeLabel(v);
|
iCont = sqlite3VdbeMakeLabel(v);
|
||||||
computeLimitRegisters(pParse, p, iBreak);
|
computeLimitRegisters(pParse, p, iBreak);
|
||||||
sqlite3VdbeAddOp(v, OP_Rewind, unionTab, iBreak);
|
sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak);
|
||||||
iStart = sqlite3VdbeCurrentAddr(v);
|
iStart = sqlite3VdbeCurrentAddr(v);
|
||||||
rc = selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
|
rc = selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
|
||||||
pOrderBy, -1, &dest, iCont, iBreak, 0);
|
pOrderBy, -1, &dest, iCont, iBreak, 0);
|
||||||
@@ -2049,9 +2049,9 @@ static int multiSelect(
|
|||||||
goto multi_select_end;
|
goto multi_select_end;
|
||||||
}
|
}
|
||||||
sqlite3VdbeResolveLabel(v, iCont);
|
sqlite3VdbeResolveLabel(v, iCont);
|
||||||
sqlite3VdbeAddOp(v, OP_Next, unionTab, iStart);
|
sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart);
|
||||||
sqlite3VdbeResolveLabel(v, iBreak);
|
sqlite3VdbeResolveLabel(v, iBreak);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, unionTab, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2074,7 +2074,7 @@ static int multiSelect(
|
|||||||
}
|
}
|
||||||
createSortingIndex(pParse, p, pOrderBy);
|
createSortingIndex(pParse, p, pOrderBy);
|
||||||
|
|
||||||
addr = sqlite3VdbeAddOp(v, OP_OpenEphemeral, tab1, 0);
|
addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0);
|
||||||
assert( p->addrOpenEphm[0] == -1 );
|
assert( p->addrOpenEphm[0] == -1 );
|
||||||
p->addrOpenEphm[0] = addr;
|
p->addrOpenEphm[0] = addr;
|
||||||
p->pRightmost->usesEphm = 1;
|
p->pRightmost->usesEphm = 1;
|
||||||
@@ -2090,7 +2090,7 @@ static int multiSelect(
|
|||||||
|
|
||||||
/* Code the current SELECT into temporary table "tab2"
|
/* Code the current SELECT into temporary table "tab2"
|
||||||
*/
|
*/
|
||||||
addr = sqlite3VdbeAddOp(v, OP_OpenEphemeral, tab2, 0);
|
addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0);
|
||||||
assert( p->addrOpenEphm[1] == -1 );
|
assert( p->addrOpenEphm[1] == -1 );
|
||||||
p->addrOpenEphm[1] = addr;
|
p->addrOpenEphm[1] = addr;
|
||||||
p->pPrior = 0;
|
p->pPrior = 0;
|
||||||
@@ -2120,9 +2120,9 @@ static int multiSelect(
|
|||||||
iBreak = sqlite3VdbeMakeLabel(v);
|
iBreak = sqlite3VdbeMakeLabel(v);
|
||||||
iCont = sqlite3VdbeMakeLabel(v);
|
iCont = sqlite3VdbeMakeLabel(v);
|
||||||
computeLimitRegisters(pParse, p, iBreak);
|
computeLimitRegisters(pParse, p, iBreak);
|
||||||
sqlite3VdbeAddOp(v, OP_Rewind, tab1, iBreak);
|
sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak);
|
||||||
iStart = sqlite3VdbeAddOp(v, OP_RowKey, tab1, 0);
|
iStart = sqlite3VdbeAddOp2(v, OP_RowKey, tab1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_NotFound, tab2, iCont);
|
sqlite3VdbeAddOp2(v, OP_NotFound, tab2, iCont);
|
||||||
rc = selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
|
rc = selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
|
||||||
pOrderBy, -1, &dest, iCont, iBreak, 0);
|
pOrderBy, -1, &dest, iCont, iBreak, 0);
|
||||||
if( rc ){
|
if( rc ){
|
||||||
@@ -2130,10 +2130,10 @@ static int multiSelect(
|
|||||||
goto multi_select_end;
|
goto multi_select_end;
|
||||||
}
|
}
|
||||||
sqlite3VdbeResolveLabel(v, iCont);
|
sqlite3VdbeResolveLabel(v, iCont);
|
||||||
sqlite3VdbeAddOp(v, OP_Next, tab1, iStart);
|
sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart);
|
||||||
sqlite3VdbeResolveLabel(v, iBreak);
|
sqlite3VdbeResolveLabel(v, iBreak);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, tab2, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, tab2, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, tab1, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, tab1, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2203,7 +2203,7 @@ static int multiSelect(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sqlite3VdbeChangeP2(v, addr, nCol);
|
sqlite3VdbeChangeP2(v, addr, nCol);
|
||||||
sqlite3VdbeChangeP3(v, addr, (char*)pKeyInfo, P3_KEYINFO);
|
sqlite3VdbeChangeP4(v, addr, (char*)pKeyInfo, P4_KEYINFO);
|
||||||
pLoop->addrOpenEphm[i] = -1;
|
pLoop->addrOpenEphm[i] = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2247,7 +2247,7 @@ static int multiSelect(
|
|||||||
addr = p->addrOpenEphm[2];
|
addr = p->addrOpenEphm[2];
|
||||||
sqlite3VdbeChangeP2(v, addr, p->pOrderBy->nExpr+2);
|
sqlite3VdbeChangeP2(v, addr, p->pOrderBy->nExpr+2);
|
||||||
pKeyInfo->nField = nOrderByExpr;
|
pKeyInfo->nField = nOrderByExpr;
|
||||||
sqlite3VdbeChangeP3(v, addr, (char*)pKeyInfo, P3_KEYINFO_HANDOFF);
|
sqlite3VdbeChangeP4(v, addr, (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
|
||||||
pKeyInfo = 0;
|
pKeyInfo = 0;
|
||||||
generateSortTail(pParse, p, v, p->pEList->nExpr, &dest);
|
generateSortTail(pParse, p, v, p->pEList->nExpr, &dest);
|
||||||
}
|
}
|
||||||
@@ -2718,7 +2718,7 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, SelectDest *pDest){
|
|||||||
/* If the output is destined for a temporary table, open that table.
|
/* If the output is destined for a temporary table, open that table.
|
||||||
*/
|
*/
|
||||||
if( pDest->eDest==SRT_EphemTab ){
|
if( pDest->eDest==SRT_EphemTab ){
|
||||||
sqlite3VdbeAddOp(v, OP_OpenEphemeral, pDest->iParm, 1);
|
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iParm, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generating code to find the min or the max. Basically all we have
|
/* Generating code to find the min or the max. Basically all we have
|
||||||
@@ -2737,7 +2737,7 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, SelectDest *pDest){
|
|||||||
sqlite3OpenTable(pParse, base, iDb, pTab, OP_OpenRead);
|
sqlite3OpenTable(pParse, base, iDb, pTab, OP_OpenRead);
|
||||||
}
|
}
|
||||||
if( pIdx==0 ){
|
if( pIdx==0 ){
|
||||||
sqlite3VdbeAddOp(v, seekOp, base, 0);
|
sqlite3VdbeAddOp2(v, seekOp, base, 0);
|
||||||
}else{
|
}else{
|
||||||
/* Even though the cursor used to open the index here is closed
|
/* Even though the cursor used to open the index here is closed
|
||||||
** as soon as a single value has been read from it, allocate it
|
** as soon as a single value has been read from it, allocate it
|
||||||
@@ -2749,12 +2749,12 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, SelectDest *pDest){
|
|||||||
KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
|
KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
|
||||||
iIdx = pParse->nTab++;
|
iIdx = pParse->nTab++;
|
||||||
assert( pIdx->pSchema==pTab->pSchema );
|
assert( pIdx->pSchema==pTab->pSchema );
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, iDb, 0);
|
||||||
sqlite3VdbeOp3(v, OP_OpenRead, iIdx, pIdx->tnum,
|
sqlite3VdbeAddOp4(v, OP_OpenRead, iIdx, pIdx->tnum, 0,
|
||||||
(char*)pKey, P3_KEYINFO_HANDOFF);
|
(char*)pKey, P4_KEYINFO_HANDOFF);
|
||||||
if( seekOp==OP_Rewind ){
|
if( seekOp==OP_Rewind ){
|
||||||
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Null, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MakeRecord, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_MakeRecord, 1, 0);
|
||||||
seekOp = OP_MoveGt;
|
seekOp = OP_MoveGt;
|
||||||
}
|
}
|
||||||
if( pIdx->aSortOrder[0]==SQLITE_SO_DESC ){
|
if( pIdx->aSortOrder[0]==SQLITE_SO_DESC ){
|
||||||
@@ -2767,10 +2767,10 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, SelectDest *pDest){
|
|||||||
seekOp = OP_MoveLt;
|
seekOp = OP_MoveLt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, seekOp, iIdx, 0);
|
sqlite3VdbeAddOp2(v, seekOp, iIdx, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_IdxRowid, iIdx, 0);
|
sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdx, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, iIdx, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, iIdx, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
|
sqlite3VdbeAddOp2(v, OP_MoveGe, base, 0);
|
||||||
}
|
}
|
||||||
eList.nExpr = 1;
|
eList.nExpr = 1;
|
||||||
memset(&eListItem, 0, sizeof(eListItem));
|
memset(&eListItem, 0, sizeof(eListItem));
|
||||||
@@ -2778,7 +2778,7 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, SelectDest *pDest){
|
|||||||
eList.a[0].pExpr = pExpr;
|
eList.a[0].pExpr = pExpr;
|
||||||
selectInnerLoop(pParse, p, &eList, 0, 0, 0, -1, pDest, brk, brk, 0);
|
selectInnerLoop(pParse, p, &eList, 0, 0, 0, -1, pDest, brk, brk, 0);
|
||||||
sqlite3VdbeResolveLabel(v, brk);
|
sqlite3VdbeResolveLabel(v, brk);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, base, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, base, 0);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -2928,10 +2928,10 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for(i=0; i<pAggInfo->nColumn; i++){
|
for(i=0; i<pAggInfo->nColumn; i++){
|
||||||
sqlite3VdbeAddOp(v, OP_MemNull, 0, pAggInfo->aCol[i].iMem);
|
sqlite3VdbeAddOp2(v, OP_MemNull, 0, pAggInfo->aCol[i].iMem);
|
||||||
}
|
}
|
||||||
for(pFunc=pAggInfo->aFunc, i=0; i<pAggInfo->nFunc; i++, pFunc++){
|
for(pFunc=pAggInfo->aFunc, i=0; i<pAggInfo->nFunc; i++, pFunc++){
|
||||||
sqlite3VdbeAddOp(v, OP_MemNull, 0, pFunc->iMem);
|
sqlite3VdbeAddOp2(v, OP_MemNull, 0, pFunc->iMem);
|
||||||
if( pFunc->iDistinct>=0 ){
|
if( pFunc->iDistinct>=0 ){
|
||||||
Expr *pE = pFunc->pExpr;
|
Expr *pE = pFunc->pExpr;
|
||||||
if( pE->pList==0 || pE->pList->nExpr!=1 ){
|
if( pE->pList==0 || pE->pList->nExpr!=1 ){
|
||||||
@@ -2940,8 +2940,8 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
|
|||||||
pFunc->iDistinct = -1;
|
pFunc->iDistinct = -1;
|
||||||
}else{
|
}else{
|
||||||
KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->pList);
|
KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->pList);
|
||||||
sqlite3VdbeOp3(v, OP_OpenEphemeral, pFunc->iDistinct, 0,
|
sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0,
|
||||||
(char*)pKeyInfo, P3_KEYINFO_HANDOFF);
|
(char*)pKeyInfo, P4_KEYINFO_HANDOFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2957,8 +2957,8 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){
|
|||||||
struct AggInfo_func *pF;
|
struct AggInfo_func *pF;
|
||||||
for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
|
for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
|
||||||
ExprList *pList = pF->pExpr->pList;
|
ExprList *pList = pF->pExpr->pList;
|
||||||
sqlite3VdbeOp3(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0,
|
sqlite3VdbeAddOp4(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0, 0,
|
||||||
(void*)pF->pFunc, P3_FUNCDEF);
|
(void*)pF->pFunc, P4_FUNCDEF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2999,16 +2999,17 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
|
|||||||
if( !pColl ){
|
if( !pColl ){
|
||||||
pColl = pParse->db->pDfltColl;
|
pColl = pParse->db->pDfltColl;
|
||||||
}
|
}
|
||||||
sqlite3VdbeOp3(v, OP_CollSeq, 0, 0, (char *)pColl, P3_COLLSEQ);
|
sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
|
||||||
}
|
}
|
||||||
sqlite3VdbeOp3(v, OP_AggStep, pF->iMem, nArg, (void*)pF->pFunc, P3_FUNCDEF);
|
sqlite3VdbeAddOp4(v, OP_AggStep, pF->iMem, nArg, 0,
|
||||||
|
(void*)pF->pFunc, P4_FUNCDEF);
|
||||||
if( addrNext ){
|
if( addrNext ){
|
||||||
sqlite3VdbeResolveLabel(v, addrNext);
|
sqlite3VdbeResolveLabel(v, addrNext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
|
for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
|
||||||
sqlite3ExprCode(pParse, pC->pExpr);
|
sqlite3ExprCode(pParse, pC->pExpr);
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, pC->iMem, 1);
|
sqlite3VdbeAddOp2(v, OP_MemStore, pC->iMem, 1);
|
||||||
}
|
}
|
||||||
pAggInfo->directMode = 0;
|
pAggInfo->directMode = 0;
|
||||||
}
|
}
|
||||||
@@ -3310,7 +3311,9 @@ int sqlite3Select(
|
|||||||
pKeyInfo = keyInfoFromExprList(pParse, pOrderBy);
|
pKeyInfo = keyInfoFromExprList(pParse, pOrderBy);
|
||||||
pOrderBy->iECursor = pParse->nTab++;
|
pOrderBy->iECursor = pParse->nTab++;
|
||||||
p->addrOpenEphm[2] = addrSortIndex =
|
p->addrOpenEphm[2] = addrSortIndex =
|
||||||
sqlite3VdbeOp3(v, OP_OpenEphemeral, pOrderBy->iECursor, pOrderBy->nExpr+2, (char*)pKeyInfo, P3_KEYINFO_HANDOFF);
|
sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
|
||||||
|
pOrderBy->iECursor, pOrderBy->nExpr+2, 0,
|
||||||
|
(char*)pKeyInfo, P4_KEYINFO_HANDOFF);
|
||||||
}else{
|
}else{
|
||||||
addrSortIndex = -1;
|
addrSortIndex = -1;
|
||||||
}
|
}
|
||||||
@@ -3318,7 +3321,7 @@ int sqlite3Select(
|
|||||||
/* If the output is destined for a temporary table, open that table.
|
/* If the output is destined for a temporary table, open that table.
|
||||||
*/
|
*/
|
||||||
if( pDest->eDest==SRT_EphemTab ){
|
if( pDest->eDest==SRT_EphemTab ){
|
||||||
sqlite3VdbeAddOp(v, OP_OpenEphemeral, pDest->iParm, pEList->nExpr);
|
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iParm, pEList->nExpr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the limiter.
|
/* Set the limiter.
|
||||||
@@ -3333,8 +3336,8 @@ int sqlite3Select(
|
|||||||
assert( isAgg || pGroupBy );
|
assert( isAgg || pGroupBy );
|
||||||
distinct = pParse->nTab++;
|
distinct = pParse->nTab++;
|
||||||
pKeyInfo = keyInfoFromExprList(pParse, p->pEList);
|
pKeyInfo = keyInfoFromExprList(pParse, p->pEList);
|
||||||
sqlite3VdbeOp3(v, OP_OpenEphemeral, distinct, 0,
|
sqlite3VdbeAddOp4(v, OP_OpenEphemeral, distinct, 0, 0,
|
||||||
(char*)pKeyInfo, P3_KEYINFO_HANDOFF);
|
(char*)pKeyInfo, P4_KEYINFO_HANDOFF);
|
||||||
}else{
|
}else{
|
||||||
distinct = -1;
|
distinct = -1;
|
||||||
}
|
}
|
||||||
@@ -3441,9 +3444,9 @@ int sqlite3Select(
|
|||||||
sAggInfo.sortingIdx = pParse->nTab++;
|
sAggInfo.sortingIdx = pParse->nTab++;
|
||||||
pKeyInfo = keyInfoFromExprList(pParse, pGroupBy);
|
pKeyInfo = keyInfoFromExprList(pParse, pGroupBy);
|
||||||
addrSortingIdx =
|
addrSortingIdx =
|
||||||
sqlite3VdbeOp3(v, OP_OpenEphemeral, sAggInfo.sortingIdx,
|
sqlite3VdbeAddOp4(v, OP_OpenEphemeral, sAggInfo.sortingIdx,
|
||||||
sAggInfo.nSortingColumn,
|
sAggInfo.nSortingColumn, 0,
|
||||||
(char*)pKeyInfo, P3_KEYINFO_HANDOFF);
|
(char*)pKeyInfo, P4_KEYINFO_HANDOFF);
|
||||||
|
|
||||||
/* Initialize memory locations used by GROUP BY aggregate processing
|
/* Initialize memory locations used by GROUP BY aggregate processing
|
||||||
*/
|
*/
|
||||||
@@ -3453,11 +3456,11 @@ int sqlite3Select(
|
|||||||
pParse->nMem += pGroupBy->nExpr;
|
pParse->nMem += pGroupBy->nExpr;
|
||||||
iBMem = pParse->nMem;
|
iBMem = pParse->nMem;
|
||||||
pParse->nMem += pGroupBy->nExpr;
|
pParse->nMem += pGroupBy->nExpr;
|
||||||
sqlite3VdbeAddOp(v, OP_MemInt, 0, iAbortFlag);
|
sqlite3VdbeAddOp2(v, OP_MemInt, 0, iAbortFlag);
|
||||||
VdbeComment((v, "clear abort flag"));
|
VdbeComment((v, "clear abort flag"));
|
||||||
sqlite3VdbeAddOp(v, OP_MemInt, 0, iUseFlag);
|
sqlite3VdbeAddOp2(v, OP_MemInt, 0, iUseFlag);
|
||||||
VdbeComment((v, "indicate accumulator empty"));
|
VdbeComment((v, "indicate accumulator empty"));
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, addrInitializeLoop);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrInitializeLoop);
|
||||||
|
|
||||||
/* Generate a subroutine that outputs a single row of the result
|
/* Generate a subroutine that outputs a single row of the result
|
||||||
** set. This subroutine first looks at the iUseFlag. If iUseFlag
|
** set. This subroutine first looks at the iUseFlag. If iUseFlag
|
||||||
@@ -3467,13 +3470,13 @@ int sqlite3Select(
|
|||||||
** order to signal the caller to abort.
|
** order to signal the caller to abort.
|
||||||
*/
|
*/
|
||||||
addrSetAbort = sqlite3VdbeCurrentAddr(v);
|
addrSetAbort = sqlite3VdbeCurrentAddr(v);
|
||||||
sqlite3VdbeAddOp(v, OP_MemInt, 1, iAbortFlag);
|
sqlite3VdbeAddOp2(v, OP_MemInt, 1, iAbortFlag);
|
||||||
VdbeComment((v, "set abort flag"));
|
VdbeComment((v, "set abort flag"));
|
||||||
sqlite3VdbeAddOp(v, OP_Return, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
|
||||||
addrOutputRow = sqlite3VdbeCurrentAddr(v);
|
addrOutputRow = sqlite3VdbeCurrentAddr(v);
|
||||||
sqlite3VdbeAddOp(v, OP_IfMemPos, iUseFlag, addrOutputRow+2);
|
sqlite3VdbeAddOp2(v, OP_IfMemPos, iUseFlag, addrOutputRow+2);
|
||||||
VdbeComment((v, "Groupby result generator entry point"));
|
VdbeComment((v, "Groupby result generator entry point"));
|
||||||
sqlite3VdbeAddOp(v, OP_Return, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
|
||||||
finalizeAggFunctions(pParse, &sAggInfo);
|
finalizeAggFunctions(pParse, &sAggInfo);
|
||||||
if( pHaving ){
|
if( pHaving ){
|
||||||
sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, 1);
|
sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, 1);
|
||||||
@@ -3484,14 +3487,14 @@ int sqlite3Select(
|
|||||||
if( rc ){
|
if( rc ){
|
||||||
goto select_end;
|
goto select_end;
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_Return, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
|
||||||
VdbeComment((v, "end groupby result generator"));
|
VdbeComment((v, "end groupby result generator"));
|
||||||
|
|
||||||
/* Generate a subroutine that will reset the group-by accumulator
|
/* Generate a subroutine that will reset the group-by accumulator
|
||||||
*/
|
*/
|
||||||
addrReset = sqlite3VdbeCurrentAddr(v);
|
addrReset = sqlite3VdbeCurrentAddr(v);
|
||||||
resetAccumulator(pParse, &sAggInfo);
|
resetAccumulator(pParse, &sAggInfo);
|
||||||
sqlite3VdbeAddOp(v, OP_Return, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
|
||||||
|
|
||||||
/* Begin a loop that will extract all source rows in GROUP BY order.
|
/* Begin a loop that will extract all source rows in GROUP BY order.
|
||||||
** This might involve two separate loops with an OP_Sort in between, or
|
** This might involve two separate loops with an OP_Sort in between, or
|
||||||
@@ -3499,7 +3502,7 @@ int sqlite3Select(
|
|||||||
** in the right order to begin with.
|
** in the right order to begin with.
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeResolveLabel(v, addrInitializeLoop);
|
sqlite3VdbeResolveLabel(v, addrInitializeLoop);
|
||||||
sqlite3VdbeAddOp(v, OP_Gosub, 0, addrReset);
|
sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrReset);
|
||||||
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy);
|
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy);
|
||||||
if( pWInfo==0 ) goto select_end;
|
if( pWInfo==0 ) goto select_end;
|
||||||
if( pGroupBy==0 ){
|
if( pGroupBy==0 ){
|
||||||
@@ -3517,7 +3520,7 @@ int sqlite3Select(
|
|||||||
*/
|
*/
|
||||||
groupBySort = 1;
|
groupBySort = 1;
|
||||||
sqlite3ExprCodeExprList(pParse, pGroupBy);
|
sqlite3ExprCodeExprList(pParse, pGroupBy);
|
||||||
sqlite3VdbeAddOp(v, OP_Sequence, sAggInfo.sortingIdx, 0);
|
sqlite3VdbeAddOp2(v, OP_Sequence, sAggInfo.sortingIdx, 0);
|
||||||
j = pGroupBy->nExpr+1;
|
j = pGroupBy->nExpr+1;
|
||||||
for(i=0; i<sAggInfo.nColumn; i++){
|
for(i=0; i<sAggInfo.nColumn; i++){
|
||||||
struct AggInfo_col *pCol = &sAggInfo.aCol[i];
|
struct AggInfo_col *pCol = &sAggInfo.aCol[i];
|
||||||
@@ -3525,10 +3528,10 @@ int sqlite3Select(
|
|||||||
sqlite3ExprCodeGetColumn(v, pCol->pTab, pCol->iColumn, pCol->iTable);
|
sqlite3ExprCodeGetColumn(v, pCol->pTab, pCol->iColumn, pCol->iTable);
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_MakeRecord, j, 0);
|
sqlite3VdbeAddOp2(v, OP_MakeRecord, j, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_IdxInsert, sAggInfo.sortingIdx, 0);
|
sqlite3VdbeAddOp2(v, OP_IdxInsert, sAggInfo.sortingIdx, 0);
|
||||||
sqlite3WhereEnd(pWInfo);
|
sqlite3WhereEnd(pWInfo);
|
||||||
sqlite3VdbeAddOp(v, OP_Sort, sAggInfo.sortingIdx, addrEnd);
|
sqlite3VdbeAddOp2(v, OP_Sort, sAggInfo.sortingIdx, addrEnd);
|
||||||
VdbeComment((v, "GROUP BY sort"));
|
VdbeComment((v, "GROUP BY sort"));
|
||||||
sAggInfo.useSortingIdx = 1;
|
sAggInfo.useSortingIdx = 1;
|
||||||
}
|
}
|
||||||
@@ -3541,24 +3544,24 @@ int sqlite3Select(
|
|||||||
addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
|
addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
|
||||||
for(j=0; j<pGroupBy->nExpr; j++){
|
for(j=0; j<pGroupBy->nExpr; j++){
|
||||||
if( groupBySort ){
|
if( groupBySort ){
|
||||||
sqlite3VdbeAddOp(v, OP_Column, sAggInfo.sortingIdx, j);
|
sqlite3VdbeAddOp2(v, OP_Column, sAggInfo.sortingIdx, j);
|
||||||
}else{
|
}else{
|
||||||
sAggInfo.directMode = 1;
|
sAggInfo.directMode = 1;
|
||||||
sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr);
|
sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, iBMem+j, j<pGroupBy->nExpr-1);
|
sqlite3VdbeAddOp2(v, OP_MemStore, iBMem+j, j<pGroupBy->nExpr-1);
|
||||||
}
|
}
|
||||||
for(j=pGroupBy->nExpr-1; j>=0; j--){
|
for(j=pGroupBy->nExpr-1; j>=0; j--){
|
||||||
if( j<pGroupBy->nExpr-1 ){
|
if( j<pGroupBy->nExpr-1 ){
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, iBMem+j, 0);
|
sqlite3VdbeAddOp2(v, OP_MemLoad, iBMem+j, 0);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, iAMem+j, 0);
|
sqlite3VdbeAddOp2(v, OP_MemLoad, iAMem+j, 0);
|
||||||
if( j==0 ){
|
if( j==0 ){
|
||||||
sqlite3VdbeAddOp(v, OP_Eq, 0x200, addrProcessRow);
|
sqlite3VdbeAddOp2(v, OP_Eq, 0x200, addrProcessRow);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_Ne, 0x200, addrGroupByChange);
|
sqlite3VdbeAddOp2(v, OP_Ne, 0x200, addrGroupByChange);
|
||||||
}
|
}
|
||||||
sqlite3VdbeChangeP3(v, -1, (void*)pKeyInfo->aColl[j], P3_COLLSEQ);
|
sqlite3VdbeChangeP4(v, -1, (void*)pKeyInfo->aColl[j], P4_COLLSEQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate code that runs whenever the GROUP BY changes.
|
/* Generate code that runs whenever the GROUP BY changes.
|
||||||
@@ -3572,13 +3575,13 @@ int sqlite3Select(
|
|||||||
*/
|
*/
|
||||||
sqlite3VdbeResolveLabel(v, addrGroupByChange);
|
sqlite3VdbeResolveLabel(v, addrGroupByChange);
|
||||||
for(j=0; j<pGroupBy->nExpr; j++){
|
for(j=0; j<pGroupBy->nExpr; j++){
|
||||||
sqlite3VdbeAddOp(v, OP_MemMove, iAMem+j, iBMem+j);
|
sqlite3VdbeAddOp2(v, OP_MemMove, iAMem+j, iBMem+j);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_Gosub, 0, addrOutputRow);
|
sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrOutputRow);
|
||||||
VdbeComment((v, "output one row"));
|
VdbeComment((v, "output one row"));
|
||||||
sqlite3VdbeAddOp(v, OP_IfMemPos, iAbortFlag, addrEnd);
|
sqlite3VdbeAddOp2(v, OP_IfMemPos, iAbortFlag, addrEnd);
|
||||||
VdbeComment((v, "check abort flag"));
|
VdbeComment((v, "check abort flag"));
|
||||||
sqlite3VdbeAddOp(v, OP_Gosub, 0, addrReset);
|
sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrReset);
|
||||||
VdbeComment((v, "reset accumulator"));
|
VdbeComment((v, "reset accumulator"));
|
||||||
|
|
||||||
/* Update the aggregate accumulators based on the content of
|
/* Update the aggregate accumulators based on the content of
|
||||||
@@ -3586,13 +3589,13 @@ int sqlite3Select(
|
|||||||
*/
|
*/
|
||||||
sqlite3VdbeResolveLabel(v, addrProcessRow);
|
sqlite3VdbeResolveLabel(v, addrProcessRow);
|
||||||
updateAccumulator(pParse, &sAggInfo);
|
updateAccumulator(pParse, &sAggInfo);
|
||||||
sqlite3VdbeAddOp(v, OP_MemInt, 1, iUseFlag);
|
sqlite3VdbeAddOp2(v, OP_MemInt, 1, iUseFlag);
|
||||||
VdbeComment((v, "indicate data in accumulator"));
|
VdbeComment((v, "indicate data in accumulator"));
|
||||||
|
|
||||||
/* End of the loop
|
/* End of the loop
|
||||||
*/
|
*/
|
||||||
if( groupBySort ){
|
if( groupBySort ){
|
||||||
sqlite3VdbeAddOp(v, OP_Next, sAggInfo.sortingIdx, addrTopOfLoop);
|
sqlite3VdbeAddOp2(v, OP_Next, sAggInfo.sortingIdx, addrTopOfLoop);
|
||||||
}else{
|
}else{
|
||||||
sqlite3WhereEnd(pWInfo);
|
sqlite3WhereEnd(pWInfo);
|
||||||
sqlite3VdbeChangeToNoop(v, addrSortingIdx, 1);
|
sqlite3VdbeChangeToNoop(v, addrSortingIdx, 1);
|
||||||
@@ -3600,7 +3603,7 @@ int sqlite3Select(
|
|||||||
|
|
||||||
/* Output the final row of result
|
/* Output the final row of result
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp(v, OP_Gosub, 0, addrOutputRow);
|
sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrOutputRow);
|
||||||
VdbeComment((v, "output final row"));
|
VdbeComment((v, "output final row"));
|
||||||
|
|
||||||
} /* endif pGroupBy */
|
} /* endif pGroupBy */
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.630 2008/01/02 17:11:14 danielk1977 Exp $
|
** @(#) $Id: sqliteInt.h,v 1.631 2008/01/03 00:01:25 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITEINT_H_
|
#ifndef _SQLITEINT_H_
|
||||||
#define _SQLITEINT_H_
|
#define _SQLITEINT_H_
|
||||||
@@ -701,7 +701,7 @@ struct CollSeq {
|
|||||||
**
|
**
|
||||||
** But rather than start with 0 or 1, we begin with 'a'. That way,
|
** But rather than start with 0 or 1, we begin with 'a'. That way,
|
||||||
** when multiple affinity types are concatenated into a string and
|
** when multiple affinity types are concatenated into a string and
|
||||||
** used as the P3 operand, they will be more readable.
|
** used as the P4 operand, they will be more readable.
|
||||||
**
|
**
|
||||||
** Note also that the numeric types are grouped together so that testing
|
** Note also that the numeric types are grouped together so that testing
|
||||||
** for a numeric type is a single comparison.
|
** for a numeric type is a single comparison.
|
||||||
@@ -1294,7 +1294,7 @@ struct NameContext {
|
|||||||
**
|
**
|
||||||
** addrOpenEphm[] entries contain the address of OP_OpenEphemeral opcodes.
|
** addrOpenEphm[] entries contain the address of OP_OpenEphemeral opcodes.
|
||||||
** These addresses must be stored so that we can go back and fill in
|
** These addresses must be stored so that we can go back and fill in
|
||||||
** the P3_KEYINFO and P2 parameters later. Neither the KeyInfo nor
|
** the P4_KEYINFO and P2 parameters later. Neither the KeyInfo nor
|
||||||
** the number of columns in P2 can be computed at the same time
|
** the number of columns in P2 can be computed at the same time
|
||||||
** as the OP_OpenEphm instruction is coded because not
|
** as the OP_OpenEphm instruction is coded because not
|
||||||
** enough information about the compound query is known at that point.
|
** enough information about the compound query is known at that point.
|
||||||
|
@@ -822,4 +822,3 @@ int fs_register(){
|
|||||||
#ifdef SQLITE_TEST
|
#ifdef SQLITE_TEST
|
||||||
int SqlitetestOnefile_Init() {return fs_register();}
|
int SqlitetestOnefile_Init() {return fs_register();}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -248,13 +248,13 @@ void sqlite3FinishTrigger(
|
|||||||
sqlite3BeginWriteOperation(pParse, 0, iDb);
|
sqlite3BeginWriteOperation(pParse, 0, iDb);
|
||||||
sqlite3OpenMasterTable(pParse, iDb);
|
sqlite3OpenMasterTable(pParse, iDb);
|
||||||
addr = sqlite3VdbeAddOpList(v, ArraySize(insertTrig), insertTrig);
|
addr = sqlite3VdbeAddOpList(v, ArraySize(insertTrig), insertTrig);
|
||||||
sqlite3VdbeChangeP3(v, addr+2, pTrig->name, 0);
|
sqlite3VdbeChangeP4(v, addr+2, pTrig->name, 0);
|
||||||
sqlite3VdbeChangeP3(v, addr+3, pTrig->table, 0);
|
sqlite3VdbeChangeP4(v, addr+3, pTrig->table, 0);
|
||||||
sqlite3VdbeChangeP3(v, addr+6, (char*)pAll->z, pAll->n);
|
sqlite3VdbeChangeP4(v, addr+6, (char*)pAll->z, pAll->n);
|
||||||
sqlite3ChangeCookie(db, v, iDb);
|
sqlite3ChangeCookie(db, v, iDb);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, 0, 0);
|
||||||
sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, sqlite3MPrintf(
|
sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, sqlite3MPrintf(
|
||||||
db, "type='trigger' AND name='%q'", pTrig->name), P3_DYNAMIC
|
db, "type='trigger' AND name='%q'", pTrig->name), P4_DYNAMIC
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -548,10 +548,10 @@ 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);
|
||||||
sqlite3VdbeChangeP3(v, base+1, pTrigger->name, 0);
|
sqlite3VdbeChangeP4(v, base+1, pTrigger->name, 0);
|
||||||
sqlite3ChangeCookie(db, v, iDb);
|
sqlite3ChangeCookie(db, v, iDb);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, 0, 0);
|
||||||
sqlite3VdbeOp3(v, OP_DropTrigger, iDb, 0, pTrigger->name, 0);
|
sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->name, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -676,7 +676,7 @@ static int codeTriggerProgram(
|
|||||||
|
|
||||||
assert( pTriggerStep!=0 );
|
assert( pTriggerStep!=0 );
|
||||||
assert( v!=0 );
|
assert( v!=0 );
|
||||||
sqlite3VdbeAddOp(v, OP_ContextPush, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_ContextPush, 0, 0);
|
||||||
VdbeComment((v, "begin trigger %s", pStepList->pTrig->name));
|
VdbeComment((v, "begin trigger %s", pStepList->pTrig->name));
|
||||||
while( pTriggerStep ){
|
while( pTriggerStep ){
|
||||||
orconf = (orconfin == OE_Default)?pTriggerStep->orconf:orconfin;
|
orconf = (orconfin == OE_Default)?pTriggerStep->orconf:orconfin;
|
||||||
@@ -695,31 +695,31 @@ static int codeTriggerProgram(
|
|||||||
case TK_UPDATE: {
|
case TK_UPDATE: {
|
||||||
SrcList *pSrc;
|
SrcList *pSrc;
|
||||||
pSrc = targetSrcList(pParse, pTriggerStep);
|
pSrc = targetSrcList(pParse, pTriggerStep);
|
||||||
sqlite3VdbeAddOp(v, OP_ResetCount, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_ResetCount, 0, 0);
|
||||||
sqlite3Update(pParse, pSrc,
|
sqlite3Update(pParse, pSrc,
|
||||||
sqlite3ExprListDup(db, pTriggerStep->pExprList),
|
sqlite3ExprListDup(db, pTriggerStep->pExprList),
|
||||||
sqlite3ExprDup(db, pTriggerStep->pWhere), orconf);
|
sqlite3ExprDup(db, pTriggerStep->pWhere), orconf);
|
||||||
sqlite3VdbeAddOp(v, OP_ResetCount, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_ResetCount, 1, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_INSERT: {
|
case TK_INSERT: {
|
||||||
SrcList *pSrc;
|
SrcList *pSrc;
|
||||||
pSrc = targetSrcList(pParse, pTriggerStep);
|
pSrc = targetSrcList(pParse, pTriggerStep);
|
||||||
sqlite3VdbeAddOp(v, OP_ResetCount, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_ResetCount, 0, 0);
|
||||||
sqlite3Insert(pParse, pSrc,
|
sqlite3Insert(pParse, pSrc,
|
||||||
sqlite3ExprListDup(db, pTriggerStep->pExprList),
|
sqlite3ExprListDup(db, pTriggerStep->pExprList),
|
||||||
sqlite3SelectDup(db, pTriggerStep->pSelect),
|
sqlite3SelectDup(db, pTriggerStep->pSelect),
|
||||||
sqlite3IdListDup(db, pTriggerStep->pIdList), orconf);
|
sqlite3IdListDup(db, pTriggerStep->pIdList), orconf);
|
||||||
sqlite3VdbeAddOp(v, OP_ResetCount, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_ResetCount, 1, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_DELETE: {
|
case TK_DELETE: {
|
||||||
SrcList *pSrc;
|
SrcList *pSrc;
|
||||||
sqlite3VdbeAddOp(v, OP_ResetCount, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_ResetCount, 0, 0);
|
||||||
pSrc = targetSrcList(pParse, pTriggerStep);
|
pSrc = targetSrcList(pParse, pTriggerStep);
|
||||||
sqlite3DeleteFrom(pParse, pSrc,
|
sqlite3DeleteFrom(pParse, pSrc,
|
||||||
sqlite3ExprDup(db, pTriggerStep->pWhere));
|
sqlite3ExprDup(db, pTriggerStep->pWhere));
|
||||||
sqlite3VdbeAddOp(v, OP_ResetCount, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_ResetCount, 1, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -727,7 +727,7 @@ static int codeTriggerProgram(
|
|||||||
}
|
}
|
||||||
pTriggerStep = pTriggerStep->pNext;
|
pTriggerStep = pTriggerStep->pNext;
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_ContextPop, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_ContextPop, 0, 0);
|
||||||
VdbeComment((v, "end trigger %s", pStepList->pTrig->name));
|
VdbeComment((v, "end trigger %s", pStepList->pTrig->name));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
122
src/update.c
122
src/update.c
@@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle UPDATE statements.
|
** to handle UPDATE statements.
|
||||||
**
|
**
|
||||||
** $Id: update.c,v 1.148 2008/01/02 16:27:10 danielk1977 Exp $
|
** $Id: update.c,v 1.149 2008/01/03 00:01:25 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ static void updateVirtualTable(
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** The most recently coded instruction was an OP_Column to retrieve the
|
** The most recently coded instruction was an OP_Column to retrieve the
|
||||||
** i-th column of table pTab. This routine sets the P3 parameter of the
|
** i-th column of table pTab. This routine sets the P4 parameter of the
|
||||||
** OP_Column to the default value, if any.
|
** OP_Column to the default value, if any.
|
||||||
**
|
**
|
||||||
** The default value of a column is specified by a DEFAULT clause in the
|
** The default value of a column is specified by a DEFAULT clause in the
|
||||||
@@ -39,9 +39,9 @@ static void updateVirtualTable(
|
|||||||
** was created, or added later to the table definition by an ALTER TABLE
|
** was created, or added later to the table definition by an ALTER TABLE
|
||||||
** command. If the latter, then the row-records in the table btree on disk
|
** command. If the latter, then the row-records in the table btree on disk
|
||||||
** may not contain a value for the column and the default value, taken
|
** may not contain a value for the column and the default value, taken
|
||||||
** from the P3 parameter of the OP_Column instruction, is returned instead.
|
** from the P4 parameter of the OP_Column instruction, is returned instead.
|
||||||
** If the former, then all row-records are guaranteed to include a value
|
** If the former, then all row-records are guaranteed to include a value
|
||||||
** for the column and the P3 value is not required.
|
** for the column and the P4 value is not required.
|
||||||
**
|
**
|
||||||
** Column definitions created by an ALTER TABLE command may only have
|
** Column definitions created by an ALTER TABLE command may only have
|
||||||
** literal default values specified: a number, null or a string. (If a more
|
** literal default values specified: a number, null or a string. (If a more
|
||||||
@@ -49,7 +49,7 @@ static void updateVirtualTable(
|
|||||||
** when the ALTER TABLE is executed and one of the literal values written
|
** when the ALTER TABLE is executed and one of the literal values written
|
||||||
** into the sqlite_master table.)
|
** into the sqlite_master table.)
|
||||||
**
|
**
|
||||||
** Therefore, the P3 parameter is only required if the default value for
|
** Therefore, the P4 parameter is only required if the default value for
|
||||||
** the column is a literal number, string or null. The sqlite3ValueFromExpr()
|
** the column is a literal number, string or null. The sqlite3ValueFromExpr()
|
||||||
** function is capable of transforming these types of expressions into
|
** function is capable of transforming these types of expressions into
|
||||||
** sqlite3_value objects.
|
** sqlite3_value objects.
|
||||||
@@ -64,8 +64,8 @@ void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i){
|
|||||||
sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc,
|
sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc,
|
||||||
pCol->affinity, &pValue);
|
pCol->affinity, &pValue);
|
||||||
if( pValue ){
|
if( pValue ){
|
||||||
sqlite3VdbeAddOp(v, OP_DfltValue, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_DfltValue, 0, 0);
|
||||||
sqlite3VdbeChangeP3(v, -1, (const char *)pValue, P3_MEM);
|
sqlite3VdbeChangeP4(v, -1, (const char *)pValue, P4_MEM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -302,25 +302,25 @@ void sqlite3Update(
|
|||||||
|
|
||||||
/* Create pseudo-tables for NEW and OLD
|
/* Create pseudo-tables for NEW and OLD
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
|
sqlite3VdbeAddOp2(v, OP_OpenPseudo, oldIdx, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_SetNumColumns, oldIdx, pTab->nCol);
|
sqlite3VdbeAddOp2(v, OP_SetNumColumns, oldIdx, pTab->nCol);
|
||||||
sqlite3VdbeAddOp(v, OP_OpenPseudo, newIdx, 0);
|
sqlite3VdbeAddOp2(v, OP_OpenPseudo, newIdx, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_SetNumColumns, newIdx, pTab->nCol);
|
sqlite3VdbeAddOp2(v, OP_SetNumColumns, newIdx, pTab->nCol);
|
||||||
|
|
||||||
iGoto = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
|
iGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
|
||||||
addr = sqlite3VdbeMakeLabel(v);
|
addr = sqlite3VdbeMakeLabel(v);
|
||||||
iBeginBeforeTrigger = sqlite3VdbeCurrentAddr(v);
|
iBeginBeforeTrigger = sqlite3VdbeCurrentAddr(v);
|
||||||
if( sqlite3CodeRowTrigger(pParse, TK_UPDATE, pChanges, TRIGGER_BEFORE, pTab,
|
if( sqlite3CodeRowTrigger(pParse, TK_UPDATE, pChanges, TRIGGER_BEFORE, pTab,
|
||||||
newIdx, oldIdx, onError, addr, &old_col_mask, &new_col_mask) ){
|
newIdx, oldIdx, onError, addr, &old_col_mask, &new_col_mask) ){
|
||||||
goto update_cleanup;
|
goto update_cleanup;
|
||||||
}
|
}
|
||||||
iEndBeforeTrigger = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
|
iEndBeforeTrigger = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
|
||||||
iBeginAfterTrigger = sqlite3VdbeCurrentAddr(v);
|
iBeginAfterTrigger = sqlite3VdbeCurrentAddr(v);
|
||||||
if( sqlite3CodeRowTrigger(pParse, TK_UPDATE, pChanges, TRIGGER_AFTER, pTab,
|
if( sqlite3CodeRowTrigger(pParse, TK_UPDATE, pChanges, TRIGGER_AFTER, pTab,
|
||||||
newIdx, oldIdx, onError, addr, &old_col_mask, &new_col_mask) ){
|
newIdx, oldIdx, onError, addr, &old_col_mask, &new_col_mask) ){
|
||||||
goto update_cleanup;
|
goto update_cleanup;
|
||||||
}
|
}
|
||||||
iEndAfterTrigger = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
|
iEndAfterTrigger = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
|
||||||
sqlite3VdbeJumpHere(v, iGoto);
|
sqlite3VdbeJumpHere(v, iGoto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,8 +344,8 @@ void sqlite3Update(
|
|||||||
|
|
||||||
/* Remember the rowid of every item to be updated.
|
/* Remember the rowid of every item to be updated.
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp(v, IsVirtual(pTab) ? OP_VRowid : OP_Rowid, iCur, 0);
|
sqlite3VdbeAddOp2(v, IsVirtual(pTab) ? OP_VRowid : OP_Rowid, iCur, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_FifoWrite, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_FifoWrite, 0, 0);
|
||||||
|
|
||||||
/* End the database scan loop.
|
/* End the database scan loop.
|
||||||
*/
|
*/
|
||||||
@@ -355,7 +355,7 @@ void sqlite3Update(
|
|||||||
*/
|
*/
|
||||||
if( db->flags & SQLITE_CountRows && !pParse->trigStack ){
|
if( db->flags & SQLITE_CountRows && !pParse->trigStack ){
|
||||||
memCnt = pParse->nMem++;
|
memCnt = pParse->nMem++;
|
||||||
sqlite3VdbeAddOp(v, OP_MemInt, 0, memCnt);
|
sqlite3VdbeAddOp2(v, OP_MemInt, 0, memCnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !isView && !IsVirtual(pTab) ){
|
if( !isView && !IsVirtual(pTab) ){
|
||||||
@@ -380,9 +380,9 @@ void sqlite3Update(
|
|||||||
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
||||||
if( openAll || aIdxUsed[i] ){
|
if( openAll || aIdxUsed[i] ){
|
||||||
KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
|
KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, iDb, 0);
|
||||||
sqlite3VdbeOp3(v, OP_OpenWrite, iCur+i+1, pIdx->tnum,
|
sqlite3VdbeAddOp4(v, OP_OpenWrite, iCur+i+1, pIdx->tnum, 0,
|
||||||
(char*)pKey, P3_KEYINFO_HANDOFF);
|
(char*)pKey, P4_KEYINFO_HANDOFF);
|
||||||
assert( pParse->nTab>iCur+i+1 );
|
assert( pParse->nTab>iCur+i+1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -395,61 +395,61 @@ void sqlite3Update(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Top of the update loop */
|
/* Top of the update loop */
|
||||||
addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, 0);
|
addr = sqlite3VdbeAddOp2(v, OP_FifoRead, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_StackDepth, -1, 0);
|
sqlite3VdbeAddOp2(v, OP_StackDepth, -1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, mem1, 0);
|
sqlite3VdbeAddOp2(v, OP_MemStore, mem1, 0);
|
||||||
|
|
||||||
if( triggers_exist ){
|
if( triggers_exist ){
|
||||||
/* Make cursor iCur point to the record that is being updated.
|
/* Make cursor iCur point to the record that is being updated.
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp(v, OP_NotExists, iCur, addr);
|
sqlite3VdbeAddOp2(v, OP_NotExists, iCur, addr);
|
||||||
|
|
||||||
/* Generate the OLD table
|
/* Generate the OLD table
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
|
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, 0);
|
||||||
if( !old_col_mask ){
|
if( !old_col_mask ){
|
||||||
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Null, 0, 0);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
|
sqlite3VdbeAddOp2(v, OP_RowData, iCur, 0);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_Insert, oldIdx, 0);
|
sqlite3VdbeAddOp2(v, OP_Insert, oldIdx, 0);
|
||||||
|
|
||||||
/* Generate the NEW table
|
/* Generate the NEW table
|
||||||
*/
|
*/
|
||||||
if( chngRowid ){
|
if( chngRowid ){
|
||||||
sqlite3ExprCodeAndCache(pParse, pRowidExpr);
|
sqlite3ExprCodeAndCache(pParse, pRowidExpr);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
|
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, 0);
|
||||||
}
|
}
|
||||||
for(i=0; i<pTab->nCol; i++){
|
for(i=0; i<pTab->nCol; i++){
|
||||||
if( i==pTab->iPKey ){
|
if( i==pTab->iPKey ){
|
||||||
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Null, 0, 0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
j = aXRef[i];
|
j = aXRef[i];
|
||||||
if( new_col_mask&((u32)1<<i) || new_col_mask==0xffffffff ){
|
if( new_col_mask&((u32)1<<i) || new_col_mask==0xffffffff ){
|
||||||
if( j<0 ){
|
if( j<0 ){
|
||||||
sqlite3VdbeAddOp(v, OP_Column, iCur, i);
|
sqlite3VdbeAddOp2(v, OP_Column, iCur, i);
|
||||||
sqlite3ColumnDefault(v, pTab, i);
|
sqlite3ColumnDefault(v, pTab, i);
|
||||||
}else{
|
}else{
|
||||||
sqlite3ExprCodeAndCache(pParse, pChanges->a[j].pExpr);
|
sqlite3ExprCodeAndCache(pParse, pChanges->a[j].pExpr);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Null, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
|
sqlite3VdbeAddOp2(v, OP_MakeRecord, pTab->nCol, 0);
|
||||||
if( !isView ){
|
if( !isView ){
|
||||||
sqlite3TableAffinityStr(v, pTab);
|
sqlite3TableAffinityStr(v, pTab);
|
||||||
}
|
}
|
||||||
if( pParse->nErr ) goto update_cleanup;
|
if( pParse->nErr ) goto update_cleanup;
|
||||||
sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0);
|
sqlite3VdbeAddOp2(v, OP_Insert, newIdx, 0);
|
||||||
|
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, iBeginBeforeTrigger);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginBeforeTrigger);
|
||||||
sqlite3VdbeJumpHere(v, iEndBeforeTrigger);
|
sqlite3VdbeJumpHere(v, iEndBeforeTrigger);
|
||||||
|
|
||||||
if( !isView ){
|
if( !isView ){
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, mem1, 0);
|
sqlite3VdbeAddOp2(v, OP_MemLoad, mem1, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -461,8 +461,8 @@ void sqlite3Update(
|
|||||||
** Also, the old data is needed to delete the old index entries.
|
** Also, the old data is needed to delete the old index entries.
|
||||||
** So make the cursor point at the old record.
|
** So make the cursor point at the old record.
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp(v, OP_NotExists, iCur, addr);
|
sqlite3VdbeAddOp2(v, OP_NotExists, iCur, addr);
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, mem1, 0);
|
sqlite3VdbeAddOp2(v, OP_MemLoad, mem1, 0);
|
||||||
|
|
||||||
/* If the record number will change, push the record number as it
|
/* If the record number will change, push the record number as it
|
||||||
** will be after the update. (The old record number is currently
|
** will be after the update. (The old record number is currently
|
||||||
@@ -470,19 +470,19 @@ void sqlite3Update(
|
|||||||
*/
|
*/
|
||||||
if( chngRowid ){
|
if( chngRowid ){
|
||||||
sqlite3ExprCode(pParse, pRowidExpr);
|
sqlite3ExprCode(pParse, pRowidExpr);
|
||||||
sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute new data for this record.
|
/* Compute new data for this record.
|
||||||
*/
|
*/
|
||||||
for(i=0; i<pTab->nCol; i++){
|
for(i=0; i<pTab->nCol; i++){
|
||||||
if( i==pTab->iPKey ){
|
if( i==pTab->iPKey ){
|
||||||
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Null, 0, 0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
j = aXRef[i];
|
j = aXRef[i];
|
||||||
if( j<0 ){
|
if( j<0 ){
|
||||||
sqlite3VdbeAddOp(v, OP_Column, iCur, i);
|
sqlite3VdbeAddOp2(v, OP_Column, iCur, i);
|
||||||
sqlite3ColumnDefault(v, pTab, i);
|
sqlite3ColumnDefault(v, pTab, i);
|
||||||
}else{
|
}else{
|
||||||
sqlite3ExprCode(pParse, pChanges->a[j].pExpr);
|
sqlite3ExprCode(pParse, pChanges->a[j].pExpr);
|
||||||
@@ -501,7 +501,7 @@ void sqlite3Update(
|
|||||||
/* If changing the record number, delete the old record.
|
/* If changing the record number, delete the old record.
|
||||||
*/
|
*/
|
||||||
if( chngRowid ){
|
if( chngRowid ){
|
||||||
sqlite3VdbeAddOp(v, OP_Delete, iCur, 0);
|
sqlite3VdbeAddOp2(v, OP_Delete, iCur, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the new index entries and the new record.
|
/* Create the new index entries and the new record.
|
||||||
@@ -512,33 +512,33 @@ void sqlite3Update(
|
|||||||
/* Increment the row counter
|
/* Increment the row counter
|
||||||
*/
|
*/
|
||||||
if( db->flags & SQLITE_CountRows && !pParse->trigStack){
|
if( db->flags & SQLITE_CountRows && !pParse->trigStack){
|
||||||
sqlite3VdbeAddOp(v, OP_MemIncr, 1, memCnt);
|
sqlite3VdbeAddOp2(v, OP_MemIncr, 1, memCnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If there are triggers, close all the cursors after each iteration
|
/* If there are triggers, close all the cursors after each iteration
|
||||||
** through the loop. The fire the after triggers.
|
** through the loop. The fire the after triggers.
|
||||||
*/
|
*/
|
||||||
if( triggers_exist ){
|
if( triggers_exist ){
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, iBeginAfterTrigger);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginAfterTrigger);
|
||||||
sqlite3VdbeJumpHere(v, iEndAfterTrigger);
|
sqlite3VdbeJumpHere(v, iEndAfterTrigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Repeat the above with the next record to be updated, until
|
/* Repeat the above with the next record to be updated, until
|
||||||
** all record selected by the WHERE clause have been updated.
|
** all record selected by the WHERE clause have been updated.
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, addr);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
|
||||||
sqlite3VdbeJumpHere(v, addr);
|
sqlite3VdbeJumpHere(v, addr);
|
||||||
|
|
||||||
/* Close all tables */
|
/* Close all tables */
|
||||||
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
||||||
if( openAll || aIdxUsed[i] ){
|
if( openAll || aIdxUsed[i] ){
|
||||||
sqlite3VdbeAddOp(v, OP_Close, iCur+i+1, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, iCur+i+1, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
|
||||||
if( triggers_exist ){
|
if( triggers_exist ){
|
||||||
sqlite3VdbeAddOp(v, OP_Close, newIdx, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, newIdx, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, oldIdx, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, oldIdx, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -547,9 +547,9 @@ void sqlite3Update(
|
|||||||
** invoke the callback function.
|
** invoke the callback function.
|
||||||
*/
|
*/
|
||||||
if( db->flags & SQLITE_CountRows && !pParse->trigStack && pParse->nested==0 ){
|
if( db->flags & SQLITE_CountRows && !pParse->trigStack && pParse->nested==0 ){
|
||||||
sqlite3VdbeAddOp(v, OP_ResultRow, memCnt, 1);
|
sqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1);
|
||||||
sqlite3VdbeSetNumCols(v, 1);
|
sqlite3VdbeSetNumCols(v, 1);
|
||||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", P4_STATIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
update_cleanup:
|
update_cleanup:
|
||||||
@@ -626,7 +626,7 @@ static void updateVirtualTable(
|
|||||||
*/
|
*/
|
||||||
assert( v );
|
assert( v );
|
||||||
ephemTab = pParse->nTab++;
|
ephemTab = pParse->nTab++;
|
||||||
sqlite3VdbeAddOp(v, OP_OpenEphemeral, ephemTab, pTab->nCol+1+(pRowid!=0));
|
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, pTab->nCol+1+(pRowid!=0));
|
||||||
|
|
||||||
/* fill the ephemeral table
|
/* fill the ephemeral table
|
||||||
*/
|
*/
|
||||||
@@ -637,23 +637,23 @@ static void updateVirtualTable(
|
|||||||
** Generate code to scan the ephemeral table and call VDelete and
|
** Generate code to scan the ephemeral table and call VDelete and
|
||||||
** VInsert
|
** VInsert
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp(v, OP_Rewind, ephemTab, 0);
|
sqlite3VdbeAddOp2(v, OP_Rewind, ephemTab, 0);
|
||||||
addr = sqlite3VdbeCurrentAddr(v);
|
addr = sqlite3VdbeCurrentAddr(v);
|
||||||
sqlite3VdbeAddOp(v, OP_Column, ephemTab, 0);
|
sqlite3VdbeAddOp2(v, OP_Column, ephemTab, 0);
|
||||||
if( pRowid ){
|
if( pRowid ){
|
||||||
sqlite3VdbeAddOp(v, OP_Column, ephemTab, 1);
|
sqlite3VdbeAddOp2(v, OP_Column, ephemTab, 1);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Dup, 0, 0);
|
||||||
}
|
}
|
||||||
for(i=0; i<pTab->nCol; i++){
|
for(i=0; i<pTab->nCol; i++){
|
||||||
sqlite3VdbeAddOp(v, OP_Column, ephemTab, i+1+(pRowid!=0));
|
sqlite3VdbeAddOp2(v, OP_Column, ephemTab, i+1+(pRowid!=0));
|
||||||
}
|
}
|
||||||
pParse->pVirtualLock = pTab;
|
pParse->pVirtualLock = pTab;
|
||||||
sqlite3VdbeOp3(v, OP_VUpdate, 0, pTab->nCol+2,
|
sqlite3VdbeAddOp4(v, OP_VUpdate, 0, pTab->nCol+2, 0,
|
||||||
(const char*)pTab->pVtab, P3_VTAB);
|
(const char*)pTab->pVtab, P4_VTAB);
|
||||||
sqlite3VdbeAddOp(v, OP_Next, ephemTab, addr);
|
sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr);
|
||||||
sqlite3VdbeJumpHere(v, addr-1);
|
sqlite3VdbeJumpHere(v, addr-1);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, ephemTab, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0);
|
||||||
|
|
||||||
/* Cleanup */
|
/* Cleanup */
|
||||||
sqlite3SelectDelete(pSelect);
|
sqlite3SelectDelete(pSelect);
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
** Most of the code in this file may be omitted by defining the
|
** Most of the code in this file may be omitted by defining the
|
||||||
** SQLITE_OMIT_VACUUM macro.
|
** SQLITE_OMIT_VACUUM macro.
|
||||||
**
|
**
|
||||||
** $Id: vacuum.c,v 1.75 2007/12/05 01:38:24 drh Exp $
|
** $Id: vacuum.c,v 1.76 2008/01/03 00:01:25 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "vdbeInt.h"
|
#include "vdbeInt.h"
|
||||||
@@ -70,7 +70,7 @@ static int execExecSql(sqlite3 *db, const char *zSql){
|
|||||||
void sqlite3Vacuum(Parse *pParse){
|
void sqlite3Vacuum(Parse *pParse){
|
||||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||||
if( v ){
|
if( v ){
|
||||||
sqlite3VdbeAddOp(v, OP_Vacuum, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Vacuum, 0, 0);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
341
src/vdbe.c
341
src/vdbe.c
@@ -22,7 +22,7 @@
|
|||||||
** the VDBE to do the work of the SQL statement. VDBE programs are
|
** the VDBE to do the work of the SQL statement. VDBE programs are
|
||||||
** similar in form to assembly language. The program consists of
|
** similar in form to assembly language. The program consists of
|
||||||
** a linear sequence of operations. Each operation has an opcode
|
** a linear sequence of operations. Each operation has an opcode
|
||||||
** and 3 operands. Operands P1 and P2 are integers. Operand P3
|
** and 3 operands. Operands P1 and P2 are integers. Operand P4
|
||||||
** is a null-terminated string. The P2 operand must be non-negative.
|
** is a null-terminated string. The P2 operand must be non-negative.
|
||||||
** Opcodes will typically ignore one or more operands. Many opcodes
|
** Opcodes will typically ignore one or more operands. Many opcodes
|
||||||
** ignore all three operands.
|
** ignore all three operands.
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
** in this file for details. If in doubt, do not deviate from existing
|
** in this file for details. If in doubt, do not deviate from existing
|
||||||
** commenting and indentation practices when changing or adding code.
|
** commenting and indentation practices when changing or adding code.
|
||||||
**
|
**
|
||||||
** $Id: vdbe.c,v 1.663 2008/01/02 14:28:13 drh Exp $
|
** $Id: vdbe.c,v 1.664 2008/01/03 00:01:25 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -482,8 +482,8 @@ int sqlite3VdbeExec(
|
|||||||
CHECK_FOR_INTERRUPT;
|
CHECK_FOR_INTERRUPT;
|
||||||
sqlite3VdbeIOTraceSql(p);
|
sqlite3VdbeIOTraceSql(p);
|
||||||
#ifdef SQLITE_DEBUG
|
#ifdef SQLITE_DEBUG
|
||||||
if( (p->db->flags & SQLITE_VdbeListing)!=0
|
if( p->pc==0 && ((p->db->flags & SQLITE_VdbeListing)!=0
|
||||||
|| sqlite3OsAccess(db->pVfs, "vdbe_explain", SQLITE_ACCESS_EXISTS)
|
|| sqlite3OsAccess(db->pVfs, "vdbe_explain", SQLITE_ACCESS_EXISTS))
|
||||||
){
|
){
|
||||||
int i;
|
int i;
|
||||||
printf("VDBE Program Listing:\n");
|
printf("VDBE Program Listing:\n");
|
||||||
@@ -655,7 +655,7 @@ case OP_Return: { /* no-push */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: Halt P1 P2 P3
|
/* Opcode: Halt P1 P2 P4
|
||||||
**
|
**
|
||||||
** Exit immediately. All open cursors, Fifos, etc are closed
|
** Exit immediately. All open cursors, Fifos, etc are closed
|
||||||
** automatically.
|
** automatically.
|
||||||
@@ -668,7 +668,7 @@ case OP_Return: { /* no-push */
|
|||||||
** then back out all changes that have occurred during this execution of the
|
** then back out all changes that have occurred during this execution of the
|
||||||
** VDBE, but do not rollback the transaction.
|
** VDBE, but do not rollback the transaction.
|
||||||
**
|
**
|
||||||
** If P3 is not null then it is an error message string.
|
** If P4 is not null then it is an error message string.
|
||||||
**
|
**
|
||||||
** There is an implied "Halt 0 0 0" instruction inserted at the very end of
|
** There is an implied "Halt 0 0 0" instruction inserted at the very end of
|
||||||
** every program. So a jump past the last instruction of the program
|
** every program. So a jump past the last instruction of the program
|
||||||
@@ -679,8 +679,8 @@ case OP_Halt: { /* no-push */
|
|||||||
p->rc = pOp->p1;
|
p->rc = pOp->p1;
|
||||||
p->pc = pc;
|
p->pc = pc;
|
||||||
p->errorAction = pOp->p2;
|
p->errorAction = pOp->p2;
|
||||||
if( pOp->p3.p ){
|
if( pOp->p4.p ){
|
||||||
sqlite3SetString(&p->zErrMsg, pOp->p3.p, (char*)0);
|
sqlite3SetString(&p->zErrMsg, pOp->p4.p, (char*)0);
|
||||||
}
|
}
|
||||||
rc = sqlite3VdbeHalt(p);
|
rc = sqlite3VdbeHalt(p);
|
||||||
assert( rc==SQLITE_BUSY || rc==SQLITE_OK );
|
assert( rc==SQLITE_BUSY || rc==SQLITE_OK );
|
||||||
@@ -726,54 +726,54 @@ case OP_Integer: {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: Int64 * * P3
|
/* Opcode: Int64 * * P4
|
||||||
**
|
**
|
||||||
** P3 is a pointer to a 64-bit integer value.
|
** P4 is a pointer to a 64-bit integer value.
|
||||||
** Push that value onto the stack.
|
** Push that value onto the stack.
|
||||||
*/
|
*/
|
||||||
case OP_Int64: {
|
case OP_Int64: {
|
||||||
pTos++;
|
pTos++;
|
||||||
assert( pOp->p3.p!=0 );
|
assert( pOp->p4.p!=0 );
|
||||||
pTos->flags = MEM_Int;
|
pTos->flags = MEM_Int;
|
||||||
memcpy(&pTos->u.i, pOp->p3.p, 8);
|
memcpy(&pTos->u.i, pOp->p4.p, 8);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: Real * * P3
|
/* Opcode: Real * * P4
|
||||||
**
|
**
|
||||||
** P3 is a pointer to a 64-bit floating point value. Push that value
|
** P4 is a pointer to a 64-bit floating point value. Push that value
|
||||||
** onto the stack.
|
** onto the stack.
|
||||||
*/
|
*/
|
||||||
case OP_Real: { /* same as TK_FLOAT, */
|
case OP_Real: { /* same as TK_FLOAT, */
|
||||||
pTos++;
|
pTos++;
|
||||||
pTos->flags = MEM_Real;
|
pTos->flags = MEM_Real;
|
||||||
memcpy(&pTos->r, pOp->p3.p, 8);
|
memcpy(&pTos->r, pOp->p4.p, 8);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: String8 * * P3
|
/* Opcode: String8 * * P4
|
||||||
**
|
**
|
||||||
** P3 points to a nul terminated UTF-8 string. This opcode is transformed
|
** P4 points to a nul terminated UTF-8 string. This opcode is transformed
|
||||||
** into an OP_String before it is executed for the first time.
|
** into an OP_String before it is executed for the first time.
|
||||||
*/
|
*/
|
||||||
case OP_String8: { /* same as TK_STRING */
|
case OP_String8: { /* same as TK_STRING */
|
||||||
assert( pOp->p3.p!=0 );
|
assert( pOp->p4.p!=0 );
|
||||||
pOp->opcode = OP_String;
|
pOp->opcode = OP_String;
|
||||||
pOp->p1 = strlen(pOp->p3.p);
|
pOp->p1 = strlen(pOp->p4.p);
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_UTF16
|
#ifndef SQLITE_OMIT_UTF16
|
||||||
if( encoding!=SQLITE_UTF8 ){
|
if( encoding!=SQLITE_UTF8 ){
|
||||||
pTos++;
|
pTos++;
|
||||||
sqlite3VdbeMemSetStr(pTos, pOp->p3.p, -1, SQLITE_UTF8, SQLITE_STATIC);
|
sqlite3VdbeMemSetStr(pTos, pOp->p4.p, -1, SQLITE_UTF8, SQLITE_STATIC);
|
||||||
if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pTos, encoding) ) goto no_mem;
|
if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pTos, encoding) ) goto no_mem;
|
||||||
if( SQLITE_OK!=sqlite3VdbeMemDynamicify(pTos) ) goto no_mem;
|
if( SQLITE_OK!=sqlite3VdbeMemDynamicify(pTos) ) goto no_mem;
|
||||||
pTos->flags &= ~(MEM_Dyn);
|
pTos->flags &= ~(MEM_Dyn);
|
||||||
pTos->flags |= MEM_Static;
|
pTos->flags |= MEM_Static;
|
||||||
if( pOp->p3type==P3_DYNAMIC ){
|
if( pOp->p4type==P4_DYNAMIC ){
|
||||||
sqlite3_free(pOp->p3.p);
|
sqlite3_free(pOp->p4.p);
|
||||||
}
|
}
|
||||||
pOp->p3type = P3_DYNAMIC;
|
pOp->p4type = P4_DYNAMIC;
|
||||||
pOp->p3.p = pTos->z;
|
pOp->p4.p = pTos->z;
|
||||||
pOp->p1 = pTos->n;
|
pOp->p1 = pTos->n;
|
||||||
if( pOp->p1>SQLITE_MAX_LENGTH ){
|
if( pOp->p1>SQLITE_MAX_LENGTH ){
|
||||||
goto too_big;
|
goto too_big;
|
||||||
@@ -787,15 +787,15 @@ case OP_String8: { /* same as TK_STRING */
|
|||||||
/* Fall through to the next case, OP_String */
|
/* Fall through to the next case, OP_String */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: String P1 * P3
|
/* Opcode: String P1 * P4
|
||||||
**
|
**
|
||||||
** The string value P3 of length P1 (bytes) is pushed onto the stack.
|
** The string value P4 of length P1 (bytes) is pushed onto the stack.
|
||||||
*/
|
*/
|
||||||
case OP_String: {
|
case OP_String: {
|
||||||
pTos++;
|
pTos++;
|
||||||
assert( pOp->p3.p!=0 );
|
assert( pOp->p4.p!=0 );
|
||||||
pTos->flags = MEM_Str|MEM_Static|MEM_Term;
|
pTos->flags = MEM_Str|MEM_Static|MEM_Term;
|
||||||
pTos->z = pOp->p3.p;
|
pTos->z = pOp->p4.p;
|
||||||
pTos->n = pOp->p1;
|
pTos->n = pOp->p1;
|
||||||
pTos->enc = encoding;
|
pTos->enc = encoding;
|
||||||
break;
|
break;
|
||||||
@@ -814,52 +814,52 @@ case OP_Null: {
|
|||||||
|
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_BLOB_LITERAL
|
#ifndef SQLITE_OMIT_BLOB_LITERAL
|
||||||
/* Opcode: HexBlob * * P3
|
/* Opcode: HexBlob * * P4
|
||||||
**
|
**
|
||||||
** P3 is an UTF-8 SQL hex encoding of a blob. The blob is pushed onto the
|
** P4 is an UTF-8 SQL hex encoding of a blob. The blob is pushed onto the
|
||||||
** vdbe stack.
|
** vdbe stack.
|
||||||
**
|
**
|
||||||
** The first time this instruction executes, in transforms itself into a
|
** The first time this instruction executes, in transforms itself into a
|
||||||
** 'Blob' opcode with a binary blob as P3.
|
** 'Blob' opcode with a binary blob as P4.
|
||||||
*/
|
*/
|
||||||
case OP_HexBlob: { /* same as TK_BLOB */
|
case OP_HexBlob: { /* same as TK_BLOB */
|
||||||
pOp->opcode = OP_Blob;
|
pOp->opcode = OP_Blob;
|
||||||
pOp->p1 = strlen(pOp->p3.p)/2;
|
pOp->p1 = strlen(pOp->p4.p)/2;
|
||||||
if( pOp->p1>SQLITE_MAX_LENGTH ){
|
if( pOp->p1>SQLITE_MAX_LENGTH ){
|
||||||
goto too_big;
|
goto too_big;
|
||||||
}
|
}
|
||||||
if( pOp->p1 ){
|
if( pOp->p1 ){
|
||||||
char *zBlob = sqlite3HexToBlob(db, pOp->p3.p);
|
char *zBlob = sqlite3HexToBlob(db, pOp->p4.p);
|
||||||
if( !zBlob ) goto no_mem;
|
if( !zBlob ) goto no_mem;
|
||||||
if( pOp->p3type==P3_DYNAMIC ){
|
if( pOp->p4type==P4_DYNAMIC ){
|
||||||
sqlite3_free(pOp->p3.p);
|
sqlite3_free(pOp->p4.p);
|
||||||
}
|
}
|
||||||
pOp->p3.p = zBlob;
|
pOp->p4.p = zBlob;
|
||||||
pOp->p3type = P3_DYNAMIC;
|
pOp->p4type = P4_DYNAMIC;
|
||||||
}else{
|
}else{
|
||||||
if( pOp->p3type==P3_DYNAMIC ){
|
if( pOp->p4type==P4_DYNAMIC ){
|
||||||
sqlite3_free(pOp->p3.p);
|
sqlite3_free(pOp->p4.p);
|
||||||
}
|
}
|
||||||
pOp->p3type = P3_STATIC;
|
pOp->p4type = P4_STATIC;
|
||||||
pOp->p3.p = "";
|
pOp->p4.p = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fall through to the next case, OP_Blob. */
|
/* Fall through to the next case, OP_Blob. */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: Blob P1 * P3
|
/* Opcode: Blob P1 * P4
|
||||||
**
|
**
|
||||||
** P3 points to a blob of data P1 bytes long. Push this
|
** P4 points to a blob of data P1 bytes long. Push this
|
||||||
** value onto the stack. This instruction is not coded directly
|
** value onto the stack. This instruction is not coded directly
|
||||||
** by the compiler. Instead, the compiler layer specifies
|
** by the compiler. Instead, the compiler layer specifies
|
||||||
** an OP_HexBlob opcode, with the hex string representation of
|
** an OP_HexBlob opcode, with the hex string representation of
|
||||||
** the blob as P3. This opcode is transformed to an OP_Blob
|
** the blob as P4. This opcode is transformed to an OP_Blob
|
||||||
** the first time it is executed.
|
** the first time it is executed.
|
||||||
*/
|
*/
|
||||||
case OP_Blob: {
|
case OP_Blob: {
|
||||||
pTos++;
|
pTos++;
|
||||||
assert( pOp->p1 <= SQLITE_MAX_LENGTH );
|
assert( pOp->p1 <= SQLITE_MAX_LENGTH );
|
||||||
sqlite3VdbeMemSetStr(pTos, pOp->p3.p, pOp->p1, 0, 0);
|
sqlite3VdbeMemSetStr(pTos, pOp->p4.p, pOp->p1, 0, 0);
|
||||||
pTos->enc = encoding;
|
pTos->enc = encoding;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1289,9 +1289,9 @@ divide_by_zero:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: CollSeq * * P3
|
/* Opcode: CollSeq * * P4
|
||||||
**
|
**
|
||||||
** P3 is a pointer to a CollSeq struct. If the next call to a user function
|
** P4 is a pointer to a CollSeq struct. If the next call to a user function
|
||||||
** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will
|
** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will
|
||||||
** be returned. This is used by the built-in min(), max() and nullif()
|
** be returned. This is used by the built-in min(), max() and nullif()
|
||||||
** functions.
|
** functions.
|
||||||
@@ -1301,13 +1301,13 @@ divide_by_zero:
|
|||||||
** publicly, only to user functions defined in func.c.
|
** publicly, only to user functions defined in func.c.
|
||||||
*/
|
*/
|
||||||
case OP_CollSeq: { /* no-push */
|
case OP_CollSeq: { /* no-push */
|
||||||
assert( pOp->p3type==P3_COLLSEQ );
|
assert( pOp->p4type==P4_COLLSEQ );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: Function P1 P2 P3
|
/* Opcode: Function P1 P2 P4
|
||||||
**
|
**
|
||||||
** Invoke a user function (P3 is a pointer to a Function structure that
|
** Invoke a user function (P4 is a pointer to a Function structure that
|
||||||
** defines the function) with P2 arguments taken from the stack. Pop all
|
** defines the function) with P2 arguments taken from the stack. Pop all
|
||||||
** arguments from the stack and push back the result.
|
** arguments from the stack and push back the result.
|
||||||
**
|
**
|
||||||
@@ -1336,12 +1336,12 @@ case OP_Function: {
|
|||||||
storeTypeInfo(pArg, encoding);
|
storeTypeInfo(pArg, encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert( pOp->p3type==P3_FUNCDEF || pOp->p3type==P3_VDBEFUNC );
|
assert( pOp->p4type==P4_FUNCDEF || pOp->p4type==P4_VDBEFUNC );
|
||||||
if( pOp->p3type==P3_FUNCDEF ){
|
if( pOp->p4type==P4_FUNCDEF ){
|
||||||
ctx.pFunc = (FuncDef*)pOp->p3.p;
|
ctx.pFunc = (FuncDef*)pOp->p4.p;
|
||||||
ctx.pVdbeFunc = 0;
|
ctx.pVdbeFunc = 0;
|
||||||
}else{
|
}else{
|
||||||
ctx.pVdbeFunc = (VdbeFunc*)pOp->p3.p;
|
ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.p;
|
||||||
ctx.pFunc = ctx.pVdbeFunc->pFunc;
|
ctx.pFunc = ctx.pVdbeFunc->pFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1352,9 +1352,9 @@ case OP_Function: {
|
|||||||
ctx.isError = 0;
|
ctx.isError = 0;
|
||||||
if( ctx.pFunc->needCollSeq ){
|
if( ctx.pFunc->needCollSeq ){
|
||||||
assert( pOp>p->aOp );
|
assert( pOp>p->aOp );
|
||||||
assert( pOp[-1].p3type==P3_COLLSEQ );
|
assert( pOp[-1].p4type==P4_COLLSEQ );
|
||||||
assert( pOp[-1].opcode==OP_CollSeq );
|
assert( pOp[-1].opcode==OP_CollSeq );
|
||||||
ctx.pColl = (CollSeq *)pOp[-1].p3.p;
|
ctx.pColl = (CollSeq *)pOp[-1].p4.p;
|
||||||
}
|
}
|
||||||
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
||||||
(*ctx.pFunc->xFunc)(&ctx, n, apVal);
|
(*ctx.pFunc->xFunc)(&ctx, n, apVal);
|
||||||
@@ -1379,8 +1379,8 @@ case OP_Function: {
|
|||||||
*/
|
*/
|
||||||
if( ctx.pVdbeFunc ){
|
if( ctx.pVdbeFunc ){
|
||||||
sqlite3VdbeDeleteAuxData(ctx.pVdbeFunc, pOp->p1);
|
sqlite3VdbeDeleteAuxData(ctx.pVdbeFunc, pOp->p1);
|
||||||
pOp->p3.p = (char *)ctx.pVdbeFunc;
|
pOp->p4.p = (char *)ctx.pVdbeFunc;
|
||||||
pOp->p3type = P3_VDBEFUNC;
|
pOp->p4type = P4_VDBEFUNC;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the function returned an error, throw an exception */
|
/* If the function returned an error, throw an exception */
|
||||||
@@ -1652,7 +1652,7 @@ case OP_ToReal: { /* same as TK_TO_REAL, no-push */
|
|||||||
}
|
}
|
||||||
#endif /* SQLITE_OMIT_CAST */
|
#endif /* SQLITE_OMIT_CAST */
|
||||||
|
|
||||||
/* Opcode: Eq P1 P2 P3
|
/* Opcode: Eq P1 P2 P4
|
||||||
**
|
**
|
||||||
** Pop the top two elements from the stack. If they are equal, then
|
** Pop the top two elements from the stack. If they are equal, then
|
||||||
** jump to instruction P2. Otherwise, continue to the next instruction.
|
** jump to instruction P2. Otherwise, continue to the next instruction.
|
||||||
@@ -1684,34 +1684,34 @@ case OP_ToReal: { /* same as TK_TO_REAL, no-push */
|
|||||||
** stack if the jump would have been taken, or a 0 if not. Push a
|
** stack if the jump would have been taken, or a 0 if not. Push a
|
||||||
** NULL if either operand was NULL.
|
** NULL if either operand was NULL.
|
||||||
**
|
**
|
||||||
** If P3 is not NULL it is a pointer to a collating sequence (a CollSeq
|
** If P4 is not NULL it is a pointer to a collating sequence (a CollSeq
|
||||||
** structure) that defines how to compare text.
|
** structure) that defines how to compare text.
|
||||||
*/
|
*/
|
||||||
/* Opcode: Ne P1 P2 P3
|
/* Opcode: Ne P1 P2 P4
|
||||||
**
|
**
|
||||||
** This works just like the Eq opcode except that the jump is taken if
|
** This works just like the Eq opcode except that the jump is taken if
|
||||||
** the operands from the stack are not equal. See the Eq opcode for
|
** the operands from the stack are not equal. See the Eq opcode for
|
||||||
** additional information.
|
** additional information.
|
||||||
*/
|
*/
|
||||||
/* Opcode: Lt P1 P2 P3
|
/* Opcode: Lt P1 P2 P4
|
||||||
**
|
**
|
||||||
** This works just like the Eq opcode except that the jump is taken if
|
** This works just like the Eq opcode except that the jump is taken if
|
||||||
** the 2nd element down on the stack is less than the top of the stack.
|
** the 2nd element down on the stack is less than the top of the stack.
|
||||||
** See the Eq opcode for additional information.
|
** See the Eq opcode for additional information.
|
||||||
*/
|
*/
|
||||||
/* Opcode: Le P1 P2 P3
|
/* Opcode: Le P1 P2 P4
|
||||||
**
|
**
|
||||||
** This works just like the Eq opcode except that the jump is taken if
|
** This works just like the Eq opcode except that the jump is taken if
|
||||||
** the 2nd element down on the stack is less than or equal to the
|
** the 2nd element down on the stack is less than or equal to the
|
||||||
** top of the stack. See the Eq opcode for additional information.
|
** top of the stack. See the Eq opcode for additional information.
|
||||||
*/
|
*/
|
||||||
/* Opcode: Gt P1 P2 P3
|
/* Opcode: Gt P1 P2 P4
|
||||||
**
|
**
|
||||||
** This works just like the Eq opcode except that the jump is taken if
|
** This works just like the Eq opcode except that the jump is taken if
|
||||||
** the 2nd element down on the stack is greater than the top of the stack.
|
** the 2nd element down on the stack is greater than the top of the stack.
|
||||||
** See the Eq opcode for additional information.
|
** See the Eq opcode for additional information.
|
||||||
*/
|
*/
|
||||||
/* Opcode: Ge P1 P2 P3
|
/* Opcode: Ge P1 P2 P4
|
||||||
**
|
**
|
||||||
** This works just like the Eq opcode except that the jump is taken if
|
** This works just like the Eq opcode except that the jump is taken if
|
||||||
** the 2nd element down on the stack is greater than or equal to the
|
** the 2nd element down on the stack is greater than or equal to the
|
||||||
@@ -1774,10 +1774,10 @@ case OP_Ge: { /* same as TK_GE, no-push */
|
|||||||
applyAffinity(pTos, affinity, encoding);
|
applyAffinity(pTos, affinity, encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert( pOp->p3type==P3_COLLSEQ || pOp->p3.p==0 );
|
assert( pOp->p4type==P4_COLLSEQ || pOp->p4.p==0 );
|
||||||
ExpandBlob(pNos);
|
ExpandBlob(pNos);
|
||||||
ExpandBlob(pTos);
|
ExpandBlob(pTos);
|
||||||
res = sqlite3MemCompare(pNos, pTos, (CollSeq*)pOp->p3.p);
|
res = sqlite3MemCompare(pNos, pTos, (CollSeq*)pOp->p4.p);
|
||||||
switch( pOp->opcode ){
|
switch( pOp->opcode ){
|
||||||
case OP_Eq: res = res==0; break;
|
case OP_Eq: res = res==0; break;
|
||||||
case OP_Ne: res = res!=0; break;
|
case OP_Ne: res = res!=0; break;
|
||||||
@@ -2028,7 +2028,7 @@ case OP_SetNumColumns: { /* no-push */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: Column P1 P2 P3
|
/* Opcode: Column P1 P2 P3 *
|
||||||
**
|
**
|
||||||
** Interpret the data that cursor P1 points to as a structure built using
|
** Interpret the data that cursor P1 points to as a structure built using
|
||||||
** the MakeRecord instruction. (See the MakeRecord opcode for additional
|
** the MakeRecord instruction. (See the MakeRecord opcode for additional
|
||||||
@@ -2036,17 +2036,17 @@ case OP_SetNumColumns: { /* no-push */
|
|||||||
** from this record. If there are less that (P2+1)
|
** from this record. If there are less that (P2+1)
|
||||||
** values in the record, extract a NULL.
|
** values in the record, extract a NULL.
|
||||||
**
|
**
|
||||||
** The value extracted is pushed onto the stack. Or if P3 is an integer
|
** The value extracted is pushed onto the stack. Or if P3 is a positive
|
||||||
** register number, then the value is written into that register.
|
** integer register number, then the value is written into that register.
|
||||||
**
|
**
|
||||||
** If the KeyAsData opcode has previously executed on this cursor, then the
|
** If the KeyAsData opcode has previously executed on this cursor, then the
|
||||||
** field might be extracted from the key rather than the data.
|
** field might be extracted from the key rather than the data.
|
||||||
**
|
**
|
||||||
** If the column contains fewer than P2 fields, then extract a NULL. Or
|
** If the column contains fewer than P2 fields, then extract a NULL. Or
|
||||||
** if the next instruction is OP_DfltValue then the P3 argument to the
|
** if the next instruction is OP_DfltValue then the P4 argument to the
|
||||||
** OP_DfltValue instruction will be a P3_MEM. Use the P3 argument of
|
** OP_DfltValue instruction will be a P4_MEM. Use the P4 argument of
|
||||||
** the OP_DfltValue instruction as the extracted value instead of NULL.
|
** the OP_DfltValue instruction as the extracted value instead of NULL.
|
||||||
** The OP_DfltValue P3 value will be a default value for a column
|
** The OP_DfltValue P4 value will be a default value for a column
|
||||||
** that has been added using the ALTER TABLE ADD COLUMN command.
|
** that has been added using the ALTER TABLE ADD COLUMN command.
|
||||||
*/
|
*/
|
||||||
case OP_Column: {
|
case OP_Column: {
|
||||||
@@ -2067,9 +2067,8 @@ case OP_Column: {
|
|||||||
|
|
||||||
sMem.flags = 0;
|
sMem.flags = 0;
|
||||||
assert( p1<p->nCursor );
|
assert( p1<p->nCursor );
|
||||||
if( pOp->p3type==P3_INT32 ){
|
if( pOp->p3>0 ){
|
||||||
assert( pOp->p3.i>=0 && pOp->p3.i<p->nMem );
|
pDest = &p->aMem[pOp->p3];
|
||||||
pDest = &p->aMem[pOp->p3.i];
|
|
||||||
}else{
|
}else{
|
||||||
pDest = ++pTos;
|
pDest = ++pTos;
|
||||||
}
|
}
|
||||||
@@ -2241,7 +2240,7 @@ case OP_Column: {
|
|||||||
/* Get the column information. If aOffset[p2] is non-zero, then
|
/* Get the column information. If aOffset[p2] is non-zero, then
|
||||||
** deserialize the value from the record. If aOffset[p2] is zero,
|
** deserialize the value from the record. If aOffset[p2] is zero,
|
||||||
** then there are not enough fields in the record to satisfy the
|
** then there are not enough fields in the record to satisfy the
|
||||||
** request. In this case, set the value NULL or to P3 if P3 is
|
** request. In this case, set the value NULL or to P4 if P4 is
|
||||||
** a pointer to a Mem object.
|
** a pointer to a Mem object.
|
||||||
*/
|
*/
|
||||||
if( aOffset[p2] ){
|
if( aOffset[p2] ){
|
||||||
@@ -2260,8 +2259,8 @@ case OP_Column: {
|
|||||||
pDest->enc = encoding;
|
pDest->enc = encoding;
|
||||||
}else{
|
}else{
|
||||||
if( pOp[1].opcode==OP_DfltValue ){
|
if( pOp[1].opcode==OP_DfltValue ){
|
||||||
assert( pOp[1].p3type==P3_MEM );
|
assert( pOp[1].p4type==P4_MEM );
|
||||||
sqlite3VdbeMemShallowCopy(pDest, (Mem *)(pOp[1].p3.p), MEM_Static);
|
sqlite3VdbeMemShallowCopy(pDest, (Mem *)(pOp[1].p4.p), MEM_Static);
|
||||||
}else{
|
}else{
|
||||||
assert( pDest->flags==MEM_Null );
|
assert( pDest->flags==MEM_Null );
|
||||||
}
|
}
|
||||||
@@ -2292,7 +2291,7 @@ op_column_out:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: DfltValue * * P3
|
/* Opcode: DfltValue * * P4
|
||||||
**
|
**
|
||||||
** This instruction always follows an OP_Column. This instruction
|
** This instruction always follows an OP_Column. This instruction
|
||||||
** does nothing by itself. It is just a place holder for the default
|
** does nothing by itself. It is just a place holder for the default
|
||||||
@@ -2302,7 +2301,7 @@ case OP_DfltValue: { /* no-push */
|
|||||||
assert( 0 );
|
assert( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: MakeRecord P1 P2 P3
|
/* Opcode: MakeRecord P1 P2 P4
|
||||||
**
|
**
|
||||||
** Convert the top abs(P1) entries of the stack into a single entry
|
** Convert the top abs(P1) entries of the stack into a single entry
|
||||||
** suitable for use as a data record in a database table or as a key
|
** suitable for use as a data record in a database table or as a key
|
||||||
@@ -2319,19 +2318,19 @@ case OP_DfltValue: { /* no-push */
|
|||||||
** to the address given by P2. This feature can be used to skip a
|
** to the address given by P2. This feature can be used to skip a
|
||||||
** uniqueness test on indices.
|
** uniqueness test on indices.
|
||||||
**
|
**
|
||||||
** P3 may be a string that is P1 characters long. The nth character of the
|
** P4 may be a string that is P1 characters long. The nth character of the
|
||||||
** string indicates the column affinity that should be used for the nth
|
** string indicates the column affinity that should be used for the nth
|
||||||
** field of the index key (i.e. the first character of P3 corresponds to the
|
** field of the index key (i.e. the first character of P4 corresponds to the
|
||||||
** lowest element on the stack).
|
** lowest element on the stack).
|
||||||
**
|
**
|
||||||
** The mapping from character to affinity is given by the SQLITE_AFF_
|
** The mapping from character to affinity is given by the SQLITE_AFF_
|
||||||
** macros defined in sqliteInt.h.
|
** macros defined in sqliteInt.h.
|
||||||
**
|
**
|
||||||
** If P3 is NULL then all index fields have the affinity NONE.
|
** If P4 is NULL then all index fields have the affinity NONE.
|
||||||
**
|
**
|
||||||
** See also OP_MakeIdxRec
|
** See also OP_MakeIdxRec
|
||||||
*/
|
*/
|
||||||
/* Opcode: MakeIdxRec P1 P2 P3
|
/* Opcode: MakeIdxRec P1 P2 P4
|
||||||
**
|
**
|
||||||
** This opcode works just OP_MakeRecord except that it reads an extra
|
** This opcode works just OP_MakeRecord except that it reads an extra
|
||||||
** integer from the stack (thus reading a total of abs(P1+1) entries)
|
** integer from the stack (thus reading a total of abs(P1+1) entries)
|
||||||
@@ -2339,7 +2338,7 @@ case OP_DfltValue: { /* no-push */
|
|||||||
** This results in an index key.
|
** This results in an index key.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
** Opcode: RegMakeRec P1 P2 P3
|
** Opcode: RegMakeRec P1 P2 P4
|
||||||
**
|
**
|
||||||
** Works like OP_MakeRecord except data is taken from registers
|
** Works like OP_MakeRecord except data is taken from registers
|
||||||
** rather than from the stack. The P1 register is an integer which
|
** rather than from the stack. The P1 register is an integer which
|
||||||
@@ -2347,7 +2346,7 @@ case OP_DfltValue: { /* no-push */
|
|||||||
** Data is taken from P1+1, P1+2, ..., P1+mem[P1].
|
** Data is taken from P1+1, P1+2, ..., P1+mem[P1].
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
** Opcode: RegMakeIRec P1 P2 P3
|
** Opcode: RegMakeIRec P1 P2 P4
|
||||||
**
|
**
|
||||||
** Works like OP_MakeIdxRec except data is taken from registers
|
** Works like OP_MakeIdxRec except data is taken from registers
|
||||||
** rather than from the stack. The P1 register is an integer which
|
** rather than from the stack. The P1 register is an integer which
|
||||||
@@ -2404,7 +2403,7 @@ case OP_MakeRecord: {
|
|||||||
}
|
}
|
||||||
jumpIfNull = pOp->p2;
|
jumpIfNull = pOp->p2;
|
||||||
addRowid = pOp->opcode==OP_MakeIdxRec || pOp->opcode==OP_RegMakeIRec;
|
addRowid = pOp->opcode==OP_MakeIdxRec || pOp->opcode==OP_RegMakeIRec;
|
||||||
zAffinity = pOp->p3.p;
|
zAffinity = pOp->p4.p;
|
||||||
|
|
||||||
if( pOp->opcode==OP_RegMakeRec || pOp->opcode==OP_RegMakeIRec ){
|
if( pOp->opcode==OP_RegMakeRec || pOp->opcode==OP_RegMakeIRec ){
|
||||||
Mem *pCount;
|
Mem *pCount;
|
||||||
@@ -2796,7 +2795,7 @@ case OP_VerifyCookie: { /* no-push */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: OpenRead P1 P2 P3
|
/* Opcode: OpenRead P1 P2 P4
|
||||||
**
|
**
|
||||||
** Open a read-only cursor for the database table whose root page is
|
** Open a read-only cursor for the database table whose root page is
|
||||||
** P2 in a database file. The database file is determined by an
|
** P2 in a database file. The database file is determined by an
|
||||||
@@ -2817,19 +2816,19 @@ case OP_VerifyCookie: { /* no-push */
|
|||||||
** to get a read lock but fails, the script terminates with an
|
** to get a read lock but fails, the script terminates with an
|
||||||
** SQLITE_BUSY error code.
|
** SQLITE_BUSY error code.
|
||||||
**
|
**
|
||||||
** The P3 value is a pointer to a KeyInfo structure that defines the
|
** The P4 value is a pointer to a KeyInfo structure that defines the
|
||||||
** content and collating sequence of indices. P3 is NULL for cursors
|
** content and collating sequence of indices. P4 is NULL for cursors
|
||||||
** that are not pointing to indices.
|
** that are not pointing to indices.
|
||||||
**
|
**
|
||||||
** See also OpenWrite.
|
** See also OpenWrite.
|
||||||
*/
|
*/
|
||||||
/* Opcode: OpenWrite P1 P2 P3
|
/* Opcode: OpenWrite P1 P2 P4
|
||||||
**
|
**
|
||||||
** Open a read/write cursor named P1 on the table or index whose root
|
** Open a read/write cursor named P1 on the table or index whose root
|
||||||
** page is P2. If P2==0 then take the root page number from the stack.
|
** page is P2. If P2==0 then take the root page number from the stack.
|
||||||
**
|
**
|
||||||
** The P3 value is a pointer to a KeyInfo structure that defines the
|
** The P4 value is a pointer to a KeyInfo structure that defines the
|
||||||
** content and collating sequence of indices. P3 is NULL for cursors
|
** content and collating sequence of indices. P4 is NULL for cursors
|
||||||
** that are not pointing to indices.
|
** that are not pointing to indices.
|
||||||
**
|
**
|
||||||
** This instruction works just like OpenRead except that it opens the cursor
|
** This instruction works just like OpenRead except that it opens the cursor
|
||||||
@@ -2882,10 +2881,10 @@ case OP_OpenWrite: { /* no-push */
|
|||||||
/* We always provide a key comparison function. If the table being
|
/* We always provide a key comparison function. If the table being
|
||||||
** opened is of type INTKEY, the comparision function will be ignored. */
|
** opened is of type INTKEY, the comparision function will be ignored. */
|
||||||
rc = sqlite3BtreeCursor(pX, p2, wrFlag,
|
rc = sqlite3BtreeCursor(pX, p2, wrFlag,
|
||||||
sqlite3VdbeRecordCompare, pOp->p3.p,
|
sqlite3VdbeRecordCompare, pOp->p4.p,
|
||||||
&pCur->pCursor);
|
&pCur->pCursor);
|
||||||
if( pOp->p3type==P3_KEYINFO ){
|
if( pOp->p4type==P4_KEYINFO ){
|
||||||
pCur->pKeyInfo = (KeyInfo*)pOp->p3.p;
|
pCur->pKeyInfo = (KeyInfo*)pOp->p4.p;
|
||||||
pCur->pIncrKey = &pCur->pKeyInfo->incrKey;
|
pCur->pIncrKey = &pCur->pKeyInfo->incrKey;
|
||||||
pCur->pKeyInfo->enc = ENC(p->db);
|
pCur->pKeyInfo->enc = ENC(p->db);
|
||||||
}else{
|
}else{
|
||||||
@@ -2913,19 +2912,19 @@ case OP_OpenWrite: { /* no-push */
|
|||||||
}
|
}
|
||||||
pCur->isTable = (flags & BTREE_INTKEY)!=0;
|
pCur->isTable = (flags & BTREE_INTKEY)!=0;
|
||||||
pCur->isIndex = (flags & BTREE_ZERODATA)!=0;
|
pCur->isIndex = (flags & BTREE_ZERODATA)!=0;
|
||||||
/* If P3==0 it means we are expected to open a table. If P3!=0 then
|
/* If P4==0 it means we are expected to open a table. If P4!=0 then
|
||||||
** we expect to be opening an index. If this is not what happened,
|
** we expect to be opening an index. If this is not what happened,
|
||||||
** then the database is corrupt
|
** then the database is corrupt
|
||||||
*/
|
*/
|
||||||
if( (pCur->isTable && pOp->p3type==P3_KEYINFO)
|
if( (pCur->isTable && pOp->p4type==P4_KEYINFO)
|
||||||
|| (pCur->isIndex && pOp->p3type!=P3_KEYINFO) ){
|
|| (pCur->isIndex && pOp->p4type!=P4_KEYINFO) ){
|
||||||
rc = SQLITE_CORRUPT_BKPT;
|
rc = SQLITE_CORRUPT_BKPT;
|
||||||
goto abort_due_to_error;
|
goto abort_due_to_error;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLITE_EMPTY: {
|
case SQLITE_EMPTY: {
|
||||||
pCur->isTable = pOp->p3type!=P3_KEYINFO;
|
pCur->isTable = pOp->p4type!=P4_KEYINFO;
|
||||||
pCur->isIndex = !pCur->isTable;
|
pCur->isIndex = !pCur->isTable;
|
||||||
rc = SQLITE_OK;
|
rc = SQLITE_OK;
|
||||||
break;
|
break;
|
||||||
@@ -2937,7 +2936,7 @@ case OP_OpenWrite: { /* no-push */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: OpenEphemeral P1 P2 P3
|
/* Opcode: OpenEphemeral P1 P2 P4
|
||||||
**
|
**
|
||||||
** Open a new cursor P1 to a transient table.
|
** Open a new cursor P1 to a transient table.
|
||||||
** The cursor is always opened read/write even if
|
** The cursor is always opened read/write even if
|
||||||
@@ -2945,8 +2944,8 @@ case OP_OpenWrite: { /* no-push */
|
|||||||
** table is deleted automatically when the cursor is closed.
|
** table is deleted automatically when the cursor is closed.
|
||||||
**
|
**
|
||||||
** P2 is the number of columns in the virtual table.
|
** P2 is the number of columns in the virtual table.
|
||||||
** The cursor points to a BTree table if P3==0 and to a BTree index
|
** The cursor points to a BTree table if P4==0 and to a BTree index
|
||||||
** if P3 is not 0. If P3 is not NULL, it points to a KeyInfo structure
|
** if P4 is not 0. If P4 is not NULL, it points to a KeyInfo structure
|
||||||
** that defines the format of keys in the index.
|
** that defines the format of keys in the index.
|
||||||
**
|
**
|
||||||
** This opcode was once called OpenTemp. But that created
|
** This opcode was once called OpenTemp. But that created
|
||||||
@@ -2980,15 +2979,15 @@ case OP_OpenEphemeral: { /* no-push */
|
|||||||
** opening it. If a transient table is required, just use the
|
** opening it. If a transient table is required, just use the
|
||||||
** automatically created table with root-page 1 (an INTKEY table).
|
** automatically created table with root-page 1 (an INTKEY table).
|
||||||
*/
|
*/
|
||||||
if( pOp->p3.p ){
|
if( pOp->p4.p ){
|
||||||
int pgno;
|
int pgno;
|
||||||
assert( pOp->p3type==P3_KEYINFO );
|
assert( pOp->p4type==P4_KEYINFO );
|
||||||
rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_ZERODATA);
|
rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_ZERODATA);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
assert( pgno==MASTER_ROOT+1 );
|
assert( pgno==MASTER_ROOT+1 );
|
||||||
rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, sqlite3VdbeRecordCompare,
|
rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, sqlite3VdbeRecordCompare,
|
||||||
pOp->p3.p, &pCx->pCursor);
|
pOp->p4.p, &pCx->pCursor);
|
||||||
pCx->pKeyInfo = (KeyInfo*)pOp->p3.p;
|
pCx->pKeyInfo = (KeyInfo*)pOp->p4.p;
|
||||||
pCx->pKeyInfo->enc = ENC(p->db);
|
pCx->pKeyInfo->enc = ENC(p->db);
|
||||||
pCx->pIncrKey = &pCx->pKeyInfo->incrKey;
|
pCx->pIncrKey = &pCx->pKeyInfo->incrKey;
|
||||||
}
|
}
|
||||||
@@ -3580,7 +3579,7 @@ case OP_NewRowid: {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: Insert P1 P2 P3
|
/* Opcode: Insert P1 P2 P4
|
||||||
**
|
**
|
||||||
** Write an entry into the table of cursor P1. A new entry is
|
** Write an entry into the table of cursor P1. A new entry is
|
||||||
** created if it doesn't already exist or the data for an existing
|
** created if it doesn't already exist or the data for an existing
|
||||||
@@ -3593,7 +3592,7 @@ case OP_NewRowid: {
|
|||||||
** then rowid is stored for subsequent return by the
|
** then rowid is stored for subsequent return by the
|
||||||
** sqlite3_last_insert_rowid() function (otherwise it is unmodified).
|
** sqlite3_last_insert_rowid() function (otherwise it is unmodified).
|
||||||
**
|
**
|
||||||
** Parameter P3 may point to a string containing the table-name, or
|
** Parameter P4 may point to a string containing the table-name, or
|
||||||
** may be NULL. If it is not NULL, then the update-hook
|
** may be NULL. If it is not NULL, then the update-hook
|
||||||
** (sqlite3.xUpdateCallback) is invoked following a successful insert.
|
** (sqlite3.xUpdateCallback) is invoked following a successful insert.
|
||||||
**
|
**
|
||||||
@@ -3657,9 +3656,9 @@ case OP_Insert: { /* no-push */
|
|||||||
pC->cacheStatus = CACHE_STALE;
|
pC->cacheStatus = CACHE_STALE;
|
||||||
|
|
||||||
/* Invoke the update-hook if required. */
|
/* Invoke the update-hook if required. */
|
||||||
if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p3.p ){
|
if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.p ){
|
||||||
const char *zDb = db->aDb[pC->iDb].zName;
|
const char *zDb = db->aDb[pC->iDb].zName;
|
||||||
const char *zTbl = pOp->p3.p;
|
const char *zTbl = pOp->p4.p;
|
||||||
int op = ((pOp->p2 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
|
int op = ((pOp->p2 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
|
||||||
assert( pC->isTable );
|
assert( pC->isTable );
|
||||||
db->xUpdateCallback(db->pUpdateArg, op, zDb, zTbl, iKey);
|
db->xUpdateCallback(db->pUpdateArg, op, zDb, zTbl, iKey);
|
||||||
@@ -3671,7 +3670,7 @@ case OP_Insert: { /* no-push */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: Delete P1 P2 P3
|
/* Opcode: Delete P1 P2 P4
|
||||||
**
|
**
|
||||||
** Delete the record at which the P1 cursor is currently pointing.
|
** Delete the record at which the P1 cursor is currently pointing.
|
||||||
**
|
**
|
||||||
@@ -3697,7 +3696,7 @@ case OP_Delete: { /* no-push */
|
|||||||
/* If the update-hook will be invoked, set iKey to the rowid of the
|
/* If the update-hook will be invoked, set iKey to the rowid of the
|
||||||
** row being deleted.
|
** row being deleted.
|
||||||
*/
|
*/
|
||||||
if( db->xUpdateCallback && pOp->p3.p ){
|
if( db->xUpdateCallback && pOp->p4.p ){
|
||||||
assert( pC->isTable );
|
assert( pC->isTable );
|
||||||
if( pC->rowidIsValid ){
|
if( pC->rowidIsValid ){
|
||||||
iKey = pC->lastRowid;
|
iKey = pC->lastRowid;
|
||||||
@@ -3717,9 +3716,9 @@ case OP_Delete: { /* no-push */
|
|||||||
pC->cacheStatus = CACHE_STALE;
|
pC->cacheStatus = CACHE_STALE;
|
||||||
|
|
||||||
/* Invoke the update-hook if required. */
|
/* Invoke the update-hook if required. */
|
||||||
if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p3.p ){
|
if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.p ){
|
||||||
const char *zDb = db->aDb[pC->iDb].zName;
|
const char *zDb = db->aDb[pC->iDb].zName;
|
||||||
const char *zTbl = pOp->p3.p;
|
const char *zTbl = pOp->p4.p;
|
||||||
db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, iKey);
|
db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, iKey);
|
||||||
assert( pC->iDb>=0 );
|
assert( pC->iDb>=0 );
|
||||||
}
|
}
|
||||||
@@ -4122,7 +4121,7 @@ case OP_IdxRowid: {
|
|||||||
** then jump to P2. Otherwise fall through to the next instruction.
|
** then jump to P2. Otherwise fall through to the next instruction.
|
||||||
** In either case, the stack is popped once.
|
** In either case, the stack is popped once.
|
||||||
*/
|
*/
|
||||||
/* Opcode: IdxGE P1 P2 P3
|
/* Opcode: IdxGE P1 P2 P4
|
||||||
**
|
**
|
||||||
** The top of the stack is an index entry that omits the ROWID. Compare
|
** The top of the stack is an index entry that omits the ROWID. Compare
|
||||||
** the top of stack against the index that P1 is currently pointing to.
|
** the top of stack against the index that P1 is currently pointing to.
|
||||||
@@ -4132,14 +4131,14 @@ case OP_IdxRowid: {
|
|||||||
** then jump to P2. Otherwise fall through to the next instruction.
|
** then jump to P2. Otherwise fall through to the next instruction.
|
||||||
** In either case, the stack is popped once.
|
** In either case, the stack is popped once.
|
||||||
**
|
**
|
||||||
** If P3 is the "+" string (or any other non-NULL string) then the
|
** If P4 is the "+" string (or any other non-NULL string) then the
|
||||||
** index taken from the top of the stack is temporarily increased by
|
** index taken from the top of the stack is temporarily increased by
|
||||||
** an epsilon prior to the comparison. This make the opcode work
|
** an epsilon prior to the comparison. This make the opcode work
|
||||||
** like IdxGT except that if the key from the stack is a prefix of
|
** like IdxGT except that if the key from the stack is a prefix of
|
||||||
** the key in the cursor, the result is false whereas it would be
|
** the key in the cursor, the result is false whereas it would be
|
||||||
** true with IdxGT.
|
** true with IdxGT.
|
||||||
*/
|
*/
|
||||||
/* Opcode: IdxLT P1 P2 P3
|
/* Opcode: IdxLT P1 P2 P4
|
||||||
**
|
**
|
||||||
** The top of the stack is an index entry that omits the ROWID. Compare
|
** The top of the stack is an index entry that omits the ROWID. Compare
|
||||||
** the top of stack against the index that P1 is currently pointing to.
|
** the top of stack against the index that P1 is currently pointing to.
|
||||||
@@ -4149,7 +4148,7 @@ case OP_IdxRowid: {
|
|||||||
** then jump to P2. Otherwise fall through to the next instruction.
|
** then jump to P2. Otherwise fall through to the next instruction.
|
||||||
** In either case, the stack is popped once.
|
** In either case, the stack is popped once.
|
||||||
**
|
**
|
||||||
** If P3 is the "+" string (or any other non-NULL string) then the
|
** If P4 is the "+" string (or any other non-NULL string) then the
|
||||||
** index taken from the top of the stack is temporarily increased by
|
** index taken from the top of the stack is temporarily increased by
|
||||||
** an epsilon prior to the comparison. This makes the opcode work
|
** an epsilon prior to the comparison. This makes the opcode work
|
||||||
** like IdxLE.
|
** like IdxLE.
|
||||||
@@ -4169,8 +4168,8 @@ case OP_IdxGE: { /* no-push */
|
|||||||
assert( pTos->flags & MEM_Blob ); /* Created using OP_MakeRecord */
|
assert( pTos->flags & MEM_Blob ); /* Created using OP_MakeRecord */
|
||||||
assert( pC->deferredMoveto==0 );
|
assert( pC->deferredMoveto==0 );
|
||||||
ExpandBlob(pTos);
|
ExpandBlob(pTos);
|
||||||
*pC->pIncrKey = pOp->p3.p!=0;
|
*pC->pIncrKey = pOp->p4.p!=0;
|
||||||
assert( pOp->p3.p==0 || pOp->opcode!=OP_IdxGT );
|
assert( pOp->p4.p==0 || pOp->opcode!=OP_IdxGT );
|
||||||
rc = sqlite3VdbeIdxKeyCompare(pC, pTos->n, (u8*)pTos->z, &res);
|
rc = sqlite3VdbeIdxKeyCompare(pC, pTos->n, (u8*)pTos->z, &res);
|
||||||
*pC->pIncrKey = 0;
|
*pC->pIncrKey = 0;
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
@@ -4262,9 +4261,9 @@ case OP_Clear: { /* no-push */
|
|||||||
*/
|
*/
|
||||||
#if 0
|
#if 0
|
||||||
Btree *pBt = db->aDb[pOp->p2].pBt;
|
Btree *pBt = db->aDb[pOp->p2].pBt;
|
||||||
if( db->xUpdateCallback && pOp->p3.p ){
|
if( db->xUpdateCallback && pOp->p4.p ){
|
||||||
const char *zDb = db->aDb[pOp->p2].zName;
|
const char *zDb = db->aDb[pOp->p2].zName;
|
||||||
const char *zTbl = pOp->p3.p;
|
const char *zTbl = pOp->p4.p;
|
||||||
BtCursor *pCur = 0;
|
BtCursor *pCur = 0;
|
||||||
int fin = 0;
|
int fin = 0;
|
||||||
|
|
||||||
@@ -4342,10 +4341,10 @@ case OP_CreateTable: {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: ParseSchema P1 P2 P3
|
/* Opcode: ParseSchema P1 P2 P4
|
||||||
**
|
**
|
||||||
** Read and parse all entries from the SQLITE_MASTER table of database P1
|
** Read and parse all entries from the SQLITE_MASTER table of database P1
|
||||||
** that match the WHERE clause P3. P2 is the "force" flag. Always do
|
** that match the WHERE clause P4. P2 is the "force" flag. Always do
|
||||||
** the parsing if P2 is true. If P2 is false, then this routine is a
|
** the parsing if P2 is true. If P2 is false, then this routine is a
|
||||||
** no-op if the schema is not currently loaded. In other words, if P2
|
** no-op if the schema is not currently loaded. In other words, if P2
|
||||||
** is false, the SQLITE_MASTER table is only parsed if the rest of the
|
** is false, the SQLITE_MASTER table is only parsed if the rest of the
|
||||||
@@ -4370,7 +4369,7 @@ case OP_ParseSchema: { /* no-push */
|
|||||||
initData.pzErrMsg = &p->zErrMsg;
|
initData.pzErrMsg = &p->zErrMsg;
|
||||||
zSql = sqlite3MPrintf(db,
|
zSql = sqlite3MPrintf(db,
|
||||||
"SELECT name, rootpage, sql FROM '%q'.%s WHERE %s",
|
"SELECT name, rootpage, sql FROM '%q'.%s WHERE %s",
|
||||||
db->aDb[iDb].zName, zMaster, pOp->p3.p);
|
db->aDb[iDb].zName, zMaster, pOp->p4.p);
|
||||||
if( zSql==0 ) goto no_mem;
|
if( zSql==0 ) goto no_mem;
|
||||||
sqlite3SafetyOff(db);
|
sqlite3SafetyOff(db);
|
||||||
assert( db->init.busy==0 );
|
assert( db->init.busy==0 );
|
||||||
@@ -4402,39 +4401,39 @@ case OP_LoadAnalysis: { /* no-push */
|
|||||||
}
|
}
|
||||||
#endif /* !defined(SQLITE_OMIT_ANALYZE) && !defined(SQLITE_OMIT_PARSER) */
|
#endif /* !defined(SQLITE_OMIT_ANALYZE) && !defined(SQLITE_OMIT_PARSER) */
|
||||||
|
|
||||||
/* Opcode: DropTable P1 * P3
|
/* Opcode: DropTable P1 * P4
|
||||||
**
|
**
|
||||||
** Remove the internal (in-memory) data structures that describe
|
** Remove the internal (in-memory) data structures that describe
|
||||||
** the table named P3 in database P1. This is called after a table
|
** the table named P4 in database P1. This is called after a table
|
||||||
** is dropped in order to keep the internal representation of the
|
** is dropped in order to keep the internal representation of the
|
||||||
** schema consistent with what is on disk.
|
** schema consistent with what is on disk.
|
||||||
*/
|
*/
|
||||||
case OP_DropTable: { /* no-push */
|
case OP_DropTable: { /* no-push */
|
||||||
sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p3.p);
|
sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p4.p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: DropIndex P1 * P3
|
/* Opcode: DropIndex P1 * P4
|
||||||
**
|
**
|
||||||
** Remove the internal (in-memory) data structures that describe
|
** Remove the internal (in-memory) data structures that describe
|
||||||
** the index named P3 in database P1. This is called after an index
|
** the index named P4 in database P1. This is called after an index
|
||||||
** is dropped in order to keep the internal representation of the
|
** is dropped in order to keep the internal representation of the
|
||||||
** schema consistent with what is on disk.
|
** schema consistent with what is on disk.
|
||||||
*/
|
*/
|
||||||
case OP_DropIndex: { /* no-push */
|
case OP_DropIndex: { /* no-push */
|
||||||
sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p3.p);
|
sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p4.p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: DropTrigger P1 * P3
|
/* Opcode: DropTrigger P1 * P4
|
||||||
**
|
**
|
||||||
** Remove the internal (in-memory) data structures that describe
|
** Remove the internal (in-memory) data structures that describe
|
||||||
** the trigger named P3 in database P1. This is called after a trigger
|
** the trigger named P4 in database P1. This is called after a trigger
|
||||||
** is dropped in order to keep the internal representation of the
|
** is dropped in order to keep the internal representation of the
|
||||||
** schema consistent with what is on disk.
|
** schema consistent with what is on disk.
|
||||||
*/
|
*/
|
||||||
case OP_DropTrigger: { /* no-push */
|
case OP_DropTrigger: { /* no-push */
|
||||||
sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p3.p);
|
sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p4.p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4768,10 +4767,10 @@ case OP_MemMove: {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: AggStep P1 P2 P3
|
/* Opcode: AggStep P1 P2 P4
|
||||||
**
|
**
|
||||||
** Execute the step function for an aggregate. The
|
** Execute the step function for an aggregate. The
|
||||||
** function has P2 arguments. P3 is a pointer to the FuncDef
|
** function has P2 arguments. P4 is a pointer to the FuncDef
|
||||||
** structure that specifies the function. Use memory location
|
** structure that specifies the function. Use memory location
|
||||||
** P1 as the accumulator.
|
** P1 as the accumulator.
|
||||||
**
|
**
|
||||||
@@ -4793,7 +4792,7 @@ case OP_AggStep: { /* no-push */
|
|||||||
apVal[i] = pRec;
|
apVal[i] = pRec;
|
||||||
storeTypeInfo(pRec, encoding);
|
storeTypeInfo(pRec, encoding);
|
||||||
}
|
}
|
||||||
ctx.pFunc = (FuncDef*)pOp->p3.p;
|
ctx.pFunc = (FuncDef*)pOp->p4.p;
|
||||||
assert( pOp->p1>=0 && pOp->p1<p->nMem );
|
assert( pOp->p1>=0 && pOp->p1<p->nMem );
|
||||||
ctx.pMem = pMem = &p->aMem[pOp->p1];
|
ctx.pMem = pMem = &p->aMem[pOp->p1];
|
||||||
pMem->n++;
|
pMem->n++;
|
||||||
@@ -4805,9 +4804,9 @@ case OP_AggStep: { /* no-push */
|
|||||||
ctx.pColl = 0;
|
ctx.pColl = 0;
|
||||||
if( ctx.pFunc->needCollSeq ){
|
if( ctx.pFunc->needCollSeq ){
|
||||||
assert( pOp>p->aOp );
|
assert( pOp>p->aOp );
|
||||||
assert( pOp[-1].p3type==P3_COLLSEQ );
|
assert( pOp[-1].p4type==P4_COLLSEQ );
|
||||||
assert( pOp[-1].opcode==OP_CollSeq );
|
assert( pOp[-1].opcode==OP_CollSeq );
|
||||||
ctx.pColl = (CollSeq *)pOp[-1].p3.p;
|
ctx.pColl = (CollSeq *)pOp[-1].p4.p;
|
||||||
}
|
}
|
||||||
(ctx.pFunc->xStep)(&ctx, n, apVal);
|
(ctx.pFunc->xStep)(&ctx, n, apVal);
|
||||||
popStack(&pTos, n);
|
popStack(&pTos, n);
|
||||||
@@ -4819,16 +4818,16 @@ case OP_AggStep: { /* no-push */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: AggFinal P1 P2 P3
|
/* Opcode: AggFinal P1 P2 P4
|
||||||
**
|
**
|
||||||
** Execute the finalizer function for an aggregate. P1 is
|
** Execute the finalizer function for an aggregate. P1 is
|
||||||
** the memory location that is the accumulator for the aggregate.
|
** the memory location that is the accumulator for the aggregate.
|
||||||
**
|
**
|
||||||
** P2 is the number of arguments that the step function takes and
|
** P2 is the number of arguments that the step function takes and
|
||||||
** P3 is a pointer to the FuncDef for this function. The P2
|
** P4 is a pointer to the FuncDef for this function. The P2
|
||||||
** argument is not used by this opcode. It is only there to disambiguate
|
** argument is not used by this opcode. It is only there to disambiguate
|
||||||
** functions that can take varying numbers of arguments. The
|
** functions that can take varying numbers of arguments. The
|
||||||
** P3 argument is only needed for the degenerate case where
|
** P4 argument is only needed for the degenerate case where
|
||||||
** the step function was not previously called.
|
** the step function was not previously called.
|
||||||
*/
|
*/
|
||||||
case OP_AggFinal: { /* no-push */
|
case OP_AggFinal: { /* no-push */
|
||||||
@@ -4836,7 +4835,7 @@ case OP_AggFinal: { /* no-push */
|
|||||||
assert( pOp->p1>=0 && pOp->p1<p->nMem );
|
assert( pOp->p1>=0 && pOp->p1<p->nMem );
|
||||||
pMem = &p->aMem[pOp->p1];
|
pMem = &p->aMem[pOp->p1];
|
||||||
assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
|
assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
|
||||||
rc = sqlite3VdbeMemFinalize(pMem, (FuncDef*)pOp->p3.p);
|
rc = sqlite3VdbeMemFinalize(pMem, (FuncDef*)pOp->p4.p);
|
||||||
if( rc==SQLITE_ERROR ){
|
if( rc==SQLITE_ERROR ){
|
||||||
sqlite3SetString(&p->zErrMsg, sqlite3_value_text(pMem), (char*)0);
|
sqlite3SetString(&p->zErrMsg, sqlite3_value_text(pMem), (char*)0);
|
||||||
}
|
}
|
||||||
@@ -4903,7 +4902,7 @@ case OP_Expire: { /* no-push */
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||||
/* Opcode: TableLock P1 P2 P3
|
/* Opcode: TableLock P1 P2 P4
|
||||||
**
|
**
|
||||||
** Obtain a lock on a particular table. This instruction is only used when
|
** Obtain a lock on a particular table. This instruction is only used when
|
||||||
** the shared-cache feature is enabled.
|
** the shared-cache feature is enabled.
|
||||||
@@ -4916,7 +4915,7 @@ case OP_Expire: { /* no-push */
|
|||||||
**
|
**
|
||||||
** P2 contains the root-page of the table to lock.
|
** P2 contains the root-page of the table to lock.
|
||||||
**
|
**
|
||||||
** P3 contains a pointer to the name of the table being locked. This is only
|
** P4 contains a pointer to the name of the table being locked. This is only
|
||||||
** used to generate an error message if the lock cannot be obtained.
|
** used to generate an error message if the lock cannot be obtained.
|
||||||
*/
|
*/
|
||||||
case OP_TableLock: { /* no-push */
|
case OP_TableLock: { /* no-push */
|
||||||
@@ -4929,7 +4928,7 @@ case OP_TableLock: { /* no-push */
|
|||||||
assert( (p->btreeMask & (1<<p1))!=0 );
|
assert( (p->btreeMask & (1<<p1))!=0 );
|
||||||
rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
|
rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
|
||||||
if( rc==SQLITE_LOCKED ){
|
if( rc==SQLITE_LOCKED ){
|
||||||
const char *z = (const char *)pOp->p3.p;
|
const char *z = (const char *)pOp->p4.p;
|
||||||
sqlite3SetString(&p->zErrMsg, "database table is locked: ", z, (char*)0);
|
sqlite3SetString(&p->zErrMsg, "database table is locked: ", z, (char*)0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -4937,47 +4936,47 @@ case OP_TableLock: { /* no-push */
|
|||||||
#endif /* SQLITE_OMIT_SHARED_CACHE */
|
#endif /* SQLITE_OMIT_SHARED_CACHE */
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
/* Opcode: VBegin * * P3
|
/* Opcode: VBegin * * P4
|
||||||
**
|
**
|
||||||
** P3 a pointer to an sqlite3_vtab structure. Call the xBegin method
|
** P4 a pointer to an sqlite3_vtab structure. Call the xBegin method
|
||||||
** for that table.
|
** for that table.
|
||||||
*/
|
*/
|
||||||
case OP_VBegin: { /* no-push */
|
case OP_VBegin: { /* no-push */
|
||||||
rc = sqlite3VtabBegin(db, (sqlite3_vtab *)pOp->p3.p);
|
rc = sqlite3VtabBegin(db, (sqlite3_vtab *)pOp->p4.p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
/* Opcode: VCreate P1 * P3
|
/* Opcode: VCreate P1 * P4
|
||||||
**
|
**
|
||||||
** P3 is the name of a virtual table in database P1. Call the xCreate method
|
** P4 is the name of a virtual table in database P1. Call the xCreate method
|
||||||
** for that table.
|
** for that table.
|
||||||
*/
|
*/
|
||||||
case OP_VCreate: { /* no-push */
|
case OP_VCreate: { /* no-push */
|
||||||
rc = sqlite3VtabCallCreate(db, pOp->p1, pOp->p3.p, &p->zErrMsg);
|
rc = sqlite3VtabCallCreate(db, pOp->p1, pOp->p4.p, &p->zErrMsg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
/* Opcode: VDestroy P1 * P3
|
/* Opcode: VDestroy P1 * P4
|
||||||
**
|
**
|
||||||
** P3 is the name of a virtual table in database P1. Call the xDestroy method
|
** P4 is the name of a virtual table in database P1. Call the xDestroy method
|
||||||
** of that table.
|
** of that table.
|
||||||
*/
|
*/
|
||||||
case OP_VDestroy: { /* no-push */
|
case OP_VDestroy: { /* no-push */
|
||||||
p->inVtabMethod = 2;
|
p->inVtabMethod = 2;
|
||||||
rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p3.p);
|
rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.p);
|
||||||
p->inVtabMethod = 0;
|
p->inVtabMethod = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
/* Opcode: VOpen P1 * P3
|
/* Opcode: VOpen P1 * P4
|
||||||
**
|
**
|
||||||
** P3 is a pointer to a virtual table object, an sqlite3_vtab structure.
|
** P4 is a pointer to a virtual table object, an sqlite3_vtab structure.
|
||||||
** P1 is a cursor number. This opcode opens a cursor to the virtual
|
** P1 is a cursor number. This opcode opens a cursor to the virtual
|
||||||
** table and stores that cursor in P1.
|
** table and stores that cursor in P1.
|
||||||
*/
|
*/
|
||||||
@@ -4985,7 +4984,7 @@ case OP_VOpen: { /* no-push */
|
|||||||
Cursor *pCur = 0;
|
Cursor *pCur = 0;
|
||||||
sqlite3_vtab_cursor *pVtabCursor = 0;
|
sqlite3_vtab_cursor *pVtabCursor = 0;
|
||||||
|
|
||||||
sqlite3_vtab *pVtab = (sqlite3_vtab *)(pOp->p3.p);
|
sqlite3_vtab *pVtab = (sqlite3_vtab *)(pOp->p4.p);
|
||||||
sqlite3_module *pModule = (sqlite3_module *)pVtab->pModule;
|
sqlite3_module *pModule = (sqlite3_module *)pVtab->pModule;
|
||||||
|
|
||||||
assert(pVtab && pModule);
|
assert(pVtab && pModule);
|
||||||
@@ -5011,13 +5010,13 @@ case OP_VOpen: { /* no-push */
|
|||||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
/* Opcode: VFilter P1 P2 P3
|
/* Opcode: VFilter P1 P2 P4
|
||||||
**
|
**
|
||||||
** P1 is a cursor opened using VOpen. P2 is an address to jump to if
|
** P1 is a cursor opened using VOpen. P2 is an address to jump to if
|
||||||
** the filtered result set is empty.
|
** the filtered result set is empty.
|
||||||
**
|
**
|
||||||
** P3 is either NULL or a string that was generated by the xBestIndex
|
** P4 is either NULL or a string that was generated by the xBestIndex
|
||||||
** method of the module. The interpretation of the P3 string is left
|
** method of the module. The interpretation of the P4 string is left
|
||||||
** to the module implementation.
|
** to the module implementation.
|
||||||
**
|
**
|
||||||
** This opcode invokes the xFilter method on the virtual table specified
|
** This opcode invokes the xFilter method on the virtual table specified
|
||||||
@@ -5059,7 +5058,7 @@ case OP_VFilter: { /* no-push */
|
|||||||
|
|
||||||
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
||||||
p->inVtabMethod = 1;
|
p->inVtabMethod = 1;
|
||||||
rc = pModule->xFilter(pCur->pVtabCursor, pTos->u.i, pOp->p3.p, nArg, apArg);
|
rc = pModule->xFilter(pCur->pVtabCursor, pTos->u.i, pOp->p4.p, nArg, apArg);
|
||||||
p->inVtabMethod = 0;
|
p->inVtabMethod = 0;
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
res = pModule->xEof(pCur->pVtabCursor);
|
res = pModule->xEof(pCur->pVtabCursor);
|
||||||
@@ -5196,15 +5195,15 @@ case OP_VNext: { /* no-push */
|
|||||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
/* Opcode: VRename * * P3
|
/* Opcode: VRename * * P4
|
||||||
**
|
**
|
||||||
** P3 is a pointer to a virtual table object, an sqlite3_vtab structure.
|
** P4 is a pointer to a virtual table object, an sqlite3_vtab structure.
|
||||||
** This opcode invokes the corresponding xRename method. The value
|
** This opcode invokes the corresponding xRename method. The value
|
||||||
** on the top of the stack is popped and passed as the zName argument
|
** on the top of the stack is popped and passed as the zName argument
|
||||||
** to the xRename method.
|
** to the xRename method.
|
||||||
*/
|
*/
|
||||||
case OP_VRename: { /* no-push */
|
case OP_VRename: { /* no-push */
|
||||||
sqlite3_vtab *pVtab = (sqlite3_vtab *)(pOp->p3.p);
|
sqlite3_vtab *pVtab = (sqlite3_vtab *)(pOp->p4.p);
|
||||||
assert( pVtab->pModule->xRename );
|
assert( pVtab->pModule->xRename );
|
||||||
|
|
||||||
Stringify(pTos, encoding);
|
Stringify(pTos, encoding);
|
||||||
@@ -5221,9 +5220,9 @@ case OP_VRename: { /* no-push */
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
/* Opcode: VUpdate P1 P2 P3
|
/* Opcode: VUpdate P1 P2 P4
|
||||||
**
|
**
|
||||||
** P3 is a pointer to a virtual table object, an sqlite3_vtab structure.
|
** P4 is a pointer to a virtual table object, an sqlite3_vtab structure.
|
||||||
** This opcode invokes the corresponding xUpdate method. P2 values
|
** This opcode invokes the corresponding xUpdate method. P2 values
|
||||||
** are taken from the stack to pass to the xUpdate invocation. The
|
** are taken from the stack to pass to the xUpdate invocation. The
|
||||||
** value on the top of the stack corresponds to the p2th element
|
** value on the top of the stack corresponds to the p2th element
|
||||||
@@ -5245,10 +5244,10 @@ case OP_VRename: { /* no-push */
|
|||||||
** is set to the value of the rowid for the row just inserted.
|
** is set to the value of the rowid for the row just inserted.
|
||||||
*/
|
*/
|
||||||
case OP_VUpdate: { /* no-push */
|
case OP_VUpdate: { /* no-push */
|
||||||
sqlite3_vtab *pVtab = (sqlite3_vtab *)(pOp->p3.p);
|
sqlite3_vtab *pVtab = (sqlite3_vtab *)(pOp->p4.p);
|
||||||
sqlite3_module *pModule = (sqlite3_module *)pVtab->pModule;
|
sqlite3_module *pModule = (sqlite3_module *)pVtab->pModule;
|
||||||
int nArg = pOp->p2;
|
int nArg = pOp->p2;
|
||||||
assert( pOp->p3type==P3_VTAB );
|
assert( pOp->p4type==P4_VTAB );
|
||||||
if( pModule->xUpdate==0 ){
|
if( pModule->xUpdate==0 ){
|
||||||
sqlite3SetString(&p->zErrMsg, "read-only table", 0);
|
sqlite3SetString(&p->zErrMsg, "read-only table", 0);
|
||||||
rc = SQLITE_ERROR;
|
rc = SQLITE_ERROR;
|
||||||
|
57
src/vdbe.h
57
src/vdbe.h
@@ -15,7 +15,7 @@
|
|||||||
** or VDBE. The VDBE implements an abstract machine that runs a
|
** or VDBE. The VDBE implements an abstract machine that runs a
|
||||||
** simple program to access and modify the underlying database.
|
** simple program to access and modify the underlying database.
|
||||||
**
|
**
|
||||||
** $Id: vdbe.h,v 1.117 2008/01/02 17:25:55 drh Exp $
|
** $Id: vdbe.h,v 1.118 2008/01/03 00:01:25 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITE_VDBE_H_
|
#ifndef _SQLITE_VDBE_H_
|
||||||
#define _SQLITE_VDBE_H_
|
#define _SQLITE_VDBE_H_
|
||||||
@@ -35,15 +35,16 @@ typedef struct Vdbe Vdbe;
|
|||||||
*/
|
*/
|
||||||
struct VdbeOp {
|
struct VdbeOp {
|
||||||
u8 opcode; /* What operation to perform */
|
u8 opcode; /* What operation to perform */
|
||||||
char p3type; /* One of the P3_xxx constants defined below */
|
char p4type; /* One of the P4_xxx constants for p4 */
|
||||||
char p4type; /* One of the P3_xxx constants for p4 */
|
u8 flags; /* Flags for internal use */
|
||||||
u8 p5; /* Fifth parameter is an unsigned character */
|
u8 p5; /* Fifth parameter is an unsigned character */
|
||||||
int p1; /* First operand */
|
int p1; /* First operand */
|
||||||
int p2; /* Second parameter (often the jump destination) */
|
int p2; /* Second parameter (often the jump destination) */
|
||||||
union { /* Third and forth parameters */
|
int p3; /* The third parameter */
|
||||||
int i; /* Integer value if p3type==P3_INT32 */
|
union { /* forth parameter */
|
||||||
|
int i; /* Integer value if p3type==P4_INT32 */
|
||||||
char *p; /* A pointer for all other value sof p3type */
|
char *p; /* A pointer for all other value sof p3type */
|
||||||
} p3, p4;
|
} p4;
|
||||||
#ifdef SQLITE_DEBUG
|
#ifdef SQLITE_DEBUG
|
||||||
char *zComment; /* Comment to improve readability */
|
char *zComment; /* Comment to improve readability */
|
||||||
#endif
|
#endif
|
||||||
@@ -69,29 +70,29 @@ typedef struct VdbeOpList VdbeOpList;
|
|||||||
/*
|
/*
|
||||||
** Allowed values of VdbeOp.p3type
|
** Allowed values of VdbeOp.p3type
|
||||||
*/
|
*/
|
||||||
#define P3_NOTUSED 0 /* The P3 parameter is not used */
|
#define P4_NOTUSED 0 /* The P4 parameter is not used */
|
||||||
#define P3_DYNAMIC (-1) /* Pointer to a string obtained from sqliteMalloc() */
|
#define P4_DYNAMIC (-1) /* Pointer to a string obtained from sqliteMalloc() */
|
||||||
#define P3_STATIC (-2) /* Pointer to a static string */
|
#define P4_STATIC (-2) /* Pointer to a static string */
|
||||||
#define P3_COLLSEQ (-4) /* P3 is a pointer to a CollSeq structure */
|
#define P4_COLLSEQ (-4) /* P4 is a pointer to a CollSeq structure */
|
||||||
#define P3_FUNCDEF (-5) /* P3 is a pointer to a FuncDef structure */
|
#define P4_FUNCDEF (-5) /* P4 is a pointer to a FuncDef structure */
|
||||||
#define P3_KEYINFO (-6) /* P3 is a pointer to a KeyInfo structure */
|
#define P4_KEYINFO (-6) /* P4 is a pointer to a KeyInfo structure */
|
||||||
#define P3_VDBEFUNC (-7) /* P3 is a pointer to a VdbeFunc structure */
|
#define P4_VDBEFUNC (-7) /* P4 is a pointer to a VdbeFunc structure */
|
||||||
#define P3_MEM (-8) /* P3 is a pointer to a Mem* structure */
|
#define P4_MEM (-8) /* P4 is a pointer to a Mem* structure */
|
||||||
#define P3_TRANSIENT (-9) /* P3 is a pointer to a transient string */
|
#define P4_TRANSIENT (-9) /* P4 is a pointer to a transient string */
|
||||||
#define P3_VTAB (-10) /* P3 is a pointer to an sqlite3_vtab structure */
|
#define P4_VTAB (-10) /* P4 is a pointer to an sqlite3_vtab structure */
|
||||||
#define P3_MPRINTF (-11) /* P3 is a string obtained from sqlite3_mprintf() */
|
#define P4_MPRINTF (-11) /* P4 is a string obtained from sqlite3_mprintf() */
|
||||||
#define P3_REAL (-12) /* P3 is a 64-bit floating point value */
|
#define P4_REAL (-12) /* P4 is a 64-bit floating point value */
|
||||||
#define P3_INT64 (-13) /* P3 is a 64-bit signed integer */
|
#define P4_INT64 (-13) /* P4 is a 64-bit signed integer */
|
||||||
#define P3_INT32 (-14) /* P3 is a 32-bit signed integer */
|
#define P4_INT32 (-14) /* P4 is a 32-bit signed integer */
|
||||||
|
|
||||||
/* When adding a P3 argument using P3_KEYINFO, a copy of the KeyInfo structure
|
/* When adding a P4 argument using P4_KEYINFO, a copy of the KeyInfo structure
|
||||||
** is made. That copy is freed when the Vdbe is finalized. But if the
|
** is made. That copy is freed when the Vdbe is finalized. But if the
|
||||||
** argument is P3_KEYINFO_HANDOFF, the passed in pointer is used. It still
|
** argument is P4_KEYINFO_HANDOFF, the passed in pointer is used. It still
|
||||||
** gets freed when the Vdbe is finalized so it still should be obtained
|
** gets freed when the Vdbe is finalized so it still should be obtained
|
||||||
** from a single sqliteMalloc(). But no copy is made and the calling
|
** from a single sqliteMalloc(). But no copy is made and the calling
|
||||||
** function should *not* try to free the KeyInfo.
|
** function should *not* try to free the KeyInfo.
|
||||||
*/
|
*/
|
||||||
#define P3_KEYINFO_HANDOFF (-9)
|
#define P4_KEYINFO_HANDOFF (-9)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The Vdbe.aColName array contains 5n Mem structures, where n is the
|
** The Vdbe.aColName array contains 5n Mem structures, where n is the
|
||||||
@@ -123,15 +124,17 @@ typedef struct VdbeOpList VdbeOpList;
|
|||||||
** for a description of what each of these routines does.
|
** for a description of what each of these routines does.
|
||||||
*/
|
*/
|
||||||
Vdbe *sqlite3VdbeCreate(sqlite3*);
|
Vdbe *sqlite3VdbeCreate(sqlite3*);
|
||||||
int sqlite3VdbeAddOp(Vdbe*,int,int,int);
|
int sqlite3VdbeAddOp0(Vdbe*,int);
|
||||||
int sqlite3VdbeOp3(Vdbe*,int,int,int,const char *zP3,int);
|
int sqlite3VdbeAddOp1(Vdbe*,int,int);
|
||||||
int sqlite3VdbeOp3Int(Vdbe*,int,int,int,int);
|
int sqlite3VdbeAddOp2(Vdbe*,int,int,int);
|
||||||
|
int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int);
|
||||||
|
int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int);
|
||||||
int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp);
|
int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp);
|
||||||
void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1);
|
void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1);
|
||||||
void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);
|
void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);
|
||||||
void sqlite3VdbeJumpHere(Vdbe*, int addr);
|
void sqlite3VdbeJumpHere(Vdbe*, int addr);
|
||||||
void sqlite3VdbeChangeToNoop(Vdbe*, int addr, int N);
|
void sqlite3VdbeChangeToNoop(Vdbe*, int addr, int N);
|
||||||
void sqlite3VdbeChangeP3(Vdbe*, int addr, const char *zP1, int N);
|
void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
|
||||||
void sqlite3VdbeUsesBtree(Vdbe*, int);
|
void sqlite3VdbeUsesBtree(Vdbe*, int);
|
||||||
VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
|
VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
|
||||||
int sqlite3VdbeMakeLabel(Vdbe*);
|
int sqlite3VdbeMakeLabel(Vdbe*);
|
||||||
|
@@ -293,10 +293,10 @@ static int sqlite3Step(Vdbe *p){
|
|||||||
if( db->xTrace && !db->init.busy ){
|
if( db->xTrace && !db->init.busy ){
|
||||||
assert( p->nOp>0 );
|
assert( p->nOp>0 );
|
||||||
assert( p->aOp[p->nOp-1].opcode==OP_Noop );
|
assert( p->aOp[p->nOp-1].opcode==OP_Noop );
|
||||||
assert( p->aOp[p->nOp-1].p3.p!=0 );
|
assert( p->aOp[p->nOp-1].p4.p!=0 );
|
||||||
assert( p->aOp[p->nOp-1].p3type==P3_DYNAMIC );
|
assert( p->aOp[p->nOp-1].p4type==P4_DYNAMIC );
|
||||||
sqlite3SafetyOff(db);
|
sqlite3SafetyOff(db);
|
||||||
db->xTrace(db->pTraceArg, p->aOp[p->nOp-1].p3.p);
|
db->xTrace(db->pTraceArg, p->aOp[p->nOp-1].p4.p);
|
||||||
if( sqlite3SafetyOn(db) ){
|
if( sqlite3SafetyOn(db) ){
|
||||||
p->rc = SQLITE_MISUSE;
|
p->rc = SQLITE_MISUSE;
|
||||||
return SQLITE_MISUSE;
|
return SQLITE_MISUSE;
|
||||||
@@ -314,7 +314,7 @@ static int sqlite3Step(Vdbe *p){
|
|||||||
*/
|
*/
|
||||||
#ifdef SQLITE_DEBUG
|
#ifdef SQLITE_DEBUG
|
||||||
if( (db->flags & SQLITE_SqlTrace)!=0 ){
|
if( (db->flags & SQLITE_SqlTrace)!=0 ){
|
||||||
sqlite3DebugPrintf("SQL-trace: %s\n", p->aOp[p->nOp-1].p3.p);
|
sqlite3DebugPrintf("SQL-trace: %s\n", p->aOp[p->nOp-1].p4.p);
|
||||||
}
|
}
|
||||||
#endif /* SQLITE_DEBUG */
|
#endif /* SQLITE_DEBUG */
|
||||||
|
|
||||||
@@ -345,9 +345,9 @@ static int sqlite3Step(Vdbe *p){
|
|||||||
elapseTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0 - p->startTime;
|
elapseTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0 - p->startTime;
|
||||||
assert( p->nOp>0 );
|
assert( p->nOp>0 );
|
||||||
assert( p->aOp[p->nOp-1].opcode==OP_Noop );
|
assert( p->aOp[p->nOp-1].opcode==OP_Noop );
|
||||||
assert( p->aOp[p->nOp-1].p3.p!=0 );
|
assert( p->aOp[p->nOp-1].p4.p!=0 );
|
||||||
assert( p->aOp[p->nOp-1].p3type==P3_DYNAMIC );
|
assert( p->aOp[p->nOp-1].p4type==P4_DYNAMIC );
|
||||||
db->xProfile(db->pProfileArg, p->aOp[p->nOp-1].p3.p, elapseTime);
|
db->xProfile(db->pProfileArg, p->aOp[p->nOp-1].p4.p, elapseTime);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1001,7 +1001,7 @@ static void createVarMap(Vdbe *p){
|
|||||||
for(j=0, pOp=p->aOp; j<p->nOp; j++, pOp++){
|
for(j=0, pOp=p->aOp; j<p->nOp; j++, pOp++){
|
||||||
if( pOp->opcode==OP_Variable ){
|
if( pOp->opcode==OP_Variable ){
|
||||||
assert( pOp->p1>0 && pOp->p1<=p->nVar );
|
assert( pOp->p1>0 && pOp->p1<=p->nVar );
|
||||||
p->azVar[pOp->p1-1] = pOp->p3.p;
|
p->azVar[pOp->p1-1] = pOp->p4.p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p->okVar = 1;
|
p->okVar = 1;
|
||||||
|
231
src/vdbeaux.c
231
src/vdbeaux.c
@@ -129,13 +129,13 @@ static void resizeOpArray(Vdbe *p, int N){
|
|||||||
**
|
**
|
||||||
** op The opcode for this instruction
|
** op The opcode for this instruction
|
||||||
**
|
**
|
||||||
** p1, p2 First two of the three possible operands.
|
** p1, p2, p3 Operands
|
||||||
**
|
**
|
||||||
** Use the sqlite3VdbeResolveLabel() function to fix an address and
|
** Use the sqlite3VdbeResolveLabel() function to fix an address and
|
||||||
** the sqlite3VdbeChangeP3() function to change the value of the P3
|
** the sqlite3VdbeChangeP4() function to change the value of the P4
|
||||||
** operand.
|
** operand.
|
||||||
*/
|
*/
|
||||||
int sqlite3VdbeAddOp(Vdbe *p, int op, int p1, int p2){
|
int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
|
||||||
int i;
|
int i;
|
||||||
VdbeOp *pOp;
|
VdbeOp *pOp;
|
||||||
|
|
||||||
@@ -152,45 +152,40 @@ int sqlite3VdbeAddOp(Vdbe *p, int op, int p1, int p2){
|
|||||||
pOp->opcode = op;
|
pOp->opcode = op;
|
||||||
pOp->p1 = p1;
|
pOp->p1 = p1;
|
||||||
pOp->p2 = p2;
|
pOp->p2 = p2;
|
||||||
pOp->p3.p = 0;
|
pOp->p3 = p3;
|
||||||
pOp->p3type = P3_NOTUSED;
|
pOp->p4.p = 0;
|
||||||
|
pOp->p4type = P4_NOTUSED;
|
||||||
p->expired = 0;
|
p->expired = 0;
|
||||||
#ifdef SQLITE_DEBUG
|
#ifdef SQLITE_DEBUG
|
||||||
if( sqlite3_vdbe_addop_trace ) sqlite3VdbePrintOp(0, i, &p->aOp[i]);
|
if( sqlite3_vdbe_addop_trace ) sqlite3VdbePrintOp(0, i, &p->aOp[i]);
|
||||||
#endif
|
#endif
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
int sqlite3VdbeAddOp0(Vdbe *p, int op){
|
||||||
/*
|
return sqlite3VdbeAddOp3(p, op, 0, 0, 0);
|
||||||
** Add an opcode that includes the p3 value as a pointer.
|
}
|
||||||
*/
|
int sqlite3VdbeAddOp1(Vdbe *p, int op, int p1){
|
||||||
int sqlite3VdbeOp3(
|
return sqlite3VdbeAddOp3(p, op, p1, 0, 0);
|
||||||
Vdbe *p, /* Add the opcode to this VM */
|
}
|
||||||
int op, /* The new opcode */
|
int sqlite3VdbeAddOp2(Vdbe *p, int op, int p1, int p2){
|
||||||
int p1, int p2, /* P1 and P2 operands */
|
return sqlite3VdbeAddOp3(p, op, p1, p2, 0);
|
||||||
const char *zP3, /* The P3 operand */
|
|
||||||
int p3type /* P3 operand type */
|
|
||||||
){
|
|
||||||
int addr = sqlite3VdbeAddOp(p, op, p1, p2);
|
|
||||||
sqlite3VdbeChangeP3(p, addr, zP3, p3type);
|
|
||||||
return addr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Add an opcode that includes the p3 value as an integer.
|
** Add an opcode that includes the p4 value as a pointer.
|
||||||
*/
|
*/
|
||||||
int sqlite3VdbeOp3Int(
|
int sqlite3VdbeAddOp4(
|
||||||
Vdbe *p, /* Add the opcode to this VM */
|
Vdbe *p, /* Add the opcode to this VM */
|
||||||
int op, /* The new opcode */
|
int op, /* The new opcode */
|
||||||
int p1, int p2, /* P1 and P2 operands */
|
int p1, /* The P1 operand */
|
||||||
int p3 /* The P3 operand */
|
int p2, /* The P2 operand */
|
||||||
|
int p3, /* The P3 operand */
|
||||||
|
const char *zP4, /* The P4 operand */
|
||||||
|
int p4type /* P4 operand type */
|
||||||
){
|
){
|
||||||
int addr = sqlite3VdbeAddOp(p, op, p1, p2);
|
int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3);
|
||||||
if( !p->db->mallocFailed ){
|
sqlite3VdbeChangeP4(p, addr, zP4, p4type);
|
||||||
Op *pOp = &p->aOp[addr];
|
|
||||||
pOp->p3.i = p3;
|
|
||||||
pOp->p3type = P3_INT32;
|
|
||||||
}
|
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,8 +397,8 @@ int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
|
|||||||
pOut->opcode = pIn->opcode;
|
pOut->opcode = pIn->opcode;
|
||||||
pOut->p1 = pIn->p1;
|
pOut->p1 = pIn->p1;
|
||||||
pOut->p2 = p2<0 ? addr + ADDR(p2) : p2;
|
pOut->p2 = p2<0 ? addr + ADDR(p2) : p2;
|
||||||
pOut->p3.p = pIn->p3;
|
pOut->p4.p = pIn->p3;
|
||||||
pOut->p3type = pIn->p3 ? P3_STATIC : P3_NOTUSED;
|
pOut->p4type = pIn->p3 ? P4_STATIC : P4_NOTUSED;
|
||||||
#ifdef SQLITE_DEBUG
|
#ifdef SQLITE_DEBUG
|
||||||
if( sqlite3_vdbe_addop_trace ){
|
if( sqlite3_vdbe_addop_trace ){
|
||||||
sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
|
sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
|
||||||
@@ -460,32 +455,32 @@ static void freeEphemeralFunction(FuncDef *pDef){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Delete a P3 value if necessary.
|
** Delete a P4 value if necessary.
|
||||||
*/
|
*/
|
||||||
static void freeP3(int p3type, void *p3){
|
static void freeP4(int p4type, void *p3){
|
||||||
if( p3 ){
|
if( p3 ){
|
||||||
switch( p3type ){
|
switch( p4type ){
|
||||||
case P3_REAL:
|
case P4_REAL:
|
||||||
case P3_INT64:
|
case P4_INT64:
|
||||||
case P3_MPRINTF:
|
case P4_MPRINTF:
|
||||||
case P3_DYNAMIC:
|
case P4_DYNAMIC:
|
||||||
case P3_KEYINFO:
|
case P4_KEYINFO:
|
||||||
case P3_KEYINFO_HANDOFF: {
|
case P4_KEYINFO_HANDOFF: {
|
||||||
sqlite3_free(p3);
|
sqlite3_free(p3);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case P3_VDBEFUNC: {
|
case P4_VDBEFUNC: {
|
||||||
VdbeFunc *pVdbeFunc = (VdbeFunc *)p3;
|
VdbeFunc *pVdbeFunc = (VdbeFunc *)p3;
|
||||||
freeEphemeralFunction(pVdbeFunc->pFunc);
|
freeEphemeralFunction(pVdbeFunc->pFunc);
|
||||||
sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
|
sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
|
||||||
sqlite3_free(pVdbeFunc);
|
sqlite3_free(pVdbeFunc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case P3_FUNCDEF: {
|
case P4_FUNCDEF: {
|
||||||
freeEphemeralFunction((FuncDef*)p3);
|
freeEphemeralFunction((FuncDef*)p3);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case P3_MEM: {
|
case P4_MEM: {
|
||||||
sqlite3ValueFree((sqlite3_value*)p3);
|
sqlite3ValueFree((sqlite3_value*)p3);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -501,7 +496,7 @@ void sqlite3VdbeChangeToNoop(Vdbe *p, int addr, int N){
|
|||||||
if( p && p->aOp ){
|
if( p && p->aOp ){
|
||||||
VdbeOp *pOp = &p->aOp[addr];
|
VdbeOp *pOp = &p->aOp[addr];
|
||||||
while( N-- ){
|
while( N-- ){
|
||||||
freeP3(pOp->p3type, pOp->p3.p);
|
freeP4(pOp->p4type, pOp->p4.p);
|
||||||
memset(pOp, 0, sizeof(pOp[0]));
|
memset(pOp, 0, sizeof(pOp[0]));
|
||||||
pOp->opcode = OP_Noop;
|
pOp->opcode = OP_Noop;
|
||||||
pOp++;
|
pOp++;
|
||||||
@@ -510,36 +505,36 @@ void sqlite3VdbeChangeToNoop(Vdbe *p, int addr, int N){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Change the value of the P3 operand for a specific instruction.
|
** Change the value of the P4 operand for a specific instruction.
|
||||||
** This routine is useful when a large program is loaded from a
|
** This routine is useful when a large program is loaded from a
|
||||||
** static array using sqlite3VdbeAddOpList but we want to make a
|
** static array using sqlite3VdbeAddOpList but we want to make a
|
||||||
** few minor changes to the program.
|
** few minor changes to the program.
|
||||||
**
|
**
|
||||||
** If n>=0 then the P3 operand is dynamic, meaning that a copy of
|
** If n>=0 then the P4 operand is dynamic, meaning that a copy of
|
||||||
** the string is made into memory obtained from sqlite3_malloc().
|
** the string is made into memory obtained from sqlite3_malloc().
|
||||||
** A value of n==0 means copy bytes of zP3 up to and including the
|
** A value of n==0 means copy bytes of zP4 up to and including the
|
||||||
** first null byte. If n>0 then copy n+1 bytes of zP3.
|
** first null byte. If n>0 then copy n+1 bytes of zP4.
|
||||||
**
|
**
|
||||||
** If n==P3_KEYINFO it means that zP3 is a pointer to a KeyInfo structure.
|
** If n==P4_KEYINFO it means that zP4 is a pointer to a KeyInfo structure.
|
||||||
** A copy is made of the KeyInfo structure into memory obtained from
|
** A copy is made of the KeyInfo structure into memory obtained from
|
||||||
** sqlite3_malloc, to be freed when the Vdbe is finalized.
|
** sqlite3_malloc, to be freed when the Vdbe is finalized.
|
||||||
** n==P3_KEYINFO_HANDOFF indicates that zP3 points to a KeyInfo structure
|
** n==P4_KEYINFO_HANDOFF indicates that zP4 points to a KeyInfo structure
|
||||||
** stored in memory that the caller has obtained from sqlite3_malloc. The
|
** stored in memory that the caller has obtained from sqlite3_malloc. The
|
||||||
** caller should not free the allocation, it will be freed when the Vdbe is
|
** caller should not free the allocation, it will be freed when the Vdbe is
|
||||||
** finalized.
|
** finalized.
|
||||||
**
|
**
|
||||||
** Other values of n (P3_STATIC, P3_COLLSEQ etc.) indicate that zP3 points
|
** Other values of n (P4_STATIC, P4_COLLSEQ etc.) indicate that zP4 points
|
||||||
** to a string or structure that is guaranteed to exist for the lifetime of
|
** to a string or structure that is guaranteed to exist for the lifetime of
|
||||||
** the Vdbe. In these cases we can just copy the pointer.
|
** the Vdbe. In these cases we can just copy the pointer.
|
||||||
**
|
**
|
||||||
** If addr<0 then change P3 on the most recently inserted instruction.
|
** If addr<0 then change P4 on the most recently inserted instruction.
|
||||||
*/
|
*/
|
||||||
void sqlite3VdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
|
void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
|
||||||
Op *pOp;
|
Op *pOp;
|
||||||
assert( p==0 || p->magic==VDBE_MAGIC_INIT );
|
assert( p==0 || p->magic==VDBE_MAGIC_INIT );
|
||||||
if( p==0 || p->aOp==0 || p->db->mallocFailed ){
|
if( p==0 || p->aOp==0 || p->db->mallocFailed ){
|
||||||
if (n != P3_KEYINFO) {
|
if (n != P4_KEYINFO) {
|
||||||
freeP3(n, (void*)*(char**)&zP3);
|
freeP4(n, (void*)*(char**)&zP4);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -548,42 +543,42 @@ void sqlite3VdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
|
|||||||
if( addr<0 ) return;
|
if( addr<0 ) return;
|
||||||
}
|
}
|
||||||
pOp = &p->aOp[addr];
|
pOp = &p->aOp[addr];
|
||||||
freeP3(pOp->p3type, pOp->p3.p);
|
freeP4(pOp->p4type, pOp->p4.p);
|
||||||
pOp->p3.p = 0;
|
pOp->p4.p = 0;
|
||||||
if( zP3==0 ){
|
if( zP4==0 ){
|
||||||
pOp->p3.p = 0;
|
pOp->p4.p = 0;
|
||||||
pOp->p3type = P3_NOTUSED;
|
pOp->p4type = P4_NOTUSED;
|
||||||
}else if( n==P3_KEYINFO ){
|
}else if( n==P4_KEYINFO ){
|
||||||
KeyInfo *pKeyInfo;
|
KeyInfo *pKeyInfo;
|
||||||
int nField, nByte;
|
int nField, nByte;
|
||||||
|
|
||||||
nField = ((KeyInfo*)zP3)->nField;
|
nField = ((KeyInfo*)zP4)->nField;
|
||||||
nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]) + nField;
|
nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]) + nField;
|
||||||
pKeyInfo = sqlite3_malloc( nByte );
|
pKeyInfo = sqlite3_malloc( nByte );
|
||||||
pOp->p3.p = (char*)pKeyInfo;
|
pOp->p4.p = (char*)pKeyInfo;
|
||||||
if( pKeyInfo ){
|
if( pKeyInfo ){
|
||||||
unsigned char *aSortOrder;
|
unsigned char *aSortOrder;
|
||||||
memcpy(pKeyInfo, zP3, nByte);
|
memcpy(pKeyInfo, zP4, nByte);
|
||||||
aSortOrder = pKeyInfo->aSortOrder;
|
aSortOrder = pKeyInfo->aSortOrder;
|
||||||
if( aSortOrder ){
|
if( aSortOrder ){
|
||||||
pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField];
|
pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField];
|
||||||
memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);
|
memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);
|
||||||
}
|
}
|
||||||
pOp->p3type = P3_KEYINFO;
|
pOp->p4type = P4_KEYINFO;
|
||||||
}else{
|
}else{
|
||||||
p->db->mallocFailed = 1;
|
p->db->mallocFailed = 1;
|
||||||
pOp->p3type = P3_NOTUSED;
|
pOp->p4type = P4_NOTUSED;
|
||||||
}
|
}
|
||||||
}else if( n==P3_KEYINFO_HANDOFF ){
|
}else if( n==P4_KEYINFO_HANDOFF ){
|
||||||
pOp->p3.p = (char*)zP3;
|
pOp->p4.p = (char*)zP4;
|
||||||
pOp->p3type = P3_KEYINFO;
|
pOp->p4type = P4_KEYINFO;
|
||||||
}else if( n<0 ){
|
}else if( n<0 ){
|
||||||
pOp->p3.p = (char*)zP3;
|
pOp->p4.p = (char*)zP4;
|
||||||
pOp->p3type = n;
|
pOp->p4type = n;
|
||||||
}else{
|
}else{
|
||||||
if( n==0 ) n = strlen(zP3);
|
if( n==0 ) n = strlen(zP4);
|
||||||
pOp->p3.p = sqlite3DbStrNDup(p->db, zP3, n);
|
pOp->p4.p = sqlite3DbStrNDup(p->db, zP4, n);
|
||||||
pOp->p3type = P3_DYNAMIC;
|
pOp->p4type = P4_DYNAMIC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -613,17 +608,17 @@ VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
|
|||||||
#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
|
#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
|
||||||
|| defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
|
|| defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
|
||||||
/*
|
/*
|
||||||
** Compute a string that describes the P3 parameter for an opcode.
|
** Compute a string that describes the P4 parameter for an opcode.
|
||||||
** Use zTemp for any required temporary buffer space.
|
** Use zTemp for any required temporary buffer space.
|
||||||
*/
|
*/
|
||||||
static char *displayP3(Op *pOp, char *zTemp, int nTemp){
|
static char *displayP4(Op *pOp, char *zTemp, int nTemp){
|
||||||
char *zP3 = zTemp;
|
char *zP4 = zTemp;
|
||||||
int nP3;
|
int nP4;
|
||||||
assert( nTemp>=20 );
|
assert( nTemp>=20 );
|
||||||
switch( pOp->p3type ){
|
switch( pOp->p4type ){
|
||||||
case P3_KEYINFO: {
|
case P4_KEYINFO: {
|
||||||
int i, j;
|
int i, j;
|
||||||
KeyInfo *pKeyInfo = (KeyInfo*)pOp->p3.p;
|
KeyInfo *pKeyInfo = (KeyInfo*)pOp->p4.p;
|
||||||
sqlite3_snprintf(nTemp, zTemp, "keyinfo(%d", pKeyInfo->nField);
|
sqlite3_snprintf(nTemp, zTemp, "keyinfo(%d", pKeyInfo->nField);
|
||||||
i = strlen(zTemp);
|
i = strlen(zTemp);
|
||||||
for(j=0; j<pKeyInfo->nField; j++){
|
for(j=0; j<pKeyInfo->nField; j++){
|
||||||
@@ -650,32 +645,32 @@ static char *displayP3(Op *pOp, char *zTemp, int nTemp){
|
|||||||
assert( i<nTemp );
|
assert( i<nTemp );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case P3_COLLSEQ: {
|
case P4_COLLSEQ: {
|
||||||
CollSeq *pColl = (CollSeq*)pOp->p3.p;
|
CollSeq *pColl = (CollSeq*)pOp->p4.p;
|
||||||
sqlite3_snprintf(nTemp, zTemp, "collseq(%.20s)", pColl->zName);
|
sqlite3_snprintf(nTemp, zTemp, "collseq(%.20s)", pColl->zName);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case P3_FUNCDEF: {
|
case P4_FUNCDEF: {
|
||||||
FuncDef *pDef = (FuncDef*)pOp->p3.p;
|
FuncDef *pDef = (FuncDef*)pOp->p4.p;
|
||||||
sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg);
|
sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case P3_INT64: {
|
case P4_INT64: {
|
||||||
sqlite3_snprintf(nTemp, zTemp, "%lld", *(sqlite3_int64*)pOp->p3.p);
|
sqlite3_snprintf(nTemp, zTemp, "%lld", *(sqlite3_int64*)pOp->p4.p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case P3_INT32: {
|
case P4_INT32: {
|
||||||
sqlite3_snprintf(nTemp, zTemp, "%d", pOp->p3.i);
|
sqlite3_snprintf(nTemp, zTemp, "%d", pOp->p4.i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case P3_REAL: {
|
case P4_REAL: {
|
||||||
sqlite3_snprintf(nTemp, zTemp, "%.16g", *(double*)pOp->p3.p);
|
sqlite3_snprintf(nTemp, zTemp, "%.16g", *(double*)pOp->p4.p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case P3_MEM: {
|
case P4_MEM: {
|
||||||
Mem *pMem = (Mem*)pOp->p3.p;
|
Mem *pMem = (Mem*)pOp->p4.p;
|
||||||
if( pMem->flags & MEM_Str ){
|
if( pMem->flags & MEM_Str ){
|
||||||
zP3 = pMem->z;
|
zP4 = pMem->z;
|
||||||
}else if( pMem->flags & MEM_Int ){
|
}else if( pMem->flags & MEM_Int ){
|
||||||
sqlite3_snprintf(nTemp, zTemp, "%lld", pMem->u.i);
|
sqlite3_snprintf(nTemp, zTemp, "%lld", pMem->u.i);
|
||||||
}else if( pMem->flags & MEM_Real ){
|
}else if( pMem->flags & MEM_Real ){
|
||||||
@@ -686,28 +681,28 @@ static char *displayP3(Op *pOp, char *zTemp, int nTemp){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
case P3_VTAB: {
|
case P4_VTAB: {
|
||||||
sqlite3_vtab *pVtab = (sqlite3_vtab*)pOp->p3.p;
|
sqlite3_vtab *pVtab = (sqlite3_vtab*)pOp->p4.p;
|
||||||
sqlite3_snprintf(nTemp, zTemp, "vtab:%p:%p", pVtab, pVtab->pModule);
|
sqlite3_snprintf(nTemp, zTemp, "vtab:%p:%p", pVtab, pVtab->pModule);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
default: {
|
default: {
|
||||||
zP3 = pOp->p3.p;
|
zP4 = pOp->p4.p;
|
||||||
if( zP3==0 || pOp->opcode==OP_Noop ){
|
if( zP4==0 || pOp->opcode==OP_Noop ){
|
||||||
zP3 = zTemp;
|
zP4 = zTemp;
|
||||||
zTemp[0] = 0;
|
zTemp[0] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert( zP3!=0 );
|
assert( zP4!=0 );
|
||||||
#ifdef SQLITE_DEBUG
|
#ifdef SQLITE_DEBUG
|
||||||
if( pOp->zComment && zP3==zTemp && (nP3 = strlen(zP3))<nTemp ){
|
if( pOp->zComment && zP4==zTemp && (nP4 = strlen(zP4))<nTemp ){
|
||||||
sqlite3_snprintf(nTemp-nP3, &zP3[nP3], "%s# %s",
|
sqlite3_snprintf(nTemp-nP4, &zP4[nP4], "%s# %s",
|
||||||
nP3>0 ? " " : "", pOp->zComment);
|
nP4>0 ? " " : "", pOp->zComment);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return zP3;
|
return zP4;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -732,13 +727,13 @@ void sqlite3VdbeUsesBtree(Vdbe *p, int i){
|
|||||||
** Print a single opcode. This routine is used for debugging only.
|
** Print a single opcode. This routine is used for debugging only.
|
||||||
*/
|
*/
|
||||||
void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){
|
void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){
|
||||||
char *zP3;
|
char *zP4;
|
||||||
char zPtr[50];
|
char zPtr[50];
|
||||||
static const char *zFormat1 = "%4d %-13s %4d %4d %s\n";
|
static const char *zFormat1 = "%4d %-13s %4d %4d %s\n";
|
||||||
if( pOut==0 ) pOut = stdout;
|
if( pOut==0 ) pOut = stdout;
|
||||||
zP3 = displayP3(pOp, zPtr, sizeof(zPtr));
|
zP4 = displayP4(pOp, zPtr, sizeof(zPtr));
|
||||||
fprintf(pOut, zFormat1,
|
fprintf(pOut, zFormat1,
|
||||||
pc, sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, zP3);
|
pc, sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, zP4);
|
||||||
fflush(pOut);
|
fflush(pOut);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -820,8 +815,8 @@ int sqlite3VdbeList(
|
|||||||
pMem->type = SQLITE_INTEGER;
|
pMem->type = SQLITE_INTEGER;
|
||||||
pMem++;
|
pMem++;
|
||||||
|
|
||||||
pMem->flags = MEM_Ephem|MEM_Str|MEM_Term; /* P3 */
|
pMem->flags = MEM_Ephem|MEM_Str|MEM_Term; /* P4 */
|
||||||
pMem->z = displayP3(pOp, pMem->zShort, sizeof(pMem->zShort));
|
pMem->z = displayP4(pOp, pMem->zShort, sizeof(pMem->zShort));
|
||||||
assert( pMem->z!=0 );
|
assert( pMem->z!=0 );
|
||||||
pMem->n = strlen(pMem->z);
|
pMem->n = strlen(pMem->z);
|
||||||
pMem->type = SQLITE_TEXT;
|
pMem->type = SQLITE_TEXT;
|
||||||
@@ -845,8 +840,8 @@ void sqlite3VdbePrintSql(Vdbe *p){
|
|||||||
VdbeOp *pOp;
|
VdbeOp *pOp;
|
||||||
if( nOp<1 ) return;
|
if( nOp<1 ) return;
|
||||||
pOp = &p->aOp[nOp-1];
|
pOp = &p->aOp[nOp-1];
|
||||||
if( pOp->opcode==OP_Noop && pOp->p3.p!=0 ){
|
if( pOp->opcode==OP_Noop && pOp->p4.p!=0 ){
|
||||||
const char *z = pOp->p3.p;
|
const char *z = pOp->p4.p;
|
||||||
while( isspace(*(u8*)z) ) z++;
|
while( isspace(*(u8*)z) ) z++;
|
||||||
printf("SQL: [%s]\n", z);
|
printf("SQL: [%s]\n", z);
|
||||||
}
|
}
|
||||||
@@ -863,10 +858,10 @@ void sqlite3VdbeIOTraceSql(Vdbe *p){
|
|||||||
if( sqlite3_io_trace==0 ) return;
|
if( sqlite3_io_trace==0 ) return;
|
||||||
if( nOp<1 ) return;
|
if( nOp<1 ) return;
|
||||||
pOp = &p->aOp[nOp-1];
|
pOp = &p->aOp[nOp-1];
|
||||||
if( pOp->opcode==OP_Noop && pOp->p3.p!=0 ){
|
if( pOp->opcode==OP_Noop && pOp->p4.p!=0 ){
|
||||||
int i, j;
|
int i, j;
|
||||||
char z[1000];
|
char z[1000];
|
||||||
sqlite3_snprintf(sizeof(z), z, "%s", pOp->p3.p);
|
sqlite3_snprintf(sizeof(z), z, "%s", pOp->p4.p);
|
||||||
for(i=0; isspace((unsigned char)z[i]); i++){}
|
for(i=0; isspace((unsigned char)z[i]); i++){}
|
||||||
for(j=0; z[i]; i++){
|
for(j=0; z[i]; i++){
|
||||||
if( isspace((unsigned char)z[i]) ){
|
if( isspace((unsigned char)z[i]) ){
|
||||||
@@ -1097,8 +1092,8 @@ void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
|
|||||||
**
|
**
|
||||||
** This call must be made after a call to sqlite3VdbeSetNumCols().
|
** This call must be made after a call to sqlite3VdbeSetNumCols().
|
||||||
**
|
**
|
||||||
** If N==P3_STATIC it means that zName is a pointer to a constant static
|
** If N==P4_STATIC it means that zName is a pointer to a constant static
|
||||||
** string and we can just copy the pointer. If it is P3_DYNAMIC, then
|
** string and we can just copy the pointer. If it is P4_DYNAMIC, then
|
||||||
** the string is freed using sqlite3_free() when the vdbe is finished with
|
** the string is freed using sqlite3_free() when the vdbe is finished with
|
||||||
** it. Otherwise, N bytes of zName are copied.
|
** it. Otherwise, N bytes of zName are copied.
|
||||||
*/
|
*/
|
||||||
@@ -1110,12 +1105,12 @@ int sqlite3VdbeSetColName(Vdbe *p, int idx, int var, const char *zName, int N){
|
|||||||
if( p->db->mallocFailed ) return SQLITE_NOMEM;
|
if( p->db->mallocFailed ) return SQLITE_NOMEM;
|
||||||
assert( p->aColName!=0 );
|
assert( p->aColName!=0 );
|
||||||
pColName = &(p->aColName[idx+var*p->nResColumn]);
|
pColName = &(p->aColName[idx+var*p->nResColumn]);
|
||||||
if( N==P3_DYNAMIC || N==P3_STATIC ){
|
if( N==P4_DYNAMIC || N==P4_STATIC ){
|
||||||
rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, SQLITE_STATIC);
|
rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, SQLITE_STATIC);
|
||||||
}else{
|
}else{
|
||||||
rc = sqlite3VdbeMemSetStr(pColName, zName, N, SQLITE_UTF8,SQLITE_TRANSIENT);
|
rc = sqlite3VdbeMemSetStr(pColName, zName, N, SQLITE_UTF8,SQLITE_TRANSIENT);
|
||||||
}
|
}
|
||||||
if( rc==SQLITE_OK && N==P3_DYNAMIC ){
|
if( rc==SQLITE_OK && N==P4_DYNAMIC ){
|
||||||
pColName->flags = (pColName->flags&(~MEM_Static))|MEM_Dyn;
|
pColName->flags = (pColName->flags&(~MEM_Static))|MEM_Dyn;
|
||||||
pColName->xDel = 0;
|
pColName->xDel = 0;
|
||||||
}
|
}
|
||||||
@@ -1728,7 +1723,7 @@ void sqlite3VdbeDelete(Vdbe *p){
|
|||||||
if( p->aOp ){
|
if( p->aOp ){
|
||||||
Op *pOp = p->aOp;
|
Op *pOp = p->aOp;
|
||||||
for(i=0; i<p->nOp; i++, pOp++){
|
for(i=0; i<p->nOp; i++, pOp++){
|
||||||
freeP3(pOp->p3type, pOp->p3.p);
|
freeP4(pOp->p4type, pOp->p4.p);
|
||||||
#ifdef SQLITE_DEBUG
|
#ifdef SQLITE_DEBUG
|
||||||
sqlite3_free(pOp->zComment);
|
sqlite3_free(pOp->zComment);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** This file contains code used to help implement virtual tables.
|
** This file contains code used to help implement virtual tables.
|
||||||
**
|
**
|
||||||
** $Id: vtab.c,v 1.59 2007/09/20 11:32:18 rse Exp $
|
** $Id: vtab.c,v 1.60 2008/01/03 00:01:25 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
@@ -278,10 +278,11 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
|
|||||||
v = sqlite3GetVdbe(pParse);
|
v = sqlite3GetVdbe(pParse);
|
||||||
sqlite3ChangeCookie(db, v, iDb);
|
sqlite3ChangeCookie(db, v, iDb);
|
||||||
|
|
||||||
sqlite3VdbeAddOp(v, OP_Expire, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Expire, 0, 0);
|
||||||
zWhere = sqlite3MPrintf(db, "name='%q'", pTab->zName);
|
zWhere = sqlite3MPrintf(db, "name='%q'", pTab->zName);
|
||||||
sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 1, zWhere, P3_DYNAMIC);
|
sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 1, 0, zWhere, P4_DYNAMIC);
|
||||||
sqlite3VdbeOp3(v, OP_VCreate, iDb, 0, pTab->zName, strlen(pTab->zName) + 1);
|
sqlite3VdbeAddOp4(v, OP_VCreate, iDb, 0, 0,
|
||||||
|
pTab->zName, strlen(pTab->zName) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we are rereading the sqlite_master table create the in-memory
|
/* If we are rereading the sqlite_master table create the in-memory
|
||||||
|
131
src/where.c
131
src/where.c
@@ -16,7 +16,7 @@
|
|||||||
** so is applicable. Because this module is responsible for selecting
|
** so is applicable. Because this module is responsible for selecting
|
||||||
** indices, you might also think of this module as the "query optimizer".
|
** indices, you might also think of this module as the "query optimizer".
|
||||||
**
|
**
|
||||||
** $Id: where.c,v 1.267 2008/01/02 00:34:37 drh Exp $
|
** $Id: where.c,v 1.268 2008/01/03 00:01:26 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -1707,7 +1707,7 @@ static void buildIndexProbe(
|
|||||||
int nColumn, /* The number of columns to check for NULL */
|
int nColumn, /* The number of columns to check for NULL */
|
||||||
Index *pIdx /* Index that we will be searching */
|
Index *pIdx /* Index that we will be searching */
|
||||||
){
|
){
|
||||||
sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
|
sqlite3VdbeAddOp2(v, OP_MakeRecord, nColumn, 0);
|
||||||
sqlite3IndexAffinityStr(v, pIdx);
|
sqlite3IndexAffinityStr(v, pIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1733,7 +1733,7 @@ static void codeEqualityTerm(
|
|||||||
if( pX->op==TK_EQ ){
|
if( pX->op==TK_EQ ){
|
||||||
sqlite3ExprCode(pParse, pX->pRight);
|
sqlite3ExprCode(pParse, pX->pRight);
|
||||||
}else if( pX->op==TK_ISNULL ){
|
}else if( pX->op==TK_ISNULL ){
|
||||||
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Null, 0, 0);
|
||||||
#ifndef SQLITE_OMIT_SUBQUERY
|
#ifndef SQLITE_OMIT_SUBQUERY
|
||||||
}else{
|
}else{
|
||||||
int eType;
|
int eType;
|
||||||
@@ -1743,7 +1743,7 @@ static void codeEqualityTerm(
|
|||||||
assert( pX->op==TK_IN );
|
assert( pX->op==TK_IN );
|
||||||
eType = sqlite3FindInIndex(pParse, pX, 1);
|
eType = sqlite3FindInIndex(pParse, pX, 1);
|
||||||
iTab = pX->iTable;
|
iTab = pX->iTable;
|
||||||
sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0);
|
sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
|
||||||
VdbeComment((v, "%.*s", pX->span.n, pX->span.z));
|
VdbeComment((v, "%.*s", pX->span.n, pX->span.z));
|
||||||
if( pLevel->nIn==0 ){
|
if( pLevel->nIn==0 ){
|
||||||
pLevel->nxt = sqlite3VdbeMakeLabel(v);
|
pLevel->nxt = sqlite3VdbeMakeLabel(v);
|
||||||
@@ -1756,8 +1756,8 @@ static void codeEqualityTerm(
|
|||||||
int op = ((eType==IN_INDEX_ROWID)?OP_Rowid:OP_Column);
|
int op = ((eType==IN_INDEX_ROWID)?OP_Rowid:OP_Column);
|
||||||
pIn += pLevel->nIn - 1;
|
pIn += pLevel->nIn - 1;
|
||||||
pIn->iCur = iTab;
|
pIn->iCur = iTab;
|
||||||
pIn->topAddr = sqlite3VdbeAddOp(v, op, iTab, 0);
|
pIn->topAddr = sqlite3VdbeAddOp2(v, op, iTab, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_IsNull, -1, 0);
|
sqlite3VdbeAddOp2(v, OP_IsNull, -1, 0);
|
||||||
}else{
|
}else{
|
||||||
pLevel->nIn = 0;
|
pLevel->nIn = 0;
|
||||||
}
|
}
|
||||||
@@ -1824,10 +1824,10 @@ static void codeAllEqualityTerms(
|
|||||||
assert( (pTerm->flags & TERM_CODED)==0 );
|
assert( (pTerm->flags & TERM_CODED)==0 );
|
||||||
codeEqualityTerm(pParse, pTerm, pLevel);
|
codeEqualityTerm(pParse, pTerm, pLevel);
|
||||||
if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){
|
if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){
|
||||||
sqlite3VdbeAddOp(v, OP_IsNull, termsInMem ? -1 : -(j+1), pLevel->brk);
|
sqlite3VdbeAddOp2(v, OP_IsNull, termsInMem ? -1 : -(j+1), pLevel->brk);
|
||||||
}
|
}
|
||||||
if( termsInMem ){
|
if( termsInMem ){
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem+j+1, 1);
|
sqlite3VdbeAddOp2(v, OP_MemStore, pLevel->iMem+j+1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1835,7 +1835,7 @@ static void codeAllEqualityTerms(
|
|||||||
*/
|
*/
|
||||||
if( termsInMem ){
|
if( termsInMem ){
|
||||||
for(j=0; j<nEq; j++){
|
for(j=0; j<nEq; j++){
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem+j+1, 0);
|
sqlite3VdbeAddOp2(v, OP_MemLoad, pLevel->iMem+j+1, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2182,7 +2182,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
if( pLevel->flags & WHERE_ORDERBY ){
|
if( pLevel->flags & WHERE_ORDERBY ){
|
||||||
zMsg = sqlite3MPrintf(db, "%z ORDER BY", zMsg);
|
zMsg = sqlite3MPrintf(db, "%z ORDER BY", zMsg);
|
||||||
}
|
}
|
||||||
sqlite3VdbeOp3(v, OP_Explain, i, pLevel->iFrom, zMsg, P3_DYNAMIC);
|
sqlite3VdbeAddOp4(v, OP_Explain, i, pLevel->iFrom, 0, zMsg, P4_DYNAMIC);
|
||||||
}
|
}
|
||||||
#endif /* SQLITE_OMIT_EXPLAIN */
|
#endif /* SQLITE_OMIT_EXPLAIN */
|
||||||
pTabItem = &pTabList->a[pLevel->iFrom];
|
pTabItem = &pTabList->a[pLevel->iFrom];
|
||||||
@@ -2192,7 +2192,8 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
if( pLevel->pBestIdx ){
|
if( pLevel->pBestIdx ){
|
||||||
int iCur = pTabItem->iCursor;
|
int iCur = pTabItem->iCursor;
|
||||||
sqlite3VdbeOp3(v, OP_VOpen, iCur, 0, (const char*)pTab->pVtab, P3_VTAB);
|
sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0,
|
||||||
|
(const char*)pTab->pVtab, P4_VTAB);
|
||||||
}else
|
}else
|
||||||
#endif
|
#endif
|
||||||
if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){
|
if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){
|
||||||
@@ -2211,11 +2212,11 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
if( (pIx = pLevel->pIdx)!=0 ){
|
if( (pIx = pLevel->pIdx)!=0 ){
|
||||||
KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx);
|
KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx);
|
||||||
assert( pIx->pSchema==pTab->pSchema );
|
assert( pIx->pSchema==pTab->pSchema );
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, iDb, 0);
|
||||||
VdbeComment((v, "%s", pIx->zName));
|
VdbeComment((v, "%s", pIx->zName));
|
||||||
sqlite3VdbeOp3(v, OP_OpenRead, iIdxCur, pIx->tnum,
|
sqlite3VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIx->tnum, 0,
|
||||||
(char*)pKey, P3_KEYINFO_HANDOFF);
|
(char*)pKey, P4_KEYINFO_HANDOFF);
|
||||||
sqlite3VdbeAddOp(v, OP_SetNumColumns, iIdxCur, pIx->nColumn+1);
|
sqlite3VdbeAddOp2(v, OP_SetNumColumns, iIdxCur, pIx->nColumn+1);
|
||||||
}
|
}
|
||||||
sqlite3CodeVerifySchema(pParse, iDb);
|
sqlite3CodeVerifySchema(pParse, iDb);
|
||||||
}
|
}
|
||||||
@@ -2262,7 +2263,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
if( pLevel->iFrom>0 && (pTabItem[0].jointype & JT_LEFT)!=0 ){
|
if( pLevel->iFrom>0 && (pTabItem[0].jointype & JT_LEFT)!=0 ){
|
||||||
if( !pParse->nMem ) pParse->nMem++;
|
if( !pParse->nMem ) pParse->nMem++;
|
||||||
pLevel->iLeftJoin = pParse->nMem++;
|
pLevel->iLeftJoin = pParse->nMem++;
|
||||||
sqlite3VdbeAddOp(v, OP_MemInt, 0, pLevel->iLeftJoin);
|
sqlite3VdbeAddOp2(v, OP_MemInt, 0, pLevel->iLeftJoin);
|
||||||
VdbeComment((v, "init LEFT JOIN no-match flag"));
|
VdbeComment((v, "init LEFT JOIN no-match flag"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2290,10 +2291,10 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
}
|
}
|
||||||
if( k==nConstraint ) break;
|
if( k==nConstraint ) break;
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, j-1, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, j-1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, pBestIdx->idxNum, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, pBestIdx->idxNum, 0);
|
||||||
sqlite3VdbeOp3(v, OP_VFilter, iCur, brk, pBestIdx->idxStr,
|
sqlite3VdbeAddOp4(v, OP_VFilter, iCur, brk, 0, pBestIdx->idxStr,
|
||||||
pBestIdx->needToFreeIdxStr ? P3_MPRINTF : P3_STATIC);
|
pBestIdx->needToFreeIdxStr ? P4_MPRINTF : P4_STATIC);
|
||||||
pBestIdx->needToFreeIdxStr = 0;
|
pBestIdx->needToFreeIdxStr = 0;
|
||||||
for(j=0; j<pBestIdx->nConstraint; j++){
|
for(j=0; j<pBestIdx->nConstraint; j++){
|
||||||
if( aUsage[j].omit ){
|
if( aUsage[j].omit ){
|
||||||
@@ -2320,8 +2321,8 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
assert( omitTable==0 );
|
assert( omitTable==0 );
|
||||||
codeEqualityTerm(pParse, pTerm, pLevel);
|
codeEqualityTerm(pParse, pTerm, pLevel);
|
||||||
nxt = pLevel->nxt;
|
nxt = pLevel->nxt;
|
||||||
sqlite3VdbeAddOp(v, OP_MustBeInt, 1, nxt);
|
sqlite3VdbeAddOp2(v, OP_MustBeInt, 1, nxt);
|
||||||
sqlite3VdbeAddOp(v, OP_NotExists, iCur, nxt);
|
sqlite3VdbeAddOp2(v, OP_NotExists, iCur, nxt);
|
||||||
VdbeComment((v, "pk"));
|
VdbeComment((v, "pk"));
|
||||||
pLevel->op = OP_Noop;
|
pLevel->op = OP_Noop;
|
||||||
}else if( pLevel->flags & WHERE_ROWID_RANGE ){
|
}else if( pLevel->flags & WHERE_ROWID_RANGE ){
|
||||||
@@ -2345,12 +2346,12 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
assert( pX!=0 );
|
assert( pX!=0 );
|
||||||
assert( pStart->leftCursor==iCur );
|
assert( pStart->leftCursor==iCur );
|
||||||
sqlite3ExprCode(pParse, pX->pRight);
|
sqlite3ExprCode(pParse, pX->pRight);
|
||||||
sqlite3VdbeAddOp(v, OP_ForceInt, pX->op==TK_LE || pX->op==TK_GT, brk);
|
sqlite3VdbeAddOp2(v, OP_ForceInt, pX->op==TK_LE || pX->op==TK_GT, brk);
|
||||||
sqlite3VdbeAddOp(v, bRev ? OP_MoveLt : OP_MoveGe, iCur, brk);
|
sqlite3VdbeAddOp2(v, bRev ? OP_MoveLt : OP_MoveGe, iCur, brk);
|
||||||
VdbeComment((v, "pk"));
|
VdbeComment((v, "pk"));
|
||||||
disableTerm(pLevel, pStart);
|
disableTerm(pLevel, pStart);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, bRev ? OP_Last : OP_Rewind, iCur, brk);
|
sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, brk);
|
||||||
}
|
}
|
||||||
if( pEnd ){
|
if( pEnd ){
|
||||||
Expr *pX;
|
Expr *pX;
|
||||||
@@ -2359,7 +2360,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
assert( pEnd->leftCursor==iCur );
|
assert( pEnd->leftCursor==iCur );
|
||||||
sqlite3ExprCode(pParse, pX->pRight);
|
sqlite3ExprCode(pParse, pX->pRight);
|
||||||
pLevel->iMem = pParse->nMem++;
|
pLevel->iMem = pParse->nMem++;
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
|
sqlite3VdbeAddOp2(v, OP_MemStore, pLevel->iMem, 1);
|
||||||
if( pX->op==TK_LT || pX->op==TK_GT ){
|
if( pX->op==TK_LT || pX->op==TK_GT ){
|
||||||
testOp = bRev ? OP_Le : OP_Ge;
|
testOp = bRev ? OP_Le : OP_Ge;
|
||||||
}else{
|
}else{
|
||||||
@@ -2372,9 +2373,9 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
pLevel->p1 = iCur;
|
pLevel->p1 = iCur;
|
||||||
pLevel->p2 = start;
|
pLevel->p2 = start;
|
||||||
if( testOp!=OP_Noop ){
|
if( testOp!=OP_Noop ){
|
||||||
sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
|
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
|
sqlite3VdbeAddOp2(v, OP_MemLoad, pLevel->iMem, 0);
|
||||||
sqlite3VdbeAddOp(v, testOp, SQLITE_AFF_NUMERIC|0x100, brk);
|
sqlite3VdbeAddOp2(v, testOp, SQLITE_AFF_NUMERIC|0x100, brk);
|
||||||
}
|
}
|
||||||
}else if( pLevel->flags & WHERE_COLUMN_RANGE ){
|
}else if( pLevel->flags & WHERE_COLUMN_RANGE ){
|
||||||
/* Case 3: The WHERE clause term that refers to the right-most
|
/* Case 3: The WHERE clause term that refers to the right-most
|
||||||
@@ -2407,7 +2408,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
** start key.
|
** start key.
|
||||||
*/
|
*/
|
||||||
for(j=0; j<nEq; j++){
|
for(j=0; j<nEq; j++){
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, nEq-1, 0);
|
sqlite3VdbeAddOp2(v, OP_Dup, nEq-1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Figure out what comparison operators to use for top and bottom
|
/* Figure out what comparison operators to use for top and bottom
|
||||||
@@ -2440,7 +2441,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
pX = pTerm->pExpr;
|
pX = pTerm->pExpr;
|
||||||
assert( (pTerm->flags & TERM_CODED)==0 );
|
assert( (pTerm->flags & TERM_CODED)==0 );
|
||||||
sqlite3ExprCode(pParse, pX->pRight);
|
sqlite3ExprCode(pParse, pX->pRight);
|
||||||
sqlite3VdbeAddOp(v, OP_IsNull, -(nEq*2+1), nxt);
|
sqlite3VdbeAddOp2(v, OP_IsNull, -(nEq*2+1), nxt);
|
||||||
topEq = pTerm->eOperator & (WO_LE|WO_GE);
|
topEq = pTerm->eOperator & (WO_LE|WO_GE);
|
||||||
disableTerm(pLevel, pTerm);
|
disableTerm(pLevel, pTerm);
|
||||||
testOp = OP_IdxGE;
|
testOp = OP_IdxGE;
|
||||||
@@ -2454,12 +2455,12 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
buildIndexProbe(v, nCol, pIdx);
|
buildIndexProbe(v, nCol, pIdx);
|
||||||
if( bRev ){
|
if( bRev ){
|
||||||
int op = topEq ? OP_MoveLe : OP_MoveLt;
|
int op = topEq ? OP_MoveLe : OP_MoveLt;
|
||||||
sqlite3VdbeAddOp(v, op, iIdxCur, nxt);
|
sqlite3VdbeAddOp2(v, op, iIdxCur, nxt);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
|
sqlite3VdbeAddOp2(v, OP_MemStore, pLevel->iMem, 1);
|
||||||
}
|
}
|
||||||
}else if( bRev ){
|
}else if( bRev ){
|
||||||
sqlite3VdbeAddOp(v, OP_Last, iIdxCur, brk);
|
sqlite3VdbeAddOp2(v, OP_Last, iIdxCur, brk);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate the start key. This is the key that defines the lower
|
/* Generate the start key. This is the key that defines the lower
|
||||||
@@ -2479,7 +2480,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
pX = pTerm->pExpr;
|
pX = pTerm->pExpr;
|
||||||
assert( (pTerm->flags & TERM_CODED)==0 );
|
assert( (pTerm->flags & TERM_CODED)==0 );
|
||||||
sqlite3ExprCode(pParse, pX->pRight);
|
sqlite3ExprCode(pParse, pX->pRight);
|
||||||
sqlite3VdbeAddOp(v, OP_IsNull, -(nEq+1), nxt);
|
sqlite3VdbeAddOp2(v, OP_IsNull, -(nEq+1), nxt);
|
||||||
btmEq = pTerm->eOperator & (WO_LE|WO_GE);
|
btmEq = pTerm->eOperator & (WO_LE|WO_GE);
|
||||||
disableTerm(pLevel, pTerm);
|
disableTerm(pLevel, pTerm);
|
||||||
}else{
|
}else{
|
||||||
@@ -2490,16 +2491,16 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
buildIndexProbe(v, nCol, pIdx);
|
buildIndexProbe(v, nCol, pIdx);
|
||||||
if( bRev ){
|
if( bRev ){
|
||||||
pLevel->iMem = pParse->nMem++;
|
pLevel->iMem = pParse->nMem++;
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
|
sqlite3VdbeAddOp2(v, OP_MemStore, pLevel->iMem, 1);
|
||||||
testOp = OP_IdxLT;
|
testOp = OP_IdxLT;
|
||||||
}else{
|
}else{
|
||||||
int op = btmEq ? OP_MoveGe : OP_MoveGt;
|
int op = btmEq ? OP_MoveGe : OP_MoveGt;
|
||||||
sqlite3VdbeAddOp(v, op, iIdxCur, nxt);
|
sqlite3VdbeAddOp2(v, op, iIdxCur, nxt);
|
||||||
}
|
}
|
||||||
}else if( bRev ){
|
}else if( bRev ){
|
||||||
testOp = OP_Noop;
|
testOp = OP_Noop;
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_Rewind, iIdxCur, brk);
|
sqlite3VdbeAddOp2(v, OP_Rewind, iIdxCur, brk);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate the the top of the loop. If there is a termination
|
/* Generate the the top of the loop. If there is a termination
|
||||||
@@ -2508,19 +2509,19 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
*/
|
*/
|
||||||
start = sqlite3VdbeCurrentAddr(v);
|
start = sqlite3VdbeCurrentAddr(v);
|
||||||
if( testOp!=OP_Noop ){
|
if( testOp!=OP_Noop ){
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
|
sqlite3VdbeAddOp2(v, OP_MemLoad, pLevel->iMem, 0);
|
||||||
sqlite3VdbeAddOp(v, testOp, iIdxCur, nxt);
|
sqlite3VdbeAddOp2(v, testOp, iIdxCur, nxt);
|
||||||
if( (topEq && !bRev) || (!btmEq && bRev) ){
|
if( (topEq && !bRev) || (!btmEq && bRev) ){
|
||||||
sqlite3VdbeChangeP3(v, -1, "+", P3_STATIC);
|
sqlite3VdbeChangeP4(v, -1, "+", P4_STATIC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( topLimit | btmLimit ){
|
if( topLimit | btmLimit ){
|
||||||
sqlite3VdbeAddOp(v, OP_Column, iIdxCur, nEq);
|
sqlite3VdbeAddOp2(v, OP_Column, iIdxCur, nEq);
|
||||||
sqlite3VdbeAddOp(v, OP_IsNull, 1, cont);
|
sqlite3VdbeAddOp2(v, OP_IsNull, 1, cont);
|
||||||
}
|
}
|
||||||
if( !omitTable ){
|
if( !omitTable ){
|
||||||
sqlite3VdbeAddOp(v, OP_IdxRowid, iIdxCur, 0);
|
sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
|
sqlite3VdbeAddOp2(v, OP_MoveGe, iCur, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Record the instruction used to terminate the loop.
|
/* Record the instruction used to terminate the loop.
|
||||||
@@ -2545,7 +2546,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
** the search
|
** the search
|
||||||
*/
|
*/
|
||||||
buildIndexProbe(v, nEq, pIdx);
|
buildIndexProbe(v, nEq, pIdx);
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 0);
|
sqlite3VdbeAddOp2(v, OP_MemStore, pLevel->iMem, 0);
|
||||||
|
|
||||||
/* Generate code (1) to move to the first matching element of the table.
|
/* Generate code (1) to move to the first matching element of the table.
|
||||||
** Then generate code (2) that jumps to "nxt" after the cursor is past
|
** Then generate code (2) that jumps to "nxt" after the cursor is past
|
||||||
@@ -2554,20 +2555,20 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
** iteration of the scan to see if the scan has finished. */
|
** iteration of the scan to see if the scan has finished. */
|
||||||
if( bRev ){
|
if( bRev ){
|
||||||
/* Scan in reverse order */
|
/* Scan in reverse order */
|
||||||
sqlite3VdbeAddOp(v, OP_MoveLe, iIdxCur, nxt);
|
sqlite3VdbeAddOp2(v, OP_MoveLe, iIdxCur, nxt);
|
||||||
start = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
|
start = sqlite3VdbeAddOp2(v, OP_MemLoad, pLevel->iMem, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_IdxLT, iIdxCur, nxt);
|
sqlite3VdbeAddOp2(v, OP_IdxLT, iIdxCur, nxt);
|
||||||
pLevel->op = OP_Prev;
|
pLevel->op = OP_Prev;
|
||||||
}else{
|
}else{
|
||||||
/* Scan in the forward order */
|
/* Scan in the forward order */
|
||||||
sqlite3VdbeAddOp(v, OP_MoveGe, iIdxCur, nxt);
|
sqlite3VdbeAddOp2(v, OP_MoveGe, iIdxCur, nxt);
|
||||||
start = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
|
start = sqlite3VdbeAddOp2(v, OP_MemLoad, pLevel->iMem, 0);
|
||||||
sqlite3VdbeOp3(v, OP_IdxGE, iIdxCur, nxt, "+", P3_STATIC);
|
sqlite3VdbeAddOp4(v, OP_IdxGE, iIdxCur, nxt, 0, "+", P4_STATIC);
|
||||||
pLevel->op = OP_Next;
|
pLevel->op = OP_Next;
|
||||||
}
|
}
|
||||||
if( !omitTable ){
|
if( !omitTable ){
|
||||||
sqlite3VdbeAddOp(v, OP_IdxRowid, iIdxCur, 0);
|
sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
|
sqlite3VdbeAddOp2(v, OP_MoveGe, iCur, 0);
|
||||||
}
|
}
|
||||||
pLevel->p1 = iIdxCur;
|
pLevel->p1 = iIdxCur;
|
||||||
pLevel->p2 = start;
|
pLevel->p2 = start;
|
||||||
@@ -2579,10 +2580,10 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
assert( bRev==0 );
|
assert( bRev==0 );
|
||||||
pLevel->op = OP_Next;
|
pLevel->op = OP_Next;
|
||||||
pLevel->p1 = iCur;
|
pLevel->p1 = iCur;
|
||||||
pLevel->p2 = 1 + sqlite3VdbeAddOp(v, OP_Rewind, iCur, brk);
|
pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, OP_Rewind, iCur, brk);
|
||||||
}
|
}
|
||||||
notReady &= ~getMask(&maskSet, iCur);
|
notReady &= ~getMask(&maskSet, iCur);
|
||||||
sqlite3VdbeAddOp(v, OP_StackDepth, -1, 0);
|
sqlite3VdbeAddOp2(v, OP_StackDepth, -1, 0);
|
||||||
|
|
||||||
/* Insert code to test every subexpression that can be completely
|
/* Insert code to test every subexpression that can be completely
|
||||||
** computed using the current set of tables.
|
** computed using the current set of tables.
|
||||||
@@ -2605,7 +2606,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
*/
|
*/
|
||||||
if( pLevel->iLeftJoin ){
|
if( pLevel->iLeftJoin ){
|
||||||
pLevel->top = sqlite3VdbeCurrentAddr(v);
|
pLevel->top = sqlite3VdbeCurrentAddr(v);
|
||||||
sqlite3VdbeAddOp(v, OP_MemInt, 1, pLevel->iLeftJoin);
|
sqlite3VdbeAddOp2(v, OP_MemInt, 1, pLevel->iLeftJoin);
|
||||||
VdbeComment((v, "record LEFT JOIN hit"));
|
VdbeComment((v, "record LEFT JOIN hit"));
|
||||||
for(pTerm=wc.a, j=0; j<wc.nTerm; j++, pTerm++){
|
for(pTerm=wc.a, j=0; j<wc.nTerm; j++, pTerm++){
|
||||||
if( pTerm->flags & (TERM_VIRTUAL|TERM_CODED) ) continue;
|
if( pTerm->flags & (TERM_VIRTUAL|TERM_CODED) ) continue;
|
||||||
@@ -2694,7 +2695,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
|||||||
pLevel = &pWInfo->a[i];
|
pLevel = &pWInfo->a[i];
|
||||||
sqlite3VdbeResolveLabel(v, pLevel->cont);
|
sqlite3VdbeResolveLabel(v, pLevel->cont);
|
||||||
if( pLevel->op!=OP_Noop ){
|
if( pLevel->op!=OP_Noop ){
|
||||||
sqlite3VdbeAddOp(v, pLevel->op, pLevel->p1, pLevel->p2);
|
sqlite3VdbeAddOp2(v, pLevel->op, pLevel->p1, pLevel->p2);
|
||||||
}
|
}
|
||||||
if( pLevel->nIn ){
|
if( pLevel->nIn ){
|
||||||
struct InLoop *pIn;
|
struct InLoop *pIn;
|
||||||
@@ -2702,7 +2703,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
|||||||
sqlite3VdbeResolveLabel(v, pLevel->nxt);
|
sqlite3VdbeResolveLabel(v, pLevel->nxt);
|
||||||
for(j=pLevel->nIn, pIn=&pLevel->aInLoop[j-1]; j>0; j--, pIn--){
|
for(j=pLevel->nIn, pIn=&pLevel->aInLoop[j-1]; j>0; j--, pIn--){
|
||||||
sqlite3VdbeJumpHere(v, pIn->topAddr+1);
|
sqlite3VdbeJumpHere(v, pIn->topAddr+1);
|
||||||
sqlite3VdbeAddOp(v, OP_Next, pIn->iCur, pIn->topAddr);
|
sqlite3VdbeAddOp2(v, OP_Next, pIn->iCur, pIn->topAddr);
|
||||||
sqlite3VdbeJumpHere(v, pIn->topAddr-1);
|
sqlite3VdbeJumpHere(v, pIn->topAddr-1);
|
||||||
}
|
}
|
||||||
sqlite3_free(pLevel->aInLoop);
|
sqlite3_free(pLevel->aInLoop);
|
||||||
@@ -2710,12 +2711,12 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
|||||||
sqlite3VdbeResolveLabel(v, pLevel->brk);
|
sqlite3VdbeResolveLabel(v, pLevel->brk);
|
||||||
if( pLevel->iLeftJoin ){
|
if( pLevel->iLeftJoin ){
|
||||||
int addr;
|
int addr;
|
||||||
addr = sqlite3VdbeAddOp(v, OP_IfMemPos, pLevel->iLeftJoin, 0);
|
addr = sqlite3VdbeAddOp2(v, OP_IfMemPos, pLevel->iLeftJoin, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_NullRow, pTabList->a[i].iCursor, 0);
|
sqlite3VdbeAddOp2(v, OP_NullRow, pTabList->a[i].iCursor, 0);
|
||||||
if( pLevel->iIdxCur>=0 ){
|
if( pLevel->iIdxCur>=0 ){
|
||||||
sqlite3VdbeAddOp(v, OP_NullRow, pLevel->iIdxCur, 0);
|
sqlite3VdbeAddOp2(v, OP_NullRow, pLevel->iIdxCur, 0);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, pLevel->top);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->top);
|
||||||
sqlite3VdbeJumpHere(v, addr);
|
sqlite3VdbeJumpHere(v, addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2733,10 +2734,10 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
|||||||
assert( pTab!=0 );
|
assert( pTab!=0 );
|
||||||
if( pTab->isEphem || pTab->pSelect ) continue;
|
if( pTab->isEphem || pTab->pSelect ) continue;
|
||||||
if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){
|
if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){
|
||||||
sqlite3VdbeAddOp(v, OP_Close, pTabItem->iCursor, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, pTabItem->iCursor, 0);
|
||||||
}
|
}
|
||||||
if( pLevel->pIdx!=0 ){
|
if( pLevel->pIdx!=0 ){
|
||||||
sqlite3VdbeAddOp(v, OP_Close, pLevel->iIdxCur, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, pLevel->iIdxCur, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this scan uses an index, make code substitutions to read data
|
/* If this scan uses an index, make code substitutions to read data
|
||||||
|
Reference in New Issue
Block a user