diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 9e3e3c5ac4..7bb67b05ab 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -534,7 +534,7 @@ examine this information is to execute queries such as: -SELECT relname, age(relfrozenxid) FROM pg_class WHERE relkind = 'r'; +SELECT relname, age(relfrozenxid) FROM pg_class WHERE relkind IN ('r', 'm'); SELECT datname, age(datfrozenxid) FROM pg_database; diff --git a/src/backend/access/heap/tuptoaster.c b/src/backend/access/heap/tuptoaster.c index c76dc24260..6728469499 100644 --- a/src/backend/access/heap/tuptoaster.c +++ b/src/backend/access/heap/tuptoaster.c @@ -512,8 +512,8 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup, bool toast_delold[MaxHeapAttributeNumber]; /* - * We should only ever be called for tuples of plain relations --- - * recursing on a toast rel is bad news. + * We should only ever be called for tuples of plain relations or + * materialized views --- recursing on a toast rel is bad news. */ Assert(rel->rd_rel->relkind == RELKIND_RELATION || rel->rd_rel->relkind == RELKIND_MATVIEW); diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index e0dcf05687..97bc93ccd6 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -761,7 +761,6 @@ objectsInSchemaToOids(GrantObjectType objtype, List *nspnames) switch (objtype) { case ACL_OBJECT_RELATION: - /* Process regular tables, views and foreign tables */ objs = getRelationsInNamespace(namespaceId, RELKIND_RELATION); objects = list_concat(objects, objs); objs = getRelationsInNamespace(namespaceId, RELKIND_VIEW); diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index f1cdef9e13..64ca3121b3 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -1152,9 +1152,8 @@ heap_create_with_catalog(const char *relname, /* * Decide whether to create an array type over the relation's rowtype. We * do not create any array types for system catalogs (ie, those made - * during initdb). We create array types for regular relations, views, - * composite types and foreign tables ... but not, eg, for toast tables or - * sequences. + * during initdb). We do not create them where the use of a relation as + * such is an implementation detail: toast tables, sequences and indexes. */ if (IsUnderPostmaster && (relkind == RELKIND_RELATION || relkind == RELKIND_VIEW || diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c index 8baf017380..5ecc92afac 100644 --- a/src/backend/commands/comment.c +++ b/src/backend/commands/comment.c @@ -98,7 +98,7 @@ CommentObject(CommentStmt *stmt) relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is not a table, view, composite type, or foreign table", + errmsg("\"%s\" is not a table, view, materialized view, composite type, or foreign table", RelationGetRelationName(relation)))); break; default: diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 9d9745e714..ec8f248eea 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -372,7 +372,7 @@ DefineIndex(IndexStmt *stmt, else ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is not a table", + errmsg("\"%s\" is not a table or materialized view", RelationGetRelationName(rel)))); } @@ -1834,8 +1834,8 @@ ReindexDatabase(const char *databaseName, bool do_system, bool do_user) /* * Scan pg_class to build a list of the relations we need to reindex. * - * We only consider plain relations here (toast rels will be processed - * indirectly by reindex_relation). + * We only consider plain relations and materialized views here (toast + * rels will be processed indirectly by reindex_relation). */ relationRelation = heap_open(RelationRelationId, AccessShareLock); scan = heap_beginscan_catalog(relationRelation, 0, NULL); diff --git a/src/backend/commands/seclabel.c b/src/backend/commands/seclabel.c index 7466e66465..eaf0d0daba 100644 --- a/src/backend/commands/seclabel.c +++ b/src/backend/commands/seclabel.c @@ -111,7 +111,7 @@ ExecSecLabelStmt(SecLabelStmt *stmt) relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is not a table, view, composite type, or foreign table", + errmsg("\"%s\" is not a table, view, materialized view, composite type, or foreign table", RelationGetRelationName(relation)))); break; default: diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 6708725d69..f56ef28e22 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -10696,7 +10696,7 @@ RangeVarCallbackForAlterRelation(const RangeVar *rv, Oid relid, Oid oldrelid, relkind != RELKIND_FOREIGN_TABLE) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is not a table, view, sequence, or foreign table", + errmsg("\"%s\" is not a table, view, materialized view, sequence, or foreign table", rv->relname))); ReleaseSysCache(tuple); diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 031433d4bb..d4a14cabff 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -2820,7 +2820,14 @@ get_rels_with_domain(Oid domainOid, LOCKMODE lockmode) NULL, format_type_be(domainOid)); - /* Otherwise we can ignore views, composite types, etc */ + /* + * Otherwise, we can ignore relations except those with both + * storage and user-chosen column types. + * + * XXX If an index-only scan could satisfy "col::some_domain" from + * a suitable expression index, this should also check expression + * index columns. + */ if (rel->rd_rel->relkind != RELKIND_RELATION && rel->rd_rel->relkind != RELKIND_MATVIEW) { diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 68fc9c6bae..2f2c6acb96 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -742,8 +742,8 @@ vac_update_datfrozenxid(void) Form_pg_class classForm = (Form_pg_class) GETSTRUCT(classTup); /* - * Only consider heap and TOAST tables (anything else should have - * InvalidTransactionId in relfrozenxid anyway.) + * Only consider relations able to hold unfrozen XIDs (anything else + * should have InvalidTransactionId in relfrozenxid anyway.) */ if (classForm->relkind != RELKIND_RELATION && classForm->relkind != RELKIND_MATVIEW && @@ -1044,7 +1044,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound) } /* - * Check that it's a vacuumable table; we used to do this in + * Check that it's a vacuumable relation; we used to do this in * get_rel_oids() but seems safer to check after we've locked the * relation. */ diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index 40e3717b75..ac662549e9 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -683,7 +683,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is not a table, view, composite type, or foreign table", + errmsg("\"%s\" is not a table, view, materialized view, composite type, or foreign table", RelationGetRelationName(relation)))); cancel_parser_errposition_callback(&pcbstate); diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c index 92396b39bd..0e9f515a09 100644 --- a/src/backend/rewrite/rewriteDefine.c +++ b/src/backend/rewrite/rewriteDefine.c @@ -258,6 +258,8 @@ DefineQueryRewrite(char *rulename, /* * Verify relation is of a type that rules can sensibly be applied to. + * Internal callers can target materialized views, but transformRuleStmt() + * blocks them for users. Don't mention them in the error message. */ if (event_relation->rd_rel->relkind != RELKIND_RELATION && event_relation->rd_rel->relkind != RELKIND_MATVIEW && diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c index 58322dc59a..247ad92ab2 100644 --- a/src/bin/pg_dump/common.c +++ b/src/bin/pg_dump/common.c @@ -269,7 +269,7 @@ flagInhTables(TableInfo *tblinfo, int numTables, for (i = 0; i < numTables; i++) { - /* Sequences and views never have parents */ + /* Some kinds never have parents */ if (tblinfo[i].relkind == RELKIND_SEQUENCE || tblinfo[i].relkind == RELKIND_VIEW || tblinfo[i].relkind == RELKIND_MATVIEW) @@ -315,7 +315,7 @@ flagInhAttrs(TableInfo *tblinfo, int numTables) int numParents; TableInfo **parents; - /* Sequences and views never have parents */ + /* Some kinds never have parents */ if (tbinfo->relkind == RELKIND_SEQUENCE || tbinfo->relkind == RELKIND_VIEW || tbinfo->relkind == RELKIND_MATVIEW) diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c index 4cd59bc3ea..c94d0d8075 100644 --- a/src/pl/tcl/pltcl.c +++ b/src/pl/tcl/pltcl.c @@ -504,7 +504,7 @@ pltcl_init_load_unknown(Tcl_Interp *interp) AccessShareLock, true); if (pmrel == NULL) return; - /* must be table or view, else ignore */ + /* sanity-check the relation kind */ if (!(pmrel->rd_rel->relkind == RELKIND_RELATION || pmrel->rd_rel->relkind == RELKIND_MATVIEW || pmrel->rd_rel->relkind == RELKIND_VIEW)) diff --git a/src/test/regress/expected/create_table_like.out b/src/test/regress/expected/create_table_like.out index 3c6b585e60..5f29b3978d 100644 --- a/src/test/regress/expected/create_table_like.out +++ b/src/test/regress/expected/create_table_like.out @@ -221,7 +221,7 @@ NOTICE: drop cascades to table inhe CREATE TABLE ctlt4 (a int, b text); CREATE SEQUENCE ctlseq1; CREATE TABLE ctlt10 (LIKE ctlseq1); -- fail -ERROR: "ctlseq1" is not a table, view, composite type, or foreign table +ERROR: "ctlseq1" is not a table, view, materialized view, composite type, or foreign table LINE 1: CREATE TABLE ctlt10 (LIKE ctlseq1); ^ CREATE VIEW ctlv1 AS SELECT * FROM ctlt4;