mirror of
https://github.com/postgres/postgres.git
synced 2026-02-15 08:37:56 -05:00
We now create contype='n' pg_constraint rows for not-null constraints on user tables. Only one such constraint is allowed for a column. We propagate these constraints to other tables during operations such as adding inheritance relationships, creating and attaching partitions and creating tables LIKE other tables. These related constraints mostly follow the well-known rules of conislocal and coninhcount that we have for CHECK constraints, with some adaptations: for example, as opposed to CHECK constraints, we don't match not-null ones by name when descending a hierarchy to alter or remove it, instead matching by the name of the column that they apply to. This means we don't require the constraint names to be identical across a hierarchy. The inheritance status of these constraints can be controlled: now we can be sure that if a parent table has one, then all children will have it as well. They can optionally be marked NO INHERIT, and then children are free not to have one. (There's currently no support for altering a NO INHERIT constraint into inheriting down the hierarchy, but that's a desirable future feature.) This also opens the door for having these constraints be marked NOT VALID, as well as allowing UNIQUE+NOT NULL to be used for functional dependency determination, as envisioned by commite49ae8d3bc. It's likely possible to allow DEFERRABLE constraints as followup work, as well. psql shows these constraints in \d+, though we may want to reconsider if this turns out to be too noisy. Earlier versions of this patch hid constraints that were on the same columns of the primary key, but I'm not sure that that's very useful. If clutter is a problem, we might be better off inventing a new \d++ command and not showing the constraints in \d+. For now, we omit these constraints on system catalog columns, because they're unlikely to achieve anything. The main difference to the previous attempt at this (b0e96f3119) is that we now require that such a constraint always exists when a primary key is in the column; we didn't require this previously which had a number of unpalatable consequences. With this requirement, the code is easier to reason about. For example: - We no longer have "throwaway constraints" during pg_dump. We needed those for the case where a table had a PK without a not-null underneath, to prevent a slow scan of the data during restore of the PK creation, which was particularly problematic for pg_upgrade. - We no longer have to cope with attnotnull being set spuriously in case a primary key is dropped indirectly (e.g., via DROP COLUMN). Some bits of code in this patch were authored by Jian He. Author: Álvaro Herrera <alvherre@alvh.no-ip.org> Author: Bernd Helmle <mailings@oopsware.de> Reviewed-by: 何建 (jian he) <jian.universality@gmail.com> Reviewed-by: 王刚 (Tender Wang) <tndrwang@gmail.com> Reviewed-by: Justin Pryzby <pryzby@telsasoft.com> Reviewed-by: Peter Eisentraut <peter.eisentraut@enterprisedb.com> Reviewed-by: Dean Rasheed <dean.a.rasheed@gmail.com> Discussion: https://postgr.es/m/202408310358.sdhumtyuy2ht@alvherre.pgsql
155 lines
4.7 KiB
C
155 lines
4.7 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* relcache.h
|
|
* Relation descriptor cache definitions.
|
|
*
|
|
*
|
|
* Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
* src/include/utils/relcache.h
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#ifndef RELCACHE_H
|
|
#define RELCACHE_H
|
|
|
|
#include "access/tupdesc.h"
|
|
#include "common/relpath.h"
|
|
#include "nodes/bitmapset.h"
|
|
|
|
|
|
/*
|
|
* Name of relcache init file(s), used to speed up backend startup
|
|
*/
|
|
#define RELCACHE_INIT_FILENAME "pg_internal.init"
|
|
|
|
typedef struct RelationData *Relation;
|
|
|
|
/* ----------------
|
|
* RelationPtr is used in the executor to support index scans
|
|
* where we have to keep track of several index relations in an
|
|
* array. -cim 9/10/89
|
|
* ----------------
|
|
*/
|
|
typedef Relation *RelationPtr;
|
|
|
|
/*
|
|
* Routines to open (lookup) and close a relcache entry
|
|
*/
|
|
extern Relation RelationIdGetRelation(Oid relationId);
|
|
extern void RelationClose(Relation relation);
|
|
|
|
/*
|
|
* Routines to compute/retrieve additional cached information
|
|
*/
|
|
extern List *RelationGetFKeyList(Relation relation);
|
|
extern List *RelationGetIndexList(Relation relation);
|
|
extern List *RelationGetStatExtList(Relation relation);
|
|
extern Oid RelationGetPrimaryKeyIndex(Relation relation, bool deferrable_ok);
|
|
extern Oid RelationGetReplicaIndex(Relation relation);
|
|
extern List *RelationGetIndexExpressions(Relation relation);
|
|
extern List *RelationGetDummyIndexExpressions(Relation relation);
|
|
extern List *RelationGetIndexPredicate(Relation relation);
|
|
extern bytea **RelationGetIndexAttOptions(Relation relation, bool copy);
|
|
|
|
/*
|
|
* Which set of columns to return by RelationGetIndexAttrBitmap.
|
|
*/
|
|
typedef enum IndexAttrBitmapKind
|
|
{
|
|
INDEX_ATTR_BITMAP_KEY,
|
|
INDEX_ATTR_BITMAP_PRIMARY_KEY,
|
|
INDEX_ATTR_BITMAP_IDENTITY_KEY,
|
|
INDEX_ATTR_BITMAP_HOT_BLOCKING,
|
|
INDEX_ATTR_BITMAP_SUMMARIZED,
|
|
} IndexAttrBitmapKind;
|
|
|
|
extern Bitmapset *RelationGetIndexAttrBitmap(Relation relation,
|
|
IndexAttrBitmapKind attrKind);
|
|
|
|
extern Bitmapset *RelationGetIdentityKeyBitmap(Relation relation);
|
|
|
|
extern void RelationGetExclusionInfo(Relation indexRelation,
|
|
Oid **operators,
|
|
Oid **procs,
|
|
uint16 **strategies);
|
|
|
|
extern void RelationInitIndexAccessInfo(Relation relation);
|
|
|
|
/* caller must include pg_publication.h */
|
|
struct PublicationDesc;
|
|
extern void RelationBuildPublicationDesc(Relation relation,
|
|
struct PublicationDesc *pubdesc);
|
|
|
|
extern void RelationInitTableAccessMethod(Relation relation);
|
|
|
|
/*
|
|
* Routines to support ereport() reports of relation-related errors
|
|
*/
|
|
extern int errtable(Relation rel);
|
|
extern int errtablecol(Relation rel, int attnum);
|
|
extern int errtablecolname(Relation rel, const char *colname);
|
|
extern int errtableconstraint(Relation rel, const char *conname);
|
|
|
|
/*
|
|
* Routines for backend startup
|
|
*/
|
|
extern void RelationCacheInitialize(void);
|
|
extern void RelationCacheInitializePhase2(void);
|
|
extern void RelationCacheInitializePhase3(void);
|
|
|
|
/*
|
|
* Routine to create a relcache entry for an about-to-be-created relation
|
|
*/
|
|
extern Relation RelationBuildLocalRelation(const char *relname,
|
|
Oid relnamespace,
|
|
TupleDesc tupDesc,
|
|
Oid relid,
|
|
Oid accessmtd,
|
|
RelFileNumber relfilenumber,
|
|
Oid reltablespace,
|
|
bool shared_relation,
|
|
bool mapped_relation,
|
|
char relpersistence,
|
|
char relkind);
|
|
|
|
/*
|
|
* Routines to manage assignment of new relfilenumber to a relation
|
|
*/
|
|
extern void RelationSetNewRelfilenumber(Relation relation, char persistence);
|
|
extern void RelationAssumeNewRelfilelocator(Relation relation);
|
|
|
|
/*
|
|
* Routines for flushing/rebuilding relcache entries in various scenarios
|
|
*/
|
|
extern void RelationForgetRelation(Oid rid);
|
|
|
|
extern void RelationCacheInvalidateEntry(Oid relationId);
|
|
|
|
extern void RelationCacheInvalidate(bool debug_discard);
|
|
|
|
#ifdef USE_ASSERT_CHECKING
|
|
extern void AssertPendingSyncs_RelationCache(void);
|
|
#else
|
|
#define AssertPendingSyncs_RelationCache() do {} while (0)
|
|
#endif
|
|
extern void AtEOXact_RelationCache(bool isCommit);
|
|
extern void AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid,
|
|
SubTransactionId parentSubid);
|
|
|
|
/*
|
|
* Routines to help manage rebuilding of relcache init files
|
|
*/
|
|
extern bool RelationIdIsInInitFile(Oid relationId);
|
|
extern void RelationCacheInitFilePreInvalidate(void);
|
|
extern void RelationCacheInitFilePostInvalidate(void);
|
|
extern void RelationCacheInitFileRemove(void);
|
|
|
|
/* should be used only by relcache.c and catcache.c */
|
|
extern PGDLLIMPORT bool criticalRelcachesBuilt;
|
|
|
|
/* should be used only by relcache.c and postinit.c */
|
|
extern PGDLLIMPORT bool criticalSharedRelcachesBuilt;
|
|
|
|
#endif /* RELCACHE_H */
|