diff options
author | Israel Lins <israelins85@yahoo.com.br> | 2013-02-07 16:18:05 -0300 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-02-15 15:47:58 +0100 |
commit | 776c488b6f6a88eb8dacafa992bf61f0167df6a3 (patch) | |
tree | fae1cc622f4801896cbc39eb296e4167ce2f255a /src/sql | |
parent | c8e34ed678145f2e5709d39007e27e186d1bc1f9 (diff) |
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 <mabrand@mabrand.nl>
Diffstat (limited to 'src/sql')
-rw-r--r-- | src/sql/kernel/qsqlresult.cpp | 75 |
1 files changed, 54 insertions, 21 deletions
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(); |