Skip to content

Commit 1277b82

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 1251096 commit 1277b82

24 files changed

+1297
-373
lines changed

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

Lines changed: 112 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ CREATE OPERATOR @>> (
4141
RIGHTARG = agtype,
4242
FUNCTION = ag_catalog.agtype_contains_top_level,
4343
COMMUTATOR = '<<@',
44-
RESTRICT = contsel,
45-
JOIN = contjoinsel
44+
RESTRICT = matchingsel,
45+
JOIN = matchingjoinsel
4646
);
4747

4848
CREATE FUNCTION ag_catalog.agtype_contained_by_top_level(agtype, agtype)
@@ -58,17 +58,114 @@ CREATE OPERATOR <<@ (
5858
RIGHTARG = agtype,
5959
FUNCTION = ag_catalog.agtype_contained_by_top_level,
6060
COMMUTATOR = '@>>',
61-
RESTRICT = contsel,
62-
JOIN = contjoinsel
61+
RESTRICT = matchingsel,
62+
JOIN = matchingjoinsel
6363
);
6464

65+
/*
66+
* We have to drop and recreate the operators, because
67+
* commutator is not modifiable using ALTER OPERATOR.
68+
*/
69+
ALTER EXTENSION age
70+
DROP OPERATOR ? (agtype, agtype);
71+
ALTER EXTENSION age
72+
DROP OPERATOR ? (agtype, text);
73+
ALTER EXTENSION age
74+
DROP OPERATOR ?| (agtype, agtype);
75+
ALTER EXTENSION age
76+
DROP OPERATOR ?| (agtype, text[]);
77+
ALTER EXTENSION age
78+
DROP OPERATOR ?& (agtype, agtype[]);
79+
ALTER EXTENSION age
80+
DROP OPERATOR ?& (agtype, text);
81+
82+
DROP OPERATOR ? (agtype, agtype), ? (agtype, text),
83+
?| (agtype, agtype), ?| (agtype, text[]),
84+
?& (agtype, agtype[]), ?& (agtype, text);
85+
86+
CREATE OPERATOR ? (
87+
LEFTARG = agtype,
88+
RIGHTARG = agtype,
89+
FUNCTION = ag_catalog.agtype_exists_agtype,
90+
RESTRICT = matchingsel,
91+
JOIN = matchingjoinsel
92+
);
93+
94+
CREATE OPERATOR ? (
95+
LEFTARG = agtype,
96+
RIGHTARG = text,
97+
FUNCTION = ag_catalog.agtype_exists,
98+
RESTRICT = matchingsel,
99+
JOIN = matchingjoinsel
100+
);
101+
102+
CREATE OPERATOR ?| (
103+
LEFTARG = agtype,
104+
RIGHTARG = agtype,
105+
FUNCTION = ag_catalog.agtype_exists_any_agtype,
106+
RESTRICT = matchingsel,
107+
JOIN = matchingjoinsel
108+
);
109+
110+
CREATE OPERATOR ?| (
111+
LEFTARG = agtype,
112+
RIGHTARG = text[],
113+
FUNCTION = ag_catalog.agtype_exists_any,
114+
RESTRICT = matchingsel,
115+
JOIN = matchingjoinsel
116+
);
117+
118+
CREATE OPERATOR ?& (
119+
LEFTARG = agtype,
120+
RIGHTARG = agtype,
121+
FUNCTION = ag_catalog.agtype_exists_all_agtype,
122+
RESTRICT = matchingsel,
123+
JOIN = matchingjoinsel
124+
);
125+
126+
CREATE OPERATOR ?& (
127+
LEFTARG = agtype,
128+
RIGHTARG = text[],
129+
FUNCTION = ag_catalog.agtype_exists_all,
130+
RESTRICT = matchingsel,
131+
JOIN = matchingjoinsel
132+
);
133+
134+
ALTER EXTENSION age
135+
ADD OPERATOR ? (agtype, agtype);
136+
ALTER EXTENSION age
137+
ADD OPERATOR ? (agtype, text);
138+
ALTER EXTENSION age
139+
ADD OPERATOR ?| (agtype, agtype);
140+
ALTER EXTENSION age
141+
ADD OPERATOR ?| (agtype, text[]);
142+
ALTER EXTENSION age
143+
ADD OPERATOR ?& (agtype, agtype[]);
144+
ALTER EXTENSION age
145+
ADD OPERATOR ?& (agtype, text);
146+
147+
ALTER OPERATOR @> (agtype, agtype)
148+
SET (RESTRICT = matchingsel, JOIN = matchingjoinsel);
149+
150+
ALTER OPERATOR @> (agtype, agtype)
151+
SET (RESTRICT = matchingsel, JOIN = matchingjoinsel);
152+
153+
ALTER OPERATOR <@ (agtype, agtype)
154+
SET (RESTRICT = matchingsel, JOIN = matchingjoinsel);
155+
156+
ALTER OPERATOR <@ (agtype, agtype)
157+
SET (RESTRICT = matchingsel, JOIN = matchingjoinsel);
158+
65159
/*
66160
* Since there is no option to add or drop operator from class,
67161
* we have to drop and recreate the whole operator class.
68162
* Reference: https://www.postgresql.org/docs/current/sql-alteropclass.html
69163
*/
70164

71-
DROP OPERATOR CLASS ag_catalog.gin_agtype_ops;
165+
ALTER EXTENSION age
166+
DROP OPERATOR CLASS ag_catalog.gin_agtype_ops USING gin;
167+
168+
DROP OPERATOR CLASS ag_catalog.gin_agtype_ops USING gin;
72169

73170
CREATE OPERATOR CLASS ag_catalog.gin_agtype_ops
74171
DEFAULT FOR TYPE agtype USING gin AS
@@ -89,6 +186,9 @@ DEFAULT FOR TYPE agtype USING gin AS
89186
internal, internal, internal),
90187
STORAGE text;
91188

189+
ALTER EXTENSION age
190+
ADD OPERATOR CLASS ag_catalog.gin_agtype_ops USING gin;
191+
92192
-- this function went from variadic "any" to just "any" type
93193
CREATE OR REPLACE FUNCTION ag_catalog.age_tostring("any")
94194
RETURNS agtype
@@ -148,4 +248,10 @@ PARALLEL SAFE
148248
AS 'MODULE_PATHNAME';
149249

150250
CREATE CAST (agtype[] AS agtype)
151-
WITH FUNCTION ag_catalog.agtype_array_to_agtype(agtype[]);
251+
WITH FUNCTION ag_catalog.agtype_array_to_agtype(agtype[]);
252+
253+
CREATE OPERATOR =~ (
254+
LEFTARG = agtype,
255+
RIGHTARG = agtype,
256+
FUNCTION = ag_catalog.age_eq_tilde
257+
);

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)