@@ -271,7 +271,7 @@ static char *convertRegProcReference(const char *proc);
271271static char *getFormattedOperatorName(const char *oproid);
272272static char *convertTSFunction(Archive *fout, Oid funcOid);
273273static OidfindLastBuiltinOid_V71(Archive *fout);
274- static char *getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts);
274+ staticconst char *getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts);
275275static void getBlobs(Archive *fout);
276276static void dumpBlob(Archive *fout, const BlobInfo *binfo);
277277static intdumpBlobs(Archive *fout, const void *arg);
@@ -11252,13 +11252,9 @@ dumpBaseType(Archive *fout, const TypeInfo *tyinfo)
1125211252appendPQExpBuffer(q, ",\n SUBSCRIPT = %s", typsubscript);
1125311253
1125411254if (OidIsValid(tyinfo->typelem))
11255- {
11256- char *elemType;
11257-
11258- elemType = getFormattedTypeName(fout, tyinfo->typelem, zeroIsError);
11259- appendPQExpBuffer(q, ",\n ELEMENT = %s", elemType);
11260- free(elemType);
11261- }
11255+ appendPQExpBuffer(q, ",\n ELEMENT = %s",
11256+ getFormattedTypeName(fout, tyinfo->typelem,
11257+ zeroIsError));
1126211258
1126311259if (strcmp(typcategory, "U") != 0)
1126411260{
@@ -12062,7 +12058,7 @@ format_function_arguments_old(Archive *fout,
1206212058for (j = 0; j < nallargs; j++)
1206312059{
1206412060Oidtypid;
12065- char *typname;
12061+ const char *typname;
1206612062const char *argmode;
1206712063const char *argname;
1206812064
@@ -12101,7 +12097,6 @@ format_function_arguments_old(Archive *fout,
1210112097 argname ? fmtId(argname) : "",
1210212098 argname ? " " : "",
1210312099 typname);
12104- free(typname);
1210512100}
1210612101appendPQExpBufferChar(&fn, ')');
1210712102return fn.data;
@@ -12130,15 +12125,12 @@ format_function_signature(Archive *fout, const FuncInfo *finfo, bool honor_quote
1213012125appendPQExpBuffer(&fn, "%s(", finfo->dobj.name);
1213112126for (j = 0; j < finfo->nargs; j++)
1213212127{
12133- char *typname;
12134-
1213512128if (j > 0)
1213612129appendPQExpBufferStr(&fn, ", ");
1213712130
12138- typname = getFormattedTypeName(fout, finfo->argtypes[j],
12139- zeroIsError);
12140- appendPQExpBufferStr(&fn, typname);
12141- free(typname);
12131+ appendPQExpBufferStr(&fn,
12132+ getFormattedTypeName(fout, finfo->argtypes[j],
12133+ zeroIsError));
1214212134}
1214312135appendPQExpBufferChar(&fn, ')');
1214412136return fn.data;
@@ -12183,7 +12175,6 @@ dumpFunc(Archive *fout, const FuncInfo *finfo)
1218312175char *prosupport;
1218412176char *proparallel;
1218512177char *lanname;
12186- char *rettypename;
1218712178intnallargs;
1218812179char **allargtypes = NULL;
1218912180char **argmodes = NULL;
@@ -12473,14 +12464,10 @@ dumpFunc(Archive *fout, const FuncInfo *finfo)
1247312464else if (funcresult)
1247412465appendPQExpBuffer(q, " RETURNS %s", funcresult);
1247512466else
12476- {
12477- rettypename = getFormattedTypeName(fout, finfo->prorettype,
12478- zeroIsError);
1247912467appendPQExpBuffer(q, " RETURNS %s%s",
1248012468 (proretset[0] == 't') ? "SETOF " : "",
12481- rettypename);
12482- free(rettypename);
12483- }
12469+ getFormattedTypeName(fout, finfo->prorettype,
12470+ zeroIsError));
1248412471
1248512472appendPQExpBuffer(q, "\n LANGUAGE %s", fmtId(lanname));
1248612473
@@ -12687,8 +12674,8 @@ dumpCast(Archive *fout, const CastInfo *cast)
1268712674PQExpBuffer labelq;
1268812675PQExpBuffer castargs;
1268912676FuncInfo *funcInfo = NULL;
12690- char *sourceType;
12691- char *targetType;
12677+ const char *sourceType;
12678+ const char *targetType;
1269212679
1269312680/* Skip if not to be dumped */
1269412681if (!cast->dobj.dump || dopt->dataOnly)
@@ -12774,9 +12761,6 @@ dumpCast(Archive *fout, const CastInfo *cast)
1277412761NULL, "",
1277512762cast->dobj.catId, 0, cast->dobj.dumpId);
1277612763
12777- free(sourceType);
12778- free(targetType);
12779-
1278012764destroyPQExpBuffer(defqry);
1278112765destroyPQExpBuffer(delqry);
1278212766destroyPQExpBuffer(labelq);
@@ -12797,7 +12781,7 @@ dumpTransform(Archive *fout, const TransformInfo *transform)
1279712781FuncInfo *fromsqlFuncInfo = NULL;
1279812782FuncInfo *tosqlFuncInfo = NULL;
1279912783char *lanname;
12800- char *transformType;
12784+ const char *transformType;
1280112785
1280212786/* Skip if not to be dumped */
1280312787if (!transform->dobj.dump || dopt->dataOnly)
@@ -12904,7 +12888,6 @@ dumpTransform(Archive *fout, const TransformInfo *transform)
1290412888transform->dobj.catId, 0, transform->dobj.dumpId);
1290512889
1290612890free(lanname);
12907- free(transformType);
1290812891destroyPQExpBuffer(defqry);
1290912892destroyPQExpBuffer(delqry);
1291012893destroyPQExpBuffer(labelq);
@@ -14202,17 +14185,11 @@ format_aggregate_signature(const AggInfo *agginfo, Archive *fout, bool honor_quo
1420214185{
1420314186appendPQExpBufferChar(&buf, '(');
1420414187for (j = 0; j < agginfo->aggfn.nargs; j++)
14205- {
14206- char *typname;
14207-
14208- typname = getFormattedTypeName(fout, agginfo->aggfn.argtypes[j],
14209- zeroIsError);
14210-
1421114188appendPQExpBuffer(&buf, "%s%s",
1421214189 (j > 0) ? ", " : "",
14213- typname);
14214- free(typname);
14215- }
14190+ getFormattedTypeName(fout,
14191+ agginfo->aggfn.argtypes[j],
14192+ zeroIsError));
1421614193appendPQExpBufferChar(&buf, ')');
1421714194}
1421814195return buf.data;
@@ -18885,8 +18862,10 @@ findDumpableDependencies(ArchiveHandle *AH, const DumpableObject *dobj,
1888518862 *
1888618863 * This does not guarantee to schema-qualify the output, so it should not
1888718864 * be used to create the target object name for CREATE or ALTER commands.
18865+ *
18866+ * Note that the result is cached and must not be freed by the caller.
1888818867 */
18889- static char *
18868+ staticconst char *
1889018869getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
1889118870{
1889218871TypeInfo *typeInfo;
@@ -18897,15 +18876,15 @@ getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
1889718876if (oid == 0)
1889818877{
1889918878if ((opts & zeroAsStar) != 0)
18900- returnpg_strdup( "*") ;
18879+ return "*";
1890118880else if ((opts & zeroAsNone) != 0)
18902- returnpg_strdup( "NONE") ;
18881+ return "NONE";
1890318882}
1890418883
1890518884/* see if we have the result cached in the type's TypeInfo record */
1890618885typeInfo = findTypeByOid(oid);
1890718886if (typeInfo && typeInfo->ftypname)
18908- returnpg_strdup( typeInfo->ftypname) ;
18887+ return typeInfo->ftypname;
1890918888
1891018889query = createPQExpBuffer();
1891118890appendPQExpBuffer(query, "SELECT pg_catalog.format_type('%u'::pg_catalog.oid, NULL)",
@@ -18919,9 +18898,14 @@ getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
1891918898PQclear(res);
1892018899destroyPQExpBuffer(query);
1892118900
18922- /* cache a copy for later requests */
18901+ /*
18902+ * Cache the result for re-use in later requests, if possible. If we
18903+ * don't have a TypeInfo for the type, the string will be leaked once the
18904+ * caller is done with it ... but that case really should not happen, so
18905+ * leaking if it does seems acceptable.
18906+ */
1892318907if (typeInfo)
18924- typeInfo->ftypname =pg_strdup( result) ;
18908+ typeInfo->ftypname = result;
1892518909
1892618910return result;
1892718911}