Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

branch-3.0: [fix](nereids) not rewrite first_value when first_value ignore nulls #45065 #45235

Merged
merged 1 commit into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"
}
Loading