提交 2b8b5d2a authored 作者: Owner's avatar Owner

Separated Merge and MergeUsing heirarchy

上级 9a63cfc7
...@@ -1050,7 +1050,7 @@ public class Parser { ...@@ -1050,7 +1050,7 @@ public class Parser {
} }
private Merge parseMerge() { private Prepared parseMerge() {
Merge command = new Merge(session); Merge command = new Merge(session);
currentPrepared = command; currentPrepared = command;
int start = lastParseIndex; int start = lastParseIndex;
...@@ -1113,7 +1113,7 @@ public class Parser { ...@@ -1113,7 +1113,7 @@ public class Parser {
String[] querySQLOutput = new String[]{null}; String[] querySQLOutput = new String[]{null};
List<Column> columnTemplateList = createQueryColumnTemplateList(null, command.getQuery(), querySQLOutput); List<Column> columnTemplateList = createQueryColumnTemplateList(null, command.getQuery(), querySQLOutput);
TableView temporarySourceTableView = createTemporarySessionView(command.getQueryAlias(), querySQLOutput[0], columnTemplateList, false, false); TableView temporarySourceTableView = createTemporarySessionView(command.getQueryAlias(), querySQLOutput[0], columnTemplateList, false, false);
command.setTemporaryTableView(temporarySourceTableView); //command.setTemporaryTableView(temporarySourceTableView);
TableFilter sourceTableFilter = new TableFilter(session, temporarySourceTableView, command.getQueryAlias(), rightsChecked, TableFilter sourceTableFilter = new TableFilter(session, temporarySourceTableView, command.getQueryAlias(), rightsChecked,
(Select) command.getQuery(), 0, null); (Select) command.getQuery(), 0, null);
...@@ -1163,7 +1163,7 @@ public class Parser { ...@@ -1163,7 +1163,7 @@ public class Parser {
if (readIf("INSERT")){ if (readIf("INSERT")){
Insert insertCommand = new Insert(session); Insert insertCommand = new Insert(session);
insertCommand.setTable(command.getTargetTable()); insertCommand.setTable(command.getTargetTable());
parseInsertGivenTable(insertCommand,command.getTargetTable()); parseInsertGivenTable(insertCommand, command.getTargetTable());
command.setInsertCommand(insertCommand); command.setInsertCommand(insertCommand);
} }
} }
......
...@@ -33,13 +33,13 @@ import org.h2.value.Value; ...@@ -33,13 +33,13 @@ import org.h2.value.Value;
*/ */
public class Merge extends Prepared { public class Merge extends Prepared {
protected Table targetTable; private Table targetTable;
protected TableFilter targetTableFilter; private TableFilter targetTableFilter;
protected Column[] columns; private Column[] columns;
protected Column[] keys; private Column[] keys;
protected final ArrayList<Expression[]> valuesExpressionList = New.arrayList(); private final ArrayList<Expression[]> valuesExpressionList = New.arrayList();
protected Query query; private Query query;
protected Prepared update; private Prepared update;
public Merge(Session session) { public Merge(Session session) {
super(session); super(session);
......
...@@ -12,24 +12,22 @@ import java.util.HashSet; ...@@ -12,24 +12,22 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.api.Trigger; import org.h2.api.Trigger;
import org.h2.command.CommandInterface;
import org.h2.command.Prepared; import org.h2.command.Prepared;
import org.h2.engine.DbObject;
import org.h2.engine.Right; import org.h2.engine.Right;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.engine.UndoLogRecord;
import org.h2.expression.ConditionAndOr; import org.h2.expression.ConditionAndOr;
import org.h2.expression.Expression; import org.h2.expression.Expression;
import org.h2.expression.ExpressionVisitor; import org.h2.expression.ExpressionVisitor;
import org.h2.expression.Parameter; import org.h2.expression.Parameter;
import org.h2.index.Index;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.result.ResultInterface; import org.h2.result.ResultInterface;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.result.RowImpl; import org.h2.result.RowImpl;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.table.PlanItem; import org.h2.table.Table;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.table.TableView; import org.h2.util.New;
import org.h2.util.StatementBuilder; import org.h2.util.StatementBuilder;
import org.h2.value.Value; import org.h2.value.Value;
...@@ -37,15 +35,24 @@ import org.h2.value.Value; ...@@ -37,15 +35,24 @@ import org.h2.value.Value;
* This class represents the statement syntax * This class represents the statement syntax
* MERGE table alias USING... * MERGE table alias USING...
*/ */
public class MergeUsing extends Merge { public class MergeUsing extends Prepared {
// Merge fields
private Table targetTable;
private TableFilter targetTableFilter;
private Column[] columns;
private Column[] keys;
private final ArrayList<Expression[]> valuesExpressionList = New.arrayList();
private Query query;
private Prepared update;
// MergeUsing fields
private TableFilter sourceTableFilter; private TableFilter sourceTableFilter;
private Expression onCondition; private Expression onCondition;
private Update updateCommand; private Update updateCommand;
private Delete deleteCommand; private Delete deleteCommand;
private Insert insertCommand; private Insert insertCommand;
private String queryAlias; private String queryAlias;
private TableView temporarySourceTableView;
private int countUpdatedRows=0; private int countUpdatedRows=0;
private Column[] sourceKeys; private Column[] sourceKeys;
private HashMap<List<Value>,Integer> sourceKeysRemembered = new HashMap<List<Value>,Integer>(); private HashMap<List<Value>,Integer> sourceKeysRemembered = new HashMap<List<Value>,Integer>();
...@@ -54,8 +61,8 @@ public class MergeUsing extends Merge { ...@@ -54,8 +61,8 @@ public class MergeUsing extends Merge {
super(merge.getSession()); super(merge.getSession());
// bring across only the already parsed data from Merge... // bring across only the already parsed data from Merge...
this.targetTable = merge.targetTable; this.targetTable = merge.getTargetTable();
this.targetTableFilter = merge.targetTableFilter; this.targetTableFilter = merge.getTargetTableFilter();
} }
...@@ -100,12 +107,16 @@ public class MergeUsing extends Merge { ...@@ -100,12 +107,16 @@ public class MergeUsing extends Merge {
throw setRow(ex, countInputRows, getSQL(sourceRowValues)); throw setRow(ex, countInputRows, getSQL(sourceRowValues));
} }
} }
// throw and exception if the source query has generated the same key column values before
if(sourceKeysRemembered.containsKey(sourceKeyValuesList)){ if(sourceKeysRemembered.containsKey(sourceKeyValuesList)){
throw DbException.get(ErrorCode.DUPLICATE_KEY_1, "Merge using ON column expression, duplicate values found:key columns" throw DbException.get(ErrorCode.DUPLICATE_KEY_1, "Merge using ON column expression, duplicate values found:key columns"
+Arrays.asList(sourceKeys).toString()+":values:"+sourceKeyValuesList.toString() +Arrays.asList(sourceKeys).toString()+":values:"+sourceKeyValuesList.toString()
+":from:"+sourceTableFilter.getTable()+":alias:"+sourceTableFilter.getTableAlias()+":current row number:"+countInputRows +":from:"+sourceTableFilter.getTable()+":alias:"+sourceTableFilter.getTableAlias()+":current row number:"+countInputRows
+":conflicting row number:"+sourceKeysRemembered.get(sourceKeyValuesList)); +":conflicting row number:"+sourceKeysRemembered.get(sourceKeyValuesList));
}else{ }else{
// remember the source column values we have used before (they are the effective ON clause keys
// and should not be repeated
sourceKeysRemembered.put(sourceKeyValuesList,countInputRows); sourceKeysRemembered.put(sourceKeyValuesList,countInputRows);
} }
...@@ -121,7 +132,7 @@ public class MergeUsing extends Merge { ...@@ -121,7 +132,7 @@ public class MergeUsing extends Merge {
throw setRow(ex, countInputRows, getSQL(sourceRowValues)); throw setRow(ex, countInputRows, getSQL(sourceRowValues));
} }
} }
merge(sourceRow, sourceRowValues,newTargetRow); merge(sourceRow, sourceRowValues, newTargetRow);
} }
rows.close(); rows.close();
targetTable.fire(session, evaluateTriggerMasks(), false); targetTable.fire(session, evaluateTriggerMasks(), false);
...@@ -430,7 +441,37 @@ public class MergeUsing extends Merge { ...@@ -430,7 +441,37 @@ public class MergeUsing extends Merge {
return query; return query;
} }
public void setTemporaryTableView(TableView temporarySourceTableView) { public void setQuery(Query query) {
this.temporarySourceTableView = temporarySourceTableView; this.query = query;
} }
public void setTargetTableFilter(TableFilter targetTableFilter) {
this.targetTableFilter = targetTableFilter;
}
public TableFilter getTargetTableFilter() {
return targetTableFilter;
}
public Table getTargetTable() {
return targetTable;
}
public void setTargetTable(Table targetTable) {
this.targetTable = targetTable;
}
// Prepared interface
@Override
public boolean isTransactional() {
return true;
}
@Override
public ResultInterface queryMeta() {
return null;
}
@Override
public int getType() {
return CommandInterface.MERGE;
}
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论