PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches
brin_2d.c
Go to the documentation of this file.
1#include "postgis_brin.h"
2
3/*
4 * As we index geometries but store either a BOX2DF or GIDX according to the
5 * operator class, we need to overload the original brin_inclusion_add_value()
6 * function to be able to do this. Other original mandatory support functions
7 * doesn't need to be overloaded.
8 *
9 * The previous limitation might be lifted, but we also eliminate some overhead
10 * by doing it this way, namely calling different functions through the
11 * FunctionCallInvoke machinery for each heap tuple.
12 */
13
15Datum
17{
18 BrinValues *column = (BrinValues *) PG_GETARG_POINTER(1);
19 Datum newval = PG_GETARG_DATUM(2);
20 bool isnull = PG_GETARG_BOOL(3);
21 BOX2DF box_geom, *box_key;
22
23 /*
24 * If the new value is null, we record that we saw it if it's the first
25 * one; otherwise, there's nothing to do.
26 */
27 if (isnull)
28 {
29 if (column->bv_hasnulls)
30 PG_RETURN_BOOL(false);
31
32 column->bv_hasnulls = true;
33 PG_RETURN_BOOL(true);
34 }
35
36 /*
37 * check other cases where it is not possible to retrieve a box
38 */
39 if (gserialized_datum_get_box2df_p(newval, &box_geom) == LW_FAILURE)
40 {
41 /*
42 * Empty entries have to be supported in the opclass: test the passed
43 * new value for emptiness; if it returns true, we need to set the
44 * "contains empty" flag in the element (unless already set).
45 */
47 if (!DatumGetBool(column->bv_values[INCLUSION_CONTAINS_EMPTY]))
48 {
49 column->bv_values[INCLUSION_CONTAINS_EMPTY] = BoolGetDatum(true);
50 PG_RETURN_BOOL(true);
51 }
52
53 PG_RETURN_BOOL(false);
54 } else
55 {
56 /*
57 * in case the entry is not empty and it is not possible to
58 * retrieve a box, raise an error
59 */
60 elog(ERROR, "Error while extracting the box2df from the geom");
61 }
62 }
63
64 /* if the recorded value is null, we just need to store the box2df */
65 if (column->bv_allnulls)
66 {
67 column->bv_values[INCLUSION_UNION] = datumCopy((Datum) &box_geom, false,
68 sizeof(BOX2DF));
69 column->bv_values[INCLUSION_UNMERGEABLE] = BoolGetDatum(false);
70 column->bv_values[INCLUSION_CONTAINS_EMPTY] = BoolGetDatum(false);
71 column->bv_allnulls = false;
72 PG_RETURN_BOOL(true);
73 }
74
75 box_key = (BOX2DF *) column->bv_values[INCLUSION_UNION];
76
77 /* Check if the stored bounding box already contains the geometry's one */
78 if (box2df_contains(box_key, &box_geom))
79 PG_RETURN_BOOL(false);
80
81 /*
82 * Otherwise, we need to enlarge the stored box2df to make it contains the
83 * current geometry
84 */
85 box_key->xmin = Min(box_key->xmin, box_geom.xmin);
86 box_key->xmax = Max(box_key->xmax, box_geom.xmax);
87 box_key->ymin = Min(box_key->ymin, box_geom.ymin);
88 box_key->ymax = Max(box_key->ymax, box_geom.ymax);
89
90 PG_RETURN_BOOL(true);
91}
92
93
95Datum
97{
98 BOX2DF *box_key = (BOX2DF *) PG_GETARG_POINTER(0);
99 BOX2DF *box_geom = (BOX2DF *) PG_GETARG_POINTER(1);
100
101 /*
102 * Check if the stored bounding box already contains the geometry's one.
103 *
104 * If not, enlarge the stored box2df to make it contains the current
105 * geometry.
106 */
107 if (!box2df_contains(box_key, box_geom))
108 {
109 box_key->xmin = Min(box_key->xmin, box_geom->xmin);
110 box_key->xmax = Max(box_key->xmax, box_geom->xmax);
111 box_key->ymin = Min(box_key->ymin, box_geom->ymin);
112 box_key->ymax = Max(box_key->ymax, box_geom->ymax);
113 }
114
115 PG_RETURN_POINTER(box_key);
116}
117
118
Datum geom2d_brin_inclusion_add_value(PG_FUNCTION_ARGS)
Definition brin_2d.c:16
Datum geom2d_brin_inclusion_merge(PG_FUNCTION_ARGS)
Definition brin_2d.c:96
PG_FUNCTION_INFO_V1(geom2d_brin_inclusion_add_value)
bool is_gserialized_from_datum_empty(Datum the_datum)
Definition brin_common.c:4
bool box2df_contains(const BOX2DF *a, const BOX2DF *b)
int gserialized_datum_get_box2df_p(Datum gsdatum, BOX2DF *box2df)
#define LW_FAILURE
Definition liblwgeom.h:96
#define INCLUSION_UNMERGEABLE
#define INCLUSION_UNION
#define INCLUSION_CONTAINS_EMPTY