PostGIS  2.4.9dev-r@@SVN_REVISION@@
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 
15 Datum
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  */
46  if (is_gserialized_from_datum_empty(newval)) {
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 bouding 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 }
#define INCLUSION_CONTAINS_EMPTY
Definition: postgis_brin.h:21
PG_FUNCTION_INFO_V1(geom2d_brin_inclusion_add_value)
#define LW_FAILURE
Definition: liblwgeom.h:79
#define INCLUSION_UNION
Definition: postgis_brin.h:19
Datum geom2d_brin_inclusion_add_value(PG_FUNCTION_ARGS)
Definition: brin_2d.c:16
int gserialized_datum_get_box2df_p(Datum gsdatum, BOX2DF *box2df)
Peak into a GSERIALIZED datum to find the bounding box.
bool box2df_contains(const BOX2DF *a, const BOX2DF *b)
bool is_gserialized_from_datum_empty(Datum the_datum)
Definition: brin_common.c:4
if(!(yy_init))
#define INCLUSION_UNMERGEABLE
Definition: postgis_brin.h:20