1
0
mirror of https://github.com/postgres/postgres.git synced 2026-10-25 01:39:28 +03:00

Dump labels in reproducible order

In pg_get_propgraphdef(), sort the labels before writing out, for a
consistent dump order.  Also, since we now have a list, we can get rid
of the separate table scan to get the count.

Co-authored-by: Peter Eisentraut <peter@eisentraut.org>
Co-authored-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Co-authored-by: Andrew Dunstan <andrew@dunslane.net>
Reviewed-by: Junwang Zhao <zhjwpku@gmail.com>
Reviewed-by: Kirill Reshke <reshkekirill@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/a855795d-e697-4fa5-8698-d20122126567@eisentraut.org
This commit is contained in:
Peter Eisentraut
2026-03-17 14:06:53 +01:00
parent 2c1a7d421f
commit c9babbc881

View File

@@ -1772,6 +1772,21 @@ make_propgraphdef_elements(StringInfo buf, Oid pgrelid, char pgekind)
table_close(pgerel, AccessShareLock);
}
struct oid_str_pair
{
Oid oid;
char *str;
};
static int
list_oid_str_pair_cmp_by_str(const ListCell *p1, const ListCell *p2)
{
struct oid_str_pair *v1 = lfirst(p1);
struct oid_str_pair *v2 = lfirst(p2);
return strcmp(v1->str, v2->str);
}
/*
* Generates label and properties list. Pass in the element OID, the element
* alias, and the graph relation OID. Result is appended to buf.
@@ -1784,6 +1799,7 @@ make_propgraphdef_labels(StringInfo buf, Oid elid, const char *elalias, Oid elre
SysScanDesc scan;
int count;
HeapTuple tup;
List *label_list = NIL;
pglrel = table_open(PropgraphElementLabelRelationId, AccessShareLock);
@@ -1792,38 +1808,51 @@ make_propgraphdef_labels(StringInfo buf, Oid elid, const char *elalias, Oid elre
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(elid));
count = 0;
scan = systable_beginscan(pglrel, PropgraphElementLabelElementLabelIndexId, true, NULL, 1, scankey);
while ((tup = systable_getnext(scan)))
{
count++;
}
systable_endscan(scan);
/*
* We want to output the labels in a deterministic order. So we first
* read all the data, then sort, then print it.
*/
scan = systable_beginscan(pglrel, PropgraphElementLabelElementLabelIndexId, true, NULL, 1, scankey);
while ((tup = systable_getnext(scan)))
{
Form_pg_propgraph_element_label pgelform = (Form_pg_propgraph_element_label) GETSTRUCT(tup);
const char *labelname;
struct oid_str_pair *osp;
labelname = get_propgraph_label_name(pgelform->pgellabelid);
osp = palloc_object(struct oid_str_pair);
osp->oid = pgelform->oid;
osp->str = get_propgraph_label_name(pgelform->pgellabelid);
if (strcmp(labelname, elalias) == 0)
label_list = lappend(label_list, osp);
}
systable_endscan(scan);
table_close(pglrel, AccessShareLock);
count = list_length(label_list);
/* Each element has at least one label. */
Assert(count > 0);
/*
* It is enough for the comparison function to compare just labels, since
* all the labels of an element table should have distinct names.
*/
list_sort(label_list, list_oid_str_pair_cmp_by_str);
foreach_ptr(struct oid_str_pair, osp, label_list)
{
if (strcmp(osp->str, elalias) == 0)
{
/* If the default label is the only label, don't print anything. */
if (count != 1)
appendStringInfo(buf, " DEFAULT LABEL");
}
else
appendStringInfo(buf, " LABEL %s", quote_identifier(labelname));
appendStringInfo(buf, " LABEL %s", quote_identifier(osp->str));
make_propgraphdef_properties(buf, pgelform->oid, elrelid);
make_propgraphdef_properties(buf, osp->oid, elrelid);
}
systable_endscan(scan);
table_close(pglrel, AccessShareLock);
}
/*