aboutsummaryrefslogtreecommitdiff
path: root/src/bin/pg_dump/pg_dump.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/pg_dump/pg_dump.c')
-rw-r--r--src/bin/pg_dump/pg_dump.c163
1 files changed, 123 insertions, 40 deletions
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 3bca417cef9..66274b442e6 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -8815,22 +8815,28 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
int i_opckeytype;
int i_opcdefault;
int i_opcfamily;
+ int i_opcfamilyname;
int i_opcfamilynsp;
int i_amname;
int i_amopstrategy;
int i_amopreqcheck;
int i_amopopr;
+ int i_sortfamily;
+ int i_sortfamilynsp;
int i_amprocnum;
int i_amproc;
char *opcintype;
char *opckeytype;
char *opcdefault;
char *opcfamily;
+ char *opcfamilyname;
char *opcfamilynsp;
char *amname;
char *amopstrategy;
char *amopreqcheck;
char *amopopr;
+ char *sortfamily;
+ char *sortfamilynsp;
char *amprocnum;
char *amproc;
bool needComma;
@@ -8860,8 +8866,8 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
{
appendPQExpBuffer(query, "SELECT opcintype::pg_catalog.regtype, "
"opckeytype::pg_catalog.regtype, "
- "opcdefault, "
- "opfname AS opcfamily, "
+ "opcdefault, opcfamily, "
+ "opfname AS opcfamilyname, "
"nspname AS opcfamilynsp, "
"(SELECT amname FROM pg_catalog.pg_am WHERE oid = opcmethod) AS amname "
"FROM pg_catalog.pg_opclass c "
@@ -8874,8 +8880,8 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
{
appendPQExpBuffer(query, "SELECT opcintype::pg_catalog.regtype, "
"opckeytype::pg_catalog.regtype, "
- "opcdefault, "
- "NULL AS opcfamily, "
+ "opcdefault, NULL AS opcfamily, "
+ "NULL AS opcfamilyname, "
"NULL AS opcfamilynsp, "
"(SELECT amname FROM pg_catalog.pg_am WHERE oid = opcamid) AS amname "
"FROM pg_catalog.pg_opclass "
@@ -8901,13 +8907,16 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
i_opckeytype = PQfnumber(res, "opckeytype");
i_opcdefault = PQfnumber(res, "opcdefault");
i_opcfamily = PQfnumber(res, "opcfamily");
+ i_opcfamilyname = PQfnumber(res, "opcfamilyname");
i_opcfamilynsp = PQfnumber(res, "opcfamilynsp");
i_amname = PQfnumber(res, "amname");
opcintype = PQgetvalue(res, 0, i_opcintype);
opckeytype = PQgetvalue(res, 0, i_opckeytype);
opcdefault = PQgetvalue(res, 0, i_opcdefault);
- opcfamily = PQgetvalue(res, 0, i_opcfamily);
+ /* opcfamily will still be needed after we PQclear res */
+ opcfamily = strdup(PQgetvalue(res, 0, i_opcfamily));
+ opcfamilyname = PQgetvalue(res, 0, i_opcfamilyname);
opcfamilynsp = PQgetvalue(res, 0, i_opcfamilynsp);
/* amname will still be needed after we PQclear res */
amname = strdup(PQgetvalue(res, 0, i_amname));
@@ -8930,14 +8939,14 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
appendPQExpBuffer(q, "FOR TYPE %s USING %s",
opcintype,
fmtId(amname));
- if (strlen(opcfamily) > 0 &&
- (strcmp(opcfamily, opcinfo->dobj.name) != 0 ||
+ if (strlen(opcfamilyname) > 0 &&
+ (strcmp(opcfamilyname, opcinfo->dobj.name) != 0 ||
strcmp(opcfamilynsp, opcinfo->dobj.namespace->dobj.name) != 0))
{
appendPQExpBuffer(q, " FAMILY ");
if (strcmp(opcfamilynsp, opcinfo->dobj.namespace->dobj.name) != 0)
appendPQExpBuffer(q, "%s.", fmtId(opcfamilynsp));
- appendPQExpBuffer(q, "%s", fmtId(opcfamily));
+ appendPQExpBuffer(q, "%s", fmtId(opcfamilyname));
}
appendPQExpBuffer(q, " AS\n ");
@@ -8954,23 +8963,41 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
/*
* Now fetch and print the OPERATOR entries (pg_amop rows).
+ *
+ * Print only those opfamily members that are tied to the opclass by
+ * pg_depend entries.
+ *
+ * XXX RECHECK is gone as of 8.4, but we'll still print it if dumping
+ * an older server's opclass in which it is used. This is to avoid
+ * hard-to-detect breakage if a newer pg_dump is used to dump from an
+ * older server and then reload into that old version. This can go
+ * away once 8.3 is so old as to not be of interest to anyone.
*/
resetPQExpBuffer(query);
- if (g_fout->remoteVersion >= 80400)
+ if (g_fout->remoteVersion >= 90100)
+ {
+ appendPQExpBuffer(query, "SELECT amopstrategy, false AS amopreqcheck, "
+ "amopopr::pg_catalog.regoperator, "
+ "opfname AS sortfamily, "
+ "nspname AS sortfamilynsp "
+ "FROM pg_catalog.pg_amop ao JOIN pg_catalog.pg_depend ON "
+ "(classid = 'pg_catalog.pg_amop'::pg_catalog.regclass AND objid = ao.oid) "
+ "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = amopsortfamily "
+ "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
+ "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
+ "AND refobjid = '%u'::pg_catalog.oid "
+ "AND amopfamily = '%s'::pg_catalog.oid "
+ "ORDER BY amopstrategy",
+ opcinfo->dobj.catId.oid,
+ opcfamily);
+ }
+ else if (g_fout->remoteVersion >= 80400)
{
- /*
- * Print only those opfamily members that are tied to the opclass by
- * pg_depend entries.
- *
- * XXX RECHECK is gone as of 8.4, but we'll still print it if dumping
- * an older server's opclass in which it is used. This is to avoid
- * hard-to-detect breakage if a newer pg_dump is used to dump from an
- * older server and then reload into that old version. This can go
- * away once 8.3 is so old as to not be of interest to anyone.
- */
appendPQExpBuffer(query, "SELECT amopstrategy, false AS amopreqcheck, "
- "amopopr::pg_catalog.regoperator "
+ "amopopr::pg_catalog.regoperator, "
+ "NULL AS sortfamily, "
+ "NULL AS sortfamilynsp "
"FROM pg_catalog.pg_amop ao, pg_catalog.pg_depend "
"WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
"AND refobjid = '%u'::pg_catalog.oid "
@@ -8981,12 +9008,10 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
}
else if (g_fout->remoteVersion >= 80300)
{
- /*
- * Print only those opfamily members that are tied to the opclass by
- * pg_depend entries.
- */
appendPQExpBuffer(query, "SELECT amopstrategy, amopreqcheck, "
- "amopopr::pg_catalog.regoperator "
+ "amopopr::pg_catalog.regoperator, "
+ "NULL AS sortfamily, "
+ "NULL AS sortfamilynsp "
"FROM pg_catalog.pg_amop ao, pg_catalog.pg_depend "
"WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
"AND refobjid = '%u'::pg_catalog.oid "
@@ -8997,8 +9022,14 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
}
else
{
+ /*
+ * Here, we print all entries since there are no opfamilies and
+ * hence no loose operators to worry about.
+ */
appendPQExpBuffer(query, "SELECT amopstrategy, amopreqcheck, "
- "amopopr::pg_catalog.regoperator "
+ "amopopr::pg_catalog.regoperator, "
+ "NULL AS sortfamily, "
+ "NULL AS sortfamilynsp "
"FROM pg_catalog.pg_amop "
"WHERE amopclaid = '%u'::pg_catalog.oid "
"ORDER BY amopstrategy",
@@ -9013,18 +9044,31 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
i_amopstrategy = PQfnumber(res, "amopstrategy");
i_amopreqcheck = PQfnumber(res, "amopreqcheck");
i_amopopr = PQfnumber(res, "amopopr");
+ i_sortfamily = PQfnumber(res, "sortfamily");
+ i_sortfamilynsp = PQfnumber(res, "sortfamilynsp");
for (i = 0; i < ntups; i++)
{
amopstrategy = PQgetvalue(res, i, i_amopstrategy);
amopreqcheck = PQgetvalue(res, i, i_amopreqcheck);
amopopr = PQgetvalue(res, i, i_amopopr);
+ sortfamily = PQgetvalue(res, i, i_sortfamily);
+ sortfamilynsp = PQgetvalue(res, i, i_sortfamilynsp);
if (needComma)
appendPQExpBuffer(q, " ,\n ");
appendPQExpBuffer(q, "OPERATOR %s %s",
amopstrategy, amopopr);
+
+ if (strlen(sortfamily) > 0)
+ {
+ appendPQExpBuffer(q, " FOR ORDER BY ");
+ if (strcmp(sortfamilynsp, opcinfo->dobj.namespace->dobj.name) != 0)
+ appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp));
+ appendPQExpBuffer(q, "%s", fmtId(sortfamily));
+ }
+
if (strcmp(amopreqcheck, "t") == 0)
appendPQExpBuffer(q, " RECHECK");
@@ -9035,15 +9079,14 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
/*
* Now fetch and print the FUNCTION entries (pg_amproc rows).
+ *
+ * Print only those opfamily members that are tied to the opclass by
+ * pg_depend entries.
*/
resetPQExpBuffer(query);
if (g_fout->remoteVersion >= 80300)
{
- /*
- * Print only those opfamily members that are tied to the opclass by
- * pg_depend entries.
- */
appendPQExpBuffer(query, "SELECT amprocnum, "
"amproc::pg_catalog.regprocedure "
"FROM pg_catalog.pg_amproc ap, pg_catalog.pg_depend "
@@ -9119,6 +9162,9 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
/*
* dumpOpfamily
* write out a single operator family definition
+ *
+ * Note: this also dumps any "loose" operator members that aren't bound to a
+ * specific opclass within the opfamily.
*/
static void
dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
@@ -9134,6 +9180,8 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
int i_amopstrategy;
int i_amopreqcheck;
int i_amopopr;
+ int i_sortfamily;
+ int i_sortfamilynsp;
int i_amprocnum;
int i_amproc;
int i_amproclefttype;
@@ -9142,6 +9190,8 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
char *amopstrategy;
char *amopreqcheck;
char *amopopr;
+ char *sortfamily;
+ char *sortfamilynsp;
char *amprocnum;
char *amproc;
char *amproclefttype;
@@ -9172,18 +9222,36 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
/*
* Fetch only those opfamily members that are tied directly to the
* opfamily by pg_depend entries.
+ *
+ * XXX RECHECK is gone as of 8.4, but we'll still print it if dumping
+ * an older server's opclass in which it is used. This is to avoid
+ * hard-to-detect breakage if a newer pg_dump is used to dump from an
+ * older server and then reload into that old version. This can go
+ * away once 8.3 is so old as to not be of interest to anyone.
*/
- if (g_fout->remoteVersion >= 80400)
+ if (g_fout->remoteVersion >= 90100)
{
- /*
- * XXX RECHECK is gone as of 8.4, but we'll still print it if dumping
- * an older server's opclass in which it is used. This is to avoid
- * hard-to-detect breakage if a newer pg_dump is used to dump from an
- * older server and then reload into that old version. This can go
- * away once 8.3 is so old as to not be of interest to anyone.
- */
appendPQExpBuffer(query, "SELECT amopstrategy, false AS amopreqcheck, "
- "amopopr::pg_catalog.regoperator "
+ "amopopr::pg_catalog.regoperator, "
+ "opfname AS sortfamily, "
+ "nspname AS sortfamilynsp "
+ "FROM pg_catalog.pg_amop ao JOIN pg_catalog.pg_depend ON "
+ "(classid = 'pg_catalog.pg_amop'::pg_catalog.regclass AND objid = ao.oid) "
+ "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = amopsortfamily "
+ "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
+ "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
+ "AND refobjid = '%u'::pg_catalog.oid "
+ "AND amopfamily = '%u'::pg_catalog.oid "
+ "ORDER BY amopstrategy",
+ opfinfo->dobj.catId.oid,
+ opfinfo->dobj.catId.oid);
+ }
+ else if (g_fout->remoteVersion >= 80400)
+ {
+ appendPQExpBuffer(query, "SELECT amopstrategy, false AS amopreqcheck, "
+ "amopopr::pg_catalog.regoperator, "
+ "NULL AS sortfamily, "
+ "NULL AS sortfamilynsp "
"FROM pg_catalog.pg_amop ao, pg_catalog.pg_depend "
"WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
"AND refobjid = '%u'::pg_catalog.oid "
@@ -9195,7 +9263,9 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
else
{
appendPQExpBuffer(query, "SELECT amopstrategy, amopreqcheck, "
- "amopopr::pg_catalog.regoperator "
+ "amopopr::pg_catalog.regoperator, "
+ "NULL AS sortfamily, "
+ "NULL AS sortfamilynsp "
"FROM pg_catalog.pg_amop ao, pg_catalog.pg_depend "
"WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
"AND refobjid = '%u'::pg_catalog.oid "
@@ -9323,18 +9393,31 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
i_amopstrategy = PQfnumber(res_ops, "amopstrategy");
i_amopreqcheck = PQfnumber(res_ops, "amopreqcheck");
i_amopopr = PQfnumber(res_ops, "amopopr");
+ i_sortfamily = PQfnumber(res_ops, "sortfamily");
+ i_sortfamilynsp = PQfnumber(res_ops, "sortfamilynsp");
for (i = 0; i < ntups; i++)
{
amopstrategy = PQgetvalue(res_ops, i, i_amopstrategy);
amopreqcheck = PQgetvalue(res_ops, i, i_amopreqcheck);
amopopr = PQgetvalue(res_ops, i, i_amopopr);
+ sortfamily = PQgetvalue(res_ops, i, i_sortfamily);
+ sortfamilynsp = PQgetvalue(res_ops, i, i_sortfamilynsp);
if (needComma)
appendPQExpBuffer(q, " ,\n ");
appendPQExpBuffer(q, "OPERATOR %s %s",
amopstrategy, amopopr);
+
+ if (strlen(sortfamily) > 0)
+ {
+ appendPQExpBuffer(q, " FOR ORDER BY ");
+ if (strcmp(sortfamilynsp, opfinfo->dobj.namespace->dobj.name) != 0)
+ appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp));
+ appendPQExpBuffer(q, "%s", fmtId(sortfamily));
+ }
+
if (strcmp(amopreqcheck, "t") == 0)
appendPQExpBuffer(q, " RECHECK");