This is an automated email from the ASF dual-hosted git repository.
jgemignani pushed a commit to branch PG11
in repository https://gitbox.apache.org/repos/asf/age.git
The following commit(s) were added to refs/heads/PG11 by this push:
new 5f4a1aff Implemented age_tail function (#1272)
5f4a1aff is described below
commit 5f4a1affe7e638ef6f14c5a9b237f96e97afd90a
Author: Matheus Farias de Oliveira Matsumoto
<[email protected]>
AuthorDate: Mon Oct 16 14:59:01 2023 -0300
Implemented age_tail function (#1272)
* Implemented age_tail function
age_tail() function returns a list containing all the elements,
excluding the first one, from a list.
* Added data type checking
* Removed extra line
---
age--1.4.0.sql | 8 +++++
regress/expected/expr.out | 39 +++++++++++++++++++++
regress/sql/expr.sql | 11 ++++++
src/backend/utils/adt/agtype.c | 77 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 135 insertions(+)
diff --git a/age--1.4.0.sql b/age--1.4.0.sql
index 46165f66..6112a039 100644
--- a/age--1.4.0.sql
+++ b/age--1.4.0.sql
@@ -3556,6 +3556,14 @@ RETURNS NULL ON NULL INPUT
PARALLEL SAFE
AS 'MODULE_PATHNAME';
+CREATE FUNCTION ag_catalog.age_tail(variadic "any")
+RETURNS agtype
+LANGUAGE c
+IMMUTABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
CREATE FUNCTION ag_catalog.age_properties(agtype)
RETURNS agtype
LANGUAGE c
diff --git a/regress/expected/expr.out b/regress/expected/expr.out
index 4620d5c0..04bab8c0 100644
--- a/regress/expected/expr.out
+++ b/regress/expected/expr.out
@@ -6771,6 +6771,45 @@ SELECT * from cypher('list', $$RETURN range(0, null,
-3)$$) as (range agtype);
ERROR: range(): neither start or end can be NULL
SELECT * from cypher('list', $$RETURN range(0, -10.0, -3.0)$$) as (range
agtype);
ERROR: range() unsupported argument type
+-- tail()
+-- should return the last elements of the list
+SELECT * FROM cypher('list', $$ RETURN tail([1,2,3,4,5]) $$) AS (tail agtype);
+ tail
+--------------
+ [2, 3, 4, 5]
+(1 row)
+
+SELECT * FROM cypher('list', $$ RETURN tail(["a","b","c","d","e"]) $$) AS
(tail agtype);
+ tail
+----------------------
+ ["b", "c", "d", "e"]
+(1 row)
+
+-- should return null
+SELECT * FROM cypher('list', $$ RETURN tail([1]) $$) AS (tail agtype);
+ tail
+------
+
+(1 row)
+
+SELECT * FROM cypher('list', $$ RETURN tail([]) $$) AS (tail agtype);
+ tail
+------
+
+(1 row)
+
+-- should throw errors
+SELECT * FROM cypher('list', $$ RETURN tail(123) $$) AS (tail agtype);
+ERROR: tail() argument must resolve to a list or null
+SELECT * FROM cypher('list', $$ RETURN tail(abc) $$) AS (tail agtype);
+ERROR: could not find rte for abc
+LINE 1: SELECT * FROM cypher('list', $$ RETURN tail(abc) $$) AS (tai...
+ ^
+SELECT * FROM cypher('list', $$ RETURN tail() $$) AS (tail agtype);
+ERROR: function ag_catalog.age_tail() does not exist
+LINE 1: SELECT * FROM cypher('list', $$ RETURN tail() $$) AS (tail a...
+ ^
+HINT: No function matches the given name and argument types. You might need
to add explicit type casts.
-- labels()
SELECT * from cypher('list', $$CREATE (u:People {name: "John"}) RETURN u$$) as
(Vertices agtype);
vertices
diff --git a/regress/sql/expr.sql b/regress/sql/expr.sql
index 122574b9..c9e12c11 100644
--- a/regress/sql/expr.sql
+++ b/regress/sql/expr.sql
@@ -2755,6 +2755,17 @@ SELECT * from cypher('list', $$RETURN range(-10, 10,
-1)$$) as (range agtype);
SELECT * from cypher('list', $$RETURN range(null, -10, -3)$$) as (range
agtype);
SELECT * from cypher('list', $$RETURN range(0, null, -3)$$) as (range agtype);
SELECT * from cypher('list', $$RETURN range(0, -10.0, -3.0)$$) as (range
agtype);
+-- tail()
+-- should return the last elements of the list
+SELECT * FROM cypher('list', $$ RETURN tail([1,2,3,4,5]) $$) AS (tail agtype);
+SELECT * FROM cypher('list', $$ RETURN tail(["a","b","c","d","e"]) $$) AS
(tail agtype);
+-- should return null
+SELECT * FROM cypher('list', $$ RETURN tail([1]) $$) AS (tail agtype);
+SELECT * FROM cypher('list', $$ RETURN tail([]) $$) AS (tail agtype);
+-- should throw errors
+SELECT * FROM cypher('list', $$ RETURN tail(123) $$) AS (tail agtype);
+SELECT * FROM cypher('list', $$ RETURN tail(abc) $$) AS (tail agtype);
+SELECT * FROM cypher('list', $$ RETURN tail() $$) AS (tail agtype);
-- labels()
SELECT * from cypher('list', $$CREATE (u:People {name: "John"}) RETURN u$$) as
(Vertices agtype);
SELECT * from cypher('list', $$CREATE (u:People {name: "Larry"}) RETURN u$$)
as (Vertices agtype);
diff --git a/src/backend/utils/adt/agtype.c b/src/backend/utils/adt/agtype.c
index 98d692b8..4aba4694 100644
--- a/src/backend/utils/adt/agtype.c
+++ b/src/backend/utils/adt/agtype.c
@@ -4994,6 +4994,83 @@ Datum age_last(PG_FUNCTION_ARGS)
PG_RETURN_POINTER(agtype_value_to_agtype(agtv_result));
}
+PG_FUNCTION_INFO_V1(age_tail);
+/*
+ * Returns a list containing all the elements, excluding the first one, from
a list.
+ */
+Datum age_tail(PG_FUNCTION_ARGS)
+{
+ Oid arg_type;
+ agtype *agt_arg = NULL;
+ agtype *agt_result = NULL;
+ agtype_in_state agis_result;
+ int count;
+ int i;
+
+ /* check number of arguments */
+ if (PG_NARGS() < 1 || PG_NARGS() > 1)
+ {
+ ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("age_tail() requires only one argument")));
+ }
+
+ /* get the data type */
+ arg_type = get_fn_expr_argtype(fcinfo->flinfo, 0);
+
+ /* check the data type */
+ if (arg_type != AGTYPEOID)
+ {
+ ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("age_tail() argument must be of type agtype")));
+ }
+
+ /* check for null */
+ if (PG_ARGISNULL(0))
+ {
+ PG_RETURN_NULL();
+ }
+
+ agt_arg = AG_GET_ARG_AGTYPE_P(0);
+ /* check for an array */
+ if (!AGT_ROOT_IS_ARRAY(agt_arg) || AGT_ROOT_IS_SCALAR(agt_arg))
+ {
+ ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("tail() argument must resolve to a list or
null")));
+ }
+
+ count = AGT_ROOT_COUNT(agt_arg);
+
+ /* if we have an empty list or only one element in the list, return null */
+ if (count <= 1)
+ {
+ PG_RETURN_NULL();
+ }
+
+ /* clear the result structure */
+ MemSet(&agis_result, 0, sizeof(agtype_in_state));
+
+ /* push the beginning of the array */
+ agis_result.res = push_agtype_value(&agis_result.parse_state,
+ WAGT_BEGIN_ARRAY, NULL);
+
+ /* iterate through the list beginning with the second item */
+ for (i = 1; i < count; i++)
+ {
+ agis_result.res = push_agtype_value(&agis_result.parse_state,
WAGT_ELEM,
+
get_ith_agtype_value_from_container(&agt_arg->root, i));
+ }
+
+ /* push the end of the array */
+ agis_result.res = push_agtype_value(&agis_result.parse_state,
+ WAGT_END_ARRAY, NULL);
+
+ agt_result = agtype_value_to_agtype(agis_result.res);
+ pfree_agtype_value(agis_result.res);
+
+ PG_RETURN_POINTER(agt_result);
+}
+
+
PG_FUNCTION_INFO_V1(age_properties);
Datum age_properties(PG_FUNCTION_ARGS)