Skip to content

Commit

Permalink
IGNITE-18458 SQL Calcite: Fix NPE on DML on non-existed table - Fixes a…
Browse files Browse the repository at this point in the history
…pache#10464.

Signed-off-by: Aleksey Plekhanov <[email protected]>
  • Loading branch information
ilhomu authored and alex-plekhanov committed Dec 30, 2022
1 parent e9dbca1 commit 6c9f56c
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ public class IgnitePlanner implements Planner, RelOptTable.ViewExpander {
return validator().validate(sqlNode);
}
catch (RuntimeException e) {
throw new ValidationException(e);
throw new ValidationException(e.getMessage(), e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
import org.apache.calcite.sql.validate.SqlValidatorScope;
import org.apache.calcite.sql.validate.SqlValidatorTable;
import org.apache.calcite.sql.validate.SqlValidatorUtil;
import org.apache.calcite.util.Static;
import org.apache.ignite.internal.processors.query.QueryUtils;
import org.apache.ignite.internal.processors.query.calcite.schema.CacheTableDescriptor;
import org.apache.ignite.internal.processors.query.calcite.schema.IgniteCacheTable;
Expand Down Expand Up @@ -153,6 +154,9 @@ public IgniteSqlValidator(SqlOperatorTable opTab, CalciteCatalogReader catalogRe
private void validateTableModify(SqlNode table) {
final SqlValidatorTable targetTable = getCatalogReader().getTable(((SqlIdentifier)table).names);

if (targetTable == null)
throw newValidationError(table, Static.RESOURCE.objectNotFound(table.toString()));

if (!targetTable.unwrap(IgniteTable.class).isModifiable())
throw newValidationError(table, IgniteResource.INSTANCE.modifyTableNotSupported(table.toString()));
}
Expand All @@ -169,6 +173,9 @@ private void validateTableModify(SqlNode table) {
final SqlIdentifier targetTable = (SqlIdentifier)call.getTargetTable();
final SqlValidatorTable table = getCatalogReader().getTable(targetTable.names);

if (table == null)
throw newValidationError(call, Static.RESOURCE.objectNotFound(targetTable.toString()));

SqlIdentifier alias = call.getAlias() != null ? call.getAlias() :
new SqlIdentifier(deriveAlias(targetTable, 0), SqlParserPos.ZERO);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,40 @@ public void testMergeKeysConflict() {
"Failed to MERGE some keys due to keys conflict");
}

/**
* Ensure that DML operations fails with proper errors on non-existent table
*/
@Test
public void testFailureOnNonExistentTable() {
assertThrows("INSERT INTO NON_EXISTENT_TABLE(ID, NAME) VALUES (1, 'Name')",
IgniteSQLException.class,
"Object 'NON_EXISTENT_TABLE' not found");

assertThrows("UPDATE NON_EXISTENT_TABLE SET NAME ='NAME' WHERE ID = 1",
IgniteSQLException.class,
"Object 'NON_EXISTENT_TABLE' not found");

assertThrows("DELETE FROM NON_EXISTENT_TABLE WHERE ID = 1",
IgniteSQLException.class,
"Object 'NON_EXISTENT_TABLE' not found");

executeSql("CREATE TABLE PERSON(ID INT, PRIMARY KEY(id), NAME VARCHAR)");

assertThrows("" +
"MERGE INTO PERSON DST USING NON_EXISTENT_TABLE SRC ON DST.ID = SRC.ID" +
" WHEN MATCHED THEN UPDATE SET NAME = SRC.NAME" +
" WHEN NOT MATCHED THEN INSERT (ID, NAME) VALUES (SRC.ID, SRC.NAME)",
IgniteSQLException.class,
"Object 'NON_EXISTENT_TABLE' not found");

assertThrows("" +
"MERGE INTO NON_EXISTENT_TABLE DST USING PERSON SRC ON DST.ID = SRC.ID" +
" WHEN MATCHED THEN UPDATE SET NAME = SRC.NAME" +
" WHEN NOT MATCHED THEN INSERT (ID, NAME) VALUES (SRC.ID, SRC.NAME)",
IgniteSQLException.class,
"Object 'NON_EXISTENT_TABLE' not found");
}

/** */
@Test
public void testInsertDefaultValue() {
Expand Down

0 comments on commit 6c9f56c

Please sign in to comment.