概要
Byzer Code Intelligence 是一个代码补全后端引擎。既可以为 Byzer 语法做补全, 也可以为标准 Spark SQL(Select语句)做补全。我们支持了 SQL 中使用的表的 Schema Infer 功能,对于 csv 等结构化文件以及数据湖内的数据,能够轻松做到字段提示。对复杂 SQL 语句,跨语句、子查询等情况也能做到准确的字段解析和提示。
Byzer 智能补全功能现阶段是作为 Byzer 的一个插件的形式提供的。以 extension 的方式接入到 Byzer-lang,然后暴露成一致的 Byzer-lang 语法调用形态,简化上层应用开发,这可以有效地保留企业原有的软件资产积累。同时,能充分利用 Byzer-lang 自身的生态和能力,有效提升数仓开发效率,在 Vscode Desktop 中结合内置的 python、scala 技术栈的静态语法提示,可以更便利地进行在线 coding。
目前 Byzer Code Intelligence 覆盖了Byzer 语言中的 8 个常用语法提示,包括 load、save、select、set、run、train、predict、register。 支持解析时提取脚本中的表,提取上游数据源或输入表字段,支持关联参数自省机制,纯后端代码提示,对比同类型语法提示工具更精确、能力更强。
从用户视角看,该插件一方面降低了新用户由于对 Byzer 语言不熟悉而产生的答疑成本,通过对内置插件参数、使用语法等信息的自动提示,方便用户快速上手和使用;另一方面通过表结构精确推断、上下文感知,可以为用户降低使用成本、提升 coding 的效率。
从技术视角看,Byzer Code Intelligence 使用 RESTFUL 的后端服务化设计,可以实现多端灵活适配。目前 Byzer Notebook 客户端的编辑器采用的是 ace-editor,其中代码提示功能就是结合自身的原有提示和 Byzer Code Intelligence。同样,在 Byzer Vscode extension 中也很方便地对 vscode 提示和 Byzer Code Intelligence 做了结合,避免了代码的冗余和实现逻辑的不一致。
使用方式
代码补全支持2种触发方式,一种是在控制台输入字母时触发,一种是使用组合键:
- windows:alt + space
- mac: option + space
功能介绍
【Byzer Code Intelligence】目标分成两个
第一个是标准 SQL 补全:
- SQL关键字补全
- 表/字段属性/函数补全
- 可二次开发自定义对接任何 Schema Provider
第二个是 Byzer 语法补全:
- 支持各种数据源提示
- 支持临时表提示
- 支持各种ET组件参数提示以及名称提示
对于表和字段补全,函数补全,相比其他一些 SQL 代码提示工具,该插件可根据当前已有的信息精确推断。比如:
select no_result_type, keywords, search_num, rank
from(
select [CURSOR IS HERE] row_number() over (PARTITION BY no_result_type order by search_num desc) as rank
from(
select jack1.*,no_result_type, keywords, sum(search_num) AS search_num
from jack.drugs_bad_case_di as jack1,jack.abc jack2
where hp_stat_date >= date_sub(current_date,30)
and action_dt >= date_sub(current_date,30)
and action_type = 'search'
and length(keywords) > 1
and (split(av, '\\.')[0] >= 11 OR (split(av, '\\.')[0] = 10 AND split(av, '\\.')[1] = 9))
--and no_result_type = 'indication'
group by no_result_type, keywords
)a
)b
where rank <=
鼠标在第三行第十列,此时系统会自动提示:
- a [表名]
- jack1展开的所有列
- no_result_type
- keywords
- search_num
如果有接口提供 schema 信息,会自动展开*,并且获取相关层级的信息从而非常精准的进行提示。同时,如果有 shcema 信息,对每个字段也支持类型提示。插件提供了非常友好和简单的接口方便用户接入自己的元数据。
用户 API 指南
部署
该插件作为Byzer engine 默认插件,所以开箱即用。
消费方接口使用
访问接口: http://127.0.0.1:9003/run/script?executeMode=autoSuggest
参数1: sql SQL脚本
参数2: lineNum 光标所在的行号 从1开始计数
参数3: columnNum 光标所在的列号,从1开始计数
比如用 Scala 写一个 client:
object Test {
def main(args: Array[String]): Unit = {
val time = System.currentTimeMillis()
val response = Request.Post("http://127.0.0.1:9003/run/script").bodyForm(
Form.form().add("executeMode", "autoSuggest").add("sql",
"""
|select spl from jack.drugs_bad_case_di as a
|""".stripMargin).add("lineNum", "2").add("columnNum", "10").build()
).execute().returnContent().asString()
println(System.currentTimeMillis() - time)
println(response)
}
}
最后结果如下:
[{"name":"split",
"metaTable":{"key":{"db":"__FUNC__","table":"split"},
"columns":[
{"name":null,"dataType":"array","isNull":true,"extra":{"zhDoc":"\nsplit函数。用于切割字符串,返回字符串数组\n"}},{"name":"str","dataType":"string","isNull":false,"extra":{"zhDoc":"待切割字符"}},
{"name":"pattern","dataType":"string","isNull":false,"extra":{"zhDoc":"分隔符"}}]},
"extra":{}}]
可以知道提示了split,并且这是一个函数,函数的参数以及返回值都有定义。
生产方编程开发
首先初始化两个词法分析器:
object AutoSuggestController {
val lexerAndParserfactory = new ReflectionL