diff --git a/mysql-test/suite/compat/oracle/r/sp.result b/mysql-test/suite/compat/oracle/r/sp.result new file mode 100644 index 0000000000000000000000000000000000000000..99845551f1bf87ff71927dd29099a96bb4c356e8 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp.result @@ -0,0 +1,68 @@ +SET sql_mode=ORACLE; +CREATE FUNCTION f1 (a INT) RETURNS CLOB +BEGIN +<<label1>> +BEGIN +IF a = 1 THEN +LEAVE label1; +END IF; +RETURN 'IS NOT 1'; +END label1; +RETURN 'IS 1'; +END; +/ +SELECT f1(1); +f1(1) +IS 1 +SELECT f1(2); +f1(2) +IS NOT 1 +DROP FUNCTION f1; +CREATE FUNCTION f1 (a INT) RETURNS INT +BEGIN +<<label1>> +LOOP +IF a = 2 THEN +LEAVE label1; +END IF; +SET a= a-1; +END LOOP; +RETURN a; +END; +/ +SELECT f1(4); +f1(4) +2 +DROP FUNCTION f1; +CREATE FUNCTION f1 (a INT) RETURNS INT +BEGIN +<<label1>> +WHILE a>0 DO +IF a = 2 THEN +LEAVE label1; +END IF; +SET a= a-1; +END WHILE label1; +RETURN a; +END; +/ +SELECT f1(4); +f1(4) +2 +DROP FUNCTION f1; +CREATE FUNCTION f1 (a INT) RETURNS INT +BEGIN +<<label1>> +REPEAT +IF a = 2 THEN +LEAVE label1; +END IF; +SET a= a-1; +UNTIL a=0 END REPEAT; +RETURN a; +END; +/ +SELECT f1(4); +f1(4) +2 +DROP FUNCTION f1; diff --git a/mysql-test/suite/compat/oracle/t/sp.test b/mysql-test/suite/compat/oracle/t/sp.test new file mode 100644 index 0000000000000000000000000000000000000000..ad55f4006a38aab46a4dd3585cb30ac850c17b39 --- /dev/null +++ b/mysql-test/suite/compat/oracle/t/sp.test @@ -0,0 +1,74 @@ +SET sql_mode=ORACLE; + +DELIMITER /; +CREATE FUNCTION f1 (a INT) RETURNS CLOB +BEGIN + <<label1>> + BEGIN + IF a = 1 THEN + LEAVE label1; + END IF; + RETURN 'IS NOT 1'; + END label1; + RETURN 'IS 1'; +END; +/ +DELIMITER ;/ +SELECT f1(1); +SELECT f1(2); +DROP FUNCTION f1; + +# LOOP WHILE REPEAT + +DELIMITER /; +CREATE FUNCTION f1 (a INT) RETURNS INT +BEGIN + <<label1>> + LOOP + IF a = 2 THEN + LEAVE label1; + END IF; + SET a= a-1; + END LOOP; + RETURN a; +END; +/ +DELIMITER ;/ +SELECT f1(4); +DROP FUNCTION f1; + + +DELIMITER /; +CREATE FUNCTION f1 (a INT) RETURNS INT +BEGIN + <<label1>> + WHILE a>0 DO + IF a = 2 THEN + LEAVE label1; + END IF; + SET a= a-1; + END WHILE label1; + RETURN a; +END; +/ +DELIMITER ;/ +SELECT f1(4); +DROP FUNCTION f1; + + +DELIMITER /; +CREATE FUNCTION f1 (a INT) RETURNS INT +BEGIN + <<label1>> + REPEAT + IF a = 2 THEN + LEAVE label1; + END IF; + SET a= a-1; + UNTIL a=0 END REPEAT; + RETURN a; +END; +/ +DELIMITER ;/ +SELECT f1(4); +DROP FUNCTION f1; diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index 19cfe41470da44be931410f9ae92e08f4f00e086..0d1b61fdc1a7270e6ef3cf540d89376b0cc0b751 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -1059,6 +1059,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); opt_component key_cache_name sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem ident_or_empty opt_constraint constraint opt_ident + label_declaration_oracle %type <lex_string_with_metadata> TEXT_STRING @@ -3507,7 +3508,7 @@ sp_opt_label: ; sp_labeled_block: - label_ident ':' BEGIN_SYM + label_declaration_oracle BEGIN_SYM { LEX *lex= Lex; sp_pcontext *ctx= lex->spcont; @@ -3519,10 +3520,10 @@ sp_labeled_block: } sp_block_content sp_opt_label { - if ($6.str) + if ($5.str) { - if (my_strcasecmp(system_charset_info, $6.str, $5->name.str) != 0) - my_yyabort_error((ER_SP_LABEL_MISMATCH, MYF(0), $6.str)); + if (my_strcasecmp(system_charset_info, $5.str, $4->name.str) != 0) + my_yyabort_error((ER_SP_LABEL_MISMATCH, MYF(0), $5.str)); } } ; @@ -3675,14 +3676,14 @@ pop_sp_empty_label: ; sp_labeled_control: - label_ident ':' LOOP_SYM + label_declaration_oracle LOOP_SYM { if (push_sp_label(thd, $1)) MYSQL_YYABORT; } loop_body pop_sp_label { } - | label_ident ':' WHILE_SYM + | label_declaration_oracle WHILE_SYM { if (push_sp_label(thd, $1)) MYSQL_YYABORT; @@ -3690,7 +3691,7 @@ sp_labeled_control: } while_body pop_sp_label { } - | label_ident ':' REPEAT_SYM + | label_declaration_oracle REPEAT_SYM { if (push_sp_label(thd, $1)) MYSQL_YYABORT; @@ -13808,6 +13809,10 @@ label_ident: } ; +label_declaration_oracle: + SHIFT_LEFT label_ident SHIFT_RIGHT { $$= $2; } + ; + ident_or_text: ident { $$=$1;} | TEXT_STRING_sys { $$=$1;}