/** Creates a OpTypes.SEQUENCE expression */
  ExpressionColumn(NumberSequence sequence, int opType) {

    super(opType);

    this.sequence = sequence;
    dataType = sequence.getDataType();
  }
  void collectObjectNames(Set set) {

    switch (opType) {
      case OpTypes.SEQUENCE:
        HsqlName name = sequence.getName();

        set.add(name);

        return;

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

      case OpTypes.PARAMETER:
      case OpTypes.VARIABLE:
        break;

      case OpTypes.COLUMN:
        set.add(column.getName());

        if (column.getName().parent != null) {
          set.add(column.getName().parent);
        }

        return;
    }
  }
  public Object getSequenceValue(NumberSequence sequence) throws HsqlException {

    if (sequenceMap == null) {
      sequenceMap = new HashMap();
      sequenceUpdateSet = new OrderedHashSet();
    }

    HsqlName key = sequence.getName();
    Object value = sequenceMap.get(key);

    if (value == null) {
      value = sequence.getValueObject();

      sequenceMap.put(key, value);
      sequenceUpdateSet.add(sequence);
    }

    return value;
  }
  protected String describe(Session session, int blanks) {

    StringBuffer sb = new StringBuffer(64);

    sb.append('\n');

    for (int i = 0; i < blanks; i++) {
      sb.append(' ');
    }

    switch (opType) {
      case OpTypes.DEFAULT:
        sb.append(Tokens.T_DEFAULT);
        break;

      case OpTypes.ASTERISK:
        sb.append("OpTypes.ASTERISK ");
        break;

      case OpTypes.VARIABLE:
        sb.append("VARIABLE: ");
        sb.append(column.getName().name);
        break;

      case OpTypes.PARAMETER:
        sb.append(Tokens.T_PARAMETER).append(": ");
        sb.append(column.getName().name);
        break;

      case OpTypes.COALESCE:
        sb.append(Tokens.T_COLUMN).append(": ");
        sb.append(columnName);

        if (alias != null) {
          sb.append(" AS ").append(alias.name);
        }
        break;

      case OpTypes.COLUMN:
        sb.append(Tokens.T_COLUMN).append(": ");
        sb.append(column.getName().getSchemaQualifiedStatementName());

        if (alias != null) {
          sb.append(" AS ").append(alias.name);
        }
        break;

      case OpTypes.DYNAMIC_PARAM:
        sb.append("DYNAMIC PARAM: ");
        sb.append(", TYPE = ").append(dataType.getNameString());
        break;

      case OpTypes.SEQUENCE:
        sb.append(Tokens.T_SEQUENCE).append(": ");
        sb.append(sequence.getName().name);
        break;

      case OpTypes.MULTICOLUMN:

        // shouldn't get here
    }

    return sb.toString();
  }
  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;
  }