/ Check-in [01874d25]
Login

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

Overview
Comment:Allow "expr IN table" as a shorthand for "expr IN (SELECT * FROM table)" (CVS 1180)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:01874d252ac44861e927dea3f5534f67e19b1fa8
User & Date: drh 2004-01-15 03:30:25
Original Comment: Allow "<expr> IN " as a shorthand for "<expr> IN (SELECT * FROM
)" (CVS 1180)
Context
2004-01-15
13:29
More aggressive retry schedule in sqlite_busy_timeout(). (CVS 1181) check-in: 5e85025b user: drh tags: trunk
03:30
Allow "expr IN table" as a shorthand for "expr IN (SELECT * FROM table)" (CVS 1180) check-in: 01874d25 user: drh tags: trunk
02:44
Reinsert the experimental sqlite_commit_hook() API. (CVS 1179) check-in: 72bc84f2 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/parse.y.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
660
661
662
663
664
665
666
















667
668
669
670
671
672
673
**
*************************************************************************
** 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.105 2003/12/06 21:43:56 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
%default_type {Token}
%extra_argument {Parse *pParse}
%syntax_error {
  if( pParse->zErrMsg==0 ){
................................................................................
}
expr(A) ::= expr(X) NOT IN LP select(Y) RP(E).  {
  A = sqliteExpr(TK_IN, X, 0, 0);
  if( A ) A->pSelect = Y;
  A = sqliteExpr(TK_NOT, A, 0, 0);
  sqliteExprSpan(A,&X->span,&E);
}

















/* CASE expressions */
expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
  A = sqliteExpr(TK_CASE, X, Z, 0);
  if( A ) A->pList = Y;
  sqliteExprSpan(A, &C, &E);
}







|







 







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







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
**
*************************************************************************
** 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.106 2004/01/15 03:30:25 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
%default_type {Token}
%extra_argument {Parse *pParse}
%syntax_error {
  if( pParse->zErrMsg==0 ){
................................................................................
}
expr(A) ::= expr(X) NOT IN LP select(Y) RP(E).  {
  A = sqliteExpr(TK_IN, X, 0, 0);
  if( A ) A->pSelect = Y;
  A = sqliteExpr(TK_NOT, A, 0, 0);
  sqliteExprSpan(A,&X->span,&E);
}
expr(A) ::= expr(X) IN nm(Y) dbnm(D). {
  SrcList *pSrc = sqliteSrcListAppend(0, &Y, &D);
  ExprList *pList = sqliteExprListAppend(0, sqliteExpr(TK_ALL,0,0,0), 0);
  A = sqliteExpr(TK_IN, X, 0, 0);
  if( A ) A->pSelect = sqliteSelectNew(pList,pSrc,0,0,0,0,0,-1,0);
  sqliteExprSpan(A,&X->span,D.z?&D:&Y);
}
expr(A) ::= expr(X) NOT IN nm(Y) dbnm(D). {
  SrcList *pSrc = sqliteSrcListAppend(0, &Y, &D);
  ExprList *pList = sqliteExprListAppend(0, sqliteExpr(TK_ALL,0,0,0), 0);
  A = sqliteExpr(TK_IN, X, 0, 0);
  if( A ) A->pSelect = sqliteSelectNew(pList,pSrc,0,0,0,0,0,-1,0);
  A = sqliteExpr(TK_NOT, A, 0, 0);
  sqliteExprSpan(A,&X->span,D.z?&D:&Y);
}


/* CASE expressions */
expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
  A = sqliteExpr(TK_CASE, X, Z, 0);
  if( A ) A->pList = Y;
  sqliteExprSpan(A, &C, &E);
}

Changes to test/in.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
272
273
274
275
276
277
278

279




280

















281
#    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 the IN and BETWEEN operator.
#
# $Id: in.test,v 1.10 2003/04/19 17:27:25 drh Exp $

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

# Generate the test data we will need for the first squences of tests.
#
do_test in-1.0 {
................................................................................
} {world}
do_test in-8.2 {
  execsql {
    SELECT b FROM t1 WHERE a IN ("hello",'there')
  }
} {world}

























finish_test







|







 







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

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
#    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 the IN and BETWEEN operator.
#
# $Id: in.test,v 1.11 2004/01/15 03:30:25 drh Exp $

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

# Generate the test data we will need for the first squences of tests.
#
do_test in-1.0 {
................................................................................
} {world}
do_test in-8.2 {
  execsql {
    SELECT b FROM t1 WHERE a IN ("hello",'there')
  }
} {world}

# Test constructs of the form:  expr IN tablename
#
do_test in-9.1 {
  execsql {
    CREATE TABLE t4 AS SELECT a FROM tb;
    SELECT * FROM t4;    
  }
} {1 2 3 5 7 9 11}
do_test in-9.2 {
  execsql {
    SELECT b FROM t1 WHERE a IN t4;
  }
} {32 128}
do_test in-9.3 {
  execsql {
    SELECT b FROM t1 WHERE a NOT IN t4;
  }
} {64 256 world}
do_test in-9.4 {
  catchsql {
    SELECT b FROM t1 WHERE a NOT IN tb;
  }
} {1 {only a single result allowed for a SELECT that is part of an expression}}

finish_test