Date: Friday, October 20, 2006 @ 20:40:52
Author: csaba
Path: /cvsroot/carob/libmysequoia
Modified: src/CarobMySQL.cpp (1.86 -> 1.87) src/CarobStmt.cpp (1.40 ->
1.41) src/Utils.cpp (1.42 -> 1.43) test/TestMySQLAPI.cpp (1.42
-> 1.43) test/TestMySQLAPI.hpp (1.18 -> 1.19)
Fill the max_length in mysql_stmt_store_result. Fixes LMS-28
-----------------------+
src/CarobMySQL.cpp | 95 ++++++++++++++++++++++++++----------------------
src/CarobStmt.cpp | 38 ++++++++++---------
src/Utils.cpp | 2 -
test/TestMySQLAPI.cpp | 50 +++++++++++++++++++++++++
test/TestMySQLAPI.hpp | 2 +
5 files changed, 125 insertions(+), 62 deletions(-)
Index: libmysequoia/src/CarobMySQL.cpp
diff -u libmysequoia/src/CarobMySQL.cpp:1.86
libmysequoia/src/CarobMySQL.cpp:1.87
--- libmysequoia/src/CarobMySQL.cpp:1.86 Wed Oct 18 16:23:41 2006
+++ libmysequoia/src/CarobMySQL.cpp Fri Oct 20 20:40:52 2006
@@ -632,57 +632,66 @@
if (res)
{
- MYSQL *mysqlPtr = 0;
- CarobMYSQL *cm = 0;
-
- //Check if it is a "live" resultset
- if (!res->data)
+ if (res->unbuffered_fetch_cancelled == 1)
{
- mysqlPtr = res->handle;
-
- //if it is a CarobMYSQL object, free the results from
there too
- if (isCarobObject(mysqlPtr))
+ // delete only the resultset
+ delete res;
+ }
+ else
+ {
+ // delete the resultset and all the fields
+ MYSQL *mysqlPtr = 0;
+ CarobMYSQL *cm = 0;
+
+ //Check if it is a "live" resultset
+ if (!res->data)
{
- cm = (CarobMYSQL *) (mysqlPtr->field_alloc.used);
- if (res == cm->liveResultPtr)
+ mysqlPtr = res->handle;
+
+ //if it is a CarobMYSQL object, free the results from
there too
+ if (isCarobObject(mysqlPtr))
{
- cm->liveResultPtr = 0;
- cm->drsPtr = 0;
- cm->stmtPtr->close();
+ cm = (CarobMYSQL *) (mysqlPtr->field_alloc.used);
+ if (res == cm->liveResultPtr)
+ {
+ cm->liveResultPtr = 0;
+ cm->drsPtr = 0;
+ cm->stmtPtr->close();
+ }
}
}
- }
-
- if (res->data)
- {
- MYSQL_ROWS *row = res->data->data;
- while (row)
+
+ if (res->data)
{
- MYSQL_ROWS *tempRow = row;
- row = row->next;
- delete_row_data(tempRow->data, res->field_count);
- delete tempRow;
+ MYSQL_ROWS *row = res->data->data;
+ while (row)
+ {
+ MYSQL_ROWS *tempRow = row;
+ row = row->next;
+ delete_row_data(tempRow->data, res->field_count);
+ delete tempRow;
+ }
+
+ delete res->data;
}
-
- delete res->data;
- }
- else
- {
- delete_row_data(res->current_row,res->field_count);
- }
-
- if (mysqlPtr && mysqlPtr->fields == res->fields)
- {
- mysqlPtr->fields = 0;
- mysqlPtr->field_count = 0;
+ else
+ {
+ delete_row_data(res->current_row,res->field_count);
+ }
+
+ if (mysqlPtr && mysqlPtr->fields == res->fields)
+ {
+ mysqlPtr->fields = 0;
+ mysqlPtr->field_count = 0;
+ }
+ delete_query_fields(res->fields, res->field_count);
+
+ delete [] res->lengths;
+ delete res;
+
+ if (mysqlPtr)
+ mysqlPtr->status = MYSQL_STATUS_READY;
}
- delete_query_fields(res->fields, res->field_count);
-
- delete [] res->lengths;
- delete res;
-
- if (mysqlPtr)
- mysqlPtr->status = MYSQL_STATUS_READY;
}
LOG4CXX_DEBUG(logger, "Leaving free_results.");
}
Index: libmysequoia/src/CarobStmt.cpp
diff -u libmysequoia/src/CarobStmt.cpp:1.40 libmysequoia/src/CarobStmt.cpp:1.41
--- libmysequoia/src/CarobStmt.cpp:1.40 Fri Oct 20 14:54:57 2006
+++ libmysequoia/src/CarobStmt.cpp Fri Oct 20 20:40:52 2006
@@ -602,23 +602,10 @@
{
result = new MYSQL_RES;
memset(result, 0, sizeof(MYSQL_RES));
- result->data = new MYSQL_DATA;
- memset(result->data, 0, sizeof(MYSQL_DATA));
- //duplicate fields to the dummy resultset
- int field_count = m_stmt->field_count;
- result->fields = new MYSQL_FIELD[field_count];
- memcpy(result->fields, m_stmt->fields, field_count * sizeof(MYSQL_FIELD));
- for (MYSQL_FIELD *colPtr=result->fields; field_count; colPtr++,
field_count--)
- {
- colPtr->name = cstrdup(colPtr->name);
- colPtr->org_name = cstrdup(colPtr->org_name);
- colPtr->table = cstrdup(colPtr->table);
- colPtr->db = cstrdup(colPtr->db);
- colPtr->catalog = cstrdup(colPtr->catalog);
- }
- result->data->fields = result->field_count = m_stmt->field_count;
- result->eof = true;
- }
+ result->unbuffered_fetch_cancelled = 1; // reminder to not to free this
resultset fields
+ result->fields = m_stmt->fields;
+ result->field_count = m_stmt->field_count;
+ }
LOG4CXX_DEBUG(logger, "Leaving result_metadata: result=" << result);
return result;
@@ -832,17 +819,21 @@
switch (fPtr->type)
{
case MYSQL_TYPE_TINY:
+ fPtr->max_length = 4;
result = new unsigned char(liveResultSet->getInt32(colNo));
break;
case MYSQL_TYPE_SHORT:
+ fPtr->max_length = 6;
result = new short(liveResultSet->getInt32(colNo));
break;
case MYSQL_TYPE_LONG:
+ fPtr->max_length = 11;
//we need to use getAsInt and not getInt32 because mysql java client
will convert the
//unsigned integer to long
result = new int(liveResultSet->getAsInt(colNo));
break;
case MYSQL_TYPE_LONGLONG:
+ fPtr->max_length = 21;
//we need to use getAsInt64 and not getInt64 because mysql java client
will convert the
//unsigned long to bigint
if (fPtr->flags & UNSIGNED_FLAG)
@@ -851,9 +842,11 @@
result = new int64_t(liveResultSet->getAsInt64(colNo));
break;
case MYSQL_TYPE_FLOAT:
+ fPtr->max_length = 331;
result = new float(liveResultSet->getFloat(colNo));
break;
case MYSQL_TYPE_DOUBLE:
+ fPtr->max_length = 331;
result = new double(liveResultSet->getDouble(colNo));
break;
case MYSQL_TYPE_TINY_BLOB:
@@ -870,22 +863,31 @@
if (fPtr->flags & BINARY_FLAG)
{
LargeData &d = liveResultSet->getByteArray(colNo);
+ fPtr->max_length = d.length;
result = new string((char *)d.data, d.length);
}
else
- result = new string(from_wstring(liveResultSet->getAsString(colNo)));
+ {
+ std::wstring ws =liveResultSet->getAsString(colNo);
+ fPtr->max_length = ws.length();
+ result = new string(from_wstring(ws));
+ }
break;
case MYSQL_TYPE_TIME:
+ fPtr->max_length = 15;
result = new int(liveResultSet->getAsInt(colNo));
break;
case MYSQL_TYPE_DATE:
+ fPtr->max_length = 10;
result = new int64_t(liveResultSet->getAsInt64(colNo));
break;
case MYSQL_TYPE_DATETIME:
case MYSQL_TYPE_TIMESTAMP:
+ fPtr->max_length = 30;
result = new SQLTimeStamp(liveResultSet->getTimeStamp(colNo));
break;
case MYSQL_TYPE_NULL:
+ fPtr->max_length = 0;
break;
default:
LOG4CXX_FATAL(logger, "This should never happen!!");
Index: libmysequoia/src/Utils.cpp
diff -u libmysequoia/src/Utils.cpp:1.42 libmysequoia/src/Utils.cpp:1.43
--- libmysequoia/src/Utils.cpp:1.42 Tue Aug 1 10:53:01 2006
+++ libmysequoia/src/Utils.cpp Fri Oct 20 20:40:52 2006
@@ -908,7 +908,7 @@
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_STRING:
{
- size_t length = min((size_t)max((int64_t)s_length - bind->offset,
(int64_t)0), (size_t)bind->buffer_length);
+ size_t length = min((size_t)max((int64_t)s_length -
(int64_t)bind->offset, (int64_t)0), (size_t)bind->buffer_length);
if (length)
memcpy(bind->buffer, s->data()+bind->offset, length);
if (length < bind->buffer_length)
Index: libmysequoia/test/TestMySQLAPI.cpp
diff -u libmysequoia/test/TestMySQLAPI.cpp:1.42
libmysequoia/test/TestMySQLAPI.cpp:1.43
--- libmysequoia/test/TestMySQLAPI.cpp:1.42 Fri Oct 20 14:54:57 2006
+++ libmysequoia/test/TestMySQLAPI.cpp Fri Oct 20 20:40:52 2006
@@ -1027,3 +1027,53 @@
CPPUNIT_ASSERT(mysql_stmt_close(stmt) == 0);
}
+
+void TestMySQLAPI::bug_lms_28_test(void)
+{
+ MYSQL_STMT *stmt;
+ MYSQL_BIND outbind[3];
+ my_bool isnull_i = true;
+ my_bool isnull_j = false;
+ my_bool isnull_c = true;
+ my_bool is_true = true;
+ int i,j;
+ char c[5];
+ char *query = "select 123, 'abc', null";
+
+ CPPUNIT_ASSERT(mysql_real_connect(mysql, HOST, USER1, PASSWD1, DB1, 0, 0, 0)
!= 0);
+
+ CPPUNIT_ASSERT((stmt = mysql_stmt_init(mysql)) != 0);
+ // calculate the max_length when storing the result
+ CPPUNIT_ASSERT(mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH,
&is_true) == 0);
+
+ CPPUNIT_ASSERT(mysql_stmt_prepare(stmt, query, strlen(query)) == 0);
+ CPPUNIT_ASSERT(mysql_stmt_execute(stmt) == 0);
+
+ // stmt_store_result must set the max_length
+ CPPUNIT_ASSERT(mysql_stmt_store_result(stmt) == 0);
+ CPPUNIT_ASSERT(stmt->fields[0].max_length == 21);
+ CPPUNIT_ASSERT(stmt->fields[1].max_length == 3);
+ CPPUNIT_ASSERT(stmt->fields[2].max_length == 0);
+
+ memset(outbind, 0, sizeof(outbind));
+ outbind[0].buffer_type= MYSQL_TYPE_LONG;
+ outbind[0].buffer= (char *)&i;
+ outbind[0].is_null = &isnull_i;
+ outbind[1].buffer_type= MYSQL_TYPE_STRING;
+ outbind[1].buffer= c;
+ outbind[1].is_null = &isnull_c;
+ outbind[1].buffer_length = stmt->fields[1].max_length + 1;
+ outbind[2].buffer_type= MYSQL_TYPE_LONG;
+ outbind[2].buffer= (char *)&j;
+ outbind[2].is_null = &isnull_j;
+ CPPUNIT_ASSERT(mysql_stmt_bind_result(stmt, outbind) == 0);
+
+ CPPUNIT_ASSERT(mysql_stmt_fetch(stmt) == 0);
+ CPPUNIT_ASSERT(isnull_i == false);
+ CPPUNIT_ASSERT(isnull_j == true);
+ CPPUNIT_ASSERT(isnull_c == false);
+ CPPUNIT_ASSERT(123 == i);
+ CPPUNIT_ASSERT(strcmp("abc", c) == 0);
+
+ CPPUNIT_ASSERT(mysql_stmt_close(stmt) == 0);
+}
Index: libmysequoia/test/TestMySQLAPI.hpp
diff -u libmysequoia/test/TestMySQLAPI.hpp:1.18
libmysequoia/test/TestMySQLAPI.hpp:1.19
--- libmysequoia/test/TestMySQLAPI.hpp:1.18 Fri Oct 20 14:54:57 2006
+++ libmysequoia/test/TestMySQLAPI.hpp Fri Oct 20 20:40:52 2006
@@ -65,6 +65,7 @@
CPPUNIT_TEST (mysql_warning_count_test);
CPPUNIT_TEST (bug_lms_24_test);
CPPUNIT_TEST (bug_lms_27_test);
+ CPPUNIT_TEST (bug_lms_28_test);
CPPUNIT_TEST_SUITE_END ();
public:
@@ -107,6 +108,7 @@
void mysql_warning_count_test(void);
void bug_lms_24_test(void);
void bug_lms_27_test(void);
+ void bug_lms_28_test(void);
private:
MYSQL *mysql;
};
_______________________________________________
Carob-commits mailing list
[email protected]
https://forge.continuent.org/mailman/listinfo/carob-commits