@@ -262,7 +262,7 @@ static char *convertRegProcReference(const char *proc);
262
262
static char *getFormattedOperatorName(const char *oproid);
263
263
static char *convertTSFunction(Archive *fout, Oid funcOid);
264
264
static 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);
266
266
static void getBlobs(Archive *fout);
267
267
static void dumpBlob(Archive *fout, const BlobInfo *binfo);
268
268
static int dumpBlobs(Archive *fout, const void *arg);
@@ -11121,13 +11121,9 @@ dumpBaseType(Archive *fout, const TypeInfo *tyinfo)
11121
11121
appendPQExpBuffer(q, ",\n SUBSCRIPT = %s", typsubscript);
11122
11122
11123
11123
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));
11131
11127
11132
11128
if (strcmp(typcategory, "U") != 0)
11133
11129
{
@@ -11931,7 +11927,7 @@ format_function_arguments_old(Archive *fout,
11931
11927
for (j = 0; j < nallargs; j++)
11932
11928
{
11933
11929
Oid typid;
11934
- char *typname;
11930
+ const char *typname;
11935
11931
const char *argmode;
11936
11932
const char *argname;
11937
11933
@@ -11970,7 +11966,6 @@ format_function_arguments_old(Archive *fout,
11970
11966
argname ? fmtId(argname) : "",
11971
11967
argname ? " " : "",
11972
11968
typname);
11973
- free(typname);
11974
11969
}
11975
11970
appendPQExpBufferChar(&fn, ')');
11976
11971
return fn.data;
@@ -11999,15 +11994,12 @@ format_function_signature(Archive *fout, const FuncInfo *finfo, bool honor_quote
11999
11994
appendPQExpBuffer(&fn, "%s(", finfo->dobj.name);
12000
11995
for (j = 0; j < finfo->nargs; j++)
12001
11996
{
12002
- char *typname;
12003
-
12004
11997
if (j > 0)
12005
11998
appendPQExpBufferStr(&fn, ", ");
12006
11999
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));
12011
12003
}
12012
12004
appendPQExpBufferChar(&fn, ')');
12013
12005
return fn.data;
@@ -12052,7 +12044,6 @@ dumpFunc(Archive *fout, const FuncInfo *finfo)
12052
12044
char *prosupport;
12053
12045
char *proparallel;
12054
12046
char *lanname;
12055
- char *rettypename;
12056
12047
int nallargs;
12057
12048
char **allargtypes = NULL;
12058
12049
char **argmodes = NULL;
@@ -12342,14 +12333,10 @@ dumpFunc(Archive *fout, const FuncInfo *finfo)
12342
12333
else if (funcresult)
12343
12334
appendPQExpBuffer(q, " RETURNS %s", funcresult);
12344
12335
else
12345
- {
12346
- rettypename = getFormattedTypeName(fout, finfo->prorettype,
12347
- zeroIsError);
12348
12336
appendPQExpBuffer(q, " RETURNS %s%s",
12349
12337
(proretset[0] == 't') ? "SETOF " : "",
12350
- rettypename);
12351
- free(rettypename);
12352
- }
12338
+ getFormattedTypeName(fout, finfo->prorettype,
12339
+ zeroIsError));
12353
12340
12354
12341
appendPQExpBuffer(q, "\n LANGUAGE %s", fmtId(lanname));
12355
12342
@@ -12556,8 +12543,8 @@ dumpCast(Archive *fout, const CastInfo *cast)
12556
12543
PQExpBuffer labelq;
12557
12544
PQExpBuffer castargs;
12558
12545
FuncInfo *funcInfo = NULL;
12559
- char *sourceType;
12560
- char *targetType;
12546
+ const char *sourceType;
12547
+ const char *targetType;
12561
12548
12562
12549
/* Skip if not to be dumped */
12563
12550
if (!cast->dobj.dump || dopt->dataOnly)
@@ -12643,9 +12630,6 @@ dumpCast(Archive *fout, const CastInfo *cast)
12643
12630
NULL, "",
12644
12631
cast->dobj.catId, 0, cast->dobj.dumpId);
12645
12632
12646
- free(sourceType);
12647
- free(targetType);
12648
-
12649
12633
destroyPQExpBuffer(defqry);
12650
12634
destroyPQExpBuffer(delqry);
12651
12635
destroyPQExpBuffer(labelq);
@@ -12666,7 +12650,7 @@ dumpTransform(Archive *fout, const TransformInfo *transform)
12666
12650
FuncInfo *fromsqlFuncInfo = NULL;
12667
12651
FuncInfo *tosqlFuncInfo = NULL;
12668
12652
char *lanname;
12669
- char *transformType;
12653
+ const char *transformType;
12670
12654
12671
12655
/* Skip if not to be dumped */
12672
12656
if (!transform->dobj.dump || dopt->dataOnly)
@@ -12773,7 +12757,6 @@ dumpTransform(Archive *fout, const TransformInfo *transform)
12773
12757
transform->dobj.catId, 0, transform->dobj.dumpId);
12774
12758
12775
12759
free(lanname);
12776
- free(transformType);
12777
12760
destroyPQExpBuffer(defqry);
12778
12761
destroyPQExpBuffer(delqry);
12779
12762
destroyPQExpBuffer(labelq);
@@ -14071,17 +14054,11 @@ format_aggregate_signature(const AggInfo *agginfo, Archive *fout, bool honor_quo
14071
14054
{
14072
14055
appendPQExpBufferChar(&buf, '(');
14073
14056
for (j = 0; j < agginfo->aggfn.nargs; j++)
14074
- {
14075
- char *typname;
14076
-
14077
- typname = getFormattedTypeName(fout, agginfo->aggfn.argtypes[j],
14078
- zeroIsError);
14079
-
14080
14057
appendPQExpBuffer(&buf, "%s%s",
14081
14058
(j > 0) ? ", " : "",
14082
- typname);
14083
- free(typname);
14084
- }
14059
+ getFormattedTypeName(fout,
14060
+ agginfo->aggfn.argtypes[j],
14061
+ zeroIsError));
14085
14062
appendPQExpBufferChar(&buf, ')');
14086
14063
}
14087
14064
return buf.data;
@@ -18754,8 +18731,10 @@ findDumpableDependencies(ArchiveHandle *AH, const DumpableObject *dobj,
18754
18731
*
18755
18732
* This does not guarantee to schema-qualify the output, so it should not
18756
18733
* 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.
18757
18736
*/
18758
- static char *
18737
+ static const char *
18759
18738
getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
18760
18739
{
18761
18740
TypeInfo *typeInfo;
@@ -18766,15 +18745,15 @@ getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
18766
18745
if (oid == 0)
18767
18746
{
18768
18747
if ((opts & zeroAsStar) != 0)
18769
- return pg_strdup( "*") ;
18748
+ return "*";
18770
18749
else if ((opts & zeroAsNone) != 0)
18771
- return pg_strdup( "NONE") ;
18750
+ return "NONE";
18772
18751
}
18773
18752
18774
18753
/* see if we have the result cached in the type's TypeInfo record */
18775
18754
typeInfo = findTypeByOid(oid);
18776
18755
if (typeInfo && typeInfo->ftypname)
18777
- return pg_strdup( typeInfo->ftypname) ;
18756
+ return typeInfo->ftypname;
18778
18757
18779
18758
query = createPQExpBuffer();
18780
18759
appendPQExpBuffer(query, "SELECT pg_catalog.format_type('%u'::pg_catalog.oid, NULL)",
@@ -18788,9 +18767,14 @@ getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
18788
18767
PQclear(res);
18789
18768
destroyPQExpBuffer(query);
18790
18769
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
+ */
18792
18776
if (typeInfo)
18793
- typeInfo->ftypname = pg_strdup( result) ;
18777
+ typeInfo->ftypname = result;
18794
18778
18795
18779
return result;
18796
18780
}
0 commit comments