Add synonym-aware name resolution to SqlFormatter with SQL-style SqlSynonym semantics and formatter-level synonym overrides#156
Conversation
Agent-Logs-Url: https://github.com/themost-framework/query/sessions/48a4fe49-749a-4721-b741-95974aa979b9 Co-authored-by: kbarbounakis <9191768+kbarbounakis@users.noreply.github.com>
SqlFormatter via pluggable escape-time hooks
| } | ||
| return ObjectNameValidator.validator.escape(str, this.settings.nameFormat); | ||
| const event = { | ||
| formatter: this, |
There was a problem hiding this comment.
It seems that it's better to use a different name like target instead of formatter
There was a problem hiding this comment.
Updated in 6e84bfb: replaced formatter with target in the resolving event payload.
| const event = { | ||
| formatter: this, | ||
| name: str, | ||
| format: this.settings.nameFormat, |
There was a problem hiding this comment.
The SqlFormatter instance is already avaiable. We don't need to pass nameFormat
There was a problem hiding this comment.
Updated in 6e84bfb: removed nameFormat from the event payload and now use formatter settings directly at escape-time.
Agent-Logs-Url: https://github.com/themost-framework/query/sessions/648745f7-74b7-49f0-9fa1-44f2cb8aad06 Co-authored-by: kbarbounakis <9191768+kbarbounakis@users.noreply.github.com>
| const event = { | ||
| target: this, | ||
| name: str, | ||
| type: 'name' |
There was a problem hiding this comment.
It seems that the event type is redundant because resolvingName event is an event emittier for resolving only events of this type,
There was a problem hiding this comment.
Removed the redundant event type payload in da5be42. No UI changes (screenshot N/A).
| @@ -0,0 +1,7 @@ | |||
| export declare class SqlSynonym { | |||
| static add(name: string, synonym: string): void; | |||
There was a problem hiding this comment.
A method for passing an array of synonyms would be very useful e.g.
SqlSynonym.add([
[ 'object1', 'synonym1' ],
[ 'object2', 'synonym2' ]
])
There was a problem hiding this comment.
Added batch array support to SqlSynonym.add() in da5be42. No UI changes (screenshot N/A).
|
|
||
| const synonyms = new Map(); | ||
|
|
||
| class SqlSynonym { |
There was a problem hiding this comment.
It seems that SqlSynonym is a subclass of Map. It would be better to override its methods and use use Map type declarations.
|
|
||
| const synonyms = new Map(); | ||
|
|
||
| class SqlSynonym { |
There was a problem hiding this comment.
SqlSynonym acts like a service and it seems that it's better to use a static method like SqlSynonym.getInstance() and the a static instance of Synonym class.
Agent-Logs-Url: https://github.com/themost-framework/query/sessions/b7f59e89-589e-4a24-89b7-34005331d980 Co-authored-by: kbarbounakis <9191768+kbarbounakis@users.noreply.github.com>
Agent-Logs-Url: https://github.com/themost-framework/query/sessions/b7f59e89-589e-4a24-89b7-34005331d980 Co-authored-by: kbarbounakis <9191768+kbarbounakis@users.noreply.github.com>
Agent-Logs-Url: https://github.com/themost-framework/query/sessions/b7f59e89-589e-4a24-89b7-34005331d980 Co-authored-by: kbarbounakis <9191768+kbarbounakis@users.noreply.github.com>
Agent-Logs-Url: https://github.com/themost-framework/query/sessions/b7f59e89-589e-4a24-89b7-34005331d980 Co-authored-by: kbarbounakis <9191768+kbarbounakis@users.noreply.github.com>
Agent-Logs-Url: https://github.com/themost-framework/query/sessions/b7f59e89-589e-4a24-89b7-34005331d980 Co-authored-by: kbarbounakis <9191768+kbarbounakis@users.noreply.github.com>
SqlFormatter via pluggable escape-time hooksSqlFormatter and enhance SqlSynonym with Map-based singleton/batch APIs
| return this.instance; | ||
| } | ||
|
|
||
| static add(name, synonym) { |
There was a problem hiding this comment.
It seems static methods lile add, remove, get etc are redundant. The static instance can be access using SqlSynonym.getInstance() without calling a static method.
There was a problem hiding this comment.
Done in cbfc2dc: removed redundant static proxy methods and now use SqlSynonym.getInstance() directly. No UI changes (screenshot N/A).
Agent-Logs-Url: https://github.com/themost-framework/query/sessions/331f93ab-0b91-4358-9d97-4b7d7d38e439 Co-authored-by: kbarbounakis <9191768+kbarbounakis@users.noreply.github.com>
| this.sortedKeys = null; | ||
| } | ||
|
|
||
| add(name, synonym) { |
There was a problem hiding this comment.
Let's try to remove add method to reduce complexity and update SqlSynonym constructor to follow Map type definition where new Map() can be called using an array of entries
interface MapConstructor {
new(): Map<any, any>;
new <K, V>(entries?: readonly (readonly [K, V])[] | null): Map<K, V>;
readonly prototype: Map<any, any>;
}There was a problem hiding this comment.
Implemented in 9f308a3: removed the custom add() method and updated SqlSynonym to support new SqlSynonym(entries) constructor usage aligned with Map initialization. No UI changes (screenshot N/A).
| if (typeof exactMatch === 'string') { | ||
| return exactMatch; | ||
| } | ||
| const keys = this.getSortedKeys(); |
There was a problem hiding this comment.
It seems that the usage of this.getSortedKeys() increases the complexitity of this method because every time that SqlSynonym should sort the keys.
There was a problem hiding this comment.
Implemented in 9f308a3: simplified resolve() by removing sorted-key caching and using a single-pass longest-prefix match over existing keys. No UI changes (screenshot N/A).
Agent-Logs-Url: https://github.com/themost-framework/query/sessions/ab666de7-8718-440b-bcf8-2a225953ac03 Co-authored-by: kbarbounakis <9191768+kbarbounakis@users.noreply.github.com>
SqlFormatter and enhance SqlSynonym with Map-based singleton/batch APIsSqlFormatter and align SqlSynonym with Map-based singleton APIs
| super(entries); | ||
| } | ||
|
|
||
| set(name, synonym) { |
There was a problem hiding this comment.
SQL synonyms are being used for simplifying SQL expressions. So, if we are using a database engine which supports schemas, we would use a synonym to declare a table in another schema e.g. sales.Products as Products. In that case the synomym is the Products and the original data object name is sales.Products. The SqlSynonym approach -and the test unit of this MR- uses the original data object name as key and the synonym as value. We should try to follow SQL synonyms usage and reverse them.
Agent-Logs-Url: https://github.com/themost-framework/query/sessions/0af5db8f-0c46-4675-bd4a-edfb48695bff Co-authored-by: kbarbounakis <9191768+kbarbounakis@users.noreply.github.com>
Agent-Logs-Url: https://github.com/themost-framework/query/sessions/0af5db8f-0c46-4675-bd4a-edfb48695bff Co-authored-by: kbarbounakis <9191768+kbarbounakis@users.noreply.github.com>
SqlFormatter and align SqlSynonym with Map-based singleton APIsSqlFormatter and align SqlSynonym with SQL-style Map-based singleton semantics
| constructor() { | ||
| // | ||
| this.provider = null; | ||
| this.resolvingName = SqlFormatter.resolvingName; |
There was a problem hiding this comment.
SqlFormatter should have an option to use their own SqlSynonym instance. This instance, if exists, might be used before using the static SqlFormatter.resolvingName
Agent-Logs-Url: https://github.com/themost-framework/query/sessions/4dd5caf9-c9a3-468d-a793-26caab8368b4 Co-authored-by: kbarbounakis <9191768+kbarbounakis@users.noreply.github.com>
Agent-Logs-Url: https://github.com/themost-framework/query/sessions/4dd5caf9-c9a3-468d-a793-26caab8368b4 Co-authored-by: kbarbounakis <9191768+kbarbounakis@users.noreply.github.com>
SqlFormatter and align SqlSynonym with SQL-style Map-based singleton semanticsSqlFormatter with SQL-style SqlSynonym semantics and formatter-level synonym overrides
SqlFormatterpreviously escaped object names directly, which prevented transparent use of database synonyms in an engine-agnostic way. This change adds formatter-level extension points and a built-in synonym service so aliases can be resolved during SQL name parsing/escaping.Formatter extension point for name resolution
SqlFormatter.resolvingName(sync event emitter) and instance access to it.escapeName()andescapeEntity()now emit a resolution event beforeObjectNameValidator.escape(...).target(the formatter instance) and currentname.Formatter-level synonym override support
SqlFormatter.synonymsresolver support (resolve(name)).escapeName()/escapeEntity(), before staticSqlFormatter.resolvingNamehandlers.Map-based singleton synonym service
SqlSynonymnow extendsMap<string, string>and acts as a singleton service viaSqlSynonym.getInstance().Mapinstance methods (set,delete,clear,get) plusresolve.SqlSynonymconstructor followsMapinitialization semantics and accepts optional entries (batch initialization vianew SqlSynonym(entries)).resolve()supports both exact and qualified-prefix replacement (e.g.Products.ProductID) using single-pass longest-prefix matching.synonym -> original object(e.g.Products -> sales.Products).Public API / typings
SqlSynonymfromsrc/index.jsandsrc/index.d.ts.SqlFormatter.resolvingNamepayload shape (target,name)SqlFormatter.synonymsresolver propertySqlSynonymas aMapsubclass withgetInstance()access andMap-compatible constructor overloads.Focused behavior coverage
spec/SqlSynonym.spec.jscoverage for:escapeEntity/escapeNameOpenDataQueryFormatter)synonym -> original)