0002-Implements-ltree-lquery-and-ltxtquery-binary-protoco.patch
application/octet-stream
Filename: 0002-Implements-ltree-lquery-and-ltxtquery-binary-protoco.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch 0002
Subject: Implements ltree, lquery, and ltxtquery binary protocol support
| File | + | − |
|---|---|---|
| contrib/ltree/crc32.c | 2 | 2 |
| contrib/ltree/crc32.h | 1 | 1 |
| contrib/ltree/lquery_op.c | 1 | 1 |
| contrib/ltree/ltree--1.2.sql | 907 | 0 |
| contrib/ltree/ltree.control | 1 | 1 |
| contrib/ltree/ltree.h | 4 | 4 |
| contrib/ltree/ltree_io.c | 179 | 24 |
| contrib/ltree/ltxtquery_io.c | 71 | 4 |
| contrib/ltree/Makefile | 1 | 1 |
From bfe6b7c2b794446c348a712efd0aa9ce59130d63 Mon Sep 17 00:00:00 2001
From: Nino Floris <mail@ninofloris.com>
Date: Sun, 18 Aug 2019 16:30:30 +0200
Subject: [PATCH] Implements ltree, lquery, and ltxtquery binary protocol
support
---
contrib/ltree/Makefile | 2 +-
contrib/ltree/crc32.c | 4 +-
contrib/ltree/crc32.h | 2 +-
contrib/ltree/lquery_op.c | 2 +-
contrib/ltree/ltree--1.2.sql | 907 +++++++++++++++++++++++++++++++++++
contrib/ltree/ltree.control | 2 +-
contrib/ltree/ltree.h | 8 +-
contrib/ltree/ltree_io.c | 203 +++++++-
contrib/ltree/ltxtquery_io.c | 75 ++-
9 files changed, 1167 insertions(+), 38 deletions(-)
create mode 100644 contrib/ltree/ltree--1.2.sql
diff --git a/contrib/ltree/Makefile b/contrib/ltree/Makefile
index 416c8da312..2a17593212 100644
--- a/contrib/ltree/Makefile
+++ b/contrib/ltree/Makefile
@@ -6,7 +6,7 @@ OBJS = ltree_io.o ltree_op.o lquery_op.o _ltree_op.o crc32.o \
PG_CPPFLAGS = -DLOWER_NODE
EXTENSION = ltree
-DATA = ltree--1.1.sql ltree--1.0--1.1.sql ltree--unpackaged--1.0.sql
+DATA = ltree--1.2.sql ltree--1.1.sql ltree--1.0--1.1.sql ltree--unpackaged--1.0.sql
PGFILEDESC = "ltree - hierarchical label data type"
HEADERS = ltree.h
diff --git a/contrib/ltree/crc32.c b/contrib/ltree/crc32.c
index 447e4b2960..1debbf9d3a 100644
--- a/contrib/ltree/crc32.c
+++ b/contrib/ltree/crc32.c
@@ -20,10 +20,10 @@
#include "crc32.h"
unsigned int
-ltree_crc32_sz(char *buf, int size)
+ltree_crc32_sz(const char *buf, int size)
{
pg_crc32 crc;
- char *p = buf;
+ const char *p = buf;
INIT_TRADITIONAL_CRC32(crc);
while (size > 0)
diff --git a/contrib/ltree/crc32.h b/contrib/ltree/crc32.h
index 269d05d0c1..958812214d 100644
--- a/contrib/ltree/crc32.h
+++ b/contrib/ltree/crc32.h
@@ -4,7 +4,7 @@
/* contrib/ltree/crc32.h */
/* Returns crc32 of data block */
-extern unsigned int ltree_crc32_sz(char *buf, int size);
+extern unsigned int ltree_crc32_sz(const char *buf, int size);
/* Returns crc32 of null-terminated string */
#define crc32(buf) ltree_crc32_sz((buf),strlen(buf))
diff --git a/contrib/ltree/lquery_op.c b/contrib/ltree/lquery_op.c
index b6d2deb1af..62172d5ea1 100644
--- a/contrib/ltree/lquery_op.c
+++ b/contrib/ltree/lquery_op.c
@@ -50,7 +50,7 @@ getlexeme(char *start, char *end, int *len)
}
bool
- compare_subnode(ltree_level *t, char *qn, int len, int (*cmpptr) (const char *, const char *, size_t), bool anyend)
+compare_subnode(ltree_level *t, char *qn, int len, int (*cmpptr) (const char *, const char *, size_t), bool anyend)
{
char *endt = t->name + t->len;
char *endq = qn + len;
diff --git a/contrib/ltree/ltree--1.2.sql b/contrib/ltree/ltree--1.2.sql
new file mode 100644
index 0000000000..ab762597e4
--- /dev/null
+++ b/contrib/ltree/ltree--1.2.sql
@@ -0,0 +1,907 @@
+/* contrib/ltree/ltree--1.2.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "CREATE EXTENSION ltree" to load this file. \quit
+
+CREATE FUNCTION ltree_in(cstring)
+RETURNS ltree
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION ltree_out(ltree)
+RETURNS cstring
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION ltree_recv(internal)
+RETURNS ltree
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION ltree_send(ltree)
+RETURNS bytea
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE TYPE ltree (
+ INTERNALLENGTH = -1,
+ INPUT = ltree_in,
+ OUTPUT = ltree_out,
+ RECEIVE = ltree_recv,
+ SEND = ltree_send,
+ STORAGE = extended
+);
+
+--Compare function for ltree
+CREATE FUNCTION ltree_cmp(ltree,ltree)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION ltree_lt(ltree,ltree)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION ltree_le(ltree,ltree)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION ltree_eq(ltree,ltree)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION ltree_ge(ltree,ltree)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION ltree_gt(ltree,ltree)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION ltree_ne(ltree,ltree)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+
+CREATE OPERATOR < (
+ LEFTARG = ltree,
+ RIGHTARG = ltree,
+ PROCEDURE = ltree_lt,
+ COMMUTATOR = '>',
+ NEGATOR = '>=',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR <= (
+ LEFTARG = ltree,
+ RIGHTARG = ltree,
+ PROCEDURE = ltree_le,
+ COMMUTATOR = '>=',
+ NEGATOR = '>',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR >= (
+ LEFTARG = ltree,
+ RIGHTARG = ltree,
+ PROCEDURE = ltree_ge,
+ COMMUTATOR = '<=',
+ NEGATOR = '<',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR > (
+ LEFTARG = ltree,
+ RIGHTARG = ltree,
+ PROCEDURE = ltree_gt,
+ COMMUTATOR = '<',
+ NEGATOR = '<=',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR = (
+ LEFTARG = ltree,
+ RIGHTARG = ltree,
+ PROCEDURE = ltree_eq,
+ COMMUTATOR = '=',
+ NEGATOR = '<>',
+ RESTRICT = eqsel,
+ JOIN = eqjoinsel,
+ SORT1 = '<',
+ SORT2 = '<'
+);
+
+CREATE OPERATOR <> (
+ LEFTARG = ltree,
+ RIGHTARG = ltree,
+ PROCEDURE = ltree_ne,
+ COMMUTATOR = '<>',
+ NEGATOR = '=',
+ RESTRICT = neqsel,
+ JOIN = neqjoinsel
+);
+
+--util functions
+
+CREATE FUNCTION subltree(ltree,int4,int4)
+RETURNS ltree
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION subpath(ltree,int4,int4)
+RETURNS ltree
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION subpath(ltree,int4)
+RETURNS ltree
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION index(ltree,ltree)
+RETURNS int4
+AS 'MODULE_PATHNAME', 'ltree_index'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION index(ltree,ltree,int4)
+RETURNS int4
+AS 'MODULE_PATHNAME', 'ltree_index'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION nlevel(ltree)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION ltree2text(ltree)
+RETURNS text
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION text2ltree(text)
+RETURNS ltree
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION lca(_ltree)
+RETURNS ltree
+AS 'MODULE_PATHNAME','_lca'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION lca(ltree,ltree)
+RETURNS ltree
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION lca(ltree,ltree,ltree)
+RETURNS ltree
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION lca(ltree,ltree,ltree,ltree)
+RETURNS ltree
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION lca(ltree,ltree,ltree,ltree,ltree)
+RETURNS ltree
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION lca(ltree,ltree,ltree,ltree,ltree,ltree)
+RETURNS ltree
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION lca(ltree,ltree,ltree,ltree,ltree,ltree,ltree)
+RETURNS ltree
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION lca(ltree,ltree,ltree,ltree,ltree,ltree,ltree,ltree)
+RETURNS ltree
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION ltree_isparent(ltree,ltree)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION ltree_risparent(ltree,ltree)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION ltree_addltree(ltree,ltree)
+RETURNS ltree
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION ltree_addtext(ltree,text)
+RETURNS ltree
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION ltree_textadd(text,ltree)
+RETURNS ltree
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION ltreeparentsel(internal, oid, internal, integer)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE OPERATOR @> (
+ LEFTARG = ltree,
+ RIGHTARG = ltree,
+ PROCEDURE = ltree_isparent,
+ COMMUTATOR = '<@',
+ RESTRICT = ltreeparentsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR ^@> (
+ LEFTARG = ltree,
+ RIGHTARG = ltree,
+ PROCEDURE = ltree_isparent,
+ COMMUTATOR = '^<@',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR <@ (
+ LEFTARG = ltree,
+ RIGHTARG = ltree,
+ PROCEDURE = ltree_risparent,
+ COMMUTATOR = '@>',
+ RESTRICT = ltreeparentsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR ^<@ (
+ LEFTARG = ltree,
+ RIGHTARG = ltree,
+ PROCEDURE = ltree_risparent,
+ COMMUTATOR = '^@>',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR || (
+ LEFTARG = ltree,
+ RIGHTARG = ltree,
+ PROCEDURE = ltree_addltree
+);
+
+CREATE OPERATOR || (
+ LEFTARG = ltree,
+ RIGHTARG = text,
+ PROCEDURE = ltree_addtext
+);
+
+CREATE OPERATOR || (
+ LEFTARG = text,
+ RIGHTARG = ltree,
+ PROCEDURE = ltree_textadd
+);
+
+
+-- B-tree support
+
+CREATE OPERATOR CLASS ltree_ops
+ DEFAULT FOR TYPE ltree USING btree AS
+ OPERATOR 1 < ,
+ OPERATOR 2 <= ,
+ OPERATOR 3 = ,
+ OPERATOR 4 >= ,
+ OPERATOR 5 > ,
+ FUNCTION 1 ltree_cmp(ltree, ltree);
+
+
+--lquery type
+CREATE FUNCTION lquery_in(cstring)
+RETURNS lquery
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION lquery_out(lquery)
+RETURNS cstring
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION lquery_recv(internal)
+RETURNS lquery
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION lquery_send(lquery)
+RETURNS bytea
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE TYPE lquery (
+ INTERNALLENGTH = -1,
+ INPUT = lquery_in,
+ OUTPUT = lquery_out,
+ RECEIVE = lquery_recv,
+ SEND = lquery_send,
+ STORAGE = extended
+);
+
+CREATE FUNCTION ltq_regex(ltree,lquery)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION ltq_rregex(lquery,ltree)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE OPERATOR ~ (
+ LEFTARG = ltree,
+ RIGHTARG = lquery,
+ PROCEDURE = ltq_regex,
+ COMMUTATOR = '~',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR ~ (
+ LEFTARG = lquery,
+ RIGHTARG = ltree,
+ PROCEDURE = ltq_rregex,
+ COMMUTATOR = '~',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+--not-indexed
+CREATE OPERATOR ^~ (
+ LEFTARG = ltree,
+ RIGHTARG = lquery,
+ PROCEDURE = ltq_regex,
+ COMMUTATOR = '^~',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR ^~ (
+ LEFTARG = lquery,
+ RIGHTARG = ltree,
+ PROCEDURE = ltq_rregex,
+ COMMUTATOR = '^~',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE FUNCTION lt_q_regex(ltree,_lquery)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION lt_q_rregex(_lquery,ltree)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE OPERATOR ? (
+ LEFTARG = ltree,
+ RIGHTARG = _lquery,
+ PROCEDURE = lt_q_regex,
+ COMMUTATOR = '?',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR ? (
+ LEFTARG = _lquery,
+ RIGHTARG = ltree,
+ PROCEDURE = lt_q_rregex,
+ COMMUTATOR = '?',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+--not-indexed
+CREATE OPERATOR ^? (
+ LEFTARG = ltree,
+ RIGHTARG = _lquery,
+ PROCEDURE = lt_q_regex,
+ COMMUTATOR = '^?',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR ^? (
+ LEFTARG = _lquery,
+ RIGHTARG = ltree,
+ PROCEDURE = lt_q_rregex,
+ COMMUTATOR = '^?',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE FUNCTION ltxtq_in(cstring)
+RETURNS ltxtquery
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION ltxtq_out(ltxtquery)
+RETURNS cstring
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION ltxtq_recv(internal)
+RETURNS ltxtquery
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION ltxtq_send(ltxtquery)
+RETURNS bytea
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE TYPE ltxtquery (
+ INTERNALLENGTH = -1,
+ INPUT = ltxtq_in,
+ OUTPUT = ltxtq_out,
+ RECEIVE = ltxtq_recv,
+ SEND = ltxtq_send,
+ STORAGE = extended
+);
+
+-- operations WITH ltxtquery
+
+CREATE FUNCTION ltxtq_exec(ltree, ltxtquery)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION ltxtq_rexec(ltxtquery, ltree)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE OPERATOR @ (
+ LEFTARG = ltree,
+ RIGHTARG = ltxtquery,
+ PROCEDURE = ltxtq_exec,
+ COMMUTATOR = '@',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR @ (
+ LEFTARG = ltxtquery,
+ RIGHTARG = ltree,
+ PROCEDURE = ltxtq_rexec,
+ COMMUTATOR = '@',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+--not-indexed
+CREATE OPERATOR ^@ (
+ LEFTARG = ltree,
+ RIGHTARG = ltxtquery,
+ PROCEDURE = ltxtq_exec,
+ COMMUTATOR = '^@',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR ^@ (
+ LEFTARG = ltxtquery,
+ RIGHTARG = ltree,
+ PROCEDURE = ltxtq_rexec,
+ COMMUTATOR = '^@',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+--GiST support for ltree
+CREATE FUNCTION ltree_gist_in(cstring)
+RETURNS ltree_gist
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION ltree_gist_out(ltree_gist)
+RETURNS cstring
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE TYPE ltree_gist (
+ internallength = -1,
+ input = ltree_gist_in,
+ output = ltree_gist_out,
+ storage = plain
+);
+
+
+CREATE FUNCTION ltree_consistent(internal,ltree,int2,oid,internal)
+RETURNS bool as 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
+
+CREATE FUNCTION ltree_compress(internal)
+RETURNS internal as 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
+
+CREATE FUNCTION ltree_decompress(internal)
+RETURNS internal as 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
+
+CREATE FUNCTION ltree_penalty(internal,internal,internal)
+RETURNS internal as 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
+
+CREATE FUNCTION ltree_picksplit(internal, internal)
+RETURNS internal as 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
+
+CREATE FUNCTION ltree_union(internal, internal)
+RETURNS ltree_gist as 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
+
+CREATE FUNCTION ltree_same(ltree_gist, ltree_gist, internal)
+RETURNS internal as 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
+
+CREATE OPERATOR CLASS gist_ltree_ops
+ DEFAULT FOR TYPE ltree USING gist AS
+ OPERATOR 1 < ,
+ OPERATOR 2 <= ,
+ OPERATOR 3 = ,
+ OPERATOR 4 >= ,
+ OPERATOR 5 > ,
+ OPERATOR 10 @> ,
+ OPERATOR 11 <@ ,
+ OPERATOR 12 ~ (ltree, lquery) ,
+ OPERATOR 13 ~ (lquery, ltree) ,
+ OPERATOR 14 @ (ltree, ltxtquery) ,
+ OPERATOR 15 @ (ltxtquery, ltree) ,
+ OPERATOR 16 ? (ltree, _lquery) ,
+ OPERATOR 17 ? (_lquery, ltree) ,
+ FUNCTION 1 ltree_consistent (internal, ltree, int2, oid, internal),
+ FUNCTION 2 ltree_union (internal, internal),
+ FUNCTION 3 ltree_compress (internal),
+ FUNCTION 4 ltree_decompress (internal),
+ FUNCTION 5 ltree_penalty (internal, internal, internal),
+ FUNCTION 6 ltree_picksplit (internal, internal),
+ FUNCTION 7 ltree_same (ltree_gist, ltree_gist, internal),
+ STORAGE ltree_gist;
+
+
+-- arrays of ltree
+
+CREATE FUNCTION _ltree_isparent(_ltree,ltree)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION _ltree_r_isparent(ltree,_ltree)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION _ltree_risparent(_ltree,ltree)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION _ltree_r_risparent(ltree,_ltree)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION _ltq_regex(_ltree,lquery)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION _ltq_rregex(lquery,_ltree)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION _lt_q_regex(_ltree,_lquery)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION _lt_q_rregex(_lquery,_ltree)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION _ltxtq_exec(_ltree, ltxtquery)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION _ltxtq_rexec(ltxtquery, _ltree)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE OPERATOR @> (
+ LEFTARG = _ltree,
+ RIGHTARG = ltree,
+ PROCEDURE = _ltree_isparent,
+ COMMUTATOR = '<@',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR <@ (
+ LEFTARG = ltree,
+ RIGHTARG = _ltree,
+ PROCEDURE = _ltree_r_isparent,
+ COMMUTATOR = '@>',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR <@ (
+ LEFTARG = _ltree,
+ RIGHTARG = ltree,
+ PROCEDURE = _ltree_risparent,
+ COMMUTATOR = '@>',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR @> (
+ LEFTARG = ltree,
+ RIGHTARG = _ltree,
+ PROCEDURE = _ltree_r_risparent,
+ COMMUTATOR = '<@',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR ~ (
+ LEFTARG = _ltree,
+ RIGHTARG = lquery,
+ PROCEDURE = _ltq_regex,
+ COMMUTATOR = '~',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR ~ (
+ LEFTARG = lquery,
+ RIGHTARG = _ltree,
+ PROCEDURE = _ltq_rregex,
+ COMMUTATOR = '~',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR ? (
+ LEFTARG = _ltree,
+ RIGHTARG = _lquery,
+ PROCEDURE = _lt_q_regex,
+ COMMUTATOR = '?',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR ? (
+ LEFTARG = _lquery,
+ RIGHTARG = _ltree,
+ PROCEDURE = _lt_q_rregex,
+ COMMUTATOR = '?',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR @ (
+ LEFTARG = _ltree,
+ RIGHTARG = ltxtquery,
+ PROCEDURE = _ltxtq_exec,
+ COMMUTATOR = '@',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR @ (
+ LEFTARG = ltxtquery,
+ RIGHTARG = _ltree,
+ PROCEDURE = _ltxtq_rexec,
+ COMMUTATOR = '@',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+
+--not indexed
+CREATE OPERATOR ^@> (
+ LEFTARG = _ltree,
+ RIGHTARG = ltree,
+ PROCEDURE = _ltree_isparent,
+ COMMUTATOR = '^<@',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR ^<@ (
+ LEFTARG = ltree,
+ RIGHTARG = _ltree,
+ PROCEDURE = _ltree_r_isparent,
+ COMMUTATOR = '^@>',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR ^<@ (
+ LEFTARG = _ltree,
+ RIGHTARG = ltree,
+ PROCEDURE = _ltree_risparent,
+ COMMUTATOR = '^@>',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR ^@> (
+ LEFTARG = ltree,
+ RIGHTARG = _ltree,
+ PROCEDURE = _ltree_r_risparent,
+ COMMUTATOR = '^<@',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR ^~ (
+ LEFTARG = _ltree,
+ RIGHTARG = lquery,
+ PROCEDURE = _ltq_regex,
+ COMMUTATOR = '^~',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR ^~ (
+ LEFTARG = lquery,
+ RIGHTARG = _ltree,
+ PROCEDURE = _ltq_rregex,
+ COMMUTATOR = '^~',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR ^? (
+ LEFTARG = _ltree,
+ RIGHTARG = _lquery,
+ PROCEDURE = _lt_q_regex,
+ COMMUTATOR = '^?',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR ^? (
+ LEFTARG = _lquery,
+ RIGHTARG = _ltree,
+ PROCEDURE = _lt_q_rregex,
+ COMMUTATOR = '^?',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR ^@ (
+ LEFTARG = _ltree,
+ RIGHTARG = ltxtquery,
+ PROCEDURE = _ltxtq_exec,
+ COMMUTATOR = '^@',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR ^@ (
+ LEFTARG = ltxtquery,
+ RIGHTARG = _ltree,
+ PROCEDURE = _ltxtq_rexec,
+ COMMUTATOR = '^@',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+--extractors
+CREATE FUNCTION _ltree_extract_isparent(_ltree,ltree)
+RETURNS ltree
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE OPERATOR ?@> (
+ LEFTARG = _ltree,
+ RIGHTARG = ltree,
+ PROCEDURE = _ltree_extract_isparent
+);
+
+CREATE FUNCTION _ltree_extract_risparent(_ltree,ltree)
+RETURNS ltree
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE OPERATOR ?<@ (
+ LEFTARG = _ltree,
+ RIGHTARG = ltree,
+ PROCEDURE = _ltree_extract_risparent
+);
+
+CREATE FUNCTION _ltq_extract_regex(_ltree,lquery)
+RETURNS ltree
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE OPERATOR ?~ (
+ LEFTARG = _ltree,
+ RIGHTARG = lquery,
+ PROCEDURE = _ltq_extract_regex
+);
+
+CREATE FUNCTION _ltxtq_extract_exec(_ltree,ltxtquery)
+RETURNS ltree
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE OPERATOR ?@ (
+ LEFTARG = _ltree,
+ RIGHTARG = ltxtquery,
+ PROCEDURE = _ltxtq_extract_exec
+);
+
+--GiST support for ltree[]
+CREATE FUNCTION _ltree_consistent(internal,_ltree,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
+
+CREATE FUNCTION _ltree_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
+
+CREATE FUNCTION _ltree_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
+
+CREATE FUNCTION _ltree_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
+
+CREATE FUNCTION _ltree_union(internal, internal)
+RETURNS ltree_gist
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
+
+CREATE FUNCTION _ltree_same(ltree_gist, ltree_gist, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
+
+CREATE OPERATOR CLASS gist__ltree_ops
+ DEFAULT FOR TYPE _ltree USING gist AS
+ OPERATOR 10 <@ (_ltree, ltree),
+ OPERATOR 11 @> (ltree, _ltree),
+ OPERATOR 12 ~ (_ltree, lquery),
+ OPERATOR 13 ~ (lquery, _ltree),
+ OPERATOR 14 @ (_ltree, ltxtquery),
+ OPERATOR 15 @ (ltxtquery, _ltree),
+ OPERATOR 16 ? (_ltree, _lquery),
+ OPERATOR 17 ? (_lquery, _ltree),
+ FUNCTION 1 _ltree_consistent (internal, _ltree, int2, oid, internal),
+ FUNCTION 2 _ltree_union (internal, internal),
+ FUNCTION 3 _ltree_compress (internal),
+ FUNCTION 4 ltree_decompress (internal),
+ FUNCTION 5 _ltree_penalty (internal, internal, internal),
+ FUNCTION 6 _ltree_picksplit (internal, internal),
+ FUNCTION 7 _ltree_same (ltree_gist, ltree_gist, internal),
+ STORAGE ltree_gist;
diff --git a/contrib/ltree/ltree.control b/contrib/ltree/ltree.control
index 03c3fb1ab5..61c8cdf40a 100644
--- a/contrib/ltree/ltree.control
+++ b/contrib/ltree/ltree.control
@@ -1,5 +1,5 @@
# ltree extension
comment = 'data type for hierarchical tree-like structures'
-default_version = '1.1'
+default_version = '1.2'
module_pathname = '$libdir/ltree'
relocatable = true
diff --git a/contrib/ltree/ltree.h b/contrib/ltree/ltree.h
index e4b8c84fa6..366e58004c 100644
--- a/contrib/ltree/ltree.h
+++ b/contrib/ltree/ltree.h
@@ -155,13 +155,13 @@ Datum ltree_textadd(PG_FUNCTION_ARGS);
/* Util function */
Datum ltree_in(PG_FUNCTION_ARGS);
-bool ltree_execute(ITEM *curitem, void *checkval,
- bool calcnot, bool (*chkcond) (void *checkval, ITEM *val));
+bool ltree_execute(ITEM *curitem, void *checkval,
+ bool calcnot, bool (*chkcond) (void *checkval, ITEM *val));
int ltree_compare(const ltree *a, const ltree *b);
bool inner_isparent(const ltree *c, const ltree *p);
-bool compare_subnode(ltree_level *t, char *q, int len,
- int (*cmpptr) (const char *, const char *, size_t), bool anyend);
+bool compare_subnode(ltree_level *t, char *q, int len,
+ int (*cmpptr) (const char *, const char *, size_t), bool anyend);
ltree *lca_inner(ltree **a, int len);
int ltree_strncasecmp(const char *a, const char *b, size_t s);
diff --git a/contrib/ltree/ltree_io.c b/contrib/ltree/ltree_io.c
index f54f037443..b5cca12835 100644
--- a/contrib/ltree/ltree_io.c
+++ b/contrib/ltree/ltree_io.c
@@ -4,28 +4,23 @@
* contrib/ltree/ltree_io.c
*/
#include "postgres.h"
+#include "libpq/pqformat.h"
#include <ctype.h>
#include "ltree.h"
#include "utils/memutils.h"
+#include "utils/builtins.h"
#include "crc32.h"
-PG_FUNCTION_INFO_V1(ltree_in);
-PG_FUNCTION_INFO_V1(ltree_out);
-PG_FUNCTION_INFO_V1(lquery_in);
-PG_FUNCTION_INFO_V1(lquery_out);
-
-
#define UNCHAR ereport(ERROR, \
(errcode(ERRCODE_SYNTAX_ERROR), \
errmsg("syntax error at position %d", \
pos)));
-
typedef struct
{
- char *start;
+ const char *start;
int len; /* length in bytes */
int flag;
int wlen; /* length in characters */
@@ -34,11 +29,14 @@ typedef struct
#define LTPRS_WAITNAME 0
#define LTPRS_WAITDELIM 1
-Datum
-ltree_in(PG_FUNCTION_ARGS)
+/*
+ * expects a null terminated string
+ * returns an ltree
+ */
+static ltree *
+parse_ltree(const char *buf)
{
- char *buf = (char *) PG_GETARG_POINTER(0);
- char *ptr;
+ const char *ptr;
nodeitem *list,
*lptr;
int num = 0,
@@ -143,13 +141,16 @@ ltree_in(PG_FUNCTION_ARGS)
}
pfree(list);
- PG_RETURN_POINTER(result);
+ return result;
}
-Datum
-ltree_out(PG_FUNCTION_ARGS)
+/*
+ * expects an ltree
+ * returns a null terminated string
+ */
+static char *
+deparse_ltree(const ltree *in)
{
- ltree *in = PG_GETARG_LTREE_P(0);
char *buf,
*ptr;
int i;
@@ -170,11 +171,85 @@ ltree_out(PG_FUNCTION_ARGS)
}
*ptr = '\0';
+ return buf;
+}
+
+PG_FUNCTION_INFO_V1(ltree_in);
+Datum
+ltree_in(PG_FUNCTION_ARGS)
+{
+ char *buf = (char *) PG_GETARG_POINTER(0);
+ ltree *result = parse_ltree(buf);
+
+ PG_RETURN_POINTER(result);
+}
+
+PG_FUNCTION_INFO_V1(ltree_out);
+Datum
+ltree_out(PG_FUNCTION_ARGS)
+{
+ ltree *in = PG_GETARG_LTREE_P(0);
+ char *buf = deparse_ltree(in);
+
PG_FREE_IF_COPY(in, 0);
PG_RETURN_POINTER(buf);
}
+/*
+ * ltree type send 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(ltree_send);
+Datum
+ltree_send(PG_FUNCTION_ARGS)
+{
+ ltree *in = PG_GETARG_LTREE_P(0);
+ StringInfoData buf;
+ int version = 1;
+ char *res = deparse_ltree(in);
+
+ pq_begintypsend(&buf);
+ pq_sendint8(&buf, version);
+ pq_sendtext(&buf, res, pg_mbstrlen(res));
+ pfree(res);
+
+ PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
+}
+
+/*
+ * ltree 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(ltree_recv);
+Datum
+ltree_recv(PG_FUNCTION_ARGS)
+{
+ StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
+ int version = pq_getmsgint(buf, 1);
+ char *str;
+ int nbytes;
+ ltree *res;
+
+ if (version == 1)
+ str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
+ else
+ elog(ERROR, "unsupported ltree version number %d", version);
+
+ res = parse_ltree(str);
+ pfree(str);
+
+ PG_RETURN_POINTER(res);
+}
+
#define LQPRS_WAITLEVEL 0
#define LQPRS_WAITDELIM 1
#define LQPRS_WAITOPEN 2
@@ -190,11 +265,14 @@ ltree_out(PG_FUNCTION_ARGS)
#define ITEMSIZE MAXALIGN(LQL_HDRSIZE+sizeof(nodeitem*))
#define NEXTLEV(x) ( (lquery_level*)( ((char*)(x)) + ITEMSIZE) )
-Datum
-lquery_in(PG_FUNCTION_ARGS)
+/*
+ * expects a null terminated string
+ * returns an lquery
+ */
+static lquery *
+parse_lquery(const char *buf)
{
- char *buf = (char *) PG_GETARG_POINTER(0);
- char *ptr;
+ const char *ptr;
int num = 0,
totallen = 0,
numOR = 0;
@@ -515,13 +593,16 @@ lquery_in(PG_FUNCTION_ARGS)
}
pfree(tmpql);
- PG_RETURN_POINTER(result);
+ return result;
}
-Datum
-lquery_out(PG_FUNCTION_ARGS)
+/*
+ * expects an lquery
+ * returns a null terminated string
+ */
+static char *
+deparse_lquery(const lquery *in)
{
- lquery *in = PG_GETARG_LQUERY_P(0);
char *buf,
*ptr;
int i,
@@ -614,7 +695,81 @@ lquery_out(PG_FUNCTION_ARGS)
}
*ptr = '\0';
+ return buf;
+}
+
+PG_FUNCTION_INFO_V1(lquery_in);
+Datum
+lquery_in(PG_FUNCTION_ARGS)
+{
+ char *buf = (char *) PG_GETARG_POINTER(0);
+ lquery *result = parse_lquery(buf);
+
+ PG_RETURN_POINTER(result);
+}
+
+PG_FUNCTION_INFO_V1(lquery_out);
+Datum
+lquery_out(PG_FUNCTION_ARGS)
+{
+ lquery *in = PG_GETARG_LQUERY_P(0);
+ char *buf = deparse_lquery(in);
+
PG_FREE_IF_COPY(in, 0);
PG_RETURN_POINTER(buf);
}
+
+/*
+ * lquery type send 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(lquery_send);
+Datum
+lquery_send(PG_FUNCTION_ARGS)
+{
+ lquery *in = PG_GETARG_LQUERY_P(0);
+ StringInfoData buf;
+ int version = 1;
+ char *res = deparse_lquery(in);
+
+ pq_begintypsend(&buf);
+ pq_sendint8(&buf, version);
+ pq_sendtext(&buf, res, pg_mbstrlen(res));
+ pfree(res);
+
+ PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
+}
+
+/*
+ * lquery 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(lquery_recv);
+Datum
+lquery_recv(PG_FUNCTION_ARGS)
+{
+ StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
+ int version = pq_getmsgint(buf, 1);
+ char *str;
+ int nbytes;
+ lquery *res;
+
+ if (version == 1)
+ str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
+ else
+ elog(ERROR, "unsupported lquery version number %d", version);
+
+ res = parse_lquery(str);
+ pfree(str);
+
+ PG_RETURN_POINTER(res);
+}
diff --git a/contrib/ltree/ltxtquery_io.c b/contrib/ltree/ltxtquery_io.c
index 56bf39d145..b2f0081053 100644
--- a/contrib/ltree/ltxtquery_io.c
+++ b/contrib/ltree/ltxtquery_io.c
@@ -4,6 +4,7 @@
* contrib/ltree/ltxtquery_io.c
*/
#include "postgres.h"
+#include "libpq/pqformat.h"
#include <ctype.h>
@@ -11,10 +12,6 @@
#include "ltree.h"
#include "miscadmin.h"
-PG_FUNCTION_INFO_V1(ltxtq_in);
-PG_FUNCTION_INFO_V1(ltxtq_out);
-
-
/* parser's states */
#define WAITOPERAND 1
#define INOPERAND 2
@@ -382,12 +379,42 @@ queryin(char *buf)
/*
* in without morphology
*/
+PG_FUNCTION_INFO_V1(ltxtq_in);
Datum
ltxtq_in(PG_FUNCTION_ARGS)
{
PG_RETURN_POINTER(queryin((char *) PG_GETARG_POINTER(0)));
}
+/*
+ * 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)
+ str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
+ else
+ elog(ERROR, "unsupported ltxtquery version number %d", version);
+
+ res = queryin(str);
+ pfree(str);
+
+ PG_RETURN_POINTER(res);
+}
+
/*
* out function
*/
@@ -512,6 +539,7 @@ infix(INFIX *in, bool first)
}
}
+PG_FUNCTION_INFO_V1(ltxtq_out);
Datum
ltxtq_out(PG_FUNCTION_ARGS)
{
@@ -534,3 +562,42 @@ ltxtq_out(PG_FUNCTION_ARGS)
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 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_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);
+
+ PG_FREE_IF_COPY(query, 0);
+ pq_begintypsend(&buf);
+ pq_sendint8(&buf, version);
+ pq_sendtext(&buf, nrm.buf, pg_mbstrlen(nrm.buf));
+ pfree(nrm.buf);
+
+ PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
+}
--
2.23.0