提交 0ce7bc4e authored 作者: Owner's avatar Owner

Added readIfAll() to cope with all-or-nothing parsing for WHEN MATCHED THEN/WHEN…

Added readIfAll() to cope with all-or-nothing parsing for WHEN MATCHED THEN/WHEN NOT MATCHED THEN syntax
上级 309eb9ef
...@@ -1112,7 +1112,10 @@ public class Parser { ...@@ -1112,7 +1112,10 @@ public class Parser {
/* a select query is supplied */ /* a select query is supplied */
if (isSelect()) { if (isSelect()) {
command.setQuery(parseSelect()); command.setQuery(parseSelect());
schemaName = savedSchemaName; // TODO: the schema name is sometimes reset in the parseSelect call - fix this by resetting it
if(schemaName==null){
schemaName = savedSchemaName;
}
read(")"); read(")");
} }
command.setQueryAlias(readFromAlias(null, Arrays.asList("ON"))); command.setQueryAlias(readFromAlias(null, Arrays.asList("ON")));
...@@ -1147,7 +1150,7 @@ public class Parser { ...@@ -1147,7 +1150,7 @@ public class Parser {
command.setOnCondition(condition); command.setOnCondition(condition);
read(")"); read(")");
if(readIf("WHEN")&&readIf("MATCHED")&&readIf("THEN")){ if(readIfAll(Arrays.asList("WHEN","MATCHED","THEN"))){
int startMatched = lastParseIndex; int startMatched = lastParseIndex;
if (readIf("UPDATE")){ if (readIf("UPDATE")){
Update updateCommand = new Update(session); Update updateCommand = new Update(session);
...@@ -1166,7 +1169,7 @@ public class Parser { ...@@ -1166,7 +1169,7 @@ public class Parser {
command.setDeleteCommand(deleteCommand); command.setDeleteCommand(deleteCommand);
} }
} }
if(readIf("WHEN")&&readIf("NOT")&&readIf("MATCHED")&&readIf("THEN")){ if(readIfAll(Arrays.asList("WHEN","NOT","MATCHED","THEN"))){
if (readIf("INSERT")){ if (readIf("INSERT")){
Insert insertCommand = new Insert(session); Insert insertCommand = new Insert(session);
insertCommand.setTable(command.getTargetTable()); insertCommand.setTable(command.getTargetTable());
...@@ -3438,7 +3441,25 @@ public class Parser { ...@@ -3438,7 +3441,25 @@ public class Parser {
addExpected(token); addExpected(token);
return false; return false;
} }
private boolean readIfAll(List<String> tokens) {
// save parse location in case we have to fail this test
int start = lastParseIndex;
for(String token: tokens){
String currentTokenUpper = currentToken.toUpperCase();
if (!currentTokenQuoted && equalsToken(token, currentTokenUpper)) {
read();
}
else{
// revert parse location
parseIndex = start;
read();
return false;
}
}
return true;
}
private boolean isToken(String token) { private boolean isToken(String token) {
boolean result = equalsToken(token, currentToken) && boolean result = equalsToken(token, currentToken) &&
!currentTokenQuoted; !currentTokenQuoted;
......
...@@ -114,7 +114,16 @@ public class TestMergeUsing extends TestBase { ...@@ -114,7 +114,16 @@ public class TestMergeUsing extends TestBase {
3 3
); );
// Duplicate source keys: SQL standard says duplicate or repeated updates in same statement should cause errors // Only insert clause
testMergeUsing(
"CREATE TABLE PARENT AS (SELECT X AS ID, 'Marcy'||X AS NAME FROM SYSTEM_RANGE(1,1) );"+
"DELETE FROM PARENT;",
"MERGE INTO PARENT AS P USING (SELECT X AS ID, 'Marcy'||X AS NAME FROM SYSTEM_RANGE(1,3) ) AS S ON (P.ID = S.ID) WHEN NOT MATCHED THEN INSERT (ID, NAME) VALUES (S.ID, S.NAME)",
GATHER_ORDERED_RESULTS_SQL,
"SELECT X AS ID, 'Marcy'||X AS NAME FROM SYSTEM_RANGE(1,3)",
3
);
// Duplicate source keys: SQL standard says duplicate or repeated updates in same statement should cause errors
// One insert, one update one delete happens, target table missing PK, no source or target alias // One insert, one update one delete happens, target table missing PK, no source or target alias
testMergeUsingException( testMergeUsingException(
"CREATE TABLE PARENT AS (SELECT X AS ID, 'Marcy'||X AS NAME FROM SYSTEM_RANGE(1,1) );"+ "CREATE TABLE PARENT AS (SELECT X AS ID, 'Marcy'||X AS NAME FROM SYSTEM_RANGE(1,1) );"+
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论