You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@age.apache.org by jg...@apache.org on 2022/01/27 01:32:24 UTC
[incubator-age] branch master updated: Allow a path of one vertex
This is an automated email from the ASF dual-hosted git repository.
jgemignani pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-age.git
The following commit(s) were added to refs/heads/master by this push:
new 9fdfe40 Allow a path of one vertex
9fdfe40 is described below
commit 9fdfe40f25d665dda603d1fa0ca1eb708baa7540
Author: John Gemignani <jr...@gmail.com>
AuthorDate: Tue Jan 25 15:59:07 2022 -0800
Allow a path of one vertex
Add in the logic to allow a path of one vertex. This will bring AGE
paths in line with others who use the openCypher specification,
namely, Neo4j.
Adjust regression tests.
---
regress/expected/agtype.out | 6 ++----
regress/expected/cypher_create.out | 11 ++++++-----
regress/expected/cypher_match.out | 24 +++++++++++++++++++-----
regress/sql/cypher_create.sql | 2 +-
regress/sql/cypher_match.sql | 2 +-
src/backend/parser/cypher_clause.c | 14 ++++++--------
src/backend/utils/adt/agtype.c | 22 +++++++++++++++-------
7 files changed, 50 insertions(+), 31 deletions(-)
diff --git a/regress/expected/agtype.out b/regress/expected/agtype.out
index 8647055..cada21f 100644
--- a/regress/expected/agtype.out
+++ b/regress/expected/agtype.out
@@ -2378,8 +2378,7 @@ SELECT _agtype_build_path(
_agtype_build_edge('1'::graphid, '2'::graphid, '3'::graphid,
$$label$$, agtype_build_map('id', 2))
);
-ERROR: paths consist of alternating vertices and edges
-HINT: paths require at least 2 vertices and 1 edge
+ERROR: a path is of the form: [vertex, (edge, vertex)*i] where i >= 0
SELECT _agtype_build_path(
_agtype_build_vertex('2'::graphid, $$label_name$$, agtype_build_map()),
_agtype_build_edge('1'::graphid, '2'::graphid, '3'::graphid,
@@ -2388,8 +2387,7 @@ SELECT _agtype_build_path(
_agtype_build_edge('1'::graphid, '4'::graphid, '5'::graphid,
$$label$$, agtype_build_map('id', 2))
);
-ERROR: paths consist of alternating vertices and edges
-HINT: paths require an odd number of elements
+ERROR: a path is of the form: [vertex, (edge, vertex)*i] where i >= 0
SELECT _agtype_build_path(
_agtype_build_vertex('2'::graphid, $$label_name$$, agtype_build_map()),
_agtype_build_edge('1'::graphid, '2'::graphid, '3'::graphid,
diff --git a/regress/expected/cypher_create.out b/regress/expected/cypher_create.out
index c2aeac6..fb92a37 100644
--- a/regress/expected/cypher_create.out
+++ b/regress/expected/cypher_create.out
@@ -518,15 +518,16 @@ $$) as (a agtype);
ERROR: variable b already exists
LINE 1: SELECT * FROM cypher('cypher_create', $$
^
--- Not a valid path
+-- A valid single vertex path
SELECT * FROM cypher('cypher_create', $$
CREATE p=(a)
RETURN p
$$) as (a agtype);
-ERROR: paths consist of alternating vertices and edges.
-LINE 2: CREATE p=(a)
- ^
-HINT: paths require at least 2 vertices and 1 edge
+ a
+------------------------------------------------------------------------
+ [{"id": 281474976710677, "label": "", "properties": {}}::vertex]::path
+(1 row)
+
--CREATE with joins
SELECT *
FROM cypher('cypher_create', $$
diff --git a/regress/expected/cypher_match.out b/regress/expected/cypher_match.out
index e334523..d2d387c 100644
--- a/regress/expected/cypher_match.out
+++ b/regress/expected/cypher_match.out
@@ -528,15 +528,29 @@ ERROR: label vmissing does not exists
LINE 1: SELECT * FROM cypher('cypher_match', $$MATCH (n:vmissing)-[]...
^
--
---Errors
+-- Path of one vertex. This should select 14
--
SELECT * FROM cypher('cypher_match', $$
MATCH p=() RETURN p
$$) AS (p agtype);
-ERROR: paths consist of alternating vertices and edges.
-LINE 2: MATCH p=() RETURN p
- ^
-HINT: paths require at least 2 vertices and 1 edge
+ p
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [{"id": 281474976710657, "label": "", "properties": {"int_key": 1, "map_key": {"key": "value"}, "list_key": [1, 2, 3], "float_key": 3.14, "string_key": "test"}}::vertex]::path
+ [{"id": 281474976710658, "label": "", "properties": {"lst": [1, null, 3.14, "string", {"key": "value"}, []]}}::vertex]::path
+ [{"id": 844424930131969, "label": "v", "properties": {}}::vertex]::path
+ [{"id": 844424930131970, "label": "v", "properties": {"i": 0}}::vertex]::path
+ [{"id": 844424930131971, "label": "v", "properties": {"i": 1}}::vertex]::path
+ [{"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex]::path
+ [{"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex]::path
+ [{"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex]::path
+ [{"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex]::path
+ [{"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex]::path
+ [{"id": 1688849860263939, "label": "v2", "properties": {"id": "end"}}::vertex]::path
+ [{"id": 2251799813685249, "label": "v3", "properties": {"id": "initial"}}::vertex]::path
+ [{"id": 2251799813685250, "label": "v3", "properties": {"id": "middle"}}::vertex]::path
+ [{"id": 2251799813685251, "label": "v3", "properties": {"id": "end"}}::vertex]::path
+(14 rows)
+
--
-- MATCH with WHERE EXISTS(pattern)
--
diff --git a/regress/sql/cypher_create.sql b/regress/sql/cypher_create.sql
index 7a0051b..62b7d16 100644
--- a/regress/sql/cypher_create.sql
+++ b/regress/sql/cypher_create.sql
@@ -231,7 +231,7 @@ SELECT * FROM cypher('cypher_create', $$
CREATE (a)-[b:e_var]->()
$$) as (a agtype);
--- Not a valid path
+-- A valid single vertex path
SELECT * FROM cypher('cypher_create', $$
CREATE p=(a)
RETURN p
diff --git a/regress/sql/cypher_match.sql b/regress/sql/cypher_match.sql
index accf0ed..1ccc316 100644
--- a/regress/sql/cypher_match.sql
+++ b/regress/sql/cypher_match.sql
@@ -290,7 +290,7 @@ SELECT * FROM cypher('cypher_match', $$MATCH (n:e1)-[]-() RETURN n$$) AS (n agty
SELECT * FROM cypher('cypher_match', $$MATCH (n:vmissing)-[]-() RETURN n$$) AS (n agtype);
--
---Errors
+-- Path of one vertex. This should select 14
--
SELECT * FROM cypher('cypher_match', $$
MATCH p=() RETURN p
diff --git a/src/backend/parser/cypher_clause.c b/src/backend/parser/cypher_clause.c
index 784b842..c540237 100644
--- a/src/backend/parser/cypher_clause.c
+++ b/src/backend/parser/cypher_clause.c
@@ -3613,13 +3613,12 @@ transform_match_create_path_variable(cypher_parsestate *cpstate,
List *entity_exprs = NIL;
ListCell *lc;
- if (list_length(entities) < 3)
+ if (list_length(entities) < 1)
{
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("paths consist of alternating vertices and edges."),
- parser_errposition(pstate, path->location),
- errhint("paths require at least 2 vertices and 1 edge")));
+ errmsg("paths require at least 1 vertex"),
+ parser_errposition(pstate, path->location)));
}
// extract the expr for each entity
@@ -4267,13 +4266,12 @@ transform_cypher_create_path(cypher_parsestate *cpstate, List **target_list,
{
TargetEntry *te;
- if (list_length(transformed_path) < 3)
+ if (list_length(transformed_path) < 1)
{
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("paths consist of alternating vertices and edges."),
- parser_errposition(pstate, path->location),
- errhint("paths require at least 2 vertices and 1 edge")));
+ errmsg("paths require at least 1 vertex"),
+ parser_errposition(pstate, path->location)));
}
te = placeholder_target_entry(cpstate, path->var_name);
diff --git a/src/backend/utils/adt/agtype.c b/src/backend/utils/adt/agtype.c
index f1768aa..e90c908 100644
--- a/src/backend/utils/adt/agtype.c
+++ b/src/backend/utils/adt/agtype.c
@@ -1780,20 +1780,18 @@ Datum _agtype_build_path(PG_FUNCTION_ARGS)
/* build argument values to build the object */
nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);
- if (nargs < 3)
+ if (nargs < 1)
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("paths consist of alternating vertices and edges"),
- errhint("paths require at least 2 vertices and 1 edge")));
+ errmsg("paths require at least 1 vertex")));
}
if (nargs % 2 == 0)
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("paths consist of alternating vertices and edges"),
- errhint("paths require an odd number of elements")));
+ errmsg("a path is of the form: [vertex, (edge, vertex)*i] where i >= 0")));
}
/*
@@ -1935,10 +1933,20 @@ Datum make_path(List *path)
result.res = push_agtype_value(&result.parse_state, WAGT_BEGIN_ARRAY, NULL);
- if (list_length(path) < 3 || list_length(path) % 2 != 1)
+ if (list_length(path) < 1)
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("paths require at least 1 vertex")));
+ }
+
+ if (list_length(path) % 2 != 1)
+ {
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("path list is not a valid path")));
+ errmsg("a path is of the form: [vertex, (edge, vertex)*i] where i >= 0")));
+ }
+
foreach (lc, path)
{