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 |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
01874d252ac44861e927dea3f5534f67 |
User & Date: | drh 2004-01-15 03:30:25.000 |
Original Comment: | Allow "<expr> IN |
Context
2004-01-15
| ||
13:29 | More aggressive retry schedule in sqlite_busy_timeout(). (CVS 1181) (check-in: 5e85025be7 user: drh tags: trunk) | |
03:30 | Allow "expr IN table" as a shorthand for "expr IN (SELECT * FROM table)" (CVS 1180) (check-in: 01874d252a user: drh tags: trunk) | |
02:44 | Reinsert the experimental sqlite_commit_hook() API. (CVS 1179) (check-in: 72bc84f2f1 user: drh tags: trunk) | |
Changes
Changes to src/parse.y.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** 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. ** | | | 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.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 ){ |
︙ | ︙ | |||
660 661 662 663 664 665 666 667 668 669 670 671 672 673 | } 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); } | > > > > > > > > > > > > > > > > | 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 | } 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 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 the IN and BETWEEN operator. # | | | 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 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 { |
︙ | ︙ | |||
272 273 274 275 276 277 278 | } {world} do_test in-8.2 { execsql { SELECT b FROM t1 WHERE a IN ("hello",'there') } } {world} | > | > > > > | > > > > > > > > > > > > > > > > > | 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 | } {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 |