summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorparihaaraka <parihaaraka@gmail.com>2013-06-14 22:38:43 +0400
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-04-29 14:42:26 +0200
commitf1eefd6cf99b2784b10390b7accf6bbe49245906 (patch)
tree1adf3ccb8dfed054682a288f3d5d7d22ab054e30
parenteb211d74cc3dbf991093ad2e799370f006de8198 (diff)
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>
-rw-r--r--src/sql/drivers/psql/qsql_psql.cpp31
-rw-r--r--tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp44
2 files changed, 70 insertions, 5 deletions
diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp
index c052e4c2e7..722595ad52 100644
--- a/src/sql/drivers/psql/qsql_psql.cpp
+++ b/src/sql/drivers/psql/qsql_psql.cpp
@@ -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;
diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
index 301c7bca51..824f042ffc 100644
--- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
+++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
@@ -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 );