diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java index 74bfba168d..a7535038a9 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java @@ -112,6 +112,7 @@ public class MySqlLexer extends Lexer { map.put("KILL", Token.KILL); map.put("IDENTIFIED", Token.IDENTIFIED); map.put("PASSWORD", Token.PASSWORD); + map.put("DUAL", Token.DUAL); DEFAULT_MYSQL_KEYWORDS = new Keywords(map); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java index d430341685..6b16264f57 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java @@ -768,7 +768,7 @@ public class MySqlStatementParser extends SQLStatementParser { if (identifierEquals("ROWS")) { lexer.nextToken(); - acceptIdentifier("IDENTIFIED"); + accept(Token.IDENTIFIED); accept(Token.BY); SQLExpr rowsIdentifiedBy = exprParser.expr(); stmt.setRowsIdentifiedBy(rowsIdentifiedBy); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java index c721d58d96..3548137860 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java @@ -5,6 +5,7 @@ import java.util.Map; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; +import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; import com.alibaba.druid.sql.dialect.mysql.ast.MySqlKey; import com.alibaba.druid.sql.dialect.mysql.ast.MySqlPrimaryKey; import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBinaryExpr; @@ -43,6 +44,13 @@ import com.alibaba.druid.stat.TableStat.Mode; public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlASTVisitor { + public boolean visit(SQLSelectStatement x) { + aliasLocal.set(new HashMap()); + aliasLocal.get().put("DUAL", null); + + return true; + } + //DUAL public boolean visit(MySqlDeleteStatement x) { aliasLocal.set(new HashMap()); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/stmt/PGSelectStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/stmt/PGSelectStatement.java index cd570b372d..1c760e401e 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/stmt/PGSelectStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/stmt/PGSelectStatement.java @@ -1,5 +1,6 @@ package com.alibaba.druid.sql.dialect.postgresql.ast.stmt; +import com.alibaba.druid.sql.ast.statement.SQLSelect; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithClause; import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitor; @@ -10,6 +11,13 @@ public class PGSelectStatement extends SQLSelectStatement implements PGSQLStatem private static final long serialVersionUID = 1L; private PGWithClause with; + public PGSelectStatement(){ + } + + public PGSelectStatement(SQLSelect select){ + super(select); + } + public PGWithClause getWith() { return with; } @@ -17,7 +25,7 @@ public class PGSelectStatement extends SQLSelectStatement implements PGSQLStatem public void setWith(PGWithClause with) { this.with = with; } - + protected void accept0(SQLASTVisitor visitor) { accept0((PGASTVisitor) visitor); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java index f27dbbf17f..8c9e059d18 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java @@ -15,6 +15,7 @@ import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithClause; import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithQuery; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGDeleteStatement; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGInsertStatement; +import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectStatement; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGTruncateStatement; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGUpdateStatement; import com.alibaba.druid.sql.parser.Lexer; @@ -311,6 +312,10 @@ public class PGSQLStatementParser extends SQLStatementParser { return withQuery; } + public PGSelectStatement parseSelect() throws ParserException { + return new PGSelectStatement(createSQLSelectParser().select()); + } + public SQLStatement parseWith() { PGWithClause with = this.parseWithClause(); if (lexer.token() == Token.INSERT) { @@ -318,7 +323,12 @@ public class PGSQLStatementParser extends SQLStatementParser { stmt.setWith(with); return stmt; } - + + if (lexer.token() == Token.SELECT) { + PGSelectStatement stmt = this.parseSelect(); + stmt.setWith(with); + return stmt; + } throw new ParserException("TODO"); } } diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java index d661f45d4d..ac439eac62 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -198,6 +198,12 @@ public class SQLExprParser extends SQLParser { sqlExpr = new SQLDefaultExpr(); lexer.nextToken(); break; + case USER: + case PASSWORD: + case DUAL: + sqlExpr = new SQLIdentifierExpr(lexer.stringVal()); + lexer.nextToken(); + break; case CASE: SQLCaseExpr caseExpr = new SQLCaseExpr(); lexer.nextToken(); diff --git a/src/main/java/com/alibaba/druid/sql/parser/Token.java b/src/main/java/com/alibaba/druid/sql/parser/Token.java index 01551c75c0..1d8f33d527 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Token.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Token.java @@ -102,6 +102,7 @@ public enum Token { KILL("KILL"), IDENTIFIED("IDENTIFIED"), PASSWORD("PASSWORD"), + DUAL("DUAL"), //postgresql WINDOW("WINDOW"), diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_0.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_0.java new file mode 100644 index 0000000000..c9f403b4c5 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_0.java @@ -0,0 +1,43 @@ +package com.alibaba.druid.bvt.sql.mysql; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.MysqlTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; +import com.alibaba.druid.stat.TableStat.Column; + +public class MySqlSelectTest_0 extends MysqlTest { + + public void test_0() throws Exception { + String sql = "SELECT CONCAT(last_name,', ',first_name) AS full_name FROM mytable ORDER BY full_name;"; + + MySqlStatementParser parser = new MySqlStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getFields()); + System.out.println("coditions : " + visitor.getConditions()); + + Assert.assertEquals(1, visitor.getTables().size()); + Assert.assertEquals(3, visitor.getFields().size()); + Assert.assertEquals(0, visitor.getConditions().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("mytable"))); + + Assert.assertTrue(visitor.getFields().contains(new Column("mytable", "last_name"))); + Assert.assertTrue(visitor.getFields().contains(new Column("mytable", "first_name"))); + Assert.assertTrue(visitor.getFields().contains(new Column("mytable", "full_name"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_1.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_1.java new file mode 100644 index 0000000000..fb5db3fb7e --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_1.java @@ -0,0 +1,44 @@ +package com.alibaba.druid.bvt.sql.mysql; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.MysqlTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; +import com.alibaba.druid.stat.TableStat.Column; + +public class MySqlSelectTest_1 extends MysqlTest { + + public void test_0() throws Exception { + String sql = "SELECT t1.name, t2.salary FROM employee t1, info t2 WHERE t1.name = t2.name;"; + + MySqlStatementParser parser = new MySqlStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getFields()); + System.out.println("coditions : " + visitor.getConditions()); + + Assert.assertEquals(2, visitor.getTables().size()); + Assert.assertEquals(3, visitor.getFields().size()); + Assert.assertEquals(2, visitor.getConditions().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employee"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("info"))); + + Assert.assertTrue(visitor.getFields().contains(new Column("employee", "name"))); + Assert.assertTrue(visitor.getFields().contains(new Column("info", "name"))); + Assert.assertTrue(visitor.getFields().contains(new Column("info", "salary"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGDeleteTest5.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGDeleteTest5.java index 1734388cee..46d47c8fce 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGDeleteTest5.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGDeleteTest5.java @@ -27,6 +27,7 @@ public class PGDeleteTest5 extends PGTest { System.out.println("Tables : " + visitor.getTables()); System.out.println("fields : " + visitor.getFields()); + System.out.println("coditions : " + visitor.getConditions()); Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("films"))); Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("producers"))); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGInsertTest0.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGInsertTest0.java index bed33fac79..e99712dc23 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGInsertTest0.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGInsertTest0.java @@ -27,6 +27,7 @@ public class PGInsertTest0 extends PGTest { System.out.println("Tables : " + visitor.getTables()); System.out.println("fields : " + visitor.getFields()); + System.out.println("coditions : " + visitor.getConditions()); Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("films"))); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGInsertTest1.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGInsertTest1.java index 805a594863..78efe5323f 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGInsertTest1.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGInsertTest1.java @@ -27,6 +27,7 @@ public class PGInsertTest1 extends PGTest { System.out.println("Tables : " + visitor.getTables()); System.out.println("fields : " + visitor.getFields()); + System.out.println("coditions : " + visitor.getConditions()); Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("films"))); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGInsertTest3.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGInsertTest3.java index 45883abd4d..497ff30bfc 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGInsertTest3.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGInsertTest3.java @@ -27,6 +27,7 @@ public class PGInsertTest3 extends PGTest { System.out.println("Tables : " + visitor.getTables()); System.out.println("fields : " + visitor.getFields()); + System.out.println("coditions : " + visitor.getConditions()); Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("films"))); Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("tmp_films"))); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGInsertTest4.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGInsertTest4.java index 6ec42097da..b3b4da579e 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGInsertTest4.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGInsertTest4.java @@ -27,6 +27,7 @@ public class PGInsertTest4 extends PGTest { System.out.println("Tables : " + visitor.getTables()); System.out.println("fields : " + visitor.getFields()); + System.out.println("coditions : " + visitor.getConditions()); Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("distributors"))); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGInsertTest5.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGInsertTest5.java index 911aa17f62..8573628669 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGInsertTest5.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGInsertTest5.java @@ -32,6 +32,7 @@ public class PGInsertTest5 extends PGTest { System.out.println("Tables : " + visitor.getTables()); System.out.println("fields : " + visitor.getFields()); + System.out.println("coditions : " + visitor.getConditions()); Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees_log"))); Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees"))); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectIntoTest.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectIntoTest.java index fc7817122c..ca75e61c51 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectIntoTest.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGSelectIntoTest.java @@ -27,6 +27,7 @@ public class PGSelectIntoTest extends PGTest { System.out.println("Tables : " + visitor.getTables()); System.out.println("fields : " + visitor.getFields()); + System.out.println("coditions : " + visitor.getConditions()); Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("films_recent"))); Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("films"))); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PostgresqlResourceTest.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PostgresqlResourceTest.java index 6c540323f8..bdd427d23f 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PostgresqlResourceTest.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PostgresqlResourceTest.java @@ -49,6 +49,7 @@ public class PostgresqlResourceTest extends PGTest { System.out.println(sql); System.out.println("Tables : " + visitor.getTables()); System.out.println("fields : " + visitor.getFields()); + System.out.println("coditions : " + visitor.getConditions()); System.out.println(); System.out.println();