]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add a count parameter to the OP_Variable opcode and use it to simplify
authordrh <drh@noemail.net>
Fri, 20 Feb 2009 03:55:05 +0000 (03:55 +0000)
committerdrh <drh@noemail.net>
Fri, 20 Feb 2009 03:55:05 +0000 (03:55 +0000)
prepared statements that copy consecutive unnamed parameters into
consecutive registers (a common case). (CVS 6309)

FossilOrigin-Name: 48b77b04935d8942eb22f0c061f3bc5e99bbd7db

manifest
manifest.uuid
src/expr.c
src/vdbe.c
src/vdbeblob.c
test/bind.test

index d53a3cff4e4d9fe69a18b7a7c4fb9e76c01b4e77..2fe9d0f079622c15bd5f91294c6245c227d553f8 100644 (file)
--- 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
index 00a0ac14acc90f0cdb5e3b5e8c2f7834b1b7d644..d0023b68f678361c881b8afb086cd406052de8c8 100644 (file)
@@ -1 +1 @@
-feccad8d0d05925ce67856d40ffe1bc7054168a0
\ No newline at end of file
+48b77b04935d8942eb22f0c061f3bc5e99bbd7db
\ No newline at end of file
index ef7c54d280a9b978226cec232c22fe26423b401e..8bc85fcb5ac449f08e0c6776ae2dfdfe2ef57c1e 100644 (file)
@@ -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;
     }
index eb856adbc952875ef99e4db2b0e490a777efc5ab..947db6058c5cfe9c55d7f1adb610344ab6119660 100644 (file)
@@ -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 && 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];
-  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;
 }
 
index 9afeb11c0bb034e91333a39e0733ce4758d321ce..0fccada5a51f32ec6e6ded61e4c6a3ee4efbe7ad 100644 (file)
@@ -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  */
index 1cd34febb5d1138b649948eed4237f4cb76df0c6..da0bf94318c55e7df597a6d5b79303759b9330cc 100644 (file)
@@ -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