1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-16 06:01:02 +03:00

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>
This commit is contained in:
Peter Eisentraut
2016-09-06 12:00:00 -04:00
parent 975768f8ea
commit 49eb0fd097
38 changed files with 438 additions and 347 deletions

View File

@ -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,