Skip to content

Commit 82cdcc7

Browse files
committed
[CALCITE-7251] SEARCH and WINDOW operations should carry source position information
Signed-off-by: Mihai Budiu <mbudiu@feldera.com>
1 parent 42ff295 commit 82cdcc7

File tree

16 files changed

+276
-66
lines changed

16 files changed

+276
-66
lines changed

core/src/main/java/org/apache/calcite/rel/core/Window.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.apache.calcite.rex.RexWindowBound;
4242
import org.apache.calcite.rex.RexWindowExclusion;
4343
import org.apache.calcite.sql.SqlAggFunction;
44+
import org.apache.calcite.sql.parser.SqlParserPos;
4445
import org.apache.calcite.util.ImmutableBitSet;
4546
import org.apache.calcite.util.ImmutableIntList;
4647
import org.apache.calcite.util.Litmus;
@@ -425,7 +426,7 @@ public RexWinAggCall(
425426
List<RexNode> operands,
426427
int ordinal,
427428
boolean distinct) {
428-
this(aggFun, type, operands, ordinal, distinct, false);
429+
this(SqlParserPos.ZERO, aggFun, type, operands, ordinal, distinct, false);
429430
}
430431

431432
/**
@@ -436,6 +437,7 @@ public RexWinAggCall(
436437
* @param operands Operands to call
437438
* @param ordinal Ordinal within its partition
438439
* @param distinct Eliminate duplicates before applying aggregate function
440+
* @deprecated Use {@link RexWinAggCall#RexWinAggCall(SqlParserPos, SqlAggFunction, RelDataType, List, int, boolean, boolean)}
439441
*/
440442
public RexWinAggCall(
441443
SqlAggFunction aggFun,
@@ -444,7 +446,27 @@ public RexWinAggCall(
444446
int ordinal,
445447
boolean distinct,
446448
boolean ignoreNulls) {
447-
super(type, aggFun, operands);
449+
this(SqlParserPos.ZERO, aggFun, type, operands, ordinal, distinct, ignoreNulls);
450+
}
451+
452+
/**
453+
* Creates a RexWinAggCall.
454+
*
455+
* @param aggFun Aggregate function
456+
* @param type Result type
457+
* @param operands Operands to call
458+
* @param ordinal Ordinal within its partition
459+
* @param distinct Eliminate duplicates before applying aggregate function
460+
*/
461+
public RexWinAggCall(
462+
SqlParserPos pos,
463+
SqlAggFunction aggFun,
464+
RelDataType type,
465+
List<RexNode> operands,
466+
int ordinal,
467+
boolean distinct,
468+
boolean ignoreNulls) {
469+
super(pos, type, aggFun, operands);
448470
this.ordinal = ordinal;
449471
this.distinct = distinct;
450472
this.ignoreNulls = ignoreNulls;

core/src/main/java/org/apache/calcite/rel/externalize/RelJson.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,15 @@ private static RexNode translateInput(RelJson relJson, int input,
298298
throw new RuntimeException("input field " + input + " is out of range");
299299
}
300300

301+
public Object toJson(SqlParserPos pos) {
302+
final Map<String, @Nullable Object> map = jsonBuilder().map();
303+
map.put("line", pos.getLineNum());
304+
map.put("column", pos.getColumnNum());
305+
map.put("end_line", pos.getEndLineNum());
306+
map.put("end_column", pos.getEndColumnNum());
307+
return map;
308+
}
309+
301310
public Object toJson(RelCollationImpl node) {
302311
final List<Object> list = new ArrayList<>();
303312
for (RelFieldCollation fieldCollation : node.getFieldCollations()) {
@@ -455,6 +464,8 @@ public Object toJson(AggregateCall node) {
455464
|| value instanceof String
456465
|| value instanceof Boolean) {
457466
return value;
467+
} else if (value instanceof SqlParserPos) {
468+
return toJson((SqlParserPos) value);
458469
} else if (value instanceof RexNode) {
459470
return toJson((RexNode) value);
460471
} else if (value instanceof RexWindow) {
@@ -641,6 +652,9 @@ public Object toJson(RexNode node) {
641652
if (node instanceof RexCall) {
642653
final RexCall call = (RexCall) node;
643654
map = jsonBuilder().map();
655+
if (call.getParserPosition() != SqlParserPos.ZERO) {
656+
map.put("pos", toJson(call.getParserPosition()));
657+
}
644658
map.put("op", toJson(call.getOperator()));
645659
final List<@Nullable Object> list = jsonBuilder().list();
646660
for (RexNode operand : call.getOperands()) {
@@ -797,7 +811,7 @@ public RexNode toRex(RelOptCluster cluster, Object o) {
797811
exclude = RexWindowExclusion.EXCLUDE_NO_OTHER;
798812
}
799813
final boolean distinct = get((Map<String, Object>) map, "distinct");
800-
return rexBuilder.makeOver(type, operator, rexOperands, partitionKeys,
814+
return rexBuilder.makeOver(SqlParserPos.ZERO, type, operator, rexOperands, partitionKeys,
801815
ImmutableList.copyOf(orderKeys),
802816
requireNonNull(lowerBound, "lowerBound"),
803817
requireNonNull(upperBound, "upperBound"),

core/src/main/java/org/apache/calcite/rel/logical/LogicalWindow.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ public static RelNode create(RelOptCluster cluster,
182182
for (RexOver over : entry.getValue()) {
183183
final RexWinAggCall aggCall =
184184
new RexWinAggCall(
185+
over.getParserPosition(),
185186
over.getAggOperator(),
186187
over.getType(),
187188
toInputRefs(over.operands),

core/src/main/java/org/apache/calcite/rel/rules/ProjectWindowTransposeRule.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ public ProjectWindowTransposeRule(RelBuilderFactory relBuilderFactory) {
121121
boolean[] update = {false};
122122
final List<RexNode> clonedOperands = visitList(call.operands, update);
123123
if (update[0]) {
124-
return new Window.RexWinAggCall(
124+
return new Window.RexWinAggCall(call.getParserPosition(),
125125
(SqlAggFunction) call.getOperator(), call.getType(),
126126
clonedOperands, aggCall.ordinal, aggCall.distinct,
127127
aggCall.ignoreNulls);

core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,8 @@ public WindowReduceExpressionsRule(Class<? extends Window> windowClass,
579579
final List<RexNode> expList = new ArrayList<>(aggCall.getOperands());
580580
if (reduceExpressions(window, expList, predicates)) {
581581
aggCall =
582-
new Window.RexWinAggCall((SqlAggFunction) aggCall.getOperator(),
582+
new Window.RexWinAggCall(aggCall.getParserPosition(),
583+
(SqlAggFunction) aggCall.getOperator(),
583584
aggCall.type, expList,
584585
aggCall.ordinal, aggCall.distinct, aggCall.ignoreNulls);
585586
reduced = true;

core/src/main/java/org/apache/calcite/rex/RexBuilder.java

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -459,15 +459,38 @@ public RexNode makeOver(
459459
boolean nullWhenCountZero,
460460
boolean distinct,
461461
boolean ignoreNulls) {
462-
return makeOver(type, operator, exprs, partitionKeys, orderKeys, lowerBound, upperBound,
463-
RexWindowExclusion.EXCLUDE_NO_OTHER, rows, allowPartial, nullWhenCountZero, distinct,
462+
return makeOver(SqlParserPos.ZERO, type, operator, exprs, partitionKeys, orderKeys, lowerBound,
463+
upperBound, RexWindowExclusion.EXCLUDE_NO_OTHER, rows, allowPartial, nullWhenCountZero,
464+
distinct, ignoreNulls);
465+
}
466+
467+
/**
468+
* Creates a call to a windowed agg.
469+
*/
470+
public RexNode makeOver(
471+
RelDataType type,
472+
SqlAggFunction operator,
473+
List<RexNode> exprs,
474+
List<RexNode> partitionKeys,
475+
ImmutableList<RexFieldCollation> orderKeys,
476+
RexWindowBound lowerBound,
477+
RexWindowBound upperBound,
478+
RexWindowExclusion exclude,
479+
boolean rows,
480+
boolean allowPartial,
481+
boolean nullWhenCountZero,
482+
boolean distinct,
483+
boolean ignoreNulls) {
484+
return makeOver(SqlParserPos.ZERO, type, operator, exprs, partitionKeys, orderKeys,
485+
lowerBound, upperBound, exclude, rows, allowPartial, nullWhenCountZero, distinct,
464486
ignoreNulls);
465487
}
466488

467489
/**
468490
* Creates a call to a windowed agg.
469491
*/
470492
public RexNode makeOver(
493+
SqlParserPos pos,
471494
RelDataType type,
472495
SqlAggFunction operator,
473496
List<RexNode> exprs,
@@ -490,7 +513,7 @@ public RexNode makeOver(
490513
rows,
491514
exclude);
492515
RexNode result =
493-
new RexOver(type, operator, exprs, window, distinct, ignoreNulls);
516+
new RexOver(pos, type, operator, exprs, window, distinct, ignoreNulls);
494517

495518
// This should be correct but need time to go over test results.
496519
// Also want to look at combing with section below.
@@ -500,12 +523,12 @@ public RexNode makeOver(
500523
result =
501524
makeCall(SqlStdOperatorTable.CASE,
502525
makeCall(SqlStdOperatorTable.GREATER_THAN,
503-
new RexOver(bigintType, SqlStdOperatorTable.COUNT, exprs,
526+
new RexOver(pos, bigintType, SqlStdOperatorTable.COUNT, exprs,
504527
window, distinct, ignoreNulls),
505528
makeLiteral(BigDecimal.ZERO, bigintType,
506529
SqlTypeName.DECIMAL)),
507530
ensureType(type, // SUM0 is non-nullable, thus need a cast
508-
new RexOver(typeFactory.createTypeWithNullability(type, false),
531+
new RexOver(pos, typeFactory.createTypeWithNullability(type, false),
509532
operator, exprs, window, distinct, ignoreNulls),
510533
false),
511534
makeNullLiteral(type));
@@ -520,7 +543,7 @@ public RexNode makeOver(
520543
SqlStdOperatorTable.CASE,
521544
makeCall(
522545
SqlStdOperatorTable.GREATER_THAN_OR_EQUAL,
523-
new RexOver(
546+
new RexOver(pos,
524547
bigintType,
525548
SqlStdOperatorTable.COUNT,
526549
ImmutableList.of(),

core/src/main/java/org/apache/calcite/rex/RexCall.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public class RexCall extends RexNode {
6161
* the source position, so the backend can produce runtime error messages
6262
* pointing to the original source position.
6363
* For calls that are can never generate runtime failures, this field may
64-
* be ZERO. Note that some optimizations may "lost" position information. */
64+
* be ZERO. Note that some optimizations may "lose" position information. */
6565
public final SqlParserPos pos;
6666
public final SqlOperator op;
6767
public final ImmutableList<RexNode> operands;

core/src/main/java/org/apache/calcite/rex/RexCopier.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ private RelDataType copy(RelDataType type) {
5050

5151
@Override public RexNode visitOver(RexOver over) {
5252
final boolean[] update = null;
53-
return new RexOver(copy(over.getType()), over.getAggOperator(),
53+
return new RexOver(over.getParserPosition(), copy(over.getType()), over.getAggOperator(),
5454
visitList(over.getOperands(), update), visitWindow(over.getWindow()),
5555
over.isDistinct(), over.ignoreNulls());
5656
}

core/src/main/java/org/apache/calcite/rex/RexOver.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.apache.calcite.rel.type.RelDataType;
2020
import org.apache.calcite.sql.SqlAggFunction;
2121
import org.apache.calcite.sql.SqlWindow;
22+
import org.apache.calcite.sql.parser.SqlParserPos;
2223
import org.apache.calcite.util.ControlFlowException;
2324
import org.apache.calcite.util.Util;
2425

@@ -58,26 +59,57 @@ public class RexOver extends RexCall {
5859
* <li>window = {@link SqlWindow}(ROWS 3 PRECEDING)
5960
* </ul>
6061
*
62+
* @param pos Parser position
6163
* @param type Result type
6264
* @param op Aggregate operator
6365
* @param operands Operands list
6466
* @param window Window specification
6567
* @param distinct Aggregate operator is applied on distinct elements
6668
*/
6769
RexOver(
70+
SqlParserPos pos,
6871
RelDataType type,
6972
SqlAggFunction op,
7073
List<RexNode> operands,
7174
RexWindow window,
7275
boolean distinct,
7376
boolean ignoreNulls) {
74-
super(type, op, operands);
77+
super(pos, type, op, operands);
7578
checkArgument(op.isAggregator());
7679
this.window = requireNonNull(window, "window");
7780
this.distinct = distinct;
7881
this.ignoreNulls = ignoreNulls;
7982
}
8083

84+
/**
85+
* Creates a RexOver.
86+
*
87+
* <p>For example, "SUM(DISTINCT x) OVER (ROWS 3 PRECEDING)" is represented
88+
* as:
89+
*
90+
* <ul>
91+
* <li>type = Integer,
92+
* <li>op = {@link org.apache.calcite.sql.fun.SqlStdOperatorTable#SUM},
93+
* <li>operands = { {@link RexFieldAccess}("x") }
94+
* <li>window = {@link SqlWindow}(ROWS 3 PRECEDING)
95+
* </ul>
96+
*
97+
* @param type Result type
98+
* @param op Aggregate operator
99+
* @param operands Operands list
100+
* @param window Window specification
101+
* @param distinct Aggregate operator is applied on distinct elements
102+
*/
103+
RexOver(
104+
RelDataType type,
105+
SqlAggFunction op,
106+
List<RexNode> operands,
107+
RexWindow window,
108+
boolean distinct,
109+
boolean ignoreNulls) {
110+
this(SqlParserPos.ZERO, type, op, operands, window, distinct, ignoreNulls);
111+
}
112+
81113
//~ Methods ----------------------------------------------------------------
82114

83115
/**

core/src/main/java/org/apache/calcite/rex/RexShuttle.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ public class RexShuttle implements RexVisitor<RexNode> {
5050
// watch out for special operators like CAST and NEW where
5151
// the type is embedded in the original call.
5252
return new RexOver(
53+
over.getParserPosition(),
5354
over.getType(),
5455
overAggregator,
5556
clonedOperands,

0 commit comments

Comments
 (0)