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

jgemignani 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 b3cee6b  feat: implement type casting, Agtype to int4[] (#107)
b3cee6b is described below

commit b3cee6b5ac1d1556d46e172ab2dd236cd73b8b89
Author: Alex Kwak <[email protected]>
AuthorDate: Wed Dec 22 10:08:43 2021 +0900

    feat: implement type casting, Agtype to int4[] (#107)
    
    * feat: implement type casting, Agtype to int4[]
    
    * chore: reformat code.
    
    * Clean up
---
 age--0.6.0.sql                 | 13 ++++++++++-
 regress/expected/agtype.out    | 21 ++++++++++++++++++
 regress/sql/agtype.sql         |  7 ++++++
 src/backend/utils/adt/agtype.c | 49 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 89 insertions(+), 1 deletion(-)

diff --git a/age--0.6.0.sql b/age--0.6.0.sql
index 272c407..78ee09d 100644
--- a/age--0.6.0.sql
+++ b/age--0.6.0.sql
@@ -3021,10 +3021,10 @@ RETURNS NULL ON NULL INPUT
 PARALLEL SAFE
 AS 'MODULE_PATHNAME';
 
--- agtype -> int2
 CREATE CAST (agtype AS int)
 WITH FUNCTION ag_catalog.agtype_to_int4(variadic "any");
 
+-- agtype -> int2
 CREATE FUNCTION ag_catalog.agtype_to_int2(variadic "any")
 RETURNS smallint
 LANGUAGE c
@@ -3036,6 +3036,17 @@ AS 'MODULE_PATHNAME';
 CREATE CAST (agtype AS smallint)
 WITH FUNCTION ag_catalog.agtype_to_int2(variadic "any");
 
+-- agtype -> int4[]
+CREATE FUNCTION ag_catalog.agtype_to_int4_array(variadic "any")
+    RETURNS int[]
+    LANGUAGE c
+    STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE CAST (agtype AS int[])
+    WITH FUNCTION ag_catalog.agtype_to_int4_array(variadic "any");
 --
 -- agtype - access operators
 --
diff --git a/regress/expected/agtype.out b/regress/expected/agtype.out
index 62ed0d1..8647055 100644
--- a/regress/expected/agtype.out
+++ b/regress/expected/agtype.out
@@ -2124,6 +2124,27 @@ SELECT bool_to_agtype(true) <> bool_to_agtype(false);
 (1 row)
 
 --
+-- Test agtype to int[]
+--
+SELECT agtype_to_int4_array(agtype_in('[1,2,3]'));
+ agtype_to_int4_array 
+----------------------
+ {1,2,3}
+(1 row)
+
+SELECT agtype_to_int4_array(agtype_in('[1.6,2.3,3.66]'));
+ agtype_to_int4_array 
+----------------------
+ {2,2,4}
+(1 row)
+
+SELECT agtype_to_int4_array(agtype_in('["6","7",3.66]'));
+ agtype_to_int4_array 
+----------------------
+ {6,7,4}
+(1 row)
+
+--
 -- Map Literal
 --
 --Invalid Map Key (should fail)
diff --git a/regress/sql/agtype.sql b/regress/sql/agtype.sql
index e08089b..3103697 100644
--- a/regress/sql/agtype.sql
+++ b/regress/sql/agtype.sql
@@ -541,6 +541,13 @@ SELECT bool_to_agtype(true) = bool_to_agtype(true);
 SELECT bool_to_agtype(true) <> bool_to_agtype(false);
 
 --
+-- Test agtype to int[]
+--
+SELECT agtype_to_int4_array(agtype_in('[1,2,3]'));
+SELECT agtype_to_int4_array(agtype_in('[1.6,2.3,3.66]'));
+SELECT agtype_to_int4_array(agtype_in('["6","7",3.66]'));
+
+--
 -- Map Literal
 --
 
diff --git a/src/backend/utils/adt/agtype.c b/src/backend/utils/adt/agtype.c
index e099679..e046b5e 100644
--- a/src/backend/utils/adt/agtype.c
+++ b/src/backend/utils/adt/agtype.c
@@ -2630,6 +2630,55 @@ Datum int8_to_agtype(PG_FUNCTION_ARGS)
     return integer_to_agtype(PG_GETARG_INT64(0));
 }
 
+PG_FUNCTION_INFO_V1(agtype_to_int4_array);
+
+/*
+ * Cast agtype to int4[].
+ */
+Datum agtype_to_int4_array(PG_FUNCTION_ARGS)
+{
+    agtype *agtype_in = AG_GET_ARG_AGTYPE_P(0);
+    agtype_value agtv;
+    agtype_iterator_token agtv_token;
+    Datum *array_value;
+    ArrayType *result;
+    int element_size;
+    int i;
+
+    agtype_iterator *agtype_iterator = agtype_iterator_init(&agtype_in->root);
+    agtv_token = agtype_iterator_next(&agtype_iterator, &agtv, false);
+
+    if(agtv.type != AGTV_ARRAY) {
+        cannot_cast_agtype_value(agtv.type, "int4[]");
+    }
+
+    element_size = agtv.val.array.num_elems;
+    array_value = (Datum *) palloc(sizeof(Datum) * element_size);
+
+    i = 0;
+    while ((agtv_token = agtype_iterator_next(&agtype_iterator, &agtv, true)) 
!= WAGT_END_ARRAY)
+    {
+        int32 element_value = 0;
+        if (agtv.type == AGTV_INTEGER)
+            element_value = DatumGetInt32(DirectFunctionCall1(int84,
+                                                              
Int64GetDatum(agtv.val.int_value)));
+        else if (agtv.type == AGTV_FLOAT)
+            element_value = DatumGetInt32(DirectFunctionCall1(dtoi4,
+                                                              
Float8GetDatum(agtv.val.float_value)));
+        else if (agtv.type == AGTV_NUMERIC)
+            element_value = DatumGetInt32(DirectFunctionCall1(numeric_int4,
+                                                              
NumericGetDatum(agtv.val.numeric)));
+        else if (agtv.type == AGTV_STRING)
+            element_value = DatumGetInt32(DirectFunctionCall1(int4in,
+                                                              
CStringGetDatum(agtv.val.string.val)));
+        array_value[i++] = element_value;
+    }
+
+    result = construct_array(array_value, element_size, INT4OID, 4, true, 'i');
+
+    PG_RETURN_ARRAYTYPE_P(result);
+}
+
 /*
  * Helper function for agtype_access_operator map access.
  * Note: This function expects that a map and a scalar key are being passed.

Reply via email to