]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
More test cases an bug fixes for the ORDER BY optimization of joins. All
authordrh <drh@noemail.net>
Thu, 27 Sep 2012 19:53:38 +0000 (19:53 +0000)
committerdrh <drh@noemail.net>
Thu, 27 Sep 2012 19:53:38 +0000 (19:53 +0000)
veryquick tests now pass.

FossilOrigin-Name: 0d573320057b0903a5589cabfb1b1ece1c57958e

manifest
manifest.uuid
src/where.c
test/e_select.test
test/orderby1.test
test/tester.tcl
test/tkt-cbd054fa6b.test
test/where.test

index e8dbbe14e01e8609c003a38450e4070932150af9..1b05b5bd9b55c2f7e8741accb4e4a40eef9af1b4 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Test\scases\sand\sbug\sfixes\sapplied\sto\sthe\sORDER\sBY\soptimization\sfor\sjoins.\nSome\stest\scases\sfail,\sbut\sexcept\sfor\sthe\snew\sorderby1.test\sfailures,\sall\nfailures\sappear\sto\sbe\sissues\swith\sthe\stests,\snot\swith\sthe\score\scode.
-D 2012-09-27T17:31:32.268
+C More\stest\scases\san\sbug\sfixes\sfor\sthe\sORDER\sBY\soptimization\sof\sjoins.\s\sAll\nveryquick\stests\snow\spass.
+D 2012-09-27T19:53:38.142
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -249,7 +249,7 @@ F src/vtab.c d8020c0a0e8ccc490ca449d7e665311b6e9f3ba9
 F src/wal.c 5acb3e7bbd31f10ba39acad9ce6b399055337a9d
 F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6
 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b
-F src/where.c a537824b2eec986c203a6a370090520b955f258b
+F src/where.c cd047c1223f6364f869d44b7d3941a687de7fcb6
 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 F test/aggnested.test 0be144b453e0622a085fae8665c32f5676708e00
@@ -386,7 +386,7 @@ F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459
 F test/e_insert.test c6ac239a97cb16dfbd0c16496f8cd871b4068c0c
 F test/e_reindex.test dfedfc32c5a282b0596c6537cbcd4217fbb1a216
 F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6
-F test/e_select.test 69013a64b469458820abb7f3281a7eaa6c1fda76
+F test/e_select.test 07e8d81268ba1ffcaf1dc4bec48956af150c42f9
 F test/e_select2.test 5c3d3da19c7b3e90ae444579db2b70098599ab92
 F test/e_update.test 161d5dc6a3ed9dd08f5264d13e20735d7a89f00c
 F test/e_uri.test 9e190ca799d9190eec6e43f2aadf1d10c06a57a3
@@ -634,7 +634,7 @@ F test/notify3.test a86259abbfb923aa27d30f0fc038c88e5251488a
 F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347
 F test/null.test a8b09b8ed87852742343b33441a9240022108993
 F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394
-F test/orderby1.test 868a4f88c4f4565684bcc18e8ed61a990ece431b
+F test/orderby1.test 31c9865626046666e81cd22ecf8e1c24a4ea41b6
 F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3
 F test/pager1.test 2163c6ef119f497a71a84137c957c63763e640ab
 F test/pager2.test 745b911dde3d1f24ae0870bd433dfa83d7c658c1
@@ -740,7 +740,7 @@ F test/tclsqlite.test a3d2df21ee98957f5de4f9dc1db0eab68047ab5d
 F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
 F test/temptable.test 51edd31c65ed1560dd600b1796e8325df96318e2
 F test/temptrigger.test 26670ed7a39cf2296a7f0a9e0a1d7bdb7abe936d
-F test/tester.tcl ed47103d30a1a4b3c1d8de207606a407e55cc5c2
+F test/tester.tcl 2f383e811010b05a83c0f00fc168cae1dd63a6d9
 F test/thread001.test 7cc2ce08f9cde95964736d11e91f9ab610f82f91
 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
@@ -784,7 +784,7 @@ F test/tkt-b72787b1.test a95e8cdad0b98af1853ac7f0afd4ab27b77bf5f3
 F test/tkt-bd484a090c.test 60460bf946f79a79712b71f202eda501ca99b898
 F test/tkt-bdc6bbbb38.test fc38bb09bdd440e3513a1f5f98fc60a075182d7d
 F test/tkt-c48d99d690.test bed446e3513ae10eec1b86fdd186ef750226c408
-F test/tkt-cbd054fa6b.test bd9fb546f63bc0c79d1776978d059fa51c5b1c63
+F test/tkt-cbd054fa6b.test 9c27ed07b333eed458e5d4543f91ecdcf05aeb19
 F test/tkt-d11f09d36e.test fb44f7961aa6d4b632fb7b9768239832210b5fc7
 F test/tkt-d635236375.test 9d37e988b47d87505bc9445be0ca447002df5d09
 F test/tkt-d82e3f3721.test bcc0dfba658d15bab30fd4a9320c9e35d214ce30
@@ -955,7 +955,7 @@ F test/walro.test a31deb621033442a76c3a61e44929250d06f81b1
 F test/walshared.test 6dda2293880c300baf5d791c307f653094585761
 F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a
 F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e
-F test/where.test 59cf231e6edaf0f20b106a26d4294847e7c6eb25
+F test/where.test ea9659ff6e31681d0cdaf964747139cb10808200
 F test/where2.test 43d4becaf5a5df854e6c21d624a1cb84c6904554
 F test/where3.test 667e75642102c97a00bf9b23d3cb267db321d006
 F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2
@@ -1017,7 +1017,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9
-P d2fcba1e143beca8c45724d2108870657c269e17
-R 388197fbdd69fccc34c9d73c7bc9f9e7
+P 75cda864ededb6dc0f84bd52ed3311753a58e351
+R 2ac4d1c44b199e10f1d07ecdc3868045
 U drh
-Z f07796285dcd213d3100411a37b9d38f
+Z 9df007fa9fa34b8089a8009c6ca9320b
index 38f15f501f3b3335c88e4a6eeb9374cde82c03f6..f52b6aaffd3a95252fe25b5a311fd1dcd3c15e99 100644 (file)
@@ -1 +1 @@
-75cda864ededb6dc0f84bd52ed3311753a58e351
\ No newline at end of file
+0d573320057b0903a5589cabfb1b1ece1c57958e
\ No newline at end of file
index 01155c14d3f4ae1da34993a1d90c0b09e5d88a13..9bdcd536c44d0e040576518e494a8287080263cb 100644 (file)
@@ -1645,13 +1645,17 @@ static int isSortingIndex(
   sqlite3 *db = pParse->db;     /* Database connection */
   int nPriorSat;                /* ORDER BY terms satisfied by outer loops */
   int seenRowid = 0;            /* True if an ORDER BY rowid term is seen */
+  int nEqOneRow;                /* Idx columns that ref unique values */
 
   if( OptimizationDisabled(db, SQLITE_OrderByIdx) ) return 0;
   if( p->i==0 ){
     nPriorSat = 0;
+    nEqOneRow = nEqCol;
   }else{
     if( OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ) return 0;
     nPriorSat = p->aLevel[p->i-1].plan.nOBSat;
+    sortOrder = bOuterRev;
+    nEqOneRow = 0;
   }
   if( p->i>0 && nEqCol==0 /*&& !allOuterLoopsUnique(p)*/ ) return nPriorSat;
   pOrderBy = p->pOrderBy;
@@ -1725,7 +1729,7 @@ static int isSortingIndex(
     assert( pTerm->sortOrder==0 || pTerm->sortOrder==1 );
     assert( iSortOrder==0 || iSortOrder==1 );
     termSortOrder = iSortOrder ^ pTerm->sortOrder;
-    if( i>nEqCol ){
+    if( i>nEqOneRow ){
       if( termSortOrder!=sortOrder ){
         /* Indices can only be used if all ORDER BY terms past the
         ** equality constraints are all either DESC or ASC. */
@@ -1741,7 +1745,7 @@ static int isSortingIndex(
       break;
     }
   }
-  *pbRev = bOuterRev ^ sortOrder;
+  *pbRev = sortOrder;
 
   /* If there was an "ORDER BY rowid" term that matched, or it is only
   ** possible for a single row from this table to match, then skip over
@@ -3296,7 +3300,7 @@ static void bestBtreeIndex(WhereBestIdx *p){
     ** So this computation assumes table records are about twice as big
     ** as index records
     */
-    if( wsFlags==WHERE_IDX_ONLY
+    if( (wsFlags&~WHERE_REVERSE)==WHERE_IDX_ONLY
      && (pWC->wctrlFlags & WHERE_ONEPASS_DESIRED)==0
      && sqlite3GlobalConfig.bUseCis
      && OptimizationEnabled(pParse->db, SQLITE_CoverIdxScan)
@@ -3421,9 +3425,10 @@ static void bestBtreeIndex(WhereBestIdx *p){
 
 
     WHERETRACE((
-      "%s(%s): nEq=%d nInMul=%d rangeDiv=%d bSort=%d bLookup=%d wsFlags=0x%x\n"
-      "         notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f\n"
-      "         used=0x%llx nOrdered=%d nOBSat=%d\n",
+      "%s(%s):\n"
+      "    nEq=%d nInMul=%d rangeDiv=%d bSort=%d bLookup=%d wsFlags=0x%08x\n"
+      "    notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f\n"
+      "    used=0x%llx nOrdered=%d nOBSat=%d\n",
       pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk"), 
       nEq, nInMul, (int)rangeDiv, bSort, bLookup, wsFlags,
       p->notReady, log10N, nRow, cost, used, nOrdered, nOBSat
@@ -5088,10 +5093,10 @@ WhereInfo *sqlite3WhereBegin(
     }
     assert( bestJ>=0 );
     assert( sWBI.notValid & getMask(pMaskSet, pTabList->a[bestJ].iCursor) );
-    WHERETRACE(("*** Optimizer selects table %d for loop %d"
-                " with cost=%.1f, nRow=%.1f, nOBSat=%d\n",
+    WHERETRACE(("*** Optimizer selects table %d for loop %d with:\n"
+                "    cost=%.1f, nRow=%.1f, nOBSat=%d wsFlags=0x%08x\n",
                 bestJ, pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow,
-                bestPlan.plan.nOBSat));
+                bestPlan.plan.nOBSat, bestPlan.plan.wsFlags));
     if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 ){
       pWInfo->nOBSat = pOrderBy->nExpr;
     }
index 9f26f6fcd3499ef3ebc5aa93bd8b1da3ba84d6d3..fb63d051de3b278a8f5ea1ee79f8ad7d983fb9ee 100644 (file)
@@ -1023,7 +1023,7 @@ do_execsql_test e_select-4.9.0 {
 #
 do_select_tests e_select-4.9 {
   1  "SELECT group_concat(one), two FROM b1 GROUP BY two" {
-    4,5 f   1 o   7,6   s 3,2 t
+    /#,# f   1 o   #,#   s #,# t/
   }
   2  "SELECT group_concat(one), sum(one) FROM b1 GROUP BY (one>4)" {
     1,2,3,4 10    5,6,7 18
@@ -1040,7 +1040,7 @@ do_select_tests e_select-4.9 {
 # values are considered equal.
 #
 do_select_tests e_select-4.10 {
-  1  "SELECT group_concat(y) FROM b2 GROUP BY x" {0,1   3   2,4}
+  1  "SELECT group_concat(y) FROM b2 GROUP BY x" {/#,#   3   #,#/}
   2  "SELECT count(*) FROM b2 GROUP BY CASE WHEN y<4 THEN NULL ELSE 0 END" {4 1}
 } 
 
@@ -1745,12 +1745,12 @@ do_select_tests e_select-8.4 {
      1 2 7    1 2 8      1 4  93    1 5 -1   
   }
   8  "SELECT z, x FROM d1 ORDER BY 2" {
-     3 1     8 1    7 1   -20 1 
-     93 1   -1 1   -1 2   93 2
+     /# 1    # 1    # 1   # 1 
+      # 1    # 1    # 2   # 2/
   }
   9  "SELECT z, x FROM d1 ORDER BY 1" {
-     -20 1  -1 2   -1 1   3 1     
-     7 1     8 1   93 2   93 1   
+     /-20 1  -1 #   -1 #   3 1
+     7 1     8 1   93 #   93 #/   
   }
 }
 
@@ -1766,10 +1766,10 @@ do_select_tests e_select-8.5 {
     94 94 9 8 4 0 0 -19
   }
   3  "SELECT z AS x, x AS z FROM d1 ORDER BY z" {
-    3 1    8 1    7 1    -20 1    93 1    -1 1    -1 2    93 2
+    /# 1    # 1    # 1    # 1    # 1    # 1    # 2    # 2/
   }
   4  "SELECT z AS x, x AS z FROM d1 ORDER BY x" {
-    -20 1    -1 2    -1 1    3 1    7 1    8 1    93 2    93 1
+    /-20 1    -1 #    -1 #    3 1    7 1    8 1    93 #    93 #/
   }
 }
 
index 2837dfcab399bb49f7cc33ea7b55ba7277c5ebe9..400659b4754ec5b6832021c21122cf405049a6ed 100644 (file)
@@ -114,7 +114,7 @@ do_test 1.4c {
     EXPLAIN QUERY PLAN
     SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
   }
-} {~/ORDER BY/}  ;# ORDER BY optimized-out
+} {/ORDER BY/}  ;# separate sorting pass due to mixed DESC/ASC
 
 
 do_test 1.5a {
@@ -130,9 +130,9 @@ do_test 1.5b {
 do_test 1.5c {
   db eval {
     EXPLAIN QUERY PLAN
-    SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
+    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
   }
-} {~/ORDER BY/}  ;# ORDER BY optimized-out
+} {/ORDER BY/}  ;# separate sorting pass due to mixed DESC/ASC
 
 do_test 1.6a {
   db eval {
@@ -152,4 +152,275 @@ do_test 1.6c {
 } {~/ORDER BY/}  ;# ORDER BY optimized-out
 
 
+# Reconstruct the test data to use indices rather than integer primary keys.
+#
+do_test 2.0 {
+  db eval {
+    BEGIN;
+    DROP TABLE album;
+    DROP TABLE track;
+    CREATE TABLE album(
+      aid INT PRIMARY KEY,
+      title TEXT NOT NULL
+    );
+    CREATE INDEX album_i1 ON album(title, aid);
+    CREATE TABLE track(
+      aid INTEGER NOT NULL REFERENCES album,
+      tn INTEGER NOT NULL,
+      name TEXT,
+      UNIQUE(aid, tn)
+    );
+    INSERT INTO album VALUES(1, '1-one'), (2, '2-two'), (3, '3-three');
+    INSERT INTO track VALUES
+        (1, 1, 'one-a'),
+        (2, 2, 'two-b'),
+        (3, 3, 'three-c'),
+        (1, 3, 'one-c'),
+        (2, 1, 'two-a'),
+        (3, 1, 'three-a');
+    COMMIT;
+  }
+} {}
+do_test 2.1a {
+  db eval {
+    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
+  }
+} {one-a one-c two-a two-b three-a three-c}
+
+# Verify that the ORDER BY clause is optimized out
+#
+do_test 2.1b {
+  db eval {
+    EXPLAIN QUERY PLAN
+    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
+  }
+} {~/ORDER BY/}  ;# ORDER BY optimized out
+
+# The same query with ORDER BY clause optimization disabled via + operators
+# should give exactly the same answer.
+#
+do_test 2.2a {
+  db eval {
+    SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
+  }
+} {one-a one-c two-a two-b three-a three-c}
+
+# The output is sorted manually in this case.
+#
+do_test 2.2b {
+  db eval {
+    EXPLAIN QUERY PLAN
+    SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
+  }
+} {/ORDER BY/}   ;# separate sorting pass due to "+" on ORDER BY terms
+
+# The same query with ORDER BY optimizations turned off via built-in test.
+#
+do_test 2.3a {
+  optimization_control db order-by-idx-join 0
+  db cache flush
+  db eval {
+    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
+  }
+} {one-a one-c two-a two-b three-a three-c}
+do_test 2.3b {
+  db eval {
+    EXPLAIN QUERY PLAN
+    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
+  }
+} {/ORDER BY/}   ;# separate sorting pass due to disabled optimization
+optimization_control db all 1
+db cache flush
+
+# Reverse order sorts
+#
+do_test 2.4a {
+  db eval {
+    SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
+  }
+} {three-a three-c two-a two-b one-a one-c}
+do_test 2.4b {
+  db eval {
+    SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn
+  }
+} {three-a three-c two-a two-b one-a one-c}  ;# verify same order after sorting
+do_test 2.4c {
+  db eval {
+    EXPLAIN QUERY PLAN
+    SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
+  }
+} {/ORDER BY/}  ;# separate sorting pass due to mixed DESC/ASC
+
+
+do_test 2.5a {
+  db eval {
+    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
+  }
+} {one-c one-a two-b two-a three-c three-a}
+do_test 2.5b {
+  db eval {
+    SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC
+  }
+} {one-c one-a two-b two-a three-c three-a}  ;# verify same order after sorting
+do_test 2.5c {
+  db eval {
+    EXPLAIN QUERY PLAN
+    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
+  }
+} {/ORDER BY/}  ;# separate sorting pass due to mixed ASC/DESC
+
+do_test 2.6a {
+  db eval {
+    SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
+  }
+} {three-c three-a two-b two-a one-c one-a}
+do_test 2.6b {
+  db eval {
+    SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn DESC
+  }
+} {three-c three-a two-b two-a one-c one-a}  ;# verify same order after sorting
+do_test 2.6c {
+  db eval {
+    EXPLAIN QUERY PLAN
+    SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
+  }
+} {~/ORDER BY/}  ;# ORDER BY optimized-out
+
+
+# Generate another test dataset, but this time using mixed ASC/DESC indices.
+#
+do_test 3.0 {
+  db eval {
+    BEGIN;
+    DROP TABLE album;
+    DROP TABLE track;
+    CREATE TABLE album(
+      aid INTEGER PRIMARY KEY,
+      title TEXT UNIQUE NOT NULL
+    );
+    CREATE TABLE track(
+      tid INTEGER PRIMARY KEY,
+      aid INTEGER NOT NULL REFERENCES album,
+      tn INTEGER NOT NULL,
+      name TEXT,
+      UNIQUE(aid ASC, tn DESC)
+    );
+    INSERT INTO album VALUES(1, '1-one'), (2, '2-two'), (3, '3-three');
+    INSERT INTO track VALUES
+        (NULL, 1, 1, 'one-a'),
+        (NULL, 2, 2, 'two-b'),
+        (NULL, 3, 3, 'three-c'),
+        (NULL, 1, 3, 'one-c'),
+        (NULL, 2, 1, 'two-a'),
+        (NULL, 3, 1, 'three-a');
+    COMMIT;
+  }
+} {}
+do_test 3.1a {
+  db eval {
+    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
+  }
+} {one-c one-a two-b two-a three-c three-a}
+
+# Verify that the ORDER BY clause is optimized out
+#
+do_test 3.1b {
+  db eval {
+    EXPLAIN QUERY PLAN
+    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
+  }
+} {~/ORDER BY/}  ;# ORDER BY optimized out
+
+# The same query with ORDER BY clause optimization disabled via + operators
+# should give exactly the same answer.
+#
+do_test 3.2a {
+  db eval {
+    SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC
+  }
+} {one-c one-a two-b two-a three-c three-a}
+
+# The output is sorted manually in this case.
+#
+do_test 3.2b {
+  db eval {
+    EXPLAIN QUERY PLAN
+    SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC
+  }
+} {/ORDER BY/}   ;# separate sorting pass due to "+" on ORDER BY terms
+
+# The same query with ORDER BY optimizations turned off via built-in test.
+#
+do_test 3.3a {
+  optimization_control db order-by-idx-join 0
+  db cache flush
+  db eval {
+    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
+  }
+} {one-c one-a two-b two-a three-c three-a}
+do_test 3.3b {
+  db eval {
+    EXPLAIN QUERY PLAN
+    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
+  }
+} {/ORDER BY/}   ;# separate sorting pass due to disabled optimization
+optimization_control db all 1
+db cache flush
+
+# Without the mixed ASC/DESC on ORDER BY
+#
+do_test 3.4a {
+  db eval {
+    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
+  }
+} {one-a one-c two-a two-b three-a three-c}
+do_test 3.4b {
+  db eval {
+    SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
+  }
+} {one-a one-c two-a two-b three-a three-c}  ;# verify same order after sorting
+do_test 3.4c {
+  db eval {
+    EXPLAIN QUERY PLAN
+    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
+  }
+} {/ORDER BY/}  ;# separate sorting pass due to mismatched DESC/ASC
+
+
+do_test 3.5a {
+  db eval {
+    SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
+  }
+} {three-c three-a two-b two-a one-c one-a}
+do_test 3.5b {
+  db eval {
+    SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn DESC
+  }
+} {three-c three-a two-b two-a one-c one-a}  ;# verify same order after sorting
+do_test 3.5c {
+  db eval {
+    EXPLAIN QUERY PLAN
+    SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
+  }
+} {/ORDER BY/}  ;# separate sorting pass due to mismatched ASC/DESC
+
+
+do_test 3.6a {
+  db eval {
+    SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
+  }
+} {three-a three-c two-a two-b one-a one-c}
+do_test 3.6b {
+  db eval {
+    SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn
+  }
+} {three-a three-c two-a two-b one-a one-c}  ;# verify same order after sorting
+do_test 3.6c {
+  db eval {
+    EXPLAIN QUERY PLAN
+    SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
+  }
+} {~/ORDER BY/}  ;# inverted ASC/DESC is optimized out
+
+
 finish_test
index 74f1e2a1b34a89e58154fc2e5e1d6287fbc82b0f..d3fa607d324d8709ed56750c4498d720b388e911 100644 (file)
@@ -538,10 +538,10 @@ proc do_test {name cmd expected} {
     } else {
       if {[regexp {^~?/.*/$} $expected]} {
         if {[string index $expected 0]=="~"} {
-          set re [string range $expected 2 end-1]
+          set re [string map {# {[-0-9.]+}} [string range $expected 2 end-1]]
           set ok [expr {![regexp $re $result]}]
         } else {
-          set re [string range $expected 1 end-1]
+          set re [string map {# {[-0-9.]+}} [string range $expected 1 end-1]]
           set ok [regexp $re $result]
         }
       } else {
index 180acf56dffde9b5c98fd649b29f66d56055b2f0..51e01991d467c38910952054ace6305acff76aec 100644 (file)
@@ -50,7 +50,7 @@ do_test tkt-cbd05-1.3 {
     WHERE idx = 't1_x' 
     GROUP BY tbl,idx
   }
-} {t1 t1_x { A B C D E F G H I}}
+} {/t1 t1_x .[ ABCDEFGHI]{10}./}
 
 do_test tkt-cbd05-2.1 {
   db eval {
@@ -82,6 +82,6 @@ do_test tkt-cbd05-2.3 {
     WHERE idx = 't1_x' 
     GROUP BY tbl,idx
   }
-} {t1 t1_x { A B C D E F G H I}}
+} {/t1 t1_x .[ ABCDEFGHI]{10}./}
 
 finish_test
index 1dab38ce55a2f6f7a034290e3347b29f22444736..e57722c430bfa95562aa8c35ce7b4bd79f7acad6 100644 (file)
@@ -383,7 +383,7 @@ ifcapable subquery {
     count {
       SELECT * FROM t1 WHERE w IN (-1,1,2,3) order by 1;
     }
-  } {1 0 4 2 1 9 3 1 16 14}
+  } {1 0 4 2 1 9 3 1 16 13}
   do_test where-5.4 {
     count {
       SELECT * FROM t1 WHERE w+0 IN (-1,1,2,3) order by 1;
@@ -1109,13 +1109,13 @@ do_test where-14.5 {
   cksort {
     SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, x.a||x.b
   } 
-} {4/4 4/1 1/4 1/1 sort}
+} {/4/[14] 4/[14] 1/[14] 1/[14] sort/}
 do_test where-14.6 {
   # This test case changed from "nosort" to "sort". See ticket 2a5629202f.
   cksort {
     SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, x.a||x.b DESC
   } 
-} {4/4 4/1 1/4 1/1 sort}
+} {/4/[14] 4/[14] 1/[14] 1/[14] sort/}
 do_test where-14.7 {
   cksort {
     SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, y.a||y.b