/ Check-in [fe329e07]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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 | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: fe329e078fa209faf62e08599a00c7efa75b8501
User & Date: drh 2002-07-31 19:50:27
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: bdbdb866 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: fe329e07 user: drh tags: trunk
00:38
Version 2.6.2 (CVS 699) check-in: 223a2150 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

    26     26   ** type to the other occurs as necessary.
    27     27   ** 
    28     28   ** Most of the code in this file is taken up by the sqliteVdbeExec()
    29     29   ** function which does the work of interpreting a VDBE program.
    30     30   ** But other routines are also provided to help in building up
    31     31   ** a program instruction by instruction.
    32     32   **
    33         -** $Id: vdbe.c,v 1.166 2002/07/30 17:20:40 drh Exp $
           33  +** $Id: vdbe.c,v 1.167 2002/07/31 19:50:27 drh Exp $
    34     34   */
    35     35   #include "sqliteInt.h"
    36     36   #include <ctype.h>
    37     37   
    38     38   /*
    39     39   ** The following global variable is incremented every time a cursor
    40     40   ** moves, either by the OP_MoveTo or the OP_Next opcode.  The test
................................................................................
  1972   1972     int tos = p->tos;
  1973   1973     VERIFY( if( tos<0 ) goto not_enough_stack; )
  1974   1974     Integerify(p, tos);
  1975   1975     aStack[tos].i += pOp->p1;
  1976   1976     break;
  1977   1977   }
  1978   1978   
  1979         -/* Opcode: MustBeInt  * P2 *
         1979  +/* Opcode: MustBeInt P1 P2 *
  1980   1980   ** 
  1981   1981   ** Force the top of the stack to be an integer.  If the top of the
  1982   1982   ** stack is not an integer and cannot be converted into an integer
  1983   1983   ** with out data loss, then jump immediately to P2, or if P2==0
  1984   1984   ** raise an SQLITE_MISMATCH exception.
         1985  +**
         1986  +** If the top of the stack is not an integer and P2 is not zero and
         1987  +** P1 is 1, then the stack is popped.  In all other cases, the depth
         1988  +** of the stack is unchanged.
  1985   1989   */
  1986   1990   case OP_MustBeInt: {
  1987   1991     int tos = p->tos;
  1988   1992     VERIFY( if( tos<0 ) goto not_enough_stack; )
  1989   1993     if( aStack[tos].flags & STK_Int ){
  1990   1994       /* Do nothing */
  1991   1995     }else if( aStack[tos].flags & STK_Real ){
................................................................................
  2008   2012     break;
  2009   2013   
  2010   2014   mismatch:
  2011   2015     if( pOp->p2==0 ){
  2012   2016       rc = SQLITE_MISMATCH;
  2013   2017       goto abort_due_to_error;
  2014   2018     }else{
         2019  +    if( pOp->p1 ) POPSTACK;
  2015   2020       pc = pOp->p2 - 1;
  2016   2021     }
  2017   2022     break;
  2018   2023   }
  2019   2024   
  2020   2025   /* Opcode: Eq P1 P2 *
  2021   2026   **

Changes to src/where.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This module contains C code that generates VDBE code used to process
    13     13   ** the WHERE clause of SQL statements.  Also found here are subroutines
    14     14   ** to generate VDBE code to evaluate expressions.
    15     15   **
    16         -** $Id: where.c,v 1.58 2002/06/28 12:18:47 drh Exp $
           16  +** $Id: where.c,v 1.59 2002/07/31 19:50:28 drh Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   
    20     20   /*
    21     21   ** The query generator uses an array of instances of this structure to
    22     22   ** help it analyze the subexpressions of the WHERE clause.  Each WHERE
    23     23   ** clause subexpression is separated from the others by an AND operator.
................................................................................
   686    686             pLevel->inP1 = pX->iTable;
   687    687           }
   688    688         }else{
   689    689           sqliteExprCode(pParse, aExpr[k].p->pLeft);
   690    690         }
   691    691         aExpr[k].p = 0;
   692    692         cont = pLevel->cont = sqliteVdbeMakeLabel(v);
   693         -      sqliteVdbeAddOp(v, OP_MustBeInt, 0, brk);
          693  +      sqliteVdbeAddOp(v, OP_MustBeInt, 1, brk);
   694    694         haveKey = 0;
   695    695         sqliteVdbeAddOp(v, OP_NotExists, base+idx, brk);
   696    696         pLevel->op = OP_Noop;
   697    697       }else if( pIdx!=0 && pLevel->score>0 && pLevel->score%4==0 ){
   698    698         /* Case 2:  There is an index and all terms of the WHERE clause that
   699    699         **          refer to the index use the "==" or "IN" operators.
   700    700         */
................................................................................
   783    783           assert( aExpr[k].p!=0 );
   784    784           assert( aExpr[k].idxLeft==idx || aExpr[k].idxRight==idx );
   785    785           if( aExpr[k].idxLeft==idx ){
   786    786             sqliteExprCode(pParse, aExpr[k].p->pRight);
   787    787           }else{
   788    788             sqliteExprCode(pParse, aExpr[k].p->pLeft);
   789    789           }
   790         -        sqliteVdbeAddOp(v, OP_MustBeInt, 0, brk);
          790  +        sqliteVdbeAddOp(v, OP_MustBeInt, 1, brk);
   791    791           if( aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT ){
   792    792             sqliteVdbeAddOp(v, OP_AddImm, 1, 0);
   793    793           }
   794    794           sqliteVdbeAddOp(v, OP_MoveTo, base+idx, brk);
   795    795           aExpr[k].p = 0;
   796    796         }else{
   797    797           sqliteVdbeAddOp(v, OP_Rewind, base+idx, brk);
................................................................................
   802    802           assert( aExpr[k].p!=0 );
   803    803           assert( aExpr[k].idxLeft==idx || aExpr[k].idxRight==idx );
   804    804           if( aExpr[k].idxLeft==idx ){
   805    805             sqliteExprCode(pParse, aExpr[k].p->pRight);
   806    806           }else{
   807    807             sqliteExprCode(pParse, aExpr[k].p->pLeft);
   808    808           }
   809         -        sqliteVdbeAddOp(v, OP_MustBeInt, 0, sqliteVdbeCurrentAddr(v)+1);
          809  +        sqliteVdbeAddOp(v, OP_MustBeInt, 1, sqliteVdbeCurrentAddr(v)+1);
   810    810           pLevel->iMem = pParse->nMem++;
   811    811           sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 0);
   812    812           if( aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT ){
   813    813             testOp = OP_Ge;
   814    814           }else{
   815    815             testOp = OP_Gt;
   816    816           }

Changes to test/join.test.

     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.
    12     12   #
    13     13   # This file implements tests for joins, including outer joins.
    14     14   #
    15         -# $Id: join.test,v 1.4 2002/07/01 12:27:09 drh Exp $
           15  +# $Id: join.test,v 1.5 2002/07/31 19:50:28 drh Exp $
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   
    20     20   do_test join-1.1 {
    21     21     execsql {
    22     22       CREATE TABLE t1(a,b,c);
................................................................................
   216    216     }
   217    217   } {1 {unknown or unsupported join type: INNER OUTER}}
   218    218   do_test join-3.7 {
   219    219     catchsql {
   220    220       SELECT * FROM t1 LEFT BOGUS JOIN t2;
   221    221     }
   222    222   } {1 {unknown or unsupported join type: LEFT BOGUS}}
          223  +
          224  +do_test join-4.1 {
          225  +  execsql {
          226  +    BEGIN;
          227  +    CREATE TABLE t5(a INTEGER PRIMARY KEY);
          228  +    CREATE TABLE t6(a INTEGER);
          229  +    INSERT INTO t6 VALUES(NULL);
          230  +    INSERT INTO t6 VALUES(NULL);
          231  +    INSERT INTO t6 SELECT * FROM t6;
          232  +    INSERT INTO t6 SELECT * FROM t6;
          233  +    INSERT INTO t6 SELECT * FROM t6;
          234  +    INSERT INTO t6 SELECT * FROM t6;
          235  +    INSERT INTO t6 SELECT * FROM t6;
          236  +    INSERT INTO t6 SELECT * FROM t6;
          237  +    COMMIT;
          238  +  }
          239  +  execsql {
          240  +    SELECT * FROM t6 NATURAL JOIN t5;
          241  +  }
          242  +} {}
          243  +do_test join-4.2 {
          244  +  execsql {
          245  +    SELECT * FROM t6, t5 WHERE t6.a<t5.a;
          246  +  }
          247  +} {}
          248  +do_test join-4.3 {
          249  +  execsql {
          250  +    SELECT * FROM t6, t5 WHERE t6.a>t5.a;
          251  +  }
          252  +} {}
          253  +do_test join-4.4 {
          254  +  execsql {
          255  +    UPDATE t6 SET a='xyz';
          256  +    SELECT * FROM t6 NATURAL JOIN t5;
          257  +  }
          258  +} {}
          259  +do_test join-4.6 {
          260  +  execsql {
          261  +    SELECT * FROM t6, t5 WHERE t6.a<t5.a;
          262  +  }
          263  +} {}
          264  +do_test join-4.7 {
          265  +  execsql {
          266  +    SELECT * FROM t6, t5 WHERE t6.a>t5.a;
          267  +  }
          268  +} {}
          269  +do_test join-4.8 {
          270  +  execsql {
          271  +    UPDATE t6 SET a=1;
          272  +    SELECT * FROM t6 NATURAL JOIN t5;
          273  +  }
          274  +} {}
          275  +do_test join-4.9 {
          276  +  execsql {
          277  +    SELECT * FROM t6, t5 WHERE t6.a<t5.a;
          278  +  }
          279  +} {}
          280  +do_test join-4.10 {
          281  +  execsql {
          282  +    SELECT * FROM t6, t5 WHERE t6.a>t5.a;
          283  +  }
          284  +} {}
   223    285   
   224    286   
   225    287   finish_test