]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
A list of arguments following a table name translates into equality
authordrh <drh@noemail.net>
Wed, 19 Aug 2015 17:11:37 +0000 (17:11 +0000)
committerdrh <drh@noemail.net>
Wed, 19 Aug 2015 17:11:37 +0000 (17:11 +0000)
constraints against hidden columns in that table.

FossilOrigin-Name: 40e12cfe4c29475417ba89fb637b4c763cf74016

12 files changed:
manifest
manifest.uuid
src/build.c
src/parse.y
src/resolve.c
src/sqliteInt.h
src/treeview.c
src/walker.c
src/where.c
src/whereInt.h
src/whereexpr.c
test/tabfunc01.test

index 97f862e1e2ab01621b87e68eea406abee4724813..758e6c154cf141e4c6d2ec167929218664e131ba 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Minor\srefactor\sof\sthe\sSrcList\sobject\sso\sthat\sit\sis\sable\sto\shold\sthe\sargument\nlist\sto\sa\stable-valued-function\sin\sthe\sFROM\sclause.
-D 2015-08-19T15:20:00.817
+C A\slist\sof\sarguments\sfollowing\sa\stable\sname\stranslates\sinto\sequality\nconstraints\sagainst\shidden\scolumns\sin\sthat\stable.
+D 2015-08-19T17:11:37.512
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 4f663b6b4954b9b1eb0e6f08387688a93b57542d
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -281,7 +281,7 @@ F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
 F src/btree.c f48b3ef91676c06a90a8832987ecef6b94c931ee
 F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1
 F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0
-F src/build.c 909416959d8948a436d86461ffacdb3b19ec8286
+F src/build.c 16051071cd855c23e47b087b49ac99c65b1d8c39
 F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
 F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b
@@ -325,7 +325,7 @@ F src/os_win.c 40b3af7a47eb1107d0d69e592bec345a3b7b798a
 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
 F src/pager.c aa916ca28606ccf4b6877dfc2b643ccbca86589f
 F src/pager.h 6d435f563b3f7fcae4b84433b76a6ac2730036e2
-F src/parse.y 2ed6efe32ec400c765fec5f3253c650ffdfeb65b
+F src/parse.y ad9af8552f6f340bd646577ca63356a6f82b6a7e
 F src/pcache.c cde06aa50962595e412d497e22fd2e07878ba1f0
 F src/pcache.h 9968603796240cdf83da7e7bef76edf90619cea9
 F src/pcache1.c d08939800abf3031bd0affd5a13fbc4d7ba3fb68
@@ -334,14 +334,14 @@ F src/pragma.h 631a91c8b0e6ca8f051a1d8a4a0da4150e04620a
 F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1
 F src/printf.c 2bc439ff20a4aad0e0ad50a37a67b5eae7d20edc
 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
-F src/resolve.c cd1c44c853c3560b3fa85637f732a9b7fc0e9295
+F src/resolve.c bbb4874decae6e60eee0395a31205d3b55cd2c00
 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
 F src/select.c c46de38c1b66355f02a839bb72eb13f277e6d19c
 F src/shell.c b1f91e60918df3a68efad1e3a11696b9a7e23d23
 F src/sqlite.h.in 447ead0a6b3293206f04a0896553955d07cfb4b9
 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
 F src/sqlite3ext.h a0b948ebc89bac13941254641326a6aa248c2cc4
-F src/sqliteInt.h 9fae37f6bcc2f9ed71fe0362972c263642326914
+F src/sqliteInt.h 89e68539d645db597366a91411468b51e73c21a0
 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
 F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179
 F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
@@ -393,7 +393,7 @@ F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
 F src/threads.c 6bbcc9fe50c917864d48287b4792d46d6e873481
 F src/tokenize.c 57cb3720f53f84d811def2069c2b169b6be539a5
-F src/treeview.c fda5cfc4635d4a436214c4593f3032d07688a0e2
+F src/treeview.c c15df00728034549ff92d78ae851b44952736d3b
 F src/trigger.c 322f23aad694e8f31d384dcfa386d52a48d3c52f
 F src/update.c 487747b328b7216bb7f6af0695d6937d5c9e605f
 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
@@ -412,11 +412,11 @@ F src/vtab.c 1e3405f78e9f248bdee6ef7a8903fadaa7222f9c
 F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
 F src/wal.c 6fb6b68969e4692593c2552c4e7bff5882de2cb8
 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
-F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
-F src/where.c a572b23993febb7bb72ee997c55da3b03d870be8
-F src/whereInt.h 5f87e3c4b0551747d119730dfebddd3c54f04047
+F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba
+F src/where.c 66518a14a1238611aa0744d6980b6b7f544f4816
+F src/whereInt.h 880a8599226ac1c00203490d934f3ed79b292572
 F src/wherecode.c 69f19535a6de0cceb10e16b31a3a03463e31bc24
-F src/whereexpr.c 9ce1c9cfedbf80c93c7d899497025ec8256ce652
+F src/whereexpr.c 6332ade8f72beebb6438734e92757da4631176e0
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@@ -1031,7 +1031,7 @@ F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2
 F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85
 F test/syscall.test d2fdaad713f103ac611fe7ef9b724c7b69f8149c
 F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6
-F test/tabfunc01.test 0c1fb6ee8eba49c13b8a4c35b8f0726397debb33
+F test/tabfunc01.test ca013d7012764f85185d0d1b77f158a7b1b3ad6d
 F test/table.test 33bf0d1fd07f304582695184b8e6feb017303816
 F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
@@ -1376,7 +1376,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P c58426dbd5ea8b8440ebcc1214f79fa63d658216
-R 8f19410a9a93222f2a2f5ce9faa04ea9
+P b919376147597c4b73421abe5788f893baf1560b
+R 03d0a3c413d15fc0179aae3fc23d1837
 U drh
-Z 28752308589cee1f3c6d24275593910d
+Z 86fabb010e68498602162c53cf0d6cc5
index d399910325c33f21f1267c087a20eb656eb83fa3..26e06bc1f6590ac4fc166e1a2601dc5a9108337f 100644 (file)
@@ -1 +1 @@
-b919376147597c4b73421abe5788f893baf1560b
\ No newline at end of file
+40e12cfe4c29475417ba89fb637b4c763cf74016
\ No newline at end of file
index 3ff49d12b54ec3870640f643cd46fc3e2842fdd1..96dc03a8251c418ca09060b43d9af7321d7bf93c 100644 (file)
@@ -3797,6 +3797,21 @@ void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){
   }
 }
 
+/*
+** Add the list of function arguments to the SrcList entry for a
+** table-valued-function.
+*/
+void sqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *pList){
+  if( p && ALWAYS(p->nSrc>0) ){
+    struct SrcList_item *pItem = &p->a[p->nSrc-1];
+    assert( pItem->fg.notIndexed==0 );
+    assert( pItem->fg.isIndexedBy==0 );
+    assert( pItem->fg.isTabFunc==0 );
+    pItem->u1.pFuncArg = pList;
+    pItem->fg.isTabFunc = 1;
+  }
+}
+
 /*
 ** When building up a FROM clause in the parser, the join operator
 ** is initially attached to the left operand.  But the code generator
index 9174abf7f93d9e6564ed503f3661ef653140ad69..3d186b28aa62e126fea45d9495414aa17b43f18a 100644 (file)
@@ -594,6 +594,11 @@ seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) as(Z) indexed_opt(I)
   A = sqlite3SrcListAppendFromTerm(pParse,X,&Y,&D,&Z,0,N,U);
   sqlite3SrcListIndexedBy(pParse, A, &I);
 }
+seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) LP exprlist(E) RP as(Z)
+                  on_opt(N) using_opt(U). {
+  A = sqlite3SrcListAppendFromTerm(pParse,X,&Y,&D,&Z,0,N,U);
+  sqlite3SrcListFuncArgs(pParse, A, E);
+}
 %ifndef SQLITE_OMIT_SUBQUERY
   seltablist(A) ::= stl_prefix(X) LP select(S) RP
                     as(Z) on_opt(N) using_opt(U). {
index ecba89162a122ac3692c4c09267ed5c401cdcd33..72d5f319c1991c32b50166c3b45eeb47c002632a 100644 (file)
@@ -1142,7 +1142,6 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
   int isCompound;         /* True if p is a compound select */
   int nCompound;          /* Number of compound terms processed so far */
   Parse *pParse;          /* Parsing context */
-  ExprList *pEList;       /* Result set expression list */
   int i;                  /* Loop counter */
   ExprList *pGroupBy;     /* The GROUP BY clause */
   Select *pLeftmost;      /* Left-most of SELECT of a compound */
@@ -1237,14 +1236,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
     sNC.pNext = pOuterNC;
   
     /* Resolve names in the result set. */
-    pEList = p->pEList;
-    assert( pEList!=0 );
-    for(i=0; i<pEList->nExpr; i++){
-      Expr *pX = pEList->a[i].pExpr;
-      if( sqlite3ResolveExprNames(&sNC, pX) ){
-        return WRC_Abort;
-      }
-    }
+    if( sqlite3ResolveExprListNames(&sNC, p->pEList) ) return WRC_Abort;
   
     /* If there are no aggregate functions in the result-set, and no GROUP BY 
     ** expression, do not allow aggregates in any of the other expressions.
@@ -1277,6 +1269,16 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
     if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort;
     if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort;
 
+    /* Resolve names in table-valued-function arguments */
+    for(i=0; i<p->pSrc->nSrc; i++){
+      struct SrcList_item *pItem = &p->pSrc->a[i];
+      if( pItem->fg.isTabFunc
+       && sqlite3ResolveExprListNames(&sNC, pItem->u1.pFuncArg) 
+      ){
+        return WRC_Abort;
+      }
+    }
+
     /* The ORDER BY and GROUP BY clauses may not refer to terms in
     ** outer queries 
     */
@@ -1440,6 +1442,21 @@ int sqlite3ResolveExprNames(
   return ExprHasProperty(pExpr, EP_Error);
 }
 
+/*
+** Resolve all names for all expression in an expression list.  This is
+** just like sqlite3ResolveExprNames() except that it works for an expression
+** list rather than a single expression.
+*/
+int sqlite3ResolveExprListNames( 
+  NameContext *pNC,       /* Namespace to resolve expressions in. */
+  ExprList *pList         /* The expression list to be analyzed. */
+){
+  int i;
+  for(i=0; i<pList->nExpr; i++){
+    if( sqlite3ResolveExprNames(pNC, pList->a[i].pExpr) ) return WRC_Abort;
+  }
+  return WRC_Continue;
+}
 
 /*
 ** Resolve all names in all expressions of a SELECT and in all
index 739678998db044540a493518376fa3916f569b4f..96a7700210e525975ac2956d413a4b1a1dd6ae21 100644 (file)
@@ -3328,6 +3328,7 @@ SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*);
 SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*,
                                       Token*, Select*, Expr*, IdList*);
 void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
+void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*);
 int sqlite3IndexedByLookup(Parse *, struct SrcList_item *);
 void sqlite3SrcListShiftJoinType(SrcList*);
 void sqlite3SrcListAssignCursors(Parse*, SrcList*);
@@ -3619,6 +3620,7 @@ void sqlite3SelectPrep(Parse*, Select*, NameContext*);
 void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p);
 int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
 int sqlite3ResolveExprNames(NameContext*, Expr*);
+int sqlite3ResolveExprListNames(NameContext*, ExprList*);
 void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
 void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);
 int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
index 77a654477dd1b3a8b1d26dff2cbb00929162f553..fbe8fd46d5a64bafb584738a4f6eafc7a64e2a81 100644 (file)
@@ -128,6 +128,9 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
       if( pItem->pSelect ){
         sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
       }
+      if( pItem->fg.isTabFunc ){
+        sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
+      }
       sqlite3TreeViewPop(pView);
     }
     sqlite3TreeViewPop(pView);
index e30bb60b5a493f19da3ddc117cf6b8d2c03e89c6..81e0f2cd60b85ea72bbaa4c877a9cbd9029d0503 100644 (file)
@@ -105,6 +105,11 @@ int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){
       if( sqlite3WalkSelect(pWalker, pItem->pSelect) ){
         return WRC_Abort;
       }
+      if( pItem->fg.isTabFunc
+       && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg)
+      ){
+        return WRC_Abort;
+      }
     }
   }
   return WRC_Continue;
index 2a84a5952a2135050365ed99b907ecb86c4162c3..bdcfeaa9aa6066acaf5d5a53eefe0268ce12f7f6 100644 (file)
@@ -4030,6 +4030,7 @@ WhereInfo *sqlite3WhereBegin(
   */
   for(ii=0; ii<pTabList->nSrc; ii++){
     createMask(pMaskSet, pTabList->a[ii].iCursor);
+    sqlite3WhereTabFuncArgs(pParse, &pTabList->a[ii], &pWInfo->sWC);
   }
 #ifndef NDEBUG
   {
index 8929d8c4be55e5ad080531b13379cbf63800fa8a..76b665d9717904072cb09a7a1781556dda6e0e34 100644 (file)
@@ -475,6 +475,7 @@ void sqlite3WhereSplit(WhereClause*,Expr*,u8);
 Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*);
 Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*);
 void sqlite3WhereExprAnalyze(SrcList*, WhereClause*);
+void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*);
 
 
 
index 3607ef5352a236a5d54240fa5dc325e1cb4f22ef..a0f7c822aff0ec8a3b0cbacac18e86b3cc1528e3 100644 (file)
@@ -1247,3 +1247,42 @@ void sqlite3WhereExprAnalyze(
     exprAnalyze(pTabList, pWC, i);
   }
 }
+
+/*
+** For table-valued-functions, transform the function arguments into
+** new WHERE clause terms.  
+**
+** Each function argument translates into an equality constraint against
+** a HIDDEN column in the table.
+*/
+void sqlite3WhereTabFuncArgs(
+  Parse *pParse,                    /* Parsing context */
+  struct SrcList_item *pItem,       /* The FROM clause term to process */
+  WhereClause *pWC                  /* Xfer function arguments to here */
+){
+  Table *pTab;
+  int j, k;
+  ExprList *pArgs;
+  Expr *pColRef;
+  Expr *pTerm;
+  if( pItem->fg.isTabFunc==0 ) return;
+  pTab = pItem->pTab;
+  assert( pTab!=0 );
+  pArgs = pItem->u1.pFuncArg;
+  assert( pArgs!=0 );
+  for(j=k=0; j<pArgs->nExpr; j++){
+    while( k<pTab->nCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){ k++; }
+    if( k>=pTab->nCol ){
+      sqlite3ErrorMsg(pParse, "too many arguments on %s - max %d",
+                      pTab->zName, j);
+      return;
+    }
+    pColRef = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
+    if( pColRef==0 ) return;
+    pColRef->iTable = pItem->iCursor;
+    pColRef->iColumn = k++;
+    pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef,
+                         sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
+    whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
+  }
+}
index f6579584407faa2ff00419f50ff10569077711bb..7393238b94f96ea98aa240fd20e22c2387888314 100644 (file)
@@ -32,5 +32,24 @@ do_execsql_test tabfunc01-1.2 {
 do_catchsql_test tabfunc01-1.3 {
   CREATE VIRTUAL TABLE t1 USING generate_series;
 } {1 {no such module: generate_series}}
+do_execsql_test tabfunc01-1.4 {
+  SELECT * FROM generate_series(1,9,2);
+} {1 3 5 7 9}
+do_execsql_test tabfunc01-1.5 {
+  SELECT * FROM generate_series(1,9);
+} {1 2 3 4 5 6 7 8 9}
+do_execsql_test tabfunc01-1.6 {
+  SELECT * FROM generate_series(1,10) WHERE step=3;
+} {1 4 7 10}
+do_catchsql_test tabfunc01-1.7 {
+  SELECT * FROM generate_series(1,9,2,11);
+} {1 {too many arguments on generate_series - max 3}}
+
+do_execsql_test tabfunc01-2.1 {
+  CREATE TABLE t1(x);
+  INSERT INTO t1(x) VALUES(2),(3);
+  SELECT *, '|' FROM t1, generate_series(1,x) ORDER BY 1, 2
+  
+} {2 1 | 2 2 | 3 1 | 3 2 | 3 3 |}
 
 finish_test