From: drh Date: Thu, 17 Mar 2011 01:34:26 +0000 (+0000) Subject: Enhances to the query planner such that "x IS NULL" constraints take the X-Git-Tag: version-3.7.6~96 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1f9c7663ce09be70beb0259fa2c71c165cab4325;p=thirdparty%2Fsqlite.git Enhances to the query planner such that "x IS NULL" constraints take the STAT2 statistics into account, just like "x=VALUE" constraints. FossilOrigin-Name: 2353176811f752a16c1f2351a3d3431919b062a9 --- diff --git a/install-sh b/install-sh old mode 100644 new mode 100755 diff --git a/manifest b/manifest index ceed9e597f..b04b624d6b 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Additional\sinterpretation\sof\sflags\sand\sconstants\sin\sthe\sVFS\strace\soutput. -D 2011-03-16T18:54:23.037 +C Enhances\sto\sthe\squery\splanner\ssuch\sthat\s"x\sIS\sNULL"\sconstraints\stake\sthe\nSTAT2\sstatistics\sinto\saccount,\sjust\slike\s"x=VALUE"\sconstraints. +D 2011-03-17T01:34:26.570 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -102,7 +102,7 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 -F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 +F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F main.mk 54190fab7cdba523e311c274c95ea480f32abfb5 F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a @@ -246,7 +246,7 @@ F src/vtab.c b297e8fa656ab5e66244ab15680d68db0adbec30 F src/wal.c 7334009b396285b658a95a3b6bc6d2b016a1f794 F src/wal.h 7a5fbb00114b7f2cd40c7e1003d4c41ce9d26840 F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f -F src/where.c 27c2f4e249213faeab548f628e52c005623f195d +F src/where.c a41a1c64aceb4138a865e6dc939f781f53401d68 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 51756962d522e474338e9b2ebb26e7364d4aa125 @@ -259,7 +259,7 @@ F test/analyze.test c1eb87067fc16ece7c07e823d6395fd831b270c5 F test/analyze2.test 8f2b1534d43f5547ce9a6b736c021d4192c75be3 F test/analyze3.test d61f55d8b472fc6e713160b1e577f7a68e63f38b F test/analyze4.test 757b37875cf9bb528d46f74497bc789c88365045 -F test/analyze5.test 0618d2fe8982a5dae1d4e92152acc8ecbaf52be2 +F test/analyze5.test adc89b92fc9fee5ca1cb0bc8512f3206ad0fe5aa F test/analyze6.test 1ba1aea8fad25a77ffd71f24522d1bb9ecc949fc F test/async.test ad4ba51b77cd118911a3fe1356b0809da9c108c3 F test/async2.test bf5e2ca2c96763b4cba3d016249ad7259a5603b6 @@ -605,7 +605,7 @@ F test/permutations.test 5b2a4cb756ffb2407cb4743163668d1d769febb6 F test/pragma.test fdfc09067ea104a0c247a1a79d8093b56656f850 F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47 F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea -F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 x +F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quota.test ddafe133653093eb9a99ccd6264884ae43f9c9b8 @@ -892,7 +892,7 @@ F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/lemon.c dfd81a51b6e27e469ba21d01a75ddf092d429027 F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc F tool/mkkeywordhash.c d2e6b4a5965e23afb80fbe74bb54648cd371f309 -F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x +F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c.tcl cf44512a48112b1ba09590548660a5a6877afdb3 F tool/mksqlite3h.tcl d76c226a5e8e1f3b5f6593bcabe5e98b3b1ec9ff @@ -917,14 +917,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P baca45c549e1c144257ee657258939640120e094 -R ce715121c7ed754dc718fb1bfe515a2f +P 3e984195f1f6d28734456dd726d226cedf207da2 +R 291ccee36a06fddbdbf66dee9d0c5dc8 U drh -Z 63d44dd1d9cda650862ed5c1ffde651b +Z 44243678e5ac002f859d95b6693267ff -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNgQdioxKgR168RlERAjrWAJ0csO53SVkhS4LgdWU2TMBY3h2/owCfSmfo -JE1tPjv0O+bB3lGc+tkEKvk= -=czhw +iD8DBQFNgWUmoxKgR168RlERArUBAJ9O6MIvLSm72rE66pJVBmPTs+4oyACdHack +G7nsgBYo5KQjyDA5i3CGse8= +=owlC -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 97ddfe5e79..86fa92432e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3e984195f1f6d28734456dd726d226cedf207da2 \ No newline at end of file +2353176811f752a16c1f2351a3d3431919b062a9 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 2b89055251..0cda03f451 100644 --- a/src/where.c +++ b/src/where.c @@ -2545,8 +2545,12 @@ int whereEqualScanEst( assert( p->aSample!=0 ); aff = p->pTable->aCol[p->aiColumn[0]].affinity; - rc = valueFromExpr(pParse, pExpr, aff, &pRhs); - if( rc ) goto whereEqualScanEst_cancel; + if( pExpr ){ + rc = valueFromExpr(pParse, pExpr, aff, &pRhs); + if( rc ) goto whereEqualScanEst_cancel; + }else{ + pRhs = sqlite3ValueNew(pParse->db); + } if( pRhs==0 ) return SQLITE_NOTFOUND; rc = whereRangeRegion(pParse, p, pRhs, 0, &iLower); if( rc ) goto whereEqualScanEst_cancel; @@ -2935,7 +2939,9 @@ static void bestBtreeIndex( ** VALUE and how common that value is according to the histogram. */ if( nRow>(double)1 && nEq==1 && pFirstTerm!=0 ){ - if( pFirstTerm->eOperator==WO_EQ ){ + if( pFirstTerm->eOperator & (WO_EQ|WO_ISNULL) ){ + testcase( pFirstTerm->eOperator==WO_EQ ); + testcase( pFirstTerm->pOperator==WO_ISNULL ); whereEqualScanEst(pParse, pProbe, pFirstTerm->pExpr->pRight, &nRow); }else if( pFirstTerm->eOperator==WO_IN && bInEst==0 ){ whereInScanEst(pParse, pProbe, pFirstTerm->pExpr->x.pList, &nRow); diff --git a/test/analyze5.test b/test/analyze5.test index e08893a180..224433b7df 100644 --- a/test/analyze5.test +++ b/test/analyze5.test @@ -164,6 +164,8 @@ foreach {testid where index rows} { 301 {y=1} t1y 50 302 {y=0.1} t1y 50 + 400 {x IS NULL} t1x 400 + } { # Verify that the expected index is used with the expected row count do_test analyze5-1.${testid}a { @@ -190,5 +192,48 @@ foreach {testid where index rows} { } {ok} } +# Increase the number of NULLs in column x +# +db eval { + UPDATE t1 SET x=NULL; + UPDATE t1 SET x=rowid + WHERE rowid IN (SELECT rowid FROM t1 ORDER BY random() LIMIT 5); + ANALYZE; +} + +# Verify that range queries generate the correct row count estimates +# +foreach {testid where index rows} { + 500 {x IS NULL AND u='charlie'} t1u 20 + 501 {x=1 AND u='charlie'} t1x 5 + 502 {x IS NULL} {} 100 + 503 {x=1} t1x 50 + 504 {x IS NOT NULL} t1x 25 + +} { + # Verify that the expected index is used with the expected row count + do_test analyze5-1.${testid}a { + set x [lindex [eqp "SELECT * FROM t1 WHERE $where"] 3] + set idx {} + regexp {INDEX (t1.) } $x all idx + regexp {~([0-9]+) rows} $x all nrow + list $idx $nrow + } [list $index $rows] + + # Verify that the same result is achieved regardless of whether or not + # the index is used + do_test analyze5-1.${testid}b { + set w2 [string map {y +y z +z} $where] + set a1 [db eval "SELECT rowid FROM t1 NOT INDEXED WHERE $w2\ + ORDER BY +rowid"] + set a2 [db eval "SELECT rowid FROM t1 WHERE $where ORDER BY +rowid"] + if {$a1==$a2} { + set res ok + } else { + set res "a1=\[$a1\] a2=\[$a2\]" + } + set res + } {ok} +} finish_test diff --git a/test/progress.test b/test/progress.test old mode 100755 new mode 100644 diff --git a/tool/mkopts.tcl b/tool/mkopts.tcl old mode 100755 new mode 100644