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

◆ gidx_brin_inclusion_add_value() [1/2]

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

Definition at line 62 of file brin_nd.c.

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