113{
114 HeapTupleHeader td;
115 Oid tupType;
117 TupleDesc tupdesc;
118 HeapTupleData tmptup,
119 *tuple;
120 int i;
121 bool needsep = false;
122 const char *sep;
123 StringInfo props = makeStringInfo();
124 bool geom_column_found = false;
125
126 sep = use_line_feeds ? ",\n " : ", ";
127
128 td = DatumGetHeapTupleHeader(composite);
129
130
131 tupType = HeapTupleHeaderGetTypeId(td);
132 tupTypmod = HeapTupleHeaderGetTypMod(td);
133 tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
134
135
136 tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
137 tmptup.t_data = td;
138 tuple = &tmptup;
139
140 appendStringInfoString(result, "{\"type\": \"Feature\", \"geometry\": ");
141
142 for (i = 0; i < tupdesc->natts; i++)
143 {
144 Datum val;
145 bool isnull;
146 char *attname;
148 Oid outfuncoid;
149 Form_pg_attribute att = TupleDescAttr(tupdesc, i);
150 bool is_geom_column = false;
151
152 if (att->attisdropped)
153 continue;
154
155 attname = NameStr(att->attname);
156
157 if (geom_column_name)
158 is_geom_column = (strcmp(attname, geom_column_name) == 0);
159 else
160 is_geom_column = (att->atttypid == geom_oid || att->atttypid == geog_oid);
161
162 if ((!geom_column_found) && is_geom_column)
163 {
164
165 geom_column_found = true;
166
167 val = heap_getattr(tuple, i + 1, tupdesc, &isnull);
168 if (!isnull)
169 {
170 appendStringInfo(result, "%s",
171 TextDatumGetCString(DirectFunctionCall2(
LWGEOM_asGeoJson, val, Int32GetDatum(maxdecimaldigits))));
172 }
173 else
174 {
175 appendStringInfoString(result, "{\"type\": null}");
176 }
177 }
178 else
179 {
180 if (needsep)
181 appendStringInfoString(props, sep);
182 needsep = true;
183
184 escape_json(props, attname);
185 appendStringInfoString(props, ": ");
186
187 val = heap_getattr(tuple, i + 1, tupdesc, &isnull);
188
189 if (isnull)
190 {
192 outfuncoid = InvalidOid;
193 }
194 else
196
197 datum_to_json(val, isnull, props, tcategory, outfuncoid,
false);
198 }
199 }
200
201 if (!geom_column_found)
202 ereport(ERROR,
203 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
204 errmsg("geometry column is missing")));
205
206 appendStringInfoString(result, ", \"properties\": {");
207 appendStringInfo(result, "%s", props->data);
208
209 appendStringInfoString(result, "}}");
210 ReleaseTupleDesc(tupdesc);
211}
static void json_categorize_type(Oid typoid, JsonTypeCategory *tcategory, Oid *outfuncoid)
Datum LWGEOM_asGeoJson(PG_FUNCTION_ARGS)
static void datum_to_json(Datum val, bool is_null, StringInfo result, JsonTypeCategory tcategory, Oid outfuncoid, bool key_scalar)