]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix an obscure problem in range estimation with STAT4.
authordrh <drh@noemail.net>
Fri, 9 Dec 2016 00:15:17 +0000 (00:15 +0000)
committerdrh <drh@noemail.net>
Fri, 9 Dec 2016 00:15:17 +0000 (00:15 +0000)
FossilOrigin-Name: 1f16c9a76bc48331799f33b30d143c632fe0e7db

manifest
manifest.uuid
src/vdbemem.c
test/analyzeF.test

index 546a10b05dd167df0d9eb33f7f7dab4469250f50..d6c3f0afbbe5489502430f39d953c1b4e7a4dd40 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sthe\sshowstat4\sutility\sprogram\sso\sthat\sis\sdisplays\sstrings\susing\nstandard\sSQL\snotation\s(single\squotes)\srather\sthan\sC-style\snotation.
-D 2016-12-08T23:52:38.728
+C Fix\san\sobscure\sproblem\sin\srange\sestimation\swith\sSTAT4.
+D 2016-12-09T00:15:17.019
 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da
@@ -461,7 +461,7 @@ F src/vdbeInt.h 9b498d3cb52dc2efb53571fb8ae8e14cf298ce84
 F src/vdbeapi.c ea4e2dc2213cc6bd7bee375a29a9b51c31b93ae0
 F src/vdbeaux.c be0797ca0c392eea2201afbf2eef0b1531e2a8b7
 F src/vdbeblob.c f4f98ea672b242f807c08c92c7faaa79e5091b65
-F src/vdbemem.c 1af2f14ab0f7004b364933ddcfc767fb880d4742
+F src/vdbemem.c d3fd85b7b7ef3eb75de29c6d7e1d10d3ca78b4fd
 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c
 F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834
 F src/vtab.c e02cacb5c7ae742631edeb9ae9f53d399f093fd8
@@ -498,7 +498,7 @@ F test/analyzeB.test a4c1c3048f6d9e090eb76e83eecb18bcf6d31a70
 F test/analyzeC.test 555a6cc388b9818b6eda6df816f01ce0a75d3a93
 F test/analyzeD.test 42af58de25a6436502e43006e9e59e2d71bcb0cf
 F test/analyzeE.test 8684e8ac5722fb97c251887ad97e5d496a98af1d
-F test/analyzeF.test 5d1fe1024ba2dfea3c18bede8c1ccef8aba1ab34
+F test/analyzeF.test f423125b557f11ad71bb29765ef9c34b6dcf4ab7
 F test/analyzer1.test 459fa02c445ddbf0101a3bad47b34290a35f2e49
 F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b
 F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b
@@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P b26df26e184ec6da4b5537526c10f42a293d09b5
-R 20c5d0b862118000112ece07f7baa65b
+P 92998e4afbe4da1723e7e5155071a0e7242bd6ff
+R 146bb5a9bbf2bccc768a9ed3b6a15043
 U drh
-Z fcf8e16d4cd3aef2bba348beb58ea104
+Z eab3e469ec793ab1e1350c15f3974350
index 314984d3d1b4fa9ae29905c30919f71943f27458..7d54383ae98936930056aa0246f57fbea6e9354e 100644 (file)
@@ -1 +1 @@
-92998e4afbe4da1723e7e5155071a0e7242bd6ff
\ No newline at end of file
+1f16c9a76bc48331799f33b30d143c632fe0e7db
\ No newline at end of file
index 2ee80045d136307e4689befd07c2e1fea0b2c7f3..9a73b627770273dbfce397659d902b7b6c0be70b 100644 (file)
@@ -1333,6 +1333,7 @@ static int valueFromExpr(
   }else if( op==TK_NULL ){
     pVal = valueNew(db, pCtx);
     if( pVal==0 ) goto no_mem;
+    sqlite3VdbeMemNumerify(pVal);
   }
 #ifndef SQLITE_OMIT_BLOB_LITERAL
   else if( op==TK_BLOB ){
index 3cbc5f47be3187ed257e8517066feaba5190400f..76891ddfe3e6b1c93ff9b8c173caa8c474886fc9 100644 (file)
@@ -120,5 +120,31 @@ do_catchsql_test 4.4 {
   SELECT * FROM t1 WHERE x = test_zeroblob(1100000) AND y = 4;
 } {1 {string or blob too big}}
 
+# 2016-12-08: Constraints of the form "x=? AND x IS NOT NULL" were being
+# mishandled.  The sqlite3Stat4ProbeSetValue() routine was assuming that
+# valueNew() was returning a Mem object that was preset to NULL, which is
+# not the case.  The consequence was the the "x IS NOT NULL" constraint
+# was used to drive the index (via the "x>NULL" pseudo-constraint) rather
+# than the "x=?" constraint.
+#
+do_execsql_test 5.1 {
+  DROP TABLE IF EXISTS t1;
+  CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c INT);
+  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<10000)
+    INSERT INTO t1(a, c) SELECT x, x FROM c;
+  UPDATE t1 SET b=printf('x%02x',a/500) WHERE a>4000;
+  UPDATE t1 SET b='xyz' where a>=9998;
+  CREATE INDEX t1b ON t1(b);
+  ANALYZE;
+  SELECT count(*), b FROM t1 GROUP BY 2 ORDER BY 2;
+} {4000 {} 499 x08 500 x09 500 x0a 500 x0b 500 x0c 500 x0d 500 x0e 500 x0f 500 x10 500 x11 500 x12 498 x13 3 xyz}
+do_execsql_test 5.2 {
+  explain query plan
+  SELECT * FROM t1 WHERE b='xyz' AND b IS NOT NULL ORDER BY +a;
+  /*                  v---- Should be "=", not ">"  */
+} {/USING INDEX t1b .b=/}
+do_execsql_test 5.3 {
+  SELECT * FROM t1 WHERE b='xyz' AND b IS NOT NULL ORDER BY +a;
+} {9998 xyz 9998 9999 xyz 9999 10000 xyz 10000}
 
 finish_test