Skip to content

Commit

Permalink
FnResolver & add support for constrained decimal
Browse files Browse the repository at this point in the history
  • Loading branch information
yliuuuu committed Feb 24, 2024
1 parent 1a39231 commit 875890a
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 12 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ Thank you to all who have contributed!
## [Unreleased]

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

### Changed
- 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.

### Deprecated

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import org.partiql.planner.internal.ir.Agg
import org.partiql.planner.internal.ir.Fn
import org.partiql.planner.internal.ir.Identifier
import org.partiql.planner.internal.ir.Rex
import org.partiql.planner.internal.typer.FnResolver.Companion.compareTo
import org.partiql.types.AnyOfType
import org.partiql.types.NullType
import org.partiql.types.StaticType
Expand Down Expand Up @@ -247,15 +248,28 @@ internal class FnResolver(private val header: Header) {

/**
* Functions are sorted by precedence (which is not rigorously defined/specified at the moment).
*
* This function first attempts to find all possible match for given args
* If there are multiple matches, then
* - return the matches that requires the lowest number of coercion
* - This is to match edges like concat(symbol, symbol) which should return symbol
* but because string has higher precedence,
* we also would have concat(cast(symbol as string), cast(symbol as string))
* added to the map first.
* - return the matches which has the highest argument precedence.
*/
private fun <T : FunctionSignature> match(signatures: List<T>, args: Args): Match<T>? {
val candidates = mutableListOf<Match<T>>()
for (signature in signatures) {
val mapping = match(signature, args)
if (mapping != null) {
return Match(signature, mapping)
candidates.add(Match(signature, mapping))
}
}
return null

// Sorted By is stable, we don't have to resort based on parameter type precedence
candidates.sortBy { it.mapping.filterNotNull().size }
return candidates.firstOrNull()
}

/**
Expand Down Expand Up @@ -288,14 +302,7 @@ internal class FnResolver(private val header: Header) {
}
}
}
// if all elements requires casting, then no match
// because there must be another function definition that requires no casting
return if (mapping.isEmpty() || mapping.contains(null)) {
// we made a match
mapping
} else {
null
}
return mapping
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ internal class TypeLattice private constructor(
INT32,
INT64,
INT,
DECIMAL,
DECIMAL_ARBITRARY,
FLOAT32,
FLOAT64,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,15 @@ private fun StaticType.asRuntimeType(): PartiQLValueType = when (this) {
is SexpType -> PartiQLValueType.SEXP
is DateType -> PartiQLValueType.DATE
// TODO: Run time decimal type does not model precision scale constraint yet
// even though we can match to Decimal vs Decimal_ARBITRARY (PVT) here
// despite that we match to Decimal vs Decimal_ARBITRARY (PVT) here
// but when mapping it back to Static Type, (i.e, mapping function return type to Value Type)
// we can only map to Unconstrained decimal (Static Type)
is DecimalType -> PartiQLValueType.DECIMAL_ARBITRARY
is DecimalType -> {
when (this.precisionScaleConstraint) {
is DecimalType.PrecisionScaleConstraint.Constrained -> PartiQLValueType.DECIMAL
DecimalType.PrecisionScaleConstraint.Unconstrained -> PartiQLValueType.DECIMAL_ARBITRARY
}
}
is FloatType -> PartiQLValueType.FLOAT64
is GraphType -> error("Graph type missing from runtime types")
is IntType -> when (this.rangeConstraint) {
Expand Down

0 comments on commit 875890a

Please sign in to comment.