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

rubenql pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git


The following commit(s) were added to refs/heads/main by this push:
     new 896054aba3 [CALCITE-7219] Enhance functional dependency computation 
performance using the existing caching mechanisms
896054aba3 is described below

commit 896054aba375330a3f8c39554cdd9b76c0fbd04f
Author: Zhen Chen <[email protected]>
AuthorDate: Sat Oct 11 08:40:24 2025 +0800

    [CALCITE-7219] Enhance functional dependency computation performance using 
the existing caching mechanisms
---
 .../rel/metadata/RelMdFunctionalDependency.java       | 18 +++++++++---------
 .../apache/calcite/test/ProxyingRelMetadataTest.java  |  8 ++++++++
 .../java/org/apache/calcite/test/RelMetadataTest.java | 19 +++++++++++++++++++
 3 files changed, 36 insertions(+), 9 deletions(-)

diff --git 
a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdFunctionalDependency.java
 
b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdFunctionalDependency.java
index ea6d58cd23..d2f2bc9f61 100644
--- 
a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdFunctionalDependency.java
+++ 
b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdFunctionalDependency.java
@@ -101,7 +101,7 @@ protected RelMdFunctionalDependency() {}
    */
   public Boolean determinesSet(RelNode rel, RelMetadataQuery mq,
       ImmutableBitSet determinants, ImmutableBitSet dependents) {
-    ArrowSet fdSet = getFDs(rel, mq);
+    ArrowSet fdSet = mq.getFDs(rel);
     return fdSet.implies(determinants, dependents);
   }
 
@@ -115,7 +115,7 @@ public Boolean determinesSet(RelNode rel, RelMetadataQuery 
mq,
    */
   public ImmutableBitSet dependents(RelNode rel, RelMetadataQuery mq,
       ImmutableBitSet ordinals) {
-    ArrowSet fdSet = getFDs(rel, mq);
+    ArrowSet fdSet = mq.getFDs(rel);
     return fdSet.dependents(ordinals);
   }
 
@@ -129,7 +129,7 @@ public ImmutableBitSet dependents(RelNode rel, 
RelMetadataQuery mq,
    */
   public Set<ImmutableBitSet> determinants(
       RelNode rel, RelMetadataQuery mq, ImmutableBitSet ordinals) {
-    ArrowSet fdSet = getFDs(rel, mq);
+    ArrowSet fdSet = mq.getFDs(rel);
     return fdSet.determinants(ordinals);
   }
 
@@ -169,7 +169,7 @@ private ArrowSet getFD(List<RelNode> inputs, 
RelMetadataQuery mq) {
       // Conservative approach for multi-input nodes without specific logic
       return ArrowSet.EMPTY;
     }
-    return getFDs(inputs.get(0), mq);
+    return mq.getFDs(inputs.get(0));
   }
 
   /**
@@ -212,7 +212,7 @@ private ArrowSet getProjectFD(Project rel, RelMetadataQuery 
mq) {
    */
   private ArrowSet getProjectionFD(
       RelNode input, List<RexNode> projections, RelMetadataQuery mq) {
-    ArrowSet inputFdSet = getFDs(input, mq);
+    ArrowSet inputFdSet = mq.getFDs(input);
     ArrowSet.Builder fdBuilder = new ArrowSet.Builder();
 
     // Create mapping from input column indices to project column indices
@@ -342,7 +342,7 @@ private static ImmutableBitSet mapAvailableCols(
    */
   private ArrowSet getAggregateFD(Aggregate rel, RelMetadataQuery mq) {
     ArrowSet.Builder fdBuilder = new ArrowSet.Builder();
-    ArrowSet inputFdSet = getFDs(rel.getInput(), mq);
+    ArrowSet inputFdSet = mq.getFDs(rel.getInput());
 
     ImmutableBitSet groupSet = rel.getGroupSet();
 
@@ -373,7 +373,7 @@ private ArrowSet getAggregateFD(Aggregate rel, 
RelMetadataQuery mq) {
    * Returns functional dependencies for Filter.
    */
   private ArrowSet getFilterFD(Filter rel, RelMetadataQuery mq) {
-    ArrowSet inputSet = getFDs(rel.getInput(), mq);
+    ArrowSet inputSet = mq.getFDs(rel.getInput());
     ArrowSet.Builder fdBuilder = new ArrowSet.Builder();
 
     // Adds equality dependencies from filter conditions.
@@ -387,8 +387,8 @@ private ArrowSet getFilterFD(Filter rel, RelMetadataQuery 
mq) {
    * Preserves and combines dependencies based on join type.
    */
   private ArrowSet getJoinFD(Join rel, RelMetadataQuery mq) {
-    ArrowSet leftFdSet = getFDs(rel.getLeft(), mq);
-    ArrowSet rightFdSet = getFDs(rel.getRight(), mq);
+    ArrowSet leftFdSet = mq.getFDs(rel.getLeft());
+    ArrowSet rightFdSet = mq.getFDs(rel.getRight());
 
     int leftFieldCount = rel.getLeft().getRowType().getFieldCount();
     JoinRelType joinType = rel.getJoinType();
diff --git 
a/core/src/test/java/org/apache/calcite/test/ProxyingRelMetadataTest.java 
b/core/src/test/java/org/apache/calcite/test/ProxyingRelMetadataTest.java
index 29f5b20f90..7f503aa2bd 100644
--- a/core/src/test/java/org/apache/calcite/test/ProxyingRelMetadataTest.java
+++ b/core/src/test/java/org/apache/calcite/test/ProxyingRelMetadataTest.java
@@ -16,6 +16,9 @@
  */
 package org.apache.calcite.test;
 
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+
 /**
  * As {@link RelMetadataTest} but uses a proxying metadata provider.
  *
@@ -26,4 +29,9 @@ public class ProxyingRelMetadataTest extends RelMetadataTest {
     return super.fixture()
         .withMetadataConfig(RelMetadataFixture.MetadataConfig.PROXYING);
   }
+
+  @Disabled("ProxyingMetadataHandlerProvider does not implement caching")
+  @Test @Override void testFunctionalDependencyCaching() {
+    // Skip this test
+  }
 }
diff --git a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java 
b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
index bbf8676f0f..93cf9fc887 100644
--- a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
@@ -111,6 +111,7 @@
 import org.apache.calcite.test.catalog.MockCatalogReaderSimple;
 import org.apache.calcite.tools.Frameworks;
 import org.apache.calcite.tools.RelBuilder;
+import org.apache.calcite.util.ArrowSet;
 import org.apache.calcite.util.Holder;
 import org.apache.calcite.util.ImmutableBitSet;
 import org.apache.calcite.util.ImmutableIntList;
@@ -156,6 +157,7 @@
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.CoreMatchers.notNullValue;
 import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.CoreMatchers.sameInstance;
 import static org.hamcrest.CoreMatchers.startsWith;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.closeTo;
@@ -911,6 +913,23 @@ final RelMetadataFixture sql(String sql) {
         ImmutableBitSet.of(sal2SumAggCall)), is(Boolean.TRUE));
   }
 
+  /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-7219";>[CALCITE-7219]
+   * Enhance functional dependency computation performance
+   * using the existing caching mechanisms</a>. */
+  @Test void testFunctionalDependencyCaching() {
+    final String sql = "select empno, ename from emp";
+    final RelNode relNode = sql(sql).toRel();
+
+    final RelMetadataQuery mq = relNode.getCluster().getMetadataQuery();
+
+    ArrowSet fd1 = mq.getFDs(relNode);
+    ArrowSet fd2 = mq.getFDs(relNode);
+
+    assertThat(mq.determines(relNode, 0, 1), is(Boolean.TRUE));
+    assertThat(fd2, sameInstance(fd1));
+  }
+
   // ----------------------------------------------------------------------
   // Tests for getColumnOrigins
   // ----------------------------------------------------------------------

Reply via email to