mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improved sql parser
This commit is contained in:
@@ -25,15 +25,14 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
*/
|
||||
public class MysqlForeignKey extends SQLForeignKeyImpl {
|
||||
|
||||
private SQLName indexName;
|
||||
private SQLName indexName;
|
||||
|
||||
private boolean hasConstraint;
|
||||
private boolean hasConstraint;
|
||||
|
||||
private Match referenceMatch;
|
||||
private Match referenceMatch;
|
||||
|
||||
private On referenceOn;
|
||||
|
||||
private Option referenceOption;
|
||||
protected Option onUpdate;
|
||||
protected Option onDelete;
|
||||
|
||||
public SQLName getIndexName() {
|
||||
return indexName;
|
||||
@@ -78,25 +77,25 @@ public class MysqlForeignKey extends SQLForeignKeyImpl {
|
||||
this.referenceMatch = referenceMatch;
|
||||
}
|
||||
|
||||
public On getReferenceOn() {
|
||||
return referenceOn;
|
||||
public Option getOnUpdate() {
|
||||
return onUpdate;
|
||||
}
|
||||
|
||||
public void setReferenceOn(On referenceOn) {
|
||||
this.referenceOn = referenceOn;
|
||||
public void setOnUpdate(Option onUpdate) {
|
||||
this.onUpdate = onUpdate;
|
||||
}
|
||||
|
||||
public Option getReferenceOption() {
|
||||
return referenceOption;
|
||||
public Option getOnDelete() {
|
||||
return onDelete;
|
||||
}
|
||||
|
||||
public void setReferenceOption(Option referenceOption) {
|
||||
this.referenceOption = referenceOption;
|
||||
public void setOnDelete(Option onDelete) {
|
||||
this.onDelete = onDelete;
|
||||
}
|
||||
|
||||
public static enum Option {
|
||||
|
||||
RESTRICT("RESTRICT"), CASCADE("CASCADE"), SET_NULL("SET NULL"), NO_ACTION("NO ACTION");
|
||||
RESTRICT("RESTRICT"), CASCADE("CASCADE"), SET_NULL("SET NULL"), NO_ACTION("NO ACTION");
|
||||
|
||||
public final String name;
|
||||
public final String name_lcase;
|
||||
@@ -113,27 +112,25 @@ public class MysqlForeignKey extends SQLForeignKeyImpl {
|
||||
}
|
||||
|
||||
public static enum Match {
|
||||
FULL("FULL"),
|
||||
PARTIAL("PARTIAL"),
|
||||
SIMPLE("SIMPLE");
|
||||
|
||||
FULL("FULL"), PARTIAL("PARTIAL"), SIMPLE("SIMPLE");
|
||||
|
||||
public final String name;
|
||||
public final String name_lcase;
|
||||
|
||||
Match(String name) {
|
||||
|
||||
Match(String name){
|
||||
this.name = name;
|
||||
this.name_lcase = name.toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
public static enum On {
|
||||
DELETE("DELETE"), //
|
||||
UPDATE("UPDATE");
|
||||
|
||||
DELETE("DELETE"), //
|
||||
UPDATE("UPDATE");
|
||||
|
||||
public final String name;
|
||||
public final String name_lcase;
|
||||
|
||||
On(String name) {
|
||||
|
||||
On(String name){
|
||||
this.name = name;
|
||||
this.name_lcase = name.toLowerCase();
|
||||
}
|
||||
|
||||
+8
-1
@@ -116,7 +116,8 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
|
||||
} else if (lexer.token() == Token.CONSTRAINT //
|
||||
|| lexer.token() == Token.PRIMARY //
|
||||
|| lexer.token() == Token.UNIQUE) {
|
||||
stmt.getTableElementList().add(parseConstraint());
|
||||
SQLTableConstraint constraint = this.parseConstraint();
|
||||
stmt.getTableElementList().add(constraint);
|
||||
} else if (lexer.token() == (Token.INDEX)) {
|
||||
lexer.nextToken();
|
||||
|
||||
@@ -144,6 +145,12 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
|
||||
}
|
||||
}
|
||||
accept(Token.RPAREN);
|
||||
|
||||
if (identifierEquals("USING")) {
|
||||
lexer.nextToken();
|
||||
idx.setIndexType(lexer.stringVal());
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
stmt.getTableElementList().add(idx);
|
||||
} else if (lexer.token() == (Token.KEY)) {
|
||||
|
||||
@@ -41,7 +41,6 @@ import com.alibaba.druid.sql.dialect.mysql.ast.MySqlPrimaryKey;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlUnique;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.MysqlForeignKey;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.MysqlForeignKey.Match;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.MysqlForeignKey.On;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.MysqlForeignKey.Option;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlCharExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlExtractExpr;
|
||||
@@ -834,39 +833,56 @@ public class MySqlExprParser extends SQLExprParser {
|
||||
}
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.ON) {
|
||||
while (lexer.token() == Token.ON) {
|
||||
lexer.nextToken();
|
||||
|
||||
if (lexer.token() == Token.DELETE) {
|
||||
fk.setReferenceOn(On.DELETE);
|
||||
lexer.nextToken();
|
||||
|
||||
Option option = parseReferenceOption();
|
||||
fk.setOnDelete(option);
|
||||
} else if (lexer.token() == Token.UPDATE) {
|
||||
fk.setReferenceOn(On.UPDATE);
|
||||
lexer.nextToken();
|
||||
|
||||
Option option = parseReferenceOption();
|
||||
fk.setOnUpdate(option);
|
||||
} else {
|
||||
throw new ParserException("syntax error, expect DELETE or UPDATE, actual " + lexer.token() + " "
|
||||
+ lexer.stringVal());
|
||||
}
|
||||
lexer.nextToken();
|
||||
|
||||
if (lexer.token() == Token.RESTRICT) {
|
||||
fk.setReferenceOption(Option.RESTRICT);
|
||||
} else if (identifierEquals("CASCADE")) {
|
||||
fk.setReferenceOption(Option.CASCADE);
|
||||
} else if (lexer.token() == Token.SET) {
|
||||
accept(Token.NULL);
|
||||
fk.setReferenceOption(Option.SET_NULL);
|
||||
} else if (identifierEquals("ON")) {
|
||||
lexer.nextToken();
|
||||
if (identifierEquals("ACTION")) {
|
||||
fk.setReferenceOption(Option.NO_ACTION);
|
||||
} else {
|
||||
throw new ParserException("syntax error, expect ACTION, actual " + lexer.token() + " "
|
||||
+ lexer.stringVal());
|
||||
}
|
||||
}
|
||||
lexer.nextToken();
|
||||
}
|
||||
return fk;
|
||||
}
|
||||
|
||||
protected Option parseReferenceOption() {
|
||||
Option option;
|
||||
if (lexer.token() == Token.RESTRICT || identifierEquals("RESTRICT")) {
|
||||
option = Option.RESTRICT;
|
||||
lexer.nextToken();
|
||||
} else if (identifierEquals("CASCADE")) {
|
||||
option = Option.CASCADE;
|
||||
lexer.nextToken();
|
||||
} else if (lexer.token() == Token.SET) {
|
||||
lexer.nextToken();
|
||||
accept(Token.NULL);
|
||||
option = Option.SET_NULL;
|
||||
} else if (identifierEquals("ON")) {
|
||||
lexer.nextToken();
|
||||
if (identifierEquals("ACTION")) {
|
||||
option = Option.NO_ACTION;
|
||||
lexer.nextToken();
|
||||
} else {
|
||||
throw new ParserException("syntax error, expect ACTION, actual " + lexer.token() + " "
|
||||
+ lexer.stringVal());
|
||||
}
|
||||
} else {
|
||||
throw new ParserException("syntax error, expect ACTION, actual " + lexer.token() + " "
|
||||
+ lexer.stringVal());
|
||||
}
|
||||
|
||||
return option;
|
||||
}
|
||||
|
||||
protected SQLAggregateExpr parseAggregateExprRest(SQLAggregateExpr aggregateExpr) {
|
||||
if (lexer.token() == Token.ORDER) {
|
||||
SQLOrderBy orderBy = this.parseOrderBy();
|
||||
|
||||
@@ -54,7 +54,6 @@ import com.alibaba.druid.sql.dialect.mysql.ast.MySqlPrimaryKey;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlUnique;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlUseIndexHint;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.MysqlForeignKey;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.MysqlForeignKey.Option;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCaseStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCaseStatement.MySqlWhenStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCursorDeclareStatement;
|
||||
@@ -2816,15 +2815,14 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
print0(ucase ? match.name : match.name_lcase);
|
||||
}
|
||||
|
||||
MysqlForeignKey.On on = x.getReferenceOn();
|
||||
if (on != null) {
|
||||
print0(ucase ? " ON " : " on ");
|
||||
print0(ucase ? on.name : on.name_lcase);
|
||||
print(' ');
|
||||
Option option = x.getReferenceOption();
|
||||
if (option != null) {
|
||||
print0(ucase ? option.name : option.name_lcase);
|
||||
}
|
||||
if (x.getOnDelete() != null) {
|
||||
print0(ucase ? " ON DELETE " : " on delete ");
|
||||
print0(ucase ? x.getOnDelete().name : x.getOnDelete().name_lcase);
|
||||
}
|
||||
|
||||
if (x.getOnDelete() != null) {
|
||||
print0(ucase ? " ON UPDATE " : " on update ");
|
||||
print0(ucase ? x.getOnDelete().name : x.getOnDelete().name_lcase);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
+3
-3
@@ -196,7 +196,7 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
|
||||
ident = expr.toString();
|
||||
}
|
||||
|
||||
if (subQueryMap.containsKey(ident)) {
|
||||
if (containsSubQuery(ident)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -575,7 +575,7 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
|
||||
if (table != null) {
|
||||
this.aliasMap.put(x.getAlias(), table);
|
||||
}
|
||||
this.subQueryMap.put(x.getAlias(), x.getSelect());
|
||||
addSubQuery(x.getAlias(), x.getSelect());
|
||||
this.setCurrentTable(x.getAlias());
|
||||
}
|
||||
|
||||
@@ -650,7 +650,7 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
|
||||
|
||||
if (alias != null) {
|
||||
putAliasMap(aliasMap, alias, null);
|
||||
subQueryMap.put(alias, x.getSubQuery());
|
||||
addSubQuery(alias, x.getSubQuery());
|
||||
}
|
||||
}
|
||||
x.getSubQuery().accept(this);
|
||||
|
||||
+1
-1
@@ -107,7 +107,7 @@ public class PGSchemaStatVisitor extends SchemaStatVisitor implements PGASTVisit
|
||||
|
||||
if (alias != null) {
|
||||
aliasMap.put(alias, null);
|
||||
subQueryMap.put(alias, x.getQuery());
|
||||
addSubQuery(alias, x.getQuery());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user