From: Tom Lane Date: Thu, 15 Apr 2021 21:24:12 +0000 (-0400) Subject: Provide query source text when parsing a SQL-standard function body. X-Git-Tag: REL_14_BETA1~209 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=409723365b2708acd3bdf2e830257504bdefac4b;p=thirdparty%2Fpostgresql.git Provide query source text when parsing a SQL-standard function body. Without this, we lose error cursor positions, as shown in the modified regression test result. Discussion: https://postgr.es/m/2197698.1617984583@sss.pgh.pa.us --- diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index dc317c83afc..e7cb5c65e9a 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -852,7 +852,9 @@ static void interpret_AS_clause(Oid languageOid, const char *languageName, char *funcname, List *as, Node *sql_body_in, List *parameterTypes, List *inParameterNames, - char **prosrc_str_p, char **probin_str_p, Node **sql_body_out) + char **prosrc_str_p, char **probin_str_p, + Node **sql_body_out, + const char *queryString) { if (!sql_body_in && !as) ereport(ERROR, @@ -929,6 +931,7 @@ interpret_AS_clause(Oid languageOid, const char *languageName, Query *q; ParseState *pstate = make_parsestate(NULL); + pstate->p_sourcetext = queryString; sql_fn_parser_setup(pstate, pinfo); q = transformStmt(pstate, stmt); if (q->commandType == CMD_UTILITY) @@ -947,6 +950,7 @@ interpret_AS_clause(Oid languageOid, const char *languageName, Query *q; ParseState *pstate = make_parsestate(NULL); + pstate->p_sourcetext = queryString; sql_fn_parser_setup(pstate, pinfo); q = transformStmt(pstate, sql_body_in); if (q->commandType == CMD_UTILITY) @@ -954,6 +958,7 @@ interpret_AS_clause(Oid languageOid, const char *languageName, errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("%s is not yet supported in unquoted SQL function body", GetCommandTagName(CreateCommandTag(q->utilityStmt)))); + free_parsestate(pstate); *sql_body_out = (Node *) q; } @@ -1220,7 +1225,8 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt) interpret_AS_clause(languageOid, language, funcname, as_clause, stmt->sql_body, parameterTypes_list, inParameterNames_list, - &prosrc_str, &probin_str, &prosqlbody); + &prosrc_str, &probin_str, &prosqlbody, + pstate->p_sourcetext); /* * Set default values for COST and ROWS depending on other parameters; diff --git a/src/test/regress/expected/create_function_3.out b/src/test/regress/expected/create_function_3.out index ce480890127..5b6bc5eddbe 100644 --- a/src/test/regress/expected/create_function_3.out +++ b/src/test/regress/expected/create_function_3.out @@ -295,6 +295,8 @@ CREATE FUNCTION functest_S_xx(x date) RETURNS boolean LANGUAGE SQL RETURN x > 1; ERROR: operator does not exist: date > integer +LINE 3: RETURN x > 1; + ^ HINT: No operator matches the given name and argument types. You might need to add explicit type casts. -- tricky parsing CREATE FUNCTION functest_S_15(x int) RETURNS boolean