[BugFix] Lead/Lag with specified default value can not adopt low-cardinality optimization (#63554)
Signed-off-by: satanson <ranpanf@gmail.com>
This commit is contained in:
parent
03c31659c2
commit
aec060a697
|
|
@ -586,12 +586,23 @@ public class DecodeCollector extends OptExpressionVisitor<DecodeInfo, DecodeInfo
|
|||
ColumnRefSet disableColumns = new ColumnRefSet();
|
||||
for (ColumnRefOperator key : windowOp.getAnalyticCall().keySet()) {
|
||||
CallOperator windowCallOp = windowOp.getAnalyticCall().get(key);
|
||||
if (!LOW_CARD_WINDOW_FUNCTIONS.contains(windowCallOp.getFnName())) {
|
||||
String fnName = windowCallOp.getFnName();
|
||||
if (!LOW_CARD_WINDOW_FUNCTIONS.contains(fnName)) {
|
||||
disableColumns.union(windowCallOp.getUsedColumns());
|
||||
disableColumns.union(key);
|
||||
continue;
|
||||
}
|
||||
|
||||
// LEAD/LAG with specified default value can not adopt low-cardinality optimization
|
||||
if ((fnName.equals(FunctionSet.LEAD) || fnName.equals(FunctionSet.LAG))) {
|
||||
ScalarOperator lastArg = windowCallOp.getArguments().get(windowCallOp.getArguments().size() - 1);
|
||||
if (!lastArg.isConstantNull()) {
|
||||
disableColumns.union(windowCallOp.getUsedColumns());
|
||||
disableColumns.union(key);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Map<Boolean, List<ScalarOperator>> argGroups = windowCallOp.getChildren().stream()
|
||||
.filter(Predicate.not(ScalarOperator::isConstant))
|
||||
.collect(Collectors.partitioningBy(ScalarOperator::isColumnRef));
|
||||
|
|
|
|||
|
|
@ -959,6 +959,38 @@ public class LowCardinalityArrayTest extends PlanTestBase {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotSupportedWindowFunctionLeadLagWithSpecifiedDefaultValue() throws Exception {
|
||||
String sqlFmt = "with cte as(\n" +
|
||||
" select s1.v1, s1.v2, t.a1 a1\n" +
|
||||
" from s1,unnest(s1.a1)t(a1) \n" +
|
||||
")\n" +
|
||||
"select v1, a1, {WINDOW_FUN}(a1, 1, 'ABCD') over(partition by v1)\n" +
|
||||
"from cte;";
|
||||
|
||||
String[] windowFuncs = new String[] {
|
||||
FunctionSet.LEAD,
|
||||
FunctionSet.LAG
|
||||
};
|
||||
|
||||
for (String wf : windowFuncs) {
|
||||
String q = sqlFmt.replace("{WINDOW_FUN}", wf);
|
||||
String plan = getVerboseExplain(q);
|
||||
String[] lines = plan.split("\n");
|
||||
List<Integer> decodeNodeLines = IntStream.range(0, lines.length).boxed()
|
||||
.filter(lineno -> lines[lineno]
|
||||
.matches("^\\s*\\d+:Decode\\s*$"))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<Integer> analyticNodeLines = IntStream.range(0, lines.length).boxed()
|
||||
.filter(lineno -> lines[lineno]
|
||||
.matches("^\\s*\\d+:ANALYTIC\\s*$"))
|
||||
.collect(Collectors.toList());
|
||||
Assertions.assertEquals(1, decodeNodeLines.size(), plan);
|
||||
Assertions.assertEquals(1, analyticNodeLines.size(), plan);
|
||||
Assertions.assertTrue(decodeNodeLines.get(0) > analyticNodeLines.get(0), plan);
|
||||
}
|
||||
}
|
||||
@Test
|
||||
public void testdWindowFunctionCount() throws Exception {
|
||||
String sql1 = "with cte as(\n" +
|
||||
|
|
|
|||
Loading…
Reference in New Issue