aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/functioncmds.c
diff options
context:
space:
mode:
authorPeter Eisentraut <peter_e@gmx.net>2016-09-06 12:00:00 -0400
committerPeter Eisentraut <peter_e@gmx.net>2016-09-06 12:00:00 -0400
commit49eb0fd0972d14014dd3533b1f1bf8c94c899883 (patch)
treebcbfa5cf8f49c1b73066a5c4eaf80f33fc4ecc53 /src/backend/commands/functioncmds.c
parent975768f8eae2581b89ceafe8b16a77ff375207fe (diff)
downloadpostgresql-49eb0fd0972d14014dd3533b1f1bf8c94c899883.tar.gz
postgresql-49eb0fd0972d14014dd3533b1f1bf8c94c899883.zip
Add location field to DefElem
Add a location field to the DefElem struct, used to parse many utility commands. Update various error messages to supply error position information. To propogate the error position information in a more systematic way, create a ParseState in standard_ProcessUtility() and pass that to interested functions implementing the utility commands. This seems better than passing the query string and then reassembling a parse state ad hoc, which violates the encapsulation of the ParseState type. Reviewed-by: Pavel Stehule <pavel.stehule@gmail.com>
Diffstat (limited to 'src/backend/commands/functioncmds.c')
-rw-r--r--src/backend/commands/functioncmds.c57
1 files changed, 30 insertions, 27 deletions
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 748c8f75d48..becafc3045a 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -167,7 +167,6 @@ compute_return_type(TypeName *returnType, Oid languageOid,
* parameters: list of FunctionParameter structs
* languageOid: OID of function language (InvalidOid if it's CREATE AGGREGATE)
* is_aggregate: needed only to determine error handling
- * queryString: likewise, needed only for error handling
*
* Results are stored into output parameters. parameterTypes must always
* be created, but the other arrays are set to NULL if not needed.
@@ -177,10 +176,10 @@ compute_return_type(TypeName *returnType, Oid languageOid,
* else it is set to the OID of the implied result type.
*/
void
-interpret_function_parameter_list(List *parameters,
+interpret_function_parameter_list(ParseState *pstate,
+ List *parameters,
Oid languageOid,
bool is_aggregate,
- const char *queryString,
oidvector **parameterTypes,
ArrayType **allParameterTypes,
ArrayType **parameterModes,
@@ -201,7 +200,6 @@ interpret_function_parameter_list(List *parameters,
bool have_defaults = false;
ListCell *x;
int i;
- ParseState *pstate;
*variadicArgType = InvalidOid; /* default result */
*requiredResultType = InvalidOid; /* default result */
@@ -212,10 +210,6 @@ interpret_function_parameter_list(List *parameters,
paramNames = (Datum *) palloc0(parameterCount * sizeof(Datum));
*parameterDefaults = NIL;
- /* may need a pstate for parse analysis of default exprs */
- pstate = make_parsestate(NULL);
- pstate->p_sourcetext = queryString;
-
/* Scan the list and extract data into work arrays */
i = 0;
foreach(x, parameters)
@@ -413,8 +407,6 @@ interpret_function_parameter_list(List *parameters,
i++;
}
- free_parsestate(pstate);
-
/* Now construct the proper outputs as needed */
*parameterTypes = buildoidvector(inTypes, inCount);
@@ -458,7 +450,8 @@ interpret_function_parameter_list(List *parameters,
* SET parameters though --- if you're redundant, the last one wins.)
*/
static bool
-compute_common_attribute(DefElem *defel,
+compute_common_attribute(ParseState *pstate,
+ DefElem *defel,
DefElem **volatility_item,
DefElem **strict_item,
DefElem **security_item,
@@ -530,7 +523,8 @@ compute_common_attribute(DefElem *defel,
duplicate_error:
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("conflicting or redundant options")));
+ errmsg("conflicting or redundant options"),
+ parser_errposition(pstate, defel->location)));
return false; /* keep compiler quiet */
}
@@ -609,7 +603,8 @@ update_proconfig_value(ArrayType *a, List *set_items)
* attributes.
*/
static void
-compute_attributes_sql_style(List *options,
+compute_attributes_sql_style(ParseState *pstate,
+ List *options,
List **as,
char **language,
Node **transform,
@@ -646,7 +641,8 @@ compute_attributes_sql_style(List *options,
if (as_item)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("conflicting or redundant options")));
+ errmsg("conflicting or redundant options"),
+ parser_errposition(pstate, defel->location)));
as_item = defel;
}
else if (strcmp(defel->defname, "language") == 0)
@@ -654,7 +650,8 @@ compute_attributes_sql_style(List *options,
if (language_item)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("conflicting or redundant options")));
+ errmsg("conflicting or redundant options"),
+ parser_errposition(pstate, defel->location)));
language_item = defel;
}
else if (strcmp(defel->defname, "transform") == 0)
@@ -662,7 +659,8 @@ compute_attributes_sql_style(List *options,
if (transform_item)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("conflicting or redundant options")));
+ errmsg("conflicting or redundant options"),
+ parser_errposition(pstate, defel->location)));
transform_item = defel;
}
else if (strcmp(defel->defname, "window") == 0)
@@ -670,10 +668,12 @@ compute_attributes_sql_style(List *options,
if (windowfunc_item)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("conflicting or redundant options")));
+ errmsg("conflicting or redundant options"),
+ parser_errposition(pstate, defel->location)));
windowfunc_item = defel;
}
- else if (compute_common_attribute(defel,
+ else if (compute_common_attribute(pstate,
+ defel,
&volatility_item,
&strict_item,
&security_item,
@@ -763,7 +763,7 @@ compute_attributes_sql_style(List *options,
*------------
*/
static void
-compute_attributes_with_style(List *parameters, bool *isStrict_p, char *volatility_p)
+compute_attributes_with_style(ParseState *pstate, List *parameters, bool *isStrict_p, char *volatility_p)
{
ListCell *pl;
@@ -783,7 +783,8 @@ compute_attributes_with_style(List *parameters, bool *isStrict_p, char *volatili
ereport(WARNING,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("unrecognized function attribute \"%s\" ignored",
- param->defname)));
+ param->defname),
+ parser_errposition(pstate, param->location)));
}
}
@@ -858,7 +859,7 @@ interpret_AS_clause(Oid languageOid, const char *languageName,
* Execute a CREATE FUNCTION utility statement.
*/
ObjectAddress
-CreateFunction(CreateFunctionStmt *stmt, const char *queryString)
+CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt)
{
char *probin_str;
char *prosrc_str;
@@ -915,7 +916,8 @@ CreateFunction(CreateFunctionStmt *stmt, const char *queryString)
parallel = PROPARALLEL_UNSAFE;
/* override attributes from explicit list */
- compute_attributes_sql_style(stmt->options,
+ compute_attributes_sql_style(pstate,
+ stmt->options,
&as_clause, &language, &transformDefElem,
&isWindowFunc, &volatility,
&isStrict, &security, &isLeakProof,
@@ -987,10 +989,10 @@ CreateFunction(CreateFunctionStmt *stmt, const char *queryString)
* Convert remaining parameters of CREATE to form wanted by
* ProcedureCreate.
*/
- interpret_function_parameter_list(stmt->parameters,
+ interpret_function_parameter_list(pstate,
+ stmt->parameters,
languageOid,
false, /* not an aggregate */
- queryString,
&parameterTypes,
&allParameterTypes,
&parameterModes,
@@ -1045,7 +1047,7 @@ CreateFunction(CreateFunctionStmt *stmt, const char *queryString)
trftypes = NULL;
}
- compute_attributes_with_style(stmt->withClause, &isStrict, &volatility);
+ compute_attributes_with_style(pstate, stmt->withClause, &isStrict, &volatility);
interpret_AS_clause(languageOid, language, funcname, as_clause,
&prosrc_str, &probin_str);
@@ -1163,7 +1165,7 @@ RemoveFunctionById(Oid funcOid)
* ALTER framework).
*/
ObjectAddress
-AlterFunction(AlterFunctionStmt *stmt)
+AlterFunction(ParseState *pstate, AlterFunctionStmt *stmt)
{
HeapTuple tup;
Oid funcOid;
@@ -1208,7 +1210,8 @@ AlterFunction(AlterFunctionStmt *stmt)
{
DefElem *defel = (DefElem *) lfirst(l);
- if (compute_common_attribute(defel,
+ if (compute_common_attribute(pstate,
+ defel,
&volatility_item,
&strict_item,
&security_def_item,