Skip to content

Commit

Permalink
[fix](nereids) not rewrite first_value when first_value ignore nulls (#…
Browse files Browse the repository at this point in the history
…45065)

this pr fix 2 things:
1.when first_value/last_value second parameter is true, which means
ignore nulls, fe should not do some rewrite.
2.adding check that first_value/last_value second parameter must be true
or false.

Related PR: #44996 #27623
  • Loading branch information
feiniaofeiafei authored and Your Name committed Dec 10, 2024
1 parent 559ca09 commit 9ff7708
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.apache.doris.nereids.trees.expressions.functions.window.PercentRank;
import org.apache.doris.nereids.trees.expressions.functions.window.Rank;
import org.apache.doris.nereids.trees.expressions.functions.window.RowNumber;
import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral;
import org.apache.doris.nereids.trees.expressions.literal.Literal;
import org.apache.doris.nereids.trees.expressions.visitor.DefaultExpressionVisitor;
import org.apache.doris.nereids.util.TypeCoercionUtils;
Expand Down Expand Up @@ -315,6 +316,10 @@ public Lead visitLead(Lead lead, Void ctx) {
*/
@Override
public FirstOrLastValue visitFirstValue(FirstValue firstValue, Void ctx) {
FirstOrLastValue.checkSecondParameter(firstValue);
if (2 == firstValue.arity() && firstValue.child(1).equals(BooleanLiteral.TRUE)) {
return firstValue;
}
Optional<WindowFrame> windowFrame = windowExpression.getWindowFrame();
if (windowFrame.isPresent()) {
WindowFrame wf = windowFrame.get();
Expand All @@ -339,6 +344,12 @@ public FirstOrLastValue visitFirstValue(FirstValue firstValue, Void ctx) {
return firstValue;
}

@Override
public FirstOrLastValue visitLastValue(LastValue lastValue, Void ctx) {
FirstOrLastValue.checkSecondParameter(lastValue);
return lastValue;
}

/**
* required WindowFrame: (RANGE, UNBOUNDED PRECEDING, CURRENT ROW)
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
package org.apache.doris.nereids.trees.expressions.functions.window;

import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable;
import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral;
import org.apache.doris.nereids.types.BooleanType;
import org.apache.doris.nereids.types.coercion.AnyDataType;

Expand Down Expand Up @@ -63,4 +65,17 @@ public FirstOrLastValue reverse() {
public List<FunctionSignature> getSignatures() {
return SIGNATURES;
}

/**check the second parameter must be true or false*/
public static void checkSecondParameter(FirstOrLastValue firstOrLastValue) {
if (1 == firstOrLastValue.arity()) {
return;
}
if (!BooleanLiteral.TRUE.equals(firstOrLastValue.child(1))
&& !BooleanLiteral.FALSE.equals(firstOrLastValue.child(1))) {
throw new AnalysisException("The second parameter of " + firstOrLastValue.getName()
+ " must be a constant or a constant expression, and the result of "
+ "the calculated constant or constant expression must be true or false.");
}
}
}
35 changes: 35 additions & 0 deletions regression-test/suites/nereids_syntax_p0/window_function.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -279,4 +279,39 @@ suite("window_function") {
)t
)a where rn=1
"""

// test first value second param is not constant
test {
sql "select first_value(c1,c1) over() from window_test"
exception "The second parameter of first_value must be a constant or a constant expression, and the result of the calculated constant or constant expression must be true or false."
}

test {
sql "select last_value(c1,c1) over() from window_test"
exception "The second parameter of last_value must be a constant or a constant expression, and the result of the calculated constant or constant expression must be true or false."
}

test {
sql "select first_value(c1,cast('abc' as boolean)) over() from window_test"
exception "The second parameter of first_value must be a constant or a constant expression, and the result of the calculated constant or constant expression must be true or false."
}
test {
sql "select first_value(c1,'') over() from window_test"
exception "The second parameter of first_value must be a constant or a constant expression, and the result of the calculated constant or constant expression must be true or false."
}
test {
sql "select last_value(c1,'345_a') over() from window_test"
exception "The second parameter of last_value must be a constant or a constant expression, and the result of the calculated constant or constant expression must be true or false."
}
sql "select last_value(c1,cast('67' as boolean)) over() from window_test"
sql "select first_value(c1,cast(56 as boolean)) over() from window_test"
sql "select last_value(c1,cast(56 as boolean)) over() from window_test"
sql "select first_value(c1,cast('true' as boolean)) over() from window_test"
sql "select last_value(c1,cast('false' as boolean)) over() from window_test"
sql "select first_value(c1,cast('1' as boolean)) over() from window_test"
sql "select last_value(c1,cast('0' as boolean)) over() from window_test"
sql "select first_value(c1,true) over() from window_test"
sql "select last_value(c1,false) over() from window_test"
sql "select first_value(c1,1) over() from window_test"
sql "select last_value(c1,0) over() from window_test"
}

0 comments on commit 9ff7708

Please sign in to comment.