1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-29 10:41:53 +03:00

Make use of qsort_arg in several places that were formerly using klugy

static variables.  This avoids any risk of potential non-reentrancy,
and in particular offers a much cleaner workaround for the Intel compiler
bug that was affecting ginutil.c.
This commit is contained in:
Tom Lane
2006-10-05 17:57:40 +00:00
parent f2332ea1e9
commit e378f82e00
6 changed files with 77 additions and 88 deletions

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/gin/ginutil.c,v 1.7 2006/10/04 00:29:48 momjian Exp $
* $PostgreSQL: pgsql/src/backend/access/gin/ginutil.c,v 1.8 2006/10/05 17:57:40 tgl Exp $
*-------------------------------------------------------------------------
*/
@ -129,62 +129,48 @@ compareEntries(GinState *ginstate, Datum a, Datum b)
);
}
static FmgrInfo *cmpDatumPtr = NULL;
#if defined(__INTEL_COMPILER) && (defined(__ia64__) || defined(__ia64))
/*
* Intel Compiler on Intel Itanium with -O2 has a bug around
* change static variable by user function called from
* libc func: it doesn't change. So mark it as volatile.
*
* It's a pity, but it's impossible to define optimization
* level here.
*/
#define VOLATILE volatile
#else
#define VOLATILE
#endif
static bool VOLATILE needUnique = FALSE;
typedef struct
{
FmgrInfo *cmpDatumFunc;
bool *needUnique;
} cmpEntriesData;
static int
cmpEntries(const void *a, const void *b)
cmpEntries(const Datum *a, const Datum *b, cmpEntriesData *arg)
{
int res = DatumGetInt32(
FunctionCall2(
cmpDatumPtr,
*(Datum *) a,
*(Datum *) b
)
);
int res = DatumGetInt32(FunctionCall2(arg->cmpDatumFunc,
*a, *b));
if (res == 0)
needUnique = TRUE;
*(arg->needUnique) = TRUE;
return res;
}
Datum *
extractEntriesS(GinState *ginstate, Datum value, uint32 *nentries)
extractEntriesS(GinState *ginstate, Datum value, uint32 *nentries,
bool *needUnique)
{
Datum *entries;
entries = (Datum *) DatumGetPointer(
FunctionCall2(
entries = (Datum *) DatumGetPointer(FunctionCall2(
&ginstate->extractValueFn,
value,
PointerGetDatum(nentries)
)
);
));
if (entries == NULL)
*nentries = 0;
*needUnique = FALSE;
if (*nentries > 1)
{
cmpDatumPtr = &ginstate->compareFn;
needUnique = FALSE;
qsort(entries, *nentries, sizeof(Datum), cmpEntries);
cmpEntriesData arg;
arg.cmpDatumFunc = &ginstate->compareFn;
arg.needUnique = needUnique;
qsort_arg(entries, *nentries, sizeof(Datum),
(qsort_arg_comparator) cmpEntries, (void *) &arg);
}
return entries;
@ -194,9 +180,11 @@ extractEntriesS(GinState *ginstate, Datum value, uint32 *nentries)
Datum *
extractEntriesSU(GinState *ginstate, Datum value, uint32 *nentries)
{
Datum *entries = extractEntriesS(ginstate, value, nentries);
bool needUnique;
Datum *entries = extractEntriesS(ginstate, value, nentries,
&needUnique);
if (*nentries > 1 && needUnique)
if (needUnique)
{
Datum *ptr,
*res;