71{
75 FuncCallContext *funcctx;
78 TupleDesc tupdesc;
79 HeapTuple tuple;
80 AttInMetadata *attinmeta;
81 MemoryContext oldcontext, newcontext;
82 Datum result;
83 char address[256];
84 char *ptr;
85 int i;
86 char *values[2];
87
88 if (SRF_IS_FIRSTCALL())
89 {
90 funcctx = SRF_FIRSTCALL_INIT();
91 newcontext = funcctx->multi_call_memory_ctx;
92
93 oldcontext = MemoryContextSwitchTo(newcontext);
94
95 pglwgeom = PG_GETARG_GSERIALIZED_P_COPY(0);
97
98
100 state->
root = lwgeom;
102
104 {
105
106
107
112 }
113
114 funcctx->user_fctx = state;
115
116
117
118
119
120 get_call_result_type(fcinfo, 0, &tupdesc);
121 BlessTupleDesc(tupdesc);
122
123
124
125
126
127 attinmeta = TupleDescGetAttInMetadata(tupdesc);
128 funcctx->attinmeta = attinmeta;
129
130 MemoryContextSwitchTo(oldcontext);
131 }
132
133
134 funcctx = SRF_PERCALL_SETUP();
135 newcontext = funcctx->multi_call_memory_ctx;
136
137
138 state = funcctx->user_fctx;
139
140
141 if ( ! state->
root ) SRF_RETURN_DONE(funcctx);
142
145 {
146 values[0] = "{}";
148 tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
149 result = HeapTupleGetDatum(tuple);
150
152 SRF_RETURN_NEXT(funcctx, result);
153 }
154
155 while (1)
156 {
159
161 {
164 {
165
166 ptr=address;
167 *ptr++='{';
169 {
170 if ( i ) ptr += sprintf(ptr, ",");
171 ptr += sprintf(ptr,
"%d", state->
stack[i]->
idx+1);
172 }
173 *ptr++='}';
174 *ptr='\0';
175
176 break;
177 }
178
179
180
181
182
183
184
185 oldcontext = MemoryContextSwitchTo(newcontext);
186
191
192 MemoryContextSwitchTo(oldcontext);
193
194 continue;
195 }
196
197 if ( !
POP(state) ) SRF_RETURN_DONE(funcctx);
199 }
200
202
203 values[0] = address;
205 tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
206 result = TupleGetDatum(funcctx->slot, tuple);
208 SRF_RETURN_NEXT(funcctx, result);
209}
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
char * lwgeom_to_hexwkb(const LWGEOM *geom, uint8_t variant, size_t *size_out)
void * lwalloc(size_t size)
int lwgeom_is_collection(const LWGEOM *lwgeom)
Determine whether a LWGEOM can contain sub-geometries or not.
static int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
GEOMDUMPNODE * stack[MAXDEPTH]