Skip to content

Commit

Permalink
[ODBC-71] Fix and testcase for the problems causing issue and around.
Browse files Browse the repository at this point in the history
These include: errors in SQLCopyDesc, that could caue a crash, support of missing
(odbc2) info types(SQL_POS_OPERATIONS, SQL_STATIC_SENSITIVITY, SQL_LOCK_TYPES, SQL_SCROLL_CONCURRENCY),
support of SQL_DESC_SEARCHABLE and SQL_DESC_SCHEMA_NAME thru SQLColAttribute.
  • Loading branch information
lawrinn committed Feb 25, 2017
1 parent 6ccf03c commit bf947c0
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 10 deletions.
19 changes: 15 additions & 4 deletions ma_connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -1390,9 +1390,6 @@ SQLRETURN MADB_DbcGetInfo(MADB_Dbc *Dbc, SQLUSMALLINT InfoType, SQLPOINTER InfoV
SLen= (SQLSMALLINT)MADB_SetString(isWChar ? &Dbc->charset : NULL, (void *)InfoValuePtr, BUFFER_CHAR_LEN(BufferLength, isWChar),
"Y", SQL_NTS, &Dbc->Error);
break;
case SQL_POS_OPERATIONS:
MADB_SET_NUM_VAL(SQLUINTEGER, InfoValuePtr, 0, StringLengthPtr);
break;
case SQL_QUOTED_IDENTIFIER_CASE:
MADB_SET_NUM_VAL(SQLUSMALLINT, InfoValuePtr, SQL_IC_SENSITIVE, StringLengthPtr);
break;
Expand Down Expand Up @@ -1579,7 +1576,21 @@ SQLRETURN MADB_DbcGetInfo(MADB_Dbc *Dbc, SQLUSMALLINT InfoType, SQLPOINTER InfoV
BUFFER_CHAR_LEN(BufferLength, isWChar),
"N", SQL_NTS, &Dbc->Error);
break;
default:
/* 2.0 types */
case SQL_POS_OPERATIONS:
MADB_SET_NUM_VAL(SQLINTEGER, InfoValuePtr, SQL_POS_POSITION | SQL_POS_REFRESH | SQL_POS_UPDATE | SQL_POS_DELETE | SQL_POS_ADD,
StringLengthPtr);
break;
case SQL_STATIC_SENSITIVITY:
MADB_SET_NUM_VAL(SQLINTEGER, InfoValuePtr, SQL_SS_DELETIONS | SQL_SS_UPDATES, StringLengthPtr);
break;
case SQL_LOCK_TYPES:
MADB_SET_NUM_VAL(SQLINTEGER, InfoValuePtr, SQL_LCK_NO_CHANGE, StringLengthPtr);
break;
case SQL_SCROLL_CONCURRENCY:
MADB_SET_NUM_VAL(SQLINTEGER, InfoValuePtr, SQL_SCCO_READ_ONLY | SQL_SCCO_OPT_VALUES, StringLengthPtr);
break;
default:
MADB_SetError(&Dbc->Error, MADB_ERR_HY096, NULL, 0);
return Dbc->Error.ReturnValue;
}
Expand Down
13 changes: 8 additions & 5 deletions ma_desc.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,14 @@ MADB_Desc *MADB_DescInit(MADB_Dbc *Dbc,enum enum_madb_desc_type DescType, my_boo
Desc->DescType= DescType;
MADB_PutErrorPrefix(Dbc, &Desc->Error);

if (my_init_dynamic_array(&Desc->Records, sizeof(MADB_DescRecord), 0, 0))
if (my_init_dynamic_array(&Desc->Records, sizeof(MADB_DescRecord), 0, MADB_DESC_INIT_REC_NUM))
{
MADB_FREE(Desc);
return NULL;
}
if (isExternal)
{
if (my_init_dynamic_array(&Desc->Stmts, sizeof(MADB_Stmt**), 0, 0))
if (my_init_dynamic_array(&Desc->Stmts, sizeof(MADB_Stmt**), 0, MADB_DESC_INIT_STMT_NUM))
{
MADB_DescFree(Desc, FALSE);
return NULL;
Expand Down Expand Up @@ -987,28 +987,31 @@ SQLRETURN MADB_DescCopyDesc(MADB_Desc *SrcDesc, MADB_Desc *DestDesc)
MADB_SetError(&DestDesc->Error, MADB_ERR_HY016, NULL, 0);
return SQL_ERROR;
}
if (!SrcDesc->Header.Count)
if (SrcDesc->DescType == MADB_DESC_IRD && !SrcDesc->Header.Count)
{
MADB_SetError(&DestDesc->Error, MADB_ERR_HY007, NULL, 0);
return SQL_ERROR;
}
/* make sure there aren't old records */
delete_dynamic(&DestDesc->Records);
if (my_init_dynamic_array(&DestDesc->Records, sizeof(MADB_DescRecord),
SrcDesc->Records.elements, SrcDesc->Records.alloc_increment))
SrcDesc->Records.max_element, SrcDesc->Records.alloc_increment))
{
MADB_SetError(&DestDesc->Error, MADB_ERR_HY001, NULL, 0);
return SQL_ERROR;
}

memcpy(&DestDesc->Header, &SrcDesc->Header, sizeof(MADB_Header));
DestDesc->AppType= SrcDesc->AppType;

/* We don't copy AppType from Src to Dest. If we copy internal descriptor to the explicit/external, it stays explicit/external */

DestDesc->DescType= SrcDesc->DescType;
memcpy(&DestDesc->Error, &SrcDesc->Error, sizeof(MADB_Error));

/* Since we never allocate pointers we can just copy content */
memcpy(DestDesc->Records.buffer, SrcDesc->Records.buffer,
SrcDesc->Records.size_of_element * SrcDesc->Records.max_element);
DestDesc->Records.elements= SrcDesc->Records.elements;
/* todo: internal buffer needs to be clearead or we need to move it outside of
record structure
*/
Expand Down
3 changes: 3 additions & 0 deletions ma_desc.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
#define MADB_DESC_WRITE 2
#define MADB_DESC_RW 3

#define MADB_DESC_INIT_REC_NUM 32
#define MADB_DESC_INIT_STMT_NUM 16

enum enum_madb_desc_type {MADB_DESC_APD= 0, MADB_DESC_ARD, MADB_DESC_IPD, MADB_DESC_IRD, MADB_DESC_UNKNOWN=254};

MADB_DescRecord *MADB_DescGetInternalRecord(MADB_Desc *Desc, SQLSMALLINT RecordNumber, SQLSMALLINT Type);
Expand Down
11 changes: 10 additions & 1 deletion ma_statement.c
Original file line number Diff line number Diff line change
Expand Up @@ -2096,6 +2096,7 @@ SQLRETURN MADB_StmtSetAttr(MADB_Stmt *Stmt, SQLINTEGER Attribute, SQLPOINTER Val
if (ValuePtr)
{
MADB_Desc *Desc= (MADB_Desc *)ValuePtr;

if (!Desc->AppType && Desc != Stmt->IArd)
{
MADB_SetError(&Stmt->Error, MADB_ERR_HY017, NULL, 0);
Expand All @@ -2107,7 +2108,7 @@ SQLRETURN MADB_StmtSetAttr(MADB_Stmt *Stmt, SQLINTEGER Attribute, SQLPOINTER Val
return Stmt->Error.ReturnValue;
}
RemoveStmtRefFromDesc(Stmt->Ard, Stmt, FALSE);
Stmt->Ard= (MADB_Desc *)ValuePtr;
Stmt->Ard= Desc;
Stmt->Ard->DescType= MADB_DESC_ARD;
if (Stmt->Ard != Stmt->IArd)
{
Expand Down Expand Up @@ -2833,9 +2834,17 @@ SQLRETURN MADB_StmtColAttr(MADB_Stmt *Stmt, SQLUSMALLINT ColumnNumber, SQLUSMALL
Record->CatalogName, strlen(Record->CatalogName), &Stmt->Error);
IsNumericAttr= FALSE;
break;
case SQL_DESC_SCHEMA_NAME:
StringLength= (SQLSMALLINT)MADB_SetString(IsWchar ? &Stmt->Connection->charset : 0,
CharacterAttributePtr, (IsWchar) ? BufferLength / sizeof(SQLWCHAR) : BufferLength,
"", 0, &Stmt->Error);
IsNumericAttr= FALSE;
case SQL_DESC_CONCISE_TYPE:
NumericAttribute= (SQLLEN)Record->ConciseType;
break;
case SQL_DESC_SEARCHABLE:
NumericAttribute= (SQLLEN)Record->Searchable;
break;
case SQL_DESC_COUNT:
NumericAttribute= (SQLLEN)Stmt->Ird->Header.Count;
break;
Expand Down
33 changes: 33 additions & 0 deletions test/desc.c
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,38 @@ ODBC_TEST(t_odbc14)
}


ODBC_TEST(t_set_explicit_copy)
{
SQLHANDLE desc1, desc2;
SQLHANDLE hstmt2;
SQLCHAR szOutData[4];
SQLINTEGER c1, c2;

/* TODO using an exp from a different dbc */

CHECK_DBC_RC(Connection, SQLAllocHandle(SQL_HANDLE_STMT, Connection, &hstmt2));

OK_SIMPLE_STMT(hstmt2, "SELECT 1, 2, 'abc'");
CHECK_HANDLE_RC(SQL_HANDLE_STMT, Stmt, SQLBindCol(Stmt, 1, SQL_C_LONG, &c1, 0, NULL));
CHECK_HANDLE_RC(SQL_HANDLE_STMT, Stmt, SQLBindCol(Stmt, 2, SQL_C_LONG, &c2, 0, NULL));
CHECK_HANDLE_RC(SQL_HANDLE_STMT, Stmt, SQLBindCol(Stmt, 3, SQL_C_CHAR, szOutData, sizeof(szOutData), NULL));

CHECK_DBC_RC(Connection, SQLAllocHandle(SQL_HANDLE_DESC, Connection, &desc2));

CHECK_STMT_RC(hstmt2, SQLGetStmtAttr(Stmt, SQL_ATTR_APP_ROW_DESC,
&desc1, 0, NULL));

CHECK_DESC_RC(desc2, SQLCopyDesc(desc1, desc2));

/* can set it to the same statement */
CHECK_STMT_RC(hstmt2, SQLSetStmtAttr(Stmt, SQL_ATTR_APP_ROW_DESC, desc2, 0));

CHECK_STMT_RC(hstmt2, SQLFreeStmt(hstmt2, SQL_DROP));

return OK;
}


MA_ODBC_TESTS my_tests[]=
{
{t_desc_paramset,"t_desc_paramset"},
Expand All @@ -647,6 +679,7 @@ MA_ODBC_TESTS my_tests[]=
{t_bug44576, "t_bug44576"},
{t_desc_curcatalog, "t_desc_curcatalog"},
{t_odbc14, "t_odbc14"},
{t_set_explicit_copy, "t_set_explicit_copy_of_ard"},
{NULL, NULL}
};

Expand Down
19 changes: 19 additions & 0 deletions test/info.c
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,24 @@ ODBC_TEST(t_odbc84)
return OK;
}

/* Test for part of problems causing ODBC-71. Other part is tested in desc.c:t_set_explicit_copy*/
ODBC_TEST(t_odbc71)
{
SQLINTEGER Info;

CHECK_DBC_RC(Connection, SQLGetInfo(Connection, SQL_POS_OPERATIONS, &Info, 0, NULL));
is_num(Info, SQL_POS_POSITION | SQL_POS_REFRESH | SQL_POS_UPDATE | SQL_POS_DELETE | SQL_POS_ADD);
CHECK_DBC_RC(Connection, SQLGetInfo(Connection, SQL_STATIC_SENSITIVITY, &Info, 0, NULL));
is_num(Info, SQL_SS_DELETIONS | SQL_SS_UPDATES);
CHECK_DBC_RC(Connection, SQLGetInfo(Connection, SQL_LOCK_TYPES, &Info, 0, NULL));
is_num(Info, SQL_LCK_NO_CHANGE);
CHECK_DBC_RC(Connection, SQLGetInfo(Connection, SQL_SCROLL_CONCURRENCY, &Info, 0, NULL));
is_num(Info, SQL_SCCO_READ_ONLY | SQL_SCCO_OPT_VALUES);

return OK;
}


MA_ODBC_TESTS my_tests[]=
{
{ t_gettypeinfo, "t_gettypeinfo", NORMAL },
Expand All @@ -571,6 +589,7 @@ MA_ODBC_TESTS my_tests[]=
{ test_need_long_data_len, "test_need_long_data_len", NORMAL },
{ t_odbc61, "odbc61_SQL_FILE_USAGE", NORMAL },
{ t_odbc84, "odbc84_WCHAR_types", NORMAL },
{ t_odbc71, "odbc71_some_odbc2_types", NORMAL },
{ NULL, NULL }
};

Expand Down

0 comments on commit bf947c0

Please sign in to comment.