This is an automated email from the ASF dual-hosted git repository.

korlov 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 343026e617 IGNITE-15979: Calcite engine. Script test runner ignores 
"statement error" queries result (#1596)
343026e617 is described below

commit 343026e6177b15928a7389c04161c4b17791a1f2
Author: Max Zhuravkov <[email protected]>
AuthorDate: Mon Feb 6 15:13:10 2023 +0400

    IGNITE-15979: Calcite engine. Script test runner ignores "statement error" 
queries result (#1596)
---
 .../apache/ignite/internal/sqllogic/Command.java   |  33 +
 .../apache/ignite/internal/sqllogic/EndLoop.java   |  41 ++
 .../ignite/internal/sqllogic/ItSqlLogicTest.java   |  70 +-
 .../org/apache/ignite/internal/sqllogic/Loop.java  |  98 +++
 .../apache/ignite/internal/sqllogic/OnlyIf.java    |  55 ++
 .../org/apache/ignite/internal/sqllogic/Query.java | 457 +++++++++++++
 .../apache/ignite/internal/sqllogic/Script.java    | 203 ++++++
 .../ignite/internal/sqllogic/ScriptContext.java    | 110 +++
 .../ignite/internal/sqllogic/ScriptException.java  |  64 ++
 .../ignite/internal/sqllogic/ScriptPosition.java   |  40 ++
 .../apache/ignite/internal/sqllogic/SkipIf.java    |  54 ++
 .../ignite/internal/sqllogic/SqlScriptRunner.java  | 753 +--------------------
 .../apache/ignite/internal/sqllogic/Statement.java | 165 +++++
 .../src/integrationTest/sql/_runner/self.test      |  97 +++
 .../sql/aggregate/aggregates/test_sum.test         |   2 +
 .../sql/aggregate/group/test_group_by.test         |   2 +
 .../sql/aggregate/group/test_group_by.test_ignore  |   1 +
 .../integrationTest/sql/function/blob/base64.test  |   4 +
 .../sql/function/numeric/test_trigo.test           |   2 +
 .../sql/function/numeric/test_type_resolution.test |  35 +
 .../sql/function/string/test_like_escape.test      |   4 -
 .../sql/join/natural/natural_join.test             |   9 +-
 .../sql/join/natural/natural_join.test_ignore      |   7 +-
 .../integrationTest/sql/order/test_order_by.test   |   5 -
 .../sql/order/test_order_by_exceptions.test        |  21 +-
 .../scalar/test_complex_correlated_subquery.test   |  28 +-
 .../test_complex_correlated_subquery.test_ignore   |   4 +-
 .../scalar/test_correlated_aggregate_subquery.test |   5 +
 .../subquery/scalar/test_correlated_subquery.test  |   4 +
 .../scalar/test_correlated_subquery_cte.test       |   6 +-
 .../sql/types/date/test_incorrect_dates.test       |  12 +
 .../sql/types/decimal/cast_from_decimal.test       |  20 +
 .../sql/types/decimal/cast_to_decimal.test         |  96 +++
 .../sql/types/decimal/decimal_arithmetic.test      |   4 +
 .../decimal/decimal_decimal_overflow_cast.test     |  20 +
 ..._overflow.test => decimal_overflow.test_ignore} |   6 +
 .../sql/types/decimal/decimal_overflow_table.test  |   6 +
 .../sql/types/decimal/test_decimal.test            |  11 +
 .../sql/types/decimal/test_decimal_ops.test        |   2 +
 .../types/string/test_scan_big_varchar.test_slow   |   9 +
 40 files changed, 1806 insertions(+), 759 deletions(-)

diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/Command.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/Command.java
new file mode 100644
index 0000000000..1b6a3e3e6e
--- /dev/null
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/Command.java
@@ -0,0 +1,33 @@
+/*
+ * 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.sqllogic;
+
+/**
+ * A base class for script commands.
+ */
+abstract class Command {
+    /** The position of this command in a script file. **/
+    final ScriptPosition posDesc;
+
+    Command(ScriptPosition posDesc) {
+        this.posDesc = posDesc;
+    }
+
+    /** Executes the command. **/
+    abstract void execute(ScriptContext ctx);
+}
diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/EndLoop.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/EndLoop.java
new file mode 100644
index 0000000000..bfe039b470
--- /dev/null
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/EndLoop.java
@@ -0,0 +1,41 @@
+/*
+ * 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.sqllogic;
+
+import java.util.Arrays;
+
+/**
+ * EndLoop command serves as a marker that ends a block of commands that forms 
a loop.
+ *
+ * @see Loop loop command
+ */
+final class EndLoop extends Command {
+
+    /** Creates an instance of Endloop command by parsing it from script and 
token. **/
+    EndLoop(Script script, ScriptContext ctx, String[] tokens) {
+        super(script.scriptPosition());
+        if (tokens.length > 1) {
+            throw new IllegalArgumentException("EndLoop accepts no arguments: 
" + Arrays.toString(tokens));
+        }
+    }
+
+    @Override
+    void execute(ScriptContext ctx) {
+        // No-op.
+    }
+}
diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/ItSqlLogicTest.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/ItSqlLogicTest.java
index 52b2ffa5ba..7ae5e52317 100644
--- 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/ItSqlLogicTest.java
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/ItSqlLogicTest.java
@@ -43,6 +43,7 @@ import org.apache.ignite.IgnitionManager;
 import org.apache.ignite.internal.logger.IgniteLogger;
 import org.apache.ignite.internal.logger.Loggers;
 import org.apache.ignite.internal.sqllogic.SqlLogicTestEnvironment.RestartMode;
+import org.apache.ignite.internal.sqllogic.SqlScriptRunner.RunnerRuntime;
 import org.apache.ignite.internal.testframework.SystemPropertiesExtension;
 import org.apache.ignite.internal.testframework.WithSystemProperty;
 import org.apache.ignite.internal.testframework.WorkDirectory;
@@ -51,6 +52,7 @@ import org.apache.ignite.internal.util.CollectionUtils;
 import org.apache.ignite.internal.util.IgniteUtils;
 import org.apache.ignite.lang.IgniteStringFormatter;
 import org.apache.ignite.lang.IgniteSystemProperties;
+import org.apache.ignite.sql.IgniteSql;
 import org.apache.ignite.sql.ResultSet;
 import org.apache.ignite.sql.Session;
 import org.apache.ignite.table.Table;
@@ -102,6 +104,36 @@ import org.junit.jupiter.api.extension.ExtendWith;
  * if by printf("%.3f"). NULL values are rendered as "NULL". Empty strings are 
rendered as "(empty)". Within non-empty strings, all control
  * characters and unprintable characters are rendered as "@".
  *
+ * <p>
+ * <b>Conditional execution</b>
+ * </p>
+ *
+ * <p>Both statements and queries can be skipped by adding {@code skipif 
condition} before them:
+ * <pre>
+ *     skipif condition
+ * </pre>
+ *
+ * <p>It is also possible to run both statements and queries only if some 
condition
+ * is specified by adding {@code onlyif condition} before them:
+ * <pre>
+ *     onlyif condition
+ * </pre>
+ * At the moment the only supported condition type is a name of a database 
engine.
+ * The default name of execution engine is ignite3.
+ * <pre>
+ *     # skips the next command if the current database engine is ignite3.
+ *     skipif ignite3
+ *
+ *     # runs the next command if the current database engine is ignite3.
+ *     onlyif ignite3
+ * </pre>
+ * <b>Extensions</b>
+ * <pre>
+ *   # similar to 'statement error' but also checks whether an error message 
contains the specified message substring.
+ *   statement error: From line 1, column 8 to line 1, column 10: Column 'COL' 
not found in any table
+ *   SELECT col
+ * </pre>
+ *
  * @see <a 
href="https://www.sqlite.org/sqllogictest/doc/trunk/about.wiki";>Extended format 
documentation.</a>
  */
 @Tag(value = "sqllogic")
@@ -118,6 +150,8 @@ public class ItSqlLogicTest {
 
     private static final IgniteLogger LOG = 
Loggers.forClass(ItSqlLogicTest.class);
 
+    private static final String DATABASE_ENGINE = "ignite3";
+
     /** Base port number. */
     private static final int BASE_PORT = 3344;
 
@@ -147,7 +181,7 @@ public class ItSqlLogicTest {
     /** Test timeout. */
     private static long TIMEOUT;
 
-    /** Regexp to filter tests scropts. */
+    /** Regexp to filter tests scripts. */
     private static Pattern TEST_REGEX;
 
     /** Cluster restart mode. */
@@ -226,11 +260,8 @@ public class ItSqlLogicTest {
 
         LOG.info(">>> Start: " + SCRIPTS_ROOT.relativize(testPath));
 
-        SqlScriptRunner r = new SqlScriptRunner(
-                testPath,
-                CollectionUtils.first(CLUSTER_NODES).sql(),
-                LOG
-        );
+        var runtime = new TestRunnerRuntime();
+        var r = new SqlScriptRunner(testPath, runtime);
 
         try {
             if (testPath.toString().endsWith("_slow")) {
@@ -319,4 +350,31 @@ public class ItSqlLogicTest {
 
         LOG.info(">>> Cluster is stopped.");
     }
+
+    private static final class TestRunnerRuntime implements RunnerRuntime {
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public IgniteSql sql() {
+            return CollectionUtils.first(CLUSTER_NODES).sql();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public IgniteLogger log() {
+            return LOG;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public String engineName() {
+            return DATABASE_ENGINE;
+        }
+    }
 }
diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/Loop.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/Loop.java
new file mode 100644
index 0000000000..9a192280b5
--- /dev/null
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/Loop.java
@@ -0,0 +1,98 @@
+/*
+ * 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.sqllogic;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Loop command allows to perform a block of commands multiple times:
+ * <pre>
+ *     # variable is an integer
+ *     loop variable start-value end-value-exclusive
+ * </pre>
+ * When an SQL statement or an SQL query is executed inside a loop, all 
placeholders {@code ${variable}}
+ * in that statement/query are replaced with the current value of that {@code 
variable}.
+ * <pre>
+ *     # Executes the query 10 times with i=[0, 2)
+ *     loop i 0 2
+ *     query I
+ *     SELECT MIN(c1) FROM (VALUES(${i}), (-1)) t(c1);
+ *     ----
+ *     -1
+ *     # A loop must be terminated by a EndLoop command.
+ *     endloop
+ *
+ *     # The above loop is equivalent to two query commands:
+ *     query I
+ *     SELECT MIN(c1) FROM (VALUES(0), (-1)) t(c1);
+ *     ----
+ *     -1
+ *
+ *     query I
+ *     SELECT MIN(c1) FROM (VALUES(1), (-1)) t(c1);
+ *     ----
+ *     -1
+ * </pre>
+ *
+ * @see EndLoop endloop command
+ */
+final class Loop extends Command {
+
+    private final List<Command> cmds = new ArrayList<>();
+
+    private final int begin;
+
+    private final int end;
+
+    private final String var;
+
+    Loop(Script script, ScriptContext ctx, String[] cmdTokens) throws 
IOException {
+        super(script.scriptPosition());
+
+        try {
+            var = cmdTokens[1];
+            begin = Integer.parseInt(cmdTokens[2]);
+            end = Integer.parseInt(cmdTokens[3]);
+        } catch (Exception e) {
+            throw script.reportInvalidCommand("Unexpected loop syntax", 
cmdTokens, e);
+        }
+
+        while (script.ready()) {
+            Command cmd = script.nextCommand();
+            if (cmd instanceof EndLoop) {
+                break;
+            }
+
+            cmds.add(cmd);
+        }
+    }
+
+    @Override
+    void execute(ScriptContext ctx) {
+        for (int i = begin; i < end; ++i) {
+            ctx.loopVars.put(var, i);
+
+            for (Command cmd : cmds) {
+                cmd.execute(ctx);
+            }
+        }
+    }
+}
diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/OnlyIf.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/OnlyIf.java
new file mode 100644
index 0000000000..c022e5e5a1
--- /dev/null
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/OnlyIf.java
@@ -0,0 +1,55 @@
+/*
+ * 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.sqllogic;
+
+import java.io.IOException;
+
+/**
+ * OnlyIf command executes the next command in a script only if the specific 
condition holds.
+ * <pre>
+ *     onlyif condition
+ *     statement ok
+ *     SELECT 1
+ * </pre>
+ * At the moment the only supported condition type is a name of a database 
engine.
+ */
+final class OnlyIf extends Command {
+
+    private final String[] condition;
+
+    private final Command command;
+
+    OnlyIf(Script script, ScriptContext ctx, String[] tokens) throws 
IOException {
+        super(script.scriptPosition());
+
+        var nextCommand = script.nextCommand();
+        if (nextCommand == null) {
+            throw script.reportInvalidCommand("Expected a next command", 
tokens);
+        }
+
+        this.command = nextCommand;
+        this.condition = tokens;
+    }
+
+    @Override
+    void execute(ScriptContext ctx) {
+        if (condition[1].equals(ctx.engineName)) {
+            command.execute(ctx);
+        }
+    }
+}
diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/Query.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/Query.java
new file mode 100644
index 0000000000..284d204aa0
--- /dev/null
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/Query.java
@@ -0,0 +1,457 @@
+/*
+ * 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.sqllogic;
+
+import com.google.common.base.Strings;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.TreeMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import org.apache.calcite.avatica.util.ByteString;
+import org.apache.ignite.internal.util.CollectionUtils;
+import org.apache.ignite.internal.util.IgniteUtils;
+
+/**
+ * Executes an SQL query and expects the specified result and fails when that 
result and an output of a query do not match.
+ * <pre>
+ *     query column_type1[column_type2,.. column_typeN] [sort_type] 
[equality_label]
+ * </pre>
+ * The expected results can be in two forms:
+ * <ul>
+ *     <li>a list of rows where items are separated by {@code TAB} character 
(#)</li>
+ *     <li>a number of rows and a hash of those results.</li>
+ * </ul>
+ * <p>
+ * # CAVEAT: beware that certain IDE settings if configured may cause 
translation of {@code TAB} characters
+ * into multiple {code SPACE} characters.
+ * </p>
+ * <pre>
+ *     # Match the results by their values
+ *     query I
+ *     SELECT c1 FROM (VALUES(1), (2)) t(c1)
+ *     ----
+ *     1
+ *     2
+ * </pre>
+ * <pre>
+ *     # Match the result by hash
+ *     query I
+ *     SELECT c1 FROM (VALUES(1), (2)) t(c1)
+ *     ----
+ *     2 values hashing to 6DDB4095EB719E2A9F0A3F95677D24E0
+ * </pre>
+ * <b>Expecting results of multiple queries to be equal</b>
+ * <p>
+ * It is possible to expect the results of multiple to be same using a 
combination of {@code label} and {@code hash}.
+ * </p>
+ * <pre>
+ *     query I nosort select-1
+ *     SELECT 1
+ *     ----
+ *     1 values hashing to B026324C6904B2A9CB4B88D6D61C81D1
+ *
+ *     # the query below is expected to have the same result as
+ *     # a query labeled select-1 and if it is not the case
+ *     # a report error is going to display that fact.
+ *     query I nosort select-1
+ *     SELECT 1 + 0
+ *     ----
+ *     1 values hashing to B026324C6904B2A9CB4B88D6D61C81D1
+ * </pre>
+ */
+final class Query extends Command {
+
+    /** Hashing label pattern. */
+    private static final Pattern HASHING_PTRN = Pattern.compile("([0-9]+) 
values hashing to ([0-9a-fA-F]+)");
+
+    /** Comparator for "valuesort" sort mode. */
+    private static final Comparator<Object> ITM_COMPARATOR = (r1, r2) -> {
+        String s1 = String.valueOf(r1);
+        String s2 = String.valueOf(r2);
+
+        return s1.compareTo(s2);
+    };
+
+    /** An SQL query string. **/
+    private final String sql;
+
+    /** Comparator for "rowsort" sort mode. */
+    private final Comparator<List<?>> rowComparator;
+
+    /** A list of column types expected in a result. **/
+    private final List<ColumnType> resTypes = new ArrayList<>();
+
+    /** Present if query results are presented in a form of rows. **/
+    private final List<List<String>> expectedRes;
+
+    /** Present if query results are presented in a form of a hash string. **/
+    private final String expectedHash;
+
+    /** Present if query results are presented in a form of a hash string. 
Otherwise -1. **/
+    private final int expectedRows;
+
+    /** Sorting algo. */
+    private SortType sortType = SortType.NOSORT;
+
+    /** Equality label. */
+    private String eqLabel;
+
+    Query(Script script, ScriptContext ctx, String[] cmd) throws IOException {
+        super(script.scriptPosition());
+
+        String resTypesChars = cmd[1];
+
+        if (cmd.length > 2) {
+            sortType = SortType.valueOf(cmd[2].toUpperCase());
+        }
+
+        if (cmd.length > 3) {
+            eqLabel = cmd[3].toLowerCase();
+        }
+
+        for (int i = 0; i < resTypesChars.length(); i++) {
+            switch (resTypesChars.charAt(i)) {
+                case 'I':
+                    resTypes.add(ColumnType.I);
+
+                    break;
+
+                case 'R':
+                    resTypes.add(ColumnType.R);
+
+                    break;
+
+                case 'T':
+                    resTypes.add(ColumnType.T);
+
+                    break;
+
+                default:
+                    throw script.reportInvalidCommand("Unknown type character 
'" + resTypesChars.charAt(i) + "'", cmd);
+            }
+        }
+
+        if (CollectionUtils.nullOrEmpty(resTypes)) {
+            throw script.reportInvalidCommand("Missing type string", cmd);
+        }
+
+        var sqlString = new StringBuilder();
+
+        // Read SQL query
+        while (script.ready()) {
+            String line = script.nextLine();
+
+            // Check for typos. Otherwise we are going to get very confusing 
errors down the road.
+            if (line.startsWith("--")) {
+                if (line.equals("----")) {
+                    break;
+                } else {
+                    throw script.reportError("Invalid query terminator 
sequence", line);
+                }
+            }
+
+            if (sqlString.length() > 0) {
+                sqlString.append("\n");
+            }
+
+            sqlString.append(line);
+        }
+
+        this.sql = sqlString.toString();
+
+        // Read expected results
+        String s = script.nextLineWithoutTrim();
+        Matcher m = HASHING_PTRN.matcher(s);
+
+        if (m.matches()) {
+            // Expected results are hashing
+            expectedRows = Integer.parseInt(m.group(1));
+            expectedHash = m.group(2);
+            expectedRes = null;
+        } else {
+            // Read expected results tuples.
+            expectedRes = new ArrayList<>();
+            expectedRows = -1;
+            expectedHash = null;
+
+            boolean singleValOnLine = false;
+
+            List<String> row = new ArrayList<>();
+
+            while (!Strings.isNullOrEmpty(s)) {
+                String[] vals = s.split("\\t");
+
+                if (!singleValOnLine && vals.length == 1 && vals.length != 
resTypes.size()) {
+                    singleValOnLine = true;
+                }
+
+                if (vals.length != resTypes.size() && !singleValOnLine) {
+                    var message = " [row=\"" + s + "\", types=" + resTypes + 
']';
+                    throw script.reportError("Invalid columns count at the 
result", message);
+                }
+
+                try {
+                    if (singleValOnLine) {
+                        row.add(ctx.nullLbl.equals(vals[0]) ? null : vals[0]);
+
+                        if (row.size() == resTypes.size()) {
+                            expectedRes.add(row);
+
+                            row = new ArrayList<>();
+                        }
+                    } else {
+                        for (String val : vals) {
+                            row.add(ctx.nullLbl.equals(val) ? null : val);
+                        }
+
+                        expectedRes.add(row);
+                        row = new ArrayList<>();
+                    }
+                } catch (Exception e) {
+                    var message = "[row=\"" + s + "\", types=" + resTypes + 
']';
+                    throw script.reportError("Cannot parse expected results", 
message, e);
+                }
+
+                s = script.nextLineWithoutTrim();
+            }
+        }
+
+        this.rowComparator = (r1, r2) -> {
+            int rows = r1.size();
+
+            for (int i = 0; i < rows; ++i) {
+                String s1 = resultToString(ctx, r1.get(i));
+                String s2 = resultToString(ctx, r2.get(i));
+
+                int comp = s1.compareTo(s2);
+
+                if (comp != 0) {
+                    return comp;
+                }
+            }
+
+            return 0;
+        };
+    }
+
+    @Override
+    void execute(ScriptContext ctx) {
+        List<List<?>> res = ctx.executeQuery(sql);
+
+        checkResult(ctx, res);
+    }
+
+    private void checkResult(ScriptContext ctx, List<List<?>> res) {
+        if (sortType == SortType.ROWSORT) {
+            res.sort(rowComparator);
+
+            if (expectedRes != null) {
+                expectedRes.sort(rowComparator);
+            }
+        } else if (sortType == SortType.VALUESORT) {
+            List<Object> flattenRes = new ArrayList<>();
+
+            res.forEach(flattenRes::addAll);
+
+            flattenRes.sort(ITM_COMPARATOR);
+
+            List<List<?>> resSizeAware = new ArrayList<>();
+            int rowLen = resTypes.size();
+            List<Object> rowRes = new ArrayList<>(rowLen);
+
+            for (Object item : flattenRes) {
+                rowRes.add(item);
+
+                if (--rowLen == 0) {
+                    resSizeAware.add(rowRes);
+                    rowRes = new ArrayList<>(rowLen);
+                    rowLen = resTypes.size();
+                }
+            }
+
+            res = resSizeAware;
+        }
+
+        if (expectedHash != null) {
+            checkResultsHashed(ctx, res);
+        } else {
+            checkResultTuples(ctx, res);
+        }
+    }
+
+    private void checkResultTuples(ScriptContext ctx, List<List<?>> res) {
+        if (expectedRes.size() != res.size()) {
+            throw new AssertionError("Invalid results rows count at: " + 
posDesc
+                    + ". [expectedRows=" + expectedRes.size() + ", 
actualRows=" + res.size()
+                    + ", expected=" + expectedRes + ", actual=" + res + ']');
+        }
+
+        for (int i = 0; i < expectedRes.size(); ++i) {
+            List<String> expectedRow = expectedRes.get(i);
+            List<?> row = res.get(i);
+
+            if (row.size() != expectedRow.size()) {
+                throw new AssertionError("Invalid columns count at: " + posDesc
+                        + ". [expected=" + expectedRes + ", actual=" + res + 
']');
+            }
+
+            for (int j = 0; j < expectedRow.size(); ++j) {
+                checkEquals(ctx,
+                        "Not expected result at: " + posDesc
+                                + ". [row=" + i + ", col=" + j
+                                + ", expected=" + expectedRow.get(j) + ", 
actual=" + resultToString(ctx, row.get(j)) + ']',
+                        expectedRow.get(j),
+                        row.get(j)
+                );
+            }
+        }
+    }
+
+    private static void checkEquals(ScriptContext ctx, String msg, String 
expectedStr, Object actual) {
+        if (actual == null && (expectedStr == null || 
ctx.nullLbl.equalsIgnoreCase(expectedStr))) {
+            return;
+        }
+
+        if (actual != null ^ expectedStr != null) {
+            throw new AssertionError(msg);
+        }
+
+        // Alternative values for boolean "0" and "1".
+        if (actual instanceof Boolean && expectedStr.equals((Boolean) actual ? 
"1" : "0")) {
+            return;
+        }
+
+        if (actual instanceof Number) {
+            if ("NaN".equals(expectedStr) || expectedStr.endsWith("Infinity")) 
{
+                if (!expectedStr.equals(String.valueOf(actual))) {
+                    throw new AssertionError(msg);
+                }
+            } else {
+                BigDecimal actDec = new BigDecimal(String.valueOf(actual));
+                BigDecimal expDec = new BigDecimal(expectedStr);
+
+                if (actDec.compareTo(expDec) != 0) {
+                    throw new AssertionError(msg);
+                }
+            }
+        } else if (actual instanceof Map) {
+            String actualStr = mapToString(ctx, (Map<? extends Comparable, ?>) 
actual);
+
+            if (!expectedStr.equals(actualStr)) {
+                throw new AssertionError(msg);
+            }
+        } else {
+            if (!String.valueOf(expectedStr).equals(resultToString(ctx, 
actual))
+                    && !("(empty)".equals(expectedStr) && resultToString(ctx, 
actual).isEmpty())) {
+                throw new AssertionError(msg);
+            }
+        }
+    }
+
+    private void checkResultsHashed(ScriptContext ctx, List<List<?>> res) {
+        Objects.requireNonNull(res, "empty result set");
+
+        ctx.messageDigest.reset();
+
+        for (List<?> row : res) {
+            for (Object col : row) {
+                ctx.messageDigest.update(resultToString(ctx, 
col).getBytes(StandardCharsets.UTF_8));
+                ctx.messageDigest.update(Script.LINE_SEPARATOR_BYTES);
+            }
+        }
+
+        String res0 = IgniteUtils.toHexString(ctx.messageDigest.digest());
+
+        if (eqLabel != null) {
+            if (res0.equals(expectedHash)) {
+                ctx.eqResStorage.computeIfAbsent(eqLabel, k -> new 
ArrayList<>()).add(sql.toString());
+            } else {
+                Collection<String> eq = ctx.eqResStorage.get(eqLabel);
+
+                if (eq != null) {
+                    throw new AssertionError("Unexpected hash result, error 
at: " + posDesc
+                            + ". Results of queries need to be equal: " + eq + 
"\n and \n" + sql);
+                }
+            }
+        }
+
+        if (!res0.equalsIgnoreCase(expectedHash)) {
+            throw new AssertionError("Unexpected hash result, error at: " + 
posDesc
+                    + ", expected=" + expectedHash + ", calculated=" + res0
+                    + ", expectedRows=" + expectedRows + ", returnedRows=" + 
res.size() * res.get(0).size());
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "Query ["
+                + "sql=" + sql
+                + ", resTypes=" + resTypes
+                + ", expectedRes=" + expectedRes
+                + ", expectedHash='" + expectedHash + '\''
+                + ", expectedRows=" + expectedRows
+                + ", sortType=" + sortType
+                + ", eqLabel='" + eqLabel + '\''
+                + ']';
+    }
+
+    private enum ColumnType {
+        I,
+        T,
+        R
+    }
+
+    private enum SortType {
+        ROWSORT,
+        VALUESORT,
+        NOSORT
+    }
+
+    private static String resultToString(ScriptContext ctx, Object res) {
+        if (res == null) {
+            return ctx.nullLbl;
+        } else if (res instanceof byte[]) {
+            return ByteString.toString((byte[]) res, 16);
+        } else if (res instanceof Map) {
+            return mapToString(ctx, (Map<?, ?>) res);
+        } else {
+            return String.valueOf(res);
+        }
+    }
+
+    private static String mapToString(ScriptContext ctx, Map<?, ?> map) {
+        if (map == null) {
+            return ctx.nullLbl;
+        }
+
+        List<String> entries = (new TreeMap<>(map)).entrySet().stream()
+                .map(e -> resultToString(ctx, e.getKey()) + ":" + 
resultToString(ctx, e.getValue()))
+                .collect(Collectors.toList());
+
+        return "{" + String.join(", ", entries) + "}";
+    }
+}
diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/Script.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/Script.java
new file mode 100644
index 0000000000..000677cd10
--- /dev/null
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/Script.java
@@ -0,0 +1,203 @@
+/*
+ * 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.sqllogic;
+
+import com.google.common.base.Strings;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Script contains a list of commands.
+ */
+final class Script implements Iterable<Command>, AutoCloseable {
+
+    /**
+     * Line separator to bytes representation.
+     * NB: Don't use {@code System.lineSeparator()} here.
+     * The separator is used to calculate hash by SQL results and mustn't be 
changed on the different platforms.
+     */
+    static final byte[] LINE_SEPARATOR_BYTES = 
"\n".getBytes(StandardCharsets.UTF_8);
+
+    /** Supported commands. **/
+    private static final Map<String, CommandParser> COMMANDS = Map.of(
+            "statement", Statement::new,
+            "query", Query::new,
+            "loop", Loop::new,
+            "endloop", EndLoop::new,
+            "skipif", SkipIf::new,
+            "onlyif", OnlyIf::new
+    );
+
+    /** A file. **/
+    private final String fileName;
+
+    private final BufferedReader buffReader;
+
+    /** The current line in a script .**/
+    private int lineNum;
+
+    /** A script execution context. **/
+    private final ScriptContext ctx;
+
+    Script(Path test, ScriptContext ctx) throws IOException {
+        this.fileName = test.getFileName().toString();
+        this.buffReader = Files.newBufferedReader(test);
+        this.ctx = ctx;
+    }
+
+    String nextLine() throws IOException {
+        return nextLineWithoutTrim();
+    }
+
+    String nextLineWithoutTrim() throws IOException {
+        String s = buffReader.readLine();
+
+        lineNum++;
+
+        return s;
+    }
+
+    boolean ready() throws IOException {
+        return buffReader.ready();
+    }
+
+    ScriptPosition scriptPosition() {
+        return new ScriptPosition(fileName, lineNum);
+    }
+
+    @Override
+    public void close() throws Exception {
+        buffReader.close();
+    }
+
+    @Nullable Command nextCommand() {
+        try {
+            while (ready()) {
+                String line = nextLine();
+
+                if (Strings.isNullOrEmpty(line) || line.startsWith("#")) {
+                    continue;
+                }
+
+                String[] tokens = line.split("\\s+");
+                if (tokens.length == 0) {
+                    throw reportError("Invalid line", line);
+                }
+
+                String token = tokens[0];
+                return parseCommand(token, tokens, line);
+            }
+
+            return null;
+        } catch (IOException e) {
+            throw reportError("Can not read next command", null, e);
+        }
+    }
+
+    private Command parseCommand(String token, String[] tokens, String line) 
throws IOException {
+        CommandParser parser = COMMANDS.get(token);
+        if (parser == null) {
+            throw reportError("Unexpected command " + token, line);
+        }
+        try {
+            return parser.parse(this, ctx, tokens);
+        } catch (Exception e) {
+            throw reportError("Failed to parse a command", line, e);
+        }
+    }
+
+    @NotNull
+    @Override
+    public Iterator<Command> iterator() {
+        Command cmd0 = nextCommand();
+        return new Iterator<>() {
+
+            private @Nullable Command cmd = cmd0;
+
+            @Override
+            public boolean hasNext() {
+                return cmd != null;
+            }
+
+            @Override
+            public Command next() {
+                if (cmd == null) {
+                    throw new NoSuchElementException();
+                }
+
+                Command ret = cmd;
+
+                cmd = nextCommand();
+
+                return ret;
+            }
+        };
+    }
+
+    ScriptException reportInvalidCommand(String error, String[] command) {
+        var pos = scriptPosition();
+
+        return new ScriptException(error, pos, Arrays.toString(command));
+    }
+
+    ScriptException reportInvalidCommand(String error, String[] command, 
@Nullable Throwable cause) {
+        var pos = scriptPosition();
+
+        return new ScriptException(error, pos, Arrays.toString(command), 
cause);
+    }
+
+    ScriptException reportError(String error, @Nullable String message) {
+        var pos = scriptPosition();
+
+        return new ScriptException(error, pos, message);
+    }
+
+    ScriptException reportError(String error, @Nullable String message, 
@Nullable Throwable cause) {
+        var pos = scriptPosition();
+
+        return new ScriptException(error, pos, message, cause);
+    }
+
+    /**
+     * Parses tokens and produces a command.
+     */
+    @FunctionalInterface
+    static interface CommandParser {
+
+        /**
+         * Parses the given array of tokens and produces a {@link Command}.
+         *
+         * @param script  a script.
+         * @param ctx  a script context,
+         * @param tokens an array of tokens. the first token in the array is 
the type of this command.
+         *
+         * @return an instance of a command.
+         * @throws IOException when i/o error ocurrs.
+         */
+        Command parse(Script script, ScriptContext ctx, String[] tokens) 
throws IOException;
+    }
+}
diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/ScriptContext.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/ScriptContext.java
new file mode 100644
index 0000000000..c4ac038472
--- /dev/null
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/ScriptContext.java
@@ -0,0 +1,110 @@
+/*
+ * 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.sqllogic;
+
+import com.google.common.collect.Streams;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import org.apache.ignite.internal.logger.IgniteLogger;
+import org.apache.ignite.internal.sqllogic.SqlScriptRunner.RunnerRuntime;
+import org.apache.ignite.sql.IgniteSql;
+import org.apache.ignite.sql.ResultSet;
+import org.apache.ignite.sql.Session;
+import org.apache.ignite.sql.SqlRow;
+
+/**
+ * ScriptContext maintains the state of a script execution and provides access
+ * to the query executor and other dependencies to script commands.
+ */
+final class ScriptContext {
+
+    /** NULL label. */
+    private static final String NULL = "NULL";
+
+    /** Query engine. */
+    private final IgniteSql ignSql;
+
+    /** Logger. */
+    final IgniteLogger log;
+
+    /** Database engine name. **/
+    final String engineName;
+
+    /** Loop variables. */
+    final Map<String, Integer> loopVars = new HashMap<>();
+
+    /** String presentation of null's. */
+    String nullLbl = NULL;
+
+    /** Equivalent results store. */
+    final Map<String, Collection<String>> eqResStorage = new HashMap<>();
+
+    /** Hash algo. */
+    final MessageDigest messageDigest;
+
+    ScriptContext(RunnerRuntime runnerRuntime) {
+        this.log = runnerRuntime.log();
+        this.engineName = runnerRuntime.engineName();
+        this.ignSql = runnerRuntime.sql();
+
+        try {
+            messageDigest = MessageDigest.getInstance("MD5");
+        } catch (NoSuchAlgorithmException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    List<List<?>> executeQuery(String sql) {
+        if (!loopVars.isEmpty()) {
+            for (Map.Entry<String, Integer> loopVar : loopVars.entrySet()) {
+                sql = sql.replaceAll("\\$\\{" + loopVar.getKey() + "\\}", 
loopVar.getValue().toString());
+            }
+        }
+
+        log.info("Execute: " + sql);
+
+        try (Session s = ignSql.createSession()) {
+            try (ResultSet<SqlRow> rs = s.execute(null, sql)) {
+                if (rs.hasRowSet()) {
+                    return Streams.stream(rs).map(
+                                    r -> {
+                                        List<?> row = new ArrayList<>();
+
+                                        for (int i = 0; i < 
rs.metadata().columns().size(); ++i) {
+                                            row.add(r.value(i));
+                                        }
+
+                                        return row;
+                                    })
+                            .collect(Collectors.toList());
+                } else if (rs.affectedRows() != -1) {
+                    return 
Collections.singletonList(Collections.singletonList(rs.affectedRows()));
+                } else {
+                    return 
Collections.singletonList(Collections.singletonList(rs.wasApplied()));
+                }
+            }
+        }
+    }
+}
diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/ScriptException.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/ScriptException.java
new file mode 100644
index 0000000000..a67a116c6f
--- /dev/null
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/ScriptException.java
@@ -0,0 +1,64 @@
+/*
+ * 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.sqllogic;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * An exception with position in a script.
+ */
+final class ScriptException extends RuntimeException {
+
+    private static final long serialVersionUID = -5972259903486232854L;
+
+    /**
+     * Creates an exception with a message in the one of the following forms.
+     * <ul>
+     *     <li>When a message parameter is specified and is not empty: {@code 
error at position: message}</li>
+     *     <li>When a message parameter is omitted: {@code error at 
position}</li>
+     * </ul>
+     *
+     * @param error an error.
+     * @param position a position in a script where a problem has occurred.
+     * @param message an additional message.
+     */
+    ScriptException(String error, ScriptPosition position, @Nullable String 
message) {
+        super(scriptErrorMessage(error, position, message));
+    }
+
+    /**
+     * Similar to {@link ScriptException#ScriptException(String, 
ScriptPosition, String)} but allow to pass a cause.
+     *
+     * @param error an error.
+     * @param position a position in a script where a problem has occurred.
+     * @param message an additional message.
+     * @param cause a cause of this exception.
+     */
+    ScriptException(String error, ScriptPosition position, @Nullable String 
message, @Nullable Throwable cause) {
+        super(scriptErrorMessage(error, position, message), cause);
+    }
+
+    private static String scriptErrorMessage(String message, ScriptPosition 
position, @Nullable String details) {
+        if (details == null || details.isEmpty()) {
+            return String.format("%s at %s", message, position);
+        } else {
+            return String.format("%s at %s: %s", message, position, details);
+        }
+    }
+}
diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/ScriptPosition.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/ScriptPosition.java
new file mode 100644
index 0000000000..a9f033f8e6
--- /dev/null
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/ScriptPosition.java
@@ -0,0 +1,40 @@
+/*
+ * 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.sqllogic;
+
+/**
+ * Position in a script file.
+ */
+final class ScriptPosition {
+
+    private final String fileName;
+
+    private final int lineNum;
+
+    ScriptPosition(String fileName, int lineNum) {
+        this.fileName = fileName;
+        this.lineNum = lineNum;
+    }
+
+    @Override
+    public String toString() {
+        // The format below is understood by Intellij IDEA
+        // and displayed as a link to a line in a file in assertion errors.
+        return '(' + fileName + ':' + lineNum + ')';
+    }
+}
diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/SkipIf.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/SkipIf.java
new file mode 100644
index 0000000000..7af0b014d3
--- /dev/null
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/SkipIf.java
@@ -0,0 +1,54 @@
+/*
+ * 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.sqllogic;
+
+/**
+ * SkipIf command skips the next command in a script if the specific condition 
does not hold.
+ * <pre>
+ *     skipif condition
+ *     statement ok
+ *     SELECT broken
+ * </pre>
+ * At the moment the only supported condition type is a name of a database 
engine.
+ */
+final class SkipIf extends Command {
+
+    private final String[] condition;
+
+    private final Command command;
+
+    SkipIf(Script script, ScriptContext ctx, String[] tokens) {
+        super(script.scriptPosition());
+
+        var nextCommand = script.nextCommand();
+        if (nextCommand == null) {
+            throw script.reportInvalidCommand("Expected a next command", 
tokens);
+        }
+
+        this.command = nextCommand;
+        this.condition = tokens;
+    }
+
+    @Override
+    void execute(ScriptContext ctx) {
+        if (condition[1].equals(ctx.engineName)) {
+            return;
+        }
+        command.execute(ctx);
+    }
+}
diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/SqlScriptRunner.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/SqlScriptRunner.java
index db130dae79..4629129f75 100644
--- 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/SqlScriptRunner.java
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/SqlScriptRunner.java
@@ -17,768 +17,63 @@
 
 package org.apache.ignite.internal.sqllogic;
 
-import com.google.common.base.Strings;
-import com.google.common.collect.Streams;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
 import java.nio.file.Path;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Objects;
-import java.util.TreeMap;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-import org.apache.calcite.avatica.util.ByteString;
 import org.apache.ignite.internal.logger.IgniteLogger;
-import org.apache.ignite.internal.util.ArrayUtils;
-import org.apache.ignite.internal.util.CollectionUtils;
-import org.apache.ignite.internal.util.IgniteUtils;
-import org.apache.ignite.lang.IgniteException;
 import org.apache.ignite.sql.IgniteSql;
-import org.apache.ignite.sql.ResultSet;
-import org.apache.ignite.sql.Session;
-import org.apache.ignite.sql.SqlRow;
-import org.jetbrains.annotations.NotNull;
 
 /**
  * Runs one SQL test script.
  */
 public class SqlScriptRunner {
-    /** UTF-8 character name. */
-    static final Charset UTF_8 = StandardCharsets.UTF_8;
 
-    /** Hashing label pattern. */
-    private static final Pattern HASHING_PTRN = Pattern.compile("([0-9]+) 
values hashing to ([0-9a-fA-F]+)");
-
-
-    /** NULL label. */
-    private static final String NULL = "NULL";
-
-    /** Comparator for "rowsort" sort mode. */
-    private final Comparator<List<?>> rowComparator = (r1, r2) -> {
-        int rows = r1.size();
-
-        for (int i = 0; i < rows; ++i) {
-            String s1 = toString(r1.get(i));
-            String s2 = toString(r2.get(i));
-
-            int comp = s1.compareTo(s2);
-
-            if (comp != 0) {
-                return comp;
-            }
-        }
+    /**
+     * Provides dependencies required for {@link SqlScriptRunner}.
+     */
+    public interface RunnerRuntime {
 
-        return 0;
-    };
+        /** Returns a query executor. **/
+        IgniteSql sql();
 
-    /** Comparator for "valuesort" sort mode. */
-    private static final Comparator<Object> ITM_COMPARATOR = (r1, r2) -> {
-        String s1 = String.valueOf(r1);
-        String s2 = String.valueOf(r2);
+        /** Returns a logger. **/
+        IgniteLogger log();
 
-        return s1.compareTo(s2);
-    };
+        /**
+         * Returns a name of the current database engine.
+         * This property is used by {@code skipif} and {@code onlyif} commands.
+         * **/
+        String engineName();
+    }
 
     /** Test script path. */
     private final Path test;
 
-    /** Query engine. */
-    private final IgniteSql ignSql;
-
-    /** Loop variables. */
-    private final Map<String, Integer> loopVars = new HashMap<>();
-
-    /** Logger. */
-    private final IgniteLogger log;
-
-    /** Script. */
-    private Script script;
-
-    /** String presentation of null's. */
-    private String nullLbl = NULL;
-
-    /**
-     * Line separator to bytes representation.
-     * NB: Don't use {@code System.lineSeparator()} here.
-     * The separator is used to calculate hash by SQL results and mustn't be 
changed on the different platforms.
-     */
-    private static final byte[] LINE_SEPARATOR_BYTES = 
"\n".getBytes(Charset.forName(UTF_8.name()));
-
-    /** Equivalent results store. */
-    private Map<String, Collection<String>> eqResStorage = new HashMap<>();
-
-    /** Hash algo. */
-    MessageDigest messageDigest;
+    /** Runtime dependencies of a script runner. **/
+    private final RunnerRuntime runnerRuntime;
 
     /**
      * Script runner constructor.
      */
-    public SqlScriptRunner(Path test, IgniteSql ignSql, IgniteLogger log) {
+    public SqlScriptRunner(Path test, RunnerRuntime runnerRuntime) {
         this.test = test;
-        this.ignSql = ignSql;
-        this.log = log;
-
-        try {
-            messageDigest = MessageDigest.getInstance("MD5");
-        } catch (NoSuchAlgorithmException e) {
-            throw new IgniteException(e);
-        }
+        this.runnerRuntime = runnerRuntime;
     }
 
     /**
      * Executes SQL file script.
      */
     public void run() throws Exception {
-        try (Script s = new Script(test)) {
-            script = s;
-            nullLbl = NULL;
+        var ctx = new ScriptContext(runnerRuntime);
 
+        try (var script = new Script(test, ctx)) {
             for (Command cmd : script) {
                 try {
-                    cmd.execute();
+                    cmd.execute(ctx);
+                } catch (Exception e) {
+                    throw script.reportError("Command execution error", 
cmd.getClass().getSimpleName(), e);
                 } finally {
-                    loopVars.clear();
-                }
-            }
-        }
-    }
-
-    private List<List<?>> sql(String sql) {
-        if (!loopVars.isEmpty()) {
-            for (Map.Entry<String, Integer> loopVar : loopVars.entrySet()) {
-                sql = sql.replaceAll("\\$\\{" + loopVar.getKey() + "\\}", 
loopVar.getValue().toString());
-            }
-        }
-
-        log.info("Execute: " + sql);
-
-        try (Session s = ignSql.createSession()) {
-            try (ResultSet<SqlRow> rs = s.execute(null, sql)) {
-                if (rs.hasRowSet()) {
-                    return Streams.stream(rs).map(
-                                    r -> {
-                                        List<?> row = new ArrayList<>();
-
-                                        for (int i = 0; i < 
rs.metadata().columns().size(); ++i) {
-                                            row.add(r.value(i));
-                                        }
-
-                                        return row;
-                                    })
-                            .collect(Collectors.toList());
-                } else if (rs.affectedRows() != -1) {
-                    return 
Collections.singletonList(Collections.singletonList(rs.affectedRows()));
-                } else {
-                    return 
Collections.singletonList(Collections.singletonList(rs.wasApplied()));
+                    ctx.loopVars.clear();
                 }
             }
         }
     }
-
-    private String toString(Object res) {
-        if (res == null) {
-            return nullLbl;
-        } else if (res instanceof byte[]) {
-            return ByteString.toString((byte[]) res, 16);
-        } else if (res instanceof Map) {
-            return mapToString((Map<?, ?>) res);
-        } else {
-            return String.valueOf(res);
-        }
-    }
-
-    private String mapToString(Map<?, ?> map) {
-        if (map == null) {
-            return nullLbl;
-        }
-
-        List<String> entries = (new TreeMap<>(map)).entrySet().stream()
-                .map(e -> toString(e.getKey()) + ":" + toString(e.getValue()))
-                .collect(Collectors.toList());
-
-        return "{" + String.join(", ", entries) + "}";
-    }
-
-    private class Script implements Iterable<Command>, AutoCloseable {
-        private final String fileName;
-
-        private final BufferedReader buffReader;
-
-        private int lineNum;
-
-        Script(Path test) throws IOException {
-            fileName = test.getFileName().toString();
-
-            buffReader = Files.newBufferedReader(test);
-        }
-
-        String nextLine() throws IOException {
-            return nextLineWithoutTrim();
-        }
-
-        String nextLineWithoutTrim() throws IOException {
-            String s = buffReader.readLine();
-
-            lineNum++;
-
-            return s;
-        }
-
-        boolean ready() throws IOException {
-            return buffReader.ready();
-        }
-
-        String positionDescription() {
-            return '(' + fileName + ':' + lineNum + ')';
-        }
-
-        @Override
-        public void close() throws Exception {
-            buffReader.close();
-        }
-
-        private Command nextCommand() {
-            try {
-                while (script.ready()) {
-                    String s = script.nextLine();
-
-                    if (Strings.isNullOrEmpty(s) || s.startsWith("#")) {
-                        continue;
-                    }
-
-                    String[] tokens = s.split("\\s+");
-
-                    assert !ArrayUtils.nullOrEmpty(tokens) : "Invalid command 
line. "
-                            + script.positionDescription() + ". [cmd=" + s + 
']';
-
-                    Command cmd = null;
-
-                    switch (tokens[0]) {
-                        case "statement":
-                            cmd = new Statement(tokens);
-
-                            break;
-
-                        case "query":
-                            cmd = new Query(tokens);
-
-                            break;
-
-                        case "loop":
-                            cmd = new Loop(tokens);
-
-                            break;
-
-                        case "endloop":
-                            cmd = new EndLoop();
-
-                            break;
-
-                        case "mode":
-                            // TODO: output_hash. output_result, debug, skip, 
unskip
-
-                            break;
-
-                        default:
-                            throw new IgniteException("Unexpected command. "
-                                    + script.positionDescription() + ". [cmd=" 
+ s + ']');
-                    }
-
-                    if (cmd != null) {
-                        return cmd;
-                    }
-                }
-
-                return null;
-            } catch (IOException e) {
-                throw new RuntimeException("Cannot read next command", e);
-            }
-        }
-
-        @NotNull
-        @Override
-        public Iterator<Command> iterator() {
-            final Command cmd0 = nextCommand();
-            return new Iterator<>() {
-                private Command cmd = cmd0;
-
-                @Override
-                public boolean hasNext() {
-                    return cmd != null;
-                }
-
-                @Override
-                public Command next() {
-                    if (cmd == null) {
-                        throw new NoSuchElementException();
-                    }
-
-                    Command ret = cmd;
-
-                    cmd = nextCommand();
-
-                    return ret;
-                }
-            };
-        }
-    }
-
-    private abstract class Command {
-        protected final String posDesc;
-
-        Command() {
-            posDesc = script.positionDescription();
-        }
-
-        abstract void execute();
-    }
-
-    private class Loop extends Command {
-        List<Command> cmds = new ArrayList<>();
-
-        int begin;
-
-        int end;
-
-        String var;
-
-        Loop(String[] cmdTokens) throws IOException {
-            try {
-                var = cmdTokens[1];
-                begin = Integer.parseInt(cmdTokens[2]);
-                end = Integer.parseInt(cmdTokens[3]);
-            } catch (Exception e) {
-                throw new IgniteException("Unexpected loop syntax. "
-                        + script.positionDescription() + ". [cmd=" + cmdTokens 
+ ']');
-            }
-
-            while (script.ready()) {
-                Command cmd = script.nextCommand();
-
-                if (cmd instanceof EndLoop) {
-                    break;
-                }
-
-                cmds.add(cmd);
-            }
-        }
-
-        @Override
-        void execute() {
-            for (int i = begin; i < end; ++i) {
-                loopVars.put(var, i);
-
-                for (Command c : cmds) {
-                    c.execute();
-                }
-            }
-        }
-    }
-
-    private class EndLoop extends Command {
-        @Override
-        void execute() {
-            // No-op.
-        }
-    }
-
-    private class Statement extends Command {
-        List<String> queries;
-
-        ExpectedStatementStatus expected;
-
-        Statement(String[] cmd) throws IOException {
-            switch (cmd[1]) {
-                case "ok":
-                    expected = ExpectedStatementStatus.OK;
-
-                    break;
-
-                case "error":
-                    expected = ExpectedStatementStatus.ERROR;
-
-                    break;
-
-                default:
-                    throw new IgniteException("Statement argument should be 
'ok' or 'error'. "
-                            + script.positionDescription() + "[cmd=" + 
Arrays.toString(cmd) + ']');
-            }
-
-            queries = new ArrayList<>();
-
-            while (script.ready()) {
-                String s = script.nextLine();
-
-                if (Strings.isNullOrEmpty(s)) {
-                    break;
-                }
-
-                queries.add(s);
-            }
-        }
-
-        @Override
-        void execute() {
-            for (String qry : queries) {
-                String[] toks = qry.split("\\s+");
-
-                if ("PRAGMA".equals(toks[0])) {
-                    String[] pragmaParams = toks[1].split("=");
-
-                    if ("null".equals(pragmaParams[0])) {
-                        nullLbl = pragmaParams[1];
-                    } else {
-                        log.info("Ignore: " + toString());
-                    }
-
-                    continue;
-                }
-
-                try {
-                    sql(qry);
-
-                    if (expected != ExpectedStatementStatus.OK) {
-                        throw new IgniteException("Error expected at: " + 
posDesc + ". Statement: " + this);
-                    }
-                } catch (Throwable e) {
-                    if (expected != ExpectedStatementStatus.ERROR) {
-                        throw new IgniteException("Error at: " + posDesc + ". 
Statement: " + this, e);
-                    }
-                }
-            }
-        }
-
-        @Override
-        public String toString() {
-            return "Statement ["
-                    + "queries=" + queries
-                    + ", expected=" + expected
-                    + ']';
-        }
-    }
-
-    private class Query extends Command {
-        List<ColumnType> resTypes = new ArrayList<>();
-
-        StringBuilder sql = new StringBuilder();
-
-        List<List<String>> expectedRes;
-
-        String expectedHash;
-
-        int expectedRows;
-
-        /** Sorting algo. */
-        SortType sortType = SortType.NOSORT;
-
-        /** Equality label. */
-        String eqLabel;
-
-        Query(String[] cmd) throws IOException {
-            String resTypesChars = cmd[1];
-
-            if (cmd.length > 2) {
-                sortType = SortType.valueOf(cmd[2].toUpperCase());
-            }
-
-            if (cmd.length > 3) {
-                eqLabel = cmd[3].toLowerCase();
-            }
-
-            for (int i = 0; i < resTypesChars.length(); i++) {
-                switch (resTypesChars.charAt(i)) {
-                    case 'I':
-                        resTypes.add(ColumnType.I);
-
-                        break;
-
-                    case 'R':
-                        resTypes.add(ColumnType.R);
-
-                        break;
-
-                    case 'T':
-                        resTypes.add(ColumnType.T);
-
-                        break;
-
-                    default:
-                        throw new IgniteException("Unknown type character '" + 
resTypesChars.charAt(i) + "' at: "
-                                + script.positionDescription() + "[cmd=" + 
Arrays.toString(cmd) + ']');
-                }
-            }
-
-            if (CollectionUtils.nullOrEmpty(resTypes)) {
-                throw new IgniteException("Missing type string at: "
-                        + script.positionDescription() + "[cmd=" + 
Arrays.toString(cmd) + ']');
-            }
-
-            // Read SQL query
-            while (script.ready()) {
-                String s = script.nextLine();
-
-                if (s.equals("----")) {
-                    break;
-                }
-
-                if (sql.length() > 0) {
-                    sql.append("\n");
-                }
-
-                sql.append(s);
-            }
-
-            // Read expected results
-            String s = script.nextLineWithoutTrim();
-            Matcher m = HASHING_PTRN.matcher(s);
-
-            if (m.matches()) {
-                // Expected results are hashing
-                expectedRows = Integer.parseInt(m.group(1));
-                expectedHash = m.group(2);
-            } else {
-                // Read expected results tuples.
-                expectedRes = new ArrayList<>();
-
-                boolean singleValOnLine = false;
-
-                List<String> row = new ArrayList<>();
-
-                while (!Strings.isNullOrEmpty(s)) {
-                    String[] vals = s.split("\\t");
-
-                    if (!singleValOnLine && vals.length == 1 && vals.length != 
resTypes.size()) {
-                        singleValOnLine = true;
-                    }
-
-                    if (vals.length != resTypes.size() && !singleValOnLine) {
-                        throw new IgniteException("Invalid columns count at 
the result at: "
-                                + script.positionDescription() + " [row=\"" + 
s + "\", types=" + resTypes + ']');
-                    }
-
-                    try {
-                        if (singleValOnLine) {
-                            row.add(nullLbl.equals(vals[0]) ? null : vals[0]);
-
-                            if (row.size() == resTypes.size()) {
-                                expectedRes.add(row);
-
-                                row = new ArrayList<>();
-                            }
-                        } else {
-                            for (String val : vals) {
-                                row.add(nullLbl.equals(val) ? null : val);
-                            }
-
-                            expectedRes.add(row);
-                            row = new ArrayList<>();
-                        }
-                    } catch (Exception e) {
-                        throw new IgniteException("Cannot parse expected 
results at: "
-                                + script.positionDescription() + "[row=\"" + s 
+ "\", types=" + resTypes + ']', e);
-                    }
-
-                    s = script.nextLineWithoutTrim();
-                }
-            }
-        }
-
-        @Override
-        void execute() {
-            try {
-                List<List<?>> res = sql(sql.toString());
-
-                checkResult(res);
-            } catch (Throwable e) {
-                throw new IgniteException("Error at: " + posDesc + ". sql: " + 
sql, e);
-            }
-        }
-
-        void checkResult(List<List<?>> res) {
-            if (sortType == SortType.ROWSORT) {
-                res.sort(rowComparator);
-
-                if (expectedRes != null) {
-                    expectedRes.sort(rowComparator);
-                }
-            } else if (sortType == SortType.VALUESORT) {
-                List<Object> flattenRes = new ArrayList<>();
-
-                res.forEach(flattenRes::addAll);
-
-                flattenRes.sort(ITM_COMPARATOR);
-
-                List<List<?>> resSizeAware = new ArrayList<>();
-                int rowLen = resTypes.size();
-                List rowRes = new ArrayList(rowLen);
-
-                for (Object item : flattenRes) {
-                    rowRes.add(item);
-
-                    if (--rowLen == 0) {
-                        resSizeAware.add(rowRes);
-                        rowRes = new ArrayList(rowLen);
-                        rowLen = resTypes.size();
-                    }
-                }
-
-                res = resSizeAware;
-            }
-
-            if (expectedHash != null) {
-                checkResultsHashed(res);
-            } else {
-                checkResultTuples(res);
-            }
-        }
-
-        private void checkResultTuples(List<List<?>> res) {
-            if (expectedRes.size() != res.size()) {
-                throw new AssertionError("Invalid results rows count at: " + 
posDesc
-                        + ". [expectedRows=" + expectedRes.size() + ", 
actualRows=" + res.size()
-                        + ", expected=" + expectedRes + ", actual=" + res + 
']');
-            }
-
-            for (int i = 0; i < expectedRes.size(); ++i) {
-                List<String> expectedRow = expectedRes.get(i);
-                List<?> row = res.get(i);
-
-                if (row.size() != expectedRow.size()) {
-                    throw new AssertionError("Invalid columns count at: " + 
posDesc
-                            + ". [expected=" + expectedRes + ", actual=" + res 
+ ']');
-                }
-
-                for (int j = 0; j < expectedRow.size(); ++j) {
-                    checkEquals(
-                            "Not expected result at: " + posDesc
-                                    + ". [row=" + i + ", col=" + j
-                                    + ", expected=" + expectedRow.get(j) + ", 
actual=" + SqlScriptRunner.this.toString(row.get(j)) + ']',
-                            expectedRow.get(j),
-                            row.get(j)
-                    );
-                }
-            }
-        }
-
-        private void checkEquals(String msg, String expectedStr, Object 
actual) {
-            if (actual == null && (expectedStr == null || 
nullLbl.equalsIgnoreCase(expectedStr))) {
-                return;
-            }
-
-            if (actual != null ^ expectedStr != null) {
-                throw new AssertionError(msg);
-            }
-
-            // Alternative values for boolean "0" and "1".
-            if (actual instanceof Boolean && expectedStr.equals((Boolean) 
actual ? "1" : "0")) {
-                return;
-            }
-
-            if (actual instanceof Number) {
-                if ("NaN".equals(expectedStr) || 
expectedStr.endsWith("Infinity")) {
-                    if (!expectedStr.equals(String.valueOf(actual))) {
-                        throw new AssertionError(msg);
-                    }
-                } else {
-                    BigDecimal actDec = new BigDecimal(String.valueOf(actual));
-                    BigDecimal expDec = new BigDecimal(expectedStr);
-
-                    if (actDec.compareTo(expDec) != 0) {
-                        throw new AssertionError(msg);
-                    }
-                }
-            } else if (actual instanceof Map) {
-                String actualStr = mapToString((Map<? extends Comparable, ?>) 
actual);
-
-                if (!expectedStr.equals(actualStr)) {
-                    throw new AssertionError(msg);
-                }
-            } else {
-                if 
(!String.valueOf(expectedStr).equals(SqlScriptRunner.this.toString(actual))
-                        && !("(empty)".equals(expectedStr) && 
SqlScriptRunner.this.toString(actual).isEmpty())) {
-                    throw new AssertionError(msg);
-                }
-            }
-        }
-
-        private void checkResultsHashed(List<List<?>> res) {
-            Objects.requireNonNull(res, "empty result set");
-
-            messageDigest.reset();
-
-            for (List<?> row : res) {
-                for (Object col : row) {
-                    
messageDigest.update(SqlScriptRunner.this.toString(col).getBytes(Charset.forName(UTF_8.name())));
-                    messageDigest.update(LINE_SEPARATOR_BYTES);
-                }
-            }
-
-            String res0 = IgniteUtils.toHexString(messageDigest.digest());
-
-            if (eqLabel != null) {
-                if (res0.equals(expectedHash)) {
-                    eqResStorage.computeIfAbsent(eqLabel, k -> new 
ArrayList<>()).add(sql.toString());
-                } else {
-                    Collection<String> eq = eqResStorage.get(eqLabel);
-
-                    if (eq != null) {
-                        throw new AssertionError("Results of queries need to 
be equal: " + eq
-                                + "\n and \n" + sql);
-                    }
-                }
-            }
-
-            if (!res0.equalsIgnoreCase(expectedHash)) {
-                throw new AssertionError("Unexpected hash result, error at: " 
+ posDesc
-                        + ", expected=" + expectedHash + ", calculated=" + res0
-                        + ", expectedRows=" + expectedRows + ", returnedRows=" 
+ res.size() * res.get(0).size());
-            }
-        }
-
-        @Override
-        public String toString() {
-            return "Query ["
-                    + "sql=" + sql
-                    + ", resTypes=" + resTypes
-                    + ", expectedRes=" + expectedRes
-                    + ", expectedHash='" + expectedHash + '\''
-                    + ", expectedRows=" + expectedRows
-                    + ", sortType=" + sortType
-                    + ", eqLabel='" + eqLabel + '\''
-                    + ']';
-        }
-    }
-
-    private enum ExpectedStatementStatus {
-        OK,
-        ERROR
-    }
-
-    private enum ColumnType {
-        I,
-        T,
-        R
-    }
-
-    private enum SortType {
-        ROWSORT,
-        VALUESORT,
-        NOSORT
-    }
 }
diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/Statement.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/Statement.java
new file mode 100644
index 0000000000..f1d6c1a6bb
--- /dev/null
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sqllogic/Statement.java
@@ -0,0 +1,165 @@
+/*
+ * 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.sqllogic;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.google.common.base.Strings;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.hamcrest.CoreMatchers;
+import org.jetbrains.annotations.Nullable;
+import org.junit.jupiter.api.Assertions;
+
+/**
+ * Statement command executes an SQL statement/an SQL query and expects either 
an error or a successful result.
+ * <pre>
+ *     # an SQL statement/query must returns successful result
+ *     statement ok
+ *     SELECT 1
+ * </pre>
+ * <pre>
+ *     # an SQL statement/query must returns and error
+ *     statement error
+ *     SELECT col
+ * </pre>
+ * <pre>
+ *     # Extension.
+ *     # an SQL statement/query must returns and error that contains the 
specified substring.
+ *     statement error: Column 'COL' not found in any table
+ *     SELECT col
+ * </pre>
+ */
+final class Statement extends Command {
+
+    private final List<String> queries;
+
+    private final ExpectedStatementStatus expected;
+
+    Statement(Script script, ScriptContext ctx, String[] cmd) throws 
IOException {
+        super(script.scriptPosition());
+
+        String expectedStatus = cmd[1];
+        switch (expectedStatus) {
+            case "ok":
+                expected = ExpectedStatementStatus.ok();
+                break;
+            case "error":
+                expected = ExpectedStatementStatus.error();
+                break;
+            default:
+                if (expectedStatus.startsWith("error:")) {
+                    String[] errorMessage = Arrays.copyOfRange(cmd, 2, 
cmd.length);
+                    expected = ExpectedStatementStatus.error(String.join(" ", 
errorMessage).trim());
+                } else {
+                    throw script.reportInvalidCommand("Statement argument 
should be 'ok' or 'error'", cmd);
+                }
+        }
+
+        queries = new ArrayList<>();
+
+        while (script.ready()) {
+            String s = script.nextLine();
+
+            if (Strings.isNullOrEmpty(s)) {
+                break;
+            }
+
+            queries.add(s);
+        }
+    }
+
+    @Override
+    void execute(ScriptContext ctx) {
+        for (String qry : queries) {
+            String[] toks = qry.split("\\s+");
+
+            if ("PRAGMA".equals(toks[0])) {
+                String[] pragmaParams = toks[1].split("=");
+
+                if ("null".equals(pragmaParams[0])) {
+                    ctx.nullLbl = pragmaParams[1];
+                } else {
+                    ctx.log.info("Ignore: " + Arrays.toString(pragmaParams));
+                }
+
+                continue;
+            }
+
+            if (expected.successful) {
+                try {
+                    ctx.executeQuery(qry);
+                } catch (Throwable e) {
+                    Assertions.fail("Not expected result at: " + posDesc + ". 
Statement: " + qry, e);
+                }
+            } else {
+                Throwable err = Assertions.assertThrows(Throwable.class, () -> 
ctx.executeQuery(qry),
+                        "Not expected result at: " + posDesc + ". Statement: " 
+ qry + ". Error: " + expected.errorMessage);
+
+                assertThat("Not expected result at: " + posDesc + ". 
Statement: " + qry
+                        + ". Expected: " + expected.errorMessage, 
err.getMessage(), expected.errorMessage);
+            }
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "Statement ["
+                + "queries=" + queries
+                + ", expected=" + expected
+                + ']';
+    }
+
+    private static class ExpectedStatementStatus {
+
+        private final boolean successful;
+
+        private final org.hamcrest.Matcher<String> errorMessage;
+
+        ExpectedStatementStatus(boolean successful, @Nullable 
org.hamcrest.Matcher<String> errorMessage) {
+            if (successful && errorMessage != null) {
+                throw new IllegalArgumentException("Successful status with 
error message: " + errorMessage);
+            }
+            this.successful = successful;
+            this.errorMessage = errorMessage;
+        }
+
+        static ExpectedStatementStatus ok() {
+            return new ExpectedStatementStatus(true, null);
+        }
+
+        static ExpectedStatementStatus error() {
+            return new ExpectedStatementStatus(false, 
CoreMatchers.any(String.class));
+        }
+
+        static ExpectedStatementStatus error(String errorMessage) {
+            return new ExpectedStatementStatus(false, 
CoreMatchers.containsString(errorMessage));
+        }
+
+        @Override
+        public String toString() {
+            if (successful) {
+                return "ok";
+            } else {
+                return "error:" + errorMessage;
+            }
+        }
+    }
+}
diff --git a/modules/runner/src/integrationTest/sql/_runner/self.test 
b/modules/runner/src/integrationTest/sql/_runner/self.test
new file mode 100644
index 0000000000..873b164430
--- /dev/null
+++ b/modules/runner/src/integrationTest/sql/_runner/self.test
@@ -0,0 +1,97 @@
+# name: test/sql/_runner/self.test
+# description: Tests for SqlScriptRunner.
+# group: [self_test]
+# prefixed with _ so they will run first.
+
+statement ok
+PRAGMA enable_verification
+
+# check null value
+statement ok
+PRAGMA null=X
+
+query I
+SELECT NULL
+----
+X
+
+# check query by rows
+query I
+SELECT c1 FROM (VALUES(1), (2)) t(c1)
+----
+1
+2
+
+# check query by rows with rowsort
+query I rowsort
+SELECT c1 FROM (VALUES(2), (1)) t(c1) ORDER BY c1 DESC
+----
+1
+2
+
+# check query by hash
+query I
+SELECT c1 FROM (VALUES(1), (2)) t(c1)
+----
+2 values hashing to 6DDB4095EB719E2A9F0A3F95677D24E0
+
+# expecting the results of multiple queries to be equal + eq label usage
+query I nosort select-1
+SELECT 1
+----
+1 values hashing to B026324C6904B2A9CB4B88D6D61C81D1
+
+# result should be the same as SELECT 1.
+# Otherwise "Results of queries need to be equal: [SELECT 1] and SELECT 1 + 0" 
error is returned.
+query I nosort select-1
+SELECT 1 + 0
+----
+1 values hashing to B026324C6904B2A9CB4B88D6D61C81D1
+
+# error w/o message
+statement error
+SELECT...
+
+# error with message
+# checks whether a message from an exception contains the given substring
+statement error: From line 1, column 8 to line 1, column 10: Column 'COL' not 
found in any table
+SELECT col
+
+# error with message
+# CAVEAT: currently it collapses multiple spaces inside a error message into 
one.
+statement error: From line 1,    column 8
+SELECT col
+
+# check loop
+loop i 0 10
+
+query I
+SELECT MIN(c1) FROM (VALUES(${i}), (-1), (2)) t(c1);
+----
+-1
+
+endloop
+
+# skipif <engine>
+
+skipif ignite3
+statement ok
+SELECT...
+
+skipif ignite3
+query I
+SELECT 1
+----
+2
+
+# onlyif <engine>
+
+onlyif ignite3
+statement ok
+SELECT 1
+
+onlyif ignite3
+query I
+SELECT 2
+----
+2
diff --git 
a/modules/runner/src/integrationTest/sql/aggregate/aggregates/test_sum.test 
b/modules/runner/src/integrationTest/sql/aggregate/aggregates/test_sum.test
index 8a0b889dec..3c169636bd 100644
--- a/modules/runner/src/integrationTest/sql/aggregate/aggregates/test_sum.test
+++ b/modules/runner/src/integrationTest/sql/aggregate/aggregates/test_sum.test
@@ -77,5 +77,7 @@ SELECT typeof(SUM(b)) FROM bigints
 DECIMAL(32767, 0)
 
 # this is too big for a bigint
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18671
 statement error
 SELECT SUM(b)::BIGINT FROM bigints
diff --git 
a/modules/runner/src/integrationTest/sql/aggregate/group/test_group_by.test 
b/modules/runner/src/integrationTest/sql/aggregate/group/test_group_by.test
index 07c3d4dc9b..6cdaf67021 100644
--- a/modules/runner/src/integrationTest/sql/aggregate/group/test_group_by.test
+++ b/modules/runner/src/integrationTest/sql/aggregate/group/test_group_by.test
@@ -133,6 +133,8 @@ NULL        NULL
 
 # aliases can only be referenced in the GROUP BY as the root column: 
operations not allowed
 # CONTROVERSIAL: this query DOES work in SQLite
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18670
 statement error
 SELECT 1 AS k, SUM(i) FROM integers GROUP BY k+1 ORDER BY 2;
 
diff --git 
a/modules/runner/src/integrationTest/sql/aggregate/group/test_group_by.test_ignore
 
b/modules/runner/src/integrationTest/sql/aggregate/group/test_group_by.test_ignore
index af852b137f..a1a6325f52 100644
--- 
a/modules/runner/src/integrationTest/sql/aggregate/group/test_group_by.test_ignore
+++ 
b/modules/runner/src/integrationTest/sql/aggregate/group/test_group_by.test_ignore
@@ -172,6 +172,7 @@ NULL        NULL    NULL
 # aliases can only be referenced in the GROUP BY as the root column: 
operations not allowed
 # CONTROVERSIAL: this query DOES work in SQLite
 statement error
+# https://issues.apache.org/jira/browse/IGNITE-18670
 SELECT 1 AS k, SUM(i) FROM integers GROUP BY k+1 ORDER BY 2;
 
 # group by column refs should be recognized, even if one uses an explicit 
table specifier and the other does not
diff --git a/modules/runner/src/integrationTest/sql/function/blob/base64.test 
b/modules/runner/src/integrationTest/sql/function/blob/base64.test
index c8a7561009..4075217f36 100644
--- a/modules/runner/src/integrationTest/sql/function/blob/base64.test
+++ b/modules/runner/src/integrationTest/sql/function/blob/base64.test
@@ -19,9 +19,13 @@ select from_base64('AAAA');
 
 # malformed base64
 # must be multiple of 4
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18669
 statement error
 SELECT from_base64('ab');
 
 # unknown bytes
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18669
 statement error
 SELECT from_base64('üab');
diff --git 
a/modules/runner/src/integrationTest/sql/function/numeric/test_trigo.test 
b/modules/runner/src/integrationTest/sql/function/numeric/test_trigo.test
index 628b30214a..f4166dbaed 100644
--- a/modules/runner/src/integrationTest/sql/function/numeric/test_trigo.test
+++ b/modules/runner/src/integrationTest/sql/function/numeric/test_trigo.test
@@ -332,6 +332,8 @@ SELECT cast(ACOS(n::double)*1000 as bigint) FROM numbers  
WHERE n between -1 and
 1570
 0
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18672
 statement error
 SELECT cast(ASIN(n)*1000 as bigint) FROM numbers ORDER BY n
 
diff --git 
a/modules/runner/src/integrationTest/sql/function/numeric/test_type_resolution.test
 
b/modules/runner/src/integrationTest/sql/function/numeric/test_type_resolution.test
index 937d0a5d3f..5e5e4bedab 100644
--- 
a/modules/runner/src/integrationTest/sql/function/numeric/test_type_resolution.test
+++ 
b/modules/runner/src/integrationTest/sql/function/numeric/test_type_resolution.test
@@ -32,6 +32,8 @@ SELECT 1::TINYINT + 1::DOUBLE
 ----
 2.000000
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18677
 statement error
 SELECT 1::TINYINT + 1::VARCHAR
 
@@ -65,6 +67,8 @@ SELECT 1::SMALLINT + 1::DOUBLE
 ----
 2.000000
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18677
 statement error
 SELECT 1::SMALLINT + 1::VARCHAR
 
@@ -98,6 +102,8 @@ SELECT 1::INTEGER + 1::DOUBLE
 ----
 2.000000
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18677
 statement error
 SELECT 1::INTEGER + 1::VARCHAR
 
@@ -131,6 +137,8 @@ SELECT 1::BIGINT + 1::DOUBLE
 ----
 2.000000
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18677
 statement error
 SELECT 1::BIGINT + 1::VARCHAR
 
@@ -164,6 +172,8 @@ SELECT 1::REAL + 1::DOUBLE
 ----
 2.000000
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18677
 statement error
 SELECT 1::REAL + 1::VARCHAR
 
@@ -197,6 +207,31 @@ SELECT 1::DOUBLE + 1::DOUBLE
 ----
 2.000000
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18677
 statement error
 SELECT 1::DOUBLE + 1::VARCHAR
 
+statement ok
+SELECT 1::TINYINT + '1'
+
+query I
+SELECT c + '1' FROM (VALUES(1, '1')) t(c, d);
+----
+2
+
+query I
+SELECT '1' + c FROM (VALUES(1, '1')) t(c, d);
+----
+2
+
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18677
+statement ok
+SELECT c + d FROM (VALUES(1, '1')) t(c, d);
+
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18677
+# fails at runtime
+statement error
+SELECT 1 + 'b'
diff --git 
a/modules/runner/src/integrationTest/sql/function/string/test_like_escape.test 
b/modules/runner/src/integrationTest/sql/function/string/test_like_escape.test
index 18e9250791..3cc192c15a 100644
--- 
a/modules/runner/src/integrationTest/sql/function/string/test_like_escape.test
+++ 
b/modules/runner/src/integrationTest/sql/function/string/test_like_escape.test
@@ -14,10 +14,6 @@ SELECT '%++' NOT LIKE '*%++' ESCAPE '*';
 ----
 false
 
-# unterminated escapes
-statement error
-SELECT '%' LIKE '%' ESCAPE '%';
-
 statement error
 SELECT '%' LIKE '*' ESCAPE '*';
 
diff --git 
a/modules/runner/src/integrationTest/sql/join/natural/natural_join.test 
b/modules/runner/src/integrationTest/sql/join/natural/natural_join.test
index 6385aa6c9f..906746d00e 100644
--- a/modules/runner/src/integrationTest/sql/join/natural/natural_join.test
+++ b/modules/runner/src/integrationTest/sql/join/natural/natural_join.test
@@ -52,9 +52,14 @@ SELECT * FROM t3 NATURAL JOIN t2
 ----
 1      3       2
 
-# no matching columns
-statement error
+# when there no matching columns are present natural join behaves like a cross 
join
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18668
+query I
 select * from (values (1)) tbl(a) natural join (values (1), (2)) tbl2(b) order 
by 1, 2
+----
+1  1
+1  2
 
 # natural join with subqueries
 query I
diff --git 
a/modules/runner/src/integrationTest/sql/join/natural/natural_join.test_ignore 
b/modules/runner/src/integrationTest/sql/join/natural/natural_join.test_ignore
index 36a0782f16..8893cdf222 100644
--- 
a/modules/runner/src/integrationTest/sql/join/natural/natural_join.test_ignore
+++ 
b/modules/runner/src/integrationTest/sql/join/natural/natural_join.test_ignore
@@ -65,9 +65,12 @@ SELECT * FROM t1 NATURAL JOIN t2 NATURAL JOIN t3
 ----
 1      2       3
 
-# no matching columns
-statement error
+# natural join chain on not matching columns behaves like join on true
+query I
 select * from (values (1)) tbl(a) natural join (values (1), (2)) tbl2(b) order 
by 1, 2
+----
+1  1
+1  2
 
 # long join chain
 query I
diff --git a/modules/runner/src/integrationTest/sql/order/test_order_by.test 
b/modules/runner/src/integrationTest/sql/order/test_order_by.test
index 05b6e67b8c..5ad4666470 100644
--- a/modules/runner/src/integrationTest/sql/order/test_order_by.test
+++ b/modules/runner/src/integrationTest/sql/order/test_order_by.test
@@ -121,8 +121,3 @@ SELECT a-10 AS k FROM test UNION SELECT a-10 AS l FROM test 
ORDER BY k;
 1
 2
 3
-
-# computations with aliases are not allowed though
-statement error
-SELECT a-10 AS k FROM test UNION SELECT a-10 AS l FROM test ORDER BY 1-k;
-
diff --git 
a/modules/runner/src/integrationTest/sql/order/test_order_by_exceptions.test 
b/modules/runner/src/integrationTest/sql/order/test_order_by_exceptions.test
index e636bbe389..1371ee617c 100644
--- a/modules/runner/src/integrationTest/sql/order/test_order_by_exceptions.test
+++ b/modules/runner/src/integrationTest/sql/order/test_order_by_exceptions.test
@@ -11,6 +11,12 @@ CREATE TABLE test (a INTEGER, b INTEGER);
 statement ok
 INSERT INTO test VALUES (11, 22), (12, 21), (13, 22);
 
+# ORDER BY negative index
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18673
+statement error
+SELECT * FROM test ORDER BY -1
+
 # ORDER BY index out of range
 statement error
 SELECT a FROM test ORDER BY 2
@@ -24,9 +30,12 @@ SELECT a FROM test ORDER BY 'hello', a
 12
 13
 
-# ambiguous reference in union alias
-statement error
+query II
 SELECT a AS k, b FROM test UNION SELECT a, b AS k FROM test ORDER BY k
+----
+11     22
+12     21
+13     22
 
 # but works if not ambiguous
 query II
@@ -37,7 +46,7 @@ SELECT a AS k, b FROM test UNION SELECT a AS k, b FROM test 
ORDER BY k
 13     22
 
 # ambiguous reference in union parameter
-statement error
+statement error: Column 'B' not found in any table
 SELECT a % 2, b FROM test UNION SELECT b, a % 2 AS k ORDER BY a % 2
 
 # but works if not ambiguous
@@ -51,10 +60,16 @@ SELECT mod(a , 2) as a, b FROM test UNION SELECT a % 2 AS 
k, b FROM test ORDER B
 statement error
 SELECT a % 2, b FROM test UNION SELECT a % 2 AS k, b FROM test ORDER BY 3
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18673
+# update error message
 statement error
 SELECT a % 2, b FROM test UNION SELECT a % 2 AS k, b FROM test ORDER BY -1
 
+skipif ignite3
 # and union itself fails if amount of entries is wrong
+# https://issues.apache.org/jira/browse/IGNITE-18673
+# update error message
 statement error
 SELECT a % 2, b FROM test UNION SELECT a % 2 AS k FROM test ORDER BY -1
 
diff --git 
a/modules/runner/src/integrationTest/sql/subquery/scalar/test_complex_correlated_subquery.test
 
b/modules/runner/src/integrationTest/sql/subquery/scalar/test_complex_correlated_subquery.test
index 3b510fda17..922b0a3585 100644
--- 
a/modules/runner/src/integrationTest/sql/subquery/scalar/test_complex_correlated_subquery.test
+++ 
b/modules/runner/src/integrationTest/sql/subquery/scalar/test_complex_correlated_subquery.test
@@ -47,21 +47,39 @@ SELECT i, (SELECT s1.i FROM integers s1 INNER JOIN integers 
s2 ON s1.i=s2.i AND
 3      1
 NULL   NULL
 
-# left outer join on arbitrary correlated subquery: not supported
-statement error
+# left outer join on arbitrary correlated subquery
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18667
+query II
 SELECT * FROM integers s1 LEFT OUTER JOIN integers s2 ON (SELECT CASE WHEN 
s1.i+s2.i>10 THEN TRUE ELSE FALSE END) ORDER BY s1.i;
+----
+1      NULL
+2      NULL
+3      NULL
+NULL   NULL
 
-# left outer join on subquery only involving LHS is not supported
-statement error
+# left outer join on subquery only involving LHS
+query II
 SELECT * FROM integers s1 LEFT OUTER JOIN integers s2 ON s1.i=s2.i AND (SELECT 
CASE WHEN s1.i>2 THEN TRUE ELSE FALSE END) ORDER BY s1.i;
+----
+1      NULL
+2      NULL
+3      3
+NULL   NULL
 
 # left outer join in correlated expression
-statement error
+query II
 SELECT i, (SELECT SUM(s1.i) FROM integers s1 LEFT OUTER JOIN integers s2 ON 
s1.i=s2.i OR s1.i=i1.i-1) AS j FROM integers i1 ORDER BY i;
+----
+1      6
+2      9
+3      12
+NULL   6
 
 # REQUIRE(CHECK_COLUMN(result, 0, {Value(), 1, 2, 3}));
 # REQUIRE(CHECK_COLUMN(result, 1, {Value(), 6, 9, 12}));
 # full outer join: both sqlite and postgres actually cannot run this one
+skipif ignite3
 statement error
 SELECT i, (SELECT SUM(s1.i) FROM integers s1 FULL OUTER JOIN integers s2 ON 
s1.i=s2.i OR s1.i=i1.i-1) AS j FROM integers i1 ORDER BY i;
 
diff --git 
a/modules/runner/src/integrationTest/sql/subquery/scalar/test_complex_correlated_subquery.test_ignore
 
b/modules/runner/src/integrationTest/sql/subquery/scalar/test_complex_correlated_subquery.test_ignore
index 2aea08c8fe..c93d493116 100644
--- 
a/modules/runner/src/integrationTest/sql/subquery/scalar/test_complex_correlated_subquery.test_ignore
+++ 
b/modules/runner/src/integrationTest/sql/subquery/scalar/test_complex_correlated_subquery.test_ignore
@@ -95,11 +95,11 @@ NULL        NULL
 3      3
 
 # left outer join on subquery only involving LHS is not supported
-statement error
+statement ok
 SELECT * FROM integers s1 LEFT OUTER JOIN integers s2 ON s1.i=s2.i AND (SELECT 
CASE WHEN s1.i>2 THEN TRUE ELSE FALSE END) ORDER BY s1.i;
 
 # left outer join in correlated expression
-statement error
+statement ok
 SELECT i, (SELECT SUM(s1.i) FROM integers s1 LEFT OUTER JOIN integers s2 ON 
s1.i=s2.i OR s1.i=i1.i-1) AS j FROM integers i1 ORDER BY i;
 
 # REQUIRE(CHECK_COLUMN(result, 0, {Value(), 1, 2, 3}));
diff --git 
a/modules/runner/src/integrationTest/sql/subquery/scalar/test_correlated_aggregate_subquery.test
 
b/modules/runner/src/integrationTest/sql/subquery/scalar/test_correlated_aggregate_subquery.test
index aa91abe0d4..52a23b8101 100644
--- 
a/modules/runner/src/integrationTest/sql/subquery/scalar/test_correlated_aggregate_subquery.test
+++ 
b/modules/runner/src/integrationTest/sql/subquery/scalar/test_correlated_aggregate_subquery.test
@@ -26,9 +26,14 @@ SELECT i, (SELECT MIN(i+2*i1.i) FROM integers) FROM integers 
i1 ORDER BY i;
 NULL   NULL
 
 # this will fail, because "i" is not an aggregate but the SUM(i1.i) turns this 
query into an aggregate
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18666
 statement error
 SELECT i, (SELECT SUM(i1.i)) FROM integers i1;
 
+# PG: ERROR:  column "i1.i" must appear in the GROUP BY clause or be used in 
an aggregate function
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18666
 statement error
 SELECT i+1, (SELECT SUM(i1.i)) FROM integers i1;
 
diff --git 
a/modules/runner/src/integrationTest/sql/subquery/scalar/test_correlated_subquery.test
 
b/modules/runner/src/integrationTest/sql/subquery/scalar/test_correlated_subquery.test
index 338f81c238..c9aa7152b6 100644
--- 
a/modules/runner/src/integrationTest/sql/subquery/scalar/test_correlated_subquery.test
+++ 
b/modules/runner/src/integrationTest/sql/subquery/scalar/test_correlated_subquery.test
@@ -79,9 +79,13 @@ SELECT i, i=ANY(SELECT i FROM integers WHERE 1=0 AND i1.i=i) 
AS j FROM integers
 NULL   false
 
 # subquery with OFFSET is not supported
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18664
 statement error
 SELECT i, (SELECT i+i1.i FROM integers LIMIT 1 OFFSET 1) AS j FROM integers i1 
ORDER BY i;
 
+# subquery with ORDER BY is not supported
+skipif ignite3
 # subquery with ORDER BY is not supported
 statement error
 SELECT i, (SELECT i+i1.i FROM integers ORDER BY 1 LIMIT 1 OFFSET 1) AS j FROM 
integers i1 ORDER BY i;
diff --git 
a/modules/runner/src/integrationTest/sql/subquery/scalar/test_correlated_subquery_cte.test
 
b/modules/runner/src/integrationTest/sql/subquery/scalar/test_correlated_subquery_cte.test
index f4de5c45c3..08810301fb 100644
--- 
a/modules/runner/src/integrationTest/sql/subquery/scalar/test_correlated_subquery_cte.test
+++ 
b/modules/runner/src/integrationTest/sql/subquery/scalar/test_correlated_subquery_cte.test
@@ -70,12 +70,16 @@ SELECT i, i=ANY(WITH i2 AS (SELECT i FROM integers WHERE 
1=0 AND i1.i=i) SELECT
 NULL   false
 
 # subquery with OFFSET is not supported
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18664
 statement error
 SELECT i, (WITH i2 AS (SELECT i+i1.i FROM integers LIMIT 1 OFFSET 1) SELECT * 
FROM i2) AS j FROM integers i1 ORDER BY i;
 
 # subquery with ORDER BY is not supported
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18665
 statement error
-SELECT i, (WITH i2 AS (SELECT i+i1.i FROM integers ORDER BY 1 LIMIT 1 OFFSET 
1) SELECT * FROM i2) AS j FROM integers i1 ORDER BY i;
+SELECT i, (WITH i2 AS (SELECT i+i1.i FROM integers ORDER BY 1 LIMIT 1 OFFSET 
1) SELECT * FROM i2) AS j FROM integers i1 ORDER BY i DESC;
 
 # correlated filter without FROM clause
 statement error
diff --git 
a/modules/runner/src/integrationTest/sql/types/date/test_incorrect_dates.test 
b/modules/runner/src/integrationTest/sql/types/date/test_incorrect_dates.test
index 267e4a3ae4..b2373599c0 100644
--- 
a/modules/runner/src/integrationTest/sql/types/date/test_incorrect_dates.test
+++ 
b/modules/runner/src/integrationTest/sql/types/date/test_incorrect_dates.test
@@ -9,18 +9,26 @@ statement error
 INSERT INTO dates VALUES ('blabla')
 
 # month out of range
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18663
 statement error
 INSERT INTO dates VALUES ('1993-20-14')
 
 # day out of range
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18663
 statement error
 INSERT INTO dates VALUES ('1993-08-99')
 
 # day out of range because not a leapyear
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18663
 statement error
 INSERT INTO dates VALUES ('1993-02-29')
 
 # day out of range because not a leapyear
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18663
 statement error
 INSERT INTO dates VALUES ('1900-02-29')
 
@@ -34,6 +42,8 @@ INSERT INTO dates VALUES ('2000-02-29')
 
 # test incorrect date formats
 # dd-mm-YYYY
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18663
 statement error
 INSERT INTO dates VALUES ('02-02-1992')
 
@@ -49,6 +59,8 @@ INSERT INTO dates VALUES ('1900-1-1')
 statement error
 INSERT INTO dates VALUES ('-100000000-01-01')
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18663
 statement error
 INSERT INTO dates VALUES ('1000000000-01-01')
 
diff --git 
a/modules/runner/src/integrationTest/sql/types/decimal/cast_from_decimal.test 
b/modules/runner/src/integrationTest/sql/types/decimal/cast_from_decimal.test
index 3e1aa22f88..f522e245ed 100644
--- 
a/modules/runner/src/integrationTest/sql/types/decimal/cast_from_decimal.test
+++ 
b/modules/runner/src/integrationTest/sql/types/decimal/cast_from_decimal.test
@@ -11,15 +11,23 @@ SELECT 127::DECIMAL(3,0)::TINYINT, 
-127::DECIMAL(3,0)::TINYINT, -7::DECIMAL(9,1)
 ----
 127    -127    -7      27      33
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 128::DECIMAL(3,0)::TINYINT
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT -128::DECIMAL(9,0)::TINYINT
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 128::DECIMAL(18,0)::TINYINT
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 14751947891758972421513::DECIMAL(38,0)::TINYINT
 
@@ -29,12 +37,18 @@ SELECT 127::DECIMAL(3,0)::SMALLINT, 
-32767::DECIMAL(5,0)::SMALLINT, -7::DECIMAL(
 ----
 127    -32767  -7      27      33
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT -32768::DECIMAL(9,0)::SMALLINT
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 32768::DECIMAL(18,0)::SMALLINT
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 14751947891758972421513::DECIMAL(38,0)::SMALLINT
 
@@ -44,9 +58,13 @@ SELECT 127::DECIMAL(3,0)::INTEGER, 
-2147483647::DECIMAL(10,0)::INTEGER, -7::DECI
 ----
 127    -2147483647     -7      27      33
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 2147483648::DECIMAL(18,0)::INTEGER
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 14751947891758972421513::DECIMAL(38,0)::INTEGER
 
@@ -56,6 +74,8 @@ SELECT 127::DECIMAL(3,0)::BIGINT, 
-9223372036854775807::DECIMAL(19,0)::BIGINT, -
 ----
 127    -9223372036854775807    -7      27      33
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 14751947891758972421513::DECIMAL(38,0)::BIGINT
 
diff --git 
a/modules/runner/src/integrationTest/sql/types/decimal/cast_to_decimal.test 
b/modules/runner/src/integrationTest/sql/types/decimal/cast_to_decimal.test
index 4758fb3353..5be5e76eb4 100644
--- a/modules/runner/src/integrationTest/sql/types/decimal/cast_to_decimal.test
+++ b/modules/runner/src/integrationTest/sql/types/decimal/cast_to_decimal.test
@@ -17,18 +17,28 @@ SELECT 100::TINYINT::DECIMAL(38,35), 
100::TINYINT::DECIMAL(9,6)
 100    100
 
 # overflow
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 100::TINYINT::DECIMAL(3,1)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 1::TINYINT::DECIMAL(3,3)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 100::TINYINT::DECIMAL(18,17)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 100::TINYINT::DECIMAL(9,7)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 100::TINYINT::DECIMAL(38,37)
 
@@ -44,18 +54,28 @@ SELECT 100::SMALLINT::DECIMAL(38,35), 
100::SMALLINT::DECIMAL(9,6)
 100    100
 
 # overflow
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 100::SMALLINT::DECIMAL(3,1)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 1::SMALLINT::DECIMAL(3,3)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 100::SMALLINT::DECIMAL(18,17)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 100::SMALLINT::DECIMAL(9,7)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 100::SMALLINT::DECIMAL(38,37)
 
@@ -71,24 +91,38 @@ SELECT 100::INTEGER::DECIMAL(38,35), 
100::INTEGER::DECIMAL(9,6), 2147483647::INT
 100    100     2147483647      -2147483647
 
 # overflow
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 100::INTEGER::DECIMAL(3,1)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 10000000::INTEGER::DECIMAL(3,1)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT -10000000::INTEGER::DECIMAL(3,1)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 1::INTEGER::DECIMAL(3,3)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 100::INTEGER::DECIMAL(18,17)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 100::INTEGER::DECIMAL(9,7)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 100::INTEGER::DECIMAL(38,37)
 
@@ -109,24 +143,38 @@ SELECT 922337203685477580::BIGINT::DECIMAL(18,0), 
(-922337203685477580)::BIGINT:
 922337203685477580     -922337203685477580
 
 # overflow
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 100::BIGINT::DECIMAL(3,1)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 10000000::BIGINT::DECIMAL(3,1)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT -10000000::BIGINT::DECIMAL(3,1)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 1::BIGINT::DECIMAL(3,3)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 100::BIGINT::DECIMAL(18,17)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 100::BIGINT::DECIMAL(9,7)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 100::BIGINT::DECIMAL(38,37)
 
@@ -147,39 +195,63 @@ SELECT 1.25::FLOAT::DECIMAL(3,2)
 1.25
 
 # overflow
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 100::FLOAT::DECIMAL(3,1)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 10000000::FLOAT::DECIMAL(3,1)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT -10000000::FLOAT::DECIMAL(3,1)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 1::FLOAT::DECIMAL(3,3)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 100::FLOAT::DECIMAL(18,17)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 100::FLOAT::DECIMAL(9,7)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 100::FLOAT::DECIMAL(38,37)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 17014118346046923173168730371588410572::FLOAT::DECIMAL(38,1)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 17014118346046923173168730371588410572::FLOAT::DECIMAL(37,0)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 17014118346046923173168730371588410572::FLOAT::DECIMAL(18,0)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 17014118346046923173168730371588410572::FLOAT::DECIMAL(9,0)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 17014118346046923173168730371588410572::FLOAT::DECIMAL(4,0)
 
@@ -200,39 +272,63 @@ SELECT 1.25::DOUBLE::DECIMAL(3,2)
 1.25
 
 # overflow
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 100::DOUBLE::DECIMAL(3,1)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 10000000::DOUBLE::DECIMAL(3,1)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT -10000000::DOUBLE::DECIMAL(3,1)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 1::DOUBLE::DECIMAL(3,3)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 100::DOUBLE::DECIMAL(18,17)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 100::DOUBLE::DECIMAL(9,7)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 100::DOUBLE::DECIMAL(38,37)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 17014118346046923173168730371588410572::DOUBLE::DECIMAL(38,1)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 17014118346046923173168730371588410572::DOUBLE::DECIMAL(37,0)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 17014118346046923173168730371588410572::DOUBLE::DECIMAL(18,0)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 17014118346046923173168730371588410572::DOUBLE::DECIMAL(9,0)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18662
 statement error
 SELECT 17014118346046923173168730371588410572::DOUBLE::DECIMAL(4,0)
 
diff --git 
a/modules/runner/src/integrationTest/sql/types/decimal/decimal_arithmetic.test 
b/modules/runner/src/integrationTest/sql/types/decimal/decimal_arithmetic.test
index 1bd60e5601..6f7c988ed6 100644
--- 
a/modules/runner/src/integrationTest/sql/types/decimal/decimal_arithmetic.test
+++ 
b/modules/runner/src/integrationTest/sql/types/decimal/decimal_arithmetic.test
@@ -58,6 +58,8 @@ SELECT ('0.5'::DECIMAL(1,1) + 10000)::VARCHAR,
 10000.5432154321543215432154321
 
 # out of range
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18660
 statement error
 SELECT ('0.54321543215432154321543215432154321'::DECIMAL(35,35) + 
10000)::VARCHAR
 
@@ -163,6 +165,8 @@ SELECT '0.001'::DECIMAL * 100::TINYINT,
 100000.000
 
 # multiplication could not be performed exactly: throw error
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18661
 statement error
 SELECT '0.000000000000000000000000000001'::DECIMAL(38,30) * 
'0.000000000000000000000000000001'::DECIMAL(38,30)
 
diff --git 
a/modules/runner/src/integrationTest/sql/types/decimal/decimal_decimal_overflow_cast.test
 
b/modules/runner/src/integrationTest/sql/types/decimal/decimal_decimal_overflow_cast.test
index 17abfb4148..ea83c9893b 100644
--- 
a/modules/runner/src/integrationTest/sql/types/decimal/decimal_decimal_overflow_cast.test
+++ 
b/modules/runner/src/integrationTest/sql/types/decimal/decimal_decimal_overflow_cast.test
@@ -28,28 +28,40 @@ SELECT 1.0::DECIMAL(38,37)::DECIMAL(2,1), 
1.0::DECIMAL(38,37)::DECIMAL(9,1), 1.0
 1.0    1.0     1.0     1.0
 
 # overflow on casting UP on scale
+skipif ignite3
 statement error
 SELECT 10.00::DECIMAL(4,2)::DECIMAL(4,3);
 
+skipif ignite3
 statement error
 SELECT 10.00::DECIMAL(4,2)::DECIMAL(9,8);
 
+skipif ignite3
 statement error
 SELECT 10.00::DECIMAL(4,2)::DECIMAL(18,17);
 
+skipif ignite3
 statement error
 SELECT 10.00::DECIMAL(4,2)::DECIMAL(38,37);
 
 # overflow on casting DOWN on scale
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18659
 statement error
 SELECT 10.00::DECIMAL(4,2)::DECIMAL(2,1);
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18659
 statement error
 SELECT 10.00::DECIMAL(9,7)::DECIMAL(7,6);
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18659
 statement error
 SELECT 10.00::DECIMAL(18,16)::DECIMAL(16,15);
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18659
 statement error
 SELECT 10.00::DECIMAL(38,36)::DECIMAL(36,35);
 
@@ -81,14 +93,22 @@ SELECT 1.0::DECIMAL(38,1)::DECIMAL(2,1), 
1.0::DECIMAL(38,1)::DECIMAL(8,1), 1.0::
 1.0    1.0     1.0     1.0
 
 # overflow on same scale
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18659
 statement error
 SELECT 1.0::DECIMAL(3,1)::DECIMAL(1,1)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18659
 statement error
 SELECT 1.0::DECIMAL(9,1)::DECIMAL(1,1)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18659
 statement error
 SELECT 1.0::DECIMAL(18,1)::DECIMAL(1,1)
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18659
 statement error
 SELECT 1.0::DECIMAL(38,1)::DECIMAL(1,1)
diff --git 
a/modules/runner/src/integrationTest/sql/types/decimal/decimal_overflow.test 
b/modules/runner/src/integrationTest/sql/types/decimal/decimal_overflow.test_ignore
similarity index 91%
rename from 
modules/runner/src/integrationTest/sql/types/decimal/decimal_overflow.test
rename to 
modules/runner/src/integrationTest/sql/types/decimal/decimal_overflow.test_ignore
index 685409d662..0ec1bec0ee 100644
--- a/modules/runner/src/integrationTest/sql/types/decimal/decimal_overflow.test
+++ 
b/modules/runner/src/integrationTest/sql/types/decimal/decimal_overflow.test_ignore
@@ -1,6 +1,7 @@
 # name: test/sql/types/decimal/decimal_overflow.test
 # description: Test overflow in various decimal computations
 # group: [decimal]
+# Ignored: https://issues.apache.org/jira/browse/IGNITE-18658
 
 statement ok
 PRAGMA enable_verification
@@ -22,15 +23,20 @@ statement error
 select 
(-50000000000000000.0::DECIMAL(18,1)-50000000000000000.0::DECIMAL(18,1));
 
 # decimals can overflow at the hugeint boundary, because we run out of bits
+skipif ignite3
+# IGNITE-18658 Sql. Decimal overflow error is not raised
 statement error
 select 
(9900000000000000000000000000000000000.0::DECIMAL(38,1)+9900000000000000000000000000000000000.0::DECIMAL(38,1));
 
+skipif ignite3
 statement error
 select 
(5000000000000000000000000000000000000.0::DECIMAL(38,1)+5000000000000000000000000000000000000.0::DECIMAL(38,1));
 
+skipif ignite3
 statement error
 select '10000000000000000000000000000000000000.0'::DECIMAL(38,1);
 
+skipif ignite3
 statement error
 select 
(-5000000000000000000000000000000000000.0::DECIMAL(38,1)-5000000000000000000000000000000000000.0::DECIMAL(38,1));
 
diff --git 
a/modules/runner/src/integrationTest/sql/types/decimal/decimal_overflow_table.test
 
b/modules/runner/src/integrationTest/sql/types/decimal/decimal_overflow_table.test
index 1c55eee06e..9b5869650d 100644
--- 
a/modules/runner/src/integrationTest/sql/types/decimal/decimal_overflow_table.test
+++ 
b/modules/runner/src/integrationTest/sql/types/decimal/decimal_overflow_table.test
@@ -17,6 +17,8 @@ SELECT d+1 FROM decimals
 ----
 99000000000000001.0
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18658
 statement error
 SELECT d+1000000000000000.0 FROM decimals
 
@@ -26,6 +28,8 @@ SELECT -1-d FROM decimals
 ----
 -99000000000000001.0
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18658
 statement error
 SELECT -1000000000000000.0-d FROM decimals
 
@@ -35,5 +39,7 @@ SELECT 1*d FROM decimals
 ----
 99000000000000000.0
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18658
 statement error
 SELECT 2*d FROM decimals
diff --git 
a/modules/runner/src/integrationTest/sql/types/decimal/test_decimal.test 
b/modules/runner/src/integrationTest/sql/types/decimal/test_decimal.test
index 8345ce5763..27a352b2ae 100644
--- a/modules/runner/src/integrationTest/sql/types/decimal/test_decimal.test
+++ b/modules/runner/src/integrationTest/sql/types/decimal/test_decimal.test
@@ -36,6 +36,8 @@ SELECT '0.123456789'::DECIMAL::VARCHAR, 
'-0.123456789'::DECIMAL::VARCHAR;
 0.123456789    -0.123456789
 
 # overflow in conversion
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18656
 statement error
 SELECT '9223372036854788.758'::DECIMAL;
 
@@ -58,9 +60,13 @@ SELECT '0.1'::DECIMAL(3, 3)::VARCHAR, '-0.1'::DECIMAL(3, 
3)::VARCHAR;
 0.100  -0.100
 
 # any value >= 1 becomes out of range, though
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18656
 statement error
 SELECT '1'::DECIMAL(3, 3)::VARCHAR;
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18656
 statement error
 SELECT '-1'::DECIMAL(3, 3)::VARCHAR;
 
@@ -129,6 +135,9 @@ SELECT '100.100'::DECIMAL(10)::VARCHAR
 
 # various error conditions
 # scale must be bigger than or equal to width
+skipif ignite3
+# IGNITE-18657 Sql. Decimal casts DECIMAL::VARCHAR
+# https://issues.apache.org/jira/browse/IGNITE-18657
 statement error
 SELECT '0.1'::DECIMAL(3, 4);
 
@@ -141,6 +150,8 @@ statement error
 SELECT '0.1'::DECIMAL(-17);
 
 # width/scale out of range
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18657
 statement error
 SELECT '0.1'::DECIMAL(1000);
 
diff --git 
a/modules/runner/src/integrationTest/sql/types/decimal/test_decimal_ops.test 
b/modules/runner/src/integrationTest/sql/types/decimal/test_decimal_ops.test
index 31a77b0ecc..1b0a521195 100644
--- a/modules/runner/src/integrationTest/sql/types/decimal/test_decimal_ops.test
+++ b/modules/runner/src/integrationTest/sql/types/decimal/test_decimal_ops.test
@@ -5,6 +5,8 @@
 statement ok
 PRAGMA enable_verification
 
+skipif ignite3
+# https://issues.apache.org/jira/browse/IGNITE-18655
 statement error
 CREATE TABLE decimals_without_params(d DECIMAL);
 
diff --git 
a/modules/runner/src/integrationTest/sql/types/string/test_scan_big_varchar.test_slow
 
b/modules/runner/src/integrationTest/sql/types/string/test_scan_big_varchar.test_slow
index 791e66c2db..8f59c5874e 100644
--- 
a/modules/runner/src/integrationTest/sql/types/string/test_scan_big_varchar.test_slow
+++ 
b/modules/runner/src/integrationTest/sql/types/string/test_scan_big_varchar.test_slow
@@ -121,6 +121,8 @@ SELECT COUNT(*), COUNT(a), MAX(CHARACTER_LENGTH(a)), 
SUM(CHARACTER_LENGTH(a)) FR
 statement ok
 INSERT INTO bigtable SELECT * FROM bigtable
 
+# Not expected result at: (test_scan_big_varchar.test_slow:124). [row=0, 
col=0, expected=2048, actual=2381]
+skipif ignite3
 query IIIR
 SELECT COUNT(*), COUNT(a), MAX(CHARACTER_LENGTH(a)), SUM(CHARACTER_LENGTH(a)) 
FROM bigtable
 ----
@@ -129,6 +131,8 @@ SELECT COUNT(*), COUNT(a), MAX(CHARACTER_LENGTH(a)), 
SUM(CHARACTER_LENGTH(a)) FR
 statement ok
 INSERT INTO bigtable SELECT * FROM bigtable
 
+# Not expected result at: (test_scan_big_varchar.test_slow:134). [row=0, 
col=0, expected=4096, actual=5722]
+skipif ignite3
 query IIIR
 SELECT COUNT(*), COUNT(a), MAX(CHARACTER_LENGTH(a)), SUM(CHARACTER_LENGTH(a)) 
FROM bigtable
 ----
@@ -137,6 +141,8 @@ SELECT COUNT(*), COUNT(a), MAX(CHARACTER_LENGTH(a)), 
SUM(CHARACTER_LENGTH(a)) FR
 statement ok
 INSERT INTO bigtable SELECT * FROM bigtable
 
+skipif ignite3
+# IGNITE-18654 Sql. test_scan_big_varchar.test_slow incorrect results.
 query IIIR
 SELECT COUNT(*), COUNT(a), MAX(CHARACTER_LENGTH(a)), SUM(CHARACTER_LENGTH(a)) 
FROM bigtable
 ----
@@ -145,6 +151,9 @@ SELECT COUNT(*), COUNT(a), MAX(CHARACTER_LENGTH(a)), 
SUM(CHARACTER_LENGTH(a)) FR
 statement ok
 INSERT INTO bigtable SELECT * FROM bigtable
 
+skipif ignite3
+# IGNITE-18654 Sql. test_scan_big_varchar.test_slow incorrect results.
+# https://issues.apache.org/jira/browse/IGNITE-18654
 query IIIR
 SELECT COUNT(*), COUNT(a), MAX(CHARACTER_LENGTH(a)), SUM(CHARACTER_LENGTH(a)) 
FROM bigtable
 ----

Reply via email to