@@ -271,7 +271,7 @@ static char *convertRegProcReference(const char *proc);
271
271
static char *getFormattedOperatorName(const char *oproid);
272
272
static char *convertTSFunction(Archive *fout, Oid funcOid);
273
273
static Oid findLastBuiltinOid_V71(Archive *fout);
274
- static char *getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts);
274
+ static const char *getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts);
275
275
static void getBlobs(Archive *fout);
276
276
static void dumpBlob(Archive *fout, const BlobInfo *binfo);
277
277
static int dumpBlobs(Archive *fout, const void *arg);
@@ -11252,13 +11252,9 @@ dumpBaseType(Archive *fout, const TypeInfo *tyinfo)
11252
11252
appendPQExpBuffer(q, ",\n SUBSCRIPT = %s", typsubscript);
11253
11253
11254
11254
if (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));
11262
11258
11263
11259
if (strcmp(typcategory, "U") != 0)
11264
11260
{
@@ -12062,7 +12058,7 @@ format_function_arguments_old(Archive *fout,
12062
12058
for (j = 0; j < nallargs; j++)
12063
12059
{
12064
12060
Oid typid;
12065
- char *typname;
12061
+ const char *typname;
12066
12062
const char *argmode;
12067
12063
const char *argname;
12068
12064
@@ -12101,7 +12097,6 @@ format_function_arguments_old(Archive *fout,
12101
12097
argname ? fmtId(argname) : "",
12102
12098
argname ? " " : "",
12103
12099
typname);
12104
- free(typname);
12105
12100
}
12106
12101
appendPQExpBufferChar(&fn, ')');
12107
12102
return fn.data;
@@ -12130,15 +12125,12 @@ format_function_signature(Archive *fout, const FuncInfo *finfo, bool honor_quote
12130
12125
appendPQExpBuffer(&fn, "%s(", finfo->dobj.name);
12131
12126
for (j = 0; j < finfo->nargs; j++)
12132
12127
{
12133
- char *typname;
12134
-
12135
12128
if (j > 0)
12136
12129
appendPQExpBufferStr(&fn, ", ");
12137
12130
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));
12142
12134
}
12143
12135
appendPQExpBufferChar(&fn, ')');
12144
12136
return fn.data;
@@ -12183,7 +12175,6 @@ dumpFunc(Archive *fout, const FuncInfo *finfo)
12183
12175
char *prosupport;
12184
12176
char *proparallel;
12185
12177
char *lanname;
12186
- char *rettypename;
12187
12178
int nallargs;
12188
12179
char **allargtypes = NULL;
12189
12180
char **argmodes = NULL;
@@ -12473,14 +12464,10 @@ dumpFunc(Archive *fout, const FuncInfo *finfo)
12473
12464
else if (funcresult)
12474
12465
appendPQExpBuffer(q, " RETURNS %s", funcresult);
12475
12466
else
12476
- {
12477
- rettypename = getFormattedTypeName(fout, finfo->prorettype,
12478
- zeroIsError);
12479
12467
appendPQExpBuffer(q, " RETURNS %s%s",
12480
12468
(proretset[0] == 't') ? "SETOF " : "",
12481
- rettypename);
12482
- free(rettypename);
12483
- }
12469
+ getFormattedTypeName(fout, finfo->prorettype,
12470
+ zeroIsError));
12484
12471
12485
12472
appendPQExpBuffer(q, "\n LANGUAGE %s", fmtId(lanname));
12486
12473
@@ -12687,8 +12674,8 @@ dumpCast(Archive *fout, const CastInfo *cast)
12687
12674
PQExpBuffer labelq;
12688
12675
PQExpBuffer castargs;
12689
12676
FuncInfo *funcInfo = NULL;
12690
- char *sourceType;
12691
- char *targetType;
12677
+ const char *sourceType;
12678
+ const char *targetType;
12692
12679
12693
12680
/* Skip if not to be dumped */
12694
12681
if (!cast->dobj.dump || dopt->dataOnly)
@@ -12774,9 +12761,6 @@ dumpCast(Archive *fout, const CastInfo *cast)
12774
12761
NULL, "",
12775
12762
cast->dobj.catId, 0, cast->dobj.dumpId);
12776
12763
12777
- free(sourceType);
12778
- free(targetType);
12779
-
12780
12764
destroyPQExpBuffer(defqry);
12781
12765
destroyPQExpBuffer(delqry);
12782
12766
destroyPQExpBuffer(labelq);
@@ -12797,7 +12781,7 @@ dumpTransform(Archive *fout, const TransformInfo *transform)
12797
12781
FuncInfo *fromsqlFuncInfo = NULL;
12798
12782
FuncInfo *tosqlFuncInfo = NULL;
12799
12783
char *lanname;
12800
- char *transformType;
12784
+ const char *transformType;
12801
12785
12802
12786
/* Skip if not to be dumped */
12803
12787
if (!transform->dobj.dump || dopt->dataOnly)
@@ -12904,7 +12888,6 @@ dumpTransform(Archive *fout, const TransformInfo *transform)
12904
12888
transform->dobj.catId, 0, transform->dobj.dumpId);
12905
12889
12906
12890
free(lanname);
12907
- free(transformType);
12908
12891
destroyPQExpBuffer(defqry);
12909
12892
destroyPQExpBuffer(delqry);
12910
12893
destroyPQExpBuffer(labelq);
@@ -14202,17 +14185,11 @@ format_aggregate_signature(const AggInfo *agginfo, Archive *fout, bool honor_quo
14202
14185
{
14203
14186
appendPQExpBufferChar(&buf, '(');
14204
14187
for (j = 0; j < agginfo->aggfn.nargs; j++)
14205
- {
14206
- char *typname;
14207
-
14208
- typname = getFormattedTypeName(fout, agginfo->aggfn.argtypes[j],
14209
- zeroIsError);
14210
-
14211
14188
appendPQExpBuffer(&buf, "%s%s",
14212
14189
(j > 0) ? ", " : "",
14213
- typname);
14214
- free(typname);
14215
- }
14190
+ getFormattedTypeName(fout,
14191
+ agginfo->aggfn.argtypes[j],
14192
+ zeroIsError));
14216
14193
appendPQExpBufferChar(&buf, ')');
14217
14194
}
14218
14195
return buf.data;
@@ -18885,8 +18862,10 @@ findDumpableDependencies(ArchiveHandle *AH, const DumpableObject *dobj,
18885
18862
*
18886
18863
* This does not guarantee to schema-qualify the output, so it should not
18887
18864
* 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.
18888
18867
*/
18889
- static char *
18868
+ static const char *
18890
18869
getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
18891
18870
{
18892
18871
TypeInfo *typeInfo;
@@ -18897,15 +18876,15 @@ getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
18897
18876
if (oid == 0)
18898
18877
{
18899
18878
if ((opts & zeroAsStar) != 0)
18900
- return pg_strdup( "*") ;
18879
+ return "*";
18901
18880
else if ((opts & zeroAsNone) != 0)
18902
- return pg_strdup( "NONE") ;
18881
+ return "NONE";
18903
18882
}
18904
18883
18905
18884
/* see if we have the result cached in the type's TypeInfo record */
18906
18885
typeInfo = findTypeByOid(oid);
18907
18886
if (typeInfo && typeInfo->ftypname)
18908
- return pg_strdup( typeInfo->ftypname) ;
18887
+ return typeInfo->ftypname;
18909
18888
18910
18889
query = createPQExpBuffer();
18911
18890
appendPQExpBuffer(query, "SELECT pg_catalog.format_type('%u'::pg_catalog.oid, NULL)",
@@ -18919,9 +18898,14 @@ getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
18919
18898
PQclear(res);
18920
18899
destroyPQExpBuffer(query);
18921
18900
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
+ */
18923
18907
if (typeInfo)
18924
- typeInfo->ftypname = pg_strdup( result) ;
18908
+ typeInfo->ftypname = result;
18925
18909
18926
18910
return result;
18927
18911
}
0 commit comments