When creating an automatic-index on a sub-query, add a unique integer to the end of each index key to ensure the entire key is unique. Fix for [8a2adec1].

FossilOrigin-Name: bfea226d0d226a046a8bfb7a7a6288850d69bd26
This commit is contained in:
dan 2015-10-24 20:31:22 +00:00
parent 7ef855f156
commit fb785b2c2b
4 changed files with 58 additions and 18 deletions

View File

@ -1,5 +1,5 @@
C Alternate\scompiler\swarning\sfix\sfor\ssqlite3StatusHighwater.
D 2015-10-22T18:06:40.381
C When\screating\san\sautomatic-index\son\sa\ssub-query,\sadd\sa\sunique\sinteger\sto\sthe\send\sof\seach\sindex\skey\sto\sensure\sthe\sentire\skey\sis\sunique.\sFix\sfor\s[8a2adec1].
D 2015-10-24T20:31:22.639
F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4
@ -415,7 +415,7 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
F src/wal.c 18b0ed49830cf04fe2d68224b41838a73ac6cd24
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba
F src/where.c 4c4646675e794ac71e701289edefd7cd81bac844
F src/where.c e3724b7b31d1e13869308ed4125305364f7d823a
F src/whereInt.h 7892bb54cf9ca0ae5c7e6094491b94c9286dc647
F src/wherecode.c b924b78acd9e623fb69bfa2cb65cd7d542166dd3
F src/whereexpr.c e63244ca06c503e5f3c5b7f3c9aea0db826089ed
@ -465,7 +465,7 @@ F test/autoindex1.test 14b63a9f1e405fe6d5bfc8c8d00249c2ebaf13ea
F test/autoindex2.test af7e595c6864cc6ef5fc38d5db579a3e34940cb8
F test/autoindex3.test a3be0d1a53a7d2edff208a5e442312957047e972
F test/autoindex4.test 49d3cd791a9baa16fb461d7ea3de80d019a819cf
F test/autoindex5.test 6f487290ce2a667c24517191651bfb8c7d86b6dc
F test/autoindex5.test 96f084a5e6024ea07cace5888df3223f3ea86990
F test/autovacuum.test 941892505d2c0f410a0cb5970dfa1c7c4e5f6e74
F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4
F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85
@ -1391,7 +1391,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P aa4e01ea1af327d1f8398ebea1c5bacc46698c3d
R a22db3919509c137f252ea9c4c395816
U mistachkin
Z cd96591ebe18ee957344d1fc4f75aaa9
P 4315d20200d578c9252dcb26e60739063a8eff1d
R dc911a631bba00e9a0808ae6a2dfaef0
U dan
Z 6491941420be3020676420319ae4eec9

View File

@ -1 +1 @@
4315d20200d578c9252dcb26e60739063a8eff1d
bfea226d0d226a046a8bfb7a7a6288850d69bd26

View File

@ -485,14 +485,20 @@ static LogEst estLog(LogEst N){
** Convert OP_Column opcodes to OP_Copy in previously generated code.
**
** This routine runs over generated VDBE code and translates OP_Column
** opcodes into OP_Copy, and OP_Rowid into OP_Null, when the table is being
** accessed via co-routine instead of via table lookup.
** opcodes into OP_Copy when the table is being accessed via co-routine
** instead of via table lookup.
**
** If the bIncrRowid parameter is 0, then any OP_Rowid instructions on
** cursor iTabCur are transformed into OP_Null. Or, if bIncrRowid is non-zero,
** then each OP_Rowid is transformed into an instruction to increment the
** value stored in its output register.
*/
static void translateColumnToCopy(
Vdbe *v, /* The VDBE containing code to translate */
int iStart, /* Translate from this opcode to the end */
int iTabCur, /* OP_Column/OP_Rowid references to this table */
int iRegister /* The first column is in this register */
int iRegister, /* The first column is in this register */
int bIncrRowid /* If non-zero, transform OP_rowid to OP_AddImm(1) */
){
VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart);
int iEnd = sqlite3VdbeCurrentAddr(v);
@ -504,11 +510,18 @@ static void translateColumnToCopy(
pOp->p2 = pOp->p3;
pOp->p3 = 0;
}else if( pOp->opcode==OP_Rowid ){
if( bIncrRowid ){
/* Increment the value stored in the P2 operand of the OP_Rowid. */
pOp->opcode = OP_AddImm;
pOp->p1 = pOp->p2;
pOp->p2 = 1;
}else{
pOp->opcode = OP_Null;
pOp->p1 = 0;
pOp->p3 = 0;
}
}
}
}
/*
@ -614,6 +627,8 @@ static void constructAutomaticIndex(
Expr *pPartial = 0; /* Partial Index Expression */
int iContinue = 0; /* Jump here to skip excluded rows */
struct SrcList_item *pTabItem; /* FROM clause term being indexed */
int addrCounter; /* Address where integer counter is initialized */
int regBase; /* Array of registers where record is assembled */
/* Generate code to skip over the creation and initialization of the
** transient index on 2nd and subsequent iterations of the loop. */
@ -742,6 +757,7 @@ static void constructAutomaticIndex(
pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom];
if( pTabItem->fg.viaCoroutine ){
int regYield = pTabItem->regReturn;
addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub);
addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield);
VdbeCoverage(v);
@ -755,12 +771,15 @@ static void constructAutomaticIndex(
pLoop->wsFlags |= WHERE_PARTIALIDX;
}
regRecord = sqlite3GetTempReg(pParse);
sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0);
regBase = sqlite3GenerateIndexKey(
pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0
);
sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
if( pTabItem->fg.viaCoroutine ){
translateColumnToCopy(v, addrTop, pLevel->iTabCur, pTabItem->regResult);
sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
translateColumnToCopy(v, addrTop, pLevel->iTabCur, pTabItem->regResult, 1);
sqlite3VdbeGoto(v, addrTop);
pTabItem->fg.viaCoroutine = 0;
}else{
@ -4509,7 +4528,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
*/
if( pTabItem->fg.viaCoroutine && !db->mallocFailed ){
translateColumnToCopy(v, pLevel->addrBody, pLevel->iTabCur,
pTabItem->regResult);
pTabItem->regResult, 0);
continue;
}

View File

@ -17,6 +17,7 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix autoindex5
# Schema is from the Debian security database
#
@ -104,5 +105,25 @@ do_execsql_test autoindex5-1.1 {
ORDER BY sp.name, st.bug_name, sp.release, sp.subrelease;
} {/SEARCH SUBQUERY 2 USING AUTOMATIC COVERING INDEX .bug_name=/}
#-------------------------------------------------------------------------
# Test that ticket [8a2adec1] has been fixed.
#
do_execsql_test 2.1 {
CREATE TABLE one(o);
INSERT INTO one DEFAULT VALUES;
CREATE TABLE t1(x, z);
INSERT INTO t1 VALUES('aaa', 4.0);
INSERT INTO t1 VALUES('aaa', 4.0);
CREATE VIEW vvv AS
SELECT * FROM t1
UNION ALL
SELECT 0, 0 WHERE 0;
SELECT (
SELECT sum(z) FROM vvv WHERE x='aaa'
) FROM one;
} {8.0}
finish_test