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

Reply via email to