studio.raptor.sqlparser.fast.expression.ExpressionVisitor Maven / Gradle / Ivy
/*
* Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package studio.raptor.sqlparser.fast.expression;
import java.util.HashSet;
import studio.raptor.sqlparser.fast.table.Table;
import studio.raptor.sqlparser.fast.table.Column;
import studio.raptor.sqlparser.fast.table.ColumnResolver;
/**
* The visitor pattern is used to iterate through all expressions of a query
* to optimize a statement.
*/
public class ExpressionVisitor {
/**
* Is the value independent on unset parameters or on columns of a higher
* level query, or sequence values (that means can it be evaluated right
* now)?
*/
public static final int INDEPENDENT = 0;
/**
* The visitor singleton for the type INDEPENDENT.
*/
public static final ExpressionVisitor INDEPENDENT_VISITOR =
new ExpressionVisitor(INDEPENDENT);
/**
* Are all aggregates MIN(column), MAX(column), or COUNT(*) for the given
* table (getTable)?
*/
public static final int OPTIMIZABLE_MIN_MAX_COUNT_ALL = 1;
/**
* Does the expression return the same results for the same parameters?
*/
public static final int DETERMINISTIC = 2;
/**
* The visitor singleton for the type DETERMINISTIC.
*/
public static final ExpressionVisitor DETERMINISTIC_VISITOR =
new ExpressionVisitor(DETERMINISTIC);
/**
* Can the expression be evaluated, that means are all columns set to
* 'evaluatable'?
*/
public static final int EVALUATABLE = 3;
/**
* The visitor singleton for the type EVALUATABLE.
*/
public static final ExpressionVisitor EVALUATABLE_VISITOR =
new ExpressionVisitor(EVALUATABLE);
/**
* Request to set the latest modification id (addDataModificationId).
*/
public static final int SET_MAX_DATA_MODIFICATION_ID = 4;
/**
* Does the expression have no side effects (change the data)?
*/
public static final int READONLY = 5;
/**
* The visitor singleton for the type EVALUATABLE.
*/
public static final ExpressionVisitor READONLY_VISITOR =
new ExpressionVisitor(READONLY);
/**
* Does an expression have no relation to the given table filter
* (getResolver)?
*/
public static final int NOT_FROM_RESOLVER = 6;
/**
* Request to get the set of dependencies (addDependency).
*/
public static final int GET_DEPENDENCIES = 7;
/**
* Can the expression be added to a condition of an outer query. Example:
* ROWNUM() can't be added as a condition to the inner query of select id
* from (select t.*, rownum as r from test t) where r between 2 and 3; Also
* a sequence expression must not be used.
*/
public static final int QUERY_COMPARABLE = 8;
/**
* Get all referenced columns.
*/
public static final int GET_COLUMNS = 9;
/**
* The visitor singleton for the type QUERY_COMPARABLE.
*/
public static final ExpressionVisitor QUERY_COMPARABLE_VISITOR =
new ExpressionVisitor(QUERY_COMPARABLE);
private final int type;
private final int queryLevel;
private final HashSet columns;
private final Table table;
private final long[] maxDataModificationId;
private final ColumnResolver resolver;
private ExpressionVisitor(int type,
int queryLevel,
HashSet columns,
Table table, ColumnResolver resolver,
long[] maxDataModificationId) {
this.type = type;
this.queryLevel = queryLevel;
this.columns = columns;
this.table = table;
this.resolver = resolver;
this.maxDataModificationId = maxDataModificationId;
}
private ExpressionVisitor(int type) {
this.type = type;
this.queryLevel = 0;
this.columns = null;
this.table = null;
this.resolver = null;
this.maxDataModificationId = null;
}
/**
* Add a new column to the set of columns.
* This is used for GET_COLUMNS visitors.
*
* @param column the additional column.
*/
void addColumn(Column column) {
columns.add(column);
}
/**
* Get the column resolver.
* This is used for NOT_FROM_RESOLVER visitors.
*
* @return the column resolver
*/
public ColumnResolver getResolver() {
return resolver;
}
/**
* Update the field maxDataModificationId if this value is higher
* than the current value.
* This is used for SET_MAX_DATA_MODIFICATION_ID visitors.
*
* @param value the data modification id
*/
public void addDataModificationId(long value) {
long m = maxDataModificationId[0];
if (value > m) {
maxDataModificationId[0] = value;
}
}
/**
* Get the last data modification.
* This is used for SET_MAX_DATA_MODIFICATION_ID visitors.
*
* @return the maximum modification id
*/
public long getMaxDataModificationId() {
return maxDataModificationId[0];
}
int getQueryLevel() {
return queryLevel;
}
/**
* Get the table.
* This is used for OPTIMIZABLE_MIN_MAX_COUNT_ALL visitors.
*
* @return the table
*/
public Table getTable() {
return table;
}
/**
* Get the visitor type.
*
* @return the type
*/
public int getType() {
return type;
}
}