Header And Logo

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

btree_inet.c

Go to the documentation of this file.
00001 /*
00002  * contrib/btree_gist/btree_inet.c
00003  */
00004 #include "postgres.h"
00005 
00006 #include "btree_gist.h"
00007 #include "btree_utils_num.h"
00008 #include "utils/builtins.h"
00009 #include "utils/inet.h"
00010 #include "catalog/pg_type.h"
00011 
00012 typedef struct inetkey
00013 {
00014     double      lower;
00015     double      upper;
00016 } inetKEY;
00017 
00018 /*
00019 ** inet ops
00020 */
00021 PG_FUNCTION_INFO_V1(gbt_inet_compress);
00022 PG_FUNCTION_INFO_V1(gbt_inet_union);
00023 PG_FUNCTION_INFO_V1(gbt_inet_picksplit);
00024 PG_FUNCTION_INFO_V1(gbt_inet_consistent);
00025 PG_FUNCTION_INFO_V1(gbt_inet_penalty);
00026 PG_FUNCTION_INFO_V1(gbt_inet_same);
00027 
00028 Datum       gbt_inet_compress(PG_FUNCTION_ARGS);
00029 Datum       gbt_inet_union(PG_FUNCTION_ARGS);
00030 Datum       gbt_inet_picksplit(PG_FUNCTION_ARGS);
00031 Datum       gbt_inet_consistent(PG_FUNCTION_ARGS);
00032 Datum       gbt_inet_penalty(PG_FUNCTION_ARGS);
00033 Datum       gbt_inet_same(PG_FUNCTION_ARGS);
00034 
00035 
00036 static bool
00037 gbt_inetgt(const void *a, const void *b)
00038 {
00039     return (*((const double *) a) > *((const double *) b));
00040 }
00041 static bool
00042 gbt_inetge(const void *a, const void *b)
00043 {
00044     return (*((const double *) a) >= *((const double *) b));
00045 }
00046 static bool
00047 gbt_ineteq(const void *a, const void *b)
00048 {
00049     return (*((const double *) a) == *((const double *) b));
00050 }
00051 static bool
00052 gbt_inetle(const void *a, const void *b)
00053 {
00054     return (*((const double *) a) <= *((const double *) b));
00055 }
00056 static bool
00057 gbt_inetlt(const void *a, const void *b)
00058 {
00059     return (*((const double *) a) < *((const double *) b));
00060 }
00061 
00062 static int
00063 gbt_inetkey_cmp(const void *a, const void *b)
00064 {
00065     inetKEY    *ia = (inetKEY *) (((const Nsrt *) a)->t);
00066     inetKEY    *ib = (inetKEY *) (((const Nsrt *) b)->t);
00067 
00068     if (ia->lower == ib->lower)
00069     {
00070         if (ia->upper == ib->upper)
00071             return 0;
00072 
00073         return (ia->upper > ib->upper) ? 1 : -1;
00074     }
00075 
00076     return (ia->lower > ib->lower) ? 1 : -1;
00077 }
00078 
00079 
00080 static const gbtree_ninfo tinfo =
00081 {
00082     gbt_t_inet,
00083     sizeof(double),
00084     gbt_inetgt,
00085     gbt_inetge,
00086     gbt_ineteq,
00087     gbt_inetle,
00088     gbt_inetlt,
00089     gbt_inetkey_cmp,
00090     NULL
00091 };
00092 
00093 
00094 /**************************************************
00095  * inet ops
00096  **************************************************/
00097 
00098 
00099 Datum
00100 gbt_inet_compress(PG_FUNCTION_ARGS)
00101 {
00102     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
00103     GISTENTRY  *retval;
00104 
00105     if (entry->leafkey)
00106     {
00107         inetKEY    *r = (inetKEY *) palloc(sizeof(inetKEY));
00108 
00109         retval = palloc(sizeof(GISTENTRY));
00110         r->lower = convert_network_to_scalar(entry->key, INETOID);
00111         r->upper = r->lower;
00112         gistentryinit(*retval, PointerGetDatum(r),
00113                       entry->rel, entry->page,
00114                       entry->offset, FALSE);
00115     }
00116     else
00117         retval = entry;
00118 
00119     PG_RETURN_POINTER(retval);
00120 }
00121 
00122 
00123 Datum
00124 gbt_inet_consistent(PG_FUNCTION_ARGS)
00125 {
00126     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
00127     double      query = convert_network_to_scalar(PG_GETARG_DATUM(1), INETOID);
00128     StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
00129 
00130     /* Oid      subtype = PG_GETARG_OID(3); */
00131     bool       *recheck = (bool *) PG_GETARG_POINTER(4);
00132     inetKEY    *kkk = (inetKEY *) DatumGetPointer(entry->key);
00133     GBT_NUMKEY_R key;
00134 
00135     /* All cases served by this function are inexact */
00136     *recheck = true;
00137 
00138     key.lower = (GBT_NUMKEY *) &kkk->lower;
00139     key.upper = (GBT_NUMKEY *) &kkk->upper;
00140 
00141     PG_RETURN_BOOL(gbt_num_consistent(&key, (void *) &query,
00142                                       &strategy, GIST_LEAF(entry), &tinfo));
00143 }
00144 
00145 
00146 Datum
00147 gbt_inet_union(PG_FUNCTION_ARGS)
00148 {
00149     GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
00150     void       *out = palloc(sizeof(inetKEY));
00151 
00152     *(int *) PG_GETARG_POINTER(1) = sizeof(inetKEY);
00153     PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
00154 }
00155 
00156 
00157 Datum
00158 gbt_inet_penalty(PG_FUNCTION_ARGS)
00159 {
00160     inetKEY    *origentry = (inetKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
00161     inetKEY    *newentry = (inetKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
00162     float      *result = (float *) PG_GETARG_POINTER(2);
00163 
00164     penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
00165 
00166     PG_RETURN_POINTER(result);
00167 
00168 }
00169 
00170 Datum
00171 gbt_inet_picksplit(PG_FUNCTION_ARGS)
00172 {
00173     PG_RETURN_POINTER(gbt_num_picksplit(
00174                                     (GistEntryVector *) PG_GETARG_POINTER(0),
00175                                       (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
00176                                         &tinfo
00177                                         ));
00178 }
00179 
00180 Datum
00181 gbt_inet_same(PG_FUNCTION_ARGS)
00182 {
00183     inetKEY    *b1 = (inetKEY *) PG_GETARG_POINTER(0);
00184     inetKEY    *b2 = (inetKEY *) PG_GETARG_POINTER(1);
00185     bool       *result = (bool *) PG_GETARG_POINTER(2);
00186 
00187     *result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
00188     PG_RETURN_POINTER(result);
00189 }