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
00009 typedef struct int64key
00010 {
00011 int64 lower;
00012 int64 upper;
00013 } int64KEY;
00014
00015
00016
00017
00018 PG_FUNCTION_INFO_V1(gbt_int8_compress);
00019 PG_FUNCTION_INFO_V1(gbt_int8_union);
00020 PG_FUNCTION_INFO_V1(gbt_int8_picksplit);
00021 PG_FUNCTION_INFO_V1(gbt_int8_consistent);
00022 PG_FUNCTION_INFO_V1(gbt_int8_distance);
00023 PG_FUNCTION_INFO_V1(gbt_int8_penalty);
00024 PG_FUNCTION_INFO_V1(gbt_int8_same);
00025
00026 Datum gbt_int8_compress(PG_FUNCTION_ARGS);
00027 Datum gbt_int8_union(PG_FUNCTION_ARGS);
00028 Datum gbt_int8_picksplit(PG_FUNCTION_ARGS);
00029 Datum gbt_int8_consistent(PG_FUNCTION_ARGS);
00030 Datum gbt_int8_distance(PG_FUNCTION_ARGS);
00031 Datum gbt_int8_penalty(PG_FUNCTION_ARGS);
00032 Datum gbt_int8_same(PG_FUNCTION_ARGS);
00033
00034
00035 static bool
00036 gbt_int8gt(const void *a, const void *b)
00037 {
00038 return (*((const int64 *) a) > *((const int64 *) b));
00039 }
00040 static bool
00041 gbt_int8ge(const void *a, const void *b)
00042 {
00043 return (*((const int64 *) a) >= *((const int64 *) b));
00044 }
00045 static bool
00046 gbt_int8eq(const void *a, const void *b)
00047 {
00048 return (*((const int64 *) a) == *((const int64 *) b));
00049 }
00050 static bool
00051 gbt_int8le(const void *a, const void *b)
00052 {
00053 return (*((const int64 *) a) <= *((const int64 *) b));
00054 }
00055 static bool
00056 gbt_int8lt(const void *a, const void *b)
00057 {
00058 return (*((const int64 *) a) < *((const int64 *) b));
00059 }
00060
00061 static int
00062 gbt_int8key_cmp(const void *a, const void *b)
00063 {
00064 int64KEY *ia = (int64KEY *) (((const Nsrt *) a)->t);
00065 int64KEY *ib = (int64KEY *) (((const Nsrt *) b)->t);
00066
00067 if (ia->lower == ib->lower)
00068 {
00069 if (ia->upper == ib->upper)
00070 return 0;
00071
00072 return (ia->upper > ib->upper) ? 1 : -1;
00073 }
00074
00075 return (ia->lower > ib->lower) ? 1 : -1;
00076 }
00077
00078 static float8
00079 gbt_int8_dist(const void *a, const void *b)
00080 {
00081 return GET_FLOAT_DISTANCE(int64, a, b);
00082 }
00083
00084
00085 static const gbtree_ninfo tinfo =
00086 {
00087 gbt_t_int8,
00088 sizeof(int64),
00089 gbt_int8gt,
00090 gbt_int8ge,
00091 gbt_int8eq,
00092 gbt_int8le,
00093 gbt_int8lt,
00094 gbt_int8key_cmp,
00095 gbt_int8_dist
00096 };
00097
00098
00099 PG_FUNCTION_INFO_V1(int8_dist);
00100 Datum int8_dist(PG_FUNCTION_ARGS);
00101 Datum
00102 int8_dist(PG_FUNCTION_ARGS)
00103 {
00104 int64 a = PG_GETARG_INT64(0);
00105 int64 b = PG_GETARG_INT64(1);
00106 int64 r;
00107 int64 ra;
00108
00109 r = a - b;
00110 ra = Abs(r);
00111
00112
00113 if (ra < 0 || (!SAMESIGN(a, b) && !SAMESIGN(r, a)))
00114 ereport(ERROR,
00115 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
00116 errmsg("bigint out of range")));
00117
00118 PG_RETURN_INT64(ra);
00119 }
00120
00121
00122
00123
00124
00125
00126
00127 Datum
00128 gbt_int8_compress(PG_FUNCTION_ARGS)
00129 {
00130 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
00131 GISTENTRY *retval = NULL;
00132
00133 PG_RETURN_POINTER(gbt_num_compress(retval, entry, &tinfo));
00134 }
00135
00136
00137 Datum
00138 gbt_int8_consistent(PG_FUNCTION_ARGS)
00139 {
00140 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
00141 int64 query = PG_GETARG_INT64(1);
00142 StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
00143
00144
00145 bool *recheck = (bool *) PG_GETARG_POINTER(4);
00146 int64KEY *kkk = (int64KEY *) DatumGetPointer(entry->key);
00147 GBT_NUMKEY_R key;
00148
00149
00150 *recheck = false;
00151
00152 key.lower = (GBT_NUMKEY *) &kkk->lower;
00153 key.upper = (GBT_NUMKEY *) &kkk->upper;
00154
00155 PG_RETURN_BOOL(
00156 gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
00157 );
00158 }
00159
00160
00161 Datum
00162 gbt_int8_distance(PG_FUNCTION_ARGS)
00163 {
00164 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
00165 int64 query = PG_GETARG_INT64(1);
00166
00167
00168 int64KEY *kkk = (int64KEY *) DatumGetPointer(entry->key);
00169 GBT_NUMKEY_R key;
00170
00171 key.lower = (GBT_NUMKEY *) &kkk->lower;
00172 key.upper = (GBT_NUMKEY *) &kkk->upper;
00173
00174 PG_RETURN_FLOAT8(
00175 gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
00176 );
00177 }
00178
00179
00180 Datum
00181 gbt_int8_union(PG_FUNCTION_ARGS)
00182 {
00183 GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
00184 void *out = palloc(sizeof(int64KEY));
00185
00186 *(int *) PG_GETARG_POINTER(1) = sizeof(int64KEY);
00187 PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
00188 }
00189
00190
00191 Datum
00192 gbt_int8_penalty(PG_FUNCTION_ARGS)
00193 {
00194 int64KEY *origentry = (int64KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
00195 int64KEY *newentry = (int64KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
00196 float *result = (float *) PG_GETARG_POINTER(2);
00197
00198 penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
00199
00200 PG_RETURN_POINTER(result);
00201 }
00202
00203 Datum
00204 gbt_int8_picksplit(PG_FUNCTION_ARGS)
00205 {
00206 PG_RETURN_POINTER(gbt_num_picksplit(
00207 (GistEntryVector *) PG_GETARG_POINTER(0),
00208 (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
00209 &tinfo
00210 ));
00211 }
00212
00213 Datum
00214 gbt_int8_same(PG_FUNCTION_ARGS)
00215 {
00216 int64KEY *b1 = (int64KEY *) PG_GETARG_POINTER(0);
00217 int64KEY *b2 = (int64KEY *) PG_GETARG_POINTER(1);
00218 bool *result = (bool *) PG_GETARG_POINTER(2);
00219
00220 *result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
00221 PG_RETURN_POINTER(result);
00222 }