From 4c0ceb35f29c211a618570e14628baaf85f4ad67 Mon Sep 17 00:00:00 2001 From: Cyrille Berger Date: Tue, 26 May 2015 10:50:53 +0200 Subject: [PATCH 1/7] add support for binary protocol for pcpatch --- pgsql/pc_inout.c | 64 +++++++++++++++++++++++++++++++++++++++++ pgsql/pointcloud.sql.in | 12 ++++++-- 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/pgsql/pc_inout.c b/pgsql/pc_inout.c index eeb5ae05..f92dd852 100644 --- a/pgsql/pc_inout.c +++ b/pgsql/pc_inout.c @@ -16,6 +16,8 @@ Datum pcpoint_in(PG_FUNCTION_ARGS); Datum pcpoint_out(PG_FUNCTION_ARGS); Datum pcpatch_in(PG_FUNCTION_ARGS); Datum pcpatch_out(PG_FUNCTION_ARGS); +Datum pcpatch_send(PG_FUNCTION_ARGS); +Datum pcpatch_recv(PG_FUNCTION_ARGS); /* Typmod support */ Datum pc_typmod_in(PG_FUNCTION_ARGS); @@ -159,6 +161,68 @@ Datum pcpatch_out(PG_FUNCTION_ARGS) PG_RETURN_CSTRING(hexwkb); } +PG_FUNCTION_INFO_V1(pcpatch_recv); +Datum pcpatch_recv(PG_FUNCTION_ARGS) +{ + StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); + size_t wkblen; + uint32 pcid = 0; + PCPATCH *patch; + SERIALIZED_PATCH *serpatch = NULL; + + PCSCHEMA *schema; + + wkblen = buf->len - buf->cursor; + uint8 *wkb = &buf->data[buf->cursor]; + + buf->cursor += buf->len; + + pcid = wkb_get_pcid(wkb); + if ( ! pcid ) + elog(ERROR, "%s: pcid is zero", __func__); + + schema = pc_schema_from_pcid(pcid, fcinfo); + if ( ! schema ) + elog(ERROR, "%s: unable to look up schema entry", __func__); + + patch = pc_patch_from_wkb(schema, wkb, wkblen); + + pcid_consistent(patch->schema->pcid, pcid); + serpatch = pc_patch_serialize(patch, NULL); + pc_patch_free(patch); + + if ( serpatch ) PG_RETURN_POINTER(serpatch); + else PG_RETURN_NULL(); +} + +PG_FUNCTION_INFO_V1(pcpatch_send); +Datum pcpatch_send(PG_FUNCTION_ARGS) +{ + PCPATCH *patch = NULL; + SERIALIZED_PATCH *serpatch = NULL; + PCSCHEMA *schema = NULL; + size_t wkb_size; + uint8 *wkb; + + bytea *result = NULL; + int result_size = 0; + + serpatch = PG_GETARG_SERPATCH_P(0); + schema = pc_schema_from_pcid(serpatch->pcid, fcinfo); + patch = pc_patch_deserialize(serpatch, schema); + wkb = pc_patch_to_wkb(patch, &wkb_size); + pc_patch_free(patch); + + result_size = wkb_size + VARHDRSZ; + result = (bytea *)palloc(result_size); + SET_VARSIZE(result, result_size); + memcpy(VARDATA(result), wkb, VARSIZE(result) - VARHDRSZ); + + pfree(wkb); + + PG_RETURN_BYTEA_P(result); +} + PG_FUNCTION_INFO_V1(pcschema_is_valid); Datum pcschema_is_valid(PG_FUNCTION_ARGS) { diff --git a/pgsql/pointcloud.sql.in b/pgsql/pointcloud.sql.in index 582630c5..d9769503 100644 --- a/pgsql/pointcloud.sql.in +++ b/pgsql/pointcloud.sql.in @@ -152,12 +152,20 @@ CREATE OR REPLACE FUNCTION pcpatch_out(pcpatch) RETURNS cstring AS 'MODULE_PATHNAME', 'pcpatch_out' LANGUAGE 'c' IMMUTABLE STRICT; +CREATE OR REPLACE FUNCTION pcpatch_send(pcpatch) + RETURNS bytea AS 'MODULE_PATHNAME', 'pcpatch_send' + LANGUAGE 'c' IMMUTABLE STRICT; + +CREATE OR REPLACE FUNCTION pcpatch_recv(internal) + RETURNS pcpatch AS 'MODULE_PATHNAME', 'pcpatch_recv' + LANGUAGE 'c' IMMUTABLE STRICT; + CREATE TYPE pcpatch ( internallength = variable, input = pcpatch_in, output = pcpatch_out, - -- send = geometry_send, - -- receive = geometry_recv, + send = pcpatch_send, + receive = pcpatch_recv, typmod_in = pc_typmod_in, typmod_out = pc_typmod_out, -- delimiter = ':', From 18e1e42f2d606996466abe2f43367a3968443eea Mon Sep 17 00:00:00 2001 From: Cyrille Berger Date: Thu, 14 Nov 2019 14:30:53 +0100 Subject: [PATCH 2/7] add unit test --- pgsql/expected/pointcloud.out | 13 +++++++++++++ pgsql/pc_inout.c | 12 ++++++------ pgsql/sql/pointcloud.sql | 12 ++++++++++-- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/pgsql/expected/pointcloud.out b/pgsql/expected/pointcloud.out index 6338fb0a..32f837c0 100644 --- a/pgsql/expected/pointcloud.out +++ b/pgsql/expected/pointcloud.out @@ -477,10 +477,23 @@ SELECT PC_Summary(pa) summary FROM pa_test_dim order by 1 limit 1; {"pcid":3, "npts":1, "srid":0, "compr":"dimensional","dims":[{"pos":0,"name":"X","size":4,"type":"int32_t","compr":"zlib","stats":{"min":-111,"max":-111,"avg":-111}},{"pos":1,"name":"Y","size":4,"type":"int32_t","compr":"zlib","stats":{"min":61,"max":61,"avg":61}},{"pos":2,"name":"Z","size":4,"type":"int32_t","compr":"zlib","stats":{"min":1600,"max":1600,"avg":1600}},{"pos":3,"name":"Intensity","size":2,"type":"uint16_t","compr":"zlib","stats":{"min":160,"max":160,"avg":160}}]} (1 row) +-- test binary +COPY pa_test TO '/tmp/file' WITH BINARY; +CREATE TABLE IF NOT EXISTS pa_test_in ( + pa PCPATCH(1) +); +COPY pa_test_in FROM '/tmp/file' WITH BINARY; +SELECT 'patch', count(*) FROM pa_test i, pa_test_in o WHERE PC_AsText(i.pa) = PC_AsText(o.pa); + ?column? | count +----------+------- + patch | 10 +(1 row) + --DROP TABLE pts_collection; DROP TABLE pt_test; DROP TABLE pa_test; DROP TABLE pa_test_dim; +DROP TABLE pa_test_in; -- See https://github.com/pgpointcloud/pointcloud/issues/44 SELECT PC_AsText(PC_Patch(ARRAY[PC_MakePoint(3, ARRAY[-127, 45, 124.0, 4.0])]::pcpoint[])); pc_astext diff --git a/pgsql/pc_inout.c b/pgsql/pc_inout.c index 87e29d39..4d686dc7 100644 --- a/pgsql/pc_inout.c +++ b/pgsql/pc_inout.c @@ -175,10 +175,10 @@ Datum pcpatch_recv(PG_FUNCTION_ARGS) wkblen = buf->len - buf->cursor; uint8 *wkb = &buf->data[buf->cursor]; - + buf->cursor += buf->len; - pcid = wkb_get_pcid(wkb); + pcid = pc_wkb_get_pcid(wkb); if ( ! pcid ) elog(ERROR, "%s: pcid is zero", __func__); @@ -187,7 +187,7 @@ Datum pcpatch_recv(PG_FUNCTION_ARGS) elog(ERROR, "%s: unable to look up schema entry", __func__); patch = pc_patch_from_wkb(schema, wkb, wkblen); - + pcid_consistent(patch->schema->pcid, pcid); serpatch = pc_patch_serialize(patch, NULL); pc_patch_free(patch); @@ -204,7 +204,7 @@ Datum pcpatch_send(PG_FUNCTION_ARGS) PCSCHEMA *schema = NULL; size_t wkb_size; uint8 *wkb; - + bytea *result = NULL; int result_size = 0; @@ -213,14 +213,14 @@ Datum pcpatch_send(PG_FUNCTION_ARGS) patch = pc_patch_deserialize(serpatch, schema); wkb = pc_patch_to_wkb(patch, &wkb_size); pc_patch_free(patch); - + result_size = wkb_size + VARHDRSZ; result = (bytea *)palloc(result_size); SET_VARSIZE(result, result_size); memcpy(VARDATA(result), wkb, VARSIZE(result) - VARHDRSZ); pfree(wkb); - + PG_RETURN_BYTEA_P(result); } diff --git a/pgsql/sql/pointcloud.sql b/pgsql/sql/pointcloud.sql index 696f6530..6f73d2cf 100644 --- a/pgsql/sql/pointcloud.sql +++ b/pgsql/sql/pointcloud.sql @@ -297,8 +297,8 @@ DELETE FROM pa_test_dim; INSERT INTO pa_test_dim (pa) SELECT PC_Patch(PC_MakePoint(3, ARRAY[x,y,z,intensity])) FROM ( - SELECT - -127+a/100.0 AS x, + SELECT + -127+a/100.0 AS x, 45+a/100.0 AS y, 1.0*a AS z, a/10 AS intensity, @@ -321,11 +321,19 @@ SELECT PC_Get(PC_PatchAvg(pa)) FROM pa_test_dim order by 1 limit 1; SELECT PC_Summary(pa) summary FROM pa_test_dim order by 1 limit 1; +-- test binary +COPY pa_test TO '/tmp/file' WITH BINARY; +CREATE TABLE IF NOT EXISTS pa_test_in ( + pa PCPATCH(1) +); +COPY pa_test_in FROM '/tmp/file' WITH BINARY; +SELECT 'patch', count(*) FROM pa_test i, pa_test_in o WHERE PC_AsText(i.pa) = PC_AsText(o.pa); --DROP TABLE pts_collection; DROP TABLE pt_test; DROP TABLE pa_test; DROP TABLE pa_test_dim; +DROP TABLE pa_test_in; -- See https://github.com/pgpointcloud/pointcloud/issues/44 SELECT PC_AsText(PC_Patch(ARRAY[PC_MakePoint(3, ARRAY[-127, 45, 124.0, 4.0])]::pcpoint[])); From 50c922d70ac3731ac74a9ed47f4f140ceb5267f0 Mon Sep 17 00:00:00 2001 From: Cyrille Berger Date: Thu, 14 Nov 2019 14:41:52 +0100 Subject: [PATCH 3/7] update older install of pointcloud to support binary --- pgsql/pointcloud.sql.in | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pgsql/pointcloud.sql.in b/pgsql/pointcloud.sql.in index a427f349..b9a7be85 100644 --- a/pgsql/pointcloud.sql.in +++ b/pgsql/pointcloud.sql.in @@ -236,10 +236,12 @@ CREATE OR REPLACE FUNCTION pcpatch_out(pcpatch) RETURNS cstring AS 'MODULE_PATHNAME', 'pcpatch_out' LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL; +-- Availability: 1.2.0next CREATE OR REPLACE FUNCTION pcpatch_send(pcpatch) RETURNS bytea AS 'MODULE_PATHNAME', 'pcpatch_send' LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL; +-- Availability: 1.2.0next CREATE OR REPLACE FUNCTION pcpatch_recv(internal) RETURNS pcpatch AS 'MODULE_PATHNAME', 'pcpatch_recv' LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL; @@ -258,6 +260,12 @@ CREATE TYPE pcpatch ( storage = external ); +-- Availability: 1.2.0next +UPDATE pg_type SET typsend = 'pcpatch_send' WHERE typname='pcpatch'; + +-- Availability: 1.2.0next +UPDATE pg_type SET typrecv = 'pcpatch_recv' WHERE typname='pcpatch'; + CREATE OR REPLACE FUNCTION PC_AsText(p pcpatch) RETURNS text AS 'MODULE_PATHNAME', 'pcpatch_as_text' LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL; From 2620e9070e34a707c835d4466f7c92e0d416262a Mon Sep 17 00:00:00 2001 From: Cyrille Berger Date: Thu, 14 Nov 2019 14:48:35 +0100 Subject: [PATCH 4/7] use a better file name --- pgsql/expected/pointcloud.out | 4 ++-- pgsql/sql/pointcloud.sql | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pgsql/expected/pointcloud.out b/pgsql/expected/pointcloud.out index 32f837c0..a3754675 100644 --- a/pgsql/expected/pointcloud.out +++ b/pgsql/expected/pointcloud.out @@ -478,11 +478,11 @@ SELECT PC_Summary(pa) summary FROM pa_test_dim order by 1 limit 1; (1 row) -- test binary -COPY pa_test TO '/tmp/file' WITH BINARY; +COPY pa_test TO '/tmp/__pgpointcloud_pa_test_file__' WITH BINARY; CREATE TABLE IF NOT EXISTS pa_test_in ( pa PCPATCH(1) ); -COPY pa_test_in FROM '/tmp/file' WITH BINARY; +COPY pa_test_in FROM '/tmp/__pgpointcloud_pa_test_file__' WITH BINARY; SELECT 'patch', count(*) FROM pa_test i, pa_test_in o WHERE PC_AsText(i.pa) = PC_AsText(o.pa); ?column? | count ----------+------- diff --git a/pgsql/sql/pointcloud.sql b/pgsql/sql/pointcloud.sql index 6f73d2cf..64e73745 100644 --- a/pgsql/sql/pointcloud.sql +++ b/pgsql/sql/pointcloud.sql @@ -322,11 +322,11 @@ SELECT PC_Get(PC_PatchAvg(pa)) FROM pa_test_dim order by 1 limit 1; SELECT PC_Summary(pa) summary FROM pa_test_dim order by 1 limit 1; -- test binary -COPY pa_test TO '/tmp/file' WITH BINARY; +COPY pa_test TO '/tmp/__pgpointcloud_pa_test_file__' WITH BINARY; CREATE TABLE IF NOT EXISTS pa_test_in ( pa PCPATCH(1) ); -COPY pa_test_in FROM '/tmp/file' WITH BINARY; +COPY pa_test_in FROM '/tmp/__pgpointcloud_pa_test_file__' WITH BINARY; SELECT 'patch', count(*) FROM pa_test i, pa_test_in o WHERE PC_AsText(i.pa) = PC_AsText(o.pa); --DROP TABLE pts_collection; From 01e6e1783559b220f3c66b5fae2917f1ff97301d Mon Sep 17 00:00:00 2001 From: Cyrille Berger Date: Thu, 14 Nov 2019 14:57:08 +0100 Subject: [PATCH 5/7] one update statement --- pgsql/pointcloud.sql.in | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pgsql/pointcloud.sql.in b/pgsql/pointcloud.sql.in index b9a7be85..c1ebe3b5 100644 --- a/pgsql/pointcloud.sql.in +++ b/pgsql/pointcloud.sql.in @@ -261,10 +261,7 @@ CREATE TYPE pcpatch ( ); -- Availability: 1.2.0next -UPDATE pg_type SET typsend = 'pcpatch_send' WHERE typname='pcpatch'; - --- Availability: 1.2.0next -UPDATE pg_type SET typrecv = 'pcpatch_recv' WHERE typname='pcpatch'; +UPDATE pg_type SET typsend = 'pcpatch_send', typreceive = 'pcpatch_recv' WHERE typname='pcpatch' AND (typsend::text != 'pcpatch_send' OR typreceive::text != 'pcpatch_recv'); CREATE OR REPLACE FUNCTION PC_AsText(p pcpatch) RETURNS text AS 'MODULE_PATHNAME', 'pcpatch_as_text' From b70f544f12dd5dfd8b60730cd369f4e72f08cb55 Mon Sep 17 00:00:00 2001 From: Cyrille Berger Date: Thu, 14 Nov 2019 15:08:44 +0100 Subject: [PATCH 6/7] add back the spaces... --- pgsql/sql/pointcloud.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pgsql/sql/pointcloud.sql b/pgsql/sql/pointcloud.sql index 64e73745..715a57d9 100644 --- a/pgsql/sql/pointcloud.sql +++ b/pgsql/sql/pointcloud.sql @@ -297,8 +297,8 @@ DELETE FROM pa_test_dim; INSERT INTO pa_test_dim (pa) SELECT PC_Patch(PC_MakePoint(3, ARRAY[x,y,z,intensity])) FROM ( - SELECT - -127+a/100.0 AS x, + SELECT + -127+a/100.0 AS x, 45+a/100.0 AS y, 1.0*a AS z, a/10 AS intensity, From fc6d7a55877ddb65d12975151f64a30a39ac17fa Mon Sep 17 00:00:00 2001 From: Cyrille Berger Date: Tue, 13 Aug 2024 10:48:29 +0200 Subject: [PATCH 7/7] fix formatting --- pgsql/pc_inout.c | 80 +++++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/pgsql/pc_inout.c b/pgsql/pc_inout.c index da4a7380..428a37ce 100644 --- a/pgsql/pc_inout.c +++ b/pgsql/pc_inout.c @@ -171,63 +171,65 @@ Datum pcpatch_out(PG_FUNCTION_ARGS) PG_FUNCTION_INFO_V1(pcpatch_recv); Datum pcpatch_recv(PG_FUNCTION_ARGS) { - StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); - size_t wkblen; - uint32 pcid = 0; - PCPATCH *patch; - SERIALIZED_PATCH *serpatch = NULL; + StringInfo buf = (StringInfo)PG_GETARG_POINTER(0); + size_t wkblen; + uint32 pcid = 0; + PCPATCH *patch; + SERIALIZED_PATCH *serpatch = NULL; - PCSCHEMA *schema; + PCSCHEMA *schema; - wkblen = buf->len - buf->cursor; - uint8 *wkb = &buf->data[buf->cursor]; + wkblen = buf->len - buf->cursor; + uint8 *wkb = &buf->data[buf->cursor]; - buf->cursor += buf->len; + buf->cursor += buf->len; - pcid = pc_wkb_get_pcid(wkb); - if ( ! pcid ) - elog(ERROR, "%s: pcid is zero", __func__); + pcid = pc_wkb_get_pcid(wkb); + if (!pcid) + elog(ERROR, "%s: pcid is zero", __func__); - schema = pc_schema_from_pcid(pcid, fcinfo); - if ( ! schema ) - elog(ERROR, "%s: unable to look up schema entry", __func__); + schema = pc_schema_from_pcid(pcid, fcinfo); + if (!schema) + elog(ERROR, "%s: unable to look up schema entry", __func__); - patch = pc_patch_from_wkb(schema, wkb, wkblen); + patch = pc_patch_from_wkb(schema, wkb, wkblen); - pcid_consistent(patch->schema->pcid, pcid); - serpatch = pc_patch_serialize(patch, NULL); - pc_patch_free(patch); + pcid_consistent(patch->schema->pcid, pcid); + serpatch = pc_patch_serialize(patch, NULL); + pc_patch_free(patch); - 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_send); Datum pcpatch_send(PG_FUNCTION_ARGS) { - PCPATCH *patch = NULL; - SERIALIZED_PATCH *serpatch = NULL; - PCSCHEMA *schema = NULL; - size_t wkb_size; - uint8 *wkb; + PCPATCH *patch = NULL; + SERIALIZED_PATCH *serpatch = NULL; + PCSCHEMA *schema = NULL; + size_t wkb_size; + uint8 *wkb; - bytea *result = NULL; - int result_size = 0; + bytea *result = NULL; + int result_size = 0; - serpatch = PG_GETARG_SERPATCH_P(0); - schema = pc_schema_from_pcid(serpatch->pcid, fcinfo); - patch = pc_patch_deserialize(serpatch, schema); - wkb = pc_patch_to_wkb(patch, &wkb_size); - pc_patch_free(patch); + serpatch = PG_GETARG_SERPATCH_P(0); + schema = pc_schema_from_pcid(serpatch->pcid, fcinfo); + patch = pc_patch_deserialize(serpatch, schema); + wkb = pc_patch_to_wkb(patch, &wkb_size); + pc_patch_free(patch); - result_size = wkb_size + VARHDRSZ; - result = (bytea *)palloc(result_size); - SET_VARSIZE(result, result_size); - memcpy(VARDATA(result), wkb, VARSIZE(result) - VARHDRSZ); + result_size = wkb_size + VARHDRSZ; + result = (bytea *)palloc(result_size); + SET_VARSIZE(result, result_size); + memcpy(VARDATA(result), wkb, VARSIZE(result) - VARHDRSZ); - pfree(wkb); + pfree(wkb); - PG_RETURN_BYTEA_P(result); + PG_RETURN_BYTEA_P(result); } PG_FUNCTION_INFO_V1(pcschema_is_valid);