class SubQuery extends Expression {

    private final Query query;
    private Expression expression;

    public SubQuery(Query query) {
        this.query = query;
    }

    @Override
    public Value getValue(ServerSession session) {
        query.setSession(session);
        Result result = query.query(2);
        try {
            int rowcount = result.getRowCount();
            if (rowcount > 1) {
                throw DbException.get(ErrorCode.SCALAR_SUBQUERY_CONTAINS_MORE_THAN_ONE_ROW);
            }
            Value v;
            if (rowcount <= 0) {
                v = ValueNull.INSTANCE;
            } else {
                result.next();
                Value[] values = result.currentRow();
                if (result.getVisibleColumnCount() == 1) {
                    v = values[0];
                } else {
                    v = ValueArray.get(values);
                }
            }
            return v;
        } finally {
            result.close();
        }
    }

    @Override
    public int getType() {
        return getExpression().getType();
    }

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

    @Override
    public int getScale() {
        return getExpression().getScale();
    }

    @Override
    public long getPrecision() {
        return getExpression().getPrecision();
    }

    @Override
    public int getDisplaySize() {
        return getExpression().getDisplaySize();
    }

    @Override
    public String getSQL() {
        return "(" + query.getPlanSQL() + ")";
    }

    private Expression getExpression() {<FILL_FUNCTION_BODY>}

    public Query getQuery() {
        return query;
    }

    @Override
    public int getCost() {
        return query.getCostAsExpression();
    }

    @Override
    public Expression[] getExpressionColumns(ServerSession session) {
        return getExpression().getExpressionColumns(session);
    }

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

        if (expression == null) {
            ArrayList<Expression> expressions = query.getExpressions();
            int columnCount = query.getColumnCount();
            if (columnCount == 1) {
                expression = expressions.get(0);
            } else {
                Expression[] list = new Expression[columnCount];
                for (int i = 0; i < columnCount; i++) {
                    list[i] = expressions.get(i);
                }
                expression = new ExpressionList(list);
            }
        }
        return expression;
    
<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