Skip to content

Commit

Permalink
ODBC-326 Error while connecting Excel via Microsoft Query
Browse files Browse the repository at this point in the history
The problem was in incorrect processing of column binding with default
C type. The error itself occured, because the bind type wasn't
recognized as integer type. But that was consequence of incorrect
internal bind type selection.
  • Loading branch information
lawrinn committed Aug 2, 2021
1 parent 6fcd1b9 commit 5914ebf
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 8 deletions.
20 changes: 13 additions & 7 deletions ma_statement.c
Original file line number Diff line number Diff line change
Expand Up @@ -1539,6 +1539,7 @@ SQLRETURN MADB_PrepareBind(MADB_Stmt *Stmt, int RowNumber)

for (i= 0; i < MADB_STMT_COLUMN_COUNT(Stmt); ++i)
{
SQLSMALLINT ConciseType;
ArdRec= MADB_DescGetInternalRecord(Stmt->Ard, i, MADB_DESC_READ);
if (ArdRec == NULL || !ArdRec->inUse)
{
Expand All @@ -1565,7 +1566,12 @@ SQLRETURN MADB_PrepareBind(MADB_Stmt *Stmt, int RowNumber)
/* We can't use application's buffer directly, as it has/can have different size, than C/C needs */
Stmt->result[i].length= &Stmt->result[i].length_value;

switch(ArdRec->ConciseType) {
ConciseType= ArdRec->ConciseType;
if (ConciseType == SQL_C_DEFAULT)
{
ConciseType= IrdRec->ConciseType;
}
switch(ConciseType) {
case SQL_C_WCHAR:
/* In worst case for 2 bytes of UTF16 in result, we need 3 bytes of utf8.
For ASCII we need 2 times less(for 2 bytes of UTF16 - 1 byte UTF8,
Expand Down Expand Up @@ -1669,7 +1675,7 @@ SQLRETURN MADB_PrepareBind(MADB_Stmt *Stmt, int RowNumber)
}
Stmt->result[i].buffer_length= (unsigned long)ArdRec->OctetLength;
Stmt->result[i].buffer= DataPtr;
Stmt->result[i].buffer_type= MADB_GetMaDBTypeAndLength(ArdRec->ConciseType,
Stmt->result[i].buffer_type= MADB_GetMaDBTypeAndLength(ConciseType,
&Stmt->result[i].is_unsigned,
&Stmt->result[i].buffer_length);
break;
Expand Down Expand Up @@ -2130,19 +2136,19 @@ SQLRETURN MADB_StmtFetch(MADB_Stmt *Stmt)
/* We will not report truncation if a dummy buffer was bound */
int col;

for (col= 0; col < MADB_STMT_COLUMN_COUNT(Stmt); ++col)
for (col = 0; col < MADB_STMT_COLUMN_COUNT(Stmt); ++col)
{
if (Stmt->stmt->bind[col].error && *Stmt->stmt->bind[col].error > 0 &&
!(Stmt->stmt->bind[col].flags & MADB_BIND_DUMMY))
!(Stmt->stmt->bind[col].flags & MADB_BIND_DUMMY))
{
MADB_DescRecord *ArdRec= MADB_DescGetInternalRecord(Stmt->Ard, col, MADB_DESC_READ),
*IrdRec= MADB_DescGetInternalRecord(Stmt->Ird, col, MADB_DESC_READ);
MADB_DescRecord* ArdRec = MADB_DescGetInternalRecord(Stmt->Ard, col, MADB_DESC_READ),
* IrdRec = MADB_DescGetInternalRecord(Stmt->Ird, col, MADB_DESC_READ);
/* If (numeric) field value and buffer are of the same size - ignoring truncation.
In some cases specs are not clear enough if certain column signed or not(think of catalog functions for example), and
some apps bind signed buffer where we return unsigdned value. And in general - if application want to fetch unsigned as
signed, or vice versa, why we should prevent that. */
if (ArdRec->OctetLength == IrdRec->OctetLength
&& MADB_IsIntType(IrdRec->ConciseType) && MADB_IsIntType(ArdRec->ConciseType))
&& MADB_IsIntType(IrdRec->ConciseType) && (ArdRec->ConciseType == SQL_C_DEFAULT || MADB_IsIntType(ArdRec->ConciseType)))
{
continue;
}
Expand Down
49 changes: 48 additions & 1 deletion test/info.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
2013, 2020 MariaDB Corporation AB
2013, 2021 MariaDB Corporation AB
The MySQL Connector/ODBC is licensed under the terms of the GPLv2
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
Expand Down Expand Up @@ -767,6 +767,52 @@ ODBC_TEST(odbc317)
return OK;
}


/* ODBC-326 Connecting Excel with MariaDB through Microsoft Query - String data right truncated
The problem occured in the SQLGetInfo call when one of fetches returned SQL_SUCCESS_WITH_INFO
because of incorrectly detected truncation
*/
ODBC_TEST(odbc326)
{
SQLLEN len[7]= {0,0,0,0,0,0,0};
SQLSMALLINT col2, col9, col15, col7;
/* This are expected ODBCv3 type results */
const SQLSMALLINT ref2[]= {SQL_BIT, SQL_BIT, SQL_TINYINT, SQL_TINYINT, SQL_BIGINT, SQL_BIGINT, SQL_LONGVARBINARY,
SQL_LONGVARBINARY, SQL_LONGVARBINARY, SQL_LONGVARBINARY, SQL_LONGVARBINARY, SQL_VARBINARY, SQL_BINARY, SQL_LONGVARCHAR ,
SQL_LONGVARCHAR, SQL_LONGVARCHAR, SQL_LONGVARCHAR, SQL_LONGVARCHAR, SQL_CHAR, SQL_NUMERIC, SQL_DECIMAL,
SQL_INTEGER, SQL_INTEGER, SQL_INTEGER, SQL_INTEGER, SQL_INTEGER, SQL_INTEGER, SQL_SMALLINT, SQL_SMALLINT,
SQL_FLOAT, SQL_DOUBLE, SQL_DOUBLE, SQL_DOUBLE, SQL_VARCHAR, SQL_VARCHAR, SQL_VARCHAR, SQL_TYPE_DATE, SQL_TYPE_TIME,
SQL_TYPE_TIMESTAMP, SQL_TYPE_TIMESTAMP, SQL_WCHAR, SQL_WVARCHAR, SQL_WLONGVARCHAR};
SQLINTEGER col3;
SQLCHAR col4[128], col5[128];
SQLRETURN rc;
unsigned int i= 0;

CHECK_STMT_RC(Stmt, SQLGetTypeInfo(Stmt, SQL_ALL_TYPES));

CHECK_STMT_RC(Stmt, SQLBindCol(Stmt, 2, SQL_C_DEFAULT, (SQLPOINTER)&col2, 2, &len[0]));
CHECK_STMT_RC(Stmt, SQLBindCol(Stmt, 4, SQL_C_CHAR, (SQLPOINTER)col4, 128, &len[1]));
CHECK_STMT_RC(Stmt, SQLBindCol(Stmt, 5, SQL_C_CHAR, (SQLPOINTER)col5, 128, &len[2]));
CHECK_STMT_RC(Stmt, SQLBindCol(Stmt, 9, SQL_C_DEFAULT, (SQLPOINTER)&col9, 2, &len[3]));
CHECK_STMT_RC(Stmt, SQLBindCol(Stmt, 3, SQL_C_DEFAULT, (SQLPOINTER)&col3, 4, &len[4]));
CHECK_STMT_RC(Stmt, SQLBindCol(Stmt, 15, SQL_C_DEFAULT, (SQLPOINTER)&col15, 2, &len[5]));
CHECK_STMT_RC(Stmt, SQLBindCol(Stmt, 7, SQL_C_DEFAULT, (SQLPOINTER)&col7, 2, &len[6]));

while ((rc = SQLFetch(Stmt)) == SQL_SUCCESS)
{
IS(i < sizeof(ref2)/sizeof(SQLSMALLINT));
is_num(col2, ref2[i]);
++i;
}

EXPECT_STMT(Stmt, rc, SQL_NO_DATA_FOUND);

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

return OK;
}


MA_ODBC_TESTS my_tests[]=
{
{ t_gettypeinfo, "t_gettypeinfo", NORMAL },
Expand All @@ -790,6 +836,7 @@ MA_ODBC_TESTS my_tests[]=
{ odbc109, "odbc109_shema_owner_term", NORMAL },
{ odbc143, "odbc143_odbc160_ANSI_QUOTES", NORMAL },
{ odbc317, "odbc317_conattributes", NORMAL },
{ odbc326, "odbc326", NORMAL },
{ NULL, NULL }
};

Expand Down

0 comments on commit 5914ebf

Please sign in to comment.