aboutsummaryrefslogtreecommitdiff
path: root/src/backend/catalog/pg_depend.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/catalog/pg_depend.c')
-rw-r--r--src/backend/catalog/pg_depend.c46
1 files changed, 40 insertions, 6 deletions
diff --git a/src/backend/catalog/pg_depend.c b/src/backend/catalog/pg_depend.c
index 09c30b13e88..25290c821fd 100644
--- a/src/backend/catalog/pg_depend.c
+++ b/src/backend/catalog/pg_depend.c
@@ -19,6 +19,7 @@
#include "access/table.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
+#include "catalog/pg_collation.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_depend.h"
#include "catalog/pg_extension.h"
@@ -27,6 +28,7 @@
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/lsyscache.h"
+#include "utils/pg_locale.h"
#include "utils/rel.h"
@@ -45,19 +47,24 @@ recordDependencyOn(const ObjectAddress *depender,
const ObjectAddress *referenced,
DependencyType behavior)
{
- recordMultipleDependencies(depender, referenced, 1, NULL, behavior);
+ recordMultipleDependencies(depender, referenced, 1, behavior, false);
}
/*
* Record multiple dependencies (of the same kind) for a single dependent
* object. This has a little less overhead than recording each separately.
+ *
+ * If record_version is true, then a record is added even if the referenced
+ * object is pinned, and the dependency version will be retrieved according to
+ * the referenced object kind. For now, only collation version is
+ * supported.
*/
void
recordMultipleDependencies(const ObjectAddress *depender,
const ObjectAddress *referenced,
int nreferenced,
- const char *version,
- DependencyType behavior)
+ DependencyType behavior,
+ bool record_version)
{
Relation dependDesc;
CatalogIndexState indstate;
@@ -66,6 +73,7 @@ recordMultipleDependencies(const ObjectAddress *depender,
max_slots,
slot_init_count,
slot_stored_count;
+ char *version = NULL;
if (nreferenced <= 0)
return; /* nothing to do */
@@ -96,12 +104,38 @@ recordMultipleDependencies(const ObjectAddress *depender,
slot_init_count = 0;
for (i = 0; i < nreferenced; i++, referenced++)
{
+ bool ignore_systempin = false;
+
+ if (record_version)
+ {
+ /* For now we only know how to deal with collations. */
+ if (referenced->classId == CollationRelationId)
+ {
+ /* C and POSIX don't need version tracking. */
+ if (referenced->objectId == C_COLLATION_OID ||
+ referenced->objectId == POSIX_COLLATION_OID)
+ continue;
+
+ version = get_collation_version_for_oid(referenced->objectId);
+
+ /*
+ * Default collation is pinned, so we need to force recording
+ * the dependency to store the version.
+ */
+ if (referenced->objectId == DEFAULT_COLLATION_OID)
+ ignore_systempin = true;
+ }
+ }
+ else
+ Assert(!version);
+
/*
* If the referenced object is pinned by the system, there's no real
- * need to record dependencies on it. This saves lots of space in
- * pg_depend, so it's worth the time taken to check.
+ * need to record dependencies on it, unless we need to record a
+ * version. This saves lots of space in pg_depend, so it's worth the
+ * time taken to check.
*/
- if (isObjectPinned(referenced, dependDesc))
+ if (!ignore_systempin && isObjectPinned(referenced, dependDesc))
continue;
if (slot_init_count < max_slots)