summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMonty <monty@mariadb.org>2016-06-18 14:28:34 +0300
committerMonty <monty@mariadb.org>2016-06-22 22:04:55 +0300
commit34eb10e4064a7f38fc7d41016a6bcc5443ebe0c3 (patch)
tree45f76f02034419697e5bff5f539b20eaac8f8c8d /sql
parente4062d4d203a6be596d3f61dfe4db1b4f91e24aa (diff)
downloadmariadb-git-34eb10e4064a7f38fc7d41016a6bcc5443ebe0c3.tar.gz
MDEV-10138 Support for decimals up to 38 digits
Decimals with float, double and decimal now works the following way: - DECIMAL_NOT_SPECIFIED is used when declaring DECIMALS without a firm number of decimals. It's only used in asserts and my_decimal_int_part. - FLOATING_POINT_DECIMALS (31) is used to mark that a FLOAT or DOUBLE was defined without decimals. This is regarded as a floating point value. - Max decimals allowed for FLOAT and DOUBLE is FLOATING_POINT_DECIMALS-1 - Clients assumes that float and double with decimals >= NOT_FIXED_DEC are floating point values (no decimals) - In the .frm decimals=FLOATING_POINT_DECIMALS are used to define floating point for float and double (31, like before) To ensure compatibility with old clients we do: - When storing float and double, we change NOT_FIXED_DEC to FLOATING_POINT_DECIMALS. - When creating fields from .frm we change for float and double FLOATING_POINT_DEC to NOT_FIXED_DEC - When sending definition for a float/decimal field without decimals to the client as part of a result set we convert NOT_FIXED_DEC to FLOATING_POINT_DECIMALS. - variance() and std() has changed to limit the decimals to FLOATING_POINT_DECIMALS -1 to not get the double converted floating point. (This was to preserve compatiblity) - FLOAT and DOUBLE still have 30 as max number of decimals. Bugs fixed: variance() printed more decimals than we support for double values. New behaviour: - Strings now have 38 decimals instead of 30 when converted to decimal - CREATE ... SELECT with a decimal with > 30 decimals will create a column with a smaller range than before as we are trying to preserve the number of decimals. Other changes - We are now using the obsolete bit FIELDFLAG_LEFT_FULLSCREEN to specify decimals > 31 - NOT_FIXED_DEC is now declared in one place - For clients, NOT_FIXED_DEC is always 31 (to ensure compatibility). On the server NOT_FIXED_DEC is DECIMAL_NOT_SPECIFIED (39) - AUTO_SEC_PART_DIGITS is taken from DECIMAL_NOT_SPECIFIED - DOUBLE conversion functions are now using DECIMAL_NOT_SPECIFIED instead of NOT_FIXED_DEC
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc66
-rw-r--r--sql/field.h37
-rw-r--r--sql/item.h2
-rw-r--r--sql/item_func.cc5
-rw-r--r--sql/item_sum.cc8
-rw-r--r--sql/protocol.cc4
-rw-r--r--sql/sql_analyse.cc6
-rw-r--r--sql/sql_string.cc2
-rw-r--r--sql/sql_table.cc17
-rw-r--r--sql/table.cc4
10 files changed, 109 insertions, 42 deletions
diff --git a/sql/field.cc b/sql/field.cc
index a5d2d759edc..0e2bc724db0 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -4435,13 +4435,13 @@ String *Field_float::val_str(String *val_buffer,
char *to=(char*) val_buffer->ptr();
size_t len;
- if (dec >= NOT_FIXED_DEC)
+ if (dec >= FLOATING_POINT_DECIMALS)
len= my_gcvt(nr, MY_GCVT_ARG_FLOAT, to_length - 1, to, NULL);
else
{
/*
We are safe here because the buffer length is 70, and
- fabs(float) < 10^39, dec < NOT_FIXED_DEC. So the resulting string
+ fabs(float) < 10^39, dec < FLOATING_POINT_DECIMALS. So the resulting string
will be not longer than 69 chars + terminating '\0'.
*/
len= my_fcvt(nr, dec, to, NULL);
@@ -4525,7 +4525,7 @@ int Field_float::do_save_field_metadata(uchar *metadata_ptr)
void Field_float::sql_type(String &res) const
{
- if (dec == NOT_FIXED_DEC)
+ if (dec >= FLOATING_POINT_DECIMALS)
{
res.set_ascii(STRING_WITH_LEN("float"));
}
@@ -4606,7 +4606,7 @@ int truncate_double(double *nr, uint field_length, uint dec,
return 1;
}
- if (dec < NOT_FIXED_DEC)
+ if (dec < FLOATING_POINT_DECIMALS)
{
uint order= field_length - dec;
uint step= array_elements(log_10) - 1;
@@ -4788,7 +4788,7 @@ String *Field_double::val_str(String *val_buffer,
char *to=(char*) val_buffer->ptr();
size_t len;
- if (dec >= NOT_FIXED_DEC)
+ if (dec >= FLOATING_POINT_DECIMALS)
len= my_gcvt(nr, MY_GCVT_ARG_DOUBLE, to_length - 1, to, NULL);
else
len= my_fcvt(nr, dec, to, NULL);
@@ -4847,7 +4847,7 @@ int Field_double::do_save_field_metadata(uchar *metadata_ptr)
void Field_double::sql_type(String &res) const
{
CHARSET_INFO *cs=res.charset();
- if (dec == NOT_FIXED_DEC)
+ if (dec >= FLOATING_POINT_DECIMALS)
{
res.set_ascii(STRING_WITH_LEN("double"));
}
@@ -9772,13 +9772,6 @@ bool Column_definition::check(THD *thd)
if (length > MAX_FIELD_BLOBLENGTH)
{
my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), field_name, MAX_FIELD_BLOBLENGTH);
- DBUG_RETURN(1);
- }
-
- if (decimals >= NOT_FIXED_DEC)
- {
- my_error(ER_TOO_BIG_SCALE, MYF(0), static_cast<ulonglong>(decimals),
- field_name, static_cast<ulong>(NOT_FIXED_DEC - 1));
DBUG_RETURN(TRUE);
}
@@ -9797,7 +9790,7 @@ bool Column_definition::check(THD *thd)
def->decimals < length))
{
my_error(ER_INVALID_DEFAULT, MYF(0), field_name);
- DBUG_RETURN(1);
+ DBUG_RETURN(TRUE);
}
else if (def->type() == Item::NULL_ITEM)
{
@@ -9811,7 +9804,7 @@ bool Column_definition::check(THD *thd)
else if (flags & AUTO_INCREMENT_FLAG)
{
my_error(ER_INVALID_DEFAULT, MYF(0), field_name);
- DBUG_RETURN(1);
+ DBUG_RETURN(TRUE);
}
}
@@ -9839,7 +9832,7 @@ bool Column_definition::check(THD *thd)
on_update->decimals < length))
{
my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name);
- DBUG_RETURN(1);
+ DBUG_RETURN(TRUE);
}
sign_len= flags & UNSIGNED_FLAG ? 0 : 1;
@@ -9873,6 +9866,12 @@ bool Column_definition::check(THD *thd)
case MYSQL_TYPE_NULL:
break;
case MYSQL_TYPE_NEWDECIMAL:
+ if (decimals >= NOT_FIXED_DEC)
+ {
+ my_error(ER_TOO_BIG_SCALE, MYF(0), static_cast<ulonglong>(decimals),
+ field_name, static_cast<ulong>(NOT_FIXED_DEC - 1));
+ DBUG_RETURN(TRUE);
+ }
my_decimal_trim(&length, &decimals);
if (length > DECIMAL_MAX_PRECISION)
{
@@ -9952,6 +9951,12 @@ bool Column_definition::check(THD *thd)
my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name);
DBUG_RETURN(TRUE);
}
+ if (decimals != NOT_FIXED_DEC && decimals >= FLOATING_POINT_DECIMALS)
+ {
+ my_error(ER_TOO_BIG_SCALE, MYF(0), static_cast<ulonglong>(decimals),
+ field_name, static_cast<ulong>(FLOATING_POINT_DECIMALS-1));
+ DBUG_RETURN(TRUE);
+ }
break;
case MYSQL_TYPE_DOUBLE:
allowed_type_modifier= AUTO_INCREMENT_FLAG;
@@ -9966,6 +9971,12 @@ bool Column_definition::check(THD *thd)
my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name);
DBUG_RETURN(TRUE);
}
+ if (decimals != NOT_FIXED_DEC && decimals >= FLOATING_POINT_DECIMALS)
+ {
+ my_error(ER_TOO_BIG_SCALE, MYF(0), static_cast<ulonglong>(decimals),
+ field_name, static_cast<ulong>(FLOATING_POINT_DECIMALS-1));
+ DBUG_RETURN(TRUE);
+ }
break;
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_TIMESTAMP2:
@@ -10280,19 +10291,29 @@ Field *make_field(TABLE_SHARE *share,
f_is_zerofill(pack_flag) != 0,
f_is_dec(pack_flag) == 0);
case MYSQL_TYPE_FLOAT:
+ {
+ int decimals= f_decimals(pack_flag);
+ if (decimals == FLOATING_POINT_DECIMALS)
+ decimals= NOT_FIXED_DEC;
return new (mem_root)
Field_float(ptr,field_length,null_pos,null_bit,
unireg_check, field_name,
- f_decimals(pack_flag),
+ decimals,
f_is_zerofill(pack_flag) != 0,
f_is_dec(pack_flag)== 0);
+ }
case MYSQL_TYPE_DOUBLE:
+ {
+ int decimals= f_decimals(pack_flag);
+ if (decimals == FLOATING_POINT_DECIMALS)
+ decimals= NOT_FIXED_DEC;
return new (mem_root)
Field_double(ptr,field_length,null_pos,null_bit,
unireg_check, field_name,
- f_decimals(pack_flag),
+ decimals,
f_is_zerofill(pack_flag) != 0,
f_is_dec(pack_flag)== 0);
+ }
case MYSQL_TYPE_TINY:
return new (mem_root)
Field_tiny(ptr,field_length,null_pos,null_bit,
@@ -10459,6 +10480,15 @@ Column_definition::Column_definition(THD *thd, Field *old_field,
buff, "YEAR(4)");
}
break;
+ case MYSQL_TYPE_FLOAT:
+ case MYSQL_TYPE_DOUBLE:
+ /*
+ Floating points are stored with FLOATING_POINT_DECIMALS but internally
+ in MariaDB used with NOT_FIXED_DEC, which is >= FLOATING_POINT_DECIMALS.
+ */
+ if (decimals >= FLOATING_POINT_DECIMALS)
+ decimals= NOT_FIXED_DEC;
+ break;
default:
break;
}
diff --git a/sql/field.h b/sql/field.h
index 736c51c2ac3..27b87dd0472 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -51,7 +51,6 @@ enum enum_check_fields
CHECK_FIELD_ERROR_FOR_NULL
};
-
/*
Common declarations for Field and Item
*/
@@ -1699,7 +1698,7 @@ public:
uint8 dec_arg, bool zero_arg, bool unsigned_arg)
:Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg,
field_name_arg, dec_arg, zero_arg, unsigned_arg),
- not_fixed(dec_arg >= NOT_FIXED_DEC)
+ not_fixed(dec_arg >= FLOATING_POINT_DECIMALS)
{}
Item_result result_type () const { return REAL_RESULT; }
Copy_func *get_copy_func(const Field *from) const
@@ -2062,12 +2061,18 @@ public:
:Field_real(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg,
dec_arg, zero_arg, unsigned_arg)
- {}
+ {
+ if (dec_arg >= FLOATING_POINT_DECIMALS)
+ dec_arg= NOT_FIXED_DEC;
+ }
Field_float(uint32 len_arg, bool maybe_null_arg, const char *field_name_arg,
uint8 dec_arg)
:Field_real((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0, (uint) 0,
NONE, field_name_arg, dec_arg, 0, 0)
- {}
+ {
+ if (dec_arg >= FLOATING_POINT_DECIMALS)
+ dec_arg= NOT_FIXED_DEC;
+ }
enum_field_types type() const { return MYSQL_TYPE_FLOAT;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_FLOAT; }
int store(const char *to,uint length,CHARSET_INFO *charset);
@@ -2097,17 +2102,27 @@ public:
:Field_real(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg,
dec_arg, zero_arg, unsigned_arg)
- {}
+ {
+ if (dec_arg >= FLOATING_POINT_DECIMALS)
+ dec_arg= NOT_FIXED_DEC;
+ }
Field_double(uint32 len_arg, bool maybe_null_arg, const char *field_name_arg,
uint8 dec_arg)
:Field_real((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "" : 0, (uint) 0,
NONE, field_name_arg, dec_arg, 0, 0)
- {}
+ {
+ if (dec_arg >= FLOATING_POINT_DECIMALS)
+ dec_arg= NOT_FIXED_DEC;
+ }
Field_double(uint32 len_arg, bool maybe_null_arg, const char *field_name_arg,
uint8 dec_arg, bool not_fixed_arg)
:Field_real((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "" : 0, (uint) 0,
NONE, field_name_arg, dec_arg, 0, 0)
- {not_fixed= not_fixed_arg; }
+ {
+ not_fixed= not_fixed_arg;
+ if (dec_arg >= FLOATING_POINT_DECIMALS)
+ dec_arg= NOT_FIXED_DEC;
+ }
enum_field_types type() const { return MYSQL_TYPE_DOUBLE;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_DOUBLE; }
int store(const char *to,uint length,CHARSET_INFO *charset);
@@ -2898,7 +2913,7 @@ new_Field_timestamp(MEM_ROOT *root,uchar *ptr, uchar *null_ptr, uchar null_bit,
return new (root)
Field_timestamp(ptr, MAX_DATETIME_WIDTH, null_ptr,
null_bit, unireg_check, field_name, share);
- if (dec == NOT_FIXED_DEC)
+ if (dec >= FLOATING_POINT_DECIMALS)
dec= MAX_DATETIME_PRECISION;
return new (root)
Field_timestamp_hires(ptr, null_ptr, null_bit, unireg_check,
@@ -2914,7 +2929,7 @@ new_Field_time(MEM_ROOT *root, uchar *ptr, uchar *null_ptr, uchar null_bit,
return new (root)
Field_time(ptr, MIN_TIME_WIDTH, null_ptr, null_bit, unireg_check,
field_name);
- if (dec == NOT_FIXED_DEC)
+ if (dec >= FLOATING_POINT_DECIMALS)
dec= MAX_DATETIME_PRECISION;
return new (root)
Field_time_hires(ptr, null_ptr, null_bit, unireg_check, field_name, dec);
@@ -2929,7 +2944,7 @@ new_Field_datetime(MEM_ROOT *root, uchar *ptr, uchar *null_ptr, uchar null_bit,
return new (root)
Field_datetime(ptr, MAX_DATETIME_WIDTH, null_ptr, null_bit,
unireg_check, field_name);
- if (dec == NOT_FIXED_DEC)
+ if (dec >= FLOATING_POINT_DECIMALS)
dec= MAX_DATETIME_PRECISION;
return new (root)
Field_datetime_hires(ptr, null_ptr, null_bit,
@@ -3886,7 +3901,7 @@ int convert_null_to_field_value_or_error(Field *field);
#define FIELDFLAG_HEX_ESCAPE ((uint) 0x10000)
#define FIELDFLAG_PACK_SHIFT 3
#define FIELDFLAG_DEC_SHIFT 8
-#define FIELDFLAG_MAX_DEC 31
+#define FIELDFLAG_MAX_DEC 63
#define FIELDFLAG_NUM_SCREEN_TYPE 0x7F01
#define FIELDFLAG_ALFA_SCREEN_TYPE 0x7800
diff --git a/sql/item.h b/sql/item.h
index 674ff6e99dc..20e5572e35e 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1107,7 +1107,7 @@ public:
virtual Item *clone_item(THD *thd) { return 0; }
virtual cond_result eq_cmp_result() const { return COND_OK; }
inline uint float_length(uint decimals_par) const
- { return decimals != NOT_FIXED_DEC ? (DBL_DIG+2+decimals_par) : DBL_DIG+8;}
+ { return decimals < FLOATING_POINT_DECIMALS ? (DBL_DIG+2+decimals_par) : DBL_DIG+8;}
/* Returns total number of decimal digits */
virtual uint decimal_precision() const;
/* Returns the number of integer part digits only */
diff --git a/sql/item_func.cc b/sql/item_func.cc
index c6a3459848e..4f2f400584b 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -646,14 +646,15 @@ void Item_func::count_real_length(Item **items, uint nitems)
unsigned_flag= false;
for (uint i=0 ; i < nitems ; i++)
{
- if (decimals != NOT_FIXED_DEC)
+ if (decimals < FLOATING_POINT_DECIMALS)
{
set_if_bigger(decimals, items[i]->decimals);
+ /* Will be ignored if items[i]->decimals >= FLOATING_POINT_DECIMALS */
set_if_bigger(length, (items[i]->max_length - items[i]->decimals));
}
set_if_bigger(max_length, items[i]->max_length);
}
- if (decimals != NOT_FIXED_DEC)
+ if (decimals < FLOATING_POINT_DECIMALS)
{
max_length= length;
length+= decimals;
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index f774ee5a561..f7e02bc55f9 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1624,7 +1624,8 @@ void Item_sum_avg::fix_length_and_dec()
}
else
{
- decimals= MY_MIN(args[0]->decimals + prec_increment, NOT_FIXED_DEC);
+ decimals= MY_MIN(args[0]->decimals + prec_increment,
+ FLOATING_POINT_DECIMALS);
max_length= MY_MIN(args[0]->max_length + prec_increment, float_length(decimals));
}
}
@@ -1839,13 +1840,14 @@ void Item_sum_variance::fix_length_and_dec()
switch (args[0]->result_type()) {
case REAL_RESULT:
case STRING_RESULT:
- decimals= MY_MIN(args[0]->decimals + 4, NOT_FIXED_DEC);
+ decimals= MY_MIN(args[0]->decimals + 4, FLOATING_POINT_DECIMALS);
break;
case INT_RESULT:
case DECIMAL_RESULT:
{
int precision= args[0]->decimal_precision()*2 + prec_increment;
- decimals= MY_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
+ decimals= MY_MIN(args[0]->decimals + prec_increment,
+ FLOATING_POINT_DECIMALS-1);
max_length= my_decimal_precision_to_length_no_truncation(precision,
decimals,
unsigned_flag);
diff --git a/sql/protocol.cc b/sql/protocol.cc
index 6469581b482..608ec553da0 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -759,6 +759,10 @@ bool Protocol::send_result_set_metadata(List<Item> *list, uint flags)
Send_field field;
item->make_field(thd, &field);
+ /* limit number of decimals for float and double */
+ if (field.type == MYSQL_TYPE_FLOAT || field.type == MYSQL_TYPE_DOUBLE)
+ set_if_smaller(field.decimals, FLOATING_POINT_DECIMALS);
+
/* Keep things compatible for old clients */
if (field.type == MYSQL_TYPE_VARCHAR)
field.type= MYSQL_TYPE_VAR_STRING;
diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc
index b2bc9fc2e87..91a80c552cb 100644
--- a/sql/sql_analyse.cc
+++ b/sql/sql_analyse.cc
@@ -409,7 +409,7 @@ void field_real::add()
if (num == 0.0)
empty++;
- if ((decs = decimals()) == NOT_FIXED_DEC)
+ if ((decs = decimals()) >= FLOATING_POINT_DECIMALS)
{
length= sprintf(buff, "%g", num);
if (rint(num) != num)
@@ -892,7 +892,7 @@ void field_real::get_opt_type(String *answer,
if (!max_notzero_dec_len)
{
- int len= (int) max_length - ((item->decimals == NOT_FIXED_DEC) ?
+ int len= (int) max_length - ((item->decimals >= FLOATING_POINT_DECIMALS) ?
0 : (item->decimals + 1));
if (min_arg >= -128 && max_arg <= (min_arg >= 0 ? 255 : 127))
@@ -912,7 +912,7 @@ void field_real::get_opt_type(String *answer,
if (min_arg >= 0)
answer->append(STRING_WITH_LEN(" UNSIGNED"));
}
- else if (item->decimals == NOT_FIXED_DEC)
+ else if (item->decimals >= FLOATING_POINT_DECIMALS)
{
if (min_arg >= -FLT_MAX && max_arg <= FLT_MAX)
answer->append(STRING_WITH_LEN("FLOAT"));
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index 40339d599af..767154e019d 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -136,7 +136,7 @@ bool String::set_real(double num,uint decimals, CHARSET_INFO *cs)
size_t len;
str_charset=cs;
- if (decimals >= NOT_FIXED_DEC)
+ if (decimals >= FLOATING_POINT_DECIMALS)
{
len= my_gcvt(num, MY_GCVT_ARG_DOUBLE, sizeof(buff) - 1, buff, NULL);
return copy(buff, len, &my_charset_latin1, cs, &dummy_errors);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 60bfe7cd1aa..6cd73978eed 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -2876,7 +2876,8 @@ int prepare_create_field(Column_definition *sql_field,
uint *blob_columns,
longlong table_flags)
{
- unsigned int dup_val_count;
+ uint dup_val_count;
+ uint decimals= sql_field->decimals;
DBUG_ENTER("prepare_create_field");
/*
@@ -2994,8 +2995,18 @@ int prepare_create_field(Column_definition *sql_field,
FIELDFLAG_DECIMAL) |
(sql_field->flags & ZEROFILL_FLAG ?
FIELDFLAG_ZEROFILL : 0) |
- (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
+ (decimals << FIELDFLAG_DEC_SHIFT));
break;
+ case MYSQL_TYPE_FLOAT:
+ case MYSQL_TYPE_DOUBLE:
+ /*
+ User specified FLOAT() or DOUBLE() without precision. Change to
+ FLOATING_POINT_DECIMALS to keep things compatible with earlier MariaDB
+ versions.
+ */
+ if (decimals >= FLOATING_POINT_DECIMALS)
+ decimals= FLOATING_POINT_DECIMALS;
+ /* fall-trough */
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_TIMESTAMP2:
/* fall-through */
@@ -3006,7 +3017,7 @@ int prepare_create_field(Column_definition *sql_field,
(sql_field->flags & ZEROFILL_FLAG ?
FIELDFLAG_ZEROFILL : 0) |
f_settype((uint) sql_field->sql_type) |
- (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
+ (decimals << FIELDFLAG_DEC_SHIFT));
break;
}
if (!(sql_field->flags & NOT_NULL_FLAG) ||
diff --git a/sql/table.cc b/sql/table.cc
index 13b6fbf9cce..208d5da37c7 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1633,6 +1633,10 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
bzero((char*) &comment, sizeof(comment));
}
+ /* Remove >32 decimals from old files */
+ if (share->mysql_version < 100200)
+ pack_flag&= ~(FIELDFLAG_LEFT_FULLSCREEN);
+
if (interval_nr && charset->mbminlen > 1)
{
/* Unescape UCS2 intervals from HEX notation */