diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 67be849829..2febcd4213 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -271,7 +271,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); @@ -11252,13 +11252,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) { @@ -12062,7 +12058,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; @@ -12101,7 +12097,6 @@ format_function_arguments_old(Archive *fout, argname ? fmtId(argname) : "", argname ? " " : "", typname); - free(typname); } appendPQExpBufferChar(&fn, ')'); return fn.data; @@ -12130,15 +12125,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; @@ -12183,7 +12175,6 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) char *prosupport; char *proparallel; char *lanname; - char *rettypename; int nallargs; char **allargtypes = NULL; char **argmodes = NULL; @@ -12473,14 +12464,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)); @@ -12687,8 +12674,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) @@ -12774,9 +12761,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); @@ -12797,7 +12781,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) @@ -12904,7 +12888,6 @@ dumpTransform(Archive *fout, const TransformInfo *transform) transform->dobj.catId, 0, transform->dobj.dumpId); free(lanname); - free(transformType); destroyPQExpBuffer(defqry); destroyPQExpBuffer(delqry); destroyPQExpBuffer(labelq); @@ -14202,17 +14185,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; @@ -18885,8 +18862,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; @@ -18897,15 +18876,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)", @@ -18919,9 +18898,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; }