use of org.h2.expression.ExpressionColumn in project h2database by h2database.
the class Query method initOrder.
/**
* Initialize the order by list. This call may extend the expressions list.
*
* @param session the session
* @param expressions the select list expressions
* @param expressionSQL the select list SQL snippets
* @param orderList the order by list
* @param visible the number of visible columns in the select list
* @param mustBeInResult all order by expressions must be in the select list
* @param filters the table filters
*/
static void initOrder(Session session, ArrayList<Expression> expressions, ArrayList<String> expressionSQL, ArrayList<SelectOrderBy> orderList, int visible, boolean mustBeInResult, ArrayList<TableFilter> filters) {
Database db = session.getDatabase();
for (SelectOrderBy o : orderList) {
Expression e = o.expression;
if (e == null) {
continue;
}
// special case: SELECT 1 AS A FROM DUAL ORDER BY A
// (oracle supports it, but only in order by, not in group by and
// not in having):
// SELECT 1 AS A FROM DUAL ORDER BY -A
boolean isAlias = false;
int idx = expressions.size();
if (e instanceof ExpressionColumn) {
// order by expression
ExpressionColumn exprCol = (ExpressionColumn) e;
String tableAlias = exprCol.getOriginalTableAliasName();
String col = exprCol.getOriginalColumnName();
for (int j = 0; j < visible; j++) {
boolean found = false;
Expression ec = expressions.get(j);
if (ec instanceof ExpressionColumn) {
// select expression
ExpressionColumn c = (ExpressionColumn) ec;
found = db.equalsIdentifiers(col, c.getColumnName());
if (found && tableAlias != null) {
String ca = c.getOriginalTableAliasName();
if (ca == null) {
found = false;
if (filters != null) {
// select id from test order by test.id
for (TableFilter f : filters) {
if (db.equalsIdentifiers(f.getTableAlias(), tableAlias)) {
found = true;
break;
}
}
}
} else {
found = db.equalsIdentifiers(ca, tableAlias);
}
}
} else if (!(ec instanceof Alias)) {
continue;
} else if (tableAlias == null && db.equalsIdentifiers(col, ec.getAlias())) {
found = true;
} else {
Expression ec2 = ec.getNonAliasExpression();
if (ec2 instanceof ExpressionColumn) {
ExpressionColumn c2 = (ExpressionColumn) ec2;
String ta = exprCol.getSQL();
String tb = c2.getSQL();
String s2 = c2.getColumnName();
found = db.equalsIdentifiers(col, s2);
if (!db.equalsIdentifiers(ta, tb)) {
found = false;
}
}
}
if (found) {
idx = j;
isAlias = true;
break;
}
}
} else {
String s = e.getSQL();
if (expressionSQL != null) {
for (int j = 0, size = expressionSQL.size(); j < size; j++) {
String s2 = expressionSQL.get(j);
if (db.equalsIdentifiers(s2, s)) {
idx = j;
isAlias = true;
break;
}
}
}
}
if (!isAlias) {
if (mustBeInResult) {
throw DbException.get(ErrorCode.ORDER_BY_NOT_IN_RESULT, e.getSQL());
}
expressions.add(e);
String sql = e.getSQL();
expressionSQL.add(sql);
}
o.columnIndexExpr = ValueExpression.get(ValueInt.get(idx + 1));
o.expression = expressions.get(idx).getNonAliasExpression();
}
}
use of org.h2.expression.ExpressionColumn in project h2database by h2database.
the class SelectUnion method prepare.
@Override
public void prepare() {
if (isPrepared) {
// sometimes a subquery is prepared twice (CREATE TABLE AS SELECT)
return;
}
if (SysProperties.CHECK && !checkInit) {
DbException.throwInternalError("not initialized");
}
isPrepared = true;
left.prepare();
right.prepare();
int len = left.getColumnCount();
// set the correct expressions now
expressions = New.arrayList();
ArrayList<Expression> le = left.getExpressions();
ArrayList<Expression> re = right.getExpressions();
ColumnNamer columnNamer = new ColumnNamer(session);
for (int i = 0; i < len; i++) {
Expression l = le.get(i);
Expression r = re.get(i);
int type = Value.getHigherOrder(l.getType(), r.getType());
long prec = Math.max(l.getPrecision(), r.getPrecision());
int scale = Math.max(l.getScale(), r.getScale());
int displaySize = Math.max(l.getDisplaySize(), r.getDisplaySize());
String columnName = columnNamer.getColumnName(l, i, l.getAlias());
Column col = new Column(columnName, type, prec, scale, displaySize);
Expression e = new ExpressionColumn(session.getDatabase(), col);
expressions.add(e);
}
if (orderList != null) {
initOrder(session, expressions, null, orderList, getColumnCount(), true, null);
sort = prepareOrder(orderList, expressions.size());
orderList = null;
}
expressionArray = expressions.toArray(new Expression[0]);
}
use of org.h2.expression.ExpressionColumn in project h2database by h2database.
the class CompareLike method createIndexConditions.
@Override
public void createIndexConditions(Session session, TableFilter filter) {
if (regexp) {
return;
}
if (!(left instanceof ExpressionColumn)) {
return;
}
ExpressionColumn l = (ExpressionColumn) left;
if (filter != l.getTableFilter()) {
return;
}
// which may be slower (possibly not in this case)
if (!right.isEverything(ExpressionVisitor.INDEPENDENT_VISITOR)) {
return;
}
if (escape != null && !escape.isEverything(ExpressionVisitor.INDEPENDENT_VISITOR)) {
return;
}
String p = right.getValue(session).getString();
if (!isInit) {
Value e = escape == null ? null : escape.getValue(session);
if (e == ValueNull.INSTANCE) {
// should already be optimized
DbException.throwInternalError();
}
initPattern(p, getEscapeChar(e));
}
if (invalidPattern) {
return;
}
if (patternLength <= 0 || patternTypes[0] != MATCH) {
// can't use an index
return;
}
int dataType = l.getColumn().getType();
if (dataType != Value.STRING && dataType != Value.STRING_IGNORECASE && dataType != Value.STRING_FIXED) {
// column is not a varchar - can't use the index
return;
}
// Get the MATCH prefix and see if we can create an index condition from
// that.
int maxMatch = 0;
StringBuilder buff = new StringBuilder();
while (maxMatch < patternLength && patternTypes[maxMatch] == MATCH) {
buff.append(patternChars[maxMatch++]);
}
String begin = buff.toString();
if (maxMatch == patternLength) {
filter.addIndexCondition(IndexCondition.get(Comparison.EQUAL, l, ValueExpression.get(ValueString.get(begin))));
} else {
// TODO check if this is correct according to Unicode rules
// (code points)
String end;
if (begin.length() > 0) {
filter.addIndexCondition(IndexCondition.get(Comparison.BIGGER_EQUAL, l, ValueExpression.get(ValueString.get(begin))));
char next = begin.charAt(begin.length() - 1);
// that is higher)
for (int i = 1; i < 2000; i++) {
end = begin.substring(0, begin.length() - 1) + (char) (next + i);
if (compareMode.compareString(begin, end, ignoreCase) == -1) {
filter.addIndexCondition(IndexCondition.get(Comparison.SMALLER, l, ValueExpression.get(ValueString.get(end))));
break;
}
}
}
}
}
use of org.h2.expression.ExpressionColumn in project h2database by h2database.
the class Comparison method optimize.
@Override
public Expression optimize(Session session) {
left = left.optimize(session);
if (right != null) {
right = right.optimize(session);
if (right instanceof ExpressionColumn) {
if (left.isConstant() || left instanceof Parameter) {
Expression temp = left;
left = right;
right = temp;
compareType = getReversedCompareType(compareType);
}
}
if (left instanceof ExpressionColumn) {
if (right.isConstant()) {
Value r = right.getValue(session);
if (r == ValueNull.INSTANCE) {
if ((compareType & NULL_SAFE) == 0) {
return ValueExpression.getNull();
}
}
int colType = left.getType();
int constType = r.getType();
int resType = Value.getHigherOrder(colType, constType);
// once.
if (constType != resType) {
Column column = ((ExpressionColumn) left).getColumn();
right = ValueExpression.get(r.convertTo(resType, MathUtils.convertLongToInt(left.getPrecision()), session.getDatabase().getMode(), column, column.getEnumerators()));
}
} else if (right instanceof Parameter) {
((Parameter) right).setColumn(((ExpressionColumn) left).getColumn());
}
}
}
if (compareType == IS_NULL || compareType == IS_NOT_NULL) {
if (left.isConstant()) {
return ValueExpression.get(getValue(session));
}
} else {
if (SysProperties.CHECK && (left == null || right == null)) {
DbException.throwInternalError(left + " " + right);
}
if (left == ValueExpression.getNull() || right == ValueExpression.getNull()) {
// a NULL constants
if ((compareType & NULL_SAFE) == 0) {
return ValueExpression.getNull();
}
}
if (left.isConstant() && right.isConstant()) {
return ValueExpression.get(getValue(session));
}
}
return this;
}
use of org.h2.expression.ExpressionColumn in project h2database by h2database.
the class Aggregate method getMinMaxColumnIndex.
private Index getMinMaxColumnIndex() {
if (on instanceof ExpressionColumn) {
ExpressionColumn col = (ExpressionColumn) on;
Column column = col.getColumn();
TableFilter filter = col.getTableFilter();
if (filter != null) {
Table table = filter.getTable();
return table.getIndexForColumn(column, true, false);
}
}
return null;
}
Aggregations