From: drh Date: Sat, 10 Dec 2011 23:18:32 +0000 (+0000) Subject: Minor cleanups of the compound-subquery flattening logic. New test cases X-Git-Tag: mountain-lion~8^2~50 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4b3ac73c2ff20a5491b9e116502403b5657afeb1;p=thirdparty%2Fsqlite.git Minor cleanups of the compound-subquery flattening logic. New test cases added for joins the compound subquery. FossilOrigin-Name: 5061d85ff934db3c217c97acbbbed3286d9e02aa --- diff --git a/manifest b/manifest index def2ec37dc..1750fa12cb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sUNION\sALL\scompounds\sto\sbe\spromoted\sup\sto\sreplace\sa\ssimple\swrapper\nSELECT\seven\sif\sthe\scompounds\sare\sjoins. -D 2011-12-10T17:17:17.131 +C Minor\scleanups\sof\sthe\scompound-subquery\sflattening\slogic.\s\sNew\stest\scases\nadded\sfor\sjoins\sthe\scompound\ssubquery. +D 2011-12-10T23:18:32.554 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -134,7 +134,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c a9c26822515f81ec21588cbb482ca6724be02e33 F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/delete.c 51d32f0a9c880663e54ce309f52e40c325d5e112 -F src/expr.c a68c194c7709388302266e9a5bd9de2243486835 +F src/expr.c 537591e95eac74af783e4eb033954fb218cf398e F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5 F src/func.c 6261ce00aad9c63cd5b4219249b05683979060e9 @@ -178,13 +178,13 @@ F src/pragma.c dd66f21fafe7be40e1a48ad4195764cc191cf583 F src/prepare.c ec4989f7f480544bdc4192fe663470d2a2d7d61e F src/printf.c 7ffb4ebb8b341f67e049695ba031da717b3d2699 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 -F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809 +F src/resolve.c 3d3e80a98f203ac6b9329e9621e29eda85ddfd40 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 -F src/select.c 8c53ca04d6f6c06dd3bba5b53070572fd26ceaaa +F src/select.c f38d6bb54dbe42409b66b038be24765f68b5d44b F src/shell.c a1eadb2fdbfa45e54307263f0c8da8ee8cd61b8b F src/sqlite.h.in 1dc07194eb1a2c69c8ef75f88022b170be08024a F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h 7a64e24659e067f3882eeb75f31d59e7b3723b8b +F src/sqliteInt.h 165409fa8adc8701148830804febeded3f2e4448 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -666,7 +666,7 @@ F test/select7.test dad6f00f0d49728a879d6eb6451d4752db0b0abe F test/select8.test 391de11bdd52339c30580dabbbbe97e3e9a3c79d F test/select9.test 74c0fb2c6eecb0219cbed0cbe3df136f8fbf9343 F test/selectA.test 06d1032fa9009314c95394f2ca2e60d9f7ae8532 -F test/selectB.test 0d072c5846071b569766e6cd7f923f646a8b2bfa +F test/selectB.test 954e4e49cf1f896d61794e440669e03a27ceea25 F test/selectC.test f9bf1bc4581b5b8158caa6e4e4f682acb379fb25 F test/server1.test 46803bd3fe8b99b30dbc5ff38ffc756f5c13a118 F test/shared.test 34945a516532b11182c3eb26e31247eee3c9ae48 @@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P bcbc7152d49107afa926c8950360c61a6cf3d244 -R fdd2391ad6c97a200fa195ba2b7608fb +P 3d4b4f4fb7c1d9f1c742fef884383e9f50f8630e +R cd399db3e1d12898eb15c691830496b3 U drh -Z 0fd477d0479c6495f79c3db569ff13d1 +Z 6e0886d4861bd3870ceeed33fcdf7d2c diff --git a/manifest.uuid b/manifest.uuid index f5b1a92778..0e5bf24ff1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3d4b4f4fb7c1d9f1c742fef884383e9f50f8630e \ No newline at end of file +5061d85ff934db3c217c97acbbbed3286d9e02aa \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index ede9c9d39c..22643ff331 100644 --- a/src/expr.c +++ b/src/expr.c @@ -870,7 +870,7 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan); pItem->sortOrder = pOldItem->sortOrder; pItem->done = 0; - pItem->iCol = pOldItem->iCol; + pItem->iOrderByCol = pOldItem->iOrderByCol; pItem->iAlias = pOldItem->iAlias; } return pNew; diff --git a/src/resolve.c b/src/resolve.c index 6d857f0074..3da48136fd 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -799,7 +799,7 @@ static int resolveCompoundOrderBy( pE->pColl = pColl; pE->flags |= EP_IntValue | flags; pE->u.iValue = iCol; - pItem->iCol = (u16)iCol; + pItem->iOrderByCol = (u16)iCol; pItem->done = 1; }else{ moreToDo = 1; @@ -848,12 +848,12 @@ int sqlite3ResolveOrderGroupBy( pEList = pSelect->pEList; assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */ for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ - if( pItem->iCol ){ - if( pItem->iCol>pEList->nExpr ){ + if( pItem->iOrderByCol ){ + if( pItem->iOrderByCol>pEList->nExpr ){ resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr); return 1; } - resolveAlias(pParse, pEList, pItem->iCol-1, pItem->pExpr, zType); + resolveAlias(pParse, pEList, pItem->iOrderByCol-1, pItem->pExpr, zType); } } return 0; @@ -900,7 +900,7 @@ static int resolveOrderGroupBy( ** a copy of the iCol-th result-set column. The subsequent call to ** sqlite3ResolveOrderGroupBy() will convert the expression to a ** copy of the iCol-th result-set expression. */ - pItem->iCol = (u16)iCol; + pItem->iOrderByCol = (u16)iCol; continue; } if( sqlite3ExprIsInteger(pE, &iCol) ){ @@ -911,12 +911,12 @@ static int resolveOrderGroupBy( resolveOutOfRangeError(pParse, zType, i+1, nResult); return 1; } - pItem->iCol = (u16)iCol; + pItem->iOrderByCol = (u16)iCol; continue; } /* Otherwise, treat the ORDER BY term as an ordinary expression */ - pItem->iCol = 0; + pItem->iOrderByCol = 0; if( sqlite3ResolveExprNames(pNC, pE) ){ return 1; } diff --git a/src/select.c b/src/select.c index 02e71960f1..f0f4b6a5f2 100644 --- a/src/select.c +++ b/src/select.c @@ -2219,8 +2219,8 @@ static int multiSelectOrderBy( for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){ struct ExprList_item *pItem; for(j=0, pItem=pOrderBy->a; jiCol>0 ); - if( pItem->iCol==i ) break; + assert( pItem->iOrderByCol>0 ); + if( pItem->iOrderByCol==i ) break; } if( j==nOrderBy ){ Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0); @@ -2228,7 +2228,7 @@ static int multiSelectOrderBy( pNew->flags |= EP_IntValue; pNew->u.iValue = i; pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew); - pOrderBy->a[nOrderBy++].iCol = (u16)i; + pOrderBy->a[nOrderBy++].iOrderByCol = (u16)i; } } } @@ -2244,8 +2244,8 @@ static int multiSelectOrderBy( if( aPermute ){ struct ExprList_item *pItem; for(i=0, pItem=pOrderBy->a; iiCol>0 && pItem->iCol<=p->pEList->nExpr ); - aPermute[i] = pItem->iCol - 1; + assert( pItem->iOrderByCol>0 && pItem->iOrderByCol<=p->pEList->nExpr ); + aPermute[i] = pItem->iOrderByCol - 1; } pKeyMerge = sqlite3DbMallocRaw(db, sizeof(*pKeyMerge)+nOrderBy*(sizeof(CollSeq*)+1)); @@ -2810,19 +2810,21 @@ static int flattenSubquery( for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){ testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ); testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate ); + assert( pSub->pSrc!=0 ); if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0 || (pSub1->pPrior && pSub1->op!=TK_ALL) - || NEVER(pSub1->pSrc==0) || pSub1->pSrc->nSrc<1 + || pSub1->pSrc->nSrc<1 ){ return 0; } + testcase( pSub1->pSrc->nSrc>1 ); } /* Restriction 18. */ if( p->pOrderBy ){ int ii; for(ii=0; iipOrderBy->nExpr; ii++){ - if( p->pOrderBy->a[ii].iCol==0 ) return 0; + if( p->pOrderBy->a[ii].iOrderByCol==0 ) return 0; } } } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 6266a9cb72..8613d865aa 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1772,7 +1772,7 @@ struct ExprList { char *zSpan; /* Original text of the expression */ u8 sortOrder; /* 1 for DESC or 0 for ASC */ u8 done; /* A flag to indicate when processing is finished */ - u16 iCol; /* For ORDER BY, column number in result set */ + u16 iOrderByCol; /* For ORDER BY, column number in result set */ u16 iAlias; /* Index into Parse.aAlias[] for zName */ } *a; /* One entry for each expression */ }; diff --git a/test/selectB.test b/test/selectB.test index b9d979acb7..05ec9c6bdb 100644 --- a/test/selectB.test +++ b/test/selectB.test @@ -194,19 +194,28 @@ do_test selectB-3.0 { } } {} -for {set ii 3} {$ii <= 4} {incr ii} { +for {set ii 3} {$ii <= 6} {incr ii} { - if {$ii == 4} { - do_test selectB-4.0 { - execsql { - CREATE INDEX i1 ON t1(a); - CREATE INDEX i2 ON t1(b); - CREATE INDEX i3 ON t1(c); - CREATE INDEX i4 ON t2(d); - CREATE INDEX i5 ON t2(e); - CREATE INDEX i6 ON t2(f); - } - } {} + switch $ii { + 4 { + optimization_control db query-flattener off + } + 5 { + optimization_control db query-flattener on + do_test selectB-5.0 { + execsql { + CREATE INDEX i1 ON t1(a); + CREATE INDEX i2 ON t1(b); + CREATE INDEX i3 ON t1(c); + CREATE INDEX i4 ON t2(d); + CREATE INDEX i5 ON t2(e); + CREATE INDEX i6 ON t2(f); + } + } {} + } + 6 { + optimization_control db query-flattener off + } } do_test selectB-$ii.1 { @@ -371,11 +380,47 @@ for {set ii 3} {$ii <= 4} {incr ii} { } } {2 4 6 3 6 9 8 10 12 12 15 18 14 16 18 21 24 27} - do_test selectB-$ii.21 { + do_test selectB-$ii.22 { execsql { SELECT * FROM (SELECT 345 UNION ALL SELECT d FROM t2) ORDER BY 1; } } {3 12 21 345} + + do_test selectB-$ii.23 { + execsql { + SELECT x, y FROM ( + SELECT a AS x, b AS y FROM t1 + UNION ALL + SELECT a*10 + 0.1, f*10 + 0.1 FROM t1 JOIN t2 ON (c=d) + UNION ALL + SELECT a*100, b*100 FROM t1 + ) ORDER BY 1; + } + } {2 4 8 10 14 16 80.1 180.1 200 400 800 1000 1400 1600} + + do_test selectB-$ii.24 { + execsql { + SELECT x, y FROM ( + SELECT a AS x, b AS y FROM t1 + UNION ALL + SELECT a*10 + 0.1, f*10 + 0.1 FROM t1 LEFT JOIN t2 ON (c=d) + UNION ALL + SELECT a*100, b*100 FROM t1 + ) ORDER BY 1; + } + } {2 4 8 10 14 16 20.1 {} 80.1 180.1 140.1 {} 200 400 800 1000 1400 1600} + + do_test selectB-$ii.25 { + execsql { + SELECT x+y FROM ( + SELECT a AS x, b AS y FROM t1 + UNION ALL + SELECT a*10 + 0.1, f*10 + 0.1 FROM t1 LEFT JOIN t2 ON (c=d) + UNION ALL + SELECT a*100, b*100 FROM t1 + ) WHERE y+x NOT NULL ORDER BY 1; + } + } {6 18 30 260.2 600 1800 3000} } finish_test