Skip to content
This repository was archived by the owner on May 9, 2024. It is now read-only.

Commit a01e3d2

Browse files
AndreyPavlenkoienkovich
authored andcommitted
Fixed window functions json deserialization in Calcite
Some expressions, like partition_keys, order_keys, lower/upper_bound are ignored by toRex().
1 parent c89a4ed commit a01e3d2

File tree

1 file changed

+50
-0
lines changed
  • omniscidb/Calcite/java/calcite/src/main/java/org/apache/calcite/rel/externalize

1 file changed

+50
-0
lines changed

omniscidb/Calcite/java/calcite/src/main/java/org/apache/calcite/rel/externalize/MapDRelJson.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import org.apache.calcite.rex.RexSubQuery;
5252
import org.apache.calcite.rex.RexWindow;
5353
import org.apache.calcite.rex.RexWindowBound;
54+
import org.apache.calcite.rex.RexWindowBounds;
5455
import org.apache.calcite.sql.JoinType;
5556
import org.apache.calcite.sql.SqlAggFunction;
5657
import org.apache.calcite.sql.SqlFunction;
@@ -69,9 +70,13 @@
6970
import java.lang.reflect.InvocationTargetException;
7071
import java.math.BigDecimal;
7172
import java.util.ArrayList;
73+
import java.util.Collections;
7274
import java.util.HashMap;
75+
import java.util.HashSet;
7376
import java.util.List;
7477
import java.util.Map;
78+
import java.util.Set;
79+
import java.util.stream.Collectors;
7580

7681
/**
7782
* Utilities for converting {@link org.apache.calcite.rel.RelNode} into JSON
@@ -437,6 +442,51 @@ RexNode toRex(RelInput relInput, Object o) {
437442
} else {
438443
type = rexBuilder.deriveReturnType(operator, rexOperands);
439444
}
445+
446+
List<Map> keys;
447+
if ((operator instanceof SqlAggFunction)
448+
&& ((keys = (List<Map>) map.getOrDefault("partition_keys", null)) != null)) {
449+
List<RexNode> partKeys = keys.stream().map(k -> toRex(relInput, k))
450+
.collect(Collectors.toList());
451+
452+
keys = (List<Map>) map.getOrDefault("order_keys", Collections.emptyList());
453+
List<RexFieldCollation> orderKeys = new ArrayList<>(keys.size());
454+
for (Map ok : keys) {
455+
RexNode left = toRex(relInput, ok.get("field"));
456+
Set<SqlKind> right = new HashSet<>();
457+
if ("DESCENDING".equals(ok.get("direction"))) right.add(SqlKind.DESCENDING);
458+
right.add("LAST".equals(ok.get("nulls")) ? SqlKind.NULLS_LAST : SqlKind.NULLS_FIRST);
459+
orderKeys.add(new RexFieldCollation(left, right));
460+
}
461+
462+
Map lower = (Map) map.getOrDefault("lower_bound", Collections.emptyMap());
463+
Map upper = (Map) map.getOrDefault("upper_bound", Collections.emptyMap());
464+
RexWindowBound lowerBound;
465+
RexWindowBound upperBound;
466+
467+
if (Boolean.TRUE.equals(lower.getOrDefault("unbounded", true))) {
468+
if (Boolean.TRUE.equals(lower.getOrDefault("preceding", true)))
469+
lowerBound = RexWindowBounds.UNBOUNDED_PRECEDING;
470+
else
471+
lowerBound = RexWindowBounds.UNBOUNDED_FOLLOWING;
472+
} else {
473+
lowerBound = RexWindowBounds.CURRENT_ROW;
474+
}
475+
if (Boolean.TRUE.equals(upper.getOrDefault("is_current_row", true))) {
476+
upperBound = RexWindowBounds.CURRENT_ROW;
477+
} else {
478+
if (Boolean.TRUE.equals(upper.getOrDefault("preceding", true)))
479+
upperBound = RexWindowBounds.UNBOUNDED_PRECEDING;
480+
else
481+
upperBound = RexWindowBounds.UNBOUNDED_FOLLOWING;
482+
}
483+
484+
boolean rows = Boolean.TRUE.equals(map.getOrDefault("is_rows", true));
485+
return rexBuilder.makeOver(type, (SqlAggFunction) operator, rexOperands,
486+
partKeys, ImmutableList.copyOf(orderKeys), lowerBound, upperBound,
487+
rows, true, false, false, false);
488+
}
489+
440490
return rexBuilder.makeCall(type, operator, rexOperands);
441491
}
442492
final Integer input = (Integer) map.get("input");

0 commit comments

Comments
 (0)