use of com.alibaba.druid.sql.ast.SQLStatement in project Mycat-Server by MyCATApache.
the class GlobalTableUtil method handleDDLSQL.
/*
* Name: 'ALTER TABLE'
Description:
Syntax:
ALTER [IGNORE] TABLE tbl_name
[alter_specification [, alter_specification] ...]
[partition_options]
如果 DDL 修改了表结构,需要重新获得表的列list
*/
private static String handleDDLSQL(String sql) {
MySqlStatementParser parser = new MySqlStatementParser(sql);
SQLStatement statement = parser.parseStatement();
// druid高版本去掉了 MySqlAlterTableStatement,在其父类 SQLAlterTableStatement 直接支持 mysql alter table 语句
// MySqlAlterTableStatement alter = (MySqlAlterTableStatement)statement;
SQLExprTableSource source = getDDLTableSource(statement);
if (source == null)
return sql;
String tableName = StringUtil.removeBackquote(source.toString());
if (StringUtils.isNotBlank(tableName))
tableName = tableName.trim();
else
return sql;
if (!isGlobalTable(tableName))
return sql;
//增加对全局表create语句的解析,如果是建表语句创建的是全局表,且表中不含"_mycat_op_time"列
//则为其增加"_mycat_op_time"列,方便导入数据。
sql = addColumnIfCreate(sql, statement);
final String tn = tableName;
MycatServer.getInstance().getListeningExecutorService().execute(new Runnable() {
public void run() {
try {
// DDL发出之后,等待3秒让DDL分发完成
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
}
// DDL 语句可能会增删 列,所以需要重新获取 全局表的 列list
reGetColumnsForTable(tn);
}
});
MycatServer.getInstance().getListeningExecutorService().execute(new Runnable() {
public void run() {
try {
// DDL发出之后,等待10分钟再次执行,全局表一般很小,DDL耗时不会超过10分钟
TimeUnit.MINUTES.sleep(10);
} catch (InterruptedException e) {
}
// DDL 语句可能会增删 列,所以需要重新获取 全局表的 列list
reGetColumnsForTable(tn);
}
});
return sql;
}
use of com.alibaba.druid.sql.ast.SQLStatement in project Mycat-Server by MyCATApache.
the class GlobalTableUtil method convertUpdateSQL.
/**
* UPDATE [LOW_PRIORITY] [IGNORE] table_reference
SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...
[WHERE where_condition]
[ORDER BY ...]
[LIMIT row_count]
Multiple-table syntax:
UPDATE [LOW_PRIORITY] [IGNORE] table_references
SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...
[WHERE where_condition]
update user, tuser set user.name='dddd',tuser.pwd='aaa'
where user.id=2 and tuser.id=0;
* @param sql update tuser set pwd='aaa', name='digdee' where id=0;
* @return
*/
public static String convertUpdateSQL(String sql) {
try {
MySqlStatementParser parser = new MySqlStatementParser(sql);
SQLStatement stmt = parser.parseStatement();
MySqlUpdateStatement update = (MySqlUpdateStatement) stmt;
SQLTableSource ts = update.getTableSource();
if (ts != null && ts.toString().contains(",")) {
System.out.println(ts.toString());
LOGGER.warn("Do not support Multiple-table udpate syntax...");
return sql;
}
String tableName = StringUtil.removeBackquote(update.getTableName().getSimpleName());
if (!isGlobalTable(tableName))
return sql;
if (!isInnerColExist(tableName))
// 没有内部列
return sql;
StringBuilder sb = new StringBuilder(150);
SQLExpr se = update.getWhere();
// where中有子查询: update company set name='com' where id in (select id from xxx where ...)
if (se instanceof SQLInSubQueryExpr) {
// return sql;
int idx = sql.toUpperCase().indexOf(" SET ") + 5;
sb.append(sql.substring(0, idx)).append(GLOBAL_TABLE_MYCAT_COLUMN).append("=").append(operationTimestamp).append(",").append(sql.substring(idx));
return sb.toString();
}
String where = null;
if (update.getWhere() != null)
where = update.getWhere().toString();
SQLOrderBy orderBy = update.getOrderBy();
Limit limit = update.getLimit();
sb.append("update ").append(tableName).append(" set ");
List<SQLUpdateSetItem> items = update.getItems();
boolean flag = false;
for (int i = 0; i < items.size(); i++) {
SQLUpdateSetItem item = items.get(i);
String col = item.getColumn().toString();
String val = item.getValue().toString();
if (StringUtil.removeBackquote(col).equalsIgnoreCase(GLOBAL_TABLE_MYCAT_COLUMN)) {
flag = true;
sb.append(col).append("=");
if (i != items.size() - 1)
sb.append(operationTimestamp).append(",");
else
sb.append(operationTimestamp);
} else {
sb.append(col).append("=");
if (i != items.size() - 1)
sb.append(val).append(",");
else
sb.append(val);
}
}
if (!flag) {
sb.append(",").append(GLOBAL_TABLE_MYCAT_COLUMN).append("=").append(operationTimestamp);
}
sb.append(" where ").append(where);
if (orderBy != null && orderBy.getItems() != null && orderBy.getItems().size() > 0) {
sb.append(" order by ");
for (int i = 0; i < orderBy.getItems().size(); i++) {
SQLSelectOrderByItem item = orderBy.getItems().get(i);
SQLOrderingSpecification os = item.getType();
sb.append(item.getExpr().toString());
if (i < orderBy.getItems().size() - 1) {
if (os != null)
sb.append(" ").append(os.toString());
sb.append(",");
} else {
if (os != null)
sb.append(" ").append(os.toString());
}
}
}
if (limit != null) {
// 分为两种情况: limit 10; limit 10,10;
sb.append(" limit ");
if (limit.getOffset() != null)
sb.append(limit.getOffset().toString()).append(",");
sb.append(limit.getRowCount().toString());
}
return sb.toString();
} catch (Exception e) {
LOGGER.warn(e.getMessage());
return sql;
}
}
use of com.alibaba.druid.sql.ast.SQLStatement in project Mycat-Server by MyCATApache.
the class DruidUpdateParserTest method throwExceptionParse.
public void throwExceptionParse(String sql, boolean throwException) throws NoSuchMethodException {
MySqlStatementParser parser = new MySqlStatementParser(sql);
List<SQLStatement> statementList = parser.parseStatementList();
SQLStatement sqlStatement = statementList.get(0);
MySqlUpdateStatement update = (MySqlUpdateStatement) sqlStatement;
SchemaConfig schemaConfig = mock(SchemaConfig.class);
Map<String, TableConfig> tables = mock(Map.class);
TableConfig tableConfig = mock(TableConfig.class);
String tableName = "hotnews";
when((schemaConfig).getTables()).thenReturn(tables);
when(tables.get(tableName)).thenReturn(tableConfig);
when(tableConfig.getParentTC()).thenReturn(null);
RouteResultset routeResultset = new RouteResultset(sql, 11);
Class c = DruidUpdateParser.class;
Method method = c.getDeclaredMethod("confirmShardColumnNotUpdated", new Class[] { SQLUpdateStatement.class, SchemaConfig.class, String.class, String.class, String.class, RouteResultset.class });
method.setAccessible(true);
try {
method.invoke(c.newInstance(), update, schemaConfig, tableName, "ID", "", routeResultset);
if (throwException) {
System.out.println("未抛异常,解析通过则不对!");
Assert.assertTrue(false);
} else {
System.out.println("未抛异常,解析通过,此情况分片字段可能在update语句中但是实际不会被更新");
Assert.assertTrue(true);
}
} catch (Exception e) {
if (throwException) {
System.out.println(e.getCause().getClass());
Assert.assertTrue(e.getCause() instanceof SQLNonTransientException);
System.out.println("抛异常原因为SQLNonTransientException则正确");
} else {
System.out.println("抛异常,需要检查");
Assert.assertTrue(false);
}
}
}
use of com.alibaba.druid.sql.ast.SQLStatement in project Mycat-Server by MyCATApache.
the class DefaultDruidParserTest method getParseTables.
private Object[] getParseTables(String sql) throws Exception {
SQLStatementParser parser = new MySqlStatementParser(sql);
SQLStatement statement = parser.parseStatement();
MycatSchemaStatVisitor visitor = new MycatSchemaStatVisitor();
LayerCachePool cachePool = mock(LayerCachePool.class);
RouteResultset rrs = new RouteResultset(sql, ServerParse.SELECT);
druidParser.parser(schema, rrs, statement, sql, cachePool, visitor);
DruidShardingParseInfo ctx = druidParser.getCtx();
return ctx.getTables().toArray();
}
use of com.alibaba.druid.sql.ast.SQLStatement in project Mycat-Server by MyCATApache.
the class GlobalTableUtilTest method parseSql.
public String parseSql(String sql) {
MySqlStatementParser parser = new MySqlStatementParser(sql);
SQLStatement statement = parser.parseStatement();
return GlobalTableUtil.addColumnIfCreate(sql, statement);
}
Aggregations