Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix for ticket #124: Fix a stack VDBE overflow problem on joins on an INTEGER PRIMARY KEY. (CVS 700) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
fe329e078fa209faf62e08599a00c7ef |
User & Date: | drh 2002-07-31 19:50:27.000 |
Context
2002-08-02
| ||
10:36 | Remove the restriction that a transaction cannot be started by one linuxthread and continued by another. Leave in the documentation the warning about not carrying a database connection across fork() but do not test for it any more. Ticket #130. (CVS 701) (check-in: bdbdb866f2 user: drh tags: trunk) | |
2002-07-31
| ||
19:50 | Fix for ticket #124: Fix a stack VDBE overflow problem on joins on an INTEGER PRIMARY KEY. (CVS 700) (check-in: fe329e078f user: drh tags: trunk) | |
00:38 | Version 2.6.2 (CVS 699) (check-in: 223a2150ac user: drh tags: trunk) | |
Changes
Changes to src/vdbe.c.
︙ | ︙ | |||
26 27 28 29 30 31 32 | ** type to the other occurs as necessary. ** ** Most of the code in this file is taken up by the sqliteVdbeExec() ** function which does the work of interpreting a VDBE program. ** But other routines are also provided to help in building up ** a program instruction by instruction. ** | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | ** type to the other occurs as necessary. ** ** Most of the code in this file is taken up by the sqliteVdbeExec() ** function which does the work of interpreting a VDBE program. ** But other routines are also provided to help in building up ** a program instruction by instruction. ** ** $Id: vdbe.c,v 1.167 2002/07/31 19:50:27 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** The following global variable is incremented every time a cursor ** moves, either by the OP_MoveTo or the OP_Next opcode. The test |
︙ | ︙ | |||
1972 1973 1974 1975 1976 1977 1978 | int tos = p->tos; VERIFY( if( tos<0 ) goto not_enough_stack; ) Integerify(p, tos); aStack[tos].i += pOp->p1; break; } | | > > > > | 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 | int tos = p->tos; VERIFY( if( tos<0 ) goto not_enough_stack; ) Integerify(p, tos); aStack[tos].i += pOp->p1; break; } /* Opcode: MustBeInt P1 P2 * ** ** Force the top of the stack to be an integer. If the top of the ** stack is not an integer and cannot be converted into an integer ** with out data loss, then jump immediately to P2, or if P2==0 ** raise an SQLITE_MISMATCH exception. ** ** If the top of the stack is not an integer and P2 is not zero and ** P1 is 1, then the stack is popped. In all other cases, the depth ** of the stack is unchanged. */ case OP_MustBeInt: { int tos = p->tos; VERIFY( if( tos<0 ) goto not_enough_stack; ) if( aStack[tos].flags & STK_Int ){ /* Do nothing */ }else if( aStack[tos].flags & STK_Real ){ |
︙ | ︙ | |||
2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 | break; mismatch: if( pOp->p2==0 ){ rc = SQLITE_MISMATCH; goto abort_due_to_error; }else{ pc = pOp->p2 - 1; } break; } /* Opcode: Eq P1 P2 * ** | > | 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 | break; mismatch: if( pOp->p2==0 ){ rc = SQLITE_MISMATCH; goto abort_due_to_error; }else{ if( pOp->p1 ) POPSTACK; pc = pOp->p2 - 1; } break; } /* Opcode: Eq P1 P2 * ** |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. Also found here are subroutines ** to generate VDBE code to evaluate expressions. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. Also found here are subroutines ** to generate VDBE code to evaluate expressions. ** ** $Id: where.c,v 1.59 2002/07/31 19:50:28 drh Exp $ */ #include "sqliteInt.h" /* ** The query generator uses an array of instances of this structure to ** help it analyze the subexpressions of the WHERE clause. Each WHERE ** clause subexpression is separated from the others by an AND operator. |
︙ | ︙ | |||
686 687 688 689 690 691 692 | pLevel->inP1 = pX->iTable; } }else{ sqliteExprCode(pParse, aExpr[k].p->pLeft); } aExpr[k].p = 0; cont = pLevel->cont = sqliteVdbeMakeLabel(v); | | | 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 | pLevel->inP1 = pX->iTable; } }else{ sqliteExprCode(pParse, aExpr[k].p->pLeft); } aExpr[k].p = 0; cont = pLevel->cont = sqliteVdbeMakeLabel(v); sqliteVdbeAddOp(v, OP_MustBeInt, 1, brk); haveKey = 0; sqliteVdbeAddOp(v, OP_NotExists, base+idx, brk); pLevel->op = OP_Noop; }else if( pIdx!=0 && pLevel->score>0 && pLevel->score%4==0 ){ /* Case 2: There is an index and all terms of the WHERE clause that ** refer to the index use the "==" or "IN" operators. */ |
︙ | ︙ | |||
783 784 785 786 787 788 789 | assert( aExpr[k].p!=0 ); assert( aExpr[k].idxLeft==idx || aExpr[k].idxRight==idx ); if( aExpr[k].idxLeft==idx ){ sqliteExprCode(pParse, aExpr[k].p->pRight); }else{ sqliteExprCode(pParse, aExpr[k].p->pLeft); } | | | | 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 | assert( aExpr[k].p!=0 ); assert( aExpr[k].idxLeft==idx || aExpr[k].idxRight==idx ); if( aExpr[k].idxLeft==idx ){ sqliteExprCode(pParse, aExpr[k].p->pRight); }else{ sqliteExprCode(pParse, aExpr[k].p->pLeft); } sqliteVdbeAddOp(v, OP_MustBeInt, 1, brk); if( aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT ){ sqliteVdbeAddOp(v, OP_AddImm, 1, 0); } sqliteVdbeAddOp(v, OP_MoveTo, base+idx, brk); aExpr[k].p = 0; }else{ sqliteVdbeAddOp(v, OP_Rewind, base+idx, brk); } if( iDirectLt[i]>=0 ){ k = iDirectLt[i]; assert( k<nExpr ); assert( aExpr[k].p!=0 ); assert( aExpr[k].idxLeft==idx || aExpr[k].idxRight==idx ); if( aExpr[k].idxLeft==idx ){ sqliteExprCode(pParse, aExpr[k].p->pRight); }else{ sqliteExprCode(pParse, aExpr[k].p->pLeft); } sqliteVdbeAddOp(v, OP_MustBeInt, 1, sqliteVdbeCurrentAddr(v)+1); pLevel->iMem = pParse->nMem++; sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 0); if( aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT ){ testOp = OP_Ge; }else{ testOp = OP_Gt; } |
︙ | ︙ |
Changes to test/join.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. # # This file implements tests for joins, including outer joins. # | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. # # This file implements tests for joins, including outer joins. # # $Id: join.test,v 1.5 2002/07/31 19:50:28 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl do_test join-1.1 { execsql { CREATE TABLE t1(a,b,c); |
︙ | ︙ | |||
216 217 218 219 220 221 222 223 | } } {1 {unknown or unsupported join type: INNER OUTER}} do_test join-3.7 { catchsql { SELECT * FROM t1 LEFT BOGUS JOIN t2; } } {1 {unknown or unsupported join type: LEFT BOGUS}} | > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 | } } {1 {unknown or unsupported join type: INNER OUTER}} do_test join-3.7 { catchsql { SELECT * FROM t1 LEFT BOGUS JOIN t2; } } {1 {unknown or unsupported join type: LEFT BOGUS}} do_test join-4.1 { execsql { BEGIN; CREATE TABLE t5(a INTEGER PRIMARY KEY); CREATE TABLE t6(a INTEGER); INSERT INTO t6 VALUES(NULL); INSERT INTO t6 VALUES(NULL); INSERT INTO t6 SELECT * FROM t6; INSERT INTO t6 SELECT * FROM t6; INSERT INTO t6 SELECT * FROM t6; INSERT INTO t6 SELECT * FROM t6; INSERT INTO t6 SELECT * FROM t6; INSERT INTO t6 SELECT * FROM t6; COMMIT; } execsql { SELECT * FROM t6 NATURAL JOIN t5; } } {} do_test join-4.2 { execsql { SELECT * FROM t6, t5 WHERE t6.a<t5.a; } } {} do_test join-4.3 { execsql { SELECT * FROM t6, t5 WHERE t6.a>t5.a; } } {} do_test join-4.4 { execsql { UPDATE t6 SET a='xyz'; SELECT * FROM t6 NATURAL JOIN t5; } } {} do_test join-4.6 { execsql { SELECT * FROM t6, t5 WHERE t6.a<t5.a; } } {} do_test join-4.7 { execsql { SELECT * FROM t6, t5 WHERE t6.a>t5.a; } } {} do_test join-4.8 { execsql { UPDATE t6 SET a=1; SELECT * FROM t6 NATURAL JOIN t5; } } {} do_test join-4.9 { execsql { SELECT * FROM t6, t5 WHERE t6.a<t5.a; } } {} do_test join-4.10 { execsql { SELECT * FROM t6, t5 WHERE t6.a>t5.a; } } {} finish_test |