diff --git a/age--1.6.0--y.y.y.sql b/age--1.6.0--y.y.y.sql index d781be986..2d693a433 100644 --- a/age--1.6.0--y.y.y.sql +++ b/age--1.6.0--y.y.y.sql @@ -31,3 +31,23 @@ --* file. We need to keep the order of these changes. --* REMOVE ALL LINES ABOVE, and this one, that start with --* +CREATE FUNCTION ag_catalog._ag_enforce_edge_uniqueness2(graphid, graphid) + RETURNS bool + LANGUAGE c + STABLE +PARALLEL SAFE +as 'MODULE_PATHNAME'; + +CREATE FUNCTION ag_catalog._ag_enforce_edge_uniqueness3(graphid, graphid, graphid) + RETURNS bool + LANGUAGE c + STABLE +PARALLEL SAFE +as 'MODULE_PATHNAME'; + +CREATE FUNCTION ag_catalog._ag_enforce_edge_uniqueness4(graphid, graphid, graphid, graphid) + RETURNS bool + LANGUAGE c + STABLE +PARALLEL SAFE +as 'MODULE_PATHNAME'; diff --git a/sql/agtype_graphid.sql b/sql/agtype_graphid.sql index 4e05943ae..0887db8a9 100644 --- a/sql/agtype_graphid.sql +++ b/sql/agtype_graphid.sql @@ -77,6 +77,27 @@ CALLED ON NULL INPUT PARALLEL SAFE AS 'MODULE_PATHNAME'; +CREATE FUNCTION ag_catalog._ag_enforce_edge_uniqueness2(graphid, graphid) + RETURNS bool + LANGUAGE c + STABLE +PARALLEL SAFE +as 'MODULE_PATHNAME'; + +CREATE FUNCTION ag_catalog._ag_enforce_edge_uniqueness3(graphid, graphid, graphid) + RETURNS bool + LANGUAGE c + STABLE +PARALLEL SAFE +as 'MODULE_PATHNAME'; + +CREATE FUNCTION ag_catalog._ag_enforce_edge_uniqueness4(graphid, graphid, graphid, graphid) + RETURNS bool + LANGUAGE c + STABLE +PARALLEL SAFE +as 'MODULE_PATHNAME'; + CREATE FUNCTION ag_catalog._ag_enforce_edge_uniqueness(VARIADIC "any") RETURNS bool LANGUAGE c diff --git a/src/backend/parser/cypher_clause.c b/src/backend/parser/cypher_clause.c index 93e710ab4..468706a87 100644 --- a/src/backend/parser/cypher_clause.c +++ b/src/backend/parser/cypher_clause.c @@ -3276,13 +3276,13 @@ static FuncCall *prevent_duplicate_edges(cypher_parsestate *cpstate, { List *edges = NIL; ListCell *lc; - List *qualified_function_name; - String *ag_catalog, *edge_fn; + List *qualified_function_name = NULL; + String *ag_catalog; + String *edge_fn = NULL; + bool is_vle_edge = false; + int nentities = list_length(entities); ag_catalog = makeString("ag_catalog"); - edge_fn = makeString("_ag_enforce_edge_uniqueness"); - - qualified_function_name = list_make2(ag_catalog, edge_fn); /* iterate through each entity, collecting the access node for each edge */ foreach (lc, entities) @@ -3298,10 +3298,33 @@ static FuncCall *prevent_duplicate_edges(cypher_parsestate *cpstate, } else if (entity->type == ENT_VLE_EDGE) { + is_vle_edge = true; edges = lappend(edges, entity->expr); } } + if (!is_vle_edge && (nentities >= 5 && nentities <= 9)) + { + if (nentities == 5) + { + edge_fn = makeString("_ag_enforce_edge_uniqueness2"); + } + else if (nentities == 7) + { + edge_fn = makeString("_ag_enforce_edge_uniqueness3"); + } + else + { + edge_fn = makeString("_ag_enforce_edge_uniqueness4"); + } + } + else + { + edge_fn = makeString("_ag_enforce_edge_uniqueness"); + } + + qualified_function_name = list_make2(ag_catalog, edge_fn); + return makeFuncCall(qualified_function_name, edges, COERCE_SQL_SYNTAX, -1); } diff --git a/src/backend/utils/adt/age_vle.c b/src/backend/utils/adt/age_vle.c index f0adab2e9..f9e4c70b8 100644 --- a/src/backend/utils/adt/age_vle.c +++ b/src/backend/utils/adt/age_vle.c @@ -2427,6 +2427,55 @@ Datum age_build_vle_match_edge(PG_FUNCTION_ARGS) PG_RETURN_POINTER(agtype_value_to_agtype(result.res)); } +PG_FUNCTION_INFO_V1(_ag_enforce_edge_uniqueness2); + +Datum _ag_enforce_edge_uniqueness2(PG_FUNCTION_ARGS) +{ + graphid gid1 = AG_GETARG_GRAPHID(0); + graphid gid2 = AG_GETARG_GRAPHID(1); + + if (gid1 == gid2) + { + PG_RETURN_BOOL(false); + } + + PG_RETURN_BOOL(true); +} + +PG_FUNCTION_INFO_V1(_ag_enforce_edge_uniqueness3); + +Datum _ag_enforce_edge_uniqueness3(PG_FUNCTION_ARGS) +{ + graphid gid1 = AG_GETARG_GRAPHID(0); + graphid gid2 = AG_GETARG_GRAPHID(1); + graphid gid3 = AG_GETARG_GRAPHID(2); + + if (gid1 == gid2 || gid1 == gid3 || gid2 == gid3) + { + PG_RETURN_BOOL(false); + } + + PG_RETURN_BOOL(true); +} + +PG_FUNCTION_INFO_V1(_ag_enforce_edge_uniqueness4); + +Datum _ag_enforce_edge_uniqueness4(PG_FUNCTION_ARGS) +{ + graphid gid1 = AG_GETARG_GRAPHID(0); + graphid gid2 = AG_GETARG_GRAPHID(1); + graphid gid3 = AG_GETARG_GRAPHID(2); + graphid gid4 = AG_GETARG_GRAPHID(3); + + if (gid1 == gid2 || gid1 == gid3 || gid1 == gid4 || + gid2 == gid3 || gid2 == gid4 || gid3 == gid4) + { + PG_RETURN_BOOL(false); + } + + PG_RETURN_BOOL(true); +} + /* * This function checks the edges in a MATCH clause to see if they are unique or * not. Filters out all the paths where the edge uniques rules are not met.