Skip to content

Commit

Permalink
Add support for binary i/o (#160)
Browse files Browse the repository at this point in the history
* Add support for binary i/o

Co-authored-by: Zacharias Knudsen <z@chari.as>
  • Loading branch information
robertozimek and zachasme authored Nov 5, 2024
1 parent 0706e05 commit 6d1e2b0
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 3 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/test-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
strategy:
matrix:
config: [Release, Debug]
pg: [15, 14, 13, 12, 11]
pg: [16, 15, 14, 13]

runs-on: ubuntu-22.04

Expand All @@ -24,7 +24,7 @@ jobs:
uses: actions/cache@v3
with:
path: ~/.cargo
key: ${{ runner.os }}-cargo-2023
key: ${{ runner.os }}-cargo-2024

- name: Install pg_validate_extupgrade
run: cargo install --locked --git https://github.com/rjuju/pg_validate_extupgrade.git
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ avoid adding features or APIs which do not map onto the
Click to see more.
</summary>

- Add support for binary I/O (see [#160], thanks [@robertozimek])

</details>

## [4.1.3] - 2023-07-26
Expand Down Expand Up @@ -258,6 +260,7 @@ avoid adding features or APIs which do not map onto the
[#112]: https://github.com/zachasme/h3-pg/pull/112
[#117]: https://github.com/zachasme/h3-pg/issues/117
[#131]: https://github.com/zachasme/h3-pg/pull/131
[#160]: https://github.com/zachasme/h3-pg/pull/160
[@abelvm]: https://github.com/AbelVM
[@kalenikaliaksandr]: https://github.com/kalenikaliaksandr
[@kmacdough]: https://github.com/kmacdough
Expand All @@ -266,3 +269,4 @@ avoid adding features or APIs which do not map onto the
[@mngr777]: https://github.com/mngr777
[@trylinka]: https://github.com/trylinka
[@rustprooflabs]: https://github.com/rustprooflabs
[@robertozimek]: https://github.com/robertozimek
12 changes: 12 additions & 0 deletions h3/sql/install/00-type.sql
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,20 @@ CREATE OR REPLACE FUNCTION
h3index_out(h3index) RETURNS cstring
AS 'h3' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;

--@ internal
CREATE OR REPLACE FUNCTION
h3index_recv(internal) RETURNS h3index
AS 'h3' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;

--@ internal
CREATE OR REPLACE FUNCTION
h3index_send(h3index) RETURNS bytea
AS 'h3' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;

CREATE TYPE h3index (
INPUT = h3index_in,
OUTPUT = h3index_out,
RECEIVE = h3index_recv,
SEND = h3index_send,
LIKE = int8
);
15 changes: 15 additions & 0 deletions h3/sql/updates/h3--4.1.3--unreleased.sql
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,18 @@

-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "ALTER EXTENSION h3 UPDATE TO 'unreleased'" to load this file. \quit

--@ internal
CREATE OR REPLACE FUNCTION
h3index_recv(internal) RETURNS h3index
AS 'h3' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;

--@ internal
CREATE OR REPLACE FUNCTION
h3index_send(h3index) RETURNS bytea
AS 'h3' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;

ALTER TYPE h3index SET (
RECEIVE = h3index_recv,
SEND = h3index_send
);
1 change: 1 addition & 0 deletions h3/src/binding/indexing.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include <fmgr.h> // PG_FUNCTION_INFO_V1
#include <utils/geo_decls.h> // PG_GETARG_POINT_P
#include <math.h> // fabs

#include "constants.h"
#include "error.h"
Expand Down
23 changes: 23 additions & 0 deletions h3/src/type.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,16 @@
#include <h3api.h>

#include <fmgr.h> // PG_FUNCTION_ARGS
#include <libpq/pqformat.h> // needed for send/recv functions

#include "error.h"
#include "type.h"

/* conversion */
PGDLLEXPORT PG_FUNCTION_INFO_V1(h3index_in);
PGDLLEXPORT PG_FUNCTION_INFO_V1(h3index_out);
PGDLLEXPORT PG_FUNCTION_INFO_V1(h3index_send);
PGDLLEXPORT PG_FUNCTION_INFO_V1(h3index_recv);
PGDLLEXPORT PG_FUNCTION_INFO_V1(h3index_to_bigint);
PGDLLEXPORT PG_FUNCTION_INFO_V1(bigint_to_h3index);

Expand All @@ -51,6 +54,26 @@ h3index_out(PG_FUNCTION_ARGS)
PG_RETURN_CSTRING(string);
}

Datum
h3index_recv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);

PG_RETURN_H3INDEX(pq_getmsgint64(buf));
}

Datum
h3index_send(PG_FUNCTION_ARGS)
{
H3Index h3 = PG_GETARG_H3INDEX(0);
StringInfoData buf;

pq_begintypsend(&buf);
pq_sendint64(&buf, h3);

PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}

/* bigint conversion functions */
Datum
h3index_to_bigint(PG_FUNCTION_ARGS)
Expand Down
2 changes: 1 addition & 1 deletion h3/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ endif()

if(PostgreSQL_VALIDATE_EXTUPGRADE)
add_test(
NAME h3_validate_extrupgrade
NAME h3_validate_extupgrade
COMMAND pg_validate_extupgrade
--extname h3
--from 0.1.0
Expand Down
16 changes: 16 additions & 0 deletions h3/test/expected/type.out
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,19 @@ SELECT :asbigint = :hexagon::bigint;
SELECT :hexagon = :asbigint::h3index;
t

--
-- TEST binary io
--
CREATE TEMPORARY TABLE h3_test_binary_send (hex h3index PRIMARY KEY);
CREATE TEMPORARY TABLE h3_test_binary_recv (hex h3index PRIMARY KEY);
INSERT INTO h3_test_binary_send (hex) SELECT * from h3_get_res_0_cells();
-- we need to use \copy instead of SQL COPY in order to have relative path
\copy h3_test_binary_send TO 'h3_test_binary.bin' (FORMAT binary)
\copy h3_test_binary_recv FROM 'h3_test_binary.bin' (FORMAT binary)
-- make sure re-imported data matches original data
SELECT array_agg(hex) is null FROM (
SELECT hex FROM h3_test_binary_send
EXCEPT SELECT hex FROM h3_test_binary_recv
) q;
t

17 changes: 17 additions & 0 deletions h3/test/sql/type.sql
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,20 @@ SELECT bool_and(:pentagon @> c) FROM (
SELECT :asbigint = :hexagon::bigint;

SELECT :hexagon = :asbigint::h3index;

--
-- TEST binary io
--
CREATE TEMPORARY TABLE h3_test_binary_send (hex h3index PRIMARY KEY);
CREATE TEMPORARY TABLE h3_test_binary_recv (hex h3index PRIMARY KEY);
INSERT INTO h3_test_binary_send (hex) SELECT * from h3_get_res_0_cells();

-- we need to use \copy instead of SQL COPY in order to have relative path
\copy h3_test_binary_send TO 'h3_test_binary.bin' (FORMAT binary)
\copy h3_test_binary_recv FROM 'h3_test_binary.bin' (FORMAT binary)

-- make sure re-imported data matches original data
SELECT array_agg(hex) is null FROM (
SELECT hex FROM h3_test_binary_send
EXCEPT SELECT hex FROM h3_test_binary_recv
) q;

0 comments on commit 6d1e2b0

Please sign in to comment.