[MDEV-9542] CONNECT engine incorrect datatype mapping with ODBC TDS driver Created: 2016-02-09 Updated: 2016-02-17 Resolved: 2016-02-16 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Storage Engine - Connect |
| Affects Version/s: | 10.1.11 |
| Fix Version/s: | 10.0.24, 10.1.12 |
| Type: | Bug | Priority: | Major |
| Reporter: | Robert Dyas | Assignee: | Olivier Bertrand |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | None | ||
| Environment: |
CentOS7 x86_64 on Google Cloud Platform (standard install) with unixODBC 2.3.1 and freetds v 0.95.19 |
||
| Attachments: |
|
| Description |
|
Using Connect engine with the Free TDS driver a couple of the data types are not mapped correctly. For example, columns declared as DATE on the remote MS SQL Server come back as character and remote columns declared as DOUBLE or FLOAT are coming back with zero decimal places. Note remote DATETIME does come back correctly as TIMESTAMP in Connect, and remote NUMERIC and DECIMAL types seem to come back correctly. In the example below, next_bill_date is a DATE on the remote MS server, discount is a FLOAT on the remote server (a percentage) and my_double is a DOUBLE on the remote MS server. So, for example, if 0.15 is the value of the discount field, it shows in isql as 0.15 but comes back in CONNECT as 0. Likewise a double as 23.45 comes back as 23.
|
| Comments |
| Comment by Robert Dyas [ 2016-02-09 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
isql result vs. connect result:
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Olivier Bertrand [ 2016-02-11 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
CONNECT tries to translate the SQL types to MariaDB types using the function:
Of course, CONNECT does not directly knows the types that have been assigned to columns, but the types returned by the ODBC driver used to access the table. For instance, if a column is of type DATE, the driver should say its type is SQL_TYPE_DATE and CONNECT will make a DATE column for it. If not, it could be a bug or just because the ODBC driver returned a wrong SQL type for it. I cannot tell what happens in your case not having the information about your source table, and not able to test with your environment and driver. Could you execute your test in ODBC test mode to check what the driver returns when asking for the column description? Note also that this occurs when creating the CONNECT table using discovery, which means not specifying the columns. In the case of wrong column definition, an easy fix is to manually define the columns with the proper type. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Robert Dyas [ 2016-02-11 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
RE "Could you execute your test in ODBC test mode to check what the driver returns when asking for the column description?" I'd be happy to - how do I do that? | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Olivier Bertrand [ 2016-02-11 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I know how to do it on Windows but not on Linux. However, instead of this, could you get more information by retrieving the remote table columns definition: Firstly by executing the function SQLColumns with isql and showing the result. This should show what the TDS driver returns. By the way, does this behaviour occur only with the TDS driver or also with other ODBC drivers? | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Robert Dyas [ 2016-02-12 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
The remote table column definitions in MS SQL Server are: ID bigint not null The above is from the MS SQL Server Management Studio. Note also that we have just started using the Simba Salesforce ODBC driver, and the auto discovery there also declares double(8,0) rather than double. A fix for both drivers that would be workable I think is for all floats/doubles created via auto discovery to be declared as double (rather than double(8,0)).... as one can always manually declare. Also, I think it would be much better for the default behavior of auto-discovery to simply skip and binary and unknown types, and possibly varchar columns exceeding a certain length (configurable) as they can always be manually declared... this option could be configurable via my.cnf. output from the following command is attached out.txt | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Robert Dyas [ 2016-02-12 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Output from CATFUNC=columns
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Robert Dyas [ 2016-02-12 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I'm not sure, but I can see the issue being that floats don't have a specific number of decimal digits (floating point) so the number is 0 in the CATFUNC=columns and the auto-discovery is using that number rather than just mapping to float (or double to be safe). I will post output from the Simba Salesforece ODBC driver, which fails completely on auto-discovery but works with manually specified columns. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Robert Dyas [ 2016-02-12 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
The following file has the output from CATFUNC=columns using the Simba Salesforece ODBC driver. Here is the CATFUNC output: sfout.txt Note there are some other issues that I'll post in a different thread (ORDER BY fails on the connect table, but if the connect table is joined with a local table, then ORDER BY works properly). | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Olivier Bertrand [ 2016-02-16 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
This was caused by Connect not handling NULL values returned by catalog functions. Note however that Connect only knows what is returned by the ODBC drivers and many are sometimes returning hazardous values. Therefore, using discovery is a nice facility with limitations and it should be regarded as normal to edit the Create Table statement produced by it to met the exact requirements of the Connect table based on a remote table. In particular, in the case of double values, you may want to specify the decimal numbers to be handled by the table. About sorting the table, please consult the documentation about how the handle this point. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Robert Dyas [ 2016-02-17 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Yes Olivier, we came to the same conclusion about wild column mappings [e.g. varchar(1300) for a Fax number from a Salesforce driver] so we are using the catfunc=columns to auto-map to our own requirements and this is working great! Thank you for your assistance - much appreciated! |