mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Update older opcode names to be more meaningful in light of the latest
code design. (CVS 2506) FossilOrigin-Name: 36f2da1f8d8d434f861ecad55c9d86549751c954
This commit is contained in:
38
manifest
38
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Elminiate\sa\sVM\sopcode\sthat\swas\sno\slonger\sneeded.\s(CVS\s2505)
|
C Update\solder\sopcode\snames\sto\sbe\smore\smeaningful\sin\slight\sof\sthe\slatest\ncode\sdesign.\s(CVS\s2506)
|
||||||
D 2005-06-12T12:01:19
|
D 2005-06-12T21:35:52
|
||||||
F Makefile.in 8129e7f261d405db783676f9ca31e0841768c652
|
F Makefile.in 8129e7f261d405db783676f9ca31e0841768c652
|
||||||
F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7
|
F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7
|
||||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||||
@@ -32,16 +32,16 @@ F src/attach.c 3615dbe960cbee4aa5ea300b8a213dad36527b0f
|
|||||||
F src/auth.c 18c5a0befe20f3a58a41e3ddd78f372faeeefe1f
|
F src/auth.c 18c5a0befe20f3a58a41e3ddd78f372faeeefe1f
|
||||||
F src/btree.c d2e09ebf755bfd665727133361b22c6a915b12d7
|
F src/btree.c d2e09ebf755bfd665727133361b22c6a915b12d7
|
||||||
F src/btree.h 41a71ce027db9ddee72cb43df2316bbe3a1d92af
|
F src/btree.h 41a71ce027db9ddee72cb43df2316bbe3a1d92af
|
||||||
F src/build.c 407343b7dac62f7ea44f166943708f6557906ae1
|
F src/build.c 593d8fda0576a72e6f1fbf8f1a61db110dde9264
|
||||||
F src/callback.c 0910b611e0c158f107ee3ff86f8a371654971e2b
|
F src/callback.c 0910b611e0c158f107ee3ff86f8a371654971e2b
|
||||||
F src/date.c 2134ef4388256e8247405178df8a61bd60dc180a
|
F src/date.c 2134ef4388256e8247405178df8a61bd60dc180a
|
||||||
F src/delete.c 811f90d1c5950e57f985fc9d207d7eee1800096e
|
F src/delete.c 4b68127f55971c7fb459146e0b6cf3bd70cfffe9
|
||||||
F src/experimental.c 50c1e3b34f752f4ac10c36f287db095c2b61766d
|
F src/experimental.c 50c1e3b34f752f4ac10c36f287db095c2b61766d
|
||||||
F src/expr.c e7245e9c3b1f890221cf5e7472c1aa1fed30d7ab
|
F src/expr.c 6d7058944c5f4b7e4304be3fe63ada91dac221a1
|
||||||
F src/func.c f208d71f741d47b63277530939f552815af8ce35
|
F src/func.c f208d71f741d47b63277530939f552815af8ce35
|
||||||
F src/hash.c 2b1b13f7400e179631c83a1be0c664608c8f021f
|
F src/hash.c 2b1b13f7400e179631c83a1be0c664608c8f021f
|
||||||
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
|
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
|
||||||
F src/insert.c 34c25c33f51a43644a42cc091ac967b070c6b6d5
|
F src/insert.c 8c0868a975fe37366ed92e1b976853be96284607
|
||||||
F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b
|
F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b
|
||||||
F src/main.c f61bdb0a1afeb2eff7285f4f3752e1085ecc55ed
|
F src/main.c f61bdb0a1afeb2eff7285f4f3752e1085ecc55ed
|
||||||
F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
|
F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
|
||||||
@@ -56,14 +56,14 @@ F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
|||||||
F src/pager.c 841a2cdddd4275de36cda26ed9dc54ae942660ce
|
F src/pager.c 841a2cdddd4275de36cda26ed9dc54ae942660ce
|
||||||
F src/pager.h 0d9153d6269d60d04af3dd84a0cc0a96253cf4a4
|
F src/pager.h 0d9153d6269d60d04af3dd84a0cc0a96253cf4a4
|
||||||
F src/parse.y 72cd7553f05fbc7b63ea9476108d0da6237f2818
|
F src/parse.y 72cd7553f05fbc7b63ea9476108d0da6237f2818
|
||||||
F src/pragma.c 344e50166437194c21332ada036671a3ac95652c
|
F src/pragma.c 5ea2ba0e43f6a83968a936b071b77bd4516d11f0
|
||||||
F src/prepare.c d53602d2f8e097225ae7c76ec764ae68f759ba47
|
F src/prepare.c d53602d2f8e097225ae7c76ec764ae68f759ba47
|
||||||
F src/printf.c 3d20b21cfecadacecac3fb7274e746cb81d3d357
|
F src/printf.c 3d20b21cfecadacecac3fb7274e746cb81d3d357
|
||||||
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
|
F src/random.c 90adff4e73a3b249eb4f1fc2a6ff9cf78c7233a4
|
||||||
F src/select.c 266416bb8af3827dd925f12646db8d59e2fe02ac
|
F src/select.c 28b752e58955c7920711fbdbfdcd369a2bd09448
|
||||||
F src/shell.c 25b3217d7c64e6497225439d261a253a23efff26
|
F src/shell.c 25b3217d7c64e6497225439d261a253a23efff26
|
||||||
F src/sqlite.h.in f28f5b018f03a66aaf0bc1ab6985d8605d6b964f
|
F src/sqlite.h.in f28f5b018f03a66aaf0bc1ab6985d8605d6b964f
|
||||||
F src/sqliteInt.h 42b464cd380dd81bf7873476fc5974985a506d71
|
F src/sqliteInt.h c620e07e0c7e6e09d8623d165427f0f1f659aad5
|
||||||
F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9
|
F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9
|
||||||
F src/tclsqlite.c af0f002d9d6ab4f7f32b9bee5b57665946e76ad9
|
F src/tclsqlite.c af0f002d9d6ab4f7f32b9bee5b57665946e76ad9
|
||||||
F src/test1.c 1ab9e62dd51a999ea1842f0bc8ae677d5ca04861
|
F src/test1.c 1ab9e62dd51a999ea1842f0bc8ae677d5ca04861
|
||||||
@@ -72,18 +72,18 @@ F src/test3.c 683e1e3819152ffd35da2f201e507228921148d0
|
|||||||
F src/test4.c 7c6b9fc33dd1f3f93c7f1ee6e5e6d016afa6c1df
|
F src/test4.c 7c6b9fc33dd1f3f93c7f1ee6e5e6d016afa6c1df
|
||||||
F src/test5.c 64f08b2a50ef371a1bd68ff206829e7b1b9997f5
|
F src/test5.c 64f08b2a50ef371a1bd68ff206829e7b1b9997f5
|
||||||
F src/tokenize.c d89743f2c0d05d49b5b4d6462432a1f3cc4765f1
|
F src/tokenize.c d89743f2c0d05d49b5b4d6462432a1f3cc4765f1
|
||||||
F src/trigger.c 1a6d0c7c51b70bdc58d5068be72034071eff23ad
|
F src/trigger.c f51dec15921629591cb98bf2e350018e268b109a
|
||||||
F src/update.c 04ea9dd784ccfeaf38a681b3edfe3b1c4edfdda7
|
F src/update.c e96c7b342cd8903c672162f4cf84d2c737943347
|
||||||
F src/utf.c bda5eb85039ef16f2d17004c1e18c96e1ab0a80c
|
F src/utf.c bda5eb85039ef16f2d17004c1e18c96e1ab0a80c
|
||||||
F src/util.c 96008b52604d08b9cc57ed37350149d6ac8a1bf3
|
F src/util.c 96008b52604d08b9cc57ed37350149d6ac8a1bf3
|
||||||
F src/vacuum.c 829d9e1a6d7c094b80e0899686670932eafd768c
|
F src/vacuum.c 829d9e1a6d7c094b80e0899686670932eafd768c
|
||||||
F src/vdbe.c 77c53143c329df6a1d5b14cbb3ed61164063c5e4
|
F src/vdbe.c c2511f392598928254504e3b2c5ec47f4fef2b53
|
||||||
F src/vdbe.h 75e466d84d362b0c4498978a9d6b1e6bd32ecf3b
|
F src/vdbe.h 75e466d84d362b0c4498978a9d6b1e6bd32ecf3b
|
||||||
F src/vdbeInt.h 4afaae2f4adcab54ad2a40dabb2e689fba7b1561
|
F src/vdbeInt.h 4312faf41630a6c215924b6c7c2f39ebb1af8ffb
|
||||||
F src/vdbeapi.c 9a9556b9d7e3a052f58de389caf69449558e7380
|
F src/vdbeapi.c 9a9556b9d7e3a052f58de389caf69449558e7380
|
||||||
F src/vdbeaux.c d078d96e47a391666af10fce2fbabb1ace19a4b0
|
F src/vdbeaux.c c99e32abeba4b7522e3922afff2c32ff4bd17eb5
|
||||||
F src/vdbemem.c 48a64ae95a9edc6e8d940300dad15d70d1670398
|
F src/vdbemem.c 48a64ae95a9edc6e8d940300dad15d70d1670398
|
||||||
F src/where.c f02baff03e2a9ed7bdc36b363b8e4024a94de919
|
F src/where.c 3a9a2258ab3364655e9ea215ad5ae7bf41813f54
|
||||||
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
|
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
|
||||||
F test/all.test 7f0988442ab811dfa41793b5b550f5828ce316f3
|
F test/all.test 7f0988442ab811dfa41793b5b550f5828ce316f3
|
||||||
F test/alter.test 9d6837a3d946b73df692b7cef2a7644d2e2f6bc6
|
F test/alter.test 9d6837a3d946b73df692b7cef2a7644d2e2f6bc6
|
||||||
@@ -281,7 +281,7 @@ F www/tclsqlite.tcl 425be741b8ae664f55cb1ef2371aab0a75109cf9
|
|||||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||||
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
|
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
|
||||||
F www/whentouse.tcl 528299b8316726dbcc5548e9aa0648c8b1bd055b
|
F www/whentouse.tcl 528299b8316726dbcc5548e9aa0648c8b1bd055b
|
||||||
P 62a7353d4af4886b1561832e8b36e8e788b38834
|
P 97b348a5ad2f090ba7a75467b97c6dfb575df09c
|
||||||
R 59f3cd1f9900eff80ed20c2925adf396
|
R 8569c8c1f2245087cc1ec4a7869dfa68
|
||||||
U drh
|
U drh
|
||||||
Z 09f39e38571ac1460392187d00e1cd29
|
Z 08316380432fe4e2f32db98927281007
|
||||||
|
@@ -1 +1 @@
|
|||||||
97b348a5ad2f090ba7a75467b97c6dfb575df09c
|
36f2da1f8d8d434f861ecad55c9d86549751c954
|
10
src/build.c
10
src/build.c
@@ -22,7 +22,7 @@
|
|||||||
** COMMIT
|
** COMMIT
|
||||||
** ROLLBACK
|
** ROLLBACK
|
||||||
**
|
**
|
||||||
** $Id: build.c,v 1.325 2005/06/06 21:19:57 drh Exp $
|
** $Id: build.c,v 1.326 2005/06/12 21:35:52 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -791,10 +791,10 @@ void sqlite3StartTable(
|
|||||||
sqlite3VdbeAddOp(v, OP_CreateTable, iDb, 0);
|
sqlite3VdbeAddOp(v, OP_CreateTable, iDb, 0);
|
||||||
}
|
}
|
||||||
sqlite3OpenMasterTable(v, iDb);
|
sqlite3OpenMasterTable(v, iDb);
|
||||||
sqlite3VdbeAddOp(v, OP_NewRecno, 0, 0);
|
sqlite3VdbeAddOp(v, OP_NewRowid, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
|
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_String8, 0, 0);
|
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0);
|
sqlite3VdbeAddOp(v, OP_Insert, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, 0, 0);
|
sqlite3VdbeAddOp(v, OP_Close, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
|
sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
|
||||||
}
|
}
|
||||||
@@ -2008,7 +2008,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
|
|||||||
addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0);
|
addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0);
|
||||||
sqlite3GenerateIndexKey(v, pIndex, iTab);
|
sqlite3GenerateIndexKey(v, pIndex, iTab);
|
||||||
isUnique = pIndex->onError!=OE_None;
|
isUnique = pIndex->onError!=OE_None;
|
||||||
sqlite3VdbeAddOp(v, OP_IdxPut, iIdx, isUnique);
|
sqlite3VdbeAddOp(v, OP_IdxInsert, iIdx, isUnique);
|
||||||
if( isUnique ){
|
if( isUnique ){
|
||||||
sqlite3VdbeChangeP3(v, -1, "indexed columns are not unique", P3_STATIC);
|
sqlite3VdbeChangeP3(v, -1, "indexed columns are not unique", P3_STATIC);
|
||||||
}
|
}
|
||||||
|
10
src/delete.c
10
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.105 2005/06/06 21:19:57 drh Exp $
|
** $Id: delete.c,v 1.106 2005/06/12 21:35:52 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -239,7 +239,7 @@ void sqlite3DeleteFrom(
|
|||||||
|
|
||||||
/* Remember the rowid of every item to be deleted.
|
/* Remember the rowid of every item to be deleted.
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
|
sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_ListWrite, 0, 0);
|
sqlite3VdbeAddOp(v, OP_ListWrite, 0, 0);
|
||||||
if( db->flags & SQLITE_CountRows ){
|
if( db->flags & SQLITE_CountRows ){
|
||||||
sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
|
sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
|
||||||
@@ -273,9 +273,9 @@ void sqlite3DeleteFrom(
|
|||||||
sqlite3OpenTableForReading(v, iCur, pTab);
|
sqlite3OpenTableForReading(v, iCur, pTab);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
|
sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
|
sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
|
sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_PutIntKey, oldIdx, 0);
|
sqlite3VdbeAddOp(v, OP_Insert, oldIdx, 0);
|
||||||
if( !isView ){
|
if( !isView ){
|
||||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
||||||
}
|
}
|
||||||
@@ -432,7 +432,7 @@ void sqlite3GenerateIndexKey(
|
|||||||
int j;
|
int j;
|
||||||
Table *pTab = pIdx->pTable;
|
Table *pTab = pIdx->pTable;
|
||||||
|
|
||||||
sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
|
sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
|
||||||
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 ){
|
||||||
|
23
src/expr.c
23
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.205 2005/06/06 21:19:57 drh Exp $
|
** $Id: expr.c,v 1.206 2005/06/12 21:35:52 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -138,7 +138,7 @@ int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){
|
|||||||
*/
|
*/
|
||||||
static int binaryCompareP1(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){
|
static int binaryCompareP1(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){
|
||||||
char aff = sqlite3ExprAffinity(pExpr2);
|
char aff = sqlite3ExprAffinity(pExpr2);
|
||||||
return (((int)sqlite3CompareAffinity(pExpr1, aff))<<8)+(jumpIfNull?1:0);
|
return ((int)sqlite3CompareAffinity(pExpr1, aff))+(jumpIfNull?0x100:0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1309,8 +1309,7 @@ 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);
|
sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1);
|
||||||
sqlite3VdbeAddOp(v, OP_String8, 0, 0);
|
sqlite3VdbeAddOp(v, OP_IdxInsert, pExpr->iTable, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_PutStrKey, pExpr->iTable, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3VdbeChangeP3(v, addr, (void *)&keyInfo, P3_KEYINFO);
|
sqlite3VdbeChangeP3(v, addr, (void *)&keyInfo, P3_KEYINFO);
|
||||||
@@ -1382,7 +1381,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
int op;
|
int op;
|
||||||
if( v==0 ) return;
|
if( v==0 ) return;
|
||||||
if( pExpr==0 ){
|
if( pExpr==0 ){
|
||||||
sqlite3VdbeAddOp(v, OP_String8, 0, 0); /* Empty expression evals to NULL */
|
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
op = pExpr->op;
|
op = pExpr->op;
|
||||||
@@ -1394,7 +1393,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
sqlite3VdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn);
|
sqlite3VdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn);
|
||||||
sqlite3ColumnDefault(v, pExpr->pTab, pExpr->iColumn);
|
sqlite3ColumnDefault(v, pExpr->pTab, pExpr->iColumn);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_Recno, pExpr->iTable, 0);
|
sqlite3VdbeAddOp(v, OP_Rowid, pExpr->iTable, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1410,6 +1409,10 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
sqlite3VdbeDequoteP3(v, -1);
|
sqlite3VdbeDequoteP3(v, -1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case TK_NULL: {
|
||||||
|
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
#ifndef SQLITE_OMIT_BLOB_LITERAL
|
#ifndef SQLITE_OMIT_BLOB_LITERAL
|
||||||
case TK_BLOB: {
|
case TK_BLOB: {
|
||||||
assert( TK_BLOB==OP_HexBlob );
|
assert( TK_BLOB==OP_HexBlob );
|
||||||
@@ -1418,10 +1421,6 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
case TK_NULL: {
|
|
||||||
sqlite3VdbeAddOp(v, OP_String8, 0, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case TK_VARIABLE: {
|
case TK_VARIABLE: {
|
||||||
sqlite3VdbeAddOp(v, OP_Variable, pExpr->iTable, 0);
|
sqlite3VdbeAddOp(v, OP_Variable, pExpr->iTable, 0);
|
||||||
if( pExpr->token.n>1 ){
|
if( pExpr->token.n>1 ){
|
||||||
@@ -1578,7 +1577,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
addr = sqlite3VdbeCurrentAddr(v);
|
addr = sqlite3VdbeCurrentAddr(v);
|
||||||
sqlite3VdbeAddOp(v, OP_NotNull, -1, addr+4); /* addr + 0 */
|
sqlite3VdbeAddOp(v, OP_NotNull, -1, addr+4); /* addr + 0 */
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, 2, 0);
|
sqlite3VdbeAddOp(v, OP_Pop, 2, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_String8, 0, 0);
|
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, addr+7);
|
sqlite3VdbeAddOp(v, OP_Goto, 0, addr+7);
|
||||||
sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1); /* addr + 4 */
|
sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1); /* addr + 4 */
|
||||||
sqlite3VdbeAddOp(v, OP_Found, pExpr->iTable, addr+7);
|
sqlite3VdbeAddOp(v, OP_Found, pExpr->iTable, addr+7);
|
||||||
@@ -1648,7 +1647,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
if( pExpr->pRight ){
|
if( pExpr->pRight ){
|
||||||
sqlite3ExprCode(pParse, pExpr->pRight);
|
sqlite3ExprCode(pParse, pExpr->pRight);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_String8, 0, 0);
|
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
||||||
}
|
}
|
||||||
sqlite3VdbeResolveLabel(v, expr_end_label);
|
sqlite3VdbeResolveLabel(v, expr_end_label);
|
||||||
break;
|
break;
|
||||||
|
64
src/insert.c
64
src/insert.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 INSERT statements in SQLite.
|
** to handle INSERT statements in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: insert.c,v 1.138 2005/03/21 01:20:58 drh Exp $
|
** $Id: insert.c,v 1.139 2005/06/12 21:35:52 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -308,7 +308,7 @@ void sqlite3Insert(
|
|||||||
sqlite3VdbeAddOp(v, OP_Column, iCur, 0);
|
sqlite3VdbeAddOp(v, OP_Column, iCur, 0);
|
||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
|
sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Ne, 28417, base+12);
|
sqlite3VdbeAddOp(v, OP_Ne, 28417, base+12);
|
||||||
sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
|
sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, counterRowid, 1);
|
sqlite3VdbeAddOp(v, OP_MemStore, counterRowid, 1);
|
||||||
sqlite3VdbeAddOp(v, OP_Column, iCur, 1);
|
sqlite3VdbeAddOp(v, OP_Column, iCur, 1);
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, counterMem, 1);
|
sqlite3VdbeAddOp(v, OP_MemStore, counterMem, 1);
|
||||||
@@ -363,9 +363,9 @@ void sqlite3Insert(
|
|||||||
sqlite3VdbeResolveLabel(v, iInsertBlock);
|
sqlite3VdbeResolveLabel(v, iInsertBlock);
|
||||||
sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
|
sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
|
||||||
sqlite3TableAffinityStr(v, pTab);
|
sqlite3TableAffinityStr(v, pTab);
|
||||||
sqlite3VdbeAddOp(v, OP_NewRecno, srcTab, 0);
|
sqlite3VdbeAddOp(v, OP_NewRowid, srcTab, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
|
sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_PutIntKey, srcTab, 0);
|
sqlite3VdbeAddOp(v, OP_Insert, srcTab, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Return, 0, 0);
|
sqlite3VdbeAddOp(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
|
||||||
@@ -547,7 +547,7 @@ void sqlite3Insert(
|
|||||||
if( !isView ){
|
if( !isView ){
|
||||||
sqlite3TableAffinityStr(v, pTab);
|
sqlite3TableAffinityStr(v, pTab);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0);
|
sqlite3VdbeAddOp(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,
|
||||||
@@ -565,7 +565,7 @@ void sqlite3Insert(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Push the record number for the new entry onto the stack. The
|
/* Push the record number for the new entry onto the stack. The
|
||||||
** record number is a randomly generate integer created by NewRecno
|
** record number is a randomly generate integer created by NewRowid
|
||||||
** except when the table has an INTEGER PRIMARY KEY column, in which
|
** except when the table has an INTEGER PRIMARY KEY column, in which
|
||||||
** case the record number is the same as that column.
|
** case the record number is the same as that column.
|
||||||
*/
|
*/
|
||||||
@@ -578,15 +578,15 @@ void sqlite3Insert(
|
|||||||
}else{
|
}else{
|
||||||
sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr);
|
sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr);
|
||||||
}
|
}
|
||||||
/* If the PRIMARY KEY expression is NULL, then use OP_NewRecno
|
/* If the PRIMARY KEY expression is NULL, then use OP_NewRowid
|
||||||
** to generate a unique primary key value.
|
** to generate a unique primary key value.
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
|
sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_NewRecno, base, counterMem);
|
sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem);
|
||||||
sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
|
sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_NewRecno, base, counterMem);
|
sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem);
|
||||||
}
|
}
|
||||||
#ifndef SQLITE_OMIT_AUTOINCREMENT
|
#ifndef SQLITE_OMIT_AUTOINCREMENT
|
||||||
if( pTab->autoInc ){
|
if( pTab->autoInc ){
|
||||||
@@ -603,7 +603,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_String8, 0, 0);
|
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if( pColumn==0 ){
|
if( pColumn==0 ){
|
||||||
@@ -690,11 +690,11 @@ void sqlite3Insert(
|
|||||||
sqlite3VdbeAddOp(v, OP_MemLoad, counterRowid, 0);
|
sqlite3VdbeAddOp(v, OP_MemLoad, counterRowid, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_NotNull, -1, base+7);
|
sqlite3VdbeAddOp(v, OP_NotNull, -1, base+7);
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_NewRecno, iCur, 0);
|
sqlite3VdbeAddOp(v, OP_NewRowid, iCur, 0);
|
||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
|
sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, counterMem, 0);
|
sqlite3VdbeAddOp(v, OP_MemLoad, counterMem, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MakeRecord, 2, 0);
|
sqlite3VdbeAddOp(v, OP_MakeRecord, 2, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_PutIntKey, iCur, 0);
|
sqlite3VdbeAddOp(v, OP_Insert, iCur, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -724,11 +724,11 @@ insert_cleanup:
|
|||||||
** When this routine is called, the stack contains (from bottom to top)
|
** When this routine is called, the stack contains (from bottom to top)
|
||||||
** the following values:
|
** the following values:
|
||||||
**
|
**
|
||||||
** 1. The recno of the row to be updated before the update. This
|
** 1. The rowid of the row to be updated before the update. This
|
||||||
** value is omitted unless we are doing an UPDATE that involves a
|
** value is omitted unless we are doing an UPDATE that involves a
|
||||||
** change to the record number.
|
** change to the record number.
|
||||||
**
|
**
|
||||||
** 2. The recno of the row after the update.
|
** 2. The rowid of the row after the update.
|
||||||
**
|
**
|
||||||
** 3. The data in the first column of the entry after the update.
|
** 3. The data in the first column of the entry after the update.
|
||||||
**
|
**
|
||||||
@@ -736,9 +736,9 @@ insert_cleanup:
|
|||||||
**
|
**
|
||||||
** N. The data in the last column of the entry after the update.
|
** N. The data in the last column of the entry after the update.
|
||||||
**
|
**
|
||||||
** The old recno shown as entry (1) above is omitted unless both isUpdate
|
** The old rowid shown as entry (1) above is omitted unless both isUpdate
|
||||||
** and recnoChng are 1. isUpdate is true for UPDATEs and false for
|
** and rowidChng are 1. isUpdate is true for UPDATEs and false for
|
||||||
** INSERTs and recnoChng is true if the record number is being changed.
|
** INSERTs and rowidChng is true if the record number is being changed.
|
||||||
**
|
**
|
||||||
** The code generated by this routine pushes additional entries onto
|
** The code generated by this routine pushes additional entries onto
|
||||||
** the stack which are the keys for new index entries for the new record.
|
** the stack which are the keys for new index entries for the new record.
|
||||||
@@ -802,7 +802,7 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
Table *pTab, /* the table into which we are inserting */
|
Table *pTab, /* the table into which we are inserting */
|
||||||
int base, /* Index of a read/write cursor pointing at pTab */
|
int base, /* Index of a read/write cursor pointing at pTab */
|
||||||
char *aIdxUsed, /* Which indices are used. NULL means all are used */
|
char *aIdxUsed, /* Which indices are used. NULL means all are used */
|
||||||
int recnoChng, /* True if the record number will change */
|
int rowidChng, /* True if the record number will change */
|
||||||
int isUpdate, /* True for UPDATE, False for INSERT */
|
int isUpdate, /* True for UPDATE, False for INSERT */
|
||||||
int overrideError, /* Override onError to this if not OE_Default */
|
int overrideError, /* Override onError to this if not OE_Default */
|
||||||
int ignoreDest /* Jump to this label on an OE_Ignore resolution */
|
int ignoreDest /* Jump to this label on an OE_Ignore resolution */
|
||||||
@@ -818,7 +818,7 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
int seenReplace = 0;
|
int seenReplace = 0;
|
||||||
int jumpInst1=0, jumpInst2;
|
int jumpInst1=0, jumpInst2;
|
||||||
int contAddr;
|
int contAddr;
|
||||||
int hasTwoRecnos = (isUpdate && recnoChng);
|
int hasTwoRowids = (isUpdate && rowidChng);
|
||||||
|
|
||||||
v = sqlite3GetVdbe(pParse);
|
v = sqlite3GetVdbe(pParse);
|
||||||
assert( v!=0 );
|
assert( v!=0 );
|
||||||
@@ -857,7 +857,7 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OE_Ignore: {
|
case OE_Ignore: {
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRecnos, 0);
|
sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRowids, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
|
sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -878,7 +878,7 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
** of the new record does not previously exist. Except, if this
|
** of the new record does not previously exist. Except, if this
|
||||||
** is an UPDATE and the primary key is not changing, that is OK.
|
** is an UPDATE and the primary key is not changing, that is OK.
|
||||||
*/
|
*/
|
||||||
if( recnoChng ){
|
if( rowidChng ){
|
||||||
onError = pTab->keyConf;
|
onError = pTab->keyConf;
|
||||||
if( overrideError!=OE_Default ){
|
if( overrideError!=OE_Default ){
|
||||||
onError = overrideError;
|
onError = overrideError;
|
||||||
@@ -908,7 +908,7 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
case OE_Replace: {
|
case OE_Replace: {
|
||||||
sqlite3GenerateRowIndexDelete(pParse->db, v, pTab, base, 0);
|
sqlite3GenerateRowIndexDelete(pParse->db, v, pTab, base, 0);
|
||||||
if( isUpdate ){
|
if( isUpdate ){
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, nCol+hasTwoRecnos, 1);
|
sqlite3VdbeAddOp(v, OP_Dup, nCol+hasTwoRowids, 1);
|
||||||
sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
|
sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
|
||||||
}
|
}
|
||||||
seenReplace = 1;
|
seenReplace = 1;
|
||||||
@@ -916,7 +916,7 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
}
|
}
|
||||||
case OE_Ignore: {
|
case OE_Ignore: {
|
||||||
assert( seenReplace==0 );
|
assert( seenReplace==0 );
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRecnos, 0);
|
sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRowids, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
|
sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -967,7 +967,7 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
|
|
||||||
|
|
||||||
/* Check to see if the new index entry will be unique */
|
/* Check to see if the new index entry will be unique */
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, extra+nCol+1+hasTwoRecnos, 1);
|
sqlite3VdbeAddOp(v, OP_Dup, extra+nCol+1+hasTwoRowids, 1);
|
||||||
jumpInst2 = sqlite3VdbeAddOp(v, OP_IsUnique, base+iCur+1, 0);
|
jumpInst2 = sqlite3VdbeAddOp(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 */
|
||||||
@@ -1004,14 +1004,14 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
}
|
}
|
||||||
case OE_Ignore: {
|
case OE_Ignore: {
|
||||||
assert( seenReplace==0 );
|
assert( seenReplace==0 );
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, nCol+extra+3+hasTwoRecnos, 0);
|
sqlite3VdbeAddOp(v, OP_Pop, nCol+extra+3+hasTwoRowids, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
|
sqlite3VdbeAddOp(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+hasTwoRecnos, 1);
|
sqlite3VdbeAddOp(v, OP_Dup, nCol+extra+1+hasTwoRowids, 1);
|
||||||
sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
|
sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
|
||||||
}
|
}
|
||||||
seenReplace = 1;
|
seenReplace = 1;
|
||||||
@@ -1031,7 +1031,7 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
** This routine generates code to finish the INSERT or UPDATE operation
|
** This routine generates code to finish the INSERT or UPDATE operation
|
||||||
** that was started by a prior call to sqlite3GenerateConstraintChecks.
|
** that was started by a prior call to sqlite3GenerateConstraintChecks.
|
||||||
** The stack must contain keys for all active indices followed by data
|
** The stack must contain keys for all active indices followed by data
|
||||||
** and the recno for the new entry. This routine creates the new
|
** and the rowid for the new entry. This routine creates the new
|
||||||
** entries in all indices and in the main table.
|
** entries in all indices and in the main table.
|
||||||
**
|
**
|
||||||
** The arguments to this routine should be the same as the first six
|
** The arguments to this routine should be the same as the first six
|
||||||
@@ -1042,7 +1042,7 @@ void sqlite3CompleteInsertion(
|
|||||||
Table *pTab, /* the table into which we are inserting */
|
Table *pTab, /* the table into which we are inserting */
|
||||||
int base, /* Index of a read/write cursor pointing at pTab */
|
int base, /* Index of a read/write cursor pointing at pTab */
|
||||||
char *aIdxUsed, /* Which indices are used. NULL means all are used */
|
char *aIdxUsed, /* Which indices are used. NULL means all are used */
|
||||||
int recnoChng, /* True if the record number will change */
|
int rowidChng, /* True if the record number will change */
|
||||||
int isUpdate, /* True for UPDATE, False for INSERT */
|
int isUpdate, /* True for UPDATE, False for INSERT */
|
||||||
int newIdx /* Index of NEW table for triggers. -1 if none */
|
int newIdx /* Index of NEW table for triggers. -1 if none */
|
||||||
){
|
){
|
||||||
@@ -1058,7 +1058,7 @@ 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_IdxPut, base+i+1, 0);
|
sqlite3VdbeAddOp(v, OP_IdxInsert, base+i+1, 0);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
|
sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
|
||||||
sqlite3TableAffinityStr(v, pTab);
|
sqlite3TableAffinityStr(v, pTab);
|
||||||
@@ -1066,7 +1066,7 @@ void sqlite3CompleteInsertion(
|
|||||||
if( newIdx>=0 ){
|
if( newIdx>=0 ){
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
|
sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
|
sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0);
|
sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if( pParse->nested ){
|
if( pParse->nested ){
|
||||||
@@ -1074,9 +1074,9 @@ void sqlite3CompleteInsertion(
|
|||||||
}else{
|
}else{
|
||||||
pik_flags = (OPFLAG_NCHANGE|(isUpdate?0:OPFLAG_LASTROWID));
|
pik_flags = (OPFLAG_NCHANGE|(isUpdate?0:OPFLAG_LASTROWID));
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_PutIntKey, base, pik_flags);
|
sqlite3VdbeAddOp(v, OP_Insert, base, pik_flags);
|
||||||
|
|
||||||
if( isUpdate && recnoChng ){
|
if( isUpdate && rowidChng ){
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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.94 2005/06/07 22:22:51 drh Exp $
|
** $Id: pragma.c,v 1.95 2005/06/12 21:35:52 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@@ -693,7 +693,7 @@ void sqlite3Pragma(
|
|||||||
static const VdbeOpList idxErr[] = {
|
static const VdbeOpList idxErr[] = {
|
||||||
{ OP_MemIncr, 0, 0, 0},
|
{ OP_MemIncr, 0, 0, 0},
|
||||||
{ OP_String8, 0, 0, "rowid "},
|
{ OP_String8, 0, 0, "rowid "},
|
||||||
{ OP_Recno, 1, 0, 0},
|
{ OP_Rowid, 1, 0, 0},
|
||||||
{ OP_String8, 0, 0, " missing from index "},
|
{ OP_String8, 0, 0, " missing from index "},
|
||||||
{ OP_String8, 0, 0, 0}, /* 4 */
|
{ OP_String8, 0, 0, 0}, /* 4 */
|
||||||
{ OP_Concat, 2, 0, 0},
|
{ OP_Concat, 2, 0, 0},
|
||||||
|
10
src/random.c
10
src/random.c
@@ -15,7 +15,7 @@
|
|||||||
** Random numbers are used by some of the database backends in order
|
** Random numbers are used by some of the database backends in order
|
||||||
** to generate random integer keys for tables or random filenames.
|
** to generate random integer keys for tables or random filenames.
|
||||||
**
|
**
|
||||||
** $Id: random.c,v 1.12 2004/05/08 08:23:32 danielk1977 Exp $
|
** $Id: random.c,v 1.13 2005/06/12 21:35:52 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@@ -26,13 +26,16 @@
|
|||||||
** must be held while executing this routine.
|
** must be held while executing this routine.
|
||||||
**
|
**
|
||||||
** Why not just use a library random generator like lrand48() for this?
|
** Why not just use a library random generator like lrand48() for this?
|
||||||
** Because the OP_NewRecno opcode in the VDBE depends on having a very
|
** Because the OP_NewRowid opcode in the VDBE depends on having a very
|
||||||
** good source of random numbers. The lrand48() library function may
|
** good source of random numbers. The lrand48() library function may
|
||||||
** well be good enough. But maybe not. Or maybe lrand48() has some
|
** well be good enough. But maybe not. Or maybe lrand48() has some
|
||||||
** subtle problems on some systems that could cause problems. It is hard
|
** subtle problems on some systems that could cause problems. It is hard
|
||||||
** to know. To minimize the risk of problems due to bad lrand48()
|
** to know. To minimize the risk of problems due to bad lrand48()
|
||||||
** implementations, SQLite uses this random number generator based
|
** implementations, SQLite uses this random number generator based
|
||||||
** on RC4, which we know works very well.
|
** on RC4, which we know works very well.
|
||||||
|
**
|
||||||
|
** (Later): Actually, OP_NewRowid does not depend on a good source of
|
||||||
|
** randomness any more. But we will leave this code in all the same.
|
||||||
*/
|
*/
|
||||||
static int randomByte(){
|
static int randomByte(){
|
||||||
unsigned char t;
|
unsigned char t;
|
||||||
@@ -95,6 +98,3 @@ void sqlite3Randomness(int N, void *pBuf){
|
|||||||
}
|
}
|
||||||
sqlite3OsLeaveMutex();
|
sqlite3OsLeaveMutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
42
src/select.c
42
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.251 2005/06/12 12:01:19 drh Exp $
|
** $Id: select.c,v 1.252 2005/06/12 21:35:52 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -326,7 +326,7 @@ static void pushOntoSorter(Parse *pParse, Vdbe *v, ExprList *pOrderBy){
|
|||||||
sqlite3ExprCode(pParse, pOrderBy->a[i].pExpr);
|
sqlite3ExprCode(pParse, pOrderBy->a[i].pExpr);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_MakeRecord, pOrderBy->nExpr, 0);
|
sqlite3VdbeAddOp(v, OP_MakeRecord, pOrderBy->nExpr, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_SortPut, 0, 0);
|
sqlite3VdbeAddOp(v, OP_SortInsert, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -422,8 +422,7 @@ static int selectInnerLoop(
|
|||||||
sqlite3VdbeAddOp(v, OP_Pop, pEList->nExpr+1, 0);
|
sqlite3VdbeAddOp(v, OP_Pop, pEList->nExpr+1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, iContinue);
|
sqlite3VdbeAddOp(v, OP_Goto, 0, iContinue);
|
||||||
VdbeComment((v, "# skip indistinct records"));
|
VdbeComment((v, "# skip indistinct records"));
|
||||||
sqlite3VdbeAddOp(v, OP_String8, 0, 0);
|
sqlite3VdbeAddOp(v, OP_IdxInsert, distinct, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_PutStrKey, distinct, 0);
|
|
||||||
if( pOrderBy==0 ){
|
if( pOrderBy==0 ){
|
||||||
codeLimiter(v, p, iContinue, iBreak, nColumn);
|
codeLimiter(v, p, iContinue, iBreak, nColumn);
|
||||||
}
|
}
|
||||||
@@ -437,8 +436,7 @@ static int selectInnerLoop(
|
|||||||
case SRT_Union: {
|
case SRT_Union: {
|
||||||
sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT);
|
sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT);
|
||||||
sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC);
|
sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC);
|
||||||
sqlite3VdbeAddOp(v, OP_String8, 0, 0);
|
sqlite3VdbeAddOp(v, OP_IdxInsert, iParm, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_PutStrKey, iParm, 0);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -464,9 +462,9 @@ static int selectInnerLoop(
|
|||||||
if( pOrderBy ){
|
if( pOrderBy ){
|
||||||
pushOntoSorter(pParse, v, pOrderBy);
|
pushOntoSorter(pParse, v, pOrderBy);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_NewRecno, iParm, 0);
|
sqlite3VdbeAddOp(v, OP_NewRowid, iParm, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
|
sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_PutIntKey, iParm, 0);
|
sqlite3VdbeAddOp(v, OP_Insert, iParm, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -490,8 +488,7 @@ static int selectInnerLoop(
|
|||||||
char aff = (iParm>>16)&0xFF;
|
char aff = (iParm>>16)&0xFF;
|
||||||
aff = sqlite3CompareAffinity(pEList->a[0].pExpr, aff);
|
aff = sqlite3CompareAffinity(pEList->a[0].pExpr, aff);
|
||||||
sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &aff, 1);
|
sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &aff, 1);
|
||||||
sqlite3VdbeAddOp(v, OP_String8, 0, 0);
|
sqlite3VdbeAddOp(v, OP_IdxInsert, (iParm&0x0000FFFF), 0);
|
||||||
sqlite3VdbeAddOp(v, OP_PutStrKey, (iParm&0x0000FFFF), 0);
|
|
||||||
}
|
}
|
||||||
sqlite3VdbeChangeP2(v, addr2, sqlite3VdbeCurrentAddr(v));
|
sqlite3VdbeChangeP2(v, addr2, sqlite3VdbeCurrentAddr(v));
|
||||||
break;
|
break;
|
||||||
@@ -603,9 +600,9 @@ static void generateSortTail(
|
|||||||
switch( eDest ){
|
switch( eDest ){
|
||||||
case SRT_Table:
|
case SRT_Table:
|
||||||
case SRT_TempTable: {
|
case SRT_TempTable: {
|
||||||
sqlite3VdbeAddOp(v, OP_NewRecno, iParm, 0);
|
sqlite3VdbeAddOp(v, OP_NewRowid, iParm, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
|
sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_PutIntKey, iParm, 0);
|
sqlite3VdbeAddOp(v, OP_Insert, iParm, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifndef SQLITE_OMIT_SUBQUERY
|
#ifndef SQLITE_OMIT_SUBQUERY
|
||||||
@@ -615,8 +612,7 @@ static void generateSortTail(
|
|||||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+3);
|
sqlite3VdbeAddOp(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+3);
|
||||||
sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, "n", P3_STATIC);
|
sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, "n", P3_STATIC);
|
||||||
sqlite3VdbeAddOp(v, OP_String8, 0, 0);
|
sqlite3VdbeAddOp(v, OP_IdxInsert, (iParm&0x0000FFFF), 0);
|
||||||
sqlite3VdbeAddOp(v, OP_PutStrKey, (iParm&0x0000FFFF), 0);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SRT_Exists:
|
case SRT_Exists:
|
||||||
@@ -1326,11 +1322,9 @@ static void computeLimitRegisters(Parse *pParse, Select *p){
|
|||||||
** DISTINCT, UNION, INTERSECT and EXCEPT select statements (but not
|
** DISTINCT, UNION, INTERSECT and EXCEPT select statements (but not
|
||||||
** UNION ALL).
|
** UNION ALL).
|
||||||
**
|
**
|
||||||
** Make the new table a KeyAsData table if keyAsData is true.
|
|
||||||
**
|
|
||||||
** The value returned is the address of the OP_OpenTemp instruction.
|
** The value returned is the address of the OP_OpenTemp instruction.
|
||||||
*/
|
*/
|
||||||
static int openTempIndex(Parse *pParse, Select *p, int iTab, int keyAsData){
|
static int openTempIndex(Parse *pParse, Select *p, int iTab){
|
||||||
KeyInfo *pKeyInfo;
|
KeyInfo *pKeyInfo;
|
||||||
int nColumn;
|
int nColumn;
|
||||||
sqlite3 *db = pParse->db;
|
sqlite3 *db = pParse->db;
|
||||||
@@ -1354,9 +1348,6 @@ static int openTempIndex(Parse *pParse, Select *p, int iTab, int keyAsData){
|
|||||||
}
|
}
|
||||||
addr = sqlite3VdbeOp3(v, OP_OpenTemp, iTab, 0,
|
addr = sqlite3VdbeOp3(v, OP_OpenTemp, iTab, 0,
|
||||||
(char*)pKeyInfo, P3_KEYINFO_HANDOFF);
|
(char*)pKeyInfo, P3_KEYINFO_HANDOFF);
|
||||||
if( keyAsData ){
|
|
||||||
sqlite3VdbeAddOp(v, OP_KeyAsData, iTab, 1);
|
|
||||||
}
|
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1551,7 +1542,6 @@ static int multiSelect(
|
|||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
goto multi_select_end;
|
goto multi_select_end;
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_KeyAsData, unionTab, 1);
|
|
||||||
}
|
}
|
||||||
assert( nAddr<sizeof(aAddr)/sizeof(aAddr[0]) );
|
assert( nAddr<sizeof(aAddr)/sizeof(aAddr[0]) );
|
||||||
aAddr[nAddr++] = sqlite3VdbeAddOp(v, OP_SetNumColumns, unionTab, 0);
|
aAddr[nAddr++] = sqlite3VdbeAddOp(v, OP_SetNumColumns, unionTab, 0);
|
||||||
@@ -1643,7 +1633,6 @@ static int multiSelect(
|
|||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
goto multi_select_end;
|
goto multi_select_end;
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_KeyAsData, tab1, 1);
|
|
||||||
assert( nAddr<sizeof(aAddr)/sizeof(aAddr[0]) );
|
assert( nAddr<sizeof(aAddr)/sizeof(aAddr[0]) );
|
||||||
aAddr[nAddr++] = sqlite3VdbeAddOp(v, OP_SetNumColumns, tab1, 0);
|
aAddr[nAddr++] = sqlite3VdbeAddOp(v, OP_SetNumColumns, tab1, 0);
|
||||||
assert( p->pEList );
|
assert( p->pEList );
|
||||||
@@ -1662,7 +1651,6 @@ static int multiSelect(
|
|||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
goto multi_select_end;
|
goto multi_select_end;
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_KeyAsData, tab2, 1);
|
|
||||||
assert( nAddr<sizeof(aAddr)/sizeof(aAddr[0]) );
|
assert( nAddr<sizeof(aAddr)/sizeof(aAddr[0]) );
|
||||||
aAddr[nAddr++] = sqlite3VdbeAddOp(v, OP_SetNumColumns, tab2, 0);
|
aAddr[nAddr++] = sqlite3VdbeAddOp(v, OP_SetNumColumns, tab2, 0);
|
||||||
p->pPrior = 0;
|
p->pPrior = 0;
|
||||||
@@ -2226,12 +2214,12 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){
|
|||||||
sqlite3VdbeOp3(v, OP_OpenRead, iIdx, pIdx->tnum,
|
sqlite3VdbeOp3(v, OP_OpenRead, iIdx, pIdx->tnum,
|
||||||
(char*)&pIdx->keyInfo, P3_KEYINFO);
|
(char*)&pIdx->keyInfo, P3_KEYINFO);
|
||||||
if( seekOp==OP_Rewind ){
|
if( seekOp==OP_Rewind ){
|
||||||
sqlite3VdbeAddOp(v, OP_String, 0, 0);
|
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MakeRecord, 1, 0);
|
sqlite3VdbeAddOp(v, OP_MakeRecord, 1, 0);
|
||||||
seekOp = OP_MoveGt;
|
seekOp = OP_MoveGt;
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, seekOp, iIdx, 0);
|
sqlite3VdbeAddOp(v, seekOp, iIdx, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_IdxRecno, iIdx, 0);
|
sqlite3VdbeAddOp(v, OP_IdxRowid, iIdx, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, iIdx, 0);
|
sqlite3VdbeAddOp(v, OP_Close, iIdx, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
|
sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
|
||||||
}
|
}
|
||||||
@@ -2741,7 +2729,7 @@ int sqlite3Select(
|
|||||||
/* Initialize the memory cell to NULL for SRT_Mem or 0 for SRT_Exists
|
/* Initialize the memory cell to NULL for SRT_Mem or 0 for SRT_Exists
|
||||||
*/
|
*/
|
||||||
if( eDest==SRT_Mem || eDest==SRT_Exists ){
|
if( eDest==SRT_Mem || eDest==SRT_Exists ){
|
||||||
sqlite3VdbeAddOp(v, eDest==SRT_Mem ? OP_String8 : OP_Integer, 0, 0);
|
sqlite3VdbeAddOp(v, eDest==SRT_Mem ? OP_Null : OP_Integer, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
|
sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2749,7 +2737,7 @@ int sqlite3Select(
|
|||||||
*/
|
*/
|
||||||
if( isDistinct ){
|
if( isDistinct ){
|
||||||
distinct = pParse->nTab++;
|
distinct = pParse->nTab++;
|
||||||
openTempIndex(pParse, p, distinct, 0);
|
openTempIndex(pParse, p, distinct);
|
||||||
}else{
|
}else{
|
||||||
distinct = -1;
|
distinct = -1;
|
||||||
}
|
}
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.386 2005/06/06 21:19:57 drh Exp $
|
** @(#) $Id: sqliteInt.h,v 1.387 2005/06/12 21:35:52 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITEINT_H_
|
#ifndef _SQLITEINT_H_
|
||||||
#define _SQLITEINT_H_
|
#define _SQLITEINT_H_
|
||||||
@@ -1141,7 +1141,7 @@ struct AuthContext {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Bitfield flags for P2 value in OP_PutIntKey and OP_Delete
|
** Bitfield flags for P2 value in OP_Insert and OP_Delete
|
||||||
*/
|
*/
|
||||||
#define OPFLAG_NCHANGE 1 /* Set to update db->nChange */
|
#define OPFLAG_NCHANGE 1 /* Set to update db->nChange */
|
||||||
#define OPFLAG_LASTROWID 2 /* Set to update db->lastRowid */
|
#define OPFLAG_LASTROWID 2 /* Set to update db->lastRowid */
|
||||||
|
@@ -215,7 +215,7 @@ void sqlite3FinishTrigger(
|
|||||||
*/
|
*/
|
||||||
if( !db->init.busy ){
|
if( !db->init.busy ){
|
||||||
static const VdbeOpList insertTrig[] = {
|
static const VdbeOpList insertTrig[] = {
|
||||||
{ OP_NewRecno, 0, 0, 0 },
|
{ OP_NewRowid, 0, 0, 0 },
|
||||||
{ OP_String8, 0, 0, "trigger" },
|
{ OP_String8, 0, 0, "trigger" },
|
||||||
{ OP_String8, 0, 0, 0 }, /* 2: trigger name */
|
{ OP_String8, 0, 0, 0 }, /* 2: trigger name */
|
||||||
{ OP_String8, 0, 0, 0 }, /* 3: table name */
|
{ OP_String8, 0, 0, 0 }, /* 3: table name */
|
||||||
@@ -224,7 +224,7 @@ void sqlite3FinishTrigger(
|
|||||||
{ OP_String8, 0, 0, 0 }, /* 6: SQL */
|
{ OP_String8, 0, 0, 0 }, /* 6: SQL */
|
||||||
{ OP_Concat, 0, 0, 0 },
|
{ OP_Concat, 0, 0, 0 },
|
||||||
{ OP_MakeRecord, 5, 0, "tttit" },
|
{ OP_MakeRecord, 5, 0, "tttit" },
|
||||||
{ OP_PutIntKey, 0, 0, 0 },
|
{ OP_Insert, 0, 0, 0 },
|
||||||
};
|
};
|
||||||
int addr;
|
int addr;
|
||||||
Vdbe *v;
|
Vdbe *v;
|
||||||
|
48
src/update.c
48
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.107 2005/04/22 02:38:38 drh Exp $
|
** $Id: update.c,v 1.108 2005/06/12 21:35:53 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -80,8 +80,8 @@ void sqlite3Update(
|
|||||||
int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the
|
int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the
|
||||||
** an expression for the i-th column of the table.
|
** an expression for the i-th column of the table.
|
||||||
** aXRef[i]==-1 if the i-th column is not changed. */
|
** aXRef[i]==-1 if the i-th column is not changed. */
|
||||||
int chngRecno; /* True if the record number is being changed */
|
int chngRowid; /* True if the record number is being changed */
|
||||||
Expr *pRecnoExpr = 0; /* Expression defining the new record number */
|
Expr *pRowidExpr = 0; /* Expression defining the new record number */
|
||||||
int openAll = 0; /* True if all indices need to be opened */
|
int openAll = 0; /* True if all indices need to be opened */
|
||||||
AuthContext sContext; /* The authorization context */
|
AuthContext sContext; /* The authorization context */
|
||||||
NameContext sNC; /* The name-context to resolve expressions in */
|
NameContext sNC; /* The name-context to resolve expressions in */
|
||||||
@@ -160,7 +160,7 @@ void sqlite3Update(
|
|||||||
** column to be updated, make sure we have authorization to change
|
** column to be updated, make sure we have authorization to change
|
||||||
** that column.
|
** that column.
|
||||||
*/
|
*/
|
||||||
chngRecno = 0;
|
chngRowid = 0;
|
||||||
for(i=0; i<pChanges->nExpr; i++){
|
for(i=0; i<pChanges->nExpr; i++){
|
||||||
if( sqlite3ExprResolveNames(&sNC, pChanges->a[i].pExpr) ){
|
if( sqlite3ExprResolveNames(&sNC, pChanges->a[i].pExpr) ){
|
||||||
goto update_cleanup;
|
goto update_cleanup;
|
||||||
@@ -168,8 +168,8 @@ void sqlite3Update(
|
|||||||
for(j=0; j<pTab->nCol; j++){
|
for(j=0; j<pTab->nCol; j++){
|
||||||
if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){
|
if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){
|
||||||
if( j==pTab->iPKey ){
|
if( j==pTab->iPKey ){
|
||||||
chngRecno = 1;
|
chngRowid = 1;
|
||||||
pRecnoExpr = pChanges->a[i].pExpr;
|
pRowidExpr = pChanges->a[i].pExpr;
|
||||||
}
|
}
|
||||||
aXRef[j] = i;
|
aXRef[j] = i;
|
||||||
break;
|
break;
|
||||||
@@ -177,8 +177,8 @@ void sqlite3Update(
|
|||||||
}
|
}
|
||||||
if( j>=pTab->nCol ){
|
if( j>=pTab->nCol ){
|
||||||
if( sqlite3IsRowid(pChanges->a[i].zName) ){
|
if( sqlite3IsRowid(pChanges->a[i].zName) ){
|
||||||
chngRecno = 1;
|
chngRowid = 1;
|
||||||
pRecnoExpr = pChanges->a[i].pExpr;
|
pRowidExpr = pChanges->a[i].pExpr;
|
||||||
}else{
|
}else{
|
||||||
sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName);
|
sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName);
|
||||||
goto update_cleanup;
|
goto update_cleanup;
|
||||||
@@ -204,7 +204,7 @@ void sqlite3Update(
|
|||||||
** number of the original table entry is changing.
|
** number of the original table entry is changing.
|
||||||
*/
|
*/
|
||||||
for(nIdx=nIdxTotal=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdxTotal++){
|
for(nIdx=nIdxTotal=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdxTotal++){
|
||||||
if( chngRecno ){
|
if( chngRowid ){
|
||||||
i = 0;
|
i = 0;
|
||||||
}else {
|
}else {
|
||||||
for(i=0; i<pIdx->nColumn; i++){
|
for(i=0; i<pIdx->nColumn; i++){
|
||||||
@@ -219,7 +219,7 @@ void sqlite3Update(
|
|||||||
aIdxUsed = (char*)&apIdx[nIdx];
|
aIdxUsed = (char*)&apIdx[nIdx];
|
||||||
}
|
}
|
||||||
for(nIdx=j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
for(nIdx=j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||||
if( chngRecno ){
|
if( chngRowid ){
|
||||||
i = 0;
|
i = 0;
|
||||||
}else{
|
}else{
|
||||||
for(i=0; i<pIdx->nColumn; i++){
|
for(i=0; i<pIdx->nColumn; i++){
|
||||||
@@ -272,7 +272,7 @@ void sqlite3Update(
|
|||||||
|
|
||||||
/* Remember the index of every item to be updated.
|
/* Remember the index of every item to be updated.
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
|
sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_ListWrite, 0, 0);
|
sqlite3VdbeAddOp(v, OP_ListWrite, 0, 0);
|
||||||
|
|
||||||
/* End the database scan loop.
|
/* End the database scan loop.
|
||||||
@@ -310,20 +310,20 @@ void sqlite3Update(
|
|||||||
|
|
||||||
/* Generate the OLD table
|
/* Generate the OLD table
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
|
sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
|
sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_PutIntKey, oldIdx, 0);
|
sqlite3VdbeAddOp(v, OP_Insert, oldIdx, 0);
|
||||||
|
|
||||||
/* Generate the NEW table
|
/* Generate the NEW table
|
||||||
*/
|
*/
|
||||||
if( chngRecno ){
|
if( chngRowid ){
|
||||||
sqlite3ExprCodeAndCache(pParse, pRecnoExpr);
|
sqlite3ExprCodeAndCache(pParse, pRowidExpr);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
|
sqlite3VdbeAddOp(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_String8, 0, 0);
|
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
j = aXRef[i];
|
j = aXRef[i];
|
||||||
@@ -339,7 +339,7 @@ void sqlite3Update(
|
|||||||
sqlite3TableAffinityStr(v, pTab);
|
sqlite3TableAffinityStr(v, pTab);
|
||||||
}
|
}
|
||||||
if( pParse->nErr ) goto update_cleanup;
|
if( pParse->nErr ) goto update_cleanup;
|
||||||
sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0);
|
sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0);
|
||||||
if( !isView ){
|
if( !isView ){
|
||||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
||||||
}
|
}
|
||||||
@@ -399,8 +399,8 @@ void sqlite3Update(
|
|||||||
** will be after the update. (The old record number is currently
|
** will be after the update. (The old record number is currently
|
||||||
** on top of the stack.)
|
** on top of the stack.)
|
||||||
*/
|
*/
|
||||||
if( chngRecno ){
|
if( chngRowid ){
|
||||||
sqlite3ExprCode(pParse, pRecnoExpr);
|
sqlite3ExprCode(pParse, pRowidExpr);
|
||||||
sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
|
sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,7 +408,7 @@ void sqlite3Update(
|
|||||||
*/
|
*/
|
||||||
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_String8, 0, 0);
|
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
j = aXRef[i];
|
j = aXRef[i];
|
||||||
@@ -422,7 +422,7 @@ void sqlite3Update(
|
|||||||
|
|
||||||
/* Do constraint checks
|
/* Do constraint checks
|
||||||
*/
|
*/
|
||||||
sqlite3GenerateConstraintChecks(pParse, pTab, iCur, aIdxUsed, chngRecno, 1,
|
sqlite3GenerateConstraintChecks(pParse, pTab, iCur, aIdxUsed, chngRowid, 1,
|
||||||
onError, addr);
|
onError, addr);
|
||||||
|
|
||||||
/* Delete the old indices for the current record.
|
/* Delete the old indices for the current record.
|
||||||
@@ -431,13 +431,13 @@ void sqlite3Update(
|
|||||||
|
|
||||||
/* If changing the record number, delete the old record.
|
/* If changing the record number, delete the old record.
|
||||||
*/
|
*/
|
||||||
if( chngRecno ){
|
if( chngRowid ){
|
||||||
sqlite3VdbeAddOp(v, OP_Delete, iCur, 0);
|
sqlite3VdbeAddOp(v, OP_Delete, iCur, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the new index entries and the new record.
|
/* Create the new index entries and the new record.
|
||||||
*/
|
*/
|
||||||
sqlite3CompleteInsertion(pParse, pTab, iCur, aIdxUsed, chngRecno, 1, -1);
|
sqlite3CompleteInsertion(pParse, pTab, iCur, aIdxUsed, chngRowid, 1, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Increment the row counter
|
/* Increment the row counter
|
||||||
|
288
src/vdbe.c
288
src/vdbe.c
@@ -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.468 2005/06/12 12:01:19 drh Exp $
|
** $Id: vdbe.c,v 1.469 2005/06/12 21:35:53 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@@ -717,7 +717,8 @@ case OP_String8: { /* same as TK_STRING */
|
|||||||
#ifndef SQLITE_OMIT_UTF16
|
#ifndef SQLITE_OMIT_UTF16
|
||||||
pOp->opcode = OP_String;
|
pOp->opcode = OP_String;
|
||||||
|
|
||||||
if( db->enc!=SQLITE_UTF8 && pOp->p3 ){
|
assert( pOp->p3!=0 );
|
||||||
|
if( db->enc!=SQLITE_UTF8 ){
|
||||||
pTos++;
|
pTos++;
|
||||||
sqlite3VdbeMemSetStr(pTos, pOp->p3, -1, SQLITE_UTF8, SQLITE_STATIC);
|
sqlite3VdbeMemSetStr(pTos, pOp->p3, -1, SQLITE_UTF8, SQLITE_STATIC);
|
||||||
if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pTos, db->enc) ) goto no_mem;
|
if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pTos, db->enc) ) goto no_mem;
|
||||||
@@ -743,7 +744,7 @@ case OP_String8: { /* same as TK_STRING */
|
|||||||
*/
|
*/
|
||||||
case OP_String: {
|
case OP_String: {
|
||||||
pTos++;
|
pTos++;
|
||||||
if( pOp->p3 ){
|
assert( pOp->p3!=0 );
|
||||||
pTos->flags = MEM_Str|MEM_Static|MEM_Term;
|
pTos->flags = MEM_Str|MEM_Static|MEM_Term;
|
||||||
pTos->z = pOp->p3;
|
pTos->z = pOp->p3;
|
||||||
#ifndef SQLITE_OMIT_UTF16
|
#ifndef SQLITE_OMIT_UTF16
|
||||||
@@ -757,12 +758,20 @@ case OP_String: {
|
|||||||
pTos->n = strlen(pTos->z);
|
pTos->n = strlen(pTos->z);
|
||||||
#endif
|
#endif
|
||||||
pTos->enc = db->enc;
|
pTos->enc = db->enc;
|
||||||
}else{
|
|
||||||
pTos->flags = MEM_Null;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Opcode: Null * * *
|
||||||
|
**
|
||||||
|
** Push a NULL onto the stack.
|
||||||
|
*/
|
||||||
|
case OP_Null: {
|
||||||
|
pTos++;
|
||||||
|
pTos->flags = MEM_Null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_BLOB_LITERAL
|
#ifndef SQLITE_OMIT_BLOB_LITERAL
|
||||||
/* Opcode: HexBlob * * P3
|
/* Opcode: HexBlob * * P3
|
||||||
**
|
**
|
||||||
@@ -1373,11 +1382,11 @@ case OP_MustBeInt: { /* no-push */
|
|||||||
** 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.
|
||||||
**
|
**
|
||||||
** The least significant byte of P1 may be either 0x00 or 0x01. If either
|
** If the 0x100 bit of P1 is true and either operand is NULL then take the
|
||||||
** operand is NULL (and thus if the result is unknown) then take the jump
|
** jump. If the 0x100 bit of P1 is false then fall thru if either operand
|
||||||
** only if the least significant byte of P1 is 0x01.
|
** is NULL.
|
||||||
**
|
**
|
||||||
** The second least significant byte of P1 must be an affinity character -
|
** The least significant byte of P1 (mask 0xff) must be an affinity character -
|
||||||
** 'n', 't', 'i' or 'o' - or 0x00. An attempt is made to coerce both values
|
** 'n', 't', 'i' or 'o' - or 0x00. An attempt is made to coerce both values
|
||||||
** according to the affinity before the comparison is made. If the byte is
|
** according to the affinity before the comparison is made. If the byte is
|
||||||
** 0x00, then numeric affinity is used.
|
** 0x00, then numeric affinity is used.
|
||||||
@@ -1446,7 +1455,7 @@ case OP_Ge: { /* same as TK_GE, no-push */
|
|||||||
if( flags&MEM_Null ){
|
if( flags&MEM_Null ){
|
||||||
popStack(&pTos, 2);
|
popStack(&pTos, 2);
|
||||||
if( pOp->p2 ){
|
if( pOp->p2 ){
|
||||||
if( (pOp->p1&0xFF) ) pc = pOp->p2-1;
|
if( pOp->p1 & 0x100 ) pc = pOp->p2-1;
|
||||||
}else{
|
}else{
|
||||||
pTos++;
|
pTos++;
|
||||||
pTos->flags = MEM_Null;
|
pTos->flags = MEM_Null;
|
||||||
@@ -1454,7 +1463,7 @@ case OP_Ge: { /* same as TK_GE, no-push */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
affinity = (pOp->p1>>8)&0xFF;
|
affinity = pOp->p1 & 0xFF;
|
||||||
if( affinity ){
|
if( affinity ){
|
||||||
applyAffinity(pNos, affinity, db->enc);
|
applyAffinity(pNos, affinity, db->enc);
|
||||||
applyAffinity(pTos, affinity, db->enc);
|
applyAffinity(pTos, affinity, db->enc);
|
||||||
@@ -1708,10 +1717,6 @@ case OP_SetNumColumns: { /* no-push */
|
|||||||
assert( p->apCsr[pOp->p1]!=0 );
|
assert( p->apCsr[pOp->p1]!=0 );
|
||||||
pC = p->apCsr[pOp->p1];
|
pC = p->apCsr[pOp->p1];
|
||||||
pC->nField = pOp->p2;
|
pC->nField = pOp->p2;
|
||||||
if( (!pC->keyAsData && pC->zeroData) || (pC->keyAsData && pC->intKey) ){
|
|
||||||
rc = SQLITE_CORRUPT;
|
|
||||||
goto abort_due_to_error;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1795,7 +1800,7 @@ case OP_Column: {
|
|||||||
}else if( pC->cacheValid ){
|
}else if( pC->cacheValid ){
|
||||||
payloadSize = pC->payloadSize;
|
payloadSize = pC->payloadSize;
|
||||||
zRec = pC->aRow;
|
zRec = pC->aRow;
|
||||||
}else if( pC->keyAsData ){
|
}else if( pC->isIndex ){
|
||||||
i64 payloadSize64;
|
i64 payloadSize64;
|
||||||
sqlite3BtreeKeySize(pCrsr, &payloadSize64);
|
sqlite3BtreeKeySize(pCrsr, &payloadSize64);
|
||||||
payloadSize = payloadSize64;
|
payloadSize = payloadSize64;
|
||||||
@@ -1850,7 +1855,7 @@ case OP_Column: {
|
|||||||
if( zRec ){
|
if( zRec ){
|
||||||
zData = zRec;
|
zData = zRec;
|
||||||
}else{
|
}else{
|
||||||
if( pC->keyAsData ){
|
if( pC->isIndex ){
|
||||||
zData = (char*)sqlite3BtreeKeyFetch(pCrsr, &avail);
|
zData = (char*)sqlite3BtreeKeyFetch(pCrsr, &avail);
|
||||||
}else{
|
}else{
|
||||||
zData = (char*)sqlite3BtreeDataFetch(pCrsr, &avail);
|
zData = (char*)sqlite3BtreeDataFetch(pCrsr, &avail);
|
||||||
@@ -1876,7 +1881,7 @@ case OP_Column: {
|
|||||||
** acquire the complete header text.
|
** acquire the complete header text.
|
||||||
*/
|
*/
|
||||||
if( !zRec && avail<szHdr ){
|
if( !zRec && avail<szHdr ){
|
||||||
rc = sqlite3VdbeMemFromBtree(pCrsr, 0, szHdr, pC->keyAsData, &sMem);
|
rc = sqlite3VdbeMemFromBtree(pCrsr, 0, szHdr, pC->isIndex, &sMem);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
goto op_column_out;
|
goto op_column_out;
|
||||||
}
|
}
|
||||||
@@ -1940,7 +1945,7 @@ case OP_Column: {
|
|||||||
zData = &zRec[aOffset[p2]];
|
zData = &zRec[aOffset[p2]];
|
||||||
}else{
|
}else{
|
||||||
len = sqlite3VdbeSerialTypeLen(aType[p2]);
|
len = sqlite3VdbeSerialTypeLen(aType[p2]);
|
||||||
rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len,pC->keyAsData,&sMem);
|
rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->isIndex,&sMem);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
goto op_column_out;
|
goto op_column_out;
|
||||||
}
|
}
|
||||||
@@ -2440,11 +2445,12 @@ case OP_OpenWrite: { /* no-push */
|
|||||||
rc = sqlite3BtreeCursor(pX, p2, wrFlag,
|
rc = sqlite3BtreeCursor(pX, p2, wrFlag,
|
||||||
sqlite3VdbeRecordCompare, pOp->p3,
|
sqlite3VdbeRecordCompare, pOp->p3,
|
||||||
&pCur->pCursor);
|
&pCur->pCursor);
|
||||||
|
if( pOp->p3type==P3_KEYINFO ){
|
||||||
pCur->pKeyInfo = (KeyInfo*)pOp->p3;
|
pCur->pKeyInfo = (KeyInfo*)pOp->p3;
|
||||||
if( pCur->pKeyInfo ){
|
|
||||||
pCur->pIncrKey = &pCur->pKeyInfo->incrKey;
|
pCur->pIncrKey = &pCur->pKeyInfo->incrKey;
|
||||||
pCur->pKeyInfo->enc = p->db->enc;
|
pCur->pKeyInfo->enc = p->db->enc;
|
||||||
}else{
|
}else{
|
||||||
|
pCur->pKeyInfo = 0;
|
||||||
pCur->pIncrKey = &pCur->bogusIncrKey;
|
pCur->pIncrKey = &pCur->bogusIncrKey;
|
||||||
}
|
}
|
||||||
switch( rc ){
|
switch( rc ){
|
||||||
@@ -2456,11 +2462,32 @@ case OP_OpenWrite: { /* no-push */
|
|||||||
}
|
}
|
||||||
case SQLITE_OK: {
|
case SQLITE_OK: {
|
||||||
int flags = sqlite3BtreeFlags(pCur->pCursor);
|
int flags = sqlite3BtreeFlags(pCur->pCursor);
|
||||||
pCur->intKey = (flags & BTREE_INTKEY)!=0;
|
/* Sanity checking. Only the lower four bits of the flags byte should
|
||||||
pCur->zeroData = (flags & BTREE_ZERODATA)!=0;
|
** be used. Bit 3 (mask 0x08) is unpreditable. The lower 3 bits
|
||||||
|
** (mask 0x07) should be either 5 (intkey+leafdata for tables) or
|
||||||
|
** 2 (zerodata for indices). If these conditions are not met it can
|
||||||
|
** only mean that we are dealing with a corrupt database file
|
||||||
|
*/
|
||||||
|
if( (flags & 0xf0)!=0 || ((flags & 0x07)!=5 && (flags & 0x07)!=2) ){
|
||||||
|
rc = SQLITE_CORRUPT;
|
||||||
|
goto abort_due_to_error;
|
||||||
|
}
|
||||||
|
pCur->isTable = (flags & BTREE_INTKEY)!=0;
|
||||||
|
pCur->isIndex = (flags & BTREE_ZERODATA)!=0;
|
||||||
|
/* If P3==0 it means we are expected to open a table. If P3!=0 then
|
||||||
|
** we expect to be opening an index. If this is not what happened,
|
||||||
|
** then the database is corrupt
|
||||||
|
*/
|
||||||
|
if( (pCur->isTable && pOp->p3type==P3_KEYINFO)
|
||||||
|
|| (pCur->isIndex && pOp->p3type!=P3_KEYINFO) ){
|
||||||
|
rc = SQLITE_CORRUPT;
|
||||||
|
goto abort_due_to_error;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLITE_EMPTY: {
|
case SQLITE_EMPTY: {
|
||||||
|
pCur->isTable = pOp->p3type!=P3_KEYINFO;
|
||||||
|
pCur->isIndex = !pCur->isTable;
|
||||||
rc = SQLITE_OK;
|
rc = SQLITE_OK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2518,12 +2545,14 @@ case OP_OpenTemp: { /* no-push */
|
|||||||
pCx->pKeyInfo->enc = p->db->enc;
|
pCx->pKeyInfo->enc = p->db->enc;
|
||||||
pCx->pIncrKey = &pCx->pKeyInfo->incrKey;
|
pCx->pIncrKey = &pCx->pKeyInfo->incrKey;
|
||||||
}
|
}
|
||||||
|
pCx->isTable = 0;
|
||||||
}else{
|
}else{
|
||||||
rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, 0, &pCx->pCursor);
|
rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, 0, &pCx->pCursor);
|
||||||
pCx->intKey = 1;
|
pCx->isTable = 1;
|
||||||
pCx->pIncrKey = &pCx->bogusIncrKey;
|
pCx->pIncrKey = &pCx->bogusIncrKey;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pCx->isIndex = !pCx->isTable;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2547,6 +2576,8 @@ case OP_OpenPseudo: { /* no-push */
|
|||||||
pCx->nullRow = 1;
|
pCx->nullRow = 1;
|
||||||
pCx->pseudoTable = 1;
|
pCx->pseudoTable = 1;
|
||||||
pCx->pIncrKey = &pCx->bogusIncrKey;
|
pCx->pIncrKey = &pCx->bogusIncrKey;
|
||||||
|
pCx->isTable = 1;
|
||||||
|
pCx->isIndex = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -2621,7 +2652,7 @@ case OP_MoveGt: { /* no-push */
|
|||||||
oc = pOp->opcode;
|
oc = pOp->opcode;
|
||||||
pC->nullRow = 0;
|
pC->nullRow = 0;
|
||||||
*pC->pIncrKey = oc==OP_MoveGt || oc==OP_MoveLe;
|
*pC->pIncrKey = oc==OP_MoveGt || oc==OP_MoveLe;
|
||||||
if( pC->intKey ){
|
if( pC->isTable ){
|
||||||
i64 iKey;
|
i64 iKey;
|
||||||
Integerify(pTos);
|
Integerify(pTos);
|
||||||
iKey = intToKey(pTos->i);
|
iKey = intToKey(pTos->i);
|
||||||
@@ -2636,15 +2667,15 @@ case OP_MoveGt: { /* no-push */
|
|||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
goto abort_due_to_error;
|
goto abort_due_to_error;
|
||||||
}
|
}
|
||||||
pC->lastRecno = pTos->i;
|
pC->lastRowid = pTos->i;
|
||||||
pC->recnoIsValid = res==0;
|
pC->rowidIsValid = res==0;
|
||||||
}else{
|
}else{
|
||||||
Stringify(pTos, db->enc);
|
Stringify(pTos, db->enc);
|
||||||
rc = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
|
rc = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
goto abort_due_to_error;
|
goto abort_due_to_error;
|
||||||
}
|
}
|
||||||
pC->recnoIsValid = 0;
|
pC->rowidIsValid = 0;
|
||||||
}
|
}
|
||||||
pC->deferredMoveto = 0;
|
pC->deferredMoveto = 0;
|
||||||
pC->cacheValid = 0;
|
pC->cacheValid = 0;
|
||||||
@@ -2654,7 +2685,7 @@ case OP_MoveGt: { /* no-push */
|
|||||||
if( res<0 ){
|
if( res<0 ){
|
||||||
rc = sqlite3BtreeNext(pC->pCursor, &res);
|
rc = sqlite3BtreeNext(pC->pCursor, &res);
|
||||||
if( rc!=SQLITE_OK ) goto abort_due_to_error;
|
if( rc!=SQLITE_OK ) goto abort_due_to_error;
|
||||||
pC->recnoIsValid = 0;
|
pC->rowidIsValid = 0;
|
||||||
}else{
|
}else{
|
||||||
res = 0;
|
res = 0;
|
||||||
}
|
}
|
||||||
@@ -2663,7 +2694,7 @@ case OP_MoveGt: { /* no-push */
|
|||||||
if( res>=0 ){
|
if( res>=0 ){
|
||||||
rc = sqlite3BtreePrevious(pC->pCursor, &res);
|
rc = sqlite3BtreePrevious(pC->pCursor, &res);
|
||||||
if( rc!=SQLITE_OK ) goto abort_due_to_error;
|
if( rc!=SQLITE_OK ) goto abort_due_to_error;
|
||||||
pC->recnoIsValid = 0;
|
pC->rowidIsValid = 0;
|
||||||
}else{
|
}else{
|
||||||
/* res might be negative because the table is empty. Check to
|
/* res might be negative because the table is empty. Check to
|
||||||
** see if this is the case.
|
** see if this is the case.
|
||||||
@@ -2686,31 +2717,46 @@ case OP_MoveGt: { /* no-push */
|
|||||||
|
|
||||||
/* Opcode: Distinct P1 P2 *
|
/* Opcode: Distinct P1 P2 *
|
||||||
**
|
**
|
||||||
** Use the top of the stack as a string key. If a record with that key does
|
** Use the top of the stack as a record created using MakeRecord. P1 is a
|
||||||
** not exist in the table of cursor P1, then jump to P2. If the record
|
** cursor on a table that declared as an index. If that table contains an
|
||||||
** does already exist, then fall thru. The cursor is left pointing
|
** entry that matches the top of the stack fall thru. If the top of the stack
|
||||||
** at the record if it exists. The key is not popped from the stack.
|
** matches no entry in P1 then jump to P2.
|
||||||
**
|
**
|
||||||
** This operation is similar to NotFound except that this operation
|
** The cursor is left pointing at the matching entry if it exists. The
|
||||||
|
** record on the top of the stack is not popped.
|
||||||
|
**
|
||||||
|
** This instruction is similar to NotFound except that this operation
|
||||||
** does not pop the key from the stack.
|
** does not pop the key from the stack.
|
||||||
**
|
**
|
||||||
|
** The instruction is used to implement the DISTINCT operator on SELECT
|
||||||
|
** statements. The P1 table is not a true index but rather a record of
|
||||||
|
** all results that have produced so far.
|
||||||
|
**
|
||||||
** See also: Found, NotFound, MoveTo, IsUnique, NotExists
|
** See also: Found, NotFound, MoveTo, IsUnique, NotExists
|
||||||
*/
|
*/
|
||||||
/* Opcode: Found P1 P2 *
|
/* Opcode: Found P1 P2 *
|
||||||
**
|
**
|
||||||
** Use the top of the stack as a string key. If a record with that key
|
** Top of the stack holds a blob constructed by MakeRecord. P1 is an index.
|
||||||
** does exist in table of P1, then jump to P2. If the record
|
** If an entry that matches the top of the stack exists in P1 then
|
||||||
** does not exist, then fall thru. The cursor is left pointing
|
** jump to P2. If the top of the stack does not match any entry in P1
|
||||||
** to the record if it exists. The key is popped from the stack.
|
** then fall thru. The P1 cursor is left pointing at the matching entry
|
||||||
|
** if it exists. The blob is popped off the top of the stack.
|
||||||
|
**
|
||||||
|
** This instruction is used to implement the IN operator where the
|
||||||
|
** left-hand side is a SELECT statement. P1 is not a true index but
|
||||||
|
** is instead a temporary index that holds the results of the SELECT
|
||||||
|
** statement. This instruction just checks to see if the left-hand side
|
||||||
|
** of the IN operator (stored on the top of the stack) exists in the
|
||||||
|
** result of the SELECT statement.
|
||||||
**
|
**
|
||||||
** See also: Distinct, NotFound, MoveTo, IsUnique, NotExists
|
** See also: Distinct, NotFound, MoveTo, IsUnique, NotExists
|
||||||
*/
|
*/
|
||||||
/* Opcode: NotFound P1 P2 *
|
/* Opcode: NotFound P1 P2 *
|
||||||
**
|
**
|
||||||
** Use the top of the stack as a string key. If a record with that key
|
** The top of the stack holds a blob constructed by MakeRecord. P1 is
|
||||||
** does not exist in table of P1, then jump to P2. If the record
|
** an index. If no entry exists in P1 that matches the blob then jump
|
||||||
** does exist, then fall thru. The cursor is left pointing to the
|
** to P1. If an entry does existing, fall through. The cursor is left
|
||||||
** record if it exists. The key is popped from the stack.
|
** pointing to the entry that matches. The blob is popped from the stack.
|
||||||
**
|
**
|
||||||
** The difference between this operation and Distinct is that
|
** The difference between this operation and Distinct is that
|
||||||
** Distinct does not pop the key from the stack.
|
** Distinct does not pop the key from the stack.
|
||||||
@@ -2728,7 +2774,7 @@ case OP_Found: { /* no-push */
|
|||||||
assert( p->apCsr[i]!=0 );
|
assert( p->apCsr[i]!=0 );
|
||||||
if( (pC = p->apCsr[i])->pCursor!=0 ){
|
if( (pC = p->apCsr[i])->pCursor!=0 ){
|
||||||
int res, rx;
|
int res, rx;
|
||||||
assert( pC->intKey==0 );
|
assert( pC->isTable==0 );
|
||||||
Stringify(pTos, db->enc);
|
Stringify(pTos, db->enc);
|
||||||
rx = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
|
rx = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
|
||||||
alreadyExists = rx==SQLITE_OK && res==0;
|
alreadyExists = rx==SQLITE_OK && res==0;
|
||||||
@@ -2755,8 +2801,8 @@ case OP_Found: { /* no-push */
|
|||||||
** stack but it leaves K unchanged.
|
** stack but it leaves K unchanged.
|
||||||
**
|
**
|
||||||
** P1 is an index. So it has no data and its key consists of a
|
** P1 is an index. So it has no data and its key consists of a
|
||||||
** record generated by OP_MakeIdxKey. This key contains one or more
|
** record generated by OP_MakeRecord where the last field is the
|
||||||
** fields followed by a ROWID field.
|
** rowid of the entry that the index refers to.
|
||||||
**
|
**
|
||||||
** This instruction asks if there is an entry in P1 where the
|
** This instruction asks if there is an entry in P1 where the
|
||||||
** fields matches K but the rowid is different from R.
|
** fields matches K but the rowid is different from R.
|
||||||
@@ -2857,8 +2903,9 @@ case OP_IsUnique: { /* no-push */
|
|||||||
** record if it exists. The integer key is popped from the stack.
|
** record if it exists. The integer key is popped from the stack.
|
||||||
**
|
**
|
||||||
** The difference between this operation and NotFound is that this
|
** The difference between this operation and NotFound is that this
|
||||||
** operation assumes the key is an integer and NotFound assumes it
|
** operation assumes the key is an integer and that P1 is a table whereas
|
||||||
** is a string.
|
** NotFound assumes key is a blob constructed from MakeRecord and
|
||||||
|
** P1 is an index.
|
||||||
**
|
**
|
||||||
** See also: Distinct, Found, MoveTo, NotFound, IsUnique
|
** See also: Distinct, Found, MoveTo, NotFound, IsUnique
|
||||||
*/
|
*/
|
||||||
@@ -2873,16 +2920,16 @@ case OP_NotExists: { /* no-push */
|
|||||||
int res;
|
int res;
|
||||||
u64 iKey;
|
u64 iKey;
|
||||||
assert( pTos->flags & MEM_Int );
|
assert( pTos->flags & MEM_Int );
|
||||||
assert( p->apCsr[i]->intKey );
|
assert( p->apCsr[i]->isTable );
|
||||||
iKey = intToKey(pTos->i);
|
iKey = intToKey(pTos->i);
|
||||||
rc = sqlite3BtreeMoveto(pCrsr, 0, iKey, &res);
|
rc = sqlite3BtreeMoveto(pCrsr, 0, iKey, &res);
|
||||||
pC->lastRecno = pTos->i;
|
pC->lastRowid = pTos->i;
|
||||||
pC->recnoIsValid = res==0;
|
pC->rowidIsValid = res==0;
|
||||||
pC->nullRow = 0;
|
pC->nullRow = 0;
|
||||||
pC->cacheValid = 0;
|
pC->cacheValid = 0;
|
||||||
if( res!=0 ){
|
if( res!=0 ){
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
pC->recnoIsValid = 0;
|
pC->rowidIsValid = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Release(pTos);
|
Release(pTos);
|
||||||
@@ -2890,9 +2937,9 @@ case OP_NotExists: { /* no-push */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: NewRecno P1 P2 *
|
/* Opcode: NewRowid P1 P2 *
|
||||||
**
|
**
|
||||||
** Get a new integer record number used as the key to a table.
|
** Get a new integer record number (a.k.a "rowid") used as the key to a table.
|
||||||
** The record number is not previously used as a key in the database
|
** The record number is not previously used as a key in the database
|
||||||
** table that cursor P1 points to. The new record number is pushed
|
** table that cursor P1 points to. The new record number is pushed
|
||||||
** onto the stack.
|
** onto the stack.
|
||||||
@@ -2904,7 +2951,7 @@ case OP_NotExists: { /* no-push */
|
|||||||
** record number. This P2 mechanism is used to help implement the
|
** record number. This P2 mechanism is used to help implement the
|
||||||
** AUTOINCREMENT feature.
|
** AUTOINCREMENT feature.
|
||||||
*/
|
*/
|
||||||
case OP_NewRecno: {
|
case OP_NewRowid: {
|
||||||
int i = pOp->p1;
|
int i = pOp->p1;
|
||||||
i64 v = 0;
|
i64 v = 0;
|
||||||
Cursor *pC;
|
Cursor *pC;
|
||||||
@@ -3032,7 +3079,7 @@ case OP_NewRecno: {
|
|||||||
goto abort_due_to_error;
|
goto abort_due_to_error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pC->recnoIsValid = 0;
|
pC->rowidIsValid = 0;
|
||||||
pC->deferredMoveto = 0;
|
pC->deferredMoveto = 0;
|
||||||
pC->cacheValid = 0;
|
pC->cacheValid = 0;
|
||||||
}
|
}
|
||||||
@@ -3042,7 +3089,7 @@ case OP_NewRecno: {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: PutIntKey P1 P2 *
|
/* Opcode: Insert P1 P2 *
|
||||||
**
|
**
|
||||||
** 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
|
||||||
@@ -3054,19 +3101,11 @@ case OP_NewRecno: {
|
|||||||
** incremented (otherwise not). If the OPFLAG_LASTROWID flag of P2 is set,
|
** incremented (otherwise not). If the OPFLAG_LASTROWID flag of P2 is set,
|
||||||
** 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's unmodified).
|
** sqlite3_last_insert_rowid() function (otherwise it's unmodified).
|
||||||
*/
|
|
||||||
/* Opcode: PutStrKey P1 * *
|
|
||||||
**
|
**
|
||||||
** Write an entry into the table of cursor P1. A new entry is
|
** This instruction only works on tables. The equivalent instruction
|
||||||
** created if it doesn't already exist or the data for an existing
|
** for indices is OP_IdxInsert.
|
||||||
** entry is overwritten. The data is the value on the top of the
|
|
||||||
** stack. The key is the next value down on the stack. The key must
|
|
||||||
** be a string. The stack is popped twice by this instruction.
|
|
||||||
**
|
|
||||||
** P1 may not be a pseudo-table opened using the OpenPseudo opcode.
|
|
||||||
*/
|
*/
|
||||||
case OP_PutIntKey: /* no-push */
|
case OP_Insert: { /* no-push */
|
||||||
case OP_PutStrKey: { /* no-push */
|
|
||||||
Mem *pNos = &pTos[-1];
|
Mem *pNos = &pTos[-1];
|
||||||
int i = pOp->p1;
|
int i = pOp->p1;
|
||||||
Cursor *pC;
|
Cursor *pC;
|
||||||
@@ -3074,37 +3113,17 @@ case OP_PutStrKey: { /* no-push */
|
|||||||
assert( i>=0 && i<p->nCursor );
|
assert( i>=0 && i<p->nCursor );
|
||||||
assert( p->apCsr[i]!=0 );
|
assert( p->apCsr[i]!=0 );
|
||||||
if( ((pC = p->apCsr[i])->pCursor!=0 || pC->pseudoTable) ){
|
if( ((pC = p->apCsr[i])->pCursor!=0 || pC->pseudoTable) ){
|
||||||
char *zKey;
|
i64 iKey; /* The integer ROWID or key for the record to be inserted */
|
||||||
i64 nKey;
|
|
||||||
i64 iKey;
|
|
||||||
if( pOp->opcode==OP_PutStrKey ){
|
|
||||||
assert( pNos->flags & MEM_Blob );
|
|
||||||
Stringify(pNos, db->enc);
|
|
||||||
nKey = pNos->n;
|
|
||||||
zKey = pNos->z;
|
|
||||||
}else{
|
|
||||||
assert( pNos->flags & MEM_Int );
|
|
||||||
|
|
||||||
/* If the table is an INTKEY table, set nKey to the value of
|
assert( pNos->flags & MEM_Int );
|
||||||
** the integer key, and zKey to NULL. Otherwise, set nKey to
|
assert( pC->isTable );
|
||||||
** sizeof(i64) and point zKey at iKey. iKey contains the integer
|
|
||||||
** key in the on-disk byte order.
|
|
||||||
*/
|
|
||||||
iKey = intToKey(pNos->i);
|
iKey = intToKey(pNos->i);
|
||||||
if( pC->intKey ){
|
|
||||||
nKey = intToKey(pNos->i);
|
|
||||||
zKey = 0;
|
|
||||||
}else{
|
|
||||||
nKey = sizeof(i64);
|
|
||||||
zKey = (char*)&iKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
|
if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
|
||||||
if( pOp->p2 & OPFLAG_LASTROWID ) db->lastRowid = pNos->i;
|
if( pOp->p2 & OPFLAG_LASTROWID ) db->lastRowid = pNos->i;
|
||||||
if( pC->nextRowidValid && pTos->i>=pC->nextRowid ){
|
if( pC->nextRowidValid && pTos->i>=pC->nextRowid ){
|
||||||
pC->nextRowidValid = 0;
|
pC->nextRowidValid = 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if( pTos->flags & MEM_Null ){
|
if( pTos->flags & MEM_Null ){
|
||||||
pTos->z = 0;
|
pTos->z = 0;
|
||||||
pTos->n = 0;
|
pTos->n = 0;
|
||||||
@@ -3113,11 +3132,6 @@ assert( pNos->flags & MEM_Blob );
|
|||||||
}
|
}
|
||||||
#ifndef SQLITE_OMIT_TRIGGER
|
#ifndef SQLITE_OMIT_TRIGGER
|
||||||
if( pC->pseudoTable ){
|
if( pC->pseudoTable ){
|
||||||
/* PutStrKey does not work for pseudo-tables.
|
|
||||||
** The following assert makes sure we are not trying to use
|
|
||||||
** PutStrKey on a pseudo-table
|
|
||||||
*/
|
|
||||||
assert( pOp->opcode==OP_PutIntKey );
|
|
||||||
sqliteFree(pC->pData);
|
sqliteFree(pC->pData);
|
||||||
pC->iKey = iKey;
|
pC->iKey = iKey;
|
||||||
pC->nData = pTos->n;
|
pC->nData = pTos->n;
|
||||||
@@ -3134,12 +3148,12 @@ assert( pNos->flags & MEM_Blob );
|
|||||||
pC->nullRow = 0;
|
pC->nullRow = 0;
|
||||||
}else{
|
}else{
|
||||||
#endif
|
#endif
|
||||||
rc = sqlite3BtreeInsert(pC->pCursor, zKey, nKey, pTos->z, pTos->n);
|
rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey, pTos->z, pTos->n);
|
||||||
#ifndef SQLITE_OMIT_TRIGGER
|
#ifndef SQLITE_OMIT_TRIGGER
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pC->recnoIsValid = 0;
|
pC->rowidIsValid = 0;
|
||||||
pC->deferredMoveto = 0;
|
pC->deferredMoveto = 0;
|
||||||
pC->cacheValid = 0;
|
pC->cacheValid = 0;
|
||||||
}
|
}
|
||||||
@@ -3193,23 +3207,6 @@ case OP_ResetCount: { /* no-push */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: KeyAsData P1 P2 *
|
|
||||||
**
|
|
||||||
** Turn the key-as-data mode for cursor P1 either on (if P2==1) or
|
|
||||||
** off (if P2==0). In key-as-data mode, the OP_Column opcode pulls
|
|
||||||
** data off of the key rather than the data. This is used for
|
|
||||||
** processing compound selects.
|
|
||||||
*/
|
|
||||||
case OP_KeyAsData: { /* no-push */
|
|
||||||
int i = pOp->p1;
|
|
||||||
Cursor *pC;
|
|
||||||
assert( i>=0 && i<p->nCursor );
|
|
||||||
pC = p->apCsr[i];
|
|
||||||
assert( pC!=0 );
|
|
||||||
pC->keyAsData = pOp->p2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Opcode: RowData P1 * *
|
/* Opcode: RowData P1 * *
|
||||||
**
|
**
|
||||||
** Push onto the stack the complete row data for cursor P1.
|
** Push onto the stack the complete row data for cursor P1.
|
||||||
@@ -3234,9 +3231,12 @@ case OP_RowData: {
|
|||||||
Cursor *pC;
|
Cursor *pC;
|
||||||
u32 n;
|
u32 n;
|
||||||
|
|
||||||
|
/* Note that RowKey and RowData are really exactly the same instruction */
|
||||||
pTos++;
|
pTos++;
|
||||||
assert( i>=0 && i<p->nCursor );
|
assert( i>=0 && i<p->nCursor );
|
||||||
pC = p->apCsr[i];
|
pC = p->apCsr[i];
|
||||||
|
assert( pC->isTable || pOp->opcode==OP_RowKey );
|
||||||
|
assert( pC->isIndex || pOp->opcode==OP_RowData );
|
||||||
assert( pC!=0 );
|
assert( pC!=0 );
|
||||||
if( pC->nullRow ){
|
if( pC->nullRow ){
|
||||||
pTos->flags = MEM_Null;
|
pTos->flags = MEM_Null;
|
||||||
@@ -3247,13 +3247,12 @@ case OP_RowData: {
|
|||||||
if( pC->nullRow ){
|
if( pC->nullRow ){
|
||||||
pTos->flags = MEM_Null;
|
pTos->flags = MEM_Null;
|
||||||
break;
|
break;
|
||||||
}else if( pC->keyAsData || pOp->opcode==OP_RowKey ){
|
}else if( pC->isIndex ){
|
||||||
i64 n64;
|
i64 n64;
|
||||||
assert( !pC->intKey );
|
assert( !pC->isTable );
|
||||||
sqlite3BtreeKeySize(pCrsr, &n64);
|
sqlite3BtreeKeySize(pCrsr, &n64);
|
||||||
n = n64;
|
n = n64;
|
||||||
}else{
|
}else{
|
||||||
assert( pC->intKey );
|
|
||||||
sqlite3BtreeDataSize(pCrsr, &n);
|
sqlite3BtreeDataSize(pCrsr, &n);
|
||||||
}
|
}
|
||||||
pTos->n = n;
|
pTos->n = n;
|
||||||
@@ -3267,11 +3266,9 @@ assert( pC->intKey );
|
|||||||
pTos->xDel = 0;
|
pTos->xDel = 0;
|
||||||
pTos->z = z;
|
pTos->z = z;
|
||||||
}
|
}
|
||||||
if( pC->keyAsData || pOp->opcode==OP_RowKey ){
|
if( pC->isIndex ){
|
||||||
assert( !pC->intKey );
|
|
||||||
sqlite3BtreeKey(pCrsr, 0, n, pTos->z);
|
sqlite3BtreeKey(pCrsr, 0, n, pTos->z);
|
||||||
}else{
|
}else{
|
||||||
assert( pC->intKey );
|
|
||||||
sqlite3BtreeData(pCrsr, 0, n, pTos->z);
|
sqlite3BtreeData(pCrsr, 0, n, pTos->z);
|
||||||
}
|
}
|
||||||
#ifndef SQLITE_OMIT_TRIGGER
|
#ifndef SQLITE_OMIT_TRIGGER
|
||||||
@@ -3286,14 +3283,12 @@ assert( pC->intKey );
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: Recno P1 * *
|
/* Opcode: Rowid P1 * *
|
||||||
**
|
**
|
||||||
** Push onto the stack an integer which is the first 4 bytes of the
|
** Push onto the stack an integer which is the key of the table entry that
|
||||||
** the key to the current entry in a sequential scan of the database
|
** P1 is currently point to.
|
||||||
** file P1. The sequential scan should have been started using the
|
|
||||||
** Next opcode.
|
|
||||||
*/
|
*/
|
||||||
case OP_Recno: {
|
case OP_Rowid: {
|
||||||
int i = pOp->p1;
|
int i = pOp->p1;
|
||||||
Cursor *pC;
|
Cursor *pC;
|
||||||
i64 v;
|
i64 v;
|
||||||
@@ -3304,8 +3299,8 @@ case OP_Recno: {
|
|||||||
rc = sqlite3VdbeCursorMoveto(pC);
|
rc = sqlite3VdbeCursorMoveto(pC);
|
||||||
if( rc ) goto abort_due_to_error;
|
if( rc ) goto abort_due_to_error;
|
||||||
pTos++;
|
pTos++;
|
||||||
if( pC->recnoIsValid ){
|
if( pC->rowidIsValid ){
|
||||||
v = pC->lastRecno;
|
v = pC->lastRowid;
|
||||||
}else if( pC->pseudoTable ){
|
}else if( pC->pseudoTable ){
|
||||||
v = keyToInt(pC->iKey);
|
v = keyToInt(pC->iKey);
|
||||||
}else if( pC->nullRow || pC->pCursor==0 ){
|
}else if( pC->nullRow || pC->pCursor==0 ){
|
||||||
@@ -3335,13 +3330,13 @@ case OP_NullRow: { /* no-push */
|
|||||||
pC = p->apCsr[i];
|
pC = p->apCsr[i];
|
||||||
assert( pC!=0 );
|
assert( pC!=0 );
|
||||||
pC->nullRow = 1;
|
pC->nullRow = 1;
|
||||||
pC->recnoIsValid = 0;
|
pC->rowidIsValid = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: Last P1 P2 *
|
/* Opcode: Last P1 P2 *
|
||||||
**
|
**
|
||||||
** The next use of the Recno or Column or Next instruction for P1
|
** The next use of the Rowid or Column or Next instruction for P1
|
||||||
** will refer to the last entry in the database table or index.
|
** will refer to the last entry in the database table or index.
|
||||||
** If the table or index is empty and P2>0, then jump immediately to P2.
|
** If the table or index is empty and P2>0, then jump immediately to P2.
|
||||||
** If P2 is 0 or if the table or index is not empty, fall through
|
** If P2 is 0 or if the table or index is not empty, fall through
|
||||||
@@ -3372,7 +3367,7 @@ case OP_Last: { /* no-push */
|
|||||||
|
|
||||||
/* Opcode: Rewind P1 P2 *
|
/* Opcode: Rewind P1 P2 *
|
||||||
**
|
**
|
||||||
** The next use of the Recno or Column or Next instruction for P1
|
** The next use of the Rowid or Column or Next instruction for P1
|
||||||
** will refer to the first entry in the database table or index.
|
** will refer to the first entry in the database table or index.
|
||||||
** If the table or index is empty and P2>0, then jump immediately to P2.
|
** If the table or index is empty and P2>0, then jump immediately to P2.
|
||||||
** If P2 is 0 or if the table or index is not empty, fall through
|
** If P2 is 0 or if the table or index is not empty, fall through
|
||||||
@@ -3445,11 +3440,11 @@ case OP_Next: { /* no-push */
|
|||||||
}else{
|
}else{
|
||||||
pC->nullRow = 1;
|
pC->nullRow = 1;
|
||||||
}
|
}
|
||||||
pC->recnoIsValid = 0;
|
pC->rowidIsValid = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: IdxPut P1 P2 P3
|
/* Opcode: IdxInsert P1 P2 P3
|
||||||
**
|
**
|
||||||
** The top of the stack holds a SQL index key made using the
|
** The top of the stack holds a SQL index key made using the
|
||||||
** MakeIdxKey instruction. This opcode writes that key into the
|
** MakeIdxKey instruction. This opcode writes that key into the
|
||||||
@@ -3459,8 +3454,11 @@ case OP_Next: { /* no-push */
|
|||||||
** the program aborts with a SQLITE_CONSTRAINT error and the database
|
** the program aborts with a SQLITE_CONSTRAINT error and the database
|
||||||
** is rolled back. If P3 is not null, then it becomes part of the
|
** is rolled back. If P3 is not null, then it becomes part of the
|
||||||
** error message returned with the SQLITE_CONSTRAINT.
|
** error message returned with the SQLITE_CONSTRAINT.
|
||||||
|
**
|
||||||
|
** This instruction only works for indices. The equivalent instruction
|
||||||
|
** for tables is OP_Insert.
|
||||||
*/
|
*/
|
||||||
case OP_IdxPut: { /* no-push */
|
case OP_IdxInsert: { /* no-push */
|
||||||
int i = pOp->p1;
|
int i = pOp->p1;
|
||||||
Cursor *pC;
|
Cursor *pC;
|
||||||
BtCursor *pCrsr;
|
BtCursor *pCrsr;
|
||||||
@@ -3497,7 +3495,7 @@ case OP_IdxPut: { /* no-push */
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert( pC->intKey==0 );
|
assert( pC->isTable==0 );
|
||||||
rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0);
|
rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0);
|
||||||
assert( pC->deferredMoveto==0 );
|
assert( pC->deferredMoveto==0 );
|
||||||
pC->cacheValid = 0;
|
pC->cacheValid = 0;
|
||||||
@@ -3534,15 +3532,15 @@ case OP_IdxDelete: { /* no-push */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: IdxRecno P1 * *
|
/* Opcode: IdxRowid P1 * *
|
||||||
**
|
**
|
||||||
** Push onto the stack an integer which is the varint located at the
|
** Push onto the stack an integer which is the last entry in the record at
|
||||||
** end of the index key pointed to by cursor P1. This integer should be
|
** the end of the index key pointed to by cursor P1. This integer should be
|
||||||
** the record number of the table entry to which this index entry points.
|
** the rowid of the table entry to which this index entry points.
|
||||||
**
|
**
|
||||||
** See also: Recno, MakeIdxKey.
|
** See also: Rowid, MakeIdxKey.
|
||||||
*/
|
*/
|
||||||
case OP_IdxRecno: {
|
case OP_IdxRowid: {
|
||||||
int i = pOp->p1;
|
int i = pOp->p1;
|
||||||
BtCursor *pCrsr;
|
BtCursor *pCrsr;
|
||||||
Cursor *pC;
|
Cursor *pC;
|
||||||
@@ -3555,7 +3553,7 @@ case OP_IdxRecno: {
|
|||||||
i64 rowid;
|
i64 rowid;
|
||||||
|
|
||||||
assert( pC->deferredMoveto==0 );
|
assert( pC->deferredMoveto==0 );
|
||||||
assert( pC->intKey==0 );
|
assert( pC->isTable==0 );
|
||||||
if( pC->nullRow ){
|
if( pC->nullRow ){
|
||||||
pTos->flags = MEM_Null;
|
pTos->flags = MEM_Null;
|
||||||
}else{
|
}else{
|
||||||
@@ -4060,13 +4058,13 @@ case OP_ContextPop: { /* no-push */
|
|||||||
}
|
}
|
||||||
#endif /* #ifndef SQLITE_OMIT_TRIGGER */
|
#endif /* #ifndef SQLITE_OMIT_TRIGGER */
|
||||||
|
|
||||||
/* Opcode: SortPut * * *
|
/* Opcode: SortInsert * * *
|
||||||
**
|
**
|
||||||
** The TOS is the key and the NOS is the data. Pop both from the stack
|
** The TOS is the key and the NOS is the data. Pop both from the stack
|
||||||
** and put them on the sorter. The key and data should have been
|
** and put them on the sorter. The key and data should have been
|
||||||
** made using the MakeRecord opcode.
|
** made using the MakeRecord opcode.
|
||||||
*/
|
*/
|
||||||
case OP_SortPut: { /* no-push */
|
case OP_SortInsert: { /* no-push */
|
||||||
Mem *pNos = &pTos[-1];
|
Mem *pNos = &pTos[-1];
|
||||||
Sorter *pSorter;
|
Sorter *pSorter;
|
||||||
assert( pNos>=p->aStack );
|
assert( pNos>=p->aStack );
|
||||||
|
@@ -60,19 +60,18 @@ typedef unsigned char Bool;
|
|||||||
*/
|
*/
|
||||||
struct Cursor {
|
struct Cursor {
|
||||||
BtCursor *pCursor; /* The cursor structure of the backend */
|
BtCursor *pCursor; /* The cursor structure of the backend */
|
||||||
i64 lastRecno; /* Last recno from a Next or NextIdx operation */
|
i64 lastRowid; /* Last rowid from a Next or NextIdx operation */
|
||||||
i64 nextRowid; /* Next rowid returned by OP_NewRowid */
|
i64 nextRowid; /* Next rowid returned by OP_NewRowid */
|
||||||
Bool zeroed; /* True if zeroed out and ready for reuse */
|
Bool zeroed; /* True if zeroed out and ready for reuse */
|
||||||
Bool recnoIsValid; /* True if lastRecno is valid */
|
Bool rowidIsValid; /* True if lastRowid is valid */
|
||||||
Bool keyAsData; /* The OP_Column command works on key instead of data */
|
|
||||||
Bool atFirst; /* True if pointing to first entry */
|
Bool atFirst; /* True if pointing to first entry */
|
||||||
Bool useRandomRowid; /* Generate new record numbers semi-randomly */
|
Bool useRandomRowid; /* Generate new record numbers semi-randomly */
|
||||||
Bool nullRow; /* True if pointing to a row with no data */
|
Bool nullRow; /* True if pointing to a row with no data */
|
||||||
Bool nextRowidValid; /* True if the nextRowid field is valid */
|
Bool nextRowidValid; /* True if the nextRowid field is valid */
|
||||||
Bool pseudoTable; /* This is a NEW or OLD pseudo-tables of a trigger */
|
Bool pseudoTable; /* This is a NEW or OLD pseudo-tables of a trigger */
|
||||||
Bool deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */
|
Bool deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */
|
||||||
Bool intKey; /* True if the table requires integer keys */
|
Bool isTable; /* True if a table requiring integer keys */
|
||||||
Bool zeroData; /* True if table contains keys only - no data */
|
Bool isIndex; /* True if an index containing keys only - no data */
|
||||||
u8 bogusIncrKey; /* Something for pIncrKey to point to if pKeyInfo==0 */
|
u8 bogusIncrKey; /* Something for pIncrKey to point to if pKeyInfo==0 */
|
||||||
i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */
|
i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */
|
||||||
Btree *pBt; /* Separate file holding temporary table */
|
Btree *pBt; /* Separate file holding temporary table */
|
||||||
|
@@ -223,7 +223,7 @@ int sqlite3VdbeOpcodeNoPush(u8 op){
|
|||||||
**
|
**
|
||||||
** This routine also does the following optimization: It scans for
|
** This routine also does the following optimization: It scans for
|
||||||
** Halt instructions where P1==SQLITE_CONSTRAINT or P2==OE_Abort or for
|
** Halt instructions where P1==SQLITE_CONSTRAINT or P2==OE_Abort or for
|
||||||
** IdxPut instructions where P2!=0. If no such instruction is
|
** IdxInsert instructions where P2!=0. If no such instruction is
|
||||||
** found, then every Statement instruction is changed to a Noop. In
|
** found, then every Statement instruction is changed to a Noop. In
|
||||||
** this way, we avoid creating the statement journal file unnecessarily.
|
** this way, we avoid creating the statement journal file unnecessarily.
|
||||||
*/
|
*/
|
||||||
@@ -249,7 +249,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs, int *pMaxStack){
|
|||||||
if( pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort ){
|
if( pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort ){
|
||||||
doesStatementRollback = 1;
|
doesStatementRollback = 1;
|
||||||
}
|
}
|
||||||
}else if( opcode==OP_IdxPut ){
|
}else if( opcode==OP_IdxInsert ){
|
||||||
if( pOp->p2 ){
|
if( pOp->p2 ){
|
||||||
doesStatementRollback = 1;
|
doesStatementRollback = 1;
|
||||||
}
|
}
|
||||||
@@ -1572,8 +1572,8 @@ int sqlite3VdbeCursorMoveto(Cursor *p){
|
|||||||
if( p->deferredMoveto ){
|
if( p->deferredMoveto ){
|
||||||
int res, rc;
|
int res, rc;
|
||||||
extern int sqlite3_search_count;
|
extern int sqlite3_search_count;
|
||||||
assert( p->intKey );
|
assert( p->isTable );
|
||||||
if( p->intKey ){
|
if( p->isTable ){
|
||||||
rc = sqlite3BtreeMoveto(p->pCursor, 0, p->movetoTarget, &res);
|
rc = sqlite3BtreeMoveto(p->pCursor, 0, p->movetoTarget, &res);
|
||||||
}else{
|
}else{
|
||||||
rc = sqlite3BtreeMoveto(p->pCursor,(char*)&p->movetoTarget,
|
rc = sqlite3BtreeMoveto(p->pCursor,(char*)&p->movetoTarget,
|
||||||
@@ -1581,8 +1581,8 @@ int sqlite3VdbeCursorMoveto(Cursor *p){
|
|||||||
}
|
}
|
||||||
if( rc ) return rc;
|
if( rc ) return rc;
|
||||||
*p->pIncrKey = 0;
|
*p->pIncrKey = 0;
|
||||||
p->lastRecno = keyToInt(p->movetoTarget);
|
p->lastRowid = keyToInt(p->movetoTarget);
|
||||||
p->recnoIsValid = res==0;
|
p->rowidIsValid = res==0;
|
||||||
if( res<0 ){
|
if( res<0 ){
|
||||||
rc = sqlite3BtreeNext(p->pCursor, &res);
|
rc = sqlite3BtreeNext(p->pCursor, &res);
|
||||||
if( rc ) return rc;
|
if( rc ) return rc;
|
||||||
|
20
src/where.c
20
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.138 2005/05/19 01:26:14 drh Exp $
|
** $Id: where.c,v 1.139 2005/06/12 21:35:53 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -497,7 +497,6 @@ static void codeEqualityTerm(
|
|||||||
sqlite3CodeSubselect(pParse, pX);
|
sqlite3CodeSubselect(pParse, pX);
|
||||||
iTab = pX->iTable;
|
iTab = pX->iTable;
|
||||||
sqlite3VdbeAddOp(v, OP_Rewind, iTab, brk);
|
sqlite3VdbeAddOp(v, OP_Rewind, iTab, brk);
|
||||||
sqlite3VdbeAddOp(v, OP_KeyAsData, iTab, 1);
|
|
||||||
VdbeComment((v, "# %.*s", pX->span.n, pX->span.z));
|
VdbeComment((v, "# %.*s", pX->span.n, pX->span.z));
|
||||||
pLevel->inP2 = sqlite3VdbeAddOp(v, OP_Column, iTab, 0);
|
pLevel->inP2 = sqlite3VdbeAddOp(v, OP_Column, iTab, 0);
|
||||||
pLevel->inOp = OP_Next;
|
pLevel->inOp = OP_Next;
|
||||||
@@ -546,7 +545,7 @@ static void codeEqualityTerm(
|
|||||||
**
|
**
|
||||||
** The code that sqlite3WhereBegin() generates leaves the cursors named
|
** The code that sqlite3WhereBegin() generates leaves the cursors named
|
||||||
** in pTabList pointing at their appropriate entries. The [...] code
|
** in pTabList pointing at their appropriate entries. The [...] code
|
||||||
** can use OP_Column and OP_Recno opcodes on these cursors to extract
|
** can use OP_Column and OP_Rowid opcodes on these cursors to extract
|
||||||
** data from the various tables of the loop.
|
** data from the various tables of the loop.
|
||||||
**
|
**
|
||||||
** If the WHERE clause is empty, the foreach loops must each scan their
|
** If the WHERE clause is empty, the foreach loops must each scan their
|
||||||
@@ -949,7 +948,6 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
(char*)&pIx->keyInfo, P3_KEYINFO);
|
(char*)&pIx->keyInfo, P3_KEYINFO);
|
||||||
}
|
}
|
||||||
if( (pLevel->score & 1)!=0 ){
|
if( (pLevel->score & 1)!=0 ){
|
||||||
sqlite3VdbeAddOp(v, OP_KeyAsData, iIdxCur, 1);
|
|
||||||
sqlite3VdbeAddOp(v, OP_SetNumColumns, iIdxCur, pIx->nColumn+1);
|
sqlite3VdbeAddOp(v, OP_SetNumColumns, iIdxCur, pIx->nColumn+1);
|
||||||
}
|
}
|
||||||
sqlite3CodeVerifySchema(pParse, pTab->iDb);
|
sqlite3CodeVerifySchema(pParse, pTab->iDb);
|
||||||
@@ -984,7 +982,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
if( i>0 && (pTabList->a[i-1].jointype & JT_LEFT)!=0 ){
|
if( i>0 && (pTabList->a[i-1].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_String8, 0, 0);
|
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1);
|
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1);
|
||||||
VdbeComment((v, "# init LEFT JOIN no-match flag"));
|
VdbeComment((v, "# init LEFT JOIN no-match flag"));
|
||||||
}
|
}
|
||||||
@@ -1061,7 +1059,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0);
|
sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_IdxIsNull, nColumn, cont);
|
sqlite3VdbeAddOp(v, OP_IdxIsNull, nColumn, cont);
|
||||||
if( !omitTable ){
|
if( !omitTable ){
|
||||||
sqlite3VdbeAddOp(v, OP_IdxRecno, iIdxCur, 0);
|
sqlite3VdbeAddOp(v, OP_IdxRowid, iIdxCur, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
|
sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
|
||||||
}
|
}
|
||||||
pLevel->p1 = iIdxCur;
|
pLevel->p1 = iIdxCur;
|
||||||
@@ -1120,9 +1118,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_Recno, iCur, 0);
|
sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
|
sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
|
||||||
sqlite3VdbeAddOp(v, testOp, (int)(('n'<<8)&0x0000FF00), brk);
|
sqlite3VdbeAddOp(v, testOp, 'n', brk);
|
||||||
}
|
}
|
||||||
}else if( pIdx==0 ){
|
}else if( pIdx==0 ){
|
||||||
/* Case 4: There is no usable index. We must do a complete
|
/* Case 4: There is no usable index. We must do a complete
|
||||||
@@ -1295,7 +1293,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0);
|
sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_IdxIsNull, nEqColumn + ((score&4)!=0), cont);
|
sqlite3VdbeAddOp(v, OP_IdxIsNull, nEqColumn + ((score&4)!=0), cont);
|
||||||
if( !omitTable ){
|
if( !omitTable ){
|
||||||
sqlite3VdbeAddOp(v, OP_IdxRecno, iIdxCur, 0);
|
sqlite3VdbeAddOp(v, OP_IdxRowid, iIdxCur, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
|
sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1424,9 +1422,9 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else if( pOp->opcode==OP_Recno ){
|
}else if( pOp->opcode==OP_Rowid ){
|
||||||
pOp->p1 = pLevel->iIdxCur;
|
pOp->p1 = pLevel->iIdxCur;
|
||||||
pOp->opcode = OP_IdxRecno;
|
pOp->opcode = OP_IdxRowid;
|
||||||
}else if( pOp->opcode==OP_NullRow ){
|
}else if( pOp->opcode==OP_NullRow ){
|
||||||
pOp->opcode = OP_Noop;
|
pOp->opcode = OP_Noop;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user