Skip to content
Permalink
Browse files
Support for Agtype Containment Ops and GIN Indices
Add support for @>, <@, ?, ?|, ?& operators postgres operators.

Alter property contraint checks in MATCH clause to use the @>  operator.

Add support for GIN Indices
  • Loading branch information
JoshInnis committed Apr 25, 2022
1 parent 58dccb6 commit 6279c1043d9095a5c06593d5dc3193f3875ffc14
Showing 13 changed files with 1,147 additions and 157 deletions.
@@ -51,6 +51,7 @@ OBJS = src/backend/age.o \
src/backend/utils/adt/age_graphid_ds.o \
src/backend/utils/adt/agtype.o \
src/backend/utils/adt/agtype_ext.o \
src/backend/utils/adt/agtype_gin.o \
src/backend/utils/adt/agtype_ops.o \
src/backend/utils/adt/agtype_parser.o \
src/backend/utils/adt/agtype_util.o \
@@ -2833,6 +2833,157 @@ CREATE OPERATOR CLASS agtype_ops_hash
OPERATOR 1 =,
FUNCTION 1 ag_catalog.agtype_hash_cmp(agtype);

--
-- Contains operators @> <@
--
CREATE FUNCTION ag_catalog.agtype_contains(agtype, agtype)
RETURNS boolean
LANGUAGE c
STABLE
RETURNS NULL ON NULL INPUT
PARALLEL SAFE
AS 'MODULE_PATHNAME';

CREATE OPERATOR @> (
LEFTARG = agtype,
RIGHTARG = agtype,
FUNCTION = ag_catalog.agtype_contains,
COMMUTATOR = '<@',
RESTRICT = contsel,
JOIN = contjoinsel
);

CREATE FUNCTION ag_catalog.agtype_contained_by(agtype, agtype)
RETURNS boolean
LANGUAGE c
STABLE
RETURNS NULL ON NULL INPUT
PARALLEL SAFE
AS 'MODULE_PATHNAME';

CREATE OPERATOR <@ (
LEFTARG = agtype,
RIGHTARG = agtype,
FUNCTION = ag_catalog.agtype_contained_by,
COMMUTATOR = '@>',
RESTRICT = contsel,
JOIN = contjoinsel
);

--
-- Key Existence Operators ? ?| ?&
--
CREATE FUNCTION ag_catalog.agtype_exists(agtype, text)
RETURNS boolean
LANGUAGE c
IMMUTABLE
RETURNS NULL ON NULL INPUT
PARALLEL SAFE
AS 'MODULE_PATHNAME';

CREATE OPERATOR ? (
LEFTARG = agtype,
RIGHTARG = text,
FUNCTION = ag_catalog.agtype_exists,
COMMUTATOR = '?',
RESTRICT = contsel,
JOIN = contjoinsel
);

CREATE FUNCTION ag_catalog.agtype_exists_any(agtype, text[])
RETURNS boolean
LANGUAGE c
IMMUTABLE
RETURNS NULL ON NULL INPUT
PARALLEL SAFE
AS 'MODULE_PATHNAME';

CREATE OPERATOR ?| (
LEFTARG = agtype,
RIGHTARG = text[],
FUNCTION = ag_catalog.agtype_exists_any,
RESTRICT = contsel,
JOIN = contjoinsel
);

CREATE FUNCTION ag_catalog.agtype_exists_all(agtype, text[])
RETURNS boolean
LANGUAGE c
IMMUTABLE
RETURNS NULL ON NULL INPUT
PARALLEL SAFE
AS 'MODULE_PATHNAME';

CREATE OPERATOR ?& (
LEFTARG = agtype,
RIGHTARG = text[],
FUNCTION = ag_catalog.agtype_exists_all,
RESTRICT = contsel,
JOIN = contjoinsel
);

--
-- agtype GIN support
--
CREATE FUNCTION ag_catalog.gin_compare_agtype(text, text)
RETURNS int
AS 'MODULE_PATHNAME'
LANGUAGE C
IMMUTABLE
STRICT
PARALLEL SAFE;

CREATE FUNCTION gin_extract_agtype(agtype, internal)
RETURNS internal
AS 'MODULE_PATHNAME'
LANGUAGE C
IMMUTABLE
STRICT
PARALLEL SAFE;

CREATE FUNCTION ag_catalog.gin_extract_agtype_query(agtype, internal, int2,
internal, internal)
RETURNS internal
AS 'MODULE_PATHNAME'
LANGUAGE C
IMMUTABLE
STRICT
PARALLEL SAFE;

CREATE FUNCTION ag_catalog.gin_consistent_agtype(internal, int2, agtype, int4,
internal, internal)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE C
IMMUTABLE
STRICT
PARALLEL SAFE;

CREATE FUNCTION ag_catalog.gin_triconsistent_agtype(internal, int2, agtype, int4,
internal, internal, internal)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE C
IMMUTABLE
STRICT
PARALLEL SAFE;

CREATE OPERATOR CLASS ag_catalog.gin_agtype_ops
DEFAULT FOR TYPE agtype USING gin AS
OPERATOR 7 @>,
OPERATOR 9 ?(agtype, text),
OPERATOR 10 ?|(agtype, text[]),
OPERATOR 11 ?&(agtype, text[]),
FUNCTION 1 ag_catalog.gin_compare_agtype(text,text),
FUNCTION 2 ag_catalog.gin_extract_agtype(agtype, internal),
FUNCTION 3 ag_catalog.gin_extract_agtype_query(agtype, internal, int2,
internal, internal),
FUNCTION 4 ag_catalog.gin_consistent_agtype(internal, int2, agtype, int4,
internal, internal),
FUNCTION 6 ag_catalog.gin_triconsistent_agtype(internal, int2, agtype, int4,
internal, internal, internal),
STORAGE text;

--
-- graph id conversion function
--
@@ -3325,13 +3476,6 @@ RETURNS NULL ON NULL INPUT
PARALLEL SAFE
AS 'MODULE_PATHNAME';

CREATE FUNCTION ag_catalog._property_constraint_check(agtype, agtype)
RETURNS boolean
LANGUAGE c
STABLE
PARALLEL SAFE
AS 'MODULE_PATHNAME';

--
-- String functions
--
@@ -875,7 +875,7 @@ SELECT 3 % '3.14::numeric'::agtype;
(1 row)

--
-- Test overloaded agytype any functions and operators for NULL input
-- Test overloaded agytype any functions and operators for NULL input
-- +, -, *, /, %, =, <>, <, >, <=, >=
-- These should all return null
SELECT agtype_any_add('null'::agtype, 1);
@@ -2486,6 +2486,102 @@ SELECT age_end_id(agtype_in('null'));

(1 row)

SELECT agtype_contains('{"id": 1}','{"id": 1}');
agtype_contains
-----------------
t
(1 row)

SELECT agtype_contains('{"id": 1}','{"id": 2}');
agtype_contains
-----------------
f
(1 row)

SELECT '{"id": 1}'::agtype @> '{"id": 1}';
?column?
----------
t
(1 row)

SELECT '{"id": 1}'::agtype @> '{"id": 2}';
?column?
----------
f
(1 row)

SELECT agtype_exists('{"id": 1}','id');
agtype_exists
---------------
t
(1 row)

SELECT agtype_exists('{"id": 1}','not_id');
agtype_exists
---------------
f
(1 row)

SELECT '{"id": 1}'::agtype ? 'id';
?column?
----------
t
(1 row)

SELECT '{"id": 1}'::agtype ? 'not_id';
?column?
----------
f
(1 row)

SELECT agtype_exists_any('{"id": 1}', array['id']);
agtype_exists_any
-------------------
t
(1 row)

SELECT agtype_exists_any('{"id": 1}', array['not_id']);
agtype_exists_any
-------------------
f
(1 row)

SELECT '{"id": 1}'::agtype ?| array['id'];
?column?
----------
t
(1 row)

SELECT '{"id": 1}'::agtype ?| array['not_id'];
?column?
----------
f
(1 row)

SELECT agtype_exists_all('{"id": 1}', array['id']);
agtype_exists_all
-------------------
t
(1 row)

SELECT agtype_exists_all('{"id": 1}', array['not_id']);
agtype_exists_all
-------------------
f
(1 row)

SELECT '{"id": 1}'::agtype ?& array['id'];
?column?
----------
t
(1 row)

SELECT '{"id": 1}'::agtype ?& array['not_id'];
?column?
----------
f
(1 row)

--
-- Test STARTS WITH, ENDS WITH, and CONTAINS
--

0 comments on commit 6279c10

Please sign in to comment.