Skip to content

Commit

Permalink
Revert "PartiQL Eval - Planner Mode (#1385)" (#1425)
Browse files Browse the repository at this point in the history
  • Loading branch information
RCHowell authored Apr 11, 2024
1 parent 6103e9e commit 5f16e67
Show file tree
Hide file tree
Showing 22 changed files with 1,158 additions and 1,731 deletions.
1 change: 0 additions & 1 deletion buildSrc/src/main/kotlin/partiql.conventions.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ java {
tasks.test {
useJUnitPlatform() // Enable JUnit5
jvmArgs.addAll(listOf("-Duser.language=en", "-Duser.country=US"))
jvmArgs.add("-Djunit.jupiter.execution.timeout.mode=disabled_on_debug")
maxHeapSize = "4g"
testLogging {
events.add(TestLogEvent.FAILED)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ internal abstract class RelJoinNestedLoop : RelPeeking() {
toReturn = join(result.isTrue(), lhsRecord!!, rhsRecord)
}
// Move the pointer to the next row for the RHS
if (toReturn == null) rhsRecord = if (rhs.hasNext()) rhs.next() else null
if (toReturn == null) rhsRecord = rhs.next()
}
while (toReturn == null)
return toReturn
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,11 @@ internal class RelOffset(

override fun hasNext(): Boolean {
if (!init) {
while (input.hasNext()) {
for (record in input) {
if (_seen >= _offset) {
break
}
_seen = _seen.add(BigInteger.ONE)
input.next()
}
init = true
}
Expand Down
6 changes: 0 additions & 6 deletions partiql-plan/src/main/resources/partiql_plan.ion
Original file line number Diff line number Diff line change
Expand Up @@ -195,12 +195,6 @@ rex::{

err::{
message: string,
causes: list::['.rex.op']
},

missing::{
message: string,
causes: list::['.rex.op']
},
],
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.partiql.planner.internal
package org.partiql.planner

import org.partiql.errors.ProblemDetails
import org.partiql.errors.ProblemSeverity
Expand All @@ -13,45 +13,21 @@ import org.partiql.types.StaticType
* This information can be used to generate end-user readable error messages and is also easy to assert
* equivalence in unit tests.
*/
internal open class PlanningProblemDetails(
public sealed class PlanningProblemDetails(
override val severity: ProblemSeverity,
val messageFormatter: () -> String,
public val messageFormatter: () -> String,
) : ProblemDetails {

companion object {
private fun quotationHint(caseSensitive: Boolean) =
if (caseSensitive) {
// Individuals that are new to SQL often try to use double quotes for string literals.
// Let's help them out a bit.
" Hint: did you intend to use single-quotes (') here? Remember that double-quotes (\") denote " +
"quoted identifiers and single-quotes denote strings."
} else {
""
}

private fun Identifier.sql(): String = when (this) {
is Identifier.Qualified -> this.sql()
is Identifier.Symbol -> this.sql()
}

private fun Identifier.Qualified.sql(): String = root.sql() + "." + steps.joinToString(".") { it.sql() }

private fun Identifier.Symbol.sql(): String = when (caseSensitivity) {
Identifier.CaseSensitivity.SENSITIVE -> "\"$symbol\""
Identifier.CaseSensitivity.INSENSITIVE -> symbol
}
}

override fun toString(): String = message
override val message: String get() = messageFormatter()

data class ParseError(val parseErrorMessage: String) :
public data class ParseError(val parseErrorMessage: String) :
PlanningProblemDetails(ProblemSeverity.ERROR, { parseErrorMessage })

data class CompileError(val errorMessage: String) :
public data class CompileError(val errorMessage: String) :
PlanningProblemDetails(ProblemSeverity.ERROR, { errorMessage })

data class UndefinedVariable(val id: BindingPath) :
public data class UndefinedVariable(val id: BindingPath) :
PlanningProblemDetails(
ProblemSeverity.ERROR,
{
Expand All @@ -61,7 +37,7 @@ internal open class PlanningProblemDetails(
}
)

data class UndefinedDmlTarget(val variableName: String, val caseSensitive: Boolean) :
public data class UndefinedDmlTarget(val variableName: String, val caseSensitive: Boolean) :
PlanningProblemDetails(
ProblemSeverity.ERROR,
{
Expand All @@ -71,25 +47,25 @@ internal open class PlanningProblemDetails(
}
)

data class VariablePreviouslyDefined(val variableName: String) :
public data class VariablePreviouslyDefined(val variableName: String) :
PlanningProblemDetails(
ProblemSeverity.ERROR,
{ "The variable '$variableName' was previously defined." }
)

data class UnimplementedFeature(val featureName: String) :
public data class UnimplementedFeature(val featureName: String) :
PlanningProblemDetails(
ProblemSeverity.ERROR,
{ "The syntax at this location is valid but utilizes unimplemented PartiQL feature '$featureName'" }
)

object InvalidDmlTarget :
public object InvalidDmlTarget :
PlanningProblemDetails(
ProblemSeverity.ERROR,
{ "Expression is not a valid DML target. Hint: only table names are allowed here." }
)

object InsertValueDisallowed :
public object InsertValueDisallowed :
PlanningProblemDetails(
ProblemSeverity.ERROR,
{
Expand All @@ -98,7 +74,7 @@ internal open class PlanningProblemDetails(
}
)

object InsertValuesDisallowed :
public object InsertValuesDisallowed :
PlanningProblemDetails(
ProblemSeverity.ERROR,
{
Expand All @@ -107,32 +83,27 @@ internal open class PlanningProblemDetails(
}
)

data class UnexpectedType(
public data class UnexpectedType(
val actualType: StaticType,
val expectedTypes: Set<StaticType>,
) : PlanningProblemDetails(ProblemSeverity.ERROR, {
"Unexpected type $actualType, expected one of ${expectedTypes.joinToString()}"
})

data class UnknownFunction(
public data class UnknownFunction(
val identifier: String,
val args: List<StaticType>,
) : PlanningProblemDetails(ProblemSeverity.ERROR, {
val types = args.joinToString { "<${it.toString().lowercase()}>" }
"Unknown function `$identifier($types)"
})

data class ExpressionAlwaysReturnsMissing(val reason: String? = null) : PlanningProblemDetails(
severity = ProblemSeverity.ERROR,
messageFormatter = { "Expression always returns null or missing: caused by $reason" }
)

object ExpressionAlwaysReturnsNullOrMissing : PlanningProblemDetails(
public object ExpressionAlwaysReturnsNullOrMissing : PlanningProblemDetails(
severity = ProblemSeverity.ERROR,
messageFormatter = { "Expression always returns null or missing." }
)

data class InvalidArgumentTypeForFunction(
public data class InvalidArgumentTypeForFunction(
val functionName: String,
val expectedType: StaticType,
val actualType: StaticType,
Expand All @@ -142,7 +113,7 @@ internal open class PlanningProblemDetails(
messageFormatter = { "Invalid argument type for $functionName. Expected $expectedType but got $actualType" }
)

data class IncompatibleTypesForOp(
public data class IncompatibleTypesForOp(
val actualTypes: List<StaticType>,
val operator: String,
) :
Expand All @@ -151,9 +122,31 @@ internal open class PlanningProblemDetails(
messageFormatter = { "${actualTypes.joinToString()} is/are incompatible data types for the '$operator' operator." }
)

data class UnresolvedExcludeExprRoot(val root: String) :
public data class UnresolvedExcludeExprRoot(val root: String) :
PlanningProblemDetails(
ProblemSeverity.ERROR,
{ "Exclude expression given an unresolvable root '$root'" }
)
}

private fun quotationHint(caseSensitive: Boolean) =
if (caseSensitive) {
// Individuals that are new to SQL often try to use double quotes for string literals.
// Let's help them out a bit.
" Hint: did you intend to use single-quotes (') here? Remember that double-quotes (\") denote " +
"quoted identifiers and single-quotes denote strings."
} else {
""
}

private fun Identifier.sql(): String = when (this) {
is Identifier.Qualified -> this.sql()
is Identifier.Symbol -> this.sql()
}

private fun Identifier.Qualified.sql(): String = root.sql() + "." + steps.joinToString(".") { it.sql() }

private fun Identifier.Symbol.sql(): String = when (caseSensitivity) {
Identifier.CaseSensitivity.SENSITIVE -> "\"$symbol\""
Identifier.CaseSensitivity.INSENSITIVE -> symbol
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public interface PartiQLPlanner {
public val catalogs: Map<String, ConnectorMetadata> = emptyMap(),
public val instant: Instant = Instant.now(),
)

public companion object {

@JvmStatic
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,25 @@
package org.partiql.planner

import org.partiql.planner.internal.PartiQLPlannerDefault
import org.partiql.planner.internal.PlannerFlag
import org.partiql.spi.connector.ConnectorMetadata

/**
* PartiQLPlannerBuilder is used to programmatically construct a [PartiQLPlanner] implementation.
*
* Usage:
* PartiQLPlanner.builder()
* .signalMode()
* .addPass(myPass)
* .build()
*/
public class PartiQLPlannerBuilder {

private val flags: MutableSet<PlannerFlag> = mutableSetOf()

private val passes: MutableList<PartiQLPlannerPass> = mutableListOf()

/**
* Build the builder, return an implementation of a [PartiQLPlanner].
*
* @return
*/
public fun build(): PartiQLPlanner = PartiQLPlannerDefault(passes, flags)
public fun build(): PartiQLPlanner = PartiQLPlannerDefault(passes)

/**
* Java style method for adding a planner pass to this planner builder.
Expand All @@ -46,13 +41,6 @@ public class PartiQLPlannerBuilder {
this.passes.addAll(passes)
}

/**
* Java style method for setting the planner to signal mode
*/
public fun signalMode(): PartiQLPlannerBuilder = this.apply {
this.flags.add(PlannerFlag.SIGNAL_MODE)
}

/**
* Java style method for assigning a Catalog name to [ConnectorMetadata].
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package org.partiql.planner.internal
package org.partiql.planner

import org.partiql.ast.Statement
import org.partiql.ast.normalize.normalize
import org.partiql.errors.ProblemCallback
import org.partiql.planner.PartiQLPlanner
import org.partiql.planner.PartiQLPlannerPass
import org.partiql.planner.internal.Env
import org.partiql.planner.internal.transforms.AstToPlan
import org.partiql.planner.internal.transforms.PlanTransform
import org.partiql.planner.internal.typer.PlanTyper
Expand All @@ -14,7 +13,6 @@ import org.partiql.planner.internal.typer.PlanTyper
*/
internal class PartiQLPlannerDefault(
private val passes: List<PartiQLPlannerPass>,
private val flags: Set<PlannerFlag>
) : PartiQLPlanner {

override fun plan(
Expand All @@ -33,12 +31,12 @@ internal class PartiQLPlannerDefault(
val root = AstToPlan.apply(ast, env)

// 3. Resolve variables
val typer = PlanTyper(env)
val typer = PlanTyper(env, onProblem)
val typed = typer.resolve(root)
val internal = org.partiql.planner.internal.ir.PartiQLPlan(typed)

// 4. Assert plan has been resolved — translating to public API
var plan = PlanTransform(flags).transform(internal, onProblem)
var plan = PlanTransform.transform(internal, onProblem)

// 5. Apply all passes
for (pass in passes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,22 +93,9 @@ internal class Env(private val session: PartiQLPlanner.Session) {
// Invoke FnResolver to determine if we made a match
val variants = item.handle.entity.getVariants()
val match = FnResolver.resolve(variants, args.map { it.type })
// If Type mismatch, then we return a missingOp whose trace is all possible candidates.
if (match == null) {
val candidates = variants.map { fnSignature ->
rexOpCallDynamicCandidate(
fn = refFn(
item.catalog,
path = item.handle.path.steps,
signature = fnSignature
),
coercions = emptyList()
)
}
return ProblemGenerator.missingRex(
rexOpCallDynamic(args, candidates, false),
ProblemGenerator.incompatibleTypesForOp(args.map { it.type }, path.normalized.joinToString("."))
)
// unable to make a match, consider returning helpful error messages given the item.variants.
return null
}
return when (match) {
is FnMatch.Dynamic -> {
Expand Down

This file was deleted.

Loading

0 comments on commit 5f16e67

Please sign in to comment.