diff --git a/src/common/backend/utils/misc/guc/guc_sql.cpp b/src/common/backend/utils/misc/guc/guc_sql.cpp index 420529c78384e43dcfafdc6e1fc0ff825f3dc81c..cbb1b8ccca49336a64cadb4cb11b0be96ffbe328 100755 --- a/src/common/backend/utils/misc/guc/guc_sql.cpp +++ b/src/common/backend/utils/misc/guc/guc_sql.cpp @@ -345,7 +345,8 @@ static const struct b_format_behavior_compat_entry b_format_behavior_compat_opti {"set_session_transaction", B_FORMAT_OPT_ENABLE_SET_SESSION_TRANSACTION}, {"enable_set_variables", B_FORMAT_OPT_ENABLE_SET_VARIABLES}, {"enable_modify_column", B_FORMAT_OPT_ENABLE_MODIFY_COLUMN}, - {"default_collation", B_FORMAT_OPT_DEFAULT_COLLATION} + {"default_collation", B_FORMAT_OPT_DEFAULT_COLLATION}, + {"fetch", B_FORMAT_OPT_FETCH} }; typedef struct behavior_compat_entry { @@ -3334,7 +3335,8 @@ static bool b_format_forbid_distribute_parameter(const char *elem) const char *forbidList[] = { "set_session_transaction", "enable_set_variables", - "enable_modify_column" + "enable_modify_column", + "fetch" }; for (int i = 0; i < B_FORMAT_FORBID_GUC_NUM; i++) { if (strcmp(forbidList[i], elem) == 0) { diff --git a/src/common/pl/plpgsql/src/pl_exec.cpp b/src/common/pl/plpgsql/src/pl_exec.cpp index 98f81398d9612f201aa85afcf1ad25ca9507d49a..296b83d83ab8e7b343a8319207772870549e6d7e 100644 --- a/src/common/pl/plpgsql/src/pl_exec.cpp +++ b/src/common/pl/plpgsql/src/pl_exec.cpp @@ -7531,6 +7531,10 @@ static int exec_stmt_fetch(PLpgSQL_execstate* estate, PLpgSQL_stmt_fetch* stmt) exec_set_found(estate, n != 0); exec_set_cursor_found(estate, (n != 0) ? PLPGSQL_TRUE : PLPGSQL_FALSE, stmt->curvar + CURSOR_FOUND); exec_set_notfound(estate, (n == 0) ? PLPGSQL_TRUE : PLPGSQL_FALSE, stmt->curvar + CURSOR_NOTFOUND); + + if (B_FETCH && n == 0) { + return PLPGSQL_RC_EXIT; + } exec_set_rowcount(estate, n, false, stmt->curvar + CURSOR_ROWCOUNT); return PLPGSQL_RC_OK; diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index f7f203cf63618dba75e49403e421e817ae64812a..a08c795049a7f821ec826289f3fa117b8b9c4809 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -140,7 +140,8 @@ extern bool contain_backend_version(uint32 version_number); #define B_FORMAT_OPT_ENABLE_SET_VARIABLES 2 #define B_FORMAT_OPT_ENABLE_MODIFY_COLUMN 4 #define B_FORMAT_OPT_DEFAULT_COLLATION 8 -#define B_FORMAT_OPT_MAX 4 +#define B_FORMAT_OPT_FETCH 16 +#define B_FORMAT_OPT_MAX 5 #define ENABLE_SET_SESSION_TRANSACTION \ ((u_sess->utils_cxt.b_format_behavior_compat_flags & B_FORMAT_OPT_ENABLE_SET_SESSION_TRANSACTION) && \ @@ -151,6 +152,8 @@ extern bool contain_backend_version(uint32 version_number); #define ENABLE_MODIFY_COLUMN \ ((u_sess->utils_cxt.b_format_behavior_compat_flags & B_FORMAT_OPT_ENABLE_MODIFY_COLUMN) && \ u_sess->attr.attr_sql.sql_compatibility == B_FORMAT) +#define B_FETCH ((u_sess->utils_cxt.b_format_behavior_compat_flags & B_FORMAT_OPT_FETCH) && \ + u_sess->attr.attr_sql.sql_compatibility == B_FORMAT) #define OPT_DISPLAY_LEADING_ZERO 1 #define OPT_END_MONTH_CALCULATE 2 @@ -218,7 +221,7 @@ extern bool contain_backend_version(uint32 version_number); #define PLSQL_COMPILE_FOR_LOOP (u_sess->utils_cxt.plsql_compile_behavior_compat_flags & PLPSQL_OPT_FOR_LOOP) #define PLSQL_COMPILE_OUTPARAM (u_sess->utils_cxt.plsql_compile_behavior_compat_flags & PLPSQL_OPT_OUTPARAM) - + #define SELECT_INTO_RETURN_NULL (u_sess->utils_cxt.behavior_compat_flags & OPT_SELECT_INTO_RETURN_NULL) /* define database compatibility Attribute */ diff --git a/src/test/regress/expected/mysql_syntax.out b/src/test/regress/expected/mysql_syntax.out index 47ea7ff96ba281f386ce9f77317954dfad05b64a..69c508be27a9e0205db23594486cc38d76fb86d1 100644 --- a/src/test/regress/expected/mysql_syntax.out +++ b/src/test/regress/expected/mysql_syntax.out @@ -296,6 +296,51 @@ begin close c1_all; end if; end +-- mysql fetch 自动退出 +show b_format_behavior_compat_options; + b_format_behavior_compat_options +---------------------------------- + +(1 row) + +set b_format_behavior_compat_options = 'fetch'; +create or replace procedure test_cursor_1 +as + company_name varchar(100); + company_loc varchar(100); + company_no integer; + +begin + declare c1_all cursor is --cursor without args + select name, loc, no from company order by 1, 2, 3; + if not c1_all%isopen then + open c1_all; + end if; + loop + fetch c1_all into company_name, company_loc, company_no; + raise notice '% : % : %',company_name,company_loc,company_no; + end loop; + if c1_all%isopen then + close c1_all; + end if; +end; +/ +call test_cursor_1(); +NOTICE: backberry : canada : 3 +NOTICE: macrosoft : usa : 1 +NOTICE: oracle : usa : 2 + test_cursor_1 +--------------- + +(1 row) + +set b_format_behavior_compat_options = ''; +show b_format_behavior_compat_options; + b_format_behavior_compat_options +---------------------------------- + +(1 row) + -- test declare condition create or replace procedure test_condition_1 as declare diff --git a/src/test/regress/sql/mysql_syntax.sql b/src/test/regress/sql/mysql_syntax.sql index 09c9e78c91dfdccd1f1e2c441f8383821b0c5814..569d7f01ad66b4f776dfba2cc71b53df8aa7a958 100644 --- a/src/test/regress/sql/mysql_syntax.sql +++ b/src/test/regress/sql/mysql_syntax.sql @@ -241,6 +241,33 @@ begin end if; end; / +-- mysql fetch 自动退出 +show b_format_behavior_compat_options; +set b_format_behavior_compat_options = 'fetch'; +create or replace procedure test_cursor_1 +as + company_name varchar(100); + company_loc varchar(100); + company_no integer; + +begin + declare c1_all cursor is --cursor without args + select name, loc, no from company order by 1, 2, 3; + if not c1_all%isopen then + open c1_all; + end if; + loop + fetch c1_all into company_name, company_loc, company_no; + raise notice '% : % : %',company_name,company_loc,company_no; + end loop; + if c1_all%isopen then + close c1_all; + end if; +end; +/ +call test_cursor_1(); +set b_format_behavior_compat_options = ''; +show b_format_behavior_compat_options; -- test declare condition create or replace procedure test_condition_1 as declare