Fix PSQL column's metadata

Fixed libpq's PQfmod() interpretation inside QPSQLResult::record()

Task-number: QTBUG-12477
Change-Id: I0e4c94ca1b06fd6a8e5b5702235cdd6d9736f8bf
Reviewed-by: Andy Shaw <andy.shaw@digia.com>
Reviewed-by: Mark Brand <mabrand@mabrand.nl>
This commit is contained in:
parihaaraka 2013-06-14 22:38:43 +04:00 committed by The Qt Project
parent eb211d74cc
commit f1eefd6cf9
2 changed files with 70 additions and 5 deletions

View File

@ -104,6 +104,11 @@
#define QXIDOID 28
#define QCIDOID 29
#define QBITOID 1560
#define QVARBITOID 1562
#define VARHDRSZ 4
/* This is a compile time switch - if PQfreemem is declared, the compiler will use that one,
otherwise it'll run in this template */
template <typename T>
@ -533,17 +538,33 @@ QSqlRecord QPSQLResult::record() const
f.setName(QString::fromUtf8(PQfname(d->result, i)));
else
f.setName(QString::fromLocal8Bit(PQfname(d->result, i)));
f.setType(qDecodePSQLType(PQftype(d->result, i)));
int ptype = PQftype(d->result, i);
f.setType(qDecodePSQLType(ptype));
int len = PQfsize(d->result, i);
int precision = PQfmod(d->result, i);
// swap length and precision if length == -1
if (len == -1 && precision > -1) {
len = precision - 4;
switch (ptype) {
case QNUMERICOID:
if (precision != -1) {
len = (precision >> 16);
precision = ((precision - VARHDRSZ) & 0xffff);
}
break;
case QBITOID:
case QVARBITOID:
len = precision;
precision = -1;
break;
default:
if (len == -1 && precision >= VARHDRSZ) {
len = precision - VARHDRSZ;
precision = -1;
}
}
f.setLength(len);
f.setPrecision(precision);
f.setSqlType(PQftype(d->result, i));
f.setSqlType(ptype);
info.append(f);
}
return info;

View File

@ -195,6 +195,9 @@ private slots:
void task_233829_data() { generic_data("QPSQL"); }
void task_233829();
void QTBUG_12477_data() { generic_data("QPSQL"); }
void QTBUG_12477();
void sqlServerReturn0_data() { generic_data(); }
void sqlServerReturn0();
@ -3012,6 +3015,47 @@ void tst_QSqlQuery::task_233829()
QVERIFY_SQL(q,exec());
}
void tst_QSqlQuery::QTBUG_12477()
{
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
if (!db.driverName().startsWith("QPSQL"))
QSKIP("PostgreSQL specific test");
QSqlQuery q(db);
QVERIFY_SQL(q, exec("SELECT 1::bit, '10101010000111101101'::varbit, "
"'10101111011'::varbit(15), '22222.20'::numeric(16,2), "
"'333333'::numeric(18), '444444'::numeric"));
QVERIFY_SQL(q, next());
QSqlRecord r = q.record();
QSqlField f;
f = r.field(0);
QCOMPARE(f.length(), 1);
QCOMPARE(f.precision(), -1);
f = r.field(1);
QCOMPARE(f.length(), -1);
QCOMPARE(f.precision(), -1);
f = r.field(2);
QCOMPARE(f.length(), 15);
QCOMPARE(f.precision(), -1);
f = r.field(3);
QCOMPARE(f.length(), 16);
QCOMPARE(f.precision(), 2);
f = r.field(4);
QCOMPARE(f.length(), 18);
QCOMPARE(f.precision(), 0);
f = r.field(5);
QCOMPARE(f.length(), -1);
QCOMPARE(f.precision(), -1);
}
void tst_QSqlQuery::sqlServerReturn0()
{
QFETCH( QString, dbName );