Re: 09.03.0100 cursor failures on various architectures

From: Heikki Linnakangas <hlinnakangas(at)vmware(dot)com>
To: Hiroshi Inoue <inoue(at)tpf(dot)co(dot)jp>
Cc: Christoph Berg <christoph(dot)berg(at)credativ(dot)de>, PostgreSQL ODBC <pgsql-odbc(at)postgresql(dot)org>, psqlodbc(at)packages(dot)debian(dot)org
Subject: Re: 09.03.0100 cursor failures on various architectures
Date: 2014-02-28 09:53:07
Message-ID: 53105C83.9090605@vmware.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: 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

In response to

Responses

Browse pgsql-odbc by date

  From Date Subject
Next Message Consolity Inc 2014-02-28 16:20:46 Bug report - ODBC Driver - Error 42P18
Previous Message Hiroshi Inoue 2014-02-27 12:35:44 Re: Kerberos/GSSAPI Instructions