From e6e765493ebfbe4ae68859d8928c771aa14a22a0 Mon Sep 17 00:00:00 2001 From: nnuanyang Date: Wed, 21 Dec 2022 00:15:10 -0800 Subject: [PATCH] condition value fix_bug --- src/common/pl/plpgsql/src/gram.y | 27 +++++++++++++-- src/test/regress/expected/mysql_syntax.out | 40 ++++++++++++++++++++++ src/test/regress/sql/mysql_syntax.sql | 28 +++++++++++++++ 3 files changed, 92 insertions(+), 3 deletions(-) diff --git a/src/common/pl/plpgsql/src/gram.y b/src/common/pl/plpgsql/src/gram.y index 5c44a52ac..f3b5b1cea 100755 --- a/src/common/pl/plpgsql/src/gram.y +++ b/src/common/pl/plpgsql/src/gram.y @@ -772,10 +772,31 @@ declare_stmt : T_DECLARE_CURSOR decl_varname K_CURSOR opt_scrollable condition_value : K_SQLSTATE { - /* next token should be a string literal */ char *sqlstatestr; - if (yylex() != SCONST) - yyerror("syntax error"); + yylex(); + if (strcmp(yylval.str, "value") ==0) { + yylex(); + } + sqlstatestr = yylval.str; + + if (strlen(sqlstatestr) != 5) + yyerror("invalid SQLSTATE code"); + if (strspn(sqlstatestr, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != 5) + yyerror("invalid SQLSTATE code"); + if (strncmp(sqlstatestr, "00", 2) == 0) { + const char* message = "bad SQLSTATE"; + InsertErrorMessage(message, plpgsql_yylloc); + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION), + errmsg("bad SQLSTATE '%s'",sqlstatestr))); + } + + $$ = MAKE_SQLSTATE(sqlstatestr[0], + sqlstatestr[1], + sqlstatestr[2], + sqlstatestr[3], + sqlstatestr[4]); + sqlstatestr = yylval.str; if (strlen(sqlstatestr) != 5) diff --git a/src/test/regress/expected/mysql_syntax.out b/src/test/regress/expected/mysql_syntax.out index 4edc6fb99..47ea7ff96 100644 --- a/src/test/regress/expected/mysql_syntax.out +++ b/src/test/regress/expected/mysql_syntax.out @@ -402,6 +402,46 @@ END; / ERROR: bad SQLSTATE '00000' CONTEXT: compilation of PL/pgSQL function "test_condition_6" near line 3 +create or replace procedure test_condition_1 as +declare + a int; +BEGIN + declare DIVISION_ZERO condition for SQLSTATE value '22012'; + a := 1/0; +exception + when DIVISION_ZERO then + BEGIN + RAISE NOTICE 'SQLSTATE = %, SQLERRM = %', SQLSTATE,SQLERRM; + END; +END; +/ +call test_condition_1(); +NOTICE: SQLSTATE = 22012, SQLERRM = division by zero + test_condition_1 +------------------ + +(1 row) + +create or replace procedure test_condition_1 as +declare + a int; +BEGIN + declare DIVISION_ZERO condition for SQLSTATE "22012"; + a := 1/0; +exception + when DIVISION_ZERO then + BEGIN + RAISE NOTICE 'SQLSTATE = %, SQLERRM = %', SQLSTATE,SQLERRM; + END; +END; +/ +call test_condition_1(); +NOTICE: SQLSTATE = 22012, SQLERRM = division by zero + test_condition_1 +------------------ + +(1 row) + \c regression drop trigger animal_trigger1; ERROR: drop trigger without table name only support in B-format database diff --git a/src/test/regress/sql/mysql_syntax.sql b/src/test/regress/sql/mysql_syntax.sql index d965d10cf..09c9e78c9 100644 --- a/src/test/regress/sql/mysql_syntax.sql +++ b/src/test/regress/sql/mysql_syntax.sql @@ -310,6 +310,34 @@ BEGIN RAISE NOTICE 'declare condition successed'; END; / +create or replace procedure test_condition_1 as +declare + a int; +BEGIN + declare DIVISION_ZERO condition for SQLSTATE value '22012'; + a := 1/0; +exception + when DIVISION_ZERO then + BEGIN + RAISE NOTICE 'SQLSTATE = %, SQLERRM = %', SQLSTATE,SQLERRM; + END; +END; +/ +call test_condition_1(); +create or replace procedure test_condition_1 as +declare + a int; +BEGIN + declare DIVISION_ZERO condition for SQLSTATE "22012"; + a := 1/0; +exception + when DIVISION_ZERO then + BEGIN + RAISE NOTICE 'SQLSTATE = %, SQLERRM = %', SQLSTATE,SQLERRM; + END; +END; +/ +call test_condition_1(); \c regression drop trigger animal_trigger1;