Skip to content

Commit

Permalink
Remove CompiledExcludeExpr usage of PartiqlPhysical.ExcludeStep
Browse files Browse the repository at this point in the history
  • Loading branch information
alancai98 committed Dec 13, 2023
1 parent c2ea303 commit 4c4062f
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 139 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
package org.partiql.lang.eval.internal.exclude

import org.partiql.lang.domains.PartiqlPhysical
/**
* Internal representation of an `EXCLUDE` expr step.
*/
internal sealed class ExcludeStep {
internal data class TupleAttr(val attr: String, val caseSensitivity: ExcludeTupleAttrCase) : ExcludeStep()
internal object TupleWildcard : ExcludeStep()
internal data class CollIndex(val index: Int) : ExcludeStep()
internal object CollectionWildcard : ExcludeStep()
}

/**
* Internal representation of an `EXCLUDE` tuple attribute case-sensitivity.
*/
internal enum class ExcludeTupleAttrCase {
INSENSITIVE, SENSITIVE
}

/**
* Represents all the compiled `EXCLUDE` paths that start with the same [CompiledExcludeExpr.root]. This variant of
Expand All @@ -26,12 +41,12 @@ internal data class CompiledExcludeExpr(
* nodes of the exclude tree.
*/
internal data class ExcludeBranch(
val step: PartiqlPhysical.ExcludeStep,
val step: ExcludeStep,
override val leaves: MutableSet<ExcludeLeaf>,
override val branches: MutableSet<ExcludeBranch>
) : ExcludeNode(leaves, branches) {
companion object {
fun empty(step: PartiqlPhysical.ExcludeStep): ExcludeBranch {
fun empty(step: ExcludeStep): ExcludeBranch {
return ExcludeBranch(step, mutableSetOf(), mutableSetOf())
}
}
Expand All @@ -42,7 +57,7 @@ internal data class ExcludeBranch(
* represents the leaves in our exclude tree.
*/
internal data class ExcludeLeaf(
val step: PartiqlPhysical.ExcludeStep,
val step: ExcludeStep,
) : ExcludeNode(mutableSetOf(), mutableSetOf())

/**
Expand Down Expand Up @@ -91,10 +106,10 @@ internal sealed class ExcludeNode(
open val leaves: MutableSet<ExcludeLeaf>,
open val branches: MutableSet<ExcludeBranch>
) {
private fun addLeaf(step: PartiqlPhysical.ExcludeStep) {
private fun addLeaf(step: ExcludeStep) {
when (step) {
is PartiqlPhysical.ExcludeStep.ExcludeTupleAttr -> {
if (leaves.contains(ExcludeLeaf(PartiqlPhysical.build { excludeTupleWildcard() }))) {
is ExcludeStep.TupleAttr -> {
if (leaves.contains(ExcludeLeaf(ExcludeStep.TupleWildcard))) {
// leaves contain wildcard; do not add; e.g. a.* and a.b -> keep a.*
} else {
// add to leaves
Expand All @@ -105,19 +120,19 @@ internal sealed class ExcludeNode(
}
}
}
is PartiqlPhysical.ExcludeStep.ExcludeTupleWildcard -> {
is ExcludeStep.TupleWildcard -> {
leaves.add(ExcludeLeaf(step))
// remove all tuple attribute exclude steps from leaves
leaves.removeIf { subLeaf ->
subLeaf.step is PartiqlPhysical.ExcludeStep.ExcludeTupleAttr
subLeaf.step is ExcludeStep.TupleAttr
}
// remove all tuple attribute/wildcard exclude steps from branches
branches.removeIf { subBranch ->
subBranch.step is PartiqlPhysical.ExcludeStep.ExcludeTupleAttr || subBranch.step is PartiqlPhysical.ExcludeStep.ExcludeTupleWildcard
subBranch.step is ExcludeStep.TupleAttr || subBranch.step is ExcludeStep.TupleWildcard
}
}
is PartiqlPhysical.ExcludeStep.ExcludeCollectionIndex -> {
if (leaves.contains(ExcludeLeaf(PartiqlPhysical.build { excludeCollectionWildcard() }))) {
is ExcludeStep.CollIndex -> {
if (leaves.contains(ExcludeLeaf(ExcludeStep.CollectionWildcard))) {
// leaves contains wildcard; do not add; e.g a[*] and a[1] -> keep a[*]
} else {
// add to leaves
Expand All @@ -128,26 +143,26 @@ internal sealed class ExcludeNode(
}
}
}
is PartiqlPhysical.ExcludeStep.ExcludeCollectionWildcard -> {
is ExcludeStep.CollectionWildcard -> {
leaves.add(ExcludeLeaf(step))
// remove all collection index exclude steps from leaves
leaves.removeIf { subLeaf ->
subLeaf.step is PartiqlPhysical.ExcludeStep.ExcludeCollectionIndex
subLeaf.step is ExcludeStep.CollIndex
}
// remove all collection index/wildcard exclude steps from branches
branches.removeIf { subBranch ->
subBranch.step is PartiqlPhysical.ExcludeStep.ExcludeCollectionIndex || subBranch.step is PartiqlPhysical.ExcludeStep.ExcludeCollectionWildcard
subBranch.step is ExcludeStep.CollIndex || subBranch.step is ExcludeStep.CollectionWildcard
}
}
}
}

private fun addBranch(steps: List<PartiqlPhysical.ExcludeStep>) {
private fun addBranch(steps: List<ExcludeStep>) {
val head = steps.first()
val tail = steps.drop(1)
when (head) {
is PartiqlPhysical.ExcludeStep.ExcludeTupleAttr -> {
if (leaves.contains(ExcludeLeaf(PartiqlPhysical.build { excludeTupleWildcard() })) || leaves.contains(
is ExcludeStep.TupleAttr -> {
if (leaves.contains(ExcludeLeaf(ExcludeStep.TupleWildcard)) || leaves.contains(
ExcludeLeaf(head)
)
) {
Expand All @@ -162,8 +177,8 @@ internal sealed class ExcludeNode(
branches.add(existingBranch)
}
}
is PartiqlPhysical.ExcludeStep.ExcludeTupleWildcard -> {
if (leaves.any { it.step is PartiqlPhysical.ExcludeStep.ExcludeTupleWildcard }) {
is ExcludeStep.TupleWildcard -> {
if (leaves.any { it.step is ExcludeStep.TupleWildcard }) {
// tuple wildcard in leaves; do nothing
} else {
val existingBranch = branches.find { subBranch ->
Expand All @@ -174,8 +189,8 @@ internal sealed class ExcludeNode(
branches.add(existingBranch)
}
}
is PartiqlPhysical.ExcludeStep.ExcludeCollectionIndex -> {
if (leaves.contains(ExcludeLeaf(PartiqlPhysical.build { excludeCollectionWildcard() })) || leaves.contains(
is ExcludeStep.CollIndex -> {
if (leaves.contains(ExcludeLeaf(ExcludeStep.CollectionWildcard)) || leaves.contains(
ExcludeLeaf(head)
)
) {
Expand All @@ -190,8 +205,8 @@ internal sealed class ExcludeNode(
branches.add(existingBranch)
}
}
is PartiqlPhysical.ExcludeStep.ExcludeCollectionWildcard -> {
if (leaves.any { it.step is PartiqlPhysical.ExcludeStep.ExcludeCollectionWildcard }) {
is ExcludeStep.CollectionWildcard -> {
if (leaves.any { it.step is ExcludeStep.CollectionWildcard }) {
// collection wildcard in leaves; do nothing
} else {
val existingBranch = branches.find { subBranch ->
Expand All @@ -205,27 +220,10 @@ internal sealed class ExcludeNode(
}
}

internal fun addNode(steps: List<PartiqlPhysical.ExcludeStep>) {
internal fun addNode(steps: List<ExcludeStep>) {
when (steps.size) {
1 -> this.addLeaf(steps.first())
else -> this.addBranch(steps)
}
}
}

/**
* Creates a list of [CompiledExcludeExpr] with each index of the resulting list corresponding to a different
* exclude path root.
*/
internal fun compileExcludeClause(excludeClause: PartiqlPhysical.Bexpr.ExcludeClause): List<CompiledExcludeExpr> {
val excludeExprs = excludeClause.exprs
val compiledExcludeExprs = excludeExprs
.groupBy { it.root }
.map { (root, exclusions) ->
exclusions.fold(CompiledExcludeExpr.empty(root.value.toInt())) { acc, exclusion ->
acc.addNode(exclusion.steps)
acc
}
}
return compiledExcludeExprs
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import org.partiql.lang.eval.ExprValue
import org.partiql.lang.eval.NaturalExprValueComparators
import org.partiql.lang.eval.internal.Thunk
import org.partiql.lang.eval.internal.ThunkValue
import org.partiql.lang.eval.internal.exclude.compileExcludeClause
import org.partiql.lang.eval.physical.operators.AggregateOperatorFactory
import org.partiql.lang.eval.physical.operators.CompiledAggregateFunction
import org.partiql.lang.eval.physical.operators.CompiledGroupKey
Expand All @@ -30,6 +29,7 @@ import org.partiql.lang.eval.physical.operators.ScanRelationalOperatorFactory
import org.partiql.lang.eval.physical.operators.SortOperatorFactory
import org.partiql.lang.eval.physical.operators.UnpivotOperatorFactory
import org.partiql.lang.eval.physical.operators.WindowRelationalOperatorFactory
import org.partiql.lang.eval.physical.operators.compileExcludeClause
import org.partiql.lang.eval.physical.operators.valueExpression
import org.partiql.lang.eval.physical.window.createBuiltinWindowFunction
import org.partiql.lang.util.toIntExact
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.partiql.lang.eval.physical.operators

import com.amazon.ionelement.api.emptyMetaContainer
import org.partiql.lang.domains.PartiqlPhysical
import org.partiql.lang.eval.ExprValue
import org.partiql.lang.eval.ExprValueType
Expand All @@ -11,6 +10,8 @@ import org.partiql.lang.eval.internal.SexpExprValue
import org.partiql.lang.eval.internal.StructExprValue
import org.partiql.lang.eval.internal.exclude.CompiledExcludeExpr
import org.partiql.lang.eval.internal.exclude.ExcludeNode
import org.partiql.lang.eval.internal.exclude.ExcludeStep
import org.partiql.lang.eval.internal.exclude.ExcludeTupleAttrCase
import org.partiql.lang.eval.internal.ext.name
import org.partiql.lang.eval.internal.ext.namedValue
import org.partiql.lang.eval.internal.newSequenceExprValue
Expand Down Expand Up @@ -77,15 +78,15 @@ private fun excludeStructExprValue(
): ExprValue {
val leavesSteps = exclusions.leaves.map { leaf -> leaf.step }
val branches = exclusions.branches
if (leavesSteps.any { it is PartiqlPhysical.ExcludeStep.ExcludeTupleWildcard }) {
if (leavesSteps.any { it is ExcludeStep.TupleWildcard }) {
// tuple wildcard at current level. return empty struct
return StructExprValue(
sequence = emptySequence(),
ordering = structExprValue.ordering
)
}
val attrsToRemove = leavesSteps.filterIsInstance<PartiqlPhysical.ExcludeStep.ExcludeTupleAttr>()
.map { it.attr.name.text }
val attrsToRemove = leavesSteps.filterIsInstance<ExcludeStep.TupleAttr>()
.map { it.attr }
.toSet()
val sequenceWithRemoved = structExprValue.mapNotNull { structField ->
if (attrsToRemove.contains(structField.name?.stringValue())) {
Expand All @@ -98,35 +99,21 @@ private fun excludeStructExprValue(
var expr = structField.value
val name = structField.name
// apply case-sensitive tuple attr exclusions
val structFieldCaseSensitiveKey = PartiqlPhysical.build {
excludeTupleAttr(
identifier(
name.stringValue(),
caseSensitive()
)
)
}
val structFieldCaseSensitiveKey = ExcludeStep.TupleAttr(name.stringValue(), ExcludeTupleAttrCase.SENSITIVE)
branches.find {
it.step == structFieldCaseSensitiveKey
}?.let {
expr = excludeExprValue(expr, it)
}
// apply case-insensitive tuple attr exclusions
val structFieldCaseInsensitiveKey = PartiqlPhysical.build {
excludeTupleAttr(
identifier(
name.stringValue(),
caseInsensitive()
)
)
}
val structFieldCaseInsensitiveKey = ExcludeStep.TupleAttr(name.stringValue(), ExcludeTupleAttrCase.INSENSITIVE)
branches.find {
it.step == structFieldCaseInsensitiveKey
}?.let {
expr = excludeExprValue(expr, it)
}
// apply tuple wildcard exclusions
val tupleWildcardKey = PartiqlPhysical.build { excludeTupleWildcard(emptyMetaContainer()) }
val tupleWildcardKey = ExcludeStep.TupleWildcard
branches.find {
it.step == tupleWildcardKey
}?.let {
Expand All @@ -144,15 +131,15 @@ private fun excludeCollectionExprValue(
): ExprValue {
val leavesSteps = exclusions.leaves.map { leaf -> leaf.step }
val branches = exclusions.branches
if (leavesSteps.any { it is PartiqlPhysical.ExcludeStep.ExcludeCollectionWildcard }) {
if (leavesSteps.any { it is ExcludeStep.CollectionWildcard }) {
// collection wildcard at current level. return empty collection
return newSequenceExprValue(exprValueType, emptySequence())
} else {
val indexesToRemove = leavesSteps.filterIsInstance<PartiqlPhysical.ExcludeStep.ExcludeCollectionIndex>()
.map { it.index.value }
val indexesToRemove = leavesSteps.filterIsInstance<ExcludeStep.CollIndex>()
.map { it.index }
.toSet()
val sequenceWithRemoved = initialExprValue.mapNotNull { element ->
if (indexesToRemove.contains(element.name?.longValue())) {
if (indexesToRemove.contains(element.name?.longValue()?.toInt())) {
null
} else {
element
Expand All @@ -162,21 +149,17 @@ private fun excludeCollectionExprValue(
var expr = element
if (initialExprValue is ListExprValue || initialExprValue is SexpExprValue) {
element as NamedExprValue
val index = element.name.longValue()
val index = element.name.longValue().toInt()
// apply collection index exclusions for lists and sexps
val elementKey = PartiqlPhysical.build {
excludeCollectionIndex(
index
)
}
val elementKey = ExcludeStep.CollIndex(index)
branches.find {
it.step == elementKey
}?.let {
expr = excludeExprValue(element.value, it)
}
}
// apply collection wildcard exclusions for lists, bags, and sexps
val collectionWildcardKey = PartiqlPhysical.build { excludeCollectionWildcard(emptyMetaContainer()) }
val collectionWildcardKey = ExcludeStep.CollectionWildcard
branches.find {
it.step == collectionWildcardKey
}?.let {
Expand Down Expand Up @@ -218,3 +201,36 @@ internal class ExcludeOperator(
}
}
}

/**
* Creates a list of [CompiledExcludeExpr] with each index of the resulting list corresponding to a different
* exclude path root.
*/
internal fun compileExcludeClause(excludeClause: PartiqlPhysical.Bexpr.ExcludeClause): List<CompiledExcludeExpr> {
val excludeExprs = excludeClause.exprs
val compiledExcludeExprs = excludeExprs
.groupBy { it.root }
.map { (root, exclusions) ->
exclusions.fold(CompiledExcludeExpr.empty(root.value.toInt())) { acc, exclusion ->
acc.addNode(exclusion.steps.map { it.toCompiledExcludeStep() })
acc
}
}
return compiledExcludeExprs
}

private fun PartiqlPhysical.ExcludeStep.toCompiledExcludeStep(): ExcludeStep {
return when (this) {
is PartiqlPhysical.ExcludeStep.ExcludeTupleAttr -> ExcludeStep.TupleAttr(this.attr.name.text, this.attr.case.toCompiledExcludeStepCase())
is PartiqlPhysical.ExcludeStep.ExcludeTupleWildcard -> ExcludeStep.TupleWildcard
is PartiqlPhysical.ExcludeStep.ExcludeCollectionIndex -> ExcludeStep.CollIndex(this.index.value.toInt())
is PartiqlPhysical.ExcludeStep.ExcludeCollectionWildcard -> ExcludeStep.CollectionWildcard
}
}

private fun PartiqlPhysical.CaseSensitivity.toCompiledExcludeStepCase(): ExcludeTupleAttrCase {
return when (this) {
is PartiqlPhysical.CaseSensitivity.CaseSensitive -> ExcludeTupleAttrCase.SENSITIVE
is PartiqlPhysical.CaseSensitivity.CaseInsensitive -> ExcludeTupleAttrCase.INSENSITIVE
}
}
Loading

0 comments on commit 4c4062f

Please sign in to comment.