Skip to content

Commit 9718899

Browse files
authored
fix(javadoc): partial isthmus (#766)
Signed-off-by: MBWhite <whitemat@uk.ibm.com>
1 parent 57ac3fb commit 9718899

3 files changed

Lines changed: 189 additions & 4 deletions

File tree

isthmus/src/main/java/io/substrait/isthmus/SubstraitRelVisitor.java

Lines changed: 174 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,28 +73,57 @@ public class SubstraitRelVisitor extends RelNodeVisitor<Rel, RuntimeException> {
7373

7474
private static final Expression.BoolLiteral TRUE = ExpressionCreator.bool(false, true);
7575

76+
/** Converter for Calcite {@link RexNode} to Substrait {@link Expression}. */
7677
protected final RexExpressionConverter rexExpressionConverter;
78+
79+
/** Converter for {@link AggregateCall} to Substrait aggregate invocation. */
7780
protected final AggregateFunctionConverter aggregateFunctionConverter;
81+
82+
/** Converter for Calcite {@link RelDataType} to Substrait {@link Type}. */
7883
protected final TypeConverter typeConverter;
84+
7985
private Map<RexFieldAccess, Integer> fieldAccessDepthMap;
8086

81-
/** Use {@link SubstraitRelVisitor#SubstraitRelVisitor(ConverterProvider)} */
87+
/**
88+
* Creates a new SubstraitRelVisitor with the specified type factory and extensions.
89+
*
90+
* @param typeFactory the Calcite type factory
91+
* @param extensions the Substrait extension collection
92+
* @deprecated Use {@link SubstraitRelVisitor#SubstraitRelVisitor(ConverterProvider)}
93+
*/
8294
@Deprecated
8395
public SubstraitRelVisitor(
8496
RelDataTypeFactory typeFactory, SimpleExtension.ExtensionCollection extensions) {
8597
this(new ConverterProvider(extensions, typeFactory));
8698
}
8799

100+
/**
101+
* Creates a new SubstraitRelVisitor with the specified converter provider.
102+
*
103+
* @param converterProvider the converter provider containing configuration and converters
104+
*/
88105
public SubstraitRelVisitor(ConverterProvider converterProvider) {
89106
this.typeConverter = converterProvider.getTypeConverter();
90107
this.aggregateFunctionConverter = converterProvider.getAggregateFunctionConverter();
91108
this.rexExpressionConverter = converterProvider.getRexExpressionConverter(this);
92109
}
93110

111+
/**
112+
* Converts a {@link RexNode} to a Substrait {@link Expression}.
113+
*
114+
* @param node Rex expression node
115+
* @return Substrait expression
116+
*/
94117
protected Expression toExpression(RexNode node) {
95118
return node.accept(rexExpressionConverter);
96119
}
97120

121+
/**
122+
* Converts a Calcite {@link org.apache.calcite.rel.core.TableScan}.
123+
*
124+
* @param scan Calcite table scan
125+
* @return Substrait named scan
126+
*/
98127
@Override
99128
public Rel visit(org.apache.calcite.rel.core.TableScan scan) {
100129
NamedStruct type = typeConverter.toNamedStruct(scan.getRowType());
@@ -104,11 +133,23 @@ public Rel visit(org.apache.calcite.rel.core.TableScan scan) {
104133
.build();
105134
}
106135

136+
/**
137+
* Converts a Calcite {@link org.apache.calcite.rel.core.TableFunctionScan}.
138+
*
139+
* @param scan Calcite table function scan
140+
* @return Converted relation or {@code super.visit(scan)}
141+
*/
107142
@Override
108143
public Rel visit(org.apache.calcite.rel.core.TableFunctionScan scan) {
109144
return super.visit(scan);
110145
}
111146

147+
/**
148+
* Converts a Calcite {@link org.apache.calcite.rel.core.Values}.
149+
*
150+
* @param values Calcite values relation
151+
* @return Substrait scan (empty or virtual table)
152+
*/
112153
@Override
113154
public Rel visit(org.apache.calcite.rel.core.Values values) {
114155
NamedStruct type = typeConverter.toNamedStruct(values.getRowType());
@@ -134,17 +175,35 @@ public Rel visit(org.apache.calcite.rel.core.Values values) {
134175
return VirtualTableScan.builder().initialSchema(type).addAllRows(structs).build();
135176
}
136177

178+
/**
179+
* Converts a Calcite {@link org.apache.calcite.rel.core.Filter}.
180+
*
181+
* @param filter Calcite filter relation
182+
* @return Substrait filter
183+
*/
137184
@Override
138185
public Rel visit(org.apache.calcite.rel.core.Filter filter) {
139186
Expression condition = toExpression(filter.getCondition());
140187
return Filter.builder().condition(condition).input(apply(filter.getInput())).build();
141188
}
142189

190+
/**
191+
* Converts a Calcite {@link org.apache.calcite.rel.core.Calc}.
192+
*
193+
* @param calc Calcite calc relation
194+
* @return Converted relation
195+
*/
143196
@Override
144197
public Rel visit(org.apache.calcite.rel.core.Calc calc) {
145198
return super.visit(calc);
146199
}
147200

201+
/**
202+
* Converts a Calcite {@link org.apache.calcite.rel.core.Project}.
203+
*
204+
* @param project Calcite project relation
205+
* @return Substrait project
206+
*/
148207
@Override
149208
public Rel visit(org.apache.calcite.rel.core.Project project) {
150209
List<Expression> expressions =
@@ -166,6 +225,12 @@ public Rel visit(org.apache.calcite.rel.core.Project project) {
166225
.build();
167226
}
168227

228+
/**
229+
* Converts a Calcite {@link org.apache.calcite.rel.core.Join}.
230+
*
231+
* @param join Calcite join relation
232+
* @return Substrait join or cross
233+
*/
169234
@Override
170235
public Rel visit(org.apache.calcite.rel.core.Join join) {
171236
Rel left = apply(join.getLeft());
@@ -200,6 +265,12 @@ private Join.JoinType asJoinType(org.apache.calcite.rel.core.Join join) {
200265
throw new UnsupportedOperationException("Unsupported join type: " + join.getJoinType());
201266
}
202267

268+
/**
269+
* Converts a Calcite {@link org.apache.calcite.rel.core.Correlate}.
270+
*
271+
* @param correlate Calcite correlate relation
272+
* @return Converted relation
273+
*/
203274
@Override
204275
public Rel visit(org.apache.calcite.rel.core.Correlate correlate) {
205276
// left input of correlated-join is similar to the left input of a logical join
@@ -211,13 +282,25 @@ public Rel visit(org.apache.calcite.rel.core.Correlate correlate) {
211282
return super.visit(correlate);
212283
}
213284

285+
/**
286+
* Converts a Calcite {@link org.apache.calcite.rel.core.Union}.
287+
*
288+
* @param union Calcite union relation
289+
* @return Substrait set-union
290+
*/
214291
@Override
215292
public Rel visit(org.apache.calcite.rel.core.Union union) {
216293
List<Rel> inputs = apply(union.getInputs());
217294
Set.SetOp setOp = union.all ? Set.SetOp.UNION_ALL : Set.SetOp.UNION_DISTINCT;
218295
return Set.builder().inputs(inputs).setOp(setOp).build();
219296
}
220297

298+
/**
299+
* Converts a Calcite {@link org.apache.calcite.rel.core.Intersect}.
300+
*
301+
* @param intersect Calcite intersect relation
302+
* @return Substrait set-intersection
303+
*/
221304
@Override
222305
public Rel visit(org.apache.calcite.rel.core.Intersect intersect) {
223306
List<Rel> inputs = apply(intersect.getInputs());
@@ -226,13 +309,26 @@ public Rel visit(org.apache.calcite.rel.core.Intersect intersect) {
226309
return Set.builder().inputs(inputs).setOp(setOp).build();
227310
}
228311

312+
/**
313+
* Converts a Calcite {@link org.apache.calcite.rel.core.Minus}.
314+
*
315+
* @param minus Calcite minus relation
316+
* @return Substrait set-minus
317+
*/
229318
@Override
230319
public Rel visit(org.apache.calcite.rel.core.Minus minus) {
231320
List<Rel> inputs = apply(minus.getInputs());
232321
Set.SetOp setOp = minus.all ? Set.SetOp.MINUS_PRIMARY_ALL : Set.SetOp.MINUS_PRIMARY;
233322
return Set.builder().inputs(inputs).setOp(setOp).build();
234323
}
235324

325+
/**
326+
* Converts a Calcite {@link org.apache.calcite.rel.core.Aggregate}.
327+
*
328+
* @param aggregate Calcite aggregate relation
329+
* @return Substrait aggregate
330+
* @throws IllegalStateException if unexpected remap state is encountered.
331+
*/
236332
@Override
237333
public Rel visit(org.apache.calcite.rel.core.Aggregate aggregate) {
238334
Rel input = apply(aggregate.getInput());
@@ -331,11 +427,23 @@ Aggregate.Measure fromAggCall(RelNode input, Type.Struct inputType, AggregateCal
331427
return builder.build();
332428
}
333429

430+
/**
431+
* Converts a Calcite {@link org.apache.calcite.rel.core.Match}.
432+
*
433+
* @param match Calcite match relation
434+
* @return Converted relation
435+
*/
334436
@Override
335437
public Rel visit(org.apache.calcite.rel.core.Match match) {
336438
return super.visit(match);
337439
}
338440

441+
/**
442+
* Converts a Calcite {@link org.apache.calcite.rel.core.Sort}.
443+
*
444+
* @param sort Calcite sort relation
445+
* @return Substrait sort/fetch chain
446+
*/
339447
@Override
340448
public Rel visit(org.apache.calcite.rel.core.Sort sort) {
341449
Rel input = apply(sort.getInput());
@@ -377,6 +485,13 @@ private long asLong(RexNode rex) {
377485
throw new UnsupportedOperationException("Unknown type: " + rex);
378486
}
379487

488+
/**
489+
* Converts a Calcite sort collation to a Substrait {@link Expression.SortField}.
490+
*
491+
* @param collation Calcite field collation
492+
* @param inputType Input record type
493+
* @return Substrait sort field
494+
*/
380495
public static Expression.SortField toSortField(
381496
RelFieldCollation collation, Type.Struct inputType) {
382497
Expression.SortDirection direction = asSortDirection(collation);
@@ -405,11 +520,24 @@ private static Expression.SortDirection asSortDirection(RelFieldCollation collat
405520
throw new IllegalArgumentException("Unsupported collation direction: " + direction);
406521
}
407522

523+
/**
524+
* Converts a Calcite {@link org.apache.calcite.rel.core.Exchange}.
525+
*
526+
* @param exchange Calcite exchange relation
527+
* @return Converted relation
528+
*/
408529
@Override
409530
public Rel visit(org.apache.calcite.rel.core.Exchange exchange) {
410531
return super.visit(exchange);
411532
}
412533

534+
/**
535+
* Converts a Calcite {@link TableModify} (INSERT/DELETE/UPDATE).
536+
*
537+
* @param modify Calcite table modify node
538+
* @return Substrait write/update relation
539+
* @throws IllegalStateException if an update column is not found in the table schema.
540+
*/
413541
@Override
414542
public Rel visit(TableModify modify) {
415543
switch (modify.getOperation()) {
@@ -518,6 +646,12 @@ private NamedStruct getSchema(final RelNode queryRelRoot) {
518646
return typeConverter.toNamedStruct(rowType);
519647
}
520648

649+
/**
650+
* Handles Calcite {@link CreateTable} as Substrait CTAS. (Create Table As Select)
651+
*
652+
* @param createTable Calcite create-table node
653+
* @return Substrait CTAS write relation
654+
*/
521655
public Rel handleCreateTable(CreateTable createTable) {
522656
RelNode input = createTable.getInput();
523657
Rel inputRel = apply(input);
@@ -532,6 +666,12 @@ public Rel handleCreateTable(CreateTable createTable) {
532666
.build();
533667
}
534668

669+
/**
670+
* Handles Calcite {@link CreateView} as Substrait view DDL.
671+
*
672+
* @param createView Calcite create-view node
673+
* @return Substrait view DDL relation
674+
*/
535675
public Rel handleCreateView(CreateView createView) {
536676
RelNode input = createView.getInput();
537677
Rel inputRel = apply(input);
@@ -548,6 +688,13 @@ public Rel handleCreateView(CreateView createView) {
548688
.build();
549689
}
550690

691+
/**
692+
* Visits other Calcite nodes (e.g., DDL wrappers).
693+
*
694+
* @param other Calcite node
695+
* @return Converted relation
696+
* @throws UnsupportedOperationException if the node type is unsupported.
697+
*/
551698
@Override
552699
public Rel visitOther(RelNode other) {
553700
if (other instanceof CreateTable) {
@@ -559,19 +706,42 @@ public Rel visitOther(RelNode other) {
559706
throw new UnsupportedOperationException("Unable to handle node: " + other);
560707
}
561708

709+
/**
710+
* Precomputes depth for outer field accesses used by correlated expressions.
711+
*
712+
* @param root Root Calcite node to analyze
713+
*/
562714
protected void popFieldAccessDepthMap(RelNode root) {
563715
final OuterReferenceResolver resolver = new OuterReferenceResolver();
564716
fieldAccessDepthMap = resolver.apply(root);
565717
}
566718

719+
/**
720+
* Returns the depth of a field access for correlated expressions.
721+
*
722+
* @param fieldAccess Rex field access
723+
* @return Depth value, or {@code null} if unknown
724+
*/
567725
public Integer getFieldAccessDepth(RexFieldAccess fieldAccess) {
568726
return fieldAccessDepthMap.get(fieldAccess);
569727
}
570728

729+
/**
730+
* Applies the visitor to a Calcite {@link RelNode}.
731+
*
732+
* @param r Calcite node
733+
* @return Converted Substrait relation
734+
*/
571735
public Rel apply(RelNode r) {
572736
return reverseAccept(r);
573737
}
574738

739+
/**
740+
* Applies the visitor to a list of Calcite {@link RelNode}s.
741+
*
742+
* @param inputs Calcite input relations
743+
* @return Converted Substrait relations
744+
*/
575745
public List<Rel> apply(List<RelNode> inputs) {
576746
return inputs.stream()
577747
.map(inputRel -> apply(inputRel))
@@ -581,9 +751,9 @@ public List<Rel> apply(List<RelNode> inputs) {
581751
/**
582752
* Deprecated, use {@link #convert(RelRoot, ConverterProvider)} directly
583753
*
584-
* @param relRoot The Calcite RelRoot to convert.
585-
* @param extensions The extension collection to use for the conversion.
586-
* @return The resulting Substrait Plan.Root.
754+
* @param relRoot The Calcite RelRoot to convert
755+
* @param extensions The extension collection to use for the conversion
756+
* @return The resulting Substrait Plan.Root
587757
*/
588758
@Deprecated
589759
public static Plan.Root convert(RelRoot relRoot, SimpleExtension.ExtensionCollection extensions) {

isthmus/src/main/java/io/substrait/isthmus/SubstraitToCalcite.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ public SubstraitToCalcite(ConverterProvider converterProvider) {
3333
this(converterProvider, null);
3434
}
3535

36+
/**
37+
* Creates a Substrait-to-Calcite converter with default type converter and a catalog reader.
38+
*
39+
* @param converterProvider the converter provider containing configuration and converters
40+
* @param catalogReader Calcite catalog reader for schema resolution.
41+
*/
3642
public SubstraitToCalcite(
3743
ConverterProvider converterProvider, Prepare.CatalogReader catalogReader) {
3844
this.converterProvider = converterProvider;

isthmus/src/main/java/io/substrait/isthmus/SubstraitToSql.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,15 @@ public SubstraitToSql(ConverterProvider converterProvider) {
3535
substraitToCalcite = converterProvider.getSubstraitToCalcite();
3636
}
3737

38+
/**
39+
* Converts a Substrait {@link Rel} to a Calcite {@link RelNode}.
40+
*
41+
* <p>This is the first step before generating SQL from Substrait plans.
42+
*
43+
* @param relRoot The Substrait relational root to convert.
44+
* @param catalog The Calcite catalog reader for schema resolution.
45+
* @return A Calcite {@link RelNode} representing the converted Substrait plan.
46+
*/
3847
public RelNode substraitRelToCalciteRel(Rel relRoot, Prepare.CatalogReader catalog) {
3948
return SubstraitRelNodeConverter.convert(relRoot, catalog, converterProvider);
4049
}

0 commit comments

Comments
 (0)