7 Mycat原理解析-DDL语句处理

前面,我们已经讲过了Mycat如何判断sql类型,然后针对不同类型的sql就行不同的处理【Mycat原理解析-SQL语句的处理】,下面,我们来看看其中的DDL语句,Mycat是怎么处理的。

结合ServerParse.java中的代码,我们来看看Mycat支持的常见的DDL语句的。

  • CREATE:create index
  • DROP:drop index
  • TRUNCATE:truncate table
  • ALTER:alter table

针对DDL语句,Mycat没有提供专门的Handler,而是使用统一的ServerConnection.execute()方法进行处理。下图展示了一条DDL语句简要的处理过程。
这里写图片描述

跟普通语句不同的地方就在于DDL语句的路由部分,下面来看看DDL语句路由部分的代码。

public static RouteResultset routeToDDLNode(RouteResultset rrs, int sqlType, String stmt,SchemaConfig schema) throws SQLSyntaxErrorException {
    stmt = getFixedSql(stmt);
    String tablename = "";
    final String upStmt = stmt.toUpperCase();
    //CREATE语句
    if(upStmt.startsWith("CREATE")){
        //CREATE INDEX语句
        if (upStmt.contains("CREATE INDEX ")){
            tablename = RouterUtil.getTableName(stmt, RouterUtil.getCreateIndexPos(upStmt, 0));
        }else {
            tablename = RouterUtil.getTableName(stmt, RouterUtil.getCreateTablePos(upStmt, 0));
        }
    //DROP语句
    }else if(upStmt.startsWith("DROP")){
        //DROP INDEX语句
        if (upStmt.contains("DROP INDEX ")){
            tablename = RouterUtil.getTableName(stmt, RouterUtil.getDropIndexPos(upStmt, 0));
        }else {
            tablename = RouterUtil.getTableName(stmt, RouterUtil.getDropTablePos(upStmt, 0));
        }
    }else if(upStmt.startsWith("ALTER")){
        tablename = RouterUtil.getTableName(stmt, RouterUtil.getAlterTablePos(upStmt, 0));
    }else if (upStmt.startsWith("TRUNCATE")){
        tablename = RouterUtil.getTableName(stmt, RouterUtil.getTruncateTablePos(upStmt, 0));
    }
    tablename = tablename.toUpperCase();

    if (schema.getTables().containsKey(tablename)){
        if(ServerParse.DDL==sqlType){
            List<String> dataNodes = new ArrayList<>();
            Map<String, TableConfig> tables = schema.getTables();
            TableConfig tc=tables.get(tablename);
            if (tables != null && (tc  != null)) {
                dataNodes = tc.getDataNodes();
            }
            boolean isSlotFunction= tc.getRule() != null && tc.getRule().getRuleAlgorithm() instanceof SlotFunction;
            Iterator<String> iterator1 = dataNodes.iterator();
            int nodeSize = dataNodes.size();
            RouteResultsetNode[] nodes = new RouteResultsetNode[nodeSize];
             if(isSlotFunction){
                 stmt=changeCreateTable(schema,tablename,stmt);
             }
            for(int i=0;i<nodeSize;i++){
                String name = iterator1.next();
                nodes[i] = new RouteResultsetNode(name, sqlType, stmt);
                nodes[i].setSource(rrs);
                if(rrs.getDataNodeSlotMap().containsKey(name)){
                    nodes[i].setSlot(rrs.getDataNodeSlotMap().get(name));
                }  else if(isSlotFunction){
                    nodes[i].setSlot(-1);
                }
            }
            rrs.setNodes(nodes);
        }
        return rrs;
    }else if(schema.getDataNode()!=null){       //默认节点ddl
        RouteResultsetNode[] nodes = new RouteResultsetNode[1];
        nodes[0] = new RouteResultsetNode(schema.getDataNode(), sqlType, stmt);
        nodes[0].setSource(rrs);
        rrs.setNodes(nodes);
        return rrs;
    }
    //both tablename and defaultnode null
    LOGGER.error("table not in schema----"+tablename);
    throw new SQLSyntaxErrorException("op table not in schema----"+tablename);
}

上面的代码主要做了下面两件事:

  1. 确定逻辑表名
  2. 构造RouteResultset对象(构造规则是每个dataNode对应一个RouteResultsetNode)。果逻辑库存在该表,根据TableConfig的配置来构造,如果不存在,根据逻辑库默认的dataNode来构造。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值