It has been decided that KDb will use the same characters to quote
identifiers as it uses to delimit query parameters: the square
brackets (). Depending on the context will decide if a quoted
identifier is a column name or a query parameter.
That is, given a table named “sample” that has two columns “id” and
“select”, KDb is able to parse the following query
SELECT [table].id AS [integer], [select], [a parameter] FROM sample [table] WHERE [select] = [another parameter] ORDER BY [integer] DESC;
and can tell apart that [a parameter] and [another parameter] are query
parameters while the rest are references to columns or column aliases.
Because query parameters and quoted identifiers share the same
characters, the lexed did not have to change much, but the parser now
needs non-terminal identifier rule to recognize both unquoted and quoted
identifiers. That is why i also had to change the tokens from the lexer.
Most of the time the context is enough to know whether the [identifier]
is a quoted identifier or a query parameter (e.g., in ORDER it can only
be the former), but this can not be done for expressions and there is
the need of a post-parse step to try to resolve the ambiguity.
I first tried to create a KDbQuotedIdentifierExpression that would
behave like a KDbVariableExpression or a KDbQueryParameterExpression
depending on whether KDbExpression::verify would be able to find the
name as a table column or alias.
However i had a lot of trouble making it work without duplicating a lot
of code from both KDbVariableExpression and KDbQueryParameterExpression
and, at the end, i changed the strategy: at first, all quoted
identifiers are assumed to be query parameters and a new
KDbExpression::resolveQuotedIdentifiers would *replace* all query
parameters whose value that can be resolved to a column with a new
As far as i could see, Kexi picks up the changes transparently and
stores the SQL in KDBSQL quoted with the new characters, and makes this
change compatible with previous versions.
The only drawback is that, from now own, if a query had a quoted
identifier for a column that the user deletes now that identifiers would
be parsed as a query parameter.
Finally, i also changed the quote character in KDb::escapeIdentifier so
that KDbNativeQueryBuilder would escape all identifiers using brackets
instead of double quotes, otherwise they would be parsed as string