75 {
76 FuncCallContext *funcctx;
77 MemoryContext oldcontext, newcontext;
78
84
85 HeapTuple tuple;
86 Datum pathpt[2];
87 bool isnull[2] = {0,0};
88 Datum result;
89
90 if (SRF_IS_FIRSTCALL()) {
91 funcctx = SRF_FIRSTCALL_INIT();
92
93 newcontext = funcctx->multi_call_memory_ctx;
94 oldcontext = MemoryContextSwitchTo(newcontext);
95
96
97 pglwgeom = PG_GETARG_GSERIALIZED_P_COPY(0);
99
100
102 MemoryContextSwitchTo(oldcontext);
103 funcctx = SRF_PERCALL_SETUP();
104 SRF_RETURN_DONE(funcctx);
105 }
106
107
108 state =
lwalloc(
sizeof *state);
109 state->
root = lwgeom;
114
115 funcctx->user_fctx = state;
116
117
118
119
120
124
125
126
127
128 if (get_call_result_type(fcinfo, 0, &funcctx->tuple_desc) != TYPEFUNC_COMPOSITE) {
129 ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
130 errmsg("set-valued function called in context that cannot accept a set")));
131 }
132
133 BlessTupleDesc(funcctx->tuple_desc);
134
135
136 get_typlenbyvalalign(INT4OID, &state->
typlen, &state->
byval, &state->
align);
137
138 MemoryContextSwitchTo(oldcontext);
139 }
140
141
142 funcctx = SRF_PERCALL_SETUP();
143 newcontext = funcctx->multi_call_memory_ctx;
144
145
146 state = funcctx->user_fctx;
147
148 while (1) {
151
152
154
155
156
157
164
166
167
168
169
170
171 switch(lwgeom->
type) {
174 if (state->
pt == 0) {
176 }
177 if (state->
pt <= 3) {
182 &pt);
183 }
186 }
187 break;
194 }
196
199 }
201 } else {
202
203
204
205
206
207
208
209
210
211
216 &pt);
217 }
218 break;
221 break;
226 }
227 break;
232 }
233 break;
234 default:
235 ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
236 errmsg(
"Invalid Geometry type %d passed to ST_DumpPoints()", lwgeom->
type)));
237 }
238 }
239
240
241
242
243
244
245
246
247
248
249 if (!lwpoint) {
250
251 if (--state->
stacklen == 0) SRF_RETURN_DONE(funcctx);
253 continue;
254 } else {
255
257
259 pathpt[0] = PointerGetDatum(construct_array(state->
path, state->
pathlen+1,
261
263
264 tuple = heap_form_tuple(funcctx->tuple_desc, pathpt, isnull);
265 result = HeapTupleGetDatum(tuple);
266 SRF_RETURN_NEXT(funcctx, result);
267 }
268 }
269
271
272
274
275 lwgeom = lwcoll->
geoms[node->
idx++];
277
281
284
285
286 continue;
287 }
288
289
290 if (--state->
stacklen == 0) SRF_RETURN_DONE(funcctx);
293 }
294}
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 can contain sub-geometries or not.
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)
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
struct dumpnode stack[MAXDEPTH]