aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2017-05-26 12:51:05 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2017-05-26 12:51:05 -0400
commit1cfc9dc75b175c68443c50a359ae5b7a2529326e (patch)
treeb4516d07d7fa89718b581b8654ea763d5a3d8a8a /src
parentd192a19799a97de20ca9424df17cb211648ba94d (diff)
downloadpostgresql-1cfc9dc75b175c68443c50a359ae5b7a2529326e.tar.gz
postgresql-1cfc9dc75b175c68443c50a359ae5b7a2529326e.zip
Fix pg_dump to not emit invalid SQL for an empty operator class.
If an operator class has no operators or functions, and doesn't need a STORAGE clause, we emitted "CREATE OPERATOR CLASS ... AS ;" which is syntactically invalid. Fix by forcing a STORAGE clause to be emitted anyway in this case. (At some point we might consider changing the grammar to allow CREATE OPERATOR CLASS without an opclass_item_list. But probably we'd want to omit the AS in that case, so that wouldn't fix this pg_dump issue anyway.) It's been like this all along, so back-patch to all supported branches. Daniel Gustafsson, tweaked by me to avoid a dangling-pointer bug Discussion: https://postgr.es/m/D9E5FC64-7A37-4F3D-B946-7E4FB468F88A@yesql.se
Diffstat (limited to 'src')
-rw-r--r--src/bin/pg_dump/pg_dump.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 0f64772a396..edeb567b5b0 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -10901,7 +10901,8 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
i_opcfamilynsp = PQfnumber(res, "opcfamilynsp");
i_amname = PQfnumber(res, "amname");
- opcintype = PQgetvalue(res, 0, i_opcintype);
+ /* opcintype may still be needed after we PQclear res */
+ opcintype = pg_strdup(PQgetvalue(res, 0, i_opcintype));
opckeytype = PQgetvalue(res, 0, i_opckeytype);
opcdefault = PQgetvalue(res, 0, i_opcdefault);
/* opcfamily will still be needed after we PQclear res */
@@ -11135,6 +11136,15 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
PQclear(res);
+ /*
+ * If needComma is still false it means we haven't added anything after
+ * the AS keyword. To avoid printing broken SQL, append a dummy STORAGE
+ * clause with the same datatype. This isn't sanctioned by the
+ * documentation, but actually DefineOpClass will treat it as a no-op.
+ */
+ if (!needComma)
+ appendPQExpBuffer(q, "STORAGE %s", opcintype);
+
appendPQExpBufferStr(q, ";\n");
appendPQExpBuffer(labelq, "OPERATOR CLASS %s",
@@ -11160,6 +11170,8 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
opcinfo->dobj.namespace->dobj.name, opcinfo->rolname,
opcinfo->dobj.catId, 0, opcinfo->dobj.dumpId);
+ free(opcintype);
+ free(opcfamily);
free(amname);
destroyPQExpBuffer(query);
destroyPQExpBuffer(q);