Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | 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) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
48b77b04935d8942eb22f0c061f3bc5e |
User & Date: | drh 2009-02-20 03:55:05.000 |
References
2010-05-12
| ||
13:50 | Remove the OP_Variable optimization of check-in [48b77b04935d894] since it can lead to malfunctions as described in ticket [26ff0c82d1e90]. (check-in: 7838163d08 user: drh tags: trunk) | |
12:12 | • New ticket [26ff0c82d1] Incorrect result when using unnamed "?" bindings. (artifact: 3e0dd9c8b5 user: drh) | |
Context
2009-02-20
| ||
10:58 | Instead of using SetNumColumns, specify the number of columns in a table or index using the P4 argument. (CVS 6310) (check-in: e43ed64963 user: danielk1977 tags: trunk) | |
03:55 | 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) (check-in: 48b77b0493 user: drh tags: trunk) | |
03:02 | Add the OP_HaltIfNull opcode and use it to simplify prepared statements for INSERTs and UPDATEs of tables with NOT NULL columns. (CVS 6308) (check-in: feccad8d0d user: drh tags: trunk) | |
Changes
Changes to src/expr.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** ** $Id: expr.c,v 1.413 2009/02/20 03:55:05 drh Exp $ */ #include "sqliteInt.h" /* ** Return the 'affinity' of the expression pExpr if any. ** ** If pExpr is a column, a reference to a column via an 'AS' alias, |
︙ | ︙ | |||
1998 1999 2000 2001 2002 2003 2004 | z = (char*)pExpr->token.z + 2; zBlob = sqlite3HexToBlob(sqlite3VdbeDb(v), z, n); sqlite3VdbeAddOp4(v, OP_Blob, n/2, target, 0, zBlob, P4_DYNAMIC); break; } #endif case TK_VARIABLE: { | > > > > > > > > > > > > > > > > | | | > | 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 | z = (char*)pExpr->token.z + 2; zBlob = sqlite3HexToBlob(sqlite3VdbeDb(v), z, n); sqlite3VdbeAddOp4(v, OP_Blob, n/2, target, 0, zBlob, P4_DYNAMIC); break; } #endif case TK_VARIABLE: { 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; } case TK_REGISTER: { inReg = pExpr->iTable; break; } |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** 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.820 2009/02/20 03:55:05 drh Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" /* ** The following global variable is incremented every time a cursor ** moves, either by the OP_SeekXX, OP_Next, or OP_Prev opcodes. The test |
︙ | ︙ | |||
973 974 975 976 977 978 979 | assert( pOp->p1 <= SQLITE_MAX_LENGTH ); sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0); pOut->enc = encoding; UPDATE_MAX_BLOBSIZE(pOut); break; } | | | | | | < | | > > | > > > | | | | > > > | | > | 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 | assert( pOp->p1 <= SQLITE_MAX_LENGTH ); sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0); pOut->enc = encoding; UPDATE_MAX_BLOBSIZE(pOut); break; } /* Opcode: Variable P1 P2 P3 P4 * ** ** 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: { int j = pOp->p1 - 1; int k = pOp->p2; Mem *pVar; 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 ); 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); } break; } /* Opcode: Move P1 P2 P3 * * ** ** Move the values in register P1..P1+P3-1 over into ** registers P2..P2+P3-1. Registers P1..P1+P1-1 are |
︙ | ︙ |
Changes to src/vdbeblob.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains code used to implement incremental BLOB I/O. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains code used to implement incremental BLOB I/O. ** ** $Id: vdbeblob.c,v 1.27 2009/02/20 03:55:05 drh Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" #ifndef SQLITE_OMIT_INCRBLOB |
︙ | ︙ | |||
71 72 73 74 75 76 77 | ** OP_Noop before exection. */ {OP_SetNumColumns, 0, 0, 0}, /* 2: Num cols for cursor */ {OP_OpenRead, 0, 0, 0}, /* 3: Open cursor 0 for reading */ {OP_SetNumColumns, 0, 0, 0}, /* 4: Num cols for cursor */ {OP_OpenWrite, 0, 0, 0}, /* 5: Open cursor 0 for read/write */ | | | 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | ** OP_Noop before exection. */ {OP_SetNumColumns, 0, 0, 0}, /* 2: Num cols for cursor */ {OP_OpenRead, 0, 0, 0}, /* 3: Open cursor 0 for reading */ {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, 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 */ {OP_Close, 0, 0, 0}, /* 10 */ {OP_Halt, 0, 0, 0}, /* 11 */ }; |
︙ | ︙ |
Changes to test/bind.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2003 September 6 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script testing the sqlite_bind API. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2003 September 6 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script testing the sqlite_bind API. # # $Id: bind.test,v 1.47 2009/02/20 03:55:05 drh Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl proc sqlite_step {stmt N VALS COLS} { upvar VALS vals |
︙ | ︙ | |||
678 679 680 681 682 683 684 685 686 | } {@a @b} do_test bind-14.3 { param_names db { SELECT @a FROM (SELECT NULL) WHERE 1 = @b } } {@a @b} do_test bind-14.4 { param_names db { SELECT @a, @b FROM (SELECT NULL) } } {@a @b} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 | } {@a @b} do_test bind-14.3 { param_names db { SELECT @a FROM (SELECT NULL) WHERE 1 = @b } } {@a @b} 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 |