Skip to content

Commit 5121093

Browse files
authored
FnResolver & add support for constrained decimal (#1378)
1 parent c3b6e66 commit 5121093

File tree

4 files changed

+29
-13
lines changed

4 files changed

+29
-13
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@ Thank you to all who have contributed!
2828
## [Unreleased]
2929

3030
### Added
31+
- Added constrained decimal as valid parameter type to functions that take in numeric parameters.
3132

3233
### Changed
34+
- Function resolution logic: Now the function resolver would match all possible candidate(based on if the argument can be coerced to the Signature parameter type). If there are multiple match it will first attempt to pick the one requires the least cast, then pick the function with the highest precedence.
3335

3436
### Deprecated
3537

partiql-planner/src/main/kotlin/org/partiql/planner/internal/typer/FnResolver.kt

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import org.partiql.planner.internal.ir.Agg
55
import org.partiql.planner.internal.ir.Fn
66
import org.partiql.planner.internal.ir.Identifier
77
import org.partiql.planner.internal.ir.Rex
8+
import org.partiql.planner.internal.typer.FnResolver.Companion.compareTo
89
import org.partiql.types.AnyOfType
910
import org.partiql.types.NullType
1011
import org.partiql.types.StaticType
@@ -247,15 +248,28 @@ internal class FnResolver(private val header: Header) {
247248

248249
/**
249250
* Functions are sorted by precedence (which is not rigorously defined/specified at the moment).
251+
*
252+
* This function first attempts to find all possible match for given args
253+
* If there are multiple matches, then
254+
* - return the matches that requires the lowest number of coercion
255+
* - This is to match edges like concat(symbol, symbol) which should return symbol
256+
* but because string has higher precedence,
257+
* we also would have concat(cast(symbol as string), cast(symbol as string))
258+
* added to the map first.
259+
* - return the matches which has the highest argument precedence.
250260
*/
251261
private fun <T : FunctionSignature> match(signatures: List<T>, args: Args): Match<T>? {
262+
val candidates = mutableListOf<Match<T>>()
252263
for (signature in signatures) {
253264
val mapping = match(signature, args)
254265
if (mapping != null) {
255-
return Match(signature, mapping)
266+
candidates.add(Match(signature, mapping))
256267
}
257268
}
258-
return null
269+
270+
// Sorted By is stable, we don't have to resort based on parameter type precedence
271+
candidates.sortBy { it.mapping.filterNotNull().size }
272+
return candidates.firstOrNull()
259273
}
260274

261275
/**
@@ -288,14 +302,7 @@ internal class FnResolver(private val header: Header) {
288302
}
289303
}
290304
}
291-
// if all elements requires casting, then no match
292-
// because there must be another function definition that requires no casting
293-
return if (mapping.isEmpty() || mapping.contains(null)) {
294-
// we made a match
295-
mapping
296-
} else {
297-
null
298-
}
305+
return mapping
299306
}
300307

301308
/**

partiql-planner/src/main/kotlin/org/partiql/planner/internal/typer/TypeLattice.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ internal class TypeLattice private constructor(
8686
INT32,
8787
INT64,
8888
INT,
89+
DECIMAL,
8990
DECIMAL_ARBITRARY,
9091
FLOAT32,
9192
FLOAT64,

partiql-planner/src/main/kotlin/org/partiql/planner/internal/typer/TypeUtils.kt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,15 @@ private fun StaticType.asRuntimeType(): PartiQLValueType = when (this) {
121121
is ListType -> PartiQLValueType.LIST
122122
is SexpType -> PartiQLValueType.SEXP
123123
is DateType -> PartiQLValueType.DATE
124-
is DecimalType -> when (this.precisionScaleConstraint) {
125-
is DecimalType.PrecisionScaleConstraint.Constrained -> PartiQLValueType.DECIMAL
126-
DecimalType.PrecisionScaleConstraint.Unconstrained -> PartiQLValueType.DECIMAL_ARBITRARY
124+
// TODO: Run time decimal type does not model precision scale constraint yet
125+
// despite that we match to Decimal vs Decimal_ARBITRARY (PVT) here
126+
// but when mapping it back to Static Type, (i.e, mapping function return type to Value Type)
127+
// we can only map to Unconstrained decimal (Static Type)
128+
is DecimalType -> {
129+
when (this.precisionScaleConstraint) {
130+
is DecimalType.PrecisionScaleConstraint.Constrained -> PartiQLValueType.DECIMAL
131+
DecimalType.PrecisionScaleConstraint.Unconstrained -> PartiQLValueType.DECIMAL_ARBITRARY
132+
}
127133
}
128134
is FloatType -> PartiQLValueType.FLOAT64
129135
is GraphType -> error("Graph type missing from runtime types")

0 commit comments

Comments
 (0)