Ensure that the sqlite3_index_info.colUsed mask always includes the PK fields of WITHOUT ROWID virtual tables.

FossilOrigin-Name: ff4ac279b02190cc2107b0b110806dd7abcea47a6589d827b5ee39d4b80fb719
This commit is contained in:
drh 2024-08-03 21:45:46 +00:00
commit 133f930e61
4 changed files with 113 additions and 9 deletions

View File

@ -1,5 +1,5 @@
C Fix\sa\stypo\sin\s[c327c0c0]\spreventing\sthe\sshell\stool\sfrom\srunning\s".dump"\sscripts\sthat\sfeature\svirtual\stables.
D 2024-08-03T18:58:25.762
C Ensure\sthat\sthe\ssqlite3_index_info.colUsed\smask\salways\sincludes\sthe\sPK\sfields\sof\sWITHOUT\sROWID\svirtual\stables.
D 2024-08-03T21:45:46.594
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@ -845,7 +845,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c 887fc4ca3f020ebb2e376f222069570834ac63bf50111ef0cbf3ae417048ed89
F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
F src/walker.c 7c7ea0115345851c3da4e04e2e239a29983b61fb5b038b94eede6aba462640e2
F src/where.c d87a4160e26a7a96a2f7ca283b147b1b283b54ba545c46acb14cfcc6ec37ae9e
F src/where.c 31d100c11a21e479e0dda679585f0ab2675e746a169349519a9a38d3ef10dec7
F src/whereInt.h 002adc3aa2cc10733b9b27958fdbe893987cd989fab25a9853941c1f9b9b0a65
F src/wherecode.c c9cac0b0b8e809c5e7e79d7796918907fb685ad99be2aaa9737f9787aa47349c
F src/whereexpr.c 7d0d34b42b9edfd8e8ca66beb3a6ef63fe211c001af54caf2ccbcd989b783290
@ -946,6 +946,7 @@ F test/bestindex9.test 1a4b93db117fd8abe74ae9be982f86aa72f01e60cd4ac541e6ede3967
F test/bestindexA.test e1b5def6b190797cacf008e6815ffb78fb30261999030d60a728d572eef44c7f
F test/bestindexB.test 328b97b69cd1a20928d5997f9ecb04d2e00f1d18e19ab27f9e9adb44d7bc51ce
F test/bestindexC.test 2df6ada16d8f00d9bb6a9664d9c323560aeed0e0ebc7a32b99d85d70037fd250
F test/bestindexD.test 6a8f6f84990bcf17dfa59652a1f935beddb7afd96f8302830fbc86b0a13df3c3
F test/between.test b9a65fb065391980119e8a781a7409d3fcf059d89968279c750e190a9a1d5263
F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59
F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc
@ -2202,8 +2203,9 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 94015cda4ceb4292ceceadb951fe5d9cb3e4e20403719b7254ad094a5b749ab3
R 29b4b37a6a2fc091f26014a6acc94dba
U dan
Z ee0e09932c59f9ad04251e6acfe5d403
P 10e97abb878debb67410902ea1af4df75a9ced1e38fec710b1796c5143aff48e c327c0c02cfefdba373cfb15933a9cdfddb578b6582f2ce7c08929203743ffe9
R 1d93f534d15ca5d5211a14297b5dec08
T +closed c327c0c02cfefdba373cfb15933a9cdfddb578b6582f2ce7c08929203743ffe9
U drh
Z cedb7caeaa81af02824696e786ffbd42
# Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
10e97abb878debb67410902ea1af4df75a9ced1e38fec710b1796c5143aff48e
ff4ac279b02190cc2107b0b110806dd7abcea47a6589d827b5ee39d4b80fb719

View File

@ -1501,6 +1501,16 @@ static sqlite3_index_info *allocateIndexInfo(
pIdxInfo->aConstraint = pIdxCons;
pIdxInfo->aOrderBy = pIdxOrderBy;
pIdxInfo->aConstraintUsage = pUsage;
pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed;
if( HasRowid(pTab)==0 ){
/* Ensure that all bits associated with PK columns are set. This is to
** ensure they are available for cases like RIGHT joins or OR loops. */
Index *pPk = sqlite3PrimaryKeyIndex((Table*)pTab);
for(i=0; i<pPk->nKeyCol; i++){
int iCol = pPk->aiColumn[i];
pIdxInfo->colUsed |= (iCol>=BMS ? ALLBITS : MASKBIT(iCol));
}
}
pHidden->pWC = pWC;
pHidden->pParse = pParse;
pHidden->eDistinct = eDistinct;
@ -4216,7 +4226,6 @@ static int whereLoopAddVirtualOne(
pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
pIdxInfo->estimatedRows = 25;
pIdxInfo->idxFlags = 0;
pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed;
pHidden->mHandleIn = 0;
/* Invoke the virtual table xBestIndex() method */

93
test/bestindexD.test Normal file
View File

@ -0,0 +1,93 @@
# 2024-08-03
#
# 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.
#
#***********************************************************************
#
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix bestindexD
ifcapable !vtab {
finish_test
return
}
register_tcl_module db
proc vtab_command {method args} {
switch -- $method {
xConnect {
return "CREATE TABLE t1(a PRIMARY KEY, b, c) WITHOUT ROWID"
}
xBestIndex {
set hdl [lindex $args 0]
set ::colUsed [$hdl mask]
set cost 1000000
set used ""
set cons 0
foreach c [$hdl constraints] {
set cost [expr $cost/10]
append used " use $cons"
incr cons
}
return "cost $cost rows $cost $used"
}
}
return {}
}
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE x1 USING tcl(vtab_command);
CREATE TABLE t2(a, b);
} {}
# This proc assumes that there is only one use of a virtual table - x1 -
# in SQL statement $sql. It tests that the colUsed value passed to the
# xBestIndex method matches the actual columns used, which is ascertained
# by searching the compiled VM code for VColumn instructions.
#
proc do_colsused_test {tn sql} {
set ::colUsed ""
execsql $sql
set got $::colUsed
set expect 0
db eval "EXPLAIN $sql" x {
if {$x(opcode)=="VColumn"} {
set expect [expr $expect | (1<<$x(p2))]
}
}
uplevel [list do_test $tn.($expect/$got) [list expr ($expect & $got)] $expect]
}
do_colsused_test 1.1 { SELECT a FROM x1 }
do_colsused_test 1.2 { SELECT a,c FROM x1 }
do_colsused_test 1.3 { SELECT b FROM x1 }
do_colsused_test 1.4 { SELECT b FROM x1 WHERE c=? }
do_colsused_test 1.5 {
select 1 from t2 full join x1;
}
do_colsused_test 1.6 {
select 1 from x1 WHERE (b=? AND c=?) OR (b=? AND c=?)
}
finish_test