1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-09 14:21:03 +03:00

Add a count parameter to the OP_Variable opcode and use it to simplify

prepared statements that copy consecutive unnamed parameters into
consecutive registers (a common case). (CVS 6309)

FossilOrigin-Name: 48b77b04935d8942eb22f0c061f3bc5e99bbd7db
This commit is contained in:
drh
2009-02-20 03:55:05 +00:00
parent 5053a79b6c
commit 08de14908d
6 changed files with 129 additions and 32 deletions

View File

@@ -1,5 +1,5 @@
C Add\sthe\sOP_HaltIfNull\sopcode\sand\suse\sit\sto\ssimplify\sprepared\sstatements\nfor\sINSERTs\sand\sUPDATEs\sof\stables\swith\sNOT\sNULL\scolumns.\s(CVS\s6308) C Add\sa\scount\sparameter\sto\sthe\sOP_Variable\sopcode\sand\suse\sit\sto\ssimplify\nprepared\sstatements\sthat\scopy\sconsecutive\sunnamed\sparameters\sinto\nconsecutive\sregisters\s(a\scommon\scase).\s(CVS\s6309)
D 2009-02-20T03:02:24 D 2009-02-20T03:55:05
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 1d83fa2b1fd326b9e121012bd1ff9740537e12b3 F Makefile.in 1d83fa2b1fd326b9e121012bd1ff9740537e12b3
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -112,7 +112,7 @@ F src/callback.c 5f10bca853e59a2c272bbfd5b720303f8b69e520
F src/complete.c cb14e06dbe79dee031031f0d9e686ff306afe07c F src/complete.c cb14e06dbe79dee031031f0d9e686ff306afe07c
F src/date.c 0d804df3bbda46329946a01ff5c75c3f4f135218 F src/date.c 0d804df3bbda46329946a01ff5c75c3f4f135218
F src/delete.c 8d2fb05b32b5dea65277a574fedb0ebaa5dd877c F src/delete.c 8d2fb05b32b5dea65277a574fedb0ebaa5dd877c
F src/expr.c 2e62c2621c0375125cacb93ad6686bb2911b629e F src/expr.c 92e6dfcd55bdffbed8c66627700d1b5c5f9889d3
F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff
F src/func.c 2fb36cd7cc24e16845db203187d1e52811b0fa9c F src/func.c 2fb36cd7cc24e16845db203187d1e52811b0fa9c
F src/global.c 448419c44ce0701104c2121b0e06919b44514c0c F src/global.c 448419c44ce0701104c2121b0e06919b44514c0c
@@ -200,12 +200,12 @@ F src/update.c 9edb83cc4322fb2dc5b7a0087cdb8fa00391f402
F src/utf.c 1da9c832dba0fa8f865b5b902d93f420a1ee4245 F src/utf.c 1da9c832dba0fa8f865b5b902d93f420a1ee4245
F src/util.c 1363f64351f3b544790f3c523439354c02f8c4e9 F src/util.c 1363f64351f3b544790f3c523439354c02f8c4e9
F src/vacuum.c 4929a585ef0fb1dfaf46302f8a9c4aa30c2d9cf5 F src/vacuum.c 4929a585ef0fb1dfaf46302f8a9c4aa30c2d9cf5
F src/vdbe.c 4533be29b997c609c6fbafeeb6985f3ec9070d8c F src/vdbe.c 3bd3acffddf8a284d3e8c1df0e286389aaf09e1a
F src/vdbe.h d70a68bee196ab228914a3902c79dbd24342a0f2 F src/vdbe.h d70a68bee196ab228914a3902c79dbd24342a0f2
F src/vdbeInt.h d12bc259b34d3d610ebf05d648eb6346d48478c3 F src/vdbeInt.h d12bc259b34d3d610ebf05d648eb6346d48478c3
F src/vdbeapi.c f94fe2eb6f48687e918f0df7eed1409cff9dcf58 F src/vdbeapi.c f94fe2eb6f48687e918f0df7eed1409cff9dcf58
F src/vdbeaux.c dd5fc23bae4647d40b00ac308acd85f5c862f01e F src/vdbeaux.c dd5fc23bae4647d40b00ac308acd85f5c862f01e
F src/vdbeblob.c b0dcebfafedcf9c0addc7901ad98f6f986c08935 F src/vdbeblob.c b06daa322e220f30dec55032c4e60e00346e153b
F src/vdbemem.c 543a79d722734d2f8b7ad70f08218c30bcc5bbf5 F src/vdbemem.c 543a79d722734d2f8b7ad70f08218c30bcc5bbf5
F src/vtab.c e39e011d7443a8d574b1b9cde207a35522e6df43 F src/vtab.c e39e011d7443a8d574b1b9cde207a35522e6df43
F src/walker.c 42bd3f00ca2ef5ae842304ec0d59903ef051412d F src/walker.c 42bd3f00ca2ef5ae842304ec0d59903ef051412d
@@ -241,7 +241,7 @@ F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f
F test/between.test 16b1776c6323faadb097a52d673e8e3d8be7d070 F test/between.test 16b1776c6323faadb097a52d673e8e3d8be7d070
F test/bigfile.test 6adfef13d24bbe0c504b4547f292b9a170184f25 F test/bigfile.test 6adfef13d24bbe0c504b4547f292b9a170184f25
F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747 F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747
F test/bind.test 3d719310b548c18d979af495ee7d80b2d9a974b0 F test/bind.test 455f7e8322a215e245414625eede3ab0e1429c14
F test/bindxfer.test d4f573750e06c34ef2309acb95ad57da1d3c983f F test/bindxfer.test d4f573750e06c34ef2309acb95ad57da1d3c983f
F test/bitvec.test ecea9aa315f36991e56e326701279b7775cb2bef F test/bitvec.test ecea9aa315f36991e56e326701279b7775cb2bef
F test/blob.test 2a38d867bdf08f9ce081776acec1ac8d4bca66be F test/blob.test 2a38d867bdf08f9ce081776acec1ac8d4bca66be
@@ -701,7 +701,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
P 58a1809257ccfb7d9112a35f79ca2f82b3daa878 P feccad8d0d05925ce67856d40ffe1bc7054168a0
R 0d19680e8f7c0d8be240916afd3b0973 R 45f3343e100f8675023b5adecf1a6bda
U drh U drh
Z d22ccd96d684ea638dc65d902b36ccb1 Z 9ee82f1e63cdb67ae7cf41ec0375cf20

View File

@@ -1 +1 @@
feccad8d0d05925ce67856d40ffe1bc7054168a0 48b77b04935d8942eb22f0c061f3bc5e99bbd7db

View File

@@ -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.412 2009/02/19 14:39:25 danielk1977 Exp $ ** $Id: expr.c,v 1.413 2009/02/20 03:55:05 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -2002,9 +2002,26 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
} }
#endif #endif
case TK_VARIABLE: { case TK_VARIABLE: {
sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iTable, target); int iPrior;
if( pExpr->token.n>1 ){ VdbeOp *pOp;
sqlite3VdbeChangeP4(v, -1, (char*)pExpr->token.z, pExpr->token.n); if( pExpr->token.n<=1
&& (iPrior = sqlite3VdbeCurrentAddr(v)-1)>=0
&& (pOp = sqlite3VdbeGetOp(v, iPrior))->opcode==OP_Variable
&& pOp->p1+pOp->p3==pExpr->iTable
&& pOp->p2+pOp->p3==target
&& pOp->p4.z==0
){
/* If the previous instruction was a copy of the previous unnamed
** parameter into the previous register, then simply increment the
** repeat count on the prior instruction rather than making a new
** instruction.
*/
pOp->p3++;
}else{
sqlite3VdbeAddOp3(v, OP_Variable, pExpr->iTable, target, 1);
if( pExpr->token.n>1 ){
sqlite3VdbeChangeP4(v, -1, (char*)pExpr->token.z, pExpr->token.n);
}
} }
break; break;
} }

View File

@@ -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.819 2009/02/20 03:02:25 drh Exp $ ** $Id: vdbe.c,v 1.820 2009/02/20 03:55:05 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include "vdbeInt.h" #include "vdbeInt.h"
@@ -977,26 +977,34 @@ case OP_Blob: { /* out2-prerelease */
break; break;
} }
/* Opcode: Variable P1 P2 * * * /* Opcode: Variable P1 P2 P3 P4 *
** **
** The value of variable P1 is written into register P2. A variable is ** Transfer the values of bound parameters P1..P1+P3-1 into registers
** an unknown in the original SQL string as handed to sqlite3_compile(). ** P2..P2+P3-1.
** Any occurrence of the '?' character in the original SQL is considered **
** a variable. Variables in the SQL string are number from left to ** If the parameter is named, then its name appears in P4 and P3==1.
** right beginning with 1. The values of variables are set using the ** The P4 value is used by sqlite3_bind_parameter_name().
** sqlite3_bind() API.
*/ */
case OP_Variable: { /* out2-prerelease */ case OP_Variable: {
int j = pOp->p1 - 1; int j = pOp->p1 - 1;
int k = pOp->p2;
Mem *pVar; Mem *pVar;
assert( j>=0 && j<p->nVar ); int n = pOp->p3;
assert( j>=0 && j+n<=p->nVar );
assert( k>=1 && k+n-1<=p->nMem );
assert( pOp->p4.z==0 || pOp->p3==1 );
pVar = &p->aVar[j]; while( n-- > 0 ){
if( sqlite3VdbeMemTooBig(pVar) ){ pVar = &p->aVar[j++];
goto too_big; if( sqlite3VdbeMemTooBig(pVar) ){
goto too_big;
}
pOut = &p->aMem[k++];
sqlite3VdbeMemReleaseExternal(pOut);
pOut->flags = MEM_Null;
sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static);
UPDATE_MAX_BLOBSIZE(pOut);
} }
sqlite3VdbeMemShallowCopy(pOut, &p->aVar[j], MEM_Static);
UPDATE_MAX_BLOBSIZE(pOut);
break; break;
} }

View File

@@ -12,7 +12,7 @@
** **
** This file contains code used to implement incremental BLOB I/O. ** This file contains code used to implement incremental BLOB I/O.
** **
** $Id: vdbeblob.c,v 1.26 2008/10/02 14:49:02 danielk1977 Exp $ ** $Id: vdbeblob.c,v 1.27 2009/02/20 03:55:05 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -75,7 +75,7 @@ int sqlite3_blob_open(
{OP_SetNumColumns, 0, 0, 0}, /* 4: Num cols for cursor */ {OP_SetNumColumns, 0, 0, 0}, /* 4: Num cols for cursor */
{OP_OpenWrite, 0, 0, 0}, /* 5: Open cursor 0 for read/write */ {OP_OpenWrite, 0, 0, 0}, /* 5: Open cursor 0 for read/write */
{OP_Variable, 1, 1, 0}, /* 6: Push the rowid to the stack */ {OP_Variable, 1, 1, 1}, /* 6: Push the rowid to the stack */
{OP_NotExists, 0, 10, 1}, /* 7: Seek the cursor */ {OP_NotExists, 0, 10, 1}, /* 7: Seek the cursor */
{OP_Column, 0, 0, 1}, /* 8 */ {OP_Column, 0, 0, 1}, /* 8 */
{OP_ResultRow, 1, 0, 0}, /* 9 */ {OP_ResultRow, 1, 0, 0}, /* 9 */

View File

@@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The # This file implements regression tests for SQLite library. The
# focus of this script testing the sqlite_bind API. # focus of this script testing the sqlite_bind API.
# #
# $Id: bind.test,v 1.46 2009/02/09 05:18:33 danielk1977 Exp $ # $Id: bind.test,v 1.47 2009/02/20 03:55:05 drh Exp $
# #
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
@@ -683,4 +683,76 @@ do_test bind-14.4 {
param_names db { SELECT @a, @b FROM (SELECT NULL) } param_names db { SELECT @a, @b FROM (SELECT NULL) }
} {@a @b} } {@a @b}
#--------------------------------------------------------------------------
# Tests of the OP_Variable opcode where P3>1
#
do_test bind-15.1 {
db eval {CREATE TABLE t4(a,b,c,d,e,f,g,h);}
set VM [sqlite3_prepare db {
INSERT INTO t4(a,b,c,d,f,g,h,e) VALUES(?,?,?,?,?,?,?,?)
} -1 TAIL]
sqlite3_bind_int $VM 1 1
sqlite3_bind_int $VM 2 2
sqlite3_bind_int $VM 3 3
sqlite3_bind_int $VM 4 4
sqlite3_bind_int $VM 5 5
sqlite3_bind_int $VM 6 6
sqlite3_bind_int $VM 7 7
sqlite3_bind_int $VM 8 8
sqlite3_step $VM
sqlite3_finalize $VM
db eval {SELECT * FROM t4}
} {1 2 3 4 8 5 6 7}
do_test bind-15.2 {
db eval {DELETE FROM t4}
set VM [sqlite3_prepare db {
INSERT INTO t4(a,b,c,d,e,f,g,h) VALUES(?,?,?,?,?,?,?,?)
} -1 TAIL]
sqlite3_bind_int $VM 1 1
sqlite3_bind_int $VM 2 2
sqlite3_bind_int $VM 3 3
sqlite3_bind_int $VM 4 4
sqlite3_bind_int $VM 5 5
sqlite3_bind_int $VM 6 6
sqlite3_bind_int $VM 7 7
sqlite3_bind_int $VM 8 8
sqlite3_step $VM
sqlite3_finalize $VM
db eval {SELECT * FROM t4}
} {1 2 3 4 5 6 7 8}
do_test bind-15.3 {
db eval {DELETE FROM t4}
set VM [sqlite3_prepare db {
INSERT INTO t4(h,g,f,e,d,c,b,a) VALUES(?,?,?,?,?,?,?,?)
} -1 TAIL]
sqlite3_bind_int $VM 1 1
sqlite3_bind_int $VM 2 2
sqlite3_bind_int $VM 3 3
sqlite3_bind_int $VM 4 4
sqlite3_bind_int $VM 5 5
sqlite3_bind_int $VM 6 6
sqlite3_bind_int $VM 7 7
sqlite3_bind_int $VM 8 8
sqlite3_step $VM
sqlite3_finalize $VM
db eval {SELECT * FROM t4}
} {8 7 6 5 4 3 2 1}
do_test bind-15.4 {
db eval {DELETE FROM t4}
set VM [sqlite3_prepare db {
INSERT INTO t4(a,b,c,d,e,f,g,h) VALUES(?,?,?,?4,?,?6,?,?)
} -1 TAIL]
sqlite3_bind_int $VM 1 1
sqlite3_bind_int $VM 2 2
sqlite3_bind_int $VM 3 3
sqlite3_bind_int $VM 4 4
sqlite3_bind_int $VM 5 5
sqlite3_bind_int $VM 6 6
sqlite3_bind_int $VM 7 7
sqlite3_bind_int $VM 8 8
sqlite3_step $VM
sqlite3_finalize $VM
db eval {SELECT * FROM t4}
} {1 2 3 4 5 6 7 8}
finish_test finish_test