use of com.actiontech.dble.config.model.SchemaConfig 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.config.model.SchemaConfig 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.config.model.SchemaConfig in project dble by actiontech.
the class DruidReplaceParser method parserChildTable.
private void parserChildTable(SchemaInfo schemaInfo, final RouteResultset rrs, MySqlReplaceStatement replace, final ServerConnection sc) throws SQLNonTransientException {
final SchemaConfig schema = schemaInfo.getSchemaConfig();
String tableName = schemaInfo.getTable();
final TableConfig tc = schema.getTables().get(tableName);
// check if the childtable replace with the multi
if (isMultiReplace(replace)) {
String msg = "ChildTable multi insert not provided";
LOGGER.info(msg);
throw new SQLNonTransientException(msg);
}
// find the value of child table join key
String joinKey = tc.getJoinKey();
int joinKeyIndex = getJoinKeyIndex(schemaInfo, replace, joinKey);
final String joinKeyVal = replace.getValuesList().get(0).getValues().get(joinKeyIndex).toString();
String realVal = StringUtil.removeApostrophe(joinKeyVal);
final String sql = RouterUtil.removeSchema(replace.toString(), schemaInfo.getSchema());
rrs.setStatement(sql);
// try to route by ER parent partition key
RouteResultset theRrs = routeByERParentKey(rrs, tc, realVal);
if (theRrs != null) {
rrs.setFinishedRoute(true);
} else {
rrs.setFinishedExecute(true);
DbleServer.getInstance().getComplexQueryExecutor().execute(new Runnable() {
// get child result will be blocked, so use ComplexQueryExecutor
@Override
public void run() {
// route by sql query root parent's data node
String findRootTBSql = tc.getLocateRTableKeySql().toLowerCase() + joinKeyVal;
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("to find root parent's node sql :" + findRootTBSql);
}
FetchStoreNodeOfChildTableHandler fetchHandler = new FetchStoreNodeOfChildTableHandler(findRootTBSql, sc.getSession2());
String dn = fetchHandler.execute(schema.getName(), tc.getRootParent().getDataNodes());
if (dn == null) {
sc.writeErrMessage(ErrorCode.ER_UNKNOWN_ERROR, "can't find (root) parent sharding node for sql:" + sql);
return;
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("found partition node for child table to insert " + dn + " sql :" + sql);
}
RouterUtil.routeToSingleNode(rrs, dn);
sc.getSession2().execute(rrs);
}
});
}
}
use of com.actiontech.dble.config.model.SchemaConfig in project dble by actiontech.
the class DruidSelectParser method executeComplexSQL.
private SchemaConfig executeComplexSQL(String schemaName, SchemaConfig schema, RouteResultset rrs, SQLSelectStatement selectStmt, ServerConnection sc) throws SQLException {
StringPtr sqlSchema = new StringPtr(null);
if (!SchemaUtil.isNoSharding(sc, selectStmt.getSelect().getQuery(), selectStmt, schemaName, sqlSchema)) {
rrs.setSqlStatement(selectStmt);
rrs.setNeedOptimizer(true);
return schema;
} else {
String realSchema = sqlSchema.get() == null ? schemaName : sqlSchema.get();
SchemaConfig schemaConfig = DbleServer.getInstance().getConfig().getSchemas().get(realSchema);
rrs.setStatement(RouterUtil.removeSchema(rrs.getStatement(), realSchema));
RouterUtil.routeToSingleNode(rrs, schemaConfig.getDataNode());
return schemaConfig;
}
}
use of com.actiontech.dble.config.model.SchemaConfig in project dble by actiontech.
the class DruidSingleUnitSelectParser method visitorParse.
@Override
public SchemaConfig visitorParse(SchemaConfig schema, RouteResultset rrs, SQLStatement stmt, ServerSchemaStatVisitor visitor, ServerConnection sc) throws SQLException {
SQLSelectStatement selectStmt = (SQLSelectStatement) stmt;
SQLSelectQuery sqlSelectQuery = selectStmt.getSelect().getQuery();
String schemaName = schema == null ? null : schema.getName();
if (sqlSelectQuery instanceof MySqlSelectQueryBlock) {
MySqlSelectQueryBlock mysqlSelectQuery = (MySqlSelectQueryBlock) selectStmt.getSelect().getQuery();
SQLTableSource mysqlFrom = mysqlSelectQuery.getFrom();
if (mysqlFrom == null) {
RouterUtil.routeNoNameTableToSingleNode(rrs, schema);
return schema;
}
if (mysqlFrom instanceof SQLSubqueryTableSource || mysqlFrom instanceof SQLJoinTableSource || mysqlFrom instanceof SQLUnionQueryTableSource) {
StringPtr sqlSchema = new StringPtr(null);
if (SchemaUtil.isNoSharding(sc, selectStmt.getSelect().getQuery(), selectStmt, schemaName, sqlSchema)) {
String realSchema = sqlSchema.get() == null ? schemaName : sqlSchema.get();
SchemaConfig schemaConfig = DbleServer.getInstance().getConfig().getSchemas().get(realSchema);
rrs.setStatement(RouterUtil.removeSchema(rrs.getStatement(), realSchema));
RouterUtil.routeToSingleNode(rrs, schemaConfig.getDataNode());
return schemaConfig;
} else {
super.visitorParse(schema, rrs, stmt, visitor, sc);
return schema;
}
}
SQLExprTableSource fromSource = (SQLExprTableSource) mysqlFrom;
SchemaInfo schemaInfo = SchemaUtil.getSchemaInfo(sc.getUser(), schemaName, fromSource);
if (schemaInfo.getSchemaConfig() == null) {
String msg = "No Supported, sql:" + stmt;
throw new SQLNonTransientException(msg);
}
if (!ServerPrivileges.checkPrivilege(sc, schemaInfo.getSchema(), schemaInfo.getTable(), CheckType.SELECT)) {
String msg = "The statement DML privilege check is not passed, sql:" + stmt;
throw new SQLNonTransientException(msg);
}
rrs.setStatement(RouterUtil.removeSchema(rrs.getStatement(), schemaInfo.getSchema()));
schema = schemaInfo.getSchemaConfig();
super.visitorParse(schema, rrs, stmt, visitor, sc);
if (visitor.isHasSubQuery()) {
this.getCtx().getRouteCalculateUnits().clear();
}
// change canRunInReadDB
if ((mysqlSelectQuery.isForUpdate() || mysqlSelectQuery.isLockInShareMode()) && !sc.isAutocommit()) {
rrs.setCanRunInReadDB(false);
}
} else if (sqlSelectQuery instanceof MySqlUnionQuery) {
StringPtr sqlSchema = new StringPtr(null);
if (SchemaUtil.isNoSharding(sc, selectStmt.getSelect().getQuery(), selectStmt, schemaName, sqlSchema)) {
String realSchema = sqlSchema.get() == null ? schemaName : sqlSchema.get();
SchemaConfig schemaConfig = DbleServer.getInstance().getConfig().getSchemas().get(realSchema);
rrs.setStatement(RouterUtil.removeSchema(rrs.getStatement(), realSchema));
RouterUtil.routeToSingleNode(rrs, schemaConfig.getDataNode());
return schemaConfig;
} else {
super.visitorParse(schema, rrs, stmt, visitor, sc);
}
}
return schema;
}
Aggregations