Skip to content

Commit 81233ce

Browse files
MatheusFarias03jrgemignani
authored andcommitted
Implemented age_tail function (#1283)
age_tail() function returns a list containing all the elements, excluding the first one, from a list.
1 parent fcdbaa7 commit 81233ce

File tree

4 files changed

+135
-0
lines changed

4 files changed

+135
-0
lines changed

age--1.4.0.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3590,6 +3590,14 @@ RETURNS NULL ON NULL INPUT
35903590
PARALLEL SAFE
35913591
AS 'MODULE_PATHNAME';
35923592

3593+
CREATE FUNCTION ag_catalog.age_tail(variadic "any")
3594+
RETURNS agtype
3595+
LANGUAGE c
3596+
IMMUTABLE
3597+
RETURNS NULL ON NULL INPUT
3598+
PARALLEL SAFE
3599+
AS 'MODULE_PATHNAME';
3600+
35933601
CREATE FUNCTION ag_catalog.age_properties(agtype)
35943602
RETURNS agtype
35953603
LANGUAGE c

regress/expected/expr.out

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6928,6 +6928,45 @@ SELECT * from cypher('list', $$RETURN range(0, null, -3)$$) as (range agtype);
69286928
ERROR: range(): neither start or end can be NULL
69296929
SELECT * from cypher('list', $$RETURN range(0, -10.0, -3.0)$$) as (range agtype);
69306930
ERROR: range() unsupported argument type
6931+
-- tail()
6932+
-- should return the last elements of the list
6933+
SELECT * FROM cypher('list', $$ RETURN tail([1,2,3,4,5]) $$) AS (tail agtype);
6934+
tail
6935+
--------------
6936+
[2, 3, 4, 5]
6937+
(1 row)
6938+
6939+
SELECT * FROM cypher('list', $$ RETURN tail(["a","b","c","d","e"]) $$) AS (tail agtype);
6940+
tail
6941+
----------------------
6942+
["b", "c", "d", "e"]
6943+
(1 row)
6944+
6945+
-- should return null
6946+
SELECT * FROM cypher('list', $$ RETURN tail([1]) $$) AS (tail agtype);
6947+
tail
6948+
------
6949+
6950+
(1 row)
6951+
6952+
SELECT * FROM cypher('list', $$ RETURN tail([]) $$) AS (tail agtype);
6953+
tail
6954+
------
6955+
6956+
(1 row)
6957+
6958+
-- should throw errors
6959+
SELECT * FROM cypher('list', $$ RETURN tail(123) $$) AS (tail agtype);
6960+
ERROR: tail() argument must resolve to a list or null
6961+
SELECT * FROM cypher('list', $$ RETURN tail(abc) $$) AS (tail agtype);
6962+
ERROR: could not find rte for abc
6963+
LINE 1: SELECT * FROM cypher('list', $$ RETURN tail(abc) $$) AS (tai...
6964+
^
6965+
SELECT * FROM cypher('list', $$ RETURN tail() $$) AS (tail agtype);
6966+
ERROR: function ag_catalog.age_tail() does not exist
6967+
LINE 1: SELECT * FROM cypher('list', $$ RETURN tail() $$) AS (tail a...
6968+
^
6969+
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
69316970
-- labels()
69326971
SELECT * from cypher('list', $$CREATE (u:People {name: "John"}) RETURN u$$) as (Vertices agtype);
69336972
vertices

regress/sql/expr.sql

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2830,6 +2830,17 @@ SELECT * from cypher('list', $$RETURN range(-10, 10, -1)$$) as (range agtype);
28302830
SELECT * from cypher('list', $$RETURN range(null, -10, -3)$$) as (range agtype);
28312831
SELECT * from cypher('list', $$RETURN range(0, null, -3)$$) as (range agtype);
28322832
SELECT * from cypher('list', $$RETURN range(0, -10.0, -3.0)$$) as (range agtype);
2833+
-- tail()
2834+
-- should return the last elements of the list
2835+
SELECT * FROM cypher('list', $$ RETURN tail([1,2,3,4,5]) $$) AS (tail agtype);
2836+
SELECT * FROM cypher('list', $$ RETURN tail(["a","b","c","d","e"]) $$) AS (tail agtype);
2837+
-- should return null
2838+
SELECT * FROM cypher('list', $$ RETURN tail([1]) $$) AS (tail agtype);
2839+
SELECT * FROM cypher('list', $$ RETURN tail([]) $$) AS (tail agtype);
2840+
-- should throw errors
2841+
SELECT * FROM cypher('list', $$ RETURN tail(123) $$) AS (tail agtype);
2842+
SELECT * FROM cypher('list', $$ RETURN tail(abc) $$) AS (tail agtype);
2843+
SELECT * FROM cypher('list', $$ RETURN tail() $$) AS (tail agtype);
28332844
-- labels()
28342845
SELECT * from cypher('list', $$CREATE (u:People {name: "John"}) RETURN u$$) as (Vertices agtype);
28352846
SELECT * from cypher('list', $$CREATE (u:People {name: "Larry"}) RETURN u$$) as (Vertices agtype);

src/backend/utils/adt/agtype.c

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5126,6 +5126,83 @@ Datum age_last(PG_FUNCTION_ARGS)
51265126
PG_RETURN_POINTER(agtype_value_to_agtype(agtv_result));
51275127
}
51285128

5129+
5130+
PG_FUNCTION_INFO_V1(age_tail);
5131+
/*
5132+
* Returns a list containing all the elements, excluding the first one, from a list.
5133+
*/
5134+
Datum age_tail(PG_FUNCTION_ARGS)
5135+
{
5136+
Oid arg_type;
5137+
agtype *agt_arg = NULL;
5138+
agtype *agt_result = NULL;
5139+
agtype_in_state agis_result;
5140+
int count;
5141+
int i;
5142+
5143+
/* check number of arguments */
5144+
if (PG_NARGS() < 1 || PG_NARGS() > 1)
5145+
{
5146+
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5147+
errmsg("age_tail() requires only one argument")));
5148+
}
5149+
5150+
/* get the data type */
5151+
arg_type = get_fn_expr_argtype(fcinfo->flinfo, 0);
5152+
5153+
/* check the data type */
5154+
if (arg_type != AGTYPEOID)
5155+
{
5156+
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5157+
errmsg("age_tail() argument must be of type agtype")));
5158+
}
5159+
5160+
/* check for null */
5161+
if (PG_ARGISNULL(0))
5162+
{
5163+
PG_RETURN_NULL();
5164+
}
5165+
5166+
agt_arg = AG_GET_ARG_AGTYPE_P(0);
5167+
/* check for an array */
5168+
if (!AGT_ROOT_IS_ARRAY(agt_arg) || AGT_ROOT_IS_SCALAR(agt_arg))
5169+
{
5170+
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5171+
errmsg("tail() argument must resolve to a list or null")));
5172+
}
5173+
5174+
count = AGT_ROOT_COUNT(agt_arg);
5175+
5176+
/* if we have an empty list or only one element in the list, return null */
5177+
if (count <= 1)
5178+
{
5179+
PG_RETURN_NULL();
5180+
}
5181+
5182+
/* clear the result structure */
5183+
MemSet(&agis_result, 0, sizeof(agtype_in_state));
5184+
5185+
/* push the beginning of the array */
5186+
agis_result.res = push_agtype_value(&agis_result.parse_state,
5187+
WAGT_BEGIN_ARRAY, NULL);
5188+
5189+
/* iterate through the list beginning with the second item */
5190+
for (i = 1; i < count; i++)
5191+
{
5192+
agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_ELEM,
5193+
get_ith_agtype_value_from_container(&agt_arg->root, i));
5194+
}
5195+
5196+
/* push the end of the array */
5197+
agis_result.res = push_agtype_value(&agis_result.parse_state,
5198+
WAGT_END_ARRAY, NULL);
5199+
5200+
agt_result = agtype_value_to_agtype(agis_result.res);
5201+
pfree_agtype_value(agis_result.res);
5202+
5203+
PG_RETURN_POINTER(agt_result);
5204+
}
5205+
51295206
PG_FUNCTION_INFO_V1(age_properties);
51305207

51315208
Datum age_properties(PG_FUNCTION_ARGS)

0 commit comments

Comments
 (0)