Skip to content

Commit

Permalink
Fix build
Browse files Browse the repository at this point in the history
  • Loading branch information
rchowell committed Dec 22, 2023
1 parent eae4d8a commit f129381
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 147 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.partiql.planner.internal.typer

import org.partiql.plugin.PartiQLFunctions

internal object FnBuiltins {

/**
* Static PartiQL casts information.
*/
@JvmStatic
val pCasts = TypeCasts.partiql()

/**
* Static PartiQL function signatures, don't recompute.
*/
@JvmStatic
val pFns = PartiQLFunctions.functions.toFnMap()

/**
* Static PartiQL operator signatures, don't recompute.
*/
@JvmStatic
val pOps = (PartiQLFunctions.operators + pCasts.relationships().map { it.castFn }).toFnMap()

/*
* Static PartiQL aggregation signatures, don't recompute.
*/
@JvmStatic
val pAggs = PartiQLFunctions.aggregations.toFnMap()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package org.partiql.planner.internal.typer

import org.partiql.types.function.FunctionParameter
import org.partiql.types.function.FunctionSignature
import org.partiql.value.PartiQLValueExperimental
import org.partiql.value.PartiQLValueType
import org.partiql.value.PartiQLValueType.ANY
import org.partiql.value.PartiQLValueType.BAG
import org.partiql.value.PartiQLValueType.BINARY
import org.partiql.value.PartiQLValueType.BLOB
import org.partiql.value.PartiQLValueType.BOOL
import org.partiql.value.PartiQLValueType.BYTE
import org.partiql.value.PartiQLValueType.CHAR
import org.partiql.value.PartiQLValueType.CLOB
import org.partiql.value.PartiQLValueType.DATE
import org.partiql.value.PartiQLValueType.DECIMAL
import org.partiql.value.PartiQLValueType.DECIMAL_ARBITRARY
import org.partiql.value.PartiQLValueType.FLOAT32
import org.partiql.value.PartiQLValueType.FLOAT64
import org.partiql.value.PartiQLValueType.INT
import org.partiql.value.PartiQLValueType.INT16
import org.partiql.value.PartiQLValueType.INT32
import org.partiql.value.PartiQLValueType.INT64
import org.partiql.value.PartiQLValueType.INT8
import org.partiql.value.PartiQLValueType.INTERVAL
import org.partiql.value.PartiQLValueType.LIST
import org.partiql.value.PartiQLValueType.MISSING
import org.partiql.value.PartiQLValueType.NULL
import org.partiql.value.PartiQLValueType.SEXP
import org.partiql.value.PartiQLValueType.STRING
import org.partiql.value.PartiQLValueType.STRUCT
import org.partiql.value.PartiQLValueType.SYMBOL
import org.partiql.value.PartiQLValueType.TIME
import org.partiql.value.PartiQLValueType.TIMESTAMP

/**
* Group all function implementations by their name, sorting by precedence.
*/
internal fun <T : FunctionSignature> List<T>.toFnMap(): FnMap<T> = this
.distinctBy { it.specific }
.sortedWith(fnPrecedence)
.groupBy { it.name }

// Function precedence comparator
// 1. Fewest args first
// 2. Parameters are compared left-to-right
internal val fnPrecedence = Comparator<FunctionSignature> { fn1, fn2 ->
// Compare number of arguments
if (fn1.parameters.size != fn2.parameters.size) {
return@Comparator fn1.parameters.size - fn2.parameters.size
}
// Compare operand type precedence
for (i in fn1.parameters.indices) {
val p1 = fn1.parameters[i]
val p2 = fn2.parameters[i]
val comparison = p1.compareTo(p2)
if (comparison != 0) return@Comparator comparison
}
// unreachable?
0
}

@OptIn(PartiQLValueExperimental::class)
internal fun FunctionParameter.compareTo(other: FunctionParameter): Int =
comparePrecedence(this.type, other.type)

@OptIn(PartiQLValueExperimental::class)
internal fun comparePrecedence(t1: PartiQLValueType, t2: PartiQLValueType): Int {
if (t1 == t2) return 0
val p1 = precedence[t1]!!
val p2 = precedence[t2]!!
return p1 - p2
}

// This simply describes some precedence for ordering functions.
// This is not explicitly defined in the PartiQL Specification!!
// This does not imply the ability to CAST; this defines function resolution behavior.
@OptIn(PartiQLValueExperimental::class)
private val precedence: Map<PartiQLValueType, Int> = listOf(
NULL,
MISSING,
BOOL,
INT8,
INT16,
INT32,
INT64,
INT,
DECIMAL,
FLOAT32,
FLOAT64,
DECIMAL_ARBITRARY, // Arbitrary precision decimal has a higher precedence than FLOAT
CHAR,
STRING,
CLOB,
SYMBOL,
BINARY,
BYTE,
BLOB,
DATE,
TIME,
TIMESTAMP,
INTERVAL,
LIST,
SEXP,
BAG,
STRUCT,
ANY,
).mapIndexed { precedence, type -> type to precedence }.toMap()
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,14 @@ package org.partiql.planner.internal.typer
import org.partiql.planner.internal.ir.Agg
import org.partiql.planner.internal.ir.Fn
import org.partiql.planner.internal.ir.Identifier
import org.partiql.plugin.PartiQLFunctions
import org.partiql.planner.internal.typer.FnBuiltins.pAggs
import org.partiql.planner.internal.typer.FnBuiltins.pCasts
import org.partiql.planner.internal.typer.FnBuiltins.pFns
import org.partiql.planner.internal.typer.FnBuiltins.pOps
import org.partiql.spi.connector.ConnectorFunctions
import org.partiql.types.function.FunctionParameter
import org.partiql.types.function.FunctionSignature
import org.partiql.value.PartiQLValueExperimental
import org.partiql.value.PartiQLValueType
import org.partiql.value.PartiQLValueType.ANY
import org.partiql.value.PartiQLValueType.BAG
import org.partiql.value.PartiQLValueType.BINARY
import org.partiql.value.PartiQLValueType.BLOB
import org.partiql.value.PartiQLValueType.BOOL
import org.partiql.value.PartiQLValueType.BYTE
import org.partiql.value.PartiQLValueType.CHAR
import org.partiql.value.PartiQLValueType.CLOB
import org.partiql.value.PartiQLValueType.DATE
import org.partiql.value.PartiQLValueType.DECIMAL
import org.partiql.value.PartiQLValueType.DECIMAL_ARBITRARY
import org.partiql.value.PartiQLValueType.FLOAT32
import org.partiql.value.PartiQLValueType.FLOAT64
import org.partiql.value.PartiQLValueType.INT
import org.partiql.value.PartiQLValueType.INT16
import org.partiql.value.PartiQLValueType.INT32
import org.partiql.value.PartiQLValueType.INT64
import org.partiql.value.PartiQLValueType.INT8
import org.partiql.value.PartiQLValueType.INTERVAL
import org.partiql.value.PartiQLValueType.LIST
import org.partiql.value.PartiQLValueType.MISSING
import org.partiql.value.PartiQLValueType.NULL
import org.partiql.value.PartiQLValueType.SEXP
import org.partiql.value.PartiQLValueType.STRING
import org.partiql.value.PartiQLValueType.STRUCT
import org.partiql.value.PartiQLValueType.SYMBOL
import org.partiql.value.PartiQLValueType.TIME
import org.partiql.value.PartiQLValueType.TIMESTAMP

/**
* Function signature lookup by name.
Expand Down Expand Up @@ -105,7 +79,8 @@ internal class FnRegistry(private val metadata: Collection<ConnectorFunctions>)
internal fun lookupCoercion(operand: PartiQLValueType, target: PartiQLValueType): FunctionSignature.Scalar? {
val i = operand.ordinal
val j = target.ordinal
return pCasts.graph[i][j]?.castFn
val rel = pCasts.graph[i][j] ?: return null
return if (rel.castType == CastType.COERCION) rel.castFn else null
}

internal fun isUnsafeCast(specific: String): Boolean = pCasts.unsafeCastSet.contains(specific)
Expand All @@ -117,107 +92,4 @@ internal class FnRegistry(private val metadata: Collection<ConnectorFunctions>)
is Identifier.Qualified -> throw IllegalArgumentException("Qualified function identifiers not supported")
is Identifier.Symbol -> identifier.symbol.lowercase()
}

companion object {

/**
* Static PartiQL casts information.
*/
@JvmStatic
val pCasts = TypeCasts.partiql()

/**
* Static PartiQL function signatures, don't recompute.
*/
@JvmStatic
val pFns = (PartiQLFunctions.functions + pCasts.relationships().map { it.castFn }).toFnMap()

/**
* Static PartiQL operator signatures, don't recompute.
*/
@JvmStatic
val pOps = PartiQLFunctions.operators.toFnMap()

/**
* Static PartiQL aggregation signatures, don't recompute.
*/
@JvmStatic
val pAggs = PartiQLFunctions.aggregations.toFnMap()

/**
* Group all function implementations by their name, sorting by precedence.
*/
fun <T : FunctionSignature> List<T>.toFnMap(): FnMap<T> = this
.distinctBy { it.specific }
.sortedWith(fnPrecedence)
.groupBy { it.name }

// ====================================
// SORTING
// ====================================

// Function precedence comparator
// 1. Fewest args first
// 2. Parameters are compared left-to-right
@JvmStatic
private val fnPrecedence = Comparator<FunctionSignature> { fn1, fn2 ->
// Compare number of arguments
if (fn1.parameters.size != fn2.parameters.size) {
return@Comparator fn1.parameters.size - fn2.parameters.size
}
// Compare operand type precedence
for (i in fn1.parameters.indices) {
val p1 = fn1.parameters[i]
val p2 = fn2.parameters[i]
val comparison = p1.compareTo(p2)
if (comparison != 0) return@Comparator comparison
}
// unreachable?
0
}

private fun FunctionParameter.compareTo(other: FunctionParameter): Int =
comparePrecedence(this.type, other.type)

private fun comparePrecedence(t1: PartiQLValueType, t2: PartiQLValueType): Int {
if (t1 == t2) return 0
val p1 = precedence[t1]!!
val p2 = precedence[t2]!!
return p1 - p2
}

// This simply describes some precedence for ordering functions.
// This is not explicitly defined in the PartiQL Specification!!
// This does not imply the ability to CAST; this defines function resolution behavior.
private val precedence: Map<PartiQLValueType, Int> = listOf(
NULL,
MISSING,
BOOL,
INT8,
INT16,
INT32,
INT64,
INT,
DECIMAL,
FLOAT32,
FLOAT64,
DECIMAL_ARBITRARY, // Arbitrary precision decimal has a higher precedence than FLOAT
CHAR,
STRING,
CLOB,
SYMBOL,
BINARY,
BYTE,
BLOB,
DATE,
TIME,
TIMESTAMP,
INTERVAL,
LIST,
SEXP,
BAG,
STRUCT,
ANY,
).mapIndexed { precedence, type -> type to precedence }.toMap()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -301,22 +301,22 @@ internal class TypeCasts private constructor(
}
}

private class RelationshipBuilder(val source: PartiQLValueType) {
private class RelationshipBuilder(val operand: PartiQLValueType) {

private val relationships = arrayOfNulls<TypeRelationship?>(N)

fun build() = relationships

fun coercion(target: PartiQLValueType) {
relationships[target] = TypeRelationship(CastType.COERCION, cast(source, target))
relationships[target] = TypeRelationship(CastType.COERCION, cast(operand, target))
}

fun explicit(target: PartiQLValueType) {
relationships[target] = TypeRelationship(CastType.EXPLICIT, cast(source, target))
relationships[target] = TypeRelationship(CastType.EXPLICIT, cast(operand, target))
}

fun unsafe(target: PartiQLValueType) {
relationships[target] = TypeRelationship(CastType.UNSAFE, cast(source, target))
relationships[target] = TypeRelationship(CastType.UNSAFE, cast(operand, target))
}

private fun cast(operand: PartiQLValueType, target: PartiQLValueType) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ package org.partiql.plugin

import org.partiql.spi.connector.ConnectorFunctions
import org.partiql.spi.function.PartiQLFunctionExperimental
import org.partiql.types.function.FunctionSignature

@OptIn(PartiQLFunctionExperimental::class)
object PartiQLFunctions : ConnectorFunctions() {

@OptIn(PartiQLFunctionExperimental::class)
override val functions = PartiQLPlugin.scalars.map { it.signature }

override val operators = PartiQLPlugin.operators.map { it.signature }
@OptIn(PartiQLFunctionExperimental::class)
override val operators: List<FunctionSignature.Scalar> = PartiQLPlugin.operators.map { it.signature }

@OptIn(PartiQLFunctionExperimental::class)
override val aggregations = PartiQLPlugin.aggregations.map { it.signature }
}
Loading

0 comments on commit f129381

Please sign in to comment.