PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ gidx_brin_inclusion_add_value() [1/2]

static Datum gidx_brin_inclusion_add_value ( __attribute__((__unused__)) BrinDesc *  bdesc,
BrinValues *  column,
Datum  newval,
bool  isnull,
int  max_dims 
)
static

Definition at line 66 of file brin_nd.c.

68{
69 char gboxmem[GIDX_MAX_SIZE];
70 GIDX *gidx_geom, *gidx_key;
71 int dims_geom, dims_key, i;
72
73 Assert(max_dims <= GIDX_MAX_DIM);
74
75 /*
76 * If the new value is null, we record that we saw it if it's the first
77 * one; otherwise, there's nothing to do.
78 */
79 if (isnull)
80 {
81 if (column->bv_hasnulls)
82 PG_RETURN_BOOL(false);
83
84 column->bv_hasnulls = true;
85 PG_RETURN_BOOL(true);
86 }
87
88 /*
89 * No need for further processing if the block range is already initialized
90 * and is marked as containing unmergeable values.
91 */
92 if (!column->bv_allnulls &&
93 DatumGetBool(column->bv_values[INCLUSION_UNMERGEABLE]))
94 PG_RETURN_BOOL(false);
95
96 /* create a new GIDX in stack memory, maximum dimensions */
97 gidx_geom = (GIDX *) gboxmem;
98
99 /*
100 * check other cases where it is not possible to retrieve a box
101 */
102 if (gserialized_datum_get_gidx_p(newval, gidx_geom) == LW_FAILURE)
103 {
104 /*
105 * Empty entries have to be supported in the opclass: test the passed
106 * new value for emptiness; if it returns true, we need to set the
107 * "contains empty" flag in the element (unless already set).
108 */
110 {
111 if (!DatumGetBool(column->bv_values[INCLUSION_CONTAINS_EMPTY]))
112 {
113 column->bv_values[INCLUSION_CONTAINS_EMPTY] = BoolGetDatum(true);
114 PG_RETURN_BOOL(true);
115 }
116
117 PG_RETURN_BOOL(false);
118 } else
119 {
120 /*
121 * in case the entry is not empty and it is not possible to
122 * retrieve a box, raise an error
123 */
124 elog(ERROR, "Error while extracting the gidx from the geom");
125 }
126 }
127
128 /* Get the actual dimension of the geometry */
129 dims_geom = GIDX_NDIMS(gidx_geom);
130
131 /* if the recorded value is null, we just need to store the GIDX */
132 if (column->bv_allnulls)
133 {
134 /*
135 * It's not safe to summarize geometries of different number of
136 * dimensions in the same range. We therefore fix the number of
137 * dimension for this range by storing the bounding box of the first
138 * geometry found as is, being careful not to store more dimension than
139 * defined in the opclass.
140 */
141 if (dims_geom > max_dims)
142 {
143 /*
144 * Diminush the varsize to only store the maximum number of
145 * dimensions allowed by the opclass
146 */
147 SET_VARSIZE(gidx_geom, VARHDRSZ + max_dims * 2 * sizeof(float));
148 dims_geom = max_dims;
149 }
150
151 column->bv_values[INCLUSION_UNION] = datumCopy((Datum) gidx_geom, false,
152 GIDX_SIZE(dims_geom));
153 column->bv_values[INCLUSION_UNMERGEABLE] = BoolGetDatum(false);
154 column->bv_values[INCLUSION_CONTAINS_EMPTY] = BoolGetDatum(false);
155 column->bv_allnulls = false;
156 PG_RETURN_BOOL(true);
157 }
158
159 gidx_key = (GIDX *) column->bv_values[INCLUSION_UNION];
160 dims_key = GIDX_NDIMS(gidx_key);
161
162 /*
163 * Mark the datum as unmergeable if its number of dimension is not the same
164 * as the one stored in the key of the current range
165 */
166 if (dims_key != dims_geom)
167 {
168 column->bv_values[INCLUSION_UNMERGEABLE] = BoolGetDatum(true);
169 PG_RETURN_BOOL(true);
170 }
171
172 /* Check if the stored bounding box already contains the geometry's one */
173 if (gidx_contains(gidx_key, gidx_geom))
174 PG_RETURN_BOOL(false);
175
176 /*
177 * Otherwise, we need to enlarge the stored GIDX to make it contains the
178 * current geometry. As we store a GIDX with a fixed number of dimensions,
179 * we just need adjust min and max
180 */
181 for ( i = 0; i < dims_key; i++ )
182 {
183 /* Adjust minimums */
184 GIDX_SET_MIN(gidx_key, i,
185 Min(GIDX_GET_MIN(gidx_key,i),GIDX_GET_MIN(gidx_geom,i)));
186 /* Adjust maximums */
187 GIDX_SET_MAX(gidx_key, i,
188 Max(GIDX_GET_MAX(gidx_key,i),GIDX_GET_MAX(gidx_geom,i)));
189 }
190
191 PG_RETURN_BOOL(true);
192}
bool is_gserialized_from_datum_empty(Datum the_datum)
Definition brin_common.c:4
bool gidx_contains(GIDX *a, GIDX *b)
#define LW_FAILURE
Definition liblwgeom.h:96
#define INCLUSION_UNMERGEABLE
#define INCLUSION_UNION
#define INCLUSION_CONTAINS_EMPTY

References gidx_contains(), INCLUSION_CONTAINS_EMPTY, INCLUSION_UNION, INCLUSION_UNMERGEABLE, is_gserialized_from_datum_empty(), and LW_FAILURE.

Here is the call graph for this function: