Go to the documentation of this file.00001
00002
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
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
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
00131 bool *recheck = (bool *) PG_GETARG_POINTER(4);
00132 inetKEY *kkk = (inetKEY *) DatumGetPointer(entry->key);
00133 GBT_NUMKEY_R key;
00134
00135
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 }