Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix a problem with using stat4 samples of type text when estimating the rows visited by a range-query/skip-scan loop. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | stat4-skipscan |
Files: | files | file ages | folders |
SHA1: |
dfb09db6d412f3bc2a71bda393813783 |
User & Date: | dan 2014-06-28 15:26:10.708 |
Context
2014-06-28
| ||
16:06 | Add header comments on new routines. Rework the sqlite3Stat4Column() routine so that is (in theory) able to deal with corrupt samples. (check-in: ef5cdf949b user: drh tags: stat4-skipscan) | |
15:26 | Fix a problem with using stat4 samples of type text when estimating the rows visited by a range-query/skip-scan loop. (check-in: dfb09db6d4 user: dan tags: stat4-skipscan) | |
14:28 | Change the VDBE to export the sqlite3MemCompare() routine and thus free where.c from the dependency on vdbeInt.h. (check-in: d186d1ac3c user: drh tags: stat4-skipscan) | |
Changes
Changes to src/vdbemem.c.
︙ | ︙ | |||
1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 | iField = nHdr; for(i=0; i<iCol; i++){ iHdr += getVarint32(&a[iHdr], t); iField += sqlite3VdbeSerialTypeLen(t); } iHdr = getVarint32(&a[iHdr], t); sqlite3VdbeSerialGet(&a[iField], t, pMem); } *ppVal = pMem; return rc; } | > | 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 | iField = nHdr; for(i=0; i<iCol; i++){ iHdr += getVarint32(&a[iHdr], t); iField += sqlite3VdbeSerialTypeLen(t); } iHdr = getVarint32(&a[iHdr], t); pMem->enc = ENC(db); sqlite3VdbeSerialGet(&a[iField], t, pMem); } *ppVal = pMem; return rc; } |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
2087 2088 2089 2090 2091 2092 2093 | ** the number of rows visited. Otherwise, estimate the number of rows ** using the method described in the header comment for this function. */ if( nDiff!=1 || pUpper==0 || pLower==0 ){ int nAdjust = (sqlite3LogEst(p->nSample) - sqlite3LogEst(nDiff)); pLoop->nOut -= nAdjust; *pbDone = 1; WHERETRACE(0x10, ("range skip-scan regions: %u..%u adjust=%d est=%d\n", | | | 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 | ** the number of rows visited. Otherwise, estimate the number of rows ** using the method described in the header comment for this function. */ if( nDiff!=1 || pUpper==0 || pLower==0 ){ int nAdjust = (sqlite3LogEst(p->nSample) - sqlite3LogEst(nDiff)); pLoop->nOut -= nAdjust; *pbDone = 1; WHERETRACE(0x10, ("range skip-scan regions: %u..%u adjust=%d est=%d\n", nLower, nUpper, nAdjust*-1, pLoop->nOut)); } }else{ assert( *pbDone==0 ); } sqlite3ValueFree(p1); |
︙ | ︙ |
Changes to test/skipscan5.test.
︙ | ︙ | |||
87 88 89 90 91 92 93 94 95 | } do_eqp_test 1.11 { SELECT * FROM t1 WHERE b < 15; } { 0 0 0 {SCAN TABLE t1} } finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | } do_eqp_test 1.11 { SELECT * FROM t1 WHERE b < 15; } { 0 0 0 {SCAN TABLE t1} } #------------------------------------------------------------------------- # Test that range-query/skip-scan estimation works with text values. # And on UTF-16 databases when there is no UTF-16 collation sequence # available. proc test_collate {enc lhs rhs} { string compare $lhs $rhs } foreach {tn dbenc coll} { 1 UTF-8 { add_test_collate db 0 0 1 } 2 UTF-16 { add_test_collate db 1 0 0 } 3 UTF-8 { add_test_collate db 0 1 0 } } { reset_db eval $coll do_execsql_test 2.$tn.1 " PRAGMA encoding = '$dbenc' " do_execsql_test 2.$tn.2 { CREATE TABLE t2(a TEXT, b TEXT, c TEXT COLLATE test_collate, d TEXT); CREATE INDEX i2 ON t2(a, b, c); } set vocab(d) { :) } set vocab(c) { a b c d e f g h i j k l m n o p q r s t } set vocab(b) { one two three } set vocab(a) { sql } do_test 2.$tn.3 { for {set i 0} {$i < 100} {incr i} { foreach var {a b c d} { set $var [lindex $vocab($var) [expr $i % [llength $vocab($var)]]] } execsql { INSERT INTO t2 VALUES($a, $b, $c, $d) } } execsql ANALYZE } {} foreach {tn2 q res} { 1 { c BETWEEN 'd' AND 'e' } {/*ANY(a) AND ANY(b) AND c>? AND c<?*/} 2 { c BETWEEN 'b' AND 'r' } {/*SCAN TABLE t2*/} 3 { c > 'q' } {/*ANY(a) AND ANY(b) AND c>?*/} 4 { c > 'e' } {/*SCAN TABLE t2*/} 5 { c < 'q' } {/*SCAN TABLE t2*/} 4 { c < 'e' } {/*ANY(a) AND ANY(b) AND c<?*/} } { set sql "EXPLAIN QUERY PLAN SELECT * FROM t2 WHERE $q" do_execsql_test 2.$tn.$tn2 $sql $res } } finish_test |