summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2010-10-29 11:32:03 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2010-10-29 11:32:03 (GMT)
commitbdc13bcc7b4d195d741142acce9b4e9b68c4d5e0 (patch)
treec5e74afb3f75790b2b64dc7964d54d4737851e9a
parentc02ef9eb331f03dbd59d2fd938c53b54f5c65cea (diff)
parentc76f9f15d1c604cdf3d68d2147a4a06d227871fa (diff)
downloadQt-bdc13bcc7b4d195d741142acce9b4e9b68c4d5e0.zip
Qt-bdc13bcc7b4d195d741142acce9b4e9b68c4d5e0.tar.gz
Qt-bdc13bcc7b4d195d741142acce9b4e9b68c4d5e0.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2: Fix possible crash in QStaticText and QDeclarativeTextLayout Fix QTBUG-14132 oracle (xe) stored procedures with bind variables get errors
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextlayout.cpp4
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp2
-rw-r--r--src/gui/painting/qpainter.cpp4
-rw-r--r--src/gui/text/qstatictext.cpp22
-rw-r--r--src/gui/text/qstatictext_p.h54
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp24
-rw-r--r--src/opengl/qpaintengine_opengl.cpp8
-rw-r--r--src/openvg/qpaintengine_vg.cpp2
-rw-r--r--src/sql/drivers/oci/qsql_oci.cpp106
-rw-r--r--tests/auto/qsqlquery/tst_qsqlquery.cpp21
10 files changed, 151 insertions, 96 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativetextlayout.cpp b/src/declarative/graphicsitems/qdeclarativetextlayout.cpp
index 89a2158..635ceab 100644
--- a/src/declarative/graphicsitems/qdeclarativetextlayout.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextlayout.cpp
@@ -94,7 +94,7 @@ class DrawTextItemRecorder: public QPaintEngine
if (!m_inertText->items.isEmpty()) {
QStaticTextItem &last = m_inertText->items[m_inertText->items.count() - 1];
- if (last.fontEngine == ti.fontEngine && last.font == ti.font() &&
+ if (last.fontEngine() == ti.fontEngine && last.font == ti.font() &&
(!m_dirtyPen || last.color == state->pen().color())) {
needFreshCurrentItem = false;
@@ -107,7 +107,7 @@ class DrawTextItemRecorder: public QPaintEngine
if (needFreshCurrentItem) {
QStaticTextItem currentItem;
- currentItem.fontEngine = ti.fontEngine;
+ currentItem.setFontEngine(ti.fontEngine);
currentItem.font = ti.font();
currentItem.charOffset = charOffset;
currentItem.numChars = ti.num_chars;
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 8f9d8ba..d4b044b 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -3300,7 +3300,7 @@ void QRasterPaintEngine::drawStaticTextItem(QStaticTextItem *textItem)
ensureState();
drawCachedGlyphs(textItem->numGlyphs, textItem->glyphs, textItem->glyphPositions,
- textItem->fontEngine);
+ textItem->fontEngine());
}
/*!
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 7fed7e4..ab9707d 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -5746,7 +5746,7 @@ void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, const QPointF *posit
QStaticTextItem staticTextItem;
staticTextItem.color = state->pen.color();
staticTextItem.font = state->font;
- staticTextItem.fontEngine = fontEngine;
+ staticTextItem.setFontEngine(fontEngine);
staticTextItem.numGlyphs = glyphCount;
staticTextItem.glyphs = reinterpret_cast<glyph_t *>(const_cast<glyph_t *>(glyphArray));
staticTextItem.glyphPositions = positions.data();
@@ -5938,7 +5938,7 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText
d->extended->drawStaticTextItem(item);
drawDecorationForGlyphs(this, item->glyphs, item->glyphPositions,
- item->numGlyphs, item->fontEngine, staticText_d->font,
+ item->numGlyphs, item->fontEngine(), staticText_d->font,
QTextCharFormat());
}
if (currentColor != oldPen.color())
diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp
index 9506006..edf248a 100644
--- a/src/gui/text/qstatictext.cpp
+++ b/src/gui/text/qstatictext.cpp
@@ -445,7 +445,7 @@ namespace {
const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
QStaticTextItem currentItem;
- currentItem.fontEngine = ti.fontEngine;
+ currentItem.setFontEngine(ti.fontEngine);
currentItem.font = ti.font();
currentItem.charOffset = m_chars.size();
currentItem.numChars = ti.num_chars;
@@ -713,4 +713,24 @@ void QStaticTextPrivate::init()
needsRelayout = false;
}
+QStaticTextItem::~QStaticTextItem()
+{
+ if (m_userData != 0 && !m_userData->ref.deref())
+ delete m_userData;
+ if (!m_fontEngine->ref.deref())
+ delete m_fontEngine;
+}
+
+void QStaticTextItem::setFontEngine(QFontEngine *fe)
+{
+ if (m_fontEngine != 0) {
+ if (!m_fontEngine->ref.deref())
+ delete m_fontEngine;
+ }
+
+ m_fontEngine = fe;
+ if (m_fontEngine != 0)
+ m_fontEngine->ref.ref();
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/text/qstatictext_p.h b/src/gui/text/qstatictext_p.h
index cb60626..87ef0d5 100644
--- a/src/gui/text/qstatictext_p.h
+++ b/src/gui/text/qstatictext_p.h
@@ -68,27 +68,60 @@ public:
OpenGLUserData
};
- QStaticTextUserData(Type t) : type(t) {}
+ QStaticTextUserData(Type t) : type(t) { ref = 0; }
virtual ~QStaticTextUserData() {}
+ QAtomicInt ref;
Type type;
};
class Q_GUI_EXPORT QStaticTextItem
{
public:
- QStaticTextItem() : chars(0), numChars(0), fontEngine(0), userData(0),
- useBackendOptimizations(false), userDataNeedsUpdate(0) {}
- ~QStaticTextItem() { delete userData; }
+ QStaticTextItem() : chars(0), numChars(0), useBackendOptimizations(false),
+ userDataNeedsUpdate(0), m_fontEngine(0), m_userData(0) {}
+
+ QStaticTextItem(const QStaticTextItem &other)
+ {
+ operator=(other);
+ }
+
+ void operator=(const QStaticTextItem &other)
+ {
+ glyphPositions = other.glyphPositions;
+ glyphs = other.glyphs;
+ chars = other.chars;
+ numGlyphs = other.numGlyphs;
+ numChars = other.numChars;
+ font = other.font;
+ color = other.color;
+ useBackendOptimizations = other.useBackendOptimizations;
+ userDataNeedsUpdate = other.userDataNeedsUpdate;
+
+ m_fontEngine = 0;
+ m_userData = 0;
+ setUserData(other.userData());
+ setFontEngine(other.fontEngine());
+ }
+
+ ~QStaticTextItem();
void setUserData(QStaticTextUserData *newUserData)
{
- if (userData == newUserData)
+ if (m_userData == newUserData)
return;
- delete userData;
- userData = newUserData;
+ if (m_userData != 0 && !m_userData->ref.deref())
+ delete m_userData;
+
+ m_userData = newUserData;
+ if (m_userData != 0)
+ m_userData->ref.ref();
}
+ QStaticTextUserData *userData() const { return m_userData; }
+
+ void setFontEngine(QFontEngine *fe);
+ QFontEngine *fontEngine() const { return m_fontEngine; }
union {
QFixedPoint *glyphPositions; // 8 bytes per glyph
@@ -108,14 +141,17 @@ public:
// 12 bytes for pointers
int numGlyphs; // 4 bytes per item
int numChars; // 4 bytes per item
- QFontEngine *fontEngine; // 4 bytes per item
QFont font; // 8 bytes per item
QColor color; // 10 bytes per item
- QStaticTextUserData *userData; // 8 bytes per item
char useBackendOptimizations : 1; // 1 byte per item
char userDataNeedsUpdate : 1; //
// ================
// 51 bytes per item
+
+private: // Needs special handling in setters, so private to avoid abuse
+ QFontEngine *m_fontEngine; // 4 bytes per item
+ QStaticTextUserData *m_userData; // 8 bytes per item
+
};
class QStaticText;
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 84c7fed..1dcb773 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -1350,8 +1350,8 @@ void QGL2PaintEngineEx::drawStaticTextItem(QStaticTextItem *textItem)
ensureActive();
- QFontEngineGlyphCache::Type glyphType = textItem->fontEngine->glyphFormat >= 0
- ? QFontEngineGlyphCache::Type(textItem->fontEngine->glyphFormat)
+ QFontEngineGlyphCache::Type glyphType = textItem->fontEngine()->glyphFormat >= 0
+ ? QFontEngineGlyphCache::Type(textItem->fontEngine()->glyphFormat)
: d->glyphCacheType;
if (glyphType == QFontEngineGlyphCache::Raster_RGBMask) {
if (d->device->alphaRequested() || state()->matrix.type() > QTransform::TxTranslate
@@ -1430,7 +1430,7 @@ void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem
{
QStaticTextItem staticTextItem;
staticTextItem.chars = const_cast<QChar *>(ti.chars);
- staticTextItem.fontEngine = ti.fontEngine;
+ staticTextItem.setFontEngine(ti.fontEngine);
staticTextItem.glyphs = glyphs.data();
staticTextItem.numChars = ti.num_chars;
staticTextItem.numGlyphs = glyphs.size();
@@ -1475,18 +1475,18 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp
QOpenGL2PaintEngineState *s = q->state();
QGLTextureGlyphCache *cache =
- (QGLTextureGlyphCache *) staticTextItem->fontEngine->glyphCache(ctx, glyphType, QTransform());
+ (QGLTextureGlyphCache *) staticTextItem->fontEngine()->glyphCache(ctx, glyphType, QTransform());
if (!cache || cache->cacheType() != glyphType) {
cache = new QGLTextureGlyphCache(ctx, glyphType, QTransform());
- staticTextItem->fontEngine->setGlyphCache(ctx, cache);
+ staticTextItem->fontEngine()->setGlyphCache(ctx, cache);
}
bool recreateVertexArrays = false;
if (staticTextItem->userDataNeedsUpdate)
recreateVertexArrays = true;
- else if (staticTextItem->userData == 0)
+ else if (staticTextItem->userData() == 0)
recreateVertexArrays = true;
- else if (staticTextItem->userData->type != QStaticTextUserData::OpenGLUserData)
+ else if (staticTextItem->userData()->type != QStaticTextUserData::OpenGLUserData)
recreateVertexArrays = true;
// We only need to update the cache with new glyphs if we are actually going to recreate the vertex arrays.
@@ -1494,8 +1494,8 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp
// cache so this text is performed before we test if the cache size has changed.
if (recreateVertexArrays) {
cache->setPaintEnginePrivate(this);
- cache->populate(staticTextItem->fontEngine, staticTextItem->numGlyphs, staticTextItem->glyphs,
- staticTextItem->glyphPositions);
+ cache->populate(staticTextItem->fontEngine(), staticTextItem->numGlyphs,
+ staticTextItem->glyphs, staticTextItem->glyphPositions);
}
if (cache->width() == 0 || cache->height() == 0)
@@ -1515,14 +1515,14 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp
if (staticTextItem->useBackendOptimizations) {
QOpenGLStaticTextUserData *userData = 0;
- if (staticTextItem->userData == 0
- || staticTextItem->userData->type != QStaticTextUserData::OpenGLUserData) {
+ if (staticTextItem->userData() == 0
+ || staticTextItem->userData()->type != QStaticTextUserData::OpenGLUserData) {
userData = new QOpenGLStaticTextUserData();
staticTextItem->setUserData(userData);
} else {
- userData = static_cast<QOpenGLStaticTextUserData*>(staticTextItem->userData);
+ userData = static_cast<QOpenGLStaticTextUserData*>(staticTextItem->userData());
}
// Use cache if backend optimizations is turned on
diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp
index 74b6b9a..a04d930 100644
--- a/src/opengl/qpaintengine_opengl.cpp
+++ b/src/opengl/qpaintengine_opengl.cpp
@@ -4918,7 +4918,7 @@ void QOpenGLPaintEngine::drawStaticTextItem(QStaticTextItem *textItem)
d->flushDrawQueue();
// make sure the glyphs we want to draw are in the cache
- qt_glyph_cache()->cacheGlyphs(d->device->context(), textItem->fontEngine, textItem->glyphs,
+ qt_glyph_cache()->cacheGlyphs(d->device->context(), textItem->fontEngine(), textItem->glyphs,
textItem->numGlyphs);
d->setGradientOps(Qt::SolidPattern, QRectF()); // turns off gradient ops
@@ -4941,13 +4941,13 @@ void QOpenGLPaintEngine::drawStaticTextItem(QStaticTextItem *textItem)
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- bool antialias = !(textItem->fontEngine->fontDef.styleStrategy & QFont::NoAntialias)
+ bool antialias = !(textItem->fontEngine()->fontDef.styleStrategy & QFont::NoAntialias)
&& (d->matrix.type() > QTransform::TxTranslate);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, antialias ? GL_LINEAR : GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, antialias ? GL_LINEAR : GL_NEAREST);
for (int i=0; i< textItem->numGlyphs; ++i) {
- QGLGlyphCoord *g = qt_glyph_cache()->lookup(textItem->fontEngine, textItem->glyphs[i]);
+ QGLGlyphCoord *g = qt_glyph_cache()->lookup(textItem->fontEngine(), textItem->glyphs[i]);
// we don't cache glyphs with no width/height
if (!g)
@@ -5003,7 +5003,7 @@ void QOpenGLPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte
{
QStaticTextItem staticTextItem;
staticTextItem.chars = const_cast<QChar *>(ti.chars);
- staticTextItem.fontEngine = ti.fontEngine;
+ staticTextItem.setFontEngine(ti.fontEngine);
staticTextItem.glyphs = glyphs.data();
staticTextItem.numChars = ti.num_chars;
staticTextItem.numGlyphs = glyphs.size();
diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp
index ce9d11a..f8788b0 100644
--- a/src/openvg/qpaintengine_vg.cpp
+++ b/src/openvg/qpaintengine_vg.cpp
@@ -3407,7 +3407,7 @@ void QVGPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
void QVGPaintEngine::drawStaticTextItem(QStaticTextItem *textItem)
{
- drawCachedGlyphs(textItem->numGlyphs, textItem->glyphs, textItem->font, textItem->fontEngine,
+ drawCachedGlyphs(textItem->numGlyphs, textItem->glyphs, textItem->font, textItem->fontEngine(),
QPointF(0, 0), textItem->glyphPositions);
}
diff --git a/src/sql/drivers/oci/qsql_oci.cpp b/src/sql/drivers/oci/qsql_oci.cpp
index e11cf75..3f30ea5 100644
--- a/src/sql/drivers/oci/qsql_oci.cpp
+++ b/src/sql/drivers/oci/qsql_oci.cpp
@@ -93,11 +93,13 @@ enum { QOCIEncoding = 2002 }; // AL16UTF16LE
enum { QOCIEncoding = 2000 }; // AL16UTF16
#endif
+#ifdef OCI_ATTR_CHARSET_FORM
// Always set the OCI_ATTR_CHARSET_FORM to SQLCS_NCHAR is safe
// because Oracle server will deal with the implicit Conversion
// Between CHAR and NCHAR.
// see: http://download.oracle.com/docs/cd/A91202_01/901_doc/appdev.901/a89857/oci05bnd.htm#422705
static const ub1 qOraCharsetForm = SQLCS_NCHAR;
+#endif
#if defined (OCI_UTF16ID)
static const ub2 qOraCharset = OCI_UTF16ID;
@@ -117,6 +119,8 @@ static // for some reason, Sun CC can't use qOraWarning when it's declared stati
void qOraWarning(const char* msg, OCIError *err);
static QSqlError qMakeError(const QString& errString, QSqlError::ErrorType type, OCIError *err);
+
+
class QOCIRowId: public QSharedData
{
public:
@@ -164,7 +168,6 @@ struct QOCIResultPrivate
int serverVersion;
int prefetchRows, prefetchMem;
- void setCharset(OCIBind* hbnd);
void setStatementAttributes();
int bindValue(OCIStmt *sql, OCIBind **hbnd, OCIError *err, int pos,
const QVariant &val, dvoid *indPtr, ub2 *tmpSize, QList<QByteArray> &tmpStorage);
@@ -176,6 +179,41 @@ struct QOCIResultPrivate
{ return q->bindValueType(i) & QSql::Out; }
inline bool isBinaryValue(int i) const
{ return q->bindValueType(i) & QSql::Binary; }
+
+ void setCharset(dvoid* handle, ub4 type) const
+ {
+ int r = 0;
+ Q_ASSERT(handle);
+
+#ifdef OCI_ATTR_CHARSET_FORM
+ r = OCIAttrSet(handle,
+ type,
+ // this const cast is safe since OCI doesn't touch
+ // the charset.
+ const_cast<void *>(static_cast<const void *>(&qOraCharsetForm)),
+ 0,
+ OCI_ATTR_CHARSET_FORM,
+ //Strange Oracle bug: some Oracle servers crash the server process with non-zero error handle (mostly for 10g).
+ //So ignore the error message here.
+ 0);
+ #ifdef QOCI_DEBUG
+ if (r != 0)
+ qWarning("QOCIResultPrivate::setCharset: Couldn't set OCI_ATTR_CHARSET_FORM.");
+ #endif
+#endif
+
+ r = OCIAttrSet(handle,
+ type,
+ // this const cast is safe since OCI doesn't touch
+ // the charset.
+ const_cast<void *>(static_cast<const void *>(&qOraCharset)),
+ 0,
+ OCI_ATTR_CHARSET_ID,
+ err);
+ if (r != 0)
+ qOraWarning("QOCIResultPrivate::setCharsetI Couldn't set OCI_ATTR_CHARSET_ID: ", err);
+
+ }
};
void QOCIResultPrivate::setStatementAttributes()
@@ -208,36 +246,6 @@ void QOCIResultPrivate::setStatementAttributes()
}
}
-void QOCIResultPrivate::setCharset(OCIBind* hbnd)
-{
- int r = 0;
-
- Q_ASSERT(hbnd);
-
- r = OCIAttrSet(hbnd,
- OCI_HTYPE_BIND,
- // this const cast is safe since OCI doesn't touch
- // the charset.
- const_cast<void *>(static_cast<const void *>(&qOraCharsetForm)),
- 0,
- OCI_ATTR_CHARSET_FORM,
- err);
- if (r != 0)
- qOraWarning("QOCIResultPrivate::setCharset: Couldn't set OCI_ATTR_CHARSET_FORM: ", err);
-
- r = OCIAttrSet(hbnd,
- OCI_HTYPE_BIND,
- // this const cast is safe since OCI doesn't touch
- // the charset.
- const_cast<void *>(static_cast<const void *>(&qOraCharset)),
- 0,
- OCI_ATTR_CHARSET_ID,
- err);
- if (r != 0)
- qOraWarning("QOCIResultPrivate::setCharset: Couldn't set OCI_ATTR_CHARSET_ID: ", err);
-
-}
-
int QOCIResultPrivate::bindValue(OCIStmt *sql, OCIBind **hbnd, OCIError *err, int pos,
const QVariant &val, dvoid *indPtr, ub2 *tmpSize, QList<QByteArray> &tmpStorage)
{
@@ -325,7 +333,7 @@ int QOCIResultPrivate::bindValue(OCIStmt *sql, OCIBind **hbnd, OCIError *err, in
(s.length() + 1) * sizeof(QChar),
SQLT_STR, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
if (r == OCI_SUCCESS)
- setCharset(*hbnd);
+ setCharset(*hbnd, OCI_HTYPE_BIND);
break;
}
} // fall through for OUT values
@@ -349,7 +357,7 @@ int QOCIResultPrivate::bindValue(OCIStmt *sql, OCIBind **hbnd, OCIError *err, in
SQLT_STR, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
}
if (r == OCI_SUCCESS)
- setCharset(*hbnd);
+ setCharset(*hbnd, OCI_HTYPE_BIND);
tmpStorage.append(ba);
break;
} // default case
@@ -688,7 +696,6 @@ class QOCICols
public:
QOCICols(int size, QOCIResultPrivate* dp);
~QOCICols();
- void setCharset(OCIDefine* dfn);
int readPiecewise(QVector<QVariant> &values, int index = 0);
int readLOBs(QVector<QVariant> &values, int index = 0);
int fieldFromDefine(OCIDefine* d);
@@ -890,7 +897,7 @@ QOCICols::QOCICols(int size, QOCIResultPrivate* dp)
&(fieldInf[idx].ind),
0, 0, OCI_DEFAULT);
if (r == 0)
- setCharset(dfn);
+ d->setCharset(dfn, OCI_HTYPE_DEFINE);
}
break;
default:
@@ -950,35 +957,6 @@ OCILobLocator **QOCICols::createLobLocator(int position, OCIEnv* env)
return &lob;
}
-void QOCICols::setCharset(OCIDefine* dfn)
-{
- int r = 0;
-
- Q_ASSERT(dfn);
-
- r = OCIAttrSet(dfn,
- OCI_HTYPE_DEFINE,
- // this const cast is safe since OCI doesn't touch
- // the charset.
- const_cast<void *>(static_cast<const void *>(&qOraCharsetForm)),
- 0,
- OCI_ATTR_CHARSET_FORM,
- d->err);
- if (r != 0)
- qOraWarning("QOCIResultPrivate::setCharset: Couldn't set OCI_ATTR_CHARSET_FORM: ", d->err);
-
- r = OCIAttrSet(dfn,
- OCI_HTYPE_DEFINE,
- // this const cast is safe since OCI doesn't touch
- // the charset.
- const_cast<void *>(static_cast<const void *>(&qOraCharset)),
- 0,
- OCI_ATTR_CHARSET_ID,
- d->err);
- if (r != 0)
- qOraWarning("QOCICols::setCharset: Couldn't set OCI_ATTR_CHARSET_ID: ", d->err);
-}
-
int QOCICols::readPiecewise(QVector<QVariant> &values, int index)
{
OCIDefine* dfn;
diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp
index c7a61a5..7c93c7a 100644
--- a/tests/auto/qsqlquery/tst_qsqlquery.cpp
+++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp
@@ -209,6 +209,8 @@ private slots:
void QTBUG_6852();
void QTBUG_5765_data() { generic_data("QMYSQL"); }
void QTBUG_5765();
+ void QTBUG_14132_data() { generic_data("QOCI"); }
+ void QTBUG_14132();
void sqlite_constraint_data() { generic_data("QSQLITE"); }
void sqlite_constraint();
@@ -2933,6 +2935,25 @@ void tst_QSqlQuery::QTBUG_551()
QCOMPARE(res_outLst[2].toString(), QLatin1String("3. Value is 2"));
}
+void tst_QSqlQuery::QTBUG_14132()
+{
+ QFETCH( QString, dbName );
+ QSqlDatabase db = QSqlDatabase::database( dbName );
+ CHECK_DATABASE( db );
+ QSqlQuery q(db);
+ const QString procedureName(qTableName("procedure", __FILE__));
+ QVERIFY_SQL(q, exec("CREATE OR REPLACE PROCEDURE "+ procedureName + " (outStr OUT varchar2) \n\
+ is \n\
+ begin \n\
+ outStr := 'OUTSTRING'; \n\
+ end;"));
+ QString outValue = "XXXXXXXXX";
+ q.prepare("CALL "+procedureName+"(?)");
+ q.addBindValue(outValue, QSql::Out);
+ QVERIFY_SQL(q, exec());
+ QCOMPARE(outValue, QLatin1String("OUTSTRING"));
+}
+
void tst_QSqlQuery::QTBUG_5251()
{
QFETCH( QString, dbName );