提交 bb5c0974 authored 作者: Owner's avatar Owner

Joined onCOndition and fix for bad named select column alias

上级 518f51d1
...@@ -159,7 +159,6 @@ import org.h2.value.ValueNull; ...@@ -159,7 +159,6 @@ import org.h2.value.ValueNull;
import org.h2.value.ValueString; import org.h2.value.ValueString;
import org.h2.value.ValueTime; import org.h2.value.ValueTime;
import org.h2.value.ValueTimestamp; import org.h2.value.ValueTimestamp;
import com.sun.tools.javac.util.Assert;
/** /**
* The parser is used to convert a SQL statement string to an command object. * The parser is used to convert a SQL statement string to an command object.
...@@ -1117,22 +1116,28 @@ public class Parser { ...@@ -1117,22 +1116,28 @@ public class Parser {
private MergeUsing parseMergeUsing(Merge oldCommand, int start) { private MergeUsing parseMergeUsing(Merge oldCommand, int start) {
if(schemaName==null){ if(schemaName==null){
schemaName = session.getCurrentSchemaName(); schemaName = session.getCurrentSchemaName();
System.out.println("schemaName="+schemaName);
} }
Schema schema = getSchema(); Schema schema = getSchema();
String savedSchemaName = schemaName;
MergeUsing command = new MergeUsing(oldCommand); MergeUsing command = new MergeUsing(oldCommand);
currentPrepared = command; currentPrepared = command;
if (readIf("(")) { if (readIf("(")) {
System.out.println("pre select schema="+getSchema()+",schemaName="+schemaName);
if (isSelect()) { if (isSelect()) {
command.setQuery(parseSelect()); command.setQuery(parseSelect());
System.out.println("post select schema="+getSchema()+",schemaName="+schemaName);
schemaName = savedSchemaName;
System.out.println("post2 select schema="+getSchema()+",schemaName="+schemaName);
read(")"); read(")");
} }
command.setQueryAlias(readFromAlias(null, Arrays.asList("ON"))); command.setQueryAlias(readFromAlias(null, Arrays.asList("ON")));
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);
System.out.println("pre:alias="+command.getQueryAlias()+",sql="+querySQLOutput[0]+",ctlist="+columnTemplateList); System.out.println("pre:alias="+command.getQueryAlias()+",sql="+querySQLOutput[0]+",ctlist="+columnTemplateList+",schema="+getSchema()+",schemaName="+schemaName);
TableView temporarySourceTableView = createTemporarySessionView(command.getQueryAlias(), querySQLOutput[0], columnTemplateList, false); TableView temporarySourceTableView = createTemporarySessionView(command.getQueryAlias(), querySQLOutput[0], columnTemplateList, false);
command.setTemporaryTableView(temporarySourceTableView); command.setTemporaryTableView(temporarySourceTableView);
...@@ -1162,7 +1167,7 @@ public class Parser { ...@@ -1162,7 +1167,7 @@ public class Parser {
read("ON"); read("ON");
read("("); read("(");
Expression condition = readExpression(); Expression condition = readExpression();
command.addOnCondition(condition); command.setOnCondition(condition);
read(")"); read(")");
if(readIf("WHEN")&&readIf("MATCHED")&&readIf("THEN")){ if(readIf("WHEN")&&readIf("MATCHED")&&readIf("THEN")){
...@@ -5194,9 +5199,12 @@ public class Parser { ...@@ -5194,9 +5199,12 @@ public class Parser {
withQuery.prepare(); withQuery.prepare();
querySQLOutput[0] = StringUtils.cache(withQuery.getPlanSQL()); querySQLOutput[0] = StringUtils.cache(withQuery.getPlanSQL());
ArrayList<Expression> withExpressions = withQuery.getExpressions(); ArrayList<Expression> withExpressions = withQuery.getExpressions();
System.out.println("withExpressions="+withExpressions);
for (int i = 0; i < withExpressions.size(); ++i) { for (int i = 0; i < withExpressions.size(); ++i) {
Expression withExp = withExpressions.get(i);
System.out.println("withExp.alias="+withExp.getAlias()+",name="+withExp.getColumnName());
String columnName = cols != null ? cols[i] String columnName = cols != null ? cols[i]
: withExpressions.get(i).getColumnName(); : (withExp.getAlias()!=null ? withExp.getAlias() : withExp.getColumnName());
columnTemplateList.add(new Column(columnName, columnTemplateList.add(new Column(columnName,
withExpressions.get(i).getType())); withExpressions.get(i).getType()));
} }
......
...@@ -49,6 +49,10 @@ public class Delete extends Prepared { ...@@ -49,6 +49,10 @@ public class Delete extends Prepared {
public void setCondition(Expression condition) { public void setCondition(Expression condition) {
this.condition = condition; this.condition = condition;
} }
public Expression getCondition( ) {
return this.condition;
}
@Override @Override
public int update() { public int update() {
...@@ -135,7 +139,13 @@ public class Delete extends Prepared { ...@@ -135,7 +139,13 @@ public class Delete extends Prepared {
condition = condition.optimize(session); condition = condition.optimize(session);
condition.createIndexConditions(session, targetTableFilter); condition.createIndexConditions(session, targetTableFilter);
} }
TableFilter[] filters = new TableFilter[] { targetTableFilter, sourceTableFilter }; TableFilter[] filters;
if(sourceTableFilter==null){
filters = new TableFilter[] { targetTableFilter };
}
else{
filters = new TableFilter[] { targetTableFilter, sourceTableFilter };
}
PlanItem item = targetTableFilter.getBestPlanItem(session, filters, 0, PlanItem item = targetTableFilter.getBestPlanItem(session, filters, 0,
ExpressionVisitor.allColumnsForTableFilters(filters)); ExpressionVisitor.allColumnsForTableFilters(filters));
targetTableFilter.setPlanItem(item); targetTableFilter.setPlanItem(item);
......
...@@ -13,6 +13,7 @@ import org.h2.command.Prepared; ...@@ -13,6 +13,7 @@ import org.h2.command.Prepared;
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.engine.UndoLogRecord;
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;
...@@ -35,7 +36,7 @@ import org.h2.value.Value; ...@@ -35,7 +36,7 @@ import org.h2.value.Value;
public class MergeUsing extends Merge { public class MergeUsing extends Merge {
private TableFilter sourceTableFilter; private TableFilter sourceTableFilter;
private ArrayList<Expression> onConditions = new ArrayList<Expression>(); private Expression onCondition;
private Update updateCommand; private Update updateCommand;
private Delete deleteCommand; private Delete deleteCommand;
private Insert insertCommand; private Insert insertCommand;
...@@ -138,7 +139,7 @@ public class MergeUsing extends Merge { ...@@ -138,7 +139,7 @@ public class MergeUsing extends Merge {
// try and update // try and update
int count = 0; int count = 0;
if(updateCommand!=null){ if(updateCommand!=null){
System.out.println("onConditions="+onConditions.toString()); System.out.println("onConditions="+onCondition.toString());
System.out.println("updatePlanSQL="+updateCommand.getPlanSQL()); System.out.println("updatePlanSQL="+updateCommand.getPlanSQL());
count += updateCommand.update(); count += updateCommand.update();
System.out.println("update.count="+count); System.out.println("update.count="+count);
...@@ -305,22 +306,20 @@ public class MergeUsing extends Merge { ...@@ -305,22 +306,20 @@ public class MergeUsing extends Merge {
public void prepare() { public void prepare() {
System.out.println("prepare:targetTableFilterAlias="+targetTableFilter.getTableAlias()); System.out.println("prepare:targetTableFilterAlias="+targetTableFilter.getTableAlias());
System.out.println("prepare:sourceTableFilterAlias="+sourceTableFilter.getTableAlias()); System.out.println("prepare:sourceTableFilterAlias="+sourceTableFilter.getTableAlias());
System.out.println("prepare:onConditions="+onConditions); System.out.println("prepare:onConditions="+onCondition);
TableFilter[] filters = new TableFilter[] { sourceTableFilter, targetTableFilter }; TableFilter[] filters = new TableFilter[] { sourceTableFilter, targetTableFilter };
for(Expression condition: onConditions) { System.out.println("onCondition="+onCondition+":op="+onCondition.getClass().getSimpleName());
System.out.println("condition="+condition+":op="+condition.getClass().getSimpleName());
condition.addFilterConditions(sourceTableFilter, true); onCondition.addFilterConditions(sourceTableFilter, true);
condition.addFilterConditions(targetTableFilter, true); onCondition.addFilterConditions(targetTableFilter, true);
condition.mapColumns(sourceTableFilter, 2); onCondition.mapColumns(sourceTableFilter, 2);
condition.mapColumns(targetTableFilter, 1); onCondition.mapColumns(targetTableFilter, 1);
condition = condition.optimize(session); onCondition = onCondition.optimize(session);
condition.createIndexConditions(session, sourceTableFilter); onCondition.createIndexConditions(session, sourceTableFilter);
//optional //optional
condition.createIndexConditions(session, targetTableFilter); onCondition.createIndexConditions(session, targetTableFilter);
}
if (columns == null) { if (columns == null) {
if (valuesExpressionList.size() > 0 && valuesExpressionList.get(0).length == 0) { if (valuesExpressionList.size() > 0 && valuesExpressionList.get(0).length == 0) {
...@@ -361,10 +360,12 @@ public class MergeUsing extends Merge { ...@@ -361,10 +360,12 @@ public class MergeUsing extends Merge {
// Not sure how these sub-prepares will work... // Not sure how these sub-prepares will work...
if(updateCommand!=null){ if(updateCommand!=null){
updateCommand.setSourceTableFilter(sourceTableFilter); updateCommand.setSourceTableFilter(sourceTableFilter);
updateCommand.setCondition(appendOnCondition(updateCommand));
updateCommand.prepare(); updateCommand.prepare();
} }
if(deleteCommand!=null){ if(deleteCommand!=null){
deleteCommand.setSourceTableFilter(sourceTableFilter); deleteCommand.setSourceTableFilter(sourceTableFilter);
deleteCommand.setCondition(appendOnCondition(deleteCommand));
deleteCommand.prepare(); deleteCommand.prepare();
} }
if(insertCommand!=null){ if(insertCommand!=null){
...@@ -375,6 +376,20 @@ public class MergeUsing extends Merge { ...@@ -375,6 +376,20 @@ public class MergeUsing extends Merge {
} }
private Expression appendOnCondition(Update updateCommand) {
if (updateCommand.getCondition()==null){
return onCondition;
}
return new ConditionAndOr(ConditionAndOr.AND,updateCommand.getCondition(),onCondition);
}
private Expression appendOnCondition(Delete deleteCommand) {
if (deleteCommand.getCondition()==null){
return onCondition;
}
return new ConditionAndOr(ConditionAndOr.AND,deleteCommand.getCondition(),onCondition);
}
private String buildPreparedSQL() { private String buildPreparedSQL() {
StatementBuilder buff = new StatementBuilder("UPDATE "); StatementBuilder buff = new StatementBuilder("UPDATE ");
buff.append(targetTable.getSQL()); buff.append(targetTable.getSQL());
...@@ -400,8 +415,8 @@ public class MergeUsing extends Merge { ...@@ -400,8 +415,8 @@ public class MergeUsing extends Merge {
this.sourceTableFilter = sourceTableFilter; this.sourceTableFilter = sourceTableFilter;
} }
public void addOnCondition(Expression condition) { public void setOnCondition(Expression condition) {
this.onConditions .add(condition); this.onCondition = condition;
} }
public Prepared getUpdateCommand() { public Prepared getUpdateCommand() {
......
...@@ -58,6 +58,10 @@ public class Update extends Prepared { ...@@ -58,6 +58,10 @@ public class Update extends Prepared {
public void setCondition(Expression condition) { public void setCondition(Expression condition) {
this.condition = condition; this.condition = condition;
} }
public Expression getCondition( ) {
return this.condition;
}
/** /**
* Add an assignment of the form column = expression. * Add an assignment of the form column = expression.
...@@ -195,7 +199,13 @@ public class Update extends Prepared { ...@@ -195,7 +199,13 @@ public class Update extends Prepared {
} }
expressionMap.put(c, e.optimize(session)); expressionMap.put(c, e.optimize(session));
} }
TableFilter[] filters = new TableFilter[] { targetTableFilter }; TableFilter[] filters;
if(sourceTableFilter==null){
filters = new TableFilter[] { targetTableFilter };
}
else{
filters = new TableFilter[] { targetTableFilter, sourceTableFilter };
}
PlanItem item = targetTableFilter.getBestPlanItem(session, filters, 0, PlanItem item = targetTableFilter.getBestPlanItem(session, filters, 0,
ExpressionVisitor.allColumnsForTableFilters(filters)); ExpressionVisitor.allColumnsForTableFilters(filters));
targetTableFilter.setPlanItem(item); targetTableFilter.setPlanItem(item);
...@@ -233,5 +243,4 @@ public class Update extends Prepared { ...@@ -233,5 +243,4 @@ public class Update extends Prepared {
public void setSourceTableFilter(TableFilter sourceTableFilter) { public void setSourceTableFilter(TableFilter sourceTableFilter) {
this.sourceTableFilter = sourceTableFilter; this.sourceTableFilter = sourceTableFilter;
} }
} }
...@@ -42,19 +42,21 @@ public class TestMergeUsing extends TestBase { ...@@ -42,19 +42,21 @@ public class TestMergeUsing extends TestBase {
stat = conn.createStatement(); stat = conn.createStatement();
stat.execute("CREATE TABLE PARENT(ID INT, NAME VARCHAR, PRIMARY KEY(ID) );"); stat.execute("CREATE TABLE PARENT(ID INT, NAME VARCHAR, PRIMARY KEY(ID) );");
prep = conn.prepareStatement("MERGE INTO PARENT AS P USING (SELECT 1 AS ID, 'Marcy' AS NAME) AS S ON (P.ID = S.ID AND 1=1 AND S.ID = P.ID) WHEN MATCHED THEN UPDATE SET P.NAME = S.NAME WHERE 2 = 2 WHEN NOT MATCHED THEN INSERT (ID, NAME) VALUES (S.ID, S.NAME)"); prep = conn.prepareStatement("MERGE INTO PARENT AS P USING (SELECT X AS ID, 'Marcy'||X AS NAME FROM SYSTEM_RANGE(1,2) ) AS S ON (P.ID = S.ID AND 1=1 AND S.ID = P.ID) WHEN MATCHED THEN UPDATE SET P.NAME = S.NAME WHERE 2 = 2 WHEN NOT MATCHED THEN INSERT (ID, NAME) VALUES (S.ID, S.NAME)");
rowCount = prep.executeUpdate(); rowCount = prep.executeUpdate();
assertEquals(1,rowCount); int[] rowArray = new int[] { 1,2 };
assertEquals(rowArray.length,rowCount);
rs = stat.executeQuery("SELECT ID, NAME FROM PARENT"); rs = stat.executeQuery("SELECT ID, NAME FROM PARENT ORDER BY ID ASC");
for (int n : new int[] { 1 }) { for (int n : rowArray) {
assertTrue(rs.next()); assertTrue(rs.next());
assertEquals(1,rs.getInt(1)); assertEquals(n,rs.getInt(1));
assertEquals("Marcy", rs.getString(2)); assertEquals("Marcy"+n, rs.getString(2));
System.out.println("id="+rs.getInt(1)+",name="+rs.getString(2)); System.out.println("id="+rs.getInt(1)+",name="+rs.getString(2));
} }
assertFalse(rs.next());
conn.close(); conn.close();
deleteDb("mergeUsingQueries"); deleteDb("mergeUsingQueries");
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论