Provide query source text when parsing a SQL-standard function body.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 15 Apr 2021 21:24:12 +0000 (17:24 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 15 Apr 2021 21:24:12 +0000 (17:24 -0400)
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

src/backend/commands/functioncmds.c
src/test/regress/expected/create_function_3.out

index dc317c83afc36487168192eebc4a898c0aba41f6..e7cb5c65e9a45e81f284ee56160ba101d5c00144 100644 (file)
@@ -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;
index ce480890127a68a5cf9509f242d9b9320489d19d..5b6bc5eddbe759e8d95186752d94d79fc4913eb6 100644 (file)
@@ -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