Thread: psqlodbc30w.dll: wrong string termination after SQLFetch for SQL_C_WCHAR buffer bound via SQLBindCol


Hi,

I have the problem described below in an ODBC application which occurs only with PostgreSQL and PostgreSQL-ODBC drivers:

When I fetch string data via ODBC of a column with the "text" datatype (but also when the datatype is "varchar") of a unicode encoded database into a SQLWCHAR-buffer, the string termination in the out-buffer is set wrong, as only the first byte of the string-termination is set to 0 (i.e., SQLWCHAR character at relevant position is 0xcdcd before fetch, and set to 0xcd00 after fetch instead of 0x000). The problem doesn't occur with other drivers (e.g., SQL-Server or SAP-DB/MaxDB).

Details:
  • PostgreSQL Server version: 7.3.2-1 running on Windows 2000 under cygwin-environment
  • PostgreSQL-ODBC driver: version: 7-03.02.00
                                                             date: 22.10.2003
                                                             dll-name: psqlodbc30w.dll
  • MS Windows ODBC-Driver Manager
  • Create unicode-encoded database  with "createdb -E UNICODE unicode" -> ok
  • Create "text"-encoded table with "CREATE TABLE unicode(name TEXT)" -> ok
  • Insert of string-data: "INSERT INTO unicode(name) VALUES ('Michael')" -> ok
  • Select in the cygwin-shell with "SELECT name FROM unicode" -> ok, returns one row with "Michael"
  • Logfiles:



When I run the ODBC-Application shown below, the number of bytes returned in the indicator buffer "nIndOut" by the driver is ok (14), but the string-termination indicator at position pOutput[8] is set to 0xcd00 instead of 0x0000 (i.e., only first byte is set to 0).

Is this a bug in the driver (as the error doesn't occur with other ODBC-drivers), or am I doing something wrong? I appriceate your comments on this problem, as I would like to make our application ready for use with PostgreSQL via ODBC.

Thanks for your help,

Michael Ziehensack



----------------------------------------------------------
BEGIN OF APPLICATION CODE
----------------------------------------------------------

#include <windows.h>
#include <sqlext.h>
#include <sql.h>
#include <stdio.h>


int main(int argc, char* argv[])
{
  SQLRETURN rc = SQL_SUCCESS;

  //! allocate environment handle
  SQLHENV henv = 0;
  rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);

  //! Set the ODBC version environment attribute */
  rc = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);

  //! allocate connection handle
  SQLHDBC hdbc = 0;
  rc = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);

  //! ... and set autocommit off
  rc = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);

  //! Connect to data source */
  rc = SQLConnectW(hdbc, (SQLWCHAR*) L"unicode", SQL_NTS,
                         (SQLWCHAR*) L"ADONIS", SQL_NTS,
                         (SQLWCHAR*) L"BPMS", SQL_NTS);

  //! Allocate statement handle
  SQLHSTMT hstmt;
  rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
  SQLWCHAR * pOutput = new SQLWCHAR[100];
  SQLINTEGER nIndOut;
  SQLINTEGER nCount;

  rc = SQLPrepareW (hstmt, (SQLWCHAR*)L"SELECT name FROM unicode", SQL_NTS);

  rc = SQLBindCol ( hstmt,
                    1,
                    SQL_C_WCHAR,
                    pOutput,
                    100,
                   &nIndOut);
   
  rc = SQLExecute (hstmt);
  rc = SQLFetch(hstmt);


  /* Error with PostgreSQL-ODBC: driver sets string termination at
     relevant position as 0xcd00 (i.e., only the first byte of the
     character is set) instead of 0x0000 !!!
   */

  nCount = wcslen(pOutput);  -> wrong, due to wrong string termination
   
  rc = SQLEndTran (SQL_HANDLE_DBC, hdbc, SQL_ROLLBACK );

  //! Free statment handle
  rc = SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
 
  //! disconnect
  rc = SQLDisconnect(hdbc);

  //! Free connection handle
  rc = SQLFreeHandle(SQL_HANDLE_DBC, hdbc);

  //! Free environment handle
  rc = SQLFreeHandle(SQL_HANDLE_ENV, henv);


  return rc;
}




Attachment