summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Ehrlicher <ch.ehrlicher@gmx.de>2024-02-26 14:35:07 +0100
committerChristian Ehrlicher <ch.ehrlicher@gmx.de>2024-03-10 19:15:47 +0100
commite2e818483fbc6fe04d364378640178ca5f91b2fb (patch)
treee9eb0fcf4b5cf18d9d8d0a69daf516f1d4b117b8
parent453e66c61bef47a83b4e498122e53b1b0404ed12 (diff)
SQL/MySQL: retrieve default column value for QSqlDatabase::record()
Retrieve the default value (if set) of a column during QSqlDatabase::record() but not for QSqlQuery::record() as it's done for the other drivers which support retrieving the default column value. Fixes: QTBUG-122723 Change-Id: I92e052bfa6d88e019c0151fbcbc1483a65770c55 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
-rw-r--r--src/plugins/sqldrivers/mysql/qsql_mysql.cpp29
-rw-r--r--src/sql/kernel/qsqlfield.cpp2
-rw-r--r--tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp11
3 files changed, 39 insertions, 3 deletions
diff --git a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
index 3525c2577a..923ed0d09a 100644
--- a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
+++ b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
@@ -1475,12 +1475,39 @@ QSqlIndex QMYSQLDriver::primaryIndex(const QString &tablename) const
QSqlRecord QMYSQLDriver::record(const QString &tablename) const
{
+ Q_D(const QMYSQLDriver);
if (!isOpen())
return {};
QSqlQuery i(createResult());
QString stmt("SELECT * FROM %1 LIMIT 0"_L1);
i.exec(stmt.arg(escapeIdentifier(tablename, QSqlDriver::TableName)));
- return i.record();
+ auto r = i.record();
+ if (r.isEmpty())
+ return r;
+ // no binding of WHERE possible with MySQL
+ // escaping on WHERE clause does not work, so use mysql_real_escape_string()
+ stmt = "SELECT column_name, column_default FROM information_schema.columns WHERE table_name = '%1'"_L1;
+ const auto baTableName = tablename.toUtf8();
+ QVarLengthArray<char> tableNameQuoted(baTableName.size() * 2 + 1);
+#if defined(MARIADB_VERSION_ID)
+ const auto len = mysql_real_escape_string(d->mysql, tableNameQuoted.data(),
+ baTableName.data(), baTableName.size());
+#else
+ const auto len = mysql_real_escape_string_quote(d->mysql, tableNameQuoted.data(),
+ baTableName.data(), baTableName.size(), '\'');
+#endif
+ if (i.exec(stmt.arg(QString::fromUtf8(tableNameQuoted.data(), len)))) {
+ while (i.next()) {
+ const auto colName = i.value(0).toString();
+ const auto recordIdx = r.indexOf(colName);
+ if (recordIdx >= 0) {
+ auto field = r.field(recordIdx);
+ field.setDefaultValue(i.value(1));
+ r.replace(recordIdx, field);
+ }
+ }
+ }
+ return r;
}
QVariant QMYSQLDriver::handle() const
diff --git a/src/sql/kernel/qsqlfield.cpp b/src/sql/kernel/qsqlfield.cpp
index 5964b47414..2995d05779 100644
--- a/src/sql/kernel/qsqlfield.cpp
+++ b/src/sql/kernel/qsqlfield.cpp
@@ -208,6 +208,8 @@ void QSqlField::setPrecision(int precision)
\since 6.8
This property holds the default value for this field.
+ Only some database drivers supports this property. Currently
+ those are SQLite, PostgreSQL, Oracle and MySQL/MariaDB.
*/
/*!
diff --git a/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp b/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp
index 2947fb7040..fb8d804843 100644
--- a/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp
+++ b/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp
@@ -35,6 +35,7 @@ static bool driverSupportsDefaultValues(QSqlDriver::DbmsType dbType)
case QSqlDriver::SQLite:
case QSqlDriver::PostgreSQL:
case QSqlDriver::Oracle:
+ case QSqlDriver::MySqlServer:
return true;
default:
break;
@@ -132,8 +133,14 @@ void tst_QSqlDriver::record()
for (int i = 0; i < fields.size(); ++i)
QCOMPARE(rec.fieldName(i), fields[i]);
- if (driverSupportsDefaultValues(dbType))
- QCOMPARE(rec.field(QStringLiteral("name")).defaultValue().toString(), QStringLiteral("defaultVal"));
+ if (driverSupportsDefaultValues(dbType)) {
+ auto defVal = rec.field(QStringLiteral("name")).defaultValue().toString();
+ if (dbType == QSqlDriver::MySqlServer && defVal.startsWith('\'') && defVal.endsWith('\'')) {
+ qDebug() << "MariaDB 10.6 default string value is escaped:" << defVal;
+ defVal = defVal.mid(1, defVal.size() - 2);
+ }
+ QCOMPARE(defVal, QStringLiteral("defaultVal"));
+ }
if (dbType == QSqlDriver::Oracle || dbType == QSqlDriver::DB2)
tablename = tablename.toUpper();