diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 4f261e8bf6..e2a5bee960 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -255,7 +255,7 @@ static char *convertRegProcReference(Archive *fout, static char *getFormattedOperatorName(Archive *fout, 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, BlobInfo *binfo); static int dumpBlobs(Archive *fout, void *arg); @@ -11009,13 +11009,9 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo) } 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) { @@ -11818,7 +11814,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; @@ -11857,7 +11853,6 @@ format_function_arguments_old(Archive *fout, argname ? fmtId(argname) : "", argname ? " " : "", typname); - free(typname); } appendPQExpBufferChar(&fn, ')'); return fn.data; @@ -11886,15 +11881,12 @@ format_function_signature(Archive *fout, FuncInfo *finfo, bool honor_quotes) 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; @@ -11938,7 +11930,6 @@ dumpFunc(Archive *fout, FuncInfo *finfo) char *prosupport; char *proparallel; char *lanname; - char *rettypename; int nallargs; char **allargtypes = NULL; char **argmodes = NULL; @@ -12295,14 +12286,10 @@ dumpFunc(Archive *fout, 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)); @@ -12509,8 +12496,8 @@ dumpCast(Archive *fout, 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) @@ -12596,9 +12583,6 @@ dumpCast(Archive *fout, CastInfo *cast) NULL, "", cast->dobj.catId, 0, cast->dobj.dumpId); - free(sourceType); - free(targetType); - destroyPQExpBuffer(defqry); destroyPQExpBuffer(delqry); destroyPQExpBuffer(labelq); @@ -12619,7 +12603,7 @@ dumpTransform(Archive *fout, 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) @@ -12726,7 +12710,6 @@ dumpTransform(Archive *fout, TransformInfo *transform) transform->dobj.catId, 0, transform->dobj.dumpId); free(lanname); - free(transformType); destroyPQExpBuffer(defqry); destroyPQExpBuffer(delqry); destroyPQExpBuffer(labelq); @@ -14018,17 +14001,11 @@ format_aggregate_signature(AggInfo *agginfo, Archive *fout, bool honor_quotes) { 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; @@ -18728,8 +18705,10 @@ findDumpableDependencies(ArchiveHandle *AH, 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; @@ -18740,15 +18719,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)", @@ -18762,9 +18741,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; }