Skip to content

Commit

Permalink
Remove the OP_Variable optimization of check-in [48b77b04935d894] sin…
Browse files Browse the repository at this point in the history
…ce it

can lead to malfunctions as described in ticket [26ff0c82d1e90].
  • Loading branch information
D. Richard Hipp committed May 12, 2010
1 parent ac401a2 commit cdac03a
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 42 deletions.
21 changes: 3 additions & 18 deletions src/expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -2353,27 +2353,12 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
}
#endif
case TK_VARIABLE: {
VdbeOp *pOp;
assert( !ExprHasProperty(pExpr, EP_IntValue) );
assert( pExpr->u.zToken!=0 );
assert( pExpr->u.zToken[0]!=0 );
if( pExpr->u.zToken[1]==0
&& (pOp = sqlite3VdbeGetOp(v, -1))->opcode==OP_Variable
&& pOp->p1+pOp->p3==pExpr->iColumn
&& 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->iColumn, target, 1);
if( pExpr->u.zToken[1]!=0 ){
sqlite3VdbeChangeP4(v, -1, pExpr->u.zToken, 0);
}
sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target);
if( pExpr->u.zToken[1]!=0 ){
sqlite3VdbeChangeP4(v, -1, pExpr->u.zToken, 0);
}
break;
}
Expand Down
33 changes: 9 additions & 24 deletions src/vdbe.c
Original file line number Diff line number Diff line change
Expand Up @@ -989,38 +989,23 @@ case OP_Blob: { /* out2-prerelease */
break;
}

/* Opcode: Variable P1 P2 P3 P4 *
/* Opcode: Variable P1 P2 * P4 *
**
** Transfer the values of bound parameters P1..P1+P3-1 into registers
** P2..P2+P3-1.
** Transfer the values of bound parameter P1 into register P2
**
** 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 p1; /* Variable to copy from */
int p2; /* Register to copy to */
int n; /* Number of values left to copy */
case OP_Variable: { /* out2-prerelease */
Mem *pVar; /* Value being transferred */

p1 = pOp->p1 - 1;
p2 = pOp->p2;
n = pOp->p3;
assert( p1>=0 && p1+n<=p->nVar );
assert( p2>=1 && p2+n-1<=p->nMem );
assert( pOp->p4.z==0 || pOp->p3==1 || pOp->p3==0 );

while( n-- > 0 ){
pVar = &p->aVar[p1++];
if( sqlite3VdbeMemTooBig(pVar) ){
goto too_big;
}
pOut = &aMem[p2++];
sqlite3VdbeMemReleaseExternal(pOut);
pOut->flags = MEM_Null;
sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static);
UPDATE_MAX_BLOBSIZE(pOut);
assert( pOp->p1>0 && pOp->p1<=p->nVar );
pVar = &p->aVar[pOp->p1 - 1];
if( sqlite3VdbeMemTooBig(pVar) ){
goto too_big;
}
sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static);
UPDATE_MAX_BLOBSIZE(pOut);
break;
}

Expand Down
33 changes: 33 additions & 0 deletions test/tkt-26ff0c2d1e.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# 2010 May 12
#
# 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 a bug found in the OP_Variable optimizer
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_test bug-20100512-1 {
set DB [sqlite3_connection_pointer db]
set SQL {SELECT case when 1 then 99 else ? end + ?}
set STMT [sqlite3_prepare_v2 $DB $SQL -1 TAIL]
set TAIL
} {}
do_test bug-20100512-2 {
sqlite3_bind_parameter_count $STMT
} 2
do_test bug-20100512-3 {
sqlite3_bind_int $STMT 1 123
sqlite3_bind_int $STMT 2 456
sqlite3_step $STMT
sqlite3_column_int $STMT 0
} {555}
sqlite3_finalize $STMT

0 comments on commit cdac03a

Please sign in to comment.