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

Merge branch 'master' of https://github.com/h2database/h2database into Issue#589

...@@ -76,6 +76,7 @@ import org.h2.command.dml.ExecuteProcedure; ...@@ -76,6 +76,7 @@ import org.h2.command.dml.ExecuteProcedure;
import org.h2.command.dml.Explain; import org.h2.command.dml.Explain;
import org.h2.command.dml.Insert; import org.h2.command.dml.Insert;
import org.h2.command.dml.Merge; import org.h2.command.dml.Merge;
import org.h2.command.dml.MergeUsing;
import org.h2.command.dml.NoOperation; import org.h2.command.dml.NoOperation;
import org.h2.command.dml.Query; import org.h2.command.dml.Query;
import org.h2.command.dml.Replace; import org.h2.command.dml.Replace;
...@@ -845,6 +846,11 @@ public class Parser { ...@@ -845,6 +846,11 @@ public class Parser {
} }
TableFilter filter = readSimpleTableFilter(0); TableFilter filter = readSimpleTableFilter(0);
command.setTableFilter(filter); command.setTableFilter(filter);
parseDeleteGivenTable(command, limit, start);
return command;
}
private void parseDeleteGivenTable(Delete command, Expression limit, int start) {
if (readIf("WHERE")) { if (readIf("WHERE")) {
Expression condition = readExpression(); Expression condition = readExpression();
command.setCondition(condition); command.setCondition(condition);
...@@ -854,7 +860,6 @@ public class Parser { ...@@ -854,7 +860,6 @@ public class Parser {
} }
command.setLimit(limit); command.setLimit(limit);
setSQL(command, "DELETE", start); setSQL(command, "DELETE", start);
return command;
} }
private IndexColumn[] parseIndexColumnList() { private IndexColumn[] parseIndexColumnList() {
...@@ -1098,17 +1103,31 @@ public class Parser { ...@@ -1098,17 +1103,31 @@ public class Parser {
table_reference ::= table / view / sub-query table_reference ::= table / view / sub-query
*/ */
/* TODO Finish coding*/ /* TODO Finish coding*/
private Merge parseMergeUsing(Merge command) { private MergeUsing parseMergeUsing(Merge oldCommand) {
MergeUsing command = new MergeUsing(oldCommand);
if (readIf("(")) { if (readIf("(")) {
if (isSelect()) { if (isSelect()) {
command.setQuery(parseSelect()); command.setQuery(parseSelect());
read(")"); read(")");
} }
command.setQueryAlias(readFromAlias(null, Arrays.asList("ON")));
} }
else{ else{
List<String> excludeIdentifiers = Arrays.asList("ON"); List<String> excludeIdentifiers = Arrays.asList("ON");
TableFilter sourceTableFilter = readSimpleTableFilterWithAliasExcludes(0,excludeIdentifiers); TableFilter sourceTableFilter = readSimpleTableFilterWithAliasExcludes(0,excludeIdentifiers);
command.setSourceTableFilter(sourceTableFilter); command.setSourceTableFilter(sourceTableFilter);
StringBuilder buff = new StringBuilder(
"SELECT * FROM "+sourceTableFilter.getTable().getName());
if(sourceTableFilter.getTableAlias()!=null){
buff.append(" AS "+sourceTableFilter.getTableAlias());
}
//ArrayList<Value> paramValues = New.arrayList();
Prepared preparedQuery = prepare(session, buff.toString(), null/*paramValues*/);
System.out.println("class="+preparedQuery.getClass());
command.setQuery((Select)preparedQuery);
} }
read("ON"); read("ON");
read("("); read("(");
...@@ -1123,22 +1142,26 @@ public class Parser { ...@@ -1123,22 +1142,26 @@ public class Parser {
TableFilter filter = command.getTargetTableFilter(); TableFilter filter = command.getTargetTableFilter();
updateCommand.setTableFilter(filter); updateCommand.setTableFilter(filter);
parseUpdateSetClause(updateCommand, filter); parseUpdateSetClause(updateCommand, filter);
command.setUpdateOrDeleteCommand(updateCommand); command.setUpdateCommand(updateCommand);
} }
if (readIf("DELETE")){ if (readIf("DELETE")){
Delete deleteCommand = new Delete(session); Delete deleteCommand = new Delete(session);
TableFilter filter = command.getTargetTableFilter(); TableFilter filter = command.getTargetTableFilter();
deleteCommand.setTableFilter(filter); deleteCommand.setTableFilter(filter);
command.setUpdateOrDeleteCommand(deleteCommand); parseDeleteGivenTable(deleteCommand,null,lastParseIndex);
command.setDeleteCommand(deleteCommand);
} }
} }
if(readIf("WHEN")&&readIf("NOT")&&readIf("MATCHED")&&readIf("THEN")){ if(readIf("WHEN")&&readIf("NOT")&&readIf("MATCHED")&&readIf("THEN")){
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);
} }
}
return command; return command;
} }
...@@ -1380,6 +1403,10 @@ public class Parser { ...@@ -1380,6 +1403,10 @@ public class Parser {
} }
} }
} }
// inherit alias for temporary views (usually CTE's) from table name
if(table.isView() && table.isTemporary() && alias==null){
alias = table.getName();
}
return new TableFilter(session, table, alias, rightsChecked, return new TableFilter(session, table, alias, rightsChecked,
currentSelect, orderInFrom++, indexHints); currentSelect, orderInFrom++, indexHints);
} }
...@@ -1401,19 +1428,22 @@ public class Parser { ...@@ -1401,19 +1428,22 @@ public class Parser {
return IndexHints.createUseIndexHints(indexNames); return IndexHints.createUseIndexHints(indexNames);
} }
private String readFromAlias(String alias) { private String readFromAlias(String alias, List<String> excludeIdentifiers) {
if (readIf("AS")) { if (readIf("AS")) {
alias = readAliasIdentifier(); alias = readAliasIdentifier();
} else if (currentTokenType == IDENTIFIER) { } else if (currentTokenType == IDENTIFIER && !excludeIdentifiers.contains(currentToken)) {
// left and right are not keywords (because they are functions as
// well)
if (!isToken("LEFT") && !isToken("RIGHT") && !isToken("FULL")) {
alias = readAliasIdentifier(); alias = readAliasIdentifier();
} }
}
return alias; return alias;
} }
private String readFromAlias(String alias) {
// left and right are not keywords (because they are functions as
// well)
List<String> excludeIdentifiers = Arrays.asList("LEFT","RIGHT","FULL");;
return readFromAlias(alias, excludeIdentifiers);
}
private Prepared parseTruncate() { private Prepared parseTruncate() {
read("TABLE"); read("TABLE");
Table table = readTableOrView(); Table table = readTableOrView();
......
...@@ -454,4 +454,8 @@ public abstract class Prepared { ...@@ -454,4 +454,8 @@ public abstract class Prepared {
public void setCteCleanups(List<TableView> cteCleanups) { public void setCteCleanups(List<TableView> cteCleanups) {
this.cteCleanups = cteCleanups; this.cteCleanups = cteCleanups;
} }
public Session getSession() {
return session;
}
} }
...@@ -33,17 +33,13 @@ import org.h2.value.Value; ...@@ -33,17 +33,13 @@ import org.h2.value.Value;
*/ */
public class Merge extends Prepared { public class Merge extends Prepared {
private Table targetTable; protected Table targetTable;
private TableFilter targetTableFilter; protected TableFilter targetTableFilter;
private Column[] columns; protected Column[] columns;
private Column[] keys; protected Column[] keys;
private final ArrayList<Expression[]> valuesExpressionList = New.arrayList(); protected final ArrayList<Expression[]> valuesExpressionList = New.arrayList();
private Query query; protected Query query;
private Prepared update; protected Prepared update;
private TableFilter sourceTableFilter;
private ArrayList<Expression> conditions = new ArrayList<Expression>();
private Prepared updateOrDeleteCommand;
private Insert insertCommand;
public Merge(Session session) { public Merge(Session session) {
super(session); super(session);
...@@ -141,7 +137,7 @@ public class Merge extends Prepared { ...@@ -141,7 +137,7 @@ public class Merge extends Prepared {
return count; return count;
} }
private void merge(Row row) { protected void merge(Row row) {
ArrayList<Parameter> k = update.getParameters(); ArrayList<Parameter> k = update.getParameters();
for (int i = 0; i < columns.length; i++) { for (int i = 0; i < columns.length; i++) {
Column col = columns[i]; Column col = columns[i];
...@@ -316,14 +312,6 @@ public class Merge extends Prepared { ...@@ -316,14 +312,6 @@ public class Merge extends Prepared {
return true; return true;
} }
public void setSourceTableFilter(TableFilter sourceTableFilter) {
this.sourceTableFilter = sourceTableFilter;
}
public void addCondition(Expression condition) {
this.conditions .add(condition);
}
public Table getTargetTable() { public Table getTargetTable() {
return targetTable; return targetTable;
} }
...@@ -337,20 +325,6 @@ public class Merge extends Prepared { ...@@ -337,20 +325,6 @@ public class Merge extends Prepared {
setTargetTable(targetTableFilter.getTable()); setTargetTable(targetTableFilter.getTable());
} }
public Prepared getUpdateOrDeleteCommand() {
return updateOrDeleteCommand;
}
public void setUpdateOrDeleteCommand(Prepared updateOrDelete) {
this.updateOrDeleteCommand = updateOrDelete;
}
public Insert getInsertCommand() {
return insertCommand;
}
public void setInsertCommand(Insert insertCommand) {
this.insertCommand = insertCommand;
}
} }
差异被折叠。
...@@ -40,6 +40,7 @@ public class TestGeneralCommonTableQueries extends TestBase { ...@@ -40,6 +40,7 @@ public class TestGeneralCommonTableQueries extends TestBase {
testDelete(); testDelete();
testMerge(); testMerge();
testCreateTable(); testCreateTable();
testNestedSQL();
} }
private void testSimpleSelect() throws Exception { private void testSimpleSelect() throws Exception {
...@@ -388,4 +389,53 @@ public class TestGeneralCommonTableQueries extends TestBase { ...@@ -388,4 +389,53 @@ public class TestGeneralCommonTableQueries extends TestBase {
conn.close(); conn.close();
deleteDb("commonTableExpressionQueries"); deleteDb("commonTableExpressionQueries");
} }
private void testNestedSQL() throws Exception {
deleteDb("commonTableExpressionQueries");
Connection conn = getConnection("commonTableExpressionQueries");
PreparedStatement prep;
ResultSet rs;
prep = conn.prepareStatement(
"WITH T1 AS ( "+
" SELECT * "+
" FROM TABLE ( "+
" K VARCHAR = ('a', 'b'), "+
" V INTEGER = (1, 2) "+
" ) "+
"), "+
" "+
" "+
"T2 AS ( "+
" SELECT * "+
" FROM TABLE ( "+
" K VARCHAR = ('a', 'b'), "+
" V INTEGER = (3, 4) "+
" ) "+
"), "+
" "+
" "+
"JOIN_CTE AS ( "+
" SELECT T1.* "+
" "+
" FROM "+
" T1 "+
" JOIN T2 ON ( "+
" T1.K = T2.K "+
" ) "+
") "+
" "+
"SELECT * FROM JOIN_CTE");
rs = prep.executeQuery();
for (String keyLetter : new String[] { "a", "b" }) {
assertTrue(rs.next());
assertContains("ab",rs.getString(1));
assertEquals(rs.getString(1),keyLetter);
assertTrue(rs.getInt(2)!=0);
}
conn.close();
deleteDb("commonTableExpressionQueries");
}
} }
\ No newline at end of file
...@@ -10333,8 +10333,8 @@ explain with recursive r(n) as ( ...@@ -10333,8 +10333,8 @@ explain with recursive r(n) as (
) )
select n from r; select n from r;
> PLAN > PLAN
> ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- > -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> WITH RECURSIVE R(N) AS ( (SELECT 1 FROM SYSTEM_RANGE(1, 1) /* PUBLIC.RANGE_INDEX */) UNION ALL (SELECT (N + 1) FROM PUBLIC.R /* PUBLIC.R.tableScan */ WHERE N < 3) ) SELECT N FROM R /* null */ > WITH RECURSIVE R(N) AS ( (SELECT 1 FROM SYSTEM_RANGE(1, 1) /* PUBLIC.RANGE_INDEX */) UNION ALL (SELECT (N + 1) FROM PUBLIC.R /* PUBLIC.R.tableScan */ WHERE N < 3) ) SELECT N FROM R R /* null */
> rows: 1 > rows: 1
select sum(n) from ( select sum(n) from (
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论