1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-05 23:56:58 +03:00

Some RELKIND macro refactoring

Add more macros to group some RELKIND_* macros:

- RELKIND_HAS_PARTITIONS()
- RELKIND_HAS_TABLESPACE()
- RELKIND_HAS_TABLE_AM()

Reviewed-by: Michael Paquier <michael@paquier.xyz>
Reviewed-by: Alvaro Herrera <alvherre@alvh.no-ip.org>
Discussion: https://www.postgresql.org/message-id/flat/a574c8f1-9c84-93ad-a9e5-65233d6fc00f%40enterprisedb.com
This commit is contained in:
Peter Eisentraut 2021-12-03 13:38:26 +01:00
parent 49422ad0cc
commit 37b2764593
14 changed files with 173 additions and 254 deletions

View File

@ -306,9 +306,7 @@ verify_heapam(PG_FUNCTION_ARGS)
/* /*
* Check that a relation's relkind and access method are both supported. * Check that a relation's relkind and access method are both supported.
*/ */
if (ctx.rel->rd_rel->relkind != RELKIND_RELATION && if (!RELKIND_HAS_TABLE_AM(ctx.rel->rd_rel->relkind) &&
ctx.rel->rd_rel->relkind != RELKIND_MATVIEW &&
ctx.rel->rd_rel->relkind != RELKIND_TOASTVALUE &&
ctx.rel->rd_rel->relkind != RELKIND_SEQUENCE) ctx.rel->rd_rel->relkind != RELKIND_SEQUENCE)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE), (errcode(ERRCODE_WRONG_OBJECT_TYPE),

View File

@ -103,9 +103,7 @@ heap_force_common(FunctionCallInfo fcinfo, HeapTupleForceOption heap_force_opt)
/* /*
* Check target relation. * Check target relation.
*/ */
if (rel->rd_rel->relkind != RELKIND_RELATION && if (!RELKIND_HAS_TABLE_AM(rel->rd_rel->relkind))
rel->rd_rel->relkind != RELKIND_MATVIEW &&
rel->rd_rel->relkind != RELKIND_TOASTVALUE)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE), (errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("cannot operate on relation \"%s\"", errmsg("cannot operate on relation \"%s\"",

View File

@ -776,9 +776,7 @@ tuple_all_visible(HeapTuple tup, TransactionId OldestXmin, Buffer buffer)
static void static void
check_relation_relkind(Relation rel) check_relation_relkind(Relation rel)
{ {
if (rel->rd_rel->relkind != RELKIND_RELATION && if (!RELKIND_HAS_TABLE_AM(rel->rd_rel->relkind))
rel->rd_rel->relkind != RELKIND_MATVIEW &&
rel->rd_rel->relkind != RELKIND_TOASTVALUE)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE), (errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("relation \"%s\" is of wrong relation kind", errmsg("relation \"%s\" is of wrong relation kind",

View File

@ -252,14 +252,13 @@ pgstat_relation(Relation rel, FunctionCallInfo fcinfo)
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot access temporary tables of other sessions"))); errmsg("cannot access temporary tables of other sessions")));
switch (rel->rd_rel->relkind) if (RELKIND_HAS_TABLE_AM(rel->rd_rel->relkind) ||
rel->rd_rel->relkind == RELKIND_SEQUENCE)
{ {
case RELKIND_RELATION:
case RELKIND_MATVIEW:
case RELKIND_TOASTVALUE:
case RELKIND_SEQUENCE:
return pgstat_heap(rel, fcinfo); return pgstat_heap(rel, fcinfo);
case RELKIND_INDEX: }
else if (rel->rd_rel->relkind == RELKIND_INDEX)
{
switch (rel->rd_rel->relam) switch (rel->rd_rel->relam)
{ {
case BTREE_AM_OID: case BTREE_AM_OID:
@ -288,9 +287,9 @@ pgstat_relation(Relation rel, FunctionCallInfo fcinfo)
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("index \"%s\" (%s) is not supported", errmsg("index \"%s\" (%s) is not supported",
RelationGetRelationName(rel), err))); RelationGetRelationName(rel), err)));
break; }
else
default: {
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot get tuple-level statistics for relation \"%s\"", errmsg("cannot get tuple-level statistics for relation \"%s\"",

View File

@ -336,35 +336,12 @@ heap_create(const char *relname,
*relfrozenxid = InvalidTransactionId; *relfrozenxid = InvalidTransactionId;
*relminmxid = InvalidMultiXactId; *relminmxid = InvalidMultiXactId;
/* Handle reltablespace for specific relkinds. */ /*
switch (relkind) * Force reltablespace to zero if the relation kind does not support
{ * tablespaces. This is mainly just for cleanliness' sake.
case RELKIND_VIEW: */
case RELKIND_COMPOSITE_TYPE: if (!RELKIND_HAS_TABLESPACE(relkind))
case RELKIND_FOREIGN_TABLE: reltablespace = InvalidOid;
/*
* Force reltablespace to zero if the relation has no physical
* storage. This is mainly just for cleanliness' sake.
*
* Partitioned tables and indexes don't have physical storage
* either, but we want to keep their tablespace settings so that
* their children can inherit it.
*/
reltablespace = InvalidOid;
break;
case RELKIND_SEQUENCE:
/*
* Force reltablespace to zero for sequences, since we don't
* support moving them around into different tablespaces.
*/
reltablespace = InvalidOid;
break;
default:
break;
}
/* /*
* Decide whether to create storage. If caller passed a valid relfilenode, * Decide whether to create storage. If caller passed a valid relfilenode,
@ -409,35 +386,20 @@ heap_create(const char *relname,
/* /*
* Have the storage manager create the relation's disk file, if needed. * Have the storage manager create the relation's disk file, if needed.
* *
* For relations the callback creates both the main and the init fork, for * For tables, the AM callback creates both the main and the init fork.
* indexes only the main fork is created. The other forks will be created * For others, only the main fork is created; the other forks will be
* on demand. * created on demand.
*/ */
if (create_storage) if (create_storage)
{ {
switch (rel->rd_rel->relkind) if (RELKIND_HAS_TABLE_AM(rel->rd_rel->relkind))
{ table_relation_set_new_filenode(rel, &rel->rd_node,
case RELKIND_VIEW: relpersistence,
case RELKIND_COMPOSITE_TYPE: relfrozenxid, relminmxid);
case RELKIND_FOREIGN_TABLE: else if (RELKIND_HAS_STORAGE(rel->rd_rel->relkind))
case RELKIND_PARTITIONED_TABLE: RelationCreateStorage(rel->rd_node, relpersistence);
case RELKIND_PARTITIONED_INDEX: else
Assert(false); Assert(false);
break;
case RELKIND_INDEX:
case RELKIND_SEQUENCE:
RelationCreateStorage(rel->rd_node, relpersistence);
break;
case RELKIND_RELATION:
case RELKIND_TOASTVALUE:
case RELKIND_MATVIEW:
table_relation_set_new_filenode(rel, &rel->rd_node,
relpersistence,
relfrozenxid, relminmxid);
break;
}
} }
/* /*
@ -1015,29 +977,16 @@ AddNewRelationTuple(Relation pg_class_desc,
*/ */
new_rel_reltup = new_rel_desc->rd_rel; new_rel_reltup = new_rel_desc->rd_rel;
switch (relkind) /* The relation is empty */
new_rel_reltup->relpages = 0;
new_rel_reltup->reltuples = -1;
new_rel_reltup->relallvisible = 0;
/* Sequences always have a known size */
if (relkind == RELKIND_SEQUENCE)
{ {
case RELKIND_RELATION: new_rel_reltup->relpages = 1;
case RELKIND_MATVIEW: new_rel_reltup->reltuples = 1;
case RELKIND_INDEX:
case RELKIND_TOASTVALUE:
/* The relation is real, but as yet empty */
new_rel_reltup->relpages = 0;
new_rel_reltup->reltuples = -1;
new_rel_reltup->relallvisible = 0;
break;
case RELKIND_SEQUENCE:
/* Sequences always have a known size */
new_rel_reltup->relpages = 1;
new_rel_reltup->reltuples = 1;
new_rel_reltup->relallvisible = 0;
break;
default:
/* Views, etc, have no disk storage */
new_rel_reltup->relpages = 0;
new_rel_reltup->reltuples = -1;
new_rel_reltup->relallvisible = 0;
break;
} }
new_rel_reltup->relfrozenxid = relfrozenxid; new_rel_reltup->relfrozenxid = relfrozenxid;
@ -1235,29 +1184,37 @@ heap_create_with_catalog(const char *relname,
if (!OidIsValid(relid)) if (!OidIsValid(relid))
{ {
/* Use binary-upgrade override for pg_class.oid/relfilenode? */ /* Use binary-upgrade override for pg_class.oid/relfilenode? */
if (IsBinaryUpgrade && if (IsBinaryUpgrade)
(relkind == RELKIND_RELATION || relkind == RELKIND_SEQUENCE ||
relkind == RELKIND_VIEW || relkind == RELKIND_MATVIEW ||
relkind == RELKIND_COMPOSITE_TYPE || relkind == RELKIND_FOREIGN_TABLE ||
relkind == RELKIND_PARTITIONED_TABLE))
{ {
if (!OidIsValid(binary_upgrade_next_heap_pg_class_oid)) /*
ereport(ERROR, * Indexes are not supported here; they use
(errcode(ERRCODE_INVALID_PARAMETER_VALUE), * binary_upgrade_next_index_pg_class_oid.
errmsg("pg_class heap OID value not set when in binary upgrade mode"))); */
Assert(relkind != RELKIND_INDEX);
Assert(relkind != RELKIND_PARTITIONED_INDEX);
relid = binary_upgrade_next_heap_pg_class_oid; if (relkind == RELKIND_TOASTVALUE)
binary_upgrade_next_heap_pg_class_oid = InvalidOid; {
/* There might be no TOAST table, so we have to test for it. */
if (OidIsValid(binary_upgrade_next_toast_pg_class_oid))
{
relid = binary_upgrade_next_toast_pg_class_oid;
binary_upgrade_next_toast_pg_class_oid = InvalidOid;
}
}
else
{
if (!OidIsValid(binary_upgrade_next_heap_pg_class_oid))
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("pg_class heap OID value not set when in binary upgrade mode")));
relid = binary_upgrade_next_heap_pg_class_oid;
binary_upgrade_next_heap_pg_class_oid = InvalidOid;
}
} }
/* There might be no TOAST table, so we have to test for it. */
else if (IsBinaryUpgrade && if (!OidIsValid(relid))
OidIsValid(binary_upgrade_next_toast_pg_class_oid) &&
relkind == RELKIND_TOASTVALUE)
{
relid = binary_upgrade_next_toast_pg_class_oid;
binary_upgrade_next_toast_pg_class_oid = InvalidOid;
}
else
relid = GetNewRelFileNode(reltablespace, pg_class_desc, relid = GetNewRelFileNode(reltablespace, pg_class_desc,
relpersistence); relpersistence);
} }
@ -1468,13 +1425,12 @@ heap_create_with_catalog(const char *relname,
/* /*
* Make a dependency link to force the relation to be deleted if its * Make a dependency link to force the relation to be deleted if its
* access method is. Do this only for relation and materialized views. * access method is.
* *
* No need to add an explicit dependency for the toast table, as the * No need to add an explicit dependency for the toast table, as the
* main table depends on it. * main table depends on it.
*/ */
if (relkind == RELKIND_RELATION || if (RELKIND_HAS_TABLE_AM(relkind) && relkind != RELKIND_TOASTVALUE)
relkind == RELKIND_MATVIEW)
{ {
ObjectAddressSet(referenced, AccessMethodRelationId, accessmtd); ObjectAddressSet(referenced, AccessMethodRelationId, accessmtd);
add_exact_object_address(&referenced, addrs); add_exact_object_address(&referenced, addrs);

View File

@ -2293,7 +2293,7 @@ index_drop(Oid indexId, bool concurrent, bool concurrent_lock_mode)
/* /*
* Schedule physical removal of the files (if any) * Schedule physical removal of the files (if any)
*/ */
if (userIndexRelation->rd_rel->relkind != RELKIND_PARTITIONED_INDEX) if (RELKIND_HAS_STORAGE(userIndexRelation->rd_rel->relkind))
RelationDropStorage(userIndexRelation); RelationDropStorage(userIndexRelation);
/* /*

View File

@ -2954,8 +2954,7 @@ reindex_error_callback(void *arg)
{ {
ReindexErrorInfo *errinfo = (ReindexErrorInfo *) arg; ReindexErrorInfo *errinfo = (ReindexErrorInfo *) arg;
Assert(errinfo->relkind == RELKIND_PARTITIONED_INDEX || Assert(RELKIND_HAS_PARTITIONS(errinfo->relkind));
errinfo->relkind == RELKIND_PARTITIONED_TABLE);
if (errinfo->relkind == RELKIND_PARTITIONED_TABLE) if (errinfo->relkind == RELKIND_PARTITIONED_TABLE)
errcontext("while reindexing partitioned table \"%s.%s\"", errcontext("while reindexing partitioned table \"%s.%s\"",
@ -2984,8 +2983,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
ErrorContextCallback errcallback; ErrorContextCallback errcallback;
ReindexErrorInfo errinfo; ReindexErrorInfo errinfo;
Assert(relkind == RELKIND_PARTITIONED_INDEX || Assert(RELKIND_HAS_PARTITIONS(relkind));
relkind == RELKIND_PARTITIONED_TABLE);
/* /*
* Check if this runs in a transaction block, with an error callback to * Check if this runs in a transaction block, with an error callback to
@ -3118,8 +3116,7 @@ ReindexMultipleInternal(List *relids, ReindexParams *params)
* Partitioned tables and indexes can never be processed directly, and * Partitioned tables and indexes can never be processed directly, and
* a list of their leaves should be built first. * a list of their leaves should be built first.
*/ */
Assert(relkind != RELKIND_PARTITIONED_INDEX && Assert(!RELKIND_HAS_PARTITIONS(relkind));
relkind != RELKIND_PARTITIONED_TABLE);
if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 && if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
relpersistence != RELPERSISTENCE_TEMP) relpersistence != RELPERSISTENCE_TEMP)

View File

@ -916,9 +916,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
errmsg("specifying a table access method is not supported on a partitioned table"))); errmsg("specifying a table access method is not supported on a partitioned table")));
} }
else if (relkind == RELKIND_RELATION || else if (RELKIND_HAS_TABLE_AM(relkind))
relkind == RELKIND_TOASTVALUE ||
relkind == RELKIND_MATVIEW)
accessMethod = default_table_access_method; accessMethod = default_table_access_method;
/* look up the access method, verify it is for a table */ /* look up the access method, verify it is for a table */
@ -13995,9 +13993,7 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode)
} }
else else
{ {
Assert(rel->rd_rel->relkind == RELKIND_RELATION || Assert(RELKIND_HAS_TABLE_AM(rel->rd_rel->relkind));
rel->rd_rel->relkind == RELKIND_MATVIEW ||
rel->rd_rel->relkind == RELKIND_TOASTVALUE);
table_relation_copy_data(rel, &newrnode); table_relation_copy_data(rel, &newrnode);
} }

View File

@ -965,17 +965,13 @@ estimate_rel_size(Relation rel, int32 *attr_widths,
BlockNumber relallvisible; BlockNumber relallvisible;
double density; double density;
switch (rel->rd_rel->relkind) if (RELKIND_HAS_TABLE_AM(rel->rd_rel->relkind))
{ {
case RELKIND_RELATION:
case RELKIND_MATVIEW:
case RELKIND_TOASTVALUE:
table_relation_estimate_size(rel, attr_widths, pages, tuples, table_relation_estimate_size(rel, attr_widths, pages, tuples,
allvisfrac); allvisfrac);
break; }
else if (rel->rd_rel->relkind == RELKIND_INDEX)
case RELKIND_INDEX: {
/* /*
* XXX: It'd probably be good to move this into a callback, * XXX: It'd probably be good to move this into a callback,
* individual index types e.g. know if they have a metapage. * individual index types e.g. know if they have a metapage.
@ -991,7 +987,7 @@ estimate_rel_size(Relation rel, int32 *attr_widths,
{ {
*tuples = 0; *tuples = 0;
*allvisfrac = 0; *allvisfrac = 0;
break; return;
} }
/* coerce values in pg_class to more desirable types */ /* coerce values in pg_class to more desirable types */
@ -1055,27 +1051,18 @@ estimate_rel_size(Relation rel, int32 *attr_widths,
*allvisfrac = 1; *allvisfrac = 1;
else else
*allvisfrac = (double) relallvisible / curpages; *allvisfrac = (double) relallvisible / curpages;
break; }
else
case RELKIND_SEQUENCE: {
/* Sequences always have a known size */ /*
*pages = 1; * Just use whatever's in pg_class. This covers foreign tables,
*tuples = 1; * sequences, and also relkinds without storage (shouldn't get
*allvisfrac = 0; * here?); see initializations in AddNewRelationTuple(). Note
break; * that FDW must cope if reltuples is -1!
case RELKIND_FOREIGN_TABLE: */
/* Just use whatever's in pg_class */
/* Note that FDW must cope if reltuples is -1! */
*pages = rel->rd_rel->relpages; *pages = rel->rd_rel->relpages;
*tuples = rel->rd_rel->reltuples; *tuples = rel->rd_rel->reltuples;
*allvisfrac = 0; *allvisfrac = 0;
break;
default:
/* else it has no disk storage; probably shouldn't get here? */
*pages = 0;
*tuples = 0;
*allvisfrac = 0;
break;
} }
} }

View File

@ -2934,37 +2934,26 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln)
BlockNumber BlockNumber
RelationGetNumberOfBlocksInFork(Relation relation, ForkNumber forkNum) RelationGetNumberOfBlocksInFork(Relation relation, ForkNumber forkNum)
{ {
switch (relation->rd_rel->relkind) if (RELKIND_HAS_TABLE_AM(relation->rd_rel->relkind))
{ {
case RELKIND_SEQUENCE: /*
case RELKIND_INDEX: * Not every table AM uses BLCKSZ wide fixed size blocks.
return smgrnblocks(RelationGetSmgr(relation), forkNum); * Therefore tableam returns the size in bytes - but for the
* purpose of this routine, we want the number of blocks.
* Therefore divide, rounding up.
*/
uint64 szbytes;
case RELKIND_RELATION: szbytes = table_relation_size(relation, forkNum);
case RELKIND_TOASTVALUE:
case RELKIND_MATVIEW:
{
/*
* Not every table AM uses BLCKSZ wide fixed size blocks.
* Therefore tableam returns the size in bytes - but for the
* purpose of this routine, we want the number of blocks.
* Therefore divide, rounding up.
*/
uint64 szbytes;
szbytes = table_relation_size(relation, forkNum); return (szbytes + (BLCKSZ - 1)) / BLCKSZ;
return (szbytes + (BLCKSZ - 1)) / BLCKSZ;
}
case RELKIND_VIEW:
case RELKIND_COMPOSITE_TYPE:
case RELKIND_FOREIGN_TABLE:
case RELKIND_PARTITIONED_INDEX:
case RELKIND_PARTITIONED_TABLE:
default:
Assert(false);
break;
} }
else if (RELKIND_HAS_STORAGE(relation->rd_rel->relkind))
{
return smgrnblocks(RelationGetSmgr(relation), forkNum);
}
else
Assert(false);
return 0; /* keep compiler quiet */ return 0; /* keep compiler quiet */
} }

View File

@ -45,9 +45,7 @@ check_rel_can_be_partition(Oid relid)
relispartition = get_rel_relispartition(relid); relispartition = get_rel_relispartition(relid);
/* Only allow relation types that can appear in partition trees. */ /* Only allow relation types that can appear in partition trees. */
if (!relispartition && if (!relispartition && !RELKIND_HAS_PARTITIONS(relkind))
relkind != RELKIND_PARTITIONED_TABLE &&
relkind != RELKIND_PARTITIONED_INDEX)
return false; return false;
return true; return true;
@ -143,8 +141,7 @@ pg_partition_tree(PG_FUNCTION_ARGS)
nulls[1] = true; nulls[1] = true;
/* isleaf */ /* isleaf */
values[2] = BoolGetDatum(relkind != RELKIND_PARTITIONED_TABLE && values[2] = BoolGetDatum(!RELKIND_HAS_PARTITIONS(relkind));
relkind != RELKIND_PARTITIONED_INDEX);
/* level */ /* level */
if (relid != rootrelid) if (relid != rootrelid)

View File

@ -1203,30 +1203,14 @@ retry:
/* /*
* initialize access method information * initialize access method information
*/ */
switch (relation->rd_rel->relkind) if (relation->rd_rel->relkind == RELKIND_INDEX ||
{ relation->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
case RELKIND_INDEX: RelationInitIndexAccessInfo(relation);
case RELKIND_PARTITIONED_INDEX: else if (RELKIND_HAS_TABLE_AM(relation->rd_rel->relkind) ||
Assert(relation->rd_rel->relam != InvalidOid); relation->rd_rel->relkind == RELKIND_SEQUENCE)
RelationInitIndexAccessInfo(relation); RelationInitTableAccessMethod(relation);
break; else
case RELKIND_RELATION: Assert(relation->rd_rel->relam == InvalidOid);
case RELKIND_TOASTVALUE:
case RELKIND_MATVIEW:
Assert(relation->rd_rel->relam != InvalidOid);
RelationInitTableAccessMethod(relation);
break;
case RELKIND_SEQUENCE:
Assert(relation->rd_rel->relam == InvalidOid);
RelationInitTableAccessMethod(relation);
break;
case RELKIND_VIEW:
case RELKIND_COMPOSITE_TYPE:
case RELKIND_FOREIGN_TABLE:
case RELKIND_PARTITIONED_TABLE:
Assert(relation->rd_rel->relam == InvalidOid);
break;
}
/* extract reloptions if any */ /* extract reloptions if any */
RelationParseRelOptions(relation, pg_class_tuple); RelationParseRelOptions(relation, pg_class_tuple);
@ -1444,6 +1428,7 @@ RelationInitIndexAccessInfo(Relation relation)
/* /*
* Look up the index's access method, save the OID of its handler function * Look up the index's access method, save the OID of its handler function
*/ */
Assert(relation->rd_rel->relam != InvalidOid);
tuple = SearchSysCache1(AMOID, ObjectIdGetDatum(relation->rd_rel->relam)); tuple = SearchSysCache1(AMOID, ObjectIdGetDatum(relation->rd_rel->relam));
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for access method %u", elog(ERROR, "cache lookup failed for access method %u",
@ -1803,6 +1788,7 @@ RelationInitTableAccessMethod(Relation relation)
* seem prudent to show that in the catalog. So just overwrite it * seem prudent to show that in the catalog. So just overwrite it
* here. * here.
*/ */
Assert(relation->rd_rel->relam == InvalidOid);
relation->rd_amhandler = F_HEAP_TABLEAM_HANDLER; relation->rd_amhandler = F_HEAP_TABLEAM_HANDLER;
} }
else if (IsCatalogRelation(relation)) else if (IsCatalogRelation(relation))
@ -3638,10 +3624,7 @@ RelationBuildLocalRelation(const char *relname,
*/ */
MemoryContextSwitchTo(oldcxt); MemoryContextSwitchTo(oldcxt);
if (relkind == RELKIND_RELATION || if (RELKIND_HAS_TABLE_AM(relkind) || relkind == RELKIND_SEQUENCE)
relkind == RELKIND_SEQUENCE ||
relkind == RELKIND_TOASTVALUE ||
relkind == RELKIND_MATVIEW)
RelationInitTableAccessMethod(rel); RelationInitTableAccessMethod(rel);
/* /*
@ -3730,32 +3713,25 @@ RelationSetNewRelfilenode(Relation relation, char persistence)
newrnode = relation->rd_node; newrnode = relation->rd_node;
newrnode.relNode = newrelfilenode; newrnode.relNode = newrelfilenode;
switch (relation->rd_rel->relkind) if (RELKIND_HAS_TABLE_AM(relation->rd_rel->relkind))
{ {
case RELKIND_INDEX: table_relation_set_new_filenode(relation, &newrnode,
case RELKIND_SEQUENCE: persistence,
{ &freezeXid, &minmulti);
/* handle these directly, at least for now */ }
SMgrRelation srel; else if (RELKIND_HAS_STORAGE(relation->rd_rel->relkind))
{
/* handle these directly, at least for now */
SMgrRelation srel;
srel = RelationCreateStorage(newrnode, persistence); srel = RelationCreateStorage(newrnode, persistence);
smgrclose(srel); smgrclose(srel);
} }
break; else
{
case RELKIND_RELATION: /* we shouldn't be called for anything else */
case RELKIND_TOASTVALUE: elog(ERROR, "relation \"%s\" does not have storage",
case RELKIND_MATVIEW: RelationGetRelationName(relation));
table_relation_set_new_filenode(relation, &newrnode,
persistence,
&freezeXid, &minmulti);
break;
default:
/* we shouldn't be called for anything else */
elog(ERROR, "relation \"%s\" does not have storage",
RelationGetRelationName(relation));
break;
} }
/* /*
@ -4207,10 +4183,7 @@ RelationCacheInitializePhase3(void)
/* Reload tableam data if needed */ /* Reload tableam data if needed */
if (relation->rd_tableam == NULL && if (relation->rd_tableam == NULL &&
(relation->rd_rel->relkind == RELKIND_RELATION || (RELKIND_HAS_TABLE_AM(relation->rd_rel->relkind) || relation->rd_rel->relkind == RELKIND_SEQUENCE))
relation->rd_rel->relkind == RELKIND_SEQUENCE ||
relation->rd_rel->relkind == RELKIND_TOASTVALUE ||
relation->rd_rel->relkind == RELKIND_MATVIEW))
{ {
RelationInitTableAccessMethod(relation); RelationInitTableAccessMethod(relation);
Assert(relation->rd_tableam != NULL); Assert(relation->rd_tableam != NULL);
@ -6127,10 +6100,7 @@ load_relcache_init_file(bool shared)
nailed_rels++; nailed_rels++;
/* Load table AM data */ /* Load table AM data */
if (rel->rd_rel->relkind == RELKIND_RELATION || if (RELKIND_HAS_TABLE_AM(rel->rd_rel->relkind) || rel->rd_rel->relkind == RELKIND_SEQUENCE)
rel->rd_rel->relkind == RELKIND_SEQUENCE ||
rel->rd_rel->relkind == RELKIND_TOASTVALUE ||
rel->rd_rel->relkind == RELKIND_MATVIEW)
RelationInitTableAccessMethod(rel); RelationInitTableAccessMethod(rel);
Assert(rel->rd_index == NULL); Assert(rel->rd_index == NULL);

View File

@ -16480,17 +16480,26 @@ dumpTableSchema(Archive *fout, const TableInfo *tbinfo)
if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
{ {
char *tablespace = NULL;
char *tableam = NULL; char *tableam = NULL;
if (tbinfo->relkind == RELKIND_RELATION || /*
tbinfo->relkind == RELKIND_MATVIEW) * _selectTablespace() relies on tablespace-enabled objects in the
* default tablespace to have a tablespace of "" (empty string) versus
* non-tablespace-enabled objects to have a tablespace of NULL.
* getTables() sets tbinfo->reltablespace to "" for the default
* tablespace (not NULL).
*/
if (RELKIND_HAS_TABLESPACE(tbinfo->relkind))
tablespace = tbinfo->reltablespace;
if (RELKIND_HAS_TABLE_AM(tbinfo->relkind))
tableam = tbinfo->amname; tableam = tbinfo->amname;
ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId, ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
ARCHIVE_OPTS(.tag = tbinfo->dobj.name, ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
.namespace = tbinfo->dobj.namespace->dobj.name, .namespace = tbinfo->dobj.namespace->dobj.name,
.tablespace = (tbinfo->relkind == RELKIND_VIEW) ? .tablespace = tablespace,
NULL : tbinfo->reltablespace,
.tableam = tableam, .tableam = tableam,
.owner = tbinfo->rolname, .owner = tbinfo->rolname,
.description = reltypename, .description = reltypename,

View File

@ -198,6 +198,31 @@ DECLARE_INDEX(pg_class_tblspc_relfilenode_index, 3455, ClassTblspcRelfilenodeInd
(relkind) == RELKIND_TOASTVALUE || \ (relkind) == RELKIND_TOASTVALUE || \
(relkind) == RELKIND_MATVIEW) (relkind) == RELKIND_MATVIEW)
#define RELKIND_HAS_PARTITIONS(relkind) \
((relkind) == RELKIND_PARTITIONED_TABLE || \
(relkind) == RELKIND_PARTITIONED_INDEX)
/*
* Relation kinds that support tablespaces: All relation kinds with storage
* support tablespaces, except that we don't support moving sequences around
* into different tablespaces. Partitioned tables and indexes don't have
* physical storage, but they have a tablespace settings so that their
* children can inherit it.
*/
#define RELKIND_HAS_TABLESPACE(relkind) \
((RELKIND_HAS_STORAGE(relkind) || RELKIND_HAS_PARTITIONS(relkind)) \
&& (relkind) != RELKIND_SEQUENCE)
/*
* Relation kinds with a table access method (rd_tableam). Although sequences
* use the heap table AM, they are enough of a special case in most uses that
* they are not included here.
*/
#define RELKIND_HAS_TABLE_AM(relkind) \
((relkind) == RELKIND_RELATION || \
(relkind) == RELKIND_TOASTVALUE || \
(relkind) == RELKIND_MATVIEW)
extern int errdetail_relkind_not_supported(char relkind); extern int errdetail_relkind_not_supported(char relkind);
#endif /* EXPOSE_TO_CLIENT_CODE */ #endif /* EXPOSE_TO_CLIENT_CODE */