summaryrefslogtreecommitdiff
path: root/src/backend/utils/adt
diff options
context:
space:
mode:
authorAndrew Dunstan <andrew@dunslane.net>2013-07-18 11:52:12 -0400
committerAndrew Dunstan <andrew@dunslane.net>2013-07-18 11:52:12 -0400
commitd26888bc4d1e539a82f21382b0000fe5bbf889d9 (patch)
tree45971c200f11e8b55af421cdadf012b4071f8ce1 /src/backend/utils/adt
parent405a468b02dd80a069b95c4eb9838cb6a562eddd (diff)
Move checking an explicit VARIADIC "any" argument into the parser.
This is more efficient and simpler . It does mean that an untyped NULL can no longer be used in such cases, which should be mentioned in Release Notes, but doesn't seem a terrible loss. The workaround is to cast the NULL to some array type. Pavel Stehule, reviewed by Jeevan Chalke.
Diffstat (limited to 'src/backend/utils/adt')
-rw-r--r--src/backend/utils/adt/ruleutils.c4
-rw-r--r--src/backend/utils/adt/varlena.c42
2 files changed, 19 insertions, 27 deletions
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 976bc98e375..40b565a11d6 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -8584,6 +8584,7 @@ generate_function_name(Oid funcid, int nargs, List *argnames, Oid *argtypes,
Oid p_rettype;
bool p_retset;
int p_nvargs;
+ Oid p_vatype;
Oid *p_true_typeids;
proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
@@ -8634,7 +8635,8 @@ generate_function_name(Oid funcid, int nargs, List *argnames, Oid *argtypes,
NIL, argnames, nargs, argtypes,
!use_variadic, true,
&p_funcid, &p_rettype,
- &p_retset, &p_nvargs, &p_true_typeids, NULL);
+ &p_retset, &p_nvargs, &p_vatype,
+ &p_true_typeids, NULL);
if ((p_result == FUNCDETAIL_NORMAL ||
p_result == FUNCDETAIL_AGGREGATE ||
p_result == FUNCDETAIL_WINDOWFUNC) &&
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c
index 56349e7e2aa..4aa344896f9 100644
--- a/src/backend/utils/adt/varlena.c
+++ b/src/backend/utils/adt/varlena.c
@@ -3820,7 +3820,6 @@ concat_internal(const char *sepstr, int argidx,
*/
if (get_fn_expr_variadic(fcinfo->flinfo))
{
- Oid arr_typid;
ArrayType *arr;
/* Should have just the one argument */
@@ -3831,20 +3830,16 @@ concat_internal(const char *sepstr, int argidx,
return NULL;
/*
- * Non-null argument had better be an array. The parser doesn't
- * enforce this for VARIADIC ANY functions (maybe it should?), so that
- * check uses ereport not just elog.
+ * Non-null argument had better be an array
+ *
+ * Correct values are ensured by parser check, but this function
+ * can be called directly, bypassing the parser, so we should do
+ * some minimal check too - this form of call requires correctly set
+ * expr argtype in flinfo.
*/
- arr_typid = get_fn_expr_argtype(fcinfo->flinfo, argidx);
- if (!OidIsValid(arr_typid))
- elog(ERROR, "could not determine data type of concat() input");
-
- if (!OidIsValid(get_element_type(arr_typid)))
- ereport(ERROR,
- (errcode(ERRCODE_DATATYPE_MISMATCH),
- errmsg("VARIADIC argument must be an array")));
+ Assert(OidIsValid(get_fn_expr_argtype(fcinfo->flinfo, argidx)));
+ Assert(OidIsValid(get_element_type(get_fn_expr_argtype(fcinfo->flinfo, argidx))));
- /* OK, safe to fetch the array value */
arr = PG_GETARG_ARRAYTYPE_P(argidx);
/*
@@ -4049,7 +4044,6 @@ text_format(PG_FUNCTION_ARGS)
/* If argument is marked VARIADIC, expand array into elements */
if (get_fn_expr_variadic(fcinfo->flinfo))
{
- Oid arr_typid;
ArrayType *arr;
int16 elmlen;
bool elmbyval;
@@ -4065,20 +4059,16 @@ text_format(PG_FUNCTION_ARGS)
else
{
/*
- * Non-null argument had better be an array. The parser doesn't
- * enforce this for VARIADIC ANY functions (maybe it should?), so
- * that check uses ereport not just elog.
+ * Non-null argument had better be an array
+ *
+ * Correct values are ensured by parser check, but this function
+ * can be called directly, bypassing the parser, so we should do
+ * some minimal check too - this form of call requires correctly set
+ * expr argtype in flinfo.
*/
- arr_typid = get_fn_expr_argtype(fcinfo->flinfo, 1);
- if (!OidIsValid(arr_typid))
- elog(ERROR, "could not determine data type of format() input");
-
- if (!OidIsValid(get_element_type(arr_typid)))
- ereport(ERROR,
- (errcode(ERRCODE_DATATYPE_MISMATCH),
- errmsg("VARIADIC argument must be an array")));
+ Assert(OidIsValid(get_fn_expr_argtype(fcinfo->flinfo, 1)));
+ Assert(OidIsValid(get_element_type(get_fn_expr_argtype(fcinfo->flinfo, 1))));
- /* OK, safe to fetch the array value */
arr = PG_GETARG_ARRAYTYPE_P(1);
/* Get info about array element type */