Skip to content

Commit 0a8df22

Browse files
authored
[BugFix] Handle join skew hint in OptExpressionDuplicator (StarRocks#68964)
Signed-off-by: m.bogusz <m.bogusz@celonis.com>
1 parent 1edc29a commit 0a8df22

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

fe/fe-core/src/main/java/com/starrocks/sql/optimizer/rule/transformation/materialization/OptExpressionDuplicator.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,12 @@ public OptExpression visitLogicalJoin(OptExpression optExpression, Void context)
401401
ScalarOperator newOnPredicate = rewriter.rewrite(onpredicate);
402402
LogicalJoinOperator.Builder joinBuilder = (LogicalJoinOperator.Builder) opBuilder;
403403
joinBuilder.setOnPredicate(newOnPredicate);
404+
405+
if (joinOperator.getSkewColumn() != null) {
406+
joinBuilder.setSkewColumn(rewriter.rewrite(joinOperator.getSkewColumn()));
407+
}
404408
}
409+
405410
return OptExpression.create(opBuilder.build(), inputs);
406411
}
407412

fe/fe-core/src/test/java/com/starrocks/sql/plan/WindowSkewTest.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,20 @@ DISTRIBUTED BY HASH(`p`) BUCKETS 3
5050
);
5151
"""
5252
);
53+
starRocksAssert.withTable(
54+
"""
55+
CREATE TABLE `window_skew_table_join` (
56+
`id` int NULL,
57+
`val` int NULL
58+
) ENGINE=OLAP
59+
DUPLICATE KEY(`id`, `val`)
60+
DISTRIBUTED BY HASH(`id`) BUCKETS 3
61+
PROPERTIES (
62+
"replication_num" = "1",
63+
"in_memory" = "false"
64+
);
65+
"""
66+
);
5367

5468
if (!starRocksAssert.databaseExist("_statistics_")) {
5569
StatisticsMetaManager m = new StatisticsMetaManager();
@@ -285,4 +299,33 @@ void testWindowWithComplexPartition() throws Exception {
285299
assertNotContains(plan, "UNION");
286300
assertContains(plan, "ANALYTIC");
287301
}
302+
@Test
303+
void testWindowSkewHintWithJoinBeforeWindow() throws Exception {
304+
// Test that the skew hint works correctly when there is a join before the window function
305+
final var table = getOlapTable("window_skew_table");
306+
final var joinTable = getOlapTable("window_skew_table_join");
307+
308+
final var statisticStorage = connectContext.getGlobalStateMgr().getStatisticStorage();
309+
final var skewedColumnStat = ColumnStatistic.builder().setNullsFraction(0.3).build();
310+
setTableStatistics(table, 1000);
311+
setTableStatistics(joinTable, 500);
312+
statisticStorage.addColumnStatistic(table, "p", skewedColumnStat);
313+
statisticStorage.getColumnStatistics(table, List.of("p", "s", "x"));
314+
315+
316+
String sql = "select a.p, a.s, b.val, sum(a.x) over (partition by a.p order by a.s) " +
317+
"from window_skew_table a " +
318+
"join [skew|b.id(NULL)] window_skew_table_join b on a.p = b.id";
319+
String plan = getFragmentPlan(sql, TExplainLevel.COSTS, "");
320+
321+
// Verify UNION rewrite is triggered
322+
assertContains(plan, "UNION");
323+
// Verify JOIN is present in the plan
324+
assertContains(plan, "JOIN");
325+
// Verify the NULL/NOT NULL predicates for skew handling
326+
assertContains(plan, "IS NULL");
327+
assertContains(plan, "IS NOT NULL");
328+
// Verify ANALYTIC window function is present
329+
assertContains(plan, "ANALYTIC");
330+
}
288331
}

0 commit comments

Comments
 (0)