Skip to content

Commit

Permalink
ODBC-152 The fix and the testcase
Browse files Browse the repository at this point in the history
The fix has been accidenatally lost in previous commit. In case if
SQL_DATA_TYPE value is fetched in bound buffer, the truncation error.
The fix casting column in the query to SIGNED
  • Loading branch information
lawrinn committed Oct 1, 2018
1 parent fa081fb commit d49df3d
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 12 deletions.
10 changes: 5 additions & 5 deletions ma_statement.h
Expand Up @@ -143,7 +143,7 @@ SQLRETURN MADB_DoExecute(MADB_Stmt *Stmt, BOOL ExecDirect);
" WHEN " XSTR(SQL_VARBINARY) " THEN CHARACTER_OCTET_LENGTH "\
" WHEN " XSTR(SQL_LONGVARBINARY) " THEN CHARACTER_OCTET_LENGTH "\
" ELSE CHARACTER_MAXIMUM_LENGTH*%u "\
"END AS SIGNED)"
"END AS SIGNED)"

/* CASE for DATA_TYPE glued in 2 parts for ODBC v2 or v3 */
#define MADB_SQL_DATATYPEp1\
Expand Down Expand Up @@ -237,20 +237,20 @@ SQLRETURN MADB_DoExecute(MADB_Stmt *Stmt, BOOL ExecDirect);
#define MADB_DEFAULT_COLUMN_OLD "IF(COLLATION_NAME IS NOT NULL AND COLUMN_DEFAULT IS NOT NULL, CONCAT(CHAR(39), COLUMN_DEFAULT, CHAR(39)), COLUMN_DEFAULT)"
#define MADB_DEFAULT_COLUMN_NEW "COLUMN_DEFAULT"
#define MADB_DEFAULT_COLUMN(DbcHndl) (MADB_ServerSupports(DbcHndl,MADB_ENCLOSES_COLUMN_DEF_WITH_QUOTES) ? MADB_DEFAULT_COLUMN_NEW : MADB_DEFAULT_COLUMN_OLD)
#define MADB_CATALOG_TYPE_SUB "CASE"\
#define MADB_CATALOG_TYPE_SUB "CAST(CASE"\
" WHEN DATA_TYPE = 'date' THEN " XSTR(SQL_DATETIME)\
" WHEN DATA_TYPE = 'time' THEN " XSTR(SQL_DATETIME)\
" WHEN DATA_TYPE = 'datetime' THEN " XSTR(SQL_DATETIME)\
" WHEN DATA_TYPE = 'timestamp' THEN " XSTR(SQL_DATETIME)\
" ELSE @dt "\
"END AS SQL_DATA_TYPE,"\
"CASE"\
"END AS SIGNED) SQL_DATA_TYPE,"\
"CAST(CASE"\
" WHEN DATA_TYPE = 'date' THEN " XSTR(SQL_CODE_DATE)\
" WHEN DATA_TYPE = 'time' THEN " XSTR(SQL_CODE_TIME)\
" WHEN DATA_TYPE = 'datetime' THEN " XSTR(SQL_CODE_TIMESTAMP)\
" WHEN DATA_TYPE = 'timestamp' THEN " XSTR(SQL_CODE_TIMESTAMP)\
" ELSE NULL "\
"END AS SQL_DATETIME_SUB,"
"END AS SIGNED) SQL_DATETIME_SUB,"
#define MADB_CATALOG_COLUMNSp4 " AS COLUMN_DEF," MADB_CATALOG_TYPE_SUB\
"IF(CHARACTER_OCTET_LENGTH IS NOT NULL, @tol, IF(DATA_TYPE='bit' AND NUMERIC_PRECISION =1, NULL, CAST((NUMERIC_PRECISION + 7)/8 AS SIGNED))) AS CHAR_OCTET_LENGTH, "\
"ORDINAL_POSITION,"\
Expand Down
55 changes: 48 additions & 7 deletions test/catalog2.c
Expand Up @@ -26,6 +26,7 @@
#include "tap.h"

/* Columns order num for SQLColumns */
#define COLUMN_NAME 4
#define DATA_TYPE 5
#define COLUMN_SIZE 7
#define BUFFER_LENGTH 8
Expand Down Expand Up @@ -1218,7 +1219,7 @@ ODBC_TEST(odbc131)
SQLULEN StrLen;
SQLSMALLINT ShortData,
SmallintFields[]= {DATA_TYPE, DECIMAL_DIGITS, NUM_PREC_RADIX, NULLABLE, SQL_DATA_TYPE, SQL_DATETIME_SUB},
IntFields[]= {COLUMN_SIZE, BUFFER_LENGTH/*, CHAR_OCTET_LENGTH, ORDINAL_POSITION*/};
IntFields[]= {COLUMN_SIZE, BUFFER_LENGTH, CHAR_OCTET_LENGTH, ORDINAL_POSITION};
SQLINTEGER IntData;

OK_SIMPLE_STMT(Stmt, "DROP TABLE IF EXISTS t_odbc131");
Expand Down Expand Up @@ -1366,20 +1367,21 @@ ODBC_TEST(odbc185)
for (i= 0; i < sizeof(expectedw)/sizeof(expectedw[0]); ++i)
{
CHECK_STMT_RC(hstmt1, SQLFetch(hstmt1));
my_fetch_str(hstmt1, buff, 4);
is_num(my_fetch_int(hstmt1, 5 /* DATA_TYPE */), expecteda[i]);
is_num(my_fetch_int(hstmt1, 14 /* SQL_DATA_TYPE */), expecteda[i]);
my_fetch_str(hstmt1, buff, COLUMN_NAME);
is_num(my_fetch_int(hstmt1, DATA_TYPE), expecteda[i]);
is_num(my_fetch_int(hstmt1, SQL_DATA_TYPE /* SQL_DATA_TYPE */), expecteda[i]);

CHECK_STMT_RC(Stmt, SQLFetch(Stmt));
my_fetch_str(Stmt, buff, 4);
is_num(my_fetch_int(Stmt, 5 /* DATA_TYPE */), expecteda[i]);
is_num(my_fetch_int(Stmt, 14 /* SQL_DATA_TYPE */), expecteda[i]);
my_fetch_str(Stmt, buff, COLUMN_NAME);
is_num(my_fetch_int(Stmt, DATA_TYPE), expecteda[i]);
is_num(my_fetch_int(Stmt, SQL_DATA_TYPE), expecteda[i]);
}

EXPECT_STMT(hstmt1, SQLFetch(hstmt1), SQL_NO_DATA_FOUND);
EXPECT_STMT(Stmt, SQLFetch(Stmt), SQL_NO_DATA_FOUND);

CHECK_STMT_RC(hstmt1, SQLFreeStmt(hstmt1, SQL_CLOSE));
CHECK_STMT_RC(Stmt, SQLFreeStmt(hstmt1, SQL_CLOSE));

OK_SIMPLE_STMT(hstmt1, "DROP TABLE t_odbc185");

Expand All @@ -1390,6 +1392,44 @@ ODBC_TEST(odbc185)
return OK;
}

ODBC_TEST(odbc152)
{
SQLSMALLINT SqlDataType, SqlDatetimeSub= 0xffff, DataType;
SQLLEN LenType= 0, LenSub= 0, LenConciseType;

OK_SIMPLE_STMT(Stmt, "DROP TABLE IF EXISTS t_odbc152");
OK_SIMPLE_STMT(Stmt, "CREATE TABLE t_odbc152 (`val` bigint(20) NOT NULL, dt datetime)");

/* It doesn't matter if we call SQLColumns or SQLColumnsW */
CHECK_STMT_RC(Stmt, SQLColumns(Stmt, NULL, SQL_NTS, NULL, 0,
"t_odbc152", SQL_NTS, NULL, SQL_NTS));

CHECK_STMT_RC(Stmt, SQLBindCol(Stmt, SQL_DATA_TYPE, SQL_C_SSHORT, &SqlDataType, 2, &LenType));
CHECK_STMT_RC(Stmt, SQLBindCol(Stmt, SQL_DATETIME_SUB, SQL_C_SSHORT, &SqlDatetimeSub, 2, &LenSub));
CHECK_STMT_RC(Stmt, SQLBindCol(Stmt, DATA_TYPE, SQL_C_SSHORT, &DataType, 2, &LenConciseType));
CHECK_STMT_RC(Stmt, SQLFetch(Stmt));
is_num(SqlDataType, SQL_BIGINT);
is_num(LenType, 2);
is_num(DataType, SQL_BIGINT);
is_num(LenConciseType, 2);
is_num(LenSub, SQL_NULL_DATA);

CHECK_STMT_RC(Stmt, SQLFetch(Stmt));
is_num(DataType, OdbcVer == SQL_OV_ODBC2 ? SQL_TIMESTAMP : SQL_TYPE_TIMESTAMP);
is_num(LenConciseType, 2);
is_num(SqlDataType, SQL_DATETIME);
is_num(LenType, 2);
is_num(SqlDatetimeSub, SQL_CODE_TIMESTAMP);
is_num(LenSub, 2);

EXPECT_STMT(Stmt, SQLFetch(Stmt), SQL_NO_DATA_FOUND);

CHECK_STMT_RC(Stmt, SQLFreeStmt(Stmt, SQL_CLOSE));

OK_SIMPLE_STMT(Stmt, "DROP TABLE t_odbc152");

return OK;
}

MA_ODBC_TESTS my_tests[]=
{
Expand All @@ -1414,6 +1454,7 @@ MA_ODBC_TESTS my_tests[]=
{odbc131, "odbc131_columns_data_len", NORMAL},
{odbc119, "odbc119_sqlstats_orderby", NORMAL},
{odbc185, "odbc185_sqlcolumns_wtypes", NORMAL},
{odbc152, "odbc152_sqlcolumns_sql_data_type", NORMAL},
{NULL, NULL}
};

Expand Down

0 comments on commit d49df3d

Please sign in to comment.