From a3855653ed06222b8c0f0329a4ab23ea8a8adbbb Mon Sep 17 00:00:00 2001
From: drh <drh@noemail.net>
Date: Mon, 3 Jun 2013 21:25:28 +0000
Subject: [PATCH] Adjust the xBestIndex methods on both the fuzzer and
 transitive_closure virtual tables so that an unused MATCH operator gets a
 really large cost. Remove ambiguities from the fuzzer test cases.

FossilOrigin-Name: e2c1af78b65a8ace976fa6c035db212e1ffc79b8
---
 ext/misc/closure.c |  6 ++++++
 ext/misc/fuzzer.c  | 13 ++++++++++++-
 manifest           | 16 ++++++++--------
 manifest.uuid      |  2 +-
 test/fuzzer1.test  | 17 +++++++++++------
 5 files changed, 38 insertions(+), 16 deletions(-)

diff --git a/ext/misc/closure.c b/ext/misc/closure.c
index 665cc7ce44..260a783042 100644
--- a/ext/misc/closure.c
+++ b/ext/misc/closure.c
@@ -826,12 +826,17 @@ static int closureBestIndex(
   int iPlan = 0;
   int i;
   int idx = 1;
+  int seenMatch = 0;
   const struct sqlite3_index_constraint *pConstraint;
   closure_vtab *pVtab = (closure_vtab*)pTab;
   double rCost = 10000000.0;
 
   pConstraint = pIdxInfo->aConstraint;
   for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
+    if( pConstraint->iColumn==CLOSURE_COL_ROOT
+     && pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
+      seenMatch = 1;
+    }
     if( pConstraint->usable==0 ) continue;
     if( (iPlan & 1)==0 
      && pConstraint->iColumn==CLOSURE_COL_ROOT
@@ -895,6 +900,7 @@ static int closureBestIndex(
   ){
     pIdxInfo->orderByConsumed = 1;
   }
+  if( seenMatch && (iPlan&1)==0 ) rCost *= 1e30;
   pIdxInfo->estimatedCost = rCost;
    
   return SQLITE_OK;
diff --git a/ext/misc/fuzzer.c b/ext/misc/fuzzer.c
index 642b8f9e92..023bdb1d09 100644
--- a/ext/misc/fuzzer.c
+++ b/ext/misc/fuzzer.c
@@ -1077,9 +1077,16 @@ static int fuzzerBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
   int iDistTerm = -1;
   int iRulesetTerm = -1;
   int i;
+  int seenMatch = 0;
   const struct sqlite3_index_constraint *pConstraint;
+  double rCost = 100000;
+
   pConstraint = pIdxInfo->aConstraint;
   for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
+    if( pConstraint->iColumn==0
+     && pConstraint->op==SQLITE_INDEX_CONSTRAINT_MATCH ){
+      seenMatch = 1;
+    }
     if( pConstraint->usable==0 ) continue;
     if( (iPlan & 1)==0 
      && pConstraint->iColumn==0
@@ -1088,6 +1095,7 @@ static int fuzzerBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
       iPlan |= 1;
       pIdxInfo->aConstraintUsage[i].argvIndex = 1;
       pIdxInfo->aConstraintUsage[i].omit = 1;
+      rCost /= 1000000.0;
     }
     if( (iPlan & 2)==0
      && pConstraint->iColumn==1
@@ -1096,6 +1104,7 @@ static int fuzzerBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
     ){
       iPlan |= 2;
       iDistTerm = i;
+      rCost /= 10.0;
     }
     if( (iPlan & 4)==0
      && pConstraint->iColumn==2
@@ -1104,6 +1113,7 @@ static int fuzzerBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
       iPlan |= 4;
       pIdxInfo->aConstraintUsage[i].omit = 1;
       iRulesetTerm = i;
+      rCost /= 10.0;
     }
   }
   if( iPlan & 2 ){
@@ -1122,7 +1132,8 @@ static int fuzzerBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
   ){
     pIdxInfo->orderByConsumed = 1;
   }
-  pIdxInfo->estimatedCost = (double)10000;
+  if( seenMatch && (iPlan&1)==0 ) rCost *= 1e30;
+  pIdxInfo->estimatedCost = rCost;
    
   return SQLITE_OK;
 }
diff --git a/manifest b/manifest
index dba927beb0..75f057b5a8 100644
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Pull\sin\srecent\strunk\schanges.\s\sFix\sthe\sORDER\sBY\soptimizer\sso\sthat\sit\sis\sbetter\nable\sto\sdeal\swith\sCOLLATE\sclauses.\s\sClean\sup\sambiguities\sin\sthe\sdescidx1.test\nscript.
-D 2013-06-03T20:46:35.011
+C Adjust\sthe\sxBestIndex\smethods\son\sboth\sthe\sfuzzer\sand\stransitive_closure\nvirtual\stables\sso\sthat\san\sunused\sMATCH\soperator\sgets\sa\sreally\slarge\scost.\nRemove\sambiguities\sfrom\sthe\sfuzzer\stest\scases.
+D 2013-06-03T21:25:28.624
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -107,8 +107,8 @@ F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43
 F ext/icu/icu.c 7538f98eab2854cf17fa5f7797bffa6c76e3863b
 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
 F ext/misc/amatch.c eae8454cd9dcb287b2a3ec2e65a865a4ac5f0d06
-F ext/misc/closure.c b88aa95fbe32edc74e16ed5bb6646d249a2bf6ad
-F ext/misc/fuzzer.c 51bd96960b6b077d41d6f3cedefbcb57f29efaa2
+F ext/misc/closure.c 997c20ddf35f85ab399f4a02a557a9baa822ec32
+F ext/misc/fuzzer.c 79ac20b68794dfe03626f3a31681e6c240583052
 F ext/misc/ieee754.c 2565ce373d842977efe0922dc50b8a41b3289556
 F ext/misc/nextchar.c 1131e2b36116ffc6fe6b2e3464bfdace27978b1e
 F ext/misc/percentile.c 4fb5e46c4312b0be74e8e497ac18f805f0e3e6c5
@@ -561,7 +561,7 @@ F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167
 F test/fuzz3.test aec64345184d1662bd30e6a17851ff659d596dc5
 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
 F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26
-F test/fuzzer1.test 41bd5aa6ae0cf18d06342a4476e3cad98604ae48
+F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36
 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
 F test/hook.test 45cb22b940c3cc0af616ba7430f666e245711a48
 F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4
@@ -1093,7 +1093,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
-P fabb21854e662b1d8e5631e79f828d5322ceb595 4d74fccf02134a998a84097b021ba9d501e34ff0
-R b746dc544342dfc07463de0423275bdc
+P 6bc71dfcf0ef757c5c2b426dd8fddc1e5ae0f598
+R 9f95af129af308d556c3b0bed3929212
 U drh
-Z 5182eac11ae0820ee1af6bccc6719c26
+Z 30d36dfc5ff4e44e38a2e90ed964881e
diff --git a/manifest.uuid b/manifest.uuid
index 1e5db89b77..5fac46b81c 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-6bc71dfcf0ef757c5c2b426dd8fddc1e5ae0f598
\ No newline at end of file
+e2c1af78b65a8ace976fa6c035db212e1ffc79b8
\ No newline at end of file
diff --git a/test/fuzzer1.test b/test/fuzzer1.test
index 473d0e1868..4ee5730807 100644
--- a/test/fuzzer1.test
+++ b/test/fuzzer1.test
@@ -1728,36 +1728,41 @@ do_execsql_test 8.1 {
 do_execsql_test 8.2.1 {
   SELECT cFrom, cTo, word 
     FROM x3_rules CROSS JOIN x3 
-    WHERE word MATCH 'a' AND cost=distance AND ruleset=2;
+    WHERE word MATCH 'a' AND cost=distance AND ruleset=2
+    ORDER BY +cTo;
 } {a x x a y y a z z}
 
 do_execsql_test 8.2.2 {
   SELECT cFrom, cTo, word 
     FROM x3 CROSS JOIN x3_rules
-    WHERE word MATCH 'a' AND cost=distance AND ruleset=2;
+    WHERE word MATCH 'a' AND cost=distance AND ruleset=2
+    ORDER BY +cTo DESC
 } {a z z a y y a x x}
 
 do_execsql_test 8.2.3 {
   SELECT cFrom, cTo, word 
     FROM x3_rules, x3 
-    WHERE word MATCH 'a' AND cost=distance AND ruleset=2;
+    WHERE word MATCH 'a' AND cost=distance AND ruleset=2
+    ORDER BY +cTo DESC;
 } {a z z a y y a x x}
 
 do_execsql_test 8.2.4 {
   SELECT cFrom, cTo, word 
     FROM x3, x3_rules
-    WHERE word MATCH 'a' AND cost=distance AND ruleset=2;
+    WHERE word MATCH 'a' AND cost=distance AND ruleset=2
+    ORDER BY +cTo DESC;
 } {a z z a y y a x x}
 
 do_execsql_test 8.2.5 {
   CREATE INDEX i1 ON x3_rules(cost);
   SELECT cFrom, cTo, word 
     FROM x3_rules, x3 
-    WHERE word MATCH 'a' AND cost=distance AND ruleset=2;
+    WHERE word MATCH 'a' AND cost=distance AND ruleset=2
+    ORDER BY +cTo DESC;
 } {a z z a y y a x x}
 
 do_execsql_test 8.2.5 {
-  SELECT word FROM x3_rules, x3 WHERE word MATCH x3_rules.cFrom AND ruleset=2;
+  SELECT word FROM x3_rules, x3 WHERE word MATCH x3_rules.cFrom AND ruleset=2
 } {a z y x a z y x a z y x}
 
 do_execsql_test 8.2.6 {