From 776c488b6f6a88eb8dacafa992bf61f0167df6a3 Mon Sep 17 00:00:00 2001 From: Israel Lins Date: Thu, 7 Feb 2013 16:18:05 -0300 Subject: QSqlResult: fix parsing of bound SQL statements Parsing for bound SQL parameters now handles identifier quoting using double quotes (") and square brackets ([]). The following has only 1 bound value but previously 2 were detected: SELECT 1 AS "A?b[?']]]de?ghi", ? Task-number: QTBUG-27159 Change-Id: Icfd02187e1126ff3b5ed11df8d4e599f574e61bf Reviewed-by: Mark Brand --- src/sql/kernel/qsqlresult.cpp | 75 +++++++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 21 deletions(-) (limited to 'src/sql') diff --git a/src/sql/kernel/qsqlresult.cpp b/src/sql/kernel/qsqlresult.cpp index 2ebfba0788..ea972abf50 100644 --- a/src/sql/kernel/qsqlresult.cpp +++ b/src/sql/kernel/qsqlresult.cpp @@ -87,17 +87,33 @@ QString QSqlResultPrivate::positionalToNamedBinding(const QString &query, QStrin QString result; result.reserve(n * 5 / 4); - bool inQuote = false; + QChar closingQuote; int count = 0; for (int i = 0; i < n; ++i) { QChar ch = query.at(i); - if (ch == QLatin1Char('?') && !inQuote) { - result += fieldSerialFunc(count++); - } else { - if (ch == QLatin1Char('\'')) - inQuote = !inQuote; + if (!closingQuote.isNull()) { + if (ch == closingQuote) { + if (closingQuote == QLatin1Char(']') + && i + 1 < n && query.at(i + 1) == closingQuote) { + // consume the extra character. don't close. + ++i; + result += ch; + } else { + closingQuote = QChar(); + } + } result += ch; + } else { + if (ch == QLatin1Char('?')) { + result += fieldSerialFunc(count++); + } else { + if (ch == QLatin1Char('\'') || ch == QLatin1Char('"') || ch == QLatin1Char('`')) + closingQuote = ch; + else if (ch == QLatin1Char('[')) + closingQuote = QLatin1Char(']'); + result += ch; + } } } result.squeeze(); @@ -110,28 +126,45 @@ QString QSqlResultPrivate::namedToPositionalBinding(const QString &query) QString result; result.reserve(n); - bool inQuote = false; + QChar closingQuote; int count = 0; int i = 0; while (i < n) { QChar ch = query.at(i); - if (ch == QLatin1Char(':') && !inQuote - && (i == 0 || query.at(i - 1) != QLatin1Char(':')) - && (i + 1 < n && qIsAlnum(query.at(i + 1)))) { - int pos = i + 2; - while (pos < n && qIsAlnum(query.at(pos))) - ++pos; - QString holder(query.mid(i, pos - i)); - indexes[holder].append(count++); - holders.append(QHolder(holder, i)); - result += QLatin1Char('?'); - i = pos; - } else { - if (ch == QLatin1Char('\'')) - inQuote = !inQuote; + if (!closingQuote.isNull()) { + if (ch == closingQuote) { + if (closingQuote == QLatin1Char(']') + && i + 1 < n && query.at(i + 1) == closingQuote) { + // consume the extra character. don't close. + ++i; + result += ch; + } else { + closingQuote = QChar(); + } + } result += ch; ++i; + } else { + if (ch == QLatin1Char(':') + && (i == 0 || query.at(i - 1) != QLatin1Char(':')) + && (i + 1 < n && qIsAlnum(query.at(i + 1)))) { + int pos = i + 2; + while (pos < n && qIsAlnum(query.at(pos))) + ++pos; + QString holder(query.mid(i, pos - i)); + indexes[holder].append(count++); + holders.append(QHolder(holder, i)); + result += QLatin1Char('?'); + i = pos; + } else { + if (ch == QLatin1Char('\'') || ch == QLatin1Char('"') || ch == QLatin1Char('`')) + closingQuote = ch; + else if (ch == QLatin1Char('[')) + closingQuote = QLatin1Char(']'); + result += ch; + ++i; + } } } result.squeeze(); -- cgit v1.2.3