SQLite

Check-in [c0e3f1c592]
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
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: c0e3f1c592f583a0659901743a368aff1927f1cb
User & Date: drh 2002-03-13 18:54:07.000
Context
2002-03-13
18:54
Version 2.4.1 (CVS 430) (check-in: 9333ecca1e 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: c0e3f1c592 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: 753adb789e user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/expr.c.
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.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







|







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.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
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
        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 */







|







462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
        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
**
*************************************************************************
** 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);







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** 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);
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

// 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 ::= .







|
|
|
|







44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

// 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
*************************************************************************
** 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>

/*







|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
*************************************************************************
** 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>

/*
417
418
419
420
421
422
423

424
425
426
427
428
429
430
          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);







>







417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
          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
#
#***********************************************************************
# 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.
#







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#
#***********************************************************************
# 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.
#
129
130
131
132
133
134
135
136


















137
    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








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

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
    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
#    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;







|







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.  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;
276
277
278
279
280
281
282









283
284
285
286
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







>
>
>
>
>
>
>
>
>




276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
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>