Skip to content
Permalink
Browse files
feat: implement type casting, Agtype to int4[] (#107)
* feat: implement type casting, Agtype to int4[]

* chore: reformat code.

* Clean up
  • Loading branch information
emotionbug committed Dec 22, 2021
1 parent c094814 commit b3cee6b5ac1d1556d46e172ab2dd236cd73b8b89
Showing 4 changed files with 89 additions and 1 deletion.
@@ -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
--
@@ -2123,6 +2123,27 @@ SELECT bool_to_agtype(true) <> bool_to_agtype(false);
t
(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
--
@@ -540,6 +540,13 @@ SELECT bool_to_agtype(null);
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
--
@@ -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.

0 comments on commit b3cee6b

Please sign in to comment.