Hi Devs,
I am looking into how Calcite handles nested lambda expressions,
particularly as it relates to integrating with *Substrait
<https://substrait.io/expressions/lambda_expressions/#lambdaparameterreference-fields>*
.
In Substrait, nested lambdas use a steps_out mechanism to reference
parameters in parent scopes.
For example: (outer_x) -> ((inner_y) -> add(outer_x, inner_y))
# - steps_out: 1 with struct_field: 0 -> outer_x
# - steps_out: 0 with struct_field: 0 -> inner_y
This would be the Calcite representation of the expression:
The RexNode Hierarchy
-
*Top Level*: RexLambda
-
*Parameters*: [RexLambdaRef(name="outer_x", index=0)]
-
*Body*: (Another RexLambda)
-
*Parameters*: [RexLambdaRef(name="inner_y", index=0)]
-
*Body*: RexCall(op: ADD)
-
*Operand 0*: RexLambdaRef (refers to inner_y)
-
*Operand 1*: RexLambdaRef (refers to outer_x)
I have a few questions regarding Calcite's RexLambda and RexLambdaRef:
1- Does Calcite natively support lexical scoping where an inner RexLambda
body contains a RexLambdaRef pointing to a parameter defined in an outer
RexLambda?
2- Is there a recommended way to represent this "depth" or "step out" logic
within RexLambdaRef, or does Calcite assume the visitor/shuttle will manage
the scope stack during traversal?
Thanks,
Limame Malainine