improved sql parser.

This commit is contained in:
wenshao
2017-06-08 09:28:08 +08:00
parent 2b75d0f853
commit 41a56b3c92
7 changed files with 230 additions and 67 deletions
@@ -21,13 +21,14 @@ import java.util.List;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.repository.SchemaObject;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLExprTableSource extends SQLTableSourceImpl {
protected SQLExpr expr;
private List<SQLName> partitions;
protected SQLExpr expr;
private List<SQLName> partitions;
private SchemaObject schemaObject;
public SQLExprTableSource(){
@@ -141,4 +142,12 @@ public class SQLExprTableSource extends SQLTableSourceImpl {
}
}
}
public SchemaObject getSchemaObject() {
return schemaObject;
}
public void setSchemaObject(SchemaObject schemaObject) {
this.schemaObject = schemaObject;
}
}
@@ -1479,6 +1479,7 @@ public class OracleStatementParser extends SQLStatementParser {
if (lexer.token() == Token.NOWAIT) {
lexer.nextToken();
stmt.setNoWait(true);
} else if (lexer.token() == Token.WAIT) {
lexer.nextToken();
stmt.setWait(exprParser.expr());
@@ -17,73 +17,23 @@ package com.alibaba.druid.sql.repository;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLTableElement;
import com.alibaba.druid.sql.ast.statement.SQLUniqueConstraint;
/**
* Created by wenshao on 03/06/2017.
*/
public class SchemaObject {
public final String name;
public final Type type;
private SQLStatement statement;
public interface SchemaObject {
public long rowCount = -1;
SQLStatement getStatement();
public SchemaObject(String name, Type type) {
this(name, type, null);
}
SQLColumnDefinition findColumn(String columName);
public SchemaObject(String name, Type type, SQLStatement statement) {
this.name = name;
this.type = type;
this.statement = statement;
}
boolean matchIndex(String columnName);
public static enum Type {
Sequence, Table, Index, Function
}
boolean matchKey(String columnName);
public SQLStatement getStatement() {
return statement;
}
SchemaObjectType getType();
public SQLColumnDefinition findColumn(String columName) {
if (statement == null) {
return null;
}
String getName();
if (statement instanceof SQLCreateTableStatement) {
return ((SQLCreateTableStatement) statement).findColumn(columName);
}
return null;
}
public boolean matchIndex(String columnName) {
if (statement == null) {
return false;
}
if (statement instanceof SQLCreateTableStatement) {
SQLTableElement index = ((SQLCreateTableStatement) statement).findIndex(columnName);
return index != null;
}
return false;
}
public boolean matchKey(String columnName) {
if (statement == null) {
return false;
}
if (statement instanceof SQLCreateTableStatement) {
SQLTableElement index = ((SQLCreateTableStatement) statement).findIndex(columnName);
return index instanceof SQLUniqueConstraint;
}
return false;
}
long getRowCount();
}
@@ -0,0 +1,104 @@
/*
* Copyright 1999-2017 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.sql.repository;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLTableElement;
import com.alibaba.druid.sql.ast.statement.SQLUniqueConstraint;
/**
* Created by wenshao on 08/06/2017.
*/
public class SchemaObjectImpl implements SchemaObject {
private final String name;
private final SchemaObjectType type;
private SQLStatement statement;
public long rowCount = -1;
public SchemaObjectImpl(String name, SchemaObjectType type) {
this(name, type, null);
}
public SchemaObjectImpl(String name, SchemaObjectType type, SQLStatement statement) {
this.name = name;
this.type = type;
this.statement = statement;
}
public static enum Type {
Sequence, Table, View, Index, Function
}
public SQLStatement getStatement() {
return statement;
}
public SQLColumnDefinition findColumn(String columName) {
if (statement == null) {
return null;
}
if (statement instanceof SQLCreateTableStatement) {
return ((SQLCreateTableStatement) statement).findColumn(columName);
}
return null;
}
public boolean matchIndex(String columnName) {
if (statement == null) {
return false;
}
if (statement instanceof SQLCreateTableStatement) {
SQLTableElement index = ((SQLCreateTableStatement) statement).findIndex(columnName);
return index != null;
}
return false;
}
public boolean matchKey(String columnName) {
if (statement == null) {
return false;
}
if (statement instanceof SQLCreateTableStatement) {
SQLTableElement index = ((SQLCreateTableStatement) statement).findIndex(columnName);
return index instanceof SQLUniqueConstraint;
}
return false;
}
@Override
public String getName() {
return name;
}
@Override
public SchemaObjectType getType() {
return type;
}
@Override
public long getRowCount() {
return rowCount;
}
}
@@ -0,0 +1,23 @@
/*
* Copyright 1999-2017 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.sql.repository;
/**
* Created by wenshao on 08/06/2017.
*/
public enum SchemaObjectType {
Sequence, Table, View, Index, Function
}
@@ -47,7 +47,7 @@ public class SchemaRepository {
String lowerName = tableName.toLowerCase();
SchemaObject object = objects.get(lowerName);
if (object != null && object.type == SchemaObject.Type.Table) {
if (object != null && object.getType() == SchemaObjectType.Table) {
return object;
}
@@ -73,7 +73,7 @@ public class SchemaRepository {
public boolean isSequence(String name) {
SchemaObject object = objects.get(name);
return object != null
&& object.type == SchemaObject.Type.Sequence;
&& object.getType() == SchemaObjectType.Sequence;
}
public class SchemaVisitor extends OracleASTVisitorAdapter {
@@ -86,7 +86,7 @@ public class SchemaRepository {
public boolean visit(SQLCreateSequenceStatement x) {
String name = x.getName().getSimpleName();
SchemaObject object = new SchemaObject(name, SchemaObject.Type.Sequence);
SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.Sequence);
objects.put(name.toLowerCase(), object);
return false;
@@ -99,7 +99,7 @@ public class SchemaRepository {
public boolean visit(SQLCreateTableStatement x) {
String name = x.computeName();
SchemaObject object = new SchemaObject(name, SchemaObject.Type.Table, x);
SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.Table, x);
objects.put(name.toLowerCase(), object);
@@ -108,7 +108,7 @@ public class SchemaRepository {
public boolean visit(SQLCreateIndexStatement x) {
String name = x.getName().getSimpleName();
SchemaObject object = new SchemaObject(name, SchemaObject.Type.Index);
SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.Index);
objects.put(name.toLowerCase(), object);
@@ -117,7 +117,7 @@ public class SchemaRepository {
public boolean visit(SQLCreateFunctionStatement x) {
String name = x.getName().getSimpleName();
SchemaObject object = new SchemaObject(name, SchemaObject.Type.Function, x);
SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.Function, x);
functions.put(name.toLowerCase(), object);
@@ -253,4 +253,24 @@ public class SchemaRepository {
computeTable(join.getRight(), tables);
}
}
public int getTableCount() {
int count = 0;
for (SchemaObject object : this.objects.values()) {
if (object.getType() == SchemaObjectType.Table) {
count++;
}
}
return count;
}
public int getViewCount() {
int count = 0;
for (SchemaObject object : this.objects.values()) {
if (object.getType() == SchemaObjectType.View) {
count++;
}
}
return count;
}
}
@@ -0,0 +1,56 @@
/*
* Copyright 1999-2017 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.bvt.sql.oracle;
import com.alibaba.druid.sql.OracleTest;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor;
import com.alibaba.druid.stat.TableStat;
import com.alibaba.druid.util.JdbcConstants;
import java.util.List;
public class OracleLockTableTest4 extends OracleTest {
public void test_0() throws Exception {
String sql = "LOCK TABLE \"TAB9527\" IN EXCLUSIVE MODE NOWAIT";
List<SQLStatement> statementList = SQLUtils.parseStatements(sql, JdbcConstants.ORACLE);
SQLStatement stmt = statementList.get(0);
print(statementList);
assertEquals(1, statementList.size());
assertEquals("LOCK TABLE \"TAB9527\" IN EXCLUSIVE MODE NOWAIT", SQLUtils.toOracleString(stmt));
OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor();
stmt.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());
assertTrue(visitor.getTables().containsKey(new TableStat.Name("FIN_SETTLEMENT_DETAIL")));
assertEquals(1, visitor.getTables().size());
assertEquals(0, visitor.getColumns().size());
// Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("bonuses", "employee_id")));
}
}