Issue 115384 - copytablewizard: bit fields fail in copy from MS Access
Summary: copytablewizard: bit fields fail in copy from MS Access
Status: CLOSED FIXED
Alias: None
Product: Base
Classification: Application
Component: code (show other issues)
Version: OOO330m13
Hardware: PC Windows XP
: P3 Trivial (vote)
Target Milestone: 3.4.0
Assignee: marc.neumann
QA Contact: issues@dba
URL:
Keywords: oooqa, regression
Depends on:
Blocks:
 
Reported: 2010-11-03 20:15 UTC by ludob
Modified: 2017-05-20 10:30 UTC (History)
2 users (show)

See Also:
Issue Type: DEFECT
Latest Confirmation in: ---
Developer Difficulty: ---


Attachments
Access test file. 1 table with bit field (116.00 KB, application/msword)
2010-11-04 08:25 UTC, ludob
no flags Details

Note You need to log in before you can comment on or make changes to this issue.
Description ludob 2010-11-03 20:15:19 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.
Comment 1 r4zoli 2010-11-04 07:31:50 UTC
@ ludob
Can you add example file to this issue which has this problem?
Comment 2 ludob 2010-11-04 08:23:33 UTC
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.
Comment 3 ludob 2010-11-04 08:25:31 UTC
Created attachment 72843 [details]
Access test file. 1 table with bit field
Comment 4 r4zoli 2010-11-04 13:49:56 UTC
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. 
Comment 5 ludob 2010-11-06 15:34:03 UTC
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.

Comment 6 ocke.janssen 2010-11-25 13:14:10 UTC
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.
Comment 7 ludob 2010-11-25 18:17:38 UTC
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. 


Comment 8 ocke.janssen 2010-11-26 07:06:50 UTC
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.
Comment 9 ludob 2010-11-26 08:06:33 UTC
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. 



Comment 10 ocke.janssen 2010-11-26 08:59:01 UTC
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. ;-)
Comment 11 ludob 2010-11-26 09:14:37 UTC
OK. Fair enough.
Comment 12 ocke.janssen 2010-12-01 07:24:28 UTC
Please verify. Thanks.

- Create an Access db for attached doc
- Copy table into a new hsqldb one

=> No error anymore.
Comment 13 marc.neumann 2011-01-26 08:05:10 UTC
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