diff --git a/regress/expected/expr.out b/regress/expected/expr.out index 806a6f65c..7b2afa2eb 100644 --- a/regress/expected/expr.out +++ b/regress/expected/expr.out @@ -10708,6 +10708,30 @@ NOTICE: graph "issue_2391" has been dropped (1 row) +-- +-- Issue 2563: age_to*list called from SQL with a non-agtype literal +-- must raise an error instead of crashing +-- +SELECT ag_catalog.age_tobooleanlist('[true]'); +ERROR: toBooleanList() argument must be of type agtype +SELECT ag_catalog.age_tofloatlist('[1.5]'); +ERROR: toFloatList() argument must be of type agtype +SELECT ag_catalog.age_tointegerlist('[1]'); +ERROR: toIntegerList() argument must be of type agtype +SELECT ag_catalog.age_tostringlist('[1]'); +ERROR: toStringList() argument must be of type agtype +SELECT ag_catalog.age_tobooleanlist('[true]'::agtype); + age_tobooleanlist +------------------- + [true] +(1 row) + +SELECT ag_catalog.age_tostringlist('[1]'::agtype); + age_tostringlist +------------------ + ["1"] +(1 row) + -- -- End of tests -- diff --git a/regress/sql/expr.sql b/regress/sql/expr.sql index d4d900a1c..71a944ddc 100644 --- a/regress/sql/expr.sql +++ b/regress/sql/expr.sql @@ -4200,6 +4200,17 @@ SELECT * FROM cypher('issue_2391', $$ $$) AS (n agtype); SELECT * FROM drop_graph('issue_2391', true); +-- +-- Issue 2563: age_to*list called from SQL with a non-agtype literal +-- must raise an error instead of crashing +-- +SELECT ag_catalog.age_tobooleanlist('[true]'); +SELECT ag_catalog.age_tofloatlist('[1.5]'); +SELECT ag_catalog.age_tointegerlist('[1]'); +SELECT ag_catalog.age_tostringlist('[1]'); +SELECT ag_catalog.age_tobooleanlist('[true]'::agtype); +SELECT ag_catalog.age_tostringlist('[1]'::agtype); + -- -- End of tests -- diff --git a/src/backend/utils/adt/agtype.c b/src/backend/utils/adt/agtype.c index cc9cc7717..84e0f36d2 100644 --- a/src/backend/utils/adt/agtype.c +++ b/src/backend/utils/adt/agtype.c @@ -6864,6 +6864,11 @@ Datum age_tobooleanlist(PG_FUNCTION_ARGS) if (PG_ARGISNULL(0)) PG_RETURN_NULL(); + /* the argument must be agtype, otherwise it cannot be read as one */ + if (get_fn_expr_argtype(fcinfo->flinfo, 0) != AGTYPEOID) + ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("toBooleanList() argument must be of type agtype"))); + 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)) @@ -7105,6 +7110,11 @@ Datum age_tofloatlist(PG_FUNCTION_ARGS) { PG_RETURN_NULL(); } + /* the argument must be agtype, otherwise it cannot be read as one */ + if (get_fn_expr_argtype(fcinfo->flinfo, 0) != AGTYPEOID) + ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("toFloatList() argument must be of type agtype"))); + agt_arg = AG_GET_ARG_AGTYPE_P(0); /* check for an array */ @@ -7462,6 +7472,11 @@ Datum age_tointegerlist(PG_FUNCTION_ARGS) { PG_RETURN_NULL(); } + /* the argument must be agtype, otherwise it cannot be read as one */ + if (get_fn_expr_argtype(fcinfo->flinfo, 0) != AGTYPEOID) + ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("toIntegerList() argument must be of type agtype"))); + 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)) @@ -8102,6 +8117,11 @@ Datum age_tostringlist(PG_FUNCTION_ARGS) { PG_RETURN_NULL(); } + /* the argument must be agtype, otherwise it cannot be read as one */ + if (get_fn_expr_argtype(fcinfo->flinfo, 0) != AGTYPEOID) + ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("toStringList() argument must be of type agtype"))); + 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))