Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | 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]. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | flattener-column-names |
Files: | files | file ages | folders |
SHA3-256: |
439cc5c52cbe6e67bbf0b6de0610f7d9 |
User & Date: | drh 2017-07-29 03:33:21.465 |
Context
2017-07-29
| ||
14:56 | Use the subquery column name, not the original SQL statement text, as the added AS clause in the query flattener. (Closed-Leaf check-in: 5df7f0e6a1 user: drh tags: flattener-column-names) | |
03:33 | 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]. (check-in: 439cc5c52c user: drh tags: flattener-column-names) | |
2017-07-28
| ||
22:22 | Update Tcl version used by the TclKit batch tool for MSVC. (check-in: bcec155e0d user: mistachkin tags: trunk) | |
Changes
Changes to src/select.c.
︙ | ︙ | |||
3765 3766 3767 3768 3769 3770 3771 | sqlite3IdListDelete(db, pSrc->a[i+iFrom].pUsing); assert( pSrc->a[i+iFrom].fg.isTabFunc==0 ); pSrc->a[i+iFrom] = pSubSrc->a[i]; iNewParent = pSubSrc->a[i].iCursor; memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i])); } pSrc->a[iFrom].fg.jointype = jointype; | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < < < < < < < < | 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 | sqlite3IdListDelete(db, pSrc->a[i+iFrom].pUsing); assert( pSrc->a[i+iFrom].fg.isTabFunc==0 ); pSrc->a[i+iFrom] = pSubSrc->a[i]; iNewParent = pSubSrc->a[i].iCursor; 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. ** ** Example: ** ** SELECT a+5, b*10 FROM (SELECT x*3 AS a, y+10 AS b FROM t1) WHERE a>b; ** \ \_____________ subquery __________/ / ** \_____________________ outer query ______________________________/ ** ** 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". */ if( pSub->pOrderBy ){ /* At this point, any non-zero iOrderByCol values indicate that the ** ORDER BY column expression is identical to the iOrderByCol'th ** expression returned by SELECT statement pSub. Since these values ** do not necessarily correspond to columns in SELECT statement pParent, ** zero them before transfering the ORDER BY clause. ** |
︙ | ︙ |