Merge pull request #297 from pblottiere/code_layout_pgsql

clang-format pgsql directory
This commit is contained in:
Paul Blottiere 2022-02-08 10:20:07 +01:00 committed by GitHub
commit 2b0a4a9bf2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 1986 additions and 1972 deletions

View File

@ -16,7 +16,7 @@ jobs:
- name: Install clang-format
run: sudo apt-get install clang-format
- name: Clang-format check
run: clang-format --dry-run --Werror -style=file lib/*.c lib/*.cpp lib/*.hpp lib/*.h lib/cunit/*.c lib/cunit/*.h
run: clang-format --dry-run --Werror -style=file pgsql/*.c pgsql/*.h lib/*.c lib/*.cpp lib/*.hpp lib/*.h lib/cunit/*.c lib/cunit/*.h
sql_code_layout:
name: SQL linter
runs-on: ubuntu-18.04

File diff suppressed because it is too large Load Diff

View File

@ -1,126 +1,124 @@
/***********************************************************************
* pc_editor.c
*
* Editor functions for points and patches in PgSQL.
*
* Copyright (c) 2017 Oslandia
*
***********************************************************************/
* pc_editor.c
*
* Editor functions for points and patches in PgSQL.
*
* Copyright (c) 2017 Oslandia
*
***********************************************************************/
#include "pc_pgsql.h" /* Common PgSQL support for our type */
#include "pc_pgsql.h" /* Common PgSQL support for our type */
Datum pcpatch_setpcid(PG_FUNCTION_ARGS);
Datum pcpatch_transform(PG_FUNCTION_ARGS);
static SERIALIZED_PATCH *
pcpatch_set_schema(SERIALIZED_PATCH *serpa,
PCSCHEMA *oschema, PCSCHEMA *nschema, float8 def)
static SERIALIZED_PATCH *pcpatch_set_schema(SERIALIZED_PATCH *serpa,
PCSCHEMA *oschema,
PCSCHEMA *nschema, float8 def)
{
SERIALIZED_PATCH *serpatch;
PCPATCH *paout;
SERIALIZED_PATCH *serpatch;
PCPATCH *paout;
if ( pc_schema_same_dimensions(oschema, nschema) )
{
// oschema and nschema have the same dimensions at the same
// positions, so we can take a fast path and avoid the
// point-by-point dimension-by-dimension copying
if (pc_schema_same_dimensions(oschema, nschema))
{
// oschema and nschema have the same dimensions at the same
// positions, so we can take a fast path and avoid the
// point-by-point dimension-by-dimension copying
if ( oschema->compression == nschema->compression )
{
// no need to deserialize the patch
serpatch = palloc(serpa->size);
if ( ! serpatch )
return NULL;
memcpy(serpatch, serpa, serpa->size);
serpatch->pcid = nschema->pcid;
return serpatch;
}
else
{
paout = pc_patch_deserialize(serpa, oschema);
if ( ! paout )
return NULL;
paout->schema = nschema;
}
} else {
PCPATCH *patch;
if (oschema->compression == nschema->compression)
{
// no need to deserialize the patch
serpatch = palloc(serpa->size);
if (!serpatch)
return NULL;
memcpy(serpatch, serpa, serpa->size);
serpatch->pcid = nschema->pcid;
return serpatch;
}
else
{
paout = pc_patch_deserialize(serpa, oschema);
if (!paout)
return NULL;
paout->schema = nschema;
}
}
else
{
PCPATCH *patch;
patch = pc_patch_deserialize(serpa, oschema);
if ( ! patch )
return NULL;
patch = pc_patch_deserialize(serpa, oschema);
if (!patch)
return NULL;
paout = pc_patch_set_schema(patch, nschema, def);
paout = pc_patch_set_schema(patch, nschema, def);
if ( patch != paout )
pc_patch_free(patch);
if (patch != paout)
pc_patch_free(patch);
if ( ! paout )
return NULL;
if (!paout)
return NULL;
}
}
serpatch = pc_patch_serialize(paout, NULL);
pc_patch_free(paout);
serpatch = pc_patch_serialize(paout, NULL);
pc_patch_free(paout);
return serpatch;
return serpatch;
}
PG_FUNCTION_INFO_V1(pcpatch_setpcid);
Datum pcpatch_setpcid(PG_FUNCTION_ARGS)
{
SERIALIZED_PATCH *serpatch;
SERIALIZED_PATCH *serpa = PG_GETARG_SERPATCH_P(0);
int32 pcid = PG_GETARG_INT32(1);
float8 def = PG_GETARG_FLOAT8(2);
PCSCHEMA *oschema = pc_schema_from_pcid(serpa->pcid, fcinfo);
PCSCHEMA *nschema = pc_schema_from_pcid(pcid, fcinfo);
SERIALIZED_PATCH *serpatch;
SERIALIZED_PATCH *serpa = PG_GETARG_SERPATCH_P(0);
int32 pcid = PG_GETARG_INT32(1);
float8 def = PG_GETARG_FLOAT8(2);
PCSCHEMA *oschema = pc_schema_from_pcid(serpa->pcid, fcinfo);
PCSCHEMA *nschema = pc_schema_from_pcid(pcid, fcinfo);
serpatch = pcpatch_set_schema(serpa, oschema, nschema, def);
if ( ! serpatch )
PG_RETURN_NULL();
PG_RETURN_POINTER(serpatch);
serpatch = pcpatch_set_schema(serpa, oschema, nschema, def);
if (!serpatch)
PG_RETURN_NULL();
PG_RETURN_POINTER(serpatch);
}
PG_FUNCTION_INFO_V1(pcpatch_transform);
Datum pcpatch_transform(PG_FUNCTION_ARGS)
{
SERIALIZED_PATCH *serpatch;
SERIALIZED_PATCH *serpa = PG_GETARG_SERPATCH_P(0);
int32 pcid = PG_GETARG_INT32(1);
float8 def = PG_GETARG_FLOAT8(2);
PCSCHEMA *oschema = pc_schema_from_pcid(serpa->pcid, fcinfo);
PCSCHEMA *nschema = pc_schema_from_pcid(pcid, fcinfo);
SERIALIZED_PATCH *serpatch;
SERIALIZED_PATCH *serpa = PG_GETARG_SERPATCH_P(0);
int32 pcid = PG_GETARG_INT32(1);
float8 def = PG_GETARG_FLOAT8(2);
PCSCHEMA *oschema = pc_schema_from_pcid(serpa->pcid, fcinfo);
PCSCHEMA *nschema = pc_schema_from_pcid(pcid, fcinfo);
// fast path to setpcid if no data transformation is required
// fast path to setpcid if no data transformation is required
if ( pc_schema_same_interpretations(oschema, nschema) )
{
serpatch = pcpatch_set_schema(serpa, oschema, nschema, def);
if ( ! serpatch )
PG_RETURN_NULL();
PG_RETURN_POINTER(serpatch);
}
else
{
PCPATCH *patch, *paout;
if (pc_schema_same_interpretations(oschema, nschema))
{
serpatch = pcpatch_set_schema(serpa, oschema, nschema, def);
if (!serpatch)
PG_RETURN_NULL();
PG_RETURN_POINTER(serpatch);
}
else
{
PCPATCH *patch, *paout;
patch = pc_patch_deserialize(serpa, oschema);
if ( ! patch )
PG_RETURN_NULL();
patch = pc_patch_deserialize(serpa, oschema);
if (!patch)
PG_RETURN_NULL();
paout = pc_patch_transform(patch, nschema, def);
paout = pc_patch_transform(patch, nschema, def);
pc_patch_free(patch);
pc_patch_free(patch);
if ( ! paout )
PG_RETURN_NULL();
if (!paout)
PG_RETURN_NULL();
serpatch = pc_patch_serialize(paout, NULL);
pc_patch_free(paout);
serpatch = pc_patch_serialize(paout, NULL);
pc_patch_free(paout);
PG_RETURN_POINTER(serpatch);
}
PG_RETURN_POINTER(serpatch);
}
}

View File

@ -1,15 +1,15 @@
/***********************************************************************
* pc_inout.c
*
* Input/output functions for points and patches in PgSQL.
*
* PgSQL Pointcloud is free and open source software provided
* by the Government of Canada
* Copyright (c) 2013 Natural Resources Canada
*
***********************************************************************/
* pc_inout.c
*
* Input/output functions for points and patches in PgSQL.
*
* PgSQL Pointcloud is free and open source software provided
* by the Government of Canada
* Copyright (c) 2013 Natural Resources Canada
*
***********************************************************************/
#include "pc_pgsql.h" /* Common PgSQL support for our type */
#include "pc_pgsql.h" /* Common PgSQL support for our type */
/* In/out functions */
Datum pcpoint_in(PG_FUNCTION_ARGS);
@ -34,437 +34,437 @@ Datum pcpoint_as_bytea(PG_FUNCTION_ARGS);
Datum pcpatch_envelope_as_bytea(PG_FUNCTION_ARGS);
Datum pcpatch_bounding_diagonal_as_bytea(PG_FUNCTION_ARGS);
static void
pcid_consistent(const uint32 pcid, const uint32 column_pcid)
static void pcid_consistent(const uint32 pcid, const uint32 column_pcid)
{
if ( column_pcid && pcid != column_pcid )
{
ereport(ERROR, (
errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("point/patch pcid (%u) does not match column pcid (%d)", pcid, column_pcid)
));
}
if (column_pcid && pcid != column_pcid)
{
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("point/patch pcid (%u) does not match column pcid (%d)",
pcid, column_pcid)));
}
}
PG_FUNCTION_INFO_V1(pcpoint_in);
Datum pcpoint_in(PG_FUNCTION_ARGS)
{
char *str = PG_GETARG_CSTRING(0);
/* Datum pc_oid = PG_GETARG_OID(1); Not needed. */
int32 typmod = 0;
uint32 pcid = 0;
PCPOINT *pt;
SERIALIZED_POINT *serpt = NULL;
char *str = PG_GETARG_CSTRING(0);
/* Datum pc_oid = PG_GETARG_OID(1); Not needed. */
int32 typmod = 0;
uint32 pcid = 0;
PCPOINT *pt;
SERIALIZED_POINT *serpt = NULL;
if ( (PG_NARGS()>2) && (!PG_ARGISNULL(2)) )
{
typmod = PG_GETARG_INT32(2);
pcid = pcid_from_typmod(typmod);
}
if ((PG_NARGS() > 2) && (!PG_ARGISNULL(2)))
{
typmod = PG_GETARG_INT32(2);
pcid = pcid_from_typmod(typmod);
}
/* Empty string. */
if ( str[0] == '\0' )
{
ereport(ERROR,(errmsg("pcpoint parse error - empty string")));
}
/* Empty string. */
if (str[0] == '\0')
{
ereport(ERROR, (errmsg("pcpoint parse error - empty string")));
}
/* Binary or text form? Let's find out. */
if ( str[0] == '0' )
{
/* Hex-encoded binary */
pt = pc_point_from_hexwkb(str, strlen(str), fcinfo);
pcid_consistent(pt->schema->pcid, pcid);
serpt = pc_point_serialize(pt);
pc_point_free(pt);
}
else
{
ereport(ERROR,(errmsg("parse error - support for text format not yet implemented")));
}
/* Binary or text form? Let's find out. */
if (str[0] == '0')
{
/* Hex-encoded binary */
pt = pc_point_from_hexwkb(str, strlen(str), fcinfo);
pcid_consistent(pt->schema->pcid, pcid);
serpt = pc_point_serialize(pt);
pc_point_free(pt);
}
else
{
ereport(
ERROR,
(errmsg("parse error - support for text format not yet implemented")));
}
if ( serpt ) PG_RETURN_POINTER(serpt);
else PG_RETURN_NULL();
if (serpt)
PG_RETURN_POINTER(serpt);
else
PG_RETURN_NULL();
}
PG_FUNCTION_INFO_V1(pcpoint_out);
Datum pcpoint_out(PG_FUNCTION_ARGS)
{
PCPOINT *pcpt = NULL;
PCSCHEMA *schema = NULL;
SERIALIZED_POINT *serpt = NULL;
char *hexwkb = NULL;
PCPOINT *pcpt = NULL;
PCSCHEMA *schema = NULL;
SERIALIZED_POINT *serpt = NULL;
char *hexwkb = NULL;
serpt = PG_GETARG_SERPOINT_P(0);
schema = pc_schema_from_pcid(serpt->pcid, fcinfo);
pcpt = pc_point_deserialize(serpt, schema);
hexwkb = pc_point_to_hexwkb(pcpt);
pc_point_free(pcpt);
PG_RETURN_CSTRING(hexwkb);
serpt = PG_GETARG_SERPOINT_P(0);
schema = pc_schema_from_pcid(serpt->pcid, fcinfo);
pcpt = pc_point_deserialize(serpt, schema);
hexwkb = pc_point_to_hexwkb(pcpt);
pc_point_free(pcpt);
PG_RETURN_CSTRING(hexwkb);
}
PG_FUNCTION_INFO_V1(pcpatch_in);
Datum pcpatch_in(PG_FUNCTION_ARGS)
{
char *str = PG_GETARG_CSTRING(0);
/* Datum geog_oid = PG_GETARG_OID(1); Not needed. */
uint32 typmod = 0, pcid = 0;
PCPATCH *patch;
SERIALIZED_PATCH *serpatch = NULL;
char *str = PG_GETARG_CSTRING(0);
/* Datum geog_oid = PG_GETARG_OID(1); Not needed. */
uint32 typmod = 0, pcid = 0;
PCPATCH *patch;
SERIALIZED_PATCH *serpatch = NULL;
if ( (PG_NARGS()>2) && (!PG_ARGISNULL(2)) )
{
typmod = PG_GETARG_INT32(2);
pcid = pcid_from_typmod(typmod);
}
if ((PG_NARGS() > 2) && (!PG_ARGISNULL(2)))
{
typmod = PG_GETARG_INT32(2);
pcid = pcid_from_typmod(typmod);
}
/* Empty string. */
if ( str[0] == '\0' )
{
ereport(ERROR,(errmsg("pcpatch parse error - empty string")));
}
/* Empty string. */
if (str[0] == '\0')
{
ereport(ERROR, (errmsg("pcpatch parse error - empty string")));
}
/* Binary or text form? Let's find out. */
if ( str[0] == '0' )
{
/* Hex-encoded binary */
patch = pc_patch_from_hexwkb(str, strlen(str), fcinfo);
pcid_consistent(patch->schema->pcid, pcid);
serpatch = pc_patch_serialize(patch, NULL);
pc_patch_free(patch);
}
else
{
ereport(ERROR,(errmsg("parse error - support for text format not yet implemented")));
}
/* Binary or text form? Let's find out. */
if (str[0] == '0')
{
/* Hex-encoded binary */
patch = pc_patch_from_hexwkb(str, strlen(str), fcinfo);
pcid_consistent(patch->schema->pcid, pcid);
serpatch = pc_patch_serialize(patch, NULL);
pc_patch_free(patch);
}
else
{
ereport(
ERROR,
(errmsg("parse error - support for text format not yet implemented")));
}
if ( serpatch ) PG_RETURN_POINTER(serpatch);
else PG_RETURN_NULL();
if (serpatch)
PG_RETURN_POINTER(serpatch);
else
PG_RETURN_NULL();
}
PG_FUNCTION_INFO_V1(pcpatch_out);
Datum pcpatch_out(PG_FUNCTION_ARGS)
{
PCPATCH *patch = NULL;
SERIALIZED_PATCH *serpatch = NULL;
char *hexwkb = NULL;
PCSCHEMA *schema = NULL;
PCPATCH *patch = NULL;
SERIALIZED_PATCH *serpatch = NULL;
char *hexwkb = NULL;
PCSCHEMA *schema = NULL;
serpatch = PG_GETARG_SERPATCH_P(0);
schema = pc_schema_from_pcid(serpatch->pcid, fcinfo);
patch = pc_patch_deserialize(serpatch, schema);
hexwkb = pc_patch_to_hexwkb(patch);
pc_patch_free(patch);
PG_RETURN_CSTRING(hexwkb);
serpatch = PG_GETARG_SERPATCH_P(0);
schema = pc_schema_from_pcid(serpatch->pcid, fcinfo);
patch = pc_patch_deserialize(serpatch, schema);
hexwkb = pc_patch_to_hexwkb(patch);
pc_patch_free(patch);
PG_RETURN_CSTRING(hexwkb);
}
PG_FUNCTION_INFO_V1(pcschema_is_valid);
Datum pcschema_is_valid(PG_FUNCTION_ARGS)
{
bool valid;
text *xml = PG_GETARG_TEXT_P(0);
char *xmlstr = text_to_cstring(xml);
PCSCHEMA *schema = pc_schema_from_xml(xmlstr);
pfree(xmlstr);
bool valid;
text *xml = PG_GETARG_TEXT_P(0);
char *xmlstr = text_to_cstring(xml);
PCSCHEMA *schema = pc_schema_from_xml(xmlstr);
pfree(xmlstr);
if ( !schema )
{
PG_RETURN_BOOL(false);
}
if (!schema)
{
PG_RETURN_BOOL(false);
}
valid = pc_schema_is_valid(schema);
pc_schema_free(schema);
PG_RETURN_BOOL(valid);
valid = pc_schema_is_valid(schema);
pc_schema_free(schema);
PG_RETURN_BOOL(valid);
}
PG_FUNCTION_INFO_V1(pcschema_get_ndims);
Datum pcschema_get_ndims(PG_FUNCTION_ARGS)
{
int ndims;
uint32 pcid = PG_GETARG_INT32(0);
PCSCHEMA *schema = pc_schema_from_pcid(pcid, fcinfo);
int ndims;
uint32 pcid = PG_GETARG_INT32(0);
PCSCHEMA *schema = pc_schema_from_pcid(pcid, fcinfo);
if ( ! schema )
elog(ERROR, "unable to load schema for pcid = %d", pcid);
if (!schema)
elog(ERROR, "unable to load schema for pcid = %d", pcid);
ndims = schema->ndims;
PG_RETURN_INT32(ndims);
ndims = schema->ndims;
PG_RETURN_INT32(ndims);
}
/**
* pcpoint_from_double_array(integer pcid, float8[] returns PcPoint
*/
* pcpoint_from_double_array(integer pcid, float8[] returns PcPoint
*/
PG_FUNCTION_INFO_V1(pcpoint_from_double_array);
Datum pcpoint_from_double_array(PG_FUNCTION_ARGS)
{
uint32 pcid = PG_GETARG_INT32(0);
ArrayType *arrptr = PG_GETARG_ARRAYTYPE_P(1);
int nelems;
float8 *vals;
PCPOINT *pt;
PCSCHEMA *schema = pc_schema_from_pcid(pcid, fcinfo);
SERIALIZED_POINT *serpt;
uint32 pcid = PG_GETARG_INT32(0);
ArrayType *arrptr = PG_GETARG_ARRAYTYPE_P(1);
int nelems;
float8 *vals;
PCPOINT *pt;
PCSCHEMA *schema = pc_schema_from_pcid(pcid, fcinfo);
SERIALIZED_POINT *serpt;
if ( ! schema )
elog(ERROR, "unable to load schema for pcid = %d", pcid);
if (!schema)
elog(ERROR, "unable to load schema for pcid = %d", pcid);
if ( ARR_ELEMTYPE(arrptr) != FLOAT8OID )
elog(ERROR, "array must be of float8[]");
if (ARR_ELEMTYPE(arrptr) != FLOAT8OID)
elog(ERROR, "array must be of float8[]");
if ( ARR_NDIM(arrptr) != 1 )
elog(ERROR, "float8[] must have only one dimension");
if (ARR_NDIM(arrptr) != 1)
elog(ERROR, "float8[] must have only one dimension");
if ( ARR_HASNULL(arrptr) )
elog(ERROR, "float8[] must not have null elements");
if (ARR_HASNULL(arrptr))
elog(ERROR, "float8[] must not have null elements");
nelems = ARR_DIMS(arrptr)[0];
if ( nelems != schema->ndims || ARR_LBOUND(arrptr)[0] > 1 )
elog(ERROR, "array dimensions do not match schema dimensions of pcid = %d", pcid);
nelems = ARR_DIMS(arrptr)[0];
if (nelems != schema->ndims || ARR_LBOUND(arrptr)[0] > 1)
elog(ERROR, "array dimensions do not match schema dimensions of pcid = %d",
pcid);
vals = (float8*) ARR_DATA_PTR(arrptr);
pt = pc_point_from_double_array(schema, vals, 0, nelems);
vals = (float8 *)ARR_DATA_PTR(arrptr);
pt = pc_point_from_double_array(schema, vals, 0, nelems);
serpt = pc_point_serialize(pt);
pc_point_free(pt);
PG_RETURN_POINTER(serpt);
serpt = pc_point_serialize(pt);
pc_point_free(pt);
PG_RETURN_POINTER(serpt);
}
PG_FUNCTION_INFO_V1(pcpoint_as_text);
Datum pcpoint_as_text(PG_FUNCTION_ARGS)
{
SERIALIZED_POINT *serpt = PG_GETARG_SERPOINT_P(0);
text *txt;
char *str;
PCSCHEMA *schema = pc_schema_from_pcid(serpt->pcid, fcinfo);
PCPOINT *pt = pc_point_deserialize(serpt, schema);
if ( ! pt )
PG_RETURN_NULL();
SERIALIZED_POINT *serpt = PG_GETARG_SERPOINT_P(0);
text *txt;
char *str;
PCSCHEMA *schema = pc_schema_from_pcid(serpt->pcid, fcinfo);
PCPOINT *pt = pc_point_deserialize(serpt, schema);
if (!pt)
PG_RETURN_NULL();
str = pc_point_to_string(pt);
pc_point_free(pt);
txt = cstring_to_text(str);
pfree(str);
PG_RETURN_TEXT_P(txt);
str = pc_point_to_string(pt);
pc_point_free(pt);
txt = cstring_to_text(str);
pfree(str);
PG_RETURN_TEXT_P(txt);
}
PG_FUNCTION_INFO_V1(pcpatch_as_text);
Datum pcpatch_as_text(PG_FUNCTION_ARGS)
{
SERIALIZED_PATCH *serpatch = PG_GETARG_SERPATCH_P(0);
text *txt;
char *str;
PCSCHEMA *schema = pc_schema_from_pcid(serpatch->pcid, fcinfo);
PCPATCH *patch = pc_patch_deserialize(serpatch, schema);
if ( ! patch )
PG_RETURN_NULL();
SERIALIZED_PATCH *serpatch = PG_GETARG_SERPATCH_P(0);
text *txt;
char *str;
PCSCHEMA *schema = pc_schema_from_pcid(serpatch->pcid, fcinfo);
PCPATCH *patch = pc_patch_deserialize(serpatch, schema);
if (!patch)
PG_RETURN_NULL();
str = pc_patch_to_string(patch);
pc_patch_free(patch);
txt = cstring_to_text(str);
pfree(str);
PG_RETURN_TEXT_P(txt);
str = pc_patch_to_string(patch);
pc_patch_free(patch);
txt = cstring_to_text(str);
pfree(str);
PG_RETURN_TEXT_P(txt);
}
PG_FUNCTION_INFO_V1(pcpoint_as_bytea);
Datum pcpoint_as_bytea(PG_FUNCTION_ARGS)
{
SERIALIZED_POINT *serpt = PG_GETARG_SERPOINT_P(0);
uint8 *bytes;
size_t bytes_size;
bytea *wkb;
size_t wkb_size;
PCSCHEMA *schema = pc_schema_from_pcid(serpt->pcid, fcinfo);
PCPOINT *pt = pc_point_deserialize(serpt, schema);
SERIALIZED_POINT *serpt = PG_GETARG_SERPOINT_P(0);
uint8 *bytes;
size_t bytes_size;
bytea *wkb;
size_t wkb_size;
PCSCHEMA *schema = pc_schema_from_pcid(serpt->pcid, fcinfo);
PCPOINT *pt = pc_point_deserialize(serpt, schema);
if ( ! pt )
PG_RETURN_NULL();
if (!pt)
PG_RETURN_NULL();
bytes = pc_point_to_geometry_wkb(pt, &bytes_size);
wkb_size = VARHDRSZ + bytes_size;
wkb = palloc(wkb_size);
memcpy(VARDATA(wkb), bytes, bytes_size);
SET_VARSIZE(wkb, wkb_size);
bytes = pc_point_to_geometry_wkb(pt, &bytes_size);
wkb_size = VARHDRSZ + bytes_size;
wkb = palloc(wkb_size);
memcpy(VARDATA(wkb), bytes, bytes_size);
SET_VARSIZE(wkb, wkb_size);
pc_point_free(pt);
pfree(bytes);
pc_point_free(pt);
pfree(bytes);
PG_RETURN_BYTEA_P(wkb);
PG_RETURN_BYTEA_P(wkb);
}
PG_FUNCTION_INFO_V1(pcpatch_envelope_as_bytea);
Datum pcpatch_envelope_as_bytea(PG_FUNCTION_ARGS)
{
uint8 *bytes;
size_t bytes_size;
bytea *wkb;
size_t wkb_size;
SERIALIZED_PATCH *serpatch = PG_GETHEADER_SERPATCH_P(0);
PCSCHEMA *schema = pc_schema_from_pcid(serpatch->pcid, fcinfo);
uint8 *bytes;
size_t bytes_size;
bytea *wkb;
size_t wkb_size;
SERIALIZED_PATCH *serpatch = PG_GETHEADER_SERPATCH_P(0);
PCSCHEMA *schema = pc_schema_from_pcid(serpatch->pcid, fcinfo);
bytes = pc_patch_to_geometry_wkb_envelope(serpatch, schema, &bytes_size);
wkb_size = VARHDRSZ + bytes_size;
wkb = palloc(wkb_size);
memcpy(VARDATA(wkb), bytes, bytes_size);
SET_VARSIZE(wkb, wkb_size);
bytes = pc_patch_to_geometry_wkb_envelope(serpatch, schema, &bytes_size);
wkb_size = VARHDRSZ + bytes_size;
wkb = palloc(wkb_size);
memcpy(VARDATA(wkb), bytes, bytes_size);
SET_VARSIZE(wkb, wkb_size);
pfree(bytes);
pfree(bytes);
PG_RETURN_BYTEA_P(wkb);
PG_RETURN_BYTEA_P(wkb);
}
PG_FUNCTION_INFO_V1(pcpatch_bounding_diagonal_as_bytea);
Datum pcpatch_bounding_diagonal_as_bytea(PG_FUNCTION_ARGS)
{
static const size_t stats_size_guess = 400;
SERIALIZED_PATCH *serpatch;
PCSCHEMA *schema;
PCSTATS *stats;
uint8 *bytes;
size_t bytes_size;
bytea *wkb;
size_t wkb_size;
static const size_t stats_size_guess = 400;
SERIALIZED_PATCH *serpatch;
PCSCHEMA *schema;
PCSTATS *stats;
uint8 *bytes;
size_t bytes_size;
bytea *wkb;
size_t wkb_size;
serpatch = PG_GETHEADERX_SERPATCH_P(0, stats_size_guess);
schema = pc_schema_from_pcid(serpatch->pcid, fcinfo);
serpatch = PG_GETHEADERX_SERPATCH_P(0, stats_size_guess);
schema = pc_schema_from_pcid(serpatch->pcid, fcinfo);
if ( schema->zdim || schema->mdim )
{
if ( stats_size_guess < pc_stats_size(schema) )
serpatch = PG_GETHEADERX_SERPATCH_P(0, pc_stats_size(schema));
if (schema->zdim || schema->mdim)
{
if (stats_size_guess < pc_stats_size(schema))
serpatch = PG_GETHEADERX_SERPATCH_P(0, pc_stats_size(schema));
stats = pc_patch_stats_deserialize(schema, serpatch->data);
if ( !stats )
PG_RETURN_NULL();
stats = pc_patch_stats_deserialize(schema, serpatch->data);
if (!stats)
PG_RETURN_NULL();
bytes = pc_bounding_diagonal_wkb_from_stats(stats, &bytes_size);
bytes = pc_bounding_diagonal_wkb_from_stats(stats, &bytes_size);
pc_stats_free(stats);
}
else
{
bytes = pc_bounding_diagonal_wkb_from_bounds(
&serpatch->bounds, schema, &bytes_size);
}
pc_stats_free(stats);
}
else
{
bytes = pc_bounding_diagonal_wkb_from_bounds(&serpatch->bounds, schema,
&bytes_size);
}
wkb_size = VARHDRSZ + bytes_size;
wkb = palloc(wkb_size);
memcpy(VARDATA(wkb), bytes, bytes_size);
SET_VARSIZE(wkb, wkb_size);
wkb_size = VARHDRSZ + bytes_size;
wkb = palloc(wkb_size);
memcpy(VARDATA(wkb), bytes, bytes_size);
SET_VARSIZE(wkb, wkb_size);
pcfree(bytes);
pcfree(bytes);
PG_RETURN_BYTEA_P(wkb);
PG_RETURN_BYTEA_P(wkb);
}
PG_FUNCTION_INFO_V1(pc_typmod_in);
Datum pc_typmod_in(PG_FUNCTION_ARGS)
{
uint32 typmod = 0;
Datum *elem_values;
int n = 0;
int i = 0;
ArrayType *arr = (ArrayType *) DatumGetPointer(PG_GETARG_DATUM(0));
uint32 typmod = 0;
Datum *elem_values;
int n = 0;
int i = 0;
ArrayType *arr = (ArrayType *)DatumGetPointer(PG_GETARG_DATUM(0));
if (ARR_ELEMTYPE(arr) != CSTRINGOID)
ereport(ERROR,
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
errmsg("typmod array must be type cstring[]")));
if (ARR_ELEMTYPE(arr) != CSTRINGOID)
ereport(ERROR, (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
errmsg("typmod array must be type cstring[]")));
if (ARR_NDIM(arr) != 1)
ereport(ERROR,
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
errmsg("typmod array must be one-dimensional")));
if (ARR_NDIM(arr) != 1)
ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
errmsg("typmod array must be one-dimensional")));
if (ARR_HASNULL(arr))
ereport(ERROR,
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
errmsg("typmod array must not contain nulls")));
if (ARR_HASNULL(arr))
ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
errmsg("typmod array must not contain nulls")));
if (ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr)) > 1)
ereport(ERROR,
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
errmsg("typmod array must have one element")));
if (ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr)) > 1)
ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
errmsg("typmod array must have one element")));
deconstruct_array(arr,
CSTRINGOID, -2, false, 'c', /* hardwire cstring representation details */
&elem_values, NULL, &n);
deconstruct_array(arr, CSTRINGOID, -2, false,
'c', /* hardwire cstring representation details */
&elem_values, NULL, &n);
for (i = 0; i < n; i++)
{
if ( i == 0 ) /* PCID */
{
char *s = DatumGetCString(elem_values[i]);
typmod = pg_atoi(s, sizeof(int32), '\0');
}
}
for (i = 0; i < n; i++)
{
if (i == 0) /* PCID */
{
char *s = DatumGetCString(elem_values[i]);
typmod = pg_atoi(s, sizeof(int32), '\0');
}
}
PG_RETURN_INT32(typmod);
PG_RETURN_INT32(typmod);
}
PG_FUNCTION_INFO_V1(pc_typmod_out);
Datum pc_typmod_out(PG_FUNCTION_ARGS)
{
char *str = (char*)palloc(64);
uint32 typmod = PG_GETARG_INT32(0);
uint32 pcid = pcid_from_typmod(typmod);
char *str = (char *)palloc(64);
uint32 typmod = PG_GETARG_INT32(0);
uint32 pcid = pcid_from_typmod(typmod);
/* No PCID value? Then no typmod at all. Return empty string. */
if ( ! pcid )
{
str[0] = '\0';
PG_RETURN_CSTRING(str);
}
else
{
sprintf(str, "(%u)", pcid);
PG_RETURN_CSTRING(str);
}
/* No PCID value? Then no typmod at all. Return empty string. */
if (!pcid)
{
str[0] = '\0';
PG_RETURN_CSTRING(str);
}
else
{
sprintf(str, "(%u)", pcid);
PG_RETURN_CSTRING(str);
}
}
PG_FUNCTION_INFO_V1(pc_typmod_pcid);
Datum pc_typmod_pcid(PG_FUNCTION_ARGS)
{
uint32 typmod = PG_GETARG_INT32(0);
uint32 pcid = pcid_from_typmod(typmod);
if ( ! pcid )
PG_RETURN_NULL();
else
PG_RETURN_INT32(pcid);
uint32 typmod = PG_GETARG_INT32(0);
uint32 pcid = pcid_from_typmod(typmod);
if (!pcid)
PG_RETURN_NULL();
else
PG_RETURN_INT32(pcid);
}
PG_FUNCTION_INFO_V1(pcpatch_enforce_typmod);
Datum pcpatch_enforce_typmod(PG_FUNCTION_ARGS)
{
SERIALIZED_PATCH *arg = PG_GETARG_SERPATCH_P(0);
uint32 typmod = PG_GETARG_INT32(1);
uint32 pcid = pcid_from_typmod(typmod);
/* We don't need to have different behavior based on explicitness. */
/* bool isExplicit = PG_GETARG_BOOL(2); */
SERIALIZED_PATCH *arg = PG_GETARG_SERPATCH_P(0);
uint32 typmod = PG_GETARG_INT32(1);
uint32 pcid = pcid_from_typmod(typmod);
/* We don't need to have different behavior based on explicitness. */
/* bool isExplicit = PG_GETARG_BOOL(2); */
/* Check if column typmod is consistent with the object */
if ( pcid != arg->pcid )
elog(ERROR, "column pcid (%d) and patch pcid (%d) are not consistent", pcid, arg->pcid);
/* Check if column typmod is consistent with the object */
if (pcid != arg->pcid)
elog(ERROR, "column pcid (%d) and patch pcid (%d) are not consistent", pcid,
arg->pcid);
PG_RETURN_POINTER(arg);
PG_RETURN_POINTER(arg);
}
PG_FUNCTION_INFO_V1(pcpoint_enforce_typmod);
Datum pcpoint_enforce_typmod(PG_FUNCTION_ARGS)
{
SERIALIZED_POINT *arg = PG_GETARG_SERPOINT_P(0);
int32 typmod = PG_GETARG_INT32(1);
uint32 pcid = pcid_from_typmod(typmod);
/* We don't need to have different behavior based on explicitness. */
/* bool isExplicit = PG_GETARG_BOOL(2); */
SERIALIZED_POINT *arg = PG_GETARG_SERPOINT_P(0);
int32 typmod = PG_GETARG_INT32(1);
uint32 pcid = pcid_from_typmod(typmod);
/* We don't need to have different behavior based on explicitness. */
/* bool isExplicit = PG_GETARG_BOOL(2); */
/* Check if column typmod is consistent with the object */
if ( pcid != arg->pcid )
elog(ERROR, "column pcid (%d) and point pcid (%d) are not consistent", pcid, arg->pcid);
/* Check if column typmod is consistent with the object */
if (pcid != arg->pcid)
elog(ERROR, "column pcid (%d) and point pcid (%d) are not consistent", pcid,
arg->pcid);
PG_RETURN_POINTER(arg);
PG_RETURN_POINTER(arg);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,13 @@
/***********************************************************************
* pc_pgsql.h
*
* Common header file for all PgSQL pointcloud functions.
*
* PgSQL Pointcloud is free and open source software provided
* by the Government of Canada
* Copyright (c) 2013 Natural Resources Canada
*
***********************************************************************/
* pc_pgsql.h
*
* Common header file for all PgSQL pointcloud functions.
*
* PgSQL Pointcloud is free and open source software provided
* by the Government of Canada
* Copyright (c) 2013 Natural Resources Canada
*
***********************************************************************/
#include "pc_api.h"
@ -15,119 +15,136 @@
#include "utils/elog.h"
/* Try to move these down */
#include "utils/array.h"
#include "utils/builtins.h" /* for pg_atoi */
#include "lib/stringinfo.h" /* For binary input */
#include "catalog/pg_type.h" /* for CSTRINGOID */
#include "lib/stringinfo.h" /* For binary input */
#include "utils/array.h"
#include "utils/builtins.h" /* for pg_atoi */
#define POINTCLOUD_FORMATS "pointcloud_formats"
#define POINTCLOUD_FORMATS_XML "schema"
#define POINTCLOUD_FORMATS_SRID "srid"
#define PG_GETARG_SERPOINT_P(argnum) (SERIALIZED_POINT*)PG_DETOAST_DATUM(PG_GETARG_DATUM(argnum))
#define PG_GETARG_SERPATCH_P(argnum) (SERIALIZED_PATCH*)PG_DETOAST_DATUM(PG_GETARG_DATUM(argnum))
#define PG_GETARG_SERPOINT_P(argnum) \
(SERIALIZED_POINT *)PG_DETOAST_DATUM(PG_GETARG_DATUM(argnum))
#define PG_GETARG_SERPATCH_P(argnum) \
(SERIALIZED_PATCH *)PG_DETOAST_DATUM(PG_GETARG_DATUM(argnum))
#define PG_GETHEADER_SERPATCH_P(argnum) (SERIALIZED_PATCH*)PG_DETOAST_DATUM_SLICE(PG_GETARG_DATUM(argnum), 0, sizeof(SERIALIZED_PATCH))
#define PG_GETHEADER_SERPATCH_P(argnum) \
(SERIALIZED_PATCH *)PG_DETOAST_DATUM_SLICE(PG_GETARG_DATUM(argnum), 0, \
sizeof(SERIALIZED_PATCH))
#define PG_GETHEADERX_SERPATCH_P(argnum, extra) (SERIALIZED_PATCH*)PG_DETOAST_DATUM_SLICE(PG_GETARG_DATUM(argnum), 0, sizeof(SERIALIZED_PATCH)+extra)
#define PG_GETHEADERX_SERPATCH_P(argnum, extra) \
(SERIALIZED_PATCH *)PG_DETOAST_DATUM_SLICE(PG_GETARG_DATUM(argnum), 0, \
sizeof(SERIALIZED_PATCH) + extra)
#define PG_GETHEADER_STATS_P(argnum, statsize) (uint8_t*)(((SERIALIZED_PATCH*)PG_DETOAST_DATUM_SLICE(PG_GETARG_DATUM(argnum), 0, sizeof(SERIALIZED_PATCH) + statsize))->data)
#define PG_GETHEADER_STATS_P(argnum, statsize) \
(uint8_t *)(((SERIALIZED_PATCH *)PG_DETOAST_DATUM_SLICE( \
PG_GETARG_DATUM(argnum), 0, \
sizeof(SERIALIZED_PATCH) + statsize)) \
->data)
#define AUTOCOMPRESS_NO 0
#define AUTOCOMPRESS_YES 1
/**
* Serialized point type for clouds. Variable length, because there can be
* an arbitrary number of dimensions. The pcid is a foreign key
* reference to the POINTCLOUD_SCHEMAS table, where
* the underlying structure of the data is described in XML,
* the spatial reference system is indicated, and the data
* packing scheme is indicated.
*/
* Serialized point type for clouds. Variable length, because there can be
* an arbitrary number of dimensions. The pcid is a foreign key
* reference to the POINTCLOUD_SCHEMAS table, where
* the underlying structure of the data is described in XML,
* the spatial reference system is indicated, and the data
* packing scheme is indicated.
*/
typedef struct
{
uint32_t size;
uint32_t pcid;
uint8_t data[1];
}
SERIALIZED_POINT;
uint32_t size;
uint32_t pcid;
uint8_t data[1];
} SERIALIZED_POINT;
/**
* PgSQL patch type (collection of points) for clouds.
* Variable length, because there can be
* an arbitrary number of points encoded within.
* The pcid is a foriegn key reference to the
* POINTCLOUD_SCHEMAS table, where
* the underlying structure of the data is described in XML,
* the spatial reference system is indicated, and the data
* packing scheme is indicated.
*/
* PgSQL patch type (collection of points) for clouds.
* Variable length, because there can be
* an arbitrary number of points encoded within.
* The pcid is a foriegn key reference to the
* POINTCLOUD_SCHEMAS table, where
* the underlying structure of the data is described in XML,
* the spatial reference system is indicated, and the data
* packing scheme is indicated.
*/
typedef struct
{
uint32_t size;
uint32_t pcid;
uint32_t compression;
uint32_t npoints;
PCBOUNDS bounds;
uint8_t data[1];
}
SERIALIZED_PATCH;
uint32_t size;
uint32_t pcid;
uint32_t compression;
uint32_t npoints;
PCBOUNDS bounds;
uint8_t data[1];
} SERIALIZED_PATCH;
/* PGSQL / POINTCLOUD UTILITY FUNCTIONS */
uint32 pcid_from_typmod(const int32 typmod);
/** Look-up the PCID in the POINTCLOUD_FORMATS table, and construct a PC_SCHEMA from the XML therein */
/** Look-up the PCID in the POINTCLOUD_FORMATS table, and construct a PC_SCHEMA
* from the XML therein */
#if PGSQL_VERSION < 120
PCSCHEMA* pc_schema_from_pcid(uint32_t pcid, FunctionCallInfoData *fcinfo);
PCSCHEMA *pc_schema_from_pcid(uint32_t pcid, FunctionCallInfoData *fcinfo);
#else
PCSCHEMA* pc_schema_from_pcid(uint32_t pcid, FunctionCallInfo fcinfo);
PCSCHEMA *pc_schema_from_pcid(uint32_t pcid, FunctionCallInfo fcinfo);
#endif
/** Look-up the PCID in the POINTCLOUD_FORMATS table, and construct a PC_SCHEMA from the XML therein */
PCSCHEMA* pc_schema_from_pcid_uncached(uint32 pcid);
/** Look-up the PCID in the POINTCLOUD_FORMATS table, and construct a PC_SCHEMA
* from the XML therein */
PCSCHEMA *pc_schema_from_pcid_uncached(uint32 pcid);
/** Turn a PCPOINT into a byte buffer suitable for saving in PgSQL */
SERIALIZED_POINT* pc_point_serialize(const PCPOINT *pcpt);
SERIALIZED_POINT *pc_point_serialize(const PCPOINT *pcpt);
/** Turn a byte buffer into a PCPOINT for processing */
PCPOINT* pc_point_deserialize(const SERIALIZED_POINT *serpt, const PCSCHEMA *schema);
PCPOINT *pc_point_deserialize(const SERIALIZED_POINT *serpt,
const PCSCHEMA *schema);
/** Create a new readwrite PCPOINT from a hex string */
#if PGSQL_VERSION < 120
PCPOINT* pc_point_from_hexwkb(const char *hexwkb, size_t hexlen, FunctionCallInfoData *fcinfo);
PCPOINT *pc_point_from_hexwkb(const char *hexwkb, size_t hexlen,
FunctionCallInfoData *fcinfo);
#else
PCPOINT* pc_point_from_hexwkb(const char *hexwkb, size_t hexlen, FunctionCallInfo fcinfo);
PCPOINT *pc_point_from_hexwkb(const char *hexwkb, size_t hexlen,
FunctionCallInfo fcinfo);
#endif
/** Create a hex representation of a PCPOINT */
char* pc_point_to_hexwkb(const PCPOINT *pt);
char *pc_point_to_hexwkb(const PCPOINT *pt);
/** How big will this thing be on disk? */
size_t pc_patch_serialized_size(const PCPATCH *patch);
/** Turn a PCPATCH into a byte buffer suitable for saving in PgSQL */
SERIALIZED_PATCH* pc_patch_serialize(const PCPATCH *patch, void *userdata);
SERIALIZED_PATCH *pc_patch_serialize(const PCPATCH *patch, void *userdata);
/** Turn a PCPATCH into an uncompressed byte buffer */
SERIALIZED_PATCH* pc_patch_serialize_to_uncompressed(const PCPATCH *patch);
SERIALIZED_PATCH *pc_patch_serialize_to_uncompressed(const PCPATCH *patch);
/** Turn a byte buffer into a PCPATCH for processing */
PCPATCH* pc_patch_deserialize(const SERIALIZED_PATCH *serpatch, const PCSCHEMA *schema);
PCPATCH *pc_patch_deserialize(const SERIALIZED_PATCH *serpatch,
const PCSCHEMA *schema);
/** Create a new readwrite PCPATCH from a hex string */
#if PGSQL_VERSION < 120
PCPATCH* pc_patch_from_hexwkb(const char *hexwkb, size_t hexlen, FunctionCallInfoData *fcinfo);
PCPATCH *pc_patch_from_hexwkb(const char *hexwkb, size_t hexlen,
FunctionCallInfoData *fcinfo);
#else
PCPATCH* pc_patch_from_hexwkb(const char *hexwkb, size_t hexlen, FunctionCallInfo fcinfo);
PCPATCH *pc_patch_from_hexwkb(const char *hexwkb, size_t hexlen,
FunctionCallInfo fcinfo);
#endif
/** Create a hex representation of a PCPOINT */
char* pc_patch_to_hexwkb(const PCPATCH *patch);
char *pc_patch_to_hexwkb(const PCPATCH *patch);
/** Returns OGC WKB for envelope of PCPATCH */
uint8_t* pc_patch_to_geometry_wkb_envelope(const SERIALIZED_PATCH *pa, const PCSCHEMA *schema, size_t *wkbsize);
uint8_t *pc_patch_to_geometry_wkb_envelope(const SERIALIZED_PATCH *pa,
const PCSCHEMA *schema,
size_t *wkbsize);
/** Read the first few bytes off an object to get the datum */
uint32 pcid_from_datum(Datum d);
PCSTATS* pc_patch_stats_deserialize(const PCSCHEMA *schema, const uint8_t *buf);
PCSTATS *pc_patch_stats_deserialize(const PCSCHEMA *schema, const uint8_t *buf);

View File

@ -1,3 +1,3 @@
#! /bin/bash
clang-format -i -style=file lib/*.c lib/*.h lib/cunit/*.c lib/*.cpp lib/*.hpp lib/cunit/*.h
clang-format -i -style=file pgsql/*.c pgsql/*.h lib/*.c lib/*.h lib/cunit/*.c lib/*.cpp lib/*.hpp lib/cunit/*.h