@@ -262,7 +262,7 @@ static char *convertRegProcReference(const char *proc);
262262static char *getFormattedOperatorName(const char *oproid);
263263static char *convertTSFunction(Archive *fout, Oid funcOid);
264264static Oid findLastBuiltinOid_V71(Archive *fout);
265- static char *getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts);
265+ static const char *getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts);
266266static void getBlobs(Archive *fout);
267267static void dumpBlob(Archive *fout, const BlobInfo *binfo);
268268static int dumpBlobs(Archive *fout, const void *arg);
@@ -11121,13 +11121,9 @@ dumpBaseType(Archive *fout, const TypeInfo *tyinfo)
1112111121 appendPQExpBuffer(q, ",\n SUBSCRIPT = %s", typsubscript);
1112211122
1112311123 if (OidIsValid(tyinfo->typelem))
11124- {
11125- char *elemType;
11126-
11127- elemType = getFormattedTypeName(fout, tyinfo->typelem, zeroIsError);
11128- appendPQExpBuffer(q, ",\n ELEMENT = %s", elemType);
11129- free(elemType);
11130- }
11124+ appendPQExpBuffer(q, ",\n ELEMENT = %s",
11125+ getFormattedTypeName(fout, tyinfo->typelem,
11126+ zeroIsError));
1113111127
1113211128 if (strcmp(typcategory, "U") != 0)
1113311129 {
@@ -11931,7 +11927,7 @@ format_function_arguments_old(Archive *fout,
1193111927 for (j = 0; j < nallargs; j++)
1193211928 {
1193311929 Oid typid;
11934- char *typname;
11930+ const char *typname;
1193511931 const char *argmode;
1193611932 const char *argname;
1193711933
@@ -11970,7 +11966,6 @@ format_function_arguments_old(Archive *fout,
1197011966 argname ? fmtId(argname) : "",
1197111967 argname ? " " : "",
1197211968 typname);
11973- free(typname);
1197411969 }
1197511970 appendPQExpBufferChar(&fn, ')');
1197611971 return fn.data;
@@ -11999,15 +11994,12 @@ format_function_signature(Archive *fout, const FuncInfo *finfo, bool honor_quote
1199911994 appendPQExpBuffer(&fn, "%s(", finfo->dobj.name);
1200011995 for (j = 0; j < finfo->nargs; j++)
1200111996 {
12002- char *typname;
12003-
1200411997 if (j > 0)
1200511998 appendPQExpBufferStr(&fn, ", ");
1200611999
12007- typname = getFormattedTypeName(fout, finfo->argtypes[j],
12008- zeroIsError);
12009- appendPQExpBufferStr(&fn, typname);
12010- free(typname);
12000+ appendPQExpBufferStr(&fn,
12001+ getFormattedTypeName(fout, finfo->argtypes[j],
12002+ zeroIsError));
1201112003 }
1201212004 appendPQExpBufferChar(&fn, ')');
1201312005 return fn.data;
@@ -12052,7 +12044,6 @@ dumpFunc(Archive *fout, const FuncInfo *finfo)
1205212044 char *prosupport;
1205312045 char *proparallel;
1205412046 char *lanname;
12055- char *rettypename;
1205612047 int nallargs;
1205712048 char **allargtypes = NULL;
1205812049 char **argmodes = NULL;
@@ -12342,14 +12333,10 @@ dumpFunc(Archive *fout, const FuncInfo *finfo)
1234212333 else if (funcresult)
1234312334 appendPQExpBuffer(q, " RETURNS %s", funcresult);
1234412335 else
12345- {
12346- rettypename = getFormattedTypeName(fout, finfo->prorettype,
12347- zeroIsError);
1234812336 appendPQExpBuffer(q, " RETURNS %s%s",
1234912337 (proretset[0] == 't') ? "SETOF " : "",
12350- rettypename);
12351- free(rettypename);
12352- }
12338+ getFormattedTypeName(fout, finfo->prorettype,
12339+ zeroIsError));
1235312340
1235412341 appendPQExpBuffer(q, "\n LANGUAGE %s", fmtId(lanname));
1235512342
@@ -12556,8 +12543,8 @@ dumpCast(Archive *fout, const CastInfo *cast)
1255612543 PQExpBuffer labelq;
1255712544 PQExpBuffer castargs;
1255812545 FuncInfo *funcInfo = NULL;
12559- char *sourceType;
12560- char *targetType;
12546+ const char *sourceType;
12547+ const char *targetType;
1256112548
1256212549 /* Skip if not to be dumped */
1256312550 if (!cast->dobj.dump || dopt->dataOnly)
@@ -12643,9 +12630,6 @@ dumpCast(Archive *fout, const CastInfo *cast)
1264312630 NULL, "",
1264412631 cast->dobj.catId, 0, cast->dobj.dumpId);
1264512632
12646- free(sourceType);
12647- free(targetType);
12648-
1264912633 destroyPQExpBuffer(defqry);
1265012634 destroyPQExpBuffer(delqry);
1265112635 destroyPQExpBuffer(labelq);
@@ -12666,7 +12650,7 @@ dumpTransform(Archive *fout, const TransformInfo *transform)
1266612650 FuncInfo *fromsqlFuncInfo = NULL;
1266712651 FuncInfo *tosqlFuncInfo = NULL;
1266812652 char *lanname;
12669- char *transformType;
12653+ const char *transformType;
1267012654
1267112655 /* Skip if not to be dumped */
1267212656 if (!transform->dobj.dump || dopt->dataOnly)
@@ -12773,7 +12757,6 @@ dumpTransform(Archive *fout, const TransformInfo *transform)
1277312757 transform->dobj.catId, 0, transform->dobj.dumpId);
1277412758
1277512759 free(lanname);
12776- free(transformType);
1277712760 destroyPQExpBuffer(defqry);
1277812761 destroyPQExpBuffer(delqry);
1277912762 destroyPQExpBuffer(labelq);
@@ -14071,17 +14054,11 @@ format_aggregate_signature(const AggInfo *agginfo, Archive *fout, bool honor_quo
1407114054 {
1407214055 appendPQExpBufferChar(&buf, '(');
1407314056 for (j = 0; j < agginfo->aggfn.nargs; j++)
14074- {
14075- char *typname;
14076-
14077- typname = getFormattedTypeName(fout, agginfo->aggfn.argtypes[j],
14078- zeroIsError);
14079-
1408014057 appendPQExpBuffer(&buf, "%s%s",
1408114058 (j > 0) ? ", " : "",
14082- typname);
14083- free(typname);
14084- }
14059+ getFormattedTypeName(fout,
14060+ agginfo->aggfn.argtypes[j],
14061+ zeroIsError));
1408514062 appendPQExpBufferChar(&buf, ')');
1408614063 }
1408714064 return buf.data;
@@ -18754,8 +18731,10 @@ findDumpableDependencies(ArchiveHandle *AH, const DumpableObject *dobj,
1875418731 *
1875518732 * This does not guarantee to schema-qualify the output, so it should not
1875618733 * be used to create the target object name for CREATE or ALTER commands.
18734+ *
18735+ * Note that the result is cached and must not be freed by the caller.
1875718736 */
18758- static char *
18737+ static const char *
1875918738getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
1876018739{
1876118740 TypeInfo *typeInfo;
@@ -18766,15 +18745,15 @@ getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
1876618745 if (oid == 0)
1876718746 {
1876818747 if ((opts & zeroAsStar) != 0)
18769- return pg_strdup( "*") ;
18748+ return "*";
1877018749 else if ((opts & zeroAsNone) != 0)
18771- return pg_strdup( "NONE") ;
18750+ return "NONE";
1877218751 }
1877318752
1877418753 /* see if we have the result cached in the type's TypeInfo record */
1877518754 typeInfo = findTypeByOid(oid);
1877618755 if (typeInfo && typeInfo->ftypname)
18777- return pg_strdup( typeInfo->ftypname) ;
18756+ return typeInfo->ftypname;
1877818757
1877918758 query = createPQExpBuffer();
1878018759 appendPQExpBuffer(query, "SELECT pg_catalog.format_type('%u'::pg_catalog.oid, NULL)",
@@ -18788,9 +18767,14 @@ getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
1878818767 PQclear(res);
1878918768 destroyPQExpBuffer(query);
1879018769
18791- /* cache a copy for later requests */
18770+ /*
18771+ * Cache the result for re-use in later requests, if possible. If we
18772+ * don't have a TypeInfo for the type, the string will be leaked once the
18773+ * caller is done with it ... but that case really should not happen, so
18774+ * leaking if it does seems acceptable.
18775+ */
1879218776 if (typeInfo)
18793- typeInfo->ftypname = pg_strdup( result) ;
18777+ typeInfo->ftypname = result;
1879418778
1879518779 return result;
1879618780}
0 commit comments