From ec23d96c86b43046cd2456829aca763ea6ba9935 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 4 Apr 2018 10:47:30 +0200 Subject: oci: Use OCIBindByPos2 to accommodate data longer than USHRT_MAX OCIBindByPos2 is only needed when using execBatch(), binding data that is longer than USHRT_MAX works for exec() so this is left unchanged. Change-Id: Ifdcf91939d184f225d24c13052ea0b81611ecf91 Reviewed-by: Edward Welbourne --- src/plugins/sqldrivers/oci/qsql_oci.cpp | 6 +++--- tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp | 24 +++++++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/plugins/sqldrivers/oci/qsql_oci.cpp b/src/plugins/sqldrivers/oci/qsql_oci.cpp index 272e1bc083..aee8e92b36 100644 --- a/src/plugins/sqldrivers/oci/qsql_oci.cpp +++ b/src/plugins/sqldrivers/oci/qsql_oci.cpp @@ -1318,7 +1318,7 @@ struct QOCIBatchColumn ub4 maxLen; ub4 recordCount; char* data; - ub2* lengths; + ub4* lengths; sb2* indicators; ub4 maxarr_len; ub4 curelep; @@ -1392,7 +1392,7 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector &boundValues, b QOCIBatchColumn &col = columns[i]; col.recordCount = boundValues.at(i).toList().count(); - col.lengths = new ub2[col.recordCount]; + col.lengths = new ub4[col.recordCount]; col.indicators = new sb2[col.recordCount]; col.maxarr_len = col.recordCount; col.curelep = col.recordCount; @@ -1556,7 +1556,7 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector &boundValues, b // binding the column - r = OCIBindByPos( + r = OCIBindByPos2( d->sql, &bindColumn.bindh, d->err, i + 1, bindColumn.data, bindColumn.maxLen, diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp index 9093485c40..23c8460133 100644 --- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp @@ -128,6 +128,8 @@ private slots: void mysql_outValues(); void oraClob_data() { generic_data("QOCI"); } void oraClob(); + void oraClobBatch_data() { generic_data("QOCI"); } + void oraClobBatch(); void oraLong_data() { generic_data("QOCI"); } void oraLong(); void oraOCINumber_data() { generic_data("QOCI"); } @@ -810,6 +812,28 @@ void tst_QSqlQuery::oraClob() QVERIFY( q.value( 1 ).toByteArray() == loong.toLatin1() ); } +void tst_QSqlQuery::oraClobBatch() +{ + QFETCH(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + const QString clobBatch(qTableName("clobBatch", __FILE__, db)); + tst_Databases::safeDropTables(db, { clobBatch }); + QSqlQuery q(db); + QVERIFY_SQL(q, exec("create table " + clobBatch + "(cl clob)")); + + const QString longString(USHRT_MAX + 1, QLatin1Char('A')); + QVERIFY_SQL(q, prepare("insert into " + clobBatch + " (cl) values(:cl)")); + const QVariantList vars = { longString }; + q.addBindValue(vars); + QVERIFY_SQL(q, execBatch()); + + QVERIFY_SQL(q, exec("select cl from " + clobBatch)); + QVERIFY(q.next()); + QCOMPARE(q.value(0).toString().count(), longString.size()); + QVERIFY(q.value(0).toString() == longString); +} + void tst_QSqlQuery::storedProceduresIBase() { QFETCH( QString, dbName ); -- cgit v1.2.3