Search in sources :

Example 1 with AbstractPartitionAlgorithm

use of com.actiontech.dble.route.function.AbstractPartitionAlgorithm in project dble by actiontech.

the class DruidInsertParser method parserBatchInsert.

/**
 * insert into .... select .... or insert into table() values (),(),....
 *
 * @param schemaInfo SchemaInfo
 * @param rrs RouteResultset
 * @param partitionColumn partitionColumn
 * @param insertStmt insertStmt
 * @throws SQLNonTransientException if the column size of values is not correct
 */
private void parserBatchInsert(SchemaInfo schemaInfo, RouteResultset rrs, String partitionColumn, MySqlInsertStatement insertStmt) throws SQLNonTransientException {
    // insert into table() values (),(),....
    SchemaConfig schema = schemaInfo.getSchemaConfig();
    String tableName = schemaInfo.getTable();
    // the size of columns
    int columnNum = getTableColumns(schemaInfo, insertStmt.getColumns());
    int shardingColIndex = tryGetShardingColIndex(schemaInfo, insertStmt, partitionColumn);
    List<ValuesClause> valueClauseList = insertStmt.getValuesList();
    Map<Integer, List<ValuesClause>> nodeValuesMap = new HashMap<>();
    TableConfig tableConfig = schema.getTables().get(tableName);
    AbstractPartitionAlgorithm algorithm = tableConfig.getRule().getRuleAlgorithm();
    for (ValuesClause valueClause : valueClauseList) {
        if (valueClause.getValues().size() != columnNum) {
            String msg = "bad insert sql columnSize != valueSize:" + columnNum + " != " + valueClause.getValues().size() + "values:" + valueClause;
            LOGGER.info(msg);
            throw new SQLNonTransientException(msg);
        }
        SQLExpr expr = valueClause.getValues().get(shardingColIndex);
        String shardingValue = shardingValueToSting(expr);
        Integer nodeIndex = algorithm.calculate(shardingValue);
        // null means can't find any valid index
        if (nodeIndex == null) {
            String msg = "can't find any valid datanode :" + tableName + " -> " + partitionColumn + " -> " + shardingValue;
            LOGGER.info(msg);
            throw new SQLNonTransientException(msg);
        }
        if (nodeValuesMap.get(nodeIndex) == null) {
            nodeValuesMap.put(nodeIndex, new ArrayList<ValuesClause>());
        }
        nodeValuesMap.get(nodeIndex).add(valueClause);
    }
    RouteResultsetNode[] nodes = new RouteResultsetNode[nodeValuesMap.size()];
    int count = 0;
    for (Map.Entry<Integer, List<ValuesClause>> node : nodeValuesMap.entrySet()) {
        Integer nodeIndex = node.getKey();
        List<ValuesClause> valuesList = node.getValue();
        insertStmt.setValuesList(valuesList);
        nodes[count] = new RouteResultsetNode(tableConfig.getDataNodes().get(nodeIndex), rrs.getSqlType(), RouterUtil.removeSchema(insertStmt.toString(), schemaInfo.getSchema()));
        count++;
    }
    rrs.setNodes(nodes);
    rrs.setFinishedRoute(true);
}
Also used : AbstractPartitionAlgorithm(com.actiontech.dble.route.function.AbstractPartitionAlgorithm) SchemaConfig(com.actiontech.dble.config.model.SchemaConfig) SQLExpr(com.alibaba.druid.sql.ast.SQLExpr) SQLNonTransientException(java.sql.SQLNonTransientException) RouteResultsetNode(com.actiontech.dble.route.RouteResultsetNode) TableConfig(com.actiontech.dble.config.model.TableConfig) ValuesClause(com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause)

Example 2 with AbstractPartitionAlgorithm

use of com.actiontech.dble.route.function.AbstractPartitionAlgorithm in project dble by actiontech.

the class DruidInsertParser method parserSingleInsert.

/**
 * @param schemaInfo SchemaInfo
 * @param rrs RouteResultset
 * @param partitionColumn partitionColumn
 * @param insertStmt insertStmt
 * @throws SQLNonTransientException if not find an valid data node
 */
private void parserSingleInsert(SchemaInfo schemaInfo, RouteResultset rrs, String partitionColumn, MySqlInsertStatement insertStmt) throws SQLNonTransientException {
    int shardingColIndex = tryGetShardingColIndex(schemaInfo, insertStmt, partitionColumn);
    SQLExpr valueExpr = insertStmt.getValues().getValues().get(shardingColIndex);
    String shardingValue = shardingValueToSting(valueExpr);
    TableConfig tableConfig = schemaInfo.getSchemaConfig().getTables().get(schemaInfo.getTable());
    AbstractPartitionAlgorithm algorithm = tableConfig.getRule().getRuleAlgorithm();
    Integer nodeIndex = algorithm.calculate(shardingValue);
    if (nodeIndex == null || nodeIndex >= tableConfig.getDataNodes().size()) {
        String msg = "can't find any valid data node :" + schemaInfo.getTable() + " -> " + partitionColumn + " -> " + shardingValue;
        LOGGER.info(msg);
        throw new SQLNonTransientException(msg);
    }
    RouteResultsetNode[] nodes = new RouteResultsetNode[1];
    nodes[0] = new RouteResultsetNode(tableConfig.getDataNodes().get(nodeIndex), rrs.getSqlType(), RouterUtil.removeSchema(insertStmt.toString(), schemaInfo.getSchema()));
    // INSERT INTO TABLEName (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1;
    if (insertStmt.getDuplicateKeyUpdate() != null) {
        List<SQLExpr> updateList = insertStmt.getDuplicateKeyUpdate();
        for (SQLExpr expr : updateList) {
            SQLBinaryOpExpr opExpr = (SQLBinaryOpExpr) expr;
            String column = StringUtil.removeBackQuote(opExpr.getLeft().toString().toUpperCase());
            if (column.equals(partitionColumn)) {
                String msg = "Sharding column can't be updated: " + schemaInfo.getTable() + " -> " + partitionColumn;
                LOGGER.info(msg);
                throw new SQLNonTransientException(msg);
            }
        }
    }
    rrs.setNodes(nodes);
    rrs.setFinishedRoute(true);
}
Also used : AbstractPartitionAlgorithm(com.actiontech.dble.route.function.AbstractPartitionAlgorithm) SQLNonTransientException(java.sql.SQLNonTransientException) RouteResultsetNode(com.actiontech.dble.route.RouteResultsetNode) TableConfig(com.actiontech.dble.config.model.TableConfig) SQLBinaryOpExpr(com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr) SQLExpr(com.alibaba.druid.sql.ast.SQLExpr)

Example 3 with AbstractPartitionAlgorithm

use of com.actiontech.dble.route.function.AbstractPartitionAlgorithm in project dble by actiontech.

the class DruidReplaceParser method parserBatchInsert.

/**
 * insert into .... select .... OR insert into table() values (),(),....
 *
 * @param schemaInfo SchemaInfo
 * @param rrs RouteResultset
 * @param partitionColumn partitionColumn
 * @param replace MySqlReplaceStatement
 * @throws SQLNonTransientException  if the column size of values is not correct
 */
private void parserBatchInsert(SchemaInfo schemaInfo, RouteResultset rrs, String partitionColumn, MySqlReplaceStatement replace) throws SQLNonTransientException {
    // insert into table() values (),(),....
    SchemaConfig schema = schemaInfo.getSchemaConfig();
    String tableName = schemaInfo.getTable();
    // column number
    int columnNum = getTableColumns(schemaInfo, replace.getColumns());
    int shardingColIndex = tryGetShardingColIndex(schemaInfo, replace, partitionColumn);
    List<SQLInsertStatement.ValuesClause> valueClauseList = replace.getValuesList();
    Map<Integer, List<SQLInsertStatement.ValuesClause>> nodeValuesMap = new HashMap<>();
    TableConfig tableConfig = schema.getTables().get(tableName);
    AbstractPartitionAlgorithm algorithm = tableConfig.getRule().getRuleAlgorithm();
    for (SQLInsertStatement.ValuesClause valueClause : valueClauseList) {
        if (valueClause.getValues().size() != columnNum) {
            String msg = "bad insert sql columnSize != valueSize:" + columnNum + " != " + valueClause.getValues().size() + "values:" + valueClause;
            LOGGER.info(msg);
            throw new SQLNonTransientException(msg);
        }
        SQLExpr expr = valueClause.getValues().get(shardingColIndex);
        String shardingValue = shardingValueToSting(expr);
        Integer nodeIndex = algorithm.calculate(shardingValue);
        // no part find for this record
        if (nodeIndex == null) {
            String msg = "can't find any valid datanode :" + tableName + " -> " + partitionColumn + " -> " + shardingValue;
            LOGGER.info(msg);
            throw new SQLNonTransientException(msg);
        }
        if (nodeValuesMap.get(nodeIndex) == null) {
            nodeValuesMap.put(nodeIndex, new ArrayList<SQLInsertStatement.ValuesClause>());
        }
        nodeValuesMap.get(nodeIndex).add(valueClause);
    }
    RouteResultsetNode[] nodes = new RouteResultsetNode[nodeValuesMap.size()];
    int count = 0;
    for (Map.Entry<Integer, List<SQLInsertStatement.ValuesClause>> node : nodeValuesMap.entrySet()) {
        Integer nodeIndex = node.getKey();
        List<SQLInsertStatement.ValuesClause> valuesList = node.getValue();
        ReplaceTemp temp = new ReplaceTemp(replace);
        temp.setValuesList(valuesList);
        nodes[count] = new RouteResultsetNode(tableConfig.getDataNodes().get(nodeIndex), rrs.getSqlType(), RouterUtil.removeSchema(temp.toString(), schemaInfo.getSchema()));
        count++;
    }
    rrs.setNodes(nodes);
    rrs.setFinishedRoute(true);
}
Also used : AbstractPartitionAlgorithm(com.actiontech.dble.route.function.AbstractPartitionAlgorithm) SchemaConfig(com.actiontech.dble.config.model.SchemaConfig) ReplaceTemp(com.actiontech.dble.route.parser.druid.ReplaceTemp) SQLExpr(com.alibaba.druid.sql.ast.SQLExpr) SQLNonTransientException(java.sql.SQLNonTransientException) RouteResultsetNode(com.actiontech.dble.route.RouteResultsetNode) SQLInsertStatement(com.alibaba.druid.sql.ast.statement.SQLInsertStatement) TableConfig(com.actiontech.dble.config.model.TableConfig)

Example 4 with AbstractPartitionAlgorithm

use of com.actiontech.dble.route.function.AbstractPartitionAlgorithm in project dble by actiontech.

the class DruidReplaceParser method parserSingleInsert.

/**
 * insert single record
 *
 * @param schemaInfo SchemaInfo
 * @param rrs RouteResultset
 * @param partitionColumn partitionColumn
 * @param replaceStatement MySqlReplaceStatement
 * @throws SQLNonTransientException if not find a valid data node
 */
private void parserSingleInsert(SchemaInfo schemaInfo, RouteResultset rrs, String partitionColumn, MySqlReplaceStatement replaceStatement) throws SQLNonTransientException {
    int shardingColIndex = tryGetShardingColIndex(schemaInfo, replaceStatement, partitionColumn);
    SQLExpr valueExpr = replaceStatement.getValuesList().get(0).getValues().get(shardingColIndex);
    String shardingValue = shardingValueToSting(valueExpr);
    TableConfig tableConfig = schemaInfo.getSchemaConfig().getTables().get(schemaInfo.getTable());
    AbstractPartitionAlgorithm algorithm = tableConfig.getRule().getRuleAlgorithm();
    Integer nodeIndex = algorithm.calculate(shardingValue);
    if (nodeIndex == null) {
        String msg = "can't find any valid data node :" + schemaInfo.getTable() + " -> " + partitionColumn + " -> " + shardingValue;
        LOGGER.info(msg);
        throw new SQLNonTransientException(msg);
    }
    RouteResultsetNode[] nodes = new RouteResultsetNode[1];
    nodes[0] = new RouteResultsetNode(tableConfig.getDataNodes().get(nodeIndex), rrs.getSqlType(), RouterUtil.removeSchema(replaceStatement.toString(), schemaInfo.getSchema()));
    rrs.setNodes(nodes);
    rrs.setFinishedRoute(true);
}
Also used : AbstractPartitionAlgorithm(com.actiontech.dble.route.function.AbstractPartitionAlgorithm) SQLNonTransientException(java.sql.SQLNonTransientException) RouteResultsetNode(com.actiontech.dble.route.RouteResultsetNode) TableConfig(com.actiontech.dble.config.model.TableConfig) SQLExpr(com.alibaba.druid.sql.ast.SQLExpr)

Example 5 with AbstractPartitionAlgorithm

use of com.actiontech.dble.route.function.AbstractPartitionAlgorithm in project dble by actiontech.

the class RouterUtil method ruleCalculate.

public static Set<String> ruleCalculate(TableConfig tc, Set<ColumnRoutePair> colRoutePairSet) {
    Set<String> routeNodeSet = new LinkedHashSet<>();
    String col = tc.getRule().getColumn();
    RuleConfig rule = tc.getRule();
    AbstractPartitionAlgorithm algorithm = rule.getRuleAlgorithm();
    for (ColumnRoutePair colPair : colRoutePairSet) {
        if (colPair.colValue != null) {
            Integer nodeIndex = algorithm.calculate(colPair.colValue);
            if (nodeIndex == null) {
                throw new IllegalArgumentException("can't find datanode for sharding column:" + col + " val:" + colPair.colValue);
            } else {
                String dataNode = tc.getDataNodes().get(nodeIndex);
                routeNodeSet.add(dataNode);
                colPair.setNodeId(nodeIndex);
            }
        } else if (colPair.rangeValue != null) {
            Integer[] nodeRange = algorithm.calculateRange(String.valueOf(colPair.rangeValue.getBeginValue()), String.valueOf(colPair.rangeValue.getEndValue()));
            if (nodeRange != null) {
                /**
                 * not sure  colPair's nodeid has other effect
                 */
                if (nodeRange.length == 0) {
                    routeNodeSet.addAll(tc.getDataNodes());
                } else {
                    ArrayList<String> dataNodes = tc.getDataNodes();
                    String dataNode = null;
                    for (Integer nodeId : nodeRange) {
                        dataNode = dataNodes.get(nodeId);
                        routeNodeSet.add(dataNode);
                    }
                }
            }
        }
    }
    return routeNodeSet;
}
Also used : AbstractPartitionAlgorithm(com.actiontech.dble.route.function.AbstractPartitionAlgorithm) ColumnRoutePair(com.actiontech.dble.sqlengine.mpp.ColumnRoutePair) RuleConfig(com.actiontech.dble.config.model.rule.RuleConfig)

Aggregations

AbstractPartitionAlgorithm (com.actiontech.dble.route.function.AbstractPartitionAlgorithm)7 SQLNonTransientException (java.sql.SQLNonTransientException)5 TableConfig (com.actiontech.dble.config.model.TableConfig)4 RouteResultsetNode (com.actiontech.dble.route.RouteResultsetNode)4 SQLExpr (com.alibaba.druid.sql.ast.SQLExpr)4 SchemaConfig (com.actiontech.dble.config.model.SchemaConfig)2 ColumnRoutePair (com.actiontech.dble.sqlengine.mpp.ColumnRoutePair)2 RuleConfig (com.actiontech.dble.config.model.rule.RuleConfig)1 ConfigException (com.actiontech.dble.config.util.ConfigException)1 ReplaceTemp (com.actiontech.dble.route.parser.druid.ReplaceTemp)1 SQLBinaryOpExpr (com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr)1 SQLInsertStatement (com.alibaba.druid.sql.ast.statement.SQLInsertStatement)1 ValuesClause (com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause)1