Header And Logo

PostgreSQL
| The world's most advanced open source database.

_int_gin.c

Go to the documentation of this file.
00001 /*
00002  * contrib/intarray/_int_gin.c
00003  */
00004 #include "postgres.h"
00005 
00006 #include "access/gin.h"
00007 #include "access/gist.h"
00008 #include "access/skey.h"
00009 
00010 #include "_int.h"
00011 
00012 PG_FUNCTION_INFO_V1(ginint4_queryextract);
00013 Datum       ginint4_queryextract(PG_FUNCTION_ARGS);
00014 
00015 Datum
00016 ginint4_queryextract(PG_FUNCTION_ARGS)
00017 {
00018     int32      *nentries = (int32 *) PG_GETARG_POINTER(1);
00019     StrategyNumber strategy = PG_GETARG_UINT16(2);
00020     int32      *searchMode = (int32 *) PG_GETARG_POINTER(6);
00021     Datum      *res = NULL;
00022 
00023     *nentries = 0;
00024 
00025     if (strategy == BooleanSearchStrategy)
00026     {
00027         QUERYTYPE  *query = PG_GETARG_QUERYTYPE_P(0);
00028         ITEM       *items = GETQUERY(query);
00029         int         i;
00030 
00031         /* empty query must fail */
00032         if (query->size <= 0)
00033             PG_RETURN_POINTER(NULL);
00034 
00035         /*
00036          * If the query doesn't have any required primitive values (for
00037          * instance, it's something like '! 42'), we have to do a full index
00038          * scan.
00039          */
00040         if (query_has_required_values(query))
00041             *searchMode = GIN_SEARCH_MODE_DEFAULT;
00042         else
00043             *searchMode = GIN_SEARCH_MODE_ALL;
00044 
00045         /*
00046          * Extract all the VAL items as things we want GIN to check for.
00047          */
00048         res = (Datum *) palloc(sizeof(Datum) * query->size);
00049         *nentries = 0;
00050 
00051         for (i = 0; i < query->size; i++)
00052         {
00053             if (items[i].type == VAL)
00054             {
00055                 res[*nentries] = Int32GetDatum(items[i].val);
00056                 (*nentries)++;
00057             }
00058         }
00059     }
00060     else
00061     {
00062         ArrayType  *query = PG_GETARG_ARRAYTYPE_P(0);
00063 
00064         CHECKARRVALID(query);
00065         *nentries = ARRNELEMS(query);
00066         if (*nentries > 0)
00067         {
00068             int32      *arr;
00069             int32       i;
00070 
00071             res = (Datum *) palloc(sizeof(Datum) * (*nentries));
00072 
00073             arr = ARRPTR(query);
00074             for (i = 0; i < *nentries; i++)
00075                 res[i] = Int32GetDatum(arr[i]);
00076         }
00077 
00078         switch (strategy)
00079         {
00080             case RTOverlapStrategyNumber:
00081                 *searchMode = GIN_SEARCH_MODE_DEFAULT;
00082                 break;
00083             case RTContainedByStrategyNumber:
00084             case RTOldContainedByStrategyNumber:
00085                 /* empty set is contained in everything */
00086                 *searchMode = GIN_SEARCH_MODE_INCLUDE_EMPTY;
00087                 break;
00088             case RTSameStrategyNumber:
00089                 if (*nentries > 0)
00090                     *searchMode = GIN_SEARCH_MODE_DEFAULT;
00091                 else
00092                     *searchMode = GIN_SEARCH_MODE_INCLUDE_EMPTY;
00093                 break;
00094             case RTContainsStrategyNumber:
00095             case RTOldContainsStrategyNumber:
00096                 if (*nentries > 0)
00097                     *searchMode = GIN_SEARCH_MODE_DEFAULT;
00098                 else    /* everything contains the empty set */
00099                     *searchMode = GIN_SEARCH_MODE_ALL;
00100                 break;
00101             default:
00102                 elog(ERROR, "ginint4_queryextract: unknown strategy number: %d",
00103                      strategy);
00104         }
00105     }
00106 
00107     PG_RETURN_POINTER(res);
00108 }
00109 
00110 PG_FUNCTION_INFO_V1(ginint4_consistent);
00111 Datum       ginint4_consistent(PG_FUNCTION_ARGS);
00112 
00113 Datum
00114 ginint4_consistent(PG_FUNCTION_ARGS)
00115 {
00116     bool       *check = (bool *) PG_GETARG_POINTER(0);
00117     StrategyNumber strategy = PG_GETARG_UINT16(1);
00118     int32       nkeys = PG_GETARG_INT32(3);
00119 
00120     /* Pointer     *extra_data = (Pointer *) PG_GETARG_POINTER(4); */
00121     bool       *recheck = (bool *) PG_GETARG_POINTER(5);
00122     bool        res = FALSE;
00123     int32       i;
00124 
00125     switch (strategy)
00126     {
00127         case RTOverlapStrategyNumber:
00128             /* result is not lossy */
00129             *recheck = false;
00130             /* at least one element in check[] is true, so result = true */
00131             res = TRUE;
00132             break;
00133         case RTContainedByStrategyNumber:
00134         case RTOldContainedByStrategyNumber:
00135             /* we will need recheck */
00136             *recheck = true;
00137             /* at least one element in check[] is true, so result = true */
00138             res = TRUE;
00139             break;
00140         case RTSameStrategyNumber:
00141             /* we will need recheck */
00142             *recheck = true;
00143             /* Must have all elements in check[] true */
00144             res = TRUE;
00145             for (i = 0; i < nkeys; i++)
00146             {
00147                 if (!check[i])
00148                 {
00149                     res = FALSE;
00150                     break;
00151                 }
00152             }
00153             break;
00154         case RTContainsStrategyNumber:
00155         case RTOldContainsStrategyNumber:
00156             /* result is not lossy */
00157             *recheck = false;
00158             /* Must have all elements in check[] true */
00159             res = TRUE;
00160             for (i = 0; i < nkeys; i++)
00161             {
00162                 if (!check[i])
00163                 {
00164                     res = FALSE;
00165                     break;
00166                 }
00167             }
00168             break;
00169         case BooleanSearchStrategy:
00170             {
00171                 QUERYTYPE  *query = PG_GETARG_QUERYTYPE_P(2);
00172 
00173                 /* result is not lossy */
00174                 *recheck = false;
00175                 res = gin_bool_consistent(query, check);
00176             }
00177             break;
00178         default:
00179             elog(ERROR, "ginint4_consistent: unknown strategy number: %d",
00180                  strategy);
00181     }
00182 
00183     PG_RETURN_BOOL(res);
00184 }