[R-sig-DB] NULL data not mapped to NA with RODBC on 64-bit Mac OS X

Harlan Harris h@r|@n @end|ng |rom h@rr|@@n@me
Wed Mar 23 20:29:24 CET 2011


Any thoughts? Is there someone else or somewhere else I might ask?

 -Harlan

On Tue, Mar 22, 2011 at 1:31 PM, Harlan Harris <harlan using harris.name> wrote:

> Hello,
>
> I seem to have hit a bug in RODBC on 64-bit versions of R on Mac OS X. I'm
> running R 2.12.1, and using R to talk to Oracle and other databases using
> RODBC 1.3-2. In 32-bit mode (R32), everything works. (The ODBC drivers are
> the ones from Actual.) In 64-bit mode (R), it seems as if NULL data is not
> being treated as missing. For example, a NULL value in an integer column is
> being returned as a 0 instead, which is wrong/bad.
>
> Diving into the code and Google a bit, it seems like an issue that's been
> seen before in other contexts. Here's the relevant C code, from
> RODBCFetchRows:
>
>         for(row = thisHandle->rowsUsed;
>         row < thisHandle->rowsFetched && j <= maximum;
>         j++, row++)
>         {
>         thisHandle->rowsUsed++;
>         if(j > blksize) {
>             blksize *= 2;
>             for (i = 0; i < nc; i++)
>             SET_VECTOR_ELT(data, i,
>                        lengthgets(VECTOR_ELT(data, i), blksize));
>         }
>         for (i = 0; i < nc; i++) {
>             SQLLEN len = thisHandle->ColData[i].IndPtr[row];
>             switch(thisHandle->ColData[i].DataType) {
>             case SQL_DOUBLE:
>             REAL(VECTOR_ELT(data, i))[j-1] =
>                 len == SQL_NULL_DATA ? NA_REAL :
>                 thisHandle->ColData[i].RData[row];
>             break;
>
> etc...
>
> Googling for SQL_NULL_DATA and related terms finds this page, about the
> same issue in a Python driver:
>
> http://code.google.com/p/pyodbc/issues/detail?id=51
>
> It appears as if SQLLEN might be unsigned in 64-bit builds, while
> SQL_NULL_DATA is -1. Casting len to be an int rather than an unsigned int
> seems to solve the problem for them.
>
> On my machine, /usr/include/sqltypes.h starts like this:
>
> /*
>  *  sqltypes.h
>  *
>  *  $Id: sqltypes.h,v 1.23 2007/10/07 13:27:13 source Exp $
>  *
>  *  ODBC typedefs
>  *
>  *  The iODBC driver manager.
>
> and defines SQLLEN as follows:
>
> #ifdef _WIN64
> typedef INT64                   SQLLEN;
> typedef UINT64                  SQLULEN;
> typedef UINT64                  SQLSETPOSIROW;
> #elif defined(STRICT_ODBC_TYPES)
> typedef long                    SQLLEN;
> typedef unsigned long           SQLULEN;
> typedef unsigned short          SQLSETPOSIROW;
> #else
> #define SQLLEN                  long
> #define SQLULEN                 unsigned long
> #define SQLSETPOSIROW           unsigned short
> #endif
>
> Seems to me like SQLLEN should be signed, but apparently not?
>
> Can anyone help? Thank you!
>
>  -Harlan
>
>

	[[alternative HTML version deleted]]




More information about the R-sig-DB mailing list