mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
bug fixed for sql parser
This commit is contained in:
@@ -179,14 +179,14 @@ public class SQLStatementParser extends SQLParser {
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
if (lexer.token() == (Token.VALUES)) {
|
||||
if (lexer.token() == Token.VALUES) {
|
||||
lexer.nextToken();
|
||||
accept(Token.LPAREN);
|
||||
SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause();
|
||||
this.exprParser.exprList(values.getValues());
|
||||
insertStatement.setValues(values);
|
||||
accept(Token.RPAREN);
|
||||
} else if (lexer.token() == (Token.SELECT)) {
|
||||
} else if (lexer.token() == Token.SELECT || lexer.token() == Token.LPAREN) {
|
||||
SQLQueryExpr queryExpr = (SQLQueryExpr) this.createExprParser().expr();
|
||||
insertStatement.setQuery(queryExpr.getSubQuery());
|
||||
}
|
||||
@@ -196,7 +196,7 @@ public class SQLStatementParser extends SQLParser {
|
||||
public boolean parseStatementListDialect(List<SQLStatement> statementList) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public SQLStatement parseDropUser() throws ParserException {
|
||||
throw new ParserException("TODO " + lexer.token());
|
||||
}
|
||||
@@ -344,6 +344,5 @@ public class SQLStatementParser extends SQLParser {
|
||||
createView.setSubQuery(new SQLSelectParser(this.lexer).select());
|
||||
return createView;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -397,6 +397,10 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter {
|
||||
x.getSubQuery().accept(this);
|
||||
|
||||
decrementIndent();
|
||||
} else if (x.getParent() instanceof ValuesClause) {
|
||||
println();
|
||||
x.getSubQuery().accept(this);
|
||||
println();
|
||||
} else {
|
||||
print("(");
|
||||
incrementIndent();
|
||||
@@ -784,7 +788,9 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter {
|
||||
print(", ");
|
||||
}
|
||||
|
||||
x.getValues().get(i).accept(this);
|
||||
SQLExpr expr = x.getValues().get(i);
|
||||
expr.setParent(x);
|
||||
expr.accept(this);
|
||||
}
|
||||
decrementIndent();
|
||||
print(")");
|
||||
|
||||
@@ -38,12 +38,14 @@ import com.alibaba.druid.stat.TableStat;
|
||||
import com.alibaba.druid.stat.TableStat.Column;
|
||||
import com.alibaba.druid.stat.TableStat.Condition;
|
||||
import com.alibaba.druid.stat.TableStat.Mode;
|
||||
import com.alibaba.druid.stat.TableStat.Relationship;
|
||||
|
||||
public class SchemaStatVisitor extends SQLASTVisitorAdapter {
|
||||
|
||||
protected final HashMap<TableStat.Name, TableStat> tableStats = new LinkedHashMap<TableStat.Name, TableStat>();
|
||||
protected final Set<Column> columns = new LinkedHashSet<Column>();
|
||||
protected final Set<Condition> conditions = new LinkedHashSet<Condition>();
|
||||
protected final Set<Relationship> relationships = new LinkedHashSet<Relationship>();
|
||||
protected final Set<Column> orderByColumns = new LinkedHashSet<Column>();
|
||||
protected final Set<Column> groupByColumns = new LinkedHashSet<Column>();
|
||||
|
||||
@@ -116,6 +118,10 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Set<Relationship> getRelationships() {
|
||||
return relationships;
|
||||
}
|
||||
|
||||
public Set<Column> getOrderByColumns() {
|
||||
return orderByColumns;
|
||||
}
|
||||
@@ -143,6 +149,8 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
|
||||
case IsNot:
|
||||
handleCondition(x.getLeft(), x.getOperator().name);
|
||||
handleCondition(x.getRight(), x.getOperator().name);
|
||||
|
||||
handleRelationship(x.getLeft(), x.getOperator().name, x.getRight());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -150,10 +158,41 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void handleRelationship(SQLExpr left, String operator, SQLExpr right) {
|
||||
Column leftColumn = getColumn(left);
|
||||
if (leftColumn == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Column rightColumn = getColumn(right);
|
||||
if (rightColumn == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Relationship relationship = new Relationship();
|
||||
relationship.setLeft(leftColumn);
|
||||
relationship.setRight(rightColumn);
|
||||
relationship.setOperator(operator);
|
||||
|
||||
this.relationships.add(relationship);
|
||||
}
|
||||
|
||||
protected void handleCondition(SQLExpr expr, String operator) {
|
||||
Column column = getColumn(expr);
|
||||
if (column == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Condition condition = new Condition();
|
||||
condition.setColumn(column);
|
||||
condition.setOperator(operator);
|
||||
this.conditions.add(condition);
|
||||
}
|
||||
|
||||
protected Column getColumn(SQLExpr expr) {
|
||||
Map<String, String> aliasMap = aliasLocal.get();
|
||||
if (aliasMap == null) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (expr instanceof SQLPropertyExpr) {
|
||||
@@ -168,22 +207,13 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
|
||||
}
|
||||
|
||||
if (table != null) {
|
||||
Condition condition = new Condition();
|
||||
condition.setColumn(new Column(table, column));
|
||||
condition.setOperator(operator);
|
||||
this.conditions.add(condition);
|
||||
} else {
|
||||
Column sqlColumn = handleSubQueryColumn(tableName, column);
|
||||
if (sqlColumn != null) {
|
||||
Condition condition = new Condition();
|
||||
condition.setColumn(sqlColumn);
|
||||
condition.setOperator(operator);
|
||||
this.conditions.add(condition);
|
||||
}
|
||||
return new Column(table, column);
|
||||
}
|
||||
|
||||
return handleSubQueryColumn(tableName, column);
|
||||
}
|
||||
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (expr instanceof SQLIdentifierExpr) {
|
||||
@@ -196,12 +226,11 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
|
||||
}
|
||||
|
||||
if (table != null) {
|
||||
Condition condition = new Condition();
|
||||
condition.setColumn(new Column(table, column));
|
||||
condition.setOperator(operator);
|
||||
this.conditions.add(condition);
|
||||
return new Column(table, column);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -112,7 +112,6 @@ public class TableStat {
|
||||
if (dropCount > 0) {
|
||||
buf.append("Drop");
|
||||
}
|
||||
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
@@ -148,6 +147,89 @@ public class TableStat {
|
||||
}
|
||||
}
|
||||
|
||||
public static class Relationship {
|
||||
|
||||
private Column left;
|
||||
private Column right;
|
||||
private String operator;
|
||||
|
||||
public Column getLeft() {
|
||||
return left;
|
||||
}
|
||||
|
||||
public void setLeft(Column left) {
|
||||
this.left = left;
|
||||
}
|
||||
|
||||
public Column getRight() {
|
||||
return right;
|
||||
}
|
||||
|
||||
public void setRight(Column right) {
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
public String getOperator() {
|
||||
return operator;
|
||||
}
|
||||
|
||||
public void setOperator(String operator) {
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((left == null) ? 0 : left.hashCode());
|
||||
result = prime * result + ((operator == null) ? 0 : operator.hashCode());
|
||||
result = prime * result + ((right == null) ? 0 : right.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Relationship other = (Relationship) obj;
|
||||
if (left == null) {
|
||||
if (other.left != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!left.equals(other.left)) {
|
||||
return false;
|
||||
}
|
||||
if (operator == null) {
|
||||
if (other.operator != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!operator.equals(other.operator)) {
|
||||
return false;
|
||||
}
|
||||
if (right == null) {
|
||||
if (other.right != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!right.equals(other.right)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return left + " " + operator + " " + right;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Condition {
|
||||
|
||||
private Column column;
|
||||
|
||||
+2
-1
@@ -10,7 +10,7 @@ import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor;
|
||||
import com.alibaba.druid.stat.TableStat;
|
||||
|
||||
public class OracleSelectTest extends OracleTest {
|
||||
public class OracleInsertTest extends OracleTest {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = "INSERT INTO films VALUES ('UA502', 'Bananas', 105, '1971-07-13', 'Comedy', '82 minutes');";
|
||||
@@ -28,6 +28,7 @@ public class OracleSelectTest extends OracleTest {
|
||||
System.out.println("Tables : " + visitor.getTables());
|
||||
System.out.println("fields : " + visitor.getColumns());
|
||||
System.out.println("coditions : " + visitor.getConditions());
|
||||
System.out.println("relationships : " + visitor.getRelationships());
|
||||
|
||||
Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("films")));
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.alibaba.druid.bvt.sql.oracle;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import com.alibaba.druid.sql.OracleTest;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor;
|
||||
import com.alibaba.druid.stat.TableStat;
|
||||
|
||||
public class OracleInsertTest1 extends OracleTest {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = "INSERT INTO bonuses(employee_id)" +
|
||||
" (SELECT e.employee_id FROM employees e, orders o" +
|
||||
" WHERE e.employee_id = o.sales_rep_id" +
|
||||
" GROUP BY e.employee_id); ";
|
||||
|
||||
OracleStatementParser parser = new OracleStatementParser(sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLStatement statemen = statementList.get(0);
|
||||
System.out.println(output(statementList));
|
||||
|
||||
Assert.assertEquals(1, statementList.size());
|
||||
|
||||
OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor();
|
||||
statemen.accept(visitor);
|
||||
|
||||
System.out.println("Tables : " + visitor.getTables());
|
||||
System.out.println("fields : " + visitor.getColumns());
|
||||
System.out.println("coditions : " + visitor.getConditions());
|
||||
System.out.println("relationships : " + visitor.getRelationships());
|
||||
|
||||
Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("bonuses")));
|
||||
Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees")));
|
||||
Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("orders")));
|
||||
|
||||
Assert.assertEquals(3, visitor.getTables().size());
|
||||
Assert.assertEquals(3, visitor.getColumns().size());
|
||||
|
||||
Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("bonuses", "employee_id")));
|
||||
Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "employee_id")));
|
||||
Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("orders", "sales_rep_id")));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -36,6 +36,7 @@ public class OracleMergeTest extends OracleTest {
|
||||
System.out.println("Tables : " + visitor.getTables());
|
||||
System.out.println("fields : " + visitor.getColumns());
|
||||
System.out.println("coditions : " + visitor.getConditions());
|
||||
System.out.println("relationships : " + visitor.getRelationships());
|
||||
|
||||
Assert.assertEquals(2, visitor.getTables().size());
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ public class OracleSelectTest2 extends OracleTest {
|
||||
System.out.println("Tables : " + visitor.getTables());
|
||||
System.out.println("fields : " + visitor.getColumns());
|
||||
System.out.println("coditions : " + visitor.getConditions());
|
||||
System.out.println("relationships : " + visitor.getRelationships());
|
||||
|
||||
Assert.assertEquals(2, visitor.getTables().size());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user