Repository navigation
Quote non-token storage option values for materialized views - #130
Open
talmacschen-arch wants to merge 1 commit into
Open
talmacschen-arch wants to merge 1 commit into
talmacschen-arch wants to merge 1 commit into
Conversation
GetAllViews builds a materialized view's WITH clause by joining
pg_class.reloptions ("name=value" elements) with ", ", the same way
GetTableStorage did for tables. A value that is not a plain token (lowercase
letters, digits, '_' or '.') does not survive that round trip. The prime case
is a PAX materialized view, whose minmax_columns/cluster_columns carry a
comma-separated column list:
CREATE MATERIALIZED VIEW ... USING pax WITH (minmax_columns=a,b) AS ...
ERROR: unrecognized parameter "b" (SQLSTATE 22023)
The matview is then never created, and its ALTER ... OWNER cascades into
"relation does not exist", so the matview is lost on restore. Uppercase or
spaced option values break the same way.
Render reloptions through a shared helper (relOptionsWithClause) used by both
the GPDB6 and GPDB7+/Cloudberry matview queries. It single-quotes any value
that is not a simple token (not matching ^[a-z0-9_.]+$), which covers the
comma, uppercase and space cases, and leaves plain-token values
(fillfactor=50, autovacuum_enabled=false, ...) byte-for-byte unchanged. It
preserves the original " WITH (...)" vs "" (no reloptions) semantics via an
explicit NULL check, and WITH ORDINALITY keeps the option order.
Verified end to end on a live Cloudberry 2.1.0 cluster: a PAX matview with
multi-column minmax_columns/cluster_columns now backs up as
`WITH (minmax_columns='a,b', cluster_columns='a,b', ...)` and restores cleanly,
while a plain heap matview with no reloptions is emitted without a WITH clause.
Add an integration test asserting the quoted WITH clause recreates the matview
verbatim.
This is the materialized-view follow-up noted in the base-table fix (apache#127);
the two share the same root cause but touch different queries.
This was referenced Oct 31, 2026
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.
Problem
GetAllViewsbuilds a materialized view'sWITHclause by joiningpg_class.reloptionsverbatim with,, the same wayGetTableStoragedid for tables (fixed in #127). A reloption value that is not a plain token does not survive the round trip. The prime case is a PAX materialized view, whoseminmax_columns/cluster_columnscarry a comma-separated column list:The matview is never created and its
ALTER ... OWNERthen cascades intorelation does not exist, so the materialized view is lost on restore. Uppercase or spaced option values break the same way.This is the materialized-view follow-up noted in #127 — same root cause, different query.
Fix
Render reloptions through a shared helper
relOptionsWithClause, used by both the GPDB6 and GPDB7+/Cloudberry matview queries. It single-quotes any value that is not a simple token (not matching^[a-z0-9_.]+$), covering the comma / uppercase / space cases, and:fillfactor=50,autovacuum_enabled=false, ...) byte-for-byte unchanged;' WITH (...)'vs''(no reloptions) behaviour via an explicitNULLcheck (so a matview without reloptions is not emitted asWITH ());WITH ORDINALITY.Matview data handling is unchanged: matviews are still emitted
WITH NO DATA; only the definition is restored (a manualREFRESH MATERIALIZED VIEWrepopulates it).Verification
End to end on a live Apache Cloudberry 2.1.0 (SynxDB4 4.5.4-3) cluster with a rebuilt
gpbackup/gprestore:gpbackup2.2.0minmax_columns='a,b', cluster_columns='a,b'WITH (minmax_columns=a,b)→unrecognized parameter "b", matview lostWITH (minmax_columns='a,b', cluster_columns='a,b', ...), restores cleanlyWITHclause (noWITH ())go build ./backup/...and the integration test package compile; added an integration test asserting the quotedWITHclause recreates the matview verbatim (CBDB-gated, with a round-tripCREATE MATERIALIZED VIEW).