You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by zs...@apache.org on 2022/03/21 11:12:10 UTC

[ignite-3] branch main updated: IGNITE-16689 Get rid of guava usage, fix JOIN with USING. - Fixes #726.

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

zstan 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 953c531  IGNITE-16689 Get rid of guava usage, fix JOIN with USING. - Fixes #726.
953c531 is described below

commit 953c531f2470bf935607cc13bf76af5750b177f7
Author: zstan <st...@gmail.com>
AuthorDate: Mon Mar 21 14:11:00 2022 +0300

    IGNITE-16689 Get rid of guava usage, fix JOIN with USING. - Fixes #726.
    
    Signed-off-by: zstan <st...@gmail.com>
---
 .../processor/AbstractProcessorTest.java           |   4 +-
 .../configuration/processor/ParsedClass.java       |   8 +-
 .../internal/runner/app/ItDataSchemaSyncTest.java  |   3 +-
 .../runner/app/jdbc/ItJdbcBatchSelfTest.java       |   2 +-
 .../app/jdbc/ItJdbcComplexDmlDdlSelfTest.java      |   2 +-
 .../app/jdbc/ItJdbcComplexQuerySelfTest.java       |   2 +-
 .../runner/app/jdbc/ItJdbcConnectionSelfTest.java  |   2 +-
 .../app/jdbc/ItJdbcDeleteStatementSelfTest.java    |   2 +-
 .../app/jdbc/ItJdbcErrorsAbstractSelfTest.java     |   2 +-
 .../runner/app/jdbc/ItJdbcErrorsSelfTest.java      |   2 +-
 .../app/jdbc/ItJdbcInsertStatementSelfTest.java    |   2 +-
 .../runner/app/jdbc/ItJdbcJoinsSelfTest.java       |   2 +-
 .../jdbc/ItJdbcMetadataPrimaryKeysSelfTest.java    |   2 +-
 .../runner/app/jdbc/ItJdbcMetadataSelfTest.java    |   2 +-
 .../runner/app/jdbc/ItJdbcResultSetSelfTest.java   |   2 +-
 .../app/jdbc/ItJdbcSelectAfterAlterTable.java      |   2 +-
 .../runner/app/jdbc/ItJdbcStatementSelfTest.java   |   2 +-
 .../app/jdbc/ItJdbcUpdateStatementSelfTest.java    |   2 +-
 .../ignite/internal/sql/engine/ItJoinTest.java     |  77 +++++++++++
 .../sql/engine/exec/exp/RexExecutorImpl.java       |   3 +-
 .../sql/engine/prepare/IgniteSqlValidator.java     |  67 ++++++++++
 .../internal/sql/engine/rel/IgniteMergeJoin.java   |   7 +-
 .../engine/rule/logical/LogicalOrToUnionRule.java  |   4 +-
 .../sql/engine/exec/RuntimeSortedIndexTest.java    |   4 +-
 .../sql/engine/exec/rel/AbstractExecutionTest.java |   4 +-
 .../exec/rel/HashAggregateExecutionTest.java       |   3 +-
 .../sql/engine/planner/AbstractPlannerTest.java    | 142 +++++++++++++++++---
 .../engine/planner/JoinWithUsingPlannerTest.java   | 143 +++++++++++++++++++++
 28 files changed, 441 insertions(+), 58 deletions(-)

diff --git a/modules/configuration-annotation-processor/src/integrationTest/java/org/apache/ignite/internal/configuration/processor/AbstractProcessorTest.java b/modules/configuration-annotation-processor/src/integrationTest/java/org/apache/ignite/internal/configuration/processor/AbstractProcessorTest.java
index c4901d3..856b13c 100644
--- a/modules/configuration-annotation-processor/src/integrationTest/java/org/apache/ignite/internal/configuration/processor/AbstractProcessorTest.java
+++ b/modules/configuration-annotation-processor/src/integrationTest/java/org/apache/ignite/internal/configuration/processor/AbstractProcessorTest.java
@@ -19,13 +19,13 @@ package org.apache.ignite.internal.configuration.processor;
 
 import static com.google.testing.compile.Compiler.javac;
 
-import com.google.common.base.Functions;
 import com.google.testing.compile.Compilation;
 import com.google.testing.compile.JavaFileObjects;
 import com.squareup.javapoet.ClassName;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 import javax.tools.JavaFileObject;
 
@@ -133,7 +133,7 @@ public class AbstractProcessorTest {
             generatedSources = compilation.generatedSourceFiles();
 
             generatedClasses = generatedSources.stream()
-                    .collect(Collectors.toMap(object -> fromGeneratedFilePath(object.getName()), Functions.identity()));
+                    .collect(Collectors.toMap(object -> fromGeneratedFilePath(object.getName()), Function.identity()));
 
             classSets = schemaClasses.stream().collect(
                     Collectors.toMap(name -> name, name -> getConfigSet(name, generatedClasses))
diff --git a/modules/configuration-annotation-processor/src/integrationTest/java/org/apache/ignite/internal/configuration/processor/ParsedClass.java b/modules/configuration-annotation-processor/src/integrationTest/java/org/apache/ignite/internal/configuration/processor/ParsedClass.java
index 9964a4d..26c5f97 100644
--- a/modules/configuration-annotation-processor/src/integrationTest/java/org/apache/ignite/internal/configuration/processor/ParsedClass.java
+++ b/modules/configuration-annotation-processor/src/integrationTest/java/org/apache/ignite/internal/configuration/processor/ParsedClass.java
@@ -17,9 +17,9 @@
 
 package org.apache.ignite.internal.configuration.processor;
 
-import com.google.common.base.Functions;
 import java.util.List;
 import java.util.Map;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 import spoon.reflect.declaration.CtClass;
 import spoon.reflect.declaration.CtConstructor;
@@ -61,15 +61,15 @@ public class ParsedClass {
 
         this.fields = cls.getAllFields()
                 .stream()
-                .collect(Collectors.toMap(CtReference::getSimpleName, Functions.identity()));
+                .collect(Collectors.toMap(CtReference::getSimpleName, Function.identity()));
 
         this.methods = cls.getMethods()
                 .stream()
-                .collect(Collectors.toMap(this::getMethodName, Functions.identity()));
+                .collect(Collectors.toMap(this::getMethodName, Function.identity()));
 
         this.constructors = cls.getConstructors()
                 .stream()
-                .collect(Collectors.toMap(this::getMethodName, Functions.identity()));
+                .collect(Collectors.toMap(this::getMethodName, Function.identity()));
     }
 
     /**
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItDataSchemaSyncTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItDataSchemaSyncTest.java
index 10209e7..031191f 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItDataSchemaSyncTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItDataSchemaSyncTest.java
@@ -22,7 +22,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 
-import com.google.common.collect.Lists;
 import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -132,7 +131,7 @@ public class ItDataSchemaSyncTest extends IgniteAbstractTest {
      */
     @AfterEach
     void afterEach() throws Exception {
-        IgniteUtils.closeAll(Lists.reverse(clusterNodes));
+        IgniteUtils.closeAll(clusterNodes);
     }
 
     /**
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcBatchSelfTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcBatchSelfTest.java
index 321e176..52c6094 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcBatchSelfTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcBatchSelfTest.java
@@ -46,7 +46,7 @@ import org.junit.jupiter.api.io.TempDir;
 /**
  * Statement test.
  */
-@Disabled("https://issues.apache.org/jira/browse/IGNITE-15655")
+@Disabled("https://issues.apache.org/jira/browse/IGNITE-16683")
 public class ItJdbcBatchSelfTest extends AbstractJdbcSelfTest {
     /** SQL CREATE TABLE query. */
     private static final String SQL_CREATE = "CREATE TABLE Person(id INT PRIMARY KEY, firstName VARCHAR, lastName VARCHAR, age INT)";
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcComplexDmlDdlSelfTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcComplexDmlDdlSelfTest.java
index daf20e4..1a24731 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcComplexDmlDdlSelfTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcComplexDmlDdlSelfTest.java
@@ -37,7 +37,7 @@ import org.junit.jupiter.api.Test;
 /**
  * Base class for complex SQL tests based on JDBC driver.
  */
-@Disabled("https://issues.apache.org/jira/browse/IGNITE-15655")
+@Disabled("https://issues.apache.org/jira/browse/IGNITE-16683")
 public class ItJdbcComplexDmlDdlSelfTest extends AbstractJdbcSelfTest {
     /** Names of companies to use. */
     private static final List<String> COMPANIES = Arrays.asList("ASF", "GNU", "BSD");
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcComplexQuerySelfTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcComplexQuerySelfTest.java
index a36b6b8..39c9285 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcComplexQuerySelfTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcComplexQuerySelfTest.java
@@ -36,7 +36,7 @@ import org.junit.jupiter.api.Test;
 /**
  * Tests for complex queries (joins, etc.).
  */
-@Disabled("https://issues.apache.org/jira/browse/IGNITE-15655")
+@Disabled("https://issues.apache.org/jira/browse/IGNITE-16683")
 public class ItJdbcComplexQuerySelfTest extends AbstractJdbcSelfTest {
     @BeforeAll
     public static void createTable() throws Exception {
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcConnectionSelfTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcConnectionSelfTest.java
index 99e7c7c..17608e6 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcConnectionSelfTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcConnectionSelfTest.java
@@ -62,7 +62,7 @@ import org.junit.jupiter.api.Test;
  * Connection test.
  */
 @SuppressWarnings("ThrowableNotThrown")
-@Disabled("https://issues.apache.org/jira/browse/IGNITE-15655")
+@Disabled("https://issues.apache.org/jira/browse/IGNITE-16683")
 public class ItJdbcConnectionSelfTest extends AbstractJdbcSelfTest {
     /**
      * Test JDBC loading via ServiceLoader.
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcDeleteStatementSelfTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcDeleteStatementSelfTest.java
index 786ab71..1f397b7 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcDeleteStatementSelfTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcDeleteStatementSelfTest.java
@@ -30,7 +30,7 @@ import org.junit.jupiter.api.Test;
 /**
  * Delete functional statement self test.
  */
-@Disabled("https://issues.apache.org/jira/browse/IGNITE-15655")
+@Disabled("https://issues.apache.org/jira/browse/IGNITE-16683")
 public class ItJdbcDeleteStatementSelfTest extends ItJdbcAbstractStatementSelfTest {
     /**
      * Execute delete query test.
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcErrorsAbstractSelfTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcErrorsAbstractSelfTest.java
index 55aff1e..e888f5f 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcErrorsAbstractSelfTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcErrorsAbstractSelfTest.java
@@ -45,7 +45,7 @@ import org.junit.jupiter.api.Test;
 /**
  * Test SQLSTATE codes propagation with (any) Ignite JDBC driver.
  */
-@Disabled("https://issues.apache.org/jira/browse/IGNITE-15655")
+@Disabled("https://issues.apache.org/jira/browse/IGNITE-16683")
 public abstract class ItJdbcErrorsAbstractSelfTest extends AbstractJdbcSelfTest {
     /**
      * Test that parsing-related error codes get propagated to Ignite SQL exceptions.
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcErrorsSelfTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcErrorsSelfTest.java
index 09017ab..631d665 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcErrorsSelfTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcErrorsSelfTest.java
@@ -35,7 +35,7 @@ import org.junit.jupiter.api.Test;
 /**
  * Test SQLSTATE codes propagation with thin client driver.
  */
-@Disabled("https://issues.apache.org/jira/browse/IGNITE-15655")
+@Disabled("https://issues.apache.org/jira/browse/IGNITE-16683")
 public class ItJdbcErrorsSelfTest extends ItJdbcErrorsAbstractSelfTest {
     /** {@inheritDoc} */
     @Override protected Connection getConnection() throws SQLException {
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcInsertStatementSelfTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcInsertStatementSelfTest.java
index 0dc6098..2b1e0c6 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcInsertStatementSelfTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcInsertStatementSelfTest.java
@@ -35,7 +35,7 @@ import org.junit.jupiter.api.Test;
 /**
  * Statement test.
  */
-@Disabled("https://issues.apache.org/jira/browse/IGNITE-15655")
+@Disabled("https://issues.apache.org/jira/browse/IGNITE-16683")
 public class ItJdbcInsertStatementSelfTest extends ItJdbcAbstractStatementSelfTest {
     /** SQL SELECT query for verification. */
     private static final String SQL_SELECT = "select sid, id, firstName, lastName, age from PUBLIC.PERSON";
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcJoinsSelfTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcJoinsSelfTest.java
index 0308817..2fd7e61 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcJoinsSelfTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcJoinsSelfTest.java
@@ -29,7 +29,7 @@ import org.junit.jupiter.api.Test;
 /**
  * Tests for complex queries with joins.
  */
-@Disabled("https://issues.apache.org/jira/browse/IGNITE-15655")
+@Disabled("https://issues.apache.org/jira/browse/IGNITE-16683")
 public class ItJdbcJoinsSelfTest extends AbstractJdbcSelfTest {
     /**
      * Check distributed OUTER join of 3 tables (T1 -> T2 -> T3) returns correct result for non-collocated data.
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcMetadataPrimaryKeysSelfTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcMetadataPrimaryKeysSelfTest.java
index 6ee86c7..3bea277 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcMetadataPrimaryKeysSelfTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcMetadataPrimaryKeysSelfTest.java
@@ -33,7 +33,7 @@ import org.junit.jupiter.api.Test;
 /**
  * Verifies that primary keys in the metadata are valid.
  */
-@Disabled("https://issues.apache.org/jira/browse/IGNITE-15655")
+@Disabled("https://issues.apache.org/jira/browse/IGNITE-16683")
 public class ItJdbcMetadataPrimaryKeysSelfTest extends AbstractJdbcSelfTest {
     /** COLUMN_NAME column index in the metadata table. */
     private static final int COL_NAME_IDX = 4;
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcMetadataSelfTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcMetadataSelfTest.java
index f0dd23e..b914e14 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcMetadataSelfTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcMetadataSelfTest.java
@@ -57,7 +57,7 @@ import org.junit.jupiter.api.Test;
 /**
  * Metadata tests.
  */
-@Disabled("https://issues.apache.org/jira/browse/IGNITE-15655")
+@Disabled("https://issues.apache.org/jira/browse/IGNITE-16683")
 public class ItJdbcMetadataSelfTest extends AbstractJdbcSelfTest {
     /** Creates tables. */
     @BeforeAll
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcResultSetSelfTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcResultSetSelfTest.java
index f07859a..a4c444c 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcResultSetSelfTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcResultSetSelfTest.java
@@ -58,7 +58,7 @@ import org.junit.jupiter.api.Test;
 /**
  * Result set test.
  */
-@Disabled("https://issues.apache.org/jira/browse/IGNITE-15655")
+@Disabled("https://issues.apache.org/jira/browse/IGNITE-16683")
 public class ItJdbcResultSetSelfTest extends AbstractJdbcSelfTest {
     /** SQL static query. */
     private static final String STATIC_SQL =
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcSelectAfterAlterTable.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcSelectAfterAlterTable.java
index 135439d..57a5963 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcSelectAfterAlterTable.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcSelectAfterAlterTable.java
@@ -32,7 +32,7 @@ import org.junit.jupiter.api.Test;
 /**
  * Base class for complex SQL tests based on JDBC driver.
  */
-@Disabled("https://issues.apache.org/jira/browse/IGNITE-15655")
+@Disabled("https://issues.apache.org/jira/browse/IGNITE-16683")
 public class ItJdbcSelectAfterAlterTable extends AbstractJdbcSelfTest {
     /** {@inheritDoc} */
     @BeforeEach
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcStatementSelfTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcStatementSelfTest.java
index 4897306..03a7c59 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcStatementSelfTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcStatementSelfTest.java
@@ -42,7 +42,7 @@ import org.junit.jupiter.api.Test;
 /**
  * Statement test.
  */
-@Disabled("https://issues.apache.org/jira/browse/IGNITE-15655")
+@Disabled("https://issues.apache.org/jira/browse/IGNITE-16683")
 public class ItJdbcStatementSelfTest extends ItJdbcAbstractStatementSelfTest {
     /** SQL query. */
     private static final String SQL = "select * from PERSON where age > 30";
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcUpdateStatementSelfTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcUpdateStatementSelfTest.java
index dbe6909..3e68d9a 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcUpdateStatementSelfTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/jdbc/ItJdbcUpdateStatementSelfTest.java
@@ -31,7 +31,7 @@ import org.junit.jupiter.api.Test;
 /**
  * Update statement self test.
  */
-@Disabled("https://issues.apache.org/jira/browse/IGNITE-15655")
+@Disabled("https://issues.apache.org/jira/browse/IGNITE-16683")
 public class ItJdbcUpdateStatementSelfTest extends AbstractJdbcSelfTest {
     /**
      * Execute test.
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItJoinTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItJoinTest.java
index e612c9b..9e638ff 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItJoinTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItJoinTest.java
@@ -725,6 +725,83 @@ public class ItJoinTest extends AbstractBasicIntegrationTest {
                 .check();
     }
 
+    /**
+     * Tests JOIN with USING clause.
+     */
+    @ParameterizedTest
+    @EnumSource
+    public void testJoinWithUsing(JoinType joinType) {
+        // Select all join columns.
+        assertQuery("SELECT * FROM t1 JOIN t2 USING (c1, c2)", joinType)
+                .returns(1, 1, 0, 1, 0, 1)
+                .returns(2, 2, 2, 2, 2, 2)
+                .returns(2, 2, 2, 2, 1, null)
+                .returns(3, 3, 3, null, 4, 3)
+                .returns(3, 3, 4, 3, 4, 3)
+                .returns(4, 4, 5, 4, 5, 4)
+                .check();
+
+        // Select all table columns explicitly.
+        assertQuery("SELECT t1.*, t2.* FROM t1 JOIN t2 USING (c1, c2)")
+                .returns(0, 1, 1, 1, 0, 1, 1, 1)
+                .returns(2, 2, 2, 2, 2, 2, 2, 2)
+                .returns(2, 2, 2, 2, 1, 2, 2, null)
+                .returns(3, 3, 3, null, 4, 3, 3, 3)
+                .returns(4, 3, 3, 3, 4, 3, 3, 3)
+                .returns(5, 4, 4, 4, 5, 4, 4, 4)
+                .check();
+
+        // Select explicit columns. Columns from using - not ambiguous.
+        assertQuery("SELECT c1, c2, t1.c3, t2.c3 FROM t1 JOIN t2 USING (c1, c2) ORDER BY c1, c2")
+                .returns(1, 1, 1, 1)
+                .returns(2, 2, 2, null)
+                .returns(2, 2, 2, 2)
+                .returns(3, 3, null, 3)
+                .returns(3, 3, 3, 3)
+                .returns(4, 4, 4, 4)
+                .check();
+    }
+
+    /**
+     * Tests NATURAL JOIN.
+     */
+    @ParameterizedTest
+    @EnumSource
+    public void testNatural(JoinType joinType) {
+        // Select all join columns.
+        assertQuery("SELECT * FROM t1 NATURAL JOIN t2", joinType)
+                .returns(0, 1, 1, 1)
+                .returns(2, 2, 2, 2)
+                .returns(4, 3, 3, 3)
+                .returns(5, 4, 4, 4)
+                .check();
+
+        // Select all tables columns explicitly.
+        assertQuery("SELECT t1.*, t2.* FROM t1 NATURAL JOIN t2", joinType)
+                .returns(0, 1, 1, 1, 0, 1, 1, 1)
+                .returns(2, 2, 2, 2, 2, 2, 2, 2)
+                .returns(4, 3, 3, 3, 4, 3, 3, 3)
+                .returns(5, 4, 4, 4, 5, 4, 4, 4)
+                .check();
+
+        // Select explicit columns.
+        assertQuery("SELECT t1.c1, t2.c2, t1.c3, t2.c3 FROM t1 NATURAL JOIN t2", joinType)
+                .returns(1, 1, 1, 1)
+                .returns(2, 2, 2, 2)
+                .returns(3, 3, 3, 3)
+                .returns(4, 4, 4, 4)
+                .check();
+
+        // Columns - not ambiguous.
+        // TODO https://issues.apache.org/jira/browse/CALCITE-4915
+        //assertQuery("SELECT c1, c2, c3 FROM t1 NATURAL JOIN t2 ORDER BY c1, c2, c3")
+        //    .returns(1, 1, 1)
+        //    .returns(2, 2, 2)
+        //    .returns(3, 3, 3)
+        //    .returns(4, 4, 4)
+        //    .check();
+    }
+
     protected QueryChecker assertQuery(String qry, JoinType joinType) {
         return AbstractBasicIntegrationTest.assertQuery(qry.replace("select", "select "
             + Arrays.stream(joinType.disabledRules).collect(Collectors.joining("','", "/*+ DISABLE_RULE('", "') */"))));
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/RexExecutorImpl.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/RexExecutorImpl.java
index 64dc9e9..4e64090 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/RexExecutorImpl.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/RexExecutorImpl.java
@@ -17,7 +17,6 @@
 
 package org.apache.ignite.internal.sql.engine.exec.exp;
 
-import com.google.common.collect.ImmutableList;
 import java.lang.reflect.Modifier;
 import java.lang.reflect.Type;
 import java.util.List;
@@ -113,7 +112,7 @@ public class RexExecutorImpl implements RexExecutor {
         final MethodDeclaration mtdDecl =
                 Expressions.methodDecl(Modifier.PUBLIC, Object[].class,
                         BuiltInMethod.FUNCTION1_APPLY.method.getName(),
-                        ImmutableList.of(root0_), blockBuilder.toBlock());
+                        List.of(root0_), blockBuilder.toBlock());
 
         String code = Expressions.toString(mtdDecl);
 
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteSqlValidator.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteSqlValidator.java
index 8d73afe..5ca453d 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteSqlValidator.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteSqlValidator.java
@@ -29,12 +29,14 @@ import org.apache.calcite.prepare.CalciteCatalogReader;
 import org.apache.calcite.prepare.Prepare;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeField;
+import org.apache.calcite.sql.JoinConditionType;
 import org.apache.calcite.sql.SqlAggFunction;
 import org.apache.calcite.sql.SqlCall;
 import org.apache.calcite.sql.SqlDelete;
 import org.apache.calcite.sql.SqlDynamicParam;
 import org.apache.calcite.sql.SqlIdentifier;
 import org.apache.calcite.sql.SqlInsert;
+import org.apache.calcite.sql.SqlJoin;
 import org.apache.calcite.sql.SqlKind;
 import org.apache.calcite.sql.SqlLiteral;
 import org.apache.calcite.sql.SqlNode;
@@ -252,6 +254,71 @@ public class IgniteSqlValidator extends SqlValidatorImpl {
         super.validateAggregateParams(aggCall, filter, null, orderList, scope);
     }
 
+    /** {@inheritDoc} */
+    @Override
+    protected SqlNode performUnconditionalRewrites(SqlNode node, boolean underFrom) {
+        // Workaround for https://issues.apache.org/jira/browse/CALCITE-4923
+        if (node instanceof SqlSelect) {
+            SqlSelect select = (SqlSelect) node;
+
+            if (select.getFrom() instanceof SqlJoin) {
+                boolean hasStar = false;
+
+                for (SqlNode expr : select.getSelectList()) {
+                    if (expr instanceof SqlIdentifier && ((SqlIdentifier) expr).isStar()
+                            && ((SqlIdentifier) expr).names.size() == 1) {
+                        hasStar = true;
+                    }
+                }
+
+                performJoinRewrites((SqlJoin) select.getFrom(), hasStar);
+            }
+        }
+
+        return super.performUnconditionalRewrites(node, underFrom);
+    }
+
+    /** Rewrites JOIN clause if required. */
+    private void performJoinRewrites(SqlJoin join, boolean hasStar) {
+        if (join.getLeft() instanceof SqlJoin) {
+            performJoinRewrites((SqlJoin) join.getLeft(), hasStar || join.isNatural());
+        }
+
+        if (join.getRight() instanceof SqlJoin) {
+            performJoinRewrites((SqlJoin) join.getRight(), hasStar || join.isNatural());
+        }
+
+        // Join with USING should be rewriten if SELECT conatins "star" in projects, NATURAL JOIN also has other issues
+        // and should be rewritten in any case.
+        if (join.isNatural() || (join.getConditionType() == JoinConditionType.USING && hasStar)) {
+            // Default Calcite validator can't expand "star" for NATURAL joins and joins with USING if some columns
+            // of join sources are filtered out by the addToSelectList method, and the count of columns in the
+            // selectList not equals to the count of fields in the corresponding rowType. Since we do filtering in the
+            // addToSelectList method (exclude _KEY and _VAL columns), to workaround the expandStar limitation we can
+            // wrap each table to a subquery. In this case columns will be filtered out on the subquery level and
+            // rowType of the subquery will have the same cardinality as selectList.
+            join.setLeft(rewriteTableToQuery(join.getLeft()));
+            join.setRight(rewriteTableToQuery(join.getRight()));
+        }
+    }
+
+    /** Wrap table to subquery "SELECT * FROM table". */
+    private SqlNode rewriteTableToQuery(SqlNode from) {
+        SqlNode src = from.getKind() == SqlKind.AS ? ((SqlCall) from).getOperandList().get(0) : from;
+
+        if (src.getKind() == SqlKind.IDENTIFIER || src.getKind() == SqlKind.TABLE_REF) {
+            String alias = deriveAlias(from, 0);
+
+            SqlSelect expandedQry = new SqlSelect(SqlParserPos.ZERO, null,
+                    SqlNodeList.of(SqlIdentifier.star(SqlParserPos.ZERO)), src, null, null, null,
+                    null, null, null, null, null);
+
+            return SqlValidatorUtil.addAlias(expandedQry, alias);
+        } else {
+            return from;
+        }
+    }
+
     private void validateAggregateFunction(SqlCall call, SqlAggFunction aggFunction) {
         if (!SqlKind.AGGREGATE.contains(aggFunction.kind)) {
             throw newValidationError(call,
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteMergeJoin.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteMergeJoin.java
index eabe33c..d0f25be 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteMergeJoin.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteMergeJoin.java
@@ -23,7 +23,6 @@ import static org.apache.calcite.rel.core.JoinRelType.FULL;
 import static org.apache.calcite.rel.core.JoinRelType.LEFT;
 import static org.apache.calcite.rel.core.JoinRelType.RIGHT;
 
-import com.google.common.collect.ImmutableList;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
@@ -174,7 +173,7 @@ public class IgniteMergeJoin extends AbstractIgniteJoin {
         return List.of(
                 Pair.of(
                         nodeTraits.replace(desiredCollation),
-                        ImmutableList.of(
+                        List.of(
                                 left.replace(leftCollation),
                                 right.replace(rightCollation)
                         )
@@ -260,7 +259,7 @@ public class IgniteMergeJoin extends AbstractIgniteJoin {
 
         return Pair.of(
                 required.replace(nodeCollation),
-                ImmutableList.of(
+                List.of(
                         left.replace(leftCollation),
                         right.replace(rightCollation)
                 )
@@ -321,7 +320,7 @@ public class IgniteMergeJoin extends AbstractIgniteJoin {
     ) {
         return Pair.of(
                 nodeTraits.replace(EMPTY),
-                ImmutableList.of(
+                List.of(
                         leftInputTraits.replace(RelCollations.of(joinInfo.leftKeys)),
                         rightInputTraits.replace(RelCollations.of(joinInfo.rightKeys))
                 )
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/logical/LogicalOrToUnionRule.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/logical/LogicalOrToUnionRule.java
index 58c2b03..d8ce518 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/logical/LogicalOrToUnionRule.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/logical/LogicalOrToUnionRule.java
@@ -17,9 +17,9 @@
 
 package org.apache.ignite.internal.sql.engine.rule.logical;
 
-import com.google.common.collect.ImmutableMap;
 import java.util.BitSet;
 import java.util.List;
+import java.util.Map;
 import org.apache.calcite.plan.RelOptCluster;
 import org.apache.calcite.plan.RelOptRule;
 import org.apache.calcite.plan.RelOptRuleCall;
@@ -185,7 +185,7 @@ public class LogicalOrToUnionRule extends RelRule<LogicalOrToUnionRule.Config> {
         RelNode rel0 = createUnionAll(cluster, input, operands.get(0), operands.get(1));
         RelNode rel1 = createUnionAll(cluster, input, operands.get(1), operands.get(0));
 
-        call.transformTo(rel0, ImmutableMap.of(rel1, rel0));
+        call.transformTo(rel0, Map.of(rel1, rel0));
     }
 
     /**
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/RuntimeSortedIndexTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/RuntimeSortedIndexTest.java
index 07dbbaf..366a697 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/RuntimeSortedIndexTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/RuntimeSortedIndexTest.java
@@ -19,13 +19,13 @@ package org.apache.ignite.internal.sql.engine.exec;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
-import com.google.common.collect.ImmutableMap;
 import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.Arrays;
 import java.util.BitSet;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
 import java.util.UUID;
 import java.util.concurrent.ThreadLocalRandom;
 import java.util.stream.Collectors;
@@ -116,7 +116,7 @@ public class RuntimeSortedIndexTest extends IgniteAbstractTest {
                         0,
                         null,
                         ArrayRowHandler.INSTANCE,
-                        ImmutableMap.of()
+                        Map.of()
                 ),
                 RelCollations.of(ImmutableIntList.copyOf(idxCols)),
                 (o1, o2) -> {
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/AbstractExecutionTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/AbstractExecutionTest.java
index be35c16..dfe0eaa 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/AbstractExecutionTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/AbstractExecutionTest.java
@@ -17,12 +17,12 @@
 
 package org.apache.ignite.internal.sql.engine.exec.rel;
 
-import com.google.common.collect.ImmutableMap;
 import it.unimi.dsi.fastutil.longs.Long2ObjectMaps;
 import java.util.ArrayDeque;
 import java.util.Deque;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.UUID;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutorService;
@@ -105,7 +105,7 @@ public class AbstractExecutionTest extends IgniteAbstractTest {
                 0,
                 fragmentDesc,
                 ArrayRowHandler.INSTANCE,
-                ImmutableMap.of()
+                Map.of()
         );
     }
 
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/HashAggregateExecutionTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/HashAggregateExecutionTest.java
index f2f2066..f33d6d6 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/HashAggregateExecutionTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/HashAggregateExecutionTest.java
@@ -25,7 +25,6 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
-import com.google.common.collect.ImmutableList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
@@ -173,7 +172,7 @@ public class HashAggregateExecutionTest extends BaseAggregateTest {
                 null
         );
 
-        ImmutableList<ImmutableBitSet> grpSets = ImmutableList.of(ImmutableBitSet.of());
+        List<ImmutableBitSet> grpSets = List.of(ImmutableBitSet.of());
 
         RelDataType aggRowType = TypeUtils.createRowType(tf, int.class);
 
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AbstractPlannerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AbstractPlannerTest.java
index 72228a5..131938d 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AbstractPlannerTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AbstractPlannerTest.java
@@ -24,17 +24,19 @@ import static org.apache.ignite.internal.sql.engine.util.Commons.FRAMEWORK_CONFI
 import static org.apache.ignite.internal.util.CollectionUtils.first;
 import static org.apache.ignite.internal.util.CollectionUtils.nullOrEmpty;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assertions.fail;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.UUID;
 import java.util.function.BiFunction;
 import java.util.function.Function;
@@ -117,6 +119,8 @@ public abstract class AbstractPlannerTest extends IgniteAbstractTest {
 
     protected static final int DEFAULT_TBL_SIZE = 500_000;
 
+    protected static final String DEFAULT_SCHEMA = "PUBLIC";
+
     /** Last error message. */
     private String lastErrorMsg;
 
@@ -209,19 +213,12 @@ public abstract class AbstractPlannerTest extends IgniteAbstractTest {
      * Create planner context for specified query.
      */
     protected PlanningContext plannerCtx(String sql, IgniteSchema publicSchema, String... disabledRules) {
-        SchemaPlus schema = createRootSchema(false)
-                .add("PUBLIC", publicSchema);
+        return plannerCtx(sql, Collections.singleton(publicSchema), disabledRules);
+    }
 
+    protected PlanningContext plannerCtx(String sql, Collection<IgniteSchema> schemas, String... disabledRules) {
         PlanningContext ctx = PlanningContext.builder()
-                .parentContext(BaseQueryContext.builder()
-                        .frameworkConfig(
-                                newConfigBuilder(FRAMEWORK_CONFIG)
-                                        .defaultSchema(schema)
-                                        .build()
-                        )
-                        .logger(log)
-                        .build()
-                )
+                .parentContext(baseQueryContext(schemas))
                 .query(sql)
                 .build();
 
@@ -229,11 +226,33 @@ public abstract class AbstractPlannerTest extends IgniteAbstractTest {
 
         assertNotNull(planner);
 
-        planner.setDisabledRules(new HashSet<>(Arrays.asList(disabledRules)));
+        planner.setDisabledRules(Set.copyOf(Arrays.asList(disabledRules)));
 
         return ctx;
     }
 
+    protected BaseQueryContext baseQueryContext(Collection<IgniteSchema> schemas) {
+        SchemaPlus rootSchema = createRootSchema(false);
+        SchemaPlus dfltSchema = null;
+
+        for (IgniteSchema igniteSchema : schemas) {
+            SchemaPlus schema = rootSchema.add(igniteSchema.getName(), igniteSchema);
+
+            if (dfltSchema == null || DEFAULT_SCHEMA.equals(schema.getName())) {
+                dfltSchema = schema;
+            }
+        }
+
+        return BaseQueryContext.builder()
+                .frameworkConfig(
+                        newConfigBuilder(FRAMEWORK_CONFIG)
+                                .defaultSchema(dfltSchema)
+                                .build()
+                )
+                .logger(log)
+                .build();
+    }
+
     /**
      * Returns the first found node of given class from expression tree.
      *
@@ -271,6 +290,19 @@ public abstract class AbstractPlannerTest extends IgniteAbstractTest {
         return physicalPlan(sql, plannerCtx(sql, publicSchema, disabledRules));
     }
 
+    protected IgniteRel physicalPlan(String sql, Collection<IgniteSchema> schemas, String... disabledRules) throws Exception {
+        return physicalPlan(plannerCtx(sql, schemas, disabledRules));
+    }
+
+    protected IgniteRel physicalPlan(PlanningContext ctx) throws Exception {
+        try (IgnitePlanner planner = ctx.planner()) {
+            assertNotNull(planner);
+            assertNotNull(ctx.query());
+
+            return physicalPlan(ctx.query(), ctx);
+        }
+    }
+
     protected IgniteRel physicalPlan(String sql, PlanningContext ctx) throws Exception {
         try (IgnitePlanner planner = ctx.planner()) {
             assertNotNull(planner);
@@ -313,6 +345,33 @@ public abstract class AbstractPlannerTest extends IgniteAbstractTest {
         return res;
     }
 
+    /**
+     * Predicate builder for "Operator has column names" condition.
+     */
+    protected <T extends RelNode> Predicate<T> hasColumns(String... cols) {
+        return node -> {
+            RelDataType rowType = node.getRowType();
+
+            String err = "Unexpected columns [expected=" + Arrays.toString(cols) + ", actual=" + rowType.getFieldNames() + ']';
+
+            if (rowType.getFieldCount() != cols.length) {
+                lastErrorMsg = err;
+
+                return false;
+            }
+
+            for (int i = 0; i < cols.length; i++) {
+                if (!cols[i].equals(rowType.getFieldNames().get(i))) {
+                    lastErrorMsg = err;
+
+                    return false;
+                }
+            }
+
+            return true;
+        };
+    }
+
     protected static void createTable(IgniteSchema schema, String name, RelDataType type, IgniteDistribution distr) {
         TestTable table = new TestTable(type, name) {
             @Override
@@ -325,6 +384,25 @@ public abstract class AbstractPlannerTest extends IgniteAbstractTest {
     }
 
     /**
+     * Creates test table with given params and schema.
+     *
+     * @param schema Table schema.
+     * @param name   Name of the table.
+     * @param distr  Distribution of the table.
+     * @param fields List of the required fields. Every odd item should be a string representing a column name, every
+     *               even item should be a class representing column's type.
+     *               E.g. {@code createTable("MY_TABLE", distribution, "ID", Integer.class, "VAL", String.class)}.
+     * @return Instance of the {@link TestTable}.
+     */
+    protected static TestTable createTable(IgniteSchema schema, String name, IgniteDistribution distr, Object... fields) {
+        TestTable tbl = createTable(name, DEFAULT_TBL_SIZE, distr, fields);
+
+        schema.addTable(name, tbl);
+
+        return tbl;
+    }
+
+    /**
      * Creates test table with given params.
      *
      * @param name   Name of the table.
@@ -368,11 +446,24 @@ public abstract class AbstractPlannerTest extends IgniteAbstractTest {
         };
     }
 
-    protected <T extends RelNode> void assertPlan(String sql, IgniteSchema schema, Predicate<T> predicate,
-            String... disabledRules) throws Exception {
-        IgniteRel plan = physicalPlan(sql, schema, disabledRules);
+    protected <T extends RelNode> void assertPlan(
+            String sql,
+            IgniteSchema schema,
+            Predicate<T> predicate,
+            String... disabledRules
+    ) throws Exception {
+        assertPlan(sql, Collections.singleton(schema), predicate, disabledRules);
+    }
+
+    protected <T extends RelNode> void assertPlan(
+            String sql,
+            Collection<IgniteSchema> schemas,
+            Predicate<T> predicate,
+            String... disabledRules
+    ) throws Exception {
+        IgniteRel plan = physicalPlan(sql, schemas, disabledRules);
 
-        checkSplitAndSerialization(plan, schema);
+        checkSplitAndSerialization(plan, schemas);
 
         if (!predicate.test((T) plan)) {
             String invalidPlanMsg = "Invalid plan (" + lastErrorMsg + "):\n"
@@ -496,7 +587,12 @@ public abstract class AbstractPlannerTest extends IgniteAbstractTest {
     }
 
     protected void checkSplitAndSerialization(IgniteRel rel, IgniteSchema publicSchema) {
+        checkSplitAndSerialization(rel, Collections.singleton(publicSchema));
+    }
+
+    protected void checkSplitAndSerialization(IgniteRel rel, Collection<IgniteSchema> schemas) {
         assertNotNull(rel);
+        assertFalse(schemas.isEmpty());
 
         rel = Cloner.clone(rel);
 
@@ -517,10 +613,14 @@ public abstract class AbstractPlannerTest extends IgniteAbstractTest {
 
         List<RelNode> deserializedNodes = new ArrayList<>();
 
-        Map<UUID, IgniteTable> tableMap = publicSchema.getTableNames().stream()
-                .map(publicSchema::getTable)
-                .map(IgniteTable.class::cast)
-                .collect(Collectors.toMap(IgniteTable::id, Function.identity()));
+        Map<UUID, IgniteTable> tableMap = new HashMap<>();
+
+        for (IgniteSchema schema : schemas) {
+            tableMap.putAll(schema.getTableNames().stream()
+                    .map(schema::getTable)
+                    .map(IgniteTable.class::cast)
+                    .collect(Collectors.toMap(IgniteTable::id, Function.identity())));
+        }
 
         for (String s : serialized) {
             RelJsonReader reader = new RelJsonReader(new SqlSchemaManagerImpl(tableMap));
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/JoinWithUsingPlannerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/JoinWithUsingPlannerTest.java
new file mode 100644
index 0000000..a88a5f6
--- /dev/null
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/JoinWithUsingPlannerTest.java
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.sql.engine.planner;
+
+import java.sql.Date;
+import java.util.ArrayList;
+import java.util.Collection;
+import org.apache.ignite.internal.sql.engine.schema.IgniteSchema;
+import org.apache.ignite.internal.sql.engine.trait.IgniteDistributions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Join with USING syntax tests.
+ */
+public class JoinWithUsingPlannerTest extends AbstractPlannerTest {
+    /** Public schemas. */
+    private static final Collection<IgniteSchema> schemas = new ArrayList<>();
+
+    @BeforeAll
+    public static void init() {
+        IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
+        IgniteSchema otherSchema = new IgniteSchema("OTHER");
+
+        createTable(publicSchema, "T1", IgniteDistributions.random(),
+                "EMPID", Integer.class, "DEPTID", Integer.class, "NAME", String.class);
+        createTable(publicSchema, "T2", IgniteDistributions.random(),
+                "DEPTID", Integer.class, "NAME", String.class, "PARENTID", Integer.class);
+        createTable(otherSchema, "T3", IgniteDistributions.random(),
+                "EMPID", Integer.class, "DEPTID", Integer.class, "D", Date.class);
+
+        schemas.add(publicSchema);
+        schemas.add(otherSchema);
+    }
+
+    @Test
+    public void testJoinWithUsing() throws Exception {
+        // Join tables without aliases.
+        assertPlan("SELECT * FROM T1 JOIN T2 USING (DEPTID)", schemas,
+                hasColumns("DEPTID", "EMPID", "NAME", "NAME0", "PARENTID"));
+
+        // Join tables with aliases.
+        assertPlan("SELECT * FROM T1 AS A1 JOIN T2 AS A2 USING (DEPTID)", schemas,
+                hasColumns("DEPTID", "EMPID", "NAME", "NAME0", "PARENTID"));
+
+        // Join tables in different schemas.
+        assertPlan("SELECT * FROM T1 JOIN OTHER.T3 USING (DEPTID)", schemas,
+                hasColumns("DEPTID", "EMPID", "NAME", "EMPID0", "D"));
+
+        // Join tables using two columns.
+        assertPlan("SELECT * FROM T1 JOIN T2 USING (DEPTID, NAME)", schemas,
+                hasColumns("DEPTID", "NAME", "EMPID", "PARENTID"));
+
+        // Double join.
+        assertPlan("SELECT * FROM T1 JOIN T2 USING (DEPTID) JOIN OTHER.T3 USING (EMPID) ", schemas,
+                hasColumns("EMPID", "DEPTID", "NAME", "NAME0", "PARENTID", "DEPTID1", "D"));
+
+        // Join table with subquery.
+        assertPlan("SELECT * FROM T1 JOIN (SELECT * FROM T2) USING (DEPTID)", schemas,
+                hasColumns("DEPTID", "EMPID", "NAME", "NAME0", "PARENTID"));
+
+        // Join subqueries.
+        assertPlan("SELECT * FROM (SELECT * FROM T1) AS T JOIN (SELECT * FROM T2) USING (DEPTID)", schemas,
+                hasColumns("DEPTID", "EMPID", "NAME", "NAME0", "PARENTID"));
+
+        // Select all tables columns.
+        assertPlan("SELECT T1.*, T2.* FROM T1 JOIN T2 USING (DEPTID)", schemas,
+                hasColumns("EMPID", "DEPTID", "NAME", "DEPTID0", "NAME0", "PARENTID"));
+
+        // Select system columns and all table columns.
+        assertPlan("SELECT T1.* FROM T1 JOIN T2 USING (DEPTID)", schemas,
+                hasColumns("EMPID", "DEPTID", "NAME"));
+
+        // System columns with "star".
+        // TODO https://issues.apache.org/jira/browse/CALCITE-4923
+        // For now we can't select system columns with "star", since when "star" is used, tables of join are rewrite to
+        // subqueries without system columns.
+        //assertPlan("SELECT *, T2._KEY FROM T1 JOIN T2 USING (DEPTID)", schemas,
+        //    hasColumns("DEPTID", "EMPID", "NAME", "NAME0", "PARENTID", "_KEY"));
+    }
+
+    @Test
+    public void testNaturalJoin() throws Exception {
+        // Join tables without aliases.
+        assertPlan("SELECT * FROM T1 NATURAL JOIN T2", schemas,
+                hasColumns("DEPTID", "NAME", "EMPID", "PARENTID"));
+
+        // Join tables with aliases.
+        assertPlan("SELECT * FROM T1 AS A1 NATURAL JOIN T2 AS A2", schemas,
+                hasColumns("DEPTID", "NAME", "EMPID", "PARENTID"));
+
+        // Join tables in different schemas.
+        assertPlan("SELECT * FROM T1 NATURAL JOIN OTHER.T3", schemas,
+                hasColumns("EMPID", "DEPTID", "NAME", "D"));
+
+        // Double join.
+        // TODO https://issues.apache.org/jira/browse/CALCITE-4921
+        //assertPlan("SELECT * FROM T1 NATURAL JOIN T2 NATURAL JOIN OTHER.T3", schemas,
+        //    hasColumns("DEPTID", "EMPTID", "NAME", "PARENTID", "D"));
+
+        // Join table with subquery.
+        assertPlan("SELECT * FROM T1 NATURAL JOIN (SELECT * FROM T2)", schemas,
+                hasColumns("DEPTID", "NAME", "EMPID", "PARENTID"));
+
+        // Join subqueries.
+        assertPlan("SELECT * FROM (SELECT * FROM T1) AS T NATURAL JOIN (SELECT * FROM T2)", schemas,
+                hasColumns("DEPTID", "NAME", "EMPID", "PARENTID"));
+
+        // Select explicit columns, system columns. Columns not ambiguous.
+        // TODO https://issues.apache.org/jira/browse/CALCITE-4915
+        //assertPlan("SELECT DEPTID, T1._KEY, T2.NAME FROM T1 NATURAL JOIN T2", schemas,
+        //    hasColumns("DEPTID", "_KEY", "NAME"));
+
+        // Select all tables columns.
+        assertPlan("SELECT T1.*, T2.* FROM T1 NATURAL JOIN T2", schemas,
+                hasColumns("EMPID", "DEPTID", "NAME", "DEPTID0", "NAME0", "PARENTID"));
+
+        // Select system columns and all table columns.
+        // TODO https://issues.apache.org/jira/browse/CALCITE-4923
+        //assertPlan("SELECT T1.*, T2._KEY FROM T1 NATURAL JOIN T2", schemas,
+        //    hasColumns("EMPID", "DEPTID", "NAME", "_KEY"));
+
+        // System columns with "star".
+        // TODO https://issues.apache.org/jira/browse/CALCITE-4923
+        //assertPlan("SELECT *, T2._KEY FROM T1 NATURAL JOIN T2", schemas,
+        //    hasColumns("DEPTID", "NAME", "EMPID", "PARENTID", "_KEY"));
+    }
+}