Skip to content

Commit a6301c7

Browse files
authored
Merge 8850837 into 5c1240c
2 parents 5c1240c + 8850837 commit a6301c7

File tree

15 files changed

+145
-224
lines changed

15 files changed

+145
-224
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ Thank you to all who have contributed!
4343
- **Breaking** The default integer literal type is now 32-bit; if the literal can not fit in a 32-bit integer, it overflows to 64-bit.
4444
- **BREAKING** `PartiQLValueType` now distinguishes between Arbitrary Precision Decimal and Fixed Precision Decimal.
4545
- **BREAKING** Function Signature Changes. Now Function signature has two subclasses, `Scalar` and `Aggregation`.
46+
- **BREAKING** Plugin Changes. Only return one Connector.Factory, use Kotlin fields. JVM signature remains the same.
4647
- **BREAKING** In the produced plan:
4748
- The new plan is fully resolved and typed.
4849
- Operators will be converted to function call.

partiql-cli/src/main/kotlin/org/partiql/cli/utils/ServiceLoaderUtil.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,13 @@ class ServiceLoaderUtil {
113113
} else {
114114
listOf()
115115
}
116-
return plugins.flatMap { plugin -> plugin.getFunctions() }
116+
return plugins.flatMap { plugin -> plugin.functions }
117+
.filterIsInstance<PartiQLFunction.Scalar>()
117118
.map { partiqlFunc -> PartiQLtoExprFunction(partiqlFunc) }
118119
}
119120

120121
@OptIn(PartiQLValueExperimental::class, PartiQLFunctionExperimental::class)
121-
private fun PartiQLtoExprFunction(customFunction: PartiQLFunction): ExprFunction {
122+
private fun PartiQLtoExprFunction(customFunction: PartiQLFunction.Scalar): ExprFunction {
122123
val name = customFunction.signature.name
123124
val parameters = customFunction.signature.parameters.map { it.type }
124125
val returnType = customFunction.signature.returns
@@ -130,8 +131,8 @@ class ServiceLoaderUtil {
130131
)
131132

132133
override fun callWithRequired(session: EvaluationSession, required: List<ExprValue>): ExprValue {
133-
val partiQLArguments = required.mapIndexed { i, expr -> ExprToPartiQLValue(expr, parameters[i]) }
134-
val partiQLResult = customFunction.invoke(session.toConnectorSession(), partiQLArguments)
134+
val partiQLArguments = required.mapIndexed { i, expr -> ExprToPartiQLValue(expr, parameters[i]) }.toTypedArray()
135+
val partiQLResult = customFunction.invoke(partiQLArguments)
135136
return PartiQLtoExprValue(partiQLResult)
136137
}
137138
}

partiql-cli/src/test/kotlin/org/partiql/cli/utils/PowTest.kt

Lines changed: 0 additions & 34 deletions
This file was deleted.

partiql-cli/src/test/kotlin/org/partiql/cli/utils/ServiceLoaderUtilTest.kt

Lines changed: 0 additions & 18 deletions
This file was deleted.

partiql-cli/src/test/kotlin/org/partiql/cli/utils/TrimLeadTest.kt

Lines changed: 0 additions & 38 deletions
This file was deleted.

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

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ internal class PlanTyper(
112112
/**
113113
* Rewrite the statement with inferred types and resolved variables
114114
*/
115-
public fun resolve(statement: Statement): Statement {
115+
fun resolve(statement: Statement): Statement {
116116
if (statement !is Statement.Query) {
117117
throw IllegalArgumentException("PartiQLPlanner only supports Query statements")
118118
}
@@ -182,15 +182,15 @@ internal class PlanTyper(
182182
}
183183

184184
// compute element type
185-
val t = rex.type as StructType
185+
val t = rex.type
186186
val e = if (t.contentClosed) {
187187
StaticType.unionOf(t.fields.map { it.value }.toSet()).flatten()
188188
} else {
189-
StaticType.ANY
189+
ANY
190190
}
191191

192192
// compute rel type
193-
val kType = StaticType.STRING
193+
val kType = STRING
194194
val vType = e
195195
val type = ctx!!.copyWithSchema(listOf(kType, vType))
196196

@@ -419,7 +419,7 @@ internal class PlanTyper(
419419

420420
if (resolvedVar == null) {
421421
handleUndefinedVariable(path.steps.last())
422-
return rex(StaticType.ANY, rexOpErr("Undefined variable ${node.identifier}"))
422+
return rex(ANY, rexOpErr("Undefined variable ${node.identifier}"))
423423
}
424424
val type = resolvedVar.type
425425
val op = when (resolvedVar) {
@@ -439,7 +439,7 @@ internal class PlanTyper(
439439
* Match path as far as possible (rewriting the steps), then infer based on resolved root and rewritten steps.
440440
*/
441441
override fun visitRexOpPath(node: Rex.Op.Path, ctx: StaticType?): Rex {
442-
val visitedSteps = node.steps.map { visitRexOpPathStep(it, null) as Rex.Op.Path.Step }
442+
val visitedSteps = node.steps.map { visitRexOpPathStep(it, null) }
443443
// 1. Resolve path prefix
444444
val (root, steps) = when (val rootOp = node.root.op) {
445445
is Rex.Op.Var.Unresolved -> {
@@ -448,7 +448,7 @@ internal class PlanTyper(
448448
val resolvedVar = env.resolve(path, locals, rootOp.scope)
449449
if (resolvedVar == null) {
450450
handleUndefinedVariable(path.steps.last())
451-
return rex(StaticType.ANY, node)
451+
return rex(ANY, node)
452452
}
453453
val type = resolvedVar.type
454454
val (op, steps) = when (resolvedVar) {
@@ -498,7 +498,7 @@ internal class PlanTyper(
498498
}
499499

500500
// 4. Invalid path reference; always MISSING
501-
if (type == StaticType.MISSING) {
501+
if (type == MISSING) {
502502
handleAlwaysMissing()
503503
return rexErr("Unknown identifier $node")
504504
}
@@ -540,7 +540,7 @@ internal class PlanTyper(
540540
is FnMatch.Dynamic -> {
541541
val types = mutableSetOf<StaticType>()
542542
if (match.isMissable && !isNotMissable) {
543-
types.add(StaticType.MISSING)
543+
types.add(MISSING)
544544
}
545545
val candidates = match.candidates.map { candidate ->
546546
val rex = toRexCall(candidate, args, isNotMissable)
@@ -574,7 +574,7 @@ internal class PlanTyper(
574574
newArgs.forEach {
575575
if (it.type == MissingType && !isNotMissable) {
576576
handleAlwaysMissing()
577-
return rex(StaticType.MISSING, rexOpCallStatic(newFn, newArgs))
577+
return rex(MISSING, rexOpCallStatic(newFn, newArgs))
578578
}
579579
}
580580

@@ -615,14 +615,14 @@ internal class PlanTyper(
615615

616616
// Return type with calculated nullability
617617
var type = when {
618-
isNull -> StaticType.NULL
618+
isNull -> NULL
619619
isNullable -> returns.toStaticType()
620620
else -> returns.toNonNullStaticType()
621621
}
622622

623623
// Some operators can return MISSING during runtime
624624
if (match.isMissable && !isNotMissable) {
625-
type = StaticType.unionOf(type, StaticType.MISSING)
625+
type = StaticType.unionOf(type, MISSING)
626626
}
627627

628628
// Finally, rewrite this node
@@ -740,8 +740,8 @@ internal class PlanTyper(
740740
}
741741
val ref = call.args.getOrNull(0) ?: error("IS STRUCT requires an argument.")
742742
val simplifiedCondition = when {
743-
ref.type.allTypes.all { it is StructType } -> rex(StaticType.BOOL, rexOpLit(boolValue(true)))
744-
ref.type.allTypes.none { it is StructType } -> rex(StaticType.BOOL, rexOpLit(boolValue(false)))
743+
ref.type.allTypes.all { it is StructType } -> rex(BOOL, rexOpLit(boolValue(true)))
744+
ref.type.allTypes.none { it is StructType } -> rex(BOOL, rexOpLit(boolValue(false)))
745745
else -> condition
746746
}
747747

@@ -789,9 +789,9 @@ internal class PlanTyper(
789789
when (field.k.op) {
790790
is Rex.Op.Lit -> {
791791
// A field is only included in the StructType if its key is a text literal
792-
val key = field.k.op as Rex.Op.Lit
792+
val key = field.k.op
793793
if (key.value is TextValue<*>) {
794-
val name = (key.value as TextValue<*>).string!!
794+
val name = key.value.string!!
795795
val type = field.v.type
796796
structKeysSeent.add(name)
797797
structTypeFields.add(StructType.Field(name, type))
@@ -919,7 +919,7 @@ internal class PlanTyper(
919919
}
920920

921921
override fun visitRexOpErr(node: Rex.Op.Err, ctx: StaticType?): PlanNode {
922-
val type = ctx ?: StaticType.ANY
922+
val type = ctx ?: ANY
923923
return rex(type, node)
924924
}
925925

@@ -968,13 +968,13 @@ internal class PlanTyper(
968968
PlanningProblemDetails.CompileError("TupleUnion wasn't normalized to exclude union types.")
969969
)
970970
)
971-
possibleOutputTypes.add(StaticType.MISSING)
971+
possibleOutputTypes.add(MISSING)
972972
}
973973
is NullType -> {
974-
return StaticType.NULL
974+
return NULL
975975
}
976976
else -> {
977-
return StaticType.MISSING
977+
return MISSING
978978
}
979979
}
980980
}
@@ -1057,7 +1057,7 @@ internal class PlanTyper(
10571057
*/
10581058
private fun inferPathStep(type: StaticType, step: Rex.Op.Path.Step): Pair<StaticType, Rex.Op.Path.Step> =
10591059
when (type) {
1060-
is AnyType -> StaticType.ANY to step
1060+
is AnyType -> ANY to step
10611061
is StructType -> inferPathStep(type, step)
10621062
is ListType, is SexpType -> inferPathStep(type as CollectionType, step) to step
10631063
is AnyOfType -> {
@@ -1066,7 +1066,7 @@ internal class PlanTyper(
10661066
else -> {
10671067
val prevTypes = type.allTypes
10681068
if (prevTypes.any { it is AnyType }) {
1069-
StaticType.ANY to step
1069+
ANY to step
10701070
} else {
10711071
val results = prevTypes.map { inferPathStep(it, step) }
10721072
val types = results.map { it.first }
@@ -1081,7 +1081,7 @@ internal class PlanTyper(
10811081
}
10821082
}
10831083
}
1084-
else -> StaticType.MISSING to step
1084+
else -> MISSING to step
10851085
}
10861086

10871087
/**
@@ -1156,13 +1156,13 @@ internal class PlanTyper(
11561156
isClosed && isOrdered -> {
11571157
struct.fields.firstOrNull { entry -> binding.isEquivalentTo(entry.key) }?.let {
11581158
(sensitive(it.key) to it.value)
1159-
} ?: (key to StaticType.MISSING)
1159+
} ?: (key to MISSING)
11601160
}
11611161
// 2. Struct is closed
11621162
isClosed -> {
11631163
val matches = struct.fields.filter { entry -> binding.isEquivalentTo(entry.key) }
11641164
when (matches.size) {
1165-
0 -> (key to StaticType.MISSING)
1165+
0 -> (key to MISSING)
11661166
1 -> matches.first().let { (sensitive(it.key) to it.value) }
11671167
else -> {
11681168
val firstKey = matches.first().key
@@ -1175,7 +1175,7 @@ internal class PlanTyper(
11751175
}
11761176
}
11771177
// 3. Struct is open
1178-
else -> (key to StaticType.ANY)
1178+
else -> (key to ANY)
11791179
}
11801180
return type to name
11811181
}
@@ -1197,7 +1197,7 @@ internal class PlanTyper(
11971197
* Let TX be the single-column table that is the result of applying the <value expression>
11981198
* to each row of T and eliminating null values <--- all NULL values are eliminated as inputs
11991199
*/
1200-
public fun resolveAgg(agg: Agg.Unresolved, arguments: List<Rex>): Pair<Rel.Op.Aggregate.Call, StaticType> {
1200+
fun resolveAgg(agg: Agg.Unresolved, arguments: List<Rex>): Pair<Rel.Op.Aggregate.Call, StaticType> {
12011201
var missingArg = false
12021202
val args = arguments.map {
12031203
val arg = visitRex(it, null)
@@ -1227,7 +1227,7 @@ internal class PlanTyper(
12271227

12281228
// Some operators can return MISSING during runtime
12291229
if (match.isMissable) {
1230-
type = StaticType.unionOf(type, StaticType.MISSING).flatten()
1230+
type = StaticType.unionOf(type, MISSING).flatten()
12311231
}
12321232

12331233
// Finally, rewrite this node
@@ -1248,7 +1248,7 @@ internal class PlanTyper(
12481248

12491249
private fun Rex.type(typeEnv: TypeEnv) = RexTyper(typeEnv).visitRex(this, this.type)
12501250

1251-
private fun rexErr(message: String) = rex(StaticType.MISSING, rexOpErr(message))
1251+
private fun rexErr(message: String) = rex(MISSING, rexOpErr(message))
12521252

12531253
/**
12541254
* I found decorating the tree with the binding names (for resolution) was easier than associating introduced
@@ -1315,7 +1315,7 @@ internal class PlanTyper(
13151315
private fun getElementTypeForFromSource(fromSourceType: StaticType): StaticType = when (fromSourceType) {
13161316
is BagType -> fromSourceType.elementType
13171317
is ListType -> fromSourceType.elementType
1318-
is AnyType -> StaticType.ANY
1318+
is AnyType -> ANY
13191319
is AnyOfType -> AnyOfType(fromSourceType.types.map { getElementTypeForFromSource(it) }.toSet())
13201320
// All the other types coerce into a bag of themselves (including null/missing/sexp).
13211321
else -> fromSourceType
@@ -1437,7 +1437,7 @@ internal class PlanTyper(
14371437
private fun Fn.Unresolved.isNotMissable(): Boolean {
14381438
return when (identifier) {
14391439
is Identifier.Qualified -> false
1440-
is Identifier.Symbol -> when ((identifier as Identifier.Symbol).symbol) {
1440+
is Identifier.Symbol -> when (identifier.symbol) {
14411441
"and" -> true
14421442
"or" -> true
14431443
"not" -> true
@@ -1450,7 +1450,7 @@ internal class PlanTyper(
14501450
}
14511451

14521452
private fun Fn.Unresolved.isTypeAssertion(): Boolean {
1453-
return (identifier is Identifier.Symbol && (identifier as Identifier.Symbol).symbol.startsWith("is"))
1453+
return (identifier is Identifier.Symbol && identifier.symbol.startsWith("is"))
14541454
}
14551455

14561456
/**

0 commit comments

Comments
 (0)