Issue Details (XML | Word | Printable)

Key: ODBC-76
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Alexander Potapchenko
Reporter: Steve Cookson
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
ODBC Driver

64 bit ODBC driver does not work in Kubuntu

Created: 15/Nov/09 05:36 PM   Updated: 09/Jul/13 11:00 AM
Component/s: None
Affects Version/s: None
Fix Version/s: 2.0.2

Environment:
AMD 64 bit
Kubuntu 9.10
Firebird 2.1
Perl 5.10.0


 Description  « Hide
Summary: I suspect the code just needs recompiling for a 64-bit architecture.
Detail: I have a Firebird 2.1 database that works perfectly under Windows, but has been problematic under a migration to Kubuntu 9.10 with ODBC driver libOdbcFb.so.

After initial problems I finally got ODBC working. But I have repeated problems with the date format (and quite possibly the integer format too). The database was created in a UK locale and Kubuntu is set to a UK locale.

I have a row containing a date field which I read once with the Perl application and I get '30/07/2009'. I read it again later and get, say, '32231-08-2\x00'. Sometimes the read works and sometimes not. Sometimes I get a valid date and sometimes I get a strange string, but always with the format nnnnn-nn-n\x00.

If I use isql-fb, it works perfectly, but if I use just isql (the ODBC product), it fails. So this leads me to believe it's an ODBC issue Here is an example, if I don't use any code but just use isql and I run the same query (select att_examination_dte from tbl_exam) three times, I get record 1 = 31893-11-15, twice and record 1 = 2009-07-24 (the correct value) the third time. There are 21 records in this table, here is the whole output (see below).

steve@steve-desktop:~$ isql end_db
+---------------------------------------+
| Connected! |
| |
| sql-statement |
| help [tablename] |
| quit |
| |
+---------------------------------------+
SQL> select att_examination_dte from tbl_exam
+----------------------------+
| ATT_EXAMINATION_DTE|
+----------------------------+
| 31893-11-15 |
| 31893-11-15 |
| 31893-11-15 |
| 31893-11-22 |
| 31893-12-05 |
| 31893-11-24 |
| 31893-11-18 |
| 31893-11-16 |
| 31893-11-23 |
| 31893-11-19 |
| 31893-11-21 |
| 31893-11-17 |
| 31893-12-11 |
| 31893-11-20 |
| 31893-12-11 |
| 31893-12-11 |
| 31893-12-11 |
| 31893-12-12 |
| 31893-12-16 |
| 31893-12-17 |
| 31894-02-05 |
+----------------------------+
SQLRowCount returns 21
21 rows fetched
SQL> select att_examination_dte from tbl_exam
+----------------------------+
| ATT_EXAMINATION_DTE|
+----------------------------+
| 31893-11-15 |
| 31893-11-15 |
| 31893-11-15 |
| 31893-11-22 |
| 31893-12-05 |
| 31893-11-24 |
| 31893-11-18 |
| 31893-11-16 |
| 31893-11-23 |
| 31893-11-19 |
| 31893-11-21 |
| 31893-11-17 |
| 31893-12-11 |
| 31893-11-20 |
| 31893-12-11 |
| 31893-12-11 |
| 31893-12-11 |
| 31893-12-12 |
| 31893-12-16 |
| 31893-12-17 |
| 31894-02-05 |
+----------------------------+
SQLRowCount returns 21
21 rows fetched
SQL> select att_examination_dte from tbl_exam
+----------------------------+
| ATT_EXAMINATION_DTE|
+----------------------------+
| 2009-07-24 |
| 2009-07-24 |
| 2009-07-24 |
| 2009-07-31 |
| 2009-08-13 |
| 2009-08-02 |
| 2009-07-27 |
| 2009-07-25 |
| 2009-08-01 |
| 2009-07-28 |
| 2009-07-30 |
| 2009-07-26 |
| 2009-08-19 |
| 2009-07-29 |
| 2009-08-19 |
| 2009-08-19 |
| 2009-08-19 |
| 2009-08-20 |
| 2009-08-24 |
| 2009-08-25 |
| 2009-10-14 |
+----------------------------+
SQLRowCount returns 21
21 rows fetched
SQL>


 All   Comments   Change History   Subversion Commits      Sort Order: Descending order - Click to sort in ascending order
Alexander Potapchenko added a comment - 08/Aug/12 05:13 PM
OdbcConvert.cpp is fixed in CVS

Ralf Friedl added a comment - 16/Jul/12 11:20 AM
I'm not sure whether it makes sense to add a comment to an issue that has not been addressed for almost three years, but I'll do it anyway.

In the ODBC driver the 64-bit support is more or less broken. The main problem is the assumption that sizeof (long) == 4. The solution would be to use the types int32_t or uint32_t.

This particular issue is caused by the definition of LO_LONG in OdbcConvert.cpp:
#define LO_LONG(l) ((long)(l))
This assumes that casting a value to long will get rid of the upper 32 bits, which is not true with 64bit long. Possible solutions:
#define LO_LONG(l) ((int32_t)(l))
#define LO_LONG(l) ((long)((l) & 0xFFFFFFFF))

There are many more places in OdbcConvert.cpp where long should be replaced with int32_t, or even with int, as long as nobody tries to compile it on a 16 bit system.