Skip to content

Commit 13bfd92

Browse files
committed
ODBC-350 The fix and the testcase
It's rather the workaround of the bug in the server - for bit(1) value in subquery it returns string representation of the value, i.e. '0' or '1' instead of '\0' or '\1', while reporting the type to be MYSQL_BIT Update of C/C to v3.3.5 Removed eol'ed server versions from travis
1 parent 9b96270 commit 13bfd92

File tree

9 files changed

+79
-15
lines changed

9 files changed

+79
-15
lines changed

.travis.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,16 +87,14 @@ jobs:
8787
os: windows
8888
language: shell
8989
name: "CS 10.6 - Windows"
90-
- env: srv=mariadb v=10.3 local=1
91-
name: "CS 10.3"
90+
- env: srv=mariadb v=10.11 local=1
91+
name: "CS 10.11"
9292
- env: srv=mariadb v=10.4 local=1
9393
name: "CS 10.4"
9494
- env: srv=mariadb v=10.5 local=1
9595
name: "CS 10.5"
9696
- env: srv=mariadb v=10.10 local=1
9797
name: "CS 10.10"
98-
- env: srv=mariadb v=10.8 local=1
99-
name: "CS 10.8"
10098
- env: srv=mariadb v=10.9 local=1
10199
name: "CS 10.9"
102100
- env: srv=mysql v=5.7

CMakeLists.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# ************************************************************************************
2-
# Copyright (C) 2013,2022 MariaDB Corporation AB
2+
# Copyright (C) 2013,2023 MariaDB Corporation AB
33
#
44
# This library is free software; you can redistribute it and/or
55
# modify it under the terms of the GNU Library General Public
@@ -131,7 +131,6 @@ IF(WIN32)
131131
STRING(REPLACE "/Zi" "/ZI" COMPILER_FLAGS ${COMPILER_FLAGS})
132132
ENDIF(NOT WITH_ASAN)
133133
MESSAGE (STATUS "CMAKE_${COMPILER}_FLAGS_${BUILD_TYPE}= ${COMPILER_FLAGS}")
134-
MESSAGE (STATUS "CMAKE_SHARED_LINKER_FLAGS_${BUILD_TYPE}= ${CMAKE_SHARED_LINKER_FLAGS_${BUILD_TYPE}}")
135134
SET(CMAKE_${COMPILER}_FLAGS_${BUILD_TYPE} ${COMPILER_FLAGS} CACHE
136135
STRING "overwritten by mariadb-odbc" FORCE)
137136
ENDIF()

libmariadb

ma_helper.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1355,4 +1355,11 @@ void MADB_InstallStmt(MADB_Stmt *Stmt, MYSQL_STMT *stmt)
13551355
MADB_StmtResetResultStructures(Stmt);
13561356
MADB_DescSetIrdMetadata(Stmt, mysql_fetch_fields(FetchMetadata(Stmt)), mysql_stmt_field_count(Stmt->stmt));
13571357
}
1358+
}
1359+
1360+
1361+
enum enum_field_types MADB_GetNativeFieldType(MADB_Stmt *Stmt, int i)
1362+
{
1363+
/* Assuming the caller knows what is it calling for - i.e. i is valid, and stmt->metadata is set. Should be */
1364+
return mysql_fetch_fields(Stmt->metadata)[i].type;
13581365
}

ma_helper.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ BOOL MADB_IsIntType (SQLSMALLINT ConciseType);
7676
/* For multistatement picks stmt handler pointed by stored index, and sets it as "current" stmt handler */
7777
void MADB_InstallStmt (MADB_Stmt *Stmt, MYSQL_STMT *stmt);
7878

79+
enum enum_field_types MADB_GetNativeFieldType(MADB_Stmt *Stmt, int i);
80+
7981
/* for dummy binding */
8082
extern my_bool DummyError;
8183

ma_odbc.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ typedef struct
8787
{
8888
SQLUSMALLINT *RowOperationPtr;
8989
SQLULEN *RowOffsetPtr;
90-
MYSQL_BIND *Bind;
90+
/* MYSQL_BIND *Bind;*/
9191
SQLLEN dummy;
9292
SQLUINTEGER BindSize; /* size of each structure if using * Row-wise Binding */
9393
SQLSMALLINT Allocated;
@@ -97,18 +97,18 @@ typedef struct
9797
{
9898
SQLUSMALLINT *ParamOperationPtr;
9999
SQLULEN *ParamOffsetPtr;
100-
MYSQL_BIND *Bind;
100+
/* MYSQL_BIND *Bind;*/
101101
SQLLEN ParamsetSize;
102102
SQLUINTEGER ParamBindType;
103103
SQLSMALLINT Allocated;
104104
} MADB_Apd;
105105

106106
typedef struct
107107
{
108-
MADB_Stmt* stmt;
108+
/*MADB_Stmt* stmt;*/
109109
SQLULEN* RowsFetched;
110110
SQLUSMALLINT* RowStatusArray;
111-
MYSQL_FIELD* Fields;
111+
/* MYSQL_FIELD* Fields;*/
112112
SQLUINTEGER FieldCount;
113113
SQLSMALLINT Allocated;
114114
} MADB_Ird;

ma_statement.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1887,7 +1887,6 @@ SQLRETURN MADB_PrepareBind(MADB_Stmt *Stmt, int RowNumber)
18871887
break;
18881888
}
18891889
}
1890-
18911890
return SQL_SUCCESS;
18921891
}
18931892
/* }}} */
@@ -1972,7 +1971,7 @@ SQLRETURN MADB_FixFetchedValues(MADB_Stmt *Stmt, int RowNumber, MYSQL_ROW_OFFSET
19721971
char *p= (char *)Stmt->result[i].buffer;
19731972
if (p)
19741973
{
1975-
*p= test(*p != '\0');
1974+
*p= test(*p != '\0' && !(MADB_GetNativeFieldType(Stmt, i) == MYSQL_TYPE_BIT && *p == '0'));
19761975
}
19771976
}
19781977
break;
@@ -2185,7 +2184,6 @@ SQLRETURN MADB_FixFetchedValues(MADB_Stmt *Stmt, int RowNumber, MYSQL_ROW_OFFSET
21852184
}
21862185
}
21872186
}
2188-
21892187
return rc;
21902188
}
21912189
/* }}} */

test/result2.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,6 +1521,65 @@ ODBC_TEST(t_odbc214)
15211521
return OK;
15221522
}
15231523

1524+
/* The server returns '0' and '1' for bit field in subquery, while reporting it as a BIT. Connector interpreted '0'
1525+
as '\1'/true while fetched as a BIT since '0' != '\0' */
1526+
ODBC_TEST(t_odbc350)
1527+
{
1528+
SQLCHAR v1= 0, v2= 0;
1529+
1530+
OK_SIMPLE_STMT(Stmt, "DROP TABLE IF EXISTS t_odbc350");
1531+
OK_SIMPLE_STMT(Stmt, "CREATE TABLE t_odbc350 (v BIT(1), v2 BIT(8), v3 BIT(9))");
1532+
OK_SIMPLE_STMT(Stmt, "INSERT INTO t_odbc350 VALUES(0, 0, 256)");
1533+
1534+
OK_SIMPLE_STMT(Stmt, "SELECT v, (SELECT v FROM t_odbc350 LIMIT 1) FROM t_odbc350");
1535+
1536+
CHECK_STMT_RC(Stmt, SQLBindCol(Stmt, 1, SQL_C_BIT, &v1, sizeof(v1), NULL));
1537+
CHECK_STMT_RC(Stmt, SQLBindCol(Stmt, 2, SQL_C_BIT, &v2, sizeof(v2), NULL));
1538+
1539+
CHECK_STMT_RC(Stmt, SQLFetch(Stmt));
1540+
is_num(v1, 0);
1541+
is_num(v2, 0);
1542+
EXPECT_STMT(Stmt, SQLFetch(Stmt), SQL_NO_DATA);
1543+
CHECK_STMT_RC(Stmt, SQLFreeStmt(Stmt, SQL_CLOSE));
1544+
1545+
OK_SIMPLE_STMT(Stmt, "UPDATE t_odbc350 SET v=1");
1546+
OK_SIMPLE_STMT(Stmt, "SELECT v, (SELECT v FROM t_odbc350 LIMIT 1) FROM t_odbc350");
1547+
1548+
CHECK_STMT_RC(Stmt, SQLFetch(Stmt));
1549+
is_num(v1, 1);
1550+
is_num(v2, 1);
1551+
EXPECT_STMT(Stmt, SQLFetch(Stmt), SQL_NO_DATA);
1552+
CHECK_STMT_RC(Stmt, SQLFreeStmt(Stmt, SQL_CLOSE));
1553+
1554+
OK_SIMPLE_STMT(Stmt, "SELECT v2, (SELECT v2 FROM t_odbc350 LIMIT 1) FROM t_odbc350");
1555+
1556+
CHECK_STMT_RC(Stmt, SQLFetch(Stmt));
1557+
is_num(v1, 0);
1558+
is_num(v2, 0);
1559+
EXPECT_STMT(Stmt, SQLFetch(Stmt), SQL_NO_DATA);
1560+
CHECK_STMT_RC(Stmt, SQLFreeStmt(Stmt, SQL_CLOSE));
1561+
1562+
OK_SIMPLE_STMT(Stmt, "SELECT v3, (SELECT v3 FROM t_odbc350 LIMIT 1) FROM t_odbc350");
1563+
1564+
CHECK_STMT_RC(Stmt, SQLFetch(Stmt));
1565+
is_num(v1, 1);
1566+
is_num(v2, 1);
1567+
EXPECT_STMT(Stmt, SQLFetch(Stmt), SQL_NO_DATA);
1568+
CHECK_STMT_RC(Stmt, SQLFreeStmt(Stmt, SQL_CLOSE));
1569+
1570+
OK_SIMPLE_STMT(Stmt, "UPDATE t_odbc350 SET v3=0");
1571+
OK_SIMPLE_STMT(Stmt, "SELECT v3, (SELECT v3 FROM t_odbc350 LIMIT 1) FROM t_odbc350");
1572+
1573+
CHECK_STMT_RC(Stmt, SQLFetch(Stmt));
1574+
is_num(v1, 0);
1575+
is_num(v2, 0);
1576+
EXPECT_STMT(Stmt, SQLFetch(Stmt), SQL_NO_DATA);
1577+
CHECK_STMT_RC(Stmt, SQLFreeStmt(Stmt, SQL_CLOSE));
1578+
OK_SIMPLE_STMT(Stmt, "DROP TABLE IF EXISTS t_odbc350");
1579+
1580+
return OK;
1581+
}
1582+
15241583

15251584
MA_ODBC_TESTS my_tests[]=
15261585
{
@@ -1554,6 +1613,7 @@ MA_ODBC_TESTS my_tests[]=
15541613
{t_odbc232, "t_odbc232"},
15551614
{t_odbc274, "t_odbc274_InsDelReplace_returning"},
15561615
{t_odbc214, "t_odbc214_medium"},
1616+
{t_odbc350, "t_odbc350_bit_in_subquery"},
15571617
{NULL, NULL}
15581618
};
15591619

test/tap.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,7 @@ BOOL is_str_ex(const char* str1, const char* str2, size_t len, BOOL verbose)
657657
{
658658
if (verbose)
659659
{
660-
fprintf(stdout, "# %s %s", str1, str2);
660+
fprintf(stdout, "# %s %s\n", str1, str2);
661661
}
662662
return str1 == NULL || str2 == NULL || strncmp(str1, str2, len) != 0;
663663
}

0 commit comments

Comments
 (0)