Header And Logo

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

btree_int2.c

Go to the documentation of this file.
00001 /*
00002  * contrib/btree_gist/btree_int2.c
00003  */
00004 #include "postgres.h"
00005 
00006 #include "btree_gist.h"
00007 #include "btree_utils_num.h"
00008 
00009 typedef struct int16key
00010 {
00011     int16       lower;
00012     int16       upper;
00013 } int16KEY;
00014 
00015 /*
00016 ** int16 ops
00017 */
00018 PG_FUNCTION_INFO_V1(gbt_int2_compress);
00019 PG_FUNCTION_INFO_V1(gbt_int2_union);
00020 PG_FUNCTION_INFO_V1(gbt_int2_picksplit);
00021 PG_FUNCTION_INFO_V1(gbt_int2_consistent);
00022 PG_FUNCTION_INFO_V1(gbt_int2_distance);
00023 PG_FUNCTION_INFO_V1(gbt_int2_penalty);
00024 PG_FUNCTION_INFO_V1(gbt_int2_same);
00025 
00026 Datum       gbt_int2_compress(PG_FUNCTION_ARGS);
00027 Datum       gbt_int2_union(PG_FUNCTION_ARGS);
00028 Datum       gbt_int2_picksplit(PG_FUNCTION_ARGS);
00029 Datum       gbt_int2_consistent(PG_FUNCTION_ARGS);
00030 Datum       gbt_int2_distance(PG_FUNCTION_ARGS);
00031 Datum       gbt_int2_penalty(PG_FUNCTION_ARGS);
00032 Datum       gbt_int2_same(PG_FUNCTION_ARGS);
00033 
00034 static bool
00035 gbt_int2gt(const void *a, const void *b)
00036 {
00037     return (*((const int16 *) a) > *((const int16 *) b));
00038 }
00039 static bool
00040 gbt_int2ge(const void *a, const void *b)
00041 {
00042     return (*((const int16 *) a) >= *((const int16 *) b));
00043 }
00044 static bool
00045 gbt_int2eq(const void *a, const void *b)
00046 {
00047     return (*((const int16 *) a) == *((const int16 *) b));
00048 }
00049 static bool
00050 gbt_int2le(const void *a, const void *b)
00051 {
00052     return (*((const int16 *) a) <= *((const int16 *) b));
00053 }
00054 static bool
00055 gbt_int2lt(const void *a, const void *b)
00056 {
00057     return (*((const int16 *) a) < *((const int16 *) b));
00058 }
00059 
00060 static int
00061 gbt_int2key_cmp(const void *a, const void *b)
00062 {
00063     int16KEY   *ia = (int16KEY *) (((const Nsrt *) a)->t);
00064     int16KEY   *ib = (int16KEY *) (((const Nsrt *) b)->t);
00065 
00066     if (ia->lower == ib->lower)
00067     {
00068         if (ia->upper == ib->upper)
00069             return 0;
00070 
00071         return (ia->upper > ib->upper) ? 1 : -1;
00072     }
00073 
00074     return (ia->lower > ib->lower) ? 1 : -1;
00075 }
00076 
00077 static float8
00078 gbt_int2_dist(const void *a, const void *b)
00079 {
00080     return GET_FLOAT_DISTANCE(int16, a, b);
00081 }
00082 
00083 
00084 static const gbtree_ninfo tinfo =
00085 {
00086     gbt_t_int2,
00087     sizeof(int16),
00088     gbt_int2gt,
00089     gbt_int2ge,
00090     gbt_int2eq,
00091     gbt_int2le,
00092     gbt_int2lt,
00093     gbt_int2key_cmp,
00094     gbt_int2_dist
00095 };
00096 
00097 
00098 PG_FUNCTION_INFO_V1(int2_dist);
00099 Datum       int2_dist(PG_FUNCTION_ARGS);
00100 Datum
00101 int2_dist(PG_FUNCTION_ARGS)
00102 {
00103     int16       a = PG_GETARG_INT16(0);
00104     int16       b = PG_GETARG_INT16(1);
00105     int16       r;
00106     int16       ra;
00107 
00108     r = a - b;
00109     ra = Abs(r);
00110 
00111     /* Overflow check. */
00112     if (ra < 0 || (!SAMESIGN(a, b) && !SAMESIGN(r, a)))
00113         ereport(ERROR,
00114                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
00115                  errmsg("smallint out of range")));
00116 
00117     PG_RETURN_INT16(ra);
00118 }
00119 
00120 
00121 /**************************************************
00122  * int16 ops
00123  **************************************************/
00124 
00125 
00126 Datum
00127 gbt_int2_compress(PG_FUNCTION_ARGS)
00128 {
00129     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
00130     GISTENTRY  *retval = NULL;
00131 
00132     PG_RETURN_POINTER(gbt_num_compress(retval, entry, &tinfo));
00133 }
00134 
00135 
00136 Datum
00137 gbt_int2_consistent(PG_FUNCTION_ARGS)
00138 {
00139     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
00140     int16       query = PG_GETARG_INT16(1);
00141     StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
00142 
00143     /* Oid      subtype = PG_GETARG_OID(3); */
00144     bool       *recheck = (bool *) PG_GETARG_POINTER(4);
00145     int16KEY   *kkk = (int16KEY *) DatumGetPointer(entry->key);
00146     GBT_NUMKEY_R key;
00147 
00148     /* All cases served by this function are exact */
00149     *recheck = false;
00150 
00151     key.lower = (GBT_NUMKEY *) &kkk->lower;
00152     key.upper = (GBT_NUMKEY *) &kkk->upper;
00153 
00154     PG_RETURN_BOOL(
00155                    gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
00156         );
00157 }
00158 
00159 
00160 Datum
00161 gbt_int2_distance(PG_FUNCTION_ARGS)
00162 {
00163     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
00164     int16       query = PG_GETARG_INT16(1);
00165 
00166     /* Oid      subtype = PG_GETARG_OID(3); */
00167     int16KEY   *kkk = (int16KEY *) DatumGetPointer(entry->key);
00168     GBT_NUMKEY_R key;
00169 
00170     key.lower = (GBT_NUMKEY *) &kkk->lower;
00171     key.upper = (GBT_NUMKEY *) &kkk->upper;
00172 
00173     PG_RETURN_FLOAT8(
00174             gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
00175         );
00176 }
00177 
00178 
00179 Datum
00180 gbt_int2_union(PG_FUNCTION_ARGS)
00181 {
00182     GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
00183     void       *out = palloc(sizeof(int16KEY));
00184 
00185     *(int *) PG_GETARG_POINTER(1) = sizeof(int16KEY);
00186     PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
00187 }
00188 
00189 
00190 Datum
00191 gbt_int2_penalty(PG_FUNCTION_ARGS)
00192 {
00193     int16KEY   *origentry = (int16KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
00194     int16KEY   *newentry = (int16KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
00195     float      *result = (float *) PG_GETARG_POINTER(2);
00196 
00197     penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
00198 
00199     PG_RETURN_POINTER(result);
00200 }
00201 
00202 Datum
00203 gbt_int2_picksplit(PG_FUNCTION_ARGS)
00204 {
00205     PG_RETURN_POINTER(gbt_num_picksplit(
00206                                     (GistEntryVector *) PG_GETARG_POINTER(0),
00207                                       (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
00208                                         &tinfo
00209                                         ));
00210 }
00211 
00212 Datum
00213 gbt_int2_same(PG_FUNCTION_ARGS)
00214 {
00215     int16KEY   *b1 = (int16KEY *) PG_GETARG_POINTER(0);
00216     int16KEY   *b2 = (int16KEY *) PG_GETARG_POINTER(1);
00217     bool       *result = (bool *) PG_GETARG_POINTER(2);
00218 
00219     *result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
00220     PG_RETURN_POINTER(result);
00221 }