This is an automated email from the ASF dual-hosted git repository.
joshinnis 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 9b89a31 Implement Label Function
9b89a31 is described below
commit 9b89a311eb59d51fd8cc2f0798ad895c7594afbd
Author: Josh Innis <[email protected]>
AuthorDate: Fri Apr 16 10:19:51 2021 -0700
Implement Label Function
Implements the label function which returns
the label of the given vertex or edge.
---
age--0.4.0.sql | 8 ++++++
regress/expected/expr.out | 63 ++++++++++++++++++++++++++++++++++++++++++
regress/sql/expr.sql | 28 +++++++++++++++++++
src/backend/utils/adt/agtype.c | 44 +++++++++++++++++++++++++++++
4 files changed, 143 insertions(+)
diff --git a/age--0.4.0.sql b/age--0.4.0.sql
index 1280d8c..907ad68 100644
--- a/age--0.4.0.sql
+++ b/age--0.4.0.sql
@@ -3213,6 +3213,14 @@ STABLE
PARALLEL SAFE
AS 'MODULE_PATHNAME';
+CREATE FUNCTION ag_catalog.age_label(agtype)
+RETURNS agtype
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
CREATE FUNCTION ag_catalog._property_constraint_check(agtype, agtype)
RETURNS boolean
LANGUAGE c
diff --git a/regress/expected/expr.out b/regress/expected/expr.out
index 9ad76eb..384bff3 100644
--- a/regress/expected/expr.out
+++ b/regress/expected/expr.out
@@ -1737,6 +1737,69 @@ ERROR: function ag_catalog.age_type() does not exist
LINE 2: RETURN type()
^
HINT: No function matches the given name and argument types. You might need
to add explicit type casts.
+-- label ()
+SELECT * FROM cypher('expr', $$
+ MATCH (v) RETURN label(v)
+$$) AS (label agtype);
+ label
+-------
+ "v"
+ "v"
+ "v"
+ "v1"
+ "v1"
+ "v1"
+(6 rows)
+
+SELECT * FROM cypher('expr', $$
+ MATCH ()-[e]->() RETURN label(e)
+$$) AS (label agtype);
+ label
+-------
+ "e1"
+ "e1"
+(2 rows)
+
+SELECT * FROM cypher('expr', $$
+ RETURN label({id: 0, label: 'typecast', properties: {}}::vertex)
+$$) AS (label agtype);
+ label
+------------
+ "typecast"
+(1 row)
+
+-- return NULL
+SELECT * FROM cypher('expr', $$
+ RETURN label(NULL)
+$$) AS (label agtype);
+ label
+-------
+
+(1 row)
+
+SELECT ag_catalog.age_label(NULL);
+ age_label
+-----------
+
+(1 row)
+
+-- should error
+SELECT * FROM cypher('expr', $$
+ MATCH p=()-[]->() RETURN label(p)
+$$) AS (label agtype);
+ERROR: label() argument must resolve to an edge or vertex
+SELECT * FROM cypher('expr', $$
+ RETURN label(1)
+$$) AS (label agtype);
+ERROR: label() argument must resolve to an edge or vertex
+SELECT * FROM cypher('expr', $$
+ MATCH (n) RETURN label([n])
+$$) AS (label agtype);
+ERROR: label() argument must resolve to an edge or vertex
+SELECT * FROM cypher('expr', $$
+ RETURN label({id: 0, label: 'failed', properties: {}})
+$$) AS (label agtype);
+ERROR: label() argument must resolve to an edge or vertex
-- timestamp() can't be done as it will always have a different value
-- size() of a string
SELECT * FROM cypher('expr', $$
diff --git a/regress/sql/expr.sql b/regress/sql/expr.sql
index 85f8403..41cee8e 100644
--- a/regress/sql/expr.sql
+++ b/regress/sql/expr.sql
@@ -817,6 +817,34 @@ $$) AS (type agtype);
SELECT * FROM cypher('expr', $$
RETURN type()
$$) AS (type agtype);
+-- label ()
+SELECT * FROM cypher('expr', $$
+ MATCH (v) RETURN label(v)
+$$) AS (label agtype);
+SELECT * FROM cypher('expr', $$
+ MATCH ()-[e]->() RETURN label(e)
+$$) AS (label agtype);
+SELECT * FROM cypher('expr', $$
+ RETURN label({id: 0, label: 'typecast', properties: {}}::vertex)
+$$) AS (label agtype);
+-- return NULL
+SELECT * FROM cypher('expr', $$
+ RETURN label(NULL)
+$$) AS (label agtype);
+SELECT ag_catalog.age_label(NULL);
+-- should error
+SELECT * FROM cypher('expr', $$
+ MATCH p=()-[]->() RETURN label(p)
+$$) AS (label agtype);
+SELECT * FROM cypher('expr', $$
+ RETURN label(1)
+$$) AS (label agtype);
+SELECT * FROM cypher('expr', $$
+ MATCH (n) RETURN label([n])
+$$) AS (label agtype);
+SELECT * FROM cypher('expr', $$
+ RETURN label({id: 0, label: 'failed', properties: {}})
+$$) AS (label agtype);
-- timestamp() can't be done as it will always have a different value
-- size() of a string
SELECT * FROM cypher('expr', $$
diff --git a/src/backend/utils/adt/agtype.c b/src/backend/utils/adt/agtype.c
index 35d4ad5..8c0c7fe 100644
--- a/src/backend/utils/adt/agtype.c
+++ b/src/backend/utils/adt/agtype.c
@@ -4687,6 +4687,50 @@ Datum age_exists(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(true);
}
+PG_FUNCTION_INFO_V1(age_label);
+/*
+ * Executor function for label(edge/vertex).
+ */
+Datum age_label(PG_FUNCTION_ARGS)
+{
+ agtype *agt_arg = NULL;
+ agtype_value *agtv_value = NULL;
+ agtype_value *label = NULL;
+
+ /* check for NULL, NULL is FALSE */
+ if (PG_ARGISNULL(0))
+ PG_RETURN_NULL();
+
+ /* get the argument */
+ agt_arg = AG_GET_ARG_AGTYPE_P(0);
+
+ // edges and vertices are considered scalars
+ if (!AGT_ROOT_IS_SCALAR(agt_arg))
+ {
+ if (AGTE_IS_NULL(agt_arg->root.children[0]))
+ PG_RETURN_NULL();
+
+ ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("label() argument must resolve to an edge or
vertex")));
+
+ }
+
+ agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);
+
+ // fail if agtype value isn't an edge or vertex
+ if (agtv_value->type != AGTV_VERTEX && agtv_value->type != AGTV_EDGE)
+ {
+ ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("label() argument must resolve to an edge or
vertex")));
+
+ }
+
+ // extract the label agtype value from the vertex or edge
+ label = get_agtype_value_object_value(agtv_value, "label");
+
+ PG_RETURN_POINTER(agtype_value_to_agtype(label));
+}
+
PG_FUNCTION_INFO_V1(age_tostring);
Datum age_tostring(PG_FUNCTION_ARGS)