/ Check-in [ac6000f0]
Login

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

Overview
Comment:Add support for table-valued functions on the RHS of an IN operator.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ac6000f050ff4efcf8a87f0825077dbf4144f073
User & Date: drh 2016-07-02 12:08:14
Context
2016-07-02
12:33
Fix a problem in table-valued functions on the RHS of an IN operator that occurs following an OOM error. check-in: bead151e user: drh tags: trunk
12:08
Add support for table-valued functions on the RHS of an IN operator. check-in: ac6000f0 user: drh tags: trunk
2016-07-01
20:12
Fix the transitive constraint logic error that can result in a null pointer dereference. Fix for ticket [e8d439c77685eca6]. check-in: 228a7879 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Show Whitespace Changes Patch

Changes to src/parse.y.

  1130   1130     }
  1131   1131     expr(A) ::= expr(A) in_op(N) LP select(Y) RP(E).  [IN] {
  1132   1132       A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0);
  1133   1133       sqlite3PExprAddSelect(pParse, A.pExpr, Y);
  1134   1134       exprNot(pParse, N, &A);
  1135   1135       A.zEnd = &E.z[E.n];
  1136   1136     }
  1137         -  expr(A) ::= expr(A) in_op(N) nm(Y) dbnm(Z). [IN] {
         1137  +  expr(A) ::= expr(A) in_op(N) nm(Y) dbnm(Z) paren_exprlist(E). [IN] {
  1138   1138       SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&Y,&Z);
  1139   1139       Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
         1140  +    if( E ) sqlite3SrcListFuncArgs(pParse, pSrc, E);
  1140   1141       A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0);
  1141   1142       sqlite3PExprAddSelect(pParse, A.pExpr, pSelect);
  1142   1143       exprNot(pParse, N, &A);
  1143   1144       A.zEnd = Z.z ? &Z.z[Z.n] : &Y.z[Y.n];
  1144   1145     }
  1145   1146     expr(A) ::= EXISTS(B) LP select(Y) RP(E). {
  1146   1147       Expr *p;
................................................................................
  1188   1189   
  1189   1190   exprlist(A) ::= nexprlist(A).
  1190   1191   exprlist(A) ::= .                            {A = 0;}
  1191   1192   nexprlist(A) ::= nexprlist(A) COMMA expr(Y).
  1192   1193       {A = sqlite3ExprListAppend(pParse,A,Y.pExpr);}
  1193   1194   nexprlist(A) ::= expr(Y).
  1194   1195       {A = sqlite3ExprListAppend(pParse,0,Y.pExpr); /*A-overwrites-Y*/}
         1196  +
         1197  +/* A paren_exprlist is an optional expression list contained inside
         1198  +** of parenthesis */
         1199  +%type paren_exprlist {ExprList*}
         1200  +%destructor paren_exprlist {sqlite3ExprListDelete(pParse->db, $$);}
         1201  +paren_exprlist(A) ::= .   {A = 0;}
         1202  +paren_exprlist(A) ::= LP exprlist(X) RP.  {A = X;}
         1203  +
  1195   1204   
  1196   1205   
  1197   1206   ///////////////////////////// The CREATE INDEX command ///////////////////////
  1198   1207   //
  1199   1208   cmd ::= createkw(S) uniqueflag(U) INDEX ifnotexists(NE) nm(X) dbnm(D)
  1200   1209           ON nm(Y) LP sortlist(Z) RP where_opt(W). {
  1201   1210     sqlite3CreateIndex(pParse, &X, &D, 

Changes to test/tabfunc01.test.

   130    130   # each step of output.  At one point, the IN operator could not be used
   131    131   # by virtual tables unless omit was set.
   132    132   #
   133    133   do_execsql_test tabfunc01-500 {
   134    134     SELECT * FROM generate_series WHERE start IN (1,7) AND stop=20 AND step=10
   135    135     ORDER BY +1;
   136    136   } {1 7 11 17}
          137  +
          138  +# Table-valued functions on the RHS of an IN operator
          139  +#
          140  +do_execsql_test tabfunc01-600 {
          141  +  CREATE TABLE t600(a INTEGER PRIMARY KEY, b TEXT);
          142  +  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100)
          143  +    INSERT INTO t600(a,b) SELECT x, printf('(%03d)',x) FROM c;
          144  +  SELECT b FROM t600 WHERE a IN generate_series(2,52,10);
          145  +} {(002) (012) (022) (032) (042) (052)}
   137    146   
   138    147   finish_test