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);
}
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);
}
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);
}
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);
}
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;
}
Aggregations