Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "PartiQL Eval - Planner Mode (#1385)" #1425

Merged
merged 1 commit into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading