提交 eef18e96 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Use array of expressions in Aggregate

上级 b27b12be
......@@ -3041,21 +3041,22 @@ public class Parser {
switch (aggregateType) {
case COUNT:
if (readIf(ASTERISK)) {
r = new Aggregate(AggregateType.COUNT_ALL, null, currentSelect, false);
r = new Aggregate(AggregateType.COUNT_ALL, new Expression[0], currentSelect, false);
} else {
boolean distinct = readDistinctAgg();
Expression on = readExpression();
if (on instanceof Wildcard && !distinct) {
// PostgreSQL compatibility: count(t.*)
r = new Aggregate(AggregateType.COUNT_ALL, null, currentSelect, false);
r = new Aggregate(AggregateType.COUNT_ALL, new Expression[0], currentSelect, false);
} else {
r = new Aggregate(AggregateType.COUNT, on, currentSelect, distinct);
r = new Aggregate(AggregateType.COUNT, new Expression[] { on }, currentSelect, distinct);
}
}
break;
case GROUP_CONCAT: {
boolean distinct = readDistinctAgg();
r = new Aggregate(AggregateType.GROUP_CONCAT, readExpression(), currentSelect, distinct);
r = new Aggregate(AggregateType.GROUP_CONCAT, new Expression[] { readExpression() }, currentSelect,
distinct);
if (equalsToken("STRING_AGG", aggregateName)) {
// PostgreSQL compatibility: string_agg(expression, delimiter)
read(COMMA);
......@@ -3077,7 +3078,7 @@ public class Parser {
}
case ARRAY_AGG: {
boolean distinct = readDistinctAgg();
r = new Aggregate(AggregateType.ARRAY_AGG, readExpression(), currentSelect, distinct);
r = new Aggregate(AggregateType.ARRAY_AGG, new Expression[] { readExpression() }, currentSelect, distinct);
if (readIf(ORDER)) {
read("BY");
r.setOrderByList(parseSimpleOrderList());
......@@ -3088,15 +3089,15 @@ public class Parser {
case PERCENTILE_DISC: {
Expression num = readExpression();
read(CLOSE_PAREN);
r = readWithinGroup(aggregateType, num);
r = readWithinGroup(aggregateType, new Expression[] { num });
break;
}
case MODE: {
if (readIf(CLOSE_PAREN)) {
r = readWithinGroup(AggregateType.MODE, null);
r = readWithinGroup(AggregateType.MODE, new Expression[0]);
} else {
Expression expr = readExpression();
r = new Aggregate(aggregateType, null, currentSelect, false);
r = new Aggregate(aggregateType, new Expression[0], currentSelect, false);
if (readIf(ORDER)) {
read("BY");
Expression expr2 = readExpression();
......@@ -3114,7 +3115,7 @@ public class Parser {
}
default:
boolean distinct = readDistinctAgg();
r = new Aggregate(aggregateType, readExpression(), currentSelect, distinct);
r = new Aggregate(aggregateType, new Expression[] { readExpression() }, currentSelect, distinct);
break;
}
read(CLOSE_PAREN);
......@@ -3122,7 +3123,7 @@ public class Parser {
return r;
}
private Aggregate readWithinGroup(AggregateType aggregateType, Expression argument) {
private Aggregate readWithinGroup(AggregateType aggregateType, Expression[] args) {
Aggregate r;
read("WITHIN");
read(GROUP);
......@@ -3130,7 +3131,7 @@ public class Parser {
read(ORDER);
read("BY");
Expression expr = readExpression();
r = new Aggregate(aggregateType, argument, currentSelect, false);
r = new Aggregate(aggregateType, args, currentSelect, false);
readAggregateOrder(r, expr, true);
return r;
}
......
......@@ -53,7 +53,7 @@ public class Aggregate extends AbstractAggregate {
private final AggregateType aggregateType;
private Expression on;
private final Expression[] args;
private Expression groupConcatSeparator;
private ArrayList<SelectOrderBy> orderByList;
private SortOrder orderBySort;
......@@ -64,20 +64,20 @@ public class Aggregate extends AbstractAggregate {
*
* @param aggregateType
* the aggregate type
* @param on
* the aggregated expression
* @param args
* the aggregated expressions
* @param select
* the select statement
* @param distinct
* if distinct is used
*/
public Aggregate(AggregateType aggregateType, Expression on, Select select, boolean distinct) {
public Aggregate(AggregateType aggregateType, Expression[] args, Select select, boolean distinct) {
super(select, distinct);
if (distinct && aggregateType == AggregateType.COUNT_ALL) {
throw DbException.throwInternalError();
}
this.aggregateType = aggregateType;
this.on = on;
this.args = args;
}
static {
......@@ -185,7 +185,7 @@ public class Aggregate extends AbstractAggregate {
@Override
protected void updateAggregate(Session session, Object aggregateData) {
AggregateData data = (AggregateData) aggregateData;
Value v = on == null ? null : on.getValue(session);
Value v = args.length == 0 ? null : args[0].getValue(session);
updateData(session, data, v, null);
}
......@@ -218,8 +218,8 @@ public class Aggregate extends AbstractAggregate {
@Override
protected void updateGroupAggregates(Session session, int stage) {
super.updateGroupAggregates(session, stage);
if (on != null) {
on.updateAggregate(session, stage);
for (Expression arg : args) {
arg.updateAggregate(session, stage);
}
if (orderByList != null) {
for (SelectOrderBy orderBy : orderByList) {
......@@ -248,7 +248,7 @@ public class Aggregate extends AbstractAggregate {
@Override
protected int getNumExpressions() {
int n = on != null ? 1 : 0;
int n = args.length;
if (orderByList != null) {
n += orderByList.size();
}
......@@ -261,8 +261,8 @@ public class Aggregate extends AbstractAggregate {
@Override
protected void rememberExpressions(Session session, Value[] array) {
int offset = 0;
if (on != null) {
array[offset++] = on.getValue(session);
for (Expression arg : args) {
array[offset++] = arg.getValue(session);
}
if (orderByList != null) {
for (SelectOrderBy o : orderByList) {
......@@ -278,7 +278,7 @@ public class Aggregate extends AbstractAggregate {
protected void updateFromExpressions(Session session, Object aggregateData, Value[] array) {
if (filterCondition == null || array[getNumExpressions() - 1].getBoolean()) {
AggregateData data = (AggregateData) aggregateData;
Value v = on == null ? null : array[0];
Value v = args.length == 0 ? null : array[0];
updateData(session, data, v, array);
}
}
......@@ -319,7 +319,7 @@ public class Aggregate extends AbstractAggregate {
}
case PERCENTILE_CONT:
case PERCENTILE_DISC: {
Value v = on.getValue(session);
Value v = args[0].getValue(session);
if (v == ValueNull.INSTANCE) {
return ValueNull.INSTANCE;
}
......@@ -333,9 +333,9 @@ public class Aggregate extends AbstractAggregate {
}
}
case MEDIAN:
return Percentile.getFromIndex(session, on, type.getValueType(), orderByList, Percentile.HALF, true);
return Percentile.getFromIndex(session, args[0], type.getValueType(), orderByList, Percentile.HALF, true);
case ENVELOPE:
return ((MVSpatialIndex) AggregateDataEnvelope.getGeometryColumnIndex(on)).getBounds(session);
return ((MVSpatialIndex) AggregateDataEnvelope.getGeometryColumnIndex(args[0])).getBounds(session);
default:
throw DbException.throwInternalError("type=" + aggregateType);
}
......@@ -528,8 +528,8 @@ public class Aggregate extends AbstractAggregate {
@Override
public void mapColumnsAnalysis(ColumnResolver resolver, int level, int innerState) {
if (on != null) {
on.mapColumns(resolver, level, innerState);
for (Expression arg : args) {
arg.mapColumns(resolver, level, innerState);
}
if (orderByList != null) {
for (SelectOrderBy o : orderByList) {
......@@ -545,9 +545,11 @@ public class Aggregate extends AbstractAggregate {
@Override
public Expression optimize(Session session) {
super.optimize(session);
if (on != null) {
on = on.optimize(session);
type = on.getType();
for (int i = 0; i < args.length; i++) {
args[i] = args[i].optimize(session);
}
if (args.length == 1) {
type = args[0].getType();
}
if (orderByList != null) {
for (SelectOrderBy o : orderByList) {
......@@ -642,8 +644,8 @@ public class Aggregate extends AbstractAggregate {
@Override
public void setEvaluatable(TableFilter tableFilter, boolean b) {
if (on != null) {
on.setEvaluatable(tableFilter, b);
for (Expression arg : args) {
arg.setEvaluatable(tableFilter, b);
}
if (orderByList != null) {
for (SelectOrderBy o : orderByList) {
......@@ -661,7 +663,7 @@ public class Aggregate extends AbstractAggregate {
if (distinct) {
builder.append("DISTINCT ");
}
on.getSQL(builder);
args[0].getSQL(builder);
Window.appendOrderBy(builder, orderByList);
if (groupConcatSeparator != null) {
builder.append(" SEPARATOR ");
......@@ -676,7 +678,7 @@ public class Aggregate extends AbstractAggregate {
if (distinct) {
builder.append("DISTINCT ");
}
on.getSQL(builder);
args[0].getSQL(builder);
Window.appendOrderBy(builder, orderByList);
builder.append(')');
return appendTailConditions(builder);
......@@ -758,14 +760,14 @@ public class Aggregate extends AbstractAggregate {
builder.append(text);
if (distinct) {
builder.append("(DISTINCT ");
on.getSQL(builder).append(')');
args[0].getSQL(builder).append(')');
} else {
builder.append('(');
if (on != null) {
if (on instanceof Subquery) {
on.getSQL(builder);
for (Expression arg : args) {
if (arg instanceof Subquery) {
arg.getSQL(builder);
} else {
on.getUnenclosedSQL(builder);
arg.getUnenclosedSQL(builder);
}
}
builder.append(')');
......@@ -779,8 +781,9 @@ public class Aggregate extends AbstractAggregate {
}
private Index getMinMaxColumnIndex() {
if (on instanceof ExpressionColumn) {
ExpressionColumn col = (ExpressionColumn) on;
Expression arg = args[0];
if (arg instanceof ExpressionColumn) {
ExpressionColumn col = (ExpressionColumn) arg;
Column column = col.getColumn();
TableFilter filter = col.getTableFilter();
if (filter != null) {
......@@ -802,7 +805,7 @@ public class Aggregate extends AbstractAggregate {
if (visitor.getType() == ExpressionVisitor.OPTIMIZABLE_AGGREGATE) {
switch (aggregateType) {
case COUNT:
if (!distinct && on.getNullable() == Column.NOT_NULLABLE) {
if (!distinct && args[0].getNullable() == Column.NOT_NULLABLE) {
return visitor.getTable().canGetRowCount();
}
return false;
......@@ -814,21 +817,23 @@ public class Aggregate extends AbstractAggregate {
return index != null;
case PERCENTILE_CONT:
case PERCENTILE_DISC:
return on.isConstant() && Percentile.getColumnIndex(orderByList.get(0).expression) != null;
return args[0].isConstant() && Percentile.getColumnIndex(orderByList.get(0).expression) != null;
case MEDIAN:
if (distinct) {
return false;
}
return Percentile.getColumnIndex(on) != null;
return Percentile.getColumnIndex(args[0]) != null;
case ENVELOPE:
return AggregateDataEnvelope.getGeometryColumnIndex(on) != null;
return AggregateDataEnvelope.getGeometryColumnIndex(args[0]) != null;
default:
return false;
}
}
if (on != null && !on.isEverything(visitor)) {
for (Expression arg : args) {
if (!arg.isEverything(visitor)) {
return false;
}
}
if (groupConcatSeparator != null && !groupConcatSeparator.isEverything(visitor)) {
return false;
}
......@@ -845,8 +850,16 @@ public class Aggregate extends AbstractAggregate {
@Override
public int getCost() {
int cost = 1;
if (on != null) {
cost += on.getCost();
for (Expression arg : args) {
cost += arg.getCost();
}
if (groupConcatSeparator != null) {
cost += groupConcatSeparator.getCost();
}
if (orderByList != null) {
for (SelectOrderBy o : orderByList) {
cost += o.expression.getCost();
}
}
if (filterCondition != null) {
cost += filterCondition.getCost();
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论