71 flatgeobuf_column **columns;
72 uint32_t columns_size = 0;
73 Oid tupType = HeapTupleHeaderGetTypeId(ctx->
row);
74 int32 tupTypmod = HeapTupleHeaderGetTypMod(ctx->
row);
75 TupleDesc tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
76 int natts = tupdesc->natts;
77 bool geom_found =
false;
79 POSTGIS_DEBUG(2,
"calling inspect_table");
81 columns = palloc(
sizeof(flatgeobuf_column *) * natts);
86 for (
int i = 0; i < natts; i++) {
87 Oid typoid = getBaseType(TupleDescAttr(tupdesc, i)->atttypid);
88 const char *key = TupleDescAttr(tupdesc, i)->attname.data;
89 POSTGIS_DEBUGF(2,
"inspecting column definition for %s with oid %d", key, typoid);
91 if (!geom_found && typoid == postgis_oid(GEOMETRYOID)) {
97 if (!geom_found && strcmp(key, ctx->
geom_name) == 0) {
103 POSTGIS_DEBUGF(2,
"creating column definition for %s with oid %d", key, typoid);
105 c = (flatgeobuf_column *) palloc0(
sizeof(flatgeobuf_column));
106 c->name = pstrdup(key);
108 columns[columns_size] = c;
113 elog(ERROR,
"no geom column found");
115 if (columns_size > 0) {
116 ctx->
ctx->columns = columns;
117 ctx->
ctx->columns_size = columns_size;
172 for (i = 0; i < (uint32_t) ctx->
tupdesc->natts; i++) {
175 datum = GetAttributeByNum(ctx->
row, i + 1, &isnull);
179 memcpy(ctx->
ctx->properties + offset, &ci,
sizeof(ci));
180 offset +=
sizeof(ci);
181 typoid = getBaseType(TupleDescAttr(ctx->
tupdesc, i)->atttypid);
184 byte_value = DatumGetBool(datum) ? 1 : 0;
186 memcpy(ctx->
ctx->properties + offset, &byte_value,
sizeof(byte_value));
187 offset +=
sizeof(byte_value);
190 short_value = DatumGetInt16(datum);
192 memcpy(ctx->
ctx->properties + offset, &short_value,
sizeof(short_value));
193 offset +=
sizeof(short_value);
196 int_value = DatumGetInt32(datum);
198 memcpy(ctx->
ctx->properties + offset, &int_value,
sizeof(int_value));
199 offset +=
sizeof(int_value);
202 long_value = DatumGetInt64(datum);
204 memcpy(ctx->
ctx->properties + offset, &long_value,
sizeof(long_value));
205 offset +=
sizeof(long_value);
208 float_value = DatumGetFloat4(datum);
210 memcpy(ctx->
ctx->properties + offset, &float_value,
sizeof(float_value));
211 offset +=
sizeof(float_value);
214 double_value = DatumGetFloat8(datum);
216 memcpy(ctx->
ctx->properties + offset, &double_value,
sizeof(double_value));
217 offset +=
sizeof(double_value);
220 string_value = text_to_cstring(DatumGetTextP(datum));
221 len = strlen(string_value);
223 memcpy(ctx->
ctx->properties + offset, &len,
sizeof(len));
224 offset +=
sizeof(len);
226 memcpy(ctx->
ctx->properties + offset, string_value, len);
229 case TIMESTAMPTZOID: {
233 const char *tzn = NULL;
234 TimestampTz timestamp;
235 timestamp = DatumGetTimestampTz(datum);
236 timestamp2tm(timestamp, &tz, &tm, &fsec, &tzn, NULL);
237 string_value = palloc(MAXDATELEN + 1);
238 EncodeDateTime(&tm, fsec,
true, tz, tzn, USE_ISO_DATES, string_value);
239 len = strlen(string_value);
241 memcpy(ctx->
ctx->properties + offset, &len,
sizeof(len));
242 offset +=
sizeof(len);
244 memcpy(ctx->
ctx->properties + offset, string_value, len);
263 POSTGIS_DEBUGF(3,
"offset %ld", offset);
264 ctx->
ctx->properties_len = offset;
282 flatgeobuf_column *column;
285 uint8_t *data = ctx->
ctx->properties;
286 uint32_t size = ctx->
ctx->properties_len;
288 POSTGIS_DEBUGF(3,
"flatgeobuf: decode_properties from byte array with length %d at offset %d", size, offset);
292 if (size > 0 && size < (
sizeof(uint16_t) +
sizeof(uint8_t)))
293 elog(ERROR,
"flatgeobuf: decode_properties: Unexpected properties data size %d", size);
294 while (offset + 1 < size) {
295 if (offset +
sizeof(uint16_t) > size)
296 elog(ERROR,
"flatgeobuf: decode_properties: Unexpected offset %d", offset);
297 memcpy(&i, data + offset,
sizeof(uint16_t));
299 offset +=
sizeof(uint16_t);
300 if (i >= ctx->
ctx->columns_size)
301 elog(ERROR,
"flatgeobuf: decode_properties: Column index %hu out of range", i);
302 column = ctx->
ctx->columns[i];
306 case flatgeobuf_column_type_bool: {
308 if (offset +
sizeof(uint8_t) > size)
309 elog(ERROR,
"flatgeobuf: decode_properties: Invalid size for bool value");
310 memcpy(&value, data + offset,
sizeof(uint8_t));
311 values[ci] = BoolGetDatum(value);
312 offset +=
sizeof(uint8_t);
315 case flatgeobuf_column_type_byte: {
317 if (offset +
sizeof(int8_t) > size)
318 elog(ERROR,
"flatgeobuf: decode_properties: Invalid size for byte value");
319 memcpy(&value, data + offset,
sizeof(int8_t));
320 values[ci] = Int8GetDatum(value);
321 offset +=
sizeof(int8_t);
324 case flatgeobuf_column_type_ubyte: {
326 if (offset +
sizeof(uint8_t) > size)
327 elog(ERROR,
"flatgeobuf: decode_properties: Invalid size for ubyte value");
328 memcpy(&value, data + offset,
sizeof(uint8_t));
329 values[ci] = UInt8GetDatum(value);
330 offset +=
sizeof(uint8_t);
333 case flatgeobuf_column_type_short: {
335 if (offset +
sizeof(int16_t) > size)
336 elog(ERROR,
"flatgeobuf: decode_properties: Invalid size for short value");
337 memcpy(&value, data + offset,
sizeof(int16_t));
338 values[ci] = Int16GetDatum(value);
339 offset +=
sizeof(int16_t);
342 case flatgeobuf_column_type_ushort: {
344 if (offset +
sizeof(uint16_t) > size)
345 elog(ERROR,
"flatgeobuf: decode_properties: Invalid size for ushort value");
346 memcpy(&value, data + offset,
sizeof(uint16_t));
347 values[ci] = UInt16GetDatum(value);
348 offset +=
sizeof(uint16_t);
351 case flatgeobuf_column_type_int: {
353 if (offset +
sizeof(int32_t) > size)
354 elog(ERROR,
"flatgeobuf: decode_properties: Invalid size for int value");
355 memcpy(&value, data + offset,
sizeof(int32_t));
356 values[ci] = Int32GetDatum(value);
357 offset +=
sizeof(int32_t);
360 case flatgeobuf_column_type_uint: {
362 if (offset +
sizeof(uint32_t) > size)
363 elog(ERROR,
"flatgeobuf: decode_properties: Invalid size for uint value");
364 memcpy(&value, data + offset,
sizeof(uint32_t));
365 values[ci] = UInt32GetDatum(value);
366 offset +=
sizeof(uint32_t);
369 case flatgeobuf_column_type_long: {
371 if (offset +
sizeof(int64_t) > size)
372 elog(ERROR,
"flatgeobuf: decode_properties: Invalid size for long value");
373 memcpy(&value, data + offset,
sizeof(int64_t));
374 values[ci] = Int64GetDatum(value);
375 offset +=
sizeof(int64_t);
378 case flatgeobuf_column_type_ulong: {
380 if (offset +
sizeof(uint64_t) > size)
381 elog(ERROR,
"flatgeobuf: decode_properties: Invalid size for ulong value");
382 memcpy(&value, data + offset,
sizeof(uint64_t));
383 values[ci] = UInt64GetDatum(value);
384 offset +=
sizeof(uint64_t);
387 case flatgeobuf_column_type_float: {
389 if (offset +
sizeof(
float) > size)
390 elog(ERROR,
"flatgeobuf: decode_properties: Invalid size for float value");
391 memcpy(&value, data + offset,
sizeof(
float));
392 values[ci] = Float4GetDatum(value);
393 offset +=
sizeof(float);
396 case flatgeobuf_column_type_double: {
398 if (offset +
sizeof(
double) > size)
399 elog(ERROR,
"flatgeobuf: decode_properties: Invalid size for double value");
400 memcpy(&value, data + offset,
sizeof(
double));
401 values[ci] = Float8GetDatum(value);
402 offset +=
sizeof(double);
405 case flatgeobuf_column_type_string: {
407 if (offset +
sizeof(len) > size)
408 elog(ERROR,
"flatgeobuf: decode_properties: Invalid size for string value");
409 memcpy(&len, data + offset,
sizeof(uint32_t));
410 offset +=
sizeof(len);
411 values[ci] = PointerGetDatum(cstring_to_text_with_len((
const char *) data + offset, len));
415 case flatgeobuf_column_type_datetime: {
418 char workbuf[MAXDATELEN + MAXDATEFIELDS];
419 char *field[MAXDATEFIELDS];
420 int ftype[MAXDATEFIELDS];
423 struct pg_tm tt, *tm = &tt;
427#if POSTGIS_PGSQL_VERSION >= 160
428 DateTimeErrorExtra extra;
430 if (offset +
sizeof(len) > size)
431 elog(ERROR,
"flatgeobuf: decode_properties: Invalid size for string value");
432 memcpy(&len, data + offset,
sizeof(uint32_t));
433 offset +=
sizeof(len);
434 buf = palloc0(len + 1);
435 memcpy(buf, (
const char *) data + offset, len);
436 ParseDateTime((
const char *) buf, workbuf,
sizeof(workbuf), field, ftype, MAXDATEFIELDS, &nf);
438#if POSTGIS_PGSQL_VERSION >= 160
439 DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tzp, &extra);
441 DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tzp);
443 tm2timestamp(tm, fsec, &tzp, &dttz);
444 values[ci] = TimestampTzGetDatum(dttz);
458 elog(ERROR,
"flatgeobuf: decode_properties: Unknown type %d", type);