use of com.alibaba.druid.sql.ast.statement.SQLExprTableSource in project druid by alibaba.
the class SQLEvalVisitorUtils method visit.
public static boolean visit(SQLEvalVisitor visitor, SQLQueryExpr x) {
if (WallVisitorUtils.isSimpleCountTableSource(null, ((SQLQueryExpr) x).getSubQuery())) {
x.putAttribute(EVAL_VALUE, 1);
return false;
}
if (x.getSubQuery().getQuery() instanceof SQLSelectQueryBlock) {
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) x.getSubQuery().getQuery();
boolean nullFrom = false;
if (queryBlock.getFrom() == null) {
nullFrom = true;
} else if (queryBlock.getFrom() instanceof SQLExprTableSource) {
SQLExpr expr = ((SQLExprTableSource) queryBlock.getFrom()).getExpr();
if (expr instanceof SQLIdentifierExpr) {
if ("dual".equalsIgnoreCase(((SQLIdentifierExpr) expr).getName())) {
nullFrom = true;
}
}
}
if (nullFrom) {
List<Object> row = new ArrayList<Object>(queryBlock.getSelectList().size());
for (int i = 0; i < queryBlock.getSelectList().size(); ++i) {
SQLSelectItem item = queryBlock.getSelectList().get(i);
item.getExpr().accept(visitor);
Object cell = item.getExpr().getAttribute(EVAL_VALUE);
row.add(cell);
}
List<List<Object>> rows = new ArrayList<List<Object>>(1);
rows.add(row);
Object result = rows;
queryBlock.putAttribute(EVAL_VALUE, result);
x.getSubQuery().putAttribute(EVAL_VALUE, result);
x.putAttribute(EVAL_VALUE, result);
return false;
}
}
return false;
}
use of com.alibaba.druid.sql.ast.statement.SQLExprTableSource in project sharding-jdbc by dangdangdotcom.
the class MySQLSelectVisitor method visit.
@Override
public boolean visit(final MySqlSelectQueryBlock x) {
stepInQuery();
if (x.getFrom() instanceof SQLExprTableSource) {
SQLExprTableSource tableExpr = (SQLExprTableSource) x.getFrom();
getParseContext().setCurrentTable(tableExpr.getExpr().toString(), Optional.fromNullable(tableExpr.getAlias()));
}
return super.visit(x);
}
use of com.alibaba.druid.sql.ast.statement.SQLExprTableSource in project druid by alibaba.
the class PGSelectParser method query.
@Override
public SQLSelectQuery query() {
if (lexer.token() == Token.VALUES) {
lexer.nextToken();
accept(Token.LPAREN);
PGValuesQuery valuesQuery = new PGValuesQuery();
this.exprParser.exprList(valuesQuery.getValues(), valuesQuery);
accept(Token.RPAREN);
return queryRest(valuesQuery);
}
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
SQLSelectQuery select = query();
if (select instanceof SQLSelectQueryBlock) {
((SQLSelectQueryBlock) select).setParenthesized(true);
}
accept(Token.RPAREN);
return queryRest(select);
}
PGSelectQueryBlock queryBlock = new PGSelectQueryBlock();
if (lexer.token() == Token.SELECT) {
lexer.nextToken();
if (lexer.token() == Token.COMMENT) {
lexer.nextToken();
}
if (lexer.token() == Token.DISTINCT) {
queryBlock.setDistionOption(SQLSetQuantifier.DISTINCT);
lexer.nextToken();
if (lexer.token() == Token.ON) {
lexer.nextToken();
for (; ; ) {
SQLExpr expr = this.createExprParser().expr();
queryBlock.getDistinctOn().add(expr);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
} else {
break;
}
}
}
} else if (lexer.token() == Token.ALL) {
queryBlock.setDistionOption(SQLSetQuantifier.ALL);
lexer.nextToken();
}
parseSelectList(queryBlock);
if (lexer.token() == Token.INTO) {
lexer.nextToken();
if (lexer.token() == Token.TEMPORARY) {
lexer.nextToken();
queryBlock.setIntoOption(IntoOption.TEMPORARY);
} else if (lexer.token() == Token.TEMP) {
lexer.nextToken();
queryBlock.setIntoOption(IntoOption.TEMP);
} else if (lexer.token() == Token.UNLOGGED) {
lexer.nextToken();
queryBlock.setIntoOption(IntoOption.UNLOGGED);
}
if (lexer.token() == Token.TABLE) {
lexer.nextToken();
}
SQLExpr name = this.createExprParser().name();
queryBlock.setInto(new SQLExprTableSource(name));
}
}
parseFrom(queryBlock);
parseWhere(queryBlock);
parseGroupBy(queryBlock);
if (lexer.token() == Token.WINDOW) {
lexer.nextToken();
PGSelectQueryBlock.WindowClause window = new PGSelectQueryBlock.WindowClause();
window.setName(this.expr());
accept(Token.AS);
for (; ; ) {
SQLExpr expr = this.createExprParser().expr();
window.getDefinition().add(expr);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
} else {
break;
}
}
queryBlock.setWindow(window);
}
queryBlock.setOrderBy(this.createExprParser().parseOrderBy());
for (; ; ) {
if (lexer.token() == Token.LIMIT) {
SQLLimit limit = new SQLLimit();
lexer.nextToken();
if (lexer.token() == Token.ALL) {
limit.setRowCount(new SQLIdentifierExpr("ALL"));
lexer.nextToken();
} else {
limit.setRowCount(expr());
}
queryBlock.setLimit(limit);
} else if (lexer.token() == Token.OFFSET) {
SQLLimit limit = queryBlock.getLimit();
if (limit == null) {
limit = new SQLLimit();
queryBlock.setLimit(limit);
}
lexer.nextToken();
SQLExpr offset = expr();
limit.setOffset(offset);
if (lexer.token() == Token.ROW || lexer.token() == Token.ROWS) {
lexer.nextToken();
}
} else {
break;
}
}
if (lexer.token() == Token.FETCH) {
lexer.nextToken();
PGSelectQueryBlock.FetchClause fetch = new PGSelectQueryBlock.FetchClause();
if (lexer.token() == Token.FIRST) {
fetch.setOption(PGSelectQueryBlock.FetchClause.Option.FIRST);
} else if (lexer.token() == Token.NEXT) {
fetch.setOption(PGSelectQueryBlock.FetchClause.Option.NEXT);
} else {
throw new ParserException("expect 'FIRST' or 'NEXT'");
}
SQLExpr count = expr();
fetch.setCount(count);
if (lexer.token() == Token.ROW || lexer.token() == Token.ROWS) {
lexer.nextToken();
} else {
throw new ParserException("expect 'ROW' or 'ROWS'");
}
if (lexer.token() == Token.ONLY) {
lexer.nextToken();
} else {
throw new ParserException("expect 'ONLY'");
}
queryBlock.setFetch(fetch);
}
if (lexer.token() == Token.FOR) {
lexer.nextToken();
PGSelectQueryBlock.ForClause forClause = new PGSelectQueryBlock.ForClause();
if (lexer.token() == Token.UPDATE) {
forClause.setOption(PGSelectQueryBlock.ForClause.Option.UPDATE);
lexer.nextToken();
} else if (lexer.token() == Token.SHARE) {
forClause.setOption(PGSelectQueryBlock.ForClause.Option.SHARE);
lexer.nextToken();
} else {
throw new ParserException("expect 'FIRST' or 'NEXT'");
}
if (lexer.token() == Token.OF) {
for (; ; ) {
SQLExpr expr = this.createExprParser().expr();
forClause.getOf().add(expr);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
} else {
break;
}
}
}
if (lexer.token() == Token.NOWAIT) {
lexer.nextToken();
forClause.setNoWait(true);
}
queryBlock.setForClause(forClause);
}
return queryRest(queryBlock);
}
use of com.alibaba.druid.sql.ast.statement.SQLExprTableSource in project druid by alibaba.
the class SQLSelectParser method parseTableSource.
public SQLTableSource parseTableSource() {
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
SQLTableSource tableSource;
if (lexer.token() == Token.SELECT || lexer.token() == Token.WITH || lexer.token == Token.SEL) {
SQLSelect select = select();
accept(Token.RPAREN);
SQLSelectQuery query = queryRest(select.getQuery());
if (query instanceof SQLUnionQuery) {
tableSource = new SQLUnionQueryTableSource((SQLUnionQuery) query);
} else {
tableSource = new SQLSubqueryTableSource(select);
}
} else if (lexer.token() == Token.LPAREN) {
tableSource = parseTableSource();
accept(Token.RPAREN);
} else {
tableSource = parseTableSource();
accept(Token.RPAREN);
}
return parseTableSourceRest(tableSource);
}
if (lexer.token() == Token.SELECT) {
throw new ParserException("TODO");
}
SQLExprTableSource tableReference = new SQLExprTableSource();
parseTableSourceQueryTableExpr(tableReference);
SQLTableSource tableSrc = parseTableSourceRest(tableReference);
if (lexer.hasComment() && lexer.isKeepComments()) {
tableSrc.addAfterComment(lexer.readAndResetComments());
}
return tableSrc;
}
use of com.alibaba.druid.sql.ast.statement.SQLExprTableSource in project Mycat_plus by coderczp.
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;
}
Aggregations