oracle sql parser support multi insert

This commit is contained in:
温少
2012-02-25 17:03:35 +08:00
parent 7d34b6efc5
commit 6160de7e60
12 changed files with 776 additions and 93 deletions
@@ -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)) {
@@ -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);
}
}
}
@@ -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;
}
@@ -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);
}
@@ -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) {
}
}
@@ -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);
}