00001
00002
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
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
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
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
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
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 }