]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Improvements to the way VALUES clauses are parsed.
authordrh <drh@noemail.net>
Thu, 16 Apr 2015 14:13:12 +0000 (14:13 +0000)
committerdrh <drh@noemail.net>
Thu, 16 Apr 2015 14:13:12 +0000 (14:13 +0000)
FossilOrigin-Name: ec5a493ad27593ca78899b3001630c1898b940ff

manifest
manifest.uuid
src/expr.c
src/parse.y
src/select.c
src/sqliteInt.h
test/select4.test

index 93195dbcb1cd8e01f24ecbd96199867ac69c74e2..e9c5d46443ce96fc612a235d28de00edcb81f1f2 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sthe\scorruptC.test\smodule\sdue\sto\sa\schange\sin\serror\smessage\stext.
-D 2015-04-16T12:12:07.953
+C Improvements\sto\sthe\sway\sVALUES\sclauses\sare\sparsed.
+D 2015-04-16T14:13:12.394
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5f78b1ab81b64e7c57a75d170832443e66c0880a
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -182,7 +182,7 @@ F src/complete.c a5cf5b4b56390cfb7b8636e8f7ddef90258dd575
 F src/ctime.c 98f89724adc891a1a4c655bee04e33e716e05887
 F src/date.c e4d50b3283696836ec1036b695ead9a19e37a5ac
 F src/delete.c 37964e6c1d73ff49cbea9ff690c9605fb15f600e
-F src/expr.c 8800584340a9b4f4c0ca55c360de751c6da0b11a
+F src/expr.c f37d5eb44a1fad4ca4faa6b0c4f1230f233e3835
 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
 F src/fkey.c 3343d551a8d810782257244fb33f2ce191493c39
 F src/func.c 1414c24c873c48796ad45942257a179a423ba42f
@@ -219,7 +219,7 @@ F src/os_win.c 03d27be3a20048ef52a648d5f0a15f5edda9f2a3
 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
 F src/pager.c 4120a49ecd37697e28f5ed807f470b9c0b88410c
 F src/pager.h c3476e7c89cdf1c6914e50a11f3714e30b4e0a77
-F src/parse.y 1299c66e7b1707322ccd8af43a359b8fb0d46d72
+F src/parse.y b5c16bc5aa5e59a7ceb0fe94defa9dce3a6b1d3c
 F src/pcache.c 10539fb959849ad6efff80050541cab3d25089d4
 F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8
 F src/pcache1.c 69d137620a305f814398bd29a0c998038c0695e9
@@ -230,12 +230,12 @@ F src/printf.c 08fa675c200aac29e561c6153f91f909ed17612f
 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
 F src/resolve.c 66cfe49a9c3b449ef13b89a8c47036a4ed167eab
 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
-F src/select.c fdac71edb73206488b44cfc0f78708e83f99f591
+F src/select.c e24bd1a7b6bf2256cf8df115d01e308c94ad9c05
 F src/shell.c 72b61a9d41ba12b67ea06fe9267abcc012c6c5bb
 F src/sqlite.h.in ca27603a36fcacdaac5a19d8ee35aaff8ce8516f
 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
 F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
-F src/sqliteInt.h 90b7bfd89d7307cd0750663da419ba4bb81e7379
+F src/sqliteInt.h af228df2a02bf1a608d678b312d46aa480470b3c
 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
 F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179
 F src/table.c e7a09215315a978057fb42c640f890160dbcc45e
@@ -839,7 +839,7 @@ F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
 F test/select1.test 53c3a5228b099601eafc7f3cc0e9cd682b07d9d5
 F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
 F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054
-F test/select4.test 16fa1cafb942f42294ec85cbb78954c2f2d15a44
+F test/select4.test d4330ee0e24e52fa21c62c6bbf999dbfcbb7dfd0
 F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535
 F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0
 F test/select7.test 7fd2ef598cfabb6b9ff6ac13973b91d0527df49d
@@ -1250,7 +1250,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 5b3de9390f2ffc4c530fd47c71c70e87972cf74b
-R 52f7fd6b33b7cf36f49fd780c8e11ee8
+P 7c0deed25762a954c78d98412d8f4a265a437d06
+R 611a860661173119865e499e8c5f5052
 U drh
-Z 89ad7719122c7a76b704b370103ce659
+Z f1f791a01fc19f4f892a113c0900910a
index c65ebcbe960910a29c68a31ecb39f55154d6a2c6..c43e82716426c8bf6dae7018f586422c4be1cabc 100644 (file)
@@ -1 +1 @@
-7c0deed25762a954c78d98412d8f4a265a437d06
\ No newline at end of file
+ec5a493ad27593ca78899b3001630c1898b940ff
\ No newline at end of file
index 77eb35aa74d15feba9f68e8681e2e1b7144ba0b9..418881ffd941031ed86b3fc3dce43b6dfe00fa8c 100644 (file)
@@ -2016,7 +2016,7 @@ int sqlite3CodeSubselect(
       pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0,
                                   &sqlite3IntTokens[1]);
       pSel->iLimit = 0;
-      pSel->selFlags &= ~SF_AllValues;
+      pSel->selFlags &= ~SF_MultiValue;
       if( sqlite3Select(pParse, pSel, &dest) ){
         return 0;
       }
index b8ef26810ca3ca2166ad15d385323896cb5234b0..ac15c3ce71f6e698c9f4a165345ccd57d0508774 100644 (file)
@@ -409,28 +409,35 @@ cmd ::= select(X).  {
 %type oneselect {Select*}
 %destructor oneselect {sqlite3SelectDelete(pParse->db, $$);}
 
-select(A) ::= with(W) selectnowith(X). {
-  Select *p = X, *pNext, *pLoop;
-  if( p ){
-    int cnt = 0, mxSelect;
-    p->pWith = W;
+%include {
+  /*
+  ** For a compound SELECT statement, make sure p->pPrior->pNext==p for
+  ** all elements in the list.  And make sure list length does not exceed
+  ** SQLITE_LIMIT_COMPOUND_SELECT.
+  */
+  void parserDoubleLinkSelect(Parse *pParse, Select *p){
     if( p->pPrior ){
-      u16 allValues = SF_Values;
-      pNext = 0;
+      Select *pNext = 0, *pLoop;
+      int mxSelect, cnt = 0;
       for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){
         pLoop->pNext = pNext;
         pLoop->selFlags |= SF_Compound;
-        allValues &= pLoop->selFlags;
       }
-      if( allValues ){
-        p->selFlags |= SF_AllValues;
-      }else if(
-        (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0
-        && cnt>mxSelect
+      if( (p->selFlags & SF_MultiValue)==0 && 
+        (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 &&
+        cnt>mxSelect
       ){
         sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
       }
     }
+  }
+}
+
+select(A) ::= with(W) selectnowith(X). {
+  Select *p = X;
+  if( p ){
+    p->pWith = W;
+    parserDoubleLinkSelect(pParse, p);
   }else{
     sqlite3WithDelete(pParse->db, W);
   }
@@ -445,12 +452,14 @@ selectnowith(A) ::= selectnowith(X) multiselect_op(Y) oneselect(Z).  {
     SrcList *pFrom;
     Token x;
     x.n = 0;
+    parserDoubleLinkSelect(pParse, pRhs);
     pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0);
     pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0);
   }
   if( pRhs ){
     pRhs->op = (u8)Y;
     pRhs->pPrior = X;
+    pRhs->selFlags &= ~SF_MultiValue;
     if( Y!=TK_ALL ) pParse->hasCompound = 1;
   }else{
     sqlite3SelectDelete(pParse->db, X);
@@ -498,13 +507,16 @@ values(A) ::= VALUES LP nexprlist(X) RP. {
   A = sqlite3SelectNew(pParse,X,0,0,0,0,0,SF_Values,0,0);
 }
 values(A) ::= values(X) COMMA LP exprlist(Y) RP. {
-  Select *pRight = sqlite3SelectNew(pParse,Y,0,0,0,0,0,SF_Values,0,0);
+  Select *pRight, *pLeft = X;
+  pRight = sqlite3SelectNew(pParse,Y,0,0,0,0,0,SF_Values|SF_MultiValue,0,0);
+  if( pLeft ) pLeft->selFlags &= ~SF_MultiValue;
   if( pRight ){
     pRight->op = TK_ALL;
-    pRight->pPrior = X;
+    pLeft = X;
+    pRight->pPrior = pLeft;
     A = pRight;
   }else{
-    A = X;
+    A = pLeft;
   }
 }
 
index 8e85ebadbf960c81a2201deccc2594a1179682b7..298ad90a1cc3366071dd65c4a7c0f9c4192f0031 100644 (file)
@@ -2108,8 +2108,7 @@ static int multiSelectValues(
   int nExpr = p->pEList->nExpr;
   int nRow = 1;
   int rc = 0;
-  assert( p->pNext==0 );
-  assert( p->selFlags & SF_AllValues );
+  assert( p->selFlags & SF_MultiValue );
   do{
     assert( p->selFlags & SF_Values );
     assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) );
@@ -2218,7 +2217,7 @@ static int multiSelect(
 
   /* Special handling for a compound-select that originates as a VALUES clause.
   */
-  if( p->selFlags & SF_AllValues ){
+  if( p->selFlags & SF_MultiValue ){
     rc = multiSelectValues(pParse, p, &dest);
     goto multi_select_end;
   }
@@ -4422,7 +4421,7 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
     sqlite3WalkSelect(&w, pSelect);
   }
   w.xSelectCallback = selectExpander;
-  if( (pSelect->selFlags & SF_AllValues)==0 ){
+  if( (pSelect->selFlags & SF_MultiValue)==0 ){
     w.xSelectCallback2 = selectPopWith;
   }
   sqlite3WalkSelect(&w, pSelect);
index ee243429191d037518e388a83245c4898cc664d3..b1a2db3a28428b8602744f5d3a6b1ea365681e61 100644 (file)
@@ -2385,7 +2385,7 @@ struct Select {
 #define SF_HasTypeInfo     0x0020  /* FROM subqueries have Table metadata */
 #define SF_Compound        0x0040  /* Part of a compound query */
 #define SF_Values          0x0080  /* Synthesized from VALUES clause */
-#define SF_AllValues       0x0100  /* All terms of compound are VALUES */
+#define SF_MultiValue      0x0100  /* Single VALUES term with multiple rows */
 #define SF_NestedFrom      0x0200  /* Part of a parenthesized FROM clause */
 #define SF_MaybeConvert    0x0400  /* Need convertCompoundSelectToSubquery() */
 #define SF_Recursive       0x0800  /* The recursive part of a recursive CTE */
index 2f3ddbe96a18ae0e2ac38d6b2e650eef214244da..ce09ba71d4d5d06e1f7aca0c93aefddee327ff97 100644 (file)
@@ -874,6 +874,14 @@ do_execsql_test select4-14.10 {
 do_execsql_test select4-14.11 {
   SELECT (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4)
 } {1}
-
+do_execsql_test select4-14.12 {
+  VALUES(1) UNION VALUES(2);
+} {1 2}
+do_execsql_test select4-14.13 {
+  VALUES(1),(2),(3) EXCEPT VALUES(2);
+} {1 3}
+do_execsql_test select4-14.14 {
+  VALUES(1),(2),(3) EXCEPT VALUES(1),(3);
+} {2}
 
 finish_test