Skip to content

Commit cc6eaad

Browse files
Add support for operators in cypher query (#2172)
- Fixed some operator signatures in .sql - Added support for PG operators in cypher. Some hardcoded operators are removed, since they are now covered by the general operator handling. - Added full typecast syntax that allows for type modifiers. - These changes also improve interoperability with other extensions, as reflected in the regression tests. - Added a new function to check if graph_oid exists.
1 parent 8262938 commit cc6eaad

24 files changed

Lines changed: 1297 additions & 373 deletions

age--1.5.0--y.y.y.sql

Lines changed: 112 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ CREATE OPERATOR @>> (
6060
RIGHTARG = agtype,
6161
FUNCTION = ag_catalog.agtype_contains_top_level,
6262
COMMUTATOR = '<<@',
63-
RESTRICT = contsel,
64-
JOIN = contjoinsel
63+
RESTRICT = matchingsel,
64+
JOIN = matchingjoinsel
6565
);
6666

6767
CREATE FUNCTION ag_catalog.agtype_contained_by_top_level(agtype, agtype)
@@ -77,17 +77,114 @@ CREATE OPERATOR <<@ (
7777
RIGHTARG = agtype,
7878
FUNCTION = ag_catalog.agtype_contained_by_top_level,
7979
COMMUTATOR = '@>>',
80-
RESTRICT = contsel,
81-
JOIN = contjoinsel
80+
RESTRICT = matchingsel,
81+
JOIN = matchingjoinsel
8282
);
8383

84+
/*
85+
* We have to drop and recreate the operators, because
86+
* commutator is not modifiable using ALTER OPERATOR.
87+
*/
88+
ALTER EXTENSION age
89+
DROP OPERATOR ? (agtype, agtype);
90+
ALTER EXTENSION age
91+
DROP OPERATOR ? (agtype, text);
92+
ALTER EXTENSION age
93+
DROP OPERATOR ?| (agtype, agtype);
94+
ALTER EXTENSION age
95+
DROP OPERATOR ?| (agtype, text[]);
96+
ALTER EXTENSION age
97+
DROP OPERATOR ?& (agtype, agtype[]);
98+
ALTER EXTENSION age
99+
DROP OPERATOR ?& (agtype, text);
100+
101+
DROP OPERATOR ? (agtype, agtype), ? (agtype, text),
102+
?| (agtype, agtype), ?| (agtype, text[]),
103+
?& (agtype, agtype[]), ?& (agtype, text);
104+
105+
CREATE OPERATOR ? (
106+
LEFTARG = agtype,
107+
RIGHTARG = agtype,
108+
FUNCTION = ag_catalog.agtype_exists_agtype,
109+
RESTRICT = matchingsel,
110+
JOIN = matchingjoinsel
111+
);
112+
113+
CREATE OPERATOR ? (
114+
LEFTARG = agtype,
115+
RIGHTARG = text,
116+
FUNCTION = ag_catalog.agtype_exists,
117+
RESTRICT = matchingsel,
118+
JOIN = matchingjoinsel
119+
);
120+
121+
CREATE OPERATOR ?| (
122+
LEFTARG = agtype,
123+
RIGHTARG = agtype,
124+
FUNCTION = ag_catalog.agtype_exists_any_agtype,
125+
RESTRICT = matchingsel,
126+
JOIN = matchingjoinsel
127+
);
128+
129+
CREATE OPERATOR ?| (
130+
LEFTARG = agtype,
131+
RIGHTARG = text[],
132+
FUNCTION = ag_catalog.agtype_exists_any,
133+
RESTRICT = matchingsel,
134+
JOIN = matchingjoinsel
135+
);
136+
137+
CREATE OPERATOR ?& (
138+
LEFTARG = agtype,
139+
RIGHTARG = agtype,
140+
FUNCTION = ag_catalog.agtype_exists_all_agtype,
141+
RESTRICT = matchingsel,
142+
JOIN = matchingjoinsel
143+
);
144+
145+
CREATE OPERATOR ?& (
146+
LEFTARG = agtype,
147+
RIGHTARG = text[],
148+
FUNCTION = ag_catalog.agtype_exists_all,
149+
RESTRICT = matchingsel,
150+
JOIN = matchingjoinsel
151+
);
152+
153+
ALTER EXTENSION age
154+
ADD OPERATOR ? (agtype, agtype);
155+
ALTER EXTENSION age
156+
ADD OPERATOR ? (agtype, text);
157+
ALTER EXTENSION age
158+
ADD OPERATOR ?| (agtype, agtype);
159+
ALTER EXTENSION age
160+
ADD OPERATOR ?| (agtype, text[]);
161+
ALTER EXTENSION age
162+
ADD OPERATOR ?& (agtype, agtype[]);
163+
ALTER EXTENSION age
164+
ADD OPERATOR ?& (agtype, text);
165+
166+
ALTER OPERATOR @> (agtype, agtype)
167+
SET (RESTRICT = matchingsel, JOIN = matchingjoinsel);
168+
169+
ALTER OPERATOR @> (agtype, agtype)
170+
SET (RESTRICT = matchingsel, JOIN = matchingjoinsel);
171+
172+
ALTER OPERATOR <@ (agtype, agtype)
173+
SET (RESTRICT = matchingsel, JOIN = matchingjoinsel);
174+
175+
ALTER OPERATOR <@ (agtype, agtype)
176+
SET (RESTRICT = matchingsel, JOIN = matchingjoinsel);
177+
84178
/*
85179
* Since there is no option to add or drop operator from class,
86180
* we have to drop and recreate the whole operator class.
87181
* Reference: https://www.postgresql.org/docs/current/sql-alteropclass.html
88182
*/
89183

90-
DROP OPERATOR CLASS ag_catalog.gin_agtype_ops;
184+
ALTER EXTENSION age
185+
DROP OPERATOR CLASS ag_catalog.gin_agtype_ops USING gin;
186+
187+
DROP OPERATOR CLASS ag_catalog.gin_agtype_ops USING gin;
91188

92189
CREATE OPERATOR CLASS ag_catalog.gin_agtype_ops
93190
DEFAULT FOR TYPE agtype USING gin AS
@@ -108,6 +205,9 @@ DEFAULT FOR TYPE agtype USING gin AS
108205
internal, internal, internal),
109206
STORAGE text;
110207

208+
ALTER EXTENSION age
209+
ADD OPERATOR CLASS ag_catalog.gin_agtype_ops USING gin;
210+
111211
-- this function went from variadic "any" to just "any" type
112212
CREATE OR REPLACE FUNCTION ag_catalog.age_tostring("any")
113213
RETURNS agtype
@@ -167,4 +267,10 @@ PARALLEL SAFE
167267
AS 'MODULE_PATHNAME';
168268

169269
CREATE CAST (agtype[] AS agtype)
170-
WITH FUNCTION ag_catalog.agtype_array_to_agtype(agtype[]);
270+
WITH FUNCTION ag_catalog.agtype_array_to_agtype(agtype[]);
271+
272+
CREATE OPERATOR =~ (
273+
LEFTARG = agtype,
274+
RIGHTARG = agtype,
275+
FUNCTION = ag_catalog.age_eq_tilde
276+
);

regress/expected/cypher_match.out

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2407,22 +2407,22 @@ SELECT * FROM cypher('cypher_match', $$ MATCH (a {name:a.name}) MATCH (a {age:a.
24072407
SELECT * FROM cypher('cypher_match', $$ MATCH p=(a)-[u {relationship: u.relationship}]->(b) RETURN p $$) as (a agtype);
24082408
a
24092409
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2410-
[{"id": 281474976710661, "label": "", "properties": {"age": 4, "name": "T"}}::vertex, {"id": 4785074604081153, "label": "knows", "end_id": 281474976710666, "start_id": 281474976710661, "properties": {"years": 3, "relationship": "friends"}}::edge, {"id": 281474976710666, "label": "", "properties": {"age": 6}}::vertex]::path
24112410
[{"id": 281474976710659, "label": "", "properties": {"age": 3, "name": "orphan"}}::vertex, {"id": 4785074604081154, "label": "knows", "end_id": 281474976710666, "start_id": 281474976710659, "properties": {"years": 4, "relationship": "enemies"}}::edge, {"id": 281474976710666, "label": "", "properties": {"age": 6}}::vertex]::path
2411+
[{"id": 281474976710661, "label": "", "properties": {"age": 4, "name": "T"}}::vertex, {"id": 4785074604081153, "label": "knows", "end_id": 281474976710666, "start_id": 281474976710661, "properties": {"years": 3, "relationship": "friends"}}::edge, {"id": 281474976710666, "label": "", "properties": {"age": 6}}::vertex]::path
24122412
(2 rows)
24132413

24142414
SELECT * FROM cypher('cypher_match', $$ MATCH p=(a)-[u {relationship: u.relationship, years: u.years}]->(b) RETURN p $$) as (a agtype);
24152415
a
24162416
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2417-
[{"id": 281474976710661, "label": "", "properties": {"age": 4, "name": "T"}}::vertex, {"id": 4785074604081153, "label": "knows", "end_id": 281474976710666, "start_id": 281474976710661, "properties": {"years": 3, "relationship": "friends"}}::edge, {"id": 281474976710666, "label": "", "properties": {"age": 6}}::vertex]::path
24182417
[{"id": 281474976710659, "label": "", "properties": {"age": 3, "name": "orphan"}}::vertex, {"id": 4785074604081154, "label": "knows", "end_id": 281474976710666, "start_id": 281474976710659, "properties": {"years": 4, "relationship": "enemies"}}::edge, {"id": 281474976710666, "label": "", "properties": {"age": 6}}::vertex]::path
2418+
[{"id": 281474976710661, "label": "", "properties": {"age": 4, "name": "T"}}::vertex, {"id": 4785074604081153, "label": "knows", "end_id": 281474976710666, "start_id": 281474976710661, "properties": {"years": 3, "relationship": "friends"}}::edge, {"id": 281474976710666, "label": "", "properties": {"age": 6}}::vertex]::path
24192419
(2 rows)
24202420

24212421
SELECT * FROM cypher('cypher_match', $$ MATCH p=(a {name:a.name})-[u {relationship: u.relationship}]->(b {age:b.age}) RETURN p $$) as (a agtype);
24222422
a
24232423
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2424-
[{"id": 281474976710661, "label": "", "properties": {"age": 4, "name": "T"}}::vertex, {"id": 4785074604081153, "label": "knows", "end_id": 281474976710666, "start_id": 281474976710661, "properties": {"years": 3, "relationship": "friends"}}::edge, {"id": 281474976710666, "label": "", "properties": {"age": 6}}::vertex]::path
24252424
[{"id": 281474976710659, "label": "", "properties": {"age": 3, "name": "orphan"}}::vertex, {"id": 4785074604081154, "label": "knows", "end_id": 281474976710666, "start_id": 281474976710659, "properties": {"years": 4, "relationship": "enemies"}}::edge, {"id": 281474976710666, "label": "", "properties": {"age": 6}}::vertex]::path
2425+
[{"id": 281474976710661, "label": "", "properties": {"age": 4, "name": "T"}}::vertex, {"id": 4785074604081153, "label": "knows", "end_id": 281474976710666, "start_id": 281474976710661, "properties": {"years": 3, "relationship": "friends"}}::edge, {"id": 281474976710666, "label": "", "properties": {"age": 6}}::vertex]::path
24262426
(2 rows)
24272427

24282428
SELECT * FROM cypher('cypher_match', $$ CREATE () WITH * MATCH (x{n0:x.n1}) RETURN 0 $$) as (a agtype);

regress/expected/cypher_vle.out

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -726,8 +726,8 @@ SELECT prepend_node('list01', 'b');
726726
SELECT * FROM show_list_use_vle('list01');
727727
node
728728
-----------------------------------------------------------------------------------
729-
{"id": 1407374883553281, "label": "node", "properties": {"content": "a"}}::vertex
730729
{"id": 1407374883553282, "label": "node", "properties": {"content": "b"}}::vertex
730+
{"id": 1407374883553281, "label": "node", "properties": {"content": "a"}}::vertex
731731
(2 rows)
732732

733733
-- prepend a node 'c'
@@ -741,9 +741,9 @@ SELECT prepend_node('list01', 'c');
741741
SELECT * FROM show_list_use_vle('list01');
742742
node
743743
-----------------------------------------------------------------------------------
744-
{"id": 1407374883553281, "label": "node", "properties": {"content": "a"}}::vertex
745-
{"id": 1407374883553282, "label": "node", "properties": {"content": "b"}}::vertex
746744
{"id": 1407374883553283, "label": "node", "properties": {"content": "c"}}::vertex
745+
{"id": 1407374883553282, "label": "node", "properties": {"content": "b"}}::vertex
746+
{"id": 1407374883553281, "label": "node", "properties": {"content": "a"}}::vertex
747747
(3 rows)
748748

749749
DROP FUNCTION show_list_use_vle;

0 commit comments

Comments
 (0)