summaryrefslogtreecommitdiff
path: root/sql/sql_yacc_ora.yy
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2020-07-08 08:31:32 +0400
committerAlexander Barkov <bar@mariadb.com>2020-08-01 07:43:50 +0400
commitd63631c3fa333373d94271d5f68196a4ecec76de (patch)
tree7482067b4521c4c6b9598cbacf8083d10ef940e5 /sql/sql_yacc_ora.yy
parenta8458a2345ea2497ada2f1bd01aeb9c34934dfc6 (diff)
downloadmariadb-git-d63631c3fa333373d94271d5f68196a4ecec76de.tar.gz
MDEV-19632 Replication aborts with ER_SLAVE_CONVERSION_FAILED upon CREATE ... SELECT in ORACLE mode
- Adding optional qualifiers to data types: CREATE TABLE t1 (a schema.DATE); Qualifiers now work only for three pre-defined schemas: mariadb_schema oracle_schema maxdb_schema These schemas are virtual (hard-coded) for now, but may turn into real databases on disk in the future. - mariadb_schema.TYPE now always resolves to a true MariaDB data type TYPE without sql_mode specific translations. - oracle_schema.DATE translates to MariaDB DATETIME. - maxdb_schema.TIMESTAMP translates to MariaDB DATETIME. - Fixing SHOW CREATE TABLE to use a qualifier for a data type TYPE if the current sql_mode translates TYPE to something else. The above changes fix the reported problem, so this script: SET sql_mode=ORACLE; CREATE TABLE t2 AS SELECT mariadb_date_column FROM t1; is now replicated as: SET sql_mode=ORACLE; CREATE TABLE t2 (mariadb_date_column mariadb_schema.DATE); and the slave can unambiguously treat DATE as the true MariaDB DATE without ORACLE specific translation to DATETIME. Similar, SET sql_mode=MAXDB; CREATE TABLE t2 AS SELECT mariadb_timestamp_column FROM t1; is now replicated as: SET sql_mode=MAXDB; CREATE TABLE t2 (mariadb_timestamp_column mariadb_schema.TIMESTAMP); so the slave treats TIMESTAMP as the true MariaDB TIMESTAMP without MAXDB specific translation to DATETIME.
Diffstat (limited to 'sql/sql_yacc_ora.yy')
-rw-r--r--sql/sql_yacc_ora.yy55
1 files changed, 27 insertions, 28 deletions
diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy
index 942f7892f04..a1eb74771ef 100644
--- a/sql/sql_yacc_ora.yy
+++ b/sql/sql_yacc_ora.yy
@@ -1260,6 +1260,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%type <type_handler> int_type real_type
%type <Lex_field_type> type_with_opt_collate field_type
+ qualified_field_type
sp_param_type_with_opt_collate
sp_param_field_type
sp_param_field_type_string
@@ -6573,10 +6574,12 @@ field_spec:
lex->init_last_field(f, &$1, NULL);
$<create_field>$= f;
+ lex->parsing_options.lookup_keywords_after_qualifier= true;
}
field_type_or_serial opt_check_constraint
{
LEX *lex=Lex;
+ lex->parsing_options.lookup_keywords_after_qualifier= false;
$$= $<create_field>2;
$$->check_constraint= $4;
@@ -6595,7 +6598,7 @@ field_spec:
;
field_type_or_serial:
- field_type { Lex->last_field->set_attributes($1, Lex->charset); }
+ qualified_field_type { Lex->last_field->set_attributes($1, Lex->charset); }
field_def
| SERIAL_SYM
{
@@ -6761,6 +6764,18 @@ column_default_expr:
}
;
+qualified_field_type:
+ field_type
+ {
+ Lex->map_data_type(Lex_ident_sys(), &($$= $1));
+ }
+ | sp_decl_ident '.' field_type
+ {
+ if (Lex->map_data_type($1, &($$= $3)))
+ MYSQL_YYABORT;
+ }
+ ;
+
field_type:
field_type_numeric
| field_type_temporal
@@ -6934,7 +6949,7 @@ field_type_temporal:
}
$$.set(&type_handler_year, $2);
}
- | DATE_SYM { $$.set(thd->type_handler_for_date()); }
+ | DATE_SYM { $$.set(&type_handler_newdate); }
| TIME_SYM opt_field_length
{
$$.set(opt_mysql56_temporal_format ?
@@ -6944,31 +6959,14 @@ field_type_temporal:
}
| TIMESTAMP opt_field_length
{
- if (thd->variables.sql_mode & MODE_MAXDB)
- $$.set(opt_mysql56_temporal_format ?
- static_cast<const Type_handler*>(&type_handler_datetime2) :
- static_cast<const Type_handler*>(&type_handler_datetime),
- $2);
- else
- {
- /*
- Unlike other types TIMESTAMP fields are NOT NULL by default.
- Unless --explicit-defaults-for-timestamp is given.
- */
- if (!opt_explicit_defaults_for_timestamp)
- Lex->last_field->flags|= NOT_NULL_FLAG;
- $$.set(opt_mysql56_temporal_format ?
- static_cast<const Type_handler*>(&type_handler_timestamp2):
- static_cast<const Type_handler*>(&type_handler_timestamp),
- $2);
- }
+ $$.set(opt_mysql56_temporal_format ?
+ static_cast<const Type_handler*>(&type_handler_timestamp2):
+ static_cast<const Type_handler*>(&type_handler_timestamp),
+ $2);
}
| DATETIME opt_field_length
{
- $$.set(opt_mysql56_temporal_format ?
- static_cast<const Type_handler*>(&type_handler_datetime2) :
- static_cast<const Type_handler*>(&type_handler_datetime),
- $2);
+ $$.set(thd->type_handler_for_datetime(), $2);
}
;
@@ -7324,27 +7322,28 @@ with_or_without_system:
type_with_opt_collate:
field_type opt_collate
{
- $$= $1;
+ Lex->map_data_type(Lex_ident_sys(), &($$= $1));
if ($2)
{
if (unlikely(!(Lex->charset= merge_charset_and_collation(Lex->charset, $2))))
MYSQL_YYABORT;
}
- Lex->last_field->set_attributes($1, Lex->charset);
+ Lex->last_field->set_attributes($$, Lex->charset);
}
;
sp_param_type_with_opt_collate:
sp_param_field_type opt_collate
{
- $$= $1;
+ Lex->map_data_type(Lex_ident_sys(), &($$= $1));
+
if ($2)
{
if (unlikely(!(Lex->charset= merge_charset_and_collation(Lex->charset, $2))))
MYSQL_YYABORT;
}
- Lex->last_field->set_attributes($1, Lex->charset);
+ Lex->last_field->set_attributes($$, Lex->charset);
}
;