Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PIG domains for planner and plan evaluator #584

Merged
merged 9 commits into from
May 10, 2022
303 changes: 303 additions & 0 deletions lang/resources/org/partiql/type-domains/partiql.ion

Large diffs are not rendered by default.

28 changes: 18 additions & 10 deletions lang/test/org/partiql/lang/eval/EvaluatingCompilerExceptionsTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import org.junit.jupiter.params.provider.ArgumentsSource
import org.partiql.lang.errors.ErrorCode
import org.partiql.lang.errors.Property
import org.partiql.lang.eval.evaluatortestframework.EvaluatorErrorTestCase
import org.partiql.lang.eval.evaluatortestframework.EvaluatorTestTarget
import org.partiql.lang.util.ArgumentsProviderBase
import org.partiql.lang.util.propertyValueMapOf
import org.partiql.lang.util.rootCause
Expand All @@ -33,7 +34,6 @@ class EvaluatingCompilerExceptionsTest : EvaluatorTestBase() {
// to follow a pattern that we'd like to change anyway.
// FIXME - these tests don't seem to work, and when enabled the options are set but the `FLOAT` type is missing
// the parameter at the point we test it in the EvaluatingCompiler
// XXX - for some reason, @Ignore did not work on this parameterized test.
@Disabled
@ParameterizedTest
@ArgumentsSource(ErrorTestCasesTestCases::class)
Expand Down Expand Up @@ -99,28 +99,32 @@ class EvaluatingCompilerExceptionsTest : EvaluatorTestBase() {
"""SELECT VALUE a FROM `[{v:5}]` AS item, @item.v AS a, @item.v AS a""",
ErrorCode.EVALUATOR_AMBIGUOUS_BINDING,
expectedErrorContext = propertyValueMapOf(1, 14, Property.BINDING_NAME to "a", Property.BINDING_NAME_MATCHES to "a, a"),
expectedPermissiveModeResult = "<<MISSING>>"
expectedPermissiveModeResult = "<<MISSING>>",
target = EvaluatorTestTarget.COMPILER_PIPELINE
)

@Test
fun topLevelCountStar() = runEvaluatorErrorTestCase(
"""COUNT(*)""",
ErrorCode.EVALUATOR_COUNT_START_NOT_ALLOWED,
expectedErrorContext = propertyValueMapOf(1, 1)
expectedErrorContext = propertyValueMapOf(1, 1),
target = EvaluatorTestTarget.COMPILER_PIPELINE
)

@Test
fun selectValueCountStar() = runEvaluatorErrorTestCase(
"""SELECT VALUE COUNT(*) FROM numbers""",
ErrorCode.EVALUATOR_COUNT_START_NOT_ALLOWED,
expectedErrorContext = propertyValueMapOf(1, 14)
expectedErrorContext = propertyValueMapOf(1, 14),
target = EvaluatorTestTarget.COMPILER_PIPELINE
)

@Test
fun selectListNestedAggregateCall() = runEvaluatorErrorTestCase(
"""SELECT SUM(AVG(n)) FROM <<numbers, numbers>> AS n""",
ErrorCode.EVALUATOR_INVALID_ARGUMENTS_FOR_AGG_FUNCTION,
expectedErrorContext = propertyValueMapOf(1, 12)
expectedErrorContext = propertyValueMapOf(1, 12),
target = EvaluatorTestTarget.COMPILER_PIPELINE
)

private val sqlWithUndefinedVariable = "SELECT VALUE y FROM << 'el1' >> AS x"
Expand All @@ -140,7 +144,8 @@ class EvaluatingCompilerExceptionsTest : EvaluatorTestBase() {
// Same query as previous test--but DO NOT throw exception this time because of UndefinedVariableBehavior.MISSING
runEvaluatorTestCase(
sqlWithUndefinedVariable, expectedResult = "[null]",
compileOptionsBuilderBlock = { undefinedVariable(UndefinedVariableBehavior.MISSING) }
compileOptionsBuilderBlock = { undefinedVariable(UndefinedVariableBehavior.MISSING) },
target = EvaluatorTestTarget.COMPILER_PIPELINE
)

private val sqlWithUndefinedQuotedVariable = "SELECT VALUE \"y\" FROM << 'el1' >> AS x"
Expand All @@ -151,7 +156,7 @@ class EvaluatingCompilerExceptionsTest : EvaluatorTestBase() {
sqlWithUndefinedQuotedVariable,
ErrorCode.EVALUATOR_QUOTED_BINDING_DOES_NOT_EXIST,
propertyValueMapOf(1, 14, Property.BINDING_NAME to "y"),
expectedPermissiveModeResult = "<<MISSING>>"
expectedPermissiveModeResult = "<<MISSING>>",
)
}

Expand All @@ -160,7 +165,8 @@ class EvaluatingCompilerExceptionsTest : EvaluatorTestBase() {
// Same query as previous test--but DO NOT throw exception this time because of UndefinedVariableBehavior.MISSING
runEvaluatorTestCase(
sqlWithUndefinedQuotedVariable, expectedResult = "[null]",
compileOptionsBuilderBlock = { undefinedVariable(UndefinedVariableBehavior.MISSING) }
compileOptionsBuilderBlock = { undefinedVariable(UndefinedVariableBehavior.MISSING) },
target = EvaluatorTestTarget.COMPILER_PIPELINE
)

@Test
Expand All @@ -187,14 +193,16 @@ class EvaluatingCompilerExceptionsTest : EvaluatorTestBase() {
fun rightJoin() = runEvaluatorErrorTestCase(
"SELECT * FROM animals AS a RIGHT CROSS JOIN animal_types AS a_type WHERE a.type = a_type.id",
ErrorCode.EVALUATOR_FEATURE_NOT_SUPPORTED_YET,
expectedErrorContext = propertyValueMapOf(1, 28, Property.FEATURE_NAME to "RIGHT and FULL JOIN")
expectedErrorContext = propertyValueMapOf(1, 28, Property.FEATURE_NAME to "RIGHT and FULL JOIN"),
target = EvaluatorTestTarget.COMPILER_PIPELINE
)

@Test
fun outerJoin() = runEvaluatorErrorTestCase(
"SELECT * FROM animals AS a OUTER CROSS JOIN animal_types AS a_type WHERE a.type = a_type.id",
ErrorCode.EVALUATOR_FEATURE_NOT_SUPPORTED_YET,
expectedErrorContext = propertyValueMapOf(1, 28, Property.FEATURE_NAME to "RIGHT and FULL JOIN")
expectedErrorContext = propertyValueMapOf(1, 28, Property.FEATURE_NAME to "RIGHT and FULL JOIN"),
target = EvaluatorTestTarget.COMPILER_PIPELINE
)

@Test
Expand Down
34 changes: 27 additions & 7 deletions lang/test/org/partiql/lang/eval/EvaluatingCompilerFromLetTests.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import org.partiql.lang.errors.ErrorCode
import org.partiql.lang.errors.Property
import org.partiql.lang.eval.evaluatortestframework.EvaluatorErrorTestCase
import org.partiql.lang.eval.evaluatortestframework.EvaluatorTestCase
import org.partiql.lang.eval.evaluatortestframework.EvaluatorTestTarget
import org.partiql.lang.util.ArgumentsProviderBase
import org.partiql.lang.util.propertyValueMapOf
import org.partiql.lang.util.to
Expand Down Expand Up @@ -35,28 +36,44 @@ class EvaluatingCompilerFromLetTests : EvaluatorTestBase() {
// LET used in GROUP BY
EvaluatorTestCase(
"SELECT * FROM C LET region AS X GROUP BY X",
"""<< {'X': `EU`}, {'X': `NA`} >>"""
"""<< {'X': `EU`}, {'X': `NA`} >>""",
target = EvaluatorTestTarget.COMPILER_PIPELINE // no support in physical plans yet for GROUP BY
),
// LET used in projection after GROUP BY
EvaluatorTestCase(
"SELECT foo FROM B LET 100 AS foo GROUP BY B.id, foo",
"""<< {'foo': 100}, {'foo': 100} >>"""
"""<< {'foo': 100}, {'foo': 100} >>""",
target = EvaluatorTestTarget.COMPILER_PIPELINE // no support in physical plans yet for GROUP BY
),
// LET used in HAVING after GROUP BY
EvaluatorTestCase(
"SELECT B.id FROM B LET 100 AS foo GROUP BY B.id, foo HAVING B.id > foo",
"""<< {'id': 200} >>"""
"""<< {'id': 200} >>""",
target = EvaluatorTestTarget.COMPILER_PIPELINE // no support in physical plans yet for HAVING
),
// LET shadowed binding
EvaluatorTestCase(
"SELECT X FROM A LET 1 AS X, 2 AS X",
"""<< {'X': 2} >>"""
),

// For the two tests immediately below--one tests the AST evaluator only and the other tests
// the phys. plan evaluator only. The query is the same but the expected result is different
// because the legacy AST evaluator has a bug not present in the physical plan evaluator:
// https://github.com/partiql/partiql-lang-kotlin/issues/549

// LET shadowing FROM binding
EvaluatorTestCase(
"SELECT * FROM A LET 100 AS A",
"""<< {'_1': 100} >>"""
"""<< { '_1': 100 } >>""",
target = EvaluatorTestTarget.COMPILER_PIPELINE
),
EvaluatorTestCase(
"SELECT * FROM A LET 100 AS A",
"""<< { 'id': 1 }>>""",
target = EvaluatorTestTarget.PLANNER_PIPELINE
),

// LET using other variables
EvaluatorTestCase(
"SELECT X, Y FROM A LET 1 AS X, X + 1 AS Y",
Expand All @@ -80,7 +97,8 @@ class EvaluatingCompilerFromLetTests : EvaluatorTestBase() {
// LET calling function with GROUP BY and aggregation
EvaluatorTestCase(
"SELECT C.region, MAX(nameLength) AS maxLen FROM C LET char_length(C.name) AS nameLength GROUP BY C.region",
"""<< {'region': `EU`, 'maxLen': 6}, {'region': `NA`, 'maxLen': 9} >>"""
"""<< {'region': `EU`, 'maxLen': 6}, {'region': `NA`, 'maxLen': 9} >>""",
target = EvaluatorTestTarget.COMPILER_PIPELINE // no support in physical plans yet for GROUP BY
),
// LET outer query has correct value
EvaluatorTestCase(
Expand Down Expand Up @@ -152,7 +170,8 @@ class EvaluatingCompilerFromLetTests : EvaluatorTestBase() {
Property.LINE_NUMBER to 1L,
Property.COLUMN_NUMBER to 63L,
Property.BINDING_NAME to "foo"
)
),
target = EvaluatorTestTarget.COMPILER_PIPELINE // no support in physical plans yet for GROUP BY
),
// LET binding referenced in projection not in GROUP BY
EvaluatorErrorTestCase(
Expand All @@ -162,7 +181,8 @@ class EvaluatingCompilerFromLetTests : EvaluatorTestBase() {
Property.LINE_NUMBER to 1L,
Property.COLUMN_NUMBER to 8L,
Property.BINDING_NAME to "foo"
)
),
target = EvaluatorTestTarget.COMPILER_PIPELINE // no support in physical plans yet for GROUP BY
)
)
}
Expand Down
37 changes: 27 additions & 10 deletions lang/test/org/partiql/lang/eval/EvaluatingCompilerGroupByTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import org.junit.Test
import org.partiql.lang.errors.ErrorCode
import org.partiql.lang.errors.Property
import org.partiql.lang.eval.evaluatortestframework.EvaluatorTestCase
import org.partiql.lang.eval.evaluatortestframework.EvaluatorTestTarget
import org.partiql.lang.util.propertyValueMapOf

class EvaluatingCompilerGroupByTest : EvaluatorTestBase() {
Expand Down Expand Up @@ -87,7 +88,13 @@ class EvaluatingCompilerGroupByTest : EvaluatorTestBase() {
).toSession()

private fun runTest(tc: EvaluatorTestCase, session: EvaluationSession) =
super.runEvaluatorTestCase(tc.copy(implicitPermissiveModeTest = false), session)
super.runEvaluatorTestCase(
tc.copy(
implicitPermissiveModeTest = false, // we are manually setting typing mode
target = EvaluatorTestTarget.COMPILER_PIPELINE // no support in physical plans yet for GROUP BY
),
session
)

companion object {

Expand Down Expand Up @@ -1142,7 +1149,8 @@ class EvaluatingCompilerGroupByTest : EvaluatorTestBase() {
"SELECT foo AS someSelectListAlias FROM <<{ 'a': 1 }>> GROUP BY someSelectListAlias",
ErrorCode.EVALUATOR_BINDING_DOES_NOT_EXIST,
propertyValueMapOf(1, 64, Property.BINDING_NAME to "someSelectListAlias"),
expectedPermissiveModeResult = "<<{}>>"
expectedPermissiveModeResult = "<<{}>>",
target = EvaluatorTestTarget.COMPILER_PIPELINE
)
}

Expand All @@ -1151,7 +1159,8 @@ class EvaluatingCompilerGroupByTest : EvaluatorTestBase() {
runEvaluatorErrorTestCase(
"SELECT MAX(@v2), @v2 FROM `[1, 2.0, 3e0, 4, 5d0]` AS v2",
ErrorCode.EVALUATOR_VARIABLE_NOT_INCLUDED_IN_GROUP_BY,
propertyValueMapOf(1, 19, Property.BINDING_NAME to "v2")
propertyValueMapOf(1, 19, Property.BINDING_NAME to "v2"),
target = EvaluatorTestTarget.COMPILER_PIPELINE
)
}

Expand All @@ -1160,7 +1169,8 @@ class EvaluatingCompilerGroupByTest : EvaluatorTestBase() {
runEvaluatorErrorTestCase(
"SELECT * FROM << {'a': 1 } >> AS f GROUP BY f.a HAVING f.id = 1",
ErrorCode.EVALUATOR_VARIABLE_NOT_INCLUDED_IN_GROUP_BY,
propertyValueMapOf(1, 56, Property.BINDING_NAME to "f")
propertyValueMapOf(1, 56, Property.BINDING_NAME to "f"),
target = EvaluatorTestTarget.COMPILER_PIPELINE
)
}

Expand All @@ -1169,7 +1179,8 @@ class EvaluatingCompilerGroupByTest : EvaluatorTestBase() {
runEvaluatorErrorTestCase(
"SELECT VALUE f.id FROM << {'a': 'b' } >> AS f GROUP BY f.a",
ErrorCode.EVALUATOR_VARIABLE_NOT_INCLUDED_IN_GROUP_BY,
propertyValueMapOf(1, 14, Property.BINDING_NAME to "f")
propertyValueMapOf(1, 14, Property.BINDING_NAME to "f"),
target = EvaluatorTestTarget.COMPILER_PIPELINE
)
}

Expand All @@ -1183,6 +1194,7 @@ class EvaluatingCompilerGroupByTest : EvaluatorTestBase() {
ErrorCode.EVALUATOR_VARIABLE_NOT_INCLUDED_IN_GROUP_BY,
propertyValueMapOf(2, 28, Property.BINDING_NAME to "O"),
session = session,
target = EvaluatorTestTarget.COMPILER_PIPELINE
)
}

Expand All @@ -1196,7 +1208,8 @@ class EvaluatingCompilerGroupByTest : EvaluatorTestBase() {
ErrorCode.EVALUATOR_QUOTED_BINDING_DOES_NOT_EXIST,
propertyValueMapOf(2, 28, Property.BINDING_NAME to "O"),
expectedPermissiveModeResult = "<<{'_2': 10}>>",
session = session
session = session,
target = EvaluatorTestTarget.COMPILER_PIPELINE
)
}

Expand All @@ -1210,7 +1223,8 @@ class EvaluatingCompilerGroupByTest : EvaluatorTestBase() {
""",
expectedErrorCode = ErrorCode.EVALUATOR_VARIABLE_NOT_INCLUDED_IN_GROUP_BY,
expectedErrorContext = propertyValueMapOf(2, 41, Property.BINDING_NAME to "c"),
session = session
session = session,
target = EvaluatorTestTarget.COMPILER_PIPELINE
)
}

Expand All @@ -1225,7 +1239,8 @@ class EvaluatingCompilerGroupByTest : EvaluatorTestBase() {
""",
expectedErrorCode = ErrorCode.EVALUATOR_VARIABLE_NOT_INCLUDED_IN_GROUP_BY,
expectedErrorContext = propertyValueMapOf(2, 41, Property.BINDING_NAME to "o"),
session = session
session = session,
target = EvaluatorTestTarget.COMPILER_PIPELINE
)
}

Expand All @@ -1244,7 +1259,8 @@ class EvaluatingCompilerGroupByTest : EvaluatorTestBase() {
""",
expectedErrorCode = ErrorCode.EVALUATOR_VARIABLE_NOT_INCLUDED_IN_GROUP_BY,
expectedErrorContext = propertyValueMapOf(2, 37, Property.BINDING_NAME to "o"),
session = session
session = session,
target = EvaluatorTestTarget.COMPILER_PIPELINE
)
}

Expand All @@ -1261,7 +1277,8 @@ class EvaluatingCompilerGroupByTest : EvaluatorTestBase() {
""",
expectedErrorCode = ErrorCode.EVALUATOR_VARIABLE_NOT_INCLUDED_IN_GROUP_BY,
expectedErrorContext = propertyValueMapOf(4, 28, Property.BINDING_NAME to "o"),
session = session
session = session,
target = EvaluatorTestTarget.COMPILER_PIPELINE
)
}
}
10 changes: 8 additions & 2 deletions lang/test/org/partiql/lang/eval/EvaluatingCompilerHavingTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import junitparams.Parameters
import org.junit.Test
import org.partiql.lang.errors.ErrorCode
import org.partiql.lang.eval.evaluatortestframework.EvaluatorTestCase
import org.partiql.lang.eval.evaluatortestframework.EvaluatorTestTarget
import org.partiql.lang.util.propertyValueMapOf

class EvaluatingCompilerHavingTest : EvaluatorTestBase() {
Expand Down Expand Up @@ -54,7 +55,11 @@ class EvaluatingCompilerHavingTest : EvaluatorTestBase() {

@Test
@Parameters
fun groupByHavingTest(tc: EvaluatorTestCase) = runEvaluatorTestCase(tc, session)
fun groupByHavingTest(tc: EvaluatorTestCase) =
runEvaluatorTestCase(
tc.copy(target = EvaluatorTestTarget.COMPILER_PIPELINE), // Phys. Algebra doesn't yet support HAVING
session
)

fun parametersForGroupByHavingTest() =
listOf(
Expand Down Expand Up @@ -179,7 +184,8 @@ class EvaluatingCompilerHavingTest : EvaluatorTestBase() {
runEvaluatorErrorTestCase(
query = "SELECT foo.bar FROM bat HAVING 1 = 1",
expectedErrorCode = ErrorCode.SEMANTIC_HAVING_USED_WITHOUT_GROUP_BY,
expectedErrorContext = propertyValueMapOf(1, 1)
expectedErrorContext = propertyValueMapOf(1, 1),
target = EvaluatorTestTarget.COMPILER_PIPELINE
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.partiql.lang.eval
import org.junit.Test
import org.partiql.lang.errors.ErrorCode
import org.partiql.lang.errors.Property
import org.partiql.lang.eval.evaluatortestframework.EvaluatorTestTarget
import org.partiql.lang.util.propertyValueMapOf

class EvaluatingCompilerLimitTests : EvaluatorTestBase() {
Expand Down Expand Up @@ -54,7 +55,8 @@ class EvaluatingCompilerLimitTests : EvaluatorTestBase() {
runEvaluatorErrorTestCase(
""" select * from <<1>> limit -1 """,
ErrorCode.EVALUATOR_NEGATIVE_LIMIT,
propertyValueMapOf(1, 29)
propertyValueMapOf(1, 29),
target = EvaluatorTestTarget.COMPILER_PIPELINE, // planner & physical plan have no support LIMIT (yet)
)

@Test
Expand All @@ -69,6 +71,7 @@ class EvaluatingCompilerLimitTests : EvaluatorTestBase() {
fun `LIMIT applied after GROUP BY`() =
runEvaluatorTestCase(
"SELECT g FROM `[{foo: 1, bar: 10}, {foo: 1, bar: 11}]` AS f GROUP BY f.foo GROUP AS g LIMIT 1",
expectedResult = """[ { 'g': [ { 'f': { 'foo': 1, 'bar': 10 } }, { 'f': { 'foo': 1, 'bar': 11 } } ] } ]"""
expectedResult = """[ { 'g': [ { 'f': { 'foo': 1, 'bar': 10 } }, { 'f': { 'foo': 1, 'bar': 11 } } ] } ]""",
target = EvaluatorTestTarget.COMPILER_PIPELINE // planner & physical plan have no support for GROUP BY (yet)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.partiql.lang.eval
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.ArgumentsSource
import org.partiql.lang.eval.evaluatortestframework.EvaluatorTestCase
import org.partiql.lang.eval.evaluatortestframework.EvaluatorTestTarget
import org.partiql.lang.eval.visitors.StaticTypeInferenceVisitorTransform
import org.partiql.lang.types.IntType
import org.partiql.lang.types.StaticType
Expand Down Expand Up @@ -152,18 +153,17 @@ class EvaluatingCompilerNAryIntOverflowTests : EvaluatorTestBase() {
globals(defaultEnv.valueBindings)
}

// We use EvaluatorTestCase/runTestCase from EvaluatorTestBase here instead of assertEval
// because the expected values are expressed in PartiQL syntax, but with assertEval it's expressed in
// Ion syntax.
val etc = EvaluatorTestCase(
query = tc.sqlUnderTest,
expectedResult = tc.expectedPermissiveModeResult,
implicitPermissiveModeTest = false,
compilerPipelineBuilderBlock = {
globalTypeBindings(defaultEnv.typeBindings)
compileOptions {
typingMode(TypingMode.PERMISSIVE)
}
}
},
target = EvaluatorTestTarget.COMPILER_PIPELINE // Requires PlannerPipeline to support globalTypeBindings and static type inference
)

runEvaluatorTestCase(etc, session)
Expand Down
Loading