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 1cc2eb0b024 IGNITE-26446 Allow batching for compatible DDL operations
only (#6835)
1cc2eb0b024 is described below
commit 1cc2eb0b0245c953112cf6f2c2037542c6d75cb8
Author: Andrew V. Mashenkov <[email protected]>
AuthorDate: Mon Nov 3 19:24:47 2025 +0300
IGNITE-26446 Allow batching for compatible DDL operations only (#6835)
---
.../sql/engine/exec/fsm/DdlBatchAware.java | 37 +++++++++
.../sql/engine/exec/fsm/DdlBatchGroup.java | 32 ++++++++
.../sql/engine/exec/fsm/DdlBatchingHelper.java | 66 +++++++++++++++
.../sql/engine/exec/fsm/MultiStatementHandler.java | 4 +
.../sql/engine/sql/IgniteSqlAlterColumn.java | 2 +
.../engine/sql/IgniteSqlAlterTableAddColumn.java | 2 +
.../engine/sql/IgniteSqlAlterTableDropColumn.java | 2 +
.../sql/IgniteSqlAlterTableSetProperties.java | 2 +
.../sql/engine/sql/IgniteSqlAlterZoneRenameTo.java | 2 +
.../sql/engine/sql/IgniteSqlAlterZoneSet.java | 2 +
.../engine/sql/IgniteSqlAlterZoneSetDefault.java | 2 +
.../sql/engine/sql/IgniteSqlCreateIndex.java | 3 +
.../sql/engine/sql/IgniteSqlCreateSchema.java | 5 +-
.../sql/engine/sql/IgniteSqlCreateTable.java | 3 +
.../sql/engine/sql/IgniteSqlCreateZone.java | 3 +
.../sql/engine/sql/IgniteSqlDropIndex.java | 3 +
.../sql/engine/sql/IgniteSqlDropSchema.java | 5 +-
.../sql/engine/sql/IgniteSqlDropTable.java | 3 +
.../internal/sql/engine/sql/IgniteSqlDropZone.java | 3 +
.../internal/sql/engine/sql/ParsedResult.java | 15 +++-
.../internal/sql/engine/sql/ParserServiceImpl.java | 33 ++++++--
.../internal/sql/engine/exec/DdlBatchingTest.java | 96 +++++++++++++++++++++-
.../sql/engine/exec/fsm/DdlBatchingHelperTest.java | 53 ++++++++++++
.../sql/engine/sql/ParserServiceImplTest.java | 31 +++++--
24 files changed, 389 insertions(+), 20 deletions(-)
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/fsm/DdlBatchAware.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/fsm/DdlBatchAware.java
new file mode 100644
index 00000000000..31a7cc2da13
--- /dev/null
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/fsm/DdlBatchAware.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.sql.engine.exec.fsm;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation that defines how multi-statement handler executes DDL statement.
+ *
+ * <p>DDL statements of the same {@link DdlBatchGroup} can be executed in
together within the same batch except {@link DdlBatchGroup#OTHER}.
+ * Statements marked as {@link DdlBatchGroup#OTHER} can be executed only
separately, this is the default behavior.
+ */
+@Target({TYPE})
+@Retention(RUNTIME)
+public @interface DdlBatchAware {
+ /** Returns DDL batch group. */
+ DdlBatchGroup group() default DdlBatchGroup.OTHER;
+}
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/fsm/DdlBatchGroup.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/fsm/DdlBatchGroup.java
new file mode 100644
index 00000000000..9dd5b09a555
--- /dev/null
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/fsm/DdlBatchGroup.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.sql.engine.exec.fsm;
+
+/**
+ * Groups that is used for DDL operations batching.
+ *
+ * @see DdlBatchAware
+ */
+public enum DdlBatchGroup {
+ /** Group for CREATE operations. */
+ CREATE,
+ /** Group for DROP operations. */
+ DROP,
+ /** Group for other DDL operations. */
+ OTHER;
+}
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/fsm/DdlBatchingHelper.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/fsm/DdlBatchingHelper.java
new file mode 100644
index 00000000000..b78358c0cf8
--- /dev/null
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/fsm/DdlBatchingHelper.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.sql.engine.exec.fsm;
+
+import org.apache.calcite.sql.SqlNode;
+import org.apache.ignite.internal.sql.engine.sql.ParsedResult;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Provide helper methods for batched DDL commands.
+ */
+public class DdlBatchingHelper {
+ /**
+ * Returns {@code true} if that statement is compatible with this
statement.
+ * Node: the operation is not commutative.
+ */
+ static boolean isCompatible(ParsedResult thisStatement, ParsedResult
thatStatement) {
+ @Nullable DdlBatchGroup batchGroup = thisStatement.ddlBatchGroup();
+ @Nullable DdlBatchGroup statementGroup = thatStatement.ddlBatchGroup();
+
+ if (batchGroup == null || statementGroup == null) {
+ // Actually, we should never get here, but If we missed smth, it
is always safe to fallback to non-batched execution.
+ assert false : "DDL statement should be batch aware.";
+
+ return false;
+ }
+
+ return isCompatible(batchGroup, statementGroup);
+ }
+
+ /**
+ * Returns {@code true} if that group is compatible with this group
+ * Node: the operation is not commutative.
+ */
+ static boolean isCompatible(DdlBatchGroup thisGroup, DdlBatchGroup
thatGroup) {
+ return (thisGroup != DdlBatchGroup.OTHER // OTHER group doesn't
support batching.
+ && thisGroup == thatGroup) // Groups matched.
+ || thisGroup == DdlBatchGroup.DROP;
+ }
+
+ /** Returns command kind or {@code null} if command is not {@link
DdlBatchAware batch aware}. */
+ public static @Nullable DdlBatchGroup extractDdlBatchGroup(SqlNode node) {
+ DdlBatchAware batchAwareAnnotation =
node.getClass().getDeclaredAnnotation(DdlBatchAware.class);
+
+ return batchAwareAnnotation == null ? null :
batchAwareAnnotation.group();
+ }
+
+ private DdlBatchingHelper() {
+ // No-op.
+ }
+}
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/fsm/MultiStatementHandler.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/fsm/MultiStatementHandler.java
index 31f8a2a5925..33558d59bfa 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/fsm/MultiStatementHandler.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/fsm/MultiStatementHandler.java
@@ -177,6 +177,10 @@ class MultiStatementHandler {
break;
}
+ if
(!DdlBatchingHelper.isCompatible(scriptStatement.parsedResult,
statement.parsedResult)) {
+ break;
+ }
+
scriptStatement = statement;
statements.poll();
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterColumn.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterColumn.java
index 346111e97a0..d727e228622 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterColumn.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterColumn.java
@@ -27,11 +27,13 @@ import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.SqlWriter;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.util.ImmutableNullableList;
+import org.apache.ignite.internal.sql.engine.exec.fsm.DdlBatchAware;
import org.jetbrains.annotations.Nullable;
/**
* Parse tree for {@code ALTER TABLE ... ALTER COLUMN} statement.
*/
+@DdlBatchAware
public class IgniteSqlAlterColumn extends IgniteAbstractSqlAlterTable {
/** ALTER TABLE .. ALTER COLUMN operator. */
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterTableAddColumn.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterTableAddColumn.java
index 92b5502b73d..0ed6e3e479b 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterTableAddColumn.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterTableAddColumn.java
@@ -28,11 +28,13 @@ import org.apache.calcite.sql.SqlNodeList;
import org.apache.calcite.sql.SqlWriter;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.util.ImmutableNullableList;
+import org.apache.ignite.internal.sql.engine.exec.fsm.DdlBatchAware;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Parse tree for {@code ALTER TABLE ... ADD COLUMN} statement.
*/
+@DdlBatchAware
public class IgniteSqlAlterTableAddColumn extends IgniteAbstractSqlAlterTable {
/** ALTER TABLE ... ADD COLUMN operator. */
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterTableDropColumn.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterTableDropColumn.java
index 293c6432537..1a5da146a51 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterTableDropColumn.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterTableDropColumn.java
@@ -28,11 +28,13 @@ import org.apache.calcite.sql.SqlNodeList;
import org.apache.calcite.sql.SqlWriter;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.util.ImmutableNullableList;
+import org.apache.ignite.internal.sql.engine.exec.fsm.DdlBatchAware;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Parse tree for {@code ALTER TABLE ... DROP COLUMN} statement.
*/
+@DdlBatchAware
public class IgniteSqlAlterTableDropColumn extends IgniteAbstractSqlAlterTable
{
/** ALTER TABLE operator. */
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterTableSetProperties.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterTableSetProperties.java
index 3a91eb95c97..49ae5321c24 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterTableSetProperties.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterTableSetProperties.java
@@ -28,11 +28,13 @@ import org.apache.calcite.sql.SqlNodeList;
import org.apache.calcite.sql.SqlWriter;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.util.ImmutableNullableList;
+import org.apache.ignite.internal.sql.engine.exec.fsm.DdlBatchAware;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Parse tree for {@code ALTER TABLE ... SET} statement.
*/
+@DdlBatchAware
public class IgniteSqlAlterTableSetProperties extends
IgniteAbstractSqlAlterTable {
/** ALTER TABLE ... SET operator. */
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterZoneRenameTo.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterZoneRenameTo.java
index fa8fb621bc6..a56bb509cf3 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterZoneRenameTo.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterZoneRenameTo.java
@@ -27,11 +27,13 @@ import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.SqlWriter;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.util.ImmutableNullableList;
+import org.apache.ignite.internal.sql.engine.exec.fsm.DdlBatchAware;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Parse tree for {@code ALTER ZONE RENAME TO} statement.
*/
+@DdlBatchAware
public class IgniteSqlAlterZoneRenameTo extends IgniteAbstractSqlAlterZone {
/** ALTER ZONE RENAME TO operator. */
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterZoneSet.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterZoneSet.java
index 85e11e85c94..8c164fb4020 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterZoneSet.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterZoneSet.java
@@ -28,11 +28,13 @@ import org.apache.calcite.sql.SqlNodeList;
import org.apache.calcite.sql.SqlWriter;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.util.ImmutableNullableList;
+import org.apache.ignite.internal.sql.engine.exec.fsm.DdlBatchAware;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Parse tree for {@code ALTER ZONE SET} statement.
*/
+@DdlBatchAware
public class IgniteSqlAlterZoneSet extends IgniteAbstractSqlAlterZone {
/** ALTER ZONE SET operator. */
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterZoneSetDefault.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterZoneSetDefault.java
index 28990eab659..971ca8cd37b 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterZoneSetDefault.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlAlterZoneSetDefault.java
@@ -26,11 +26,13 @@ import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.SqlWriter;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.util.ImmutableNullableList;
+import org.apache.ignite.internal.sql.engine.exec.fsm.DdlBatchAware;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Parse tree for {@code ALTER ZONE SET DEFAULT} statement.
*/
+@DdlBatchAware
public class IgniteSqlAlterZoneSetDefault extends IgniteAbstractSqlAlterZone {
/** ALTER ZONE SET DEFAULT operator. */
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlCreateIndex.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlCreateIndex.java
index b99e01a4147..40db137c60a 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlCreateIndex.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlCreateIndex.java
@@ -29,11 +29,14 @@ import org.apache.calcite.sql.SqlNodeList;
import org.apache.calcite.sql.SqlWriter;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.util.ImmutableNullableList;
+import org.apache.ignite.internal.sql.engine.exec.fsm.DdlBatchAware;
+import org.apache.ignite.internal.sql.engine.exec.fsm.DdlBatchGroup;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Parse tree for {@code CREATE INDEX} statement.
*/
+@DdlBatchAware(group = DdlBatchGroup.CREATE)
public class IgniteSqlCreateIndex extends SqlCreate {
/** CREATE INDEX operator. */
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlCreateSchema.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlCreateSchema.java
index 1de9c2508a4..02130b02b84 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlCreateSchema.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlCreateSchema.java
@@ -28,11 +28,14 @@ import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.SqlWriter;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.util.ImmutableNullableList;
+import org.apache.ignite.internal.sql.engine.exec.fsm.DdlBatchAware;
+import org.apache.ignite.internal.sql.engine.exec.fsm.DdlBatchGroup;
import org.jetbrains.annotations.Nullable;
/**
* Parse tree for {@code CREATE SCHEMA} statement.
*/
+@DdlBatchAware(group = DdlBatchGroup.CREATE)
public class IgniteSqlCreateSchema extends SqlCreate {
/** CREATE SCHEMA operator. */
@@ -40,7 +43,7 @@ public class IgniteSqlCreateSchema extends SqlCreate {
/** Constructor. */
protected Operator(boolean existFlag) {
- super("CREATE SCHEMA", SqlKind.OTHER_DDL, existFlag);
+ super("CREATE SCHEMA", SqlKind.CREATE_SCHEMA, existFlag);
}
/** {@inheritDoc} */
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlCreateTable.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlCreateTable.java
index 587ffa6c6a4..8acb2a948d4 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlCreateTable.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlCreateTable.java
@@ -29,11 +29,14 @@ import org.apache.calcite.sql.SqlNodeList;
import org.apache.calcite.sql.SqlWriter;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.util.ImmutableNullableList;
+import org.apache.ignite.internal.sql.engine.exec.fsm.DdlBatchAware;
+import org.apache.ignite.internal.sql.engine.exec.fsm.DdlBatchGroup;
import org.jetbrains.annotations.Nullable;
/**
* Parse tree for {@code CREATE TABLE} statement with Ignite specific features.
*/
+@DdlBatchAware(group = DdlBatchGroup.CREATE)
public class IgniteSqlCreateTable extends SqlCreate {
/** CREATE TABLE operator. */
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlCreateZone.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlCreateZone.java
index 0aae15d5ab0..f09e1267114 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlCreateZone.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlCreateZone.java
@@ -34,11 +34,14 @@ import org.apache.calcite.sql.SqlWriter;
import org.apache.calcite.sql.SqlWriter.FrameTypeEnum;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.util.ImmutableNullableList;
+import org.apache.ignite.internal.sql.engine.exec.fsm.DdlBatchAware;
+import org.apache.ignite.internal.sql.engine.exec.fsm.DdlBatchGroup;
import org.jetbrains.annotations.Nullable;
/**
* Parse tree for {@code CREATE ZONE} statement with Ignite specific features.
*/
+@DdlBatchAware(group = DdlBatchGroup.CREATE)
public class IgniteSqlCreateZone extends SqlCreate {
private static final String STORAGE_PROFILES_OPTION_NAME =
"STORAGE_PROFILES";
private static final Pattern STORAGE_PROFILES_SPLIT_PATTERN =
Pattern.compile("\\s*,\\s*");
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlDropIndex.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlDropIndex.java
index 2bbfe94ff80..b885df42558 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlDropIndex.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlDropIndex.java
@@ -28,11 +28,14 @@ import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.SqlWriter;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.util.ImmutableNullableList;
+import org.apache.ignite.internal.sql.engine.exec.fsm.DdlBatchAware;
+import org.apache.ignite.internal.sql.engine.exec.fsm.DdlBatchGroup;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Parse tree for {@code DROP INDEX} statement.
*/
+@DdlBatchAware(group = DdlBatchGroup.DROP)
public class IgniteSqlDropIndex extends SqlDrop {
/** DROP INDEX operator. */
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlDropSchema.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlDropSchema.java
index b94dcbf315c..2c7ce35216c 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlDropSchema.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlDropSchema.java
@@ -28,11 +28,14 @@ import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.SqlWriter;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.util.ImmutableNullableList;
+import org.apache.ignite.internal.sql.engine.exec.fsm.DdlBatchAware;
+import org.apache.ignite.internal.sql.engine.exec.fsm.DdlBatchGroup;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Parse tree for {@code DROP SCHEMA} statement.
*/
+@DdlBatchAware(group = DdlBatchGroup.DROP)
public class IgniteSqlDropSchema extends SqlDrop {
/** DROP SCHEMA operator. */
@@ -41,7 +44,7 @@ public class IgniteSqlDropSchema extends SqlDrop {
/** Constructor. */
protected Operator(boolean existFlag, IgniteSqlDropSchemaBehavior
dropBehavior) {
- super("DROP SCHEMA", SqlKind.OTHER_DDL, existFlag);
+ super("DROP SCHEMA", SqlKind.DROP_SCHEMA, existFlag);
this.dropBehavior = dropBehavior;
}
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlDropTable.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlDropTable.java
index cfc3f3e9b9e..d266e7750e4 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlDropTable.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlDropTable.java
@@ -27,11 +27,14 @@ import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.SqlWriter;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.util.ImmutableNullableList;
+import org.apache.ignite.internal.sql.engine.exec.fsm.DdlBatchAware;
+import org.apache.ignite.internal.sql.engine.exec.fsm.DdlBatchGroup;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Parse tree for {@code DROP TABLE} statement.
*/
+@DdlBatchAware(group = DdlBatchGroup.DROP)
public class IgniteSqlDropTable extends SqlDrop {
/** DROP TABLE operator. */
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlDropZone.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlDropZone.java
index a515acaa781..e583cf9191e 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlDropZone.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlDropZone.java
@@ -28,11 +28,14 @@ import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.SqlWriter;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.util.ImmutableNullableList;
+import org.apache.ignite.internal.sql.engine.exec.fsm.DdlBatchAware;
+import org.apache.ignite.internal.sql.engine.exec.fsm.DdlBatchGroup;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Parse tree for {@code DROP ZONE} statement.
*/
+@DdlBatchAware(group = DdlBatchGroup.DROP)
public class IgniteSqlDropZone extends SqlDrop {
/** DROP ZONE operator. */
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/ParsedResult.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/ParsedResult.java
index 27b3a79192a..cafc62e01ec 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/ParsedResult.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/ParsedResult.java
@@ -19,6 +19,8 @@ package org.apache.ignite.internal.sql.engine.sql;
import org.apache.calcite.sql.SqlNode;
import org.apache.ignite.internal.sql.engine.SqlQueryType;
+import org.apache.ignite.internal.sql.engine.exec.fsm.DdlBatchGroup;
+import org.jetbrains.annotations.Nullable;
/**
* Result of the parse.
@@ -43,6 +45,17 @@ public interface ParsedResult {
/** Returns the count of the dynamic params (specified by question marks
in the query text) used in the query. */
int dynamicParamsCount();
- /** Returns the syntax tree of the query according to the grammar rules. */
+ /**
+ * Returns the syntax tree of the query according to the grammar rules for
planning purposes.
+ *
+ * <p>Note: Each call should return new tree instance.
+ */
SqlNode parsedTree();
+
+ /**
+ * Returns {@link DdlBatchGroup} for batching purposes or {@code null} if
not applicable.
+ */
+ default @Nullable DdlBatchGroup ddlBatchGroup() {
+ return null;
+ }
}
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/ParserServiceImpl.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/ParserServiceImpl.java
index 94b808ac8b1..95130b3cca9 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/ParserServiceImpl.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/ParserServiceImpl.java
@@ -29,7 +29,10 @@ import org.apache.calcite.sql.dialect.AnsiSqlDialect;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.sql.pretty.SqlPrettyWriter;
import org.apache.ignite.internal.sql.engine.SqlQueryType;
+import org.apache.ignite.internal.sql.engine.exec.fsm.DdlBatchGroup;
+import org.apache.ignite.internal.sql.engine.exec.fsm.DdlBatchingHelper;
import org.apache.ignite.internal.sql.engine.util.Commons;
+import org.jetbrains.annotations.Nullable;
/**
* An implementation of {@link ParserService} that, apart of parsing,
introduces cache of parsed results.
@@ -85,13 +88,15 @@ public class ParserServiceImpl implements ParserService {
originalQuery,
normalizedQuery,
result.dynamicParamsCount(),
- () -> {
- if (queryType != SqlQueryType.TX_CONTROL &&
!used.compareAndSet(false, true)) {
- throw new IllegalStateException("Parsed result of
script is not reusable.");
- }
-
- return parsedTree;
- }
+ DdlBatchingHelper.extractDdlBatchGroup(parsedTree),
+ queryType == SqlQueryType.TX_CONTROL ? () -> parsedTree
+ : () -> {
+ if (!used.compareAndSet(false, true)) {
+ throw new IllegalStateException("Parsed
result of script is not reusable.");
+ }
+
+ return parsedTree;
+ }
));
}
@@ -141,6 +146,7 @@ public class ParserServiceImpl implements ParserService {
originalQuery,
normalizedQuery,
dynamicParamsCount,
+ DdlBatchingHelper.extractDdlBatchGroup(parsedTree),
() -> {
// Descendants of SqlNode class are mutable, thus we must
use every
// syntax node only once to avoid problem. But we already
parsed the
@@ -164,12 +170,14 @@ public class ParserServiceImpl implements ParserService {
private final String normalizedQuery;
private final int dynamicParamCount;
private final Supplier<SqlNode> parsedTreeSupplier;
+ private final @Nullable DdlBatchGroup ddlBatchGroup;
private ParsedResultImpl(
SqlQueryType queryType,
String originalQuery,
String normalizedQuery,
int dynamicParamCount,
+ @Nullable DdlBatchGroup ddlBatchGroup,
Supplier<SqlNode> parsedTreeSupplier
) {
this.queryType = queryType;
@@ -177,6 +185,11 @@ public class ParserServiceImpl implements ParserService {
this.normalizedQuery = normalizedQuery;
this.dynamicParamCount = dynamicParamCount;
this.parsedTreeSupplier = parsedTreeSupplier;
+ this.ddlBatchGroup = ddlBatchGroup;
+
+ // Here we ensure that DDL batch group is set for DDL queries.
+ // For the case the one missed adding DDL operation to the
Multi-statement test.
+ assert queryType != SqlQueryType.DDL || ddlBatchGroup != null :
"DDL query without batch group";
}
/** {@inheritDoc} */
@@ -203,6 +216,12 @@ public class ParserServiceImpl implements ParserService {
return dynamicParamCount;
}
+ /** {@inheritDoc} */
+ @Override
+ public @Nullable DdlBatchGroup ddlBatchGroup() {
+ return ddlBatchGroup;
+ }
+
/** {@inheritDoc} */
@Override
public SqlNode parsedTree() {
diff --git
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/DdlBatchingTest.java
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/DdlBatchingTest.java
index a479a86fa06..9c3e2917509 100644
---
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/DdlBatchingTest.java
+++
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/DdlBatchingTest.java
@@ -92,7 +92,7 @@ public class DdlBatchingTest extends BaseIgniteAbstractTest {
@Test
void schemaAndTableCreatedInTheSameBatch() {
AsyncSqlCursor<InternalSqlRow> cursor = gatewayNode.executeQuery(
- "CREATE SCHEMA my_schema;"
+ "CREATE SCHEMA my_schema;"
+ "CREATE TABLE my_schema.t1 (id INT PRIMARY KEY,
val_1 INT, val_2 INT);"
+ "CREATE INDEX t1_ind_1 ON my_schema.t1 (val_1);"
);
@@ -196,13 +196,101 @@ public class DdlBatchingTest extends
BaseIgniteAbstractTest {
assertIndexExists("t1_ind_2");
}
+ @Test
+ void batchIsSplitByAlter() {
+ AsyncSqlCursor<InternalSqlRow> cursor = gatewayNode.executeQuery(
+ "CREATE TABLE t1 (id INT PRIMARY KEY, val_1 INT, val_2 INT);"
+ + "ALTER TABLE t1 ADD COLUMN val_3 INT;"
+ + "ALTER TABLE t1 DROP COLUMN val_2;"
+ + "CREATE TABLE t2 (id INT PRIMARY KEY, val_1 INT,
val_2 INT);"
+ );
+
+ // CREATE TABLE t1 (id INT PRIMARY KEY, val_1 INT, val_2 INT)
+ assertDdlResult(cursor, true);
+ assertThat(cursor.hasNextResult(), is(true));
+ assertThat(cursor.nextResult(), willSucceedFast());
+
+ // ALTER TABLE t ADD COLUMN val_3 INT;
+ cursor = cursor.nextResult().join();
+ assertDdlResult(cursor, true);
+ assertThat(cursor.hasNextResult(), is(true));
+ assertThat(cursor.nextResult(), willSucceedFast());
+
+ // ALTER TABLE t DROP COLUMN val_2 INT;
+ cursor = cursor.nextResult().join();
+ assertDdlResult(cursor, true);
+ assertThat(cursor.hasNextResult(), is(true));
+ assertThat(cursor.nextResult(), willSucceedFast());
+
+ // CREATE TABLE t2 (id INT PRIMARY KEY, val_1 INT, val_2 INT)
+ cursor = cursor.nextResult().join();
+ assertDdlResult(cursor, true);
+ assertThat(cursor.hasNextResult(), is(false));
+
+ // ALTER splits the batch
+ assertEquals(4, executeCallCounter.get());
+
+ assertTableExists("t1");
+ assertTableExists("t2");
+ }
+
+ @Test
+ void batchIsSplitByDrop() {
+ AsyncSqlCursor<InternalSqlRow> cursor = gatewayNode.executeQuery(
+ "CREATE TABLE t1 (id INT PRIMARY KEY, val_1 INT, val_2 INT);"
+ + "CREATE TABLE t2 (id INT PRIMARY KEY, val_1 INT,
val_2 INT);"
+ + "CREATE INDEX t1_ind_1 ON t1 (val_1);"
+ + "DROP TABLE t1;"
+ + "DROP TABLE t2;"
+ + "CREATE TABLE t1 (id INT PRIMARY KEY, val_1 INT,
val_2 INT);"
+ );
+
+ // CREATE TABLE t1 (id INT PRIMARY KEY, val_1 INT, val_2 INT)
+ assertDdlResult(cursor, true);
+ assertThat(cursor.hasNextResult(), is(true));
+ assertThat(cursor.nextResult(), willSucceedFast());
+
+ // CREATE TABLE t2 (id INT PRIMARY KEY, val_1 INT, val_2 INT)
+ cursor = cursor.nextResult().join();
+ assertDdlResult(cursor, true);
+ assertThat(cursor.hasNextResult(), is(true));
+ assertThat(cursor.nextResult(), willSucceedFast());
+
+ // CREATE INDEX t1_ind_1 ON t1 (val_1)
+ cursor = cursor.nextResult().join();
+ assertDdlResult(cursor, true);
+ assertThat(cursor.hasNextResult(), is(true));
+ assertThat(cursor.nextResult(), willSucceedFast());
+
+ // DROP TABLE t1
+ cursor = cursor.nextResult().join();
+ assertDdlResult(cursor, true);
+ assertThat(cursor.hasNextResult(), is(true));
+ assertThat(cursor.nextResult(), willSucceedFast());
+
+ // DROP TABLE t2
+ cursor = cursor.nextResult().join();
+ assertDdlResult(cursor, true);
+ assertThat(cursor.hasNextResult(), is(true));
+ assertThat(cursor.nextResult(), willSucceedFast());
+
+ // CREATE TABLE t1 (id INT PRIMARY KEY, val_1 INT, val_2 INT)
+ cursor = cursor.nextResult().join();
+ assertDdlResult(cursor, true);
+ assertThat(cursor.hasNextResult(), is(false));
+
+ assertEquals(2, executeCallCounter.get());
+ assertTableExists("t1");
+ assertIndexNotExists("t1_ind_1");
+ }
+
@Test
void batchIsSplitByOtherStatements() {
AsyncSqlCursor<InternalSqlRow> cursor = gatewayNode.executeQuery(
"INSERT INTO blackhole SELECT x FROM system_range(1, 10);"
+ "CREATE TABLE t1 (id INT PRIMARY KEY, val_1 INT,
val_2 INT);"
+ "CREATE INDEX t1_ind_1 ON t1 (val_1);"
- + "CREATE INDEX t1_ind_2 ON t1 (val_2);"
+ + "CREATE INDEX t1_ind_2 ON t1 (val_2);"
+ "INSERT INTO blackhole SELECT x FROM system_range(1,
10);"
+ "CREATE TABLE t2 (id INT PRIMARY KEY, val_1 INT,
val_2 INT);"
+ "CREATE INDEX t2_ind_1 ON t2 (val_1);"
@@ -367,10 +455,10 @@ public class DdlBatchingTest extends
BaseIgniteAbstractTest {
}
/**
- * This case makes sure that exception thrown is matched the order of
execution, and not the order
+ * This case makes sure that exception thrown is matched the order of
execution, and not the order
* exceptions appear.
*
- * <p>To be more specific, first seen exception relates to absent PK
definition in 3rd statement, but
+ * <p>To be more specific, first seen exception relates to absent PK
definition in 3rd statement, but
* during execution the exception that should be thrown is the one
denoting that table with given name
* already exists (2nd statement).
*/
diff --git
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/fsm/DdlBatchingHelperTest.java
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/fsm/DdlBatchingHelperTest.java
new file mode 100644
index 00000000000..ae28eb3cd36
--- /dev/null
+++
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/fsm/DdlBatchingHelperTest.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.sql.engine.exec.fsm;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.EnumSet;
+import org.junit.jupiter.api.Test;
+
+/**
+ * DdlBatchingHelper self-test.
+ */
+public class DdlBatchingHelperTest {
+ @Test
+ void testDdlBatchingHelper() {
+ EnumSet<DdlBatchGroup> allExceptOther =
EnumSet.complementOf(EnumSet.of(DdlBatchGroup.OTHER));
+
+ assert !allExceptOther.isEmpty();
+
+ // Any group is compatible with itself (except OTHER).
+ for (DdlBatchGroup group : allExceptOther) {
+ assertTrue(DdlBatchingHelper.isCompatible(group, group),
group.toString());
+ }
+
+ // DROP can be followed by any other group (incl. OTHER).
+ for (DdlBatchGroup group : DdlBatchGroup.values()) {
+ assertTrue(DdlBatchingHelper.isCompatible(DdlBatchGroup.DROP,
group), group.toString());
+ }
+
+ // Other incompatible cases.
+ for (DdlBatchGroup batchGroup :
EnumSet.complementOf(EnumSet.of(DdlBatchGroup.DROP))) {
+ for (DdlBatchGroup group :
EnumSet.complementOf(EnumSet.of(batchGroup))) {
+ assertFalse(DdlBatchingHelper.isCompatible(batchGroup, group),
batchGroup + " vs " + group);
+ }
+ }
+ }
+}
diff --git
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/sql/ParserServiceImplTest.java
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/sql/ParserServiceImplTest.java
index d372ea8987a..21997a3159f 100644
---
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/sql/ParserServiceImplTest.java
+++
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/sql/ParserServiceImplTest.java
@@ -21,13 +21,18 @@ import static
org.apache.ignite.internal.sql.engine.util.SqlTestUtils.assertThro
import static
org.apache.ignite.internal.testframework.IgniteTestUtils.assertThrowsWithCause;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNotSame;
+import java.util.Arrays;
+import java.util.EnumSet;
import java.util.List;
+import java.util.stream.Collectors;
import org.apache.calcite.sql.SqlNode;
import org.apache.ignite.internal.lang.IgniteStringBuilder;
import org.apache.ignite.internal.sql.engine.SqlQueryType;
@@ -46,7 +51,9 @@ public class ParserServiceImplTest {
DML("INSERT INTO my_table VALUES (1, 1)", SqlQueryType.DML),
DDL("CREATE TABLE my_table (id INT PRIMARY KEY, avl INT)",
SqlQueryType.DDL),
EXPLAIN_QUERY("EXPLAIN PLAN FOR SELECT * FROM my_table",
SqlQueryType.EXPLAIN),
- EXPLAIN_DML("EXPLAIN PLAN FOR INSERT INTO my_table VALUES (1, 1)",
SqlQueryType.EXPLAIN);
+ EXPLAIN_DML("EXPLAIN PLAN FOR INSERT INTO my_table VALUES (1, 1)",
SqlQueryType.EXPLAIN),
+ TX_CONTROL("COMMIT", SqlQueryType.TX_CONTROL),
+ KILL("KILL QUERY 'abc'", SqlQueryType.KILL);
private final String text;
private final SqlQueryType type;
@@ -57,6 +64,14 @@ public class ParserServiceImplTest {
}
}
+ @Test
+ void ensureAllStatementsAreCovered() {
+ List<SqlQueryType> statementTypes =
Arrays.stream(Statement.values()).map(s -> s.type).collect(Collectors.toList());
+ EnumSet<SqlQueryType> missedTypes =
EnumSet.complementOf(EnumSet.copyOf(statementTypes));
+
+ assertThat(missedTypes, empty());
+ }
+
@ParameterizedTest
@EnumSource(Statement.class)
void serviceReturnsResultOfExpectedType(Statement statement) {
@@ -134,11 +149,15 @@ public class ParserServiceImplTest {
SqlNode parsedTree = result.parsedTree();
- assertThrowsWithCause(
- result::parsedTree,
- IllegalStateException.class,
- "Parsed result of script is not reusable"
- );
+ if (statements.get(i).type == SqlQueryType.TX_CONTROL) {
+ assertNotNull(result.parsedTree());
+ } else {
+ assertThrowsWithCause(
+ result::parsedTree,
+ IllegalStateException.class,
+ "Parsed result of script is not reusable"
+ );
+ }
assertThat(parsedTree, notNullValue());
assertThat(parsedTree.toString(),
equalTo(singleStatementResult.parsedTree().toString()));