From: drh Date: Sat, 29 Jul 2017 03:33:21 +0000 (+0000) Subject: In the query flattener, only add AS clauses to output columns of the outer X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f76f7c2e2b2cdabc4938e53bc20a2bbc0db1e85e;p=thirdparty%2Fsqlite.git In the query flattener, only add AS clauses to output columns of the outer 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 --- diff --git a/manifest b/manifest index 2a591e1217..79354a3de2 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index cd8f4e8643..677dd10766 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bcec155e0d6c6b17ae09d5a366c080723d01ff40dbc1a0ad0bb669a91db1b850 \ No newline at end of file +439cc5c52cbe6e67bbf0b6de0610f7d95ca9eb994f032547dc3535fd2c9dfc78 \ No newline at end of file diff --git a/src/select.c b/src/select.c index a3ada4ef79..79c23dfcc8 100644 --- a/src/select.c +++ b/src/select.c @@ -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; inExpr; 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; inExpr; 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