Skip to content

Commit

Permalink
Moves scalar subquery test to planner
Browse files Browse the repository at this point in the history
Adds PError for scalar subquery degree violation
  • Loading branch information
johnedquinn committed Feb 7, 2025
1 parent 285973a commit f424ddd
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ class CteTests {
""".trimIndent(),
),
// TODO: Figure out if this should be allowed. In PostgreSQL, it is allowed. In SQL Spec, I'm not sure.
// As such, updating the implementation to allow for this would be a non-breaking change.
FailureTestCase(
name = "Attempting to reference another with list element",
input = """
Expand Down Expand Up @@ -213,21 +214,6 @@ class CteTests {
)
}

@Test
@Disabled("This does fail, however, failure occurs during planning. Please add this test to the planning stage.")
fun cteDegree() {
val tc = FailureTestCase(
name = "CTE with degree greater than 1 used in subquery",
input = """
WITH x AS (
SELECT * FROM << { 'a': 1, 'b': 2 } >> AS t
)
SELECT VALUE y + (SELECT * FROM x) FROM <<100>> AS y;
""".trimIndent(),
)
tc.run()
}

// TODO: Figure out the right behavior here.
@Test
@Disabled(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,16 @@ internal object PErrors {
)
}

internal fun degreeViolationScalarSubquery(actual: Int, location: SourceLocation? = null): PError {
return PError(
PError.DEGREE_VIOLATION_SCALAR_SUBQUERY,
Severity.ERROR(),
PErrorKind.SEMANTIC(),
location,
mapOf("ACTUAL" to actual),
)
}

private fun internalError(cause: Throwable): PError = PError(
PError.INTERNAL_ERROR,
Severity.ERROR(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1071,10 +1071,10 @@ internal class PlanTyper(private val env: Env, config: Context) {
}
val n = cons.fields.size
if (n != 1) {
error("SELECT constructor with $n attributes cannot be coerced to a scalar. Found constructor type: $cons")
env.listener.report(PErrors.degreeViolationScalarSubquery(n))
}
// If we made it this far, then we can coerce this subquery to a scalar
val type = cons.fields.first().type
val type = cons.fields.firstOrNull()?.type ?: PType.dynamic().toCType()
return Rex(type, subquery)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3917,6 +3917,27 @@ internal class PlanTyperTestsPorted {
@Execution(ExecutionMode.CONCURRENT)
fun testCasts(tc: TestCase) = runTest(tc)

/**
* While all existing CTE tests exist in the evaluator, this one exists in the planner, since it causes a compilation
* error. In the future, it might be a good idea to consolidate our tests as end-to-end tests.
*/
@Test
fun testCteWithDegreeGtOne() {
val tc = ErrorTestCase(
name = "CTE with degree greater than 1 used in subquery",
query = """
WITH x AS (
SELECT * FROM << { 'a': 1, 'b': 2 } >> AS t
)
SELECT VALUE y + (SELECT * FROM x) FROM <<100>> AS y;
""".trimIndent(),
problemHandler = assertProblemExists(
PErrors.degreeViolationScalarSubquery(2)
)
)
runTest(tc)
}

// --------- Finish Parameterized Tests ------

//
Expand Down
1 change: 1 addition & 0 deletions partiql-spi/api/partiql-spi.api
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ public final class org/partiql/spi/catalog/Table$DefaultImpls {
public final class org/partiql/spi/errors/PError : org/partiql/spi/Enum {
public static final field ALWAYS_MISSING I
public static final field CARDINALITY_VIOLATION I
public static final field DEGREE_VIOLATION_SCALAR_SUBQUERY I
public static final field DIVISION_BY_ZERO I
public static final field FEATURE_NOT_SUPPORTED I
public static final field FUNCTION_NOT_FOUND I
Expand Down
18 changes: 18 additions & 0 deletions partiql-spi/src/main/java/org/partiql/spi/errors/PError.java
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ public String name() throws UnsupportedCodeException {
return "INVALID_CHAR_VALUE_FOR_CAST";
case DIVISION_BY_ZERO:
return "DIVISION_BY_ZERO";
case DEGREE_VIOLATION_SCALAR_SUBQUERY:
return "DEGREE_VIOLATION_SCALAR_SUBQUERY";
default:
throw new UnsupportedCodeException(code);
}
Expand Down Expand Up @@ -544,4 +546,20 @@ public static PError INTERNAL_ERROR(@NotNull PErrorKind kind, @Nullable SourceLo
* </p>
*/
public static final int DIVISION_BY_ZERO = 19;

/**
* <p>
* This is a runtime/compilation/planning error emitted when the degree of a scalar subquery is not 1 (one).
* </p>
* <p>
* Potentially available properties:
* <ul>
* <li><b>ACTUAL</b> ({@link Integer}): The actual degree of the scalar subquery.</li>
* </ul>
* </p>
* <p>
* Example error message: <code>[location]: Degree of scalar subquery must be 1 (one). Actual degree: [actual].</code>
* </p>
*/
public static final int DEGREE_VIOLATION_SCALAR_SUBQUERY = 20;
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class PErrorCodeTests {
"NUMERIC_VALUE_OUT_OF_RANGE" to 17,
"INVALID_CHAR_VALUE_FOR_CAST" to 18,
"DIVISION_BY_ZERO" to 19,
"DEGREE_VIOLATION_SCALAR_SUBQUERY" to 20
)

// Preparation
Expand Down

0 comments on commit f424ddd

Please sign in to comment.