Skip to content

Commit 531c414

Browse files
committed
Bug #33748725 JDBC: Aggregate Function returning bad value on BIT field
type
1 parent e38389f commit 531c414

16 files changed

+88
-53
lines changed

driver/mysql_ps_resultset_metadata.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,13 @@ namespace mysql
5656

5757
/* {{{ MySQL_PreparedResultSetMetaData::MySQL_PreparedResultSetMetaData -I- */
5858
MySQL_PreparedResultSetMetaData::MySQL_PreparedResultSetMetaData(boost::shared_ptr< NativeAPI::NativeStatementWrapper > & _proxy,
59-
boost::shared_ptr< MySQL_DebugLogger> & l)
59+
boost::shared_ptr< MySQL_DebugLogger> & l)
6060
: proxy(_proxy), logger(l), result_meta( _proxy->result_metadata()),
61-
num_fields(_proxy->field_count())
61+
num_fields(_proxy->field_count()),
62+
server_version(_proxy->server_version())
6263
{
6364
CPP_ENTER("MySQL_PreparedResultSetMetaData::MySQL_PreparedResultSetMetaData");
65+
6466
}
6567
/* }}} */
6668

@@ -164,7 +166,7 @@ MySQL_PreparedResultSetMetaData::getColumnType(unsigned int columnIndex)
164166
int mysql_type = getFieldMeta(columnIndex)->type;
165167
CPP_INFO_FMT("type=%d", mysql_type);
166168
int ret = sql::mysql::util::mysql_type_to_datatype(
167-
getFieldMeta(columnIndex)
169+
getFieldMeta(columnIndex), server_version
168170
);
169171
CPP_INFO_FMT("our type is %d", ret);
170172
return ret;

driver/mysql_ps_resultset_metadata.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ class MySQL_PreparedResultSetMetaData : public sql::ResultSetMetaData
6363

6464
unsigned int num_fields;
6565

66+
unsigned long server_version;
67+
6668
public:
6769
MySQL_PreparedResultSetMetaData(boost::shared_ptr< NativeAPI::NativeStatementWrapper > & _proxy,
6870
boost::shared_ptr< MySQL_DebugLogger> & l);

driver/mysql_resultset.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ MySQL_ResultSet::MySQL_ResultSet(boost::shared_ptr< NativeAPI::NativeResultsetWr
8181
std::cout << "Elements=" << field_name_to_index_map.size() << "\n";
8282
#endif
8383
rs_meta.reset(new MySQL_ResultSetMetaData(result, logger));
84+
85+
server_version = proxy.lock()->get_server_version();
8486
}
8587
/* }}} */
8688

@@ -512,11 +514,11 @@ MySQL_ResultSet::getInt64(const uint32_t columnIndex) const
512514
return 0;
513515
}
514516

515-
516517
CPP_INFO_FMT("%ssigned", (getFieldMeta(columnIndex)->flags & UNSIGNED_FLAG)? "un":"");
518+
517519
was_null = false;
518520
if (getFieldMeta(columnIndex)->type == MYSQL_TYPE_BIT &&
519-
getFieldMeta(columnIndex)->flags != (BINARY_FLAG|UNSIGNED_FLAG)) {
521+
(server_version >= 80028 || !(getFieldMeta(columnIndex)->flags & BINARY_FLAG))) {
520522
uint64_t uval = 0;
521523
std::div_t length= std::div(getFieldMeta(columnIndex)->length, 8);
522524
if (length.rem) {
@@ -579,8 +581,9 @@ MySQL_ResultSet::getUInt64(const uint32_t columnIndex) const
579581

580582
CPP_INFO_FMT("%ssigned", (getFieldMeta(columnIndex)->flags & UNSIGNED_FLAG)? "un":"");
581583
was_null = false;
584+
582585
if (getFieldMeta(columnIndex)->type == MYSQL_TYPE_BIT &&
583-
getFieldMeta(columnIndex)->flags != (BINARY_FLAG|UNSIGNED_FLAG)) {
586+
( server_version >= 80028 || !(getFieldMeta(columnIndex)->flags & BINARY_FLAG))) {
584587
uint64_t uval = 0;
585588
std::div_t length= std::div(getFieldMeta(columnIndex)->length, 8);
586589
if (length.rem) {

driver/mysql_resultset.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ class MySQL_ResultSet : public sql::ResultSet
8080

8181
sql::ResultSet::enum_type resultset_type;
8282

83+
unsigned long server_version;
84+
8385
protected:
8486
void checkValid() const;
8587
void checkScrollable() const;

driver/mysql_resultset_metadata.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ MySQL_ResultSetMetaData::MySQL_ResultSetMetaData(boost::shared_ptr< NativeAPI::N
6464
if (result_p) {
6565
num_fields = result_p->num_fields();
6666
}
67+
server_version = result.lock()->server_version();
6768
}
6869
/* }}} */
6970

@@ -179,7 +180,9 @@ MySQL_ResultSetMetaData::getColumnType(unsigned int columnIndex)
179180
checkValid();
180181
checkColumnIndex(columnIndex);
181182

182-
return sql::mysql::util::mysql_type_to_datatype(getFieldMeta(columnIndex));
183+
return sql::mysql::util::mysql_type_to_datatype(
184+
getFieldMeta(columnIndex),
185+
server_version);
183186
}
184187
/* }}} */
185188

driver/mysql_resultset_metadata.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ class MySQL_ResultSetMetaData : public sql::ResultSetMetaData
6161
{
6262
boost::weak_ptr< NativeAPI::NativeResultsetWrapper > result;
6363
boost::shared_ptr< MySQL_DebugLogger > logger;
64+
unsigned long server_version;
6465
unsigned int num_fields;
6566

6667
public:

driver/mysql_util.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -397,11 +397,12 @@ const OUR_CHARSET * find_charset(unsigned int charsetnr)
397397

398398
/* {{{ mysql_to_datatype() -I- */
399399
int
400-
mysql_type_to_datatype(const MYSQL_FIELD * const field)
400+
mysql_type_to_datatype(const MYSQL_FIELD * const field,
401+
unsigned long server_version)
401402
{
402403
switch (field->type) {
403404
case MYSQL_TYPE_BIT:
404-
if (field->flags !=(BINARY_FLAG|UNSIGNED_FLAG))
405+
if (server_version >= 80028 || !(field->flags & BINARY_FLAG))
405406
return sql::DataType::BIT;
406407
return sql::DataType::BINARY;
407408
case MYSQL_TYPE_DECIMAL:

driver/mysql_util.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,8 @@ void throwSQLException(::sql::mysql::NativeAPI::NativeConnectionWrapper & proxy)
185185
void throwSQLException(::sql::mysql::NativeAPI::NativeStatementWrapper & proxy);
186186

187187
int mysql_string_type_to_datatype(const sql::SQLString & name);
188-
int mysql_type_to_datatype(const MYSQL_FIELD * const field);
188+
int mysql_type_to_datatype(const MYSQL_FIELD * const fieldm,
189+
unsigned long server_version);
189190
const char * mysql_type_to_string(const MYSQL_FIELD * const field, boost::shared_ptr< sql::mysql::MySQL_DebugLogger > & l);
190191

191192
char * utf8_strup(const char * const src, size_t srclen);

driver/nativeapi/mysql_native_connection_wrapper.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ MySQL_NativeConnectionWrapper::store_result()
565565
return NULL;
566566
}
567567

568-
return new MySQL_NativeResultsetWrapper(raw, api);
568+
return new MySQL_NativeResultsetWrapper(mysql, raw, api);
569569
}
570570
/* }}} */
571571

@@ -601,7 +601,7 @@ MySQL_NativeConnectionWrapper::use_result()
601601
return NULL;
602602
}
603603

604-
return new MySQL_NativeResultsetWrapper(raw, api);
604+
return new MySQL_NativeResultsetWrapper(mysql, raw, api);
605605
}
606606
/* }}} */
607607

driver/nativeapi/mysql_native_resultset_wrapper.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ namespace NativeAPI
4646
{
4747

4848
/* {{{ MySQL_NativeResultsetWrapper::MySQL_NativeResultsetWrapper */
49-
MySQL_NativeResultsetWrapper::MySQL_NativeResultsetWrapper(::MYSQL_RES * res, boost::shared_ptr< NativeAPI::IMySQLCAPI > & _capi
49+
MySQL_NativeResultsetWrapper::MySQL_NativeResultsetWrapper(::MYSQL *_mysql,::MYSQL_RES * res, boost::shared_ptr< NativeAPI::IMySQLCAPI > & _capi
5050
/*, boost::shared_ptr< MySQL_DebugLogger > & l*/)
51-
: /*logger(l),*/ capi(_capi), rs(res)
51+
: /*logger(l),*/ capi(_capi), mysql(_mysql), rs(res)
5252
{
5353
}
5454
/* }}} */
@@ -61,6 +61,13 @@ MySQL_NativeResultsetWrapper::~MySQL_NativeResultsetWrapper()
6161
}
6262
/* }}} */
6363

64+
/* {{{ MySQL_NativeResultsetWrapper::server_version */
65+
unsigned long
66+
MySQL_NativeResultsetWrapper::server_version()
67+
{
68+
return capi->get_server_version(mysql);
69+
}
70+
/* }}} */
6471

6572
/* {{{ MySQL_NativeResultsetWrapper::data_seek */
6673
void

driver/nativeapi/mysql_native_resultset_wrapper.h

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,10 @@
4040

4141
#if (MYCPPCONN_STATIC_MYSQL_VERSION_ID > 80004)
4242
struct MYSQL_RES;
43+
struct MYSQL;
4344
#else
45+
struct st_mysql;
46+
#define MYSQL st_mysql
4447
struct st_mysql_res;
4548
#define MYSQL_RES st_mysql_res
4649
#endif
@@ -60,23 +63,25 @@ class IMySQLCAPI;
6063
class MySQL_NativeResultsetWrapper : public NativeResultsetWrapper
6164
{
6265
public:
63-
MySQL_NativeResultsetWrapper(::MYSQL_RES *, boost::shared_ptr<NativeAPI::IMySQLCAPI> &/*, boost::shared_ptr< MySQL_DebugLogger > & l*/);
66+
MySQL_NativeResultsetWrapper(::MYSQL *,::MYSQL_RES *, boost::shared_ptr<NativeAPI::IMySQLCAPI> &/*, boost::shared_ptr< MySQL_DebugLogger > & l*/);
6467

6568
~MySQL_NativeResultsetWrapper();
6669

67-
void data_seek(uint64_t);
70+
unsigned long server_version() override;
6871

69-
::MYSQL_FIELD * fetch_field();
72+
void data_seek(uint64_t) override;
7073

71-
::MYSQL_FIELD * fetch_field_direct(unsigned int);
74+
::MYSQL_FIELD * fetch_field() override;
7275

73-
unsigned long * fetch_lengths();
76+
::MYSQL_FIELD * fetch_field_direct(unsigned int) override;
7477

75-
char** fetch_row();
78+
unsigned long * fetch_lengths() override;
7679

77-
unsigned int num_fields();
80+
char** fetch_row() override;
7881

79-
uint64_t num_rows();
82+
unsigned int num_fields() override;
83+
84+
uint64_t num_rows() override;
8085

8186
//boost::shared_ptr<IMySQLCAPI> getApiHandle();
8287

@@ -89,6 +94,7 @@ class MySQL_NativeResultsetWrapper : public NativeResultsetWrapper
8994

9095
boost::shared_ptr< NativeAPI::IMySQLCAPI > capi;
9196

97+
::MYSQL *mysql;
9298
::MYSQL_RES * rs;
9399
};
94100

driver/nativeapi/mysql_native_statement_wrapper.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,15 @@ MySQL_NativeStatementWrapper::~MySQL_NativeStatementWrapper()
6767
/* }}} */
6868

6969

70+
/* {{{ MySQL_NativeStatementWrapper::affected_rows() */
71+
unsigned long
72+
MySQL_NativeStatementWrapper::server_version()
73+
{
74+
return api->get_server_version(stmt->mysql);
75+
}
76+
/* }}} */
77+
78+
7079
/* {{{ MySQL_NativeStatementWrapper::affected_rows() */
7180
uint64_t
7281
MySQL_NativeStatementWrapper::affected_rows()
@@ -212,7 +221,7 @@ MySQL_NativeStatementWrapper::result_metadata()
212221
return NULL;
213222
}
214223

215-
return new MySQL_NativeResultsetWrapper(raw, api);
224+
return new MySQL_NativeResultsetWrapper(stmt->mysql, raw, api);
216225
}
217226
/* }}} */
218227

driver/nativeapi/mysql_native_statement_wrapper.h

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -72,49 +72,51 @@ class MySQL_NativeStatementWrapper : public NativeStatementWrapper
7272
MySQL_NativeStatementWrapper(::MYSQL_STMT *, boost::shared_ptr<IMySQLCAPI>, NativeConnectionWrapper * connProxy);
7373
~MySQL_NativeStatementWrapper();
7474

75-
uint64_t affected_rows();
75+
unsigned long server_version() override;
7676

77-
bool attr_set(MySQL_Statement_Options option, const void *arg);
77+
uint64_t affected_rows() override;
7878

79-
bool bind_param(::MYSQL_BIND *);
79+
bool attr_set(MySQL_Statement_Options option, const void *arg) override;
8080

81-
bool bind_result(::MYSQL_BIND *);
81+
bool bind_param(::MYSQL_BIND *) override;
8282

83-
void data_seek(uint64_t );
83+
bool bind_result(::MYSQL_BIND *) override;
8484

85-
unsigned int errNo();
85+
void data_seek(uint64_t ) override;
8686

87-
sql::SQLString error();
87+
unsigned int errNo() override;
8888

89-
int execute ();
89+
sql::SQLString error() override;
9090

91-
int fetch();
91+
int execute () override;
9292

93-
unsigned int field_count();
93+
int fetch() override;
9494

95-
bool more_results();
95+
unsigned int field_count() override;
9696

97-
int next_result();
97+
bool more_results() override;
9898

99-
uint64_t num_rows();
99+
int next_result() override;
100100

101-
unsigned long param_count();
101+
uint64_t num_rows() override;
102102

103-
int prepare (const ::sql::SQLString &);
103+
unsigned long param_count() override;
104104

105-
NativeResultsetWrapper * result_metadata();
105+
int prepare (const ::sql::SQLString &) override;
106106

107-
bool send_long_data(unsigned int par_number, const char * data, unsigned long len);
107+
NativeResultsetWrapper * result_metadata() override;
108108

109-
::sql::SQLString sqlstate();
109+
bool send_long_data(unsigned int par_number, const char * data, unsigned long len) override;
110110

111-
int store_result();
111+
::sql::SQLString sqlstate() override;
112112

113-
int stmt_next_result();
113+
int store_result() override;
114114

115-
bool stmt_free_result();
115+
int stmt_next_result() override;
116116

117-
unsigned int warning_count();
117+
bool stmt_free_result() override;
118+
119+
unsigned int warning_count() override;
118120
};
119121

120122

driver/nativeapi/native_resultset_wrapper.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ class NativeResultsetWrapper : public boost::noncopyable
6060
public:
6161
virtual ~NativeResultsetWrapper(){}
6262

63+
virtual unsigned long server_version() = 0;
64+
6365
virtual void data_seek(uint64_t) = 0;
6466

6567
virtual ::MYSQL_FIELD * fetch_field() = 0;

driver/nativeapi/native_statement_wrapper.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ class NativeStatementWrapper : public boost::noncopyable
7272

7373
virtual ~NativeStatementWrapper(){}
7474

75+
virtual unsigned long server_version() = 0;
76+
7577
virtual uint64_t affected_rows() = 0;
7678

7779
virtual bool attr_set(MySQL_Statement_Options attr, const void *arg) = 0;

test/unit/bugs/bugs.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -718,10 +718,6 @@ void bugs::bug68523()
718718

719719
void bugs::bug66235()
720720
{
721-
// TODO: remove this block when the test is fixed
722-
if (!getenv("RUN_BUG_66235"))
723-
return;
724-
725721
logMsg("bug::bug66235");
726722
try
727723
{
@@ -824,10 +820,6 @@ void bugs::bug21066575()
824820

825821
void bugs::bug14520822()
826822
{
827-
// TODO: remove this block when the test is fixed
828-
if (!getenv("RUN_BUG_14520822"))
829-
return;
830-
831823
logMsg("bug::bug14520822");
832824
try
833825
{

0 commit comments

Comments
 (0)