use of org.hsqldb_voltpatches.lib.HsqlList in project voltdb by VoltDB.
the class ParserRoutine method compileSetStatement.
/**
* Creates SET Statement for PSM from this parse context.
*/
StatementSimple compileSetStatement(RangeVariable[] rangeVars) {
read();
OrderedHashSet colNames = new OrderedHashSet();
HsqlArrayList exprList = new HsqlArrayList();
readSetClauseList(rangeVars, colNames, exprList);
if (exprList.size() > 1) {
throw Error.error(ErrorCode.X_42602);
}
Expression expression = (Expression) exprList.get(0);
if (expression.getDegree() != colNames.size()) {
// throw Error.error(ErrorCode.X_42546);
}
int[] indexes = new int[colNames.size()];
ColumnSchema[] variables = new ColumnSchema[colNames.size()];
setVariables(rangeVars, colNames, indexes, variables);
HsqlList unresolved = expression.resolveColumnReferences(rangeVars, rangeVars.length, null, false);
unresolved = Expression.resolveColumnSet(rangeVars, unresolved, null);
ExpressionColumn.checkColumnsResolved(unresolved);
expression.resolveTypes(session, null);
StatementSimple cs = new StatementSimple(StatementTypes.ASSIGNMENT, variables, expression, indexes);
return cs;
}
use of org.hsqldb_voltpatches.lib.HsqlList in project voltdb by VoltDB.
the class QueryExpression method resolve.
public void resolve(Session session, RangeVariable[] outerRanges) {
resolveReferences(session);
if (unresolvedExpressions != null) {
for (int i = 0; i < unresolvedExpressions.size(); i++) {
Expression e = (Expression) unresolvedExpressions.get(i);
HsqlList list = e.resolveColumnReferences(outerRanges, null);
ExpressionColumn.checkColumnsResolved(list);
}
}
resolveTypes(session);
}
use of org.hsqldb_voltpatches.lib.HsqlList in project voltdb by VoltDB.
the class QuerySpecification method resolveColumnReferencesInGroupBy.
/************************* Volt DB Extensions *************************/
void resolveColumnReferencesInGroupBy() {
if (unresolvedExpressions == null || unresolvedExpressions.isEmpty()) {
return;
}
/**
* Hsql HashSet does not work properly to remove duplicates, I doubt the hash
* function or equal function on expression work properly or something else
* is wrong. So use list
*
*/
// resolve GROUP BY columns/expressions
HsqlList newUnresolvedExpressions = new ArrayListIdentity();
int size = unresolvedExpressions.size();
for (int i = 0; i < size; i++) {
Object obj = unresolvedExpressions.get(i);
newUnresolvedExpressions.add(obj);
if (i + 1 < size && obj == unresolvedExpressions.get(i + 1)) {
// unresolvedExpressions is a public member that can be accessed from anywhere and
// I (xin) am 90% percent sure about the hsql adds the unresolved expression twice
// together for our targeted GROUP BY alias case.
// so we want to skip the repeated expression also.
// For other unresolved expression, it may differs.
i += 1;
}
if (obj instanceof ExpressionColumn == false) {
continue;
}
ExpressionColumn element = (ExpressionColumn) obj;
if (element.tableName != null) {
// this alias does not belong to any table
continue;
}
// group by alias which is thought as an column
if (element.getType() != OpTypes.COLUMN) {
continue;
}
// find the unsolved expression in the groupBy list
int k = indexLimitVisible;
int endGroupbyIndex = indexLimitVisible + groupByColumnCount;
for (; k < endGroupbyIndex; k++) {
if (element == exprColumns[k]) {
break;
}
}
if (k == endGroupbyIndex) {
// not found in selected list
continue;
}
assert (exprColumns[k].getType() == OpTypes.COLUMN);
ExpressionColumn exprCol = (ExpressionColumn) exprColumns[k];
String alias = exprCol.getColumnName();
if (alias == null) {
// we should not handle this case (group by constants)
continue;
}
// Find it in the SELECT list. We need to look at all
// the select list elements to see if there are more
// than one.
int matchcount = 0;
for (int j = 0; j < indexLimitVisible; j++) {
Expression selectCol = exprColumns[j];
if (selectCol.alias == null) {
// columns referenced by their alias must have an alias
continue;
}
if (alias.equals(selectCol.alias.name)) {
matchcount += 1;
// This may be an alias to an aggregate
// column. But we'll find that later, so
// don't check for it here.
exprColumns[k] = selectCol;
exprColumnList.set(k, selectCol);
if (matchcount == 1) {
newUnresolvedExpressions.remove(element);
}
}
}
if (matchcount > 1) {
throw new HsqlException(String.format("Group by expression \"%s\" is ambiguous", alias), "", 0);
}
}
unresolvedExpressions = newUnresolvedExpressions;
}
use of org.hsqldb_voltpatches.lib.HsqlList in project voltdb by VoltDB.
the class QuerySpecification method resolveColumnReferencesAndAllocate.
private void resolveColumnReferencesAndAllocate(Expression expression, int count, boolean withSequences) {
if (expression == null) {
return;
}
HsqlList list = expression.resolveColumnReferences(rangeVariables, count, null, withSequences);
if (list != null) {
for (int i = 0; i < list.size(); i++) {
Expression e = (Expression) list.get(i);
boolean resolved;
if (e.isSelfAggregate()) {
resolved = resolveColumnReferences(e.getLeftNode(), count, false);
} else {
resolved = resolveColumnReferences(e, count, withSequences);
}
if (resolved) {
if (e.isSelfAggregate()) {
if (aggregateSet == null) {
aggregateSet = new ArrayListIdentity();
}
aggregateSet.add(e);
isAggregated = true;
expression.isAggregate = true;
}
if (resolvedSubqueryExpressions == null) {
resolvedSubqueryExpressions = new ArrayListIdentity();
}
resolvedSubqueryExpressions.add(e);
} else {
if (unresolvedExpressions == null) {
unresolvedExpressions = new ArrayListIdentity();
}
unresolvedExpressions.add(e);
}
}
}
}
use of org.hsqldb_voltpatches.lib.HsqlList in project voltdb by VoltDB.
the class QuerySpecification method resolveExpressionTypes.
/**
* Sets the types of all the expressions used in this SELECT list.
*/
public void resolveExpressionTypes(Session session) {
for (int i = 0; i < indexStartAggregates; i++) {
Expression e = exprColumns[i];
e.resolveTypes(session, null);
if (e.getType() == OpTypes.ROW) {
throw Error.error(ErrorCode.X_42564);
}
}
for (int i = 0, len = rangeVariables.length; i < len; i++) {
Expression e = rangeVariables[i].nonIndexJoinCondition;
if (e != null) {
e.resolveTypes(session, null);
if (e.getDataType() != Type.SQL_BOOLEAN) {
throw Error.error(ErrorCode.X_42568);
}
}
}
if (queryCondition != null) {
queryCondition.resolveTypes(session, null);
if (queryCondition.getDataType() != Type.SQL_BOOLEAN) {
throw Error.error(ErrorCode.X_42568);
}
if (queryCondition.opType == OpTypes.VALUE) {
if (!((boolean) queryCondition.valueData)) {
// WHERE false => LIMIT 0
SortAndSlice sortAndSlice = new SortAndSlice();
ExpressionValue limit0 = new ExpressionValue(ValuePool.INTEGER_0, Type.SQL_INTEGER);
ExpressionValue offset = new ExpressionValue(ValuePool.INTEGER_0, Type.SQL_INTEGER);
sortAndSlice.addLimitCondition(new ExpressionOp(OpTypes.LIMIT, offset, limit0));
addSortAndSlice(sortAndSlice);
}
// Leave out the original WHERE condition no matter it is WHERE true or WHERE false.
queryCondition = null;
} else {
// A VoltDB extension to guard against abuse of aggregates in subqueries.
// Make sure no aggregates in WHERE clause
tempSet.clear();
Expression.collectAllExpressions(tempSet, queryCondition, Expression.aggregateFunctionSet, Expression.subqueryExpressionSet);
if (!tempSet.isEmpty()) {
// two error messages for two different unsupported cases.
if (!isTopLevel) {
HsqlList columnSet = new OrderedHashSet();
Iterator aggIt = tempSet.iterator();
while (aggIt.hasNext()) {
Expression nextAggr = (Expression) aggIt.next();
Expression.collectAllExpressions(columnSet, nextAggr, Expression.columnExpressionSet, Expression.emptyExpressionSet);
}
Iterator columnIt = columnSet.iterator();
while (columnIt.hasNext()) {
Expression nextColumn = (Expression) columnIt.next();
assert (nextColumn instanceof ExpressionColumn);
ExpressionColumn nextColumnEx = (ExpressionColumn) nextColumn;
String tableName = nextColumnEx.rangeVariable.rangeTable.tableName.name;
String tableAlias = (nextColumnEx.rangeVariable.tableAlias != null) ? nextColumnEx.rangeVariable.tableAlias.name : null;
boolean resolved = false;
for (RangeVariable rv : rangeVariables) {
if (rv.rangeTable.tableName.name.equals(tableName)) {
if (rv.tableAlias == null && tableAlias == null) {
resolved = true;
} else if (rv.tableAlias != null && tableAlias != null) {
resolved = tableAlias.equals(rv.tableAlias.name);
}
}
}
if (!resolved) {
throw Error.error(ErrorCode.X_47001);
}
}
}
// with local columns
throw Error.error(ErrorCode.X_47000);
}
// End of VoltDB extension
}
}
if (havingCondition != null) {
havingCondition.resolveTypes(session, null);
if (havingCondition.getDataType() != Type.SQL_BOOLEAN) {
throw Error.error(ErrorCode.X_42568);
}
}
}
Aggregations