Skip to content

Commit

Permalink
Merge pull request #1508 from johnedquinn/v1-conformance-variable-res…
Browse files Browse the repository at this point in the history
…olution

Updates rules for variable resolution
  • Loading branch information
johnedquinn authored Jul 15, 2024
2 parents ff03b0a + 86718c2 commit 8b4e0d3
Show file tree
Hide file tree
Showing 14 changed files with 386 additions and 341 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import org.partiql.value.Int64Value
import org.partiql.value.Int8Value
import org.partiql.value.IntValue
import org.partiql.value.ListValue
import org.partiql.value.MissingValue
import org.partiql.value.NullValue
import org.partiql.value.NumericValue
import org.partiql.value.PartiQLValue
Expand All @@ -46,6 +47,7 @@ import org.partiql.value.int64Value
import org.partiql.value.int8Value
import org.partiql.value.intValue
import org.partiql.value.listValue
import org.partiql.value.missingValue
import org.partiql.value.sexpValue
import org.partiql.value.stringValue
import org.partiql.value.structValue
Expand All @@ -59,7 +61,8 @@ import java.math.BigInteger
internal class ExprCast(val arg: Operator.Expr, val cast: Ref.Cast) : Operator.Expr {
@OptIn(PartiQLValueExperimental::class)
override fun eval(env: Environment): Datum {
val arg = arg.eval(env).toPartiQLValue()
val argDatum = arg.eval(env)
val arg = argDatum.toPartiQLValue()
try {
val partiqlValue = when (PType.fromPartiQLValueType(arg.type).kind) {
PType.Kind.DYNAMIC -> TODO("Not Possible")
Expand All @@ -86,9 +89,9 @@ internal class ExprCast(val arg: Operator.Expr, val cast: Ref.Cast) : Operator.E
PType.Kind.BAG -> castFromCollection(arg as BagValue<*>, cast.target)
PType.Kind.LIST -> castFromCollection(arg as ListValue<*>, cast.target)
PType.Kind.SEXP -> castFromCollection(arg as SexpValue<*>, cast.target)
PType.Kind.STRUCT -> TODO("CAST FROM STRUCT not yet implemented")
PType.Kind.STRUCT -> castFromStruct(argDatum, cast.target).toPartiQLValue()
PType.Kind.ROW -> TODO("CAST FROM ROW not yet implemented")
PType.Kind.UNKNOWN -> TODO("CAST FROM UNKNOWN not yet implemented")
PType.Kind.UNKNOWN -> castFromUnknown(arg, cast.target)
PType.Kind.VARCHAR -> TODO("CAST FROM VARCHAR not yet implemented")
}
return Datum.of(partiqlValue)
Expand All @@ -97,6 +100,22 @@ internal class ExprCast(val arg: Operator.Expr, val cast: Ref.Cast) : Operator.E
}
}

/**
* For now, we cannot cast from struct to anything else. Throw a type check exception.
*/
private fun castFromStruct(value: Datum, t: PType): Datum {
throw TypeCheckException()
}

@OptIn(PartiQLValueExperimental::class)
private fun castFromUnknown(value: PartiQLValue, t: PType): PartiQLValue {
return when (value) {
is NullValue -> castFromNull(value, t)
is MissingValue -> missingValue() // TODO: Is this allowed?
else -> error("This shouldn't have happened")
}
}

@OptIn(PartiQLValueExperimental::class)
private fun castFromNull(value: NullValue, t: PType): PartiQLValue {
return when (t.kind) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1311,7 +1311,16 @@ class PartiQLEngineDefaultTest {

internal fun assert() {
val permissiveResult = run(mode = PartiQLEngine.Mode.PERMISSIVE)
assert(expectedPermissive == permissiveResult.first) {
val assertionCondition = try {
expectedPermissive == permissiveResult.first
} catch (t: Throwable) {
val str = buildString {
appendLine("Test Name: $name")
PlanPrinter.append(this, permissiveResult.second)
}
throw RuntimeException(str, t)
}
assert(assertionCondition) {
comparisonString(expectedPermissive, permissiveResult.first, permissiveResult.second)
}
var error: Throwable? = null
Expand Down Expand Up @@ -1344,7 +1353,13 @@ class PartiQLEngineDefaultTest {
val prepared = engine.prepare(plan.plan, PartiQLEngine.Session(mapOf("memory" to connector), mode = mode))
when (val result = engine.execute(prepared)) {
is PartiQLResult.Value -> return result.value to plan.plan
is PartiQLResult.Error -> throw result.cause
is PartiQLResult.Error -> {
val str = buildString {
appendLine("Execution resulted in an unexpected error. Plan:")
PlanPrinter.append(this, plan.plan)
}
throw RuntimeException(str, result.cause)
}
}
}

Expand All @@ -1368,51 +1383,26 @@ class PartiQLEngineDefaultTest {
}

@Test
@Disabled
fun developmentTest() {
val tc = SuccessTestCase(
input = """
SELECT *
EXCLUDE
t.a.b.c[*].field_x
FROM [{
'a': {
'b': {
'c': [
{ -- c[0]; field_x to be removed
'field_x': 0,
'field_y': 0
},
{ -- c[1]; field_x to be removed
'field_x': 1,
'field_y': 1
},
{ -- c[2]; field_x to be removed
'field_x': 2,
'field_y': 2
}
]
}
}
}] AS t
""".trimIndent(),
expected = bagValue(
structValue(
"a" to structValue(
"b" to structValue(
"c" to listValue(
structValue(
"field_y" to int32Value(0)
),
structValue(
"field_y" to int32Value(1)
),
structValue(
"field_y" to int32Value(2)
)
)
)
)
)
SELECT VALUE
CASE x + 1
WHEN NULL THEN 'shouldnt be null'
WHEN MISSING THEN 'shouldnt be missing'
WHEN i THEN 'ONE'
WHEN f THEN 'TWO'
WHEN d THEN 'THREE'
ELSE '?'
END
FROM << i, f, d, null, missing >> AS x
""",
expected = boolValue(true),
globals = listOf(
SuccessTestCase.Global("i", "1"),
SuccessTestCase.Global("f", "2e0"),
SuccessTestCase.Global("d", "3.")
)
)
tc.assert()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import org.partiql.planner.internal.ir.rexOpCallDynamicCandidate
import org.partiql.planner.internal.ir.rexOpCastResolved
import org.partiql.planner.internal.ir.rexOpVarGlobal
import org.partiql.planner.internal.typer.CompilerType
import org.partiql.planner.internal.typer.TypeEnv.Companion.toPath
import org.partiql.planner.internal.typer.Scope.Companion.toPath
import org.partiql.spi.BindingCase
import org.partiql.spi.BindingName
import org.partiql.spi.BindingPath
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.partiql.planner.internal
import org.partiql.planner.internal.casts.Coercions
import org.partiql.planner.internal.ir.Ref
import org.partiql.planner.internal.typer.CompilerType
import org.partiql.planner.internal.typer.PlanTyper.Companion.toCType
import org.partiql.spi.fn.FnExperimental
import org.partiql.spi.fn.FnSignature
import org.partiql.types.PType.Kind
Expand Down Expand Up @@ -144,10 +145,14 @@ internal object FnResolver {
exactInputTypes++
continue
}
// 2. Match ANY, no coercion needed
// TODO: Rewrite args in this scenario
arg.kind == Kind.UNKNOWN || p.type.kind == Kind.DYNAMIC || arg.kind == Kind.DYNAMIC -> continue
// 3. Check for a coercion
// 2. Match ANY parameter, no coercion needed
p.type.kind == Kind.DYNAMIC -> continue
arg.kind == Kind.UNKNOWN -> continue
// 3. Allow for ANY arguments
arg.kind == Kind.DYNAMIC -> {
mapping[i] = Ref.Cast(arg, p.type.toCType(), Ref.Cast.Safety.UNSAFE, true)
}
// 4. Check for a coercion
else -> when (val coercion = Coercions.get(arg, p.type)) {
null -> return null // short-circuit
else -> mapping[i] = coercion
Expand Down
Loading

0 comments on commit 8b4e0d3

Please sign in to comment.