mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
sql parser improved support db2 merge syntax. for issue #1324
This commit is contained in:
+5
-5
@@ -13,21 +13,21 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.oracle.ast.clause;
|
||||
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.dialect.oracle.ast.OracleSQLObjectImpl;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
|
||||
import com.alibaba.druid.sql.ast.SQLObjectImpl;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class OracleErrorLoggingClause extends OracleSQLObjectImpl {
|
||||
public class SQLErrorLoggingClause extends SQLObjectImpl {
|
||||
|
||||
private SQLName into;
|
||||
private SQLExpr simpleExpression;
|
||||
private SQLExpr limit;
|
||||
|
||||
@Override
|
||||
public void accept0(OracleASTVisitor visitor) {
|
||||
public void accept0(SQLASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, into);
|
||||
acceptChild(visitor, simpleExpression);
|
||||
+13
-16
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.oracle.ast.stmt;
|
||||
package com.alibaba.druid.sql.ast.statement;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -21,14 +21,11 @@ import java.util.List;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLHint;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleErrorLoggingClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
|
||||
import com.alibaba.druid.sql.ast.SQLObjectImpl;
|
||||
import com.alibaba.druid.sql.ast.SQLStatementImpl;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class OracleMergeStatement extends OracleStatementImpl {
|
||||
public class SQLMergeStatement extends SQLStatementImpl {
|
||||
|
||||
private final List<SQLHint> hints = new ArrayList<SQLHint>();
|
||||
|
||||
@@ -38,9 +35,9 @@ public class OracleMergeStatement extends OracleStatementImpl {
|
||||
private SQLExpr on;
|
||||
private MergeUpdateClause updateClause;
|
||||
private MergeInsertClause insertClause;
|
||||
private OracleErrorLoggingClause errorLoggingClause;
|
||||
private SQLErrorLoggingClause errorLoggingClause;
|
||||
|
||||
public void accept0(OracleASTVisitor visitor) {
|
||||
public void accept0(SQLASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, into);
|
||||
acceptChild(visitor, using);
|
||||
@@ -107,11 +104,11 @@ public class OracleMergeStatement extends OracleStatementImpl {
|
||||
this.insertClause = insertClause;
|
||||
}
|
||||
|
||||
public OracleErrorLoggingClause getErrorLoggingClause() {
|
||||
public SQLErrorLoggingClause getErrorLoggingClause() {
|
||||
return errorLoggingClause;
|
||||
}
|
||||
|
||||
public void setErrorLoggingClause(OracleErrorLoggingClause errorLoggingClause) {
|
||||
public void setErrorLoggingClause(SQLErrorLoggingClause errorLoggingClause) {
|
||||
this.errorLoggingClause = errorLoggingClause;
|
||||
}
|
||||
|
||||
@@ -119,7 +116,7 @@ public class OracleMergeStatement extends OracleStatementImpl {
|
||||
return hints;
|
||||
}
|
||||
|
||||
public static class MergeUpdateClause extends OracleSQLObjectImpl {
|
||||
public static class MergeUpdateClause extends SQLObjectImpl {
|
||||
|
||||
private List<SQLUpdateSetItem> items = new ArrayList<SQLUpdateSetItem>();
|
||||
private SQLExpr where;
|
||||
@@ -153,7 +150,7 @@ public class OracleMergeStatement extends OracleStatementImpl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept0(OracleASTVisitor visitor) {
|
||||
public void accept0(SQLASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, items);
|
||||
acceptChild(visitor, where);
|
||||
@@ -164,14 +161,14 @@ public class OracleMergeStatement extends OracleStatementImpl {
|
||||
|
||||
}
|
||||
|
||||
public static class MergeInsertClause extends OracleSQLObjectImpl {
|
||||
public static class MergeInsertClause extends SQLObjectImpl {
|
||||
|
||||
private List<SQLExpr> columns = new ArrayList<SQLExpr>();
|
||||
private List<SQLExpr> values = new ArrayList<SQLExpr>();
|
||||
private SQLExpr where;
|
||||
|
||||
@Override
|
||||
public void accept0(OracleASTVisitor visitor) {
|
||||
public void accept0(SQLASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, columns);
|
||||
acceptChild(visitor, columns);
|
||||
@@ -40,6 +40,9 @@ public class DB2Lexer extends Lexer {
|
||||
map.put("CONCAT", Token.CONCAT);
|
||||
map.put("CONTINUE", Token.CONTINUE);
|
||||
map.put("IDENTITY", Token.IDENTITY);
|
||||
map.put("MERGE", Token.MERGE);
|
||||
map.put("USING", Token.USING);
|
||||
map.put("MATCHED", Token.MATCHED);
|
||||
|
||||
DEFAULT_DB2_KEYWORDS = new Keywords(map);
|
||||
}
|
||||
|
||||
+4
-4
@@ -19,8 +19,8 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLHint;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLErrorLoggingClause;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleErrorLoggingClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleReturningClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleOutputVisitor;
|
||||
@@ -29,7 +29,7 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
public class OracleInsertStatement extends SQLInsertStatement implements OracleStatement {
|
||||
|
||||
private OracleReturningClause returning;
|
||||
private OracleErrorLoggingClause errorLogging;
|
||||
private SQLErrorLoggingClause errorLogging;
|
||||
private List<SQLHint> hints = new ArrayList<SQLHint>();
|
||||
|
||||
public List<SQLHint> getHints() {
|
||||
@@ -48,11 +48,11 @@ public class OracleInsertStatement extends SQLInsertStatement implements OracleS
|
||||
this.returning = returning;
|
||||
}
|
||||
|
||||
public OracleErrorLoggingClause getErrorLogging() {
|
||||
public SQLErrorLoggingClause getErrorLogging() {
|
||||
return errorLogging;
|
||||
}
|
||||
|
||||
public void setErrorLogging(OracleErrorLoggingClause errorLogging) {
|
||||
public void setErrorLogging(SQLErrorLoggingClause errorLogging) {
|
||||
this.errorLogging = errorLogging;
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -20,11 +20,11 @@ import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLHint;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLErrorLoggingClause;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertInto;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObject;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleErrorLoggingClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleReturningClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
@@ -158,7 +158,7 @@ public class OracleMultiInsertStatement extends OracleStatementImpl {
|
||||
public static class InsertIntoClause extends SQLInsertInto implements OracleSQLObject, Entry {
|
||||
|
||||
private OracleReturningClause returning;
|
||||
private OracleErrorLoggingClause errorLogging;
|
||||
private SQLErrorLoggingClause errorLogging;
|
||||
|
||||
public InsertIntoClause(){
|
||||
|
||||
@@ -172,11 +172,11 @@ public class OracleMultiInsertStatement extends OracleStatementImpl {
|
||||
this.returning = returning;
|
||||
}
|
||||
|
||||
public OracleErrorLoggingClause getErrorLogging() {
|
||||
public SQLErrorLoggingClause getErrorLogging() {
|
||||
return errorLogging;
|
||||
}
|
||||
|
||||
public void setErrorLogging(OracleErrorLoggingClause errorLogging) {
|
||||
public void setErrorLogging(SQLErrorLoggingClause errorLogging) {
|
||||
this.errorLogging = errorLogging;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,11 +51,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSetStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleErrorLoggingClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleReturningClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterIndexStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterProcedureStatement;
|
||||
@@ -91,11 +87,9 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLabelStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLockTableStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLockTableStatement.LockMode;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePLSQLCommitStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSavePointStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelect;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSetTransactionStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleStatement;
|
||||
import com.alibaba.druid.sql.parser.Lexer;
|
||||
@@ -119,10 +113,6 @@ public class OracleStatementParser extends SQLStatementParser {
|
||||
return (OracleExprParser) exprParser;
|
||||
}
|
||||
|
||||
public void parseHints(List<SQLHint> hints) {
|
||||
this.getExprParser().parseHints(hints);
|
||||
}
|
||||
|
||||
public OracleCreateTableParser getSQLCreateTableParser() {
|
||||
return new OracleCreateTableParser(lexer);
|
||||
}
|
||||
@@ -1100,119 +1090,6 @@ public class OracleStatementParser extends SQLStatementParser {
|
||||
return new OracleSelectParser(this.exprParser);
|
||||
}
|
||||
|
||||
public OracleMergeStatement parseMerge() {
|
||||
accept(Token.MERGE);
|
||||
|
||||
OracleMergeStatement stmt = new OracleMergeStatement();
|
||||
|
||||
parseHints(stmt.getHints());
|
||||
|
||||
accept(Token.INTO);
|
||||
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
OracleSelect select = this.createSQLSelectParser().select();
|
||||
SQLSubqueryTableSource tableSource = new SQLSubqueryTableSource(select);
|
||||
stmt.setInto(tableSource);
|
||||
accept(Token.RPAREN);
|
||||
} else {
|
||||
stmt.setInto(exprParser.name());
|
||||
}
|
||||
|
||||
stmt.setAlias(as());
|
||||
|
||||
accept(Token.USING);
|
||||
|
||||
SQLTableSource using = this.createSQLSelectParser().parseTableSource();
|
||||
stmt.setUsing(using);
|
||||
|
||||
accept(Token.ON);
|
||||
stmt.setOn(exprParser.expr());
|
||||
|
||||
boolean insertFlag = false;
|
||||
if (lexer.token() == Token.WHEN) {
|
||||
lexer.nextToken();
|
||||
if (lexer.token() == Token.MATCHED) {
|
||||
OracleMergeStatement.MergeUpdateClause updateClause = new OracleMergeStatement.MergeUpdateClause();
|
||||
lexer.nextToken();
|
||||
accept(Token.THEN);
|
||||
accept(Token.UPDATE);
|
||||
accept(Token.SET);
|
||||
|
||||
for (;;) {
|
||||
SQLUpdateSetItem item = this.exprParser.parseUpdateSetItem();
|
||||
|
||||
updateClause.addItem(item);
|
||||
item.setParent(updateClause);
|
||||
|
||||
if (lexer.token() == (Token.COMMA)) {
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.WHERE) {
|
||||
lexer.nextToken();
|
||||
updateClause.setWhere(exprParser.expr());
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.DELETE) {
|
||||
lexer.nextToken();
|
||||
accept(Token.WHERE);
|
||||
updateClause.setWhere(exprParser.expr());
|
||||
}
|
||||
|
||||
stmt.setUpdateClause(updateClause);
|
||||
} else if (lexer.token() == Token.NOT) {
|
||||
lexer.nextToken();
|
||||
insertFlag = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!insertFlag) {
|
||||
if (lexer.token() == Token.WHEN) {
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.NOT) {
|
||||
lexer.nextToken();
|
||||
insertFlag = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (insertFlag) {
|
||||
OracleMergeStatement.MergeInsertClause insertClause = new OracleMergeStatement.MergeInsertClause();
|
||||
|
||||
accept(Token.MATCHED);
|
||||
accept(Token.THEN);
|
||||
accept(Token.INSERT);
|
||||
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
accept(Token.LPAREN);
|
||||
exprParser.exprList(insertClause.getColumns(), insertClause);
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
accept(Token.VALUES);
|
||||
accept(Token.LPAREN);
|
||||
exprParser.exprList(insertClause.getValues(), insertClause);
|
||||
accept(Token.RPAREN);
|
||||
|
||||
if (lexer.token() == Token.WHERE) {
|
||||
lexer.nextToken();
|
||||
insertClause.setWhere(exprParser.expr());
|
||||
}
|
||||
|
||||
stmt.setInsertClause(insertClause);
|
||||
}
|
||||
|
||||
OracleErrorLoggingClause errorClause = parseErrorLoggingClause();
|
||||
stmt.setErrorLoggingClause(errorClause);
|
||||
|
||||
return stmt;
|
||||
}
|
||||
|
||||
public OracleStatement parseInsert() {
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
OracleInsertStatement stmt = new OracleInsertStatement();
|
||||
@@ -1322,34 +1199,6 @@ public class OracleStatementParser extends SQLStatementParser {
|
||||
return stmt;
|
||||
}
|
||||
|
||||
private OracleErrorLoggingClause parseErrorLoggingClause() {
|
||||
if (identifierEquals("LOG")) {
|
||||
OracleErrorLoggingClause errorClause = new OracleErrorLoggingClause();
|
||||
|
||||
lexer.nextToken();
|
||||
accept(Token.ERRORS);
|
||||
if (lexer.token() == Token.INTO) {
|
||||
lexer.nextToken();
|
||||
errorClause.setInto(exprParser.name());
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
errorClause.setSimpleExpression(exprParser.expr());
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.REJECT) {
|
||||
lexer.nextToken();
|
||||
accept(Token.LIMIT);
|
||||
errorClause.setLimit(exprParser.expr());
|
||||
}
|
||||
|
||||
return errorClause;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public OracleReturningClause parseReturningClause() {
|
||||
OracleReturningClause clause = null;
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOf
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfSnapshotClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.VersionsFlashbackQueryClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleErrorLoggingClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleLobStorageClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleReturningClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleStorageClause;
|
||||
@@ -79,7 +78,6 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleGotoStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLabelStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLockTableStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement.ConditionalInsertClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement.ConditionalInsertClauseItem;
|
||||
@@ -269,22 +267,6 @@ public interface OracleASTVisitor extends SQLASTVisitor {
|
||||
|
||||
void endVisit(ModelClause x);
|
||||
|
||||
boolean visit(OracleMergeStatement x);
|
||||
|
||||
void endVisit(OracleMergeStatement x);
|
||||
|
||||
boolean visit(OracleMergeStatement.MergeUpdateClause x);
|
||||
|
||||
void endVisit(OracleMergeStatement.MergeUpdateClause x);
|
||||
|
||||
boolean visit(OracleMergeStatement.MergeInsertClause x);
|
||||
|
||||
void endVisit(OracleMergeStatement.MergeInsertClause x);
|
||||
|
||||
boolean visit(OracleErrorLoggingClause x);
|
||||
|
||||
void endVisit(OracleErrorLoggingClause x);
|
||||
|
||||
boolean visit(OracleReturningClause x);
|
||||
|
||||
void endVisit(OracleReturningClause x);
|
||||
|
||||
+2
-23
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.oracle.visitor;
|
||||
|
||||
import com.alibaba.druid.sql.ast.statement.SQLMergeStatement.MergeInsertClause;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLMergeStatement.MergeUpdateClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalDay;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalYear;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeTimestamp;
|
||||
@@ -31,7 +33,6 @@ import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.ModelColumnCl
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.ModelRulesClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.QueryPartitionClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.ReturnRowsClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleErrorLoggingClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleLobStorageClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleReturningClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleStorageClause;
|
||||
@@ -87,9 +88,6 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleGotoStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLabelStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLockTableStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement.MergeInsertClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement.MergeUpdateClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement.ConditionalInsertClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement.ConditionalInsertClauseItem;
|
||||
@@ -553,15 +551,6 @@ public class OracleASTVisitorAdapter extends SQLASTVisitorAdapter implements Ora
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleMergeStatement x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleMergeStatement x) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MergeUpdateClause x) {
|
||||
return true;
|
||||
@@ -582,16 +571,6 @@ public class OracleASTVisitorAdapter extends SQLASTVisitorAdapter implements Ora
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleErrorLoggingClause x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleErrorLoggingClause x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleReturningClause x) {
|
||||
return true;
|
||||
|
||||
@@ -65,7 +65,6 @@ import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.ModelRulesCla
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.QueryPartitionClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.ReferenceModelClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.ReturnRowsClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleErrorLoggingClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleLobStorageClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleReturningClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleStorageClause;
|
||||
@@ -126,9 +125,6 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleGotoStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLabelStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLockTableStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement.MergeInsertClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement.MergeUpdateClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement.ConditionalInsertClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement.ConditionalInsertClauseItem;
|
||||
@@ -1285,138 +1281,6 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleMergeStatement x) {
|
||||
print0(ucase ? "MERGE " : "merge ");
|
||||
if (x.getHints().size() > 0) {
|
||||
printAndAccept(x.getHints(), ", ");
|
||||
print(' ');
|
||||
}
|
||||
|
||||
print0(ucase ? "INTO " : "into ");
|
||||
x.getInto().accept(this);
|
||||
|
||||
if (x.getAlias() != null) {
|
||||
print(' ');
|
||||
print0(x.getAlias());
|
||||
}
|
||||
|
||||
println();
|
||||
print0(ucase ? "USING " : "using ");
|
||||
x.getUsing().accept(this);
|
||||
|
||||
print0(ucase ? " ON (" : " on (");
|
||||
x.getOn().accept(this);
|
||||
print0(") ");
|
||||
|
||||
if (x.getUpdateClause() != null) {
|
||||
println();
|
||||
x.getUpdateClause().accept(this);
|
||||
}
|
||||
|
||||
if (x.getInsertClause() != null) {
|
||||
println();
|
||||
x.getInsertClause().accept(this);
|
||||
}
|
||||
|
||||
if (x.getErrorLoggingClause() != null) {
|
||||
println();
|
||||
x.getErrorLoggingClause().accept(this);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleMergeStatement x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MergeUpdateClause x) {
|
||||
print0(ucase ? "WHEN MATCHED THEN UPDATE SET " : "when matched then update set ");
|
||||
printAndAccept(x.getItems(), ", ");
|
||||
if (x.getWhere() != null) {
|
||||
incrementIndent();
|
||||
println();
|
||||
print0(ucase ? "WHERE " : "where ");
|
||||
x.getWhere().setParent(x);
|
||||
x.getWhere().accept(this);
|
||||
decrementIndent();
|
||||
}
|
||||
|
||||
if (x.getDeleteWhere() != null) {
|
||||
incrementIndent();
|
||||
println();
|
||||
print0(ucase ? "DELETE WHERE " : "delete where ");
|
||||
x.getDeleteWhere().setParent(x);
|
||||
x.getDeleteWhere().accept(this);
|
||||
decrementIndent();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(MergeUpdateClause x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MergeInsertClause x) {
|
||||
print0(ucase ? "WHEN NOT MATCHED THEN INSERT" : "when not matched then insert");
|
||||
if (x.getColumns().size() > 0) {
|
||||
print(' ');
|
||||
printAndAccept(x.getColumns(), ", ");
|
||||
}
|
||||
print0(ucase ? " VALUES (" : " values (");
|
||||
printAndAccept(x.getValues(), ", ");
|
||||
print(')');
|
||||
if (x.getWhere() != null) {
|
||||
incrementIndent();
|
||||
println();
|
||||
print0(ucase ? "WHERE " : "where ");
|
||||
x.getWhere().setParent(x);
|
||||
x.getWhere().accept(this);
|
||||
decrementIndent();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(MergeInsertClause x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleErrorLoggingClause x) {
|
||||
print0(ucase ? "LOG ERRORS " : "log errors ");
|
||||
if (x.getInto() != null) {
|
||||
print0(ucase ? "INTO " : "into ");
|
||||
x.getInto().accept(this);
|
||||
print(' ');
|
||||
}
|
||||
|
||||
if (x.getSimpleExpression() != null) {
|
||||
print('(');
|
||||
x.getSimpleExpression().accept(this);
|
||||
print(')');
|
||||
}
|
||||
|
||||
if (x.getLimit() != null) {
|
||||
print0(ucase ? " REJECT LIMIT " : " reject limit ");
|
||||
x.getLimit().accept(this);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleErrorLoggingClause x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleReturningClause x) {
|
||||
print0(ucase ? "RETURNING " : "returning ");
|
||||
|
||||
+2
-57
@@ -34,6 +34,8 @@ import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLForeignKeyImpl;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLMergeStatement.MergeInsertClause;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLMergeStatement.MergeUpdateClause;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
||||
@@ -54,7 +56,6 @@ import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.ModelColumnCl
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.ModelRulesClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.QueryPartitionClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.ReturnRowsClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleErrorLoggingClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleLobStorageClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleReturningClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleStorageClause;
|
||||
@@ -110,9 +111,6 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleGotoStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLabelStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLockTableStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement.MergeInsertClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement.MergeUpdateClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement.ConditionalInsertClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement.ConditionalInsertClauseItem;
|
||||
@@ -826,49 +824,6 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleMergeStatement x) {
|
||||
setAliasMap();
|
||||
|
||||
String originalTable = getCurrentTable();
|
||||
|
||||
setMode(x.getUsing(), Mode.Select);
|
||||
x.getUsing().accept(this);
|
||||
|
||||
setMode(x, Mode.Merge);
|
||||
|
||||
String ident = x.getInto().toString();
|
||||
setCurrentTable(x, ident);
|
||||
x.putAttribute("_old_local_", originalTable);
|
||||
|
||||
TableStat stat = getTableStat(ident);
|
||||
stat.incrementMergeCount();
|
||||
|
||||
Map<String, String> aliasMap = getAliasMap();
|
||||
if (aliasMap != null) {
|
||||
if (x.getAlias() != null) {
|
||||
putAliasMap(aliasMap, x.getAlias(), ident);
|
||||
}
|
||||
putAliasMap(aliasMap, ident, ident);
|
||||
}
|
||||
|
||||
x.getOn().accept(this);
|
||||
|
||||
if (x.getUpdateClause() != null) {
|
||||
x.getUpdateClause().accept(this);
|
||||
}
|
||||
|
||||
if (x.getInsertClause() != null) {
|
||||
x.getInsertClause().accept(this);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleMergeStatement x) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MergeUpdateClause x) {
|
||||
return true;
|
||||
@@ -889,16 +844,6 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleErrorLoggingClause x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleErrorLoggingClause x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleReturningClause x) {
|
||||
return true;
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLHint;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLObject;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
@@ -74,12 +75,14 @@ import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDropTriggerStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDropUserStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDropViewStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLErrorLoggingClause;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExplainStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLFetchStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLGrantStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertInto;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLMergeStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLObjectType;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLOpenStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLPrimaryKey;
|
||||
@@ -91,12 +94,12 @@ import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSetStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUseStatement;
|
||||
import com.alibaba.druid.sql.dialect.odps.parser.OdpsSelectParser;
|
||||
|
||||
public class SQLStatementParser extends SQLParser {
|
||||
|
||||
@@ -400,6 +403,11 @@ public class SQLStatementParser extends SQLParser {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.MERGE) {
|
||||
statementList.add(this.parseMerge());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (parseStatementListDialect(statementList)) {
|
||||
continue;
|
||||
@@ -1834,7 +1842,7 @@ public class SQLStatementParser extends SQLParser {
|
||||
}
|
||||
|
||||
public SQLSelectParser createSQLSelectParser() {
|
||||
return new OdpsSelectParser(this.exprParser);
|
||||
return new SQLSelectParser(this.exprParser);
|
||||
}
|
||||
|
||||
public SQLUpdateStatement parseUpdateStatement() {
|
||||
@@ -2136,4 +2144,149 @@ public class SQLStatementParser extends SQLParser {
|
||||
public void setParseValuesSize(int parseValuesSize) {
|
||||
this.parseValuesSize = parseValuesSize;
|
||||
}
|
||||
|
||||
public SQLMergeStatement parseMerge() {
|
||||
accept(Token.MERGE);
|
||||
|
||||
SQLMergeStatement stmt = new SQLMergeStatement();
|
||||
|
||||
parseHints(stmt.getHints());
|
||||
|
||||
accept(Token.INTO);
|
||||
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
SQLSelect select = this.createSQLSelectParser().select();
|
||||
SQLSubqueryTableSource tableSource = new SQLSubqueryTableSource(select);
|
||||
stmt.setInto(tableSource);
|
||||
accept(Token.RPAREN);
|
||||
} else {
|
||||
stmt.setInto(exprParser.name());
|
||||
}
|
||||
|
||||
stmt.setAlias(as());
|
||||
|
||||
accept(Token.USING);
|
||||
|
||||
SQLTableSource using = this.createSQLSelectParser().parseTableSource();
|
||||
stmt.setUsing(using);
|
||||
|
||||
accept(Token.ON);
|
||||
stmt.setOn(exprParser.expr());
|
||||
|
||||
boolean insertFlag = false;
|
||||
if (lexer.token() == Token.WHEN) {
|
||||
lexer.nextToken();
|
||||
if (lexer.token() == Token.MATCHED) {
|
||||
SQLMergeStatement.MergeUpdateClause updateClause = new SQLMergeStatement.MergeUpdateClause();
|
||||
lexer.nextToken();
|
||||
accept(Token.THEN);
|
||||
accept(Token.UPDATE);
|
||||
accept(Token.SET);
|
||||
|
||||
for (;;) {
|
||||
SQLUpdateSetItem item = this.exprParser.parseUpdateSetItem();
|
||||
|
||||
updateClause.addItem(item);
|
||||
item.setParent(updateClause);
|
||||
|
||||
if (lexer.token() == (Token.COMMA)) {
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.WHERE) {
|
||||
lexer.nextToken();
|
||||
updateClause.setWhere(exprParser.expr());
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.DELETE) {
|
||||
lexer.nextToken();
|
||||
accept(Token.WHERE);
|
||||
updateClause.setWhere(exprParser.expr());
|
||||
}
|
||||
|
||||
stmt.setUpdateClause(updateClause);
|
||||
} else if (lexer.token() == Token.NOT) {
|
||||
lexer.nextToken();
|
||||
insertFlag = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!insertFlag) {
|
||||
if (lexer.token() == Token.WHEN) {
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.NOT) {
|
||||
lexer.nextToken();
|
||||
insertFlag = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (insertFlag) {
|
||||
SQLMergeStatement.MergeInsertClause insertClause = new SQLMergeStatement.MergeInsertClause();
|
||||
|
||||
accept(Token.MATCHED);
|
||||
accept(Token.THEN);
|
||||
accept(Token.INSERT);
|
||||
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
accept(Token.LPAREN);
|
||||
exprParser.exprList(insertClause.getColumns(), insertClause);
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
accept(Token.VALUES);
|
||||
accept(Token.LPAREN);
|
||||
exprParser.exprList(insertClause.getValues(), insertClause);
|
||||
accept(Token.RPAREN);
|
||||
|
||||
if (lexer.token() == Token.WHERE) {
|
||||
lexer.nextToken();
|
||||
insertClause.setWhere(exprParser.expr());
|
||||
}
|
||||
|
||||
stmt.setInsertClause(insertClause);
|
||||
}
|
||||
|
||||
SQLErrorLoggingClause errorClause = parseErrorLoggingClause();
|
||||
stmt.setErrorLoggingClause(errorClause);
|
||||
|
||||
return stmt;
|
||||
}
|
||||
|
||||
protected SQLErrorLoggingClause parseErrorLoggingClause() {
|
||||
if (identifierEquals("LOG")) {
|
||||
SQLErrorLoggingClause errorClause = new SQLErrorLoggingClause();
|
||||
|
||||
lexer.nextToken();
|
||||
accept(Token.ERRORS);
|
||||
if (lexer.token() == Token.INTO) {
|
||||
lexer.nextToken();
|
||||
errorClause.setInto(exprParser.name());
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
errorClause.setSimpleExpression(exprParser.expr());
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.REJECT) {
|
||||
lexer.nextToken();
|
||||
accept(Token.LIMIT);
|
||||
errorClause.setLimit(exprParser.expr());
|
||||
}
|
||||
|
||||
return errorClause;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void parseHints(List<SQLHint> hints) {
|
||||
this.getExprParser().parseHints(hints);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +88,8 @@ import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement.TriggerEven
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement.TriggerType;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource.JoinType;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLMergeStatement.MergeInsertClause;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLMergeStatement.MergeUpdateClause;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements PrintableVisitor {
|
||||
@@ -3107,4 +3109,116 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab
|
||||
print0(ucase ? x.getFunction().name : x.getFunction().name_lcase);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLMergeStatement x) {
|
||||
print0(ucase ? "MERGE " : "merge ");
|
||||
if (x.getHints().size() > 0) {
|
||||
printAndAccept(x.getHints(), ", ");
|
||||
print(' ');
|
||||
}
|
||||
|
||||
print0(ucase ? "INTO " : "into ");
|
||||
x.getInto().accept(this);
|
||||
|
||||
if (x.getAlias() != null) {
|
||||
print(' ');
|
||||
print0(x.getAlias());
|
||||
}
|
||||
|
||||
println();
|
||||
print0(ucase ? "USING " : "using ");
|
||||
x.getUsing().accept(this);
|
||||
|
||||
print0(ucase ? " ON (" : " on (");
|
||||
x.getOn().accept(this);
|
||||
print0(") ");
|
||||
|
||||
if (x.getUpdateClause() != null) {
|
||||
println();
|
||||
x.getUpdateClause().accept(this);
|
||||
}
|
||||
|
||||
if (x.getInsertClause() != null) {
|
||||
println();
|
||||
x.getInsertClause().accept(this);
|
||||
}
|
||||
|
||||
if (x.getErrorLoggingClause() != null) {
|
||||
println();
|
||||
x.getErrorLoggingClause().accept(this);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MergeUpdateClause x) {
|
||||
print0(ucase ? "WHEN MATCHED THEN UPDATE SET " : "when matched then update set ");
|
||||
printAndAccept(x.getItems(), ", ");
|
||||
if (x.getWhere() != null) {
|
||||
incrementIndent();
|
||||
println();
|
||||
print0(ucase ? "WHERE " : "where ");
|
||||
x.getWhere().setParent(x);
|
||||
x.getWhere().accept(this);
|
||||
decrementIndent();
|
||||
}
|
||||
|
||||
if (x.getDeleteWhere() != null) {
|
||||
incrementIndent();
|
||||
println();
|
||||
print0(ucase ? "DELETE WHERE " : "delete where ");
|
||||
x.getDeleteWhere().setParent(x);
|
||||
x.getDeleteWhere().accept(this);
|
||||
decrementIndent();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MergeInsertClause x) {
|
||||
print0(ucase ? "WHEN NOT MATCHED THEN INSERT" : "when not matched then insert");
|
||||
if (x.getColumns().size() > 0) {
|
||||
print(' ');
|
||||
printAndAccept(x.getColumns(), ", ");
|
||||
}
|
||||
print0(ucase ? " VALUES (" : " values (");
|
||||
printAndAccept(x.getValues(), ", ");
|
||||
print(')');
|
||||
if (x.getWhere() != null) {
|
||||
incrementIndent();
|
||||
println();
|
||||
print0(ucase ? "WHERE " : "where ");
|
||||
x.getWhere().setParent(x);
|
||||
x.getWhere().accept(this);
|
||||
decrementIndent();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLErrorLoggingClause x) {
|
||||
print0(ucase ? "LOG ERRORS " : "log errors ");
|
||||
if (x.getInto() != null) {
|
||||
print0(ucase ? "INTO " : "into ");
|
||||
x.getInto().accept(this);
|
||||
print(' ');
|
||||
}
|
||||
|
||||
if (x.getSimpleExpression() != null) {
|
||||
print('(');
|
||||
x.getSimpleExpression().accept(this);
|
||||
print(')');
|
||||
}
|
||||
|
||||
if (x.getLimit() != null) {
|
||||
print0(ucase ? " REJECT LIMIT " : " reject limit ");
|
||||
x.getLimit().accept(this);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -700,5 +700,20 @@ public interface SQLASTVisitor {
|
||||
boolean visit(SQLSequenceExpr x);
|
||||
|
||||
void endVisit(SQLSequenceExpr x);
|
||||
|
||||
boolean visit(SQLMergeStatement x);
|
||||
|
||||
void endVisit(SQLMergeStatement x);
|
||||
|
||||
boolean visit(SQLMergeStatement.MergeUpdateClause x);
|
||||
|
||||
void endVisit(SQLMergeStatement.MergeUpdateClause x);
|
||||
|
||||
boolean visit(SQLMergeStatement.MergeInsertClause x);
|
||||
|
||||
void endVisit(SQLMergeStatement.MergeInsertClause x);
|
||||
|
||||
boolean visit(SQLErrorLoggingClause x);
|
||||
|
||||
void endVisit(SQLErrorLoggingClause x);
|
||||
}
|
||||
|
||||
@@ -68,6 +68,8 @@ import com.alibaba.druid.sql.ast.expr.SQLUnaryExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.*;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLMergeStatement.MergeInsertClause;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLMergeStatement.MergeUpdateClause;
|
||||
|
||||
public class SQLASTVisitorAdapter implements SQLASTVisitor {
|
||||
|
||||
@@ -1523,5 +1525,44 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor {
|
||||
public void endVisit(SQLSequenceExpr x) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLMergeStatement x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(SQLMergeStatement x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MergeUpdateClause x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(MergeUpdateClause x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MergeInsertClause x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(MergeInsertClause x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLErrorLoggingClause x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(SQLErrorLoggingClause x) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,6 +101,7 @@ import com.alibaba.druid.sql.ast.statement.SQLForeignKeyImpl;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLGrantStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLMergeStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLObjectType;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLOpenStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLRevokeStatement;
|
||||
@@ -1689,4 +1690,43 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
|
||||
public boolean visit(SQLSequenceExpr x) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLMergeStatement x) {
|
||||
setAliasMap();
|
||||
|
||||
String originalTable = getCurrentTable();
|
||||
|
||||
setMode(x.getUsing(), Mode.Select);
|
||||
x.getUsing().accept(this);
|
||||
|
||||
setMode(x, Mode.Merge);
|
||||
|
||||
String ident = x.getInto().toString();
|
||||
setCurrentTable(x, ident);
|
||||
x.putAttribute("_old_local_", originalTable);
|
||||
|
||||
TableStat stat = getTableStat(ident);
|
||||
stat.incrementMergeCount();
|
||||
|
||||
Map<String, String> aliasMap = getAliasMap();
|
||||
if (aliasMap != null) {
|
||||
if (x.getAlias() != null) {
|
||||
putAliasMap(aliasMap, x.getAlias(), ident);
|
||||
}
|
||||
putAliasMap(aliasMap, ident, ident);
|
||||
}
|
||||
|
||||
x.getOn().accept(this);
|
||||
|
||||
if (x.getUpdateClause() != null) {
|
||||
x.getUpdateClause().accept(this);
|
||||
}
|
||||
|
||||
if (x.getInsertClause() != null) {
|
||||
x.getInsertClause().accept(this);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@ import com.alibaba.druid.sql.ast.statement.SQLInsertInto;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLMergeStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLRollbackStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause;
|
||||
@@ -113,7 +114,6 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlStartTransactionSt
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateSequenceStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGShowStatement;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerCommitStatement;
|
||||
@@ -2404,7 +2404,7 @@ public class WallVisitorUtils {
|
||||
allow = true;
|
||||
denyMessage = "multi-insert not allow";
|
||||
errorCode = ErrorCode.INSERT_NOT_ALLOW;
|
||||
} else if (x instanceof OracleMergeStatement) {
|
||||
} else if (x instanceof SQLMergeStatement) {
|
||||
allow = config.isMergeAllow();
|
||||
denyMessage = "merge not allow";
|
||||
errorCode = ErrorCode.MERGE_NOT_ALLOW;
|
||||
|
||||
Reference in New Issue
Block a user