Skip to content

Commit

Permalink
Add EXCLUDE over unions; remove erroring
Browse files Browse the repository at this point in the history
  • Loading branch information
alancai98 committed Sep 29, 2023
1 parent 0adf26c commit d60d08c
Show file tree
Hide file tree
Showing 3 changed files with 216 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,6 @@ sealed class PlanningProblemDetails(
"Please use the `INSERT INTO <table> << <expr>, ... >>` form instead."
}
)

object InvalidExcludeExpr : PlanningProblemDetails(
severity = ProblemSeverity.ERROR,
messageFormatter = {
"Exclusion expression data type mismatch"
}
)
}

private fun quotationHint(caseSensitive: Boolean) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ internal object PlanTyper : PlanRewriter<PlanTyper.Context>() {
* - EXCLUDE on a binding tuple variable (e.g. SELECT ... EXCLUDE t FROM t) -- error?
* - currently a parser error
* - EXCLUDE on a union type -- give an error/warning? no-op? exclude on each type in union?
* - currently is a no-op
* - currently exclude on each union type
* - If SELECT list includes an attribute that is excluded, we could consider giving an error in PlanTyper or
* some other semantic pass
* - currently does not give an error
Expand Down Expand Up @@ -251,7 +251,9 @@ internal object PlanTyper : PlanRewriter<PlanTyper.Context>() {
}
}
else -> {
handleInvalidExcludeExpr(ctx)
// currently no change to field.value and no error thrown; could consider an error/warning in
// the future
outputFields.add(StructType.Field(field.key, field.value))
}
}
}
Expand All @@ -267,10 +269,16 @@ internal object PlanTyper : PlanRewriter<PlanTyper.Context>() {
}
}
is ExcludeStep.CollectionWildcard -> {
elementType = excludeExprSteps(elementType, steps.drop(1), lastStepAsOptional = lastStepAsOptional, ctx)
if (steps.size > 1) {
elementType =
excludeExprSteps(elementType, steps.drop(1), lastStepAsOptional = lastStepAsOptional, ctx)
}
// currently no change to elementType if collection wildcard is last element; this behavior could
// change based on RFC definition
}
else -> {
handleInvalidExcludeExpr(ctx)
// currently no change to elementType and no error thrown; could consider an error/warning in
// the future
}
}
return when (c) {
Expand All @@ -283,6 +291,13 @@ internal object PlanTyper : PlanRewriter<PlanTyper.Context>() {
return when (type) {
is StructType -> excludeExprStepsStruct(type, steps, lastStepAsOptional)
is CollectionType -> excludeExprStepsCollection(type, steps, lastStepAsOptional)
is AnyOfType -> {
StaticType.unionOf(
type.types.map {
excludeExprSteps(it, steps, lastStepAsOptional, ctx)
}.toSet()
)
}
else -> type
}
}
Expand Down Expand Up @@ -1804,16 +1819,6 @@ internal object PlanTyper : PlanRewriter<PlanTyper.Context>() {
return StaticType.ANY
}

private fun handleInvalidExcludeExpr(ctx: Context): StaticType {
ctx.problemHandler.handleProblem(
Problem(
sourceLocation = UNKNOWN_PROBLEM_LOCATION,
details = PlanningProblemDetails.InvalidExcludeExpr
)
)
return StaticType.ANY
}

private fun handleDuplicateAliasesError(ctx: Context) {
ctx.problemHandler.handleProblem(
Problem(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1201,7 +1201,7 @@ class PartiQLSchemaInferencerTests {
)
),
SuccessTestCase(
name = "EXCLUDE SELECT star collection index as last element",
name = "EXCLUDE SELECT star collection index as last step",
query = """SELECT *
EXCLUDE
t.a.b.c[0]
Expand Down Expand Up @@ -1238,6 +1238,27 @@ class PartiQLSchemaInferencerTests {
)
)
),
// EXCLUDE regression test (behavior subject to change pending RFC)
SuccessTestCase(
name = "EXCLUDE SELECT star collection wildcard as last step",
query = """SELECT *
EXCLUDE
t.a[*]
FROM [{
'a': [0, 1, 2]
}] AS t""",
expected = BagType(
StructType(
fields = mapOf(
"a" to ListType(
elementType = StaticType.INT // empty list but still preserve typing information
)
),
contentClosed = true,
constraints = setOf(TupleConstraint.Open(false), TupleConstraint.UniqueAttrs(true), TupleConstraint.Ordered)
)
)
),
SuccessTestCase(
name = "EXCLUDE SELECT star list wildcard",
query = """SELECT *
Expand Down Expand Up @@ -1949,30 +1970,109 @@ class PartiQLSchemaInferencerTests {
)
)
),
// EXCLUDE regression test (behavior subject to change pending RFC)
ErrorTestCase(
name = "invalid exclude union of types",
query = """SELECT * EXCLUDE t.a[*]
// EXCLUDE regression test (behavior subject to change pending RFC); could give error/warning
SuccessTestCase(
name = "exclude union of types",
query = """SELECT t EXCLUDE t.a.b
FROM <<
{
'a': { -- `a` is a struct here
'b': {
'c': 0,
'd': 'foo'
}
'a': {
'b': 1, -- `b` to be excluded
'c': 'foo'
}
},
{
'a': [ -- `a` is a list here
{
'c': 0,
'd': 'foo'
}
]
'a': NULL
}
>> AS t""",
expected = BagType(
StructType(
fields = mapOf(
"t" to StaticType.unionOf(
StructType(
fields = mapOf(
"a" to StructType(
fields = mapOf(
"c" to StaticType.STRING
),
contentClosed = true,
constraints = setOf(TupleConstraint.Open(false), TupleConstraint.UniqueAttrs(true))
)
),
contentClosed = true,
constraints = setOf(TupleConstraint.Open(false), TupleConstraint.UniqueAttrs(true))
),
StructType(
fields = mapOf(
"a" to StaticType.NULL
),
contentClosed = true,
constraints = setOf(TupleConstraint.Open(false), TupleConstraint.UniqueAttrs(true))
),
)
),
contentClosed = true,
constraints = setOf(TupleConstraint.Open(false), TupleConstraint.UniqueAttrs(true), TupleConstraint.Ordered)
)
)
),
ErrorTestCase(
// EXCLUDE regression test (behavior subject to change pending RFC); could give error/warning
SuccessTestCase(
name = "exclude union of types nullable nested type",
query = """SELECT t EXCLUDE t.a.b
FROM <<
{
'a': {
'b': 1, -- `b` to be excluded
'c': 'foo'
}
},
{
'a': {
'b': 1, -- `b` to be excluded
'c': NULL
}
}
>> AS t""",
expected = BagType(
StructType(
fields = mapOf(
"t" to StaticType.unionOf(
StructType(
fields = mapOf(
"a" to StructType(
fields = mapOf(
"c" to StaticType.STRING
),
contentClosed = true,
constraints = setOf(TupleConstraint.Open(false), TupleConstraint.UniqueAttrs(true))
)
),
contentClosed = true,
constraints = setOf(TupleConstraint.Open(false), TupleConstraint.UniqueAttrs(true))
),
StructType(
fields = mapOf(
"a" to StructType(
fields = mapOf(
"c" to StaticType.NULL
),
contentClosed = true,
constraints = setOf(TupleConstraint.Open(false), TupleConstraint.UniqueAttrs(true))
)
),
contentClosed = true,
constraints = setOf(TupleConstraint.Open(false), TupleConstraint.UniqueAttrs(true))
),
)
),
contentClosed = true,
constraints = setOf(TupleConstraint.Open(false), TupleConstraint.UniqueAttrs(true), TupleConstraint.Ordered)
)
)
),
// EXCLUDE regression test (behavior subject to change pending RFC); could give error/warning
SuccessTestCase(
name = "invalid exclude collection wildcard",
query = """SELECT * EXCLUDE t.a[*]
FROM <<
Expand All @@ -1985,14 +2085,31 @@ class PartiQLSchemaInferencerTests {
}
}
>> AS t""",
problemHandler = assertProblemExists {
Problem(
UNKNOWN_PROBLEM_LOCATION,
PlanningProblemDetails.InvalidExcludeExpr
expected = BagType(
elementType = StructType(
fields = mapOf(
"a" to StructType(
fields = mapOf(
"b" to StructType(
fields = mapOf(
"c" to StaticType.INT,
"d" to StaticType.STRING
),
contentClosed = true,
constraints = setOf(TupleConstraint.Open(false), TupleConstraint.UniqueAttrs(true))
)
),
contentClosed = true,
constraints = setOf(TupleConstraint.Open(false), TupleConstraint.UniqueAttrs(true))
)
),
contentClosed = true,
constraints = setOf(TupleConstraint.Open(false), TupleConstraint.UniqueAttrs(true), TupleConstraint.Ordered)
)
}
)
),
ErrorTestCase(
// EXCLUDE regression test (behavior subject to change pending RFC); could give error/warning
SuccessTestCase(
name = "invalid exclude collection index",
query = """SELECT * EXCLUDE t.a[1]
FROM <<
Expand All @@ -2005,14 +2122,31 @@ class PartiQLSchemaInferencerTests {
}
}
>> AS t""",
problemHandler = assertProblemExists {
Problem(
UNKNOWN_PROBLEM_LOCATION,
PlanningProblemDetails.InvalidExcludeExpr
expected = BagType(
elementType = StructType(
fields = mapOf(
"a" to StructType(
fields = mapOf(
"b" to StructType(
fields = mapOf(
"c" to StaticType.INT,
"d" to StaticType.STRING
),
contentClosed = true,
constraints = setOf(TupleConstraint.Open(false), TupleConstraint.UniqueAttrs(true))
)
),
contentClosed = true,
constraints = setOf(TupleConstraint.Open(false), TupleConstraint.UniqueAttrs(true))
)
),
contentClosed = true,
constraints = setOf(TupleConstraint.Open(false), TupleConstraint.UniqueAttrs(true), TupleConstraint.Ordered)
)
}
)
),
ErrorTestCase(
// EXCLUDE regression test (behavior subject to change pending RFC); could give error/warning
SuccessTestCase(
name = "invalid exclude tuple attr",
query = """SELECT * EXCLUDE t.a.b
FROM <<
Expand All @@ -2024,14 +2158,26 @@ class PartiQLSchemaInferencerTests {
]
}
>> AS t""",
problemHandler = assertProblemExists {
Problem(
UNKNOWN_PROBLEM_LOCATION,
PlanningProblemDetails.InvalidExcludeExpr
expected = BagType(
elementType = StructType(
fields = mapOf(
"a" to ListType(
elementType = StructType(
fields = mapOf(
"b" to StaticType.INT
),
contentClosed = true,
constraints = setOf(TupleConstraint.Open(false), TupleConstraint.UniqueAttrs(true))
)
)
),
contentClosed = true,
constraints = setOf(TupleConstraint.Open(false), TupleConstraint.UniqueAttrs(true), TupleConstraint.Ordered)
)
}
)
),
ErrorTestCase(
// EXCLUDE regression test (behavior subject to change pending RFC); could give error/warning
SuccessTestCase(
name = "invalid exclude tuple wildcard",
query = """SELECT * EXCLUDE t.a.*
FROM <<
Expand All @@ -2043,12 +2189,23 @@ class PartiQLSchemaInferencerTests {
]
}
>> AS t""",
problemHandler = assertProblemExists {
Problem(
UNKNOWN_PROBLEM_LOCATION,
PlanningProblemDetails.InvalidExcludeExpr
expected = BagType(
elementType = StructType(
fields = mapOf(
"a" to ListType(
elementType = StructType(
fields = mapOf(
"b" to StaticType.INT
),
contentClosed = true,
constraints = setOf(TupleConstraint.Open(false), TupleConstraint.UniqueAttrs(true))
)
)
),
contentClosed = true,
constraints = setOf(TupleConstraint.Open(false), TupleConstraint.UniqueAttrs(true), TupleConstraint.Ordered)
)
}
)
),
SuccessTestCase(
name = "BITWISE_AND_1",
Expand Down

0 comments on commit d60d08c

Please sign in to comment.