static void checkColumnsResolved(HsqlList set) {

    if (set != null && !set.isEmpty()) {
      StringBuffer sb = new StringBuffer();
      Expression e = (Expression) set.get(0);

      if (e instanceof ExpressionColumn) {
        ExpressionColumn c = (ExpressionColumn) e;

        if (c.schema != null) {
          sb.append(c.schema + '.');
        }

        if (c.tableName != null) {
          sb.append(c.tableName + '.');
        }

        throw Error.error(ErrorCode.X_42501, sb.toString() + c.getColumnName());
      } else {
        OrderedHashSet newSet = new OrderedHashSet();

        e.collectAllExpressions(
            newSet, Expression.columnExpressionSet, Expression.emptyExpressionSet);

        // throw with column name
        checkColumnsResolved(newSet);

        // throw anyway if not found
        throw Error.error(ErrorCode.X_42501);
      }
    }
  }
  public void resolveRangeTable(
      Session session,
      RangeVariable[] rangeVariables,
      int rangeCount,
      RangeVariable[] outerRanges) {

    Table table = rangeTable;
    SubQuery subQuery = table.getSubQuery();

    if (subQuery != null && !subQuery.isResolved()) {
      if (subQuery.dataExpression != null) {
        HsqlList unresolved =
            subQuery.dataExpression.resolveColumnReferences(
                session, RangeVariable.emptyArray, null);

        if (unresolved != null) {
          unresolved =
              subQuery.dataExpression.resolveColumnReferences(
                  session, rangeVariables, rangeCount, null, true);
        }

        if (unresolved != null) {
          unresolved = subQuery.dataExpression.resolveColumnReferences(session, outerRanges, null);
        }

        if (unresolved != null) {
          throw Error.error(ErrorCode.X_42501, ((Expression) unresolved.get(0)).getSQL());
        }

        subQuery.dataExpression.resolveTypes(session, null);
        setRangeTableVariables();
      }

      if (subQuery.queryExpression != null) {
        subQuery.queryExpression.resolveReferences(session, outerRanges);

        HsqlList list = subQuery.queryExpression.getUnresolvedExpressions();

        // todo resolve against i ranges
        HsqlList unresolved =
            Expression.resolveColumnSet(session, rangeVariables, rangeCount, list, null);

        if (unresolved != null) {
          throw Error.error(ErrorCode.X_42501, ((Expression) unresolved.get(0)).getSQL());
        }

        subQuery.queryExpression.resolveTypes(session);
        subQuery.prepareTable(session);
        subQuery.setCorrelated();
        setRangeTableVariables();
      }
    }
  }
  /** Tells whether the given list contains the same data as the vector */
  private boolean equalsVector(HsqlList list, Vector vector) {

    if (list.size() != vector.size()) {
      return false;
    }

    org.hsqldb.lib.Iterator listElements = list.iterator();
    Enumeration vectorElements = vector.elements();
    Object listObj = null;
    Object vectorObj = null;

    while (listElements.hasNext()) {
      listObj = listElements.next();
      vectorObj = vectorElements.nextElement();

      if (!listObj.equals(vectorObj)) {
        return false;
      }
    }

    return true;
  }
  public HsqlList resolveColumnReferences(
      RangeVariable[] rangeVarArray,
      int rangeCount,
      HsqlList unresolvedSet,
      boolean acceptsSequences) {

    if (unresolvedSet == null) {
      unresolvedSet = new ArrayListIdentity();
    }

    unresolvedSet.add(this);

    return unresolvedSet;
  }
  public HsqlList resolveColumnReferences(
      Session session,
      RangeVariable[] rangeVarArray,
      int rangeCount,
      HsqlList unresolvedSet,
      boolean acceptsSequences) {

    switch (opType) {
      case OpTypes.SEQUENCE:
        if (!acceptsSequences) {
          throw Error.error(ErrorCode.X_42598);
        }
        break;

      case OpTypes.ROWNUM:
      case OpTypes.MULTICOLUMN:
      case OpTypes.DYNAMIC_PARAM:
      case OpTypes.ASTERISK:
      case OpTypes.SIMPLE_COLUMN:
      case OpTypes.COALESCE:
      case OpTypes.DIAGNOSTICS_VARIABLE:
        break;

      case OpTypes.COLUMN:
      case OpTypes.PARAMETER:
      case OpTypes.VARIABLE:
        {
          boolean resolved = false;
          boolean tableQualified = tableName != null;

          if (rangeVariable != null) {
            return unresolvedSet;
          }

          for (int i = 0; i < rangeCount; i++) {
            RangeVariable rangeVar = rangeVarArray[i];

            if (rangeVar == null) {
              continue;
            }

            if (resolved) {
              if (session.database.sqlEnforceRefs) {
                if (resolvesDuplicateColumnReference(rangeVar)) {
                  String message = getColumnName();

                  if (alias != null) {
                    StringBuffer sb = new StringBuffer(message);

                    sb.append(' ').append(Tokens.T_AS).append(' ').append(alias.getStatementName());

                    message = sb.toString();
                  }

                  throw Error.error(ErrorCode.X_42580, message);
                }
              }
            } else {
              if (resolveColumnReference(rangeVar)) {
                if (tableQualified) {
                  return unresolvedSet;
                }

                resolved = true;

                continue;
              }
            }
          }

          if (resolved) {
            return unresolvedSet;
          }

          if (session.database.sqlSyntaxOra) {
            if (acceptsSequences && tableName != null) {
              if (Tokens.T_CURRVAL.equals(columnName)) {
                NumberSequence seq =
                    session.database.schemaManager.getSequence(
                        tableName, session.getSchemaName(schema), false);

                if (seq != null) {
                  opType = OpTypes.SEQUENCE_CURRENT;
                  dataType = seq.getDataType();
                  sequence = seq;
                  schema = null;
                  tableName = null;
                  columnName = null;
                  resolved = true;
                }
              } else if (Tokens.T_NEXTVAL.equals(columnName)) {
                NumberSequence seq =
                    session.database.schemaManager.getSequence(
                        tableName, session.getSchemaName(schema), false);

                if (seq != null) {
                  opType = OpTypes.SEQUENCE;
                  dataType = seq.getDataType();
                  sequence = seq;
                  schema = null;
                  tableName = null;
                  columnName = null;
                  resolved = true;
                }
              }
            }
          }

          if (resolved) {
            return unresolvedSet;
          }

          if (unresolvedSet == null) {
            unresolvedSet = new ArrayListIdentity();
          }

          unresolvedSet.add(this);
        }
    }

    return unresolvedSet;
  }