@@ -265,6 +265,8 @@ internal object RexConverter {
265
265
266
266
val fromList = mutableListOf<Rel >()
267
267
268
+ var varRefIndex = 0 // tracking var ref index
269
+
268
270
val pathNavi = newSteps.fold(newRoot) { current, step ->
269
271
val path = when (step) {
270
272
is Expr .Path .Step .Index -> {
@@ -298,17 +300,44 @@ internal object RexConverter {
298
300
op
299
301
}
300
302
303
+ // Unpivot and Wildcard steps trigger the rewrite
304
+ // According to spec Section 4.3
305
+ // ew1p1...wnpn
306
+ // rewrite to:
307
+ // SELECT VALUE v_n.p_n
308
+ // FROM
309
+ // u_1 e as v_1
310
+ // u_2 @v_1.p_1 as v_2
311
+ // ...
312
+ // u_n @v_(n-1).p_(n-1) as v_n
313
+ // The From clause needs to be rewritten to
314
+ // Join <------------------- schema: [(k_1), v_1, (k_2), v_2, ..., (k_(n-1)) v_(n-1)]
315
+ // / \
316
+ // ... un @v_(n-1).p_(n-1) <-- stack: [global, typeEnv: [outer: [global], schema: [(k_1), v_1, (k_2), v_2, ..., (k_(n-1)) v_(n-1)]]]
317
+ // Join <----------------------- schema: [(k_1), v_1, (k_2), v_2, (k_3), v_3]
318
+ // / \
319
+ // u_2 @v_1.p_1 as v2 <------- stack: [global, typeEnv: [outer: [global], schema: [(k_1), v_1, (k_2), v_2]]]
320
+ // JOIN <---------------------------- schema: [(k_1), v_1, (k_2), v_2]
321
+ // / \
322
+ // u_1 e as v_1 < ----\----------------------- stack: [global]
323
+ // u_2 @v_1.p_1 as v2 <------ stack: [global, typeEnv: [outer: [global], schema: [(k_1), v_1]]]
324
+ // while doing the traversal, instead of passing the stack,
325
+ // each join will produce its own schema and pass the schema as a type Env.
326
+ // The (k_i) indicate the possible key binding produced by unpivot.
327
+ // We calculate the var ref on the fly.
301
328
is Expr .Path .Step .Unpivot -> {
302
329
// Unpivot produces two binding, in this context we want the value,
303
330
// which always going to be the second binding
304
- val op = rexOpVarLocal(1 , 1 )
331
+ val op = rexOpVarLocal(1 , varRefIndex + 1 )
332
+ varRefIndex + = 2
305
333
val index = fromList.size
306
334
fromList.add(relFromUnpivot(current, index))
307
335
op
308
336
}
309
337
is Expr .Path .Step .Wildcard -> {
310
338
// Scan produce only one binding
311
- val op = rexOpVarLocal(1 , 0 )
339
+ val op = rexOpVarLocal(1 , varRefIndex)
340
+ varRefIndex + = 1
312
341
val index = fromList.size
313
342
fromList.add(relFromDefault(current, index))
314
343
op
0 commit comments