SQL/PSQL: Avoid copies of data in QByteArray when binding such a value
Fixes: QTBUG-132303 Change-Id: I84e822078d684850c5c0384338cfa4c01fe5007f Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de> (cherry picked from commit f346a6065d36cda4ceacce03962ba58a7cf91019) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
33d74f3f58
commit
79f96014d1
@ -818,25 +818,25 @@ void QPSQLResult::virtual_hook(int id, void *data)
|
|||||||
QSqlResult::virtual_hook(id, data);
|
QSqlResult::virtual_hook(id, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static QList<QByteArray> qCreateParamArray(const QList<QVariant> &boundValues, const QPSQLDriver *driver)
|
static auto qCreateParam(QSqlField &f, const QVariant &boundValue, const QPSQLDriver *driver)
|
||||||
{
|
{
|
||||||
if (boundValues.isEmpty())
|
std::pair<QByteArray, bool /*binary*/> param;
|
||||||
return {};
|
if (!QSqlResultPrivate::isVariantNull(boundValue)) {
|
||||||
|
// in this switch we define faster ways to convert string, ideally we could use binary formats for more types
|
||||||
QList<QByteArray> params;
|
switch (boundValue.metaType().id()) {
|
||||||
params.reserve(boundValues.size());
|
case QMetaType::QByteArray:
|
||||||
QSqlField f;
|
param = {boundValue.toByteArray(), true};
|
||||||
for (const QVariant &val : boundValues) {
|
break;
|
||||||
QByteArray bval;
|
default: {
|
||||||
if (!QSqlResultPrivate::isVariantNull(val)) {
|
f.setMetaType(boundValue.metaType());
|
||||||
f.setMetaType(val.metaType());
|
f.setValue(boundValue);
|
||||||
f.setValue(val);
|
const QString strval = driver->formatValue<true>(f);
|
||||||
if (QString strval = driver->formatValue<true>(f); !strval.isNull())
|
param = {strval.isNull() ? QByteArray{} : strval.toUtf8(), false};
|
||||||
bval = strval.toUtf8();
|
break;
|
||||||
}
|
}
|
||||||
params.append(bval);
|
|
||||||
}
|
}
|
||||||
return params;
|
}
|
||||||
|
return param;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString qMakePreparedStmtId()
|
QString qMakePreparedStmtId()
|
||||||
@ -881,14 +881,25 @@ bool QPSQLResult::exec()
|
|||||||
|
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
const QList<QByteArray> params = qCreateParamArray(boundValues(), static_cast<const QPSQLDriver *>(driver()));
|
|
||||||
QVarLengthArray<const char *> pgParams;
|
QVarLengthArray<const char *> pgParams;
|
||||||
pgParams.reserve(params.size());
|
QVarLengthArray<int> pgParamLengths;
|
||||||
for (const QByteArray ¶m : params)
|
QVarLengthArray<int> pgParamFormats;
|
||||||
|
QVarLengthArray<QByteArray> _refsToKeep;
|
||||||
|
|
||||||
|
if (const QVariantList values = boundValues(); !values.isEmpty()) {
|
||||||
|
QSqlField f;
|
||||||
|
for (const QVariant &value : values) {
|
||||||
|
auto [param, binary] = qCreateParam(f, value, static_cast<const QPSQLDriver *>(driver()));
|
||||||
pgParams.emplace_back(param.constBegin());
|
pgParams.emplace_back(param.constBegin());
|
||||||
|
pgParamLengths.emplace_back(param.size());
|
||||||
|
pgParamFormats.emplace_back(binary);
|
||||||
|
if (!param.isNull())
|
||||||
|
_refsToKeep.emplace_back(std::move(param));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
d->result = PQexecPrepared(d->drv_d_func()->connection, d->preparedStmtId.toUtf8(), pgParams.size(),
|
d->result = PQexecPrepared(d->drv_d_func()->connection, d->preparedStmtId.toUtf8(), pgParams.size(),
|
||||||
pgParams.data(), nullptr, nullptr, 0);
|
pgParams.data(), pgParamLengths.data(), pgParamFormats.data(), 0);
|
||||||
|
|
||||||
const auto status = PQresultStatus(d->result);
|
const auto status = PQresultStatus(d->result);
|
||||||
if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) {
|
if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user