Bug #85665 sdi deserialize missing ColumnImpl::m_numeric_scale_null
Submitted: 28 Mar 2017 7:42 Modified: 6 Apr 2017 21:44
Reporter: Magnus Blåudd Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Data Dictionary Severity:S2 (Serious)
Version:8.0.1 OS:Any
Assigned to: CPU Architecture:Any

[28 Mar 2017 7:42] Magnus Blåudd
Description:
When serializing and deserializing a table with DECIMAL data type the m_numeric_scale_null member variable of ColumnImpl is not updated. This seems to be since the deserialize code bypasses the member function setters for the member variables. Thus the m_numeric_scale_null variable is not set to false when m_numeric_scale is assigned a value.

The setter:
  virtual void dd::ColumnImpl::set_numeric_scale(uint numeric_scale)
  {
    m_numeric_scale_null= false;
    m_numeric_scale= numeric_scale;
  }

The deserialize:
bool
Column_impl::deserialize(Sdi_rcontext *rctx, const RJ_Value &val)
{
  <snip>
  read(&m_char_length, val, "char_length");
  read(&m_numeric_precision, val, "numeric_precision");
  read(&m_numeric_scale, val, "numeric_scale");
  ^^^^^^^^^^^^^^^^^^^ leaving m_numeric_scale_null at default value true.

This is then later detected by a DBUG_ASSERT in fill_column_from_dd:
  // Decimals
  if (field_type == MYSQL_TYPE_DECIMAL || field_type == MYSQL_TYPE_NEWDECIMAL)
  {
    DBUG_ASSERT(col_obj->is_numeric_scale_null() == false);
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ HERE
    decimals= col_obj->numeric_scale();
  }
  else if (field_type == MYSQL_TYPE_FLOAT || field_type == MYSQL_TYPE_DOUBLE)
  {
    decimals= col_obj->is_numeric_scale_null() ? NOT_FIXED_DEC :
                                                 col_obj->numeric_scale();
  }
  else
    decimals= 0;

Most likely also m_datetime_precision_null is affected by same problem.

How to repeat:
CREATE TABLE product (category INT NOT NULL, id INT NOT NULL, price DECIMAL, PRIMARY KEY(category, id));
serialize
deserialize
insert the deserialized table into DD
open table from dd
check the is_numeric_scale_null() for column price is false

Suggested fix:
Set m_numeric_scale_null (and most likely also m_datetime_precision_null) to false when deserializing a value for m_numeric_scale.
Improve unit test to check that roundtrip works also for DECIMAL and DATETIME data types.
[6 Apr 2017 21:44] Daniel Price
Posted by developer:
 
Fixed as of the upcoming 8.0.2 release, and here's the changelog entry:

After importing a table with DECIMAL column, accessing the table raised
an assertion.