sql: Don't panic when a to-text cast needs a disallowed subquery#37067
Merged
aljoscha merged 1 commit intoJun 16, 2026
Merged
Conversation
ggevay
approved these changes
Jun 16, 2026
`typeconv::to_string` and `to_jsonb` assumed casting any type to text always
succeeds and called `.expect("cast known to exist")`. That assumption is
wrong: the `mz_aclitem` and `reg*` text casts are implemented as catalog
subqueries, and `plan_cast` rejects subqueries in contexts that disallow them
-- a `RETURNING` clause, or the element-cast context of `to_jsonb` on an array
or list. The cast then returns an error that `.expect()` turned into a panic,
crashing the worker.
We now thread the cast error through `to_string`/`to_jsonb` and their callers,
so these cases produce a graceful planning error (e.g. "pg_catalog.concat does
not support casting from regtype to text") instead of panicking.
This only stops the panic. Making these casts work in subquery-disallowed
contexts to match PostgreSQL (which evaluates them via the type's output
function) is a larger change and is not attempted here.
Fixes SQL-270
Fixes SQL-269
c15f639 to
cc71823
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Fixes SQL-270
Fixes SQL-269
Several SQLancer/SQLsmith builds hit a coordinator/worker panic:
typeconv::to_stringandto_jsonbassumed that casting any type to textalways succeeds and called
.expect("cast known to exist"). That assumption iswrong: the
mz_aclitemandreg*(regtype,regclass, ...) text casts areimplemented as catalog subqueries, and
plan_castrejects subqueries incontexts that disallow them -- a
RETURNINGclause, or the element-cast contextof
to_jsonbon an array/list. The cast returns an error, and.expect()turned that into a panic that crashes the worker. Reachable from plain user
input, e.g.:
Description
Change
to_stringandto_jsonbto returnResult<HirScalarExpr, PlanError>and thread the
plan_casterror through their (few) callers with?. Thecasts that genuinely never fail (numeric widening for JSON numbers) keep their
.expect().These queries now produce a graceful, query-level planning error instead of
panicking, e.g.
pg_catalog.concat does not support casting from regtype to textandto_jsonb does not support casting from mz_aclitem to text.This is the "stop the bleeding" fix that the team agreed on in the issue
discussion. It does not make these casts work in subquery-disallowed
contexts, so it diverges from PostgreSQL, which evaluates them via the type's
output function and succeeds. Closing that gap (planning such casts as Rust
functions that read the catalog directly, or lifting the
allow_subqueriesrestriction where a dataflow is involved) is a larger change left as follow-up.
Verification
New regression tests:
test/sqllogictest/regtype.slt--concat(regtype)succeeds in a plainSELECTbut errors gracefully in aRETURNINGclause (SQL-270).test/sqllogictest/jsonb.slt--to_jsonb/jsonb_build_arrayovermz_aclitem[]andregclass[]error gracefully (SQL-269).I also confirmed against a real PostgreSQL 16 that all of these queries succeed
there, which is why full parity is called out as follow-up rather than the
behavior asserted here.
cargo check,cargo fmt, andcargo clippy -p mz-sql --all-targets -- -D warningspass locally.