Re: FK Constraint sort order with pg_dump

Поиск
Список
Период
Сортировка
От Tom Lane
Тема Re: FK Constraint sort order with pg_dump
Дата
Msg-id 286980.1658436393@sss.pgh.pa.us
обсуждение исходный текст
Ответ на Re: FK Constraint sort order with pg_dump  (Christian Barthel <bch@online.de>)
Список pgsql-general
Christian Barthel <bch@online.de> writes:
> On Thursday, July 21, 2022, Adrian Klaver wrote:
>> Why does it matter?

> As the comment in pg_dump.c states, logically identical schemas should
> produce identical dumps:

Agreed, but this is far from the only deficiency in DOTypeNameCompare.
If we're going to try to fill in the gaps, we should be systematic
about it.  I took a quick stab at implementing the cases it omits,
as attached.  There are still a few gaps:

* DO_OPCLASS and DO_OPFAMILY ought to have a subsidiary sort on the
access method name, since their names are only unique per-access-method.
The trouble here is that OpclassInfo/OpfamilyInfo don't provide any
way to get to the access method.  That could be fixed with more fields,
and maybe it's worth doing, but I didn't do that here.

* For casts, the cast name is consed up as the concatenation of the source
and target type names, which isn't enough to guarantee uniqueness.  We
could add the types' schema names, perhaps ... is it worth the trouble?
(Not to mention possible breakage of scripts that expect the current
naming convention.)

* Likewise for transforms, we'd need to add the type's schema name if
we want the transform name to be unique.

Not sure whether it's worth venturing into such nonlocal fixes.

            regards, tom lane

diff --git a/src/bin/pg_dump/pg_dump_sort.c b/src/bin/pg_dump/pg_dump_sort.c
index 5de3241eb4..2282c002ae 100644
--- a/src/bin/pg_dump/pg_dump_sort.c
+++ b/src/bin/pg_dump/pg_dump_sort.c
@@ -280,6 +280,34 @@ DOTypeNameCompare(const void *p1, const void *p2)
         if (cmpval != 0)
             return cmpval;
     }
+    else if (obj1->objType == DO_CONSTRAINT ||
+             obj1->objType == DO_FK_CONSTRAINT)
+    {
+        ConstraintInfo *cobj1 = *(ConstraintInfo *const *) p1;
+        ConstraintInfo *cobj2 = *(ConstraintInfo *const *) p2;
+        const char *objname1;
+        const char *objname2;
+
+        /* Sort by owning object name (namespace was considered already) */
+        if (cobj1->contable)
+            objname1 = cobj1->contable->dobj.name;
+        else if (cobj1->condomain)
+            objname1 = cobj1->condomain->dobj.name;
+        else
+            objname1 = NULL;
+        if (cobj2->contable)
+            objname2 = cobj2->contable->dobj.name;
+        else if (cobj2->condomain)
+            objname2 = cobj2->condomain->dobj.name;
+        else
+            objname2 = NULL;
+        if (objname1 && objname2)
+        {
+            cmpval = strcmp(objname1, objname2);
+            if (cmpval != 0)
+                return cmpval;
+        }
+    }
     else if (obj1->objType == DO_POLICY)
     {
         PolicyInfo *pobj1 = *(PolicyInfo *const *) p1;
@@ -291,6 +319,17 @@ DOTypeNameCompare(const void *p1, const void *p2)
         if (cmpval != 0)
             return cmpval;
     }
+    else if (obj1->objType == DO_RULE)
+    {
+        RuleInfo   *robj1 = *(RuleInfo *const *) p1;
+        RuleInfo   *robj2 = *(RuleInfo *const *) p2;
+
+        /* Sort by table name (table namespace was considered already) */
+        cmpval = strcmp(robj1->ruletable->dobj.name,
+                        robj2->ruletable->dobj.name);
+        if (cmpval != 0)
+            return cmpval;
+    }
     else if (obj1->objType == DO_TRIGGER)
     {
         TriggerInfo *tobj1 = *(TriggerInfo *const *) p1;
@@ -302,6 +341,39 @@ DOTypeNameCompare(const void *p1, const void *p2)
         if (cmpval != 0)
             return cmpval;
     }
+    else if (obj1->objType == DO_DEFAULT_ACL)
+    {
+        DefaultACLInfo *daclobj1 = *(DefaultACLInfo *const *) p1;
+        DefaultACLInfo *daclobj2 = *(DefaultACLInfo *const *) p2;
+
+        /* Sort by role name (objtype and namespace were considered already) */
+        cmpval = strcmp(daclobj1->defaclrole,
+                        daclobj2->defaclrole);
+        if (cmpval != 0)
+            return cmpval;
+    }
+    else if (obj1->objType == DO_PUBLICATION_REL)
+    {
+        PublicationRelInfo *probj1 = *(PublicationRelInfo *const *) p1;
+        PublicationRelInfo *probj2 = *(PublicationRelInfo *const *) p2;
+
+        /* Sort by publication name (table name/nsp was considered already) */
+        cmpval = strcmp(probj1->publication->dobj.name,
+                        probj2->publication->dobj.name);
+        if (cmpval != 0)
+            return cmpval;
+    }
+    else if (obj1->objType == DO_PUBLICATION_TABLE_IN_SCHEMA)
+    {
+        PublicationSchemaInfo *psobj1 = *(PublicationSchemaInfo *const *) p1;
+        PublicationSchemaInfo *psobj2 = *(PublicationSchemaInfo *const *) p2;
+
+        /* Sort by publication name (schema name was considered already) */
+        cmpval = strcmp(psobj1->publication->dobj.name,
+                        psobj2->publication->dobj.name);
+        if (cmpval != 0)
+            return cmpval;
+    }
 
     /* Usually shouldn't get here, but if we do, sort by OID */
     return oidcmp(obj1->catId.oid, obj2->catId.oid);

В списке pgsql-general по дате отправления:

Предыдущее
От: Adrian Klaver
Дата:
Сообщение: Re: FK Constraint sort order with pg_dump
Следующее
От: Zsolt Ero
Дата:
Сообщение: Re: could not link file in wal restore lines