Sql ODBC driver: add direct support for float and short datatype
This patch adds native support for SQL_REAL (float) and SQL_SMALLINT (short). Previously those datatypes were mapped to double and integer. [ChangeLog][QtSql] The ODBC driver now properly maps QMetaType::Float to real sql datatype and QMetaType::Short to smallint Fixes: QTBUG-8963 Fixes: QTBUG-57279 Change-Id: Ifec4c609734dbe6165c1ebdadb461c2aae47ba78 Reviewed-by: Andy Shaw <andy.shaw@qt.io>
This commit is contained in:
parent
161e8f4d5d
commit
b211148e4b
@ -347,12 +347,16 @@ static QMetaType qDecodeODBCType(SQLSMALLINT sqltype, bool isSigned = true)
|
||||
switch (sqltype) {
|
||||
case SQL_DECIMAL:
|
||||
case SQL_NUMERIC:
|
||||
case SQL_REAL:
|
||||
case SQL_FLOAT:
|
||||
case SQL_DOUBLE:
|
||||
case SQL_FLOAT: // 24 or 53 bits precision
|
||||
case SQL_DOUBLE:// 53 bits
|
||||
type = QMetaType::Double;
|
||||
break;
|
||||
case SQL_REAL: // 24 bits
|
||||
type = QMetaType::Float;
|
||||
break;
|
||||
case SQL_SMALLINT:
|
||||
type = isSigned ? QMetaType::Short : QMetaType::UShort;
|
||||
break;
|
||||
case SQL_INTEGER:
|
||||
case SQL_BIT:
|
||||
type = isSigned ? QMetaType::Int : QMetaType::UInt;
|
||||
@ -1220,9 +1224,11 @@ QVariant QODBCResult::data(int field)
|
||||
d->fieldCache[i] = qGetBigIntData(d->hStmt, i, false);
|
||||
break;
|
||||
case QMetaType::Int:
|
||||
case QMetaType::Short:
|
||||
d->fieldCache[i] = qGetIntData(d->hStmt, i);
|
||||
break;
|
||||
break;
|
||||
case QMetaType::UInt:
|
||||
case QMetaType::UShort:
|
||||
d->fieldCache[i] = qGetIntData(d->hStmt, i, false);
|
||||
break;
|
||||
case QMetaType::QDate:
|
||||
@ -1513,6 +1519,30 @@ bool QODBCResult::exec()
|
||||
0,
|
||||
*ind == SQL_NULL_DATA ? ind : NULL);
|
||||
break;
|
||||
case QMetaType::Short:
|
||||
r = SQLBindParameter(d->hStmt,
|
||||
i + 1,
|
||||
qParamType[bindValueType(i) & QSql::InOut],
|
||||
SQL_C_SSHORT,
|
||||
SQL_SMALLINT,
|
||||
0,
|
||||
0,
|
||||
const_cast<void *>(val.constData()),
|
||||
0,
|
||||
*ind == SQL_NULL_DATA ? ind : NULL);
|
||||
break;
|
||||
case QMetaType::UShort:
|
||||
r = SQLBindParameter(d->hStmt,
|
||||
i + 1,
|
||||
qParamType[bindValueType(i) & QSql::InOut],
|
||||
SQL_C_USHORT,
|
||||
SQL_NUMERIC,
|
||||
15,
|
||||
0,
|
||||
const_cast<void *>(val.constData()),
|
||||
0,
|
||||
*ind == SQL_NULL_DATA ? ind : NULL);
|
||||
break;
|
||||
case QMetaType::Double:
|
||||
r = SQLBindParameter(d->hStmt,
|
||||
i + 1,
|
||||
@ -1525,6 +1555,18 @@ bool QODBCResult::exec()
|
||||
0,
|
||||
*ind == SQL_NULL_DATA ? ind : NULL);
|
||||
break;
|
||||
case QMetaType::Float:
|
||||
r = SQLBindParameter(d->hStmt,
|
||||
i + 1,
|
||||
qParamType[bindValueType(i) & QSql::InOut],
|
||||
SQL_C_FLOAT,
|
||||
SQL_REAL,
|
||||
0,
|
||||
0,
|
||||
const_cast<void *>(val.constData()),
|
||||
0,
|
||||
*ind == SQL_NULL_DATA ? ind : NULL);
|
||||
break;
|
||||
case QMetaType::LongLong:
|
||||
r = SQLBindParameter(d->hStmt,
|
||||
i + 1,
|
||||
@ -1705,8 +1747,11 @@ bool QODBCResult::exec()
|
||||
QTime(dt.hour, dt.minute, dt.second, dt.fraction / 1000000)));
|
||||
break; }
|
||||
case QMetaType::Bool:
|
||||
case QMetaType::Short:
|
||||
case QMetaType::UShort:
|
||||
case QMetaType::Int:
|
||||
case QMetaType::UInt:
|
||||
case QMetaType::Float:
|
||||
case QMetaType::Double:
|
||||
case QMetaType::QByteArray:
|
||||
case QMetaType::LongLong:
|
||||
|
@ -99,6 +99,8 @@ private slots:
|
||||
void recordSQLServer();
|
||||
void recordIBase_data() {generic_data("QIBASE"); }
|
||||
void recordIBase();
|
||||
void recordODBC_data() { generic_data("QODBC"); }
|
||||
void recordODBC();
|
||||
|
||||
void eventNotificationIBase_data() { generic_data("QIBASE"); }
|
||||
void eventNotificationIBase();
|
||||
@ -1016,6 +1018,41 @@ void tst_QSqlDatabase::recordIBase()
|
||||
commonFieldTest(fieldDefs, db, fieldCount);
|
||||
}
|
||||
|
||||
void tst_QSqlDatabase::recordODBC()
|
||||
{
|
||||
QFETCH(QString, dbName);
|
||||
QSqlDatabase db = QSqlDatabase::database(dbName);
|
||||
CHECK_DATABASE(db);
|
||||
|
||||
static QDateTime dt(QDate::currentDate(), QTime(1, 2, 3, 0));
|
||||
static const FieldDef fieldDefs[] = {
|
||||
FieldDef("decimal(10, 9)", QMetaType::Double, 1.123456789),
|
||||
FieldDef("numeric(5, 2)", QMetaType::Double, 123.67),
|
||||
FieldDef("float", QMetaType::Double, 1.123456789),
|
||||
FieldDef("double precision", QMetaType::Double, 1.123456789),
|
||||
FieldDef("real", QMetaType::Float, 1.12345),
|
||||
|
||||
// FieldDef("tinyint", QMetaType::Char, 127), // not supported by psqlODBC
|
||||
FieldDef("smallint", QMetaType::Short, 32767),
|
||||
FieldDef("integer", QMetaType::Int, 2147483647),
|
||||
FieldDef("bigint", QMetaType::LongLong, Q_INT64_C(9223372036854775807)),
|
||||
|
||||
FieldDef("date", QMetaType::QDate, QDate::currentDate()),
|
||||
FieldDef("timestamp", QMetaType::QDateTime, dt, false),
|
||||
FieldDef("time", QMetaType::QTime, dt.time()),
|
||||
FieldDef("char(20)", QMetaType::QString, "Blah"),
|
||||
FieldDef("varchar(20)", QMetaType::QString, "BlahBlah"),
|
||||
FieldDef("text", QMetaType::QString, QString("blah6")),
|
||||
|
||||
FieldDef()
|
||||
};
|
||||
|
||||
const int fieldCount = createFieldTable(fieldDefs, db);
|
||||
QVERIFY(fieldCount > 0);
|
||||
|
||||
commonFieldTest(fieldDefs, db, fieldCount);
|
||||
}
|
||||
|
||||
void tst_QSqlDatabase::recordSQLite()
|
||||
{
|
||||
QFETCH(QString, dbName);
|
||||
|
Loading…
x
Reference in New Issue
Block a user