improved sql parser.

This commit is contained in:
wenshao
2017-06-21 12:49:49 +08:00
parent 17c22cf84a
commit a679837026
13 changed files with 952 additions and 7 deletions
@@ -17,6 +17,8 @@ package com.alibaba.druid.sql.ast.statement;
import com.alibaba.druid.sql.ast.SQLCommentHint;
import com.alibaba.druid.sql.ast.SQLDataTypeImpl;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import java.util.List;
@@ -78,6 +80,17 @@ public class SQLCharacterDataType extends SQLDataTypeImpl {
this.hints = hints;
}
public int getLength() {
if (this.arguments.size() == 1) {
SQLExpr arg = this.arguments.get(0);
if (arg instanceof SQLIntegerExpr) {
return ((SQLIntegerExpr) arg).getNumber().intValue();
}
}
return -1;
}
@Override
protected void accept0(SQLASTVisitor visitor) {
if (visitor.visit(this)) {
@@ -20,6 +20,7 @@ import java.util.HashMap;
import java.util.List;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLDataType;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLStatementImpl;
@@ -27,6 +28,7 @@ import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlTableIndex;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.stat.TableStat;
import com.alibaba.druid.util.lang.Consumer;
public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLStatement {
@@ -213,4 +215,16 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS
return null;
}
public void forEachColumn(Consumer<SQLColumnDefinition> columnConsumer) {
if (columnConsumer == null) {
return;
}
for (SQLTableElement element : this.tableElementList) {
if (element instanceof SQLColumnDefinition) {
columnConsumer.accept((SQLColumnDefinition) element);
}
}
}
}
@@ -157,4 +157,28 @@ public class SQLSelectItem extends SQLObjectImpl implements SQLReplaceable {
return false;
}
public boolean match(String alias) {
if (alias == null) {
return false;
}
String alias_normalized = SQLUtils.normalize(alias);
if (alias_normalized.equalsIgnoreCase(this.alias)) {
return true;
}
if (expr instanceof SQLIdentifierExpr) {
String ident = ((SQLIdentifierExpr) expr).getName();
return alias_normalized.equalsIgnoreCase(SQLUtils.normalize(ident));
}
if (expr instanceof SQLPropertyExpr) {
String ident = ((SQLPropertyExpr) expr).getName();
return alias_normalized.equalsIgnoreCase(SQLUtils.normalize(ident));
}
return false;
}
}
@@ -18,7 +18,9 @@ package com.alibaba.druid.sql.ast.statement;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.*;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery, SQLReplaceable {
@@ -421,4 +423,20 @@ public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery
}
return false;
}
public SQLSelectItem findSelectItem(String ident) {
if (ident == null) {
return null;
}
String ident_normalized = SQLUtils.normalize(ident);
for (SQLSelectItem item : this.selectList) {
if (item.match(ident_normalized)) {
return item;
}
}
return null;
}
}
@@ -982,7 +982,7 @@ public class OracleExprParser extends SQLExprParser {
rightExp = equalityRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Equality, rightExp, getDbType());
} else if (lexer.token() == Token.BANGEQ) {
} else if (lexer.token() == Token.BANGEQ || lexer.token() == Token.CARETEQ) {
lexer.nextToken();
rightExp = shift();
@@ -582,7 +582,12 @@ public class Lexer {
break;
case '^':
scanChar();
token = Token.CARET;
if (ch == '=') {
scanChar();
token = Token.CARETEQ;
} else {
token = Token.CARET;
}
break;
case '%':
scanChar();
@@ -334,7 +334,8 @@ public enum Token {
SLASH("/"),
AMP("&"),
BAR("|"),
CARET("^"),
CARET("^"),
CARETEQ("^="),
PERCENT("%"),
LTLT("<<"),
GTGT(">>"),
@@ -29,6 +29,8 @@ import java.sql.Connection;
import java.sql.Driver;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.HashSet;
import java.util.Set;
public class MySqlUtils {
static Class<?> utilClass;
@@ -104,4 +106,24 @@ public class MySqlUtils {
}
return null;
}
private static Set<String> keywords;
public static boolean isKeyword(String name) {
if (name == null) {
return false;
}
String name_lower = name.toLowerCase();
Set<String> words = keywords;
if (words == null) {
words = new HashSet<String>();
Utils.loadFromFile("META-INF/druid/parser/mysql/keywords", words);
keywords = words;
}
return words.contains(name_lower);
}
}
@@ -15,10 +15,8 @@
*/
package com.alibaba.druid.util;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
@@ -28,6 +26,7 @@ import javax.transaction.xa.XAException;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.OracleResultSet;
import oracle.jdbc.OracleStatement;
import oracle.jdbc.driver.DatabaseError;
import oracle.jdbc.internal.OraclePreparedStatement;
import oracle.jdbc.xa.client.OracleXAConnection;
import oracle.sql.ROWID;
@@ -203,4 +202,24 @@ public class OracleUtils {
return tables.contains(table_lower);
}
private static Set<String> keywords;
public static boolean isKeyword(String name) {
if (name == null) {
return false;
}
String name_lower = name.toLowerCase();
Set<String> words = keywords;
if (words == null) {
words = new HashSet<String>();
Utils.loadFromFile("META-INF/druid/parser/oracle/keywords", words);
keywords = words;
}
return words.contains(name_lower);
}
}
@@ -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.util.lang;
/**
* Created by wenshao on 20/06/2017.
*/
public interface Consumer<T> {
void accept(T t);
}