76 {
77 FuncCallContext *funcctx;
78 MemoryContext oldcontext, newcontext;
79
85
86 HeapTuple tuple;
87 Datum pathpt[2];
88 bool isnull[2] = {0,0};
90
91 if (SRF_IS_FIRSTCALL()) {
92 funcctx = SRF_FIRSTCALL_INIT();
93
94 newcontext = funcctx->multi_call_memory_ctx;
95 oldcontext = MemoryContextSwitchTo(newcontext);
96
97
98 pglwgeom = PG_GETARG_GSERIALIZED_P_COPY(0);
100
101
103 MemoryContextSwitchTo(oldcontext);
104 funcctx = SRF_PERCALL_SETUP();
105 SRF_RETURN_DONE(funcctx);
106 }
107
108
109 state =
lwalloc(
sizeof *state);
110 state->
root = lwgeom;
115
116 funcctx->user_fctx = state;
117
118
119
120
121
125
126
127
128
129 if (get_call_result_type(fcinfo, 0, &funcctx->tuple_desc) != TYPEFUNC_COMPOSITE) {
130 ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
131 errmsg("set-valued function called in context that cannot accept a set")));
132 }
133
134 BlessTupleDesc(funcctx->tuple_desc);
135
136
137 get_typlenbyvalalign(INT4OID, &state->
typlen, &state->
byval, &state->
align);
138
139 MemoryContextSwitchTo(oldcontext);
140 }
141
142
143 funcctx = SRF_PERCALL_SETUP();
144 newcontext = funcctx->multi_call_memory_ctx;
145
146
147 state = funcctx->user_fctx;
148
149 while (1) {
152
153
155
156
157
158
165
167
168
169
170
171
172 switch(lwgeom->
type) {
175 if (state->
pt == 0) {
177 }
178 if (state->
pt <= 3) {
183 &pt);
184 }
187 }
188 break;
195 }
197
200 }
202 } else {
203
204
205
206
207
208
209
210
211
212
217 &pt);
218 }
219 break;
222 break;
227 }
228 break;
233 }
234 break;
235 default:
236 ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
237 errmsg(
"Invalid Geometry type %d passed to ST_DumpPoints()", lwgeom->
type)));
238 }
239 }
240
241
242
243
244
245
246
247
248
249
250 if (!lwpoint) {
251
252 if (--state->
stacklen == 0) SRF_RETURN_DONE(funcctx);
254 continue;
255 } else {
256
258
260 pathpt[0] = PointerGetDatum(construct_array(state->
path, state->
pathlen+1,
262
263 pathpt[1] = PointerGetDatum(geometry_serialize((
LWGEOM*)lwpoint));
264
265 tuple = heap_form_tuple(funcctx->tuple_desc, pathpt, isnull);
266 result = HeapTupleGetDatum(tuple);
267 SRF_RETURN_NEXT(funcctx,
result);
268 }
269 }
270
272
273
275
277 elog(ERROR, "Unable to dump overly nested collection");
278
279
280 lwgeom = lwcoll->
geoms[node->
idx++];
282
286
289
290
291 continue;
292 }
293
294
295 if (--state->
stacklen == 0) SRF_RETURN_DONE(funcctx);
297 }
298}
char result[OUT_DOUBLE_BUFFER_SIZE]
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
LWPOINT * lwline_get_lwpoint(const LWLINE *line, uint32_t where)
Returns freshly allocated LWPOINT that corresponds to the index where.
LWPOINT * lwcircstring_get_lwpoint(const LWCIRCSTRING *circ, uint32_t where)
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
void * lwalloc(size_t size)
LWPOLY * lwgeom_as_lwpoly(const LWGEOM *lwgeom)
LWTRIANGLE * lwgeom_as_lwtriangle(const LWGEOM *lwgeom)
int lwgeom_is_collection(const LWGEOM *lwgeom)
Determine whether a LWGEOM contains sub-geometries or not This basically just checks that the struct ...
LWCIRCSTRING * lwgeom_as_lwcircstring(const LWGEOM *lwgeom)
int getPoint4d_p(const POINTARRAY *pa, uint32_t n, POINT4D *point)
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
LWPOINT * lwpoint_make(int32_t srid, int hasz, int hasm, const POINT4D *p)
int lwgeom_has_m(const LWGEOM *geom)
Return LW_TRUE if geometry has M ordinates.
static LWPOINT * lwgeom_as_lwpoint(const LWGEOM *lwgeom)
static int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
struct dumpnode stack[MAXDEPTH]