mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-18 10:21:03 +03:00
Improved handling of USING and NATURAL JOIN in 3-way and higher joins.
Ticket [3338b3fa19ac4ab] FossilOrigin-Name: 551ce407bd77149865423511bd52eba2f404161a
This commit is contained in:
16
manifest
16
manifest
@@ -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.
|
C Improved\shandling\sof\sUSING\sand\sNATURAL\sJOIN\sin\s3-way\sand\shigher\sjoins.\nTicket\s[3338b3fa19ac4ab]
|
||||||
D 2011-10-18T12:44:04.580
|
D 2011-10-18T18:10:40.151
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897
|
F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@@ -177,7 +177,7 @@ F src/pragma.c da8ef96b3eec351e81e0061c39810e548bcc96d7
|
|||||||
F src/prepare.c e64261559a3187698a3e7e6c8b001a4f4f98dab4
|
F src/prepare.c e64261559a3187698a3e7e6c8b001a4f4f98dab4
|
||||||
F src/printf.c 03104cbff6959ff45df69dc9060ba6212f60a869
|
F src/printf.c 03104cbff6959ff45df69dc9060ba6212f60a869
|
||||||
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
||||||
F src/resolve.c 36368f44569208fa074e61f4dd0b6c4fb60ca2b4
|
F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809
|
||||||
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
|
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
|
||||||
F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6
|
F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6
|
||||||
F src/shell.c f0ab793261ab045a0b8c47fa2707e8a894d2898f
|
F src/shell.c f0ab793261ab045a0b8c47fa2707e8a894d2898f
|
||||||
@@ -913,7 +913,7 @@ F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a
|
|||||||
F test/walthread.test a2ed5270eb695284d4ad27d252517bdc3317ee2a
|
F test/walthread.test a2ed5270eb695284d4ad27d252517bdc3317ee2a
|
||||||
F test/where.test de337a3fe0a459ec7c93db16a519657a90552330
|
F test/where.test de337a3fe0a459ec7c93db16a519657a90552330
|
||||||
F test/where2.test 43d4becaf5a5df854e6c21d624a1cb84c6904554
|
F test/where2.test 43d4becaf5a5df854e6c21d624a1cb84c6904554
|
||||||
F test/where3.test 8e1175c7ef710c70502858fc4fb08d784b3620b9
|
F test/where3.test 667e75642102c97a00bf9b23d3cb267db321d006
|
||||||
F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2
|
F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2
|
||||||
F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
|
F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
|
||||||
F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
|
F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
|
||||||
@@ -970,7 +970,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
|
|||||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||||
F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
|
F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
|
||||||
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
||||||
P 491ff5fb2504173d6905e38b8ea35737338aaa84
|
P 3126754c72351c724be29d75a194bfc3e7b67205
|
||||||
R 58f061e71ad84767d73477085e2bfcf6
|
R ed8534091276e292d87550ffda27999e
|
||||||
U dan
|
U drh
|
||||||
Z b0882f47410096d3d98223e9ef02aa47
|
Z a262b8d3562a7e10f8c3ec0f3139747f
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
3126754c72351c724be29d75a194bfc3e7b67205
|
551ce407bd77149865423511bd52eba2f404161a
|
||||||
@@ -98,6 +98,24 @@ static void resolveAlias(
|
|||||||
sqlite3DbFree(db, pDup);
|
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
|
** 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
|
** 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++){
|
for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
|
||||||
if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
|
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++;
|
cnt++;
|
||||||
pExpr->iTable = pItem->iCursor;
|
pExpr->iTable = pItem->iCursor;
|
||||||
pExpr->pTab = pTab;
|
pExpr->pTab = pTab;
|
||||||
@@ -197,26 +222,6 @@ static int lookupName(
|
|||||||
pSchema = pTab->pSchema;
|
pSchema = pTab->pSchema;
|
||||||
/* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
|
/* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
|
||||||
pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -342,4 +342,87 @@ do_execsql_test where3-5.3 {
|
|||||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
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
|
finish_test
|
||||||
|
|||||||
Reference in New Issue
Block a user