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)

Reply via email to