This is an automated email from the ASF dual-hosted git repository.

mtaha pushed a commit to branch PG16
in repository https://gitbox.apache.org/repos/asf/age.git


The following commit(s) were added to refs/heads/PG16 by this push:
     new 6afddd5b Add function is_valid_label_name (#1913)
6afddd5b is described below

commit 6afddd5b9a9fe2d08d6bcf818b0adc73fc3213dd
Author: John Gemignani <[email protected]>
AuthorDate: Mon Jun 17 13:43:22 2024 -0700

    Add function is_valid_label_name (#1913)
    
    Added the function is_valid_label_name (#1911) per user request.
    
    This function will return a boolean value for any agtype string
    passed, depending on whether it is a valid name for a label. For
    all other types, not an agtype string, it will error out. Depending
    on user requirements, this could be changed in the future.
    
    Added regression tests.
---
 regress/expected/name_validation.out  | 27 +++++++++++++++++++++
 regress/sql/name_validation.sql       |  8 +++++++
 sql/agtype_string.sql                 |  7 ++++++
 src/backend/commands/label_commands.c | 45 +++++++++++++++++++++++++++++++++++
 4 files changed, 87 insertions(+)

diff --git a/regress/expected/name_validation.out 
b/regress/expected/name_validation.out
index a1bc779c..232582bc 100644
--- a/regress/expected/name_validation.out
+++ b/regress/expected/name_validation.out
@@ -369,6 +369,33 @@ SELECT * from cypher('graph123', $$ CREATE 
(:A)-[:`mylabel2`]->(:C) $$) as (a ag
 ---
 (0 rows)
 
+-- user label validation
+-- invalid
+SELECT * from cypher('graph123', $$ return is_valid_label_name('1label') $$) 
as (result agtype);
+ result 
+--------
+ false
+(1 row)
+
+SELECT * from cypher('graph123', $$ return is_valid_label_name('2label') $$) 
as (result agtype);
+ result 
+--------
+ false
+(1 row)
+
+-- valid
+SELECT * from cypher('graph123', $$ return is_valid_label_name('label1') $$) 
as (result agtype);
+ result 
+--------
+ true
+(1 row)
+
+SELECT * from cypher('graph123', $$ return is_valid_label_name('label2') $$) 
as (result agtype);
+ result 
+--------
+ true
+(1 row)
+
 -- clean up
 SELECT drop_graph('graph123', true);
 NOTICE:  drop cascades to 18 other objects
diff --git a/regress/sql/name_validation.sql b/regress/sql/name_validation.sql
index b67d113a..bfb5d886 100644
--- a/regress/sql/name_validation.sql
+++ b/regress/sql/name_validation.sql
@@ -145,6 +145,14 @@ SELECT * from cypher('graph123', $$ CREATE 
(:A)-[:`my&label2`]->(:C) $$) as (a a
 SELECT * from cypher('graph123', $$ CREATE (a:`mylabel`) $$) as (a agtype);
 SELECT * from cypher('graph123', $$ CREATE (:A)-[:`mylabel2`]->(:C) $$) as (a 
agtype);
 
+-- user label validation
+-- invalid
+SELECT * from cypher('graph123', $$ return is_valid_label_name('1label') $$) 
as (result agtype);
+SELECT * from cypher('graph123', $$ return is_valid_label_name('2label') $$) 
as (result agtype);
+-- valid
+SELECT * from cypher('graph123', $$ return is_valid_label_name('label1') $$) 
as (result agtype);
+SELECT * from cypher('graph123', $$ return is_valid_label_name('label2') $$) 
as (result agtype);
+
 -- clean up
 SELECT drop_graph('graph123', true);
 
diff --git a/sql/agtype_string.sql b/sql/agtype_string.sql
index 430b189b..e7485769 100644
--- a/sql/agtype_string.sql
+++ b/sql/agtype_string.sql
@@ -51,3 +51,10 @@ CREATE FUNCTION ag_catalog.age_eq_tilde(agtype, agtype)
     STABLE
 PARALLEL SAFE
 AS 'MODULE_PATHNAME';
+
+CREATE FUNCTION ag_catalog.age_is_valid_label_name(agtype)
+    RETURNS boolean
+    LANGUAGE c
+    IMMUTABLE
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
diff --git a/src/backend/commands/label_commands.c 
b/src/backend/commands/label_commands.c
index 80da6b02..5887a927 100644
--- a/src/backend/commands/label_commands.c
+++ b/src/backend/commands/label_commands.c
@@ -94,7 +94,52 @@ static void range_var_callback_for_remove_relation(const 
RangeVar *rel,
                                                    Oid odl_rel_oid,
                                                    void *arg);
 
+PG_FUNCTION_INFO_V1(age_is_valid_label_name);
 
+Datum age_is_valid_label_name(PG_FUNCTION_ARGS)
+{
+    agtype *agt_arg = NULL;
+    agtype_value *agtv_value = NULL;
+    char *label_name = NULL;
+    bool is_valid = false;
+
+    if (PG_ARGISNULL(0))
+    {
+        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                errmsg("label name must not be NULL")));
+    }
+
+    agt_arg = AG_GET_ARG_AGTYPE_P(0);
+
+    if (!AGT_ROOT_IS_SCALAR(agt_arg))
+    {
+        ereport(ERROR,
+                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                 errmsg("is_valid_label_name() only supports scalar 
arguments")));
+    }
+
+    agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);
+
+    if (agtv_value->type != AGTV_STRING)
+    {
+        ereport(ERROR,
+                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                 errmsg("is_valid_label_name() only supports string 
arguments")));
+    }
+
+    label_name = pnstrdup(agtv_value->val.string.val,
+                          agtv_value->val.string.len);
+
+    is_valid = is_valid_label(label_name, 0);
+    pfree(label_name);
+
+    if (is_valid)
+    {
+        PG_RETURN_BOOL(true);
+    }
+
+    PG_RETURN_BOOL(false);
+}
 
 PG_FUNCTION_INFO_V1(create_vlabel);
 

Reply via email to