mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
oracle sql parser support multi insert
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
package com.alibaba.druid.sql.ast.statement;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
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.statement.SQLInsertStatement.ValuesClause;
|
||||
|
||||
public abstract class SQLInsertInto extends SQLObjectImpl {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
protected SQLName tableName;
|
||||
protected String alias;
|
||||
|
||||
protected final List<SQLExpr> columns = new ArrayList<SQLExpr>();
|
||||
protected ValuesClause values;
|
||||
protected SQLSelect query;
|
||||
|
||||
public SQLInsertInto(){
|
||||
|
||||
}
|
||||
|
||||
public String getAlias() {
|
||||
return alias;
|
||||
}
|
||||
|
||||
public void setAlias(String alias) {
|
||||
this.alias = alias;
|
||||
}
|
||||
|
||||
public SQLName getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
public void setTableName(SQLName tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
public SQLSelect getQuery() {
|
||||
return query;
|
||||
}
|
||||
|
||||
public void setQuery(SQLSelect query) {
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
public List<SQLExpr> getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
public ValuesClause getValues() {
|
||||
return values;
|
||||
}
|
||||
|
||||
public void setValues(ValuesClause values) {
|
||||
this.values = values;
|
||||
}
|
||||
}
|
||||
@@ -19,61 +19,18 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
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.SQLStatementImpl;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class SQLInsertStatement extends SQLStatementImpl {
|
||||
public class SQLInsertStatement extends SQLInsertInto implements SQLStatement {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
protected SQLName tableName;
|
||||
protected String alias;
|
||||
|
||||
protected final List<SQLExpr> columns = new ArrayList<SQLExpr>();
|
||||
protected ValuesClause values;
|
||||
protected SQLSelect query;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public SQLInsertStatement(){
|
||||
|
||||
}
|
||||
|
||||
public String getAlias() {
|
||||
return alias;
|
||||
}
|
||||
|
||||
public void setAlias(String alias) {
|
||||
this.alias = alias;
|
||||
}
|
||||
|
||||
public SQLName getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
public void setTableName(SQLName tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
public SQLSelect getQuery() {
|
||||
return query;
|
||||
}
|
||||
|
||||
public void setQuery(SQLSelect query) {
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
public List<SQLExpr> getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
public ValuesClause getValues() {
|
||||
return values;
|
||||
}
|
||||
|
||||
public void setValues(ValuesClause values) {
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
|
||||
+174
-2
@@ -1,15 +1,187 @@
|
||||
package com.alibaba.druid.sql.dialect.oracle.ast.stmt;
|
||||
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertInto;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleHint;
|
||||
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;
|
||||
|
||||
public class OracleMultiInsertStatement extends OracleStatementImpl {
|
||||
|
||||
public static enum Option {
|
||||
ALL, FIRST
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private SQLSelect subQuery;
|
||||
private Option option;
|
||||
private List<Entry> entries = new ArrayList<Entry>();
|
||||
private List<OracleHint> hints = new ArrayList<OracleHint>();
|
||||
|
||||
public List<OracleHint> getHints() {
|
||||
return hints;
|
||||
}
|
||||
|
||||
public void setHints(List<OracleHint> hints) {
|
||||
this.hints = hints;
|
||||
}
|
||||
|
||||
public List<Entry> getEntries() {
|
||||
return entries;
|
||||
}
|
||||
|
||||
public void setEntries(List<Entry> entries) {
|
||||
this.entries = entries;
|
||||
}
|
||||
|
||||
public Option getOption() {
|
||||
return option;
|
||||
}
|
||||
|
||||
public void setOption(Option option) {
|
||||
this.option = option;
|
||||
}
|
||||
|
||||
public SQLSelect getSubQuery() {
|
||||
return subQuery;
|
||||
}
|
||||
|
||||
public void setSubQuery(SQLSelect subQuery) {
|
||||
this.subQuery = subQuery;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept0(OracleASTVisitor visitor) {
|
||||
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, this.entries);
|
||||
acceptChild(visitor, this.subQuery);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
public static interface Entry extends OracleSQLObject {
|
||||
|
||||
}
|
||||
|
||||
public static class ConditionalInsertClause extends OracleSQLObjectImpl implements Entry {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private List<ConditionalInsertClauseItem> items = new ArrayList<ConditionalInsertClauseItem>();
|
||||
private InsertIntoClause elseItem;
|
||||
|
||||
public InsertIntoClause getElseItem() {
|
||||
return elseItem;
|
||||
}
|
||||
|
||||
public void setElseItem(InsertIntoClause elseItem) {
|
||||
this.elseItem = elseItem;
|
||||
}
|
||||
|
||||
public List<ConditionalInsertClauseItem> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
public void setItems(List<ConditionalInsertClauseItem> items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept0(OracleASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, items);
|
||||
acceptChild(visitor, elseItem);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class ConditionalInsertClauseItem extends OracleSQLObjectImpl {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private SQLExpr when;
|
||||
private InsertIntoClause then;
|
||||
|
||||
public SQLExpr getWhen() {
|
||||
return when;
|
||||
}
|
||||
|
||||
public void setWhen(SQLExpr when) {
|
||||
this.when = when;
|
||||
}
|
||||
|
||||
public InsertIntoClause getThen() {
|
||||
return then;
|
||||
}
|
||||
|
||||
public void setThen(InsertIntoClause then) {
|
||||
this.then = then;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept0(OracleASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, when);
|
||||
acceptChild(visitor, then);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class InsertIntoClause extends SQLInsertInto implements OracleSQLObject, Entry {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private OracleReturningClause returning;
|
||||
private OracleErrorLoggingClause errorLogging;
|
||||
|
||||
public InsertIntoClause(){
|
||||
|
||||
}
|
||||
|
||||
public OracleReturningClause getReturning() {
|
||||
return returning;
|
||||
}
|
||||
|
||||
public void setReturning(OracleReturningClause returning) {
|
||||
this.returning = returning;
|
||||
}
|
||||
|
||||
public OracleErrorLoggingClause getErrorLogging() {
|
||||
return errorLogging;
|
||||
}
|
||||
|
||||
public void setErrorLogging(OracleErrorLoggingClause errorLogging) {
|
||||
this.errorLogging = errorLogging;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
this.accept0((OracleASTVisitor) visitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept0(OracleASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
this.acceptChild(visitor, tableName);
|
||||
this.acceptChild(visitor, columns);
|
||||
this.acceptChild(visitor, values);
|
||||
this.acceptChild(visitor, query);
|
||||
this.acceptChild(visitor, returning);
|
||||
this.acceptChild(visitor, errorLogging);
|
||||
}
|
||||
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+66
-5
@@ -19,6 +19,7 @@ import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
|
||||
@@ -26,6 +27,7 @@ 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.OracleInsertStatement;
|
||||
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.OracleStatement;
|
||||
import com.alibaba.druid.sql.parser.Lexer;
|
||||
@@ -233,14 +235,73 @@ public class OracleStatementParser extends SQLStatementParser {
|
||||
|
||||
public OracleStatement parseInsert() {
|
||||
accept(Token.INSERT);
|
||||
accept(Token.INTO);
|
||||
|
||||
OracleInsertStatement stmt = new OracleInsertStatement();
|
||||
if (lexer.token() == Token.INTO) {
|
||||
OracleInsertStatement stmt = new OracleInsertStatement();
|
||||
|
||||
parseInsert0(stmt);
|
||||
parseInsert0(stmt);
|
||||
|
||||
stmt.setReturning(parseReturningClause());
|
||||
stmt.setErrorLogging(parseErrorLoggingClause());
|
||||
stmt.setReturning(parseReturningClause());
|
||||
stmt.setErrorLogging(parseErrorLoggingClause());
|
||||
|
||||
return stmt;
|
||||
}
|
||||
|
||||
return parseMultiInsert();
|
||||
}
|
||||
|
||||
public OracleStatement parseMultiInsert() {
|
||||
OracleMultiInsertStatement stmt = new OracleMultiInsertStatement();
|
||||
|
||||
if (lexer.token() == Token.ALL) {
|
||||
lexer.nextToken();
|
||||
stmt.setOption(OracleMultiInsertStatement.Option.ALL);
|
||||
} else if (lexer.token() == Token.FIRST) {
|
||||
lexer.nextToken();
|
||||
stmt.setOption(OracleMultiInsertStatement.Option.FIRST);
|
||||
}
|
||||
|
||||
while (lexer.token() == Token.INTO) {
|
||||
OracleMultiInsertStatement.InsertIntoClause clause = new OracleMultiInsertStatement.InsertIntoClause();
|
||||
|
||||
parseInsert0(clause);
|
||||
|
||||
clause.setReturning(parseReturningClause());
|
||||
clause.setErrorLogging(parseErrorLoggingClause());
|
||||
|
||||
stmt.getEntries().add(clause);
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.WHEN) {
|
||||
OracleMultiInsertStatement.ConditionalInsertClause clause = new OracleMultiInsertStatement.ConditionalInsertClause();
|
||||
|
||||
while (lexer.token() == Token.WHEN) {
|
||||
lexer.nextToken();
|
||||
|
||||
OracleMultiInsertStatement.ConditionalInsertClauseItem item = new OracleMultiInsertStatement.ConditionalInsertClauseItem();
|
||||
|
||||
item.setWhen(this.createExprParser().expr());
|
||||
accept(Token.THEN);
|
||||
OracleMultiInsertStatement.InsertIntoClause insertInto = new OracleMultiInsertStatement.InsertIntoClause();
|
||||
parseInsert0(insertInto);
|
||||
item.setThen(insertInto);
|
||||
|
||||
clause.getItems().add(item);
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.ELSE) {
|
||||
lexer.nextToken();
|
||||
|
||||
OracleMultiInsertStatement.InsertIntoClause insertInto = new OracleMultiInsertStatement.InsertIntoClause();
|
||||
parseInsert0(insertInto, false);
|
||||
clause.setElseItem(insertInto);
|
||||
}
|
||||
|
||||
stmt.getEntries().add(clause);
|
||||
}
|
||||
|
||||
SQLSelect subQuery = this.createSQLSelectParser().select();
|
||||
stmt.setSubQuery(subQuery);
|
||||
|
||||
return stmt;
|
||||
}
|
||||
|
||||
+44
@@ -42,6 +42,10 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement;
|
||||
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;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement.InsertIntoClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleOrderByItem;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePLSQLCommitStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelect;
|
||||
@@ -713,5 +717,45 @@ public class OracleASTVIsitorAdapter extends SQLASTVisitorAdapter implements Ora
|
||||
public void endVisit(OracleInsertStatement x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(InsertIntoClause x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(InsertIntoClause x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleMultiInsertStatement x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleMultiInsertStatement x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(ConditionalInsertClause x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(ConditionalInsertClause x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(ConditionalInsertClauseItem x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(ConditionalInsertClauseItem x) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -46,6 +46,10 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleConstraintState;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement;
|
||||
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;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement.InsertIntoClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleOrderByItem;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePLSQLCommitStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelect;
|
||||
@@ -310,4 +314,20 @@ public interface OracleASTVisitor extends SQLASTVisitor {
|
||||
boolean visit(OracleInsertStatement x);
|
||||
|
||||
void endVisit(OracleInsertStatement x);
|
||||
|
||||
boolean visit(InsertIntoClause x);
|
||||
|
||||
void endVisit(InsertIntoClause x);
|
||||
|
||||
boolean visit(OracleMultiInsertStatement x);
|
||||
|
||||
void endVisit(OracleMultiInsertStatement x);
|
||||
|
||||
boolean visit(ConditionalInsertClause x);
|
||||
|
||||
void endVisit(ConditionalInsertClause x);
|
||||
|
||||
boolean visit(ConditionalInsertClauseItem x);
|
||||
|
||||
void endVisit(ConditionalInsertClauseItem x);
|
||||
}
|
||||
|
||||
+149
-24
@@ -74,6 +74,10 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement;
|
||||
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;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement.InsertIntoClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleOrderByItem;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePLSQLCommitStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelect;
|
||||
@@ -1324,43 +1328,43 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
printAndAccept(x.getHints(), ", ");
|
||||
print(" ");
|
||||
}
|
||||
|
||||
|
||||
print("INTO ");
|
||||
x.getInto().accept(this);
|
||||
|
||||
|
||||
if (x.getAlias() != null) {
|
||||
print(" ");
|
||||
print(x.getAlias());
|
||||
}
|
||||
|
||||
|
||||
println();
|
||||
print("USING ");
|
||||
x.getUsing().accept(this);
|
||||
|
||||
|
||||
print(" ON ");
|
||||
x.getOn().accept(this);
|
||||
|
||||
|
||||
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
|
||||
@@ -1374,7 +1378,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
x.getWhere().accept(this);
|
||||
decrementIndent();
|
||||
}
|
||||
|
||||
|
||||
if (x.getDeleteWhere() != null) {
|
||||
incrementIndent();
|
||||
println();
|
||||
@@ -1382,13 +1386,13 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
x.getDeleteWhere().accept(this);
|
||||
decrementIndent();
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(MergeUpdateClause x) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1405,13 +1409,13 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
x.getWhere().accept(this);
|
||||
decrementIndent();
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(MergeInsertClause x) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1422,54 +1426,55 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
x.getInto().accept(this);
|
||||
print(" ");
|
||||
}
|
||||
|
||||
|
||||
if (x.getSimpleExpression() != null) {
|
||||
print("(");
|
||||
x.getSimpleExpression().accept(this);
|
||||
print(")");
|
||||
}
|
||||
|
||||
|
||||
if (x.getLimit() != null) {
|
||||
print(" REJECT LIMIT ");
|
||||
x.getLimit().accept(this);
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleErrorLoggingClause x) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleReturningClause x) {
|
||||
print("RETURNING ");
|
||||
printAndAccept(x.getItems(), ", ");
|
||||
print(" INTO ");
|
||||
printAndAccept(x.getValues(), ", ");
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleReturningClause x) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleInsertStatement x) {
|
||||
visit((SQLInsertStatement) x);
|
||||
|
||||
|
||||
if (x.getReturning() != null) {
|
||||
println();
|
||||
x.getReturning().accept(this);
|
||||
}
|
||||
|
||||
|
||||
if (x.getErrorLogging() != null) {
|
||||
println();
|
||||
x.getErrorLogging().accept(this);
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1477,4 +1482,124 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
public void endVisit(OracleInsertStatement x) {
|
||||
endVisit((SQLInsertStatement) x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(InsertIntoClause x) {
|
||||
print("INTO ");
|
||||
|
||||
x.getTableName().accept(this);
|
||||
|
||||
if (x.getColumns().size() > 0) {
|
||||
incrementIndent();
|
||||
println();
|
||||
print("(");
|
||||
for (int i = 0, size = x.getColumns().size(); i < size; ++i) {
|
||||
if (i != 0) {
|
||||
if (i % 5 == 0) {
|
||||
println();
|
||||
}
|
||||
print(", ");
|
||||
}
|
||||
x.getColumns().get(i).accept(this);
|
||||
}
|
||||
print(")");
|
||||
decrementIndent();
|
||||
}
|
||||
|
||||
if (x.getValues() != null) {
|
||||
println();
|
||||
print("VALUES ");
|
||||
x.getValues().accept(this);
|
||||
} else {
|
||||
if (x.getQuery() != null) {
|
||||
println();
|
||||
x.getQuery().setParent(x);
|
||||
x.getQuery().accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(InsertIntoClause x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleMultiInsertStatement x) {
|
||||
print("INSERT ");
|
||||
|
||||
if (x.getHints().size() > 0) {
|
||||
this.printHints(x.getHints());
|
||||
}
|
||||
|
||||
if (x.getOption() != null) {
|
||||
print(x.getOption().name());
|
||||
print(" ");
|
||||
}
|
||||
|
||||
for (int i = 0, size = x.getEntries().size(); i < size; ++i) {
|
||||
incrementIndent();
|
||||
println();
|
||||
x.getEntries().get(i).accept(this);
|
||||
decrementIndent();
|
||||
}
|
||||
|
||||
println();
|
||||
x.getSubQuery().accept(this);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleMultiInsertStatement x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(ConditionalInsertClause x) {
|
||||
for (int i = 0, size = x.getItems().size(); i < size; ++i) {
|
||||
if (i != 0) {
|
||||
println();
|
||||
}
|
||||
|
||||
ConditionalInsertClauseItem item = x.getItems().get(i);
|
||||
|
||||
item.accept(this);
|
||||
}
|
||||
|
||||
if (x.getElseItem() != null) {
|
||||
println();
|
||||
print("ELSE");
|
||||
incrementIndent();
|
||||
println();
|
||||
x.getElseItem().accept(this);
|
||||
decrementIndent();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(ConditionalInsertClause x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(ConditionalInsertClauseItem x) {
|
||||
print("WHEN ");
|
||||
x.getWhen().accept(this);
|
||||
print(" THEN");
|
||||
incrementIndent();
|
||||
println();
|
||||
x.getThen().accept(this);
|
||||
decrementIndent();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(ConditionalInsertClauseItem x) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+118
-13
@@ -5,6 +5,7 @@ import java.util.Map;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLObject;
|
||||
import com.alibaba.druid.sql.ast.SQLOrderBy;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLAggregateExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
@@ -30,8 +31,8 @@ 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.ReturnRowsClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleErrorLoggingClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.PartitionExtensionClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleReturningClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.PartitionExtensionClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.SampleClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.SearchClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.SubqueryFactoringClause;
|
||||
@@ -51,9 +52,14 @@ import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleOuterExpr;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleTimestampExpr;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleConstraintState;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement;
|
||||
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;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement.InsertIntoClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleOrderByItem;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePLSQLCommitStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelect;
|
||||
@@ -65,7 +71,6 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectPivot.Item;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectRestriction.CheckOption;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectRestriction.ReadOnly;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectSubqueryTableSource;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectUnPivot;
|
||||
@@ -221,7 +226,7 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
|
||||
return false;
|
||||
}
|
||||
|
||||
return super.visit(x);
|
||||
return super.visit(x);
|
||||
}
|
||||
|
||||
public boolean visit(SQLIdentifierExpr x) {
|
||||
@@ -815,12 +820,12 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
|
||||
|
||||
x.putAttribute("_original_use_mode", modeLocal.get());
|
||||
modeLocal.set(Mode.Merge);
|
||||
|
||||
|
||||
String originalTable = currentTableLocal.get();
|
||||
|
||||
x.getUsing().accept(this);
|
||||
|
||||
String ident = x.getInto().toString();
|
||||
String ident = x.getInto().toString();
|
||||
currentTableLocal.set(ident);
|
||||
x.putAttribute("_old_local_", originalTable);
|
||||
|
||||
@@ -838,13 +843,13 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
|
||||
}
|
||||
aliasMap.put(ident, ident);
|
||||
}
|
||||
|
||||
|
||||
x.getOn().accept(this);
|
||||
|
||||
|
||||
if (x.getUpdateClause() != null) {
|
||||
x.getUpdateClause().accept(this);
|
||||
}
|
||||
|
||||
|
||||
if (x.getInsertClause() != null) {
|
||||
x.getInsertClause().accept(this);
|
||||
}
|
||||
@@ -885,18 +890,16 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
|
||||
@Override
|
||||
public void endVisit(OracleErrorLoggingClause x) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleReturningClause x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleReturningClause x) {
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -908,4 +911,106 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
|
||||
public void endVisit(OracleInsertStatement x) {
|
||||
endVisit((SQLInsertStatement) x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(InsertIntoClause x) {
|
||||
String originalTable = currentTableLocal.get();
|
||||
|
||||
if (x.getTableName() instanceof SQLName) {
|
||||
String ident = ((SQLName) x.getTableName()).toString();
|
||||
currentTableLocal.set(ident);
|
||||
x.putAttribute("_old_local_", originalTable);
|
||||
|
||||
TableStat stat = tableStats.get(ident);
|
||||
if (stat == null) {
|
||||
stat = new TableStat();
|
||||
tableStats.put(new TableStat.Name(ident), stat);
|
||||
}
|
||||
stat.incrementInsertCount();
|
||||
|
||||
Map<String, String> aliasMap = aliasLocal.get();
|
||||
if (aliasMap != null) {
|
||||
if (x.getAlias() != null) {
|
||||
aliasMap.put(x.getAlias(), ident);
|
||||
}
|
||||
aliasMap.put(ident, ident);
|
||||
}
|
||||
}
|
||||
|
||||
accept(x.getColumns());
|
||||
accept(x.getQuery());
|
||||
accept(x.getReturning());
|
||||
accept(x.getErrorLogging());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(InsertIntoClause x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleMultiInsertStatement x) {
|
||||
x.putAttribute("_original_use_mode", modeLocal.get());
|
||||
modeLocal.set(Mode.Insert);
|
||||
|
||||
aliasLocal.set(new HashMap<String, String>());
|
||||
|
||||
accept(x.getSubQuery());
|
||||
|
||||
for (OracleMultiInsertStatement.Entry entry : x.getEntries()) {
|
||||
entry.setParent(x);
|
||||
}
|
||||
|
||||
accept(x.getEntries());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleMultiInsertStatement x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(ConditionalInsertClause x) {
|
||||
for (ConditionalInsertClauseItem item : x.getItems()) {
|
||||
item.setParent(x);
|
||||
}
|
||||
if (x.getElseItem() != null) {
|
||||
x.getElseItem().setParent(x);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(ConditionalInsertClause x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(ConditionalInsertClauseItem x) {
|
||||
String originalTable = currentTableLocal.get();
|
||||
SQLObject parent = x.getParent();
|
||||
if (parent instanceof ConditionalInsertClause) {
|
||||
parent = parent.getParent();
|
||||
}
|
||||
if (parent instanceof OracleMultiInsertStatement) {
|
||||
SQLSelect subQuery = ((OracleMultiInsertStatement) parent).getSubQuery();
|
||||
if (subQuery != null) {
|
||||
String table = (String) subQuery.getAttribute("_table_");
|
||||
currentTableLocal.set(table);
|
||||
}
|
||||
}
|
||||
x.getWhen().accept(this);
|
||||
x.getThen().accept(this);
|
||||
currentTableLocal.set(originalTable);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(ConditionalInsertClauseItem x) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateViewStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertInto;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSetStatement;
|
||||
@@ -161,15 +162,20 @@ public class SQLStatementParser extends SQLParser {
|
||||
|
||||
public SQLStatement parseInsert() {
|
||||
accept(Token.INSERT);
|
||||
accept(Token.INTO);
|
||||
|
||||
SQLInsertStatement insertStatement = new SQLInsertStatement();
|
||||
|
||||
parseInsert0(insertStatement);
|
||||
return insertStatement;
|
||||
}
|
||||
|
||||
protected void parseInsert0(SQLInsertInto insertStatement) {
|
||||
parseInsert0(insertStatement, true);
|
||||
}
|
||||
|
||||
protected void parseInsert0(SQLInsertStatement insertStatement) {
|
||||
protected void parseInsert0(SQLInsertInto insertStatement, boolean acceptSubQuery) {
|
||||
accept(Token.INTO);
|
||||
|
||||
SQLName tableName = this.exprParser.name();
|
||||
insertStatement.setTableName(tableName);
|
||||
|
||||
@@ -191,7 +197,7 @@ public class SQLStatementParser extends SQLParser {
|
||||
this.exprParser.exprList(values.getValues());
|
||||
insertStatement.setValues(values);
|
||||
accept(Token.RPAREN);
|
||||
} else if (lexer.token() == Token.SELECT || lexer.token() == Token.LPAREN) {
|
||||
} else if (acceptSubQuery && (lexer.token() == Token.SELECT || lexer.token() == Token.LPAREN)) {
|
||||
SQLQueryExpr queryExpr = (SQLQueryExpr) this.createExprParser().expr();
|
||||
insertStatement.setQuery(queryExpr.getSubQuery());
|
||||
}
|
||||
|
||||
@@ -363,6 +363,10 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
|
||||
currentTableLocal.set(null);
|
||||
} else {
|
||||
currentTableLocal.set(ident);
|
||||
x.putAttribute("_table_", ident);
|
||||
if (x.getParent() instanceof SQLSelect) {
|
||||
x.getParent().putAttribute("_table_", ident);
|
||||
}
|
||||
}
|
||||
x.putAttribute("_old_local_", originalTable);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user