提交 920722fc authored 作者: Owner's avatar Owner

Refined extra error messages

上级 cc1b27b5
......@@ -124,10 +124,10 @@ MERGE INTO TEST KEY(ID) VALUES(2, 'World')
"Commands (DML)","MERGE USING","
MERGE INTO targetTableName [ [AS] targetAlias]
USING { ( select ) | sourceTableName }[ [AS] sourceAlias ]
ON ( expression )
[ WHEN MATCHED THEN [ update ] [ delete] ]
[ WHEN NOT MATCHED THEN insert ]
USING { ( select ) | sourceTableName }[ [AS] sourceAlias ]
ON ( expression )
[ WHEN MATCHED THEN [ update ] [ delete] ]
[ WHEN NOT MATCHED THEN insert ]
","
Updates or deletes existing rows, and insert rows that don't exist. The ON clause
specifies the matching column expression and must be specified. If more than one row
......
......@@ -106,7 +106,7 @@ public class MergeUsing extends Merge {
}
}
if(sourceKeysRemembered.containsKey(sourceKeyValuesList)){
throw DbException.get(ErrorCode.DUPLICATE_KEY_1, "Merge using ON column expression, duplicate values found:keys"
throw DbException.get(ErrorCode.DUPLICATE_KEY_1, "Merge using ON column expression, duplicate values found:key columns"
+Arrays.asList(sourceKeys).toString()+":values:"+sourceKeyValuesList.toString()
+":from:"+sourceTableFilter.getTable()+":alias:"+sourceTableFilter.getTableAlias()+":current row number:"+countInputRows
+":conflicting row number:"+sourceKeysRemembered.get(sourceKeyValuesList));
......@@ -174,7 +174,7 @@ public class MergeUsing extends Merge {
rowUpdateCount += updateCommand.update();
System.out.println("update.count="+rowUpdateCount);
}
if(deleteCommand!=null && rowUpdateCount==0){
if(deleteCommand!=null){
System.out.println("deleteCommand="+deleteCommand.getPlanSQL());
rowUpdateCount += deleteCommand.update();
System.out.println("delete.count="+rowUpdateCount);
......@@ -364,12 +364,20 @@ public class MergeUsing extends Merge {
if (keys == null) {
HashSet<Column> targetColumns = buildColumnListFromOnCondition(targetTableFilter);
keys = targetColumns.toArray(new Column[1]);
}
keys = targetColumns.toArray(new Column[0]);
System.out.println("keys.length="+keys.length);
}
if(keys.length==0){
throw DbException.get(ErrorCode.COLUMN_NOT_FOUND_1,"No references to target columns found in ON clause:"+targetTableFilter.toString());
}
if (sourceKeys == null) {
HashSet<Column> sourceColumns = buildColumnListFromOnCondition(sourceTableFilter);
sourceKeys = sourceColumns.toArray(new Column[1]);
sourceKeys = sourceColumns.toArray(new Column[0]);
System.out.println("sourceKeys.length="+sourceKeys.length);
}
if(sourceKeys.length==0){
throw DbException.get(ErrorCode.COLUMN_NOT_FOUND_1,"No references to source columns found in ON clause:"+sourceTableFilter.toString());
}
// only do the optimise now - before we have already gathered the unoptimized column data
onCondition = onCondition.optimize(session);
......@@ -434,21 +442,19 @@ public class MergeUsing extends Merge {
}
private HashSet<Column> buildColumnListFromOnCondition(TableFilter targetTableFilter) {
HashSet<Column> targetColumns = new HashSet<Column>();
private HashSet<Column> buildColumnListFromOnCondition(TableFilter anyTableFilter) {
HashSet<Column> filteredColumns = new HashSet<Column>();
HashSet<Column> columns = new HashSet<Column>();
ExpressionVisitor visitor = ExpressionVisitor.getColumnsVisitor(columns);
onCondition.isEverything(visitor);
for(Column c: columns){
if(c.getTable()==targetTableFilter.getTable()){
targetColumns.add(c);
System.out.println("C="+c);
if(c!=null && c.getTable()==anyTableFilter.getTable()){
filteredColumns.add(c);
}
}
System.out.println("columnsVisitedForTable"+targetTableFilter.getTable()+"="+targetColumns);
if (targetColumns.isEmpty()) {
throw DbException.get(ErrorCode.CONSTRAINT_NOT_FOUND_1, "ON (condition) target columns missing");
}
return targetColumns;
System.out.println("columnsVisitedForTable"+anyTableFilter.getTable()+"="+filteredColumns);
return filteredColumns;
}
private Expression appendOnCondition(Update updateCommand) {
......
......@@ -123,7 +123,7 @@ public class TestMergeUsing extends TestBase {
GATHER_ORDERED_RESULTS_SQL,
"SELECT 1 AS ID, 'Marcy'||X||X AS NAME FROM SYSTEM_RANGE(1,1)",
3,
"Unique index or primary key violation: \"Merge using ON column expression, duplicate values found:keys[ID]:values:[1]:from:PUBLIC.SOURCE:alias:SOURCE:current row number:2:conflicting row number:1"
"Unique index or primary key violation: \"Merge using ON column expression, duplicate values found:key columns[ID]:values:[1]:from:PUBLIC.SOURCE:alias:SOURCE:current row number:2:conflicting row number:1"
);
// Duplicate key updated 3 rows at once, only 1 expected
......@@ -136,7 +136,27 @@ public class TestMergeUsing extends TestBase {
3,
"Duplicate key updated 3 rows at once, only 1 expected"
);
}
// Missing target columns in ON expression
testMergeUsingException(
"CREATE TABLE PARENT AS (SELECT 1 AS ID, 'Marcy'||X AS NAME FROM SYSTEM_RANGE(1,3) );"+
"CREATE TABLE SOURCE AS (SELECT X AS ID, 'Marcy'||X AS NAME FROM SYSTEM_RANGE(1,3) );",
"MERGE INTO PARENT USING SOURCE ON (1 = SOURCE.ID) WHEN MATCHED THEN UPDATE SET PARENT.NAME = SOURCE.NAME||SOURCE.ID WHERE PARENT.ID = 2 DELETE WHERE PARENT.ID = 1 WHEN NOT MATCHED THEN INSERT (ID, NAME) VALUES (SOURCE.ID, SOURCE.NAME)",
GATHER_ORDERED_RESULTS_SQL,
"SELECT X AS ID, 'Marcy'||X||X AS NAME FROM SYSTEM_RANGE(2,2) UNION ALL SELECT X AS ID, 'Marcy'||X AS NAME FROM SYSTEM_RANGE(3,3)",
3,
"No references to target columns found in ON clause"
);
// Missing source columns in ON expression
testMergeUsingException(
"CREATE TABLE PARENT AS (SELECT 1 AS ID, 'Marcy'||X AS NAME FROM SYSTEM_RANGE(1,3) );"+
"CREATE TABLE SOURCE AS (SELECT X AS ID, 'Marcy'||X AS NAME FROM SYSTEM_RANGE(1,3) );",
"MERGE INTO PARENT USING SOURCE ON (PARENT.ID = 1) WHEN MATCHED THEN UPDATE SET PARENT.NAME = SOURCE.NAME||SOURCE.ID WHERE PARENT.ID = 2 DELETE WHERE PARENT.ID = 1 WHEN NOT MATCHED THEN INSERT (ID, NAME) VALUES (SOURCE.ID, SOURCE.NAME)",
GATHER_ORDERED_RESULTS_SQL,
"SELECT X AS ID, 'Marcy'||X||X AS NAME FROM SYSTEM_RANGE(2,2) UNION ALL SELECT X AS ID, 'Marcy'||X AS NAME FROM SYSTEM_RANGE(3,3)",
3,
"No references to source columns found in ON clause"
);
}
/**
* Run a test case of the merge using syntax
......@@ -192,6 +212,7 @@ public class TestMergeUsing extends TestBase {
* @param gatherResultsSQL - a select which gathers the results of the merge from the target table
* @param expectedResultsSQL - a select which returns the expected results in the target table
* @param expectedRowUpdateCount - how many updates should be expected from the merge using
* @param exceptionMessage - the exception message expected
* @throws Exception
*/
private void testMergeUsingException(String setupSQL, String statementUnderTest, String gatherResultsSQL,
......@@ -201,6 +222,9 @@ public class TestMergeUsing extends TestBase {
expectedResultsSQL, expectedRowUpdateCount);
}
catch(RuntimeException|org.h2.jdbc.JdbcSQLException e){
if(!e.getMessage().contains(exceptionMessage)){
e.printStackTrace();
}
assertContains(e.getMessage(),exceptionMessage);
return;
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论