Header And Logo

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

btree_bit.c

Go to the documentation of this file.
00001 /*
00002  * contrib/btree_gist/btree_bit.c
00003  */
00004 #include "postgres.h"
00005 
00006 #include "btree_gist.h"
00007 #include "btree_utils_var.h"
00008 #include "utils/bytea.h"
00009 #include "utils/varbit.h"
00010 
00011 
00012 /*
00013 ** Bit ops
00014 */
00015 PG_FUNCTION_INFO_V1(gbt_bit_compress);
00016 PG_FUNCTION_INFO_V1(gbt_bit_union);
00017 PG_FUNCTION_INFO_V1(gbt_bit_picksplit);
00018 PG_FUNCTION_INFO_V1(gbt_bit_consistent);
00019 PG_FUNCTION_INFO_V1(gbt_bit_penalty);
00020 PG_FUNCTION_INFO_V1(gbt_bit_same);
00021 
00022 Datum       gbt_bit_compress(PG_FUNCTION_ARGS);
00023 Datum       gbt_bit_union(PG_FUNCTION_ARGS);
00024 Datum       gbt_bit_picksplit(PG_FUNCTION_ARGS);
00025 Datum       gbt_bit_consistent(PG_FUNCTION_ARGS);
00026 Datum       gbt_bit_penalty(PG_FUNCTION_ARGS);
00027 Datum       gbt_bit_same(PG_FUNCTION_ARGS);
00028 
00029 
00030 
00031 /* define for comparison */
00032 
00033 static bool
00034 gbt_bitgt(const void *a, const void *b, Oid collation)
00035 {
00036     return DatumGetBool(DirectFunctionCall2(bitgt,
00037                                             PointerGetDatum(a),
00038                                             PointerGetDatum(b)));
00039 }
00040 
00041 static bool
00042 gbt_bitge(const void *a, const void *b, Oid collation)
00043 {
00044     return DatumGetBool(DirectFunctionCall2(bitge,
00045                                             PointerGetDatum(a),
00046                                             PointerGetDatum(b)));
00047 }
00048 
00049 static bool
00050 gbt_biteq(const void *a, const void *b, Oid collation)
00051 {
00052     return DatumGetBool(DirectFunctionCall2(biteq,
00053                                             PointerGetDatum(a),
00054                                             PointerGetDatum(b)));
00055 }
00056 
00057 static bool
00058 gbt_bitle(const void *a, const void *b, Oid collation)
00059 {
00060     return DatumGetBool(DirectFunctionCall2(bitle,
00061                                             PointerGetDatum(a),
00062                                             PointerGetDatum(b)));
00063 }
00064 
00065 static bool
00066 gbt_bitlt(const void *a, const void *b, Oid collation)
00067 {
00068     return DatumGetBool(DirectFunctionCall2(bitlt,
00069                                             PointerGetDatum(a),
00070                                             PointerGetDatum(b)));
00071 }
00072 
00073 static int32
00074 gbt_bitcmp(const void *a, const void *b, Oid collation)
00075 {
00076     return DatumGetInt32(DirectFunctionCall2(byteacmp,
00077                                              PointerGetDatum(a),
00078                                              PointerGetDatum(b)));
00079 }
00080 
00081 
00082 static bytea *
00083 gbt_bit_xfrm(bytea *leaf)
00084 {
00085     bytea      *out = leaf;
00086     int         s = INTALIGN(VARBITBYTES(leaf) + VARHDRSZ);
00087 
00088     out = palloc(s);
00089     SET_VARSIZE(out, s);
00090     memcpy((void *) VARDATA(out), (void *) VARBITS(leaf), VARBITBYTES(leaf));
00091     return out;
00092 }
00093 
00094 
00095 
00096 
00097 static GBT_VARKEY *
00098 gbt_bit_l2n(GBT_VARKEY *leaf)
00099 {
00100 
00101     GBT_VARKEY *out = leaf;
00102     GBT_VARKEY_R r = gbt_var_key_readable(leaf);
00103     bytea      *o;
00104 
00105     o = gbt_bit_xfrm(r.lower);
00106     r.upper = r.lower = o;
00107     out = gbt_var_key_copy(&r, TRUE);
00108     pfree(o);
00109 
00110     return out;
00111 
00112 }
00113 
00114 static const gbtree_vinfo tinfo =
00115 {
00116     gbt_t_bit,
00117     0,
00118     TRUE,
00119     gbt_bitgt,
00120     gbt_bitge,
00121     gbt_biteq,
00122     gbt_bitle,
00123     gbt_bitlt,
00124     gbt_bitcmp,
00125     gbt_bit_l2n
00126 };
00127 
00128 
00129 /**************************************************
00130  * Bit ops
00131  **************************************************/
00132 
00133 Datum
00134 gbt_bit_compress(PG_FUNCTION_ARGS)
00135 {
00136     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
00137 
00138     PG_RETURN_POINTER(gbt_var_compress(entry, &tinfo));
00139 }
00140 
00141 Datum
00142 gbt_bit_consistent(PG_FUNCTION_ARGS)
00143 {
00144     GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
00145     void       *query = (void *) DatumGetByteaP(PG_GETARG_DATUM(1));
00146     StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
00147 
00148     /* Oid      subtype = PG_GETARG_OID(3); */
00149     bool       *recheck = (bool *) PG_GETARG_POINTER(4);
00150     bool        retval;
00151     GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
00152     GBT_VARKEY_R r = gbt_var_key_readable(key);
00153 
00154     /* All cases served by this function are exact */
00155     *recheck = false;
00156 
00157     if (GIST_LEAF(entry))
00158         retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
00159                                     TRUE, &tinfo);
00160     else
00161     {
00162         bytea      *q = gbt_bit_xfrm((bytea *) query);
00163 
00164         retval = gbt_var_consistent(&r, q, strategy, PG_GET_COLLATION(),
00165                                     FALSE, &tinfo);
00166     }
00167     PG_RETURN_BOOL(retval);
00168 }
00169 
00170 
00171 
00172 Datum
00173 gbt_bit_union(PG_FUNCTION_ARGS)
00174 {
00175     GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
00176     int32      *size = (int *) PG_GETARG_POINTER(1);
00177 
00178     PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
00179                                     &tinfo));
00180 }
00181 
00182 
00183 Datum
00184 gbt_bit_picksplit(PG_FUNCTION_ARGS)
00185 {
00186     GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
00187     GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
00188 
00189     gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
00190                       &tinfo);
00191     PG_RETURN_POINTER(v);
00192 }
00193 
00194 Datum
00195 gbt_bit_same(PG_FUNCTION_ARGS)
00196 {
00197     Datum       d1 = PG_GETARG_DATUM(0);
00198     Datum       d2 = PG_GETARG_DATUM(1);
00199     bool       *result = (bool *) PG_GETARG_POINTER(2);
00200 
00201     *result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo);
00202     PG_RETURN_POINTER(result);
00203 }
00204 
00205 
00206 Datum
00207 gbt_bit_penalty(PG_FUNCTION_ARGS)
00208 {
00209     GISTENTRY  *o = (GISTENTRY *) PG_GETARG_POINTER(0);
00210     GISTENTRY  *n = (GISTENTRY *) PG_GETARG_POINTER(1);
00211     float      *result = (float *) PG_GETARG_POINTER(2);
00212 
00213     PG_RETURN_POINTER(gbt_var_penalty(result, o, n, PG_GET_COLLATION(),
00214                                       &tinfo));
00215 }