提交 f2c91521 authored 作者: Thomas Mueller's avatar Thomas Mueller

Nested outer joins without brackets were not working as expected.

上级 f96bcd3a
...@@ -610,7 +610,6 @@ public class Parser { ...@@ -610,7 +610,6 @@ public class Parser {
return schema; return schema;
} }
private Schema getSchema() { private Schema getSchema() {
return getSchema(schemaName); return getSchema(schemaName);
} }
...@@ -980,14 +979,12 @@ public class Parser { ...@@ -980,14 +979,12 @@ public class Parser {
} else { } else {
TableFilter top; TableFilter top;
if (database.getSettings().nestedJoins) { if (database.getSettings().nestedJoins) {
String joinTable = Constants.PREFIX_JOIN + parseIndex; top = readTableFilter(false);
top = new TableFilter(session, getDualTable(true), joinTable, rightsChecked, currentSelect); top = readJoin(top, currentSelect, false, false);
TableFilter n = readTableFilter(false); top = getNested(top);
n = readJoin(n, currentSelect, false);
top.addJoin(n, false, true, null);
} else { } else {
top = readTableFilter(fromOuter); top = readTableFilter(fromOuter);
top = readJoin(top, currentSelect, fromOuter); top = readJoin(top, currentSelect, false, fromOuter);
} }
read(")"); read(")");
alias = readFromAlias(null); alias = readFromAlias(null);
...@@ -1257,25 +1254,25 @@ public class Parser { ...@@ -1257,25 +1254,25 @@ public class Parser {
return command; return command;
} }
private TableFilter readJoin(TableFilter top, Select command, boolean fromOuter) { private TableFilter readJoin(TableFilter top, Select command, boolean nested, boolean fromOuter) {
boolean joined = false;
TableFilter last = top; TableFilter last = top;
boolean nestedJoins = database.getSettings().nestedJoins; boolean nestedJoins = database.getSettings().nestedJoins;
while (true) { while (true) {
if (readIf("RIGHT")) { if (readIf("RIGHT")) {
readIf("OUTER"); readIf("OUTER");
read("JOIN"); read("JOIN");
joined = true;
// the right hand side is the 'inner' table usually // the right hand side is the 'inner' table usually
TableFilter newTop = readTableFilter(fromOuter); TableFilter newTop = readTableFilter(fromOuter);
newTop = readJoin(newTop, command, true); newTop = readJoin(newTop, command, nested, true);
Expression on = null; Expression on = null;
if (readIf("ON")) { if (readIf("ON")) {
on = readExpression(); on = readExpression();
} }
if (nestedJoins) { if (nestedJoins) {
String joinTable = Constants.PREFIX_JOIN + parseIndex; top = getNested(top);
TableFilter nt = new TableFilter(session, getDualTable(true), joinTable, rightsChecked, currentSelect); newTop.addJoin(top, true, false, on);
nt.addJoin(top, false, true, null);
newTop.addJoin(nt, true, false, on);
} else { } else {
newTop.addJoin(top, true, false, on); newTop.addJoin(top, true, false, on);
} }
...@@ -1284,8 +1281,13 @@ public class Parser { ...@@ -1284,8 +1281,13 @@ public class Parser {
} else if (readIf("LEFT")) { } else if (readIf("LEFT")) {
readIf("OUTER"); readIf("OUTER");
read("JOIN"); read("JOIN");
joined = true;
TableFilter join = readTableFilter(true); TableFilter join = readTableFilter(true);
top = readJoin(top, command, true); if (nestedJoins) {
join = readJoin(join, command, true, true);
} else {
top = readJoin(top, command, false, true);
}
Expression on = null; Expression on = null;
if (readIf("ON")) { if (readIf("ON")) {
on = readExpression(); on = readExpression();
...@@ -1296,8 +1298,9 @@ public class Parser { ...@@ -1296,8 +1298,9 @@ public class Parser {
throw getSyntaxError(); throw getSyntaxError();
} else if (readIf("INNER")) { } else if (readIf("INNER")) {
read("JOIN"); read("JOIN");
joined = true;
TableFilter join = readTableFilter(fromOuter); TableFilter join = readTableFilter(fromOuter);
top = readJoin(top, command, false); top = readJoin(top, command, false, false);
Expression on = null; Expression on = null;
if (readIf("ON")) { if (readIf("ON")) {
on = readExpression(); on = readExpression();
...@@ -1309,8 +1312,9 @@ public class Parser { ...@@ -1309,8 +1312,9 @@ public class Parser {
} }
last = join; last = join;
} else if (readIf("JOIN")) { } else if (readIf("JOIN")) {
joined = true;
TableFilter join = readTableFilter(fromOuter); TableFilter join = readTableFilter(fromOuter);
top = readJoin(top, command, false); top = readJoin(top, command, false, false);
Expression on = null; Expression on = null;
if (readIf("ON")) { if (readIf("ON")) {
on = readExpression(); on = readExpression();
...@@ -1323,6 +1327,7 @@ public class Parser { ...@@ -1323,6 +1327,7 @@ public class Parser {
last = join; last = join;
} else if (readIf("CROSS")) { } else if (readIf("CROSS")) {
read("JOIN"); read("JOIN");
joined = true;
TableFilter join = readTableFilter(fromOuter); TableFilter join = readTableFilter(fromOuter);
if (nestedJoins) { if (nestedJoins) {
top.addJoin(join, false, false, null); top.addJoin(join, false, false, null);
...@@ -1332,6 +1337,7 @@ public class Parser { ...@@ -1332,6 +1337,7 @@ public class Parser {
last = join; last = join;
} else if (readIf("NATURAL")) { } else if (readIf("NATURAL")) {
read("JOIN"); read("JOIN");
joined = true;
TableFilter join = readTableFilter(fromOuter); TableFilter join = readTableFilter(fromOuter);
Column[] tableCols = last.getTable().getColumns(); Column[] tableCols = last.getTable().getColumns();
Column[] joinCols = join.getTable().getColumns(); Column[] joinCols = join.getTable().getColumns();
...@@ -1358,7 +1364,7 @@ public class Parser { ...@@ -1358,7 +1364,7 @@ public class Parser {
} }
} }
if (nestedJoins) { if (nestedJoins) {
top.addJoin(join, false, false, on); top.addJoin(join, false, nested, on);
} else { } else {
top.addJoin(join, fromOuter, false, on); top.addJoin(join, fromOuter, false, on);
} }
...@@ -1367,6 +1373,16 @@ public class Parser { ...@@ -1367,6 +1373,16 @@ public class Parser {
break; break;
} }
} }
if (nested && joined) {
top = getNested(top);
}
return top;
}
private TableFilter getNested(TableFilter n) {
String joinTable = Constants.PREFIX_JOIN + parseIndex;
TableFilter top = new TableFilter(session, getDualTable(true), joinTable, rightsChecked, currentSelect);
top.addJoin(n, false, true, null);
return top; return top;
} }
...@@ -1606,7 +1622,7 @@ public class Parser { ...@@ -1606,7 +1622,7 @@ public class Parser {
} }
private void parseJoinTableFilter(TableFilter top, final Select command) { private void parseJoinTableFilter(TableFilter top, final Select command) {
top = readJoin(top, command, top.isJoinOuter()); top = readJoin(top, command, false, top.isJoinOuter());
command.addTableFilter(top, true); command.addTableFilter(top, true);
boolean isOuter = false; boolean isOuter = false;
while (true) { while (true) {
...@@ -2051,7 +2067,7 @@ public class Parser { ...@@ -2051,7 +2067,7 @@ public class Parser {
ArrayList<Expression> params = New.arrayList(); ArrayList<Expression> params = New.arrayList();
do { do {
params.add(readExpression()); params.add(readExpression());
} while(readIf(",")); } while (readIf(","));
read(")"); read(")");
Expression[] list = new Expression[params.size()]; Expression[] list = new Expression[params.size()];
params.toArray(list); params.toArray(list);
......
...@@ -242,6 +242,22 @@ public class TestNestedJoins extends TestBase { ...@@ -242,6 +242,22 @@ public class TestNestedJoins extends TestBase {
ResultSet rs; ResultSet rs;
String sql; String sql;
/*
create table a(id int);
create table b(id int);
create table c(id int);
select * from a inner join b inner join c on c.id = b.id on b.id = a.id;
drop table a, b, c;
*/
stat.execute("create table a(id int)");
stat.execute("create table b(id int)");
stat.execute("create table c(id int)");
rs = stat.executeQuery("explain select * from a inner join b inner join c on c.id = b.id on b.id = a.id");
assertTrue(rs.next());
sql = rs.getString(1);
assertTrue("nested", sql.indexOf("(") >= 0);
stat.execute("drop table a, b, c");
/* /*
create table test(id int primary key, x int) create table test(id int primary key, x int)
as select x, x from system_range(1, 10); as select x, x from system_range(1, 10);
...@@ -268,7 +284,7 @@ public class TestNestedJoins extends TestBase { ...@@ -268,7 +284,7 @@ public class TestNestedJoins extends TestBase {
assertTrue(rs.next()); assertTrue(rs.next());
sql = rs.getString(1); sql = rs.getString(1);
int todo; int todo;
// assertTrue("using table scan", sql.indexOf("tableScan") < 0); // assertTrue("using table scan", sql.indexOf("tableScan") < 0);
stat.execute("drop table test"); stat.execute("drop table test");
stat.execute("drop table o"); stat.execute("drop table o");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论