mirror of
https://github.com/postgres/postgres.git
synced 2025-05-05 09:19:17 +03:00
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
This commit is contained in:
parent
9c34a05b7d
commit
0461b66e36
@ -12440,7 +12440,8 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
|
|||||||
i_opcfamilynsp = PQfnumber(res, "opcfamilynsp");
|
i_opcfamilynsp = PQfnumber(res, "opcfamilynsp");
|
||||||
i_amname = PQfnumber(res, "amname");
|
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);
|
opckeytype = PQgetvalue(res, 0, i_opckeytype);
|
||||||
opcdefault = PQgetvalue(res, 0, i_opcdefault);
|
opcdefault = PQgetvalue(res, 0, i_opcdefault);
|
||||||
/* opcfamily will still be needed after we PQclear res */
|
/* opcfamily will still be needed after we PQclear res */
|
||||||
@ -12674,6 +12675,15 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
|
|||||||
|
|
||||||
PQclear(res);
|
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");
|
appendPQExpBufferStr(q, ";\n");
|
||||||
|
|
||||||
appendPQExpBuffer(labelq, "OPERATOR CLASS %s",
|
appendPQExpBuffer(labelq, "OPERATOR CLASS %s",
|
||||||
@ -12701,6 +12711,8 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
|
|||||||
opcinfo->dobj.namespace->dobj.name, opcinfo->rolname,
|
opcinfo->dobj.namespace->dobj.name, opcinfo->rolname,
|
||||||
opcinfo->dobj.catId, 0, opcinfo->dobj.dumpId);
|
opcinfo->dobj.catId, 0, opcinfo->dobj.dumpId);
|
||||||
|
|
||||||
|
free(opcintype);
|
||||||
|
free(opcfamily);
|
||||||
free(amname);
|
free(amname);
|
||||||
destroyPQExpBuffer(query);
|
destroyPQExpBuffer(query);
|
||||||
destroyPQExpBuffer(q);
|
destroyPQExpBuffer(q);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user