Skip to content

Commit

Permalink
improved sql parser. for issue #2080
Browse files Browse the repository at this point in the history
  • Loading branch information
wenshao committed Oct 31, 2017
1 parent 46e8847 commit 1cfe3c6
Show file tree
Hide file tree
Showing 13 changed files with 316 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.alibaba.druid.sql.ast.statement;

import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLObject;

Expand All @@ -24,5 +25,8 @@ public interface SQLConstraint extends SQLObject {

void setName(SQLName value);

SQLExpr getComment();
void setComment(SQLExpr x);

void simplify();
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,20 @@

import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLCommentHint;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLObjectImpl;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;

import java.util.List;

public abstract class SQLConstraintImpl extends SQLObjectImpl implements SQLConstraint {
protected String dbType;

protected String dbType;
protected SQLName name;
private Boolean enable;
private Boolean validate;
private Boolean rely;
protected Boolean enable;
protected Boolean validate;
protected Boolean rely;
protected SQLExpr comment;

public List<SQLCommentHint> hints;

Expand Down Expand Up @@ -106,6 +107,17 @@ public void setDbType(String dbType) {
this.dbType = dbType;
}

public SQLExpr getComment() {
return comment;
}

public void setComment(SQLExpr x) {
if (x != null) {
x.setParent(this);
}
this.comment = x;
}

public void simplify() {
if (this.name instanceof SQLIdentifierExpr) {
SQLIdentifierExpr identExpr = (SQLIdentifierExpr) this.name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ public void setUpsert(boolean upsert) {

public static class ValuesClause extends SQLObjectImpl {

private final List<SQLExpr> values;

private transient String originalString;
private final List<SQLExpr> values;
private transient String originalString;
private transient int replaceCount;

public ValuesClause(){
this(new ArrayList<SQLExpr>());
Expand Down Expand Up @@ -151,6 +151,14 @@ public String getOriginalString() {
public void setOriginalString(String originalString) {
this.originalString = originalString;
}

public int getReplaceCount() {
return replaceCount;
}

public void incrementReplaceCount() {
this.replaceCount++;
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,7 @@
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
import com.alibaba.druid.sql.ast.expr.SQLNumberExpr;
import com.alibaba.druid.sql.ast.statement.SQLAssignItem;
import com.alibaba.druid.sql.ast.statement.SQLCheck;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLForeignKeyConstraint;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLTableConstraint;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.ast.statement.*;
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.MySqlUnique;
Expand Down Expand Up @@ -784,6 +777,8 @@ protected SQLTableConstraint parseConstraint() {
name = this.exprParser.name();
}

SQLTableConstraint constraint = null;

if (lexer.token() == (Token.KEY)) {
lexer.nextToken();

Expand Down Expand Up @@ -840,41 +835,44 @@ protected SQLTableConstraint parseConstraint() {
lexer.nextToken();
}

return key;
}

if (lexer.token() == Token.PRIMARY) {
constraint = key;
} else if (lexer.token() == Token.PRIMARY) {
MySqlPrimaryKey pk = this.getExprParser().parsePrimaryKey();
if (name != null) {
pk.setName(name);
}
pk.setHasConstaint(hasConstaint);
return pk;
}

if (lexer.token() == Token.UNIQUE) {
constraint = pk;
} else if (lexer.token() == Token.UNIQUE) {
MySqlUnique uk = this.getExprParser().parseUnique();
if (name != null) {
uk.setName(name);
}
uk.setHasConstaint(hasConstaint);
return uk;
}

if (lexer.token() == Token.FOREIGN) {
constraint = uk;
} else if (lexer.token() == Token.FOREIGN) {
MysqlForeignKey fk = this.getExprParser().parseForeignKey();
fk.setName(name);
fk.setHasConstraint(hasConstaint);
return fk;
}

if (lexer.token() == Token.CHECK) {
constraint = fk;
} else if (lexer.token() == Token.CHECK) {
lexer.nextToken();
SQLCheck check = new SQLCheck();
check.setName(name);
SQLExpr expr = this.exprParser.expr();
check.setExpr(expr);
return check;
constraint = check;
}

if (constraint != null) {
if (lexer.token() == Token.COMMENT) {
lexer.nextToken();
SQLExpr comment = this.exprParser.primary();
constraint.setComment(comment);
}

return constraint;
}

throw new ParserException("TODO. " + lexer.info());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.alibaba.druid.sql.dialect.mysql.parser;

import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.*;
import com.alibaba.druid.sql.ast.SQLParameter.ParameterType;
import com.alibaba.druid.sql.ast.expr.*;
Expand All @@ -36,6 +37,7 @@
import com.alibaba.druid.sql.dialect.mysql.ast.statement.*;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLockTableStatement.LockType;
import com.alibaba.druid.sql.parser.*;
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
import com.alibaba.druid.util.FnvHash;
import com.alibaba.druid.util.JdbcConstants;

Expand Down Expand Up @@ -2385,12 +2387,14 @@ public SQLInsertStatement parseInsert() {
int pos = lexer.pos();
if (cachedColumns != null
&& lexer.text.startsWith(cachedColumns.columnsString, pos)) {
List<SQLExpr> columns = stmt.getColumns();
List<SQLExpr> cachedColumns2 = cachedColumns.columns;
for (int i = 0, size = cachedColumns2.size(); i < size; i++) {
columns.add(cachedColumns2.get(i).clone());
if (!lexer.isEnabled(SQLParserFeature.OptimizedForParameterized)) {
List<SQLExpr> columns = stmt.getColumns();
List<SQLExpr> cachedColumns2 = cachedColumns.columns;
for (int i = 0, size = cachedColumns2.size(); i < size; i++) {
columns.add(cachedColumns2.get(i).clone());
}
}
stmt.setColumnsString(cachedColumns.columnsString);
stmt.setColumnsString(cachedColumns.columnsFormattedString);
int p2 = pos + cachedColumns.columnsString.length();
lexer.reset(p2);
lexer.nextToken();
Expand Down Expand Up @@ -2449,8 +2453,14 @@ public SQLInsertStatement parseInsert() {
clonedColumns.add(columns.get(i).clone());
}

insertColumnsCache.put(tableName.hashCode64(), columnsString, clonedColumns);
stmt.setColumnsString(columnsString);
StringBuilder buf = new StringBuilder();
SQLASTOutputVisitor outputVisitor = SQLUtils.createOutputVisitor(buf, dbType);
outputVisitor.printInsertColumns(columns);

String formattedColumnsString = buf.toString();

insertColumnsCache.put(tableName.hashCode64(), columnsString, formattedColumnsString, clonedColumns);
stmt.setColumnsString(formattedColumnsString);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -859,27 +859,32 @@ public boolean visit(MySqlInsertStatement x) {
tableSource.accept(this);
}

List<SQLExpr> columns = x.getColumns();
if (columns.size() > 0) {
this.indentCount++;
print0(" (");
for (int i = 0, size = columns.size(); i < size; ++i) {
if (i != 0) {
if (i % 5 == 0) {
println();
String columnsString = x.getColumnsString();
if (columnsString != null) {
print0(columnsString);
} else {
List<SQLExpr> columns = x.getColumns();
if (columns.size() > 0) {
this.indentCount++;
print0(" (");
for (int i = 0, size = columns.size(); i < size; ++i) {
if (i != 0) {
if (i % 5 == 0) {
println();
}
print0(", ");
}
print0(", ");
}

SQLExpr column = columns.get(i);
if (column instanceof SQLIdentifierExpr) {
print0(((SQLIdentifierExpr) column).getName());
} else {
printExpr(column);
SQLExpr column = columns.get(i);
if (column instanceof SQLIdentifierExpr) {
print0(((SQLIdentifierExpr) column).getName());
} else {
printExpr(column);
}
}
print(')');
this.indentCount--;
}
print(')');
this.indentCount--;
}

List<SQLInsertStatement.ValuesClause> valuesList = x.getValuesList();
Expand Down Expand Up @@ -2682,6 +2687,12 @@ public boolean visit(MySqlUnique x) {
printAndAccept(x.getColumns(), ", ");
print(')');

SQLExpr comment = x.getComment();
if (comment != null) {
print0(" COMMENT ");
comment.accept(this);
}

return false;
}

Expand Down Expand Up @@ -4025,4 +4036,40 @@ protected void printQuery(SQLSelectQuery x) {
x.accept(this);
}
}

public void printInsertColumns(List<SQLExpr> columns) {
final int size = columns.size();
if (size > 0) {
if (size > 5) {
this.indentCount++;
print(' ');
}
print('(');
for (int i = 0; i < size; ++i) {
if (i != 0) {
if (i % 5 == 0) {
println();
}
print0(", ");
}

SQLExpr column = columns.get(i);
if (column instanceof SQLIdentifierExpr) {
visit((SQLIdentifierExpr) column);
} else {
printExpr(column);
}

String dataType = (String) column.getAttribute("dataType");
if (dataType != null) {
print(' ');
print(dataType);
}
}
print(')');
if (size > 5) {
this.indentCount--;
}
}
}
} //
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public final Entry get(long hashCode64) {
return null;
}

public boolean put(long hashCode64, String columnsString, List<SQLExpr> columns) {
public boolean put(long hashCode64, String columnsString, String columnsFormattedString, List<SQLExpr> columns) {
final int bucket = ((int) hashCode64) & indexMask;

for (Entry entry = buckets[bucket]; entry != null; entry = entry.next) {
Expand All @@ -58,7 +58,7 @@ public boolean put(long hashCode64, String columnsString, List<SQLExpr> columns)
}
}

Entry entry = new Entry(hashCode64, columnsString, columns, buckets[bucket]);
Entry entry = new Entry(hashCode64, columnsString, columnsFormattedString, columns, buckets[bucket]);
buckets[bucket] = entry; // 并发是处理时会可能导致缓存丢失,但不影响正确性

return false;
Expand All @@ -67,12 +67,14 @@ public boolean put(long hashCode64, String columnsString, List<SQLExpr> columns)
public final static class Entry {
public final long hashCode64;
public final String columnsString;
public final String columnsFormattedString;
public final List<SQLExpr> columns;
public final Entry next;

public Entry(long hashCode64, String columnsString, List<SQLExpr> columns, Entry next) {
public Entry(long hashCode64, String columnsString, String columnsFormattedString, List<SQLExpr> columns, Entry next) {
this.hashCode64 = hashCode64;
this.columnsString = columnsString;
this.columnsFormattedString = columnsFormattedString;
this.columns = columns;
this.next = next;
}
Expand Down
Loading

0 comments on commit 1cfe3c6

Please sign in to comment.