Search in sources :

Example 1 with ArrayListIdentity

use of org.hsqldb_voltpatches.lib.ArrayListIdentity in project voltdb by VoltDB.

the class ExpressionColumn method resolveColumnReferences.

@Override
public HsqlList resolveColumnReferences(RangeVariable[] rangeVarArray, int rangeCount, HsqlList unresolvedSet, boolean acceptsSequences) {
    switch(opType) {
        case OpTypes.SEQUENCE:
            if (!acceptsSequences) {
                throw Error.error(ErrorCode.X_42598);
            }
            break;
        case OpTypes.MULTICOLUMN:
        case OpTypes.DYNAMIC_PARAM:
        case OpTypes.ASTERISK:
        case OpTypes.SIMPLE_COLUMN:
        case OpTypes.COALESCE:
            break;
        case OpTypes.PARAMETER:
        case OpTypes.VARIABLE:
        case OpTypes.COLUMN:
            if (rangeVariable != null) {
                return unresolvedSet;
            }
            // Look in all the range variables.  We may
            // find this column more than once, and that
            // would be an error See ENG-9367.
            //
            // Note that we can't actually commit to a resolution
            // until we have looked everywhere.  This means we need to
            // store up potential resolutions until we have looked at all
            // the range variables.  If we find just one, we finally
            // resolve it. below.
            java.util.Set<ColumnReferenceResolution> usingResolutions = new java.util.TreeSet<>(m_comparator);
            java.util.Set<ColumnReferenceResolution> rangeVariableResolutions = new java.util.TreeSet<>(m_comparator);
            ColumnReferenceResolution lastRes = null;
            int foundSize = 0;
            for (int i = 0; i < rangeCount; i++) {
                RangeVariable rangeVar = rangeVarArray[i];
                if (rangeVar == null) {
                    continue;
                }
                ColumnReferenceResolution resolution = resolveColumnReference(rangeVar);
                if (resolution != null) {
                    if (resolution instanceof ExpressionColumnReferenceResolution) {
                        if (usingResolutions.add(resolution)) {
                            foundSize += 1;
                        }
                    } else {
                        assert (resolution instanceof RangeVariableColumnReferenceResolution);
                        if (rangeVariableResolutions.add(resolution)) {
                            foundSize += 1;
                        }
                    }
                    // Cache this in case this is the only resolution.
                    lastRes = resolution;
                }
            }
            if (foundSize == 1) {
                lastRes.finallyResolve();
                return unresolvedSet;
            }
            if (foundSize > 1) {
                StringBuffer sb = new StringBuffer();
                sb.append(String.format("Column \"%s\" is ambiguous.  It's in tables: ", columnName));
                String sep = "";
                //       in name order.
                if (usingResolutions.size() > 0) {
                    sb.append("USING(");
                    appendNameList(sb, usingResolutions, "");
                    sb.append(")");
                    sep = ", ";
                }
                appendNameList(sb, rangeVariableResolutions, sep);
                throw new HsqlException(sb.toString(), "", 0);
            }
            // to the unresolved set.
            if (unresolvedSet == null) {
                unresolvedSet = new ArrayListIdentity();
            }
            unresolvedSet.add(this);
    }
    // IF we got to here, return the set of unresolved columns.
    return unresolvedSet;
}
Also used : ArrayListIdentity(org.hsqldb_voltpatches.lib.ArrayListIdentity)

Example 2 with ArrayListIdentity

use of org.hsqldb_voltpatches.lib.ArrayListIdentity 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;
}
Also used : ArrayListIdentity(org.hsqldb_voltpatches.lib.ArrayListIdentity) HsqlList(org.hsqldb_voltpatches.lib.HsqlList)

Example 3 with ArrayListIdentity

use of org.hsqldb_voltpatches.lib.ArrayListIdentity 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);
            }
        }
    }
}
Also used : ArrayListIdentity(org.hsqldb_voltpatches.lib.ArrayListIdentity) HsqlList(org.hsqldb_voltpatches.lib.HsqlList)

Aggregations

ArrayListIdentity (org.hsqldb_voltpatches.lib.ArrayListIdentity)3 HsqlList (org.hsqldb_voltpatches.lib.HsqlList)2