diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 7d2baf0504..a2dc42e278 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -262,7 +262,7 @@ static char *convertRegProcReference(const char *proc); static char *getFormattedOperatorName(const char *oproid); static char *convertTSFunction(Archive *fout, Oid funcOid); static Oid findLastBuiltinOid_V71(Archive *fout); -static char *getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts); +static const char *getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts); static void getBlobs(Archive *fout); static void dumpBlob(Archive *fout, const BlobInfo *binfo); static int dumpBlobs(Archive *fout, const void *arg); @@ -11121,13 +11121,9 @@ dumpBaseType(Archive *fout, const TypeInfo *tyinfo) appendPQExpBuffer(q, ",\n SUBSCRIPT = %s", typsubscript); if (OidIsValid(tyinfo->typelem)) - { - char *elemType; - - elemType = getFormattedTypeName(fout, tyinfo->typelem, zeroIsError); - appendPQExpBuffer(q, ",\n ELEMENT = %s", elemType); - free(elemType); - } + appendPQExpBuffer(q, ",\n ELEMENT = %s", + getFormattedTypeName(fout, tyinfo->typelem, + zeroIsError)); if (strcmp(typcategory, "U") != 0) { @@ -11931,7 +11927,7 @@ format_function_arguments_old(Archive *fout, for (j = 0; j < nallargs; j++) { Oid typid; - char *typname; + const char *typname; const char *argmode; const char *argname; @@ -11970,7 +11966,6 @@ format_function_arguments_old(Archive *fout, argname ? fmtId(argname) : "", argname ? " " : "", typname); - free(typname); } appendPQExpBufferChar(&fn, ')'); return fn.data; @@ -11999,15 +11994,12 @@ format_function_signature(Archive *fout, const FuncInfo *finfo, bool honor_quote appendPQExpBuffer(&fn, "%s(", finfo->dobj.name); for (j = 0; j < finfo->nargs; j++) { - char *typname; - if (j > 0) appendPQExpBufferStr(&fn, ", "); - typname = getFormattedTypeName(fout, finfo->argtypes[j], - zeroIsError); - appendPQExpBufferStr(&fn, typname); - free(typname); + appendPQExpBufferStr(&fn, + getFormattedTypeName(fout, finfo->argtypes[j], + zeroIsError)); } appendPQExpBufferChar(&fn, ')'); return fn.data; @@ -12052,7 +12044,6 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) char *prosupport; char *proparallel; char *lanname; - char *rettypename; int nallargs; char **allargtypes = NULL; char **argmodes = NULL; @@ -12342,14 +12333,10 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) else if (funcresult) appendPQExpBuffer(q, " RETURNS %s", funcresult); else - { - rettypename = getFormattedTypeName(fout, finfo->prorettype, - zeroIsError); appendPQExpBuffer(q, " RETURNS %s%s", (proretset[0] == 't') ? "SETOF " : "", - rettypename); - free(rettypename); - } + getFormattedTypeName(fout, finfo->prorettype, + zeroIsError)); appendPQExpBuffer(q, "\n LANGUAGE %s", fmtId(lanname)); @@ -12556,8 +12543,8 @@ dumpCast(Archive *fout, const CastInfo *cast) PQExpBuffer labelq; PQExpBuffer castargs; FuncInfo *funcInfo = NULL; - char *sourceType; - char *targetType; + const char *sourceType; + const char *targetType; /* Skip if not to be dumped */ if (!cast->dobj.dump || dopt->dataOnly) @@ -12643,9 +12630,6 @@ dumpCast(Archive *fout, const CastInfo *cast) NULL, "", cast->dobj.catId, 0, cast->dobj.dumpId); - free(sourceType); - free(targetType); - destroyPQExpBuffer(defqry); destroyPQExpBuffer(delqry); destroyPQExpBuffer(labelq); @@ -12666,7 +12650,7 @@ dumpTransform(Archive *fout, const TransformInfo *transform) FuncInfo *fromsqlFuncInfo = NULL; FuncInfo *tosqlFuncInfo = NULL; char *lanname; - char *transformType; + const char *transformType; /* Skip if not to be dumped */ if (!transform->dobj.dump || dopt->dataOnly) @@ -12773,7 +12757,6 @@ dumpTransform(Archive *fout, const TransformInfo *transform) transform->dobj.catId, 0, transform->dobj.dumpId); free(lanname); - free(transformType); destroyPQExpBuffer(defqry); destroyPQExpBuffer(delqry); destroyPQExpBuffer(labelq); @@ -14071,17 +14054,11 @@ format_aggregate_signature(const AggInfo *agginfo, Archive *fout, bool honor_quo { appendPQExpBufferChar(&buf, '('); for (j = 0; j < agginfo->aggfn.nargs; j++) - { - char *typname; - - typname = getFormattedTypeName(fout, agginfo->aggfn.argtypes[j], - zeroIsError); - appendPQExpBuffer(&buf, "%s%s", (j > 0) ? ", " : "", - typname); - free(typname); - } + getFormattedTypeName(fout, + agginfo->aggfn.argtypes[j], + zeroIsError)); appendPQExpBufferChar(&buf, ')'); } return buf.data; @@ -18754,8 +18731,10 @@ findDumpableDependencies(ArchiveHandle *AH, const DumpableObject *dobj, * * This does not guarantee to schema-qualify the output, so it should not * be used to create the target object name for CREATE or ALTER commands. + * + * Note that the result is cached and must not be freed by the caller. */ -static char * +static const char * getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts) { TypeInfo *typeInfo; @@ -18766,15 +18745,15 @@ getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts) if (oid == 0) { if ((opts & zeroAsStar) != 0) - return pg_strdup("*"); + return "*"; else if ((opts & zeroAsNone) != 0) - return pg_strdup("NONE"); + return "NONE"; } /* see if we have the result cached in the type's TypeInfo record */ typeInfo = findTypeByOid(oid); if (typeInfo && typeInfo->ftypname) - return pg_strdup(typeInfo->ftypname); + return typeInfo->ftypname; query = createPQExpBuffer(); appendPQExpBuffer(query, "SELECT pg_catalog.format_type('%u'::pg_catalog.oid, NULL)", @@ -18788,9 +18767,14 @@ getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts) PQclear(res); destroyPQExpBuffer(query); - /* cache a copy for later requests */ + /* + * Cache the result for re-use in later requests, if possible. If we + * don't have a TypeInfo for the type, the string will be leaked once the + * caller is done with it ... but that case really should not happen, so + * leaking if it does seems acceptable. + */ if (typeInfo) - typeInfo->ftypname = pg_strdup(result); + typeInfo->ftypname = result; return result; }