*** src/bin/pg_dump/pg_dump.c --- src/bin/pg_dump/pg_dump.c *************** *** 134,139 **** static void dumpBaseType(Archive *fout, TypeInfo *tinfo); --- 134,140 ---- static void dumpEnumType(Archive *fout, TypeInfo *tinfo); static void dumpDomain(Archive *fout, TypeInfo *tinfo); static void dumpCompositeType(Archive *fout, TypeInfo *tinfo); + static void dumpCompositeTypeColsComment(Archive *fout, TypeInfo *tinfo); static void dumpShellType(Archive *fout, ShellTypeInfo *stinfo); static void dumpProcLang(Archive *fout, ProcLangInfo *plang); static void dumpFunc(Archive *fout, FuncInfo *finfo); *************** *** 6755,6762 **** dumpCompositeType(Archive *fout, TypeInfo *tinfo) --- 6756,6864 ---- destroyPQExpBuffer(q); destroyPQExpBuffer(delq); destroyPQExpBuffer(query); + + /* Dump column comments */ + dumpCompositeTypeColsComment(fout, tinfo); + } + + /* + * dumpCompositeTypeColsComment + * writes out to fout the queries to recreate comments on columns of + * composite types + */ + static void + dumpCompositeTypeColsComment(Archive *fout, TypeInfo *tinfo) + { + CommentItem *comments; + int ncomments; + PGresult *res; + PQExpBuffer query; + PQExpBuffer attrquery = createPQExpBuffer(); + PQExpBuffer target; + Oid colTableOid; + int i; + int ntups; + int i_attname; + int i_attnum; + + appendPQExpBuffer(attrquery, + "SELECT pg_class.tableoid, " + " pg_attribute.attname, " + " pg_attribute.attnum " + "FROM pg_class, pg_attribute " + "WHERE pg_class.oid = '%u' and pg_class.oid = pg_attribute.attrelid " + "ORDER BY pg_attribute.attnum ", + tinfo->typrelid); + + /* Fetch column's attname */ + res = PQexec(g_conn, attrquery->data); + check_sql_result(res, g_conn, attrquery->data, PGRES_TUPLES_OK); + ntups = PQntuples(res); + if (ntups < 1) + { + write_msg(NULL, "query returned no rows: %s\n", attrquery->data); + exit_nicely(); + } + colTableOid = atooid(PQgetvalue(res, 0, PQfnumber(res, "tableoid"))); + + /* Search for comments associated with relation, using table */ + ncomments = findComments(fout, + colTableOid, + tinfo->typrelid, + &comments); + + /* If comments exist, build COMMENT ON statements */ + if (ncomments <= 0) + return; + + query = createPQExpBuffer(); + target = createPQExpBuffer(); + + i_attnum = PQfnumber(res, "attnum"); + i_attname = PQfnumber(res, "attname"); + while (ncomments > 0) + { + const char *descr = comments->descr; + /* Just to be safe */ + const char *attname = "unknown"; + for (i = 0; i < ntups; i++) + { + if (atoi(PQgetvalue(res, i, i_attnum)) == comments->objsubid) + { + attname = PQgetvalue(res, i, i_attname); + break; + } + } + resetPQExpBuffer(target); + appendPQExpBuffer(target, "COLUMN %s.", + fmtId(tinfo->dobj.name)); + appendPQExpBuffer(target, "%s", + fmtId(attname)); + + resetPQExpBuffer(query); + appendPQExpBuffer(query, "COMMENT ON %s IS ", target->data); + appendStringLiteralAH(query, descr, fout); + appendPQExpBuffer(query, ";\n"); + + ArchiveEntry(fout, nilCatalogId, createDumpId(), + target->data, + tinfo->dobj.namespace->dobj.name, + NULL, + tinfo->rolname, + false, "COMMENT", SECTION_NONE, query->data, "", NULL, + &(tinfo->dobj.dumpId), 1, + NULL, NULL); + + comments++; + ncomments--; + } + destroyPQExpBuffer(attrquery); + destroyPQExpBuffer(query); + destroyPQExpBuffer(target); + PQclear(res); } + /* * dumpShellType * writes out to fout the queries to create a shell type