This is an automated email from the ASF dual-hosted git repository.
ppa pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new d7a6037705 IGNITE-19116 Sql. Fixed NPE when a DML statement fails on a
non-existing table (#1917)
d7a6037705 is described below
commit d7a6037705f85a66cf086d70316d4d2855da7360
Author: Pavel Pereslegin <[email protected]>
AuthorDate: Wed Apr 12 22:50:43 2023 +0300
IGNITE-19116 Sql. Fixed NPE when a DML statement fails on a non-existing
table (#1917)
---
.../sql/engine/prepare/IgniteSqlValidator.java | 13 ++++++++-
.../sql/engine/planner/DmlPlannerTest.java | 31 ++++++++++++++++++++++
2 files changed, 43 insertions(+), 1 deletion(-)
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteSqlValidator.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteSqlValidator.java
index e084e73113..311a13181f 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteSqlValidator.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteSqlValidator.java
@@ -169,6 +169,11 @@ public class IgniteSqlValidator extends SqlValidatorImpl {
final SqlIdentifier targetTable = (SqlIdentifier)
call.getTargetTable();
final SqlValidatorTable table =
getCatalogReader().getTable(targetTable.names);
+ if (table == null) {
+ // TODO IGNITE-14865 Calcite exception should be converted/wrapped
into a public ignite exception.
+ throw newValidationError(call.getTargetTable(),
RESOURCE.objectNotFound(targetTable.toString()));
+ }
+
SqlIdentifier alias = call.getAlias() != null ? call.getAlias() :
new SqlIdentifier(deriveAlias(targetTable, 0),
SqlParserPos.ZERO);
@@ -208,7 +213,13 @@ public class IgniteSqlValidator extends SqlValidatorImpl {
@Override
protected SqlSelect createSourceSelectForDelete(SqlDelete call) {
final SqlNodeList selectList = new SqlNodeList(SqlParserPos.ZERO);
- final SqlValidatorTable table =
getCatalogReader().getTable(((SqlIdentifier) call.getTargetTable()).names);
+ final SqlIdentifier targetTable = (SqlIdentifier)
call.getTargetTable();
+ final SqlValidatorTable table =
getCatalogReader().getTable(targetTable.names);
+
+ if (table == null) {
+ // TODO IGNITE-14865 Calcite exception should be converted/wrapped
into a public ignite exception.
+ throw newValidationError(targetTable,
RESOURCE.objectNotFound(targetTable.toString()));
+ }
table.unwrap(IgniteTable.class).descriptor().deleteRowType((IgniteTypeFactory)
typeFactory)
.getFieldNames().stream()
diff --git
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/DmlPlannerTest.java
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/DmlPlannerTest.java
index 8613120468..6200ffa7cb 100644
---
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/DmlPlannerTest.java
+++
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/DmlPlannerTest.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.sql.engine.planner;
import java.util.List;
import java.util.UUID;
import java.util.stream.Stream;
+import org.apache.calcite.sql.validate.SqlValidatorException;
import org.apache.ignite.internal.schema.NativeTypes;
import org.apache.ignite.internal.sql.engine.framework.TestBuilders;
import org.apache.ignite.internal.sql.engine.rel.IgniteExchange;
@@ -30,6 +31,7 @@ import
org.apache.ignite.internal.sql.engine.schema.IgniteSchema;
import org.apache.ignite.internal.sql.engine.schema.IgniteTable;
import org.apache.ignite.internal.sql.engine.trait.IgniteDistribution;
import org.apache.ignite.internal.sql.engine.trait.IgniteDistributions;
+import org.apache.ignite.internal.testframework.IgniteTestUtils;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
@@ -152,6 +154,35 @@ public class DmlPlannerTest extends AbstractPlannerTest {
);
}
+ /**
+ * Test for check basic dml operators when table doesn't exist.
+ */
+ @ParameterizedTest
+ @MethodSource("basicStatements")
+ public void testDmlQueriesOnNonExistingTable(String query) {
+ //noinspection ThrowableNotThrown
+ IgniteTestUtils.assertThrowsWithCause(
+ () -> physicalPlan(query, createSchema(newTestTable("TEST",
IgniteDistributions.single()))),
+ SqlValidatorException.class,
+ "Object 'UNKNOWN' not found"
+ );
+ }
+
+ private static Stream<String> basicStatements() {
+ return Stream.of(
+ "SELECT * FROM unknown",
+ "INSERT INTO unknown VALUES(1)",
+ "UPDATE unknown SET ID=1",
+ "DELETE FROM unknown",
+ "MERGE INTO unknown DST USING test SRC ON DST.C1 = SRC.C1"
+ + " WHEN MATCHED THEN UPDATE SET C2 = SRC.C2"
+ + " WHEN NOT MATCHED THEN INSERT (C1, C2) VALUES
(SRC.C1, SRC.C2)",
+ "MERGE INTO test DST USING unknown SRC ON DST.C1 = SRC.C1"
+ + " WHEN MATCHED THEN UPDATE SET C2 = SRC.C2"
+ + " WHEN NOT MATCHED THEN INSERT (C1, C2) VALUES
(SRC.C1, SRC.C2)"
+ );
+ }
+
// Class name is fully-qualified because AbstractPlannerTest defines a
class with the same name.
private static org.apache.ignite.internal.sql.engine.framework.TestTable
newTestTable(
String tableName, IgniteDistribution distribution) {