MDEV-12161 Can't specify collation for virtual columns
sql standard (2016) allows <collate clause> in two places in the <column definition> - as a part of the <data type> or at the very end. Let's do that too. Side effect: in column/SP declaration `COLLATE cs_coll` automatically implies `CHARACTER SET cs` (unless charset was specified explicitly). See changes in sp-ucs2.result
This commit is contained in:
parent
9b750dcbd8
commit
4c448836d4
@ -100,20 +100,20 @@ RETURNS VARCHAR(64) CHARACTER SET ucs2
|
|||||||
BEGIN
|
BEGIN
|
||||||
RETURN 'str';
|
RETURN 'str';
|
||||||
END|
|
END|
|
||||||
ERROR 42000: COLLATION 'ucs2_unicode_ci' is not valid for CHARACTER SET 'latin1'
|
DROP FUNCTION f|
|
||||||
CREATE FUNCTION f(f1 VARCHAR(64) CHARACTER SET ucs2)
|
CREATE FUNCTION f(f1 VARCHAR(64) CHARACTER SET ucs2)
|
||||||
RETURNS VARCHAR(64) COLLATE ucs2_unicode_ci
|
RETURNS VARCHAR(64) COLLATE ucs2_unicode_ci
|
||||||
BEGIN
|
BEGIN
|
||||||
RETURN 'str';
|
RETURN 'str';
|
||||||
END|
|
END|
|
||||||
ERROR 42000: COLLATION 'ucs2_unicode_ci' is not valid for CHARACTER SET 'latin1'
|
DROP FUNCTION f|
|
||||||
CREATE FUNCTION f(f1 VARCHAR(64) CHARACTER SET ucs2)
|
CREATE FUNCTION f(f1 VARCHAR(64) CHARACTER SET ucs2)
|
||||||
RETURNS VARCHAR(64) CHARACTER SET ucs2
|
RETURNS VARCHAR(64) CHARACTER SET ucs2
|
||||||
BEGIN
|
BEGIN
|
||||||
DECLARE f2 VARCHAR(64) COLLATE ucs2_unicode_ci;
|
DECLARE f2 VARCHAR(64) COLLATE ucs2_unicode_ci;
|
||||||
RETURN 'str';
|
RETURN 'str';
|
||||||
END|
|
END|
|
||||||
ERROR 42000: COLLATION 'ucs2_unicode_ci' is not valid for CHARACTER SET 'latin1'
|
DROP FUNCTION f|
|
||||||
SET NAMES utf8;
|
SET NAMES utf8;
|
||||||
DROP FUNCTION IF EXISTS bug48766;
|
DROP FUNCTION IF EXISTS bug48766;
|
||||||
CREATE FUNCTION bug48766 ()
|
CREATE FUNCTION bug48766 ()
|
||||||
|
@ -343,11 +343,12 @@ DELETE FROM t1 WHERE c=1;
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
}
|
}
|
||||||
|
|
||||||
--error ER_PARSE_ERROR
|
|
||||||
CREATE TABLE t1 (c CHAR(10) CHARACTER SET utf8 COLLATE utf8_bin GENERATED ALWAYS AS ("foo bar"));
|
CREATE TABLE t1 (c CHAR(10) CHARACTER SET utf8 COLLATE utf8_bin GENERATED ALWAYS AS ("foo bar"));
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 (i INT);
|
CREATE TABLE t1 (i INT);
|
||||||
--error ER_PARSE_ERROR
|
|
||||||
ALTER TABLE t1 ADD COLUMN c CHAR(10) CHARACTER SET utf8 COLLATE utf8_bin GENERATED ALWAYS AS ("foo bar");
|
ALTER TABLE t1 ADD COLUMN c CHAR(10) CHARACTER SET utf8 COLLATE utf8_bin GENERATED ALWAYS AS ("foo bar");
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
--error ER_PARSE_ERROR
|
--error ER_PARSE_ERROR
|
||||||
CREATE TABLE t1 (i INT COLLATE utf8_bin, c INT COLLATE utf8_bin GENERATED ALWAYS AS (10));
|
CREATE TABLE t1 (i INT COLLATE utf8_bin, c INT COLLATE utf8_bin GENERATED ALWAYS AS (10));
|
||||||
|
@ -426,10 +426,20 @@ INSERT INTO t1(a) VALUES(0);
|
|||||||
DELETE FROM t1 WHERE c=1;
|
DELETE FROM t1 WHERE c=1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 (c CHAR(10) CHARACTER SET utf8 COLLATE utf8_bin GENERATED ALWAYS AS ("foo bar"));
|
CREATE TABLE t1 (c CHAR(10) CHARACTER SET utf8 COLLATE utf8_bin GENERATED ALWAYS AS ("foo bar"));
|
||||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'GENERATED ALWAYS AS ("foo bar"))' at line 1
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`c` char(10) CHARACTER SET utf8 COLLATE utf8_bin GENERATED ALWAYS AS ('foo bar') VIRTUAL
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 (i INT);
|
CREATE TABLE t1 (i INT);
|
||||||
ALTER TABLE t1 ADD COLUMN c CHAR(10) CHARACTER SET utf8 COLLATE utf8_bin GENERATED ALWAYS AS ("foo bar");
|
ALTER TABLE t1 ADD COLUMN c CHAR(10) CHARACTER SET utf8 COLLATE utf8_bin GENERATED ALWAYS AS ("foo bar");
|
||||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'GENERATED ALWAYS AS ("foo bar")' at line 1
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`i` int(11) DEFAULT NULL,
|
||||||
|
`c` char(10) CHARACTER SET utf8 COLLATE utf8_bin GENERATED ALWAYS AS ('foo bar') VIRTUAL
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 (i INT COLLATE utf8_bin, c INT COLLATE utf8_bin GENERATED ALWAYS AS (10));
|
CREATE TABLE t1 (i INT COLLATE utf8_bin, c INT COLLATE utf8_bin GENERATED ALWAYS AS (10));
|
||||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'GENERATED ALWAYS AS (10))' at line 1
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'GENERATED ALWAYS AS (10))' at line 1
|
||||||
|
@ -426,10 +426,20 @@ INSERT INTO t1(a) VALUES(0);
|
|||||||
DELETE FROM t1 WHERE c=1;
|
DELETE FROM t1 WHERE c=1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 (c CHAR(10) CHARACTER SET utf8 COLLATE utf8_bin GENERATED ALWAYS AS ("foo bar"));
|
CREATE TABLE t1 (c CHAR(10) CHARACTER SET utf8 COLLATE utf8_bin GENERATED ALWAYS AS ("foo bar"));
|
||||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'GENERATED ALWAYS AS ("foo bar"))' at line 1
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`c` char(10) CHARACTER SET utf8 COLLATE utf8_bin GENERATED ALWAYS AS ('foo bar') VIRTUAL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 (i INT);
|
CREATE TABLE t1 (i INT);
|
||||||
ALTER TABLE t1 ADD COLUMN c CHAR(10) CHARACTER SET utf8 COLLATE utf8_bin GENERATED ALWAYS AS ("foo bar");
|
ALTER TABLE t1 ADD COLUMN c CHAR(10) CHARACTER SET utf8 COLLATE utf8_bin GENERATED ALWAYS AS ("foo bar");
|
||||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'GENERATED ALWAYS AS ("foo bar")' at line 1
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`i` int(11) DEFAULT NULL,
|
||||||
|
`c` char(10) CHARACTER SET utf8 COLLATE utf8_bin GENERATED ALWAYS AS ('foo bar') VIRTUAL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 (i INT COLLATE utf8_bin, c INT COLLATE utf8_bin GENERATED ALWAYS AS (10));
|
CREATE TABLE t1 (i INT COLLATE utf8_bin, c INT COLLATE utf8_bin GENERATED ALWAYS AS (10));
|
||||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'GENERATED ALWAYS AS (10))' at line 1
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'GENERATED ALWAYS AS (10))' at line 1
|
||||||
|
@ -114,35 +114,35 @@ DROP FUNCTION f1|
|
|||||||
#
|
#
|
||||||
# COLLATE with no CHARACTER SET in IN param
|
# COLLATE with no CHARACTER SET in IN param
|
||||||
#
|
#
|
||||||
--error ER_COLLATION_CHARSET_MISMATCH
|
|
||||||
CREATE FUNCTION f(f1 VARCHAR(64) COLLATE ucs2_unicode_ci)
|
CREATE FUNCTION f(f1 VARCHAR(64) COLLATE ucs2_unicode_ci)
|
||||||
RETURNS VARCHAR(64) CHARACTER SET ucs2
|
RETURNS VARCHAR(64) CHARACTER SET ucs2
|
||||||
BEGIN
|
BEGIN
|
||||||
RETURN 'str';
|
RETURN 'str';
|
||||||
END|
|
END|
|
||||||
|
DROP FUNCTION f|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# COLLATE with no CHARACTER SET in RETURNS
|
# COLLATE with no CHARACTER SET in RETURNS
|
||||||
#
|
#
|
||||||
--error ER_COLLATION_CHARSET_MISMATCH
|
|
||||||
CREATE FUNCTION f(f1 VARCHAR(64) CHARACTER SET ucs2)
|
CREATE FUNCTION f(f1 VARCHAR(64) CHARACTER SET ucs2)
|
||||||
RETURNS VARCHAR(64) COLLATE ucs2_unicode_ci
|
RETURNS VARCHAR(64) COLLATE ucs2_unicode_ci
|
||||||
BEGIN
|
BEGIN
|
||||||
RETURN 'str';
|
RETURN 'str';
|
||||||
END|
|
END|
|
||||||
|
DROP FUNCTION f|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# COLLATE with no CHARACTER SET in DECLARE
|
# COLLATE with no CHARACTER SET in DECLARE
|
||||||
#
|
#
|
||||||
--error ER_COLLATION_CHARSET_MISMATCH
|
|
||||||
CREATE FUNCTION f(f1 VARCHAR(64) CHARACTER SET ucs2)
|
CREATE FUNCTION f(f1 VARCHAR(64) CHARACTER SET ucs2)
|
||||||
RETURNS VARCHAR(64) CHARACTER SET ucs2
|
RETURNS VARCHAR(64) CHARACTER SET ucs2
|
||||||
BEGIN
|
BEGIN
|
||||||
DECLARE f2 VARCHAR(64) COLLATE ucs2_unicode_ci;
|
DECLARE f2 VARCHAR(64) COLLATE ucs2_unicode_ci;
|
||||||
RETURN 'str';
|
RETURN 'str';
|
||||||
END|
|
END|
|
||||||
|
DROP FUNCTION f|
|
||||||
|
|
||||||
|
|
||||||
delimiter ;|
|
delimiter ;|
|
||||||
|
@ -2013,8 +2013,13 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
|
|||||||
/*
|
/*
|
||||||
For string types dump collation name only if
|
For string types dump collation name only if
|
||||||
collation is not primary for the given charset
|
collation is not primary for the given charset
|
||||||
|
|
||||||
|
For generated fields don't print the COLLATE clause if
|
||||||
|
the collation matches the expression's collation.
|
||||||
*/
|
*/
|
||||||
if (!(field->charset()->state & MY_CS_PRIMARY) && !field->vcol_info)
|
if (!(field->charset()->state & MY_CS_PRIMARY) &&
|
||||||
|
(!field->vcol_info ||
|
||||||
|
field->charset() != field->vcol_info->expr->collation.collation))
|
||||||
{
|
{
|
||||||
packet->append(STRING_WITH_LEN(" COLLATE "));
|
packet->append(STRING_WITH_LEN(" COLLATE "));
|
||||||
packet->append(field->charset()->name);
|
packet->append(field->charset()->name);
|
||||||
|
@ -1033,7 +1033,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
Currently there are 98 shift/reduce conflicts.
|
Currently there are 98 shift/reduce conflicts.
|
||||||
We should not introduce new conflicts any more.
|
We should not introduce new conflicts any more.
|
||||||
*/
|
*/
|
||||||
%expect 98
|
%expect 109
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Comments for TOKENS.
|
Comments for TOKENS.
|
||||||
@ -1774,7 +1774,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
|
|
||||||
%type <field_type> int_type real_type
|
%type <field_type> int_type real_type
|
||||||
|
|
||||||
%type <Lex_field_type> type_with_opt_collate field_type
|
%type <Lex_field_type> field_type
|
||||||
|
|
||||||
%type <Lex_dyncol_type> opt_dyncol_type dyncol_type
|
%type <Lex_dyncol_type> opt_dyncol_type dyncol_type
|
||||||
numeric_dyncol_type temporal_dyncol_type string_dyncol_type
|
numeric_dyncol_type temporal_dyncol_type string_dyncol_type
|
||||||
@ -3010,11 +3010,12 @@ sp_param_name_and_type:
|
|||||||
thd->variables.collation_database);
|
thd->variables.collation_database);
|
||||||
$<spvar>$= spvar;
|
$<spvar>$= spvar;
|
||||||
}
|
}
|
||||||
type_with_opt_collate
|
field_type
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
sp_variable *spvar= $<spvar>2;
|
sp_variable *spvar= $<spvar>2;
|
||||||
|
|
||||||
|
Lex->set_last_field_type($3);
|
||||||
if (lex->sphead->fill_field_definition(thd, lex, lex->last_field))
|
if (lex->sphead->fill_field_definition(thd, lex, lex->last_field))
|
||||||
{
|
{
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
@ -3096,13 +3097,14 @@ sp_decl:
|
|||||||
thd->lex->init_last_field(&spvar->field_def, spvar->name.str,
|
thd->lex->init_last_field(&spvar->field_def, spvar->name.str,
|
||||||
thd->variables.collation_database);
|
thd->variables.collation_database);
|
||||||
}
|
}
|
||||||
type_with_opt_collate
|
field_type
|
||||||
sp_opt_default
|
sp_opt_default
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
sp_pcontext *pctx= lex->spcont;
|
sp_pcontext *pctx= lex->spcont;
|
||||||
uint num_vars= pctx->context_var_count();
|
uint num_vars= pctx->context_var_count();
|
||||||
Item *dflt_value_item= $5;
|
Item *dflt_value_item= $5;
|
||||||
|
Lex->set_last_field_type($4);
|
||||||
|
|
||||||
if (!dflt_value_item)
|
if (!dflt_value_item)
|
||||||
{
|
{
|
||||||
@ -6665,20 +6667,6 @@ serial_attribute:
|
|||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
type_with_opt_collate:
|
|
||||||
field_type opt_collate
|
|
||||||
{
|
|
||||||
$$= $1;
|
|
||||||
|
|
||||||
if ($2)
|
|
||||||
{
|
|
||||||
if (!(Lex->charset= merge_charset_and_collation(Lex->charset, $2)))
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
}
|
|
||||||
Lex->set_last_field_type($1);
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
charset:
|
charset:
|
||||||
CHAR_SYM SET {}
|
CHAR_SYM SET {}
|
||||||
| CHARSET {}
|
| CHARSET {}
|
||||||
@ -6751,12 +6739,25 @@ charset_or_alias:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
collate: COLLATE_SYM collation_name_or_default
|
||||||
|
{
|
||||||
|
Lex->charset= Lex->last_field->charset= $2;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
opt_binary:
|
opt_binary:
|
||||||
/* empty */ { bincmp_collation(NULL, false); }
|
/* empty */ { bincmp_collation(NULL, false); }
|
||||||
| BYTE_SYM { bincmp_collation(&my_charset_bin, false); }
|
| BYTE_SYM { bincmp_collation(&my_charset_bin, false); }
|
||||||
| charset_or_alias opt_bin_mod { bincmp_collation($1, $2); }
|
| charset_or_alias opt_bin_mod { bincmp_collation($1, $2); }
|
||||||
| BINARY { bincmp_collation(NULL, true); }
|
| BINARY { bincmp_collation(NULL, true); }
|
||||||
| BINARY charset_or_alias { bincmp_collation($2, true); }
|
| BINARY charset_or_alias { bincmp_collation($2, true); }
|
||||||
|
| charset_or_alias collate
|
||||||
|
{
|
||||||
|
if (!my_charset_same(Lex->charset, $1))
|
||||||
|
my_yyabort_error((ER_COLLATION_CHARSET_MISMATCH, MYF(0),
|
||||||
|
Lex->charset->name, $1->csname));
|
||||||
|
}
|
||||||
|
| collate { }
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_bin_mod:
|
opt_bin_mod:
|
||||||
@ -16854,8 +16855,9 @@ sf_tail:
|
|||||||
lex->init_last_field(&lex->sphead->m_return_field_def, NULL,
|
lex->init_last_field(&lex->sphead->m_return_field_def, NULL,
|
||||||
thd->variables.collation_database);
|
thd->variables.collation_database);
|
||||||
}
|
}
|
||||||
type_with_opt_collate /* $11 */
|
field_type /* $11 */
|
||||||
{ /* $12 */
|
{ /* $12 */
|
||||||
|
Lex->set_last_field_type($11);
|
||||||
if (Lex->sphead->fill_field_definition(thd, Lex, Lex->last_field))
|
if (Lex->sphead->fill_field_definition(thd, Lex, Lex->last_field))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user