Skip to content

Commit b1244cc

Browse files
authored
Merge pull request #1435 from johnedquinn/v1-conformance-nullif-coalesce
Adds support for NULLIF and COALESCE
2 parents 41c00fd + 0bcc3e2 commit b1244cc

File tree

3 files changed

+63
-0
lines changed

3 files changed

+63
-0
lines changed

partiql-eval/src/main/kotlin/org/partiql/eval/internal/Compiler.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@ import org.partiql.eval.internal.operator.rex.ExprCallDynamic
2323
import org.partiql.eval.internal.operator.rex.ExprCallStatic
2424
import org.partiql.eval.internal.operator.rex.ExprCase
2525
import org.partiql.eval.internal.operator.rex.ExprCast
26+
import org.partiql.eval.internal.operator.rex.ExprCoalesce
2627
import org.partiql.eval.internal.operator.rex.ExprCollection
2728
import org.partiql.eval.internal.operator.rex.ExprLiteral
29+
import org.partiql.eval.internal.operator.rex.ExprNullIf
2830
import org.partiql.eval.internal.operator.rex.ExprPathIndex
2931
import org.partiql.eval.internal.operator.rex.ExprPathKey
3032
import org.partiql.eval.internal.operator.rex.ExprPathSymbol
@@ -132,6 +134,17 @@ internal class Compiler(
132134
}
133135
}
134136

137+
override fun visitRexOpCoalesce(node: Rex.Op.Coalesce, ctx: StaticType?): Operator {
138+
val args = Array(node.args.size) { visitRex(node.args[it], node.args[it].type) }
139+
return ExprCoalesce(args)
140+
}
141+
142+
override fun visitRexOpNullif(node: Rex.Op.Nullif, ctx: StaticType?): Operator {
143+
val value = visitRex(node.value, node.value.type)
144+
val nullifier = visitRex(node.nullifier, node.value.type)
145+
return ExprNullIf(value, nullifier)
146+
}
147+
135148
/**
136149
* All variables from the local scope have a depth of 0.
137150
*
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package org.partiql.eval.internal.operator.rex
2+
3+
import org.partiql.eval.internal.Environment
4+
import org.partiql.eval.internal.operator.Operator
5+
import org.partiql.value.PartiQLValue
6+
import org.partiql.value.PartiQLValueExperimental
7+
import org.partiql.value.PartiQLValueType
8+
import org.partiql.value.nullValue
9+
10+
internal class ExprCoalesce(
11+
private val args: Array<Operator.Expr>
12+
) : Operator.Expr {
13+
14+
@PartiQLValueExperimental
15+
override fun eval(env: Environment): PartiQLValue {
16+
for (arg in args) {
17+
val result = arg.eval(env)
18+
if (!result.isNull && result.type != PartiQLValueType.MISSING) {
19+
return result
20+
}
21+
}
22+
return nullValue()
23+
}
24+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package org.partiql.eval.internal.operator.rex
2+
3+
import org.partiql.eval.internal.Environment
4+
import org.partiql.eval.internal.operator.Operator
5+
import org.partiql.value.PartiQLValue
6+
import org.partiql.value.PartiQLValueExperimental
7+
import org.partiql.value.nullValue
8+
9+
internal class ExprNullIf(
10+
private val valueExpr: Operator.Expr,
11+
private val nullifierExpr: Operator.Expr
12+
) : Operator.Expr {
13+
14+
@OptIn(PartiQLValueExperimental::class)
15+
private val comparator = PartiQLValue.comparator()
16+
17+
@PartiQLValueExperimental
18+
override fun eval(env: Environment): PartiQLValue {
19+
val value = valueExpr.eval(env)
20+
val nullifier = nullifierExpr.eval(env)
21+
return when (comparator.compare(value, nullifier)) {
22+
0 -> nullValue()
23+
else -> value
24+
}
25+
}
26+
}

0 commit comments

Comments
 (0)