@@ -56,8 +56,20 @@ internal class Compiler(
56
56
private val symbols : Symbols
57
57
) : PlanBaseVisitor<Operator, StaticType?>() {
58
58
59
+ /* *
60
+ * The variables environment
61
+ */
59
62
private val env: Environment = Environment ()
60
63
64
+ /* *
65
+ * Aids in determining the index by which we will query [Environment.get] for [Rex.Op.Var.depth].
66
+ *
67
+ * @see scope
68
+ * @see Environment
69
+ * @see Rex.Op.Var
70
+ */
71
+ private var scopeSize = 0
72
+
61
73
fun compile (): Operator .Expr {
62
74
return visitPartiQLPlan(plan, null )
63
75
}
@@ -108,28 +120,34 @@ internal class Compiler(
108
120
}
109
121
110
122
override fun visitRexOpSelect (node : Rex .Op .Select , ctx : StaticType ? ): Operator .Expr {
111
- val rel = visitRel(node.rel, ctx)
112
- val ordered = node.rel.type.props.contains(Rel .Prop .ORDERED )
113
- val constructor = visitRex(node.constructor , ctx).modeHandled()
114
- return ExprSelect (rel, constructor , ordered, env)
123
+ return scope {
124
+ val rel = visitRel(node.rel, ctx)
125
+ val ordered = node.rel.type.props.contains(Rel .Prop .ORDERED )
126
+ val constructor = visitRex(node.constructor , ctx).modeHandled()
127
+ ExprSelect (rel, constructor , ordered, env)
128
+ }
115
129
}
116
130
117
131
override fun visitRexOpSubquery (node : Rex .Op .Subquery , ctx : StaticType ? ): Operator {
118
- val constructor = visitRex(node.constructor , ctx)
119
- val input = visitRel(node.rel, ctx)
120
- return when (node.coercion) {
121
- Rex .Op .Subquery .Coercion .SCALAR -> ExprSubquery .Scalar (constructor , input, env)
122
- Rex .Op .Subquery .Coercion .ROW -> ExprSubquery .Row (constructor , input, env)
132
+ return scope {
133
+ val constructor = visitRex(node.constructor , ctx)
134
+ val input = visitRel(node.rel, ctx)
135
+ when (node.coercion) {
136
+ Rex .Op .Subquery .Coercion .SCALAR -> ExprSubquery .Scalar (constructor , input, env)
137
+ Rex .Op .Subquery .Coercion .ROW -> ExprSubquery .Row (constructor , input, env)
138
+ }
123
139
}
124
140
}
125
141
126
142
override fun visitRexOpPivot (node : Rex .Op .Pivot , ctx : StaticType ? ): Operator {
127
- val rel = visitRel(node.rel, ctx)
128
- val key = visitRex(node.key, ctx)
129
- val value = visitRex(node.value, ctx)
130
- return when (session.mode) {
131
- PartiQLEngine .Mode .PERMISSIVE -> ExprPivotPermissive (rel, key, value)
132
- PartiQLEngine .Mode .STRICT -> ExprPivot (rel, key, value)
143
+ return scope {
144
+ val rel = visitRel(node.rel, ctx)
145
+ val key = visitRex(node.key, ctx)
146
+ val value = visitRex(node.value, ctx)
147
+ when (session.mode) {
148
+ PartiQLEngine .Mode .PERMISSIVE -> ExprPivotPermissive (rel, key, value)
149
+ PartiQLEngine .Mode .STRICT -> ExprPivot (rel, key, value)
150
+ }
133
151
}
134
152
}
135
153
@@ -142,7 +160,10 @@ internal class Compiler(
142
160
override fun visitRexOpVar (node : Rex .Op .Var , ctx : StaticType ? ): Operator {
143
161
return when (node.depth) {
144
162
0 -> ExprVarLocal (node.ref)
145
- else -> ExprVarOuter (node.depth - 1 , node.ref, env)
163
+ else -> {
164
+ val index = scopeSize - node.depth
165
+ ExprVarOuter (index, node.ref, env)
166
+ }
146
167
}
147
168
}
148
169
@@ -249,7 +270,7 @@ internal class Compiler(
249
270
250
271
override fun visitRelOpJoin (node : Rel .Op .Join , ctx : StaticType ? ): Operator {
251
272
val lhs = visitRel(node.lhs, ctx)
252
- val rhs = visitRel(node.rhs, ctx)
273
+ val rhs = scope { visitRel(node.rhs, ctx) }
253
274
val condition = visitRex(node.rex, ctx)
254
275
return when (node.type) {
255
276
Rel .Op .Join .Type .INNER -> RelJoinInner (lhs, rhs, condition, env)
@@ -320,4 +341,20 @@ internal class Compiler(
320
341
}
321
342
return item
322
343
}
344
+
345
+ /* *
346
+ * Figuratively creates a new scope by incrementing/decrementing the [scopeSize] before/after the [block] invocation.
347
+ *
348
+ * @see scopeSize
349
+ * @see Environment
350
+ * @see Rex.Op.Var
351
+ */
352
+ private inline fun <T > scope (block : () -> T ): T {
353
+ scopeSize++
354
+ try {
355
+ return block.invoke()
356
+ } finally {
357
+ scopeSize--
358
+ }
359
+ }
323
360
}
0 commit comments