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

posted on 2024-03-07 08:00  荣锋亮  阅读(18)  评论(0编辑  收藏  举报

导航