<table><tr><td style="">jfita created this revision.<br />jfita added reviewers: staniek, piggz.<br />Herald added a project: KDb.<br />Herald added a subscriber: Kexi-Devel-list.<br />jfita requested review of this revision.
</td><a style="text-decoration: none; padding: 4px 8px; margin: 0 8px 8px; float: right; color: #464C5C; font-weight: bold; border-radius: 3px; background-color: #F7F7F9; background-image: linear-gradient(to bottom,#fff,#f1f0f1); display: inline-block; border: 1px solid rgba(71,87,120,.2);" href="https://phabricator.kde.org/D29346">View Revision</a></tr></table><br /><div><strong>REVISION SUMMARY</strong><div><p>It has been decided that KDb will use the same characters to quote<br />
identifiers as it uses to delimit query parameters: the square<br />
brackets ([]). Depending on the context will decide if a quoted<br />
identifier is a column name or a query parameter.</p>

<p>That is, given a table named “sample” that has two columns “id” and<br />
“select”, KDb is able to parse the following query</p>

<div class="remarkup-code-block" style="margin: 12px 0;" data-code-lang="text" data-sigil="remarkup-code-block"><pre class="remarkup-code" style="font: 11px/15px "Menlo", "Consolas", "Monaco", monospace; padding: 12px; margin: 0; background: rgba(71, 87, 120, 0.08);">SELECT [table].id AS [integer], [select], [a parameter] FROM sample [table] WHERE [select] = [another parameter] ORDER BY [integer] DESC;</pre></div>

<p>and can tell apart that [a parameter] and [another parameter] are query<br />
parameters while the rest are references to columns or column aliases.</p>

<p>Because query parameters and quoted identifiers share the same<br />
characters, the lexed did not have to change much, but the parser now<br />
needs non-terminal identifier rule to recognize both unquoted and quoted<br />
identifiers. That is why i also had to change the tokens from the lexer.</p>

<p>Most of the time the context is enough to know whether the [identifier]<br />
is a quoted identifier or a query parameter (e.g., in ORDER it can only<br />
be the former), but this can not be done for expressions and there is<br />
the need of a post-parse step to try to resolve the ambiguity.</p>

<p>I first tried to create a KDbQuotedIdentifierExpression that would<br />
behave like a KDbVariableExpression or a KDbQueryParameterExpression<br />
depending on whether KDbExpression::verify would be able to find the<br />
name as a table column or alias.</p>

<p>However i had a lot of trouble making it work without duplicating a lot<br />
of code from both KDbVariableExpression and KDbQueryParameterExpression<br />
and, at the end, i changed the strategy: at first, all quoted<br />
identifiers are assumed to be query parameters and a new<br />
KDbExpression::resolveQuotedIdentifiers would *replace* all query<br />
parameters whose value that can be resolved to a column with a new<br />
KDbVariableExpression.</p>

<p>As far as i could see, Kexi picks up the changes transparently and<br />
stores the SQL in KDBSQL quoted with the new characters, and makes this<br />
change compatible with previous versions.</p>

<p>The only drawback is that, from now own, if a query had a quoted<br />
identifier for a column that the user deletes now that identifiers would<br />
be parsed as a query parameter.</p>

<p>Finally, i also changed the quote character in KDb::escapeIdentifier so<br />
that KDbNativeQueryBuilder would escape all identifiers using brackets<br />
instead of double quotes, otherwise they would be parsed as string<br />
literals instead.</p>

<p>BUG:332161<br />
BUG:420599</p>

<p>FIXED-IN:3.2.1</p></div></div><br /><div><strong>REPOSITORY</strong><div><div>R15 KDb</div></div></div><br /><div><strong>BRANCH</strong><div><div>332161-autotests</div></div></div><br /><div><strong>REVISION DETAIL</strong><div><a href="https://phabricator.kde.org/D29346">https://phabricator.kde.org/D29346</a></div></div><br /><div><strong>AFFECTED FILES</strong><div><div>autotests/ExpressionsTest.cpp<br />
autotests/ExpressionsTest.h<br />
autotests/OrderByColumnTest.cpp<br />
autotests/parser/SqlParserTest.cpp<br />
autotests/parser/data/statements.txt<br />
autotests/tools/IdentifierTest.cpp<br />
src/KDb.cpp<br />
src/expression/KDbExpression.cpp<br />
src/expression/KDbExpression.h<br />
src/expression/KDbQueryParameterExpression.cpp<br />
src/parser/KDbParser_p.cpp<br />
src/parser/KDbSqlParser.y<br />
src/parser/KDbSqlScanner.l<br />
src/parser/generated/KDbToken.cpp<br />
src/parser/generated/KDbToken.h<br />
src/parser/generated/sqlparser.cpp<br />
src/parser/generated/sqlparser.h<br />
src/parser/generated/sqlscanner.cpp</div></div></div><br /><div><strong>To: </strong>jfita, staniek, piggz<br /><strong>Cc: </strong>Kexi-Devel-list, barman, wicik, staniek<br /></div>