From: drh Date: Tue, 3 Dec 2002 02:22:52 +0000 (+0000) Subject: Honor ORDER BY clauses in VIEWs. Ticket #193. (CVS 792) X-Git-Tag: version-3.6.10~5281 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=174b619591e546f206c9c0c631622c990f89d1d1;p=thirdparty%2Fsqlite.git Honor ORDER BY clauses in VIEWs. Ticket #193. (CVS 792) FossilOrigin-Name: dbf7893234a6c5d6bb2d931e52080bb05784c0c9 --- diff --git a/manifest b/manifest index 8852a9be79..1b2b630d92 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sto\sthe\spager\sto\savoid\sopening\sjournal\sfiles\sunnecessarily.\s\sThis\scan\nsometimes\sresults\sin\sa\ssignificant\sspeed\simprovement.\s(CVS\s791) -D 2002-12-02T04:25:20 +C Honor\sORDER\sBY\sclauses\sin\sVIEWs.\s\sTicket\s#193.\s(CVS\s792) +D 2002-12-03T02:22:52 F Makefile.in 868c17a1ae1c07603d491274cc8f86c04acf2a1e F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -20,7 +20,7 @@ F spec.template 238f7db425a78dc1bb7682e56e3834c7270a3f5e F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea F src/btree.c cd46130a7f68e3880a59aa5502b64be37bf31e91 F src/btree.h 0ca6c2631338df62e4f7894252d9347ae234eda9 -F src/build.c ede692549ce5c43a80e2a9954421ccaee116b2df +F src/build.c 415dce8886aabb6d45851caed7014707056d668b F src/delete.c aad9d4051ab46e6f6391ea5f7b8994a7c05bdd15 F src/encode.c 6c9c87d5b7b2c0101d011ebc283a80abf672a4d1 F src/expr.c 9427b4d1d04ede1095994b8e042abe2e6fea7443 @@ -37,7 +37,7 @@ F src/pager.h 540833e8cb826b80ce2e39aa917deee5e12db626 F src/parse.y 469c9636ff713e63c00234662209f11668671ae9 F src/printf.c 5c50fc1da75c8f5bf432b1ad17d91d6653acd167 F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe -F src/select.c ce82596a2eaaf418edba45b2426f41065e49578b +F src/select.c a03c317ff8400752da3b4997e4329949a6f4626c F src/shell.c 53185af128613a2bac79d50128f4c17794f0f992 F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e F src/sqlite.h.in 98b1574b2362abe02c4a4c73b9dbf99bcd713ab3 @@ -54,7 +54,7 @@ F src/update.c 881e4c8e7c786545da4fd2d95da19252b2e31137 F src/util.c ca7650ef2cc2d50241e48029fca109a3016144ee F src/vdbe.c 2c2472a93d0708920384c05d6099b637ab2229ce F src/vdbe.h b7584044223104ba7896a7f87b66daebdd6022ba -F src/where.c 615a0f0bed305bcb27073c69347ea75018e8b58d +F src/where.c 1de1a326235bb7f9ef7d3d58c08c0ac73dcd3acf F test/all.test efd958d048c70a3247997c482f0b33561f7759f0 F test/bigfile.test 38d1071817caceb636c613e3546082b90e749a49 F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578 @@ -113,7 +113,7 @@ F test/unique.test 572aa791327c1e8d797932263e9d67f176cfdb44 F test/update.test 7ffb062d580a972e7870d0f51d5af3ab9bfeae08 F test/vacuum.test 059871b312eb910bbe49dafde1d01490cc2c6bbe F test/version.test 605fd0d7e7d571370c32b12dbf395b58953de246 -F test/view.test 76d3fe155f1215f9dde1ccad1d1bce5c803132d0 +F test/view.test c64fa39ea57f3c2066c854290f032ad13b23b83d F test/where.test 9c1c2c13cfff419ea38451e78cf3d0d238fabc27 F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b F tool/lemon.c 022adc2830c2705828f744d2c59798bd462eb465 @@ -151,7 +151,7 @@ F www/speed.tcl a20a792738475b68756ea7a19321600f23d1d803 F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218 -P 9864a1265b5a37c12b0dd8446d81b84c5a3acc43 -R 18e5cbae11f3fb92134940cf13959666 +P fa5c042585c601449ede7319d0c5993cd8ba75a4 +R 3fe16b5077b1d335cf384ebc20ff49d3 U drh -Z 0253bbaf25ee8c0f348685f72f181f39 +Z b7816d8e84826cea34ed2b8aced87dca diff --git a/manifest.uuid b/manifest.uuid index e0cdf9927b..cd82938521 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fa5c042585c601449ede7319d0c5993cd8ba75a4 \ No newline at end of file +dbf7893234a6c5d6bb2d931e52080bb05784c0c9 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 522f88c7b1..9ef20d86dd 100644 --- a/src/build.c +++ b/src/build.c @@ -25,7 +25,7 @@ ** ROLLBACK ** PRAGMA ** -** $Id: build.c,v 1.116 2002/12/02 04:25:21 drh Exp $ +** $Id: build.c,v 1.117 2002/12/03 02:22:52 drh Exp $ */ #include "sqliteInt.h" #include @@ -898,11 +898,7 @@ void sqliteCreateView( sqliteSelectDelete(pSelect); return; } - /* Ignore ORDER BY clauses on a SELECT */ - if( pSelect->pOrderBy ){ - sqliteExprListDelete(pSelect->pOrderBy); - pSelect->pOrderBy = 0; - } + /* Make a copy of the entire SELECT statement that defines the view. ** This will force all the Expr.token.z values to be dynamically ** allocated rather than point to the input string - which means that diff --git a/src/select.c b/src/select.c index caf0adcd37..cd5e29baf3 100644 --- a/src/select.c +++ b/src/select.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** -** $Id: select.c,v 1.115 2002/10/27 19:35:35 drh Exp $ +** $Id: select.c,v 1.116 2002/12/03 02:22:52 drh Exp $ */ #include "sqliteInt.h" @@ -1470,6 +1470,8 @@ substExprList(ExprList *pList, int iTable, ExprList *pEList, int iSub){ ** (10) The subquery does not use aggregates or the outer query does not ** use LIMIT. ** +** (11) The subquery and the outer query do not both have ORDER BY clauses. +** ** In this routine, the "p" parameter is a pointer to the outer query. ** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query ** uses aggregates and subqueryIsAgg is true if the subquery uses aggregates. @@ -1511,6 +1513,7 @@ static int flattenSubquery( return 0; } if( (p->isDistinct || p->nLimit>=0) && subqueryIsAgg ) return 0; + if( p->pOrderBy && pSub->pOrderBy ) return 0; /* If we reach this point, it means flattening is permitted for the ** i-th entry of the FROM clause in the outer query. @@ -1529,7 +1532,14 @@ static int flattenSubquery( substExprList(p->pGroupBy, iParent, pSub->pEList, iSub); substExpr(p->pHaving, iParent, pSub->pEList, iSub); } - substExprList(p->pOrderBy, iParent, pSub->pEList, iSub); + if( pSub->pOrderBy ){ + assert( p->pOrderBy==0 ); + p->pOrderBy = pSub->pOrderBy; + pSub->pOrderBy = 0; + changeTablesInList(p->pOrderBy, iSub, iParent); + }else if( p->pOrderBy ){ + substExprList(p->pOrderBy, iParent, pSub->pEList, iSub); + } if( pSub->pWhere ){ pWhere = sqliteExprDup(pSub->pWhere); if( iParent!=iSub ){ diff --git a/src/where.c b/src/where.c index 7470a669ce..1c37040de7 100644 --- a/src/where.c +++ b/src/where.c @@ -13,7 +13,7 @@ ** the WHERE clause of SQL statements. Also found here are subroutines ** to generate VDBE code to evaluate expressions. ** -** $Id: where.c,v 1.66 2002/10/27 19:35:35 drh Exp $ +** $Id: where.c,v 1.67 2002/12/03 02:22:52 drh Exp $ */ #include "sqliteInt.h" @@ -426,6 +426,8 @@ WhereInfo *sqliteWhereBegin( ** set iDirectEq[i] to the index of the term. For terms of the ** form ROWIDexpr or ROWID>=expr set iDirectGt[i]. + ** + ** (Added:) Treat ROWID IN expr like ROWID=expr. */ pWInfo->a[i].iCur = -1; iDirectEq[i] = -1; @@ -651,7 +653,7 @@ WhereInfo *sqliteWhereBegin( WhereLevel *pLevel = &pWInfo->a[i]; /* If this is the right table of a LEFT OUTER JOIN, allocate and - ** initialize a memory cell that record if this table matches any + ** initialize a memory cell that records if this table matches any ** row of the left table of the join. */ if( i>0 && (pTabList->a[i-1].jointype & JT_LEFT)!=0 ){ diff --git a/test/view.test b/test/view.test index cc03bf886e..2d6952d2ea 100644 --- a/test/view.test +++ b/test/view.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing VIEW statements. # -# $Id: view.test,v 1.11 2002/08/25 19:20:43 drh Exp $ +# $Id: view.test,v 1.12 2002/12/03 02:22:53 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -297,4 +297,45 @@ do_test view-8.5 { } } {13 6} +# Tests for a bug found by Michiel de Wit involving ORDER BY in a VIEW. +# +do_test view-9.1 { + execsql { + INSERT INTO t2 SELECT * FROM t2 WHERE a<5; + INSERT INTO t2 SELECT * FROM t2 WHERE a<4; + INSERT INTO t2 SELECT * FROM t2 WHERE a<3; + SELECT DISTINCT count(*) FROM t2 GROUP BY a ORDER BY 1; + } +} {1 2 4 8} +do_test view-9.2 { + execsql { + SELECT DISTINCT count(*) FROM t2 GROUP BY a ORDER BY 1 LIMIT 3; + } +} {1 2 4} +do_test view-9.3 { + execsql { + CREATE VIEW v9 AS + SELECT DISTINCT count(*) FROM t2 GROUP BY a ORDER BY 1 LIMIT 3; + SELECT * FROM v9; + } +} {1 2 4} +do_test view-9.4 { + execsql { + SELECT * FROM v9 ORDER BY 1 DESC; + } +} {4 2 1} +do_test view-9.5 { + execsql { + CREATE VIEW v10 AS + SELECT DISTINCT a, count(*) FROM t2 GROUP BY a ORDER BY 2 LIMIT 3; + SELECT * FROM v10; + } +} {5 1 4 2 3 4} +do_test view-9.6 { + execsql { + SELECT * FROM v10 ORDER BY 1; + } +} {3 4 4 2 5 1} + + finish_test