Add fast functions for checking edge uniqueness (#2227)
Added fast functions for checking edge uniqueness. This will help
improve performance for MATCH queries with paths longer than 3 but
less than 11. The normal edge uniqueness function will deal with
any path 11 and over.
modified: age--1.6.0--y.y.y.sql
modified: sql/agtype_graphid.sql
modified: src/backend/parser/cypher_clause.c
modified: src/backend/utils/adt/age_vle.c
diff --git a/age--1.6.0--y.y.y.sql b/age--1.6.0--y.y.y.sql
index d781be9..2d693a4 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 4e05943..0887db8 100644
--- a/sql/agtype_graphid.sql
+++ b/sql/agtype_graphid.sql
@@ -77,6 +77,27 @@
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 93e710a..468706a 100644
--- a/src/backend/parser/cypher_clause.c
+++ b/src/backend/parser/cypher_clause.c
@@ -3276,13 +3276,13 @@
{
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 @@
}
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 f0adab2..f9e4c70 100644
--- a/src/backend/utils/adt/age_vle.c
+++ b/src/backend/utils/adt/age_vle.c
@@ -2427,6 +2427,55 @@
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.