SQLite

Check-in [ac6000f050]
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
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ac6000f050ff4efcf8a87f0825077dbf4144f073
User & Date: drh 2016-07-02 12:08:14.436
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: bead151e72 user: drh tags: trunk)
12:08
Add support for table-valued functions on the RHS of an IN operator. (check-in: ac6000f050 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: 228a787987 user: drh tags: trunk)
Changes
Side-by-Side Diff Show Whitespace Changes Patch
Changes to src/parse.y.
1130
1131
1132
1133
1134
1135
1136
1137

1138
1139

1140
1141
1142
1143
1144
1145
1146
1130
1131
1132
1133
1134
1135
1136

1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147







-
+


+







  }
  expr(A) ::= expr(A) in_op(N) LP select(Y) RP(E).  [IN] {
    A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0);
    sqlite3PExprAddSelect(pParse, A.pExpr, Y);
    exprNot(pParse, N, &A);
    A.zEnd = &E.z[E.n];
  }
  expr(A) ::= expr(A) in_op(N) nm(Y) dbnm(Z). [IN] {
  expr(A) ::= expr(A) in_op(N) nm(Y) dbnm(Z) paren_exprlist(E). [IN] {
    SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&Y,&Z);
    Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
    if( E ) sqlite3SrcListFuncArgs(pParse, pSrc, E);
    A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0);
    sqlite3PExprAddSelect(pParse, A.pExpr, pSelect);
    exprNot(pParse, N, &A);
    A.zEnd = Z.z ? &Z.z[Z.n] : &Y.z[Y.n];
  }
  expr(A) ::= EXISTS(B) LP select(Y) RP(E). {
    Expr *p;
1188
1189
1190
1191
1192
1193
1194








1195
1196
1197
1198
1199
1200
1201
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210







+
+
+
+
+
+
+
+








exprlist(A) ::= nexprlist(A).
exprlist(A) ::= .                            {A = 0;}
nexprlist(A) ::= nexprlist(A) COMMA expr(Y).
    {A = sqlite3ExprListAppend(pParse,A,Y.pExpr);}
nexprlist(A) ::= expr(Y).
    {A = sqlite3ExprListAppend(pParse,0,Y.pExpr); /*A-overwrites-Y*/}

/* A paren_exprlist is an optional expression list contained inside
** of parenthesis */
%type paren_exprlist {ExprList*}
%destructor paren_exprlist {sqlite3ExprListDelete(pParse->db, $$);}
paren_exprlist(A) ::= .   {A = 0;}
paren_exprlist(A) ::= LP exprlist(X) RP.  {A = X;}



///////////////////////////// The CREATE INDEX command ///////////////////////
//
cmd ::= createkw(S) uniqueflag(U) INDEX ifnotexists(NE) nm(X) dbnm(D)
        ON nm(Y) LP sortlist(Z) RP where_opt(W). {
  sqlite3CreateIndex(pParse, &X, &D, 
Changes to test/tabfunc01.test.
130
131
132
133
134
135
136









137
138
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147







+
+
+
+
+
+
+
+
+


# each step of output.  At one point, the IN operator could not be used
# by virtual tables unless omit was set.
#
do_execsql_test tabfunc01-500 {
  SELECT * FROM generate_series WHERE start IN (1,7) AND stop=20 AND step=10
  ORDER BY +1;
} {1 7 11 17}

# Table-valued functions on the RHS of an IN operator
#
do_execsql_test tabfunc01-600 {
  CREATE TABLE t600(a INTEGER PRIMARY KEY, b TEXT);
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100)
    INSERT INTO t600(a,b) SELECT x, printf('(%03d)',x) FROM c;
  SELECT b FROM t600 WHERE a IN generate_series(2,52,10);
} {(002) (012) (022) (032) (042) (052)}

finish_test