Unverified 提交 7e5ab118 authored 作者: Noel Grandin's avatar Noel Grandin 提交者: GitHub

Merge pull request #906 from katzyn/join

Fix obscure error on non-standard SELECT * FROM A LEFT JOIN B NATURAL JOIN C
...@@ -1733,7 +1733,7 @@ public class Parser { ...@@ -1733,7 +1733,7 @@ public class Parser {
on = readExpression(); on = readExpression();
} }
top = getNested(top); top = getNested(top);
join.addJoin(top, true, false, on); join.addJoin(top, true, on);
top = join; top = join;
} else if (readIf("LEFT")) { } else if (readIf("LEFT")) {
readIf("OUTER"); readIf("OUTER");
...@@ -1744,7 +1744,7 @@ public class Parser { ...@@ -1744,7 +1744,7 @@ public class Parser {
if (readIf("ON")) { if (readIf("ON")) {
on = readExpression(); on = readExpression();
} }
top.addJoin(join, true, false, on); top.addJoin(join, true, on);
} else if (readIf("FULL")) { } else if (readIf("FULL")) {
throw getSyntaxError(); throw getSyntaxError();
} else if (readIf("INNER")) { } else if (readIf("INNER")) {
...@@ -1755,7 +1755,7 @@ public class Parser { ...@@ -1755,7 +1755,7 @@ public class Parser {
if (readIf("ON")) { if (readIf("ON")) {
on = readExpression(); on = readExpression();
} }
top.addJoin(join, false, false, on); top.addJoin(join, false, on);
} else if (readIf("JOIN")) { } else if (readIf("JOIN")) {
join = readTableFilter(); join = readTableFilter();
top = readJoin(top, false); top = readJoin(top, false);
...@@ -1763,11 +1763,11 @@ public class Parser { ...@@ -1763,11 +1763,11 @@ public class Parser {
if (readIf("ON")) { if (readIf("ON")) {
on = readExpression(); on = readExpression();
} }
top.addJoin(join, false, false, on); top.addJoin(join, false, on);
} else if (readIf("CROSS")) { } else if (readIf("CROSS")) {
read("JOIN"); read("JOIN");
join = readTableFilter(); join = readTableFilter();
top.addJoin(join, false, false, null); top.addJoin(join, false, null);
} else if (readIf("NATURAL")) { } else if (readIf("NATURAL")) {
read("JOIN"); read("JOIN");
join = readTableFilter(); join = readTableFilter();
...@@ -1799,7 +1799,7 @@ public class Parser { ...@@ -1799,7 +1799,7 @@ public class Parser {
} }
} }
} }
top.addJoin(join, false, nested, on); top.addJoin(join, false, on);
} else { } else {
break; break;
} }
...@@ -1817,7 +1817,7 @@ public class Parser { ...@@ -1817,7 +1817,7 @@ public class Parser {
TableFilter top = new TableFilter(session, getDualTable(true), TableFilter top = new TableFilter(session, getDualTable(true),
joinTable, rightsChecked, currentSelect, n.getOrderInFrom(), joinTable, rightsChecked, currentSelect, n.getOrderInFrom(),
null); null);
top.addJoin(n, false, true, null); top.setNestedJoin(n);
return top; return top;
} }
...@@ -2490,7 +2490,7 @@ public class Parser { ...@@ -2490,7 +2490,7 @@ public class Parser {
int idx = filters.indexOf(rightFilter); int idx = filters.indexOf(rightFilter);
if (idx >= 0) { if (idx >= 0) {
filters.remove(idx); filters.remove(idx);
leftFilter.addJoin(rightFilter, true, false, r); leftFilter.addJoin(rightFilter, true, r);
} else { } else {
rightFilter.mapAndAddFilter(r); rightFilter.mapAndAddFilter(r);
} }
......
...@@ -247,7 +247,7 @@ class Optimizer { ...@@ -247,7 +247,7 @@ class Optimizer {
TableFilter[] f2 = bestPlan.getFilters(); TableFilter[] f2 = bestPlan.getFilters();
topFilter = f2[0]; topFilter = f2[0];
for (int i = 0; i < f2.length - 1; i++) { for (int i = 0; i < f2.length - 1; i++) {
f2[i].addJoin(f2[i + 1], false, false, null); f2[i].addJoin(f2[i + 1], false, null);
} }
if (parse) { if (parse) {
return; return;
......
...@@ -637,44 +637,38 @@ public class TableFilter implements ColumnResolver { ...@@ -637,44 +637,38 @@ public class TableFilter implements ColumnResolver {
* *
* @param filter the joined table filter * @param filter the joined table filter
* @param outer if this is an outer join * @param outer if this is an outer join
* @param nested if this is a nested join
* @param on the join condition * @param on the join condition
*/ */
public void addJoin(TableFilter filter, boolean outer, boolean nested, Expression on) { public void addJoin(TableFilter filter, boolean outer, Expression on) {
if (on != null) { if (on != null) {
on.mapColumns(this, 0); on.mapColumns(this, 0);
TableFilterVisitor visitor = new MapColumnsVisitor(on); TableFilterVisitor visitor = new MapColumnsVisitor(on);
visit(visitor); visit(visitor);
filter.visit(visitor); filter.visit(visitor);
} }
if (nested) { if (join == null) {
if (nestedJoin != null) { join = filter;
throw DbException.throwInternalError();
}
nestedJoin = filter;
filter.joinOuter = outer; filter.joinOuter = outer;
if (outer) { if (outer) {
visit(new JOIVisitor()); filter.visit(new JOIVisitor());
} }
if (on != null) { if (on != null) {
filter.mapAndAddFilter(on); filter.mapAndAddFilter(on);
} }
} else { } else {
if (join == null) { join.addJoin(filter, outer, on);
join = filter;
filter.joinOuter = outer;
if (outer) {
filter.visit(new JOIVisitor());
}
if (on != null) {
filter.mapAndAddFilter(on);
}
} else {
join.addJoin(filter, outer, false, on);
}
} }
} }
/**
* Set a nested joined table.
*
* @param filter the joined table filter
*/
public void setNestedJoin(TableFilter filter) {
nestedJoin = filter;
}
/** /**
* Map the columns and add the join condition. * Map the columns and add the join condition.
* *
......
...@@ -668,3 +668,82 @@ DROP TABLE PARENT; ...@@ -668,3 +668,82 @@ DROP TABLE PARENT;
DROP TABLE CHILD; DROP TABLE CHILD;
> ok > ok
CREATE TABLE A(A1 INT, A2 INT);
> ok
INSERT INTO A VALUES (1, 2);
> update count: 1
CREATE TABLE B(B1 INT, B2 INT);
> ok
INSERT INTO B VALUES (1, 2);
> update count: 1
CREATE TABLE C(B1 INT, C1 INT);
> ok
INSERT INTO C VALUES (1, 2);
> update count: 1
SELECT * FROM A LEFT JOIN B ON TRUE;
> A1 A2 B1 B2
> -- -- -- --
> 1 2 1 2
> rows: 1
SELECT A.A1, A.A2, B.B1, B.B2 FROM A RIGHT JOIN B ON TRUE;
> A1 A2 B1 B2
> -- -- -- --
> 1 2 1 2
> rows: 1
-- this syntax without ON or USING in not standard
SELECT * FROM A LEFT JOIN B;
> A1 A2 B1 B2
> -- -- -- --
> 1 2 1 2
> rows: 1
-- this syntax without ON or USING in not standard
SELECT A.A1, A.A2, B.B1, B.B2 FROM A RIGHT JOIN B;
> A1 A2 B1 B2
> -- -- -- --
> 1 2 1 2
> rows: 1
SELECT * FROM A LEFT JOIN B ON TRUE NATURAL JOIN C;
> A1 A2 B1 B2 C1
> -- -- -- -- --
> 1 2 1 2 2
> rows: 1
SELECT A.A1, A.A2, B.B1, B.B2, C.C1 FROM A RIGHT JOIN B ON TRUE NATURAL JOIN C;
> A1 A2 B1 B2 C1
> -- -- -- -- --
> 1 2 1 2 2
> rows: 1
-- this syntax without ON or USING in not standard
SELECT * FROM A LEFT JOIN B NATURAL JOIN C;
> A1 A2 B1 B2 C1
> -- -- -- -- --
> 1 2 1 2 2
> rows: 1
-- this syntax without ON or USING in not standard
SELECT A.A1, A.A2, B.B1, B.B2, C.C1 FROM A RIGHT JOIN B NATURAL JOIN C;
> A1 A2 B1 B2 C1
> -- -- -- -- --
> 1 2 1 2 2
> rows: 1
DROP TABLE A;
> ok
DROP TABLE B;
> ok
DROP TABLE C;
> ok
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论