text: /*
   * contrib/intarray/_int_gin.c
   */
  #include "postgres.h"
  
  #include "_int.h"
  #include "access/gin.h"
  #include "access/stratnum.h"
  
  PG_FUNCTION_INFO_V1(ginint4_queryextract);
  
  Datum
  ginint4_queryextract(PG_FUNCTION_ARGS)
  {
  	int32	   *nentries = (int32 *) PG_GETARG_POINTER(1);
  	StrategyNumber strategy = PG_GETARG_UINT16(2);
  	int32	   *searchMode = (int32 *) PG_GETARG_POINTER(6);
  	Datum	   *res = NULL;
  
  	*nentries = 0;
  
  	if (strategy == BooleanSearchStrategy)
  	{
  		QUERYTYPE  *query = PG_GETARG_QUERYTYPE_P(0);
  		ITEM	   *items = GETQUERY(query);
  		int			i;
  
  		/* empty query must fail */
  		if (query->size <= 0)
  			PG_RETURN_POINTER(NULL);
  
  		/*
  		 * If the query doesn't have any required primitive values (for
  		 * instance, it's something like '! 42'), we have to do a full index
  		 * scan.
  		 */
  		if (query_has_required_values(query))
  			*searchMode = GIN_SEARCH_MODE_DEFAULT;
  		else
  			*searchMode = GIN_SEARCH_MODE_ALL;
  
  		/*
  		 * Extract all the VAL items as things we want GIN to check for.
  		 */
  		res = (Datum *) palloc(sizeof(Datum) * query->size);
  		*nentries = 0;
  
  		for (i = 0; i < query->size; i++)
  		{
  			if (items[i].type == VAL)
  			{
  				res[*nentries] = Int32GetDatum(items[i].val);
  				(*nentries)++;
  			}
  		}
  	}
  	else
  	{
  		ArrayType  *query = PG_GETARG_ARRAYTYPE_P(0);
  
  		CHECKARRVALID(query);
  		*nentries = ARRNELEMS(query);
  		if (*nentries > 0)
  		{
  			int32	   *arr;
  			int32		i;
  
  			res = (Datum *) palloc(sizeof(Datum) * (*nentries));
  
  			arr = ARRPTR(query);
  			for (i = 0; i < *nentries; i++)
  				res[i] = Int32GetDatum(arr[i]);
  		}
  
  		switch (strategy)
  		{
  			case RTOverlapStrategyNumber:
  				*searchMode = GIN_SEARCH_MODE_DEFAULT;
  				break;
  			case RTContainedByStrategyNumber:
  			case RTOldContainedByStrategyNumber:
  				/* empty set is contained in everything */
  				*searchMode = GIN_SEARCH_MODE_INCLUDE_EMPTY;
  				break;
  			case RTSameStrategyNumber:
  				if (*nentries > 0)
  					*searchMode = GIN_SEARCH_MODE_DEFAULT;
  				else
  					*searchMode = GIN_SEARCH_MODE_INCLUDE_EMPTY;
  				break;
  			case RTContainsStrategyNumber:
  			case RTOldContainsStrategyNumber:
  				if (*nentries > 0)
  					*searchMode = GIN_SEARCH_MODE_DEFAULT;
  				else			/* everything contains the empty set */
  					*searchMode = GIN_SEARCH_MODE_ALL;
  				break;
  			default:
  				elog(ERROR, "ginint4_queryextract: unknown strategy number: %d",
  					 strategy);
  		}
  	}
  
  	PG_RETURN_POINTER(res);
  }
  
  PG_FUNCTION_INFO_V1(ginint4_consistent);
  
  Datum
  ginint4_consistent(PG_FUNCTION_ARGS)
  {
  	bool	   *check = (bool *) PG_GETARG_POINTER(0);
  	StrategyNumber strategy = PG_GETARG_UINT16(1);
  	int32		nkeys = PG_GETARG_INT32(3);
  
  	/* Pointer	   *extra_data = (Pointer *) PG_GETARG_POINTER(4); */
  	bool	   *recheck = (bool *) PG_GETARG_POINTER(5);
  	bool		res = false;
  	int32		i;
  
  	switch (strategy)
  	{
  		case RTOverlapStrategyNumber:
  			/* result is not lossy */
  			*recheck = false;
  			/* at least one element in check[] is true, so result = true */
  			res = true;
  			break;
  		case RTContainedByStrategyNumber:
  		case RTOldContainedByStrategyNumber:
  			/* we will need recheck */
  			*recheck = true;
  			/* at least one element in check[] is true, so result = true */
  			res = true;
  			break;
  		case RTSameStrategyNumber:
  			/* we will need recheck */
  			*recheck = true;
  			/* Must have all elements in check[] true */
  			res = true;
  			for (i = 0; i < nkeys; i++)
  			{
  				if (!check[i])
  				{
  					res = false;
  					break;
  				}
  			}
  			break;
  		case RTContainsStrategyNumber:
  		case RTOldContainsStrategyNumber:
  			/* result is not lossy */
  			*recheck = false;
  			/* Must have all elements in check[] true */
  			res = true;
  			for (i = 0; i < nkeys; i++)
  			{
  				if (!check[i])
  				{
  					res = false;
  					break;
  				}
  			}
  			break;
  		case BooleanSearchStrategy:
  			{
  				QUERYTYPE  *query = PG_GETARG_QUERYTYPE_P(2);
  
  				/* result is not lossy */
  				*recheck = false;
  				res = gin_bool_consistent(query, check);
  			}
  			break;
  		default:
  			elog(ERROR, "ginint4_consistent: unknown strategy number: %d",
  				 strategy);
  	}
  
  	PG_RETURN_BOOL(res);
  }
  