Search in sources :

Example 1 with AggregateType

use of org.h2.expression.Aggregate.AggregateType in project h2database by h2database.

the class Parser method readAggregate.

private Expression readAggregate(AggregateType aggregateType, String aggregateName) {
    if (currentSelect == null) {
        throw getSyntaxError();
    }
    currentSelect.setGroupQuery();
    Aggregate r;
    if (aggregateType == AggregateType.COUNT) {
        if (readIf("*")) {
            r = new Aggregate(AggregateType.COUNT_ALL, null, currentSelect, false);
        } else {
            boolean distinct = readIf("DISTINCT");
            Expression on = readExpression();
            if (on instanceof Wildcard && !distinct) {
                // PostgreSQL compatibility: count(t.*)
                r = new Aggregate(AggregateType.COUNT_ALL, null, currentSelect, false);
            } else {
                r = new Aggregate(AggregateType.COUNT, on, currentSelect, distinct);
            }
        }
    } else if (aggregateType == AggregateType.GROUP_CONCAT) {
        boolean distinct = readIf("DISTINCT");
        if (equalsToken("GROUP_CONCAT", aggregateName)) {
            r = new Aggregate(AggregateType.GROUP_CONCAT, readExpression(), currentSelect, distinct);
            if (readIf("ORDER")) {
                read("BY");
                r.setOrderByList(parseSimpleOrderList());
            }
            if (readIf("SEPARATOR")) {
                r.setGroupConcatSeparator(readExpression());
            }
        } else if (equalsToken("STRING_AGG", aggregateName)) {
            // PostgreSQL compatibility: string_agg(expression, delimiter)
            r = new Aggregate(AggregateType.GROUP_CONCAT, readExpression(), currentSelect, distinct);
            read(",");
            r.setGroupConcatSeparator(readExpression());
            if (readIf("ORDER")) {
                read("BY");
                r.setOrderByList(parseSimpleOrderList());
            }
        } else {
            r = null;
        }
    } else if (aggregateType == AggregateType.ARRAY_AGG) {
        boolean distinct = readIf("DISTINCT");
        r = new Aggregate(AggregateType.ARRAY_AGG, readExpression(), currentSelect, distinct);
        if (readIf("ORDER")) {
            read("BY");
            r.setOrderByList(parseSimpleOrderList());
        }
    } else {
        boolean distinct = readIf("DISTINCT");
        r = new Aggregate(aggregateType, readExpression(), currentSelect, distinct);
    }
    read(")");
    if (r != null && readIf("FILTER")) {
        read("(");
        read("WHERE");
        Expression condition = readExpression();
        read(")");
        r.setFilterCondition(condition);
    }
    return r;
}
Also used : Expression(org.h2.expression.Expression) ValueExpression(org.h2.expression.ValueExpression) Wildcard(org.h2.expression.Wildcard) UserAggregate(org.h2.engine.UserAggregate) DropAggregate(org.h2.command.ddl.DropAggregate) Aggregate(org.h2.expression.Aggregate) JavaAggregate(org.h2.expression.JavaAggregate) CreateAggregate(org.h2.command.ddl.CreateAggregate)

Example 2 with AggregateType

use of org.h2.expression.Aggregate.AggregateType in project h2database by h2database.

the class AggregateDataDefault method getValue.

@Override
Value getValue(Database database, int dataType, boolean distinct) {
    if (distinct) {
        count = 0;
        groupDistinct(database, dataType);
    }
    Value v = null;
    switch(aggregateType) {
        case SUM:
        case MIN:
        case MAX:
        case BIT_OR:
        case BIT_AND:
        case BOOL_OR:
        case BOOL_AND:
            v = value;
            break;
        case AVG:
            if (value != null) {
                v = divide(value, count);
            }
            break;
        case STDDEV_POP:
            {
                if (count < 1) {
                    return ValueNull.INSTANCE;
                }
                v = ValueDouble.get(Math.sqrt(m2 / count));
                break;
            }
        case STDDEV_SAMP:
            {
                if (count < 2) {
                    return ValueNull.INSTANCE;
                }
                v = ValueDouble.get(Math.sqrt(m2 / (count - 1)));
                break;
            }
        case VAR_POP:
            {
                if (count < 1) {
                    return ValueNull.INSTANCE;
                }
                v = ValueDouble.get(m2 / count);
                break;
            }
        case VAR_SAMP:
            {
                if (count < 2) {
                    return ValueNull.INSTANCE;
                }
                v = ValueDouble.get(m2 / (count - 1));
                break;
            }
        default:
            DbException.throwInternalError("type=" + aggregateType);
    }
    return v == null ? ValueNull.INSTANCE : v.convertTo(dataType);
}
Also used : Value(org.h2.value.Value)

Example 3 with AggregateType

use of org.h2.expression.Aggregate.AggregateType in project h2database by h2database.

the class Parser method readFunction.

private Expression readFunction(Schema schema, String name) {
    if (schema != null) {
        return readJavaFunction(schema, name, true);
    }
    boolean allowOverride = database.isAllowBuiltinAliasOverride();
    if (allowOverride) {
        JavaFunction jf = readJavaFunction(null, name, false);
        if (jf != null) {
            return jf;
        }
    }
    AggregateType agg = getAggregateType(name);
    if (agg != null) {
        return readAggregate(agg, name);
    }
    Function function = Function.getFunction(database, name);
    if (function == null) {
        UserAggregate aggregate = database.findAggregate(name);
        if (aggregate != null) {
            return readJavaAggregate(aggregate);
        }
        if (allowOverride) {
            throw DbException.get(ErrorCode.FUNCTION_NOT_FOUND_1, name);
        }
        return readJavaFunction(null, name, true);
    }
    switch(function.getFunctionType()) {
        case Function.CAST:
            {
                function.setParameter(0, readExpression());
                read("AS");
                Column type = parseColumnWithType(null);
                function.setDataType(type);
                read(")");
                break;
            }
        case Function.CONVERT:
            {
                if (database.getMode().swapConvertFunctionParameters) {
                    Column type = parseColumnWithType(null);
                    function.setDataType(type);
                    read(",");
                    function.setParameter(0, readExpression());
                    read(")");
                } else {
                    function.setParameter(0, readExpression());
                    read(",");
                    Column type = parseColumnWithType(null);
                    function.setDataType(type);
                    read(")");
                }
                break;
            }
        case Function.EXTRACT:
            {
                function.setParameter(0, ValueExpression.get(ValueString.get(currentToken)));
                read();
                read("FROM");
                function.setParameter(1, readExpression());
                read(")");
                break;
            }
        case Function.DATE_ADD:
        case Function.DATE_DIFF:
            {
                if (DateTimeFunctions.isDatePart(currentToken)) {
                    function.setParameter(0, ValueExpression.get(ValueString.get(currentToken)));
                    read();
                } else {
                    function.setParameter(0, readExpression());
                }
                read(",");
                function.setParameter(1, readExpression());
                read(",");
                function.setParameter(2, readExpression());
                read(")");
                break;
            }
        case Function.SUBSTRING:
            {
                // Different variants include:
                // SUBSTRING(X,1)
                // SUBSTRING(X,1,1)
                // SUBSTRING(X FROM 1 FOR 1) -- Postgres
                // SUBSTRING(X FROM 1) -- Postgres
                // SUBSTRING(X FOR 1) -- Postgres
                function.setParameter(0, readExpression());
                if (readIf("FROM")) {
                    function.setParameter(1, readExpression());
                    if (readIf("FOR")) {
                        function.setParameter(2, readExpression());
                    }
                } else if (readIf("FOR")) {
                    function.setParameter(1, ValueExpression.get(ValueInt.get(0)));
                    function.setParameter(2, readExpression());
                } else {
                    read(",");
                    function.setParameter(1, readExpression());
                    if (readIf(",")) {
                        function.setParameter(2, readExpression());
                    }
                }
                read(")");
                break;
            }
        case Function.POSITION:
            {
                // can't read expression because IN would be read too early
                function.setParameter(0, readConcat());
                if (!readIf(",")) {
                    read("IN");
                }
                function.setParameter(1, readExpression());
                read(")");
                break;
            }
        case Function.TRIM:
            {
                Expression space = null;
                if (readIf("LEADING")) {
                    function = Function.getFunction(database, "LTRIM");
                    if (!readIf("FROM")) {
                        space = readExpression();
                        read("FROM");
                    }
                } else if (readIf("TRAILING")) {
                    function = Function.getFunction(database, "RTRIM");
                    if (!readIf("FROM")) {
                        space = readExpression();
                        read("FROM");
                    }
                } else if (readIf("BOTH")) {
                    if (!readIf("FROM")) {
                        space = readExpression();
                        read("FROM");
                    }
                }
                Expression p0 = readExpression();
                if (readIf(",")) {
                    space = readExpression();
                } else if (readIf("FROM")) {
                    space = p0;
                    p0 = readExpression();
                }
                function.setParameter(0, p0);
                if (space != null) {
                    function.setParameter(1, space);
                }
                read(")");
                break;
            }
        case Function.TABLE:
        case Function.TABLE_DISTINCT:
            {
                int i = 0;
                ArrayList<Column> columns = New.arrayList();
                do {
                    String columnName = readAliasIdentifier();
                    Column column = parseColumnWithType(columnName);
                    columns.add(column);
                    read("=");
                    function.setParameter(i, readExpression());
                    i++;
                } while (readIfMore(true));
                TableFunction tf = (TableFunction) function;
                tf.setColumns(columns);
                break;
            }
        case Function.ROW_NUMBER:
            read(")");
            read("OVER");
            read("(");
            read(")");
            if (currentSelect == null && currentPrepared == null) {
                throw getSyntaxError();
            }
            return new Rownum(currentSelect == null ? currentPrepared : currentSelect);
        default:
            if (!readIf(")")) {
                int i = 0;
                do {
                    function.setParameter(i++, readExpression());
                } while (readIfMore(true));
            }
    }
    function.doneWithParameters();
    return function;
}
Also used : Function(org.h2.expression.Function) TableFunction(org.h2.expression.TableFunction) JavaFunction(org.h2.expression.JavaFunction) UserAggregate(org.h2.engine.UserAggregate) AlterTableRenameColumn(org.h2.command.ddl.AlterTableRenameColumn) AlterTableAlterColumn(org.h2.command.ddl.AlterTableAlterColumn) Column(org.h2.table.Column) ExpressionColumn(org.h2.expression.ExpressionColumn) IndexColumn(org.h2.table.IndexColumn) Expression(org.h2.expression.Expression) ValueExpression(org.h2.expression.ValueExpression) ArrayList(java.util.ArrayList) JavaFunction(org.h2.expression.JavaFunction) TableFunction(org.h2.expression.TableFunction) ValueString(org.h2.value.ValueString) AggregateType(org.h2.expression.Aggregate.AggregateType) Rownum(org.h2.expression.Rownum) AlterTableRenameConstraint(org.h2.command.ddl.AlterTableRenameConstraint) AlterTableAddConstraint(org.h2.command.ddl.AlterTableAddConstraint) AlterTableDropConstraint(org.h2.command.ddl.AlterTableDropConstraint)

Aggregations

UserAggregate (org.h2.engine.UserAggregate)2 Expression (org.h2.expression.Expression)2 ValueExpression (org.h2.expression.ValueExpression)2 ArrayList (java.util.ArrayList)1 AlterTableAddConstraint (org.h2.command.ddl.AlterTableAddConstraint)1 AlterTableAlterColumn (org.h2.command.ddl.AlterTableAlterColumn)1 AlterTableDropConstraint (org.h2.command.ddl.AlterTableDropConstraint)1 AlterTableRenameColumn (org.h2.command.ddl.AlterTableRenameColumn)1 AlterTableRenameConstraint (org.h2.command.ddl.AlterTableRenameConstraint)1 CreateAggregate (org.h2.command.ddl.CreateAggregate)1 DropAggregate (org.h2.command.ddl.DropAggregate)1 Aggregate (org.h2.expression.Aggregate)1 AggregateType (org.h2.expression.Aggregate.AggregateType)1 ExpressionColumn (org.h2.expression.ExpressionColumn)1 Function (org.h2.expression.Function)1 JavaAggregate (org.h2.expression.JavaAggregate)1 JavaFunction (org.h2.expression.JavaFunction)1 Rownum (org.h2.expression.Rownum)1 TableFunction (org.h2.expression.TableFunction)1 Wildcard (org.h2.expression.Wildcard)1