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) {
|
switch (sqltype) {
|
||||||
case SQL_DECIMAL:
|
case SQL_DECIMAL:
|
||||||
case SQL_NUMERIC:
|
case SQL_NUMERIC:
|
||||||
case SQL_REAL:
|
case SQL_FLOAT: // 24 or 53 bits precision
|
||||||
case SQL_FLOAT:
|
case SQL_DOUBLE:// 53 bits
|
||||||
case SQL_DOUBLE:
|
|
||||||
type = QMetaType::Double;
|
type = QMetaType::Double;
|
||||||
break;
|
break;
|
||||||
|
case SQL_REAL: // 24 bits
|
||||||
|
type = QMetaType::Float;
|
||||||
|
break;
|
||||||
case SQL_SMALLINT:
|
case SQL_SMALLINT:
|
||||||
|
type = isSigned ? QMetaType::Short : QMetaType::UShort;
|
||||||
|
break;
|
||||||
case SQL_INTEGER:
|
case SQL_INTEGER:
|
||||||
case SQL_BIT:
|
case SQL_BIT:
|
||||||
type = isSigned ? QMetaType::Int : QMetaType::UInt;
|
type = isSigned ? QMetaType::Int : QMetaType::UInt;
|
||||||
@ -1220,9 +1224,11 @@ QVariant QODBCResult::data(int field)
|
|||||||
d->fieldCache[i] = qGetBigIntData(d->hStmt, i, false);
|
d->fieldCache[i] = qGetBigIntData(d->hStmt, i, false);
|
||||||
break;
|
break;
|
||||||
case QMetaType::Int:
|
case QMetaType::Int:
|
||||||
|
case QMetaType::Short:
|
||||||
d->fieldCache[i] = qGetIntData(d->hStmt, i);
|
d->fieldCache[i] = qGetIntData(d->hStmt, i);
|
||||||
break;
|
break;
|
||||||
case QMetaType::UInt:
|
case QMetaType::UInt:
|
||||||
|
case QMetaType::UShort:
|
||||||
d->fieldCache[i] = qGetIntData(d->hStmt, i, false);
|
d->fieldCache[i] = qGetIntData(d->hStmt, i, false);
|
||||||
break;
|
break;
|
||||||
case QMetaType::QDate:
|
case QMetaType::QDate:
|
||||||
@ -1513,6 +1519,30 @@ bool QODBCResult::exec()
|
|||||||
0,
|
0,
|
||||||
*ind == SQL_NULL_DATA ? ind : NULL);
|
*ind == SQL_NULL_DATA ? ind : NULL);
|
||||||
break;
|
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:
|
case QMetaType::Double:
|
||||||
r = SQLBindParameter(d->hStmt,
|
r = SQLBindParameter(d->hStmt,
|
||||||
i + 1,
|
i + 1,
|
||||||
@ -1525,6 +1555,18 @@ bool QODBCResult::exec()
|
|||||||
0,
|
0,
|
||||||
*ind == SQL_NULL_DATA ? ind : NULL);
|
*ind == SQL_NULL_DATA ? ind : NULL);
|
||||||
break;
|
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:
|
case QMetaType::LongLong:
|
||||||
r = SQLBindParameter(d->hStmt,
|
r = SQLBindParameter(d->hStmt,
|
||||||
i + 1,
|
i + 1,
|
||||||
@ -1705,8 +1747,11 @@ bool QODBCResult::exec()
|
|||||||
QTime(dt.hour, dt.minute, dt.second, dt.fraction / 1000000)));
|
QTime(dt.hour, dt.minute, dt.second, dt.fraction / 1000000)));
|
||||||
break; }
|
break; }
|
||||||
case QMetaType::Bool:
|
case QMetaType::Bool:
|
||||||
|
case QMetaType::Short:
|
||||||
|
case QMetaType::UShort:
|
||||||
case QMetaType::Int:
|
case QMetaType::Int:
|
||||||
case QMetaType::UInt:
|
case QMetaType::UInt:
|
||||||
|
case QMetaType::Float:
|
||||||
case QMetaType::Double:
|
case QMetaType::Double:
|
||||||
case QMetaType::QByteArray:
|
case QMetaType::QByteArray:
|
||||||
case QMetaType::LongLong:
|
case QMetaType::LongLong:
|
||||||
|
@ -99,6 +99,8 @@ private slots:
|
|||||||
void recordSQLServer();
|
void recordSQLServer();
|
||||||
void recordIBase_data() {generic_data("QIBASE"); }
|
void recordIBase_data() {generic_data("QIBASE"); }
|
||||||
void recordIBase();
|
void recordIBase();
|
||||||
|
void recordODBC_data() { generic_data("QODBC"); }
|
||||||
|
void recordODBC();
|
||||||
|
|
||||||
void eventNotificationIBase_data() { generic_data("QIBASE"); }
|
void eventNotificationIBase_data() { generic_data("QIBASE"); }
|
||||||
void eventNotificationIBase();
|
void eventNotificationIBase();
|
||||||
@ -1016,6 +1018,41 @@ void tst_QSqlDatabase::recordIBase()
|
|||||||
commonFieldTest(fieldDefs, db, fieldCount);
|
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()
|
void tst_QSqlDatabase::recordSQLite()
|
||||||
{
|
{
|
||||||
QFETCH(QString, dbName);
|
QFETCH(QString, dbName);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user