From: drh Date: Sat, 5 Sep 2015 22:36:07 +0000 (+0000) Subject: Omit all use of Expr nodes for TK_AS, as those nodes no longer served a useful X-Git-Tag: version-3.9.0~146 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0b8d255c37ea9830cecabb57f1c2ba6305eacc44;p=thirdparty%2Fsqlite.git Omit all use of Expr nodes for TK_AS, as those nodes no longer served a useful purpose and in fact interferred with the query planner. FossilOrigin-Name: 7ab0b258eabfcfb7f1b0bd1b12e166d2f267823d --- diff --git a/manifest b/manifest index f9b770eebc..bcf650cd13 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sunreachable\sconditional\sin\sthe\sWHERE\sclause\sanalysis\slogic. -D 2015-09-05T19:21:00.671 +C Omit\sall\suse\sof\sExpr\snodes\sfor\sTK_AS,\sas\sthose\snodes\sno\slonger\sserved\sa\suseful\npurpose\sand\sin\sfact\sinterferred\swith\sthe\squery\splanner. +D 2015-09-05T22:36:07.095 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in f85066ce844a28b671aaeeff320921cd0ce36239 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -291,7 +291,7 @@ F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b F src/date.c fb1c99172017dcc8e237339132c91a21a0788584 F src/dbstat.c f402e77e25089c6003d0c60b3233b9b3947d599a F src/delete.c 6792c80d7fb54c4df9f7680413952600e7439492 -F src/expr.c f3c4d165dea72b268a7b922d00035af1d510dd78 +F src/expr.c 3a76afcdac925294c39903b7002ddb9e5fd29863 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 83e1baba999bed3144ea5a2143fc922edf51135f F src/func.c ecdd69ec6a1e406f04cc73324be2ebbf6354197f @@ -337,14 +337,14 @@ F src/pragma.h 631a91c8b0e6ca8f051a1d8a4a0da4150e04620a F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1 F src/printf.c 0c4bcdd1c2e2521024f0a69cb5eb334f86b3652a F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 -F src/resolve.c 47c00ca0ab24d4b8113c6c05aa07bc6cf6eac9af +F src/resolve.c 3126f7694b8ce0f97282d7dd3a5198b8fa18dce9 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c c17613385bc6b095c421b1f30548814f5fd8a9b2 F src/shell.c 6332ef06db1390ef812cfdff1fc97b4fd76cdd42 F src/sqlite.h.in 378bebc8fe6a88bade25e5f23b7e6123fdc64b00 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h f700e6a9dd1fdcccc9951ab022b366fb66b9e413 -F src/sqliteInt.h e7e92112a71aeb214c66ebdea1366560535614d1 +F src/sqliteInt.h ad5504745ef37aca44365a2b91173bc399d71e7e F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179 F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -396,7 +396,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 46036cbbceada0836833531b2d963edbca3d9cfa +F src/treeview.c 154f0acc622fa3514de8777dcedf4c8a8802b4ce F src/trigger.c 322f23aad694e8f31d384dcfa386d52a48d3c52f F src/update.c 3c5bc9570df3bfafa0db36828406a8a14e4c426e F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c @@ -782,7 +782,7 @@ F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7 F test/index6.test 7102ec371414c42dfb1d5ca37eb4519aa9edc23a F test/index7.test 9c6765a74fc3fcde7aebc5b3bd40d98df14a527c F test/indexedby.test 5f527a78bae74c61b8046ae3037f9dfb0bf0c353 -F test/indexexpr1.test 3c5033412f851f225e3a37d6795709df71bea638 +F test/indexexpr1.test 4feec154aadacb033b41acc1760a18edc4c60470 F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 F test/insert.test 38742b5e9601c8f8d76e9b7555f7270288c2d371 @@ -1383,7 +1383,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 d2761357a0496ec1e590c7c9e397c5b5c904f91a -R 9921ff0c69ded6987711a9a840df906d +P 24924a58197e558a9e8800cc5c91dc8fb32f3557 +R 7e67010ff7c10ab44fd6cfd6cc975796 U drh -Z 612add4179403f74341dc4eb50c9c3d3 +Z 8a5f85b9c3f71859f18b9284198b5fad diff --git a/manifest.uuid b/manifest.uuid index 4767aec925..86f4bfaeac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -24924a58197e558a9e8800cc5c91dc8fb32f3557 \ No newline at end of file +7ab0b258eabfcfb7f1b0bd1b12e166d2f267823d \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 00228d9a3f..3141cd9dbd 100644 --- a/src/expr.c +++ b/src/expr.c @@ -91,7 +91,7 @@ Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){ } /* -** Skip over any TK_COLLATE or TK_AS operators and any unlikely() +** Skip over any TK_COLLATE operators and any unlikely() ** or likelihood() function at the root of an expression. */ Expr *sqlite3ExprSkipCollate(Expr *pExpr){ @@ -102,7 +102,7 @@ Expr *sqlite3ExprSkipCollate(Expr *pExpr){ assert( pExpr->op==TK_FUNCTION ); pExpr = pExpr->x.pList->a[0].pExpr; }else{ - assert( pExpr->op==TK_COLLATE || pExpr->op==TK_AS ); + assert( pExpr->op==TK_COLLATE ); pExpr = pExpr->pLeft; } } @@ -2701,10 +2701,6 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ inReg = pExpr->iTable; break; } - case TK_AS: { - inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); - break; - } #ifndef SQLITE_OMIT_CAST case TK_CAST: { /* Expressions of the form: CAST(pLeft AS token) */ diff --git a/src/resolve.c b/src/resolve.c index 22df223948..2c4212ba7d 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -45,30 +45,6 @@ static void incrAggFunctionDepth(Expr *pExpr, int N){ ** Turn the pExpr expression into an alias for the iCol-th column of the ** result set in pEList. ** -** If the result set column is a simple column reference, then this routine -** makes an exact copy. But for any other kind of expression, this -** routine make a copy of the result set column as the argument to the -** TK_AS operator. The TK_AS operator causes the expression to be -** evaluated just once and then reused for each alias. -** -** The reason for suppressing the TK_AS term when the expression is a simple -** column reference is so that the column reference will be recognized as -** usable by indices within the WHERE clause processing logic. -** -** The TK_AS operator is inhibited if zType[0]=='G'. This means -** that in a GROUP BY clause, the expression is evaluated twice. Hence: -** -** SELECT random()%5 AS x, count(*) FROM tab GROUP BY x -** -** Is equivalent to: -** -** SELECT random()%5 AS x, count(*) FROM tab GROUP BY random()%5 -** -** The result of random()%5 in the GROUP BY clause is probably different -** from the result in the result-set. On the other hand Standard SQL does -** not allow the GROUP BY clause to contain references to result-set columns. -** So this should never come up in well-formed queries. -** ** If the reference is followed by a COLLATE operator, then make sure ** the COLLATE operator is preserved. For example: ** @@ -102,19 +78,11 @@ static void resolveAlias( db = pParse->db; pDup = sqlite3ExprDup(db, pOrig, 0); if( pDup==0 ) return; - if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){ - incrAggFunctionDepth(pDup, nSubquery); - pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0); - if( pDup==0 ) return; - ExprSetProperty(pDup, EP_Skip); - if( pEList->a[iCol].u.x.iAlias==0 ){ - pEList->a[iCol].u.x.iAlias = (u16)(++pParse->nAlias); - } - pDup->iTable = pEList->a[iCol].u.x.iAlias; - } + if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery); if( pExpr->op==TK_COLLATE ){ pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); } + ExprSetProperty(pDup, EP_Alias); /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This ** prevents ExprDelete() from deleting the Expr structure itself, @@ -506,7 +474,7 @@ static int lookupName( lookupname_end: if( cnt==1 ){ assert( pNC!=0 ); - if( pExpr->op!=TK_AS ){ + if( !ExprHasProperty(pExpr, EP_Alias) ){ sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList); } /* Increment the nRef value on all name contexts from TopNC up to diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 69315ed466..89b3d798f1 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2135,6 +2135,7 @@ struct Expr { #define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */ #define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */ #define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */ +#define EP_Alias 0x400000 /* Is an alias for a result set column */ /* ** Combinations of two or more EP_* flags diff --git a/src/treeview.c b/src/treeview.c index 59c07e4742..971de4e8bc 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -253,11 +253,6 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ sqlite3TreeViewLine(pView,"REGISTER(%d)", pExpr->iTable); break; } - case TK_AS: { - sqlite3TreeViewLine(pView,"AS %Q", pExpr->u.zToken); - sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); - break; - } case TK_ID: { sqlite3TreeViewLine(pView,"ID \"%w\"", pExpr->u.zToken); break; diff --git a/test/indexexpr1.test b/test/indexexpr1.test index faaf292de5..0c925c9f92 100644 --- a/test/indexexpr1.test +++ b/test/indexexpr1.test @@ -198,4 +198,25 @@ do_catchsql_test indexexpr1-410 { INSERT INTO t3 SELECT * FROM t3 WHERE rowid=10; } {1 {UNIQUE constraint failed: index 't3abc'}} +do_execsql_test indexexpr1-500 { + CREATE TABLE t5(a); + CREATE TABLE cnt(x); + WITH RECURSIVE + c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5) + INSERT INTO cnt(x) SELECT x FROM c; + INSERT INTO t5(a) SELECT printf('abc%03dxyz',x) FROM cnt; + CREATE INDEX t5ax ON t5( substr(a,4,3) ); +} {} +do_execsql_test indexexpr1-510 { + -- The use of the "k" alias in the WHERE clause is technically + -- illegal, but SQLite allows it for historical reasons. In this + -- test and the next, verify that "k" can be used by the t5ax index + SELECT substr(a,4,3) AS k FROM cnt, t5 WHERE k=printf('%03d',x); +} {001 002 003 004 005} +do_execsql_test indexexpr1-510eqp { + EXPLAIN QUERY PLAN + SELECT substr(a,4,3) AS k FROM cnt, t5 WHERE k=printf('%03d',x); +} {/USING INDEX t5ax/} + + finish_test