]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
In the query flattener, only add AS clauses to output columns of the outer
authordrh <drh@noemail.net>
Sat, 29 Jul 2017 03:33:21 +0000 (03:33 +0000)
committerdrh <drh@noemail.net>
Sat, 29 Jul 2017 03:33:21 +0000 (03:33 +0000)
query that are copied directly from the inner query.  Formerly, all columns
of the outer query received an AS clause if they did not have one already.
This is a proposed fix for ticket [de3403bf5ae5f72].

FossilOrigin-Name: 439cc5c52cbe6e67bbf0b6de0610f7d95ca9eb994f032547dc3535fd2c9dfc78

manifest
manifest.uuid
src/select.c

index 2a591e1217b20f2ffe3729fe073322ec40d8e073..79354a3de23a4f0479f669ee48e8d0c4327e5daf 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Update\sTcl\sversion\sused\sby\sthe\sTclKit\sbatch\stool\sfor\sMSVC.
-D 2017-07-28T22:22:15.250
+C In\sthe\squery\sflattener,\sonly\sadd\sAS\sclauses\sto\soutput\scolumns\sof\sthe\souter\nquery\sthat\sare\scopied\sdirectly\sfrom\sthe\sinner\squery.\s\sFormerly,\sall\scolumns\nof\sthe\souter\squery\sreceived\san\sAS\sclause\sif\sthey\sdid\snot\shave\sone\salready.\nThis\sis\sa\sproposed\sfix\sfor\sticket\s[de3403bf5ae5f72].
+D 2017-07-29T03:33:21.465
 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016
@@ -452,7 +452,7 @@ F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2
 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
 F src/resolve.c 4324a94573b1e29286f8121e4881db59eaedc014afeb274c8d3e07ed282e0e20
 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
-F src/select.c c6bf96a7f9d7d68f929de84738c599a30d0a725ab0b54420e70545743cd5ee7b
+F src/select.c 2da6bc6f1dc48ee6f1b7278fefec51185f583e260b326f191e331b0d7faa3272
 F src/shell.c bd6a37cbe8bf64ef6a6a74fdc50f067d3148149b4ce2b4d03154663e66ded55f
 F src/shell.c.in b5725acacba95ccefa57b6d068f710e29ba8239c3aa704628a1902a1f729c175
 F src/sqlite.h.in 0e2603c23f0747c5660669f946e231730af000c76d1653b153dcf2c26fce0a6b
@@ -1637,7 +1637,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 3286e1a07b0693049a07f0865bf93749c461ea8f6d1175ec2d1642886673d8ac
-R fa880debd22b5643c43c3f5ac12562f1
-U mistachkin
-Z 2ba3113508e5372bd91f947e270302b1
+P bcec155e0d6c6b17ae09d5a366c080723d01ff40dbc1a0ad0bb669a91db1b850
+R 45c8dd957f6aab7de79a5415e3464bd4
+T *branch * flattener-column-names
+T *sym-flattener-column-names *
+T -sym-trunk *
+U drh
+Z 62bad34cdd55bc284474093ae2886434
index cd8f4e864337fbc3bde52d6d849e8a66baa9d1cb..677dd10766fc1b95405bbc405a25da19ef5efa50 100644 (file)
@@ -1 +1 @@
-bcec155e0d6c6b17ae09d5a366c080723d01ff40dbc1a0ad0bb669a91db1b850
\ No newline at end of file
+439cc5c52cbe6e67bbf0b6de0610f7d95ca9eb994f032547dc3535fd2c9dfc78
\ No newline at end of file
index a3ada4ef799ec5884f06c0912bc26eb8d8cc9b10..79c23dfcc81e4b28d54e97d5761c58c76c0d4409 100644 (file)
@@ -3769,7 +3769,51 @@ static int flattenSubquery(
       memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
     }
     pSrc->a[iFrom].fg.jointype = jointype;
-  
+
+    /* For every result column in the outer query that does not have an AS
+    ** clause, if that column is a reference to an output column from the
+    ** inner query, then preserve the name of the column as it was written
+    ** in the original SQL text of the outer query by added an AS clause.
+    ** This prevents the outer query column from taking on a name derived
+    ** from inner query column name.
+    **
+    ** Example:
+    **     CREATE TABLE t1(a,b);
+    **     CREATE VIEW v1(x,y) AS SELECT a,b FROM t1;
+    **     SELECT x,y FROM v1;
+    **
+    ** The inner "v1" subquery will get flattened into the outer query.  After
+    ** flattening, the outer query becomes:  "SELECT a,b FROM t1".  But the
+    ** new query gives column names of "a" and "b", not the "x" and "y" that
+    ** the programmer expected.  This step adds AS clauses so that the
+    ** flattened query becomes:  "SELECT a AS x, b AS y FROM t1".
+    **
+    ** This is not a perfect solution.  The added AS clause is the same text as
+    ** the original input SQL.  So if the input SQL used goofy column names
+    ** like "SELECT v1.X,(y) FROM v1", then the added AS clauses will be those
+    ** same goofy colum names "v1.X" and "(y)", not just "x" and "y".  We could
+    ** improve that, but doing so might break lots of legacy code that depends
+    ** on the current behavior which dates back to around 2004.
+    **
+    ** Update on 2017-07-29:  The AS clause is only inserted into outer query
+    ** result columns that get substituted for inner query columns.  Formerly
+    ** an AS clause was added to *all* columns in the outer query that did not
+    ** already have one, even columns that had nothing to do with the inner
+    ** query.
+    */
+    pList = pParent->pEList;
+    for(i=0; i<pList->nExpr; i++){
+      Expr *p;
+      if( pList->a[i].zName==0
+       && (p = pList->a[i].pExpr)->op==TK_COLUMN
+       && p->iTable==iParent
+      ){
+        char *zName = sqlite3DbStrDup(db, pList->a[i].zSpan);
+        sqlite3Dequote(zName);
+        pList->a[i].zName = zName;
+      }
+    }
+
     /* Now begin substituting subquery result set expressions for 
     ** references to the iParent in the outer query.
     ** 
@@ -3782,14 +3826,6 @@ static int flattenSubquery(
     ** We look at every expression in the outer query and every place we see
     ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10".
     */
-    pList = pParent->pEList;
-    for(i=0; i<pList->nExpr; i++){
-      if( pList->a[i].zName==0 ){
-        char *zName = sqlite3DbStrDup(db, pList->a[i].zSpan);
-        sqlite3Dequote(zName);
-        pList->a[i].zName = zName;
-      }
-    }
     if( pSub->pOrderBy ){
       /* At this point, any non-zero iOrderByCol values indicate that the
       ** ORDER BY column expression is identical to the iOrderByCol'th