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.