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

alexpl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 77987eaa70f IGNITE-27700 SQL Calcite: Fix merge filter to scan after 
trimmed fields - Fixes #12675.
77987eaa70f is described below

commit 77987eaa70f2aeb181a0f95b3206ba86930ac9ba
Author: Aleksey Plekhanov <[email protected]>
AuthorDate: Wed Feb 4 12:21:16 2026 +0300

    IGNITE-27700 SQL Calcite: Fix merge filter to scan after trimmed fields - 
Fixes #12675.
    
    Signed-off-by: Aleksey Plekhanov <[email protected]>
---
 .../calcite/exec/exp/IgniteScalarFunction.java     | 19 +++++--
 .../query/calcite/exec/exp/RexExecutorImpl.java    | 28 +++++++++-
 .../query/calcite/prepare/PlannerHelper.java       |  4 +-
 .../query/calcite/prepare/PlannerPhase.java        |  1 +
 .../query/calcite/rel/AbstractIndexScan.java       |  4 +-
 .../query/calcite/rel/IgniteIndexScan.java         | 13 +++--
 .../query/calcite/rel/IgniteTableScan.java         | 17 ++++--
 .../rel/ProjectableFilterableTableScan.java        | 13 +++--
 .../rel/logical/IgniteLogicalIndexScan.java        |  7 ++-
 .../rel/logical/IgniteLogicalTableScan.java        | 14 +++--
 .../calcite/rule/LogicalScanConverterRule.java     |  5 +-
 .../calcite/rule/logical/ExposeIndexRule.java      |  4 +-
 .../calcite/rule/logical/FilterScanMergeRule.java  |  6 +--
 .../calcite/rule/logical/LogicalOrToUnionRule.java |  1 +
 .../calcite/rule/logical/ProjectScanMergeRule.java |  8 ++-
 .../query/calcite/schema/CacheIndexImpl.java       | 13 -----
 .../query/calcite/schema/CacheTableImpl.java       | 18 -------
 .../query/calcite/schema/IgniteIndex.java          | 10 +++-
 .../query/calcite/schema/IgniteTable.java          | 27 +---------
 .../query/calcite/schema/SchemaHolderImpl.java     |  4 +-
 .../query/calcite/schema/SystemViewIndexImpl.java  | 14 -----
 .../query/calcite/schema/SystemViewTableImpl.java  | 17 ------
 .../calcite/exec/LogicalRelImplementorTest.java    | 13 +++++
 .../integration/AbstractBasicIntegrationTest.java  | 13 -----
 .../integration/HashSpoolIntegrationTest.java      | 10 ++--
 .../calcite/integration/tpch/TpchScale100Test.java | 16 ------
 .../planner/ProjectFilterScanMergePlannerTest.java | 63 ++++++++++++++++------
 .../planner/RexSimplificationPlannerTest.java      | 51 ++++++++++++++++++
 .../calcite/planner/SerializationPlannerTest.java  |  2 +-
 .../query/calcite/planner/TestTable.java           | 17 ------
 30 files changed, 242 insertions(+), 190 deletions(-)

diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteScalarFunction.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteScalarFunction.java
index 8c43f5a8620..09f377e3560 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteScalarFunction.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteScalarFunction.java
@@ -26,28 +26,41 @@ import org.apache.calcite.schema.ScalarFunction;
  * Implementation of {@link ScalarFunction} for Ignite user defined functions.
  */
 public class IgniteScalarFunction extends IgniteReflectiveFunctionBase 
implements ScalarFunction {
+    /** */
+    private final boolean deterministic;
+
     /**
      * Private constructor.
      */
-    private IgniteScalarFunction(Method method, CallImplementor implementor) {
+    private IgniteScalarFunction(Method method, CallImplementor implementor, 
boolean deterministic) {
         super(method, implementor);
+
+        this.deterministic = deterministic;
     }
 
     /**
      * Creates {@link ScalarFunction} from given method.
      *
      * @param method Method that is used to implement the function.
+     * @param deterministic Is function deterministic.
      * @return Created {@link ScalarFunction}.
      */
-    public static ScalarFunction create(Method method) {
+    public static ScalarFunction create(Method method, boolean deterministic) {
         CallImplementor implementor = RexImpTable.createImplementor(
             new ReflectiveCallNotNullImplementor(method), NullPolicy.NONE, 
false);
 
-        return new IgniteScalarFunction(method, implementor);
+        return new IgniteScalarFunction(method, implementor, deterministic);
     }
 
     /** {@inheritDoc} */
     @Override public RelDataType getReturnType(RelDataTypeFactory typeFactory) 
{
         return typeFactory.createJavaType(method.getReturnType());
     }
+
+    /**
+     * @return Deterministic flag.
+     */
+    public boolean isDeterministic() {
+        return deterministic;
+    }
 }
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/RexExecutorImpl.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/RexExecutorImpl.java
index 3fe6d8c37b0..eb1297bcc59 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/RexExecutorImpl.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/RexExecutorImpl.java
@@ -19,7 +19,6 @@ package 
org.apache.ignite.internal.processors.query.calcite.exec.exp;
 import java.lang.reflect.Modifier;
 import java.lang.reflect.Type;
 import java.util.List;
-
 import com.google.common.collect.ImmutableList;
 import org.apache.calcite.DataContext;
 import org.apache.calcite.adapter.java.JavaTypeFactory;
@@ -35,14 +34,19 @@ import org.apache.calcite.linq4j.tree.ParameterExpression;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeFactory;
 import org.apache.calcite.rex.RexBuilder;
+import org.apache.calcite.rex.RexCall;
 import org.apache.calcite.rex.RexExecutable;
 import org.apache.calcite.rex.RexExecutor;
 import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.rex.RexProgram;
 import org.apache.calcite.rex.RexProgramBuilder;
+import org.apache.calcite.rex.RexVisitor;
+import org.apache.calcite.rex.RexVisitorImpl;
 import org.apache.calcite.sql.validate.SqlConformance;
 import org.apache.calcite.sql.validate.SqlConformanceEnum;
+import org.apache.calcite.sql.validate.SqlUserDefinedFunction;
 import org.apache.calcite.util.BuiltInMethod;
+import org.apache.calcite.util.ControlFlowException;
 import org.apache.calcite.util.Util;
 import 
org.apache.ignite.internal.processors.query.calcite.type.IgniteCustomType;
 
@@ -133,12 +137,34 @@ public class RexExecutorImpl implements RexExecutor {
      * Do constant reduction using generated code.
      */
     @Override public void reduce(RexBuilder rexBuilder, List<RexNode> 
constExps, List<RexNode> reducedValues) {
+        RexVisitor<Void> nonDeterministicUdfFinder = new 
RexVisitorImpl<Void>(true) {
+            @Override public Void visitCall(RexCall call) {
+                if (call.getOperator() instanceof SqlUserDefinedFunction) {
+                    SqlUserDefinedFunction udfFunc = 
(SqlUserDefinedFunction)call.getOperator();
+
+                    if (udfFunc.getFunction() instanceof IgniteScalarFunction
+                        && 
!((IgniteScalarFunction)udfFunc.getFunction()).isDeterministic())
+                        throw Util.FoundOne.NULL; // Don't reduce 
non-deterministic UDF functions.
+                }
+
+                return super.visitCall(call);
+            }
+        };
+
         for (RexNode node : constExps) {
             // Do not simplify custom types, since we can't convert it to 
literal of this type.
             if (node.getType() instanceof IgniteCustomType) {
                 reducedValues.addAll(constExps);
                 return;
             }
+
+            try {
+                node.accept(nonDeterministicUdfFinder);
+            }
+            catch (ControlFlowException foundNonDeterministic) {
+                reducedValues.addAll(constExps);
+                return;
+            }
         }
         final String code = compile(rexBuilder, constExps,
             (list, index, storageType) -> {
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/PlannerHelper.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/PlannerHelper.java
index 289a7b9b473..1cef9ab4ce6 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/PlannerHelper.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/PlannerHelper.java
@@ -127,10 +127,10 @@ public class PlannerHelper {
 
             rel = planner.extractConjunctionOverDisjunctionCommonPart(rel);
 
-            rel = planner.trimUnusedFields(root.withRel(rel)).rel;
-
             rel = planner.transform(PlannerPhase.HEP_FILTER_PUSH_DOWN, 
rel.getTraitSet(), rel);
 
+            rel = planner.trimUnusedFields(root.withRel(rel)).rel;
+
             // The following pushed down project can erase top-level hints. We 
store them to reassign hints for join nodes.
             // Clear the inherit pathes to consider the hints as not 
propogated ones.
             List<RelHint> topHints = HintUtils.allRelHints(rel).stream().map(h 
-> h.inheritPath.isEmpty()
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/PlannerPhase.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/PlannerPhase.java
index 0ff9ae9510b..b8333a54166 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/PlannerPhase.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/PlannerPhase.java
@@ -108,6 +108,7 @@ public enum PlannerPhase {
         @Override public RuleSet getRules(PlanningContext ctx) {
             return ctx.rules(
                 RuleSets.ofList(
+                    CoreRules.FILTER_REDUCE_EXPRESSIONS,
                     FilterScanMergeRule.TABLE_SCAN_SKIP_CORRELATED,
 
                     CoreRules.FILTER_MERGE,
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/AbstractIndexScan.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/AbstractIndexScan.java
index 40efc54172e..c5041d4c773 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/AbstractIndexScan.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/AbstractIndexScan.java
@@ -27,6 +27,7 @@ import org.apache.calcite.plan.RelTraitSet;
 import org.apache.calcite.rel.RelInput;
 import org.apache.calcite.rel.RelWriter;
 import org.apache.calcite.rel.metadata.RelMetadataQuery;
+import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rex.RexBuilder;
 import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.rex.RexUtil;
@@ -67,12 +68,13 @@ public abstract class AbstractIndexScan extends 
ProjectableFilterableTableScan {
         RelTraitSet traitSet,
         RelOptTable table,
         String idxName,
+        @Nullable RelDataType rowType,
         @Nullable List<RexNode> proj,
         @Nullable RexNode cond,
         @Nullable List<SearchBounds> searchBounds,
         @Nullable ImmutableBitSet reqColumns
     ) {
-        super(cluster, traitSet, Collections.emptyList(), table, proj, cond, 
reqColumns);
+        super(cluster, traitSet, Collections.emptyList(), table, rowType, 
proj, cond, reqColumns);
 
         this.idxName = idxName;
         this.searchBounds = searchBounds;
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteIndexScan.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteIndexScan.java
index 066e1b9d37c..a7397ffcedb 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteIndexScan.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteIndexScan.java
@@ -24,6 +24,7 @@ import org.apache.calcite.plan.RelTraitSet;
 import org.apache.calcite.rel.RelCollation;
 import org.apache.calcite.rel.RelInput;
 import org.apache.calcite.rel.RelWriter;
+import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.util.ImmutableBitSet;
 import 
org.apache.ignite.internal.processors.query.calcite.prepare.bounds.SearchBounds;
@@ -64,6 +65,7 @@ public class IgniteIndexScan extends AbstractIndexScan 
implements SourceAwareIgn
      * @param traits Traits of this relational expression
      * @param tbl Table definition.
      * @param idxName Index name.
+     * @param rowType Row type.
      * @param proj Projects.
      * @param cond Filters.
      * @param requiredCols Participating columns.
@@ -74,13 +76,14 @@ public class IgniteIndexScan extends AbstractIndexScan 
implements SourceAwareIgn
         RelTraitSet traits,
         RelOptTable tbl,
         String idxName,
+        @Nullable RelDataType rowType,
         @Nullable List<RexNode> proj,
         @Nullable RexNode cond,
         @Nullable List<SearchBounds> searchBounds,
         @Nullable ImmutableBitSet requiredCols,
         RelCollation collation
     ) {
-        this(-1L, cluster, traits, tbl, idxName, proj, cond, searchBounds, 
requiredCols, collation);
+        this(-1L, cluster, traits, tbl, idxName, rowType, proj, cond, 
searchBounds, requiredCols, collation);
     }
 
     /**
@@ -89,6 +92,7 @@ public class IgniteIndexScan extends AbstractIndexScan 
implements SourceAwareIgn
      * @param traits Traits of this relational expression
      * @param tbl Table definition.
      * @param idxName Index name.
+     * @param rowType Row type.
      * @param proj Projects.
      * @param cond Filters.
      * @param requiredCols Participating colunms.
@@ -100,13 +104,14 @@ public class IgniteIndexScan extends AbstractIndexScan 
implements SourceAwareIgn
         RelTraitSet traits,
         RelOptTable tbl,
         String idxName,
+        @Nullable RelDataType rowType,
         @Nullable List<RexNode> proj,
         @Nullable RexNode cond,
         @Nullable List<SearchBounds> searchBounds,
         @Nullable ImmutableBitSet requiredCols,
         RelCollation collation
     ) {
-        super(cluster, traits, tbl, idxName, proj, cond, searchBounds, 
requiredCols);
+        super(cluster, traits, tbl, idxName, rowType, proj, cond, 
searchBounds, requiredCols);
 
         this.sourceId = sourceId;
         this.collation = collation;
@@ -132,13 +137,13 @@ public class IgniteIndexScan extends AbstractIndexScan 
implements SourceAwareIgn
     /** {@inheritDoc} */
     @Override public IgniteRel clone(long sourceId) {
         return new IgniteIndexScan(sourceId, getCluster(), getTraitSet(), 
getTable(),
-            idxName, projects, condition, searchBounds, requiredColumns, 
collation);
+            idxName, rowType, projects, condition, searchBounds, 
requiredColumns, collation);
     }
 
     /** {@inheritDoc} */
     @Override public IgniteRel clone(RelOptCluster cluster, List<IgniteRel> 
inputs) {
         return new IgniteIndexScan(sourceId, cluster, getTraitSet(), 
getTable(),
-            idxName, projects, condition, searchBounds, requiredColumns, 
collation);
+            idxName, rowType, projects, condition, searchBounds, 
requiredColumns, collation);
     }
 
     /** {@inheritDoc} */
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteTableScan.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteTableScan.java
index 6291a5433b6..c35b415f197 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteTableScan.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteTableScan.java
@@ -24,6 +24,7 @@ import org.apache.calcite.plan.RelOptTable;
 import org.apache.calcite.plan.RelTraitSet;
 import org.apache.calcite.rel.RelInput;
 import org.apache.calcite.rel.RelWriter;
+import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.util.ImmutableBitSet;
 import org.jetbrains.annotations.Nullable;
@@ -63,7 +64,7 @@ public class IgniteTableScan extends 
ProjectableFilterableTableScan implements S
         RelTraitSet traits,
         RelOptTable tbl
     ) {
-        this(cluster, traits, tbl, null, null, null);
+        this(cluster, traits, tbl, null, null, null, null);
     }
 
     /**
@@ -71,6 +72,7 @@ public class IgniteTableScan extends 
ProjectableFilterableTableScan implements S
      * @param cluster Cluster that this relational expression belongs to
      * @param traits Traits of this relational expression
      * @param tbl Table definition.
+     * @param rowType Row type.
      * @param proj Projects.
      * @param cond Filters.
      * @param requiredColunms Participating colunms.
@@ -79,11 +81,12 @@ public class IgniteTableScan extends 
ProjectableFilterableTableScan implements S
         RelOptCluster cluster,
         RelTraitSet traits,
         RelOptTable tbl,
+        @Nullable RelDataType rowType,
         @Nullable List<RexNode> proj,
         @Nullable RexNode cond,
         @Nullable ImmutableBitSet requiredColunms
     ) {
-        this(-1L, cluster, traits, tbl, proj, cond, requiredColunms);
+        this(-1L, cluster, traits, tbl, rowType, proj, cond, requiredColunms);
     }
 
     /**
@@ -91,6 +94,7 @@ public class IgniteTableScan extends 
ProjectableFilterableTableScan implements S
      * @param cluster Cluster that this relational expression belongs to
      * @param traits Traits of this relational expression
      * @param tbl Table definition.
+     * @param rowType Row type.
      * @param proj Projects.
      * @param cond Filters.
      * @param requiredColunms Participating colunms.
@@ -100,11 +104,12 @@ public class IgniteTableScan extends 
ProjectableFilterableTableScan implements S
         RelOptCluster cluster,
         RelTraitSet traits,
         RelOptTable tbl,
+        @Nullable RelDataType rowType,
         @Nullable List<RexNode> proj,
         @Nullable RexNode cond,
         @Nullable ImmutableBitSet requiredColunms
     ) {
-        super(cluster, traits, ImmutableList.of(), tbl, proj, cond, 
requiredColunms);
+        super(cluster, traits, ImmutableList.of(), tbl, rowType, proj, cond, 
requiredColunms);
         this.sourceId = sourceId;
     }
 
@@ -126,11 +131,13 @@ public class IgniteTableScan extends 
ProjectableFilterableTableScan implements S
 
     /** {@inheritDoc} */
     @Override public IgniteRel clone(long sourceId) {
-        return new IgniteTableScan(sourceId, getCluster(), getTraitSet(), 
getTable(), projects, condition, requiredColumns);
+        return new IgniteTableScan(sourceId, getCluster(), getTraitSet(), 
getTable(), rowType, projects, condition,
+            requiredColumns);
     }
 
     /** {@inheritDoc} */
     @Override public IgniteRel clone(RelOptCluster cluster, List<IgniteRel> 
inputs) {
-        return new IgniteTableScan(sourceId, cluster, getTraitSet(), 
getTable(), projects, condition, requiredColumns);
+        return new IgniteTableScan(sourceId, cluster, getTraitSet(), 
getTable(), rowType, projects, condition,
+            requiredColumns);
     }
 }
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/ProjectableFilterableTableScan.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/ProjectableFilterableTableScan.java
index 9c41fdd9e3d..bef05a9b5e3 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/ProjectableFilterableTableScan.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/ProjectableFilterableTableScan.java
@@ -75,12 +75,16 @@ public abstract class ProjectableFilterableTableScan 
extends TableScan {
         RelTraitSet traitSet,
         List<RelHint> hints,
         RelOptTable table,
+        @Nullable RelDataType rowType,
         @Nullable List<RexNode> proj,
         @Nullable RexNode cond,
         @Nullable ImmutableBitSet reqColumns
     ) {
         super(cluster, traitSet, hints, table);
 
+        assert proj == null || rowType != null : "rowType should be provided 
if project != null";
+
+        this.rowType = rowType;
         projects = proj;
         condition = cond;
         requiredColumns = reqColumns;
@@ -90,6 +94,7 @@ public abstract class ProjectableFilterableTableScan extends 
TableScan {
     protected ProjectableFilterableTableScan(RelInput input) {
         super(input);
         condition = input.getExpression("filters");
+        rowType = input.get("rowType") == null ? null : 
input.getRowType("rowType");
         projects = input.get("projects") == null ? null : 
input.getExpressionList("projects");
         requiredColumns = input.get("requiredColumns") == null ? null : 
input.getBitSet("requiredColumns");
     }
@@ -129,6 +134,7 @@ public abstract class ProjectableFilterableTableScan 
extends TableScan {
         }
 
         return pw
+            .itemIf("rowType", rowType, projects != null) // Intentional 
project check here.
             .itemIf("projects", projects, projects != null)
             .itemIf("requiredColumns", requiredColumns, requiredColumns != 
null);
     }
@@ -151,10 +157,9 @@ public abstract class ProjectableFilterableTableScan 
extends TableScan {
 
     /** {@inheritDoc} */
     @Override public RelDataType deriveRowType() {
-        if (projects != null)
-            return RexUtil.createStructType(Commons.typeFactory(getCluster()), 
projects);
-        else
-            return 
table.unwrap(IgniteTable.class).getRowType(Commons.typeFactory(getCluster()), 
requiredColumns);
+        assert projects == null : "For merged projects rowType should be 
provided explicetely";
+
+        return 
table.unwrap(IgniteTable.class).getRowType(Commons.typeFactory(getCluster()), 
requiredColumns);
     }
 
     /** */
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/logical/IgniteLogicalIndexScan.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/logical/IgniteLogicalIndexScan.java
index 2602c21ded6..c0cfa088e6f 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/logical/IgniteLogicalIndexScan.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/logical/IgniteLogicalIndexScan.java
@@ -21,6 +21,7 @@ import java.util.List;
 import org.apache.calcite.plan.RelOptCluster;
 import org.apache.calcite.plan.RelOptTable;
 import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.util.ImmutableBitSet;
 import 
org.apache.ignite.internal.processors.query.calcite.prepare.bounds.SearchBounds;
@@ -37,6 +38,7 @@ public class IgniteLogicalIndexScan extends AbstractIndexScan 
{
         RelTraitSet traits,
         RelOptTable table,
         String idxName,
+        @Nullable RelDataType rowType,
         @Nullable List<RexNode> proj,
         @Nullable RexNode cond,
         @Nullable ImmutableBitSet requiredColumns
@@ -51,6 +53,7 @@ public class IgniteLogicalIndexScan extends AbstractIndexScan 
{
             traits,
             table,
             idxName,
+            rowType,
             proj,
             cond,
             searchBounds,
@@ -63,6 +66,7 @@ public class IgniteLogicalIndexScan extends AbstractIndexScan 
{
      * @param traits Traits of this relational expression
      * @param tbl Table definition.
      * @param idxName Index name.
+     * @param rowType Row type.
      * @param proj Projects.
      * @param cond Filters.
      * @param searchBounds Index search bounds.
@@ -73,11 +77,12 @@ public class IgniteLogicalIndexScan extends 
AbstractIndexScan {
         RelTraitSet traits,
         RelOptTable tbl,
         String idxName,
+        @Nullable RelDataType rowType,
         @Nullable List<RexNode> proj,
         @Nullable RexNode cond,
         @Nullable List<SearchBounds> searchBounds,
         @Nullable ImmutableBitSet requiredCols
     ) {
-        super(cluster, traits, tbl, idxName, proj, cond, searchBounds, 
requiredCols);
+        super(cluster, traits, tbl, idxName, rowType, proj, cond, 
searchBounds, requiredCols);
     }
 }
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/logical/IgniteLogicalTableScan.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/logical/IgniteLogicalTableScan.java
index caa08a90aef..1cbd7544bf5 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/logical/IgniteLogicalTableScan.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/logical/IgniteLogicalTableScan.java
@@ -24,6 +24,7 @@ import org.apache.calcite.plan.RelOptCluster;
 import org.apache.calcite.plan.RelOptTable;
 import org.apache.calcite.plan.RelTraitSet;
 import org.apache.calcite.rel.hint.RelHint;
+import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.util.ImmutableBitSet;
 import 
org.apache.ignite.internal.processors.query.calcite.rel.ProjectableFilterableTableScan;
@@ -37,12 +38,13 @@ public class IgniteLogicalTableScan extends 
ProjectableFilterableTableScan {
         RelTraitSet traits,
         RelOptTable tbl,
         @Nullable List<RelHint> hints,
+        @Nullable RelDataType rowType,
         @Nullable List<RexNode> proj,
         @Nullable RexNode cond,
         @Nullable ImmutableBitSet requiredColumns
     ) {
-        return new IgniteLogicalTableScan(cluster, traits, tbl, hints == null 
? ImmutableList.of() : hints, proj, cond,
-            requiredColumns);
+        return new IgniteLogicalTableScan(cluster, traits, tbl, hints == null 
? ImmutableList.of() : hints,
+            rowType, proj, cond, requiredColumns);
     }
 
     /**
@@ -51,6 +53,7 @@ public class IgniteLogicalTableScan extends 
ProjectableFilterableTableScan {
      * @param traits Traits of this relational expression.
      * @param tbl Table definition.
      * @param hints Hints.
+     * @param rowType Row type.
      * @param proj Projects.
      * @param cond Filters.
      * @param requiredColunms Participating colunms.
@@ -60,16 +63,17 @@ public class IgniteLogicalTableScan extends 
ProjectableFilterableTableScan {
         RelTraitSet traits,
         RelOptTable tbl,
         List<RelHint> hints,
+        @Nullable RelDataType rowType,
         @Nullable List<RexNode> proj,
         @Nullable RexNode cond,
         @Nullable ImmutableBitSet requiredColunms
     ) {
-        super(cluster, traits, hints, tbl, proj, cond, requiredColunms);
+        super(cluster, traits, hints, tbl, rowType, proj, cond, 
requiredColunms);
     }
 
     /** {@inheritDoc} */
     @Override public IgniteLogicalTableScan withHints(List<RelHint> hints) {
-        return new IgniteLogicalTableScan(getCluster(), getTraitSet(), 
getTable(), hints, projects(), condition(),
-            requiredColumns());
+        return new IgniteLogicalTableScan(getCluster(), getTraitSet(), 
getTable(), hints,
+            rowType, projects(), condition(), requiredColumns());
     }
 }
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/LogicalScanConverterRule.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/LogicalScanConverterRule.java
index 3d3f98c9186..3496ff37ed9 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/LogicalScanConverterRule.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/LogicalScanConverterRule.java
@@ -111,6 +111,7 @@ public abstract class LogicalScanConverterRule<T extends 
ProjectableFilterableTa
                     traits,
                     rel.getTable(),
                     rel.indexName(),
+                    rel.getRowType(),
                     rel.projects(),
                     rel.condition(),
                     rel.searchBounds(),
@@ -163,8 +164,8 @@ public abstract class LogicalScanConverterRule<T extends 
ProjectableFilterableTa
                 if (!corrIds.isEmpty())
                     traits = 
traits.replace(CorrelationTrait.correlations(corrIds));
 
-                return new IgniteTableScan(rel.getCluster(), traits,
-                    rel.getTable(), rel.projects(), rel.condition(), 
rel.requiredColumns());
+                return new IgniteTableScan(rel.getCluster(), traits, 
rel.getTable(),
+                    rel.getRowType(), rel.projects(), rel.condition(), 
rel.requiredColumns());
             }
         };
 
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/logical/ExposeIndexRule.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/logical/ExposeIndexRule.java
index 8c3f48bbe5e..4b9144db13a 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/logical/ExposeIndexRule.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/logical/ExposeIndexRule.java
@@ -32,6 +32,7 @@ import org.apache.calcite.plan.RelRule;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rel.core.TableScan;
 import org.apache.calcite.rel.hint.RelHint;
+import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.util.ImmutableBitSet;
 import org.apache.ignite.internal.processors.query.calcite.hint.HintDefinition;
@@ -75,6 +76,7 @@ public class ExposeIndexRule extends 
RelRule<ExposeIndexRule.Config> {
 
         RelOptTable optTable = scan.getTable();
         IgniteTable igniteTable = optTable.unwrap(IgniteTable.class);
+        RelDataType rowType = scan.getRowType();
         List<RexNode> proj = scan.projects();
         RexNode condition = scan.condition();
         ImmutableBitSet requiredCols = scan.requiredColumns();
@@ -83,7 +85,7 @@ public class ExposeIndexRule extends 
RelRule<ExposeIndexRule.Config> {
             return;
 
         List<IgniteLogicalIndexScan> indexes = 
igniteTable.indexes().values().stream()
-            .map(idx -> idx.toRel(cluster, optTable, proj, condition, 
requiredCols))
+            .map(idx -> idx.toRel(cluster, optTable, rowType, proj, condition, 
requiredCols))
             .collect(Collectors.toList());
 
         assert !indexes.isEmpty();
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/logical/FilterScanMergeRule.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/logical/FilterScanMergeRule.java
index f1c2ca78d3e..1b886792e5d 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/logical/FilterScanMergeRule.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/logical/FilterScanMergeRule.java
@@ -158,7 +158,7 @@ public abstract class FilterScanMergeRule<T extends 
ProjectableFilterableTableSc
                 return null;
             }
 
-            return IgniteLogicalIndexScan.create(cluster, traits, 
scan.getTable(), scan.indexName(),
+            return IgniteLogicalIndexScan.create(cluster, traits, 
scan.getTable(), scan.indexName(), scan.getRowType(),
                 scan.projects(), cond, scan.requiredColumns());
         }
     }
@@ -177,8 +177,8 @@ public abstract class FilterScanMergeRule<T extends 
ProjectableFilterableTableSc
             RelTraitSet traits,
             RexNode cond
         ) {
-            return IgniteLogicalTableScan.create(cluster, traits, 
scan.getTable(), scan.getHints(), scan.projects(),
-                cond, scan.requiredColumns());
+            return IgniteLogicalTableScan.create(cluster, traits, 
scan.getTable(), scan.getHints(), scan.getRowType(),
+                scan.projects(), cond, scan.requiredColumns());
         }
     }
 
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/logical/LogicalOrToUnionRule.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/logical/LogicalOrToUnionRule.java
index 78315018970..73901351c96 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/logical/LogicalOrToUnionRule.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/logical/LogicalOrToUnionRule.java
@@ -165,6 +165,7 @@ public class LogicalOrToUnionRule extends 
RelRule<LogicalOrToUnionRule.Config> {
             trait,
             scan.getTable(),
             scan.getHints(),
+            scan.getRowType(),
             scan.projects(),
             condition,
             scan.requiredColumns()
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/logical/ProjectScanMergeRule.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/logical/ProjectScanMergeRule.java
index 739e17f868a..5a1ecc83217 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/logical/ProjectScanMergeRule.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/logical/ProjectScanMergeRule.java
@@ -24,6 +24,7 @@ import org.apache.calcite.plan.RelOptRuleCall;
 import org.apache.calcite.plan.RelRule;
 import org.apache.calcite.plan.RelTraitSet;
 import org.apache.calcite.rel.logical.LogicalProject;
+import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rex.RexInputRef;
 import org.apache.calcite.rex.RexLocalRef;
 import org.apache.calcite.rex.RexNode;
@@ -58,6 +59,7 @@ public abstract class ProjectScanMergeRule<T extends 
ProjectableFilterableTableS
         RelOptCluster cluster,
         T scan,
         RelTraitSet traits,
+        RelDataType rowType,
         List<RexNode> projections,
         RexNode cond,
         ImmutableBitSet requiredColumns
@@ -140,7 +142,7 @@ public abstract class ProjectScanMergeRule<T extends 
ProjectableFilterableTableS
         if (RexUtils.isIdentity(projects, tbl.getRowType(typeFactory, 
requiredColumns), true))
             projects = null;
 
-        T res = createNode(cluster, scan, traits, projects, cond, 
requiredColumns);
+        T res = createNode(cluster, scan, traits, relProject.getRowType(), 
projects, cond, requiredColumns);
 
         if (res == null)
             return;
@@ -167,6 +169,7 @@ public abstract class ProjectScanMergeRule<T extends 
ProjectableFilterableTableS
             RelOptCluster cluster,
             IgniteLogicalTableScan scan,
             RelTraitSet traits,
+            RelDataType rowType,
             List<RexNode> projections,
             RexNode cond,
             ImmutableBitSet requiredColumns
@@ -176,6 +179,7 @@ public abstract class ProjectScanMergeRule<T extends 
ProjectableFilterableTableS
                 traits,
                 scan.getTable(),
                 scan.getHints(),
+                rowType,
                 projections,
                 cond,
                 requiredColumns
@@ -199,6 +203,7 @@ public abstract class ProjectScanMergeRule<T extends 
ProjectableFilterableTableS
             RelOptCluster cluster,
             IgniteLogicalIndexScan scan,
             RelTraitSet traits,
+            RelDataType rowType,
             List<RexNode> projections,
             RexNode cond,
             ImmutableBitSet requiredColumns
@@ -214,6 +219,7 @@ public abstract class ProjectScanMergeRule<T extends 
ProjectableFilterableTableS
                 traits,
                 scan.getTable(),
                 scan.indexName(),
+                rowType,
                 projections,
                 cond, requiredColumns
             );
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/CacheIndexImpl.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/CacheIndexImpl.java
index c09544f96fa..3806436eb87 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/CacheIndexImpl.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/CacheIndexImpl.java
@@ -21,7 +21,6 @@ import java.util.Collections;
 import java.util.List;
 import java.util.UUID;
 import org.apache.calcite.plan.RelOptCluster;
-import org.apache.calcite.plan.RelOptTable;
 import org.apache.calcite.rel.RelCollation;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rex.RexNode;
@@ -42,7 +41,6 @@ import 
org.apache.ignite.internal.processors.query.calcite.exec.IndexScan;
 import 
org.apache.ignite.internal.processors.query.calcite.exec.exp.RangeIterable;
 import 
org.apache.ignite.internal.processors.query.calcite.metadata.ColocationGroup;
 import 
org.apache.ignite.internal.processors.query.calcite.prepare.bounds.SearchBounds;
-import 
org.apache.ignite.internal.processors.query.calcite.rel.logical.IgniteLogicalIndexScan;
 import org.apache.ignite.internal.processors.query.calcite.util.Commons;
 import org.apache.ignite.internal.processors.query.calcite.util.RexUtils;
 import org.jetbrains.annotations.Nullable;
@@ -91,17 +89,6 @@ public class CacheIndexImpl implements IgniteIndex {
         return idx;
     }
 
-    /** {@inheritDoc} */
-    @Override public IgniteLogicalIndexScan toRel(
-        RelOptCluster cluster,
-        RelOptTable relOptTbl,
-        @Nullable List<RexNode> proj,
-        @Nullable RexNode cond,
-        @Nullable ImmutableBitSet requiredColumns
-    ) {
-        return IgniteLogicalIndexScan.create(cluster, cluster.traitSet(), 
relOptTbl, idxName, proj, cond, requiredColumns);
-    }
-
     /** */
     @Override public <Row> Iterable<Row> scan(
         ExecutionContext<Row> execCtx,
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/CacheTableImpl.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/CacheTableImpl.java
index bc74437c3d4..2f06b666660 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/CacheTableImpl.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/CacheTableImpl.java
@@ -18,16 +18,11 @@
 package org.apache.ignite.internal.processors.query.calcite.schema;
 
 import java.util.Collections;
-import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 import java.util.concurrent.ConcurrentHashMap;
-import org.apache.calcite.plan.RelOptCluster;
-import org.apache.calcite.plan.RelOptTable;
-import org.apache.calcite.rel.hint.RelHint;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeFactory;
-import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.schema.Statistic;
 import org.apache.calcite.schema.impl.AbstractTable;
 import org.apache.calcite.util.ImmutableBitSet;
@@ -37,7 +32,6 @@ import 
org.apache.ignite.internal.processors.query.calcite.exec.ExecutionContext
 import org.apache.ignite.internal.processors.query.calcite.exec.TableScan;
 import 
org.apache.ignite.internal.processors.query.calcite.metadata.ColocationGroup;
 import 
org.apache.ignite.internal.processors.query.calcite.prepare.MappingQueryContext;
-import 
org.apache.ignite.internal.processors.query.calcite.rel.logical.IgniteLogicalTableScan;
 import 
org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistribution;
 import 
org.apache.ignite.internal.processors.query.calcite.type.IgniteTypeFactory;
 import org.apache.ignite.internal.processors.query.stat.ObjectStatisticsImpl;
@@ -95,18 +89,6 @@ public class CacheTableImpl extends AbstractTable implements 
IgniteCacheTable {
         return desc;
     }
 
-    /** {@inheritDoc} */
-    @Override public IgniteLogicalTableScan toRel(
-        RelOptCluster cluster,
-        RelOptTable relOptTbl,
-        @Nullable List<RexNode> proj,
-        @Nullable RexNode cond,
-        @Nullable ImmutableBitSet requiredColumns,
-        @Nullable List<RelHint> hints
-    ) {
-        return IgniteLogicalTableScan.create(cluster, cluster.traitSet(), 
relOptTbl, hints, proj, cond, requiredColumns);
-    }
-
     /** {@inheritDoc} */
     @Override public <Row> Iterable<Row> scan(
         ExecutionContext<Row> execCtx,
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/IgniteIndex.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/IgniteIndex.java
index 903d4eddf5d..07d48624acb 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/IgniteIndex.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/IgniteIndex.java
@@ -20,6 +20,7 @@ import java.util.List;
 import org.apache.calcite.plan.RelOptCluster;
 import org.apache.calcite.plan.RelOptTable;
 import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.util.ImmutableBitSet;
 import 
org.apache.ignite.internal.processors.query.calcite.exec.ExecutionContext;
@@ -47,18 +48,23 @@ public interface IgniteIndex {
      *
      * @param cluster         Custer.
      * @param relOptTbl       Table.
+     * @param rowType         Row type.
      * @param proj            List of required projections.
      * @param cond            Conditions to filter rows.
      * @param requiredColumns Set of columns to extract from original row.
      * @return Table relational expression.
      */
-    public IgniteLogicalIndexScan toRel(
+    public default IgniteLogicalIndexScan toRel(
         RelOptCluster cluster,
         RelOptTable relOptTbl,
+        RelDataType rowType,
         @Nullable List<RexNode> proj,
         @Nullable RexNode cond,
         @Nullable ImmutableBitSet requiredColumns
-    );
+    ) {
+        return IgniteLogicalIndexScan.create(cluster, cluster.traitSet(), 
relOptTbl, name(),
+            rowType, proj, cond, requiredColumns);
+    }
 
     /**
      * Converts condition to index find predicate.
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/IgniteTable.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/IgniteTable.java
index df52e419997..e88bcaf2204 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/IgniteTable.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/IgniteTable.java
@@ -16,15 +16,11 @@
  */
 package org.apache.ignite.internal.processors.query.calcite.schema;
 
-import java.util.List;
 import java.util.Map;
-import org.apache.calcite.plan.RelOptCluster;
 import org.apache.calcite.plan.RelOptTable;
 import org.apache.calcite.rel.core.TableScan;
-import org.apache.calcite.rel.hint.RelHint;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeFactory;
-import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.schema.TranslatableTable;
 import org.apache.calcite.util.ImmutableBitSet;
 import 
org.apache.ignite.internal.processors.query.calcite.exec.ExecutionContext;
@@ -58,29 +54,10 @@ public interface IgniteTable extends TranslatableTable {
 
     /** {@inheritDoc} */
     @Override default TableScan toRel(RelOptTable.ToRelContext ctx, 
RelOptTable relOptTable) {
-        return toRel(ctx.getCluster(), relOptTable, null, null, null, 
ctx.getTableHints());
+        return IgniteLogicalTableScan.create(ctx.getCluster(), 
ctx.getCluster().traitSet(), relOptTable,
+            ctx.getTableHints(), null, null, null, null);
     }
 
-    /**
-     * Converts table into relational expression.
-     *
-     * @param cluster Custer.
-     * @param relOptTbl Table.
-     * @param proj List of required projections.
-     * @param cond Conditions to filter rows.
-     * @param requiredColumns Set of columns to extract from original row.
-     * @param hints Table hints.
-     * @return Table relational expression.
-     */
-    IgniteLogicalTableScan toRel(
-        RelOptCluster cluster,
-        RelOptTable relOptTbl,
-        @Nullable List<RexNode> proj,
-        @Nullable RexNode cond,
-        @Nullable ImmutableBitSet requiredColumns,
-        @Nullable List<RelHint> hints
-    );
-
     /**
      * Creates rows iterator over the table.
      *
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/SchemaHolderImpl.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/SchemaHolderImpl.java
index d5c2f4746cc..b9eae82520f 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/SchemaHolderImpl.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/SchemaHolderImpl.java
@@ -365,7 +365,9 @@ public class SchemaHolderImpl extends AbstractService 
implements SchemaHolder, S
 
         IgniteSchema schema = igniteSchemas.computeIfAbsent(schemaName, 
IgniteSchema::new);
 
-        schema.addFunction(name.toUpperCase(), 
IgniteScalarFunction.create(method));
+        // Can't change deterministic flag on SqlUserDefinedFunction, at least 
store this flag in wrapped function
+        // to process it in Ignite-controlled code.
+        schema.addFunction(name.toUpperCase(), 
IgniteScalarFunction.create(method, deterministic));
 
         rebuild();
     }
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/SystemViewIndexImpl.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/SystemViewIndexImpl.java
index 1a8abd64aea..b26aac325b3 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/SystemViewIndexImpl.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/SystemViewIndexImpl.java
@@ -19,7 +19,6 @@ package 
org.apache.ignite.internal.processors.query.calcite.schema;
 import java.util.Collections;
 import java.util.List;
 import org.apache.calcite.plan.RelOptCluster;
-import org.apache.calcite.plan.RelOptTable;
 import org.apache.calcite.rel.RelCollation;
 import org.apache.calcite.rel.RelCollations;
 import org.apache.calcite.rel.type.RelDataType;
@@ -31,7 +30,6 @@ import 
org.apache.ignite.internal.processors.query.calcite.exec.SystemViewScan;
 import 
org.apache.ignite.internal.processors.query.calcite.exec.exp.RangeIterable;
 import 
org.apache.ignite.internal.processors.query.calcite.metadata.ColocationGroup;
 import 
org.apache.ignite.internal.processors.query.calcite.prepare.bounds.SearchBounds;
-import 
org.apache.ignite.internal.processors.query.calcite.rel.logical.IgniteLogicalIndexScan;
 import org.apache.ignite.internal.processors.query.calcite.util.RexUtils;
 import org.jetbrains.annotations.Nullable;
 
@@ -66,18 +64,6 @@ public class SystemViewIndexImpl implements IgniteIndex {
         return tbl;
     }
 
-    /** {@inheritDoc} */
-    @Override public IgniteLogicalIndexScan toRel(
-        RelOptCluster cluster,
-        RelOptTable relOptTbl,
-        @Nullable List<RexNode> proj,
-        @Nullable RexNode cond,
-        @Nullable ImmutableBitSet requiredColumns
-    ) {
-        return IgniteLogicalIndexScan.create(cluster, cluster.traitSet(), 
relOptTbl, idxName, proj, cond,
-            requiredColumns);
-    }
-
     /** */
     @Override public <Row> Iterable<Row> scan(
         ExecutionContext<Row> execCtx,
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/SystemViewTableImpl.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/SystemViewTableImpl.java
index 4333a9832ad..92ed57c41eb 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/SystemViewTableImpl.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/SystemViewTableImpl.java
@@ -21,13 +21,9 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import com.google.common.collect.ImmutableList;
-import org.apache.calcite.plan.RelOptCluster;
-import org.apache.calcite.plan.RelOptTable;
 import org.apache.calcite.rel.RelCollation;
-import org.apache.calcite.rel.hint.RelHint;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeFactory;
-import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.schema.Statistic;
 import org.apache.calcite.schema.impl.AbstractTable;
 import org.apache.calcite.util.ImmutableBitSet;
@@ -35,7 +31,6 @@ import 
org.apache.ignite.internal.processors.query.calcite.exec.ExecutionContext
 import org.apache.ignite.internal.processors.query.calcite.exec.SystemViewScan;
 import 
org.apache.ignite.internal.processors.query.calcite.metadata.ColocationGroup;
 import 
org.apache.ignite.internal.processors.query.calcite.prepare.MappingQueryContext;
-import 
org.apache.ignite.internal.processors.query.calcite.rel.logical.IgniteLogicalTableScan;
 import 
org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistribution;
 import 
org.apache.ignite.internal.processors.query.calcite.type.IgniteTypeFactory;
 import org.jetbrains.annotations.Nullable;
@@ -87,18 +82,6 @@ public class SystemViewTableImpl extends AbstractTable 
implements IgniteTable {
         return desc;
     }
 
-    /** {@inheritDoc} */
-    @Override public IgniteLogicalTableScan toRel(
-        RelOptCluster cluster,
-        RelOptTable relOptTbl,
-        @Nullable List<RexNode> proj,
-        @Nullable RexNode cond,
-        @Nullable ImmutableBitSet requiredColumns,
-        @Nullable List<RelHint> hints
-    ) {
-        return IgniteLogicalTableScan.create(cluster, cluster.traitSet(), 
relOptTbl, hints, proj, cond, requiredColumns);
-    }
-
     /** {@inheritDoc} */
     @Override public <Row> Iterable<Row> scan(
         ExecutionContext<Row> execCtx,
diff --git 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/LogicalRelImplementorTest.java
 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/LogicalRelImplementorTest.java
index 6e4419be92c..06a00e8622f 100644
--- 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/LogicalRelImplementorTest.java
+++ 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/LogicalRelImplementorTest.java
@@ -250,6 +250,12 @@ public class LogicalRelImplementorTest extends 
GridCommonAbstractTest {
         RelDataType sqlTypeInt = rowType.getFieldList().get(2).getType();
         RelDataType sqlTypeVarchar = rowType.getFieldList().get(3).getType();
 
+        RelDataType projRowType = new RelDataTypeFactory.Builder(tf)
+            .add("A", sqlTypeVarchar)
+            .add("B", sqlTypeInt)
+            .add("C", sqlTypeInt)
+            .build();
+
         // Projects, filters and required columns.
         List<RexNode> project = F.asList(
             rexBuilder.makeLocalRef(sqlTypeVarchar, 1),
@@ -308,6 +314,7 @@ public class LogicalRelImplementorTest extends 
GridCommonAbstractTest {
             cluster.traitSet(),
             qctx.catalogReader().getTable(F.asList("PUBLIC", "TBL")),
             "IDX",
+            projRowType,
             project,
             filter,
             RexUtils.buildSortedSearchBounds(cluster, idxCollation, filter, 
rowType, requiredColumns),
@@ -390,6 +397,10 @@ public class LogicalRelImplementorTest extends 
GridCommonAbstractTest {
         RelDataType sqlTypeInt = rowType.getFieldList().get(2).getType();
         RelDataType sqlTypeVarchar = rowType.getFieldList().get(3).getType();
 
+        RelDataType projRowType = new RelDataTypeFactory.Builder(tf)
+            .add("A", sqlTypeVarchar)
+            .build();
+
         List<RexNode> project = 
F.asList(rexBuilder.makeLocalRef(sqlTypeVarchar, 1));
 
         RexNode filterOneField = rexBuilder.makeCall(
@@ -411,6 +422,7 @@ public class LogicalRelImplementorTest extends 
GridCommonAbstractTest {
             cluster.traitSet(),
             qctx.catalogReader().getTable(F.asList("PUBLIC", "TBL")),
             QueryUtils.PRIMARY_KEY_INDEX,
+            projRowType,
             project,
             filterOneField,
             RexUtils.buildSortedSearchBounds(cluster, idxCollation, 
filterOneField, rowType, requiredColumns),
@@ -440,6 +452,7 @@ public class LogicalRelImplementorTest extends 
GridCommonAbstractTest {
             templateScan.getTraitSet().replace(collation),
             templateScan.getTable(),
             templateScan.indexName(),
+            templateScan.getRowType(),
             projects,
             filters,
             templateScan.searchBounds(),
diff --git 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/AbstractBasicIntegrationTest.java
 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/AbstractBasicIntegrationTest.java
index 3e453410060..0cac27a032b 100644
--- 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/AbstractBasicIntegrationTest.java
+++ 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/AbstractBasicIntegrationTest.java
@@ -20,7 +20,6 @@ package 
org.apache.ignite.internal.processors.query.calcite.integration;
 import java.util.Collections;
 import java.util.List;
 import org.apache.calcite.plan.RelOptCluster;
-import org.apache.calcite.plan.RelOptTable;
 import org.apache.calcite.rel.RelCollation;
 import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.util.ImmutableBitSet;
@@ -42,7 +41,6 @@ import 
org.apache.ignite.internal.processors.query.calcite.exec.ExecutionService
 import 
org.apache.ignite.internal.processors.query.calcite.exec.exp.RangeIterable;
 import 
org.apache.ignite.internal.processors.query.calcite.metadata.ColocationGroup;
 import 
org.apache.ignite.internal.processors.query.calcite.prepare.bounds.SearchBounds;
-import 
org.apache.ignite.internal.processors.query.calcite.rel.logical.IgniteLogicalIndexScan;
 import org.apache.ignite.internal.processors.query.calcite.schema.IgniteIndex;
 import org.apache.ignite.internal.processors.query.calcite.schema.IgniteTable;
 import org.apache.ignite.internal.processors.query.calcite.util.Commons;
@@ -308,17 +306,6 @@ public class AbstractBasicIntegrationTest extends 
GridCommonAbstractTest {
             return delegate.table();
         }
 
-        /** {@inheritDoc} */
-        @Override public IgniteLogicalIndexScan toRel(
-            RelOptCluster cluster,
-            RelOptTable relOptTbl,
-            @Nullable List<RexNode> proj,
-            @Nullable RexNode cond,
-            @Nullable ImmutableBitSet requiredColumns
-        ) {
-            return delegate.toRel(cluster, relOptTbl, proj, cond, 
requiredColumns);
-        }
-
         /** {@inheritDoc} */
         @Override public List<SearchBounds> toSearchBounds(
             RelOptCluster cluster,
diff --git 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/HashSpoolIntegrationTest.java
 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/HashSpoolIntegrationTest.java
index 605e1175687..f0313935fa0 100644
--- 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/HashSpoolIntegrationTest.java
+++ 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/HashSpoolIntegrationTest.java
@@ -68,15 +68,17 @@ public class HashSpoolIntegrationTest extends 
AbstractBasicIntegrationTransactio
     @Test
     public void testHashSpoolCondition() {
         executeSql("CREATE TABLE t(i INTEGER) WITH " + atomicity());
-        executeSql("INSERT INTO t VALUES (0), (1), (2)");
+        executeSql("INSERT INTO t VALUES (0), (1), (2), (3), (4)");
 
-        String sql = "SELECT i, (SELECT i FROM t WHERE i=t1.i AND i-1=0) FROM 
t AS t1";
+        String sql = "SELECT i, (SELECT i FROM t WHERE i=t1.i AND i-1>0) FROM 
t AS t1";
 
         assertQuery(sql)
             .matches(QueryChecker.containsSubPlan("IgniteHashIndexSpool"))
             .returns(0, null)
-            .returns(1, 1)
-            .returns(2, null)
+            .returns(1, null)
+            .returns(2, 2)
+            .returns(3, 3)
+            .returns(4, 4)
             .check();
     }
 
diff --git 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/tpch/TpchScale100Test.java
 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/tpch/TpchScale100Test.java
index 8578fb66c06..d16e37ffb13 100644
--- 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/tpch/TpchScale100Test.java
+++ 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/tpch/TpchScale100Test.java
@@ -17,24 +17,8 @@
 
 package org.apache.ignite.internal.processors.query.calcite.integration.tpch;
 
-import java.util.Collection;
-import java.util.LinkedHashSet;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
 /** */
-@RunWith(Parameterized.class)
 public class TpchScale100Test extends AbstractTpchTest {
-    /** TODO Revise after https://issues.apache.org/jira/browse/IGNITE-25129 */
-    @Parameterized.Parameters(name = "queryId={0}")
-    public static Collection<Integer> params() {
-        Collection<Integer> res = new LinkedHashSet<>(USED_TESTS);
-
-        res.remove(16);
-
-        return res;
-    }
-
     /** {@inheritDoc} */
     @Override protected double scale() {
         return 1.0;
diff --git 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/ProjectFilterScanMergePlannerTest.java
 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/ProjectFilterScanMergePlannerTest.java
index 0c64365efb8..95b0b3c2700 100644
--- 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/ProjectFilterScanMergePlannerTest.java
+++ 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/ProjectFilterScanMergePlannerTest.java
@@ -20,10 +20,7 @@ package 
org.apache.ignite.internal.processors.query.calcite.planner;
 import java.util.List;
 import java.util.Objects;
 import java.util.stream.Collectors;
-import org.apache.calcite.rel.type.RelDataType;
-import org.apache.calcite.rel.type.RelDataTypeFactory;
 import org.apache.calcite.rex.RexNode;
-import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.calcite.util.ImmutableBitSet;
 import 
org.apache.ignite.internal.processors.query.calcite.prepare.bounds.SearchBounds;
 import org.apache.ignite.internal.processors.query.calcite.rel.IgniteAggregate;
@@ -31,11 +28,11 @@ import 
org.apache.ignite.internal.processors.query.calcite.rel.IgniteIndexScan;
 import org.apache.ignite.internal.processors.query.calcite.rel.IgniteTableScan;
 import org.apache.ignite.internal.processors.query.calcite.schema.IgniteSchema;
 import 
org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistributions;
-import 
org.apache.ignite.internal.processors.query.calcite.type.IgniteTypeFactory;
-import 
org.apache.ignite.internal.processors.query.calcite.type.IgniteTypeSystem;
 import org.junit.Before;
 import org.junit.Test;
 
+import static org.apache.calcite.sql.type.SqlTypeName.INTEGER;
+
 /**
  * Tests ProjectScanMergeRule and FilterScanMergeRule.
  */
@@ -48,17 +45,9 @@ public class ProjectFilterScanMergePlannerTest extends 
AbstractPlannerTest {
     @Override public void setup() {
         super.setup();
 
-        publicSchema = new IgniteSchema("PUBLIC");
-
-        IgniteTypeFactory f = new IgniteTypeFactory(IgniteTypeSystem.INSTANCE);
-
-        RelDataType type = new RelDataTypeFactory.Builder(f)
-            .add("A", f.createSqlType(SqlTypeName.INTEGER))
-            .add("B", f.createSqlType(SqlTypeName.INTEGER))
-            .add("C", f.createSqlType(SqlTypeName.INTEGER))
-            .build();
-
-        createTable(publicSchema, "TBL", type, IgniteDistributions.single(), 
null);
+        publicSchema = createSchema(
+            createTable("TBL", IgniteDistributions.single(), "A", INTEGER, 
"B", INTEGER, "C", INTEGER)
+        );
     }
 
     /** */
@@ -258,6 +247,48 @@ public class ProjectFilterScanMergePlannerTest extends 
AbstractPlannerTest {
             .and(scan -> 
ImmutableBitSet.of(0).equals(scan.requiredColumns())));
     }
 
+    /**
+     * Check that not correlated part of correllated filter is merged into 
scan and trim unused fields is applied.
+     */
+    @Test
+    public void testCorrelatedFilterWithTrimMerge() throws Exception {
+        IgniteSchema schema = createSchema(
+            // Create table with random distributeion, to avoid correlated 
filter to scan merging.
+            createTable("TBL", IgniteDistributions.random(), "A", INTEGER, 
"B", INTEGER, "C", INTEGER)
+        );
+
+        String sql = "SELECT (SELECT a FROM tbl t2 WHERE t1.a = t2.a AND b > 
1) FROM tbl AS t1";
+
+        assertPlan(sql, schema, 
hasChildThat(isInstanceOf(IgniteAggregate.class)
+            .and(hasChildThat(isTableScan("TBL")
+                .and(scan -> scan.condition() != null)
+                .and(scan -> ">($t1, 1)".equals(scan.condition().toString()))
+                .and(scan -> ImmutableBitSet.of(0, 
1).equals(scan.requiredColumns())))))
+        );
+    }
+
+    /**
+     * Check that filter with always-false condition is not merged to scan and 
replaced with empty values.
+     */
+    @Test
+    public void testAlwaysFalseFilterNotMerged() throws Exception {
+        // Trimmed fields, not reduced condition.
+        assertPlan("SELECT a FROM tbl WHERE false", publicSchema,
+            nodeOrAnyChild(isTableScan("TBL")).negate());
+
+        // Trimmed fields, reduced condition.
+        assertPlan("SELECT a FROM tbl WHERE a = 1 AND a = 0", publicSchema,
+            nodeOrAnyChild(isTableScan("TBL")).negate());
+
+        // Not trimmed fields, not reduced condition.
+        assertPlan("SELECT * FROM tbl WHERE false", publicSchema,
+            nodeOrAnyChild(isTableScan("TBL")).negate());
+
+        // Not trimmed fields, reduced condition.
+        assertPlan("SELECT * FROM tbl WHERE a = 1 AND a = 0", publicSchema,
+            nodeOrAnyChild(isTableScan("TBL")).negate());
+    }
+
     /** */
     private static List<RexNode> searchBoundsCondition(List<SearchBounds> 
searchBounds) {
         return 
searchBounds.stream().filter(Objects::nonNull).map(SearchBounds::condition).collect(Collectors.toList());
diff --git 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/RexSimplificationPlannerTest.java
 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/RexSimplificationPlannerTest.java
index 840e53ae862..6e242bf8d1e 100644
--- 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/RexSimplificationPlannerTest.java
+++ 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/RexSimplificationPlannerTest.java
@@ -17,14 +17,18 @@
 
 package org.apache.ignite.internal.processors.query.calcite.planner;
 
+import org.apache.calcite.linq4j.tree.Types;
 import org.apache.calcite.rel.core.Join;
 import org.apache.calcite.util.Util;
+import 
org.apache.ignite.internal.processors.query.calcite.exec.exp.IgniteScalarFunction;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteValues;
 import 
org.apache.ignite.internal.processors.query.calcite.rel.ProjectableFilterableTableScan;
 import org.apache.ignite.internal.processors.query.calcite.schema.IgniteSchema;
 import 
org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistributions;
 import org.junit.Test;
 
 import static org.apache.calcite.sql.type.SqlTypeName.INTEGER;
+import static 
org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistributions.single;
 
 /**
  * Tests for Rex simplification.
@@ -193,4 +197,51 @@ public class RexSimplificationPlannerTest extends 
AbstractPlannerTest {
                     .equals(s.condition().toString()))
         );
     }
+
+    /** */
+    @Test
+    public void testFunctionFilterReduction() throws Exception {
+        IgniteSchema publicSchema = createSchema(createTable("T", single(), 
"ID", INTEGER));
+
+        // Deterministic echo.
+        publicSchema.addFunction("ECHO", IgniteScalarFunction.create(
+            Types.lookupMethod(RexSimplificationPlannerTest.class, "echo", 
int.class), true));
+
+        // Non-deterministic echo.
+        publicSchema.addFunction("ECHO_ND", IgniteScalarFunction.create(
+            Types.lookupMethod(RexSimplificationPlannerTest.class, "echo", 
int.class), false));
+
+        // Deterministic function with literal reduced (always-true).
+        assertPlan("SELECT * FROM t WHERE id = 0 AND echo(1) = 1", 
publicSchema, isTableScan("T")
+            .and(s -> "=($t0, 0)".equals(s.condition().toString())));
+
+        // Deterministic function with literal reduced (always-false).
+        assertPlan("SELECT * FROM t WHERE id = 0 AND echo(0) = 1", 
publicSchema, isInstanceOf(IgniteValues.class)
+            .and(v -> v.getTuples().isEmpty()));
+
+        // Deterministic function with another deterministic function reduced.
+        assertPlan("SELECT * FROM t WHERE id = 0 AND echo(echo(1)) = 1", 
publicSchema, isTableScan("T")
+            .and(s -> "=($t0, 0)".equals(s.condition().toString())));
+
+        // Deterministic function with column not reduced.
+        assertPlan("SELECT * FROM t WHERE id = 0 AND echo(id) = 1", 
publicSchema, isTableScan("T")
+            .and(s -> "AND(=($t0, 0), =(ECHO($t0), 
1))".equals(s.condition().toString())));
+
+        // Deterministic function with dynamic param not reduced.
+        assertPlan("SELECT * FROM t WHERE id = 0 AND echo(?::int) = ?", 
publicSchema, isTableScan("T")
+            .and(s -> "AND(=($t0, 0), =(ECHO(CAST(?0):INTEGER), 
?1))".equals(s.condition().toString())));
+
+        // Non-deterministic function not reduced.
+        assertPlan("SELECT * FROM t WHERE id = 0 AND echo_nd(1) = 1", 
publicSchema, isTableScan("T")
+            .and(s -> "AND(=($t0, 0), =(ECHO_ND(1), 
1))".equals(s.condition().toString())));
+
+        // Deterministic function with non-deterministic function not reduced.
+        assertPlan("SELECT * FROM t WHERE id = 0 AND echo(echo_nd(1)) = 1", 
publicSchema, isTableScan("T")
+            .and(s -> "AND(=($t0, 0), =(ECHO(ECHO_ND(1)), 
1))".equals(s.condition().toString())));
+    }
+
+    /** */
+    public static int echo(int val) {
+        return val;
+    }
 }
diff --git 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/SerializationPlannerTest.java
 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/SerializationPlannerTest.java
index 8e3528dfb9b..bc2ff7e89fe 100644
--- 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/SerializationPlannerTest.java
+++ 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/SerializationPlannerTest.java
@@ -101,7 +101,7 @@ public class SerializationPlannerTest extends 
AbstractPlannerTest {
         IgniteSchema funcSchema = new IgniteSchema("FUNC");
 
         funcSchema.addFunction("ECHO", IgniteScalarFunction.create(
-            Types.lookupMethod(SerializationPlannerTest.class, "echo", 
int.class)));
+            Types.lookupMethod(SerializationPlannerTest.class, "echo", 
int.class), false));
 
         assertPlan("SELECT func.echo(id) FROM orders", List.of(publicSchema, 
funcSchema),
             isTableScan("ORDERS"));
diff --git 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/TestTable.java
 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/TestTable.java
index a4e5ab611e8..5f5b5979b6f 100644
--- 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/TestTable.java
+++ 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/TestTable.java
@@ -23,24 +23,20 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import org.apache.calcite.config.CalciteConnectionConfig;
-import org.apache.calcite.plan.RelOptCluster;
 import org.apache.calcite.plan.RelOptTable;
 import org.apache.calcite.rel.RelCollation;
 import org.apache.calcite.rel.RelFieldCollation;
 import org.apache.calcite.rel.core.TableModify;
-import org.apache.calcite.rel.hint.RelHint;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeFactory;
 import org.apache.calcite.rel.type.RelDataTypeField;
 import org.apache.calcite.rel.type.RelDataTypeImpl;
 import org.apache.calcite.rel.type.RelProtoDataType;
-import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.schema.Schema;
 import org.apache.calcite.schema.Statistic;
 import org.apache.calcite.schema.Wrapper;
@@ -63,7 +59,6 @@ import org.apache.ignite.internal.processors.query.QueryUtils;
 import 
org.apache.ignite.internal.processors.query.calcite.exec.ExecutionContext;
 import 
org.apache.ignite.internal.processors.query.calcite.metadata.ColocationGroup;
 import 
org.apache.ignite.internal.processors.query.calcite.prepare.MappingQueryContext;
-import 
org.apache.ignite.internal.processors.query.calcite.rel.logical.IgniteLogicalTableScan;
 import 
org.apache.ignite.internal.processors.query.calcite.schema.CacheIndexImpl;
 import 
org.apache.ignite.internal.processors.query.calcite.schema.CacheTableDescriptor;
 import 
org.apache.ignite.internal.processors.query.calcite.schema.ColumnDescriptor;
@@ -163,18 +158,6 @@ public class TestTable implements IgniteCacheTable, 
Wrapper {
         return this;
     }
 
-    /** {@inheritDoc} */
-    @Override public IgniteLogicalTableScan toRel(
-        RelOptCluster cluster,
-        RelOptTable relOptTbl,
-        @Nullable List<RexNode> proj,
-        @Nullable RexNode cond,
-        @Nullable ImmutableBitSet requiredColumns,
-        @Nullable List<RelHint> hints
-    ) {
-        return IgniteLogicalTableScan.create(cluster, cluster.traitSet(), 
relOptTbl, hints, proj, cond, requiredColumns);
-    }
-
     /** {@inheritDoc} */
     @Override public RelDataType getRowType(RelDataTypeFactory typeFactory, 
ImmutableBitSet bitSet) {
         RelDataType rowType = protoType.apply(typeFactory);

Reply via email to