Re: 09.03.0100 cursor failures on various architectures - Mailing list pgsql-odbc
From | Heikki Linnakangas |
---|---|
Subject | Re: 09.03.0100 cursor failures on various architectures |
Date | |
Msg-id | 53105C83.9090605@vmware.com Whole thread Raw |
In response to | Re: 09.03.0100 cursor failures on various architectures (Hiroshi Inoue <inoue@tpf.co.jp>) |
Responses |
Re: 09.03.0100 cursor failures on various architectures
|
List | pgsql-odbc |
On 02/27/2014 01:30 PM, Hiroshi Inoue wrote: > (2014/02/26 17:51), Heikki Linnakangas wrote: >> It works on Windows, because sizeof(long) == sizeof(SQLINTEGER) on >> Windows, and it works with unixODBC because unixODBC defines SQL_C_LONG >> as 32-bits regardless of the actual width of "long". > > The ODBC spec clearly mentiones that SQL_C_LONG corresponds to > SQLINTEGER from the first. It also clearly says that the native C type corresponding SQL_C_LONG and SQL_INTEGER is "long". That's all true in the Microsoft world, but on a platform where sizeof(long) == 8, one of the equivalences must be broken. SQL_C_LONG has to correspong to either SQLINTEGER, or "long". The ODBC spec naturally doesn't say which one, because it's not concerned with other platforms. > > But it's not a good >> way to write an application. Why use the ODBC extension SQL_C_LONG >> instead of the SQL_INTEGER type code specified by SQL/CLI? SQL_INTEGER >> is more clear, and as a bonus, it also complies with SQL/CLI. > > Aren't you forgetting ODBC is very old? > Though ODBC and sql/cli are closely related, ODBC is older than > sql/cli. When ODBC was introduced more than 20 years ago, > Microsoft didn't have 32-bit OS yet. That's why SQLINTEGER was > was denoted as *long int* not *int*. It meant 32-bit integrs for > both their working 16-bit OS and coming 32-bit OS. > Of cource the spec was only for 16/32bit. There was no guarantee > how the 64-bit spec would be in the future. At the time pretty many > people expected that int in future 64-bit OSes would be 64-bit integers. Yeah, I understand the history. > So I don't surprize even if SQLINTEGER means 64-bit integers sometime > somewhere. > But I don't believe SQL_C_LONG stands for the type other than > SQLINTEGER. Please tell me where I can find such a fact. Surely, in the early ODBC versions, SQL_C_LONG clearly meant "long", not SQLINTEGER. That's why it's called SQL_C_*LONG*. When 64-bit operating systems arrived, that became confusing because it was no longer a given that "long" is 32-bits. It was not a problem for Microsoft and the ODBC spec, because on Windows, "long" is indeed 32-bits. So in the ODBC spec, SQL_C_LONG stands for both SQLINTEGER and "long", because they are the same. But for the cross-platform CLI specification, that was not good enough. To resolve the situation, they didn't bring in the SQL_C_* type codes. Instead, you use the SQL_INTEGER type code, and it refers to an SQLINTEGER variable. >>> Even though SQL/CLI is a standard, ODBC also has been a (defact?) >>> standard which is older than CLI and widely used. >>> They are different standard. >>> We should begin a project e.g. pgsqlcli when we are to stop >>> using SQL_C_XXXX. >> >> ODBC is a superset of SQL/CLI [1]. An application written for SQL/CLI >> works with ODBC libraries and drivers. But not the other way round; an >> application that's written to the ODBC spec does not necessarily work >> with other SQL/CLI implementations. > > Though you emphasize ODBC is a superset, ODBC was not a superset > of sql/cli from the first. In the first place SQL/CLI didn't exist > when ODBC was introduced. Of cource SQL_C_XXXX was not an extension > of sql/cli spec then. You can't find SQL_C_XXXX because SQL_C_XXXX > is a C-specific concept and maybe sql/cli shrinked the spec so as > to avoid language-specific concept. As a result the spec uses the > same notations SQL_xxxx for different kind of concepts. ODBC uses > different notations for different kind of concepts. Yeah. > Which do you prefer? I would recommend applications to not use SQL_C_xxx type codes. I would recommend using a SQLINTEGER variable with SQL_INTEGER type code. That's the most readable, and most portable option. (I actually like the idea of separate SQL_C_xxx type codes, to refer to the native types. I agree it's slightly confusing to use the same SQL_INTEGER code to refer to the SQL data type, and the C variable's datatype. But alas, if SQL_C_LONG doesn't in fact mean "long", then that's even more confusing, and it's better to stay away from that. With SQL_INTEGER, at least it's clear that it refers to an SQLINTEGER variable. I wish unixOdbc had chosen differently, and decided that SQL_C_LONG != SQL_INTEGER, and it refers to "long", whatever "long" is on your platform. IMHO that would've been more clear. But it's too late to worry about that.) > When ODBC was introduced more than 20 years ago, working OSs of > Mirosoft was 16-bit ones. 32-bit integers must have been denoted > as *long int*. They used SQL_C_LONG because *long* was the most > portable data type which means 32-bit integers then. > > Now I'm examining what SQLINTEGER means in SQL/CLI spec though > it may be an old one. > Hmmm, could you please tell me SQLINTEGER is a 32-bit integer, > 64-bit one or platform-dependent one on 64-bit platforms? > I find a line > SQLINTEGER long Length of buffers for column data and ... > Is it right in the latest spec? Hmm, I don't see that line in my copy. But it does include a sample sqlcli.h header file that has this in Annex H: typedef long SQLINTEGER; typedef long long SQLBIGINT; That probably assumes that "long" is 32-bits wide. The Annex has been marked as "informative", so it's only meant as an example, though. It's worth noting that if you use SQL_INTEGER type code and SQLINTEGER variable consistently, and avoid SQL_C_LONG and "long", it doesn't matter whether SQLINTEGER is 32- or 64-bits wide. It also doesn't matter if SQL_C_LONG == SQL_INTEGER. Your application will work regardless of that. - Heikki
pgsql-odbc by date: