提交 4e720dde authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Write sort order of MODE aggregate to its SQL representation

上级 f11e8fa8
......@@ -3690,7 +3690,7 @@ MEDIAN(X)
"Functions (Aggregate)","MODE","
{ MODE( value ) [ ORDER BY expression [ ASC | DESC ] ] }
| { MODE() WITHIN GROUP(ORDER BY expression [ ASC | DESC ]) }
| { MODE() WITHIN GROUP (ORDER BY expression [ ASC | DESC ]) }
[FILTER (WHERE expression)] [OVER windowNameOrSpecification]
","
Returns the value that occurs with the greatest frequency.
......@@ -3706,7 +3706,7 @@ Aggregates are only allowed in select statements.
","
MODE(X)
MODE(X ORDER BY X)
MODE() WITHIN GROUP(ORDER BY X)
MODE() WITHIN GROUP (ORDER BY X)
"
"Functions (Aggregate)","ENVELOPE","
......
......@@ -3095,11 +3095,11 @@ public class Parser {
read(ORDER);
read("BY");
Expression expr = readExpression();
r = new Aggregate(AggregateType.MODE, expr, currentSelect, false);
setModeAggOrder(r, expr);
r = new Aggregate(AggregateType.MODE, null, currentSelect, false);
setModeAggOrder(r, expr, true);
} else {
Expression expr = readExpression();
r = new Aggregate(aggregateType, expr, currentSelect, false);
r = new Aggregate(aggregateType, null, currentSelect, false);
if (readIf(ORDER)) {
read("BY");
Expression expr2 = readExpression();
......@@ -3108,7 +3108,9 @@ public class Parser {
throw DbException.getSyntaxError(ErrorCode.IDENTICAL_EXPRESSIONS_SHOULD_BE_USED, sqlCommand,
lastParseIndex, sql, sql2);
}
setModeAggOrder(r, expr);
setModeAggOrder(r, expr, true);
} else {
setModeAggOrder(r, expr, false);
}
}
break;
......@@ -3125,11 +3127,13 @@ public class Parser {
return r;
}
private void setModeAggOrder(Aggregate r, Expression expr) {
private void setModeAggOrder(Aggregate r, Expression expr, boolean parseSortType) {
ArrayList<SelectOrderBy> orderList = new ArrayList<>(1);
SelectOrderBy order = new SelectOrderBy();
order.expression = expr;
order.sortType = parseSimpleSortType();
if (parseSortType) {
order.sortType = parseSimpleSortType();
}
orderList.add(order);
r.setOrderByList(orderList);
}
......
......@@ -294,14 +294,22 @@ public class Aggregate extends AbstractAggregate {
}
private void updateData(Session session, AggregateData data, Value v, Value[] remembered) {
if (aggregateType == AggregateType.GROUP_CONCAT) {
switch (aggregateType) {
case GROUP_CONCAT:
if (v != ValueNull.INSTANCE) {
v = updateCollecting(session, v.convertTo(Value.STRING), remembered);
}
} else if (aggregateType == AggregateType.ARRAY_AGG) {
break;
case ARRAY_AGG:
if (v != ValueNull.INSTANCE) {
v = updateCollecting(session, v, remembered);
}
break;
case MODE:
v = orderByList.get(0).expression.getValue(session);
break;
default:
// Use argument as is
}
data.add(session.getDatabase(), v);
}
......@@ -647,7 +655,9 @@ public class Aggregate extends AbstractAggregate {
case MIN:
case MAX:
case MEDIAN:
break;
case MODE:
type = orderByList.get(0).expression.getType();
break;
case STDDEV_POP:
case STDDEV_SAMP:
......@@ -792,13 +802,20 @@ public class Aggregate extends AbstractAggregate {
on.getSQL(builder).append(')');
} else {
builder.append('(');
if (on instanceof Subquery) {
on.getSQL(builder);
} else {
on.getUnenclosedSQL(builder);
if (on != null) {
if (on instanceof Subquery) {
on.getSQL(builder);
} else {
on.getUnenclosedSQL(builder);
}
}
builder.append(')');
}
if (orderByList != null) {
builder.append(" WITHIN GROUP (");
Window.appendOrderBy(builder, orderByList);
builder.append(')');
}
return appendTailConditions(builder);
}
......
......@@ -21,10 +21,16 @@ SELECT MODE(V) FROM TEST;
INSERT INTO TEST VALUES (1), (2), (3), (1), (2), (1);
> update count: 6
SELECT MODE(V), MODE(V) FILTER (WHERE (V > 1)), MODE(V) FILTER (WHERE (V < 0)) FROM TEST;
> MODE(V) MODE(V) FILTER (WHERE (V > 1)) MODE(V) FILTER (WHERE (V < 0))
> ------- ------------------------------ ------------------------------
> 1 2 null
SELECT MODE(V), MODE() WITHIN GROUP (ORDER BY V DESC) FROM TEST;
> MODE() WITHIN GROUP (ORDER BY V) MODE() WITHIN GROUP (ORDER BY V DESC)
> -------------------------------- -------------------------------------
> 1 1
> rows: 1
SELECT MODE(V) FILTER (WHERE (V > 1)), MODE(V) FILTER (WHERE (V < 0)) FROM TEST;
> MODE() WITHIN GROUP (ORDER BY V) FILTER (WHERE (V > 1)) MODE() WITHIN GROUP (ORDER BY V) FILTER (WHERE (V < 0))
> ------------------------------------------------------- -------------------------------------------------------
> 2 null
> rows: 1
-- Oracle compatibility
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论