diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2020-04-01 17:31:29 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2020-04-01 17:31:29 -0400 |
commit | 949a9f043eb70a4986041b47513579f9a13d6a33 (patch) | |
tree | 5870f8152a71ed8701a552d9bb22e78750afcaad /contrib/ltree/ltxtquery_io.c | |
parent | 501b0187998c24d4a950459d9bf5e67f9f3e4a25 (diff) |
Add support for binary I/O of ltree, lquery, and ltxtquery types.
Not much to say here --- does what it says on the tin. The "binary"
representation in each case is really just the same as the text format,
though we prefix a version-number byte in case anyone ever feels
motivated to change that. Thus, there's not any expectation of improved
speed or reduced space; the point here is just to allow clients to use
binary format for all columns of a query result or COPY data.
This makes use of the recently added ALTER TYPE support to add binary
I/O functions to an existing data type. As in commit a80818605,
we can piggy-back on there already being a new-for-v13 version of the
ltree extension, so we don't need a new update script file.
Nino Floris, reviewed by Alexander Korotkov and myself
Discussion: https://postgr.es/m/CANmj9Vxx50jOo1L7iSRxd142NyTz6Bdcgg7u9P3Z8o0=HGkYyQ@mail.gmail.com
Diffstat (limited to 'contrib/ltree/ltxtquery_io.c')
-rw-r--r-- | contrib/ltree/ltxtquery_io.c | 73 |
1 files changed, 69 insertions, 4 deletions
diff --git a/contrib/ltree/ltxtquery_io.c b/contrib/ltree/ltxtquery_io.c index db347f77721..d967f92110f 100644 --- a/contrib/ltree/ltxtquery_io.c +++ b/contrib/ltree/ltxtquery_io.c @@ -8,12 +8,10 @@ #include <ctype.h> #include "crc32.h" +#include "libpq/pqformat.h" #include "ltree.h" #include "miscadmin.h" -PG_FUNCTION_INFO_V1(ltxtq_in); -PG_FUNCTION_INFO_V1(ltxtq_out); - /* parser's states */ #define WAITOPERAND 1 @@ -381,6 +379,7 @@ queryin(char *buf) /* * in without morphology */ +PG_FUNCTION_INFO_V1(ltxtq_in); Datum ltxtq_in(PG_FUNCTION_ARGS) { @@ -388,6 +387,34 @@ ltxtq_in(PG_FUNCTION_ARGS) } /* + * ltxtquery type recv function + * + * The type is sent as text in binary mode, so this is almost the same + * as the input function, but it's prefixed with a version number so we + * can change the binary format sent in future if necessary. For now, + * only version 1 is supported. + */ +PG_FUNCTION_INFO_V1(ltxtq_recv); +Datum +ltxtq_recv(PG_FUNCTION_ARGS) +{ + StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); + int version = pq_getmsgint(buf, 1); + char *str; + int nbytes; + ltxtquery *res; + + if (version != 1) + elog(ERROR, "unsupported ltxtquery version number %d", version); + + str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes); + res = queryin(str); + pfree(str); + + PG_RETURN_POINTER(res); +} + +/* * out function */ typedef struct @@ -511,6 +538,7 @@ infix(INFIX *in, bool first) } } +PG_FUNCTION_INFO_V1(ltxtq_out); Datum ltxtq_out(PG_FUNCTION_ARGS) { @@ -530,6 +558,43 @@ ltxtq_out(PG_FUNCTION_ARGS) nrm.op = GETOPERAND(query); infix(&nrm, true); - PG_FREE_IF_COPY(query, 0); PG_RETURN_POINTER(nrm.buf); } + +/* + * ltxtquery type send function + * + * The type is sent as text in binary mode, so this is almost the same + * as the output function, but it's prefixed with a version number so we + * can change the binary format sent in future if necessary. For now, + * only version 1 is supported. + */ +PG_FUNCTION_INFO_V1(ltxtq_send); +Datum +ltxtq_send(PG_FUNCTION_ARGS) +{ + ltxtquery *query = PG_GETARG_LTXTQUERY_P(0); + StringInfoData buf; + int version = 1; + INFIX nrm; + + if (query->size == 0) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("syntax error"), + errdetail("Empty query."))); + + nrm.curpol = GETQUERY(query); + nrm.buflen = 32; + nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen); + *(nrm.cur) = '\0'; + nrm.op = GETOPERAND(query); + infix(&nrm, true); + + pq_begintypsend(&buf); + pq_sendint8(&buf, version); + pq_sendtext(&buf, nrm.buf, strlen(nrm.buf)); + pfree(nrm.buf); + + PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); +} |