Apache OpenOffice (AOO) Bugzilla – Issue 115384
copytablewizard: bit fields fail in copy from MS Access
Last modified: 2017-05-20 10:30:46 UTC
Copying an ms access table containing a bit field (field type Yes/No [bit]) with copytablewizard fails with an "S1000 The type could not be converted" error. This is a regression as it worked fine in versions 3.2.0 and 3.2.1. When copying to an ODBC destination, ODBC trace enabled, the error occurs just before binding the parameter for the INSERT statement. If the bitfield is fe. field #3, you will find BindParameter for fields #1 and #2 followed by SQLFreeStmt -> statement aborted.
@ ludob Can you add example file to this issue which has this problem?
Original mdb's are too big to attach so I created a new one. 1 table containing an index and a boolean. I tried to copy the table to a new database (internal format) or an ODBC attached one: same error. Note that the table is created correctly in ODBC using a bit value (if the driver supports it). In the new database (internal format) it creates an integer field although the boolean field type exists. The error occurs when copying data. Since ODBC uses bit and internal uses integer, the conversion error is obviously in the ADO part.
Created attachment 72843 [details] Access test file. 1 table with bit field
I can confirm it on win7. I checked in OOo 3.3. RC3 and DEV300m92, the BIT field not converted to new table with Built in HSQLDB odb file, when Use copy table wizard, selected Yes/No Boolean field type, for boolean. When clicked on, Create, I get error: An error occurred. Do you want to continue copying? More gives: SQL Status: S1000 Error code: 1000 The type could not be converted. If I click on yes twice, the Table created, but without data. If I use only next, next not change, data taype, it creates text field, but same errors, and no data. (It is same with cws hsqldb19 dated 2010.11.04, it is support Bit field type). I can copy without problem in OOo 3.2.1,it seems to me it is a regression.
The problem is in dbaccess/source/ui/uno/copytablewizard.cxx. changeset 266756 moved "case DataType::BIT" in the function CopyTableWizard::impl_copyRows_throw. DataType::BIT now results in a call to aTransfer.transferComplexValue( &XRow::getBytes, &XParameters::setBytes ). getBytes tries to convert the VT_BOOL value to VT_ARRAY, which fails. Putting DataType::BIT back where it was, together with DataType::BOOLEAN, solves the problem in my copy of DEV300_m92.
Fixed in cws dba34b. Now BIT length is checked, when > 1 use getBytes otherwise getBoolean The problem here is that Access returns 2 for BIT so I adjusted that as well that the metadata of access now return 1 for Boolean length.
Had a look at dba34b: #i115384# check if the length of BIT > 1 otherwise use setBoolean, and change typeinfo for ado types. Although I don't understand all changes I wanted to share a few comments: 1) ADOS::MapADOType2Jdbc doesn't produce any DataType::BIT anymore. adBoolean is translated to DataType::BOOLEAN. This alone would solve the original problem. The case DataType::BIT: in copytablewizard doesn't occur anymore when copying from ADO tables. 2) From your comments regarding Access reporting size 2 for adBoolean I fear that the number of bits and the byte representation gets mixed up. Access uses 2 bytes internally for a single Yes/No value. Hence, it reports size 2. It doesn't know multiple bit values. MySQL on the other hand knows multiple bit fields and will return up to 8 bytes to represent up to 64 bits. Using ODBC a MySQL BIT(1) and a BIT(5) field will return size 1, a BIT(31) field will return size 4, etc. However, only BIT(1) will return the SQL_BIT type (MySQl Connector ODBC 5.1). Multiple bit fields return SQL_BINARY. So, I don't know what database/interface source would cause a positive test BIT>1.
You missed another part of the fix. I also introduced a new entry in the configuration file for Access which fakes the type info reported by the driver. Now the Boolean type return a length of 1 instead as before a length of 2. <node oor:name="TypeInfoSettings" oor:op="replace"> <prop oor:name="Value" oor:type="oor:string-list"> <value oor:separator=",">Column(2) = 16,Column(3) = 1</value> </prop> </node> This will search for column 2 has the value 16 and replace column 3 with the value 1. As far as I remember MySQL they return a TINYINT for BIT(X) x > 1.
I correctly understood that you were faking the length for boolean fields to 1. My point was that the code doesn't get to the case DataType::BIT: anymore for ADO sources. Therefor the length of the boolean doesn't matter anymore in copytablewizard. Output of SQLColumns using odbcte32 and MySQl Connector ODBC 5.1 for a table containing bit(1) , bit(5) and bit(31) fields: "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "COLUMN_NAME", "DATA_TYPE", "TYPE_NAME", "COLUMN_SIZE", "BUFFER_LENGTH", "DECIMAL_DIGITS", "NUM_PREC_RADIX", "NULLABLE", "REMARKS", "COLUMN_DEF", "SQL_DATA_TYPE", "SQL_DATETIME_SUB", "CHAR_OCTET_LENGTH", "ORDINAL_POSITION", "IS_NULLABLE" "test", <Null>, "bits", "id", 4, "integer", 10, 4, 0, 10, 1, "", <Null>, 4, <Null>, <Null>, 1, "YES" "test", <Null>, "bits", "bit1", -7, "bit", 1, 1, 0, 10, 0, "", <Null>, -7, <Null>, <Null>, 2, "NO" "test", <Null>, "bits", "bit5", -2, "bit", 1, 1, <Null>, <Null>, 0, "", <Null>, -2, <Null>, 1, 3, "NO" "test", <Null>, "bits", "bit31", -2, "bit", 4, 4, <Null>, <Null>, 0, "", <Null>, -2, <Null>, 4, 4, "NO" DATA_TYPE -7 = SQL_BIT and -2 = SQL_BINARY. I remember also having seen somewhere MySQL returning TINYINT for smaller bitfields (1<x<9). Again, my point here is that TINYINT maps to DataType::TINYINT just as BINARY maps to DataType::BINARY and that the test for the bit length won't be executed.
It doesn't matter anymore for the copytable wizard but the table designer shows the wrong precision. I just saw that Access returns a length of zero when creating a table with only a boolean field. >So, I don't know what database/interface source would cause a positive test BIT>1. I don't remember the root cause why I inserted the setBytes call, but I believe there exists somewhere a db which returns > 1 for that. Let's call defensive programming. ;-)
OK. Fair enough.
Please verify. Thanks. - Create an Access db for attached doc - Copy table into a new hsqldb one => No error anymore.
verified in CWS dba34b find more information about this CWS, like when it is available in the master builds, in EIS, the Environment Information System: http://eis.services.openoffice.org/EIS2/cws.ShowCWS?Path=DEV300%2Fdba34b