This is an automated email from the ASF dual-hosted git repository.
amashenkov 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 c70b547321 IGNITE-19262 Sql. Throw exception on explicit TX with DDL
(#1948)
c70b547321 is described below
commit c70b54732178685a380588d61a992924f2746c21
Author: Andrew V. Mashenkov <[email protected]>
AuthorDate: Wed Apr 19 18:28:13 2023 +0300
IGNITE-19262 Sql. Throw exception on explicit TX with DDL (#1948)
---
.../apache/ignite/jdbc/AbstractJdbcSelfTest.java | 2 ++
.../apache/ignite/jdbc/ItJdbcErrorsSelfTest.java | 21 ++++++++++++
.../internal/sql/api/ItSqlAsynchronousApiTest.java | 34 ++++++++++++++++++
.../sql/api/ItSqlClientSynchronousApiTest.java | 6 ++++
.../internal/sql/api/ItSqlSynchronousApiTest.java | 40 ++++++++++++++++++++++
.../internal/sql/engine/SqlQueryProcessor.java | 15 ++++++--
6 files changed, 116 insertions(+), 2 deletions(-)
diff --git
a/modules/jdbc/src/integrationTest/java/org/apache/ignite/jdbc/AbstractJdbcSelfTest.java
b/modules/jdbc/src/integrationTest/java/org/apache/ignite/jdbc/AbstractJdbcSelfTest.java
index d02e5d1f7f..4cbc43fb3b 100644
---
a/modules/jdbc/src/integrationTest/java/org/apache/ignite/jdbc/AbstractJdbcSelfTest.java
+++
b/modules/jdbc/src/integrationTest/java/org/apache/ignite/jdbc/AbstractJdbcSelfTest.java
@@ -118,6 +118,8 @@ public class AbstractJdbcSelfTest extends
BaseIgniteAbstractTest {
protected void beforeTest(TestInfo testInfo) throws Exception {
setupBase(testInfo, WORK_DIR);
+ conn.setAutoCommit(true);
+
stmt = conn.createStatement();
assert stmt != null;
diff --git
a/modules/jdbc/src/integrationTest/java/org/apache/ignite/jdbc/ItJdbcErrorsSelfTest.java
b/modules/jdbc/src/integrationTest/java/org/apache/ignite/jdbc/ItJdbcErrorsSelfTest.java
index a77702acaa..2f6bad76a1 100644
---
a/modules/jdbc/src/integrationTest/java/org/apache/ignite/jdbc/ItJdbcErrorsSelfTest.java
+++
b/modules/jdbc/src/integrationTest/java/org/apache/ignite/jdbc/ItJdbcErrorsSelfTest.java
@@ -141,6 +141,27 @@ public class ItJdbcErrorsSelfTest extends
ItJdbcErrorsAbstractSelfTest {
}
}
+ /**
+ * Test error code when trying to execute DDL query within a transaction.
+ *
+ * @throws SQLException if failed.
+ */
+ @Disabled("https://issues.apache.org/jira/browse/IGNITE-18985")
+ @Test
+ public void testDdlWithDisabledAutoCommit() throws SQLException {
+ conn.setAutoCommit(false);
+
+ try (Statement stmt = conn.createStatement()) {
+ stmt.executeUpdate("CREATE TABLE test2 (id int primary key, val
varchar)");
+
+ fail("SQLException is expected");
+ } catch (SQLException e) {
+ assertTrue(e.getMessage() != null
+ && e.getMessage().contains("DDL doesn't support
transactions."),
+ "Unexpected error message: " + e.getMessage());
+ }
+ }
+
/**
* Check that unsupported explain of update operation causes Exception on
the driver side with correct code and
* message.
diff --git
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItSqlAsynchronousApiTest.java
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItSqlAsynchronousApiTest.java
index 0fdd77892a..56bcd4563b 100644
---
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItSqlAsynchronousApiTest.java
+++
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItSqlAsynchronousApiTest.java
@@ -599,6 +599,40 @@ public class ItSqlAsynchronousApiTest extends
ClusterPerClassIntegrationTest {
}
}
+ /**
+ * DDL is non-transactional.
+ */
+ @Test
+ public void ddlInTransaction() {
+ Session ses = igniteSql().createSession();
+ sql("CREATE TABLE TEST(ID INT PRIMARY KEY, VAL0 INT)");
+
+ {
+ Transaction tx = igniteTx().begin();
+ try {
+ assertThrowsWithCause(() -> await(ses.executeAsync(tx, "CREATE
TABLE TEST2(ID INT PRIMARY KEY, VAL0 INT)")),
+ SqlException.class,
+ "DDL doesn't support transactions."
+ );
+ } finally {
+ tx.rollback();
+ }
+ }
+ {
+ Transaction tx = igniteTx().begin();
+ AsyncResultSet<SqlRow> res = await(ses.executeAsync(tx, "INSERT
INTO TEST VALUES (?, ?)", -1, -1));
+ assertEquals(1, res.affectedRows());
+
+ assertThrowsWithCause(() -> await(ses.executeAsync(tx, "CREATE
TABLE TEST2(ID INT PRIMARY KEY, VAL0 INT)")),
+ SqlException.class,
+ "DDL doesn't support transactions."
+ );
+ tx.commit();
+
+ assertEquals(1, sql("SELECT ID FROM TEST WHERE ID = -1").size());
+ }
+ }
+
@Test
public void closeSession() {
sql("CREATE TABLE TEST(ID INT PRIMARY KEY, VAL0 INT)");
diff --git
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItSqlClientSynchronousApiTest.java
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItSqlClientSynchronousApiTest.java
index b055b6f251..671f0d3a1d 100644
---
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItSqlClientSynchronousApiTest.java
+++
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItSqlClientSynchronousApiTest.java
@@ -22,6 +22,7 @@ import static
org.apache.ignite.internal.runner.app.client.ItAbstractThinClientT
import org.apache.ignite.client.IgniteClient;
import org.apache.ignite.sql.IgniteSql;
import org.apache.ignite.sql.Session;
+import org.apache.ignite.tx.IgniteTransactions;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
@@ -49,6 +50,11 @@ public class ItSqlClientSynchronousApiTest extends
ItSqlSynchronousApiTest {
return client.sql();
}
+ @Override
+ protected IgniteTransactions igniteTx() {
+ return client.transactions();
+ }
+
@Override
@Test
public void dml() {
diff --git
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItSqlSynchronousApiTest.java
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItSqlSynchronousApiTest.java
index 0603dccee2..2b8a4aa09a 100644
---
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItSqlSynchronousApiTest.java
+++
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItSqlSynchronousApiTest.java
@@ -56,6 +56,8 @@ import org.apache.ignite.sql.SqlBatchException;
import org.apache.ignite.sql.SqlException;
import org.apache.ignite.sql.SqlRow;
import org.apache.ignite.table.Table;
+import org.apache.ignite.tx.IgniteTransactions;
+import org.apache.ignite.tx.Transaction;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
@@ -92,6 +94,10 @@ public class ItSqlSynchronousApiTest extends
ClusterPerClassIntegrationTest {
return CLUSTER_NODES.get(0).sql();
}
+ protected IgniteTransactions igniteTx() {
+ return CLUSTER_NODES.get(0).transactions();
+ }
+
@Test
public void ddl() throws Exception {
IgniteSql sql = igniteSql();
@@ -279,6 +285,40 @@ public class ItSqlSynchronousApiTest extends
ClusterPerClassIntegrationTest {
rs.close();
assertThrowsWithCause(() -> rs.forEachRemaining(Object::hashCode),
CursorClosedException.class);
}
+ }
+
+ /**
+ * DDL is non-transactional.
+ */
+ @Test
+ public void ddlInTransaction() {
+ Session ses = igniteSql().createSession();
+ sql("CREATE TABLE TEST(ID INT PRIMARY KEY, VAL0 INT)");
+
+ {
+ Transaction tx = igniteTx().begin();
+ try {
+ assertThrowsWithCause(() -> ses.execute(tx, "CREATE TABLE
TEST2(ID INT PRIMARY KEY, VAL0 INT)"),
+ SqlException.class,
+ "DDL doesn't support transactions."
+ );
+ } finally {
+ tx.rollback();
+ }
+ }
+ {
+ Transaction tx = igniteTx().begin();
+ ResultSet<SqlRow> res = ses.execute(tx, "INSERT INTO TEST VALUES
(?, ?)", -1, -1);
+ assertEquals(1, res.affectedRows());
+
+ assertThrowsWithCause(() -> ses.execute(tx, "CREATE TABLE TEST2(ID
INT PRIMARY KEY, VAL0 INT)"),
+ SqlException.class,
+ "DDL doesn't support transactions."
+ );
+ tx.commit();
+
+ assertEquals(1, sql("SELECT ID FROM TEST WHERE ID = -1").size());
+ }
TxManager txManagerInternal = (TxManager)
IgniteTestUtils.getFieldValue(CLUSTER_NODES.get(0), IgniteImpl.class,
"txManager");
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/SqlQueryProcessor.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/SqlQueryProcessor.java
index 4366c4f63a..7c3f29d78e 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/SqlQueryProcessor.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/SqlQueryProcessor.java
@@ -23,6 +23,7 @@ import static
org.apache.ignite.lang.ErrorGroups.Sql.QUERY_INVALID_ERR;
import static org.apache.ignite.lang.ErrorGroups.Sql.SCHEMA_NOT_FOUND_ERR;
import static org.apache.ignite.lang.ErrorGroups.Sql.SESSION_EXPIRED_ERR;
import static org.apache.ignite.lang.ErrorGroups.Sql.SESSION_NOT_FOUND_ERR;
+import static
org.apache.ignite.lang.ErrorGroups.Sql.UNSUPPORTED_DDL_OPERATION_ERR;
import static
org.apache.ignite.lang.ErrorGroups.Sql.UNSUPPORTED_SQL_OPERATION_KIND_ERR;
import static org.apache.ignite.lang.IgniteStringFormatter.format;
@@ -414,7 +415,7 @@ public class SqlQueryProcessor implements QueryProcessor {
StatementParseResult parseResult =
IgniteSqlParser.parse(sql, StatementParseResult.MODE);
SqlNode sqlNode = parseResult.statement();
- validateParsedStatement(context, parseResult, sqlNode,
params);
+ validateParsedStatement(context, outerTx, parseResult,
sqlNode, params);
return sqlNode;
})
@@ -591,7 +592,13 @@ public class SqlQueryProcessor implements QueryProcessor {
}
/** Performs additional validation of a parsed statement. **/
- private static void validateParsedStatement(QueryContext context,
ParseResult parseResult, SqlNode node, Object[] params) {
+ private static void validateParsedStatement(
+ QueryContext context,
+ InternalTransaction outerTx,
+ ParseResult parseResult,
+ SqlNode node,
+ Object[] params
+ ) {
Set<SqlQueryType> allowedTypes = context.allowedQueryTypes();
SqlQueryType queryType = Commons.getQueryType(node);
@@ -607,6 +614,10 @@ public class SqlQueryProcessor implements QueryProcessor {
throw new QueryValidationException(message);
}
+ if (SqlQueryType.DDL == queryType && outerTx != null) {
+ throw new SqlException(UNSUPPORTED_DDL_OPERATION_ERR, "DDL doesn't
support transactions.");
+ }
+
if (parseResult.dynamicParamsCount() != params.length) {
String message = format(
"Unexpected number of query parameters. Provided {} but
there is only {} dynamic parameter(s).",