@@ -6,8 +6,6 @@ import org.partiql.eval.internal.exclude.ExcludeFieldCase
6
6
import org.partiql.eval.internal.exclude.ExcludeNode
7
7
import org.partiql.eval.internal.exclude.ExcludeStep
8
8
import org.partiql.eval.internal.operator.Operator
9
- import org.partiql.plan.Identifier
10
- import org.partiql.plan.Rel
11
9
import org.partiql.value.BagValue
12
10
import org.partiql.value.CollectionValue
13
11
import org.partiql.value.ListValue
@@ -22,8 +20,8 @@ import org.partiql.value.sexpValue
22
20
import org.partiql.value.structValue
23
21
24
22
internal class RelExclude (
25
- val input : Operator .Relation ,
26
- private val compiledExcludeItems : List <CompiledExcludeItem >
23
+ private val input : Operator .Relation ,
24
+ private val exclusions : List <CompiledExcludeItem >
27
25
) : Operator.Relation {
28
26
29
27
override fun open () {
@@ -33,7 +31,7 @@ internal class RelExclude(
33
31
override fun next (): Record ? {
34
32
while (true ) {
35
33
val row = input.next() ? : return null
36
- val newRecord = compiledExcludeItems .fold(row) { curRecord, expr ->
34
+ val newRecord = exclusions .fold(row) { curRecord, expr ->
37
35
excludeOnRecord(curRecord, expr)
38
36
}
39
37
return newRecord
@@ -43,170 +41,138 @@ internal class RelExclude(
43
41
override fun close () {
44
42
input.close()
45
43
}
46
- }
47
44
48
- @OptIn(PartiQLValueExperimental ::class )
49
- private fun excludeOnRecord (
50
- record : Record ,
51
- exclusions : CompiledExcludeItem
52
- ): Record {
53
- val values = record.values
54
- val value = values.getOrNull(exclusions.root)
55
- val newValues = if (value != null ) {
56
- values[exclusions.root] = excludeOnPartiQLValue(value, exclusions)
57
- values
58
- } else {
59
- values
60
- }
61
- return Record (newValues)
62
- }
63
-
64
- @OptIn(PartiQLValueExperimental ::class )
65
- private fun excludeOnStructValue (
66
- structValue : StructValue <* >,
67
- exclusions : ExcludeNode
68
- ): PartiQLValue {
69
- val leavesSteps = exclusions.leaves.map { leaf -> leaf.step }
70
- val branches = exclusions.branches
71
- if (leavesSteps.any { it is ExcludeStep .StructWildcard }) {
72
- // tuple wildcard at current level. return empty struct
73
- return structValue<PartiQLValue >()
74
- }
75
- val attrsToRemove = leavesSteps.filterIsInstance<ExcludeStep .StructField >()
76
- .map { it.attr }
77
- .toSet()
78
- val entriesWithRemoved = structValue.entries.filter { structField ->
79
- ! attrsToRemove.contains(structField.first)
80
- }
81
- val finalStruct = entriesWithRemoved.map { structField ->
82
- val name = structField.first
83
- var expr = structField.second
84
- // apply case-sensitive tuple attr exclusions
85
- val structFieldCaseSensitiveKey = ExcludeStep .StructField (name, ExcludeFieldCase .SENSITIVE )
86
- branches.find {
87
- it.step == structFieldCaseSensitiveKey
88
- }?.let {
89
- expr = excludeOnPartiQLValue(expr, it)
90
- }
91
- // apply case-insensitive tuple attr exclusions
92
- val structFieldCaseInsensitiveKey = ExcludeStep .StructField (name, ExcludeFieldCase .INSENSITIVE )
93
- branches.find {
94
- it.step == structFieldCaseInsensitiveKey
95
- }?.let {
96
- expr = excludeOnPartiQLValue(expr, it)
97
- }
98
- // apply tuple wildcard exclusions
99
- val tupleWildcardKey = ExcludeStep .StructWildcard
100
- branches.find {
101
- it.step == tupleWildcardKey
102
- }?.let {
103
- expr = excludeOnPartiQLValue(expr, it)
45
+ @OptIn(PartiQLValueExperimental ::class )
46
+ private fun excludeOnRecord (
47
+ record : Record ,
48
+ exclusions : CompiledExcludeItem
49
+ ): Record {
50
+ val values = record.values
51
+ val value = values.getOrNull(exclusions.root)
52
+ val newValues = if (value != null ) {
53
+ values[exclusions.root] = excludeOnPartiQLValue(value, exclusions)
54
+ values
55
+ } else {
56
+ values
104
57
}
105
- Pair (name, expr )
58
+ return Record (newValues )
106
59
}
107
- return structValue(finalStruct)
108
- }
109
60
110
- /* *
111
- * Returns a [PartiQLValue] created from an iterable of [coll]. Requires [type] to be a collection type
112
- * (i.e. [PartiQLValueType.LIST], [PartiQLValueType.BAG], or [PartiQLValueType.SEXP]).
113
- */
114
- @OptIn(PartiQLValueExperimental ::class )
115
- private fun newCollValue (type : PartiQLValueType , coll : Iterable <PartiQLValue >): PartiQLValue {
116
- return when (type) {
117
- PartiQLValueType .LIST -> listValue(coll)
118
- PartiQLValueType .BAG -> bagValue(coll)
119
- PartiQLValueType .SEXP -> sexpValue(coll)
120
- else -> error(" Collection type required" )
121
- }
122
- }
123
-
124
- @OptIn(PartiQLValueExperimental ::class )
125
- private fun excludeOnCollValue (
126
- coll : CollectionValue <* >,
127
- type : PartiQLValueType ,
128
- exclusions : ExcludeNode
129
- ): PartiQLValue {
130
- val leavesSteps = exclusions.leaves.map { leaf -> leaf.step }
131
- val branches = exclusions.branches
132
- if (leavesSteps.any { it is ExcludeStep .CollWildcard }) {
133
- // collection wildcard at current level. return empty collection
134
- return newCollValue(type, emptyList())
135
- } else {
136
- val indexesToRemove = leavesSteps.filterIsInstance<ExcludeStep .CollIndex >()
137
- .map { it.index }
61
+ @OptIn(PartiQLValueExperimental ::class )
62
+ private fun excludeOnStructValue (
63
+ structValue : StructValue <* >,
64
+ exclusions : ExcludeNode
65
+ ): PartiQLValue {
66
+ val leavesSteps = exclusions.leaves.map { leaf -> leaf.step }
67
+ val branches = exclusions.branches
68
+ if (leavesSteps.any { it is ExcludeStep .StructWildcard }) {
69
+ // tuple wildcard at current level. return empty struct
70
+ return structValue<PartiQLValue >()
71
+ }
72
+ val attrsToRemove = leavesSteps.filterIsInstance<ExcludeStep .StructField >()
73
+ .map { it.attr }
138
74
.toSet()
139
- val collWithRemoved = when (coll) {
140
- is BagValue -> coll
141
- is ListValue , is SexpValue -> coll.filterIndexed { index, _ ->
142
- ! indexesToRemove.contains(index)
143
- }
75
+ val entriesWithRemoved = structValue.entries.filter { structField ->
76
+ ! attrsToRemove.contains(structField.first)
144
77
}
145
- val finalColl = collWithRemoved.mapIndexed { index, element ->
146
- var expr = element
147
- if (coll is ListValue || coll is SexpValue ) {
148
- // apply collection index exclusions for lists and sexps
149
- val elementKey = ExcludeStep .CollIndex (index)
150
- branches.find {
151
- it.step == elementKey
152
- }?.let {
153
- expr = excludeOnPartiQLValue(element, it)
154
- }
78
+ val finalStruct = entriesWithRemoved.map { structField ->
79
+ val name = structField.first
80
+ var expr = structField.second
81
+ // apply case-sensitive tuple attr exclusions
82
+ val structFieldCaseSensitiveKey = ExcludeStep .StructField (name, ExcludeFieldCase .SENSITIVE )
83
+ branches.find {
84
+ it.step == structFieldCaseSensitiveKey
85
+ }?.let {
86
+ expr = excludeOnPartiQLValue(expr, it)
87
+ }
88
+ // apply case-insensitive tuple attr exclusions
89
+ val structFieldCaseInsensitiveKey = ExcludeStep .StructField (name, ExcludeFieldCase .INSENSITIVE )
90
+ branches.find {
91
+ it.step == structFieldCaseInsensitiveKey
92
+ }?.let {
93
+ expr = excludeOnPartiQLValue(expr, it)
155
94
}
156
- // apply collection wildcard exclusions for lists, bags, and sexps
157
- val collectionWildcardKey = ExcludeStep .CollWildcard
95
+ // apply tuple wildcard exclusions
96
+ val tupleWildcardKey = ExcludeStep .StructWildcard
158
97
branches.find {
159
- it.step == collectionWildcardKey
98
+ it.step == tupleWildcardKey
160
99
}?.let {
161
100
expr = excludeOnPartiQLValue(expr, it)
162
101
}
163
- expr
102
+ Pair (name, expr)
164
103
}
165
- return newCollValue(type, finalColl )
104
+ return structValue(finalStruct )
166
105
}
167
- }
168
106
169
- @OptIn(PartiQLValueExperimental ::class )
170
- private fun excludeOnPartiQLValue (initialPartiQLValue : PartiQLValue , exclusions : ExcludeNode ): PartiQLValue {
171
- return when (initialPartiQLValue) {
172
- is StructValue <* > -> excludeOnStructValue(initialPartiQLValue, exclusions)
173
- is BagValue <* > -> excludeOnCollValue(initialPartiQLValue, PartiQLValueType .BAG , exclusions)
174
- is ListValue <* > -> excludeOnCollValue(initialPartiQLValue, PartiQLValueType .LIST , exclusions)
175
- is SexpValue <* > -> excludeOnCollValue(initialPartiQLValue, PartiQLValueType .SEXP , exclusions)
176
- else -> {
177
- initialPartiQLValue
107
+ /* *
108
+ * Returns a [PartiQLValue] created from an iterable of [coll]. Requires [type] to be a collection type
109
+ * (i.e. [PartiQLValueType.LIST], [PartiQLValueType.BAG], or [PartiQLValueType.SEXP]).
110
+ */
111
+ @OptIn(PartiQLValueExperimental ::class )
112
+ private fun newCollValue (type : PartiQLValueType , coll : Iterable <PartiQLValue >): PartiQLValue {
113
+ return when (type) {
114
+ PartiQLValueType .LIST -> listValue(coll)
115
+ PartiQLValueType .BAG -> bagValue(coll)
116
+ PartiQLValueType .SEXP -> sexpValue(coll)
117
+ else -> error(" Collection type required" )
178
118
}
179
119
}
180
- }
181
120
182
- /* *
183
- * Creates a list of [CompiledExcludeItem] with each index of the resulting list corresponding to a different
184
- * exclude path root.
185
- */
186
- internal fun compileExcludeItems (excludeExprs : List <Rel .Op .Exclude .Item >): List <CompiledExcludeItem > {
187
- val compiledExcludeItems = excludeExprs
188
- .groupBy { it.root }
189
- .map { (root, exclusions) ->
190
- exclusions.fold(CompiledExcludeItem .empty(root.ref)) { acc, exclusion ->
191
- acc.addNode(exclusion.steps.map { it.toCompiledExcludeStep() })
192
- acc
121
+ @OptIn(PartiQLValueExperimental ::class )
122
+ private fun excludeOnCollValue (
123
+ coll : CollectionValue <* >,
124
+ type : PartiQLValueType ,
125
+ exclusions : ExcludeNode
126
+ ): PartiQLValue {
127
+ val leavesSteps = exclusions.leaves.map { leaf -> leaf.step }
128
+ val branches = exclusions.branches
129
+ if (leavesSteps.any { it is ExcludeStep .CollWildcard }) {
130
+ // collection wildcard at current level. return empty collection
131
+ return newCollValue(type, emptyList())
132
+ } else {
133
+ val indexesToRemove = leavesSteps.filterIsInstance<ExcludeStep .CollIndex >()
134
+ .map { it.index }
135
+ .toSet()
136
+ val collWithRemoved = when (coll) {
137
+ is BagValue -> coll
138
+ is ListValue , is SexpValue -> coll.filterIndexed { index, _ ->
139
+ ! indexesToRemove.contains(index)
140
+ }
141
+ }
142
+ val finalColl = collWithRemoved.mapIndexed { index, element ->
143
+ var expr = element
144
+ if (coll is ListValue || coll is SexpValue ) {
145
+ // apply collection index exclusions for lists and sexps
146
+ val elementKey = ExcludeStep .CollIndex (index)
147
+ branches.find {
148
+ it.step == elementKey
149
+ }?.let {
150
+ expr = excludeOnPartiQLValue(element, it)
151
+ }
152
+ }
153
+ // apply collection wildcard exclusions for lists, bags, and sexps
154
+ val collectionWildcardKey = ExcludeStep .CollWildcard
155
+ branches.find {
156
+ it.step == collectionWildcardKey
157
+ }?.let {
158
+ expr = excludeOnPartiQLValue(expr, it)
159
+ }
160
+ expr
193
161
}
162
+ return newCollValue(type, finalColl)
194
163
}
195
- return compiledExcludeItems
196
- }
197
-
198
- private fun Rel.Op.Exclude.Step.toCompiledExcludeStep (): ExcludeStep {
199
- return when (this ) {
200
- is Rel .Op .Exclude .Step .StructField -> ExcludeStep .StructField (this .symbol.symbol, this .symbol.caseSensitivity.toCompiledExcludeStepCase())
201
- is Rel .Op .Exclude .Step .StructWildcard -> ExcludeStep .StructWildcard
202
- is Rel .Op .Exclude .Step .CollIndex -> ExcludeStep .CollIndex (this .index)
203
- is Rel .Op .Exclude .Step .CollWildcard -> ExcludeStep .CollWildcard
204
164
}
205
- }
206
165
207
- private fun Identifier.CaseSensitivity.toCompiledExcludeStepCase (): ExcludeFieldCase {
208
- return when (this ) {
209
- Identifier .CaseSensitivity .SENSITIVE -> ExcludeFieldCase .SENSITIVE
210
- Identifier .CaseSensitivity .INSENSITIVE -> ExcludeFieldCase .INSENSITIVE
166
+ @OptIn(PartiQLValueExperimental ::class )
167
+ private fun excludeOnPartiQLValue (initialPartiQLValue : PartiQLValue , exclusions : ExcludeNode ): PartiQLValue {
168
+ return when (initialPartiQLValue) {
169
+ is StructValue <* > -> excludeOnStructValue(initialPartiQLValue, exclusions)
170
+ is BagValue <* > -> excludeOnCollValue(initialPartiQLValue, PartiQLValueType .BAG , exclusions)
171
+ is ListValue <* > -> excludeOnCollValue(initialPartiQLValue, PartiQLValueType .LIST , exclusions)
172
+ is SexpValue <* > -> excludeOnCollValue(initialPartiQLValue, PartiQLValueType .SEXP , exclusions)
173
+ else -> {
174
+ initialPartiQLValue
175
+ }
176
+ }
211
177
}
212
178
}
0 commit comments