Skip to content

fix: return error instead of panicking on append with mismatched columns#6025

Open
prql-bot wants to merge 1 commit into
mainfrom
fix/append-column-mismatch-panic
Open

fix: return error instead of panicking on append with mismatched columns#6025
prql-bot wants to merge 1 commit into
mainfrom
fix/append-column-mismatch-panic

Conversation

@prql-bot

Copy link
Copy Markdown
Collaborator

Problem

Compiling an append of two relations with a different number of columns crashes prqlc with a panic instead of returning a compile error:

$ printf 'from a | select {x, y} | append (from b | select {x})\n' | prqlc compile
The application panicked (crashed).
Message:  not yet implemented
Location: prqlc/prqlc/src/semantic/resolver/types.rs:424

The column shape comes straight from the user's query, so this is a panic on user input — which CLAUDE.md explicitly forbids ("Never panic on user input or recoverable errors"). A second todo!() (the catch-all arm in type_intersection) is reachable the same way when the appended columns have incompatible types (e.g. int vs float).

Fix

type_intersection, type_intersection_of_tuples, and maybe_type_intersection now return Result<Ty>, and the three todo!() calls become proper Error returns. The append call site in infer_type_of_special_func attaches the input relation's span, so the error points at the offending pipeline:

Error:
   ╭─[ :1:10 ]
   │
 1 │ from a | select {x, y} | append (from b | select {x})
   │          ──────┬──────
   │                ╰──────── cannot combine relations with different numbers of columns
   │
   │ Help: `append` requires both tables to have matching columns
───╯

This is deliberately a minimal, design-neutral change: it does not decide what column-mismatched append should do (that's the open question in #4724, #5165, and #5349) — it only converts an unrecoverable panic into a graceful, recoverable error. Appends with matching columns are unaffected and still compile to UNION ALL.

Tests

Two regression tests in the resolver transforms module assert the rendered error for the mismatched-count and incompatible-type cases. Both would panic (and abort the test run) before this change.

Found during the nightly code-quality survey.

`append`-ing two relations with a different number of columns (or with
columns of incompatible types) crashed the compiler with a `todo!()` panic
in `type_intersection` rather than producing a compile error. Since the
column shape comes directly from user queries, this violated the
"never panic on user input" rule.

Thread a `Result` through `type_intersection` / `type_intersection_of_tuples`
/ `maybe_type_intersection` and replace the three `todo!()` calls with proper
`Error` returns. The `append` call site attaches the input relation's span so
the error points at the offending pipeline.

This does not change the eventual semantics of column-mismatched `append`
(tracked in #4724 / #5165 / #5349) — it only converts the panic into a
graceful, recoverable error.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant