@@ -30,8 +30,10 @@ import org.partiql.planner.internal.ir.identifierQualified
30
30
import org.partiql.planner.internal.ir.identifierSymbol
31
31
import org.partiql.planner.internal.ir.rex
32
32
import org.partiql.planner.internal.ir.rexOpCallStatic
33
+ import org.partiql.planner.internal.ir.rexOpCoalesce
33
34
import org.partiql.planner.internal.ir.rexOpCollection
34
35
import org.partiql.planner.internal.ir.rexOpLit
36
+ import org.partiql.planner.internal.ir.rexOpNullif
35
37
import org.partiql.planner.internal.ir.rexOpPathIndex
36
38
import org.partiql.planner.internal.ir.rexOpPathKey
37
39
import org.partiql.planner.internal.ir.rexOpPathSymbol
@@ -107,7 +109,7 @@ internal object RexConverter {
107
109
private fun visitExprCoerce (node : Expr , ctx : Env , coercion : Rex .Op .Subquery .Coercion = Rex .Op .Subquery .Coercion .SCALAR ): Rex {
108
110
val rex = super .visitExpr(node, ctx)
109
111
return when (rex.op is Rex .Op .Select ) {
110
- true -> rex(StaticType .ANY , rexOpSubquery(rex.op as Rex . Op . Select , coercion))
112
+ true -> rex(StaticType .ANY , rexOpSubquery(rex.op, coercion))
111
113
else -> rex
112
114
}
113
115
}
@@ -439,44 +441,21 @@ internal object RexConverter {
439
441
return rex(type, call)
440
442
}
441
443
442
- // coalesce(expr1, expr2, ... exprN) ->
443
- // CASE
444
- // WHEN expr1 IS NOT NULL THEN EXPR1
445
- // ...
446
- // WHEN exprn is NOT NULL THEN exprn
447
- // ELSE NULL END
448
- override fun visitExprCoalesce (node : Expr .Coalesce , ctx : Env ): Rex = plan {
444
+ override fun visitExprCoalesce (node : Expr .Coalesce , ctx : Env ): Rex {
449
445
val type = StaticType .ANY
450
- val createBranch: (Rex ) -> Rex .Op .Case .Branch = { expr: Rex ->
451
- val updatedCondition = rex(type, negate(call(" is_null" , expr)))
452
- rexOpCaseBranch(updatedCondition, expr)
446
+ val values = node.args.map { arg ->
447
+ visitExprCoerce(arg, ctx)
453
448
}
454
-
455
- val branches = node.args.map {
456
- createBranch(visitExpr(it, ctx))
457
- }.toMutableList()
458
-
459
- val defaultRex = rex(type = StaticType .NULL , op = rexOpLit(value = nullValue()))
460
- val op = rexOpCase(branches, defaultRex)
461
- rex(type, op)
449
+ val op = rexOpCoalesce(values)
450
+ return rex(type, op)
462
451
}
463
452
464
- // nullIf(expr1, expr2) ->
465
- // CASE
466
- // WHEN expr1 = expr2 THEN NULL
467
- // ELSE expr1 END
468
- override fun visitExprNullIf (node : Expr .NullIf , ctx : Env ): Rex = plan {
453
+ override fun visitExprNullIf (node : Expr .NullIf , ctx : Env ): Rex {
469
454
val type = StaticType .ANY
470
- val expr1 = visitExpr(node.value, ctx)
471
- val expr2 = visitExpr(node.nullifier, ctx)
472
- val id = identifierSymbol(Expr .Binary .Op .EQ .name.lowercase(), Identifier .CaseSensitivity .SENSITIVE )
473
- val fn = fnUnresolved(id, true )
474
- val call = rexOpCallStatic(fn, listOf (expr1, expr2))
475
- val branches = listOf (
476
- rexOpCaseBranch(rex(type, call), rex(type = StaticType .NULL , op = rexOpLit(value = nullValue()))),
477
- )
478
- val op = rexOpCase(branches.toMutableList(), expr1)
479
- rex(type, op)
455
+ val expr1 = visitExprCoerce(node.value, ctx)
456
+ val expr2 = visitExprCoerce(node.nullifier, ctx)
457
+ val op = rexOpNullif(expr1, expr2)
458
+ return rex(type, op)
480
459
}
481
460
482
461
/* *
0 commit comments