Datatype Mapping

The SQL Server ODBC driver implements SQLDescribeCol and SQLColAttributes using the metadata information returned in the TDS header for that result set. Normally, an Open Data Services gateway application sets this metadata information via the srv_describe call, using SQL Server datatype codes, so that the Open Data Services ODBC driver maps the SQL Server datatype to the ODBC datatype and returns the information to the client.

This method of datatype mapping is valid whenever there is a one-to-one correspondence between the datatype supported by the data source, by SQL Server, and by the ODBC client (as with integer and floating-point datatypes). However, this method is not valid when an ODBC datatype is supported by the data source but has no corresponding SQL Server datatype (and therefore no underlying TDS protocol support).

For example, the TIMESTAMP datatype creates mapping incompatibilities between the three systems. Open Data Services gateways could convert TIMESTAMP data to character data using the default ODBC conversion, and then describe the data as SRVVARCHAR using srv_describe. It is important to note that if the only datatype information passed to the Open Data Services ODBC driver is the SQL Server SRVVARCHAR datatype, the driver has no way of knowing the original datatype. Thus, without additional datatype information, the SQLDescribeCol and SQLColAttributes calls made by the driver cannot return a TIMESTAMP datatype to the ODBC application.

Open Data Services gateway applications can convey lost information about the original datatype to the Open Data Services ODBC driver by filling in the Open Data Services usertype descriptor. To set this user-defined datatype field, use the srv_setutype call. The gateway should encode a user-defined datatype for all fields of a result set, regardless of whether there is an exact match to a SQL Server datatype. If the gateway does not set a usertype descriptor, the Open Data Services ODBC driver assumes that the data source supports SQL Server datatypes.

The following information about the original datatype must be conveyed in the user datatype field:

To convey this extra information in the 4 bytes that are provided for a user datatype, the user datatype field returned in the TDS metadata is formatted using the following structure:

typedef struct odsusertype
{
    CHAR    fType;
        BYTE fNullable:1,
            fCaseSensitive:1,
            fUpdateable:2,
            fUnused:2,
            fNew:2;
        union
        {
            struct
            {
                BYTE cbPrecision;
                BYTE ibScale;
            } num;
            SWORD    cbPrecision;
        };
    } ODSUSERTYPE;
    #define NEWODBCTYPE 1
    #define NEWUSERTYPE 2