Fix a bug (ticket [fc7bd6358f59]) that caused incorrect query results in

three way queries that involved comparing INTEGER and TEXT columns for
equality.

FossilOrigin-Name: 7097241c1220ada318f8eda938c3e3430b94a606
This commit is contained in:
drh 2013-03-06 01:55:27 +00:00
parent a0272d8255
commit 459f63e7ed
4 changed files with 95 additions and 12 deletions

View File

@ -1,5 +1,5 @@
C Add\sthe\sSQLITE_READONLY_ROLLBACK\sextended\serror\scode.\nDo\snot\stry\sto\sset\sthe\spermissions\son\sjournal\sor\swal\sfiles\sexcept\sif\sthe\nfilesize\sis\sinitially\szero\s(indicating\sthat\sit\sis\sa\snew\sfile.)
D 2013-03-06T01:48:20.423
C Fix\sa\sbug\s(ticket\s[fc7bd6358f59])\sthat\scaused\sincorrect\squery\sresults\sin\nthree\sway\squeries\sthat\sinvolved\scomparing\sINTEGER\sand\sTEXT\scolumns\sfor\nequality.
D 2013-03-06T01:55:27.319
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 9a804abbd3cae82d196e4d33aba13239e32522a5
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -252,7 +252,7 @@ F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83
F src/wal.c f5c7b5027d0ed0e9bc9afeb4a3a8dfea762ec7d2
F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6
F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b
F src/where.c 43e05406f0e05960a62d4719ed77f551f8204d3f
F src/where.c 8b7690cae8700b385d8a53a39387cf8054d8cc47
F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
@ -809,6 +809,7 @@ F test/tkt-f7b4edec.test d998a08ff2b18b7f62edce8e3044317c45efe6c7
F test/tkt-f973c7ac31.test 1da0ed15ec2c7749fb5ce2828cd69d07153ad9f4
F test/tkt-fa7bf5ec.test 9102dfea58aa371d78969da735f9392c57e2e035
F test/tkt-fc62af4523.test 72825d3febdedcd5593a27989fc05accdbfc2bb4
F test/tkt-fc7bd6358f.test 634bb4af7d661e82d6b61b80c86727bad698e08f
F test/tkt1435.test f8c52c41de6e5ca02f1845f3a46e18e25cadac00
F test/tkt1443.test bacc311da5c96a227bf8c167e77a30c99f8e8368
F test/tkt1444.test a9d72f9e942708bd82dde6c707da61c489e213e9
@ -1036,7 +1037,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
P 717863fca6d58828bf9321bc8b169e385ad4263f 4f5f3aebe81c3cbe539db3e33ec38fa3de47e90b
R 4624808bc8666139dd43b7c21e0d98ea
P ce4ac66a4b623a3cee1a63089dd5ba8341244f1e
R d68087991aff1a0f42c82b57cc68e943
U drh
Z 5a1f66c8d1d16d93a8aa4820fbcfcadc
Z 8c08911ad7848ca72da641a08c68b6f0

View File

@ -1 +1 @@
ce4ac66a4b623a3cee1a63089dd5ba8341244f1e
7097241c1220ada318f8eda938c3e3430b94a606

View File

@ -643,9 +643,8 @@ static u16 operatorMask(int op){
** then try for the one with no dependencies on <expr> - in other words where
** <expr> is a constant expression of some kind. Only return entries of
** the form "X <op> Y" where Y is a column in another table if no terms of
** the form "X <op> <const-expr>" exist. Other than this priority, if there
** are two or more terms that match, then the choice of which term to return
** is arbitrary.
** the form "X <op> <const-expr>" exist. If no terms with a constant RHS
** exist, try to return a term that does not use WO_EQUIV.
*/
static WhereTerm *findTerm(
WhereClause *pWC, /* The WHERE clause to be searched */
@ -704,8 +703,12 @@ static WhereTerm *findTerm(
continue;
}
}
pResult = pTerm;
if( pTerm->prereqRight==0 ) goto findTerm_success;
if( pTerm->prereqRight==0 ){
pResult = pTerm;
goto findTerm_success;
}else if( pResult==0 ){
pResult = pTerm;
}
}
if( (pTerm->eOperator & WO_EQUIV)!=0
&& nEquiv<ArraySize(aEquiv)
@ -4231,6 +4234,7 @@ static Bitmask codeOneLoopStart(
addrNxt = pLevel->addrNxt;
sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt);
sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg);
sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1);
sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
VdbeComment((v, "pk"));
pLevel->op = OP_Noop;

78
test/tkt-fc7bd6358f.test Normal file
View File

@ -0,0 +1,78 @@
# 2013 March 05
#
# 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.
#
#***********************************************************************
# This file implements regression tests for SQLite library. Specifically,
# it tests that ticket [fc7bd6358f]:
#
# The following SQL yields an incorrect result (zero rows) in all
# versions of SQLite between 3.6.14 and 3.7.15.2:
#
# CREATE TABLE t(textid TEXT);
# INSERT INTO t VALUES('12');
# INSERT INTO t VALUES('34');
# CREATE TABLE i(intid INTEGER PRIMARY KEY);
# INSERT INTO i VALUES(12);
# INSERT INTO i VALUES(34);
#
# SELECT t1.textid AS a, i.intid AS b, t2.textid AS c
# FROM t t1, i, t t2
# WHERE t1.textid = i.intid
# AND t1.textid = t2.textid;
#
# The correct result should be two rows, one with 12|12|12 and the other
# with 34|34|34. With this bug, no rows are returned. Bisecting shows that
# this bug was introduced with check-in [dd4d67a67454] on 2009-04-23.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
do_test tkt-fc7bd6358f.100 {
db eval {
CREATE TABLE t(textid TEXT);
INSERT INTO t VALUES('12');
INSERT INTO t VALUES('34');
CREATE TABLE i(intid INTEGER PRIMARY KEY);
INSERT INTO i VALUES(12);
INSERT INTO i VALUES(34);
}
} {}
unset -nocomplain from
unset -nocomplain where
unset -nocomplain a
unset -nocomplain b
foreach {a from} {
1 {FROM t t1, i, t t2}
2 {FROM i, t t1, t t2}
3 {FROM t t1, t t2, i}
} {
foreach {b where} {
1 {WHERE t1.textid=i.intid AND t1.textid=t2.textid}
2 {WHERE i.intid=t1.textid AND t1.textid=t2.textid}
3 {WHERE t1.textid=i.intid AND i.intid=t2.textid}
4 {WHERE t1.textid=i.intid AND t2.textid=i.intid}
5 {WHERE i.intid=t1.textid AND i.intid=t2.textid}
6 {WHERE i.intid=t1.textid AND t2.textid=i.intid}
7 {WHERE t1.textid=t2.textid AND i.intid=t2.textid}
8 {WHERE t1.textid=t2.textid AND t2.textid=i.intid}
} {
do_test tkt-fc7bd6358f.110.$a.$b.1 {
db eval {PRAGMA automatic_index=ON}
db eval "SELECT t1.textid, i.intid, t2.textid $from $where"
} {12 12 12 34 34 34}
do_test tkt-fc7bd6358f.110.$a.$b.2 {
db eval {PRAGMA automatic_index=OFF}
db eval "SELECT t1.textid, i.intid, t2.textid $from $where"
} {12 12 12 34 34 34}
}
}
finish_test