class Parameter extends Expression implements CommandParameter {

    private Value value;
    private Column column;
    private final int index;

    public Parameter(int index) {
        this.index = index;
    }

    @Override
    public String getSQL() {
        return "?" + (index + 1);
    }

    @Override
    public int getIndex() {
        return index;
    }

    @Override
    public void setValue(Value v, boolean closeOld) {
        // don't need to close the old value as temporary files are anyway removed
        this.value = v;
    }

    @Override
    public void setValue(Value v) {
        this.value = v;
    }

    @Override
    public Value getValue() {
        if (value == null) {
            // to allow parameters in function tables
            return ValueNull.INSTANCE;
        }
        return value;
    }

    @Override
    public Value getValue(ServerSession session) {
        return getValue();
    }

    @Override
    public int getType() {
        if (value != null) {
            return value.getType();
        }
        if (column != null) {
            return column.getType();
        }
        return Value.UNKNOWN;
    }

    @Override
    public void checkSet() {
        if (value == null) {
            throw DbException.get(ErrorCode.PARAMETER_NOT_SET_1, "#" + (index + 1));
        }
    }

    @Override
    public boolean isValueSet() {
        return value != null;
    }

    @Override
    public Expression optimize(ServerSession session) {
        return this;
    }

    @Override
    public boolean isConstant() {
        return false;
    }

    @Override
    public int getScale() {
        if (value != null) {
            return value.getScale();
        }
        if (column != null) {
            return column.getScale();
        }
        return 0;
    }

    @Override
    public long getPrecision() {
        if (value != null) {
            return value.getPrecision();
        }
        if (column != null) {
            return column.getPrecision();
        }
        return 0;
    }

    @Override
    public int getDisplaySize() {
        if (value != null) {
            return value.getDisplaySize();
        }
        if (column != null) {
            return column.getDisplaySize();
        }
        return 0;
    }

    @Override
    public int getNullable() {<FILL_FUNCTION_BODY>}

    @Override
    public int getCost() {
        return 0;
    }

    @Override
    public Expression getNotIfPossible(ServerSession session) {
        return new Comparison(session, Comparison.EQUAL, this,
                ValueExpression.get(ValueBoolean.get(false)));
    }

    public void setColumn(Column column) {
        this.column = column;
    }

    @Override
    public <R> R accept(ExpressionVisitor<R> visitor) {
        return visitor.visitParameter(this);
    }
}

        if (column != null) {
            return column.isNullable() ? Column.NULLABLE : Column.NOT_NULLABLE;
        }
        return super.getNullable();
    
<methods>public non-sealed void <init>() ,public R accept(ExpressionVisitor<R>) ,public void addFilterConditions(com.lealone.sql.optimizer.TableFilter, boolean) ,public void createIndexConditions(com.lealone.db.session.ServerSession, com.lealone.sql.optimizer.TableFilter) ,public java.lang.String getAlias() ,public boolean getBooleanValue(com.lealone.db.session.ServerSession) ,public java.lang.String getColumnName() ,public void getColumns(Set<?>) ,public abstract int getCost() ,public void getDependencies(Set<?>) ,public abstract int getDisplaySize() ,public com.lealone.sql.expression.Expression[] getExpressionColumns(com.lealone.db.session.ServerSession) ,public static com.lealone.sql.expression.Expression[] getExpressionColumns(com.lealone.db.session.ServerSession, com.lealone.db.value.ValueArray) ,public static com.lealone.sql.expression.Expression[] getExpressionColumns(com.lealone.db.session.ServerSession, java.sql.ResultSet) ,public com.lealone.sql.expression.Expression getNonAliasExpression() ,public com.lealone.sql.expression.Expression getNotIfPossible(com.lealone.db.session.ServerSession) ,public int getNullable() ,public abstract long getPrecision() ,public abstract java.lang.String getSQL() ,public abstract int getScale() ,public java.lang.String getSchemaName() ,public java.lang.String getTableName() ,public abstract int getType() ,public com.lealone.db.value.Value getValue(com.lealone.db.session.Session) ,public abstract com.lealone.db.value.Value getValue(com.lealone.db.session.ServerSession) ,public boolean isAutoIncrement() ,public boolean isConstant() ,public boolean isEvaluatable() ,public boolean isValueSet() ,public boolean isWildcard() ,public void mapColumns(com.lealone.sql.optimizer.ColumnResolver, int) ,public abstract com.lealone.sql.expression.Expression optimize(com.lealone.db.session.ServerSession) ,public com.lealone.sql.expression.Expression optimize(com.lealone.db.session.Session) ,public java.lang.String toString() ,public void updateAggregate(com.lealone.db.session.ServerSession) <variables>private boolean addedToFilter