treat the MYSQL_FIELD as read-only
authorDebian Qt/KDE Maintainers <debian-qt-kde@lists.debian.org>
Thu, 29 Sep 2022 08:41:52 +0000 (09:41 +0100)
committerDmitry Shachnev <mitya57@debian.org>
Thu, 29 Sep 2022 08:41:52 +0000 (09:41 +0100)
Origin: upstream, https://code.qt.io/cgit/qt/qtbase.git/commit/?id=549ee216fd5bf2b3
Last-Update: 2021-11-13

The MariaDB-connector-c version 3.2 and MariaDB server version 10.6
cooperate to avoid re-transferring the query metadata, so the fact that
we were modifying it was causing it to improperly decode the DATETIME
data types into string, as we had asked. We ended up with a 7-byte
string that was actually the date binary-encoded.

Gbp-Pq: Name mysql_field_readonly.diff

src/plugins/sqldrivers/mysql/qsql_mysql.cpp

index 7ca055eea24a979d0b2f2a9776649b3f5a2a1b19..49a6ae5b7ca74c06fd075abb9a4ebe81a8e3e816 100644 (file)
@@ -223,7 +223,7 @@ public:
     struct QMyField
     {
         char *outField = nullptr;
-        MYSQL_FIELD *myField = nullptr;
+        const MYSQL_FIELD *myField = nullptr;
         QMetaType::Type type = QMetaType::UnknownType;
         my_bool nullIndicator = false;
         ulong bufLength = 0ul;
@@ -361,11 +361,10 @@ static bool qIsInteger(int t)
 void QMYSQLResultPrivate::bindBlobs()
 {
     int i;
-    MYSQL_FIELD *fieldInfo;
     MYSQL_BIND *bind;
 
     for(i = 0; i < fields.count(); ++i) {
-        fieldInfo = fields.at(i).myField;
+        const MYSQL_FIELD *fieldInfo = fields.at(i).myField;
         if (qIsBlob(inBinds[i].buffer_type) && meta && fieldInfo) {
             bind = &inBinds[i];
             bind->buffer_length = fieldInfo->max_length;
@@ -392,35 +391,34 @@ bool QMYSQLResultPrivate::bindInValues()
     inBinds = new MYSQL_BIND[fields.size()];
     memset(inBinds, 0, fields.size() * sizeof(MYSQL_BIND));
 
-    MYSQL_FIELD *fieldInfo;
+    const MYSQL_FIELD *fieldInfo;
 
     while((fieldInfo = mysql_fetch_field(meta))) {
+        MYSQL_BIND *bind = &inBinds[i];
+
         QMyField &f = fields[i];
         f.myField = fieldInfo;
-
+        bind->buffer_length = f.bufLength = fieldInfo->length + 1;
+        bind->buffer_type = fieldInfo->type;
         f.type = qDecodeMYSQLType(fieldInfo->type, fieldInfo->flags);
         if (qIsBlob(fieldInfo->type)) {
             // the size of a blob-field is available as soon as we call
             // mysql_stmt_store_result()
             // after mysql_stmt_exec() in QMYSQLResult::exec()
-            fieldInfo->length = 0;
+            bind->buffer_length = f.bufLength = 0;
             hasBlobs = true;
         } else if (qIsInteger(f.type)) {
-            fieldInfo->length = 8;
+            bind->buffer_length = f.bufLength = 8;
         } else {
-            fieldInfo->type = MYSQL_TYPE_STRING;
+            bind->buffer_type = MYSQL_TYPE_STRING;
         }
-        bind = &inBinds[i];
-        field = new char[fieldInfo->length + 1];
-        memset(field, 0, fieldInfo->length + 1);
 
-        bind->buffer_type = fieldInfo->type;
-        bind->buffer = field;
-        bind->buffer_length = f.bufLength = fieldInfo->length + 1;
         bind->is_null = &f.nullIndicator;
         bind->length = &f.bufLength;
         bind->is_unsigned = fieldInfo->flags & UNSIGNED_FLAG ? 1 : 0;
-        f.outField=field;
+
+        char *field = new char[bind->buffer_length + 1]{};
+        bind->buffer = f.outField = field;
 
         ++i;
     }