diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2024-10-31 15:53:58 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2024-10-31 16:09:27 -0400 |
commit | 89e51abcb2905d6beaa09a7d3603d6882ac27033 (patch) | |
tree | 27dba1ec7f0bd023f1bfa5103fbafdf3c0841595 /src/backend/commands/functioncmds.c | |
parent | b82c877e76e2398409e823773413079668cf1881 (diff) | |
download | postgresql-89e51abcb2905d6beaa09a7d3603d6882ac27033.tar.gz postgresql-89e51abcb2905d6beaa09a7d3603d6882ac27033.zip |
Add a parse location field to struct FunctionParameter.
This allows an error cursor to be supplied for a bunch of
bad-function-definition errors that previously lacked one,
or that cheated a bit by pointing at the contained type name
when the error isn't really about that.
Bump catversion from an abundance of caution --- I don't think
this node type can actually appear in stored views/rules, but
better safe than sorry.
Jian He and Tom Lane (extracted from a larger patch by Jian,
with some additional work by me)
Discussion: https://postgr.es/m/CACJufxEmONE3P2En=jopZy1m=cCCUs65M4+1o52MW5og9oaUPA@mail.gmail.com
Diffstat (limited to 'src/backend/commands/functioncmds.c')
-rw-r--r-- | src/backend/commands/functioncmds.c | 47 |
1 files changed, 31 insertions, 16 deletions
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index d43b89d3efa..6fc3863265d 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -232,7 +232,7 @@ interpret_function_parameter_list(ParseState *pstate, if (fpmode == FUNC_PARAM_DEFAULT) fpmode = FUNC_PARAM_IN; - typtup = LookupTypeName(NULL, t, NULL, false); + typtup = LookupTypeName(pstate, t, NULL, false); if (typtup) { if (!((Form_pg_type) GETSTRUCT(typtup))->typisdefined) @@ -242,18 +242,21 @@ interpret_function_parameter_list(ParseState *pstate, ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), errmsg("SQL function cannot accept shell type %s", - TypeNameToString(t)))); + TypeNameToString(t)), + parser_errposition(pstate, t->location))); /* We don't allow creating aggregates on shell types either */ else if (objtype == OBJECT_AGGREGATE) ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), errmsg("aggregate cannot accept shell type %s", - TypeNameToString(t)))); + TypeNameToString(t)), + parser_errposition(pstate, t->location))); else ereport(NOTICE, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("argument type %s is only a shell", - TypeNameToString(t)))); + TypeNameToString(t)), + parser_errposition(pstate, t->location))); } toid = typeTypeId(typtup); ReleaseSysCache(typtup); @@ -263,7 +266,8 @@ interpret_function_parameter_list(ParseState *pstate, ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("type %s does not exist", - TypeNameToString(t)))); + TypeNameToString(t)), + parser_errposition(pstate, t->location))); toid = InvalidOid; /* keep compiler quiet */ } @@ -276,15 +280,18 @@ interpret_function_parameter_list(ParseState *pstate, if (objtype == OBJECT_AGGREGATE) ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("aggregates cannot accept set arguments"))); + errmsg("aggregates cannot accept set arguments"), + parser_errposition(pstate, fp->location))); else if (objtype == OBJECT_PROCEDURE) ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("procedures cannot accept set arguments"))); + errmsg("procedures cannot accept set arguments"), + parser_errposition(pstate, fp->location))); else ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("functions cannot accept set arguments"))); + errmsg("functions cannot accept set arguments"), + parser_errposition(pstate, fp->location))); } /* handle input parameters */ @@ -294,7 +301,8 @@ interpret_function_parameter_list(ParseState *pstate, if (varCount > 0) ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("VARIADIC parameter must be the last input parameter"))); + errmsg("VARIADIC parameter must be the last input parameter"), + parser_errposition(pstate, fp->location))); inTypes[inCount++] = toid; isinput = true; if (parameterTypes_list) @@ -314,7 +322,8 @@ interpret_function_parameter_list(ParseState *pstate, if (varCount > 0) ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("VARIADIC parameter must be the last parameter"))); + errmsg("VARIADIC parameter must be the last parameter"), + parser_errposition(pstate, fp->location))); /* Procedures with output parameters always return RECORD */ *requiredResultType = RECORDOID; } @@ -339,7 +348,8 @@ interpret_function_parameter_list(ParseState *pstate, if (!OidIsValid(get_element_type(toid))) ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("VARIADIC parameter must be an array"))); + errmsg("VARIADIC parameter must be an array"), + parser_errposition(pstate, fp->location))); break; } } @@ -385,7 +395,8 @@ interpret_function_parameter_list(ParseState *pstate, ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), errmsg("parameter name \"%s\" used more than once", - fp->name))); + fp->name), + parser_errposition(pstate, fp->location))); } paramNames[i] = CStringGetTextDatum(fp->name); @@ -402,7 +413,8 @@ interpret_function_parameter_list(ParseState *pstate, if (!isinput) ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("only input parameters can have default values"))); + errmsg("only input parameters can have default values"), + parser_errposition(pstate, fp->location))); def = transformExpr(pstate, fp->defexpr, EXPR_KIND_FUNCTION_DEFAULT); @@ -417,7 +429,8 @@ interpret_function_parameter_list(ParseState *pstate, contain_var_clause(def)) ereport(ERROR, (errcode(ERRCODE_INVALID_COLUMN_REFERENCE), - errmsg("cannot use table references in parameter default value"))); + errmsg("cannot use table references in parameter default value"), + parser_errposition(pstate, fp->location))); /* * transformExpr() should have already rejected subqueries, @@ -441,7 +454,8 @@ interpret_function_parameter_list(ParseState *pstate, if (isinput && have_defaults) ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("input parameters after one with a default value must also have defaults"))); + errmsg("input parameters after one with a default value must also have defaults"), + parser_errposition(pstate, fp->location))); /* * For procedures, we also can't allow OUT parameters after one @@ -451,7 +465,8 @@ interpret_function_parameter_list(ParseState *pstate, if (objtype == OBJECT_PROCEDURE && have_defaults) ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("procedure OUT parameters cannot appear after one with a default value"))); + errmsg("procedure OUT parameters cannot appear after one with a default value"), + parser_errposition(pstate, fp->location))); } i++; |