SQL PostgreSQL/SQlite: Properly decode default varchar parameter

The default values for varchar columns were not decoded properly.

Task-number: QTBUG-46968
Change-Id: Ie13d48c316cd694240f7e287010b97afc8c6c341
Reviewed-by: Robert Szefner <robertsz27@interia.pl>
Reviewed-by: Andy Shaw <andy.shaw@qt.io>
This commit is contained in:
Christian Ehrlicher 2018-09-05 21:32:14 +02:00
parent 9d1c881f49
commit 0d1481b4d2
3 changed files with 31 additions and 5 deletions

View File

@ -1465,8 +1465,11 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const
precision = -1;
}
QString defVal = query.value(5).toString();
if (!defVal.isEmpty() && defVal.at(0) == QLatin1Char('\''))
defVal = defVal.mid(1, defVal.length() - 2);
if (!defVal.isEmpty() && defVal.at(0) == QLatin1Char('\'')) {
const int end = defVal.lastIndexOf(QLatin1Char('\''));
if (end > 0)
defVal = defVal.mid(1, end - 1);
}
QSqlField f(query.value(0).toString(), qDecodePSQLType(query.value(1).toInt()), tablename);
f.setRequired(query.value(2).toBool());
f.setLength(len);

View File

@ -917,13 +917,20 @@ static QSqlIndex qGetTableInfo(QSqlQuery &q, const QString &tableName, bool only
if (onlyPIndex && !isPk)
continue;
QString typeName = q.value(2).toString().toLower();
QString defVal = q.value(4).toString();
if (!defVal.isEmpty() && defVal.at(0) == QLatin1Char('\'')) {
const int end = defVal.lastIndexOf(QLatin1Char('\''));
if (end > 0)
defVal = defVal.mid(1, end - 1);
}
QSqlField fld(q.value(1).toString(), qGetColumnType(typeName), tableName);
if (isPk && (typeName == QLatin1String("integer")))
// INTEGER PRIMARY KEY fields are auto-generated in sqlite
// INT PRIMARY KEY is not the same as INTEGER PRIMARY KEY!
fld.setAutoValue(true);
fld.setRequired(q.value(3).toInt() != 0);
fld.setDefaultValue(q.value(4));
fld.setDefaultValue(defVal);
ind.append(fld);
}
return ind;

View File

@ -54,6 +54,18 @@ private slots:
void formatValue();
};
static bool driverSupportsDefaultValues(QSqlDriver::DbmsType dbType)
{
switch (dbType) {
case QSqlDriver::SQLite:
case QSqlDriver::PostgreSQL:
case QSqlDriver::Oracle:
return true;
default:
break;
}
return false;
}
void tst_QSqlDriver::initTestCase_data()
{
@ -81,8 +93,9 @@ void tst_QSqlDriver::recreateTestTables(QSqlDatabase db)
doubleField = "more_data double precision";
else
doubleField = "more_data double(8,7)";
const QString defValue(driverSupportsDefaultValues(dbType) ? QStringLiteral("DEFAULT 'defaultVal'") : QString());
QVERIFY_SQL( q, exec("create table " + relTEST1 +
" (id int not null primary key, name varchar(20), title_key int, another_title_key int, " + doubleField + QLatin1Char(')')));
" (id int not null primary key, name varchar(20) " + defValue + ", title_key int, another_title_key int, " + doubleField + QLatin1Char(')')));
QVERIFY_SQL( q, exec("insert into " + relTEST1 + " values(1, 'harry', 1, 2, 1.234567)"));
QVERIFY_SQL( q, exec("insert into " + relTEST1 + " values(2, 'trond', 2, 1, 8.901234)"));
QVERIFY_SQL( q, exec("insert into " + relTEST1 + " values(3, 'vohi', 1, 2, 5.678901)"));
@ -127,7 +140,7 @@ void tst_QSqlDriver::record()
//check we can get records using an unquoted mixed case table name
QSqlRecord rec = db.driver()->record(tablename);
QCOMPARE(rec.count(), 5);
QCOMPARE(rec.count(), fields.size());
QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
// QTBUG-1363: QSqlField::length() always return -1 when using QODBC3 driver and QSqlDatabase::record()
@ -141,6 +154,9 @@ void tst_QSqlDriver::record()
for (int i = 0; i < fields.count(); ++i)
QCOMPARE(rec.fieldName(i), fields[i]);
if (driverSupportsDefaultValues(dbType))
QCOMPARE(rec.field(QStringLiteral("name")).defaultValue().toString(), QStringLiteral("defaultVal"));
if (dbType == QSqlDriver::Interbase || dbType == QSqlDriver::Oracle || dbType == QSqlDriver::DB2)
tablename = tablename.toUpper();
else if (dbType == QSqlDriver::PostgreSQL)