Closed mrt181 closed 9 months ago
Hello @mrt181,
wouldn't the former approach constitute a breaking change for existing users? It alters the casing.
We could also consider introducing an additional configuration named EntityCreationMetadata.UseBacktics
, or we could implement an attribute that would decorate classes and properties:
[UseBackticks]
public class Foo
{
[UseBackticks]
public string Bar { get; set; }
}
I think the attribute-based approach could also be utilized for data retrieval. What are your thoughts on this?
Yes just backticking everything isn't good enough.
Maybe the second approach from the patch is more viable as it only escapes when the column identifier is a keyword and the statement would fail without the escaped identifiers anyway.
The attribute approach is explicit but also exposes the user to the ksqlDB internals.
This can be annoying when the fields are not under the control of the user, for example they are provided via code Gen from a given schema or they come from a shared library for data exchange.
Alright, we can include backticks only when the column identifier matches a keyword. However, in such cases, it's crucial to keep the list of existing keywords you've already provided updated whenever new ones are introduced. This method of escaping should also be implemented for insert and select statements.
Would you prefer to draft a pull request for this, or shall I take care of it?
I do it tomorrow
Awesome, I am looking forward to it! Thank you in advance.
@tomasfabian I have created the necessary column identifier check by utilizing the SqlBase.g4 grammer from the ksql project (that project does the same).
I would like to make this an opt-in feature, that is keep the current functionality and provide a way to escape if desired/necessary.
This is my current idea.
// in public record EntityCreationMetadata
public IdentifierEscaping IdentifierFormat { get; set; } = IdentifierEscaping.None;
public enum IdentifierEscaping
{
None = 0,
Keywords = 1,
Always = 2,
}
metadata is send to the StatementGenerator
where the column identifieres are created.
The first option keeps the current behavior. The second would escape if an identifer is a keyword. The third option would always escape (see: https://docs.ksqldb.io/en/latest/reference/sql/syntax/lexical-structure/#identifiers)
What's your opinion on that?
Sure why not? The same enum could be also applied to the KSqlDBContextOptions
:
You must select from it by backticking the stream name and column name and using the original casing:
SELECT `@MY-identifier-stream-column!` FROM `s1` EMIT CHANGES;
Is there an existing .NET package for the SqlBase.g4 grammar? I'm not sure if it is possible to take it from ksql project as it is due to copyrights etc.
The confluenct license forbids competition as a SaaS. This library doesn't do that so should be good to go.
I released a new version:
dotnet add package ksqlDb.RestApi.Client --version 3.6.0
Thank you, @mrt181, on behalf of the entire community for your contribution to this nice enhancement! :)
When I try to create or replace a table that contains a reserved keyword in a column identifier that identifier is not masked.
On the second attempt I use backticks to mask the
end
identifier.The rest api client does not mask identifiers that contain keywords.
One option might be to always mask the column names like this:
Another option would be to introduce a check that escapes when necessary: keywords.patch