summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVicențiu Ciorbaru <vicentiu@mariadb.org>2019-12-04 23:37:04 +0200
committerVicențiu Ciorbaru <vicentiu@mariadb.org>2019-12-04 23:37:04 +0200
commita3514c50dc8a517531e76233065eb0d84bde4b9f (patch)
treecb6833d8011ed69f311fa5ae99eb54d08dc0049c
parentcfa76e7750e8ef7eedc3cd55a1126b90abade054 (diff)
downloadmariadb-git-10.3-vicentiu.tar.gz
-rw-r--r--mysql-test/main/json_compat.test3
-rw-r--r--sql/field.cc18
-rw-r--r--sql/field.h11
-rw-r--r--sql/sql_type.cc10
-rw-r--r--sql/table.cc62
5 files changed, 60 insertions, 44 deletions
diff --git a/mysql-test/main/json_compat.test b/mysql-test/main/json_compat.test
index ed8a9a29e1a..44ed1be3344 100644
--- a/mysql-test/main/json_compat.test
+++ b/mysql-test/main/json_compat.test
@@ -16,4 +16,5 @@ show tables;
#show create table t_isam;
alter table t_isam force;
show create table t_isam;
-show create table t_isam_compressed;
+select * from t_isam;
+#show create table t_isam_compressed;
diff --git a/sql/field.cc b/sql/field.cc
index 34a3d264302..4f3b388f59f 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -10601,12 +10601,6 @@ Field *make_field(TABLE_SHARE *share,
FLAGSTR(pack_flag, FIELDFLAG_PACK),
FLAGSTR(pack_flag, FIELDFLAG_BLOB)));
- /*
- if (handler == &type_handler_mysql_json)
- {
- return new (mem_root) Field_mysql_json(ptr, field_name);
- }
- */
if (handler == &type_handler_row)
{
@@ -10637,6 +10631,7 @@ Field *make_field(TABLE_SHARE *share,
}
+
if (f_is_alpha(pack_flag))
{
if (!f_is_packed(pack_flag))
@@ -10678,6 +10673,13 @@ Field *make_field(TABLE_SHARE *share,
f_packtype(pack_flag));
uint pack_length= tmp->calc_pack_length(field_length);
+ if (handler == &type_handler_mysql_json)
+ {
+ return new (mem_root) Field_mysql_json(ptr, null_pos, null_bit,
+ unireg_check, field_name, share,
+ pack_length, field_charset);
+ }
+
#ifdef HAVE_SPATIAL
if (f_is_geom(pack_flag))
{
@@ -10688,10 +10690,6 @@ Field *make_field(TABLE_SHARE *share,
pack_length, geom_type, srid);
}
#endif
- if (f_is_json(pack_flag))
- return new Field_mysql_json(ptr, null_pos, null_bit,
- unireg_check, field_name, share,
- pack_length, field_charset);
if (f_is_blob(pack_flag))
{
if (unireg_check == Field::TMYSQL_COMPRESSED)
diff --git a/sql/field.h b/sql/field.h
index 9d741fc0a11..28d8b27d42f 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -3665,7 +3665,9 @@ public:
return do_field_int;
*/
if (!(from->flags & BLOB_FLAG) || from->charset() != charset() ||
- !from->compression_method() != !compression_method())
+ !from->compression_method() != !compression_method() ||
+ /* Always perform conversion from mysql_json. */
+ from->type_handler() == &type_handler_mysql_json)
return do_conv_blob;
if (from->pack_length() != Field_blob::pack_length())
return do_copy_blob;
@@ -4854,7 +4856,12 @@ class Field_mysql_json :public Field_blob
{
return MYSQL_TYPE_LONG_BLOB;
}
+ const Type_handler *type_handler() const
+ {
+ return &type_handler_mysql_json;
+ }
bool parse_mysql(String*, bool, const char *) const;
+
};
uint pack_length_to_packflag(uint type);
@@ -4880,7 +4887,6 @@ bool check_expression(Virtual_column_info *vcol, LEX_CSTRING *name,
#define FIELDFLAG_GEOM 2048U // mangled with decimals!
#define FIELDFLAG_TREAT_BIT_AS_CHAR 4096U /* use Field_bit_as_char */
-#define FIELDFLAG_JSON 4096U // Shares same flag
#define FIELDFLAG_LONG_DECIMAL 8192U
#define FIELDFLAG_NO_DEFAULT 16384U /* sql */
#define FIELDFLAG_MAYBE_NULL 32768U // sql
@@ -4909,7 +4915,6 @@ bool check_expression(Virtual_column_info *vcol, LEX_CSTRING *name,
#define f_bit_as_char(x) ((x) & FIELDFLAG_TREAT_BIT_AS_CHAR)
#define f_is_hex_escape(x) ((x) & FIELDFLAG_HEX_ESCAPE)
#define f_visibility(x) (static_cast<field_visibility_t> ((x) & INVISIBLE_MAX_BITS))
-#define f_is_json(x) (((x) & (FIELDFLAG_JSON | FIELDFLAG_NUMBER | FIELDFLAG_BITFIELD)) == FIELDFLAG_JSON)
inline
ulonglong TABLE::vers_end_id() const
diff --git a/sql/sql_type.cc b/sql/sql_type.cc
index 15beb1a6856..17d8fe4daf1 100644
--- a/sql/sql_type.cc
+++ b/sql/sql_type.cc
@@ -2486,11 +2486,17 @@ Field *Type_handler_mysql_json::make_table_field(const LEX_CSTRING *name,
const Type_all_attributes &attr,
TABLE *table) const
{
+ /*
+ DBUG_ASSERT will be removed when we reuse make_table_field()
+ for make_field() in field.cc
+ */
+ DBUG_ASSERT(0);
+
DBUG_ASSERT(0);
return new (table->in_use->mem_root)
Field_mysql_json(addr.ptr, addr.null_ptr, addr.null_bit,
- Field::NONE, name, table->s,
- 2, attr.collation);
+ Field::NONE, name, table->s,
+ 4, attr.collation);
}
/*************************************************************************/
/*
diff --git a/sql/table.cc b/sql/table.cc
index c64fb8ca821..1966c68898f 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1804,6 +1804,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
Field::utype unireg_check;
const Type_handler *handler;
uint32 flags= 0;
+ bool handle_field_as_mysql_json= false;
if (new_frm_ver >= 3)
{
@@ -1856,36 +1857,39 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
}
}
-/*
- Special handling to be able to read MySQL JSON types when
- converting a MySQL table (MyISAM) to MariaDB table.
-*/
- if (share->mysql_version >= 50700 &&
- share->mysql_version < 100000 &&
- strpos[13] == (uchar) MYSQL_TYPE_VIRTUAL)
- {
- if(thd->lex->sql_command != SQLCOM_ALTER_TABLE) /* ||
- thd->lex->alter_info.flags != ALTER_RECREATE ||
- thd->lex->alter_info.flags != )
- */
- {
- // Raise an error for every operation expect `alter table <table_name> force`
- mysql_table_to_upgrade=1;
- goto err;
- }
- field_type= MYSQL_TYPE_LONG_BLOB;
- }
- else if ((uchar)field_type == (uchar)MYSQL_TYPE_VIRTUAL)
+ if ((uchar)field_type == (uchar)MYSQL_TYPE_VIRTUAL)
{
- if (!interval_nr) // Expect non-null expression
- goto err;
/*
- MariaDB version 10.0 version.
- The interval_id byte in the .frm file stores the length of the
- expression statement for a virtual column.
+ Special handling to be able to read MySQL JSON types when
+ converting a MySQL table to a MariaDB table. MYSQL_TYPE_VIRTUAL
+ has the same value as MySQL's JSON type number, which we should
+ interpret as a special long blob.
*/
- vcol_info_length= interval_nr;
- interval_nr= 0;
+ if (unlikely(share->mysql_version >= 50700 &&
+ share->mysql_version < 100000))
+ {
+ if(thd->lex->sql_command != SQLCOM_ALTER_TABLE ||
+ thd->lex->alter_info.flags != ALTER_RECREATE)
+ {
+ // Raise an error for every operation except `alter table force`.
+ mysql_table_to_upgrade=1;
+ goto err;
+ }
+ handle_field_as_mysql_json= true;
+ field_type= MYSQL_TYPE_LONG_BLOB;
+ }
+ else
+ {
+ if (!interval_nr) // Expect non-null expression
+ goto err;
+ /*
+ MariaDB version 10.0 version.
+ The interval_id byte in the .frm file stores the length of the
+ expression statement for a virtual column.
+ */
+ vcol_info_length= interval_nr;
+ interval_nr= 0;
+ }
}
if (!comment_length)
@@ -2067,7 +2071,9 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
unireg_check= (Field::utype) MTYP_TYPENR(unireg_type);
name.str= fieldnames.type_names[i];
name.length= strlen(name.str);
- if (!(handler= Type_handler::get_handler_by_real_type(field_type)))
+ if (handle_field_as_mysql_json)
+ handler= &type_handler_mysql_json;
+ else if (!(handler= Type_handler::get_handler_by_real_type(field_type)))
goto err; // Not supported field type
*field_ptr= reg_field=
make_field(share, &share->mem_root, record+recpos, (uint32) field_length,