/ Check-in [c0e3f1c5]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix bug in anonymous subquery in a join. Parser requires a semicolon or end-of-input before executing. (CVS 429)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:c0e3f1c592f583a0659901743a368aff1927f1cb
User & Date: drh 2002-03-13 18:54:07
Context
2002-03-13
18:54
Version 2.4.1 (CVS 430) check-in: 9333ecca user: drh tags: trunk
18:54
Fix bug in anonymous subquery in a join. Parser requires a semicolon or end-of-input before executing. (CVS 429) check-in: c0e3f1c5 user: drh tags: trunk
2002-03-12
23:10
Fix the return type of the xStep function in the FuncDef structure definition. (CVS 428) check-in: 753adb78 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/expr.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
**    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.55 2002/03/06 03:08:26 drh Exp $
*/
#include "sqliteInt.h"


/*
** Construct a new expression node and return a pointer to it.  Memory
** for this node is obtained from sqliteMalloc().  The calling function
................................................................................
        if( pTab==0 ) continue;
        assert( pTab->nCol>0 );
        if( pTabList->a[i].zAlias ){
          zTab = pTabList->a[i].zAlias;
        }else{
          zTab = pTab->zName;
        }
        if( sqliteStrICmp(zTab, zLeft)!=0 ) continue;
        if( 0==(cntTab++) ) pExpr->iTable = i + base;
        for(j=0; j<pTab->nCol; j++){
          if( sqliteStrICmp(pTab->aCol[j].zName, zRight)==0 ){
            cnt++;
            pExpr->iTable = i + base;
            if( j==pTab->iPKey ){
              /* Substitute the record number for the INTEGER PRIMARY KEY */







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
**    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.56 2002/03/13 18:54:07 drh Exp $
*/
#include "sqliteInt.h"


/*
** Construct a new expression node and return a pointer to it.  Memory
** for this node is obtained from sqliteMalloc().  The calling function
................................................................................
        if( pTab==0 ) continue;
        assert( pTab->nCol>0 );
        if( pTabList->a[i].zAlias ){
          zTab = pTabList->a[i].zAlias;
        }else{
          zTab = pTab->zName;
        }
        if( zTab==0 || sqliteStrICmp(zTab, zLeft)!=0 ) continue;
        if( 0==(cntTab++) ) pExpr->iTable = i + base;
        for(j=0; j<pTab->nCol; j++){
          if( sqliteStrICmp(pTab->aCol[j].zName, zRight)==0 ){
            cnt++;
            pExpr->iTable = i + base;
            if( j==pTab->iPKey ){
              /* Substitute the record number for the INTEGER PRIMARY KEY */

Changes to src/parse.y.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
**
*************************************************************************
** This file contains SQLite's grammar for SQL.  Process this file
** using the lemon parser generator to generate C code that runs
** the parser.  Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
** @(#) $Id: parse.y,v 1.56 2002/03/05 01:11:14 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
%default_type {Token}
%extra_argument {Parse *pParse}
%syntax_error {
  sqliteSetString(&pParse->zErrMsg,"syntax error",0);
................................................................................

// Input is zero or more commands.
input ::= cmdlist.

// A list of commands is zero or more commands
//
cmdlist ::= ecmd.
cmdlist ::= cmdlist SEMI ecmd.
ecmd ::= explain cmd.  {sqliteExec(pParse);}
ecmd ::= cmd.          {sqliteExec(pParse);}
ecmd ::= .
explain ::= EXPLAIN.    {pParse->explain = 1;}

///////////////////// Begin and end transactions. ////////////////////////////
//

cmd ::= BEGIN trans_opt onconf(R).  {sqliteBeginTransaction(pParse,R);}
trans_opt ::= .







|







 







|
|
|
|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
**
*************************************************************************
** This file contains SQLite's grammar for SQL.  Process this file
** using the lemon parser generator to generate C code that runs
** the parser.  Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
** @(#) $Id: parse.y,v 1.57 2002/03/13 18:54:08 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
%default_type {Token}
%extra_argument {Parse *pParse}
%syntax_error {
  sqliteSetString(&pParse->zErrMsg,"syntax error",0);
................................................................................

// Input is zero or more commands.
input ::= cmdlist.

// A list of commands is zero or more commands
//
cmdlist ::= ecmd.
cmdlist ::= cmdlist ecmd.
ecmd ::= explain cmd SEMI.  {sqliteExec(pParse);}
ecmd ::= cmd SEMI.          {sqliteExec(pParse);}
ecmd ::= SEMI.
explain ::= EXPLAIN.    {pParse->explain = 1;}

///////////////////// Begin and end transactions. ////////////////////////////
//

cmd ::= BEGIN trans_opt onconf(R).  {sqliteBeginTransaction(pParse,R);}
trans_opt ::= .

Changes to src/tokenize.c.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
417
418
419
420
421
422
423

424
425
426
427
428
429
430
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.38 2002/02/23 02:32:10 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*
................................................................................
          sqliteSetString(pzErrMsg, sqlite_error_string(pParse->rc), 0);
          nErr++;
        }
        break;
    }
  }
  if( zSql[i]==0 ){

    sqliteParser(pEngine, 0, pParse->sLastToken, pParse);
    if( pParse->zErrMsg && pParse->sErrToken.z ){
       sqliteSetNString(pzErrMsg, "near \"", -1, 
          pParse->sErrToken.z, pParse->sErrToken.n,
          "\": ", -1,
          pParse->zErrMsg, -1,
          0);







|







 







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.39 2002/03/13 18:54:08 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*
................................................................................
          sqliteSetString(pzErrMsg, sqlite_error_string(pParse->rc), 0);
          nErr++;
        }
        break;
    }
  }
  if( zSql[i]==0 ){
    sqliteParser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
    sqliteParser(pEngine, 0, pParse->sLastToken, pParse);
    if( pParse->zErrMsg && pParse->sErrToken.z ){
       sqliteSetNString(pzErrMsg, "near \"", -1, 
          pParse->sErrToken.z, pParse->sErrToken.n,
          "\": ", -1,
          pParse->zErrMsg, -1,
          0);

Changes to test/misc1.test.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
129
130
131
132
133
134
135
136


















137
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for miscellanous features that were
# left out of other test files.
#
# $Id: misc1.test,v 1.3 2002/02/14 12:50:35 drh Exp $

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

# Test the creation and use of tables that have a large number
# of columns.
#
................................................................................
    INSERT INTO t2 SELECT '4 - ' || a FROM t2;
    INSERT INTO t2 SELECT '5 - ' || a FROM t2;
    INSERT INTO t2 SELECT '6 - ' || a FROM t2;
    COMMIT;
    SELECT count(*) FROM t2;
  }
} {64}



















finish_test







|







 








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for miscellanous features that were
# left out of other test files.
#
# $Id: misc1.test,v 1.4 2002/03/13 18:54:08 drh Exp $

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

# Test the creation and use of tables that have a large number
# of columns.
#
................................................................................
    INSERT INTO t2 SELECT '4 - ' || a FROM t2;
    INSERT INTO t2 SELECT '5 - ' || a FROM t2;
    INSERT INTO t2 SELECT '6 - ' || a FROM t2;
    COMMIT;
    SELECT count(*) FROM t2;
  }
} {64}

# Make sure we actually see a semicolon or end-of-file in the SQL input
# before executing a command.  Thus if "WHERE" is misspelled on an UPDATE,
# the user won't accidently update every record.
#
do_test misc1-5.1 {
  catchsql {
    CREATE TABLE t3(a,b);
    INSERT INTO t3 VALUES(1,2);
    INSERT INTO t3 VALUES(3,4);
    UPDATE t3 SET a=0 WHEREwww b=2;
  }
} {1 {near "WHEREwww": syntax error}}
do_test misc1-5.2 {
  execsql {
    SELECT * FROM t3 ORDER BY a;
  }
} {1 2 3 4}

finish_test

Changes to test/select6.test.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
276
277
278
279
280
281
282









283
284
285
286
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing SELECT statements that contain
# subqueries in their FROM clause.
#
# $Id: select6.test,v 1.6 2002/03/03 03:42:31 drh Exp $

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

do_test select6-1.0 {
  execsql {
    BEGIN;
................................................................................
do_test select6-5.1 {
  execsql {
    SELECT a,x,b FROM
      (SELECT x+3 AS 'a', x FROM t1 WHERE y=3) AS 'p',
      (SELECT x AS 'b' FROM t1 WHERE y=4) AS 'q'
    WHERE a=b
    ORDER BY a









  }
} {8 5 8 9 6 9 10 7 10}

finish_test







|







 







>
>
>
>
>
>
>
>
>




8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing SELECT statements that contain
# subqueries in their FROM clause.
#
# $Id: select6.test,v 1.7 2002/03/13 18:54:09 drh Exp $

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

do_test select6-1.0 {
  execsql {
    BEGIN;
................................................................................
do_test select6-5.1 {
  execsql {
    SELECT a,x,b FROM
      (SELECT x+3 AS 'a', x FROM t1 WHERE y=3) AS 'p',
      (SELECT x AS 'b' FROM t1 WHERE y=4) AS 'q'
    WHERE a=b
    ORDER BY a
  }
} {8 5 8 9 6 9 10 7 10}
do_test select6-5.2 {
  execsql {
    SELECT a,x,b FROM
      (SELECT x+3 AS 'a', x FROM t1 WHERE y=3),
      (SELECT x AS 'b' FROM t1 WHERE y=4)
    WHERE a=b
    ORDER BY a
  }
} {8 5 8 9 6 9 10 7 10}

finish_test

Changes to www/changes.tcl.

12
13
14
15
16
17
18








19
20
21
22
23
24
25
}


proc chng {date desc} {
  puts "<DT><B>$date</B></DT>"
  puts "<DD><P><UL>$desc</UL></P></DD>"
}









chng {2002 Mar 10 (2.4.0)} {
<li>Change the name of the sanity_check PRAGMA to <b>integrity_check</b>
    and make it available in all compiles.</li>
<li>SELECT min() or max() of an indexed column with no WHERE or GROUP BY
    clause is handled as a special case which avoids a complete table scan.</li>
<li>Automatically generated ROWIDs are now sequential.</li>







>
>
>
>
>
>
>
>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
}


proc chng {date desc} {
  puts "<DT><B>$date</B></DT>"
  puts "<DD><P><UL>$desc</UL></P></DD>"
}

chng {2002 Mar 13 (2.4.1)} {
<li>Using an unnamed subquery in a FROM clause would cause a segfault.</p>
<li>The parser insist on seeing a semicolon or the end of input before
    executing a statement.  This avoids an accidental disaster if the
    WHERE keyword is misspelled in an UPDATE or DELETE statement.</li>
}


chng {2002 Mar 10 (2.4.0)} {
<li>Change the name of the sanity_check PRAGMA to <b>integrity_check</b>
    and make it available in all compiles.</li>
<li>SELECT min() or max() of an indexed column with no WHERE or GROUP BY
    clause is handled as a special case which avoids a complete table scan.</li>
<li>Automatically generated ROWIDs are now sequential.</li>