Skip to content

Conversation

@teskje
Copy link
Contributor

@teskje teskje commented Jan 8, 2026

This PR adds much more detail to the error message users see when they try to create a replacement materialized view with a schema different from the target. Some of the mismatches (nullability, keys) can be surprising, so good error reporting is essential to avoid user confusion.

Previously users would see the error:

ERROR: incompatible schema

Now they get detailed information about the mismatch:

ERROR: replacement schema differs from target schema
DETAIL: column at position 1: name mismatch (target: "a", replacement: "c")

Motivation

  • This PR adds a known-desirable feature.

Part of https://github.com/MaterializeInc/database-issues/issues/9903

Tips for reviewer

Checklist

  • This PR has adequate test coverage / QA involvement has been duly considered. (trigger-ci for additional test/nightly runs)
  • This PR has an associated up-to-date design doc, is a design doc (template), or is sufficiently small to not require a design.
  • If this PR evolves an existing $T ⇔ Proto$T mapping (possibly in a backwards-incompatible way), then it is tagged with a T-proto label.
  • If this PR will require changes to cloud orchestration or tests, there is a companion cloud PR to account for those changes that is tagged with the release-blocker label (example).
  • If this PR includes major user-facing behavior changes, I have pinged the relevant PM to schedule a changelog post.

@teskje teskje marked this pull request as ready for review January 8, 2026 17:15
@teskje teskje requested review from a team as code owners January 8, 2026 17:15
@teskje teskje requested a review from ggevay January 8, 2026 17:15
Copy link
Contributor

@bkirwi bkirwi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall +1 from me! Commented on a couple of things to look at before merging.

/// Keys of the left relation.
pub left: Vec<Vec<ColumnName>>,
/// Keys of the right relation.
pub right: Vec<Vec<ColumnName>>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the order of keys meaningful? (If we have the same keys in different orders, would this be unnecessarily strict?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably not, at least not in the rich diff. Might not even be meaningful in the RelationDesc type. We use the first element as the "default key" for default indexes, but I don't think we really care which key we use for that. I'm also not sure under what conditions we'd end up with multiple keys.

Copy link
Contributor Author

@teskje teskje Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made these BTreeSets in the diff type but didn't touch RelationDesc itself, as that seems like it would require a larger refactor.

I also realized that testing for schema changes using PartialEq is not correct because it wouldn't treat two schemas with the same keys in different orders as not equal. So in the replacement MV sequencing I'm now always computing the diff and then checking if that is empty.

let right_arity = other.arity();
let common_arity = std::cmp::min(left_arity, right_arity);

for idx in 0..common_arity {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think RelationDesc actually guarantees that these are dense... if eg. drop_column has been called.

It's probably accurate for now, though, since nobody currently calls those methods! But ideally we'd either leave a comment / warning here or iterate over the indices that are actually present.

Copy link
Contributor Author

@teskje teskje Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, interesting! I can't quite wrap my head around what it means to have holes in the column indexes. There can't be any holes in Rows right?

For example, suppose I have a RelationDesc with three columns (a int, b int, c int), but b has been dropped. How do rows in that relation look like at the SQL level? (1, NULL, 3)? (1, 3)? If it's the latter, does that mean that column indexes don't directly correspond to positions in the output and the error/diff reporting has to take that into account?

This commit adds much more detail to the error message users see when
they try to create a replacement materialized view with a schema
different from the target. Some of the mismatches (nullability, keys)
can be surprising, so good error reporting is essential to avoid user
confusion.

Previously users would see the error:
```
ERROR: incompatible schema
```

Now they get detailed information about the mismatch:
```
ERROR: replacement schema differs from target schema
DETAIL: column at position 1: name mismatch (target: "a", replacement: "c")
```
@teskje teskje force-pushed the replacement-mv-schema-mismatch-error branch from a8590e3 to b13aa38 Compare January 9, 2026 11:19
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.

2 participants