On Tue, Oct 15, 2024 at 12:45 AM Tom Lane <t...@sss.pgh.pa.us> wrote:
>
> jian he <jian.universal...@gmail.com> writes:
> > On Mon, Oct 14, 2024 at 1:13 AM Tom Lane <t...@sss.pgh.pa.us> wrote:
> >> Right, but we might not have entered either of those previous
> >> if-blocks.
>
> > in src/backend/parser/gram.y
> > your makeRawStmt changes (v4) seem to guarantee that
> > RawStmt->stmt_location >= 0.
>
> Yes, I would expect that any RawStmt we see here will have valid
> stmt_location.  What you seem to be missing is that an error could
> be thrown from
>
> >     raw_parsetree_list = pg_parse_query(sql);
>
> before execute_sql_string reaches its loop over RawStmts.  In that
> case we'll reach script_error_callback with callback_arg.stmt_location
> still being -1.
>
Thanks for your reply.
I think I got it.



        if (location < 0 || syntaxerrposition < location ||
            (len > 0 && syntaxerrposition > location + len))
        {
            int            slen = strlen(query);
            location = len = 0;
            .....
        }
        else
            elog(INFO, "should not reached here");

just found out the"elog(INFO, "should not reached here");" part never reached.
in script_error_callback, for syntax error (error while parsing the raw string.)
we can bookkeeping the line number.

so we don't need to loop it again for syntax error in:
        for (query = callback_arg->sql; *query; query++)
        {
            if (--location < 0)
                break;
            if (*query == '\n')
                linenumber++;
        }
since we already did it in loop
"for (int loc = 0; loc < slen; loc++)"


i guess, we don't need performance in script_error_callback,
but in script_error_callback arrange code seperate  syntax error(raw
parser) and other error seems good.
please check the attached minor refactor.
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index 86ea9cd9da..ff7d77f8e9 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -692,6 +692,8 @@ script_error_callback(void *arg)
 	const char *query = callback_arg->sql;
 	int			location = callback_arg->stmt_location;
 	int			len = callback_arg->stmt_len;
+	bool		raw_syntaxerr = false;
+	int			syntaxerrline_no = 0;
 	int			syntaxerrposition;
 	const char *lastslash;
 
@@ -730,6 +732,8 @@ script_error_callback(void *arg)
 			location = len = 0;
 			for (int loc = 0; loc < slen; loc++)
 			{
+				if (query[loc] == '\n')
+					syntaxerrline_no++;
 				if (query[loc] != ';')
 					continue;
 				if (query[loc + 1] == '\r')
@@ -766,6 +770,7 @@ script_error_callback(void *arg)
 		errposition(0);
 		internalerrposition(syntaxerrposition);
 		internalerrquery(pnstrdup(query, len));
+		raw_syntaxerr = true;
 	}
 	else if (location >= 0)
 	{
@@ -794,17 +799,22 @@ script_error_callback(void *arg)
 	 */
 	if (location >= 0)
 	{
-		int			linenumber = 1;
-
-		for (query = callback_arg->sql; *query; query++)
+		if (!raw_syntaxerr)
 		{
-			if (--location < 0)
-				break;
-			if (*query == '\n')
-				linenumber++;
+			int			linenumber = 1;
+			for (query = callback_arg->sql; *query; query++)
+			{
+				if (--location < 0)
+					break;
+				if (*query == '\n')
+					linenumber++;
+			}
+			errcontext("extension script file \"%s\", near line %d",
+					lastslash, linenumber);
 		}
-		errcontext("extension script file \"%s\", near line %d",
-				   lastslash, linenumber);
+		else
+			errcontext("extension script file \"%s\", near line %d",
+					lastslash, syntaxerrline_no);
 	}
 	else
 		errcontext("extension script file \"%s\"", lastslash);

Reply via email to