Skip to content

Commit 21180d7

Browse files
committed
Fix build
1 parent 7485cb8 commit 21180d7

File tree

6 files changed

+168
-147
lines changed

6 files changed

+168
-147
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package org.partiql.planner.internal.typer
2+
3+
import org.partiql.plugin.PartiQLFunctions
4+
5+
internal object FnBuiltins {
6+
7+
/**
8+
* Static PartiQL casts information.
9+
*/
10+
@JvmStatic
11+
val pCasts = TypeCasts.partiql()
12+
13+
/**
14+
* Static PartiQL function signatures, don't recompute.
15+
*/
16+
@JvmStatic
17+
val pFns = PartiQLFunctions.functions.toFnMap()
18+
19+
/**
20+
* Static PartiQL operator signatures, don't recompute.
21+
*/
22+
@JvmStatic
23+
val pOps = (PartiQLFunctions.operators + pCasts.relationships().map { it.castFn }).toFnMap()
24+
25+
/*
26+
* Static PartiQL aggregation signatures, don't recompute.
27+
*/
28+
@JvmStatic
29+
val pAggs = PartiQLFunctions.aggregations.toFnMap()
30+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package org.partiql.planner.internal.typer
2+
3+
import org.partiql.types.function.FunctionParameter
4+
import org.partiql.types.function.FunctionSignature
5+
import org.partiql.value.PartiQLValueExperimental
6+
import org.partiql.value.PartiQLValueType
7+
import org.partiql.value.PartiQLValueType.ANY
8+
import org.partiql.value.PartiQLValueType.BAG
9+
import org.partiql.value.PartiQLValueType.BINARY
10+
import org.partiql.value.PartiQLValueType.BLOB
11+
import org.partiql.value.PartiQLValueType.BOOL
12+
import org.partiql.value.PartiQLValueType.BYTE
13+
import org.partiql.value.PartiQLValueType.CHAR
14+
import org.partiql.value.PartiQLValueType.CLOB
15+
import org.partiql.value.PartiQLValueType.DATE
16+
import org.partiql.value.PartiQLValueType.DECIMAL
17+
import org.partiql.value.PartiQLValueType.DECIMAL_ARBITRARY
18+
import org.partiql.value.PartiQLValueType.FLOAT32
19+
import org.partiql.value.PartiQLValueType.FLOAT64
20+
import org.partiql.value.PartiQLValueType.INT
21+
import org.partiql.value.PartiQLValueType.INT16
22+
import org.partiql.value.PartiQLValueType.INT32
23+
import org.partiql.value.PartiQLValueType.INT64
24+
import org.partiql.value.PartiQLValueType.INT8
25+
import org.partiql.value.PartiQLValueType.INTERVAL
26+
import org.partiql.value.PartiQLValueType.LIST
27+
import org.partiql.value.PartiQLValueType.MISSING
28+
import org.partiql.value.PartiQLValueType.NULL
29+
import org.partiql.value.PartiQLValueType.SEXP
30+
import org.partiql.value.PartiQLValueType.STRING
31+
import org.partiql.value.PartiQLValueType.STRUCT
32+
import org.partiql.value.PartiQLValueType.SYMBOL
33+
import org.partiql.value.PartiQLValueType.TIME
34+
import org.partiql.value.PartiQLValueType.TIMESTAMP
35+
36+
/**
37+
* Group all function implementations by their name, sorting by precedence.
38+
*/
39+
internal fun <T : FunctionSignature> List<T>.toFnMap(): FnMap<T> = this
40+
.distinctBy { it.specific }
41+
.sortedWith(fnPrecedence)
42+
.groupBy { it.name }
43+
44+
// Function precedence comparator
45+
// 1. Fewest args first
46+
// 2. Parameters are compared left-to-right
47+
internal val fnPrecedence = Comparator<FunctionSignature> { fn1, fn2 ->
48+
// Compare number of arguments
49+
if (fn1.parameters.size != fn2.parameters.size) {
50+
return@Comparator fn1.parameters.size - fn2.parameters.size
51+
}
52+
// Compare operand type precedence
53+
for (i in fn1.parameters.indices) {
54+
val p1 = fn1.parameters[i]
55+
val p2 = fn2.parameters[i]
56+
val comparison = p1.compareTo(p2)
57+
if (comparison != 0) return@Comparator comparison
58+
}
59+
// unreachable?
60+
0
61+
}
62+
63+
@OptIn(PartiQLValueExperimental::class)
64+
internal fun FunctionParameter.compareTo(other: FunctionParameter): Int =
65+
comparePrecedence(this.type, other.type)
66+
67+
@OptIn(PartiQLValueExperimental::class)
68+
internal fun comparePrecedence(t1: PartiQLValueType, t2: PartiQLValueType): Int {
69+
if (t1 == t2) return 0
70+
val p1 = precedence[t1]!!
71+
val p2 = precedence[t2]!!
72+
return p1 - p2
73+
}
74+
75+
// This simply describes some precedence for ordering functions.
76+
// This is not explicitly defined in the PartiQL Specification!!
77+
// This does not imply the ability to CAST; this defines function resolution behavior.
78+
@OptIn(PartiQLValueExperimental::class)
79+
private val precedence: Map<PartiQLValueType, Int> = listOf(
80+
NULL,
81+
MISSING,
82+
BOOL,
83+
INT8,
84+
INT16,
85+
INT32,
86+
INT64,
87+
INT,
88+
DECIMAL,
89+
FLOAT32,
90+
FLOAT64,
91+
DECIMAL_ARBITRARY, // Arbitrary precision decimal has a higher precedence than FLOAT
92+
CHAR,
93+
STRING,
94+
CLOB,
95+
SYMBOL,
96+
BINARY,
97+
BYTE,
98+
BLOB,
99+
DATE,
100+
TIME,
101+
TIMESTAMP,
102+
INTERVAL,
103+
LIST,
104+
SEXP,
105+
BAG,
106+
STRUCT,
107+
ANY,
108+
).mapIndexed { precedence, type -> type to precedence }.toMap()

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

Lines changed: 6 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -3,40 +3,14 @@ package org.partiql.planner.internal.typer
33
import org.partiql.planner.internal.ir.Agg
44
import org.partiql.planner.internal.ir.Fn
55
import org.partiql.planner.internal.ir.Identifier
6-
import org.partiql.plugin.PartiQLFunctions
6+
import org.partiql.planner.internal.typer.FnBuiltins.pAggs
7+
import org.partiql.planner.internal.typer.FnBuiltins.pCasts
8+
import org.partiql.planner.internal.typer.FnBuiltins.pFns
9+
import org.partiql.planner.internal.typer.FnBuiltins.pOps
710
import org.partiql.spi.connector.ConnectorFunctions
8-
import org.partiql.types.function.FunctionParameter
911
import org.partiql.types.function.FunctionSignature
1012
import org.partiql.value.PartiQLValueExperimental
1113
import org.partiql.value.PartiQLValueType
12-
import org.partiql.value.PartiQLValueType.ANY
13-
import org.partiql.value.PartiQLValueType.BAG
14-
import org.partiql.value.PartiQLValueType.BINARY
15-
import org.partiql.value.PartiQLValueType.BLOB
16-
import org.partiql.value.PartiQLValueType.BOOL
17-
import org.partiql.value.PartiQLValueType.BYTE
18-
import org.partiql.value.PartiQLValueType.CHAR
19-
import org.partiql.value.PartiQLValueType.CLOB
20-
import org.partiql.value.PartiQLValueType.DATE
21-
import org.partiql.value.PartiQLValueType.DECIMAL
22-
import org.partiql.value.PartiQLValueType.DECIMAL_ARBITRARY
23-
import org.partiql.value.PartiQLValueType.FLOAT32
24-
import org.partiql.value.PartiQLValueType.FLOAT64
25-
import org.partiql.value.PartiQLValueType.INT
26-
import org.partiql.value.PartiQLValueType.INT16
27-
import org.partiql.value.PartiQLValueType.INT32
28-
import org.partiql.value.PartiQLValueType.INT64
29-
import org.partiql.value.PartiQLValueType.INT8
30-
import org.partiql.value.PartiQLValueType.INTERVAL
31-
import org.partiql.value.PartiQLValueType.LIST
32-
import org.partiql.value.PartiQLValueType.MISSING
33-
import org.partiql.value.PartiQLValueType.NULL
34-
import org.partiql.value.PartiQLValueType.SEXP
35-
import org.partiql.value.PartiQLValueType.STRING
36-
import org.partiql.value.PartiQLValueType.STRUCT
37-
import org.partiql.value.PartiQLValueType.SYMBOL
38-
import org.partiql.value.PartiQLValueType.TIME
39-
import org.partiql.value.PartiQLValueType.TIMESTAMP
4014

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

11186
internal fun isUnsafeCast(specific: String): Boolean = pCasts.unsafeCastSet.contains(specific)
@@ -117,107 +92,4 @@ internal class FnRegistry(private val metadata: Collection<ConnectorFunctions>)
11792
is Identifier.Qualified -> throw IllegalArgumentException("Qualified function identifiers not supported")
11893
is Identifier.Symbol -> identifier.symbol.lowercase()
11994
}
120-
121-
companion object {
122-
123-
/**
124-
* Static PartiQL casts information.
125-
*/
126-
@JvmStatic
127-
val pCasts = TypeCasts.partiql()
128-
129-
/**
130-
* Static PartiQL function signatures, don't recompute.
131-
*/
132-
@JvmStatic
133-
val pFns = (PartiQLFunctions.functions + pCasts.relationships().map { it.castFn }).toFnMap()
134-
135-
/**
136-
* Static PartiQL operator signatures, don't recompute.
137-
*/
138-
@JvmStatic
139-
val pOps = PartiQLFunctions.operators.toFnMap()
140-
141-
/**
142-
* Static PartiQL aggregation signatures, don't recompute.
143-
*/
144-
@JvmStatic
145-
val pAggs = PartiQLFunctions.aggregations.toFnMap()
146-
147-
/**
148-
* Group all function implementations by their name, sorting by precedence.
149-
*/
150-
fun <T : FunctionSignature> List<T>.toFnMap(): FnMap<T> = this
151-
.distinctBy { it.specific }
152-
.sortedWith(fnPrecedence)
153-
.groupBy { it.name }
154-
155-
// ====================================
156-
// SORTING
157-
// ====================================
158-
159-
// Function precedence comparator
160-
// 1. Fewest args first
161-
// 2. Parameters are compared left-to-right
162-
@JvmStatic
163-
private val fnPrecedence = Comparator<FunctionSignature> { fn1, fn2 ->
164-
// Compare number of arguments
165-
if (fn1.parameters.size != fn2.parameters.size) {
166-
return@Comparator fn1.parameters.size - fn2.parameters.size
167-
}
168-
// Compare operand type precedence
169-
for (i in fn1.parameters.indices) {
170-
val p1 = fn1.parameters[i]
171-
val p2 = fn2.parameters[i]
172-
val comparison = p1.compareTo(p2)
173-
if (comparison != 0) return@Comparator comparison
174-
}
175-
// unreachable?
176-
0
177-
}
178-
179-
private fun FunctionParameter.compareTo(other: FunctionParameter): Int =
180-
comparePrecedence(this.type, other.type)
181-
182-
private fun comparePrecedence(t1: PartiQLValueType, t2: PartiQLValueType): Int {
183-
if (t1 == t2) return 0
184-
val p1 = precedence[t1]!!
185-
val p2 = precedence[t2]!!
186-
return p1 - p2
187-
}
188-
189-
// This simply describes some precedence for ordering functions.
190-
// This is not explicitly defined in the PartiQL Specification!!
191-
// This does not imply the ability to CAST; this defines function resolution behavior.
192-
private val precedence: Map<PartiQLValueType, Int> = listOf(
193-
NULL,
194-
MISSING,
195-
BOOL,
196-
INT8,
197-
INT16,
198-
INT32,
199-
INT64,
200-
INT,
201-
DECIMAL,
202-
FLOAT32,
203-
FLOAT64,
204-
DECIMAL_ARBITRARY, // Arbitrary precision decimal has a higher precedence than FLOAT
205-
CHAR,
206-
STRING,
207-
CLOB,
208-
SYMBOL,
209-
BINARY,
210-
BYTE,
211-
BLOB,
212-
DATE,
213-
TIME,
214-
TIMESTAMP,
215-
INTERVAL,
216-
LIST,
217-
SEXP,
218-
BAG,
219-
STRUCT,
220-
ANY,
221-
).mapIndexed { precedence, type -> type to precedence }.toMap()
222-
}
22395
}

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -301,22 +301,22 @@ internal class TypeCasts private constructor(
301301
}
302302
}
303303

304-
private class RelationshipBuilder(val source: PartiQLValueType) {
304+
private class RelationshipBuilder(val operand: PartiQLValueType) {
305305

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

308308
fun build() = relationships
309309

310310
fun coercion(target: PartiQLValueType) {
311-
relationships[target] = TypeRelationship(CastType.COERCION, cast(source, target))
311+
relationships[target] = TypeRelationship(CastType.COERCION, cast(operand, target))
312312
}
313313

314314
fun explicit(target: PartiQLValueType) {
315-
relationships[target] = TypeRelationship(CastType.EXPLICIT, cast(source, target))
315+
relationships[target] = TypeRelationship(CastType.EXPLICIT, cast(operand, target))
316316
}
317317

318318
fun unsafe(target: PartiQLValueType) {
319-
relationships[target] = TypeRelationship(CastType.UNSAFE, cast(source, target))
319+
relationships[target] = TypeRelationship(CastType.UNSAFE, cast(operand, target))
320320
}
321321

322322
private fun cast(operand: PartiQLValueType, target: PartiQLValueType) =

plugins/partiql-plugin/src/main/kotlin/org/partiql/plugin/PartiQLFunctions.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@ package org.partiql.plugin
22

33
import org.partiql.spi.connector.ConnectorFunctions
44
import org.partiql.spi.function.PartiQLFunctionExperimental
5+
import org.partiql.types.function.FunctionSignature
56

6-
@OptIn(PartiQLFunctionExperimental::class)
77
object PartiQLFunctions : ConnectorFunctions() {
88

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

11-
override val operators = PartiQLPlugin.operators.map { it.signature }
12+
@OptIn(PartiQLFunctionExperimental::class)
13+
override val operators: List<FunctionSignature.Scalar> = PartiQLPlugin.operators.map { it.signature }
1214

15+
@OptIn(PartiQLFunctionExperimental::class)
1316
override val aggregations = PartiQLPlugin.aggregations.map { it.signature }
1417
}

0 commit comments

Comments
 (0)