dremio sql 编辑器自动提示服务简单说明
dremio 以前代码自动提示的是一个独立的service,之后统一调整到dac的backend 中了,以下是关于实现的一个简单说明
服务接口
sql 自动提示,实际上是基于前端与后段集成起来实现的,前端部分我先不介绍,核心主要说明下关于后端部分
- 接口
@POST
@Path("/autocomplete")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public AutocompleteResponse getSuggestions(AutocompleteRequest request) {
Preconditions.checkNotNull(request);
return AutocompleteProxy.getSuggestions(
catalogServiceHelper,
request
);
}
- 内部处理
AutocompleteProxy 类使用了CatalogServiceHelper,获取推荐代码
可以看到需要结合前端传递的参数,区分不同的类型,container,column,refefence,branch,tag 等进行处理
public static AutocompleteResponse getSuggestions(
CatalogServiceHelper catalogServiceHelper,
AutocompleteRequest request) {
Preconditions.checkArgument(request.getCatalogEntityKeys() != null, "CatalogEntity keys can be empty but must be provided");
switch(request.getType()) {
case CONTAINER: {
return getContainerSuggestions(catalogServiceHelper, request.getCatalogEntityKeys(), request.getQueryContext(), request.getPrefix(), request.getRefType(), request.getRefValue());
}
case COLUMN: {
return getColumnSuggestions(catalogServiceHelper, request.getCatalogEntityKeys(), request.getQueryContext(), request.getPrefix(), request.getRefType(), request.getRefValue());
}
case REFERENCE:
case BRANCH:
case TAG: {
return getReferenceSuggestions(catalogServiceHelper, request.getCatalogEntityKeys(), request.getPrefix(), request.getType());
}
default:
throw new RuntimeException("Unknown autocomplete type " + request.getType());
}
}
- getContainerSuggestions 参考处理
private static List<CatalogItem> getMatchingContainersFromPath(
CatalogServiceHelper catalogServiceHelper,
List<String> catalogEntityKey,
String prefix,
String refType,
String refValue) {
List<CatalogItem> matchingContainers;
// 通过catalogServiceHelper 获取需要的信息
if (catalogEntityKey.isEmpty()) {
matchingContainers = catalogServiceHelper.getTopLevelCatalogItems(Collections.EMPTY_LIST);
addSystemSources(matchingContainers, catalogServiceHelper);
} else {
try {
matchingContainers = catalogServiceHelper.getCatalogChildrenForPath(catalogEntityKey, refType, refValue);
} catch (AccessControlException ignored) {
matchingContainers = Collections.EMPTY_LIST;
}
}
return matchingContainers.stream()
.filter((item) -> {
String itemName = Iterables.getLast(item.getPath(), null);
if (itemName == null) {
return false;
} else if (prefix == null) {
return true;
} else {
return StringUtils.startsWithIgnoreCase(itemName, prefix);
}
})
.collect(Collectors.toList());
}
说明
对于函数部分的自动提示是直接接口获取所有内部函数,然后通过前端实现的,如果看过以前实现的化,发现新版本的实现简单了不少,不少功能
需要前端的处理(monaco 编辑器)
参考资料
dac/backend/src/main/java/com/dremio/dac/service/autocomplete/AutocompleteProxy.java
dac/backend/src/main/java/com/dremio/dac/service/catalog/CatalogServiceHelper.java
dac/ui/src/components/SQLAutoCompleteLists.js
dac/ui/src/pages/ExplorePage/components/SqlEditor/SqlEditorController.js