class ACount extends BuiltInAggregate {

    public ACount(int type, Expression on, Select select, boolean distinct) {
        super(type, on, select, distinct);
    }

    @Override
    public Expression optimize(ServerSession session) {<FILL_FUNCTION_BODY>}

    @Override
    protected AggregateData createAggregateData() {
        return new AggregateDataCount();
    }

    @Override
    public String getSQL() {
        return getSQL("COUNT");
    }

    public class AggregateDataCount extends AggregateData {

        private long count;
        private ValueHashMap<AggregateDataCount> distinctValues;

        public long getCount() {
            return count;
        }

        public void setCount(long count) {
            this.count = count;
        }

        public ValueHashMap<AggregateDataCount> getDistinctValues() {
            return distinctValues;
        }

        public void setDistinctValues(ValueHashMap<AggregateDataCount> distinctValues) {
            this.distinctValues = distinctValues;
        }

        public boolean isDistinct() {
            return distinct;
        }

        @Override
        public void add(ServerSession session, Value v) {
            if (v == ValueNull.INSTANCE) {
                return;
            }
            count++;
            if (distinct) {
                if (distinctValues == null) {
                    distinctValues = ValueHashMap.newInstance();
                }
                distinctValues.put(v, this);
            }
        }

        @Override
        Value getValue(ServerSession session) {
            if (distinct) {
                if (distinctValues != null) {
                    count = distinctValues.size();
                } else {
                    count = 0;
                }
            }
            return ValueLong.get(count);
        }
    }
}

        super.optimize(session);
        dataType = Value.LONG;
        scale = 0;
        precision = ValueLong.PRECISION;
        displaySize = ValueLong.DISPLAY_SIZE;
        return this;
    
<methods>public void <init>(int, com.lealone.sql.expression.Expression, com.lealone.sql.query.Select, boolean) ,public R accept(ExpressionVisitor<R>) ,public int getAType() ,public com.lealone.sql.expression.aggregate.AggregateData getAggregateData() ,public int getCost() ,public int getDisplaySize() ,public com.lealone.sql.expression.Expression getOn() ,public long getPrecision() ,public int getScale() ,public com.lealone.db.value.Value getValue(com.lealone.db.session.ServerSession) ,public boolean isOptimizable(com.lealone.db.table.Table) ,public com.lealone.sql.expression.Expression optimize(com.lealone.db.session.ServerSession) ,public void updateAggregate(com.lealone.db.session.ServerSession) <variables>protected int displaySize,protected final non-sealed boolean distinct,protected com.lealone.sql.expression.Expression on,protected long precision,protected int scale,protected final non-sealed int type