Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0decd5e

Browse files
committed
Sort dump objects independent of OIDs, for the 7 holdout object types.
pg_dump sorts objects by their logical names, e.g. (nspname, relname,tgname), before dependency-driven reordering. That removes one sourceof logically-identical databases differing in their schema-only dumps.In other words, it helps with schema diffing. The logical name sortignored essential sort keys for constraints, operators, PUBLICATION... FOR TABLE, PUBLICATION ... FOR TABLES IN SCHEMA, operator classes,and operator families. pg_dump's sort then depended on object OID,yielding spurious schema diffs. After this change, OIDs affect dumporder only in the event of catalog corruption. While pg_dump alsowrongly ignored pg_collation.collencoding, CREATE COLLATION restrictionshave been keeping that imperceptible in practical use.Use techniques like we use for object types already having full sort keycoverage. Where the pertinent queries weren't fetching the ignored sortkeys, this adds columns to those queries and stores those keys in memoryfor the long term.The ignorance of sort keys became more problematic when commit172259a added a schema diff testsensitive to it. Buildfarm member hippopotamus witnessed that.However, dump order stability isn't a new goal, and this might avoidother dump comparison failures. Hence, back-patch to v13 (all supportedversions).Reviewed-by: Robert Haas <robertmhaas@gmail.com>Discussion:https://postgr.es/m/20250707192654.9e.nmisch@google.comBackpatch-through: 13
1 parent3357471 commit0decd5e

File tree

6 files changed

+335
-30
lines changed

6 files changed

+335
-30
lines changed

‎src/bin/pg_dump/common.c‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include<ctype.h>
1919

20+
#include"catalog/pg_am_d.h"
2021
#include"catalog/pg_class_d.h"
2122
#include"catalog/pg_collation_d.h"
2223
#include"catalog/pg_extension_d.h"
@@ -944,6 +945,24 @@ findOprByOid(Oid oid)
944945
return (OprInfo*)dobj;
945946
}
946947

948+
/*
949+
* findAccessMethodByOid
950+
* finds the DumpableObject for the access method with the given oid
951+
* returns NULL if not found
952+
*/
953+
AccessMethodInfo*
954+
findAccessMethodByOid(Oidoid)
955+
{
956+
CatalogIdcatId;
957+
DumpableObject*dobj;
958+
959+
catId.tableoid=AccessMethodRelationId;
960+
catId.oid=oid;
961+
dobj=findObjectByCatalogId(catId);
962+
Assert(dobj==NULL||dobj->objType==DO_ACCESS_METHOD);
963+
return (AccessMethodInfo*)dobj;
964+
}
965+
947966
/*
948967
* findCollationByOid
949968
* finds the DumpableObject for the collation with the given oid

‎src/bin/pg_dump/pg_dump.c‎

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2207,6 +2207,13 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout)
22072207
static void
22082208
selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout)
22092209
{
2210+
/* see getAccessMethods() comment about v9.6. */
2211+
if (fout->remoteVersion < 90600)
2212+
{
2213+
method->dobj.dump = DUMP_COMPONENT_NONE;
2214+
return;
2215+
}
2216+
22102217
if (checkExtensionMembership(&method->dobj, fout))
22112218
return;/* extension membership overrides all else */
22122219

@@ -6262,6 +6269,8 @@ getOperators(Archive *fout)
62626269
inti_oprnamespace;
62636270
inti_oprowner;
62646271
inti_oprkind;
6272+
inti_oprleft;
6273+
inti_oprright;
62656274
inti_oprcode;
62666275

62676276
/*
@@ -6273,6 +6282,8 @@ getOperators(Archive *fout)
62736282
"oprnamespace, "
62746283
"oprowner, "
62756284
"oprkind, "
6285+
"oprleft, "
6286+
"oprright, "
62766287
"oprcode::oid AS oprcode "
62776288
"FROM pg_operator");
62786289

@@ -6288,6 +6299,8 @@ getOperators(Archive *fout)
62886299
i_oprnamespace = PQfnumber(res, "oprnamespace");
62896300
i_oprowner = PQfnumber(res, "oprowner");
62906301
i_oprkind = PQfnumber(res, "oprkind");
6302+
i_oprleft = PQfnumber(res, "oprleft");
6303+
i_oprright = PQfnumber(res, "oprright");
62916304
i_oprcode = PQfnumber(res, "oprcode");
62926305

62936306
for (i = 0; i < ntups; i++)
@@ -6301,6 +6314,8 @@ getOperators(Archive *fout)
63016314
findNamespace(atooid(PQgetvalue(res, i, i_oprnamespace)));
63026315
oprinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_oprowner));
63036316
oprinfo[i].oprkind = (PQgetvalue(res, i, i_oprkind))[0];
6317+
oprinfo[i].oprleft = atooid(PQgetvalue(res, i, i_oprleft));
6318+
oprinfo[i].oprright = atooid(PQgetvalue(res, i, i_oprright));
63046319
oprinfo[i].oprcode = atooid(PQgetvalue(res, i, i_oprcode));
63056320

63066321
/* Decide whether we want to dump it */
@@ -6329,6 +6344,7 @@ getCollations(Archive *fout)
63296344
inti_collname;
63306345
inti_collnamespace;
63316346
inti_collowner;
6347+
inti_collencoding;
63326348

63336349
query = createPQExpBuffer();
63346350

@@ -6339,7 +6355,8 @@ getCollations(Archive *fout)
63396355

63406356
appendPQExpBufferStr(query, "SELECT tableoid, oid, collname, "
63416357
"collnamespace, "
6342-
"collowner "
6358+
"collowner, "
6359+
"collencoding "
63436360
"FROM pg_collation");
63446361

63456362
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
@@ -6353,6 +6370,7 @@ getCollations(Archive *fout)
63536370
i_collname = PQfnumber(res, "collname");
63546371
i_collnamespace = PQfnumber(res, "collnamespace");
63556372
i_collowner = PQfnumber(res, "collowner");
6373+
i_collencoding = PQfnumber(res, "collencoding");
63566374

63576375
for (i = 0; i < ntups; i++)
63586376
{
@@ -6364,6 +6382,7 @@ getCollations(Archive *fout)
63646382
collinfo[i].dobj.namespace =
63656383
findNamespace(atooid(PQgetvalue(res, i, i_collnamespace)));
63666384
collinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_collowner));
6385+
collinfo[i].collencoding = atoi(PQgetvalue(res, i, i_collencoding));
63676386

63686387
/* Decide whether we want to dump it */
63696388
selectDumpableObject(&(collinfo[i].dobj), fout);
@@ -6454,16 +6473,28 @@ getAccessMethods(Archive *fout)
64546473
inti_amhandler;
64556474
inti_amtype;
64566475

6457-
/* Before 9.6, there are no user-defined access methods */
6458-
if (fout->remoteVersion < 90600)
6459-
return;
6460-
64616476
query = createPQExpBuffer();
64626477

6463-
/* Select all access methods from pg_am table */
6464-
appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, amtype, "
6465-
"amhandler::pg_catalog.regproc AS amhandler "
6466-
"FROM pg_am");
6478+
/*
6479+
* Select all access methods from pg_am table. v9.6 introduced CREATE
6480+
* ACCESS METHOD, so earlier versions usually have only built-in access
6481+
* methods. v9.6 also changed the access method API, replacing dozens of
6482+
* pg_am columns with amhandler. Even if a user created an access method
6483+
* by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am
6484+
* columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read
6485+
* pg_am just to facilitate findAccessMethodByOid() providing the
6486+
* OID-to-name mapping.
6487+
*/
6488+
appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, ");
6489+
if (fout->remoteVersion >= 90600)
6490+
appendPQExpBufferStr(query,
6491+
"amtype, "
6492+
"amhandler::pg_catalog.regproc AS amhandler ");
6493+
else
6494+
appendPQExpBufferStr(query,
6495+
"'i'::pg_catalog.\"char\" AS amtype, "
6496+
"'-'::pg_catalog.regproc AS amhandler ");
6497+
appendPQExpBufferStr(query, "FROM pg_am");
64676498

64686499
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
64696500

@@ -6512,6 +6543,7 @@ getOpclasses(Archive *fout)
65126543
OpclassInfo *opcinfo;
65136544
inti_tableoid;
65146545
inti_oid;
6546+
inti_opcmethod;
65156547
inti_opcname;
65166548
inti_opcnamespace;
65176549
inti_opcowner;
@@ -6521,7 +6553,7 @@ getOpclasses(Archive *fout)
65216553
* system-defined opclasses at dump-out time.
65226554
*/
65236555

6524-
appendPQExpBufferStr(query, "SELECT tableoid, oid, opcname, "
6556+
appendPQExpBufferStr(query, "SELECT tableoid, oid,opcmethod,opcname, "
65256557
"opcnamespace, "
65266558
"opcowner "
65276559
"FROM pg_opclass");
@@ -6534,6 +6566,7 @@ getOpclasses(Archive *fout)
65346566

65356567
i_tableoid = PQfnumber(res, "tableoid");
65366568
i_oid = PQfnumber(res, "oid");
6569+
i_opcmethod = PQfnumber(res, "opcmethod");
65376570
i_opcname = PQfnumber(res, "opcname");
65386571
i_opcnamespace = PQfnumber(res, "opcnamespace");
65396572
i_opcowner = PQfnumber(res, "opcowner");
@@ -6547,6 +6580,7 @@ getOpclasses(Archive *fout)
65476580
opcinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opcname));
65486581
opcinfo[i].dobj.namespace =
65496582
findNamespace(atooid(PQgetvalue(res, i, i_opcnamespace)));
6583+
opcinfo[i].opcmethod = atooid(PQgetvalue(res, i, i_opcmethod));
65506584
opcinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_opcowner));
65516585

65526586
/* Decide whether we want to dump it */
@@ -6572,6 +6606,7 @@ getOpfamilies(Archive *fout)
65726606
OpfamilyInfo *opfinfo;
65736607
inti_tableoid;
65746608
inti_oid;
6609+
inti_opfmethod;
65756610
inti_opfname;
65766611
inti_opfnamespace;
65776612
inti_opfowner;
@@ -6583,7 +6618,7 @@ getOpfamilies(Archive *fout)
65836618
* system-defined opfamilies at dump-out time.
65846619
*/
65856620

6586-
appendPQExpBufferStr(query, "SELECT tableoid, oid, opfname, "
6621+
appendPQExpBufferStr(query, "SELECT tableoid, oid,opfmethod,opfname, "
65876622
"opfnamespace, "
65886623
"opfowner "
65896624
"FROM pg_opfamily");
@@ -6597,6 +6632,7 @@ getOpfamilies(Archive *fout)
65976632
i_tableoid = PQfnumber(res, "tableoid");
65986633
i_oid = PQfnumber(res, "oid");
65996634
i_opfname = PQfnumber(res, "opfname");
6635+
i_opfmethod = PQfnumber(res, "opfmethod");
66006636
i_opfnamespace = PQfnumber(res, "opfnamespace");
66016637
i_opfowner = PQfnumber(res, "opfowner");
66026638

@@ -6609,6 +6645,7 @@ getOpfamilies(Archive *fout)
66096645
opfinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opfname));
66106646
opfinfo[i].dobj.namespace =
66116647
findNamespace(atooid(PQgetvalue(res, i, i_opfnamespace)));
6648+
opfinfo[i].opfmethod = atooid(PQgetvalue(res, i, i_opfmethod));
66126649
opfinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_opfowner));
66136650

66146651
/* Decide whether we want to dump it */

‎src/bin/pg_dump/pg_dump.h‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,8 @@ typedef struct _oprInfo
260260
DumpableObjectdobj;
261261
constchar*rolname;
262262
charoprkind;
263+
Oidoprleft;
264+
Oidoprright;
263265
Oidoprcode;
264266
}OprInfo;
265267

@@ -273,19 +275,22 @@ typedef struct _accessMethodInfo
273275
typedefstruct_opclassInfo
274276
{
275277
DumpableObjectdobj;
278+
Oidopcmethod;
276279
constchar*rolname;
277280
}OpclassInfo;
278281

279282
typedefstruct_opfamilyInfo
280283
{
281284
DumpableObjectdobj;
285+
Oidopfmethod;
282286
constchar*rolname;
283287
}OpfamilyInfo;
284288

285289
typedefstruct_collInfo
286290
{
287291
DumpableObjectdobj;
288292
constchar*rolname;
293+
intcollencoding;
289294
}CollInfo;
290295

291296
typedefstruct_convInfo
@@ -760,6 +765,7 @@ extern TableInfo *findTableByOid(Oid oid);
760765
externTypeInfo*findTypeByOid(Oidoid);
761766
externFuncInfo*findFuncByOid(Oidoid);
762767
externOprInfo*findOprByOid(Oidoid);
768+
externAccessMethodInfo*findAccessMethodByOid(Oidoid);
763769
externCollInfo*findCollationByOid(Oidoid);
764770
externNamespaceInfo*findNamespaceByOid(Oidoid);
765771
externExtensionInfo*findExtensionByOid(Oidoid);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp