use of io.mycat.util.Pair in project Mycat2 by MyCATApache.
the class CreateViewSQLHandler method onExecute.
@Override
protected Future<Void> onExecute(SQLRequest<SQLCreateViewStatement> request, MycatDataContext dataContext, Response response) {
LockService lockService = MetaClusterCurrent.wrapper(LockService.class);
SQLCreateViewStatement ast = request.getAst();
resolveSQLExprTableSource(ast.getTableSource(), dataContext);
return lockService.lock(DDL_LOCK, new Supplier<Future<Void>>() {
@Override
public Future<Void> get() {
String schemaName = Optional.ofNullable(ast.getSchema()).orElse(dataContext.getDefaultSchema());
schemaName = SQLUtils.normalize(schemaName);
String viewName = SQLUtils.normalize(ast.getName().getSimpleName());
SQLSelect subQuery = ast.getSubQuery();
SQLSelectStatement sqlSelectStatement = new SQLSelectStatement();
sqlSelectStatement.setSelect(subQuery);
List<String> aliasList = Optional.ofNullable(ast.getColumns()).orElse(Collections.emptyList()).stream().map(i -> SQLUtils.normalize(i.toString())).collect(Collectors.toList());
HackRouter hackRouter = new HackRouter(sqlSelectStatement, dataContext);
boolean distSql = !hackRouter.analyse();
try (MycatRouterConfigOps ops = ConfigUpdater.getOps()) {
if (!distSql) {
Pair<String, String> plan = hackRouter.getPlan();
JdbcConnectionManager jdbcConnectionManager = MetaClusterCurrent.wrapper(JdbcConnectionManager.class);
try (DefaultConnection connection = jdbcConnectionManager.getConnection(plan.getKey())) {
Connection rawConnection = connection.getRawConnection();
Statement statement = rawConnection.createStatement();
statement.setMaxRows(0);
MycatRowMetaData metaData = connection.executeQuery(plan.getValue()).getMetaData();
if (!aliasList.isEmpty()) {
metaData = RenameMycatRowMetaData.of(metaData, aliasList);
}
String createTableSql = PrototypeService.generateSql(schemaName, viewName, metaData.metaData());
ops.putNormalTable(schemaName, viewName, (MySqlCreateTableStatement) SQLUtils.parseSingleMysqlStatement(createTableSql));
statement.close();
try {
SQLSelectStatement phySQLSelectStatement = (SQLSelectStatement) SQLUtils.parseSingleMysqlStatement(plan.getValue());
ast.setSubQuery(phySQLSelectStatement.getSelect());
// 建立物理视图
JdbcUtils.execute(rawConnection, ast.toString());
} catch (Throwable throwable) {
LOGGER.error("build phy view fail", throwable);
}
}
} else {
ops.addView(schemaName, viewName, ast.toString());
}
ops.commit();
return response.sendOk();
} catch (Throwable throwable) {
return Future.failedFuture(throwable);
}
}
});
}
use of io.mycat.util.Pair in project Mycat2 by MyCATApache.
the class HackRouter method analyse.
public boolean analyse() {
Set<Pair<String, String>> tableNames = new HashSet<>();
Set<String> methods = new HashSet<>();
AtomicBoolean hasVar = new AtomicBoolean(false);
selectStatement.accept(new MySqlASTVisitorAdapter() {
@Override
public boolean visit(SQLExprTableSource x) {
String tableName = x.getTableName();
if (tableName != null) {
String schema = Optional.ofNullable(x.getSchema()).orElse(defaultSchema);
if (schema == null) {
throw new MycatException("please use schema;");
}
tableNames.add(Pair.of(SQLUtils.normalize(schema), SQLUtils.normalize(tableName)));
}
return super.visit(x);
}
@Override
public boolean visit(SQLMethodInvokeExpr x) {
methods.add(x.getMethodName());
return super.visit(x);
}
@Override
public boolean visit(SQLVariantRefExpr x) {
if (!"?".equals(x.getName())) {
hasVar.set(true);
}
return super.visit(x);
}
});
this.metadataManager = MetaClusterCurrent.wrapper(MetadataManager.class);
if (PUSH_DOWN_SELECT_DUAL && tableNames.isEmpty() && !hasVar.get()) {
if (!methods.isEmpty() && methods.stream().noneMatch(name -> SQLRBORewriter.Information_Functions.containsKey(SQLUtils.normalize(name), false))) {
targetMap = NameMap.immutableCopyOf(Collections.emptyMap());
targetName = MetadataManager.getPrototype();
return true;
}
}
res = metadataManager.checkVaildNormalRoute(tableNames);
if (res.isPresent()) {
Distribution distribution = res.get();
ImmutableMap.Builder<String, Partition> builder = ImmutableMap.builder();
builder.putAll(distribution.getGlobalTables().stream().collect(Collectors.toMap(k -> k.getUniqueName(), v -> v.getDataNode())));
Map<String, Partition> normalMap = distribution.getNormalTables().stream().collect(Collectors.toMap(k -> k.getUniqueName(), v -> v.getDataNode()));
builder.putAll(normalMap);
targetMap = NameMap.immutableCopyOf(builder.build());
switch(distribution.type()) {
case BROADCAST:
List<Partition> globalDataNode = distribution.getGlobalTables().get(0).getGlobalDataNode();
int i = ThreadLocalRandom.current().nextInt(0, globalDataNode.size());
targetName = globalDataNode.get(i).getTargetName();
return true;
case SHARDING:
return false;
case PHY:
{
targetName = normalMap.values().iterator().next().getTargetName();
return true;
}
}
} else {
return false;
}
return false;
}
use of io.mycat.util.Pair in project Mycat2 by MyCATApache.
the class UpdateSQLHandler method updateHandler.
@SneakyThrows
public static Future<Void> updateHandler(SQLStatement sqlStatement, MycatDataContext dataContext, SQLTableSource tableSourceArg, Response receiver) {
boolean insert = sqlStatement instanceof SQLInsertStatement;
if (tableSourceArg instanceof SQLExprTableSource) {
SQLExprTableSource tableSource = (SQLExprTableSource) tableSourceArg;
String schemaName = Optional.ofNullable(tableSource.getSchema() == null ? dataContext.getDefaultSchema() : tableSource.getSchema()).map(i -> SQLUtils.normalize(i)).orElse(null);
String tableName = SQLUtils.normalize(tableSource.getTableName());
if (schemaName == null) {
return receiver.sendError("unknown schema", MySQLErrorCode.ER_UNKNOWN_ERROR);
}
tableSource.setSchema(schemaName);
SchemaHandler schemaHandler;
MetadataManager metadataManager = MetaClusterCurrent.wrapper(MetadataManager.class);
Optional<NameMap<SchemaHandler>> handlerMapOptional = Optional.ofNullable(metadataManager.getSchemaMap());
Optional<String> targetNameOptional = Optional.ofNullable(metadataManager.getPrototype());
if (!handlerMapOptional.isPresent()) {
if (targetNameOptional.isPresent()) {
if (insert) {
DrdsSqlWithParams drdsSqlWithParams = MycatPreparedStatementUtil.outputToParameterizedProxySql((MySqlInsertStatement) sqlStatement);
return receiver.proxyInsert(Collections.singletonList(targetNameOptional.get()), drdsSqlWithParams.getParameterizedSQL(), drdsSqlWithParams.getParams());
} else {
DrdsSqlWithParams drdsSqlWithParams = DrdsRunnerHelper.preParse(sqlStatement, dataContext.getDefaultSchema());
return receiver.proxyUpdate(Collections.singletonList(targetNameOptional.get()), drdsSqlWithParams.getParameterizedSQL(), drdsSqlWithParams.getParams());
}
} else {
return receiver.sendError(new MycatException("Unable to route:" + sqlStatement));
}
} else {
NameMap<SchemaHandler> handlerMap = handlerMapOptional.get();
schemaHandler = Optional.ofNullable(handlerMap.get(schemaName)).orElseGet(() -> {
if (dataContext.getDefaultSchema() == null) {
// 可能schemaName有值,但是值名不是配置的名字
throw new MycatException("unknown schema:" + schemaName);
}
return handlerMap.get(dataContext.getDefaultSchema());
});
if (schemaHandler == null) {
return receiver.sendError(new MycatException("Unable to route:" + sqlStatement));
}
}
String defaultTargetName = schemaHandler.defaultTargetName();
NameMap<TableHandler> tableMap = schemaHandler.logicTables();
TableHandler tableHandler = tableMap.get(tableName);
// /////////////////////////////common///////////////////////////////
if (tableHandler == null) {
if (insert) {
DrdsSqlWithParams drdsSqlWithParams = MycatPreparedStatementUtil.outputToParameterizedProxySql((MySqlInsertStatement) sqlStatement);
return receiver.proxyInsert(Collections.singletonList(Objects.requireNonNull(defaultTargetName, "can not route :" + drdsSqlWithParams)), drdsSqlWithParams.getParameterizedSQL(), drdsSqlWithParams.getParams());
} else {
DrdsSqlWithParams drdsSqlWithParams = DrdsRunnerHelper.preParse(sqlStatement, null);
return receiver.proxyUpdate(Collections.singletonList(Objects.requireNonNull(defaultTargetName, "can not route :" + drdsSqlWithParams)), drdsSqlWithParams.getParameterizedSQL(), drdsSqlWithParams.getParams());
}
}
switch(tableHandler.getType()) {
case NORMAL:
DrdsSqlWithParams drdsSqlWithParams;
if (insert) {
drdsSqlWithParams = MycatPreparedStatementUtil.outputToParameterizedProxySql((MySqlInsertStatement) sqlStatement);
} else {
drdsSqlWithParams = DrdsRunnerHelper.preParse(sqlStatement, dataContext.getDefaultSchema());
}
HackRouter hackRouter = new HackRouter(drdsSqlWithParams.getParameterizedStatement(), dataContext);
if (hackRouter.analyse()) {
Pair<String, String> plan = hackRouter.getPlan();
if (insert) {
return receiver.proxyInsert(Collections.singletonList(plan.getKey()), plan.getValue(), drdsSqlWithParams.getParams());
} else {
return receiver.proxyUpdate(Collections.singletonList(plan.getKey()), plan.getValue(), drdsSqlWithParams.getParams());
}
}
break;
default:
break;
}
DrdsSqlWithParams drdsSqlWithParams = DrdsRunnerHelper.preParse(sqlStatement, dataContext.getDefaultSchema());
return executeUpdate(drdsSqlWithParams, dataContext, receiver, schemaName);
}
DrdsSqlWithParams drdsSqlWithParams = insert ? MycatPreparedStatementUtil.outputToParameterizedProxySql((MySqlInsertStatement) sqlStatement) : DrdsRunnerHelper.preParse(sqlStatement, dataContext.getDefaultSchema());
HackRouter hackRouter = new HackRouter(drdsSqlWithParams.getParameterizedStatement(), dataContext);
if (hackRouter.analyse()) {
Pair<String, String> plan = hackRouter.getPlan();
if (insert) {
return receiver.proxyInsert(Collections.singletonList(plan.getKey()), plan.getValue(), drdsSqlWithParams.getParams());
} else {
return receiver.proxyUpdate(Collections.singletonList(plan.getKey()), plan.getValue(), drdsSqlWithParams.getParams());
}
}
return receiver.sendError(new MycatException("can not route " + sqlStatement));
}
Aggregations