return command;
}
private TableFilter readJoin(TableFilter top, Select command, boolean nested, boolean fromOuter) {
boolean joined = false;
TableFilter last = top;
boolean nestedJoins = database.getSettings().nestedJoins;
while (true) {
if (readIf("RIGHT")) {
readIf("OUTER");
read("JOIN");
joined = true;
// the right hand side is the 'inner' table usually
TableFilter newTop = readTableFilter(fromOuter);
newTop = readJoin(newTop, command, nested, true);
Expression on = null;
if (readIf("ON")) {
on = readExpression();
}
if (nestedJoins) {
top = getNested(top);
newTop.addJoin(top, true, false, on);
} else {
newTop.addJoin(top, true, false, on);
}
top = newTop;
last = newTop;
} else if (readIf("LEFT")) {
readIf("OUTER");
read("JOIN");
joined = true;
TableFilter join = readTableFilter(true);
if (nestedJoins) {
join = readJoin(join, command, true, true);
} else {
top = readJoin(top, command, false, true);
}
Expression on = null;
if (readIf("ON")) {
on = readExpression();
}
top.addJoin(join, true, false, on);
last = join;
} else if (readIf("FULL")) {
throw getSyntaxError();
} else if (readIf("INNER")) {
read("JOIN");
joined = true;
TableFilter join = readTableFilter(fromOuter);
top = readJoin(top, command, false, false);
Expression on = null;
if (readIf("ON")) {
on = readExpression();
}
if (nestedJoins) {
top.addJoin(join, false, false, on);
} else {
top.addJoin(join, fromOuter, false, on);
}
last = join;
} else if (readIf("JOIN")) {
joined = true;
TableFilter join = readTableFilter(fromOuter);
top = readJoin(top, command, false, false);
Expression on = null;
if (readIf("ON")) {
on = readExpression();
}
if (nestedJoins) {
top.addJoin(join, false, false, on);
} else {
top.addJoin(join, fromOuter, false, on);
}
last = join;
} else if (readIf("CROSS")) {
read("JOIN");
joined = true;
TableFilter join = readTableFilter(fromOuter);
if (nestedJoins) {
top.addJoin(join, false, false, null);
} else {
top.addJoin(join, fromOuter, false, null);
}
last = join;
} else if (readIf("NATURAL")) {
read("JOIN");
joined = true;
TableFilter join = readTableFilter(fromOuter);
Column[] tableCols = last.getTable().getColumns();
Column[] joinCols = join.getTable().getColumns();
String tableSchema = last.getTable().getSchema().getName();
String joinSchema = join.getTable().getSchema().getName();
Expression on = null;
for (Column tc : tableCols) {
String tableColumnName = tc.getFullName();
for (Column c : joinCols) {
String joinColumnName = c.getFullName();
if (equalsToken(tableColumnName, joinColumnName)) {
join.addNaturalJoinColumn(c);
Expression tableExpr = new ExpressionColumn(database, tableSchema, last.getTableAlias(),
tc.getColumnFamilyName(), tableColumnName);
Expression joinExpr = new ExpressionColumn(database, joinSchema, join.getTableAlias(),
c.getColumnFamilyName(), joinColumnName);
Expression equal = new Comparison(session, Comparison.EQUAL, tableExpr, joinExpr);
if (on == null) {
on = equal;
} else {