mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
Merge pull request #2201 from JohnCailj/dev
improved update statement parser for mysql
This commit is contained in:
@@ -36,13 +36,15 @@ public class SQLUpdateStatement extends SQLStatementImpl implements SQLReplaceab
|
||||
protected SQLTableSource tableSource;
|
||||
protected List<SQLExpr> returning;
|
||||
|
||||
protected List<SQLHint> hints;
|
||||
|
||||
// for mysql
|
||||
protected SQLOrderBy orderBy;
|
||||
|
||||
public SQLUpdateStatement(){
|
||||
|
||||
}
|
||||
|
||||
|
||||
public SQLUpdateStatement(String dbType){
|
||||
super (dbType);
|
||||
}
|
||||
@@ -90,7 +92,7 @@ public class SQLUpdateStatement extends SQLStatementImpl implements SQLReplaceab
|
||||
public List<SQLUpdateSetItem> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
|
||||
public void addItem(SQLUpdateSetItem item) {
|
||||
this.items.add(item);
|
||||
item.setParent(this);
|
||||
@@ -115,6 +117,25 @@ public class SQLUpdateStatement extends SQLStatementImpl implements SQLReplaceab
|
||||
this.from = from;
|
||||
}
|
||||
|
||||
public int getHintsSize() {
|
||||
if (hints == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return hints.size();
|
||||
}
|
||||
|
||||
public List<SQLHint> getHints() {
|
||||
if (hints == null) {
|
||||
hints = new ArrayList<SQLHint>(2);
|
||||
}
|
||||
return hints;
|
||||
}
|
||||
|
||||
public void setHints(List<SQLHint> hints) {
|
||||
this.hints = hints;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void output(StringBuffer buf) {
|
||||
SQLASTOutputVisitor visitor = SQLUtils.createOutputVisitor(buf, dbType);
|
||||
@@ -129,6 +150,7 @@ public class SQLUpdateStatement extends SQLStatementImpl implements SQLReplaceab
|
||||
acceptChild(visitor, items);
|
||||
acceptChild(visitor, where);
|
||||
acceptChild(visitor, orderBy);
|
||||
acceptChild(visitor, hints);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
@@ -260,4 +282,34 @@ public class SQLUpdateStatement extends SQLStatementImpl implements SQLReplaceab
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
SQLUpdateStatement that = (SQLUpdateStatement) o;
|
||||
|
||||
if (with != null ? !with.equals(that.with) : that.with != null) return false;
|
||||
if (items != null ? !items.equals(that.items) : that.items != null) return false;
|
||||
if (where != null ? !where.equals(that.where) : that.where != null) return false;
|
||||
if (from != null ? !from.equals(that.from) : that.from != null) return false;
|
||||
if (hints != null ? !hints.equals(that.hints) : that.hints != null) return false;
|
||||
if (tableSource != null ? !tableSource.equals(that.tableSource) : that.tableSource != null) return false;
|
||||
if (returning != null ? !returning.equals(that.returning) : that.returning != null) return false;
|
||||
return orderBy != null ? orderBy.equals(that.orderBy) : that.orderBy == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = with != null ? with.hashCode() : 0;
|
||||
result = 31 * result + (items != null ? items.hashCode() : 0);
|
||||
result = 31 * result + (where != null ? where.hashCode() : 0);
|
||||
result = 31 * result + (from != null ? from.hashCode() : 0);
|
||||
result = 31 * result + (tableSource != null ? tableSource.hashCode() : 0);
|
||||
result = 31 * result + (returning != null ? returning.hashCode() : 0);
|
||||
result = 31 * result + (orderBy != null ? orderBy.hashCode() : 0);
|
||||
result = 31 * result + (hints != null ? hints.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,6 +323,10 @@ public class MySqlSelectParser extends SQLSelectParser {
|
||||
}
|
||||
}
|
||||
|
||||
while (lexer.token() == Token.HINT) {
|
||||
this.exprParser.parseHints(update.getHints());
|
||||
}
|
||||
|
||||
SQLSelectParser selectParser = this.exprParser.createSelectParser();
|
||||
SQLTableSource updateTableSource = selectParser.parseTableSource();
|
||||
update.setTableSource(updateTableSource);
|
||||
|
||||
@@ -1594,6 +1594,12 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
print0(ucase ? "IGNORE " : "ignore ");
|
||||
}
|
||||
|
||||
|
||||
if (x.getHints() != null && x.getHints().size() > 0) {
|
||||
printAndAccept(x.getHints(), " ");
|
||||
print0(" ");
|
||||
}
|
||||
|
||||
if (x.isCommitOnSuccess()) {
|
||||
print0(ucase ? "COMMIT_ON_SUCCESS " : "commit_on_success ");
|
||||
}
|
||||
|
||||
@@ -2818,7 +2818,13 @@ public class SQLExprParser extends SQLParser {
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public void parseHints(List hints) {
|
||||
if (lexer.token == Token.HINT) {
|
||||
hints.add(new SQLCommentHint(lexer.stringVal()));
|
||||
SQLCommentHint hint = new SQLCommentHint(lexer.stringVal());
|
||||
|
||||
if (lexer.commentCount > 0) {
|
||||
hint.addBeforeComment(lexer.comments);
|
||||
}
|
||||
|
||||
hints.add(hint);
|
||||
lexer.nextToken();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3257,6 +3257,11 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
}
|
||||
|
||||
public boolean visit(SQLCommentHint x) {
|
||||
if (x.hasBeforeComment()) {
|
||||
printlnComment(x.getBeforeCommentsDirect());
|
||||
print0(" ");
|
||||
}
|
||||
|
||||
print0("/*");
|
||||
print0(x.getText());
|
||||
print0("*/");
|
||||
|
||||
@@ -48,4 +48,13 @@ public class MySqlHintStatementTest extends TestCase {
|
||||
+ "\n"
|
||||
+ "\n/*!40101 SET character_set_client = @saved_cs_client */;", rs);
|
||||
}
|
||||
public void test_1() throws Exception {
|
||||
String sql = "update "
|
||||
+ "/*MS-MRCHISHUB-MH-MESSAGE-UPDATE*/ "
|
||||
+ "/*+ INDEX(mh_message primary) */ "
|
||||
+ "mh_message set gmt_modified = now(),status= '099' where id = 1244918;";
|
||||
String rs = SQLUtils.formatMySql(sql);
|
||||
assertEquals("UPDATE /*MS-MRCHISHUB-MH-MESSAGE-UPDATE*/ /*+ INDEX(mh_message primary) */ mh_message\n"
|
||||
+ "SET gmt_modified = now(), status = '099'\n" + "WHERE id = 1244918;", rs);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -52,7 +52,7 @@ public class MySqlSelectTest_49_for_update_no_wait extends MysqlTest {
|
||||
|
||||
{
|
||||
String output = SQLUtils.toMySqlString(stmt);
|
||||
assertEquals("SELECT /*+INDEX(AR_II_M_004 PRIMARY) */ tnt_inst_id, ar_no, ar_nm, ar_tp_code, ar_entity_type\n" +
|
||||
assertEquals("SELECT /*MS-ARCORE-AR-II-M-QUERY-IN-LOCK-BY-AR-NOS*/ /*+INDEX(AR_II_M_004 PRIMARY) */ tnt_inst_id, ar_no, ar_nm, ar_tp_code, ar_entity_type\n" +
|
||||
"FROM tb_001\n" +
|
||||
"WHERE tnt_inst_id = ?\n" +
|
||||
"\tAND ar_no IN (?)\n" +
|
||||
@@ -61,7 +61,7 @@ public class MySqlSelectTest_49_for_update_no_wait extends MysqlTest {
|
||||
}
|
||||
{
|
||||
String output = SQLUtils.toMySqlString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION);
|
||||
assertEquals("select /*+INDEX(AR_II_M_004 PRIMARY) */ tnt_inst_id, ar_no, ar_nm, ar_tp_code, ar_entity_type\n" +
|
||||
assertEquals("select /*MS-ARCORE-AR-II-M-QUERY-IN-LOCK-BY-AR-NOS*/ /*+INDEX(AR_II_M_004 PRIMARY) */ tnt_inst_id, ar_no, ar_nm, ar_tp_code, ar_entity_type\n" +
|
||||
"from tb_001\n" +
|
||||
"where tnt_inst_id = ?\n" +
|
||||
"\tand ar_no in (?)\n" +
|
||||
@@ -71,7 +71,7 @@ public class MySqlSelectTest_49_for_update_no_wait extends MysqlTest {
|
||||
|
||||
{
|
||||
String output = SQLUtils.toMySqlString(stmt, new SQLUtils.FormatOption(true, true, true));
|
||||
assertEquals("SELECT /*+INDEX(AR_II_M_004 PRIMARY) */ tnt_inst_id, ar_no, ar_nm, ar_tp_code, ar_entity_type\n" +
|
||||
assertEquals("SELECT /*MS-ARCORE-AR-II-M-QUERY-IN-LOCK-BY-AR-NOS*/ /*+INDEX(AR_II_M_004 PRIMARY) */ tnt_inst_id, ar_no, ar_nm, ar_tp_code, ar_entity_type\n" +
|
||||
"FROM tb\n" +
|
||||
"WHERE tnt_inst_id = ?\n" +
|
||||
"\tAND ar_no IN (?)\n" +
|
||||
|
||||
@@ -66,7 +66,7 @@ public class OracleSelectTest104 extends OracleTest {
|
||||
{
|
||||
String text = SQLUtils.toOracleString(stmt);
|
||||
|
||||
assertEquals("SELECT /*+ cursor_sharing_exact dynamic_sampling(0) no_sql_tune no_monitoring optimizer_features_enable(default) */ SUM(C1)\n" +
|
||||
assertEquals("SELECT /* DS_SVC */ /*+ cursor_sharing_exact dynamic_sampling(0) no_sql_tune no_monitoring optimizer_features_enable(default) */ SUM(C1)\n" +
|
||||
"FROM (\n" +
|
||||
"\tSELECT /*+ qb_name(\"innerQuery\") */ 1 AS C1\n" +
|
||||
"\tFROM SYS.\"X$KZSPR\" \"X$KZSPR\"\n" +
|
||||
|
||||
Reference in New Issue
Block a user