SQLite

Check-in [6593199a4d]
Login

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

Overview
Comment:Fix some memory leaks caused by obscure syntax errors in SQL. (CVS 2882)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 6593199a4d0d0e1f9cc2f48d30327b1c03a8170e
User & Date: danielk1977 2006-01-07 14:02:27.000
Context
2006-01-07
16:06
Enable redefinable I/O if the SQLITE_ENABLE_REDEF_IO macro exists. (CVS 2883) (check-in: e170e15766 user: drh tags: trunk)
14:02
Fix some memory leaks caused by obscure syntax errors in SQL. (CVS 2882) (check-in: 6593199a4d user: danielk1977 tags: trunk)
13:21
In shared-cache mode, lock all required tables before beginning to execute the body of the statement program. (CVS 2881) (check-in: 23b587b05b user: danielk1977 tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
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.191 2006/01/04 15:54:36 drh Exp $
*/

// All token codes are small integers with #defines that begin with "TK_"
%token_prefix TK_

// The type of the data attached to each token is Token.  This is also the
// default type for non-terminals.







|







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.192 2006/01/07 14:02:27 danielk1977 Exp $
*/

// All token codes are small integers with #defines that begin with "TK_"
%token_prefix TK_

// The type of the data attached to each token is Token.  This is also the
// default type for non-terminals.
681
682
683
684
685
686
687

688
689
690
691
692
693
694
expr(A) ::= expr(X) PLUS|MINUS(OP) expr(Y).     {A = sqlite3Expr(@OP, X, Y, 0);}
expr(A) ::= expr(X) STAR|SLASH|REM(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);}
expr(A) ::= expr(X) CONCAT(OP) expr(Y).         {A = sqlite3Expr(@OP, X, Y, 0);}
%type likeop {struct LikeOp}
likeop(A) ::= LIKE_KW(X).     {A.operator = X; A.not = 0;}
likeop(A) ::= NOT LIKE_KW(X). {A.operator = X; A.not = 1;}
%type escape {Expr*}

escape(X) ::= ESCAPE expr(A). [ESCAPE] {X = A;}
escape(X) ::= .               [ESCAPE] {X = 0;}
expr(A) ::= expr(X) likeop(OP) expr(Y) escape(E).  [LIKE_KW]  {
  ExprList *pList = sqlite3ExprListAppend(0, Y, 0);
  pList = sqlite3ExprListAppend(pList, X, 0);
  if( E ){
    pList = sqlite3ExprListAppend(pList, E, 0);







>







681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
expr(A) ::= expr(X) PLUS|MINUS(OP) expr(Y).     {A = sqlite3Expr(@OP, X, Y, 0);}
expr(A) ::= expr(X) STAR|SLASH|REM(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);}
expr(A) ::= expr(X) CONCAT(OP) expr(Y).         {A = sqlite3Expr(@OP, X, Y, 0);}
%type likeop {struct LikeOp}
likeop(A) ::= LIKE_KW(X).     {A.operator = X; A.not = 0;}
likeop(A) ::= NOT LIKE_KW(X). {A.operator = X; A.not = 1;}
%type escape {Expr*}
%destructor escape {sqlite3ExprDelete($$);}
escape(X) ::= ESCAPE expr(A). [ESCAPE] {X = A;}
escape(X) ::= .               [ESCAPE] {X = 0;}
expr(A) ::= expr(X) likeop(OP) expr(Y) escape(E).  [LIKE_KW]  {
  ExprList *pList = sqlite3ExprListAppend(0, Y, 0);
  pList = sqlite3ExprListAppend(pList, X, 0);
  if( E ){
    pList = sqlite3ExprListAppend(pList, E, 0);
813
814
815
816
817
818
819

820
821
822

823
824
825
826
827
828
829
  A = sqlite3ExprListAppend(A, Z, 0);
}
case_exprlist(A) ::= WHEN expr(Y) THEN expr(Z). {
  A = sqlite3ExprListAppend(0, Y, 0);
  A = sqlite3ExprListAppend(A, Z, 0);
}
%type case_else {Expr*}

case_else(A) ::=  ELSE expr(X).         {A = X;}
case_else(A) ::=  .                     {A = 0;} 
%type case_operand {Expr*}

case_operand(A) ::= expr(X).            {A = X;} 
case_operand(A) ::= .                   {A = 0;} 

%type exprlist {ExprList*}
%destructor exprlist {sqlite3ExprListDelete($$);}
%type expritem {Expr*}
%destructor expritem {sqlite3ExprDelete($$);}







>



>







814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
  A = sqlite3ExprListAppend(A, Z, 0);
}
case_exprlist(A) ::= WHEN expr(Y) THEN expr(Z). {
  A = sqlite3ExprListAppend(0, Y, 0);
  A = sqlite3ExprListAppend(A, Z, 0);
}
%type case_else {Expr*}
%destructor case_else {sqlite3ExprDelete($$);}
case_else(A) ::=  ELSE expr(X).         {A = X;}
case_else(A) ::=  .                     {A = 0;} 
%type case_operand {Expr*}
%destructor case_operand {sqlite3ExprDelete($$);}
case_operand(A) ::= expr(X).            {A = X;} 
case_operand(A) ::= .                   {A = 0;} 

%type exprlist {ExprList*}
%destructor exprlist {sqlite3ExprListDelete($$);}
%type expritem {Expr*}
%destructor expritem {sqlite3ExprDelete($$);}
936
937
938
939
940
941
942

943
944
945
946
947
948
949

%type foreach_clause {int}
foreach_clause(A) ::= .                   { A = TK_ROW; }
foreach_clause(A) ::= FOR EACH ROW.       { A = TK_ROW; }
foreach_clause(A) ::= FOR EACH STATEMENT. { A = TK_STATEMENT; }

%type when_clause {Expr*}

when_clause(A) ::= .             { A = 0; }
when_clause(A) ::= WHEN expr(X). { A = X; }

%type trigger_cmd_list {TriggerStep*}
%destructor trigger_cmd_list {sqlite3DeleteTriggerStep($$);}
trigger_cmd_list(A) ::= trigger_cmd(X) SEMI trigger_cmd_list(Y). {
  X->pNext = Y;







>







939
940
941
942
943
944
945
946
947
948
949
950
951
952
953

%type foreach_clause {int}
foreach_clause(A) ::= .                   { A = TK_ROW; }
foreach_clause(A) ::= FOR EACH ROW.       { A = TK_ROW; }
foreach_clause(A) ::= FOR EACH STATEMENT. { A = TK_STATEMENT; }

%type when_clause {Expr*}
%destructor when_clause {sqlite3ExprDelete($$);}
when_clause(A) ::= .             { A = 0; }
when_clause(A) ::= WHEN expr(X). { A = X; }

%type trigger_cmd_list {TriggerStep*}
%destructor trigger_cmd_list {sqlite3DeleteTriggerStep($$);}
trigger_cmd_list(A) ::= trigger_cmd(X) SEMI trigger_cmd_list(Y). {
  X->pNext = Y;
999
1000
1001
1002
1003
1004
1005

1006
1007
1008
1009
1010
1011
1012
%endif // !SQLITE_OMIT_TRIGGER

//////////////////////// ATTACH DATABASE file AS name /////////////////////////
cmd ::= ATTACH database_kw_opt expr(F) AS expr(D) key_opt(K). {
  sqlite3Attach(pParse, F, D, K);
}
%type key_opt {Expr *}

key_opt(A) ::= .                     { A = 0; }
key_opt(A) ::= KEY expr(X).          { A = X; }

database_kw_opt ::= DATABASE.
database_kw_opt ::= .

//////////////////////// DETACH DATABASE name /////////////////////////////////







>







1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
%endif // !SQLITE_OMIT_TRIGGER

//////////////////////// ATTACH DATABASE file AS name /////////////////////////
cmd ::= ATTACH database_kw_opt expr(F) AS expr(D) key_opt(K). {
  sqlite3Attach(pParse, F, D, K);
}
%type key_opt {Expr *}
%destructor key_opt {sqlite3ExprDelete($$);}
key_opt(A) ::= .                     { A = 0; }
key_opt(A) ::= KEY expr(X).          { A = X; }

database_kw_opt ::= DATABASE.
database_kw_opt ::= .

//////////////////////// DETACH DATABASE name /////////////////////////////////
Changes to test/expr.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2001 September 15
#
# 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 file is testing expressions.
#
# $Id: expr.test,v 1.48 2005/11/14 22:29:06 drh Exp $

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

# Create a table to work with.
#
execsql {CREATE TABLE test1(i1 int, i2 int, r1 real, r2 real, t1 text, t2 text)}













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2001 September 15
#
# 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 file is testing expressions.
#
# $Id: expr.test,v 1.49 2006/01/07 14:02:27 danielk1977 Exp $

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

# Create a table to work with.
#
execsql {CREATE TABLE test1(i1 int, i2 int, r1 real, r2 real, t1 text, t2 text)}
629
630
631
632
633
634
635





636




637


638
do_test expr-11.1 {
  execsql {SELECT typeof(9223372036854775807)}
} {integer}
do_test expr-11.2 {
  execsql {SELECT typeof(9223372036854775808)}
} {real}














finish_test







>
>
>
>
>
|
>
>
>
>
|
>
>

629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
do_test expr-11.1 {
  execsql {SELECT typeof(9223372036854775807)}
} {integer}
do_test expr-11.2 {
  execsql {SELECT typeof(9223372036854775808)}
} {real}

# These two statements used to leak memory (because of missing %destructor
# directives in parse.y).
do_test expr-12.1 {
  catchsql {
    SELECT (CASE a>4 THEN 1 ELSE 0 END) FROM test1;
  }
} {1 {near "THEN": syntax error}}
do_test expr-12.2 {
  catchsql {
    SELECT (CASE WHEN a>4 THEN 1 ELSE 0) FROM test1;
  }
} {1 {near ")": syntax error}}

finish_test