Interbase: Add support for the boolean type

This is added to Interbase in v7 and Firebird in v3 which has been
available for sometime now. This means the minimum supported for
Interbase is now v7.

[ChangeLog][QtSQL][Interbase] The minimum required version for Interbase
is now v7.

Fixes: QTBUG-83401
Change-Id: I9927fd962f25c935be8ed5d2b7c76c00fb88cd8c
Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
This commit is contained in:
Andy Shaw 2020-08-02 14:54:28 +02:00
parent 37f4c6fbc2
commit 37e7c3c116
4 changed files with 32 additions and 6 deletions

View File

@ -64,6 +64,11 @@ QT_BEGIN_NAMESPACE
#define SQLDA_CURRENT_VERSION SQLDA_VERSION1
#endif
// Firebird uses blr_bool and not blr_boolean_dtype which is what Interbase uses
#ifndef blr_boolean_dtype
#define blr_boolean_dtype blr_bool
#endif
enum { QIBaseChunkSize = SHRT_MAX / 2 };
static bool getIBaseError(QString& msg, const ISC_STATUS* status, ISC_LONG &sqlcode)
@ -117,6 +122,7 @@ static void initDA(XSQLDA *sqlda)
case SQL_TYPE_DATE:
case SQL_TEXT:
case SQL_BLOB:
case SQL_BOOLEAN:
sqlda->sqlvar[i].sqldata = new char[sqlda->sqlvar[i].sqllen];
break;
case SQL_ARRAY:
@ -179,6 +185,8 @@ static QVariant::Type qIBaseTypeName(int iType, bool hasScale)
case blr_d_float:
case blr_double:
return QVariant::Double;
case blr_boolean_dtype:
return QVariant::Bool;
}
qWarning("qIBaseTypeName: unknown datatype: %d", iType);
return QVariant::Invalid;
@ -208,6 +216,8 @@ static QVariant::Type qIBaseTypeName2(int iType, bool hasScale)
return QVariant::List;
case SQL_BLOB:
return QVariant::ByteArray;
case SQL_BOOLEAN:
return QVariant::Bool;
default:
return QVariant::Invalid;
}
@ -378,7 +388,6 @@ public:
bool writeBlob(int i, const QByteArray &ba);
QVariant fetchArray(int pos, ISC_QUAD *arr);
bool writeArray(int i, const QList<QVariant> &list);
public:
ISC_STATUS status[20];
isc_tr_handle trans;
@ -549,6 +558,9 @@ static char* readArrayBuffer(QList<QVariant>& list, char *buffer, short curDim,
buffer += sizeof(ISC_DATE);
}
break;
case blr_boolean_dtype:
valList = toList<bool>(&buffer, numElements[dim]);
break;
}
}
if (dim > 0)
@ -739,6 +751,9 @@ static char* createArrayBuffer(char *buffer, const QList<QVariant> &list,
buffer += sizeof(ISC_TIMESTAMP);
}
break;
case QVariant::Bool:
buffer = fillList<bool>(buffer, list);
break;
default:
break;
}
@ -1032,6 +1047,9 @@ bool QIBaseResult::exec()
case SQL_ARRAY:
ok &= d->writeArray(para, val.toList());
break;
case SQL_BOOLEAN:
*((bool*)d->inda->sqlvar[para].sqldata) = val.toBool();
break;
default:
qWarning("QIBaseResult::exec: Unknown datatype %d",
d->inda->sqlvar[para].sqltype & ~1);
@ -1184,6 +1202,9 @@ bool QIBaseResult::gotoNext(QSqlCachedResult::ValueCache& row, int rowIdx)
case SQL_ARRAY:
row[idx] = d->fetchArray(i, (ISC_QUAD*)buf);
break;
case SQL_BOOLEAN:
row[idx] = QVariant(bool((*(bool*)buf)));
break;
default:
// unknown type - don't even try to fetch
row[idx] = QVariant();

View File

@ -47,7 +47,7 @@
\table
\header \li Driver name \li DBMS
\row \li \l{#QDB2}{QDB2} \li IBM DB2 (version 7.1 and above)
\row \li \l{#QIBASE}{QIBASE} \li Borland InterBase
\row \li \l{#QIBASE}{QIBASE} \li Borland InterBase (version 7.0 and above) or Firebird (version 3.0 and above)
\row \li \l{#QMYSQL}{QMYSQL / MARIADB} \li MySQL or MariaDB (version 5.6 and above)
\row \li \l{#QOCI}{QOCI} \li Oracle Call Interface Driver (version 12.1 and above)
\row \li \l{#QODBC}{QODBC}

View File

@ -1000,6 +1000,7 @@ void tst_QSqlDatabase::recordIBase()
FieldDef("time", QVariant::Time, QTime::currentTime()),
FieldDef("decimal(18)", QVariant::LongLong, Q_INT64_C(9223372036854775807)),
FieldDef("numeric(5,2)", QVariant::Double, 123.45),
FieldDef("boolean", QVariant::Bool, true),
FieldDef()
};

View File

@ -620,7 +620,8 @@ void tst_QSqlQuery::bindBool()
const QString tableName(qTableName("bindBool", __FILE__, db));
q.exec("DROP TABLE " + tableName);
QString colType = dbType == QSqlDriver::PostgreSQL ? QLatin1String("BOOLEAN") : QLatin1String("INT");
const bool useBooleanType = (dbType == QSqlDriver::PostgreSQL || dbType == QSqlDriver::Interbase);
const QString colType = useBooleanType ? QLatin1String("BOOLEAN") : QLatin1String("INT");
QVERIFY_SQL(q, exec("CREATE TABLE " + tableName + " (id INT, flag " + colType + " NOT NULL, PRIMARY KEY(id))"));
for (int i = 0; i < 2; ++i) {
@ -4777,20 +4778,23 @@ void tst_QSqlQuery::ibaseArray()
tst_Databases::safeDropTable(db, arrayTable);
QSqlQuery qry(db);
QVERIFY_SQL(qry, exec("create table " + arrayTable + " (intData int[0:4], longData bigint[5], "
"charData varchar(255)[5])"));
QVERIFY_SQL(qry, prepare("insert into " + arrayTable + " (intData, longData, charData) "
"values(?, ?, ?)"));
"charData varchar(255)[5], boolData boolean[2])"));
QVERIFY_SQL(qry, prepare("insert into " + arrayTable + " (intData, longData, charData, boolData) "
"values(?, ?, ?, ?)"));
const auto intArray = QVariant{QVariantList{1, 2, 3, 4711, 815}};
const auto charArray = QVariant{QVariantList{"AAA", "BBB", "CCC", "DDD", "EEE"}};
const auto boolArray = QVariant{QVariantList{true, false}};
qry.bindValue(0, intArray);
qry.bindValue(1, intArray);
qry.bindValue(2, charArray);
qry.bindValue(3, boolArray);
QVERIFY_SQL(qry, exec());
QVERIFY_SQL(qry, exec("select * from " + arrayTable));
QVERIFY(qry.next());
QCOMPARE(qry.value(0).toList(), intArray.toList());
QCOMPARE(qry.value(1).toList(), intArray.toList());
QCOMPARE(qry.value(2).toList(), charArray.toList());
QCOMPARE(qry.value(3).toList(), boolArray.toList());
}
QTEST_MAIN( tst_QSqlQuery )