dt-sql-parser icon indicating copy to clipboard operation
dt-sql-parser copied to clipboard

[Feature Request]: 希望 getSuggestionAtCaretPosition 返回的 "column" 的 wordRanges 可以包含到值

Open wonghan opened this issue 6 months ago • 5 comments

Topic

Enhance existing features

Which SQL?

Hive

SQL content

SELECT * from hive_current_catalog_schema1 WHERE hive_current_catalog_schema1 =

What happened?

此时返回的补全项是重新推荐一个新的column Image

Description

希望 getSuggestionAtCaretPosition 返回的 "column" 的 wordRanges 可以包含到值,如期望返回的 column wordRanges 的结构:

[
    {
        "syntaxContextType": "column",
        "wordRanges": [
            {
                "text": "hive_current_catalog_schema1",
                "line": 1,
                "startIndex": 49,
                "endIndex": 76,
                "startColumn": 50,
                "endColumn": 78
            },
            {
                "text": " ",
                "line": 1,
                "startIndex": 77,
                "endIndex": 77,
                "startColumn": 78,
                "endColumn": 79
            },
            {
                "text": "=",
                "line": 1,
                "startIndex": 78,
                "endIndex": 78,
                "startColumn": 79,
                "endColumn": 80
            },
           {
                "text": " ",
                "line": 1,
                "startIndex": 79,
                "endIndex": 79,
                "startColumn": 80,
                "endColumn": 81
            }
        ]
    }
]

这样的话,可以根据当前的column,去进行下一步的处理,如查询这个column有什么枚举值之类的

wonghan avatar Jun 05 '25 06:06 wonghan

可以再具体点吗,比如示例 SQL、期望返回的 column wordRanges 是什么结构

liuxy0551 avatar Jun 05 '25 06:06 liuxy0551

可以再具体点吗,比如示例 SQL、期望返回的 column wordRanges 是什么结构

已补充 @liuxy0551

wonghan avatar Jun 05 '25 07:06 wonghan

  1. dt-sql-parser 只提示光标位置可以填写的语法类型,这里提示可以写 COLUMN,需要在自身业务中自行实现填充补全项,可以参考 https://github.com/DTStack/monaco-sql-languages/blob/main/website/src/languages/helpers/completionService.ts#L97 关于 TABLE 补全项的填充。
  2. 在实现时,可能需要通过接口获取当前 sql 语句中多个表的所有字段,然后根据光标位置已有代码的内容长度判断填充 Database/Table/Column。
  3. 举例:wordRanges 为空时此时可以直接将字段列表填充进补全项,wordRanges 有值时 COLUMN 可能为 table.columndatabase.table.column Image
  4. completionService 中返回的 entities 可以帮助我们拿到当前 sql 语句中的 tables,拿到 tables 就方便去获取表的字段了
// 当前语句中有的表
const tablesInAllSql: EntityContext[] =
    entities?.filter(
        (entity: EntityContext) => entity.entityContextType === EntityContextType.TABLE
    ) ?? [];

// 当前语句的表,可能是多个,比如使用了 join
const tablesInCurrentSql: EntityContext[] = tablesInAllSql.filter(
    (entity: EntityContext) => entity?.belongStmt?.isContainCaret
);

liuxy0551 avatar Jun 05 '25 08:06 liuxy0551

@liuxy0551

  1. 感谢你的解答,不过我的诉求不是在这个地方推荐表的字段,我想要的是推荐是字段的值

  2. 比如这个地方,假设 hive_current_catalog_schema1 是枚举类型,那我可以在 = 之后,推荐字段的枚举值 enum1 / enum2 / ...

Image
  1. 因为当前在 = 之后,再按一次空格,此时 getSuggestionAtCaretPosition 会将此位置当作新字段的开始,返回如下:

Image

因此我无法知道当前的位置其实是 [字段] [操作符] [值] [值] 的位置,就无法实现 推荐字段的枚举值 的功能

  1. 因此我假设,假如 dt-sql-parser 返回的值,可以扩展到操作符之后,比如:
[
    {
        "syntaxContextType": "column",
        "wordRanges": [
            {
                "text": "hive_current_catalog_schema1",
                "line": 1,
                "startIndex": 49,
                "endIndex": 76,
                "startColumn": 50,
                "endColumn": 78
            },
            {
                "text": " ",
                "line": 1,
                "startIndex": 77,
                "endIndex": 77,
                "startColumn": 78,
                "endColumn": 79
            },
            {
                "text": "=",
                "line": 1,
                "startIndex": 78,
                "endIndex": 78,
                "startColumn": 79,
                "endColumn": 80
            },
           {
                "text": " ",
                "line": 1,
                "startIndex": 79,
                "endIndex": 79,
                "startColumn": 80,
                "endColumn": 81
            }
        ]
    }
]

那我就可以按照 @liuxy0551 说的表字段的推荐方法,去做字段值的推荐。

  1. 除了这么修改,如果有其他方法,可以做到 推荐字段的值 的功能,欢迎指导,感谢!

wonghan avatar Jun 05 '25 08:06 wonghan

谢谢你的解释,我了解了你的预期。

  1. 目前 dt-sql-parser 没有做这么细支上的需求,做到了 COLUMN 的提示补全,但是没有对 COLUMN 的各种属性进一步做延伸功能。
  2. 可以讨论下这个需求如何实现。从我的角度看,可能需要修改底层的 g4 语法文件,文件在 src/grammar/hive/HiveSqlParser.g4,不过这需要比较了解 g4 文件的语法。
  3. 比如 HiveSQL 和 SparkSQL 想要支持的话,结构也不尽相同,HiveSQL columnName 和值 这部分相对复杂点,层级更多:
Image Image

抱歉,我们目前没有该功能的迭代计划,无法快速帮助你实现你的预期。

liuxy0551 avatar Jun 05 '25 10:06 liuxy0551