This is an automated email from the ASF dual-hosted git repository. alexpl pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push: new 6c9f56c838f IGNITE-18458 SQL Calcite: Fix NPE on DML on non-existed table - Fixes #10464. 6c9f56c838f is described below commit 6c9f56c838f7c6247b6a15dd07fd75be1e8c061c Author: Ilhom Ulmasov <ilhom.ulma...@gmail.com> AuthorDate: Fri Dec 30 15:20:42 2022 +0300 IGNITE-18458 SQL Calcite: Fix NPE on DML on non-existed table - Fixes #10464. Signed-off-by: Aleksey Plekhanov <plehanov.a...@gmail.com> --- .../query/calcite/prepare/IgnitePlanner.java | 2 +- .../query/calcite/prepare/IgniteSqlValidator.java | 7 +++++ .../integration/TableDmlIntegrationTest.java | 34 ++++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgnitePlanner.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgnitePlanner.java index db7d66e9575..475d6ba3269 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgnitePlanner.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgnitePlanner.java @@ -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); } } diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteSqlValidator.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteSqlValidator.java index 74143e198d2..09b2b240cb6 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteSqlValidator.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteSqlValidator.java @@ -61,6 +61,7 @@ import org.apache.calcite.sql.validate.SqlValidatorNamespace; 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; @@ -153,6 +154,9 @@ public class IgniteSqlValidator extends SqlValidatorImpl { 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())); } @@ -169,6 +173,9 @@ public class IgniteSqlValidator extends SqlValidatorImpl { 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); diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/TableDmlIntegrationTest.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/TableDmlIntegrationTest.java index 5e1e76f21a9..06f5b58a142 100644 --- a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/TableDmlIntegrationTest.java +++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/TableDmlIntegrationTest.java @@ -458,6 +458,40 @@ public class TableDmlIntegrationTest extends AbstractBasicIntegrationTest { "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() {