From: drh Date: Fri, 20 Feb 2009 03:55:05 +0000 (+0000) Subject: Add a count parameter to the OP_Variable opcode and use it to simplify X-Git-Tag: version-3.6.15~441 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=08de14908d354c34206db249807703683e84676a;p=thirdparty%2Fsqlite.git 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 --- diff --git a/manifest b/manifest index d53a3cff4e..2fe9d0f079 100644 --- a/manifest +++ b/manifest @@ -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) -D 2009-02-20T03:02:24 +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:55:05 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 1d83fa2b1fd326b9e121012bd1ff9740537e12b3 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -112,7 +112,7 @@ F src/callback.c 5f10bca853e59a2c272bbfd5b720303f8b69e520 F src/complete.c cb14e06dbe79dee031031f0d9e686ff306afe07c F src/date.c 0d804df3bbda46329946a01ff5c75c3f4f135218 F src/delete.c 8d2fb05b32b5dea65277a574fedb0ebaa5dd877c -F src/expr.c 2e62c2621c0375125cacb93ad6686bb2911b629e +F src/expr.c 92e6dfcd55bdffbed8c66627700d1b5c5f9889d3 F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff F src/func.c 2fb36cd7cc24e16845db203187d1e52811b0fa9c F src/global.c 448419c44ce0701104c2121b0e06919b44514c0c @@ -200,12 +200,12 @@ F src/update.c 9edb83cc4322fb2dc5b7a0087cdb8fa00391f402 F src/utf.c 1da9c832dba0fa8f865b5b902d93f420a1ee4245 F src/util.c 1363f64351f3b544790f3c523439354c02f8c4e9 F src/vacuum.c 4929a585ef0fb1dfaf46302f8a9c4aa30c2d9cf5 -F src/vdbe.c 4533be29b997c609c6fbafeeb6985f3ec9070d8c +F src/vdbe.c 3bd3acffddf8a284d3e8c1df0e286389aaf09e1a F src/vdbe.h d70a68bee196ab228914a3902c79dbd24342a0f2 F src/vdbeInt.h d12bc259b34d3d610ebf05d648eb6346d48478c3 F src/vdbeapi.c f94fe2eb6f48687e918f0df7eed1409cff9dcf58 F src/vdbeaux.c dd5fc23bae4647d40b00ac308acd85f5c862f01e -F src/vdbeblob.c b0dcebfafedcf9c0addc7901ad98f6f986c08935 +F src/vdbeblob.c b06daa322e220f30dec55032c4e60e00346e153b F src/vdbemem.c 543a79d722734d2f8b7ad70f08218c30bcc5bbf5 F src/vtab.c e39e011d7443a8d574b1b9cde207a35522e6df43 F src/walker.c 42bd3f00ca2ef5ae842304ec0d59903ef051412d @@ -241,7 +241,7 @@ F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f F test/between.test 16b1776c6323faadb097a52d673e8e3d8be7d070 F test/bigfile.test 6adfef13d24bbe0c504b4547f292b9a170184f25 F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747 -F test/bind.test 3d719310b548c18d979af495ee7d80b2d9a974b0 +F test/bind.test 455f7e8322a215e245414625eede3ab0e1429c14 F test/bindxfer.test d4f573750e06c34ef2309acb95ad57da1d3c983f F test/bitvec.test ecea9aa315f36991e56e326701279b7775cb2bef F test/blob.test 2a38d867bdf08f9ce081776acec1ac8d4bca66be @@ -701,7 +701,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e -P 58a1809257ccfb7d9112a35f79ca2f82b3daa878 -R 0d19680e8f7c0d8be240916afd3b0973 +P feccad8d0d05925ce67856d40ffe1bc7054168a0 +R 45f3343e100f8675023b5adecf1a6bda U drh -Z d22ccd96d684ea638dc65d902b36ccb1 +Z 9ee82f1e63cdb67ae7cf41ec0375cf20 diff --git a/manifest.uuid b/manifest.uuid index 00a0ac14ac..d0023b68f6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -feccad8d0d05925ce67856d40ffe1bc7054168a0 \ No newline at end of file +48b77b04935d8942eb22f0c061f3bc5e99bbd7db \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index ef7c54d280..8bc85fcb5a 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** 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" @@ -2002,9 +2002,26 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ } #endif case TK_VARIABLE: { - sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iTable, target); - if( pExpr->token.n>1 ){ - sqlite3VdbeChangeP4(v, -1, (char*)pExpr->token.z, pExpr->token.n); + int iPrior; + VdbeOp *pOp; + 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; } diff --git a/src/vdbe.c b/src/vdbe.c index eb856adbc9..947db6058c 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -43,7 +43,7 @@ ** in this file for details. If in doubt, do not deviate from existing ** 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 "vdbeInt.h" @@ -977,26 +977,34 @@ case OP_Blob: { /* out2-prerelease */ break; } -/* Opcode: Variable P1 P2 * * * +/* Opcode: Variable P1 P2 P3 P4 * ** -** The value of variable P1 is written into register P2. A variable is -** an unknown in the original SQL string as handed to sqlite3_compile(). -** Any occurrence of the '?' character in the original SQL is considered -** a variable. Variables in the SQL string are number from left to -** right beginning with 1. The values of variables are set using the -** sqlite3_bind() API. +** Transfer the values of bound parameters P1..P1+P3-1 into registers +** P2..P2+P3-1. +** +** If the parameter is named, then its name appears in P4 and P3==1. +** The P4 value is used by sqlite3_bind_parameter_name(). */ -case OP_Variable: { /* out2-prerelease */ +case OP_Variable: { int j = pOp->p1 - 1; + int k = pOp->p2; Mem *pVar; - assert( j>=0 && jnVar ); + 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]; - if( sqlite3VdbeMemTooBig(pVar) ){ - goto too_big; + while( n-- > 0 ){ + pVar = &p->aVar[j++]; + 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; } diff --git a/src/vdbeblob.c b/src/vdbeblob.c index 9afeb11c0b..0fccada5a5 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -12,7 +12,7 @@ ** ** 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" @@ -75,7 +75,7 @@ int sqlite3_blob_open( {OP_SetNumColumns, 0, 0, 0}, /* 4: Num cols for cursor */ {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_Column, 0, 0, 1}, /* 8 */ {OP_ResultRow, 1, 0, 0}, /* 9 */ diff --git a/test/bind.test b/test/bind.test index 1cd34febb5..da0bf94318 100644 --- a/test/bind.test +++ b/test/bind.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # 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] @@ -683,4 +683,76 @@ do_test bind-14.4 { param_names db { SELECT @a, @b FROM (SELECT NULL) } } {@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