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

Reject invalid usages of window frames in optimize()

上级 0ef8cba8
......@@ -2555,7 +2555,7 @@ ROWS|RANGE|GROUP
[EXCLUDE {CURRENT ROW|GROUP|TIES|NO OTHERS}]
","
A window frame clause.
Is currently supported only in aggregates and FIRST_VALUE(), LAST_VALUE(), and NTH_VALUE() window functions.
May be specified only for aggregates and FIRST_VALUE(), LAST_VALUE(), and NTH_VALUE() window functions.
","
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE GROUP
"
......
......@@ -3049,7 +3049,7 @@ public class Parser {
}
Window over = null;
if (readIf("OVER")) {
over = readWindowSpecification(aggregate);
over = readWindowSpecification();
aggregate.setOverCondition(over);
currentSelect.setWindowQuery();
} else if (!isAggregate) {
......@@ -3059,7 +3059,7 @@ public class Parser {
}
}
private Window readWindowSpecification(AbstractAggregate aggregate) {
private Window readWindowSpecification() {
read(OPEN_PAREN);
ArrayList<Expression> partitionBy = null;
if (readIf("PARTITION")) {
......@@ -3075,21 +3075,7 @@ public class Parser {
read("BY");
orderBy = parseSimpleOrderList();
}
WindowFrame frame;
if (aggregate instanceof WindowFunction) {
WindowFunction w = (WindowFunction) aggregate;
switch (w.getFunctionType()) {
case FIRST_VALUE:
case LAST_VALUE:
case NTH_VALUE:
frame = readWindowFrame();
break;
default:
frame = null;
}
} else {
frame = readWindowFrame();
}
WindowFrame frame = readWindowFrame();
read(CLOSE_PAREN);
return new Window(partitionBy, orderBy, frame);
}
......
......@@ -177,7 +177,7 @@ public final class Window {
* @see Expression#getSQL()
*/
public String getSQL() {
if (partitionBy == null && orderBy == null) {
if (partitionBy == null && orderBy == null && frame == null) {
return "OVER ()";
}
StringBuilder builder = new StringBuilder().append("OVER (");
......@@ -192,7 +192,10 @@ public final class Window {
}
appendOrderBy(builder, orderBy);
if (frame != null && !frame.isDefault()) {
builder.append(' ').append(frame.getSQL());
if (builder.charAt(builder.length() - 1) != '(') {
builder.append(' ');
}
builder.append(frame.getSQL());
}
return builder.append(')').toString();
}
......
......@@ -400,6 +400,17 @@ public class WindowFunction extends AbstractAggregate {
@Override
public Expression optimize(Session session) {
if (over.getWindowFrame() != null) {
switch (type) {
case FIRST_VALUE:
case LAST_VALUE:
case NTH_VALUE:
break;
default:
String sql = getSQL();
throw DbException.getSyntaxError(sql, sql.length() - 1);
}
}
super.optimize(session);
if (args != null) {
for (int i = 0; i < args.length; i++) {
......
......@@ -129,5 +129,11 @@ SELECT LEAD(VALUE, -1) OVER (ORDER BY ID) FROM TEST;
SELECT LAG(VALUE, -1) OVER (ORDER BY ID) FROM TEST;
> exception INVALID_VALUE_2
SELECT LEAD(VALUE) OVER (ORDER BY ID RANGE CURRENT ROW) FROM TEST;
> exception SYNTAX_ERROR_1
SELECT LAG(VALUE) OVER (ORDER BY ID RANGE CURRENT ROW) FROM TEST;
> exception SYNTAX_ERROR_1
DROP TABLE TEST;
> ok
......@@ -113,3 +113,5 @@ SELECT NTILE(X) OVER (ORDER BY X) FROM (SELECT * FROM SYSTEM_RANGE(1, 6));
> 6
> rows (ordered): 6
SELECT NTILE(X) OVER (ORDER BY X RANGE CURRENT ROW) FROM (SELECT * FROM SYSTEM_RANGE(1, 1));
> exception SYNTAX_ERROR_1
......@@ -100,6 +100,21 @@ SELECT
> 4 1 1 0.0 1.0
> rows: 4
SELECT ROW_NUMBER() OVER (ORDER BY ID RANGE CURRENT ROW) FROM TEST;
> exception SYNTAX_ERROR_1
SELECT RANK() OVER (ORDER BY ID RANGE CURRENT ROW) FROM TEST;
> exception SYNTAX_ERROR_1
SELECT DENSE_RANK() OVER (ORDER BY ID RANGE CURRENT ROW) FROM TEST;
> exception SYNTAX_ERROR_1
SELECT PERCENT_RANK() OVER (ORDER BY ID RANGE CURRENT ROW) FROM TEST;
> exception SYNTAX_ERROR_1
SELECT CUME_DIST() OVER (ORDER BY ID RANGE CURRENT ROW) FROM TEST;
> exception SYNTAX_ERROR_1
DROP TABLE TEST;
> ok
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论