@@ -5,9 +5,6 @@ import org.partiql.planner.internal.ir.Agg
5
5
import org.partiql.planner.internal.ir.Fn
6
6
import org.partiql.planner.internal.ir.Identifier
7
7
import org.partiql.planner.internal.ir.Rex
8
- import org.partiql.planner.internal.typer.FnResolver.Companion.compareTo
9
- import org.partiql.types.AnyOfType
10
- import org.partiql.types.NullType
11
8
import org.partiql.types.StaticType
12
9
import org.partiql.types.function.FunctionParameter
13
10
import org.partiql.types.function.FunctionSignature
@@ -33,8 +30,6 @@ import org.partiql.value.PartiQLValueType.INT64
33
30
import org.partiql.value.PartiQLValueType.INT8
34
31
import org.partiql.value.PartiQLValueType.INTERVAL
35
32
import org.partiql.value.PartiQLValueType.LIST
36
- import org.partiql.value.PartiQLValueType.MISSING
37
- import org.partiql.value.PartiQLValueType.NULL
38
33
import org.partiql.value.PartiQLValueType.SEXP
39
34
import org.partiql.value.PartiQLValueType.STRING
40
35
import org.partiql.value.PartiQLValueType.STRUCT
@@ -76,27 +71,19 @@ internal sealed class FnMatch<T : FunctionSignature> {
76
71
*
77
72
* @property signature
78
73
* @property mapping
79
- * @property isMissable TRUE when anyone of the arguments _could_ be MISSING. We *always* propagate MISSING.
80
74
*/
81
75
public data class Ok <T : FunctionSignature >(
82
76
public val signature : T ,
83
77
public val mapping : Mapping ,
84
- public val isMissable : Boolean ,
85
78
) : FnMatch<T>()
86
79
87
80
/* *
88
81
* This represents dynamic dispatch.
89
82
*
90
83
* @property candidates an ordered list of potentially applicable functions to dispatch dynamically.
91
- * @property isMissable TRUE when the argument permutations may not definitively invoke one of the candidates. You
92
- * can think of [isMissable] as being the same as "not exhaustive". For example, if we have ABS(INT | STRING), then
93
- * this function call [isMissable] because there isn't an `ABS(STRING)` function signature AKA we haven't exhausted
94
- * all the arguments. On the other hand, take an "exhaustive" scenario: ABS(INT | DEC). In this case, [isMissable]
95
- * is false because we have functions for each potential argument AKA we have exhausted the arguments.
96
84
*/
97
85
public data class Dynamic <T : FunctionSignature >(
98
- public val candidates : List <Ok <T >>,
99
- public val isMissable : Boolean
86
+ public val candidates : List <Ok <T >>
100
87
) : FnMatch<T>()
101
88
102
89
public data class Error <T : FunctionSignature >(
@@ -162,12 +149,8 @@ internal class FnResolver(private val header: Header) {
162
149
*/
163
150
public fun resolveFn (fn : Fn .Unresolved , args : List <Rex >): FnMatch <FunctionSignature .Scalar > {
164
151
val candidates = lookup(fn)
165
- var canReturnMissing = false
166
152
val parameterPermutations = buildArgumentPermutations(args.map { it.type }).mapNotNull { argList ->
167
153
argList.mapIndexed { i, arg ->
168
- if (arg.isMissable()) {
169
- canReturnMissing = true
170
- }
171
154
// Skip over if we cannot convert type to runtime type.
172
155
val argType = arg.toRuntimeTypeOrNull() ? : return @mapNotNull null
173
156
FunctionParameter (" arg-$i " , argType)
@@ -176,12 +159,10 @@ internal class FnResolver(private val header: Header) {
176
159
val potentialFunctions = parameterPermutations.mapNotNull { parameters ->
177
160
when (val match = match(candidates, parameters)) {
178
161
null -> {
179
- canReturnMissing = true
180
162
null
181
163
}
182
164
else -> {
183
- val isMissable = canReturnMissing || isUnsafeCast(match.signature.specific)
184
- FnMatch .Ok (match.signature, match.mapping, isMissable)
165
+ FnMatch .Ok (match.signature, match.mapping)
185
166
}
186
167
}
187
168
}
@@ -190,18 +171,12 @@ internal class FnResolver(private val header: Header) {
190
171
return when (orderedUniqueFunctions.size) {
191
172
0 -> FnMatch .Error (fn.identifier, args, candidates)
192
173
1 -> orderedUniqueFunctions.first()
193
- else -> FnMatch .Dynamic (orderedUniqueFunctions, canReturnMissing )
174
+ else -> FnMatch .Dynamic (orderedUniqueFunctions)
194
175
}
195
176
}
196
177
197
178
private fun buildArgumentPermutations (args : List <StaticType >): List <List <StaticType >> {
198
- val flattenedArgs = args.map {
199
- if (it is AnyOfType ) {
200
- it.flatten().allTypes.filter { it !is NullType }
201
- } else {
202
- it.flatten().allTypes
203
- }
204
- }
179
+ val flattenedArgs = args.map { it.flatten().allTypes }
205
180
return buildArgumentPermutations(flattenedArgs, accumulator = emptyList())
206
181
}
207
182
@@ -229,19 +204,13 @@ internal class FnResolver(private val header: Header) {
229
204
*/
230
205
public fun resolveAgg (agg : Agg .Unresolved , args : List <Rex >): FnMatch <FunctionSignature .Aggregation > {
231
206
val candidates = lookup(agg)
232
- var hadMissingArg = false
233
207
val parameters = args.mapIndexed { i, arg ->
234
- if (! hadMissingArg && arg.type.isMissable()) {
235
- hadMissingArg = true
236
- }
237
208
FunctionParameter (" arg-$i " , arg.type.toRuntimeType())
238
209
}
239
- val match = match(candidates, parameters)
240
- return when (match) {
210
+ return when (val match = match(candidates, parameters)) {
241
211
null -> FnMatch .Error (agg.identifier, args, candidates)
242
212
else -> {
243
- val isMissable = hadMissingArg || isUnsafeCast(match.signature.specific)
244
- FnMatch .Ok (match.signature, match.mapping, isMissable)
213
+ FnMatch .Ok (match.signature, match.mapping)
245
214
}
246
215
}
247
216
}
@@ -290,9 +259,7 @@ internal class FnResolver(private val header: Header) {
290
259
a.type == p.type -> mapping.add(null )
291
260
// 2. Match ANY, no coercion needed
292
261
p.type == ANY -> mapping.add(null )
293
- // 3. Match NULL argument
294
- a.type == NULL -> mapping.add(null )
295
- // 4. Check for a coercion
262
+ // 3. Check for a coercion
296
263
else -> {
297
264
val coercion = lookupCoercion(a.type, p.type)
298
265
when (coercion) {
@@ -440,8 +407,10 @@ internal class FnResolver(private val header: Header) {
440
407
// This is not explicitly defined in the PartiQL Specification!!
441
408
// This does not imply the ability to CAST; this defines function resolution behavior.
442
409
private val precedence: Map <PartiQLValueType , Int > = listOf (
443
- NULL ,
444
- MISSING ,
410
+ @Suppress(" DEPRECATION" )
411
+ PartiQLValueType .NULL , // TODO: Remove
412
+ @Suppress(" DEPRECATION" )
413
+ PartiQLValueType .MISSING , // TODO: Remove
445
414
BOOL ,
446
415
INT8 ,
447
416
INT16 ,
0 commit comments