Skip to content

Commit 3ea095e

Browse files
Address comments
1 parent d5bc50d commit 3ea095e

File tree

1 file changed

+28
-30
lines changed

1 file changed

+28
-30
lines changed

core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,30 @@ protected RexNode removeCorrelationExpr(
575575
}
576576

577577
if (isCorVarDefined && (rel.fetch != null || rel.offset != null)) {
578-
return decorrelateFetchOneSort(rel, frame);
578+
if (rel.offset == null
579+
&& rel.fetch != null
580+
&& RexLiteral.longValue(rel.fetch) == 0) {
581+
return null;
582+
}
583+
584+
//
585+
// Rewrite logic:
586+
//
587+
// For correlated Sort with LIMIT/OFFSET:
588+
// Special case: if OFFSET is null and FETCH = 1,
589+
// we may rewrite as an Aggregate using MIN/MAX.
590+
Frame aggFrame = decorrelateSortAsAggregate(rel, frame);
591+
if (aggFrame != null) {
592+
return aggFrame;
593+
}
594+
595+
// General case: rewrite as
596+
// Project(original_fields..., corVars..., rn)
597+
// where rn = ROW_NUMBER() OVER (PARTITION BY corVars ORDER BY sortExprs
598+
// ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
599+
// Filter(rn > offset, rn <= offset + fetch)
600+
// This preserves per-corVar LIMIT/OFFSET semantics.
601+
return decorrelateSortWithRowNumber(rel, frame);
579602
}
580603

581604
final RelNode newInput = frame.r;
@@ -1036,32 +1059,7 @@ private static void shiftMapping(Map<Integer, Integer> mapping, int startIndex,
10361059
return null;
10371060
}
10381061

1039-
protected @Nullable Frame decorrelateFetchOneSort(Sort sort, final Frame frame) {
1040-
if (sort.offset == null
1041-
&& sort.fetch != null
1042-
&& RexLiteral.intValue(sort.fetch) == 0) {
1043-
return null;
1044-
}
1045-
1046-
//
1047-
// Rewrite logic:
1048-
//
1049-
// For correlated Sort with LIMIT/OFFSET:
1050-
// 1) Special case: if OFFSET is null and FETCH = 1, we may rewrite as an Aggregate
1051-
// using MIN/MAX (see decorrelateSortAsAggregate).
1052-
// 2) General case: rewrite as
1053-
// Project(original_fields..., corVars..., rn)
1054-
// where rn = ROW_NUMBER() OVER (PARTITION BY corVars ORDER BY sortExprs
1055-
// ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
1056-
// Filter(rn > offset, rn <= offset + fetch)
1057-
// This preserves per-corVar LIMIT/OFFSET semantics.
1058-
//
1059-
1060-
Frame aggFrame = decorrelateSortAsAggregate(sort, frame);
1061-
if (aggFrame != null) {
1062-
return aggFrame;
1063-
}
1064-
1062+
protected @Nullable Frame decorrelateSortWithRowNumber(Sort sort, final Frame frame) {
10651063
final Map<Integer, Integer> mapOldToNewOutputs = new HashMap<>();
10661064
final NavigableMap<CorDef, Integer> corDefOutputs = new TreeMap<>();
10671065

@@ -1143,7 +1141,7 @@ private static void shiftMapping(Map<Integer, Integer> mapping, int startIndex,
11431141
if (sort.offset != null) {
11441142
return null;
11451143
}
1146-
if (sort.fetch == null || RexLiteral.intValue(sort.fetch) != 1) {
1144+
if (sort.fetch == null || RexLiteral.longValue(sort.fetch) != 1) {
11471145
return null;
11481146
}
11491147

@@ -1376,7 +1374,7 @@ private static void shiftMapping(Map<Integer, Integer> mapping, int startIndex,
13761374
final int newOutput =
13771375
newLocalOutputs.indexOf(newLocalOutput)
13781376
+ requireNonNull(mapNewInputToNewOffset.get(newInput),
1379-
() -> "mapNewInputToNewOffset.get(" + newInput + ")")
1377+
() -> "mapNewInputToNewOffset.get(" + newInput + ")")
13801378
+ valueGenFieldOffset;
13811379

13821380
corDefOutputs.put(corRef.def(), newOutput);
@@ -3339,7 +3337,7 @@ private CorelMap(Multimap<RelNode, CorRef> mapRefRelToCorRef,
33393337
&& mapRefRelToCorRef.equals(((CorelMap) obj).mapRefRelToCorRef)
33403338
&& mapCorToCorRel.equals(((CorelMap) obj).mapCorToCorRel)
33413339
&& mapFieldAccessToCorRef.equals(
3342-
((CorelMap) obj).mapFieldAccessToCorRef);
3340+
((CorelMap) obj).mapFieldAccessToCorRef);
33433341
}
33443342

33453343
@Override public int hashCode() {

0 commit comments

Comments
 (0)