package io.mycat.route.parser.druid.impl;
import io.mycat.route.RouteResultset;
import io.mycat.route.util.RouterUtil;
import io.mycat.server.config.node.SchemaConfig;
import io.mycat.server.config.node.TableConfig;
import io.mycat.util.StringUtil;
import java.sql.SQLNonTransientException;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement;
public class DruidUpdateParser extends DefaultDruidParser {
@Override
public void statementParse(SchemaConfig schema, RouteResultset rrs, SQLStatement stmt) throws SQLNonTransientException {
if(ctx.getTables() != null && ctx.getTables().size() > 1 && !schema.isNoSharding()) {
String msg = "multi table related update not supported,tables:" + ctx.getTables();
LOGGER.warn(msg);
throw new SQLNonTransientException(msg);
}
MySqlUpdateStatement update = (MySqlUpdateStatement)stmt;
String tableName = StringUtil.removeBackquote(update.getTableName().getSimpleName().toUpperCase());
List<SQLUpdateSetItem> updateSetItem = update.getItems();
TableConfig tc = schema.getTables().get(tableName);
if (tc == null) {
return;
}
if(RouterUtil.isNoSharding(schema,tableName)) {//整个schema都不分库或者该表不拆分
RouterUtil.routeForTableMeta(rrs, schema, tableName, rrs.getStatement());
rrs.setFinishedRoute(true);
return;
}
String partitionColumn = tc.getPartitionColumn();
String joinKey = tc.getJoinKey();
if(tc.isGlobalTable() || (partitionColumn == null && joinKey == null)) {
//修改全局表 update 受影响的行数
RouterUtil.routeToMultiNode(false, rrs, tc.getDataNodes(), rrs.getStatement(),tc.isGlobalTable());
rrs.setFinishedRoute(true);
return;
}
if(updateSetItem != null && updateSetItem.size() > 0) {
boolean hasParent = (schema.getTables().get(tableName).getParentTC() != null);
for(SQLUpdateSetItem item : updateSetItem) {
String column = StringUtil.removeBackquote(item.getColumn().toString().toUpperCase());
if(partitionColumn != null && partitionColumn.equals(column)) {
String msg = "partion key can't be updated " + tableName + "->" + partitionColumn;
LOGGER.warn(msg);
throw new SQLNonTransientException(msg);
}
if(hasParent) {
if(column.equals(joinKey)) {
String msg = "parent relation column can't be updated " + tableName + "->" + joinKey;
LOGGER.warn(msg);
throw new SQLNonTransientException(msg);
}
rrs.setCacheAble(true);
}
}
}
// if(ctx.getTablesAndConditions().size() > 0) {
// Map<String, Set<ColumnRoutePair>> map = ctx.getTablesAndConditions().get(tableName);
// if(map != null) {
// for(Map.Entry<String, Set<ColumnRoutePair>> entry : map.entrySet()) {
// String column = entry.getKey();
// Set<ColumnRoutePair> value = entry.getValue();
// if(column.toUpperCase().equals(anObject))
// }
// }
//
// }
// System.out.println();
if(schema.getTables().get(tableName).isGlobalTable() && ctx.getRouteCalculateUnit().getTablesAndConditions().size() > 1) {
throw new SQLNonTransientException("global table not supported multi table related update "+ tableName);
}
}
}