Search in sources :

Example 1 with Aggregate

use of org.h2.api.Aggregate in project h2database by h2database.

the class Parser method parseCreate.

private Prepared parseCreate() {
    boolean orReplace = false;
    if (readIf("OR")) {
        read("REPLACE");
        orReplace = true;
    }
    boolean force = readIf("FORCE");
    if (readIf("VIEW")) {
        return parseCreateView(force, orReplace);
    } else if (readIf("ALIAS")) {
        return parseCreateFunctionAlias(force);
    } else if (readIf("SEQUENCE")) {
        return parseCreateSequence();
    } else if (readIf("USER")) {
        return parseCreateUser();
    } else if (readIf("TRIGGER")) {
        return parseCreateTrigger(force);
    } else if (readIf("ROLE")) {
        return parseCreateRole();
    } else if (readIf("SCHEMA")) {
        return parseCreateSchema();
    } else if (readIf("CONSTANT")) {
        return parseCreateConstant();
    } else if (readIf("DOMAIN")) {
        return parseCreateUserDataType();
    } else if (readIf("TYPE")) {
        return parseCreateUserDataType();
    } else if (readIf("DATATYPE")) {
        return parseCreateUserDataType();
    } else if (readIf("AGGREGATE")) {
        return parseCreateAggregate(force);
    } else if (readIf("LINKED")) {
        return parseCreateLinkedTable(false, false, force);
    }
    // tables or linked tables
    boolean memory = false, cached = false;
    if (readIf("MEMORY")) {
        memory = true;
    } else if (readIf("CACHED")) {
        cached = true;
    }
    if (readIf("LOCAL")) {
        read("TEMPORARY");
        if (readIf("LINKED")) {
            return parseCreateLinkedTable(true, false, force);
        }
        read("TABLE");
        return parseCreateTable(true, false, cached);
    } else if (readIf("GLOBAL")) {
        read("TEMPORARY");
        if (readIf("LINKED")) {
            return parseCreateLinkedTable(true, true, force);
        }
        read("TABLE");
        return parseCreateTable(true, true, cached);
    } else if (readIf("TEMP") || readIf("TEMPORARY")) {
        if (readIf("LINKED")) {
            return parseCreateLinkedTable(true, true, force);
        }
        read("TABLE");
        return parseCreateTable(true, true, cached);
    } else if (readIf("TABLE")) {
        if (!cached && !memory) {
            cached = database.getDefaultTableType() == Table.TYPE_CACHED;
        }
        return parseCreateTable(false, false, cached);
    } else if (readIf("SYNONYM")) {
        return parseCreateSynonym(orReplace);
    } else {
        boolean hash = false, primaryKey = false;
        boolean unique = false, spatial = false;
        String indexName = null;
        Schema oldSchema = null;
        boolean ifNotExists = false;
        if (readIf("PRIMARY")) {
            read("KEY");
            if (readIf("HASH")) {
                hash = true;
            }
            primaryKey = true;
            if (!isToken("ON")) {
                ifNotExists = readIfNotExists();
                indexName = readIdentifierWithSchema(null);
                oldSchema = getSchema();
            }
        } else {
            if (readIf("UNIQUE")) {
                unique = true;
            }
            if (readIf("HASH")) {
                hash = true;
            }
            if (readIf("SPATIAL")) {
                spatial = true;
            }
            if (readIf("INDEX")) {
                if (!isToken("ON")) {
                    ifNotExists = readIfNotExists();
                    indexName = readIdentifierWithSchema(null);
                    oldSchema = getSchema();
                }
            } else {
                throw getSyntaxError();
            }
        }
        read("ON");
        String tableName = readIdentifierWithSchema();
        checkSchema(oldSchema);
        CreateIndex command = new CreateIndex(session, getSchema());
        command.setIfNotExists(ifNotExists);
        command.setPrimaryKey(primaryKey);
        command.setTableName(tableName);
        command.setUnique(unique);
        command.setIndexName(indexName);
        command.setComment(readCommentIf());
        read("(");
        command.setIndexColumns(parseIndexColumnList());
        if (readIf("USING")) {
            if (hash) {
                throw getSyntaxError();
            }
            if (spatial) {
                throw getSyntaxError();
            }
            if (readIf("BTREE")) {
            // default
            } else if (readIf("RTREE")) {
                spatial = true;
            } else if (readIf("HASH")) {
                hash = true;
            } else {
                throw getSyntaxError();
            }
        }
        command.setHash(hash);
        command.setSpatial(spatial);
        return command;
    }
}
Also used : CreateIndex(org.h2.command.ddl.CreateIndex) DropSchema(org.h2.command.ddl.DropSchema) CreateSchema(org.h2.command.ddl.CreateSchema) Schema(org.h2.schema.Schema) ValueString(org.h2.value.ValueString)

Example 2 with Aggregate

use of org.h2.api.Aggregate in project h2database by h2database.

the class Parser method parseEndOfQuery.

private void parseEndOfQuery(Query command) {
    if (readIf("ORDER")) {
        read("BY");
        Select oldSelect = currentSelect;
        if (command instanceof Select) {
            currentSelect = (Select) command;
        }
        ArrayList<SelectOrderBy> orderList = New.arrayList();
        do {
            boolean canBeNumber = true;
            if (readIf("=")) {
                canBeNumber = false;
            }
            SelectOrderBy order = new SelectOrderBy();
            Expression expr = readExpression();
            if (canBeNumber && expr instanceof ValueExpression && expr.getType() == Value.INT) {
                order.columnIndexExpr = expr;
            } else if (expr instanceof Parameter) {
                recompileAlways = true;
                order.columnIndexExpr = expr;
            } else {
                order.expression = expr;
            }
            if (readIf("DESC")) {
                order.descending = true;
            } else {
                readIf("ASC");
            }
            if (readIf("NULLS")) {
                if (readIf("FIRST")) {
                    order.nullsFirst = true;
                } else {
                    read("LAST");
                    order.nullsLast = true;
                }
            }
            orderList.add(order);
        } while (readIf(","));
        command.setOrder(orderList);
        currentSelect = oldSelect;
    }
    // make sure aggregate functions will not work here
    Select temp = currentSelect;
    currentSelect = null;
    // http://sqlpro.developpez.com/SQL2008/
    if (readIf("OFFSET")) {
        command.setOffset(readExpression().optimize(session));
        if (!readIf("ROW")) {
            readIf("ROWS");
        }
    }
    if (readIf("FETCH")) {
        if (!readIf("FIRST")) {
            read("NEXT");
        }
        if (readIf("ROW")) {
            command.setLimit(ValueExpression.get(ValueInt.get(1)));
        } else {
            Expression limit = readExpression().optimize(session);
            command.setLimit(limit);
            if (!readIf("ROW")) {
                read("ROWS");
            }
        }
        read("ONLY");
    }
    currentSelect = temp;
    if (readIf("LIMIT")) {
        temp = currentSelect;
        // make sure aggregate functions will not work here
        currentSelect = null;
        Expression limit = readExpression().optimize(session);
        command.setLimit(limit);
        if (readIf("OFFSET")) {
            Expression offset = readExpression().optimize(session);
            command.setOffset(offset);
        } else if (readIf(",")) {
            // MySQL: [offset, ] rowcount
            Expression offset = limit;
            limit = readExpression().optimize(session);
            command.setOffset(offset);
            command.setLimit(limit);
        }
        if (readIf("SAMPLE_SIZE")) {
            Expression sampleSize = readExpression().optimize(session);
            command.setSampleSize(sampleSize);
        }
        currentSelect = temp;
    }
    if (readIf("FOR")) {
        if (readIf("UPDATE")) {
            if (readIf("OF")) {
                do {
                    readIdentifierWithSchema();
                } while (readIf(","));
            } else if (readIf("NOWAIT")) {
            // TODO parser: select for update nowait: should not wait
            }
            command.setForUpdate(true);
        } else if (readIf("READ") || readIf("FETCH")) {
            read("ONLY");
        }
    }
    if (database.getMode().isolationLevelInSelectOrInsertStatement) {
        parseIsolationClause();
    }
}
Also used : SelectOrderBy(org.h2.command.dml.SelectOrderBy) Expression(org.h2.expression.Expression) ValueExpression(org.h2.expression.ValueExpression) ValueExpression(org.h2.expression.ValueExpression) ConditionInSelect(org.h2.expression.ConditionInSelect) Select(org.h2.command.dml.Select) Parameter(org.h2.expression.Parameter) ConditionInParameter(org.h2.expression.ConditionInParameter)

Example 3 with Aggregate

use of org.h2.api.Aggregate in project h2database by h2database.

the class Parser method readJavaAggregate.

private JavaAggregate readJavaAggregate(UserAggregate aggregate) {
    ArrayList<Expression> params = New.arrayList();
    do {
        params.add(readExpression());
    } while (readIfMore(true));
    Expression filterCondition;
    if (readIf("FILTER")) {
        read("(");
        read("WHERE");
        filterCondition = readExpression();
        read(")");
    } else {
        filterCondition = null;
    }
    Expression[] list = params.toArray(new Expression[0]);
    JavaAggregate agg = new JavaAggregate(aggregate, list, currentSelect, filterCondition);
    currentSelect.setGroupQuery();
    return agg;
}
Also used : Expression(org.h2.expression.Expression) ValueExpression(org.h2.expression.ValueExpression) JavaAggregate(org.h2.expression.JavaAggregate)

Example 4 with Aggregate

use of org.h2.api.Aggregate 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 5 with Aggregate

use of org.h2.api.Aggregate in project h2database by h2database.

the class Select method queryWithoutCache.

@Override
protected ResultInterface queryWithoutCache(int maxRows, ResultTarget target) {
    int limitRows = maxRows == 0 ? -1 : maxRows;
    if (limitExpr != null) {
        Value v = limitExpr.getValue(session);
        int l = v == ValueNull.INSTANCE ? -1 : v.getInt();
        if (limitRows < 0) {
            limitRows = l;
        } else if (l >= 0) {
            limitRows = Math.min(l, limitRows);
        }
    }
    boolean lazy = session.isLazyQueryExecution() && target == null && !isForUpdate && !isQuickAggregateQuery && limitRows != 0 && offsetExpr == null && isReadOnly();
    int columnCount = expressions.size();
    LocalResult result = null;
    if (!lazy && (target == null || !session.getDatabase().getSettings().optimizeInsertFromSelect)) {
        result = createLocalResult(result);
    }
    if (sort != null && (!sortUsingIndex || distinct)) {
        result = createLocalResult(result);
        result.setSortOrder(sort);
    }
    if (distinct && !isDistinctQuery) {
        result = createLocalResult(result);
        result.setDistinct();
    }
    if (randomAccessResult) {
        result = createLocalResult(result);
    }
    if (isGroupQuery && !isGroupSortedQuery) {
        result = createLocalResult(result);
    }
    if (!lazy && (limitRows >= 0 || offsetExpr != null)) {
        result = createLocalResult(result);
    }
    topTableFilter.startQuery(session);
    topTableFilter.reset();
    boolean exclusive = isForUpdate && !isForUpdateMvcc;
    if (isForUpdateMvcc) {
        if (isGroupQuery) {
            throw DbException.getUnsupportedException("MVCC=TRUE && FOR UPDATE && GROUP");
        } else if (distinct) {
            throw DbException.getUnsupportedException("MVCC=TRUE && FOR UPDATE && DISTINCT");
        } else if (isQuickAggregateQuery) {
            throw DbException.getUnsupportedException("MVCC=TRUE && FOR UPDATE && AGGREGATE");
        } else if (topTableFilter.getJoin() != null) {
            throw DbException.getUnsupportedException("MVCC=TRUE && FOR UPDATE && JOIN");
        }
    }
    topTableFilter.lock(session, exclusive, exclusive);
    ResultTarget to = result != null ? result : target;
    lazy &= to == null;
    LazyResult lazyResult = null;
    if (limitRows != 0) {
        try {
            if (isQuickAggregateQuery) {
                queryQuick(columnCount, to);
            } else if (isGroupQuery) {
                if (isGroupSortedQuery) {
                    lazyResult = queryGroupSorted(columnCount, to);
                } else {
                    queryGroup(columnCount, result);
                }
            } else if (isDistinctQuery) {
                queryDistinct(to, limitRows);
            } else {
                lazyResult = queryFlat(columnCount, to, limitRows);
            }
        } finally {
            if (!lazy) {
                resetJoinBatchAfterQuery();
            }
        }
    }
    assert lazy == (lazyResult != null) : lazy;
    if (lazyResult != null) {
        if (limitRows > 0) {
            lazyResult.setLimit(limitRows);
        }
        return lazyResult;
    }
    if (offsetExpr != null) {
        result.setOffset(offsetExpr.getValue(session).getInt());
    }
    if (limitRows >= 0) {
        result.setLimit(limitRows);
    }
    if (result != null) {
        result.done();
        if (target != null) {
            while (result.next()) {
                target.addRow(result.currentRow());
            }
            result.close();
            return null;
        }
        return result;
    }
    return null;
}
Also used : Value(org.h2.value.Value)

Aggregations

UserAggregate (org.h2.engine.UserAggregate)8 Expression (org.h2.expression.Expression)6 ValueExpression (org.h2.expression.ValueExpression)6 Aggregate (org.h2.api.Aggregate)5 Connection (java.sql.Connection)4 ResultSet (java.sql.ResultSet)4 SQLException (java.sql.SQLException)4 Statement (java.sql.Statement)4 SimpleResultSet (org.h2.tools.SimpleResultSet)4 ValueString (org.h2.value.ValueString)4 CallableStatement (java.sql.CallableStatement)3 PreparedStatement (java.sql.PreparedStatement)3 ConditionInSelect (org.h2.expression.ConditionInSelect)3 Column (org.h2.table.Column)3 IndexColumn (org.h2.table.IndexColumn)3 DatabaseMetaData (java.sql.DatabaseMetaData)2 AlterTableAddConstraint (org.h2.command.ddl.AlterTableAddConstraint)2 AlterTableAlterColumn (org.h2.command.ddl.AlterTableAlterColumn)2 DropFunctionAlias (org.h2.command.ddl.DropFunctionAlias)2 DropSchema (org.h2.command.ddl.DropSchema)2