Reject unsupported query operators during execution planning

This commit is contained in:
Timothy J. Aveni
2026-09-20 23:58:07 -07:00
parent 47a3fe9eae
commit 08e322e59f
4 changed files with 132 additions and 0 deletions
+24
View File
@@ -284,3 +284,27 @@ test("implementation selection is explicit, target checked and independent of ma
"service",
);
});
test("execution planning rejects unsupported grouping before installing the query", async () => {
const workspace = await loadReaderWorkspace((name, text) =>
name === "queries/reader-screen.graphql"
? text.replace("aggregate { count }", "groups(by: {color: true}, first: 10) { entries { aggregate { count } } }")
: text,
);
assert.throws(() => compileExecutionPlan(workspace), /QUERY_OPERATOR_UNSUPPORTED.*grouping/);
});
test("a count-only local query still requires complete relationship admission", async () => {
for (const source of [
"query ReplicaInputs { root { sourceRevision } }",
"query ReplicaInputs { root { highlights(first: 1) { entries { node { color } } } } }",
]) {
const workspace = await loadReaderWorkspace((name, text) => {
if (name === "queries/replica-inputs.graphql") return source;
if (name === "queries/reader-screen.graphql")
return "query ReaderScreen { root { _qx { relations { highlights { aggregate { count } } } } } }";
return text;
});
assert.throws(() => compileExecutionPlan(workspace), /REPLICA_TRAVERSAL_MISSING|REPLICA_RELATION_INCOMPLETE/);
}
});
+12
View File
@@ -108,3 +108,15 @@ test("typed reference operands and scalar membership tests reject unbounded lite
/1000 operands/,
);
});
test("new runtime operator matrix accepts direct count and rejects unsupported relational plans", async () => {
const { unsupportedQueryOperator } = await import("../src/execution-world/query-operators.js");
assert.equal(unsupportedQueryOperator(await compile("aggregate { count }")), undefined);
for (const expression of [
"aggregate { sum { estimatedHours } }",
"filter(where: {estimatedHours: {gt: 0}}) { aggregate { count } }",
"distinct(by: {estimatedHours: true}) { aggregate { count } }",
"aggregate { count @skip(if: true) }",
])
assert.ok(unsupportedQueryOperator(await compile(expression)), expression);
});