Add binary I/O capability for cube datatype.

We can adjust the not-yet-released cube--1.4--1.5.sql upgrade
rather than making a whole new version.

KaiGai Kohei

Discussion: https://postgr.es/m/CAOP8fzZO4y60QPTK=RGDXeVeVHV9tLHKOsh7voUOoUouVCPV8A@mail.gmail.com
This commit is contained in:
Tom Lane 2021-03-06 12:04:00 -05:00
parent e045565dae
commit 1265a9c8f8
2 changed files with 69 additions and 0 deletions

View File

@ -6,3 +6,16 @@
-- Remove @ and ~
DROP OPERATOR @ (cube, cube);
DROP OPERATOR ~ (cube, cube);
-- Add binary input/output handlers
CREATE FUNCTION cube_recv(internal)
RETURNS cube
AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
CREATE FUNCTION cube_send(cube)
RETURNS bytea
AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
ALTER TYPE cube SET ( RECEIVE = cube_recv, SEND = cube_send );

View File

@ -13,6 +13,7 @@
#include "access/gist.h"
#include "access/stratnum.h"
#include "cubedata.h"
#include "libpq/pqformat.h"
#include "utils/array.h"
#include "utils/float.h"
@ -31,6 +32,8 @@ PG_FUNCTION_INFO_V1(cube_in);
PG_FUNCTION_INFO_V1(cube_a_f8_f8);
PG_FUNCTION_INFO_V1(cube_a_f8);
PG_FUNCTION_INFO_V1(cube_out);
PG_FUNCTION_INFO_V1(cube_send);
PG_FUNCTION_INFO_V1(cube_recv);
PG_FUNCTION_INFO_V1(cube_f8);
PG_FUNCTION_INFO_V1(cube_f8_f8);
PG_FUNCTION_INFO_V1(cube_c_f8);
@ -319,6 +322,59 @@ cube_out(PG_FUNCTION_ARGS)
PG_RETURN_CSTRING(buf.data);
}
/*
* cube_send - a binary output handler for cube type
*/
Datum
cube_send(PG_FUNCTION_ARGS)
{
NDBOX *cube = PG_GETARG_NDBOX_P(0);
StringInfoData buf;
int32 i,
nitems = DIM(cube);
pq_begintypsend(&buf);
pq_sendint32(&buf, cube->header);
if (!IS_POINT(cube))
nitems += nitems;
/* for symmetry with cube_recv, we don't use LL_COORD/UR_COORD here */
for (i = 0; i < nitems; i++)
pq_sendfloat8(&buf, cube->x[i]);
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}
/*
* cube_recv - a binary input handler for cube type
*/
Datum
cube_recv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
int32 header;
int32 i,
nitems;
NDBOX *cube;
header = pq_getmsgint(buf, sizeof(int32));
nitems = (header & DIM_MASK);
if (nitems > CUBE_MAX_DIM)
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("cube dimension is too large"),
errdetail("A cube cannot have more than %d dimensions.",
CUBE_MAX_DIM)));
if ((header & POINT_BIT) == 0)
nitems += nitems;
cube = palloc(offsetof(NDBOX, x) + sizeof(double) * nitems);
SET_VARSIZE(cube, offsetof(NDBOX, x) + sizeof(double) * nitems);
cube->header = header;
for (i = 0; i < nitems; i++)
cube->x[i] = pq_getmsgfloat8(buf);
PG_RETURN_NDBOX_P(cube);
}
/*****************************************************************************
* GiST functions