use of org.h2.table.TableFilter in project h2database by h2database.
the class Parser method readCondition.
private Expression readCondition() {
if (readIf("NOT")) {
return new ConditionNot(readCondition());
}
if (readIf("EXISTS")) {
read("(");
Query query = parseSelect();
// can not reduce expression because it might be a union except
// query with distinct
read(")");
return new ConditionExists(query);
}
if (readIf("INTERSECTS")) {
read("(");
Expression r1 = readConcat();
read(",");
Expression r2 = readConcat();
read(")");
return new Comparison(session, Comparison.SPATIAL_INTERSECTS, r1, r2);
}
Expression r = readConcat();
while (true) {
// special case: NOT NULL is not part of an expression (as in CREATE
// TABLE TEST(ID INT DEFAULT 0 NOT NULL))
int backup = parseIndex;
boolean not = false;
if (readIf("NOT")) {
not = true;
if (isToken("NULL")) {
// this really only works for NOT NULL!
parseIndex = backup;
currentToken = "NOT";
break;
}
}
if (readIf("LIKE")) {
Expression b = readConcat();
Expression esc = null;
if (readIf("ESCAPE")) {
esc = readConcat();
}
recompileAlways = true;
r = new CompareLike(database, r, b, esc, false);
} else if (readIf("ILIKE")) {
Function function = Function.getFunction(database, "CAST");
function.setDataType(new Column("X", Value.STRING_IGNORECASE));
function.setParameter(0, r);
r = function;
Expression b = readConcat();
Expression esc = null;
if (readIf("ESCAPE")) {
esc = readConcat();
}
recompileAlways = true;
r = new CompareLike(database, r, b, esc, false);
} else if (readIf("REGEXP")) {
Expression b = readConcat();
recompileAlways = true;
r = new CompareLike(database, r, b, null, true);
} else if (readIf("IS")) {
if (readIf("NOT")) {
if (readIf("NULL")) {
r = new Comparison(session, Comparison.IS_NOT_NULL, r, null);
} else if (readIf("DISTINCT")) {
read("FROM");
r = new Comparison(session, Comparison.EQUAL_NULL_SAFE, r, readConcat());
} else {
r = new Comparison(session, Comparison.NOT_EQUAL_NULL_SAFE, r, readConcat());
}
} else if (readIf("NULL")) {
r = new Comparison(session, Comparison.IS_NULL, r, null);
} else if (readIf("DISTINCT")) {
read("FROM");
r = new Comparison(session, Comparison.NOT_EQUAL_NULL_SAFE, r, readConcat());
} else {
r = new Comparison(session, Comparison.EQUAL_NULL_SAFE, r, readConcat());
}
} else if (readIf("IN")) {
read("(");
if (readIf(")")) {
if (database.getMode().prohibitEmptyInPredicate) {
throw getSyntaxError();
}
r = ValueExpression.get(ValueBoolean.FALSE);
} else {
if (isSelect()) {
Query query = parseSelect();
// can not be lazy because we have to call
// method ResultInterface.containsDistinct
// which is not supported for lazy execution
query.setNeverLazy(true);
r = new ConditionInSelect(database, r, query, false, Comparison.EQUAL);
} else {
ArrayList<Expression> v = New.arrayList();
Expression last;
do {
last = readExpression();
v.add(last);
} while (readIf(","));
if (v.size() == 1 && (last instanceof Subquery)) {
Subquery s = (Subquery) last;
Query q = s.getQuery();
r = new ConditionInSelect(database, r, q, false, Comparison.EQUAL);
} else {
r = new ConditionIn(database, r, v);
}
}
read(")");
}
} else if (readIf("BETWEEN")) {
Expression low = readConcat();
read("AND");
Expression high = readConcat();
Expression condLow = new Comparison(session, Comparison.SMALLER_EQUAL, low, r);
Expression condHigh = new Comparison(session, Comparison.BIGGER_EQUAL, high, r);
r = new ConditionAndOr(ConditionAndOr.AND, condLow, condHigh);
} else {
int compareType = getCompareType(currentTokenType);
if (compareType < 0) {
break;
}
read();
if (readIf("ALL")) {
read("(");
Query query = parseSelect();
r = new ConditionInSelect(database, r, query, true, compareType);
read(")");
} else if (readIf("ANY") || readIf("SOME")) {
read("(");
if (currentTokenType == PARAMETER && compareType == 0) {
Parameter p = readParameter();
r = new ConditionInParameter(database, r, p);
} else {
Query query = parseSelect();
r = new ConditionInSelect(database, r, query, false, compareType);
}
read(")");
} else {
Expression right = readConcat();
if (SysProperties.OLD_STYLE_OUTER_JOIN && readIf("(") && readIf("+") && readIf(")")) {
// join with (+)
if (r instanceof ExpressionColumn && right instanceof ExpressionColumn) {
ExpressionColumn leftCol = (ExpressionColumn) r;
ExpressionColumn rightCol = (ExpressionColumn) right;
ArrayList<TableFilter> filters = currentSelect.getTopFilters();
for (TableFilter f : filters) {
while (f != null) {
leftCol.mapColumns(f, 0);
rightCol.mapColumns(f, 0);
f = f.getJoin();
}
}
TableFilter leftFilter = leftCol.getTableFilter();
TableFilter rightFilter = rightCol.getTableFilter();
r = new Comparison(session, compareType, r, right);
if (leftFilter != null && rightFilter != null) {
int idx = filters.indexOf(rightFilter);
if (idx >= 0) {
filters.remove(idx);
leftFilter.addJoin(rightFilter, true, r);
} else {
rightFilter.mapAndAddFilter(r);
}
r = ValueExpression.get(ValueBoolean.TRUE);
}
}
} else {
r = new Comparison(session, compareType, r, right);
}
}
}
if (not) {
r = new ConditionNot(r);
}
}
return r;
}
use of org.h2.table.TableFilter in project h2database by h2database.
the class Parser method parseUpdateSetClause.
private void parseUpdateSetClause(Update command, TableFilter filter, int start) {
read("SET");
if (readIf("(")) {
ArrayList<Column> columns = New.arrayList();
do {
Column column = readTableColumn(filter);
columns.add(column);
} while (readIfMore(true));
read("=");
Expression expression = readExpression();
if (columns.size() == 1) {
// the expression is parsed as a simple value
command.setAssignment(columns.get(0), expression);
} else {
for (int i = 0, size = columns.size(); i < size; i++) {
Column column = columns.get(i);
Function f = Function.getFunction(database, "ARRAY_GET");
f.setParameter(0, expression);
f.setParameter(1, ValueExpression.get(ValueInt.get(i + 1)));
f.doneWithParameters();
command.setAssignment(column, f);
}
}
} else {
do {
Column column = readTableColumn(filter);
read("=");
Expression expression;
if (readIf("DEFAULT")) {
expression = ValueExpression.getDefault();
} else {
expression = readExpression();
}
command.setAssignment(column, expression);
} while (readIf(","));
}
if (readIf("WHERE")) {
Expression condition = readExpression();
command.setCondition(condition);
}
if (readIf("ORDER")) {
// for MySQL compatibility
// (this syntax is supported, but ignored)
read("BY");
parseSimpleOrderList();
}
if (readIf("LIMIT")) {
Expression limit = readTerm().optimize(session);
command.setLimit(limit);
}
setSQL(command, "UPDATE", start);
}
use of org.h2.table.TableFilter in project h2database by h2database.
the class Parser method parseJoinTableFilter.
private void parseJoinTableFilter(TableFilter top, final Select command) {
top = readJoin(top);
command.addTableFilter(top, true);
boolean isOuter = false;
while (true) {
TableFilter n = top.getNestedJoin();
if (n != null) {
n.visit(new TableFilterVisitor() {
@Override
public void accept(TableFilter f) {
command.addTableFilter(f, false);
}
});
}
TableFilter join = top.getJoin();
if (join == null) {
break;
}
isOuter = isOuter | join.isJoinOuter();
if (isOuter) {
command.addTableFilter(join, false);
} else {
// make flat so the optimizer can work better
Expression on = join.getJoinCondition();
if (on != null) {
command.addCondition(on);
}
join.removeJoinCondition();
top.removeJoin();
command.addTableFilter(join, true);
}
top = join;
}
}
use of org.h2.table.TableFilter in project h2database by h2database.
the class Parser method readTableColumn.
private Column readTableColumn(TableFilter filter) {
String tableAlias = null;
String columnName = readColumnIdentifier();
if (readIf(".")) {
tableAlias = columnName;
columnName = readColumnIdentifier();
if (readIf(".")) {
String schema = tableAlias;
tableAlias = columnName;
columnName = readColumnIdentifier();
if (readIf(".")) {
String catalogName = schema;
schema = tableAlias;
tableAlias = columnName;
columnName = readColumnIdentifier();
if (!equalsToken(catalogName, database.getShortName())) {
throw DbException.get(ErrorCode.DATABASE_NOT_FOUND_1, catalogName);
}
}
if (!equalsToken(schema, filter.getTable().getSchema().getName())) {
throw DbException.get(ErrorCode.SCHEMA_NOT_FOUND_1, schema);
}
}
if (!equalsToken(tableAlias, filter.getTableAlias())) {
throw DbException.get(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, tableAlias);
}
}
if (database.getSettings().rowId) {
if (Column.ROWID.equals(columnName)) {
return filter.getRowIdColumn();
}
}
return filter.getTable().getColumn(columnName);
}
use of org.h2.table.TableFilter in project h2database by h2database.
the class Parser method parseSelectSimple.
private Select parseSelectSimple() {
boolean fromFirst;
if (readIf("SELECT")) {
fromFirst = false;
} else if (readIf("FROM")) {
fromFirst = true;
} else {
throw getSyntaxError();
}
Select command = new Select(session);
int start = lastParseIndex;
Select oldSelect = currentSelect;
currentSelect = command;
currentPrepared = command;
if (fromFirst) {
parseSelectSimpleFromPart(command);
read("SELECT");
parseSelectSimpleSelectPart(command);
} else {
parseSelectSimpleSelectPart(command);
if (!readIf("FROM")) {
// select without FROM: convert to SELECT ... FROM
// SYSTEM_RANGE(1,1)
Table dual = getDualTable(false);
TableFilter filter = new TableFilter(session, dual, null, rightsChecked, currentSelect, 0, null);
command.addTableFilter(filter, true);
} else {
parseSelectSimpleFromPart(command);
}
}
if (readIf("WHERE")) {
Expression condition = readExpression();
command.addCondition(condition);
}
// the group by is read for the outer select (or not a select)
// so that columns that are not grouped can be used
currentSelect = oldSelect;
if (readIf("GROUP")) {
read("BY");
command.setGroupQuery();
ArrayList<Expression> list = New.arrayList();
do {
Expression expr = readExpression();
list.add(expr);
} while (readIf(","));
command.setGroupBy(list);
}
currentSelect = command;
if (readIf("HAVING")) {
command.setGroupQuery();
Expression condition = readExpression();
command.setHaving(condition);
}
command.setParameterList(parameters);
currentSelect = oldSelect;
setSQL(command, "SELECT", start);
return command;
}
Aggregations