use of de.neemann.digital.hdl.model2.expression.Expression 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 de.neemann.digital.hdl.model2.expression.Expression 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 de.neemann.digital.hdl.model2.expression.Expression in project h2database by h2database.
the class Update method getPlanSQL.
@Override
public String getPlanSQL() {
StatementBuilder buff = new StatementBuilder("UPDATE ");
buff.append(targetTableFilter.getPlanSQL(false)).append("\nSET\n ");
for (Column c : columns) {
Expression e = expressionMap.get(c);
buff.appendExceptFirst(",\n ");
buff.append(c.getName()).append(" = ").append(e.getSQL());
}
if (condition != null) {
buff.append("\nWHERE ").append(StringUtils.unEnclose(condition.getSQL()));
}
if (limitExpr != null) {
buff.append("\nLIMIT ").append(StringUtils.unEnclose(limitExpr.getSQL()));
}
return buff.toString();
}
use of de.neemann.digital.hdl.model2.expression.Expression in project h2database by h2database.
the class Update method prepare.
@Override
public void prepare() {
if (condition != null) {
condition.mapColumns(targetTableFilter, 0);
condition = condition.optimize(session);
condition.createIndexConditions(session, targetTableFilter);
}
for (Column c : columns) {
Expression e = expressionMap.get(c);
e.mapColumns(targetTableFilter, 0);
if (sourceTableFilter != null) {
e.mapColumns(sourceTableFilter, 0);
}
expressionMap.put(c, e.optimize(session));
}
TableFilter[] filters;
if (sourceTableFilter == null) {
filters = new TableFilter[] { targetTableFilter };
} else {
filters = new TableFilter[] { targetTableFilter, sourceTableFilter };
}
PlanItem item = targetTableFilter.getBestPlanItem(session, filters, 0, ExpressionVisitor.allColumnsForTableFilters(filters));
targetTableFilter.setPlanItem(item);
targetTableFilter.prepare();
}
use of de.neemann.digital.hdl.model2.expression.Expression in project h2database by h2database.
the class Merge method update.
@Override
public int update() {
int count;
session.getUser().checkRight(targetTable, Right.INSERT);
session.getUser().checkRight(targetTable, Right.UPDATE);
setCurrentRowNumber(0);
GeneratedKeys generatedKeys = session.getGeneratedKeys();
if (!valuesExpressionList.isEmpty()) {
// process values in list
count = 0;
generatedKeys.initialize(targetTable);
for (int x = 0, size = valuesExpressionList.size(); x < size; x++) {
setCurrentRowNumber(x + 1);
generatedKeys.nextRow();
Expression[] expr = valuesExpressionList.get(x);
Row newRow = targetTable.getTemplateRow();
for (int i = 0, len = columns.length; i < len; i++) {
Column c = columns[i];
int index = c.getColumnId();
Expression e = expr[i];
if (e != null) {
// e can be null (DEFAULT)
try {
Value v = c.convert(e.getValue(session));
newRow.setValue(index, v);
if (e instanceof SequenceValue) {
generatedKeys.add(c);
}
} catch (DbException ex) {
throw setRow(ex, count, getSQL(expr));
}
}
}
merge(newRow);
count++;
}
} else {
// process select data for list
query.setNeverLazy(true);
ResultInterface rows = query.query(0);
count = 0;
targetTable.fire(session, Trigger.UPDATE | Trigger.INSERT, true);
targetTable.lock(session, true, false);
while (rows.next()) {
count++;
generatedKeys.nextRow();
Value[] r = rows.currentRow();
Row newRow = targetTable.getTemplateRow();
setCurrentRowNumber(count);
for (int j = 0; j < columns.length; j++) {
Column c = columns[j];
int index = c.getColumnId();
try {
Value v = c.convert(r[j]);
newRow.setValue(index, v);
} catch (DbException ex) {
throw setRow(ex, count, getSQL(r));
}
}
merge(newRow);
}
rows.close();
targetTable.fire(session, Trigger.UPDATE | Trigger.INSERT, false);
}
return count;
}
Aggregations