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;
}
}
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();
}
}
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;
}
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;
}
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;
}
Aggregations