• dremio 实现类似官方create user sql 处理的思路


    主要说明思路,后边有时间了会进行开发的说明

    官方特性说明

    sabot/kernel/src/main/java/com/dremio/exec/planner/sql/parser/SqlCreateUser.java

    public class SqlCreateUser extends SqlCall implements SimpleDirectHandler.Creator {
      private final SqlIdentifier username;
      private final SqlNode password;
      public static final SqlSpecialOperator OPERATOR = new SqlSpecialOperator("CREATE", SqlKind.OTHER) {
        @Override
        public SqlCall createCall(SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands) {
          Preconditions.checkArgument(operands.length == 1, "SqlCreateUser.createCall() has to get at least 1 operands!");
          if (operands.length == 2){
            return new SqlCreateUser(
              pos,
              (SqlIdentifier) operands[0],
              (SqlNode) operands[1]
            );
          }
          return new SqlCreateUser(
            pos,
            (SqlIdentifier) operands[0]
          );
        }
      };
     
      public SqlCreateUser(SqlParserPos pos, SqlIdentifier username) {
        super(pos);
        this.username = username;
        this.password = null;
      }
     
      public SqlCreateUser(SqlParserPos pos, SqlIdentifier username, SqlNode password) {
        super(pos);
        this.username = username;
        this.password = password;
      }
     
      @Override
      public SimpleDirectHandler toDirectHandler(QueryContext context) {
        try {
         // 此处是创建用户的核心
          final Class<?> cl = Class.forName("com.dremio.exec.planner.sql.handlers.UserCreateHandler");
          final Constructor<?> ctor = cl.getConstructor(QueryContext.class);
          return (SimpleDirectHandler) ctor.newInstance(context);
        } catch (ClassNotFoundException e) {
          // Assume failure to find class means that we aren't running Enterprise Edition
          throw UserException.unsupportedError(e)
            .message("CREATE USER action is only supported in Enterprise Edition.")
            .buildSilently();
        } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
          throw Throwables.propagate(e);
        }
     
      }

    从上边可以看出官方的就是一个class 文件。。。。

    handler 开发说明

    • 方法签名
    public abstract class SimpleDirectHandler implements SqlDirectHandler<SimpleCommandResult> {
      @Override
      public Class<SimpleCommandResult> getResultType() {
        return SimpleCommandResult.class;
      }
     
      public interface Creator {
        SimpleDirectHandler toDirectHandler(QueryContext context);
      }
    }
    • 参考实现
      sabot/kernel/src/main/java/com/dremio/exec/planner/sql/handlers/direct/UseSchemaHandler.java
      dremio 内部的一个
     
    public class UseSchemaHandler extends SimpleDirectHandler {
      private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(UseSchemaHandler.class);
     
      private final UserSession session;
      private final Catalog catalog;
     
      public UseSchemaHandler(UserSession session, Catalog catalog) {
        this.session = session;
        this.catalog = catalog;
      }
     
      @Override
      public List<SimpleCommandResult> toResult(String sql, SqlNode sqlNode) throws Exception {
        final SqlUseSchema useSchema = SqlNodeUtil.unwrap(sqlNode, SqlUseSchema.class);
        // first we try locally.
        NamespaceKey orig = new NamespaceKey(useSchema.getSchema());
        NamespaceKey defaultPath = catalog.resolveToDefault(orig);
        NamespaceKey compoundPath = orig.size() == 1 && orig.getRoot().contains(".") ? new NamespaceKey(SqlUtils.parseSchemaPath(orig.getRoot())) : null;
     
        if(defaultPath != null && catalog.containerExists(defaultPath)) {
          session.setDefaultSchemaPath(defaultPath.getPathComponents());
        } else if (catalog.containerExists(orig)) {
          session.setDefaultSchemaPath(orig.getPathComponents());
        } else if(compoundPath != null && catalog.containerExists(compoundPath)) {
          // kept to support old compound use statements.
          session.setDefaultSchemaPath(compoundPath.getPathComponents());
        } else {
          throw UserException.validationError().message("Schema [%s] is not valid with respect to either root schema or current default schema.", orig).build(logger);
        }
     
        return Collections.singletonList(SimpleCommandResult.successful("Default schema changed to [%s]", session.getDefaultSchemaPath()));
      }
    }

    自己实现

    思路就是参考以上的,只是用户管理我们需要集成官方的UserService ,参考地址,具体官方默认实现是SimpleUserService
    services/users/src/main/java/com/dremio/service/users/UserService.java
    services/users/src/main/java/com/dremio/service/users/SimpleUserService.java

    说明

    以上只是一个简单的思路,实现起来也不是很难,实际上dremio好多企业特性也是基于次方法解决的
    从源码上我们也可以猜测官方企业版本主要也是多了一些jar吧,所以官方还是比较务实的,好多特性也是提供给了
    社区的,只是部分企业特性独立开了jar了,后续我们的升级迭代也是比较方法的

    参考资料

    https://github.com/dremio/dremio-oss

  • 相关阅读:
    API接口智能化测试探索与实践
    程序员的社会地位
    程序员五六年能存100万,你说你焦虑个啥!!!
    苹果公司宣布:公司内部的员工有权讨论自己的工作条件和薪酬
    男子股票账户突然多了一个亿!结果……
    你选择双休还是单休?
    PAL制式和NTSC制式的定义及区别(转)
    javascript入门系列演示·三种弹出对话框的用法实例(转)
    sink相关
    Ubuntu下安装gsteditor
  • 原文地址:https://www.cnblogs.com/rongfengliang/p/15484913.html
Copyright © 2020-2023  润新知