diff --git a/src/backend/parser/parse_graphtable.c b/src/backend/parser/parse_graphtable.c index bf805b4beb6..136d87e61cf 100644 --- a/src/backend/parser/parse_graphtable.c +++ b/src/backend/parser/parse_graphtable.c @@ -225,11 +225,6 @@ transformGraphElementPattern(ParseState *pstate, GraphElementPattern *gep) { GraphTableParseState *gpstate = pstate->p_graph_table_pstate; - if (gep->kind != VERTEX_PATTERN && !IS_EDGE_PATTERN(gep->kind)) - ereport(ERROR, - errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("unsupported element pattern kind: \"%s\"", get_gep_kind_name(gep->kind))); - if (gep->quantifier) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -253,10 +248,53 @@ static Node * transformPathTerm(ParseState *pstate, List *path_term) { List *result = NIL; + GraphElementPattern *prev_gep = NULL; foreach_node(GraphElementPattern, gep, path_term) + { + if (gep->kind != VERTEX_PATTERN && !IS_EDGE_PATTERN(gep->kind)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("unsupported element pattern kind: \"%s\"", get_gep_kind_name(gep->kind)), + parser_errposition(pstate, gep->location))); + + if (IS_EDGE_PATTERN(gep->kind)) + { + if (!prev_gep) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("path pattern cannot start with an edge pattern"), + parser_errposition(pstate, gep->location))); + else if (prev_gep->kind != VERTEX_PATTERN) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("edge pattern must be preceded by a vertex pattern"), + parser_errposition(pstate, gep->location))); + } + else + { + if (prev_gep && !IS_EDGE_PATTERN(prev_gep->kind)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("adjacent vertex patterns are not supported"), + parser_errposition(pstate, gep->location))); + } + result = lappend(result, transformGraphElementPattern(pstate, gep)); + prev_gep = gep; + } + + /* Path pattern should have at least one element pattern. */ + Assert(prev_gep); + + if (IS_EDGE_PATTERN(prev_gep->kind)) + { + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("path pattern cannot end with an edge pattern"), + parser_errposition(pstate, prev_gep->location))); + } return (Node *) result; } diff --git a/src/backend/rewrite/rewriteGraphTable.c b/src/backend/rewrite/rewriteGraphTable.c index 9c293586e44..2c3199d3230 100644 --- a/src/backend/rewrite/rewriteGraphTable.c +++ b/src/backend/rewrite/rewriteGraphTable.c @@ -300,6 +300,11 @@ generate_queries_for_path_pattern(RangeTblEntry *rte, List *path_pattern) errmsg("an edge cannot connect more than two vertexes even in a cyclic pattern")); prev_pf->src_pf = pf; } + else + { + Assert(prev_pf->kind == VERTEX_PATTERN); + Assert(IS_EDGE_PATTERN(pf->kind)); + } if (pf->kind == EDGE_PATTERN_RIGHT || pf->kind == EDGE_PATTERN_ANY) { @@ -319,6 +324,11 @@ generate_queries_for_path_pattern(RangeTblEntry *rte, List *path_pattern) errmsg("an edge cannot connect more than two vertexes even in a cyclic pattern")); pf->dest_pf = prev_pf; } + else + { + Assert(pf->kind == VERTEX_PATTERN); + Assert(IS_EDGE_PATTERN(prev_pf->kind)); + } } prev_pf = pf; diff --git a/src/test/regress/expected/graph_table.out b/src/test/regress/expected/graph_table.out index 27c81ec6e42..2fc5a2e8c5a 100644 --- a/src/test/regress/expected/graph_table.out +++ b/src/test/regress/expected/graph_table.out @@ -103,6 +103,8 @@ SELECT customer_name FROM GRAPH_TABLE (myshop MATCH (c IS customers)->{1,2}(o IS ERROR: element pattern quantifier is not supported SELECT * FROM GRAPH_TABLE (myshop MATCH ((c IS customers)->(o IS orders)) COLUMNS (c.name)); ERROR: unsupported element pattern kind: "nested path pattern" +LINE 1: SELECT * FROM GRAPH_TABLE (myshop MATCH ((c IS customers)->(... + ^ -- a property graph can be referenced only from within GRAPH_TABLE clause. SELECT * FROM myshop; -- error ERROR: cannot open relation "myshop" @@ -420,6 +422,23 @@ SELECT * FROM GRAPH_TABLE (myshop MATCH (c IS customers WHERE c.* IS NOT NULL)-[ ERROR: "*" not allowed here LINE 1: ...M GRAPH_TABLE (myshop MATCH (c IS customers WHERE c.* IS NOT... ^ +-- consecutive element patterns with same kind +SELECT * FROM GRAPH_TABLE (g1 MATCH ()() COLUMNS (1 as one)); +ERROR: adjacent vertex patterns are not supported +LINE 1: SELECT * FROM GRAPH_TABLE (g1 MATCH ()() COLUMNS (1 as one))... + ^ +SELECT * FROM GRAPH_TABLE (g1 MATCH -> COLUMNS (1 AS one)); +ERROR: path pattern cannot start with an edge pattern +LINE 1: SELECT * FROM GRAPH_TABLE (g1 MATCH -> COLUMNS (1 AS one)); + ^ +SELECT * FROM GRAPH_TABLE (g1 MATCH ()-[]- COLUMNS (1 AS one)); +ERROR: path pattern cannot end with an edge pattern +LINE 1: SELECT * FROM GRAPH_TABLE (g1 MATCH ()-[]- COLUMNS (1 AS one... + ^ +SELECT * FROM GRAPH_TABLE (g1 MATCH ()-> ->() COLUMNS (1 AS one)); +ERROR: edge pattern must be preceded by a vertex pattern +LINE 1: SELECT * FROM GRAPH_TABLE (g1 MATCH ()-> ->() COLUMNS (1 AS ... + ^ -- select all the properties across all the labels associated with a given type -- of graph element SELECT * FROM GRAPH_TABLE (g1 MATCH (src)-[conn]->(dest) COLUMNS (src.vname AS svname, conn.ename AS cename, dest.vname AS dvname, src.vprop1 AS svp1, src.vprop2 AS svp2, src.lprop1 AS slp1, dest.vprop1 AS dvp1, dest.vprop2 AS dvp2, dest.lprop1 AS dlp1, conn.eprop1 AS cep1, conn.lprop2 AS clp2)); diff --git a/src/test/regress/sql/graph_table.sql b/src/test/regress/sql/graph_table.sql index 6d2b08b997b..7c2438e84a3 100644 --- a/src/test/regress/sql/graph_table.sql +++ b/src/test/regress/sql/graph_table.sql @@ -289,6 +289,12 @@ SELECT * FROM GRAPH_TABLE (g1 MATCH (src IS el1 | vl1)-[conn]->(dest) COLUMNS (c SELECT * FROM GRAPH_TABLE (myshop MATCH (c IS customers WHERE c.address = 'US')-[IS customer_orders]->(o IS orders) COLUMNS (c.*)); -- star anywhere else is not allowed as a property reference SELECT * FROM GRAPH_TABLE (myshop MATCH (c IS customers WHERE c.* IS NOT NULL)-[IS customer_orders]->(o IS orders) COLUMNS (c.name)); +-- consecutive element patterns with same kind +SELECT * FROM GRAPH_TABLE (g1 MATCH ()() COLUMNS (1 as one)); +SELECT * FROM GRAPH_TABLE (g1 MATCH -> COLUMNS (1 AS one)); +SELECT * FROM GRAPH_TABLE (g1 MATCH ()-[]- COLUMNS (1 AS one)); +SELECT * FROM GRAPH_TABLE (g1 MATCH ()-> ->() COLUMNS (1 AS one)); + -- select all the properties across all the labels associated with a given type -- of graph element