提交 f8db7bb7 编写于 作者: D Daniel Gustafsson 提交者: Heikki Linnakangas

Fix pg_dump to not emit invalid SQL for an empty operator class.

This is a backport of the below commit from upstream to handle empty
operator classes in pg_dump. The bug was first found in Greenplum but
applied as an upstream-first fix. Cherry-picking was not possible due
to interim changes not yet in Greenplum.

  commit 0461b66e
  Author: Tom Lane <tgl@sss.pgh.pa.us>
  Date:   Fri May 26 12:51:05 2017 -0400

    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
上级 96e953a7
......@@ -7953,7 +7953,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 = PQgetvalue(res, 0, i_opcfamily);
......@@ -8115,6 +8116,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);
appendPQExpBuffer(q, ";\n");
ArchiveEntry(fout, opcinfo->dobj.catId, opcinfo->dobj.dumpId,
......@@ -8136,6 +8146,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
NULL, opcinfo->rolname,
opcinfo->dobj.catId, 0, opcinfo->dobj.dumpId);
free(opcintype);
free(amname);
destroyPQExpBuffer(query);
destroyPQExpBuffer(q);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册