提交 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;
import org.h2.value.ValueString;
import org.h2.value.ValueTime;
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.
......@@ -1117,22 +1116,28 @@ public class Parser {
private MergeUsing parseMergeUsing(Merge oldCommand, int start) {
if(schemaName==null){
schemaName = session.getCurrentSchemaName();
System.out.println("schemaName="+schemaName);
}
Schema schema = getSchema();
String savedSchemaName = schemaName;
MergeUsing command = new MergeUsing(oldCommand);
currentPrepared = command;
if (readIf("(")) {
System.out.println("pre select schema="+getSchema()+",schemaName="+schemaName);
if (isSelect()) {
command.setQuery(parseSelect());
System.out.println("post select schema="+getSchema()+",schemaName="+schemaName);
schemaName = savedSchemaName;
System.out.println("post2 select schema="+getSchema()+",schemaName="+schemaName);
read(")");
}
command.setQueryAlias(readFromAlias(null, Arrays.asList("ON")));
String[] querySQLOutput = new String[]{null};
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);
command.setTemporaryTableView(temporarySourceTableView);
......@@ -1162,7 +1167,7 @@ public class Parser {
read("ON");
read("(");
Expression condition = readExpression();
command.addOnCondition(condition);
command.setOnCondition(condition);
read(")");
if(readIf("WHEN")&&readIf("MATCHED")&&readIf("THEN")){
......@@ -5194,9 +5199,12 @@ public class Parser {
withQuery.prepare();
querySQLOutput[0] = StringUtils.cache(withQuery.getPlanSQL());
ArrayList<Expression> withExpressions = withQuery.getExpressions();
System.out.println("withExpressions="+withExpressions);
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]
: withExpressions.get(i).getColumnName();
: (withExp.getAlias()!=null ? withExp.getAlias() : withExp.getColumnName());
columnTemplateList.add(new Column(columnName,
withExpressions.get(i).getType()));
}
......
......@@ -50,6 +50,10 @@ public class Delete extends Prepared {
this.condition = condition;
}
public Expression getCondition( ) {
return this.condition;
}
@Override
public int update() {
targetTableFilter.startQuery(session);
......@@ -135,7 +139,13 @@ public class Delete extends Prepared {
condition = condition.optimize(session);
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,
ExpressionVisitor.allColumnsForTableFilters(filters));
targetTableFilter.setPlanItem(item);
......
......@@ -13,6 +13,7 @@ import org.h2.command.Prepared;
import org.h2.engine.Right;
import org.h2.engine.Session;
import org.h2.engine.UndoLogRecord;
import org.h2.expression.ConditionAndOr;
import org.h2.expression.Expression;
import org.h2.expression.ExpressionVisitor;
import org.h2.expression.Parameter;
......@@ -35,7 +36,7 @@ import org.h2.value.Value;
public class MergeUsing extends Merge {
private TableFilter sourceTableFilter;
private ArrayList<Expression> onConditions = new ArrayList<Expression>();
private Expression onCondition;
private Update updateCommand;
private Delete deleteCommand;
private Insert insertCommand;
......@@ -138,7 +139,7 @@ public class MergeUsing extends Merge {
// try and update
int count = 0;
if(updateCommand!=null){
System.out.println("onConditions="+onConditions.toString());
System.out.println("onConditions="+onCondition.toString());
System.out.println("updatePlanSQL="+updateCommand.getPlanSQL());
count += updateCommand.update();
System.out.println("update.count="+count);
......@@ -305,22 +306,20 @@ public class MergeUsing extends Merge {
public void prepare() {
System.out.println("prepare:targetTableFilterAlias="+targetTableFilter.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 };
for(Expression condition: onConditions) {
System.out.println("condition="+condition+":op="+condition.getClass().getSimpleName());
System.out.println("onCondition="+onCondition+":op="+onCondition.getClass().getSimpleName());
condition.addFilterConditions(sourceTableFilter, true);
condition.addFilterConditions(targetTableFilter, true);
condition.mapColumns(sourceTableFilter, 2);
condition.mapColumns(targetTableFilter, 1);
condition = condition.optimize(session);
condition.createIndexConditions(session, sourceTableFilter);
onCondition.addFilterConditions(sourceTableFilter, true);
onCondition.addFilterConditions(targetTableFilter, true);
onCondition.mapColumns(sourceTableFilter, 2);
onCondition.mapColumns(targetTableFilter, 1);
onCondition = onCondition.optimize(session);
onCondition.createIndexConditions(session, sourceTableFilter);
//optional
condition.createIndexConditions(session, targetTableFilter);
}
onCondition.createIndexConditions(session, targetTableFilter);
if (columns == null) {
if (valuesExpressionList.size() > 0 && valuesExpressionList.get(0).length == 0) {
......@@ -361,10 +360,12 @@ public class MergeUsing extends Merge {
// Not sure how these sub-prepares will work...
if(updateCommand!=null){
updateCommand.setSourceTableFilter(sourceTableFilter);
updateCommand.setCondition(appendOnCondition(updateCommand));
updateCommand.prepare();
}
if(deleteCommand!=null){
deleteCommand.setSourceTableFilter(sourceTableFilter);
deleteCommand.setCondition(appendOnCondition(deleteCommand));
deleteCommand.prepare();
}
if(insertCommand!=null){
......@@ -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() {
StatementBuilder buff = new StatementBuilder("UPDATE ");
buff.append(targetTable.getSQL());
......@@ -400,8 +415,8 @@ public class MergeUsing extends Merge {
this.sourceTableFilter = sourceTableFilter;
}
public void addOnCondition(Expression condition) {
this.onConditions .add(condition);
public void setOnCondition(Expression condition) {
this.onCondition = condition;
}
public Prepared getUpdateCommand() {
......
......@@ -59,6 +59,10 @@ public class Update extends Prepared {
this.condition = condition;
}
public Expression getCondition( ) {
return this.condition;
}
/**
* Add an assignment of the form column = expression.
*
......@@ -195,7 +199,13 @@ public class Update extends Prepared {
}
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,
ExpressionVisitor.allColumnsForTableFilters(filters));
targetTableFilter.setPlanItem(item);
......@@ -233,5 +243,4 @@ public class Update extends Prepared {
public void setSourceTableFilter(TableFilter sourceTableFilter) {
this.sourceTableFilter = sourceTableFilter;
}
}
......@@ -42,19 +42,21 @@ public class TestMergeUsing extends TestBase {
stat = conn.createStatement();
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();
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());
assertEquals(1,rs.getInt(1));
assertEquals("Marcy", rs.getString(2));
assertEquals(n,rs.getInt(1));
assertEquals("Marcy"+n, rs.getString(2));
System.out.println("id="+rs.getInt(1)+",name="+rs.getString(2));
}
assertFalse(rs.next());
conn.close();
deleteDb("mergeUsingQueries");
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论