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