diff options
author | Peter Eisentraut <peter_e@gmx.net> | 2016-09-06 12:00:00 -0400 |
---|---|---|
committer | Peter Eisentraut <peter_e@gmx.net> | 2016-09-06 12:00:00 -0400 |
commit | 49eb0fd0972d14014dd3533b1f1bf8c94c899883 (patch) | |
tree | bcbfa5cf8f49c1b73066a5c4eaf80f33fc4ecc53 /src/backend/commands/functioncmds.c | |
parent | 975768f8eae2581b89ceafe8b16a77ff375207fe (diff) | |
download | postgresql-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.c | 57 |
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, ¶meterTypes, &allParameterTypes, ¶meterModes, @@ -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, |