Description:
SQLExecute fails with return code 99 (SQL_NEED_DATA) when run in optimzed executable with optimization -O2. The same code just recompiled with -g works.
It looks like that SQLBindParam does not to very well in optimzed binary or GCC 3.2(.3) compiler optimizer breaks the addresses of bound input parameters.
The configuration:
Linux 7.3
GCC 3.2 (3.2.3 as well)
MySQL client libs 4.0.18
UnixODBC 2.2.6 (reproduced with 2.2.10 as well)
MyODBC 3.51.09 (thread-safe build)
MySQL server 4.0.20
- on Linux 7.3
- defaults: InnoDB+ansi
- RPM download from MySQL)
The UnixODBC trace log is attached bellow, first the debug version then the optimzed version of the same code was running producing two different results. Neither UnixODBC nor MyODBC has been touched between runs.
MyODBC debug logging is broken even if compiled with --with-debug configure option.
The UnixODBC trace logs follows (connection params removed):
[ODBC][5780][__handles.c][444]
Exit:[SQL_SUCCESS]
Environment = 0x8058e38
[ODBC][5780][SQLSetEnvAttr.c][182]
Entry:
Environment = 0x8058e38
Attribute = SQL_ATTR_ODBC_VERSION
Value = 0x3
StrLen = 4
[ODBC][5780][SQLSetEnvAttr.c][349]
Exit:[SQL_SUCCESS]
[ODBC][5780][SQLDrivers.c][219]
Entry:
Environment = 0x8058e38
Direction = 2
[ODBC][5780][SQLDrivers.c][443]
Exit:[SQL_SUCCESS]
[ODBC][5780][SQLDrivers.c][219]
Entry:
Environment = 0x8058e38
Direction = 1
[ODBC][5780][SQLDrivers.c][443]
Exit:[SQL_SUCCESS]
[ODBC][5780][SQLDrivers.c][219]
Entry:
Environment = 0x8058e38
Direction = 1
[ODBC][5780][SQLDrivers.c][443]
Exit:[SQL_NO_DATA]
[ODBC][5780][SQLAllocHandle.c][345]
Entry:
Handle Type = 2
Input Handle = 0x8058e38
[ODBC][5780][SQLAllocHandle.c][463]
Exit:[SQL_SUCCESS]
Output Handle = 0x80593c8
[ODBC][5780][SQLDriverConnect.c][675]
Entry:
Connection = 0x80593c8
Window Hdl = (nil)
Str In = [DRIVER={MySQL};SERVER=;DATABASE=RADO_POOL;USER=;PASSWORD=;OPTION=524292;][length = 106 (SQL_NTS)]
Str Out = 0xbfff9ea0
Str Out Max = 4096
Str Out Ptr = 0xbfff9e9e
Completion = 0
UNICODE Using encoding ASCII 'ISO8859-1' and UNICODE 'UCS-2LE'
[ODBC][5780][SQLDriverConnect.c][1484]
Exit:[SQL_SUCCESS]
Connection Out [DRIVER={MySQL ODBC 3.51 Driver};DESC=;DB=RADO_POOL;SERVER=]
[ODBC][5780][SQLAllocHandle.c][510]
Entry:
Handle Type = 3
Input Handle = 0x80593c8
[ODBC][5780][SQLAllocHandle.c][872]
Exit:[SQL_SUCCESS]
Output Handle = 0x8073c20
[ODBC][5780][SQLPrepare.c][180]
Entry:
Statement = 0x8073c20
SQL = [INSERT INTO "RADO_POOL"."DataTable" ("id","x","y","comments") VALUES (?,?,?,?)][length = 78 (SQL_NTS)]
[ODBC][5780][SQLPrepare.c][355]
Exit:[SQL_SUCCESS]
[ODBC][5780][SQLBindParameter.c][193]
Entry:
Statement = 0x8073c20
Param Number = 1
Param Type = 1
C Type = -15 SQL_C_SSHORT
SQL Type = 4 SQL_INTEGER
Col Def = 0
Scale = 0
Rgb Value = 0xbfff9e6e
Value Max = 0
StrLen Or Ind = 0xbfff9d18
[ODBC][5780][SQLBindParameter.c][339]
Exit:[SQL_SUCCESS]
[ODBC][5780][SQLBindParameter.c][193]
Entry:
Statement = 0x8073c20
Param Number = 2
Param Type = 1
C Type = 7 SQL_C_FLOAT
SQL Type = 6 SQL_FLOAT
Col Def = 0
Scale = 0
Rgb Value = 0xbfff9d14
Value Max = 0
StrLen Or Ind = 0xbfff9d10
[ODBC][5780][SQLBindParameter.c][339]
Exit:[SQL_SUCCESS]
[ODBC][5780][SQLBindParameter.c][193]
Entry:
Statement = 0x8073c20
Param Number = 3
Param Type = 1
C Type = 8 SQL_C_DOUBLE
SQL Type = 8 SQL_DOUBLE
Col Def = 0
Scale = 0
Rgb Value = 0xbfff9d08
Value Max = 0
StrLen Or Ind = 0xbfff9d04
[ODBC][5780][SQLBindParameter.c][339]
Exit:[SQL_SUCCESS]
[ODBC][5780][SQLBindParameter.c][193]
Entry:
Statement = 0x8073c20
Param Number = 4
Param Type = 1
C Type = 1 SQL_C_CHAR
SQL Type = 1 SQL_CHAR
Col Def = 256
Scale = 0
Rgb Value = 0xbfff9d60
Value Max = 0
StrLen Or Ind = 0xbfff9d00
[ODBC][5780][SQLBindParameter.c][339]
Exit:[SQL_SUCCESS]
[ODBC][5780][SQLExecute.c][183]
Entry:
Statement = 0x8073c20
[ODBC][5780][SQLExecute.c][344]
Exit:[SQL_NEED_DATA]
[ODBC][5780][SQLGetDiagRec.c][632]
Entry:
Connection = 0x80593c8
Rec Number = 1
SQLState = 0xbfff9c40
Native = 0xbfff98dc
Message Text = 0xbfff9a40
Buffer Length = 512
Text Len Ptr = 0xbfff9a3e
[ODBC][5780][SQLGetDiagRec.c][669]
Exit:[SQL_NO_DATA]
--------------------------------
[ODBC][5823][__handles.c][444]
Exit:[SQL_SUCCESS]
Environment = 0x805ce90
[ODBC][5823][SQLSetEnvAttr.c][182]
Entry:
Environment = 0x805ce90
Attribute = SQL_ATTR_ODBC_VERSION
Value = 0x3
StrLen = 4
[ODBC][5823][SQLSetEnvAttr.c][349]
Exit:[SQL_SUCCESS]
[ODBC][5823][SQLDrivers.c][219]
Entry:
Environment = 0x805ce90
Direction = 2
[ODBC][5823][SQLDrivers.c][443]
Exit:[SQL_SUCCESS]
[ODBC][5823][SQLDrivers.c][219]
Entry:
Environment = 0x805ce90
Direction = 1
[ODBC][5823][SQLDrivers.c][443]
Exit:[SQL_SUCCESS]
[ODBC][5823][SQLDrivers.c][219]
Entry:
Environment = 0x805ce90
Direction = 1
[ODBC][5823][SQLDrivers.c][443]
Exit:[SQL_NO_DATA]
[ODBC][5823][SQLAllocHandle.c][345]
Entry:
Handle Type = 2
Input Handle = 0x805ce90
[ODBC][5823][SQLAllocHandle.c][463]
Exit:[SQL_SUCCESS]
Output Handle = 0x805d420
[ODBC][5823][SQLDriverConnect.c][675]
Entry:
Connection = 0x805d420
Window Hdl = (nil)
Str In = [DRIVER={MySQL};SERVER=;DATABASE=RADO_POOL;USER=;PASSWORD=;OPTION=524292;][length = 106 (SQL_NTS)]
Str Out = 0xbfff9a60
Str Out Max = 4096
Str Out Ptr = 0xbfff9a5e
Completion = 0
UNICODE Using encoding ASCII 'ISO8859-1' and UNICODE 'UCS-2LE'
[ODBC][5823][SQLDriverConnect.c][1484]
Exit:[SQL_SUCCESS]
Connection Out [DRIVER={MySQL ODBC 3.51 Driver};DESC=;DB=RADO_POOL;SERVER=]
[ODBC][5823][SQLAllocHandle.c][510]
Entry:
Handle Type = 3
Input Handle = 0x805d420
[ODBC][5823][SQLAllocHandle.c][872]
Exit:[SQL_SUCCESS]
Output Handle = 0x8077cb8
[ODBC][5823][SQLPrepare.c][180]
Entry:
Statement = 0x8077cb8
SQL = [INSERT INTO "RADO_POOL"."DataTable" ("id","x","y","comments") VALUES (?,?,?,?)][length = 78 (SQL_NTS)]
[ODBC][5823][SQLPrepare.c][355]
Exit:[SQL_SUCCESS]
[ODBC][5823][SQLBindParameter.c][193]
Entry:
Statement = 0x8077cb8
Param Number = 1
Param Type = 1
C Type = -15 SQL_C_SSHORT
SQL Type = 4 SQL_INTEGER
Col Def = 0
Scale = 0
Rgb Value = 0xbfff9a1a
Value Max = 0
StrLen Or Ind = 0xbfff98ec
[ODBC][5823][SQLBindParameter.c][339]
Exit:[SQL_SUCCESS]
[ODBC][5823][SQLBindParameter.c][193]
Entry:
Statement = 0x8077cb8
Param Number = 2
Param Type = 1
C Type = 7 SQL_C_FLOAT
SQL Type = 6 SQL_FLOAT
Col Def = 0
Scale = 0
Rgb Value = 0xbfff9a14
Value Max = 0
StrLen Or Ind = 0xbfff98e8
[ODBC][5823][SQLBindParameter.c][339]
Exit:[SQL_SUCCESS]
[ODBC][5823][SQLBindParameter.c][193]
Entry:
Statement = 0x8077cb8
Param Number = 3
Param Type = 1
C Type = 8 SQL_C_DOUBLE
SQL Type = 8 SQL_DOUBLE
Col Def = 0
Scale = 0
Rgb Value = 0xbfff9a08
Value Max = 0
StrLen Or Ind = 0xbfff98e4
[ODBC][5823][SQLBindParameter.c][339]
Exit:[SQL_SUCCESS]
[ODBC][5823][SQLBindParameter.c][193]
Entry:
Statement = 0x8077cb8
Param Number = 4
Param Type = 1
C Type = 1 SQL_C_CHAR
SQL Type = 1 SQL_CHAR
Col Def = 256
Scale = 0
Rgb Value = 0xbfff9900
Value Max = 0
StrLen Or Ind = 0xbfff98e0
[ODBC][5823][SQLBindParameter.c][339]
Exit:[SQL_SUCCESS]
[ODBC][5823][SQLExecute.c][183]
Entry:
Statement = 0x8077cb8
[ODBC][5823][SQLExecute.c][344]
Exit:[SQL_SUCCESS]
[ODBC][5823][SQLFreeHandle.c][365]
Entry:
Handle Type = 3
Input Handle = 0x8077cb8
[ODBC][5823][SQLFreeHandle.c][462]
Exit:[SQL_SUCCESS]
[ODBC][5823][SQLDisconnect.c][204]
Entry:
Connection = 0x805d420
[ODBC][5823][SQLDisconnect.c][341]
Exit:[SQL_SUCCESS]
[ODBC][5823][SQLFreeHandle.c][268]
Entry:
Handle Type = 2
Input Handle = 0x805d420
[ODBC][5823][SQLFreeHandle.c][317]
Exit:[SQL_SUCCESS]
[ODBC][5823][SQLFreeHandle.c][203]
Entry:
Handle Type = 1
Input Handle = 0x805ce90
How to repeat:
Create InnoDB database `RADO_POOL` and inside the table as:
CREATE TABLE `DataTable` (
`id` int(11) default NULL,
`x` float default NULL,
`y` double default NULL,
`comments` varchar(255) default NULL
) TYPE=InnoDB
then connect and do:
SQLHANDLE statement;
rc = SQLAllocHandle( SQL_HANDLE_STMT, con, &statement );
SQLCHAR* sqlStr = (SQLCHAR*)"INSERT INTO \"RADO_POOL\".\"DataTable\" (\"id\",\"x\",\"y\",\"comments\") VALUES (?,?,?,?)";
short id;
float x;
double y;
std::string comment;
SQLCHAR caddr[256];;
/* Prepare the SQL statement with parameter markers. */
rc = SQLPrepare( statement, sqlStr, SQL_NTS );
SQLINTEGER cbId, cbX, cbY, cbComment;
/* Specify data types and buffers for OrderID, CustID, OpenDate, SalesPerson, */
/* Status parameter data. */
SQLBindParameter( statement, 1, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &id, 0, &cbId );
SQLBindParameter( statement, 2, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_FLOAT, 0, 0, &x, 0, &cbX );
SQLBindParameter( statement, 3, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_DOUBLE, 0, 0, &y, 0, &cbY );
SQLBindParameter( statement, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 256, 0, caddr, 0, &cbComment );
/* Specify first row of parameter data. */
id = 1;
x = 1.1;
y = 1.11;
comment = "First row";
::strncpy( (char*)caddr, comment.c_str(), 256 );
/* Execute statement with first row. */
rc = SQLExecute( statement );
std::cout << "Statement >>" << (char*)sqlStr << "<< executed with return code " << rc << std::endl;