Beispiel #1
0
 private RouteResultset routeWithPartitionColumn(
     SchemaConfig schema,
     TableConfig tc,
     QueryTreeNode ast,
     InsertParseInf parsInf,
     RouteResultset rrs,
     String stmt,
     LayerCachePool cachePool)
     throws SQLNonTransientException {
   String partColumn = tc.getPartitionColumn();
   if (partColumn != null) {
     String sharindVal = parsInf.columnPairMap.get(partColumn);
     if (sharindVal != null) {
       Set<ColumnRoutePair> col2Val = new HashSet<ColumnRoutePair>(1);
       col2Val.add(new ColumnRoutePair(sharindVal));
       return tryRouteForTable(ast, schema, rrs, false, stmt, tc, col2Val, null, cachePool);
     } else { // must provide sharding_id when insert
       String inf = "bad insert sql (sharding column:" + partColumn + " not provided," + stmt;
       LOGGER.warn(inf);
       throw new SQLNonTransientException(inf);
     }
   }
   return null;
 }
Beispiel #2
0
  /**
   * 简单描述该方法的实现功能
   *
   * @param ast QueryTreeNode
   * @param schema 数据库名
   * @param rrs 数据路由集合
   * @param isSelect 是否是select语句标志
   * @param sql 执行语句
   * @param tc 表实体
   * @param ruleCol2Val 一个ColumnRoutePair集合
   * @param allColConds 一个ColumnRoutePair集合
   * @param cachePool
   * @return 一个数据路由集合
   * @throws SQLNonTransientException
   * @author mycat
   */
  private RouteResultset tryRouteForTable(
      QueryTreeNode ast,
      SchemaConfig schema,
      RouteResultset rrs,
      boolean isSelect,
      String sql,
      TableConfig tc,
      Set<ColumnRoutePair> ruleCol2Val,
      Map<String, Set<ColumnRoutePair>> allColConds,
      LayerCachePool cachePool)
      throws SQLNonTransientException {

    if (tc.getTableType() == TableConfig.TYPE_GLOBAL_TABLE && isSelect) {
      sql = addSQLLmit(schema, rrs, ast, sql);
      return RouterUtil.routeToSingleNode(rrs, tc.getRandomDataNode(), sql);
    }

    // no partion define or no where condtion for this table or no
    // partion column condtions
    boolean cache = isSelect;
    if (ruleCol2Val == null || ruleCol2Val.isEmpty()) {
      if (tc.isRuleRequired()) {
        throw new IllegalArgumentException(
            "route rule for table " + tc.getName() + " is required: " + sql);

      } else if (allColConds != null && allColConds.size() == 1) {
        // try if can route by ER relation
        if (tc.isSecondLevel() && tc.getParentTC().getPartitionColumn().equals(tc.getParentKey())) {
          Set<ColumnRoutePair> joinKeyPairs = allColConds.get(tc.getJoinKey());
          if (joinKeyPairs != null) {
            Set<String> dataNodeSet = RouterUtil.ruleCalculate(tc.getParentTC(), joinKeyPairs);
            if (dataNodeSet.isEmpty()) {
              throw new SQLNonTransientException("parent key can't find any valid datanode ");
            }
            if (LOGGER.isDebugEnabled()) {
              LOGGER.debug(
                  "found partion nodes (using parent partion rule directly) for child table to update  "
                      + Arrays.toString(dataNodeSet.toArray())
                      + " sql :"
                      + sql);
            }
            if (dataNodeSet.size() > 1) {
              return routeToMultiNode(schema, isSelect, isSelect, ast, rrs, dataNodeSet, sql);
            } else {
              rrs.setCacheAble(true);
              return RouterUtil.routeToSingleNode(rrs, dataNodeSet.iterator().next(), sql);
            }
          }
        }

        // try by primary key if found in cache
        Set<ColumnRoutePair> primaryKeyPairs = allColConds.get(tc.getPrimaryKey());
        if (primaryKeyPairs != null) {
          if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("try to find cache by primary key ");
          }
          cache = false;
          Set<String> dataNodes = new HashSet<String>(primaryKeyPairs.size());
          boolean allFound = true;
          String tableKey = schema.getName() + '_' + tc.getName();
          for (ColumnRoutePair pair : primaryKeyPairs) {
            String cacheKey = pair.colValue;
            String dataNode = (String) cachePool.get(tableKey, cacheKey);
            if (dataNode == null) {
              allFound = false;
              break;
            } else {
              dataNodes.add(dataNode);
            }
          }
          if (allFound) {
            return routeToMultiNode(schema, isSelect, isSelect, ast, rrs, dataNodes, sql);
          }
          // need cache primary key ->datanode relation
          if (isSelect && tc.getPrimaryKey() != null) {
            rrs.setPrimaryKey(tableKey + '.' + tc.getPrimaryKey());
          }
        }
      }
      return routeToMultiNode(schema, isSelect, cache, ast, rrs, tc.getDataNodes(), sql);
    }
    // match table with where condtion of partion colum values
    Set<String> dataNodeSet = RouterUtil.ruleCalculate(tc, ruleCol2Val);
    if (dataNodeSet.size() == 1) {
      rrs.setCacheAble(isSelect);
      return RouterUtil.routeToSingleNode(rrs, dataNodeSet.iterator().next(), sql);
    } else {
      return routeToMultiNode(schema, isSelect, isSelect, ast, rrs, dataNodeSet, sql);
    }
  }