Andrew Dunstan <andrew.duns...@2ndquadrant.com> writes:
> On 02/23/2017 04:41 PM, Tom Lane wrote:
>> BTW, while I'm looking at this ... isn't gin_enum_cmp broken on its face?

> Yes, that's what I'm trying to fix.

I'd forgotten where this thread started.  For a minute there I thought
we had a live bug, rather than a deficiency in code-under-development.

After thinking about that, I believe that enum_cmp_internal is a rather
considerable hazard.  It might not be our only function that requires
fcinfo->flinfo cache space just some of the time not all the time, but
I don't recall anyplace else that could so easily undergo a reasonable
amount of testing without *ever* reaching the case where it requires
that cache space.  So I'm now worried that it wouldn't be too hard for
such a bug to get past us.

I think we should address that by adding a non-bypassable Assert that
the caller did provide flinfo, as in the attached.

                        regards, tom lane

diff --git a/src/backend/utils/adt/enum.c b/src/backend/utils/adt/enum.c
index 8110ee2..b1d2a6f 100644
*** a/src/backend/utils/adt/enum.c
--- b/src/backend/utils/adt/enum.c
*************** enum_cmp_internal(Oid arg1, Oid arg2, Fu
*** 263,268 ****
--- 263,277 ----
  {
  	TypeCacheEntry *tcache;
  
+ 	/*
+ 	 * We don't need the typcache except in the hopefully-uncommon case that
+ 	 * one or both Oids are odd.  This means that cursory testing of code that
+ 	 * fails to pass flinfo to an enum comparison function might not disclose
+ 	 * the oversight.  To make such errors more obvious, Assert that we have a
+ 	 * place to cache even when we take a fast-path exit.
+ 	 */
+ 	Assert(fcinfo->flinfo != NULL);
+ 
  	/* Equal OIDs are equal no matter what */
  	if (arg1 == arg2)
  		return 0;
*************** enum_cmp(PG_FUNCTION_ARGS)
*** 381,392 ****
  	Oid			a = PG_GETARG_OID(0);
  	Oid			b = PG_GETARG_OID(1);
  
! 	if (a == b)
! 		PG_RETURN_INT32(0);
! 	else if (enum_cmp_internal(a, b, fcinfo) > 0)
! 		PG_RETURN_INT32(1);
! 	else
! 		PG_RETURN_INT32(-1);
  }
  
  /* Enum programming support functions */
--- 390,396 ----
  	Oid			a = PG_GETARG_OID(0);
  	Oid			b = PG_GETARG_OID(1);
  
! 	PG_RETURN_INT32(enum_cmp_internal(a, b, fcinfo));
  }
  
  /* Enum programming support functions */
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to