GISTENTRY * gbt_var_compress(GISTENTRY *entry, const gbtree_vinfo *tinfo) { GISTENTRY *retval; if (entry->leafkey) { GBT_VARKEY *r = NULL; bytea *leaf = (bytea *) DatumGetPointer(PG_DETOAST_DATUM(entry->key)); GBT_VARKEY_R u; u.lower = u.upper = leaf; r = gbt_var_key_copy(&u, FALSE); retval = palloc(sizeof(GISTENTRY)); gistentryinit(*retval, PointerGetDatum(r), entry->rel, entry->page, entry->offset, TRUE); } else retval = entry; return (retval); }
void gbt_var_bin_union(Datum *u, GBT_VARKEY *e, Oid collation, const gbtree_vinfo *tinfo) { GBT_VARKEY_R eo = gbt_var_key_readable(e); GBT_VARKEY_R nr; if (eo.lower == eo.upper) /* leaf */ { GBT_VARKEY *tmp; tmp = gbt_var_leaf2node(e, tinfo); if (tmp != e) eo = gbt_var_key_readable(tmp); } if (DatumGetPointer(*u)) { GBT_VARKEY_R ro = gbt_var_key_readable((GBT_VARKEY *) DatumGetPointer(*u)); bool update = false; nr.lower = ro.lower; nr.upper = ro.upper; if ((*tinfo->f_cmp) (ro.lower, eo.lower, collation) > 0) { nr.lower = eo.lower; update = true; } if ((*tinfo->f_cmp) (ro.upper, eo.upper, collation) < 0) { nr.upper = eo.upper; update = true; } if (update) *u = PointerGetDatum(gbt_var_key_copy(&nr)); } else { nr.lower = eo.lower; nr.upper = eo.upper; *u = PointerGetDatum(gbt_var_key_copy(&nr)); } }
void gbt_var_bin_union(Datum *u, GBT_VARKEY *e, Oid collation, const gbtree_vinfo *tinfo) { GBT_VARKEY *nk = NULL; GBT_VARKEY *tmp = NULL; GBT_VARKEY_R nr; GBT_VARKEY_R eo = gbt_var_key_readable(e); if (eo.lower == eo.upper) /* leaf */ { tmp = gbt_var_leaf2node(e, tinfo); if (tmp != e) eo = gbt_var_key_readable(tmp); } if (DatumGetPointer(*u)) { GBT_VARKEY_R ro = gbt_var_key_readable((GBT_VARKEY *) DatumGetPointer(*u)); if ((*tinfo->f_cmp) (ro.lower, eo.lower, collation) > 0) { nr.lower = eo.lower; nr.upper = ro.upper; nk = gbt_var_key_copy(&nr, TRUE); } if ((*tinfo->f_cmp) (ro.upper, eo.upper, collation) < 0) { nr.upper = eo.upper; nr.lower = ro.lower; nk = gbt_var_key_copy(&nr, TRUE); } if (nk) *u = PointerGetDatum(nk); } else { nr.lower = eo.lower; nr.upper = eo.upper; *u = PointerGetDatum(gbt_var_key_copy(&nr, TRUE)); } }
static GBT_VARKEY * gbt_bit_l2n(GBT_VARKEY *leaf) { GBT_VARKEY *out = leaf; GBT_VARKEY_R r = gbt_var_key_readable(leaf); bytea *o; o = gbt_bit_xfrm(r.lower); r.upper = r.lower = o; out = gbt_var_key_copy(&r); pfree(o); return out; }
GBT_VARKEY * gbt_var_union(const GistEntryVector *entryvec, int32 *size, Oid collation, const gbtree_vinfo *tinfo) { int i = 0, numranges = entryvec->n; GBT_VARKEY *cur; Datum out; GBT_VARKEY_R rk; *size = sizeof(GBT_VARKEY); cur = (GBT_VARKEY *) DatumGetPointer(entryvec->vector[0].key); rk = gbt_var_key_readable(cur); out = PointerGetDatum(gbt_var_key_copy(&rk, TRUE)); for (i = 1; i < numranges; i++) { cur = (GBT_VARKEY *) DatumGetPointer(entryvec->vector[i].key); gbt_var_bin_union(&out, cur, collation, tinfo); } /* Truncate (=compress) key */ if (tinfo->trnc) { int32 plen; GBT_VARKEY *trc = NULL; plen = gbt_var_node_cp_len((GBT_VARKEY *) DatumGetPointer(out), tinfo); trc = gbt_var_node_truncate((GBT_VARKEY *) DatumGetPointer(out), plen + 1, tinfo); out = PointerGetDatum(trc); } return ((GBT_VARKEY *) DatumGetPointer(out)); }
Datum gbt_numeric_penalty(PG_FUNCTION_ARGS) { GISTENTRY *o = (GISTENTRY *) PG_GETARG_POINTER(0); GISTENTRY *n = (GISTENTRY *) PG_GETARG_POINTER(1); float *result = (float *) PG_GETARG_POINTER(2); Numeric us, os, ds; GBT_VARKEY *org = (GBT_VARKEY *) DatumGetPointer(o->key); GBT_VARKEY *newe = (GBT_VARKEY *) DatumGetPointer(n->key); Datum uni; GBT_VARKEY_R rk, ok, uk; rk = gbt_var_key_readable(org); uni = PointerGetDatum(gbt_var_key_copy(&rk, TRUE)); gbt_var_bin_union(&uni, newe, &tinfo); ok = gbt_var_key_readable(org); uk = gbt_var_key_readable((GBT_VARKEY *) DatumGetPointer(uni)); us = DatumGetNumeric(DirectFunctionCall2( numeric_sub, PointerGetDatum(uk.upper), PointerGetDatum(uk.lower) )); os = DatumGetNumeric(DirectFunctionCall2( numeric_sub, PointerGetDatum(ok.upper), PointerGetDatum(ok.lower) )); ds = DatumGetNumeric(DirectFunctionCall2( numeric_sub, NumericGetDatum(us), NumericGetDatum(os) )); if (numeric_is_nan(us)) { if (numeric_is_nan(os)) *result = 0.0; else *result = 1.0; } else { Numeric nul = DatumGetNumeric(DirectFunctionCall1(int4_numeric, Int32GetDatum(0))); *result = 0.0; if (DirectFunctionCall2(numeric_gt, NumericGetDatum(ds), NumericGetDatum(nul))) { *result += FLT_MIN; os = DatumGetNumeric(DirectFunctionCall2( numeric_div, NumericGetDatum(ds), NumericGetDatum(us) )); *result += (float4) DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow, NumericGetDatum(os))); } } if (*result > 0) *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1)); PG_RETURN_POINTER(result); }