Improved handling of USING and NATURAL JOIN in 3-way and higher joins.

Ticket [3338b3fa19ac4ab]

FossilOrigin-Name: 551ce407bd77149865423511bd52eba2f404161a
This commit is contained in:
drh 2011-10-18 18:10:40 +00:00
parent 42495cd46f
commit e802c5da01
4 changed files with 118 additions and 30 deletions

View File

@ -1,5 +1,5 @@
C Fix\sa\sfloating-point\sexception\sthat\scan\soccur\swhen\san\sFTS4\squery\scontains\sa\slarge\snumber\sof\stokens\sconnected\sby\sAND\sor\sNEAR\soperators.
D 2011-10-18T12:44:04.580
C Improved\shandling\sof\sUSING\sand\sNATURAL\sJOIN\sin\s3-way\sand\shigher\sjoins.\nTicket\s[3338b3fa19ac4ab]
D 2011-10-18T18:10:40.151
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -177,7 +177,7 @@ F src/pragma.c da8ef96b3eec351e81e0061c39810e548bcc96d7
F src/prepare.c e64261559a3187698a3e7e6c8b001a4f4f98dab4
F src/printf.c 03104cbff6959ff45df69dc9060ba6212f60a869
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
F src/resolve.c 36368f44569208fa074e61f4dd0b6c4fb60ca2b4
F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6
F src/shell.c f0ab793261ab045a0b8c47fa2707e8a894d2898f
@ -913,7 +913,7 @@ F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a
F test/walthread.test a2ed5270eb695284d4ad27d252517bdc3317ee2a
F test/where.test de337a3fe0a459ec7c93db16a519657a90552330
F test/where2.test 43d4becaf5a5df854e6c21d624a1cb84c6904554
F test/where3.test 8e1175c7ef710c70502858fc4fb08d784b3620b9
F test/where3.test 667e75642102c97a00bf9b23d3cb267db321d006
F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2
F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
@ -970,7 +970,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
P 491ff5fb2504173d6905e38b8ea35737338aaa84
R 58f061e71ad84767d73477085e2bfcf6
U dan
Z b0882f47410096d3d98223e9ef02aa47
P 3126754c72351c724be29d75a194bfc3e7b67205
R ed8534091276e292d87550ffda27999e
U drh
Z a262b8d3562a7e10f8c3ec0f3139747f

View File

@ -1 +1 @@
3126754c72351c724be29d75a194bfc3e7b67205
551ce407bd77149865423511bd52eba2f404161a

View File

@ -98,6 +98,24 @@ static void resolveAlias(
sqlite3DbFree(db, pDup);
}
/*
** Return TRUE if the name zCol occurs anywhere in the USING clause.
**
** Return FALSE if the USING clause is NULL or if it does not contain
** zCol.
*/
static int nameInUsingClause(IdList *pUsing, const char *zCol){
if( pUsing ){
int k;
for(k=0; k<pUsing->nId; k++){
if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ) return 1;
}
}
return 0;
}
/*
** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
** that name in the set of source tables in pSrcList and make the pExpr
@ -189,7 +207,14 @@ static int lookupName(
}
for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
IdList *pUsing;
/* If there has been exactly one prior match and this match
** is for the right-hand table of a NATURAL JOIN or is in a
** USING clause, then skip this match.
*/
if( cnt==1 ){
if( pItem->jointype & JT_NATURAL ) continue;
if( nameInUsingClause(pItem->pUsing, zCol) ) continue;
}
cnt++;
pExpr->iTable = pItem->iCursor;
pExpr->pTab = pTab;
@ -197,26 +222,6 @@ static int lookupName(
pSchema = pTab->pSchema;
/* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j;
if( i<pSrcList->nSrc-1 ){
if( pItem[1].jointype & JT_NATURAL ){
/* If this match occurred in the left table of a natural join,
** then skip the right table to avoid a duplicate match */
pItem++;
i++;
}else if( (pUsing = pItem[1].pUsing)!=0 ){
/* If this match occurs on a column that is in the USING clause
** of a join, skip the search of the right table of the join
** to avoid a duplicate match there. */
int k;
for(k=0; k<pUsing->nId; k++){
if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ){
pItem++;
i++;
break;
}
}
}
}
break;
}
}

View File

@ -342,4 +342,87 @@ do_execsql_test where3-5.3 {
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
}
# Name resolution with NATURAL JOIN and USING
#
do_test where3-6.setup {
db eval {
CREATE TABLE t6w(a, w);
INSERT INTO t6w VALUES(1, 'w-one');
INSERT INTO t6w VALUES(2, 'w-two');
INSERT INTO t6w VALUES(9, 'w-nine');
CREATE TABLE t6x(a, x);
INSERT INTO t6x VALUES(1, 'x-one');
INSERT INTO t6x VALUES(3, 'x-three');
INSERT INTO t6x VALUES(9, 'x-nine');
CREATE TABLE t6y(a, y);
INSERT INTO t6y VALUES(1, 'y-one');
INSERT INTO t6y VALUES(4, 'y-four');
INSERT INTO t6y VALUES(9, 'y-nine');
CREATE TABLE t6z(a, z);
INSERT INTO t6z VALUES(1, 'z-one');
INSERT INTO t6z VALUES(5, 'z-five');
INSERT INTO t6z VALUES(9, 'z-nine');
}
} {}
set cnt 0
foreach predicate {
{}
{ORDER BY a}
{ORDER BY t6w.a}
{WHERE a>0}
{WHERE t6y.a>0}
{WHERE a>0 ORDER BY a}
} {
incr cnt
do_test where3-6.$cnt.1 {
set sql "SELECT * FROM t6w NATURAL JOIN t6x NATURAL JOIN t6y"
append sql " NATURAL JOIN t6z "
append sql $::predicate
db eval $sql
} {1 w-one x-one y-one z-one 9 w-nine x-nine y-nine z-nine}
do_test where3-6.$cnt.2 {
set sql "SELECT * FROM t6w JOIN t6x USING(a) JOIN t6y USING(a)"
append sql " JOIN t6z USING(a) "
append sql $::predicate
db eval $sql
} {1 w-one x-one y-one z-one 9 w-nine x-nine y-nine z-nine}
do_test where3-6.$cnt.3 {
set sql "SELECT * FROM t6w NATURAL JOIN t6x JOIN t6y USING(a)"
append sql " JOIN t6z USING(a) "
append sql $::predicate
db eval $sql
} {1 w-one x-one y-one z-one 9 w-nine x-nine y-nine z-nine}
do_test where3-6.$cnt.4 {
set sql "SELECT * FROM t6w JOIN t6x USING(a) NATURAL JOIN t6y"
append sql " JOIN t6z USING(a) "
append sql $::predicate
db eval $sql
} {1 w-one x-one y-one z-one 9 w-nine x-nine y-nine z-nine}
do_test where3-6.$cnt.5 {
set sql "SELECT * FROM t6w JOIN t6x USING(a) JOIN t6y USING(a)"
append sql " NATURAL JOIN t6z "
append sql $::predicate
db eval $sql
} {1 w-one x-one y-one z-one 9 w-nine x-nine y-nine z-nine}
do_test where3-6.$cnt.6 {
set sql "SELECT * FROM t6w JOIN t6x USING(a) NATURAL JOIN t6y"
append sql " NATURAL JOIN t6z "
append sql $::predicate
db eval $sql
} {1 w-one x-one y-one z-one 9 w-nine x-nine y-nine z-nine}
do_test where3-6.$cnt.7 {
set sql "SELECT * FROM t6w NATURAL JOIN t6x JOIN t6y USING(a)"
append sql " NATURAL JOIN t6z "
append sql $::predicate
db eval $sql
} {1 w-one x-one y-one z-one 9 w-nine x-nine y-nine z-nine}
do_test where3-6.$cnt.8 {
set sql "SELECT * FROM t6w NATURAL JOIN t6x NATURAL JOIN t6y"
append sql " JOIN t6z USING(a) "
append sql $::predicate
db eval $sql
} {1 w-one x-one y-one z-one 9 w-nine x-nine y-nine z-nine}
}
finish_test