]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix for 2a5629202f. When considering whether or not a UNIQUE index may be used to...
authordan <dan@noemail.net>
Fri, 20 Apr 2012 15:24:53 +0000 (15:24 +0000)
committerdan <dan@noemail.net>
Fri, 20 Apr 2012 15:24:53 +0000 (15:24 +0000)
FossilOrigin-Name: 9870e4c4fef10112c987c40cb1b95255a7214202

manifest
manifest.uuid
src/where.c
test/tkt-2a5629202f.test [new file with mode: 0644]
test/where.test

index f029544c0df977dee29b2d1af3c3ee0cd0df911d..700e7257778aa40d5912cdbff00bb647086bd32e 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Remove\sobsolete\sart.
-D 2012-04-20T12:02:32.039
+C Fix\sfor\s2a5629202f.\sWhen\sconsidering\swhether\sor\snot\sa\sUNIQUE\sindex\smay\sbe\sused\sto\soptimize\san\sORDER\sBY\sclause,\sdo\snot\sassume\sthat\sall\sindex\sentries\sare\sdistinct\sunless\sthere\sis\ssome\sreason\sto\sbelieve\sthat\sthe\sindex\scontains\sno\sNULL\svalues.
+D 2012-04-20T15:24:53.110
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 2f37e468503dbe79d35c9f6dffcf3fae1ae9ec20
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -246,7 +246,7 @@ F src/vtab.c ab90fb600a3f5e4b7c48d22a4cdb2d6b23239847
 F src/wal.c 7bb3ad807afc7973406c805d5157ec7a2f65e146
 F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6
 F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
-F src/where.c 2112422a404dcca5d47f6630bdf180bccd36c62b
+F src/where.c e25ae482e94226df7f95fa4e0545cc7064e86574
 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
@@ -733,6 +733,7 @@ F test/threadtest2.c ace893054fa134af3fc8d6e7cfecddb8e3acefb9
 F test/threadtest3.c 0ed13e09690f6204d7455fac3b0e8ece490f6eef
 F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c
 F test/tkt-26ff0c2d1e.test 888324e751512972c6e0d1a09df740d8f5aaf660
+F test/tkt-2a5629202f.test 1ab32e084e9fc3d36be6dee2617530846a0eb0b6
 F test/tkt-2d1a5c67d.test b028a811049eb472cb2d3a43fc8ce4f6894eebda
 F test/tkt-2ea2425d34.test 1cf13e6f75d149b3209a0cb32927a82d3d79fb28
 F test/tkt-31338dca7e.test 1f714c14b6682c5db715e0bda347926a3456f7a9
@@ -931,7 +932,7 @@ F test/walro.test e6bb27762c9f22601cbb8bff6e0acfd124e74b63
 F test/walshared.test 6dda2293880c300baf5d791c307f653094585761
 F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a
 F test/walthread.test a2ed5270eb695284d4ad27d252517bdc3317ee2a
-F test/where.test de337a3fe0a459ec7c93db16a519657a90552330
+F test/where.test 4c9f69987ed2aa0173fa930f2b41ab9879478cd8
 F test/where2.test 43d4becaf5a5df854e6c21d624a1cb84c6904554
 F test/where3.test 667e75642102c97a00bf9b23d3cb267db321d006
 F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2
@@ -992,7 +993,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
 F tool/warnings-clang.sh a8a0a3babda96dfb1ff51adda3cbbf3dfb7266c2
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
-P 3281972eaa46cb57fd9f0387063f47430dc0a3b4
-R 996fa506825219f1b7ce0687d37d97d8
-U drh
-Z 27a58991babc71a559ca9c653e33aa72
+P 372a90e2264a29ce543c093766cdec764d18b5a5
+R c55b0e9d6060c081eba144f695f549a1
+U dan
+Z 3f4edf7c59f1f66ed37303deb846aef3
index 19174a46d2e242e4c4208c33fe9d7cd090e460bb..c191b9349f2a336129b29cec977d6d98b4b216b2 100644 (file)
@@ -1 +1 @@
-372a90e2264a29ce543c093766cdec764d18b5a5
\ No newline at end of file
+9870e4c4fef10112c987c40cb1b95255a7214202
\ No newline at end of file
index 5471f71dcf3d7709b646efe937ef32b78ac5d554..f2c180959b9eeb1d8ea975821e512754f2d27f6c 100644 (file)
@@ -1718,14 +1718,26 @@ static int isSortingIndex(
   }
   if( pIdx->onError!=OE_None && i==pIdx->nColumn
       && (wsFlags & WHERE_COLUMN_NULL)==0
-      && !referencesOtherTables(pOrderBy, pMaskSet, j, base) ){
-    /* All terms of this index match some prefix of the ORDER BY clause
-    ** and the index is UNIQUE and no terms on the tail of the ORDER BY
-    ** clause reference other tables in a join.  If this is all true then
-    ** the order by clause is superfluous.  Not that if the matching
-    ** condition is IS NULL then the result is not necessarily unique
-    ** even on a UNIQUE index, so disallow those cases. */
-    return 1;
+      && !referencesOtherTables(pOrderBy, pMaskSet, j, base) 
+  ){
+    Column *aCol = pIdx->pTable->aCol;
+    int i;
+
+    /* All terms of this index match some prefix of the ORDER BY clause,
+    ** the index is UNIQUE, and no terms on the tail of the ORDER BY
+    ** refer to other tables in a join. So, assuming that the index entries
+    ** visited contain no NULL values, then this index delivers rows in
+    ** the required order.
+    **
+    ** It is not possible for any of the first nEqCol index fields to be
+    ** NULL (since the corresponding "=" operator in the WHERE clause would 
+    ** not be true). So if all remaining index columns have NOT NULL 
+    ** constaints attached to them, we can be confident that the visited
+    ** index entries are free of NULLs.  */
+    for(i=nEqCol; i<pIdx->nColumn; i++){
+      if( aCol[pIdx->aiColumn[i]].notNull==0 ) break;
+    }
+    return (i>=pIdx->nColumn);
   }
   return 0;
 }
diff --git a/test/tkt-2a5629202f.test b/test/tkt-2a5629202f.test
new file mode 100644 (file)
index 0000000..037f100
--- /dev/null
@@ -0,0 +1,71 @@
+# 2012 April 19
+#
+# The author disclaims copyright to this source code.  In place of
+# a legal notice, here is a blessing:
+#
+#    May you do good and not evil.
+#    May you find forgiveness for yourself and forgive others.
+#    May you share freely, never taking more than you give.
+#
+#***********************************************************************
+# The tests in this file were used while developing the SQLite 4 code. 
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set testprefix tkt-2a5629202f
+
+# This procedure executes the SQL.  Then it checks to see if the OP_Sort
+# opcode was executed.  If an OP_Sort did occur, then "sort" is appended
+# to the result.  If no OP_Sort happened, then "nosort" is appended.
+#
+# This procedure is used to check to make sure sorting is or is not
+# occurring as expected.
+#
+proc cksort {sql} {
+  set data [execsql $sql]
+  if {[db status sort]} {set x sort} {set x nosort}
+  lappend data $x
+  return $data
+}
+
+do_execsql_test 1.1 {
+  CREATE TABLE t8(b TEXT, c TEXT);
+  INSERT INTO t8 VALUES('a',  'one');
+  INSERT INTO t8 VALUES('b',  'two');
+  INSERT INTO t8 VALUES(NULL, 'three');
+  INSERT INTO t8 VALUES(NULL, 'four');
+}
+
+do_execsql_test 1.2 {
+  SELECT coalesce(b, 'null') || '/' || c FROM t8 x ORDER BY x.b, x.c
+} {null/four null/three a/one b/two}
+
+do_execsql_test 1.3 {
+  CREATE UNIQUE INDEX i1 ON t8(b);
+  SELECT coalesce(b, 'null') || '/' || c FROM t8 x ORDER BY x.b, x.c
+} {null/four null/three a/one b/two}
+
+#-------------------------------------------------------------------------
+#
+
+do_execsql_test 2.1 {
+  CREATE TABLE t2(a, b NOT NULL, c);
+  CREATE UNIQUE INDEX t2ab ON t2(a, b);
+  CREATE UNIQUE INDEX t2ba ON t2(b, a);
+}
+
+do_test 2.2 {
+  cksort { SELECT * FROM t2 WHERE a = 10 ORDER BY a, b, c }
+} {nosort}
+
+do_test 2.3 {
+  cksort { SELECT * FROM t2 WHERE b = 10 ORDER BY a, b, c }
+} {sort}
+
+do_test 2.4 {
+  cksort { SELECT * FROM t2 WHERE a IS NULL ORDER BY a, b, c }
+} {sort}
+
+finish_test
+
index 9145bcc7535ef6882f5ab60fbc40f096f1a6236a..3826a5f64a7f81d20e47e018e3a0e89a67ad721b 100644 (file)
@@ -1105,15 +1105,17 @@ do_test where-14.4 {
   } 
 } {1/1 1/4 4/1 4/4 nosort}
 do_test where-14.5 {
+  # 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
   } 
-} {4/1 4/4 1/1 1/4 nosort}
+} {4/1 4/4 1/1 1/4 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/1 4/4 1/1 1/4 nosort}
+} {4/1 4/4 1/1 1/4 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