summaryrefslogtreecommitdiff
path: root/contrib/ltree/ltxtquery_io.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2020-04-01 17:31:29 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2020-04-01 17:31:29 -0400
commit949a9f043eb70a4986041b47513579f9a13d6a33 (patch)
tree5870f8152a71ed8701a552d9bb22e78750afcaad /contrib/ltree/ltxtquery_io.c
parent501b0187998c24d4a950459d9bf5e67f9f3e4a25 (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.c73
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));
+}