1 /* 2 * contrib/btree_gist/btree_float4.c 3 */ 4 #include "postgres.h" 5 6 #include "btree_gist.h" 7 #include "btree_utils_num.h" 8 9 typedef struct float4key 10 { 11 float4 lower; 12 float4 upper; 13 } float4KEY; 14 15 /* 16 ** float4 ops 17 */ 18 PG_FUNCTION_INFO_V1(gbt_float4_compress); 19 PG_FUNCTION_INFO_V1(gbt_float4_fetch); 20 PG_FUNCTION_INFO_V1(gbt_float4_union); 21 PG_FUNCTION_INFO_V1(gbt_float4_picksplit); 22 PG_FUNCTION_INFO_V1(gbt_float4_consistent); 23 PG_FUNCTION_INFO_V1(gbt_float4_distance); 24 PG_FUNCTION_INFO_V1(gbt_float4_penalty); 25 PG_FUNCTION_INFO_V1(gbt_float4_same); 26 27 static bool 28 gbt_float4gt(const void *a, const void *b, FmgrInfo *flinfo) 29 { 30 return (*((const float4 *) a) > *((const float4 *) b)); 31 } 32 static bool 33 gbt_float4ge(const void *a, const void *b, FmgrInfo *flinfo) 34 { 35 return (*((const float4 *) a) >= *((const float4 *) b)); 36 } 37 static bool 38 gbt_float4eq(const void *a, const void *b, FmgrInfo *flinfo) 39 { 40 return (*((const float4 *) a) == *((const float4 *) b)); 41 } 42 static bool 43 gbt_float4le(const void *a, const void *b, FmgrInfo *flinfo) 44 { 45 return (*((const float4 *) a) <= *((const float4 *) b)); 46 } 47 static bool 48 gbt_float4lt(const void *a, const void *b, FmgrInfo *flinfo) 49 { 50 return (*((const float4 *) a) < *((const float4 *) b)); 51 } 52 53 static int 54 gbt_float4key_cmp(const void *a, const void *b, FmgrInfo *flinfo) 55 { 56 float4KEY *ia = (float4KEY *) (((const Nsrt *) a)->t); 57 float4KEY *ib = (float4KEY *) (((const Nsrt *) b)->t); 58 59 if (ia->lower == ib->lower) 60 { 61 if (ia->upper == ib->upper) 62 return 0; 63 64 return (ia->upper > ib->upper) ? 1 : -1; 65 } 66 67 return (ia->lower > ib->lower) ? 1 : -1; 68 } 69 70 static float8 71 gbt_float4_dist(const void *a, const void *b, FmgrInfo *flinfo) 72 { 73 return GET_FLOAT_DISTANCE(float4, a, b); 74 } 75 76 77 static const gbtree_ninfo tinfo = 78 { 79 gbt_t_float4, 80 sizeof(float4), 81 8, /* sizeof(gbtreekey8) */ 82 gbt_float4gt, 83 gbt_float4ge, 84 gbt_float4eq, 85 gbt_float4le, 86 gbt_float4lt, 87 gbt_float4key_cmp, 88 gbt_float4_dist 89 }; 90 91 92 PG_FUNCTION_INFO_V1(float4_dist); 93 Datum 94 float4_dist(PG_FUNCTION_ARGS) 95 { 96 float4 a = PG_GETARG_FLOAT4(0); 97 float4 b = PG_GETARG_FLOAT4(1); 98 float4 r; 99 100 r = a - b; 101 CHECKFLOATVAL(r, isinf(a) || isinf(b), true); 102 103 PG_RETURN_FLOAT4(Abs(r)); 104 } 105 106 107 /************************************************** 108 * float4 ops 109 **************************************************/ 110 111 112 Datum 113 gbt_float4_compress(PG_FUNCTION_ARGS) 114 { 115 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); 116 117 PG_RETURN_POINTER(gbt_num_compress(entry, &tinfo)); 118 } 119 120 Datum 121 gbt_float4_fetch(PG_FUNCTION_ARGS) 122 { 123 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); 124 125 PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo)); 126 } 127 128 Datum 129 gbt_float4_consistent(PG_FUNCTION_ARGS) 130 { 131 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); 132 float4 query = PG_GETARG_FLOAT4(1); 133 StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); 134 135 /* Oid subtype = PG_GETARG_OID(3); */ 136 bool *recheck = (bool *) PG_GETARG_POINTER(4); 137 float4KEY *kkk = (float4KEY *) DatumGetPointer(entry->key); 138 GBT_NUMKEY_R key; 139 140 /* All cases served by this function are exact */ 141 *recheck = false; 142 143 key.lower = (GBT_NUMKEY *) &kkk->lower; 144 key.upper = (GBT_NUMKEY *) &kkk->upper; 145 146 PG_RETURN_BOOL( 147 gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo) 148 ); 149 } 150 151 152 Datum 153 gbt_float4_distance(PG_FUNCTION_ARGS) 154 { 155 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); 156 float4 query = PG_GETARG_FLOAT4(1); 157 158 /* Oid subtype = PG_GETARG_OID(3); */ 159 float4KEY *kkk = (float4KEY *) DatumGetPointer(entry->key); 160 GBT_NUMKEY_R key; 161 162 key.lower = (GBT_NUMKEY *) &kkk->lower; 163 key.upper = (GBT_NUMKEY *) &kkk->upper; 164 165 PG_RETURN_FLOAT8( 166 gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo) 167 ); 168 } 169 170 171 Datum 172 gbt_float4_union(PG_FUNCTION_ARGS) 173 { 174 GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); 175 void *out = palloc(sizeof(float4KEY)); 176 177 *(int *) PG_GETARG_POINTER(1) = sizeof(float4KEY); 178 PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo)); 179 } 180 181 182 Datum 183 gbt_float4_penalty(PG_FUNCTION_ARGS) 184 { 185 float4KEY *origentry = (float4KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key); 186 float4KEY *newentry = (float4KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key); 187 float *result = (float *) PG_GETARG_POINTER(2); 188 189 penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper); 190 191 PG_RETURN_POINTER(result); 192 193 } 194 195 Datum 196 gbt_float4_picksplit(PG_FUNCTION_ARGS) 197 { 198 PG_RETURN_POINTER(gbt_num_picksplit( 199 (GistEntryVector *) PG_GETARG_POINTER(0), 200 (GIST_SPLITVEC *) PG_GETARG_POINTER(1), 201 &tinfo, fcinfo->flinfo 202 )); 203 } 204 205 Datum 206 gbt_float4_same(PG_FUNCTION_ARGS) 207 { 208 float4KEY *b1 = (float4KEY *) PG_GETARG_POINTER(0); 209 float4KEY *b2 = (float4KEY *) PG_GETARG_POINTER(1); 210 bool *result = (bool *) PG_GETARG_POINTER(2); 211 212 *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo); 213 PG_RETURN_POINTER(result); 214 } 215