Bug #38156 Access singles are converted to MySQL fixed doubles
Submitted: 15 Jul 2008 23:13 Modified: 19 Oct 2009 10:39
Reporter: Chris Kukuchka Email Updates:
Status: Duplicate Impact on me:
None 
Category:MySQL Migration Toolkit Severity:S2 (Serious)
Version:1.1.17 OS:Any
Assigned to: CPU Architecture:Any
Tags: CHECKED

[15 Jul 2008 23:13] Chris Kukuchka
Description:
During migration, the scale of Access singles are being set to 1/3 the field length with no concern to what is set within Access.  Upon import, the data is then rounded causing loss of decimal precision.

This is basically the same as Bug #17880 which is currently languishing in a "No Feedback" status.

How to repeat:
Create an Access table with three fields:
Create field 1
	Field Name: name
	Data Type: text
	Field Size: 50 (default)
Create field 2
	Field Name: auto
	Data Type: number
	Field Size: Single
	Decimal Places: Auto (default)
Create field 3
	Field Name: fixed
	Data Type: number
	Field Size: Single
	Decimal Places: 3

Populate table with sample data:
	0	1	1
	1	1.1	1.1
	2	1.12	1.12
	3	1.123	1.123
	4	1.1234	1.1234
	5	1.12345	1.12345
	6	1.123456	1.123456

Run Migration (run with default options)

Examine resultant table:

Database structure:
+--------+--------------+------+-----+---------+-------+
| Field  | Type         | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+-------+
| name   | varchar(50)  | YES  |     | NULL    |       |
| auto   | decimal(7,2) | YES  |     | NULL    |       |
| fixed  | decimal(7,2) | YES  |     | NULL    |       |
+--------+--------------+------+-----+---------+-------+
Database values:
+-------+-------+--------+
| name  | auto  | fixed  |
+-------+-------+--------+
| 0     | 1.00  | 1.00   |
| 1     | 1.10  | 1.10   |
| 2     | 1.12  | 1.12   |
| 3     | 1.12  | 1.12   |
| 4     | 1.12  | 1.12   |
| 5     | 1.12  | 1.12   |
| 6     | 1.12  | 1.12   |
+-------+-------+--------+

Both numeric columns got changed to a fixed scale of 2 and the decimal portion of the numbers got rounded off.  Also notice how within Access, the Decimal places setting has not real effect.  Even though, in Access, I specified a fixed number of decimal places for the 'fixed' column, Access still allowed more than three digits right of the decimal.  This behavior should be reflected in the migration in order to ensure all data is transferred accurately.

Suggested fix:
From what I can see, it seems the problem comes from the code in MigrationAccess.java which attempts to translate the field structure:

187 } else if (sourceDatatypeName.equalsIgnoreCase("REAL")
188     || sourceDatatypeName.equalsIgnoreCase("DOUBLE")) {
189   targetColumn.setDatatypeName("DOUBLE");
190
191   if ((targetColumn.getScale() == 0)
192       && (migrationParams != null)
193       && (migrationParams.get("autoDecimalDigits")
194           .equalsIgnoreCase("yes"))) {
195     targetColumn.setScale(targetColumn.getPrecision() / 3);
196   }

I believe line 195 is forcing the scale for these fields to be 1/3 of precision.  To me, this does not seem like an accurate translation when Access allows for total of 7 digits and variable scale on single type fields.  In my tests, it seems the better option would be to set the precision and scale
to -1 during the translation as is done for FLOAT values from Oracle in MigrationOracle.java.

To implement this change would mean replacing the above line 195 with this code:

195    targetColumn.setScale( -1 ); targetColumn.setPrecision( -1 );

My tests show this results in a target field of DOUBLE with no length or scale.  The major difference being the resulting field holds more digits than the original Access field.  However, it does properly allow for variable scale.
[18 Mar 2009 13:02] Susanne Ebrecht
Verified as described.
[19 Oct 2009 10:39] Susanne Ebrecht
This is a duplicate of bug #17880