mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-08-30 01:57:19 +02:00
Avoid useless malloc/free traffic around getFormattedTypeName().
Coverity complained that one caller of getFormattedTypeName() failed
to free the returned string. Which is true, but rather than fixing
that one, let's get rid of this tedious and error-prone requirement.
Now that getFormattedTypeName() caches its result, strdup'ing that
result and expecting the caller to free it accomplishes little except
to waste cycles. We do create a leak in the case where getTypes didn't
make a TypeInfo for the type, but that basically shouldn't ever happen.
Back-patch, as commit 6c450a861
was. This isn't a particularly
interesting bug fix, but the API change seems like a hazard for
future back-patching activity if we don't back-patch it.
This commit is contained in:
parent
cbba6ba3a0
commit
da7d81dd05
@ -255,7 +255,7 @@ static char *convertRegProcReference(Archive *fout,
|
|||||||
static char *getFormattedOperatorName(Archive *fout, const char *oproid);
|
static char *getFormattedOperatorName(Archive *fout, const char *oproid);
|
||||||
static char *convertTSFunction(Archive *fout, Oid funcOid);
|
static char *convertTSFunction(Archive *fout, Oid funcOid);
|
||||||
static Oid findLastBuiltinOid_V71(Archive *fout);
|
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 getBlobs(Archive *fout);
|
||||||
static void dumpBlob(Archive *fout, BlobInfo *binfo);
|
static void dumpBlob(Archive *fout, BlobInfo *binfo);
|
||||||
static int dumpBlobs(Archive *fout, void *arg);
|
static int dumpBlobs(Archive *fout, void *arg);
|
||||||
@ -11009,13 +11009,9 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (OidIsValid(tyinfo->typelem))
|
if (OidIsValid(tyinfo->typelem))
|
||||||
{
|
appendPQExpBuffer(q, ",\n ELEMENT = %s",
|
||||||
char *elemType;
|
getFormattedTypeName(fout, tyinfo->typelem,
|
||||||
|
zeroIsError));
|
||||||
elemType = getFormattedTypeName(fout, tyinfo->typelem, zeroIsError);
|
|
||||||
appendPQExpBuffer(q, ",\n ELEMENT = %s", elemType);
|
|
||||||
free(elemType);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(typcategory, "U") != 0)
|
if (strcmp(typcategory, "U") != 0)
|
||||||
{
|
{
|
||||||
@ -11818,7 +11814,7 @@ format_function_arguments_old(Archive *fout,
|
|||||||
for (j = 0; j < nallargs; j++)
|
for (j = 0; j < nallargs; j++)
|
||||||
{
|
{
|
||||||
Oid typid;
|
Oid typid;
|
||||||
char *typname;
|
const char *typname;
|
||||||
const char *argmode;
|
const char *argmode;
|
||||||
const char *argname;
|
const char *argname;
|
||||||
|
|
||||||
@ -11857,7 +11853,6 @@ format_function_arguments_old(Archive *fout,
|
|||||||
argname ? fmtId(argname) : "",
|
argname ? fmtId(argname) : "",
|
||||||
argname ? " " : "",
|
argname ? " " : "",
|
||||||
typname);
|
typname);
|
||||||
free(typname);
|
|
||||||
}
|
}
|
||||||
appendPQExpBufferChar(&fn, ')');
|
appendPQExpBufferChar(&fn, ')');
|
||||||
return fn.data;
|
return fn.data;
|
||||||
@ -11886,15 +11881,12 @@ format_function_signature(Archive *fout, FuncInfo *finfo, bool honor_quotes)
|
|||||||
appendPQExpBuffer(&fn, "%s(", finfo->dobj.name);
|
appendPQExpBuffer(&fn, "%s(", finfo->dobj.name);
|
||||||
for (j = 0; j < finfo->nargs; j++)
|
for (j = 0; j < finfo->nargs; j++)
|
||||||
{
|
{
|
||||||
char *typname;
|
|
||||||
|
|
||||||
if (j > 0)
|
if (j > 0)
|
||||||
appendPQExpBufferStr(&fn, ", ");
|
appendPQExpBufferStr(&fn, ", ");
|
||||||
|
|
||||||
typname = getFormattedTypeName(fout, finfo->argtypes[j],
|
appendPQExpBufferStr(&fn,
|
||||||
zeroIsError);
|
getFormattedTypeName(fout, finfo->argtypes[j],
|
||||||
appendPQExpBufferStr(&fn, typname);
|
zeroIsError));
|
||||||
free(typname);
|
|
||||||
}
|
}
|
||||||
appendPQExpBufferChar(&fn, ')');
|
appendPQExpBufferChar(&fn, ')');
|
||||||
return fn.data;
|
return fn.data;
|
||||||
@ -11938,7 +11930,6 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
|
|||||||
char *prosupport;
|
char *prosupport;
|
||||||
char *proparallel;
|
char *proparallel;
|
||||||
char *lanname;
|
char *lanname;
|
||||||
char *rettypename;
|
|
||||||
int nallargs;
|
int nallargs;
|
||||||
char **allargtypes = NULL;
|
char **allargtypes = NULL;
|
||||||
char **argmodes = NULL;
|
char **argmodes = NULL;
|
||||||
@ -12295,14 +12286,10 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
|
|||||||
else if (funcresult)
|
else if (funcresult)
|
||||||
appendPQExpBuffer(q, " RETURNS %s", funcresult);
|
appendPQExpBuffer(q, " RETURNS %s", funcresult);
|
||||||
else
|
else
|
||||||
{
|
|
||||||
rettypename = getFormattedTypeName(fout, finfo->prorettype,
|
|
||||||
zeroIsError);
|
|
||||||
appendPQExpBuffer(q, " RETURNS %s%s",
|
appendPQExpBuffer(q, " RETURNS %s%s",
|
||||||
(proretset[0] == 't') ? "SETOF " : "",
|
(proretset[0] == 't') ? "SETOF " : "",
|
||||||
rettypename);
|
getFormattedTypeName(fout, finfo->prorettype,
|
||||||
free(rettypename);
|
zeroIsError));
|
||||||
}
|
|
||||||
|
|
||||||
appendPQExpBuffer(q, "\n LANGUAGE %s", fmtId(lanname));
|
appendPQExpBuffer(q, "\n LANGUAGE %s", fmtId(lanname));
|
||||||
|
|
||||||
@ -12509,8 +12496,8 @@ dumpCast(Archive *fout, CastInfo *cast)
|
|||||||
PQExpBuffer labelq;
|
PQExpBuffer labelq;
|
||||||
PQExpBuffer castargs;
|
PQExpBuffer castargs;
|
||||||
FuncInfo *funcInfo = NULL;
|
FuncInfo *funcInfo = NULL;
|
||||||
char *sourceType;
|
const char *sourceType;
|
||||||
char *targetType;
|
const char *targetType;
|
||||||
|
|
||||||
/* Skip if not to be dumped */
|
/* Skip if not to be dumped */
|
||||||
if (!cast->dobj.dump || dopt->dataOnly)
|
if (!cast->dobj.dump || dopt->dataOnly)
|
||||||
@ -12596,9 +12583,6 @@ dumpCast(Archive *fout, CastInfo *cast)
|
|||||||
NULL, "",
|
NULL, "",
|
||||||
cast->dobj.catId, 0, cast->dobj.dumpId);
|
cast->dobj.catId, 0, cast->dobj.dumpId);
|
||||||
|
|
||||||
free(sourceType);
|
|
||||||
free(targetType);
|
|
||||||
|
|
||||||
destroyPQExpBuffer(defqry);
|
destroyPQExpBuffer(defqry);
|
||||||
destroyPQExpBuffer(delqry);
|
destroyPQExpBuffer(delqry);
|
||||||
destroyPQExpBuffer(labelq);
|
destroyPQExpBuffer(labelq);
|
||||||
@ -12619,7 +12603,7 @@ dumpTransform(Archive *fout, TransformInfo *transform)
|
|||||||
FuncInfo *fromsqlFuncInfo = NULL;
|
FuncInfo *fromsqlFuncInfo = NULL;
|
||||||
FuncInfo *tosqlFuncInfo = NULL;
|
FuncInfo *tosqlFuncInfo = NULL;
|
||||||
char *lanname;
|
char *lanname;
|
||||||
char *transformType;
|
const char *transformType;
|
||||||
|
|
||||||
/* Skip if not to be dumped */
|
/* Skip if not to be dumped */
|
||||||
if (!transform->dobj.dump || dopt->dataOnly)
|
if (!transform->dobj.dump || dopt->dataOnly)
|
||||||
@ -12726,7 +12710,6 @@ dumpTransform(Archive *fout, TransformInfo *transform)
|
|||||||
transform->dobj.catId, 0, transform->dobj.dumpId);
|
transform->dobj.catId, 0, transform->dobj.dumpId);
|
||||||
|
|
||||||
free(lanname);
|
free(lanname);
|
||||||
free(transformType);
|
|
||||||
destroyPQExpBuffer(defqry);
|
destroyPQExpBuffer(defqry);
|
||||||
destroyPQExpBuffer(delqry);
|
destroyPQExpBuffer(delqry);
|
||||||
destroyPQExpBuffer(labelq);
|
destroyPQExpBuffer(labelq);
|
||||||
@ -14018,17 +14001,11 @@ format_aggregate_signature(AggInfo *agginfo, Archive *fout, bool honor_quotes)
|
|||||||
{
|
{
|
||||||
appendPQExpBufferChar(&buf, '(');
|
appendPQExpBufferChar(&buf, '(');
|
||||||
for (j = 0; j < agginfo->aggfn.nargs; j++)
|
for (j = 0; j < agginfo->aggfn.nargs; j++)
|
||||||
{
|
|
||||||
char *typname;
|
|
||||||
|
|
||||||
typname = getFormattedTypeName(fout, agginfo->aggfn.argtypes[j],
|
|
||||||
zeroIsError);
|
|
||||||
|
|
||||||
appendPQExpBuffer(&buf, "%s%s",
|
appendPQExpBuffer(&buf, "%s%s",
|
||||||
(j > 0) ? ", " : "",
|
(j > 0) ? ", " : "",
|
||||||
typname);
|
getFormattedTypeName(fout,
|
||||||
free(typname);
|
agginfo->aggfn.argtypes[j],
|
||||||
}
|
zeroIsError));
|
||||||
appendPQExpBufferChar(&buf, ')');
|
appendPQExpBufferChar(&buf, ')');
|
||||||
}
|
}
|
||||||
return buf.data;
|
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
|
* 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.
|
* 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)
|
getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
|
||||||
{
|
{
|
||||||
TypeInfo *typeInfo;
|
TypeInfo *typeInfo;
|
||||||
@ -18740,15 +18719,15 @@ getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
|
|||||||
if (oid == 0)
|
if (oid == 0)
|
||||||
{
|
{
|
||||||
if ((opts & zeroAsStar) != 0)
|
if ((opts & zeroAsStar) != 0)
|
||||||
return pg_strdup("*");
|
return "*";
|
||||||
else if ((opts & zeroAsNone) != 0)
|
else if ((opts & zeroAsNone) != 0)
|
||||||
return pg_strdup("NONE");
|
return "NONE";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* see if we have the result cached in the type's TypeInfo record */
|
/* see if we have the result cached in the type's TypeInfo record */
|
||||||
typeInfo = findTypeByOid(oid);
|
typeInfo = findTypeByOid(oid);
|
||||||
if (typeInfo && typeInfo->ftypname)
|
if (typeInfo && typeInfo->ftypname)
|
||||||
return pg_strdup(typeInfo->ftypname);
|
return typeInfo->ftypname;
|
||||||
|
|
||||||
query = createPQExpBuffer();
|
query = createPQExpBuffer();
|
||||||
appendPQExpBuffer(query, "SELECT pg_catalog.format_type('%u'::pg_catalog.oid, NULL)",
|
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);
|
PQclear(res);
|
||||||
destroyPQExpBuffer(query);
|
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)
|
if (typeInfo)
|
||||||
typeInfo->ftypname = pg_strdup(result);
|
typeInfo->ftypname = result;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user