From 02a72cf87c51cf3e33627e1f358d18205f7bba3b Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Mon, 19 Sep 2016 09:43:00 +0400 Subject: [PATCH] MDEV-10596 Allow VARCHAR and VARCHAR2 without length as a data type of routine parameters and in RETURN clause --- .../suite/compat/oracle/r/sp-code.result | 70 ++++---- .../suite/compat/oracle/r/sp-param.result | 132 ++++++++++++++ mysql-test/suite/compat/oracle/t/sp-param.inc | 9 + .../suite/compat/oracle/t/sp-param.test | 37 ++++ sql/sql_yacc_ora.yy | 169 +++++++++++++++--- 5 files changed, 360 insertions(+), 57 deletions(-) create mode 100644 mysql-test/suite/compat/oracle/r/sp-param.result create mode 100644 mysql-test/suite/compat/oracle/t/sp-param.inc create mode 100644 mysql-test/suite/compat/oracle/t/sp-param.test diff --git a/mysql-test/suite/compat/oracle/r/sp-code.result b/mysql-test/suite/compat/oracle/r/sp-code.result index d96028d6e4dc3..f9691d18cccfd 100644 --- a/mysql-test/suite/compat/oracle/r/sp-code.result +++ b/mysql-test/suite/compat/oracle/r/sp-code.result @@ -652,19 +652,19 @@ Pos Instruction 0 set total@4 0 1 set ia@5 1 2 set [upper_bound]@6 a@0 -3 jump_if_not 17(17) (ia@5 <= [upper_bound]@6) -4 set total@4 (total@4 + 1000) +3 jump_if_not 17(17) ia@5 <= [upper_bound]@6 +4 set total@4 total@4 + 1000 5 set ib@7 1 6 set [upper_bound]@8 b@2 -7 jump_if_not 15(15) (ib@7 <= [upper_bound]@8) -8 set total@4 (total@4 + 1) -9 jump_if_not 11(0) (ib@7 = limitb@3) +7 jump_if_not 15(15) ib@7 <= [upper_bound]@8 +8 set total@4 total@4 + 1 +9 jump_if_not 11(0) ib@7 = limitb@3 10 jump 15 -11 jump_if_not 13(0) (ia@5 = limita@1) +11 jump_if_not 13(0) ia@5 = limita@1 12 jump 17 -13 set ib@7 (ib@7 + 1) +13 set ib@7 ib@7 + 1 14 jump 7 -15 set ia@5 (ia@5 + 1) +15 set ia@5 ia@5 + 1 16 jump 3 17 freturn 3 total@4 SELECT f1(2, 1, 2, 2) FROM DUAL; @@ -699,13 +699,13 @@ Pos Instruction 0 set total@1 0 1 set i@2 1 2 set [upper_bound]@3 a@0 -3 jump_if_not 11(11) (i@2 <= [upper_bound]@3) -4 set total@1 (total@1 + 1000) -5 jump_if_not 8(8) (i@2 = 5) -6 set i@2 (i@2 + 1) +3 jump_if_not 11(11) i@2 <= [upper_bound]@3 +4 set total@1 total@1 + 1000 +5 jump_if_not 8(8) i@2 = 5 +6 set i@2 i@2 + 1 7 jump 3 -8 set total@1 (total@1 + 1) -9 set i@2 (i@2 + 1) +8 set total@1 total@1 + 1 +9 set i@2 i@2 + 1 10 jump 3 11 freturn 3 total@1 SELECT f1(3), f1(4), f1(5), f1(6) FROM DUAL; @@ -736,18 +736,18 @@ Pos Instruction 0 set total@1 0 1 set i@2 1 2 set [upper_bound]@3 a@0 -3 jump_if_not 16(16) (i@2 <= [upper_bound]@3) +3 jump_if_not 16(16) i@2 <= [upper_bound]@3 4 set j@4 1 5 set [upper_bound]@5 2 -6 jump_if_not 14(14) (j@4 <= [upper_bound]@5) -7 set total@1 (total@1 + 1000) -8 jump_if_not 11(11) (i@2 = 5) -9 set i@2 (i@2 + 1) +6 jump_if_not 14(14) j@4 <= [upper_bound]@5 +7 set total@1 total@1 + 1000 +8 jump_if_not 11(11) i@2 = 5 +9 set i@2 i@2 + 1 10 jump 3 -11 set total@1 (total@1 + 1) -12 set j@4 (j@4 + 1) +11 set total@1 total@1 + 1 +12 set j@4 j@4 + 1 13 jump 6 -14 set i@2 (i@2 + 1) +14 set i@2 i@2 + 1 15 jump 3 16 freturn 3 total@1 SELECT f1(3), f1(4), f1(5), f1(6) FROM DUAL; @@ -779,18 +779,18 @@ Pos Instruction 0 set total@1 0 1 set j@2 1 2 set [upper_bound]@3 2 -3 jump_if_not 16(16) (j@2 <= [upper_bound]@3) +3 jump_if_not 16(16) j@2 <= [upper_bound]@3 4 set i@4 1 5 set [upper_bound]@5 a@0 -6 jump_if_not 14(14) (i@4 <= [upper_bound]@5) -7 set total@1 (total@1 + 1000) -8 jump_if_not 11(11) (i@4 = 5) -9 set i@4 (i@4 + 1) +6 jump_if_not 14(14) i@4 <= [upper_bound]@5 +7 set total@1 total@1 + 1000 +8 jump_if_not 11(11) i@4 = 5 +9 set i@4 i@4 + 1 10 jump 6 -11 set total@1 (total@1 + 1) -12 set i@4 (i@4 + 1) +11 set total@1 total@1 + 1 +12 set i@4 i@4 + 1 13 jump 6 -14 set j@2 (j@2 + 1) +14 set j@2 j@2 + 1 15 jump 3 16 freturn 3 total@1 SELECT f1(3), f1(4), f1(5), f1(6) FROM DUAL; @@ -815,12 +815,12 @@ Pos Instruction 0 set total@1 0 1 set i@2 1 2 set [upper_bound]@3 a@0 -3 jump_if_not 10(10) (i@2 <= [upper_bound]@3) -4 jump_if_not 7(0) (i@2 = 5) -5 set i@2 (i@2 + 1) +3 jump_if_not 10(10) i@2 <= [upper_bound]@3 +4 jump_if_not 7(0) i@2 = 5 +5 set i@2 i@2 + 1 6 jump 3 -7 set total@1 (total@1 + 1) -8 set i@2 (i@2 + 1) +7 set total@1 total@1 + 1 +8 set i@2 i@2 + 1 9 jump 3 10 freturn 3 total@1 SELECT f1(3), f1(4), f1(5), f1(6) FROM DUAL; diff --git a/mysql-test/suite/compat/oracle/r/sp-param.result b/mysql-test/suite/compat/oracle/r/sp-param.result new file mode 100644 index 0000000000000..4f4585c4570fb --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-param.result @@ -0,0 +1,132 @@ +SET sql_mode=ORACLE; +# +# MDEV-10596 Allow VARCHAR and VARCHAR2 without length as a data type of routine parameters and in RETURN clause +# +CREATE FUNCTION f1(param CHAR) RETURN CHAR AS BEGIN RETURN param; END;; +SHOW CREATE FUNCTION f1; +Function sql_mode Create Function character_set_client collation_connection Database Collation +f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param CHAR) RETURN varchar(2000) CHARSET latin1 +AS BEGIN RETURN param; END latin1 latin1_swedish_ci latin1_swedish_ci +SELECT LENGTH(f1(REPEAT('a',2000)));; +LENGTH(f1(REPEAT('a',2000))) +2000 +CREATE TABLE t1 AS SELECT f1(REPEAT('a',2000)) AS a;; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" text DEFAULT NULL +) +DROP TABLE t1; +DROP FUNCTION f1; +CREATE FUNCTION f1(param NCHAR) RETURN NCHAR AS BEGIN RETURN param; END;; +SHOW CREATE FUNCTION f1; +Function sql_mode Create Function character_set_client collation_connection Database Collation +f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param NCHAR) RETURN varchar(2000) CHARSET utf8 +AS BEGIN RETURN param; END latin1 latin1_swedish_ci latin1_swedish_ci +SELECT LENGTH(f1(REPEAT('a',2000)));; +LENGTH(f1(REPEAT('a',2000))) +2000 +CREATE TABLE t1 AS SELECT f1(REPEAT('a',2000)) AS a;; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" text CHARACTER SET utf8 DEFAULT NULL +) +DROP TABLE t1; +DROP FUNCTION f1; +CREATE FUNCTION f1(param BINARY) RETURN BINARY AS BEGIN RETURN param; END;; +SHOW CREATE FUNCTION f1; +Function sql_mode Create Function character_set_client collation_connection Database Collation +f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param BINARY) RETURN varbinary(2000) +AS BEGIN RETURN param; END latin1 latin1_swedish_ci latin1_swedish_ci +SELECT LENGTH(f1(REPEAT('a',2000)));; +LENGTH(f1(REPEAT('a',2000))) +2000 +CREATE TABLE t1 AS SELECT f1(REPEAT('a',2000)) AS a;; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" blob DEFAULT NULL +) +DROP TABLE t1; +DROP FUNCTION f1; +CREATE FUNCTION f1(param VARCHAR) RETURN VARCHAR AS BEGIN RETURN param; END;; +SHOW CREATE FUNCTION f1; +Function sql_mode Create Function character_set_client collation_connection Database Collation +f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param VARCHAR) RETURN varchar(4000) CHARSET latin1 +AS BEGIN RETURN param; END latin1 latin1_swedish_ci latin1_swedish_ci +SELECT LENGTH(f1(REPEAT('a',4000)));; +LENGTH(f1(REPEAT('a',4000))) +4000 +CREATE TABLE t1 AS SELECT f1(REPEAT('a',4000)) AS a;; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" text DEFAULT NULL +) +DROP TABLE t1; +DROP FUNCTION f1; +CREATE FUNCTION f1(param VARCHAR2) RETURN VARCHAR2 AS BEGIN RETURN param; END;; +SHOW CREATE FUNCTION f1; +Function sql_mode Create Function character_set_client collation_connection Database Collation +f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param VARCHAR2) RETURN varchar(4000) CHARSET latin1 +AS BEGIN RETURN param; END latin1 latin1_swedish_ci latin1_swedish_ci +SELECT LENGTH(f1(REPEAT('a',4000)));; +LENGTH(f1(REPEAT('a',4000))) +4000 +CREATE TABLE t1 AS SELECT f1(REPEAT('a',4000)) AS a;; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" text DEFAULT NULL +) +DROP TABLE t1; +DROP FUNCTION f1; +CREATE FUNCTION f1(param NVARCHAR) RETURN NVARCHAR AS BEGIN RETURN param; END;; +SHOW CREATE FUNCTION f1; +Function sql_mode Create Function character_set_client collation_connection Database Collation +f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param NVARCHAR) RETURN varchar(4000) CHARSET utf8 +AS BEGIN RETURN param; END latin1 latin1_swedish_ci latin1_swedish_ci +SELECT LENGTH(f1(REPEAT('a',4000)));; +LENGTH(f1(REPEAT('a',4000))) +4000 +CREATE TABLE t1 AS SELECT f1(REPEAT('a',4000)) AS a;; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" text CHARACTER SET utf8 DEFAULT NULL +) +DROP TABLE t1; +DROP FUNCTION f1; +CREATE FUNCTION f1(param VARBINARY) RETURN VARBINARY AS BEGIN RETURN param; END;; +SHOW CREATE FUNCTION f1; +Function sql_mode Create Function character_set_client collation_connection Database Collation +f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param VARBINARY) RETURN varbinary(4000) +AS BEGIN RETURN param; END latin1 latin1_swedish_ci latin1_swedish_ci +SELECT LENGTH(f1(REPEAT('a',4000)));; +LENGTH(f1(REPEAT('a',4000))) +4000 +CREATE TABLE t1 AS SELECT f1(REPEAT('a',4000)) AS a;; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" blob DEFAULT NULL +) +DROP TABLE t1; +DROP FUNCTION f1; +CREATE FUNCTION f1(param RAW) RETURN RAW AS BEGIN RETURN param; END;; +SHOW CREATE FUNCTION f1; +Function sql_mode Create Function character_set_client collation_connection Database Collation +f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param RAW) RETURN varbinary(4000) +AS BEGIN RETURN param; END latin1 latin1_swedish_ci latin1_swedish_ci +SELECT LENGTH(f1(REPEAT('a',4000)));; +LENGTH(f1(REPEAT('a',4000))) +4000 +CREATE TABLE t1 AS SELECT f1(REPEAT('a',4000)) AS a;; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" blob DEFAULT NULL +) +DROP TABLE t1; +DROP FUNCTION f1; diff --git a/mysql-test/suite/compat/oracle/t/sp-param.inc b/mysql-test/suite/compat/oracle/t/sp-param.inc new file mode 100644 index 0000000000000..35bce8accea18 --- /dev/null +++ b/mysql-test/suite/compat/oracle/t/sp-param.inc @@ -0,0 +1,9 @@ +--eval CREATE FUNCTION f1(param $type) RETURN $type AS BEGIN RETURN param; END; +SHOW CREATE FUNCTION f1; + +--eval SELECT LENGTH(f1(REPEAT('a',$length))); +--eval CREATE TABLE t1 AS SELECT f1(REPEAT('a',$length)) AS a; + +SHOW CREATE TABLE t1; +DROP TABLE t1; +DROP FUNCTION f1; diff --git a/mysql-test/suite/compat/oracle/t/sp-param.test b/mysql-test/suite/compat/oracle/t/sp-param.test new file mode 100644 index 0000000000000..23203317f504f --- /dev/null +++ b/mysql-test/suite/compat/oracle/t/sp-param.test @@ -0,0 +1,37 @@ +SET sql_mode=ORACLE; + +--echo # +--echo # MDEV-10596 Allow VARCHAR and VARCHAR2 without length as a data type of routine parameters and in RETURN clause +--echo # + +--let type = CHAR +--let length = 2000 +--source sp-param.inc + +--let type = NCHAR +--let length = 2000 +--source sp-param.inc + +--let type = BINARY +--let length = 2000 +--source sp-param.inc + +--let type = VARCHAR +--let length = 4000 +--source sp-param.inc + +--let type = VARCHAR2 +--let length = 4000 +--source sp-param.inc + +--let type = NVARCHAR +--let length = 4000 +--source sp-param.inc + +--let type = VARBINARY +--let length = 4000 +--source sp-param.inc + +--let type = RAW +--let length = 4000 +--source sp-param.inc diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index 9f8bdd1ef3812..417a140a9187b 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -1007,6 +1007,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); wild_and_where field_length opt_field_length opt_field_length_default_1 colon_with_pos + opt_field_length_default_sp_param_char + opt_field_length_default_sp_param_varchar %type opt_place @@ -1017,6 +1019,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type int_type real_type %type type_with_opt_collate field_type + sp_param_type_with_opt_collate + sp_param_field_type + sp_param_field_type_string + field_type_numeric + field_type_string + field_type_lob + field_type_temporal + field_type_misc %type opt_dyncol_type dyncol_type numeric_dyncol_type temporal_dyncol_type string_dyncol_type @@ -2267,7 +2277,7 @@ sp_param_name: ; sp_param_name_and_type: - sp_param_name type_with_opt_collate + sp_param_name sp_param_type_with_opt_collate { if (Lex->sp_param_fill_definition($$= $1)) MYSQL_YYABORT; @@ -2286,7 +2296,7 @@ sp_pdparams: ; sp_pdparam: - sp_param_name sp_opt_inout type_with_opt_collate + sp_param_name sp_opt_inout sp_param_type_with_opt_collate { $1->mode= $2; if (Lex->sp_param_fill_definition($1)) @@ -5611,6 +5621,24 @@ column_default_expr: ; field_type: + field_type_numeric + | field_type_temporal + | field_type_string + | field_type_lob + | field_type_misc + ; + + +sp_param_field_type: + field_type_numeric + | field_type_temporal + | sp_param_field_type_string + | field_type_lob + | field_type_misc + ; + + +field_type_numeric: int_type opt_field_length field_options { $$.set($1, $2); } | real_type opt_precision field_options { $$.set($1, $2); } | FLOAT_SYM float_options field_options @@ -5641,7 +5669,24 @@ field_type: { $$.set(MYSQL_TYPE_TINY, "1"); } - | char opt_field_length_default_1 opt_binary + | DECIMAL_SYM float_options field_options + { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);} + | NUMBER_SYM float_options field_options + { + if ($2.length() != 0) + $$.set(MYSQL_TYPE_NEWDECIMAL, $2); + else + $$.set(MYSQL_TYPE_DOUBLE); + } + | NUMERIC_SYM float_options field_options + { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);} + | FIXED_SYM float_options field_options + { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);} + ; + + +field_type_string: + char opt_field_length_default_1 opt_binary { $$.set(MYSQL_TYPE_STRING, $2); } @@ -5678,7 +5723,52 @@ field_type: Lex->charset= &my_charset_bin; $$.set(MYSQL_TYPE_VARCHAR, $2); } - | YEAR_SYM opt_field_length field_options + ; + + +sp_param_field_type_string: + char opt_field_length_default_sp_param_char opt_binary + { + $$.set(MYSQL_TYPE_VARCHAR, $2); + } + | nchar opt_field_length_default_sp_param_char opt_bin_mod + { + $$.set(MYSQL_TYPE_VARCHAR, $2); + bincmp_collation(national_charset_info, $3); + } + | BINARY opt_field_length_default_sp_param_char + { + Lex->charset=&my_charset_bin; + $$.set(MYSQL_TYPE_VARCHAR, $2); + } + | varchar opt_field_length_default_sp_param_varchar opt_binary + { + $$.set(MYSQL_TYPE_VARCHAR, $2); + } + | VARCHAR2 opt_field_length_default_sp_param_varchar opt_binary + { + $$.set(MYSQL_TYPE_VARCHAR, $2); + } + | nvarchar opt_field_length_default_sp_param_varchar opt_bin_mod + { + $$.set(MYSQL_TYPE_VARCHAR, $2); + bincmp_collation(national_charset_info, $3); + } + | VARBINARY opt_field_length_default_sp_param_varchar + { + Lex->charset= &my_charset_bin; + $$.set(MYSQL_TYPE_VARCHAR, $2); + } + | RAW opt_field_length_default_sp_param_varchar + { + Lex->charset= &my_charset_bin; + $$.set(MYSQL_TYPE_VARCHAR, $2); + } + ; + + +field_type_temporal: + YEAR_SYM opt_field_length field_options { if ($2) { @@ -5722,7 +5812,11 @@ field_type: | DATETIME opt_field_length { $$.set(opt_mysql56_temporal_format ? MYSQL_TYPE_DATETIME2 : MYSQL_TYPE_DATETIME, $2); } - | TINYBLOB + ; + + +field_type_lob: + TINYBLOB { Lex->charset=&my_charset_bin; $$.set(MYSQL_TYPE_TINY_BLOB); @@ -5770,25 +5864,16 @@ field_type: { $$.set(MYSQL_TYPE_LONG_BLOB); } | CLOB opt_binary { $$.set(MYSQL_TYPE_LONG_BLOB); } - | DECIMAL_SYM float_options field_options - { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);} - | NUMBER_SYM float_options field_options - { - if ($2.length() != 0) - $$.set(MYSQL_TYPE_NEWDECIMAL, $2); - else - $$.set(MYSQL_TYPE_DOUBLE); - } - | NUMERIC_SYM float_options field_options - { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);} - | FIXED_SYM float_options field_options - { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);} - | ENUM '(' string_list ')' opt_binary + | LONG_SYM opt_binary + { $$.set(MYSQL_TYPE_MEDIUM_BLOB); } + ; + + +field_type_misc: + ENUM '(' string_list ')' opt_binary { $$.set(MYSQL_TYPE_ENUM); } | SET '(' string_list ')' opt_binary { $$.set(MYSQL_TYPE_SET); } - | LONG_SYM opt_binary - { $$.set(MYSQL_TYPE_MEDIUM_BLOB); } ; spatial_type: @@ -5894,6 +5979,33 @@ opt_field_length_default_1: /* empty */ { $$= (char*) "1"; } | field_length { $$= $1; } + +/* + In sql_mode=ORACLE, a VARCHAR with no length is used + in SP parameters and return values and it's translated to VARCHAR(4000), + where 4000 is the maximum possible size for VARCHAR. + + In MariaDB the limit for VARCHAR is 65535 bytes. + We could translate VARCHAR with no length to VARCHAR(65535), but + it would mean that for multi-byte character sets we'd have to translate + VARCHAR to MEDIUMTEXT, to guarantee 65535 characters. + + Also we could translate VARCHAR to VARCHAR(16383), where 16383 is + the maximum possible length in characters in case of mbmaxlen=4 + (e.g. utf32, utf16, utf8mb4). However, we'll have character sets with + mbmaxlen=5 soon (e.g. gb18030). + + Let's translate VARCHAR to VARCHAR(4000), which covert all possible Oracle + values. +*/ +opt_field_length_default_sp_param_varchar: + /* empty */ { $$= (char*) "4000"; } + | field_length { $$= $1; } + +opt_field_length_default_sp_param_char: + /* empty */ { $$= (char*) "2000"; } + | field_length { $$= $1; } + opt_precision: /* empty */ { $$.set(0, 0); } | precision { $$= $1; } @@ -6001,6 +6113,19 @@ type_with_opt_collate: } ; +sp_param_type_with_opt_collate: + sp_param_field_type opt_collate + { + $$= $1; + if ($2) + { + if (!(Lex->charset= merge_charset_and_collation(Lex->charset, $2))) + MYSQL_YYABORT; + } + Lex->last_field->set_attributes($1, Lex->charset); + } + ; + charset: CHAR_SYM SET {} | CHARSET {} @@ -16116,7 +16241,7 @@ sf_tail: lex->init_last_field(&lex->sphead->m_return_field_def, NULL, thd->variables.collation_database); } - type_with_opt_collate /* $8 */ + sp_param_type_with_opt_collate /* $8 */ { /* $9 */ if (Lex->sphead->fill_field_definition(thd, Lex->last_field)) MYSQL_YYABORT;