Decoupled planning: add support for unnest (#17177)

* adds support for `UNNEST` expressions
* introduces `LogicalUnnestRule` to transform a `Correlate` doing UNNEST into a `LogicalUnnest`
* `UnnestInputCleanupRule` could move the final unnested expr into the `LogicalUnnest` itself (usually its an `mv_to_array` expression)
* enhanced source unwrapping to utilize `FilteredDataSource` if it looks right
diff --git a/processing/src/main/java/org/apache/druid/query/FilteredDataSource.java b/processing/src/main/java/org/apache/druid/query/FilteredDataSource.java
index 2d3104a..1644b32 100644
--- a/processing/src/main/java/org/apache/druid/query/FilteredDataSource.java
+++ b/processing/src/main/java/org/apache/druid/query/FilteredDataSource.java
@@ -51,7 +51,6 @@
  */
 public class FilteredDataSource implements DataSource
 {
-
   private final DataSource base;
   private final DimFilter filter;
 
diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/planner/CalciteRulesManager.java b/sql/src/main/java/org/apache/druid/sql/calcite/planner/CalciteRulesManager.java
index a7b4ba2..d6dd131 100644
--- a/sql/src/main/java/org/apache/druid/sql/calcite/planner/CalciteRulesManager.java
+++ b/sql/src/main/java/org/apache/druid/sql/calcite/planner/CalciteRulesManager.java
@@ -71,6 +71,8 @@
 import org.apache.druid.sql.calcite.rule.logical.DruidAggregateRemoveRedundancyRule;
 import org.apache.druid.sql.calcite.rule.logical.DruidJoinRule;
 import org.apache.druid.sql.calcite.rule.logical.DruidLogicalRules;
+import org.apache.druid.sql.calcite.rule.logical.LogicalUnnestRule;
+import org.apache.druid.sql.calcite.rule.logical.UnnestInputCleanupRule;
 import org.apache.druid.sql.calcite.run.EngineFeature;
 import org.apache.druid.sql.hook.DruidHook;
 
@@ -280,7 +282,8 @@
     builder.addRuleInstance(CoreRules.UNION_MERGE);
     builder.addRuleInstance(JoinExtractFilterRule.Config.DEFAULT.toRule());
     builder.addRuleInstance(FilterIntoJoinRuleConfig.DEFAULT.withPredicate(DruidJoinRule::isSupportedPredicate).toRule());
-
+    builder.addRuleInstance(new LogicalUnnestRule());
+    builder.addRuleInstance(new UnnestInputCleanupRule());
     return Programs.of(builder.build(), true, DefaultRelMetadataProvider.INSTANCE);
   }
 
diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/planner/querygen/DruidQueryGenerator.java b/sql/src/main/java/org/apache/druid/sql/calcite/planner/querygen/DruidQueryGenerator.java
index 28de4e8..511065b 100644
--- a/sql/src/main/java/org/apache/druid/sql/calcite/planner/querygen/DruidQueryGenerator.java
+++ b/sql/src/main/java/org/apache/druid/sql/calcite/planner/querygen/DruidQueryGenerator.java
@@ -28,7 +28,11 @@
 import org.apache.calcite.rel.core.Window;
 import org.apache.calcite.rex.RexBuilder;
 import org.apache.druid.error.DruidException;
+import org.apache.druid.query.DataSource;
+import org.apache.druid.query.FilteredDataSource;
 import org.apache.druid.query.QueryDataSource;
+import org.apache.druid.query.filter.DimFilter;
+import org.apache.druid.sql.calcite.filtration.Filtration;
 import org.apache.druid.sql.calcite.planner.PlannerContext;
 import org.apache.druid.sql.calcite.planner.querygen.DruidQueryGenerator.PDQVertexFactory.PDQVertex;
 import org.apache.druid.sql.calcite.planner.querygen.SourceDescProducer.SourceDesc;
@@ -232,6 +236,11 @@
       }
       return this == RIGHT;
     }
+
+    boolean filteredDatasourceAllowed()
+    {
+      return this == NONE;
+    }
   }
 
   /**
@@ -401,7 +410,13 @@
         if (canUnwrapSourceDesc()) {
           DruidQuery q = buildQuery(false);
           SourceDesc origInput = getSource();
-          return new SourceDesc(origInput.dataSource, q.getOutputRowSignature());
+          DataSource dataSource;
+          if (q.getFilter() == null) {
+            dataSource = origInput.dataSource;
+          } else {
+            dataSource = makeFilteredDataSource(origInput, q.getFilter());
+          }
+          return new SourceDesc(dataSource, q.getOutputRowSignature());
         }
         throw DruidException.defensive("Can't unwrap source of vertex[%s]", partialDruidQuery);
       }
@@ -415,14 +430,29 @@
         if (partialDruidQuery.stage() == Stage.SCAN) {
           return true;
         }
+        if (jst.filteredDatasourceAllowed() && partialDruidQuery.stage() == PartialDruidQuery.Stage.WHERE_FILTER) {
+          return true;
+        }
         if (partialDruidQuery.stage() == PartialDruidQuery.Stage.SELECT_PROJECT &&
-            partialDruidQuery.getWhereFilter() == null &&
+            (jst.filteredDatasourceAllowed() || partialDruidQuery.getWhereFilter() == null) &&
             partialDruidQuery.getSelectProject().isMapping()) {
           return true;
         }
         return false;
       }
     }
+  }
 
+  /**
+   * This method should not live here.
+   *
+   * The fact that {@link Filtration} have to be run on the filter is out-of scope here.
+   */
+  public static FilteredDataSource makeFilteredDataSource(SourceDesc sd, DimFilter filter)
+  {
+
+    Filtration filtration = Filtration.create(filter).optimizeFilterOnly(sd.rowSignature);
+    DimFilter newFilter = filtration.getDimFilter();
+    return FilteredDataSource.create(sd.dataSource, newFilter);
   }
 }
diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidCorrelateUnnestRel.java b/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidCorrelateUnnestRel.java
index e5c403f..f3b4550 100644
--- a/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidCorrelateUnnestRel.java
+++ b/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidCorrelateUnnestRel.java
@@ -577,7 +577,7 @@
   /**
    * Shuttle that replaces correlating variables with regular field accesses to the left-hand side.
    */
-  private static class CorrelatedFieldAccessToInputRef extends RexShuttle
+  public static class CorrelatedFieldAccessToInputRef extends RexShuttle
   {
     private final CorrelationId correlationId;
 
@@ -595,7 +595,6 @@
           return new RexInputRef(fieldAccess.getField().getIndex(), fieldAccess.getType());
         }
       }
-
       return super.visitFieldAccess(fieldAccess);
     }
   }
diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidJoinQueryRel.java b/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidJoinQueryRel.java
index e62b386..5615da3 100644
--- a/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidJoinQueryRel.java
+++ b/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidJoinQueryRel.java
@@ -423,7 +423,7 @@
              && DruidRels.druidTableIfLeafRel(right).filter(table -> table.getDataSource().isGlobal()).isPresent());
   }
 
-  static Set<String> findExistingJoinPrefixes(DataSource... dataSources)
+  public static Set<String> findExistingJoinPrefixes(DataSource... dataSources)
   {
     final ArrayList<DataSource> copy = new ArrayList<>(Arrays.asList(dataSources));
 
@@ -442,7 +442,7 @@
    * Returns a Pair of "rightPrefix" (for JoinDataSource) and the signature of rows that will result from
    * applying that prefix.
    */
-  static Pair<String, RowSignature> computeJoinRowSignature(
+  public static Pair<String, RowSignature> computeJoinRowSignature(
       final RowSignature leftSignature,
       final RowSignature rightSignature,
       final Set<String> prefixes
diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidQuery.java b/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidQuery.java
index f675727..f8d33f5 100644
--- a/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidQuery.java
+++ b/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidQuery.java
@@ -793,7 +793,10 @@
   public static List<DimFilter> getAllFiltersUnderDataSource(DataSource d, List<DimFilter> dimFilterList)
   {
     if (d instanceof FilteredDataSource) {
-      dimFilterList.add(((FilteredDataSource) d).getFilter());
+      DimFilter filter = ((FilteredDataSource) d).getFilter();
+      if (filter != null) {
+        dimFilterList.add(filter);
+      }
     }
     for (DataSource ds : d.getChildren()) {
       dimFilterList.addAll(getAllFiltersUnderDataSource(ds, dimFilterList));
@@ -1746,4 +1749,9 @@
     }
     return builder.build();
   }
+
+  public DimFilter getFilter()
+  {
+    return filter;
+  }
 }
diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidRel.java b/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidRel.java
index 8db108f..3deff68 100644
--- a/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidRel.java
+++ b/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidRel.java
@@ -148,7 +148,9 @@
       }
       if (other instanceof DruidRel<?>) {
         DruidRel<?> druidRel = (DruidRel<?>) other;
-        return druidRel.getPartialDruidQuery().leafRel();
+        if (druidRel.getPartialDruidQuery() != null && druidRel.getPartialDruidQuery().leafRel() != null) {
+          return druidRel.getPartialDruidQuery().leafRel();
+        }
       }
       return other;
     }
diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/rule/logical/DruidLogicalRules.java b/sql/src/main/java/org/apache/druid/sql/calcite/rule/logical/DruidLogicalRules.java
index a7d1a2c..7d53aeb 100644
--- a/sql/src/main/java/org/apache/druid/sql/calcite/rule/logical/DruidLogicalRules.java
+++ b/sql/src/main/java/org/apache/druid/sql/calcite/rule/logical/DruidLogicalRules.java
@@ -105,7 +105,8 @@
                 Convention.NONE,
                 DruidLogicalConvention.instance(),
                 DruidJoinRule.class.getSimpleName()
-            )
+            ),
+            DruidUnnestRule.INSTANCE
         )
     );
   }
diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/rule/logical/DruidUnnest.java b/sql/src/main/java/org/apache/druid/sql/calcite/rule/logical/DruidUnnest.java
new file mode 100644
index 0000000..67170ff
--- /dev/null
+++ b/sql/src/main/java/org/apache/druid/sql/calcite/rule/logical/DruidUnnest.java
@@ -0,0 +1,128 @@
+/*
+ * 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.druid.sql.calcite.rule.logical;
+
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rex.RexNode;
+import org.apache.druid.query.DataSource;
+import org.apache.druid.query.UnnestDataSource;
+import org.apache.druid.query.filter.DimFilter;
+import org.apache.druid.segment.VirtualColumn;
+import org.apache.druid.segment.column.RowSignature;
+import org.apache.druid.sql.calcite.expression.DruidExpression;
+import org.apache.druid.sql.calcite.expression.Expressions;
+import org.apache.druid.sql.calcite.filtration.Filtration;
+import org.apache.druid.sql.calcite.planner.Calcites;
+import org.apache.druid.sql.calcite.planner.PlannerContext;
+import org.apache.druid.sql.calcite.planner.querygen.SourceDescProducer;
+import org.apache.druid.sql.calcite.rel.DruidJoinQueryRel;
+import org.apache.druid.sql.calcite.rel.logical.DruidLogicalNode;
+
+import java.util.List;
+
+public class DruidUnnest extends Unnest implements DruidLogicalNode, SourceDescProducer
+{
+  protected DruidUnnest(RelOptCluster cluster, RelTraitSet traits, RelNode input, RexNode unnestExpr,
+      RelDataType rowType, RexNode condition)
+  {
+    super(cluster, traits, input, unnestExpr, rowType, condition);
+  }
+
+  @Override
+  protected RelNode copy(RelTraitSet traitSet, RelNode input)
+  {
+    return new DruidUnnest(getCluster(), traitSet, input, unnestExpr, rowType, filter);
+  }
+
+  @Override
+  public SourceDesc getSourceDesc(PlannerContext plannerContext, List<SourceDesc> sources)
+  {
+    SourceDesc inputDesc = sources.get(0);
+
+    RowSignature outputRowSignature = computeRowOutputSignature(inputDesc);
+
+    RowSignature filterRowSignature = RowSignature.builder().add(
+        outputRowSignature.getColumnName(outputRowSignature.size() - 1),
+        outputRowSignature.getColumnType(outputRowSignature.size() - 1).get()
+    ).build();
+
+    VirtualColumn virtualColumn = buildUnnestVirtualColumn(
+        plannerContext,
+        inputDesc,
+        filterRowSignature.getColumnName(0)
+    );
+
+    DimFilter dimFilter = buildDimFilter(plannerContext, filterRowSignature);
+    DataSource dataSource = UnnestDataSource.create(inputDesc.dataSource, virtualColumn, dimFilter);
+    return new SourceDesc(dataSource, outputRowSignature);
+  }
+
+  private DimFilter buildDimFilter(PlannerContext plannerContext, RowSignature filterRowSignature)
+  {
+    if (filter == null) {
+      return null;
+    }
+    DimFilter dimFilter = Expressions.toFilter(
+        plannerContext,
+        filterRowSignature,
+        null,
+        filter
+    );
+    return Filtration.create(dimFilter).optimizeFilterOnly(filterRowSignature).getDimFilter();
+  }
+
+  private VirtualColumn buildUnnestVirtualColumn(PlannerContext plannerContext, SourceDesc inputDesc, String columnName)
+  {
+    final DruidExpression expressionToUnnest = Expressions.toDruidExpression(
+        plannerContext,
+        inputDesc.rowSignature,
+        unnestExpr
+    );
+
+    VirtualColumn virtualColumn = expressionToUnnest.toVirtualColumn(
+        columnName,
+        Calcites.getColumnTypeForRelDataType(
+            unnestExpr.getType()
+        ),
+        plannerContext.getExpressionParser()
+    );
+    return virtualColumn;
+  }
+
+  private RowSignature computeRowOutputSignature(SourceDesc inputDesc)
+  {
+    return DruidJoinQueryRel.computeJoinRowSignature(
+        inputDesc.rowSignature,
+        RowSignature.builder().add(
+            "unnest",
+            Calcites.getColumnTypeForRelDataType(getUnnestedType())
+        ).build(),
+        DruidJoinQueryRel.findExistingJoinPrefixes(inputDesc.dataSource)
+    ).rhs;
+  }
+
+  private RelDataType getUnnestedType()
+  {
+    return rowType.getFieldList().get(rowType.getFieldCount() - 1).getType();
+  }
+}
diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/rule/logical/DruidUnnestRule.java b/sql/src/main/java/org/apache/druid/sql/calcite/rule/logical/DruidUnnestRule.java
new file mode 100644
index 0000000..257bb7c
--- /dev/null
+++ b/sql/src/main/java/org/apache/druid/sql/calcite/rule/logical/DruidUnnestRule.java
@@ -0,0 +1,61 @@
+/*
+ * 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.druid.sql.calcite.rule.logical;
+
+import org.apache.calcite.plan.Convention;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.convert.ConverterRule;
+import org.apache.druid.sql.calcite.rel.logical.DruidLogicalConvention;
+
+public class DruidUnnestRule extends ConverterRule
+{
+  private static Config CONFIG = Config.INSTANCE.withConversion(
+      LogicalUnnest.class,
+      Convention.NONE,
+      DruidLogicalConvention.instance(),
+      DruidUnnestRule.class.getSimpleName()
+  );
+
+  public static final DruidUnnestRule INSTANCE = new DruidUnnestRule(CONFIG);
+
+  private DruidUnnestRule(Config config)
+  {
+    super(config);
+  }
+
+  @Override
+  public RelNode convert(RelNode rel)
+  {
+    LogicalUnnest unnest = (LogicalUnnest) rel;
+    RelTraitSet newTrait = unnest.getTraitSet().replace(DruidLogicalConvention.instance());
+    return new DruidUnnest(
+        rel.getCluster(),
+        newTrait,
+        convert(
+            unnest.getInput(),
+            DruidLogicalConvention.instance()
+        ),
+        unnest.getUnnestExpr(),
+        unnest.getRowType(),
+        unnest.filter
+    );
+  }
+}
diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/rule/logical/DruidValuesRule.java b/sql/src/main/java/org/apache/druid/sql/calcite/rule/logical/DruidValuesRule.java
index 5fca4a2..4c00805 100644
--- a/sql/src/main/java/org/apache/druid/sql/calcite/rule/logical/DruidValuesRule.java
+++ b/sql/src/main/java/org/apache/druid/sql/calcite/rule/logical/DruidValuesRule.java
@@ -32,7 +32,6 @@
  */
 public class DruidValuesRule extends ConverterRule
 {
-
   public DruidValuesRule(
       Class<? extends RelNode> clazz,
       RelTrait in,
diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/rule/logical/LogicalUnnest.java b/sql/src/main/java/org/apache/druid/sql/calcite/rule/logical/LogicalUnnest.java
new file mode 100644
index 0000000..e23d4c6
--- /dev/null
+++ b/sql/src/main/java/org/apache/druid/sql/calcite/rule/logical/LogicalUnnest.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.sql.calcite.rule.logical;
+
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rex.RexNode;
+
+public class LogicalUnnest extends Unnest
+{
+  protected LogicalUnnest(RelOptCluster cluster, RelTraitSet traits, RelNode input, RexNode unnestExpr,
+      RelDataType rowType, RexNode condition)
+  {
+    super(cluster, traits, input, unnestExpr, rowType, condition);
+  }
+
+  @Override
+  protected RelNode copy(RelTraitSet traitSet, RelNode input)
+  {
+    return new LogicalUnnest(getCluster(), traitSet, input, unnestExpr, rowType, filter);
+  }
+}
diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/rule/logical/LogicalUnnestRule.java b/sql/src/main/java/org/apache/druid/sql/calcite/rule/logical/LogicalUnnestRule.java
new file mode 100644
index 0000000..662cf76
--- /dev/null
+++ b/sql/src/main/java/org/apache/druid/sql/calcite/rule/logical/LogicalUnnestRule.java
@@ -0,0 +1,160 @@
+/*
+ * 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.druid.sql.calcite.rule.logical;
+
+import com.google.common.collect.Iterables;
+import org.apache.calcite.plan.RelOptRule;
+import org.apache.calcite.plan.RelOptRuleCall;
+import org.apache.calcite.plan.RelOptUtil;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.Filter;
+import org.apache.calcite.rel.core.Project;
+import org.apache.calcite.rel.core.Uncollect;
+import org.apache.calcite.rel.logical.LogicalCorrelate;
+import org.apache.calcite.rel.logical.LogicalValues;
+import org.apache.calcite.rel.rules.SubstitutionRule;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.tools.RelBuilder;
+import org.apache.druid.error.DruidException;
+import org.apache.druid.sql.calcite.rel.DruidCorrelateUnnestRel;
+
+/**
+ * Recognizes a LogicalUnnest operation in the plan.
+ *
+ * Matches on the layout:
+ *
+ * <pre>
+ *   LogicalCorrelate(correlation=[$cor0], joinType=[inner], requiredColumns=[{4}])
+ *     RelNodeSubtree
+ *     Uncollect
+ *       LogicalProject(arrayLongNulls=[$cor0.arrayLongNulls])
+ *         LogicalValues(tuples=[[{ 0 }]])
+ * </pre>
+ *
+ * Translates it to use a {@link LogicalUnnest} like:
+ *
+ * <pre>
+ *   LogicalUnnest(unnestExpr=[$cor0.arrayLongNulls])
+ *     RelNodeSubtree
+ * </pre>
+ *
+ * It raises an error for cases when {@link LogicalCorrelate} can't be
+ * translated as those are currently unsupported in Druid.
+ */
+public class LogicalUnnestRule extends RelOptRule implements SubstitutionRule
+{
+  public LogicalUnnestRule()
+  {
+    super(operand(LogicalCorrelate.class, any()));
+  }
+
+  @Override
+  public boolean autoPruneOld()
+  {
+    return true;
+  }
+
+  @Override
+  public void onMatch(RelOptRuleCall call)
+  {
+    LogicalCorrelate cor = call.rel(0);
+    UnnestConfiguration unnestConfig = unwrapUnnestConfigurationExpression(cor.getRight().stripped());
+
+    if (unnestConfig == null) {
+      throw DruidException.defensive("Couldn't process possible unnest for reltree: \n%s", RelOptUtil.toString(cor));
+    }
+
+    unnestConfig.expr = new DruidCorrelateUnnestRel.CorrelatedFieldAccessToInputRef(cor.getCorrelationId())
+        .apply(unnestConfig.expr);
+
+    RelBuilder builder = call.builder();
+    builder.push(cor.getLeft());
+    RelNode newNode = builder.push(
+        new LogicalUnnest(
+            cor.getCluster(),
+            cor.getTraitSet(),
+            builder.build(),
+            unnestConfig.expr,
+            cor.getRowType(),
+            unnestConfig.condition
+        )
+    ).build();
+    call.transformTo(newNode);
+  }
+
+  private static class UnnestConfiguration
+  {
+    public RexNode expr;
+    private RexNode condition;
+
+    public UnnestConfiguration(RexNode unnestExpression, RexNode condition)
+    {
+      this.expr = unnestExpression;
+      this.condition = condition;
+    }
+
+    public static UnnestConfiguration ofExpression(RexNode unnestExpression)
+    {
+      return new UnnestConfiguration(unnestExpression, null);
+    }
+
+    public UnnestConfiguration withFilter(RexNode condition)
+    {
+      return new UnnestConfiguration(expr, condition);
+    }
+  }
+
+  private UnnestConfiguration unwrapUnnestConfigurationExpression(RelNode rel)
+  {
+    rel = rel.stripped();
+    if (rel instanceof Filter) {
+      Filter filter = (Filter) rel;
+      UnnestConfiguration conf = unwrapUnnestConfigurationExpression(filter.getInput());
+      if (conf != null) {
+        return conf.withFilter(filter.getCondition());
+      }
+    }
+    if (rel instanceof Uncollect) {
+      Uncollect uncollect = (Uncollect) rel;
+      if (!uncollect.withOrdinality) {
+        return unwrapProjectExpression(uncollect.getInput());
+      }
+    }
+    return null;
+  }
+
+  private UnnestConfiguration unwrapProjectExpression(RelNode rel)
+  {
+    rel = rel.stripped();
+    if (rel instanceof Project) {
+      Project project = (Project) rel;
+      if (isValues(project.getInput().stripped())) {
+        return UnnestConfiguration.ofExpression(Iterables.getOnlyElement(project.getProjects()));
+      }
+    }
+    return null;
+  }
+
+  private boolean isValues(RelNode rel)
+  {
+    rel = rel.stripped();
+    return (rel instanceof LogicalValues);
+  }
+}
diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/rule/logical/Unnest.java b/sql/src/main/java/org/apache/druid/sql/calcite/rule/logical/Unnest.java
new file mode 100644
index 0000000..58680b0
--- /dev/null
+++ b/sql/src/main/java/org/apache/druid/sql/calcite/rule/logical/Unnest.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.sql.calcite.rule.logical;
+
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.RelWriter;
+import org.apache.calcite.rel.SingleRel;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rex.RexNode;
+
+import java.util.List;
+
+public abstract class Unnest extends SingleRel
+{
+  protected final RexNode unnestExpr;
+  protected final RexNode filter;
+
+  protected Unnest(RelOptCluster cluster, RelTraitSet traits, RelNode input, RexNode unnestExpr,
+      RelDataType rowType, RexNode condition)
+  {
+    super(cluster, traits, input);
+    this.unnestExpr = unnestExpr;
+    this.rowType = rowType;
+    this.filter = condition;
+  }
+
+  public final RexNode getUnnestExpr()
+  {
+    return unnestExpr;
+  }
+
+  @Override
+  public RelWriter explainTerms(RelWriter pw)
+  {
+    return super.explainTerms(pw)
+        .item("unnestExpr", unnestExpr)
+        .itemIf("filter", filter, filter != null);
+  }
+
+  @Override
+  public final RelNode copy(RelTraitSet traitSet, List<RelNode> inputs)
+  {
+    return copy(traitSet, inputs.get(0));
+  }
+
+  protected abstract RelNode copy(RelTraitSet traitSet, RelNode input);
+}
diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/rule/logical/UnnestInputCleanupRule.java b/sql/src/main/java/org/apache/druid/sql/calcite/rule/logical/UnnestInputCleanupRule.java
new file mode 100644
index 0000000..baae4c4
--- /dev/null
+++ b/sql/src/main/java/org/apache/druid/sql/calcite/rule/logical/UnnestInputCleanupRule.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.druid.sql.calcite.rule.logical;
+
+import org.apache.calcite.plan.RelOptRule;
+import org.apache.calcite.plan.RelOptRuleCall;
+import org.apache.calcite.plan.RelOptUtil.InputFinder;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.Project;
+import org.apache.calcite.rel.rules.SubstitutionRule;
+import org.apache.calcite.rex.RexInputRef;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexShuttle;
+import org.apache.calcite.util.ImmutableBitSet;
+import org.apache.druid.error.DruidException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Makes tweaks to LogicalUnnest input.
+ *
+ * Removes any MV_TO_ARRAY call if its present for the input of the
+ * {@link LogicalUnnest}.
+ *
+ */
+public class UnnestInputCleanupRule extends RelOptRule implements SubstitutionRule
+{
+  public UnnestInputCleanupRule()
+  {
+    super(
+        operand(
+            LogicalUnnest.class,
+            operand(Project.class, any())
+        )
+    );
+  }
+
+  @Override
+  public void onMatch(RelOptRuleCall call)
+  {
+    LogicalUnnest unnest = call.rel(0);
+    Project project = call.rel(1);
+
+    ImmutableBitSet input = InputFinder.analyze(unnest.unnestExpr).build();
+    if (input.isEmpty()) {
+      throw DruidException.defensive("Found an unbound unnest expression.");
+    }
+
+    if (!(unnest.unnestExpr instanceof RexInputRef)) {
+      // could be supported; but is there a need?
+      return;
+    }
+    if (input.cardinality() != 1) {
+      return;
+    }
+
+    int inputIndex = input.nextSetBit(0);
+
+    List<RexNode> projects = new ArrayList<>(project.getProjects());
+    RexNode unnestInput = projects.get(inputIndex);
+
+    projects.set(
+        inputIndex,
+        call.builder().getRexBuilder().makeInputRef(project.getInput(), 0)
+    );
+
+    RexNode newUnnestExpr = unnestInput.accept(new ExpressionPullerRexShuttle(projects, inputIndex));
+
+    if (projects.size() != project.getProjects().size()) {
+      // lets leave this for later
+      return;
+    }
+
+
+    RelNode newInputRel = call.builder()
+        .push(project.getInput())
+        .project(projects)
+        .build();
+
+
+    RelNode newUnnest = new LogicalUnnest(
+        unnest.getCluster(), unnest.getTraitSet(), newInputRel, newUnnestExpr,
+        unnest.getRowType(), unnest.filter
+    );
+    call.transformTo(newUnnest);
+    call.getPlanner().prune(unnest);
+  }
+
+  /**
+   * Pulls an expression thru a {@link Project}.
+   *
+   * May add new projections to the passed mutable list.
+   */
+  private static class ExpressionPullerRexShuttle extends RexShuttle
+  {
+    private final List<RexNode> projects;
+    private int replaceableIndex;
+
+    private ExpressionPullerRexShuttle(List<RexNode> projects, int replaceableIndex)
+    {
+      this.projects = projects;
+      this.replaceableIndex = replaceableIndex;
+    }
+
+    @Override
+    public RexNode visitInputRef(RexInputRef inputRef)
+    {
+      int newIndex = projects.indexOf(inputRef);
+      if (newIndex < 0) {
+        if (replaceableIndex >= 0) {
+          newIndex = replaceableIndex;
+          projects.set(replaceableIndex, inputRef);
+          replaceableIndex = -1;
+        } else {
+          newIndex = projects.size();
+          projects.add(inputRef);
+        }
+      }
+      if (newIndex == inputRef.getIndex()) {
+        return inputRef;
+      } else {
+        return new RexInputRef(newIndex, inputRef.getType());
+      }
+    }
+  }
+}
diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/BaseCalciteQueryTest.java b/sql/src/test/java/org/apache/druid/sql/calcite/BaseCalciteQueryTest.java
index 4b26af3..42cf41f 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/BaseCalciteQueryTest.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/BaseCalciteQueryTest.java
@@ -560,6 +560,25 @@
     return new ExpressionVirtualColumn(name, expression, outputType, CalciteTests.createExprMacroTable());
   }
 
+  /**
+   * Optionally updates the VC defintion for the one planned by the decoupled planner.
+   *
+   * Compared to original plans; decoupled planner:
+   *  * moves the mv_to_array into the VC
+   *  * the type is an ARRAY
+   */
+  public ExpressionVirtualColumn nestedExpressionVirtualColumn(
+      String name,
+      String expression,
+      ColumnType outputType)
+  {
+    if (testBuilder().isDecoupledMode()) {
+      expression = StringUtils.format("mv_to_array(%s)", expression);
+      outputType = ColumnType.ofArray(outputType);
+    }
+    return expressionVirtualColumn(name, expression, outputType);
+  }
+
   public static JoinDataSource join(
       DataSource left,
       DataSource right,
diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteArraysQueryTest.java b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteArraysQueryTest.java
index b2f87b3..531da0f 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteArraysQueryTest.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteArraysQueryTest.java
@@ -68,6 +68,9 @@
 import org.apache.druid.segment.column.RowSignature;
 import org.apache.druid.segment.join.JoinType;
 import org.apache.druid.segment.virtual.ExpressionVirtualColumn;
+import org.apache.druid.sql.calcite.DecoupledTestConfig.IgnoreQueriesReason;
+import org.apache.druid.sql.calcite.DecoupledTestConfig.QuidemTestCaseReason;
+import org.apache.druid.sql.calcite.NotYetSupported.Modes;
 import org.apache.druid.sql.calcite.filtration.Filtration;
 import org.apache.druid.sql.calcite.util.CalciteTests;
 import org.apache.druid.sql.calcite.util.SqlTestFramework.StandardComponentSupplier;
@@ -3885,6 +3888,7 @@
 
   }
 
+  @NotYetSupported(Modes.UNNEST_INLINED)
   @Test
   public void testUnnestInline()
   {
@@ -3919,6 +3923,7 @@
     );
   }
 
+  @NotYetSupported(Modes.UNNEST_INLINED)
   @Test
   public void testUnnestInlineWithCount()
   {
@@ -3949,6 +3954,7 @@
     );
   }
 
+  @NotYetSupported(Modes.UNNEST_RESULT_MISMATCH)
   @Test
   public void testUnnest()
   {
@@ -3959,7 +3965,7 @@
             Druids.newScanQueryBuilder()
                   .dataSource(UnnestDataSource.create(
                       new TableDataSource(CalciteTests.DATASOURCE3),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       null
                   ))
                   .intervals(querySegmentSpec(Filtration.eternity()))
@@ -4333,6 +4339,7 @@
     );
   }
 
+  @NotYetSupported(Modes.UNNEST_RESULT_MISMATCH)
   @Test
   public void testUnnestTwice()
   {
@@ -4356,11 +4363,7 @@
                               ),
                               null
                           ),
-                          expressionVirtualColumn(
-                              "_j0.unnest",
-                              "\"dim3\"",
-                              ColumnType.STRING
-                          ),
+                          nestedExpressionVirtualColumn("_j0.unnest", "\"dim3\"", ColumnType.STRING),
                           null
                       )
                   )
@@ -4513,11 +4516,7 @@
                               ),
                               in("j0.unnest", ImmutableList.of("1", "2"))
                           ),
-                          expressionVirtualColumn(
-                              "_j0.unnest",
-                              "\"dim3\"",
-                              ColumnType.STRING
-                          ),
+                          nestedExpressionVirtualColumn("_j0.unnest", "\"dim3\"", ColumnType.STRING),
                           new LikeDimFilter("_j0.unnest", "_", null, null)
                       )
                   )
@@ -4553,6 +4552,7 @@
   }
 
 
+  @DecoupledTestConfig(ignoreExpectedQueriesReason = IgnoreQueriesReason.UNNEST_EXTRA_SCANQUERY)
   @Test
   public void testUnnestThriceWithFiltersOnDimAndUnnestCol()
   {
@@ -4570,11 +4570,7 @@
                           FilteredDataSource.create(
                               UnnestDataSource.create(
                                   new TableDataSource(CalciteTests.DATASOURCE5),
-                                  expressionVirtualColumn(
-                                      "j0.unnest",
-                                      "\"dimMultivalEnumerated\"",
-                                      ColumnType.STRING
-                                  ),
+                                  nestedExpressionVirtualColumn("j0.unnest", "\"dimMultivalEnumerated\"", ColumnType.STRING),
                                   null
                               ),
                               and(
@@ -4584,17 +4580,9 @@
                                   equality("j0.unnest", "Baz", ColumnType.STRING)
                               )
                           ),
-                          expressionVirtualColumn(
-                              "_j0.unnest",
-                              "\"dimMultivalEnumerated\"",
-                              ColumnType.STRING
-                          ), null
+                          nestedExpressionVirtualColumn("_j0.unnest", "\"dimMultivalEnumerated\"", ColumnType.STRING), null
                       ),
-                      expressionVirtualColumn(
-                          "__j0.unnest",
-                          "\"dimMultivalEnumerated\"",
-                          ColumnType.STRING
-                      ),
+                      nestedExpressionVirtualColumn("__j0.unnest", "\"dimMultivalEnumerated\"", ColumnType.STRING),
                       null
                   )
               )
@@ -4649,6 +4637,8 @@
         )
     );
   }
+
+  @DecoupledTestConfig(ignoreExpectedQueriesReason = IgnoreQueriesReason.UNNEST_EXTRA_SCANQUERY)
   @Test
   public void testUnnestThriceWithFiltersOnDimAndAllUnnestColumns()
   {
@@ -4800,11 +4790,7 @@
                               FilteredDataSource.create(
                                   UnnestDataSource.create(
                                       new TableDataSource(CalciteTests.DATASOURCE5),
-                                      expressionVirtualColumn(
-                                          "j0.unnest",
-                                          "\"dimMultivalEnumerated\"",
-                                          ColumnType.STRING
-                                      ),
+                                      nestedExpressionVirtualColumn("j0.unnest", "\"dimMultivalEnumerated\"", ColumnType.STRING),
                                       null
                                   ),
                                   NullHandling.sqlCompatible() ? equality("dimZipf", "27", ColumnType.LONG) : range(
@@ -4816,11 +4802,7 @@
                                       false
                                   )
                               ),
-                              expressionVirtualColumn(
-                                  "_j0.unnest",
-                                  "\"dimMultivalEnumerated\"",
-                                  ColumnType.STRING
-                              ),
+                              nestedExpressionVirtualColumn("_j0.unnest", "\"dimMultivalEnumerated\"", ColumnType.STRING),
                               null
                           ),
                           or(
@@ -4828,11 +4810,7 @@
                               equality("_j0.unnest", "Hello", ColumnType.STRING)
                           ) // (j0.unnest = Baz || _j0.unnest = Hello)
                       ),
-                      expressionVirtualColumn(
-                          "__j0.unnest",
-                          "\"dimMultivalEnumerated\"",
-                          ColumnType.STRING
-                      ),
+                      nestedExpressionVirtualColumn("__j0.unnest", "\"dimMultivalEnumerated\"", ColumnType.STRING),
                       equality("__j0.unnest", "World", ColumnType.STRING)
                   )
               )
@@ -4932,6 +4910,7 @@
     );
   }
 
+  @NotYetSupported(Modes.UNNEST_RESULT_MISMATCH)
   @Test
   public void testUnnestWithGroupBy()
   {
@@ -4943,7 +4922,7 @@
             GroupByQuery.builder()
                         .setDataSource(UnnestDataSource.create(
                             new TableDataSource(CalciteTests.DATASOURCE3),
-                            expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                            nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                             null
                         ))
                         .setInterval(querySegmentSpec(Filtration.eternity()))
@@ -5002,6 +4981,7 @@
     );
   }
 
+  @NotYetSupported(Modes.UNNEST_RESULT_MISMATCH)
   @Test
   public void testUnnestWithGroupByOrderBy()
   {
@@ -5013,7 +4993,7 @@
             GroupByQuery.builder()
                         .setDataSource(UnnestDataSource.create(
                             new TableDataSource(CalciteTests.DATASOURCE3),
-                            expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                            nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                             null
                         ))
                         .setInterval(querySegmentSpec(Filtration.eternity()))
@@ -5053,6 +5033,7 @@
     );
   }
 
+  @NotYetSupported(Modes.UNNEST_RESULT_MISMATCH)
   @Test
   public void testUnnestWithGroupByOrderByWithLimit()
   {
@@ -5063,7 +5044,7 @@
             new TopNQueryBuilder()
                 .dataSource(UnnestDataSource.create(
                     new TableDataSource(CalciteTests.DATASOURCE3),
-                    expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                    nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                     null
                 ))
                 .intervals(querySegmentSpec(Filtration.eternity()))
@@ -5101,7 +5082,7 @@
             GroupByQuery.builder()
                         .setDataSource(UnnestDataSource.create(
                             new TableDataSource(CalciteTests.DATASOURCE3),
-                            expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                            nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                             null
                         ))
                         .setInterval(querySegmentSpec(Filtration.eternity()))
@@ -5138,7 +5119,7 @@
             Druids.newScanQueryBuilder()
                   .dataSource(UnnestDataSource.create(
                       new TableDataSource(CalciteTests.DATASOURCE3),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       null
                   ))
                   .intervals(querySegmentSpec(Filtration.eternity()))
@@ -5156,6 +5137,7 @@
     );
   }
 
+  @NotYetSupported(Modes.UNNEST_RESULT_MISMATCH)
   @Test
   public void testUnnestFirstQueryOnSelect()
   {
@@ -5166,7 +5148,7 @@
             Druids.newScanQueryBuilder()
                   .dataSource(UnnestDataSource.create(
                       new TableDataSource(CalciteTests.DATASOURCE3),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       null
                   ))
                   .intervals(querySegmentSpec(Filtration.eternity()))
@@ -5208,11 +5190,7 @@
         ImmutableList.of(Druids.newScanQueryBuilder()
                                .dataSource(UnnestDataSource.create(
                                    new TableDataSource(CalciteTests.DATASOURCE3),
-                                   expressionVirtualColumn(
-                                       "j0.unnest",
-                                       "\"dim3\"",
-                                       ColumnType.STRING
-                                   ),
+                                   nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                                    equality("j0.unnest", "a", ColumnType.STRING)
                                ))
                                .intervals(querySegmentSpec(Filtration.eternity()))
@@ -5247,11 +5225,7 @@
         ImmutableList.of(Druids.newScanQueryBuilder()
                                .dataSource(UnnestDataSource.create(
                                    new TableDataSource(CalciteTests.DATASOURCE3),
-                                   expressionVirtualColumn(
-                                       "j0.unnest",
-                                       "\"dim3\"",
-                                       ColumnType.STRING
-                                   ),
+                                   nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                                    null
                                ))
                                .intervals(querySegmentSpec(Filtration.eternity()))
@@ -5275,6 +5249,8 @@
         )
     );
   }
+
+  @DecoupledTestConfig(quidemReason = QuidemTestCaseReason.UNNEST_EXTRA_SCAN, separateDefaultModeTest = true)
   @Test
   public void testUnnestWithFilters()
   {
@@ -5288,7 +5264,7 @@
                           new TableDataSource(CalciteTests.DATASOURCE3),
                           equality("dim2", "a", ColumnType.STRING)
                       ),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       null
                   ))
                   .intervals(querySegmentSpec(Filtration.eternity()))
@@ -5305,6 +5281,7 @@
     );
   }
 
+  @DecoupledTestConfig(quidemReason = QuidemTestCaseReason.UNNEST_EXTRA_SCAN, separateDefaultModeTest = true)
   @Test
   public void testUnnestWithFiltersWithExpressionInInnerQuery()
   {
@@ -5318,7 +5295,7 @@
                           new TableDataSource(CalciteTests.DATASOURCE3),
                           equality("dim2", "a", ColumnType.STRING)
                       ),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       null
                   ))
                   .intervals(querySegmentSpec(Filtration.eternity()))
@@ -5340,6 +5317,7 @@
     );
   }
 
+  @DecoupledTestConfig(quidemReason = QuidemTestCaseReason.UNNEST_EXTRA_SCAN, separateDefaultModeTest = true)
   @Test
   public void testUnnestWithInFiltersWithExpressionInInnerQuery()
   {
@@ -5353,7 +5331,7 @@
                           new TableDataSource(CalciteTests.DATASOURCE3),
                           in("dim2", ImmutableList.of("a", "b"))
                       ),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       null
                   ))
                   .intervals(querySegmentSpec(Filtration.eternity()))
@@ -5373,6 +5351,7 @@
     );
   }
 
+  @DecoupledTestConfig(quidemReason = QuidemTestCaseReason.UNUSED_VIRTUALCOLUMN, separateDefaultModeTest = true)
   @Test
   public void testUnnestWithFiltersInnerLimit()
   {
@@ -5395,7 +5374,7 @@
                               .context(QUERY_CONTEXT_UNNEST)
                               .build()
                       ),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       null
                   ))
                   .intervals(querySegmentSpec(Filtration.eternity()))
@@ -5417,6 +5396,7 @@
     );
   }
 
+  @DecoupledTestConfig(quidemReason = QuidemTestCaseReason.UNNEST_EXTRA_SCAN, separateDefaultModeTest = true)
   @Test
   public void testUnnestWithFiltersInsideAndOutside()
   {
@@ -5453,6 +5433,7 @@
     );
   }
 
+  @DecoupledTestConfig(ignoreExpectedQueriesReason = IgnoreQueriesReason.UNNEST_EXTRA_SCANQUERY)
   @Test
   public void testUnnestWithFiltersInsideAndOutside1()
   {
@@ -5492,6 +5473,7 @@
     );
   }
 
+  @DecoupledTestConfig(ignoreExpectedQueriesReason = IgnoreQueriesReason.UNNEST_EXTRA_SCANQUERY)
   @Test
   public void testUnnestWithFiltersOutside()
   {
@@ -5532,6 +5514,7 @@
     );
   }
 
+  @NotYetSupported(Modes.UNNEST_RESULT_MISMATCH)
   @Test
   public void testUnnestWithInFilters()
   {
@@ -5545,7 +5528,7 @@
                           new TableDataSource(CalciteTests.DATASOURCE3),
                           in("dim2", ImmutableList.of("a", "b", "ab", "abc"))
                       ),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       null
                   ))
                   .intervals(querySegmentSpec(Filtration.eternity()))
@@ -5655,6 +5638,8 @@
     );
   }
 
+  @NotYetSupported(Modes.UNNEST_RESULT_MISMATCH)
+  @DecoupledTestConfig(ignoreExpectedQueriesReason = IgnoreQueriesReason.UNNEST_EXTRA_SCANQUERY)
   @Test
   public void testUnnestWithJoinOnTheLeft()
   {
@@ -5713,6 +5698,7 @@
     );
   }
 
+  @NotYetSupported(Modes.UNNEST_INLINED)
   @Test
   public void testUnnestWithConstant()
   {
@@ -5769,6 +5755,7 @@
     );
   }
 
+  @NotYetSupported(Modes.UNNEST_RESULT_MISMATCH)
   @Test
   public void testUnnestWithSQLFunctionOnUnnestedColumn()
   {
@@ -5779,7 +5766,7 @@
             Druids.newScanQueryBuilder()
                   .dataSource(UnnestDataSource.create(
                       new TableDataSource(CalciteTests.DATASOURCE3),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       null
                   ))
                   .intervals(querySegmentSpec(Filtration.eternity()))
@@ -5826,7 +5813,7 @@
                           new TableDataSource(CalciteTests.DATASOURCE3),
                           range("m1", ColumnType.LONG, null, 10L, false, true)
                       ),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       in("j0.unnest", ImmutableSet.of("a", "b"))
                   ))
                   .intervals(querySegmentSpec(Filtration.eternity()))
@@ -5883,7 +5870,7 @@
             Druids.newScanQueryBuilder()
                   .dataSource(UnnestDataSource.create(
                       new TableDataSource(CalciteTests.DATASOURCE3),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       in("j0.unnest", ImmutableSet.of("foo", "bar"))
                   ))
                   .intervals(querySegmentSpec(Filtration.eternity()))
@@ -5896,6 +5883,7 @@
     );
   }
 
+  @DecoupledTestConfig(quidemReason = QuidemTestCaseReason.UNNEST_DIFFERENT_RESULTSET, separateDefaultModeTest = true)
   @Test
   public void testUnnestWithNotFiltersOnUnnestedColumn()
   {
@@ -5906,7 +5894,7 @@
             Druids.newScanQueryBuilder()
                   .dataSource(UnnestDataSource.create(
                       new TableDataSource(CalciteTests.DATASOURCE3),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       not(equality("j0.unnest", "d", ColumnType.STRING))
                   ))
                   .intervals(querySegmentSpec(Filtration.eternity()))
@@ -5945,7 +5933,7 @@
             Druids.newScanQueryBuilder()
                   .dataSource(UnnestDataSource.create(
                       new TableDataSource(CalciteTests.DATASOURCE3),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       equality("j0.unnest", "b", ColumnType.STRING)
                   ))
                   .intervals(querySegmentSpec(Filtration.eternity()))
@@ -6034,7 +6022,7 @@
                               range("m2", ColumnType.LONG, null, 10L, false, true)
                           )
                       ),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       equality("j0.unnest", "b", ColumnType.STRING)
                   ))
                   .intervals(querySegmentSpec(Filtration.eternity()))
@@ -6060,7 +6048,7 @@
             Druids.newScanQueryBuilder()
                   .dataSource(UnnestDataSource.create(
                       new TableDataSource(CalciteTests.DATASOURCE3),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       null
                   ))
                   .intervals(querySegmentSpec(Filtration.eternity()))
@@ -6093,7 +6081,7 @@
             Druids.newScanQueryBuilder()
                   .dataSource(UnnestDataSource.create(
                       new TableDataSource(CalciteTests.DATASOURCE3),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       in("j0.unnest", ImmutableSet.of("a", "b"))
                   ))
                   .intervals(querySegmentSpec(Filtration.eternity()))
@@ -6120,7 +6108,7 @@
             Druids.newScanQueryBuilder()
                   .dataSource(UnnestDataSource.create(
                       new TableDataSource(CalciteTests.DATASOURCE3),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       in("j0.unnest", ImmutableSet.of("b", "d"))
                   ))
                   .intervals(querySegmentSpec(Filtration.eternity()))
@@ -6137,6 +6125,7 @@
     );
   }
 
+  @DecoupledTestConfig(quidemReason = QuidemTestCaseReason.UNNEST_DIFFERENT_RESULTSET, separateDefaultModeTest = true)
   @Test
   public void testUnnestWithMultipleOrFiltersOnVariationsOfUnnestedColumns()
   {
@@ -6147,7 +6136,7 @@
             Druids.newScanQueryBuilder()
                   .dataSource(UnnestDataSource.create(
                       new TableDataSource(CalciteTests.DATASOURCE3),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       or(
                           expressionFilter("(strlen(\"j0.unnest\") < 2)"),
                           equality("j0.unnest", "d", ColumnType.STRING)
@@ -6197,7 +6186,7 @@
                               range("m2", ColumnType.LONG, null, 2L, false, true)
                           )
                       ),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       null
                   ))
                   .intervals(querySegmentSpec(Filtration.eternity()))
@@ -6258,7 +6247,7 @@
             Druids.newScanQueryBuilder()
                   .dataSource(UnnestDataSource.create(
                       new TableDataSource(CalciteTests.DATASOURCE3),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       null
                   ))
                   .intervals(querySegmentSpec(Filtration.eternity()))
@@ -6291,7 +6280,7 @@
             Druids.newScanQueryBuilder()
                   .dataSource(UnnestDataSource.create(
                       new TableDataSource(CalciteTests.DATASOURCE3),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       null
                   ))
                   .intervals(querySegmentSpec(Filtration.eternity()))
@@ -6315,6 +6304,7 @@
     );
   }
 
+  @NotYetSupported(Modes.UNNEST_RESULT_MISMATCH)
   @Test
   public void testUnnestWithCountOnColumn()
   {
@@ -6326,7 +6316,7 @@
             Druids.newTimeseriesQueryBuilder()
                   .dataSource(UnnestDataSource.create(
                       new TableDataSource(CalciteTests.DATASOURCE3),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       null
                   ))
                   .intervals(querySegmentSpec(Filtration.eternity()))
@@ -6351,7 +6341,7 @@
             GroupByQuery.builder()
                         .setDataSource(UnnestDataSource.create(
                             new TableDataSource(CalciteTests.DATASOURCE3),
-                            expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                            nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                             null
                         ))
                         .setInterval(querySegmentSpec(Filtration.eternity()))
@@ -6405,7 +6395,7 @@
             Druids.newTimeseriesQueryBuilder()
                   .dataSource(UnnestDataSource.create(
                       new TableDataSource(CalciteTests.DATASOURCE3),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       null
                   ))
                   .intervals(querySegmentSpec(Filtration.eternity()))
@@ -6460,7 +6450,7 @@
             GroupByQuery.builder()
                         .setDataSource(UnnestDataSource.create(
                             new TableDataSource(CalciteTests.DATASOURCE3),
-                            expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                            nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                             in("j0.unnest", ImmutableSet.of("a", "c"))
                         ))
                         .setInterval(querySegmentSpec(Filtration.eternity()))
@@ -6490,7 +6480,7 @@
             GroupByQuery.builder()
                         .setDataSource(UnnestDataSource.create(
                             new TableDataSource(CalciteTests.DATASOURCE3),
-                            expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                            nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                             in("j0.unnest", ImmutableSet.of("a", "c"))
                         ))
                         .setInterval(querySegmentSpec(Filtration.eternity()))
@@ -6629,7 +6619,7 @@
                           new TableDataSource(CalciteTests.DATASOURCE1),
                           range("__time", ColumnType.LONG, 946771200000L, 946858200000L, false, false)
                       ),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       null
                   ))
                   .intervals(querySegmentSpec(Intervals.of("2000-01-02T00:00:00.000Z/2000-01-03T00:10:00.001Z")))
@@ -6684,6 +6674,7 @@
     );
   }
 
+  @DecoupledTestConfig(ignoreExpectedQueriesReason = IgnoreQueriesReason.UNNEST_EXTRA_SCANQUERY)
   @Test
   public void testUnnestWithTimeFilterAndAnotherFilter()
   {
@@ -6702,7 +6693,7 @@
                               range("__time", ColumnType.LONG, 946771200000L, 946858200000L, false, false)
                           )
                       ),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       null
                   ))
                   .intervals(querySegmentSpec(Intervals.of("2000-01-02T00:00:00.000Z/2000-01-03T00:10:00.001Z")))
@@ -6736,7 +6727,7 @@
                               range("__time", ColumnType.LONG, 946771200000L, 946858200000L, false, false)
                           )
                       ),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       null
                   ))
                   .intervals(querySegmentSpec(Filtration.eternity()))
@@ -6771,7 +6762,7 @@
                           expressionVirtualColumn("j0.unnest", "array(\"m1\",\"m2\")", ColumnType.FLOAT_ARRAY),
                           null
                       ),
-                      expressionVirtualColumn("_j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("_j0.unnest", "\"dim3\"", ColumnType.STRING),
                       null
                   ))
                   .intervals(querySegmentSpec(Intervals.of("2000-01-02T00:00:00.000Z/2000-01-03T00:10:00.001Z")))
@@ -6814,7 +6805,7 @@
                           expressionVirtualColumn("_j0.unnest", "array(\"dim1\",\"dim2\")", ColumnType.STRING_ARRAY),
                           null
                       ),
-                      expressionVirtualColumn("__j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("__j0.unnest", "\"dim3\"", ColumnType.STRING),
                       null
                   ))
                   .intervals(querySegmentSpec(Intervals.of("2000-01-02T00:00:00.000Z/2000-01-03T00:10:00.001Z")))
@@ -6840,6 +6831,7 @@
     );
   }
 
+  @DecoupledTestConfig(ignoreExpectedQueriesReason = IgnoreQueriesReason.UNNEST_EXTRA_SCANQUERY)
   @Test
   public void testUnnestWithTimeFilterInsideSubquery()
   {
@@ -6890,6 +6882,7 @@
     );
   }
 
+  @DecoupledTestConfig(ignoreExpectedQueriesReason = IgnoreQueriesReason.UNNEST_EXTRA_SCANQUERY)
   @Test
   public void testUnnestWithTimeFilterInsideSubqueryArrayColumns()
   {
@@ -6938,6 +6931,7 @@
     );
   }
 
+  @DecoupledTestConfig(ignoreExpectedQueriesReason = IgnoreQueriesReason.UNNEST_EXTRA_SCANQUERY)
   @Test
   public void testUnnestWithFilterAndUnnestNestedBackToBack()
   {
@@ -7018,6 +7012,7 @@
     );
   }
 
+  @DecoupledTestConfig(ignoreExpectedQueriesReason = IgnoreQueriesReason.UNNEST_EXTRA_SCANQUERY)
   @Test
   public void testUnnestWithLookup()
   {
@@ -7047,6 +7042,7 @@
     );
   }
 
+  @DecoupledTestConfig(quidemReason = QuidemTestCaseReason.UNNEST_VC_USES_PROJECTED_CONSTANT)
   @Test
   public void testUnnestWithGroupByOnExpression()
   {
@@ -7197,6 +7193,7 @@
     );
   }
 
+  @DecoupledTestConfig(quidemReason = QuidemTestCaseReason.UNNEST_DIFFERENT_RESULTSET, separateDefaultModeTest = true)
   @Test
   public void testUnnestExtractionFn()
   {
@@ -7207,7 +7204,7 @@
             Druids.newScanQueryBuilder()
                   .dataSource(UnnestDataSource.create(
                       new TableDataSource(CalciteTests.DATASOURCE3),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       NullHandling.sqlCompatible()
                       ? expressionFilter("(substring(\"j0.unnest\", 0, -1) != 'b')")
                       : not(selector("j0.unnest", "b", new SubstringDimExtractionFn(0, null)))
@@ -7246,7 +7243,7 @@
             Druids.newScanQueryBuilder()
                   .dataSource(UnnestDataSource.create(
                       new TableDataSource(CalciteTests.DATASOURCE3),
-                      expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                      nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                       NullHandling.sqlCompatible()
                       ? expressionFilter("notnull(substring(\"j0.unnest\", 0, -1))")
                       : not(selector("j0.unnest", null, new SubstringDimExtractionFn(0, null)))
diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteCorrelatedQueryTest.java b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteCorrelatedQueryTest.java
index e0d71b6..ef442ec 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteCorrelatedQueryTest.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteCorrelatedQueryTest.java
@@ -42,6 +42,7 @@
 import org.apache.druid.segment.column.ColumnType;
 import org.apache.druid.segment.join.JoinType;
 import org.apache.druid.segment.virtual.ExpressionVirtualColumn;
+import org.apache.druid.sql.calcite.DecoupledTestConfig.IgnoreQueriesReason;
 import org.apache.druid.sql.calcite.util.CalciteTests;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.MethodSource;
@@ -168,6 +169,7 @@
     );
   }
 
+  @DecoupledTestConfig(ignoreExpectedQueriesReason = IgnoreQueriesReason.UNNEST_EXTRA_SCANQUERY)
   @MethodSource("provideQueryContexts")
   @ParameterizedTest(name = "{0}")
   public void testCorrelatedSubqueryWithLeftFilter(Map<String, Object> queryContext)
@@ -257,6 +259,7 @@
     );
   }
 
+  @DecoupledTestConfig(ignoreExpectedQueriesReason = IgnoreQueriesReason.UNNEST_EXTRA_SCANQUERY)
   @MethodSource("provideQueryContexts")
   @ParameterizedTest(name = "{0}")
   public void testCorrelatedSubqueryWithLeftFilter_leftDirectAccessDisabled(Map<String, Object> queryContext)
@@ -352,6 +355,7 @@
     );
   }
 
+  @DecoupledTestConfig(ignoreExpectedQueriesReason = IgnoreQueriesReason.UNNEST_EXTRA_SCANQUERY)
   @MethodSource("provideQueryContexts")
   @ParameterizedTest(name = "{0}")
   public void testCorrelatedSubqueryWithCorrelatedQueryFilter(Map<String, Object> queryContext)
@@ -446,6 +450,7 @@
     );
   }
 
+  @DecoupledTestConfig(ignoreExpectedQueriesReason = IgnoreQueriesReason.UNNEST_EXTRA_SCANQUERY)
   @MethodSource("provideQueryContexts")
   @ParameterizedTest(name = "{0}")
   public void testCorrelatedSubqueryWithCorrelatedQueryFilter_Scan(Map<String, Object> queryContext)
diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteJoinQueryTest.java b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteJoinQueryTest.java
index 026261b..4ab78be 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteJoinQueryTest.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteJoinQueryTest.java
@@ -84,6 +84,7 @@
 import org.apache.druid.segment.virtual.ListFilteredVirtualColumn;
 import org.apache.druid.server.QueryLifecycle;
 import org.apache.druid.server.security.Access;
+import org.apache.druid.sql.calcite.DecoupledTestConfig.IgnoreQueriesReason;
 import org.apache.druid.sql.calcite.DecoupledTestConfig.QuidemTestCaseReason;
 import org.apache.druid.sql.calcite.NotYetSupported.Modes;
 import org.apache.druid.sql.calcite.SqlTestFrameworkConfig.MinTopNThreshold;
@@ -4948,7 +4949,7 @@
     );
   }
 
-  @DecoupledTestConfig(quidemReason = QuidemTestCaseReason.IRRELEVANT_SCANQUERY, separateDefaultModeTest = true)
+  @DecoupledTestConfig(quidemReason = QuidemTestCaseReason.SCAN_QUERY_ON_FILTERED_DS_DOING_FILTERING, separateDefaultModeTest = true)
   @MethodSource("provideQueryContexts")
   @ParameterizedTest(name = "{0}")
   public void testNestedGroupByOnInlineDataSourceWithFilter(Map<String, Object> queryContext)
@@ -6139,7 +6140,6 @@
   }
 
   @Test
-  @NotYetSupported(Modes.UNNEST_NOT_SUPPORTED_CORRELATE_CONVERSION)
   public void testJoinsWithUnnestOnLeft()
   {
     // Segment map function of MSQ needs some work
@@ -6160,7 +6160,7 @@
                     join(
                         UnnestDataSource.create(
                             new TableDataSource(CalciteTests.DATASOURCE1),
-                            expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                            nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                             null
                         ),
                         new QueryDataSource(
@@ -6193,8 +6193,8 @@
     );
   }
 
+  @DecoupledTestConfig(ignoreExpectedQueriesReason = IgnoreQueriesReason.UNNEST_EXTRA_SCANQUERY)
   @Test
-  @NotYetSupported(Modes.UNNEST_NOT_SUPPORTED_CORRELATE_CONVERSION)
   public void testJoinsWithUnnestOverFilteredDSOnLeft()
   {
     // Segment map function of MSQ needs some work
@@ -6252,7 +6252,6 @@
   }
 
   @Test
-  @NotYetSupported(Modes.UNNEST_NOT_SUPPORTED_CORRELATE_CONVERSION)
   public void testJoinsWithUnnestOverJoin()
   {
     // Segment map function of MSQ needs some work
@@ -6288,7 +6287,7 @@
                                 "(\"dim2\" == \"j0.dim2\")",
                                 JoinType.INNER
                             ),
-                            expressionVirtualColumn("_j0.unnest", "\"dim3\"", ColumnType.STRING),
+                            nestedExpressionVirtualColumn("_j0.unnest", "\"dim3\"", ColumnType.STRING),
                             null
                         ),
                         new QueryDataSource(
@@ -6337,7 +6336,6 @@
   }
 
   @Test
-  @NotYetSupported(Modes.UNNEST_NOT_SUPPORTED_CORRELATE_CONVERSION)
   public void testSelfJoinsWithUnnestOnLeftAndRight()
   {
     // Segment map function of MSQ needs some work
@@ -6358,7 +6356,7 @@
                     join(
                         UnnestDataSource.create(
                             new TableDataSource(CalciteTests.DATASOURCE1),
-                            expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                            nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                             null
                         ),
                         new QueryDataSource(
@@ -6366,7 +6364,7 @@
                                 .intervals(querySegmentSpec(Filtration.eternity()))
                                 .dataSource(UnnestDataSource.create(
                                     new TableDataSource(CalciteTests.DATASOURCE1),
-                                    expressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
+                                    nestedExpressionVirtualColumn("j0.unnest", "\"dim3\"", ColumnType.STRING),
                                     null
                                 ))
                                 .columns("dim2", "j0.unnest")
@@ -6405,8 +6403,8 @@
     );
   }
 
+  @DecoupledTestConfig(ignoreExpectedQueriesReason = IgnoreQueriesReason.UNNEST_EXTRA_SCANQUERY)
   @Test
-  @NotYetSupported(Modes.UNNEST_NOT_SUPPORTED_CORRELATE_CONVERSION)
   public void testJoinsOverUnnestOverFilterDSOverJoin()
   {
     // Segment map function of MSQ needs some work
diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteNestedDataQueryTest.java b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteNestedDataQueryTest.java
index b03b669..013753a 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteNestedDataQueryTest.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteNestedDataQueryTest.java
@@ -75,6 +75,7 @@
 import org.apache.druid.segment.writeout.OffHeapMemorySegmentWriteOutMediumFactory;
 import org.apache.druid.server.SpecificSegmentsQuerySegmentWalker;
 import org.apache.druid.sql.calcite.CalciteNestedDataQueryTest.NestedComponentSupplier;
+import org.apache.druid.sql.calcite.NotYetSupported.Modes;
 import org.apache.druid.sql.calcite.filtration.Filtration;
 import org.apache.druid.sql.calcite.util.SqlTestFramework.StandardComponentSupplier;
 import org.apache.druid.sql.calcite.util.TestDataBuilder;
@@ -7347,6 +7348,7 @@
     );
   }
 
+  @NotYetSupported(Modes.ERROR_CANNOT_TRANSLATE_COUNT_DISTINCT)
   @Test
   public void testApproxCountDistinctOnUnsupportedComplexColumn()
   {
diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/DecoupledExtension.java b/sql/src/test/java/org/apache/druid/sql/calcite/DecoupledExtension.java
index 094a23c..e6311f8 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/DecoupledExtension.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/DecoupledExtension.java
@@ -21,6 +21,7 @@
 
 import com.google.common.collect.ImmutableMap;
 import org.apache.druid.common.config.NullHandling;
+import org.apache.druid.query.Query;
 import org.apache.druid.query.QueryContexts;
 import org.apache.druid.quidem.DruidQTestInfo;
 import org.apache.druid.quidem.ProjectPathUtils;
@@ -32,6 +33,7 @@
 import org.junit.jupiter.api.extension.ExtensionContext;
 
 import java.io.File;
+import java.util.List;
 
 public class DecoupledExtension implements BeforeEachCallback
 {
@@ -64,6 +66,8 @@
 
     boolean runQuidem = (decTestConfig != null && decTestConfig.quidemReason().isPresent());
 
+    boolean ignoreQueries = (decTestConfig != null && decTestConfig.ignoreExpectedQueriesReason().isPresent());
+
     CalciteTestConfig testConfig = baseTest.new CalciteTestConfig(CONTEXT_OVERRIDES)
     {
 
@@ -101,6 +105,17 @@
     };
 
     QueryTestBuilder builder = new QueryTestBuilder(testConfig)
+    {
+      @Override
+      public QueryTestBuilder expectedQueries(List<Query<?>> expectedQueries)
+      {
+        if (ignoreQueries) {
+          return this;
+        } else {
+          return super.expectedQueries(expectedQueries);
+        }
+      }
+    }
         .cannotVectorize(baseTest.cannotVectorize)
         .skipVectorize(baseTest.skipVectorize);
 
diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/DecoupledPlanningCalciteArraysQueryTest.java b/sql/src/test/java/org/apache/druid/sql/calcite/DecoupledPlanningCalciteArraysQueryTest.java
new file mode 100644
index 0000000..d1a64e8
--- /dev/null
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/DecoupledPlanningCalciteArraysQueryTest.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.sql.calcite;
+
+import org.apache.druid.sql.calcite.NotYetSupported.NotYetSupportedProcessor;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+@ExtendWith(NotYetSupportedProcessor.class)
+public class DecoupledPlanningCalciteArraysQueryTest extends CalciteArraysQueryTest
+{
+  @RegisterExtension
+  DecoupledExtension decoupledExtension = new DecoupledExtension(this);
+
+  @Override
+  protected QueryTestBuilder testBuilder()
+  {
+    return decoupledExtension.testBuilder();
+  }
+}
diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/DecoupledPlanningCalciteCorrelatedQueryTest.java b/sql/src/test/java/org/apache/druid/sql/calcite/DecoupledPlanningCalciteCorrelatedQueryTest.java
new file mode 100644
index 0000000..031167c
--- /dev/null
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/DecoupledPlanningCalciteCorrelatedQueryTest.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.sql.calcite;
+
+import org.apache.druid.sql.calcite.NotYetSupported.NotYetSupportedProcessor;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+@ExtendWith(NotYetSupportedProcessor.class)
+public class DecoupledPlanningCalciteCorrelatedQueryTest extends CalciteCorrelatedQueryTest
+{
+  @RegisterExtension
+  DecoupledExtension decoupledExtension = new DecoupledExtension(this);
+
+  @Override
+  protected QueryTestBuilder testBuilder()
+  {
+    return decoupledExtension.testBuilder();
+  }
+}
diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/DecoupledPlanningCalciteNestedDataQueryTest.java b/sql/src/test/java/org/apache/druid/sql/calcite/DecoupledPlanningCalciteNestedDataQueryTest.java
new file mode 100644
index 0000000..b4e246d
--- /dev/null
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/DecoupledPlanningCalciteNestedDataQueryTest.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.sql.calcite;
+
+import org.apache.druid.sql.calcite.NotYetSupported.NotYetSupportedProcessor;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+@ExtendWith(NotYetSupportedProcessor.class)
+public class DecoupledPlanningCalciteNestedDataQueryTest extends CalciteNestedDataQueryTest
+{
+  @RegisterExtension
+  DecoupledExtension decoupledExtension = new DecoupledExtension(this);
+
+  @Override
+  protected QueryTestBuilder testBuilder()
+  {
+    return decoupledExtension.testBuilder();
+  }
+}
diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/DecoupledTestConfig.java b/sql/src/test/java/org/apache/druid/sql/calcite/DecoupledTestConfig.java
index 9bc4fe0..10d631b 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/DecoupledTestConfig.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/DecoupledTestConfig.java
@@ -21,6 +21,8 @@
 
 import org.apache.calcite.rel.rules.CoreRules;
 import org.apache.druid.query.QueryContexts;
+import org.apache.druid.query.UnnestDataSource;
+
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -40,6 +42,25 @@
    */
   QuidemTestCaseReason quidemReason() default QuidemTestCaseReason.NONE;
 
+  /**
+   * Run the tests normally; however disable the native plan checks.
+   */
+  IgnoreQueriesReason ignoreExpectedQueriesReason() default IgnoreQueriesReason.NONE;
+
+  enum IgnoreQueriesReason
+  {
+    NONE,
+    /**
+     * An extra ScanQuery to service a Project and/or Filter was added.
+     */
+    UNNEST_EXTRA_SCANQUERY;
+
+    public boolean isPresent()
+    {
+      return this != NONE;
+    }
+  }
+
   enum QuidemTestCaseReason
   {
     NONE,
@@ -114,7 +135,29 @@
     /**
      * Strange things; needs more investigation
      */
-    IRRELEVANT_SCANQUERY;
+    IRRELEVANT_SCANQUERY,
+    /**
+     * Extra scan query under {@link UnnestDataSource}.
+     */
+    UNNEST_EXTRA_SCAN,
+    /**
+     * Extra virtualcolumn appeared; seemingly unused
+     */
+    UNUSED_VIRTUALCOLUMN,
+    /**
+     * Unnest uses a VC to access a constant like array(1,2,3).
+     */
+    UNNEST_VC_USES_PROJECTED_CONSTANT,
+    /**
+     * This should need some investigation.
+     *
+     * Its not invalid; just strange.
+     */
+    SCAN_QUERY_ON_FILTERED_DS_DOING_FILTERING,
+    /**
+     * New plan UNNEST-s a different resultset.
+     */
+    UNNEST_DIFFERENT_RESULTSET;
 
     public boolean isPresent()
     {
diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/NotYetSupported.java b/sql/src/test/java/org/apache/druid/sql/calcite/NotYetSupported.java
index 2939d30..8dad971 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/NotYetSupported.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/NotYetSupported.java
@@ -91,10 +91,12 @@
     UNSUPPORTED_NULL_ORDERING(DruidException.class, "(A|DE)SCENDING ordering with NULLS (LAST|FIRST)"),
     UNION_WITH_COMPLEX_OPERAND(DruidException.class, "Only Table and Values are supported as inputs for Union"),
     UNION_MORE_STRICT_ROWTYPE_CHECK(DruidException.class, "Row signature mismatch in Union inputs"),
-    UNNEST_NOT_SUPPORTED_CORRELATE_CONVERSION(DruidException.class, "Missing conversion( is|s are) LogicalCorrelate"),
     SORT_REMOVE_TROUBLE(DruidException.class, "Calcite assertion violated.*Sort\\.<init>"),
     SORT_REMOVE_CONSTANT_KEYS_CONFLICT(DruidException.class, "not enough rules"),
-    REQUIRE_TIME_CONDITION(CannotBuildQueryException.class, "requireTimeCondition is enabled");
+    REQUIRE_TIME_CONDITION(CannotBuildQueryException.class, "requireTimeCondition is enabled"),
+    ERROR_CANNOT_TRANSLATE_COUNT_DISTINCT(AssertionError.class, "Cannot translate aggregator.COUNT.DISTINCT"),
+    UNNEST_INLINED(Exception.class, "Missing conversion is Uncollect"),
+    UNNEST_RESULT_MISMATCH(AssertionError.class, "(Result count mismatch|column content mismatch)");
     // @formatter:on
 
     public Class<? extends Throwable> throwableClass;
diff --git a/sql/src/test/quidem/org.apache.druid.quidem.SqlQuidemTest/unnest.iq b/sql/src/test/quidem/org.apache.druid.quidem.SqlQuidemTest/unnest.iq
new file mode 100644
index 0000000..aac89b7
--- /dev/null
+++ b/sql/src/test/quidem/org.apache.druid.quidem.SqlQuidemTest/unnest.iq
@@ -0,0 +1,89 @@
+#!set plannerStrategy DECOUPLED
+!use druidtest://?numMergeBuffers=3
+!set outputformat mysql
+
+SELECT d3 FROM (select * from druid.numfoo where dim2='a'), UNNEST(MV_TO_ARRAY(dim3)) as unnested (d3);
+LogicalProject(d3=[$17])
+  LogicalProject(__time=[$0], dim1=[$1], dim2=[$2], dim3=[$3], dim4=[$4], dim5=[$5], dim6=[$6], d1=[$7], d2=[$8], f1=[$9], f2=[$10], l1=[$11], l2=[$12], cnt=[$13], m1=[$14], m2=[$15], unique_dim1=[$16], d3=[$18])
+    LogicalCorrelate(correlation=[$cor0], joinType=[inner], requiredColumns=[{17}])
+      LogicalProject(__time=[$0], dim1=[$1], dim2=[$2], dim3=[$3], dim4=[$4], dim5=[$5], dim6=[$6], d1=[$7], d2=[$8], f1=[$9], f2=[$10], l1=[$11], l2=[$12], cnt=[$13], m1=[$14], m2=[$15], unique_dim1=[$16], $f17=[MV_TO_ARRAY($3)])
+        LogicalFilter(condition=[=($2, 'a')])
+          LogicalTableScan(table=[[druid, numfoo]])
+      LogicalProject(d3=[$0])
+        Uncollect
+          LogicalProject(EXPR$0=[$cor0.$f17])
+            LogicalValues(tuples=[[{ 0 }]])
+
+!convertedPlan
+
+
+LogicalProject(d3=[$18])
+  LogicalCorrelate(correlation=[$cor0], joinType=[inner], requiredColumns=[{17}])
+    LogicalProject(__time=[$0], dim1=[$1], dim2=[CAST('a':VARCHAR):VARCHAR], dim3=[$3], dim4=[$4], dim5=[$5], dim6=[$6], d1=[$7], d2=[$8], f1=[$9], f2=[$10], l1=[$11], l2=[$12], cnt=[$13], m1=[$14], m2=[$15], unique_dim1=[$16], $f17=[MV_TO_ARRAY($3)])
+      LogicalFilter(condition=[=($2, 'a')])
+        LogicalTableScan(table=[[druid, numfoo]])
+    Uncollect
+      LogicalProject(EXPR$0=[$cor0.$f17])
+        LogicalValues(tuples=[[{ 0 }]])
+
+!logicalPlan
+
+LogicalProject(d3=[$17])
+  LogicalCorrelate(correlation=[$cor2], joinType=[inner], requiredColumns=[{3}])
+    LogicalFilter(condition=[=($2, 'a')])
+      LogicalTableScan(table=[[druid, numfoo]])
+    DruidUnnestRel(expr=[MV_TO_ARRAY($cor2.dim3)], filter=[null])
+
+!druidPlan
+{
+  "queryType" : "scan",
+  "dataSource" : {
+    "type" : "unnest",
+    "base" : {
+      "type" : "filter",
+      "base" : {
+        "type" : "table",
+        "name" : "numfoo"
+      },
+      "filter" : {
+        "type" : "equals",
+        "column" : "dim2",
+        "matchValueType" : "STRING",
+        "matchValue" : "a"
+      }
+    },
+    "virtualColumn" : {
+      "type" : "expression",
+      "name" : "j0.unnest",
+      "expression" : "\"dim3\"",
+      "outputType" : "STRING"
+    },
+    "unnestFilter" : null
+  },
+  "intervals" : {
+    "type" : "intervals",
+    "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+  },
+  "resultFormat" : "compactedList",
+  "columns" : [ "j0.unnest" ],
+  "columnTypes" : [ "STRING" ],
+  "granularity" : {
+    "type" : "all"
+  },
+  "legacy" : false
+}
+!nativePlan
++----+
+| d3 |
++----+
+|    |
+| a  |
+| b  |
++----+
+(3 rows)
+
+!ok
+
+# LogicalPlan plan = calcite.plan();
+# PhysicalQuery pq = DruidQueryGenerator.generate(plan);
+
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestExtractionFn@NullHandling=default.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestExtractionFn@NullHandling=default.iq
new file mode 100644
index 0000000..2acefa4
--- /dev/null
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestExtractionFn@NullHandling=default.iq
@@ -0,0 +1,81 @@
+# testUnnestExtractionFn@NullHandling=default case-crc:404dc668
+# quidem testcase reason: UNNEST_DIFFERENT_RESULTSET
+!set debug true
+!set defaultTimeout 300000
+!set maxScatterGatherBytes 9223372036854775807
+!set plannerStrategy DECOUPLED
+!set sqlCurrentTimestamp 2000-01-01T00:00:00Z
+!set sqlQueryId dummy
+!set sqlStringifyArrays false
+!set outputformat mysql
+!use druidtest:///
+SELECT substring(d3,1) FROM druid.numfoo, UNNEST(MV_TO_ARRAY(dim3)) as unnested (d3) WHERE substring(d3,1) <> 'b';
++--------+
+| EXPR$0 |
++--------+
+| a      |
+| c      |
+| d      |
++--------+
+(3 rows)
+
+!ok
+LogicalProject(EXPR$0=[SUBSTRING($18, 1)])
+  LogicalUnnest(unnestExpr=[MV_TO_ARRAY($3)], filter=[<>(SUBSTRING($0, 1), 'b')])
+    LogicalProject(__time=[$0], dim1=[$1], dim2=[$2], dim3=[$3], dim4=[$4], dim5=[$5], dim6=[$6], d1=[$7], d2=[$8], f1=[$9], f2=[$10], l1=[$11], l2=[$12], cnt=[$13], m1=[$14], m2=[$15], unique_dim1=[$16], __time0=[$0])
+      LogicalTableScan(table=[[druid, numfoo]])
+
+!logicalPlan
+DruidProject(EXPR$0=[SUBSTRING($18, 1)], druid=[logical])
+  DruidUnnest(unnestExpr=[MV_TO_ARRAY($3)], filter=[<>(SUBSTRING($0, 1), 'b')])
+    DruidProject(__time=[$0], dim1=[$1], dim2=[$2], dim3=[$3], dim4=[$4], dim5=[$5], dim6=[$6], d1=[$7], d2=[$8], f1=[$9], f2=[$10], l1=[$11], l2=[$12], cnt=[$13], m1=[$14], m2=[$15], unique_dim1=[$16], __time0=[$0], druid=[logical])
+      DruidTableScan(table=[[druid, numfoo]], druid=[logical])
+
+!druidPlan
+{
+  "queryType" : "scan",
+  "dataSource" : {
+    "type" : "unnest",
+    "base" : {
+      "type" : "table",
+      "name" : "numfoo"
+    },
+    "virtualColumn" : {
+      "type" : "expression",
+      "name" : "j0.unnest",
+      "expression" : "mv_to_array(\"dim3\")",
+      "outputType" : "ARRAY<STRING>"
+    },
+    "unnestFilter" : {
+      "type" : "not",
+      "field" : {
+        "type" : "selector",
+        "dimension" : "j0.unnest",
+        "value" : "b",
+        "extractionFn" : {
+          "type" : "substring",
+          "index" : 0,
+          "length" : null
+        }
+      }
+    }
+  },
+  "intervals" : {
+    "type" : "intervals",
+    "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+  },
+  "virtualColumns" : [ {
+    "type" : "expression",
+    "name" : "v0",
+    "expression" : "substring(\"j0.unnest\", 0, -1)",
+    "outputType" : "STRING"
+  } ],
+  "resultFormat" : "compactedList",
+  "columns" : [ "v0" ],
+  "columnTypes" : [ "STRING" ],
+  "granularity" : {
+    "type" : "all"
+  },
+  "legacy" : false
+}
+!nativePlan
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestExtractionFn@NullHandling=sql.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestExtractionFn@NullHandling=sql.iq
new file mode 100644
index 0000000..ca41ee3
--- /dev/null
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestExtractionFn@NullHandling=sql.iq
@@ -0,0 +1,72 @@
+# testUnnestExtractionFn@NullHandling=sql case-crc:404dc668
+# quidem testcase reason: UNNEST_DIFFERENT_RESULTSET
+!set debug true
+!set defaultTimeout 300000
+!set maxScatterGatherBytes 9223372036854775807
+!set plannerStrategy DECOUPLED
+!set sqlCurrentTimestamp 2000-01-01T00:00:00Z
+!set sqlQueryId dummy
+!set sqlStringifyArrays false
+!set outputformat mysql
+!use druidtest:///
+SELECT substring(d3,1) FROM druid.numfoo, UNNEST(MV_TO_ARRAY(dim3)) as unnested (d3) WHERE substring(d3,1) <> 'b';
++--------+
+| EXPR$0 |
++--------+
+| a      |
+| c      |
+| d      |
++--------+
+(3 rows)
+
+!ok
+LogicalProject(EXPR$0=[SUBSTRING($18, 1)])
+  LogicalUnnest(unnestExpr=[MV_TO_ARRAY($3)], filter=[<>(SUBSTRING($0, 1), 'b')])
+    LogicalProject(__time=[$0], dim1=[$1], dim2=[$2], dim3=[$3], dim4=[$4], dim5=[$5], dim6=[$6], d1=[$7], d2=[$8], f1=[$9], f2=[$10], l1=[$11], l2=[$12], cnt=[$13], m1=[$14], m2=[$15], unique_dim1=[$16], __time0=[$0])
+      LogicalTableScan(table=[[druid, numfoo]])
+
+!logicalPlan
+DruidProject(EXPR$0=[SUBSTRING($18, 1)], druid=[logical])
+  DruidUnnest(unnestExpr=[MV_TO_ARRAY($3)], filter=[<>(SUBSTRING($0, 1), 'b')])
+    DruidProject(__time=[$0], dim1=[$1], dim2=[$2], dim3=[$3], dim4=[$4], dim5=[$5], dim6=[$6], d1=[$7], d2=[$8], f1=[$9], f2=[$10], l1=[$11], l2=[$12], cnt=[$13], m1=[$14], m2=[$15], unique_dim1=[$16], __time0=[$0], druid=[logical])
+      DruidTableScan(table=[[druid, numfoo]], druid=[logical])
+
+!druidPlan
+{
+  "queryType" : "scan",
+  "dataSource" : {
+    "type" : "unnest",
+    "base" : {
+      "type" : "table",
+      "name" : "numfoo"
+    },
+    "virtualColumn" : {
+      "type" : "expression",
+      "name" : "j0.unnest",
+      "expression" : "mv_to_array(\"dim3\")",
+      "outputType" : "ARRAY<STRING>"
+    },
+    "unnestFilter" : {
+      "type" : "expression",
+      "expression" : "(substring(\"j0.unnest\", 0, -1) != 'b')"
+    }
+  },
+  "intervals" : {
+    "type" : "intervals",
+    "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+  },
+  "virtualColumns" : [ {
+    "type" : "expression",
+    "name" : "v0",
+    "expression" : "substring(\"j0.unnest\", 0, -1)",
+    "outputType" : "STRING"
+  } ],
+  "resultFormat" : "compactedList",
+  "columns" : [ "v0" ],
+  "columnTypes" : [ "STRING" ],
+  "granularity" : {
+    "type" : "all"
+  },
+  "legacy" : false
+}
+!nativePlan
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithFilters@NullHandling=default.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithFilters@NullHandling=default.iq
new file mode 100644
index 0000000..64963f6
--- /dev/null
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithFilters@NullHandling=default.iq
@@ -0,0 +1,92 @@
+# testUnnestWithFilters@NullHandling=default case-crc:810b3e0d
+# quidem testcase reason: UNNEST_EXTRA_SCAN
+!set debug true
+!set defaultTimeout 300000
+!set maxScatterGatherBytes 9223372036854775807
+!set plannerStrategy DECOUPLED
+!set sqlCurrentTimestamp 2000-01-01T00:00:00Z
+!set sqlQueryId dummy
+!set sqlStringifyArrays false
+!set outputformat mysql
+!use druidtest:///
+SELECT d3 FROM (select * from druid.numfoo where dim2='a'), UNNEST(MV_TO_ARRAY(dim3)) as unnested (d3);
++----+
+| d3 |
++----+
+| a  |
+| b  |
++----+
+(2 rows)
+
+!ok
+LogicalProject(d3=[$18])
+  LogicalUnnest(unnestExpr=[MV_TO_ARRAY($3)])
+    LogicalProject(__time=[$0], dim1=[$1], $f2=[CAST('a':VARCHAR):VARCHAR], dim3=[$3], dim4=[$4], dim5=[$5], dim6=[$6], d1=[$7], d2=[$8], f1=[$9], f2=[$10], l1=[$11], l2=[$12], cnt=[$13], m1=[$14], m2=[$15], unique_dim1=[$16], __time0=[$0])
+      LogicalFilter(condition=[=($2, 'a')])
+        LogicalTableScan(table=[[druid, numfoo]])
+
+!logicalPlan
+DruidProject(d3=[$18], druid=[logical])
+  DruidUnnest(unnestExpr=[MV_TO_ARRAY($3)])
+    DruidProject(__time=[$0], dim1=[$1], $f2=[CAST('a':VARCHAR):VARCHAR], dim3=[$3], dim4=[$4], dim5=[$5], dim6=[$6], d1=[$7], d2=[$8], f1=[$9], f2=[$10], l1=[$11], l2=[$12], cnt=[$13], m1=[$14], m2=[$15], unique_dim1=[$16], __time0=[$0], druid=[logical])
+      DruidFilter(condition=[=($2, 'a')])
+        DruidTableScan(table=[[druid, numfoo]], druid=[logical])
+
+!druidPlan
+{
+  "queryType" : "scan",
+  "dataSource" : {
+    "type" : "unnest",
+    "base" : {
+      "type" : "query",
+      "query" : {
+        "queryType" : "scan",
+        "dataSource" : {
+          "type" : "table",
+          "name" : "numfoo"
+        },
+        "intervals" : {
+          "type" : "intervals",
+          "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+        },
+        "virtualColumns" : [ {
+          "type" : "expression",
+          "name" : "v0",
+          "expression" : "'a'",
+          "outputType" : "STRING"
+        } ],
+        "resultFormat" : "compactedList",
+        "filter" : {
+          "type" : "selector",
+          "dimension" : "dim2",
+          "value" : "a"
+        },
+        "columns" : [ "__time", "cnt", "d1", "d2", "dim1", "dim3", "dim4", "dim5", "dim6", "f1", "f2", "l1", "l2", "m1", "m2", "unique_dim1", "v0" ],
+        "columnTypes" : [ "LONG", "LONG", "DOUBLE", "DOUBLE", "STRING", "STRING", "STRING", "STRING", "STRING", "FLOAT", "FLOAT", "LONG", "LONG", "FLOAT", "DOUBLE", "COMPLEX<hyperUnique>", "STRING" ],
+        "granularity" : {
+          "type" : "all"
+        },
+        "legacy" : false
+      }
+    },
+    "virtualColumn" : {
+      "type" : "expression",
+      "name" : "j0.unnest",
+      "expression" : "mv_to_array(\"dim3\")",
+      "outputType" : "ARRAY<STRING>"
+    },
+    "unnestFilter" : null
+  },
+  "intervals" : {
+    "type" : "intervals",
+    "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+  },
+  "resultFormat" : "compactedList",
+  "columns" : [ "j0.unnest" ],
+  "columnTypes" : [ "STRING" ],
+  "granularity" : {
+    "type" : "all"
+  },
+  "legacy" : false
+}
+!nativePlan
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithFilters@NullHandling=sql.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithFilters@NullHandling=sql.iq
new file mode 100644
index 0000000..f032fc5
--- /dev/null
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithFilters@NullHandling=sql.iq
@@ -0,0 +1,94 @@
+# testUnnestWithFilters@NullHandling=sql case-crc:810b3e0d
+# quidem testcase reason: UNNEST_EXTRA_SCAN
+!set debug true
+!set defaultTimeout 300000
+!set maxScatterGatherBytes 9223372036854775807
+!set plannerStrategy DECOUPLED
+!set sqlCurrentTimestamp 2000-01-01T00:00:00Z
+!set sqlQueryId dummy
+!set sqlStringifyArrays false
+!set outputformat mysql
+!use druidtest:///
+SELECT d3 FROM (select * from druid.numfoo where dim2='a'), UNNEST(MV_TO_ARRAY(dim3)) as unnested (d3);
++----+
+| d3 |
++----+
+|    |
+| a  |
+| b  |
++----+
+(3 rows)
+
+!ok
+LogicalProject(d3=[$18])
+  LogicalUnnest(unnestExpr=[MV_TO_ARRAY($3)])
+    LogicalProject(__time=[$0], dim1=[$1], $f2=[CAST('a':VARCHAR):VARCHAR], dim3=[$3], dim4=[$4], dim5=[$5], dim6=[$6], d1=[$7], d2=[$8], f1=[$9], f2=[$10], l1=[$11], l2=[$12], cnt=[$13], m1=[$14], m2=[$15], unique_dim1=[$16], __time0=[$0])
+      LogicalFilter(condition=[=($2, 'a')])
+        LogicalTableScan(table=[[druid, numfoo]])
+
+!logicalPlan
+DruidProject(d3=[$18], druid=[logical])
+  DruidUnnest(unnestExpr=[MV_TO_ARRAY($3)])
+    DruidProject(__time=[$0], dim1=[$1], $f2=[CAST('a':VARCHAR):VARCHAR], dim3=[$3], dim4=[$4], dim5=[$5], dim6=[$6], d1=[$7], d2=[$8], f1=[$9], f2=[$10], l1=[$11], l2=[$12], cnt=[$13], m1=[$14], m2=[$15], unique_dim1=[$16], __time0=[$0], druid=[logical])
+      DruidFilter(condition=[=($2, 'a')])
+        DruidTableScan(table=[[druid, numfoo]], druid=[logical])
+
+!druidPlan
+{
+  "queryType" : "scan",
+  "dataSource" : {
+    "type" : "unnest",
+    "base" : {
+      "type" : "query",
+      "query" : {
+        "queryType" : "scan",
+        "dataSource" : {
+          "type" : "table",
+          "name" : "numfoo"
+        },
+        "intervals" : {
+          "type" : "intervals",
+          "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+        },
+        "virtualColumns" : [ {
+          "type" : "expression",
+          "name" : "v0",
+          "expression" : "'a'",
+          "outputType" : "STRING"
+        } ],
+        "resultFormat" : "compactedList",
+        "filter" : {
+          "type" : "equals",
+          "column" : "dim2",
+          "matchValueType" : "STRING",
+          "matchValue" : "a"
+        },
+        "columns" : [ "__time", "cnt", "d1", "d2", "dim1", "dim3", "dim4", "dim5", "dim6", "f1", "f2", "l1", "l2", "m1", "m2", "unique_dim1", "v0" ],
+        "columnTypes" : [ "LONG", "LONG", "DOUBLE", "DOUBLE", "STRING", "STRING", "STRING", "STRING", "STRING", "FLOAT", "FLOAT", "LONG", "LONG", "FLOAT", "DOUBLE", "COMPLEX<hyperUnique>", "STRING" ],
+        "granularity" : {
+          "type" : "all"
+        },
+        "legacy" : false
+      }
+    },
+    "virtualColumn" : {
+      "type" : "expression",
+      "name" : "j0.unnest",
+      "expression" : "mv_to_array(\"dim3\")",
+      "outputType" : "ARRAY<STRING>"
+    },
+    "unnestFilter" : null
+  },
+  "intervals" : {
+    "type" : "intervals",
+    "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+  },
+  "resultFormat" : "compactedList",
+  "columns" : [ "j0.unnest" ],
+  "columnTypes" : [ "STRING" ],
+  "granularity" : {
+    "type" : "all"
+  },
+  "legacy" : false
+}
+!nativePlan
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithFiltersInnerLimit@NullHandling=default.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithFiltersInnerLimit@NullHandling=default.iq
new file mode 100644
index 0000000..0d98641
--- /dev/null
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithFiltersInnerLimit@NullHandling=default.iq
@@ -0,0 +1,95 @@
+# testUnnestWithFiltersInnerLimit@NullHandling=default case-crc:1f5acfc8
+# quidem testcase reason: UNUSED_VIRTUALCOLUMN
+!set debug true
+!set defaultTimeout 300000
+!set maxScatterGatherBytes 9223372036854775807
+!set plannerStrategy DECOUPLED
+!set sqlCurrentTimestamp 2000-01-01T00:00:00Z
+!set sqlQueryId dummy
+!set sqlStringifyArrays false
+!set outputformat mysql
+!use druidtest:///
+SELECT d3 FROM (select dim2,dim3 from druid.numfoo where dim2='a' LIMIT 2), UNNEST(MV_TO_ARRAY(dim3)) as unnested (d3);
++----+
+| d3 |
++----+
+| a  |
+| b  |
++----+
+(2 rows)
+
+!ok
+LogicalProject(d3=[$3])
+  LogicalUnnest(unnestExpr=[MV_TO_ARRAY($1)])
+    LogicalProject($f0=[CAST('a':VARCHAR):VARCHAR], dim3=[$3], __time=[$0])
+      LogicalSort(fetch=[2])
+        LogicalFilter(condition=[=($2, 'a')])
+          LogicalTableScan(table=[[druid, numfoo]])
+
+!logicalPlan
+DruidProject(d3=[$3], druid=[logical])
+  DruidUnnest(unnestExpr=[MV_TO_ARRAY($1)])
+    DruidProject($f0=[CAST('a':VARCHAR):VARCHAR], dim3=[$3], __time=[$0], druid=[logical])
+      DruidSort(fetch=[2], druid=[logical])
+        DruidFilter(condition=[=($2, 'a')])
+          DruidTableScan(table=[[druid, numfoo]], druid=[logical])
+
+!druidPlan
+{
+  "queryType" : "scan",
+  "dataSource" : {
+    "type" : "unnest",
+    "base" : {
+      "type" : "query",
+      "query" : {
+        "queryType" : "scan",
+        "dataSource" : {
+          "type" : "table",
+          "name" : "numfoo"
+        },
+        "intervals" : {
+          "type" : "intervals",
+          "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+        },
+        "virtualColumns" : [ {
+          "type" : "expression",
+          "name" : "v0",
+          "expression" : "'a'",
+          "outputType" : "STRING"
+        } ],
+        "resultFormat" : "compactedList",
+        "limit" : 2,
+        "filter" : {
+          "type" : "selector",
+          "dimension" : "dim2",
+          "value" : "a"
+        },
+        "columns" : [ "__time", "dim3", "v0" ],
+        "columnTypes" : [ "LONG", "STRING", "STRING" ],
+        "granularity" : {
+          "type" : "all"
+        },
+        "legacy" : false
+      }
+    },
+    "virtualColumn" : {
+      "type" : "expression",
+      "name" : "j0.unnest",
+      "expression" : "mv_to_array(\"dim3\")",
+      "outputType" : "ARRAY<STRING>"
+    },
+    "unnestFilter" : null
+  },
+  "intervals" : {
+    "type" : "intervals",
+    "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+  },
+  "resultFormat" : "compactedList",
+  "columns" : [ "j0.unnest" ],
+  "columnTypes" : [ "STRING" ],
+  "granularity" : {
+    "type" : "all"
+  },
+  "legacy" : false
+}
+!nativePlan
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithFiltersInnerLimit@NullHandling=sql.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithFiltersInnerLimit@NullHandling=sql.iq
new file mode 100644
index 0000000..878106d
--- /dev/null
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithFiltersInnerLimit@NullHandling=sql.iq
@@ -0,0 +1,97 @@
+# testUnnestWithFiltersInnerLimit@NullHandling=sql case-crc:1f5acfc8
+# quidem testcase reason: UNUSED_VIRTUALCOLUMN
+!set debug true
+!set defaultTimeout 300000
+!set maxScatterGatherBytes 9223372036854775807
+!set plannerStrategy DECOUPLED
+!set sqlCurrentTimestamp 2000-01-01T00:00:00Z
+!set sqlQueryId dummy
+!set sqlStringifyArrays false
+!set outputformat mysql
+!use druidtest:///
+SELECT d3 FROM (select dim2,dim3 from druid.numfoo where dim2='a' LIMIT 2), UNNEST(MV_TO_ARRAY(dim3)) as unnested (d3);
++----+
+| d3 |
++----+
+|    |
+| a  |
+| b  |
++----+
+(3 rows)
+
+!ok
+LogicalProject(d3=[$3])
+  LogicalUnnest(unnestExpr=[MV_TO_ARRAY($1)])
+    LogicalProject($f0=[CAST('a':VARCHAR):VARCHAR], dim3=[$3], __time=[$0])
+      LogicalSort(fetch=[2])
+        LogicalFilter(condition=[=($2, 'a')])
+          LogicalTableScan(table=[[druid, numfoo]])
+
+!logicalPlan
+DruidProject(d3=[$3], druid=[logical])
+  DruidUnnest(unnestExpr=[MV_TO_ARRAY($1)])
+    DruidProject($f0=[CAST('a':VARCHAR):VARCHAR], dim3=[$3], __time=[$0], druid=[logical])
+      DruidSort(fetch=[2], druid=[logical])
+        DruidFilter(condition=[=($2, 'a')])
+          DruidTableScan(table=[[druid, numfoo]], druid=[logical])
+
+!druidPlan
+{
+  "queryType" : "scan",
+  "dataSource" : {
+    "type" : "unnest",
+    "base" : {
+      "type" : "query",
+      "query" : {
+        "queryType" : "scan",
+        "dataSource" : {
+          "type" : "table",
+          "name" : "numfoo"
+        },
+        "intervals" : {
+          "type" : "intervals",
+          "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+        },
+        "virtualColumns" : [ {
+          "type" : "expression",
+          "name" : "v0",
+          "expression" : "'a'",
+          "outputType" : "STRING"
+        } ],
+        "resultFormat" : "compactedList",
+        "limit" : 2,
+        "filter" : {
+          "type" : "equals",
+          "column" : "dim2",
+          "matchValueType" : "STRING",
+          "matchValue" : "a"
+        },
+        "columns" : [ "__time", "dim3", "v0" ],
+        "columnTypes" : [ "LONG", "STRING", "STRING" ],
+        "granularity" : {
+          "type" : "all"
+        },
+        "legacy" : false
+      }
+    },
+    "virtualColumn" : {
+      "type" : "expression",
+      "name" : "j0.unnest",
+      "expression" : "mv_to_array(\"dim3\")",
+      "outputType" : "ARRAY<STRING>"
+    },
+    "unnestFilter" : null
+  },
+  "intervals" : {
+    "type" : "intervals",
+    "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+  },
+  "resultFormat" : "compactedList",
+  "columns" : [ "j0.unnest" ],
+  "columnTypes" : [ "STRING" ],
+  "granularity" : {
+    "type" : "all"
+  },
+  "legacy" : false
+}
+!nativePlan
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithFiltersInsideAndOutside@NullHandling=default.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithFiltersInsideAndOutside@NullHandling=default.iq
new file mode 100644
index 0000000..ca22c18
--- /dev/null
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithFiltersInsideAndOutside@NullHandling=default.iq
@@ -0,0 +1,112 @@
+# testUnnestWithFiltersInsideAndOutside@NullHandling=default case-crc:10c26262
+# quidem testcase reason: UNNEST_EXTRA_SCAN
+!set debug true
+!set defaultTimeout 300000
+!set maxScatterGatherBytes 9223372036854775807
+!set plannerStrategy DECOUPLED
+!set sqlCurrentTimestamp 2000-01-01T00:00:00Z
+!set sqlQueryId dummy
+!set sqlStringifyArrays false
+!set outputformat mysql
+!use druidtest:///
+SELECT d3 FROM
+  (select * from druid.numfoo where dim2='a') as t,
+  UNNEST(MV_TO_ARRAY(dim3)) as unnested (d3)
+WHERE t.dim1 <> 'foo'
+AND unnested.d3 <> 'b';
++----+
+| d3 |
++----+
+| a  |
++----+
+(1 row)
+
+!ok
+LogicalProject(d3=[$18])
+  LogicalUnnest(unnestExpr=[MV_TO_ARRAY($3)], filter=[<>($0, 'b')])
+    LogicalProject(__time=[$0], dim1=[$1], $f2=[CAST('a':VARCHAR):VARCHAR], dim3=[$3], dim4=[$4], dim5=[$5], dim6=[$6], d1=[$7], d2=[$8], f1=[$9], f2=[$10], l1=[$11], l2=[$12], cnt=[$13], m1=[$14], m2=[$15], unique_dim1=[$16], __time0=[$0])
+      LogicalFilter(condition=[AND(=($2, 'a'), <>($1, 'foo'))])
+        LogicalTableScan(table=[[druid, numfoo]])
+
+!logicalPlan
+DruidProject(d3=[$18], druid=[logical])
+  DruidUnnest(unnestExpr=[MV_TO_ARRAY($3)], filter=[<>($0, 'b')])
+    DruidProject(__time=[$0], dim1=[$1], $f2=[CAST('a':VARCHAR):VARCHAR], dim3=[$3], dim4=[$4], dim5=[$5], dim6=[$6], d1=[$7], d2=[$8], f1=[$9], f2=[$10], l1=[$11], l2=[$12], cnt=[$13], m1=[$14], m2=[$15], unique_dim1=[$16], __time0=[$0], druid=[logical])
+      DruidFilter(condition=[AND(=($2, 'a'), <>($1, 'foo'))])
+        DruidTableScan(table=[[druid, numfoo]], druid=[logical])
+
+!druidPlan
+{
+  "queryType" : "scan",
+  "dataSource" : {
+    "type" : "unnest",
+    "base" : {
+      "type" : "query",
+      "query" : {
+        "queryType" : "scan",
+        "dataSource" : {
+          "type" : "table",
+          "name" : "numfoo"
+        },
+        "intervals" : {
+          "type" : "intervals",
+          "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+        },
+        "virtualColumns" : [ {
+          "type" : "expression",
+          "name" : "v0",
+          "expression" : "'a'",
+          "outputType" : "STRING"
+        } ],
+        "resultFormat" : "compactedList",
+        "filter" : {
+          "type" : "and",
+          "fields" : [ {
+            "type" : "selector",
+            "dimension" : "dim2",
+            "value" : "a"
+          }, {
+            "type" : "not",
+            "field" : {
+              "type" : "selector",
+              "dimension" : "dim1",
+              "value" : "foo"
+            }
+          } ]
+        },
+        "columns" : [ "__time", "cnt", "d1", "d2", "dim1", "dim3", "dim4", "dim5", "dim6", "f1", "f2", "l1", "l2", "m1", "m2", "unique_dim1", "v0" ],
+        "columnTypes" : [ "LONG", "LONG", "DOUBLE", "DOUBLE", "STRING", "STRING", "STRING", "STRING", "STRING", "FLOAT", "FLOAT", "LONG", "LONG", "FLOAT", "DOUBLE", "COMPLEX<hyperUnique>", "STRING" ],
+        "granularity" : {
+          "type" : "all"
+        },
+        "legacy" : false
+      }
+    },
+    "virtualColumn" : {
+      "type" : "expression",
+      "name" : "j0.unnest",
+      "expression" : "mv_to_array(\"dim3\")",
+      "outputType" : "ARRAY<STRING>"
+    },
+    "unnestFilter" : {
+      "type" : "not",
+      "field" : {
+        "type" : "selector",
+        "dimension" : "j0.unnest",
+        "value" : "b"
+      }
+    }
+  },
+  "intervals" : {
+    "type" : "intervals",
+    "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+  },
+  "resultFormat" : "compactedList",
+  "columns" : [ "j0.unnest" ],
+  "columnTypes" : [ "STRING" ],
+  "granularity" : {
+    "type" : "all"
+  },
+  "legacy" : false
+}
+!nativePlan
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithFiltersInsideAndOutside@NullHandling=sql.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithFiltersInsideAndOutside@NullHandling=sql.iq
new file mode 100644
index 0000000..45c21b7
--- /dev/null
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithFiltersInsideAndOutside@NullHandling=sql.iq
@@ -0,0 +1,116 @@
+# testUnnestWithFiltersInsideAndOutside@NullHandling=sql case-crc:10c26262
+# quidem testcase reason: UNNEST_EXTRA_SCAN
+!set debug true
+!set defaultTimeout 300000
+!set maxScatterGatherBytes 9223372036854775807
+!set plannerStrategy DECOUPLED
+!set sqlCurrentTimestamp 2000-01-01T00:00:00Z
+!set sqlQueryId dummy
+!set sqlStringifyArrays false
+!set outputformat mysql
+!use druidtest:///
+SELECT d3 FROM
+  (select * from druid.numfoo where dim2='a') as t,
+  UNNEST(MV_TO_ARRAY(dim3)) as unnested (d3)
+WHERE t.dim1 <> 'foo'
+AND unnested.d3 <> 'b';
++----+
+| d3 |
++----+
+|    |
+| a  |
++----+
+(2 rows)
+
+!ok
+LogicalProject(d3=[$18])
+  LogicalUnnest(unnestExpr=[MV_TO_ARRAY($3)], filter=[<>($0, 'b')])
+    LogicalProject(__time=[$0], dim1=[$1], $f2=[CAST('a':VARCHAR):VARCHAR], dim3=[$3], dim4=[$4], dim5=[$5], dim6=[$6], d1=[$7], d2=[$8], f1=[$9], f2=[$10], l1=[$11], l2=[$12], cnt=[$13], m1=[$14], m2=[$15], unique_dim1=[$16], __time0=[$0])
+      LogicalFilter(condition=[AND(=($2, 'a'), <>($1, 'foo'))])
+        LogicalTableScan(table=[[druid, numfoo]])
+
+!logicalPlan
+DruidProject(d3=[$18], druid=[logical])
+  DruidUnnest(unnestExpr=[MV_TO_ARRAY($3)], filter=[<>($0, 'b')])
+    DruidProject(__time=[$0], dim1=[$1], $f2=[CAST('a':VARCHAR):VARCHAR], dim3=[$3], dim4=[$4], dim5=[$5], dim6=[$6], d1=[$7], d2=[$8], f1=[$9], f2=[$10], l1=[$11], l2=[$12], cnt=[$13], m1=[$14], m2=[$15], unique_dim1=[$16], __time0=[$0], druid=[logical])
+      DruidFilter(condition=[AND(=($2, 'a'), <>($1, 'foo'))])
+        DruidTableScan(table=[[druid, numfoo]], druid=[logical])
+
+!druidPlan
+{
+  "queryType" : "scan",
+  "dataSource" : {
+    "type" : "unnest",
+    "base" : {
+      "type" : "query",
+      "query" : {
+        "queryType" : "scan",
+        "dataSource" : {
+          "type" : "table",
+          "name" : "numfoo"
+        },
+        "intervals" : {
+          "type" : "intervals",
+          "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+        },
+        "virtualColumns" : [ {
+          "type" : "expression",
+          "name" : "v0",
+          "expression" : "'a'",
+          "outputType" : "STRING"
+        } ],
+        "resultFormat" : "compactedList",
+        "filter" : {
+          "type" : "and",
+          "fields" : [ {
+            "type" : "equals",
+            "column" : "dim2",
+            "matchValueType" : "STRING",
+            "matchValue" : "a"
+          }, {
+            "type" : "not",
+            "field" : {
+              "type" : "equals",
+              "column" : "dim1",
+              "matchValueType" : "STRING",
+              "matchValue" : "foo"
+            }
+          } ]
+        },
+        "columns" : [ "__time", "cnt", "d1", "d2", "dim1", "dim3", "dim4", "dim5", "dim6", "f1", "f2", "l1", "l2", "m1", "m2", "unique_dim1", "v0" ],
+        "columnTypes" : [ "LONG", "LONG", "DOUBLE", "DOUBLE", "STRING", "STRING", "STRING", "STRING", "STRING", "FLOAT", "FLOAT", "LONG", "LONG", "FLOAT", "DOUBLE", "COMPLEX<hyperUnique>", "STRING" ],
+        "granularity" : {
+          "type" : "all"
+        },
+        "legacy" : false
+      }
+    },
+    "virtualColumn" : {
+      "type" : "expression",
+      "name" : "j0.unnest",
+      "expression" : "mv_to_array(\"dim3\")",
+      "outputType" : "ARRAY<STRING>"
+    },
+    "unnestFilter" : {
+      "type" : "not",
+      "field" : {
+        "type" : "equals",
+        "column" : "j0.unnest",
+        "matchValueType" : "STRING",
+        "matchValue" : "b"
+      }
+    }
+  },
+  "intervals" : {
+    "type" : "intervals",
+    "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+  },
+  "resultFormat" : "compactedList",
+  "columns" : [ "j0.unnest" ],
+  "columnTypes" : [ "STRING" ],
+  "granularity" : {
+    "type" : "all"
+  },
+  "legacy" : false
+}
+!nativePlan
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithFiltersWithExpressionInInnerQuery@NullHandling=default.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithFiltersWithExpressionInInnerQuery@NullHandling=default.iq
new file mode 100644
index 0000000..6ca74e4
--- /dev/null
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithFiltersWithExpressionInInnerQuery@NullHandling=default.iq
@@ -0,0 +1,92 @@
+# testUnnestWithFiltersWithExpressionInInnerQuery@NullHandling=default case-crc:fa9be8db
+# quidem testcase reason: UNNEST_EXTRA_SCAN
+!set debug true
+!set defaultTimeout 300000
+!set maxScatterGatherBytes 9223372036854775807
+!set plannerStrategy DECOUPLED
+!set sqlCurrentTimestamp 2000-01-01T00:00:00Z
+!set sqlQueryId dummy
+!set sqlStringifyArrays false
+!set outputformat mysql
+!use druidtest:///
+SELECT t,d3 FROM (select FLOOR(__time to hour) t, dim3 from druid.numfoo where dim2='a'), UNNEST(MV_TO_ARRAY(dim3)) as unnested (d3);
++-------------------------+----+
+| t                       | d3 |
++-------------------------+----+
+| 2000-01-01 00:00:00.000 | a  |
+| 2000-01-01 00:00:00.000 | b  |
++-------------------------+----+
+(2 rows)
+
+!ok
+LogicalProject(t=[$0], d3=[$3])
+  LogicalUnnest(unnestExpr=[MV_TO_ARRAY($1)])
+    LogicalProject($f0=[FLOOR($0, FLAG(HOUR))], dim3=[$3], __time=[$0])
+      LogicalFilter(condition=[=($2, 'a')])
+        LogicalTableScan(table=[[druid, numfoo]])
+
+!logicalPlan
+DruidProject(t=[$0], d3=[$3], druid=[logical])
+  DruidUnnest(unnestExpr=[MV_TO_ARRAY($1)])
+    DruidProject($f0=[FLOOR($0, FLAG(HOUR))], dim3=[$3], __time=[$0], druid=[logical])
+      DruidFilter(condition=[=($2, 'a')])
+        DruidTableScan(table=[[druid, numfoo]], druid=[logical])
+
+!druidPlan
+{
+  "queryType" : "scan",
+  "dataSource" : {
+    "type" : "unnest",
+    "base" : {
+      "type" : "query",
+      "query" : {
+        "queryType" : "scan",
+        "dataSource" : {
+          "type" : "table",
+          "name" : "numfoo"
+        },
+        "intervals" : {
+          "type" : "intervals",
+          "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+        },
+        "virtualColumns" : [ {
+          "type" : "expression",
+          "name" : "v0",
+          "expression" : "timestamp_floor(\"__time\",'PT1H',null,'UTC')",
+          "outputType" : "LONG"
+        } ],
+        "resultFormat" : "compactedList",
+        "filter" : {
+          "type" : "selector",
+          "dimension" : "dim2",
+          "value" : "a"
+        },
+        "columns" : [ "__time", "dim3", "v0" ],
+        "columnTypes" : [ "LONG", "STRING", "LONG" ],
+        "granularity" : {
+          "type" : "all"
+        },
+        "legacy" : false
+      }
+    },
+    "virtualColumn" : {
+      "type" : "expression",
+      "name" : "j0.unnest",
+      "expression" : "mv_to_array(\"dim3\")",
+      "outputType" : "ARRAY<STRING>"
+    },
+    "unnestFilter" : null
+  },
+  "intervals" : {
+    "type" : "intervals",
+    "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+  },
+  "resultFormat" : "compactedList",
+  "columns" : [ "j0.unnest", "v0" ],
+  "columnTypes" : [ "STRING", "LONG" ],
+  "granularity" : {
+    "type" : "all"
+  },
+  "legacy" : false
+}
+!nativePlan
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithFiltersWithExpressionInInnerQuery@NullHandling=sql.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithFiltersWithExpressionInInnerQuery@NullHandling=sql.iq
new file mode 100644
index 0000000..1f523a1
--- /dev/null
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithFiltersWithExpressionInInnerQuery@NullHandling=sql.iq
@@ -0,0 +1,94 @@
+# testUnnestWithFiltersWithExpressionInInnerQuery@NullHandling=sql case-crc:fa9be8db
+# quidem testcase reason: UNNEST_EXTRA_SCAN
+!set debug true
+!set defaultTimeout 300000
+!set maxScatterGatherBytes 9223372036854775807
+!set plannerStrategy DECOUPLED
+!set sqlCurrentTimestamp 2000-01-01T00:00:00Z
+!set sqlQueryId dummy
+!set sqlStringifyArrays false
+!set outputformat mysql
+!use druidtest:///
+SELECT t,d3 FROM (select FLOOR(__time to hour) t, dim3 from druid.numfoo where dim2='a'), UNNEST(MV_TO_ARRAY(dim3)) as unnested (d3);
++-------------------------+----+
+| t                       | d3 |
++-------------------------+----+
+| 2000-01-01 00:00:00.000 | a  |
+| 2000-01-01 00:00:00.000 | b  |
+| 2001-01-01 00:00:00.000 |    |
++-------------------------+----+
+(3 rows)
+
+!ok
+LogicalProject(t=[$0], d3=[$3])
+  LogicalUnnest(unnestExpr=[MV_TO_ARRAY($1)])
+    LogicalProject($f0=[FLOOR($0, FLAG(HOUR))], dim3=[$3], __time=[$0])
+      LogicalFilter(condition=[=($2, 'a')])
+        LogicalTableScan(table=[[druid, numfoo]])
+
+!logicalPlan
+DruidProject(t=[$0], d3=[$3], druid=[logical])
+  DruidUnnest(unnestExpr=[MV_TO_ARRAY($1)])
+    DruidProject($f0=[FLOOR($0, FLAG(HOUR))], dim3=[$3], __time=[$0], druid=[logical])
+      DruidFilter(condition=[=($2, 'a')])
+        DruidTableScan(table=[[druid, numfoo]], druid=[logical])
+
+!druidPlan
+{
+  "queryType" : "scan",
+  "dataSource" : {
+    "type" : "unnest",
+    "base" : {
+      "type" : "query",
+      "query" : {
+        "queryType" : "scan",
+        "dataSource" : {
+          "type" : "table",
+          "name" : "numfoo"
+        },
+        "intervals" : {
+          "type" : "intervals",
+          "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+        },
+        "virtualColumns" : [ {
+          "type" : "expression",
+          "name" : "v0",
+          "expression" : "timestamp_floor(\"__time\",'PT1H',null,'UTC')",
+          "outputType" : "LONG"
+        } ],
+        "resultFormat" : "compactedList",
+        "filter" : {
+          "type" : "equals",
+          "column" : "dim2",
+          "matchValueType" : "STRING",
+          "matchValue" : "a"
+        },
+        "columns" : [ "__time", "dim3", "v0" ],
+        "columnTypes" : [ "LONG", "STRING", "LONG" ],
+        "granularity" : {
+          "type" : "all"
+        },
+        "legacy" : false
+      }
+    },
+    "virtualColumn" : {
+      "type" : "expression",
+      "name" : "j0.unnest",
+      "expression" : "mv_to_array(\"dim3\")",
+      "outputType" : "ARRAY<STRING>"
+    },
+    "unnestFilter" : null
+  },
+  "intervals" : {
+    "type" : "intervals",
+    "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+  },
+  "resultFormat" : "compactedList",
+  "columns" : [ "j0.unnest", "v0" ],
+  "columnTypes" : [ "STRING", "LONG" ],
+  "granularity" : {
+    "type" : "all"
+  },
+  "legacy" : false
+}
+!nativePlan
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithGroupByOnExpression.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithGroupByOnExpression.iq
new file mode 100644
index 0000000..0816c2e
--- /dev/null
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithGroupByOnExpression.iq
@@ -0,0 +1,98 @@
+# testUnnestWithGroupByOnExpression case-crc:d500d30b
+# quidem testcase reason: UNNEST_VC_USES_PROJECTED_CONSTANT
+!set debug true
+!set defaultTimeout 300000
+!set maxScatterGatherBytes 9223372036854775807
+!set plannerStrategy DECOUPLED
+!set sqlCurrentTimestamp 2000-01-01T00:00:00Z
+!set sqlQueryId dummy
+!set sqlStringifyArrays false
+!set outputformat mysql
+!use druidtest:///
+WITH X as 
+(
+SELECT
+ARRAY[1,2,3] as allNums
+FROM foo
+GROUP BY 1
+)
+select * from X CROSS JOIN UNNEST(X.allNums) as ud(num);
++-----------+-----+
+| allNums   | num |
++-----------+-----+
+| [1, 2, 3] |   1 |
+| [1, 2, 3] |   2 |
+| [1, 2, 3] |   3 |
++-----------+-----+
+(3 rows)
+
+!ok
+LogicalUnnest(unnestExpr=[$0])
+  LogicalAggregate(group=[{0}])
+    LogicalProject(allNums=[ARRAY(1, 2, 3)])
+      LogicalTableScan(table=[[druid, foo]])
+
+!logicalPlan
+DruidUnnest(unnestExpr=[$0])
+  DruidAggregate(group=[{0}], druid=[logical])
+    DruidProject(allNums=[ARRAY(1, 2, 3)], druid=[logical])
+      DruidTableScan(table=[[druid, foo]], druid=[logical])
+
+!druidPlan
+{
+  "queryType" : "scan",
+  "dataSource" : {
+    "type" : "unnest",
+    "base" : {
+      "type" : "query",
+      "query" : {
+        "queryType" : "groupBy",
+        "dataSource" : {
+          "type" : "table",
+          "name" : "foo"
+        },
+        "intervals" : {
+          "type" : "intervals",
+          "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+        },
+        "virtualColumns" : [ {
+          "type" : "expression",
+          "name" : "v0",
+          "expression" : "array(1,2,3)",
+          "outputType" : "ARRAY<LONG>"
+        } ],
+        "granularity" : {
+          "type" : "all"
+        },
+        "dimensions" : [ {
+          "type" : "default",
+          "dimension" : "v0",
+          "outputName" : "d0",
+          "outputType" : "ARRAY<LONG>"
+        } ],
+        "limitSpec" : {
+          "type" : "NoopLimitSpec"
+        }
+      }
+    },
+    "virtualColumn" : {
+      "type" : "expression",
+      "name" : "j0.unnest",
+      "expression" : "\"d0\"",
+      "outputType" : "ARRAY<LONG>"
+    },
+    "unnestFilter" : null
+  },
+  "intervals" : {
+    "type" : "intervals",
+    "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+  },
+  "resultFormat" : "compactedList",
+  "columns" : [ "d0", "j0.unnest" ],
+  "columnTypes" : [ "ARRAY<LONG>", "LONG" ],
+  "granularity" : {
+    "type" : "all"
+  },
+  "legacy" : false
+}
+!nativePlan
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithInFiltersWithExpressionInInnerQuery@NullHandling=default.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithInFiltersWithExpressionInInnerQuery@NullHandling=default.iq
new file mode 100644
index 0000000..6c20313
--- /dev/null
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithInFiltersWithExpressionInInnerQuery@NullHandling=default.iq
@@ -0,0 +1,92 @@
+# testUnnestWithInFiltersWithExpressionInInnerQuery@NullHandling=default case-crc:49354254
+# quidem testcase reason: UNNEST_EXTRA_SCAN
+!set debug true
+!set defaultTimeout 300000
+!set maxScatterGatherBytes 9223372036854775807
+!set plannerStrategy DECOUPLED
+!set sqlCurrentTimestamp 2000-01-01T00:00:00Z
+!set sqlQueryId dummy
+!set sqlStringifyArrays false
+!set outputformat mysql
+!use druidtest:///
+SELECT t,d3 FROM (select FLOOR(__time to hour) t, dim3 from druid.numfoo where dim2 IN ('a','b')), UNNEST(MV_TO_ARRAY(dim3)) as unnested (d3);
++-------------------------+----+
+| t                       | d3 |
++-------------------------+----+
+| 2000-01-01 00:00:00.000 | a  |
+| 2000-01-01 00:00:00.000 | b  |
++-------------------------+----+
+(2 rows)
+
+!ok
+LogicalProject(t=[$0], d3=[$3])
+  LogicalUnnest(unnestExpr=[MV_TO_ARRAY($1)])
+    LogicalProject($f0=[FLOOR($0, FLAG(HOUR))], dim3=[$3], __time=[$0])
+      LogicalFilter(condition=[SEARCH($2, Sarg['a':VARCHAR, 'b':VARCHAR]:VARCHAR)])
+        LogicalTableScan(table=[[druid, numfoo]])
+
+!logicalPlan
+DruidProject(t=[$0], d3=[$3], druid=[logical])
+  DruidUnnest(unnestExpr=[MV_TO_ARRAY($1)])
+    DruidProject($f0=[FLOOR($0, FLAG(HOUR))], dim3=[$3], __time=[$0], druid=[logical])
+      DruidFilter(condition=[SEARCH($2, Sarg['a':VARCHAR, 'b':VARCHAR]:VARCHAR)])
+        DruidTableScan(table=[[druid, numfoo]], druid=[logical])
+
+!druidPlan
+{
+  "queryType" : "scan",
+  "dataSource" : {
+    "type" : "unnest",
+    "base" : {
+      "type" : "query",
+      "query" : {
+        "queryType" : "scan",
+        "dataSource" : {
+          "type" : "table",
+          "name" : "numfoo"
+        },
+        "intervals" : {
+          "type" : "intervals",
+          "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+        },
+        "virtualColumns" : [ {
+          "type" : "expression",
+          "name" : "v0",
+          "expression" : "timestamp_floor(\"__time\",'PT1H',null,'UTC')",
+          "outputType" : "LONG"
+        } ],
+        "resultFormat" : "compactedList",
+        "filter" : {
+          "type" : "in",
+          "dimension" : "dim2",
+          "values" : [ "a", "b" ]
+        },
+        "columns" : [ "__time", "dim3", "v0" ],
+        "columnTypes" : [ "LONG", "STRING", "LONG" ],
+        "granularity" : {
+          "type" : "all"
+        },
+        "legacy" : false
+      }
+    },
+    "virtualColumn" : {
+      "type" : "expression",
+      "name" : "j0.unnest",
+      "expression" : "mv_to_array(\"dim3\")",
+      "outputType" : "ARRAY<STRING>"
+    },
+    "unnestFilter" : null
+  },
+  "intervals" : {
+    "type" : "intervals",
+    "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+  },
+  "resultFormat" : "compactedList",
+  "columns" : [ "j0.unnest", "v0" ],
+  "columnTypes" : [ "STRING", "LONG" ],
+  "granularity" : {
+    "type" : "all"
+  },
+  "legacy" : false
+}
+!nativePlan
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithInFiltersWithExpressionInInnerQuery@NullHandling=sql.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithInFiltersWithExpressionInInnerQuery@NullHandling=sql.iq
new file mode 100644
index 0000000..35e883c
--- /dev/null
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithInFiltersWithExpressionInInnerQuery@NullHandling=sql.iq
@@ -0,0 +1,94 @@
+# testUnnestWithInFiltersWithExpressionInInnerQuery@NullHandling=sql case-crc:49354254
+# quidem testcase reason: UNNEST_EXTRA_SCAN
+!set debug true
+!set defaultTimeout 300000
+!set maxScatterGatherBytes 9223372036854775807
+!set plannerStrategy DECOUPLED
+!set sqlCurrentTimestamp 2000-01-01T00:00:00Z
+!set sqlQueryId dummy
+!set sqlStringifyArrays false
+!set outputformat mysql
+!use druidtest:///
+SELECT t,d3 FROM (select FLOOR(__time to hour) t, dim3 from druid.numfoo where dim2 IN ('a','b')), UNNEST(MV_TO_ARRAY(dim3)) as unnested (d3);
++-------------------------+----+
+| t                       | d3 |
++-------------------------+----+
+| 2000-01-01 00:00:00.000 | a  |
+| 2000-01-01 00:00:00.000 | b  |
+| 2001-01-01 00:00:00.000 |    |
++-------------------------+----+
+(3 rows)
+
+!ok
+LogicalProject(t=[$0], d3=[$3])
+  LogicalUnnest(unnestExpr=[MV_TO_ARRAY($1)])
+    LogicalProject($f0=[FLOOR($0, FLAG(HOUR))], dim3=[$3], __time=[$0])
+      LogicalFilter(condition=[SEARCH($2, Sarg['a':VARCHAR, 'b':VARCHAR]:VARCHAR)])
+        LogicalTableScan(table=[[druid, numfoo]])
+
+!logicalPlan
+DruidProject(t=[$0], d3=[$3], druid=[logical])
+  DruidUnnest(unnestExpr=[MV_TO_ARRAY($1)])
+    DruidProject($f0=[FLOOR($0, FLAG(HOUR))], dim3=[$3], __time=[$0], druid=[logical])
+      DruidFilter(condition=[SEARCH($2, Sarg['a':VARCHAR, 'b':VARCHAR]:VARCHAR)])
+        DruidTableScan(table=[[druid, numfoo]], druid=[logical])
+
+!druidPlan
+{
+  "queryType" : "scan",
+  "dataSource" : {
+    "type" : "unnest",
+    "base" : {
+      "type" : "query",
+      "query" : {
+        "queryType" : "scan",
+        "dataSource" : {
+          "type" : "table",
+          "name" : "numfoo"
+        },
+        "intervals" : {
+          "type" : "intervals",
+          "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+        },
+        "virtualColumns" : [ {
+          "type" : "expression",
+          "name" : "v0",
+          "expression" : "timestamp_floor(\"__time\",'PT1H',null,'UTC')",
+          "outputType" : "LONG"
+        } ],
+        "resultFormat" : "compactedList",
+        "filter" : {
+          "type" : "inType",
+          "column" : "dim2",
+          "matchValueType" : "STRING",
+          "sortedValues" : [ "a", "b" ]
+        },
+        "columns" : [ "__time", "dim3", "v0" ],
+        "columnTypes" : [ "LONG", "STRING", "LONG" ],
+        "granularity" : {
+          "type" : "all"
+        },
+        "legacy" : false
+      }
+    },
+    "virtualColumn" : {
+      "type" : "expression",
+      "name" : "j0.unnest",
+      "expression" : "mv_to_array(\"dim3\")",
+      "outputType" : "ARRAY<STRING>"
+    },
+    "unnestFilter" : null
+  },
+  "intervals" : {
+    "type" : "intervals",
+    "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+  },
+  "resultFormat" : "compactedList",
+  "columns" : [ "j0.unnest", "v0" ],
+  "columnTypes" : [ "STRING", "LONG" ],
+  "granularity" : {
+    "type" : "all"
+  },
+  "legacy" : false
+}
+!nativePlan
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithMultipleOrFiltersOnVariationsOfUnnestedColumns@NullHandling=default.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithMultipleOrFiltersOnVariationsOfUnnestedColumns@NullHandling=default.iq
new file mode 100644
index 0000000..4f12b57
--- /dev/null
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithMultipleOrFiltersOnVariationsOfUnnestedColumns@NullHandling=default.iq
@@ -0,0 +1,75 @@
+# testUnnestWithMultipleOrFiltersOnVariationsOfUnnestedColumns@NullHandling=default case-crc:02630011
+# quidem testcase reason: UNNEST_DIFFERENT_RESULTSET
+!set debug true
+!set defaultTimeout 300000
+!set maxScatterGatherBytes 9223372036854775807
+!set plannerStrategy DECOUPLED
+!set sqlCurrentTimestamp 2000-01-01T00:00:00Z
+!set sqlQueryId dummy
+!set sqlStringifyArrays false
+!set outputformat mysql
+!use druidtest:///
+SELECT d3 FROM druid.numfoo, UNNEST(MV_TO_ARRAY(dim3)) as unnested (d3) where strlen(d3) < 2 or d3='d' ;
++----+
+| d3 |
++----+
+| a  |
+| b  |
+| b  |
+| c  |
+| d  |
++----+
+(5 rows)
+
+!ok
+LogicalProject(d3=[$18])
+  LogicalUnnest(unnestExpr=[MV_TO_ARRAY($3)], filter=[OR(<(STRLEN($0), 2), =($0, 'd'))])
+    LogicalProject(__time=[$0], dim1=[$1], dim2=[$2], dim3=[$3], dim4=[$4], dim5=[$5], dim6=[$6], d1=[$7], d2=[$8], f1=[$9], f2=[$10], l1=[$11], l2=[$12], cnt=[$13], m1=[$14], m2=[$15], unique_dim1=[$16], __time0=[$0])
+      LogicalTableScan(table=[[druid, numfoo]])
+
+!logicalPlan
+DruidProject(d3=[$18], druid=[logical])
+  DruidUnnest(unnestExpr=[MV_TO_ARRAY($3)], filter=[OR(<(STRLEN($0), 2), =($0, 'd'))])
+    DruidProject(__time=[$0], dim1=[$1], dim2=[$2], dim3=[$3], dim4=[$4], dim5=[$5], dim6=[$6], d1=[$7], d2=[$8], f1=[$9], f2=[$10], l1=[$11], l2=[$12], cnt=[$13], m1=[$14], m2=[$15], unique_dim1=[$16], __time0=[$0], druid=[logical])
+      DruidTableScan(table=[[druid, numfoo]], druid=[logical])
+
+!druidPlan
+{
+  "queryType" : "scan",
+  "dataSource" : {
+    "type" : "unnest",
+    "base" : {
+      "type" : "table",
+      "name" : "numfoo"
+    },
+    "virtualColumn" : {
+      "type" : "expression",
+      "name" : "j0.unnest",
+      "expression" : "mv_to_array(\"dim3\")",
+      "outputType" : "ARRAY<STRING>"
+    },
+    "unnestFilter" : {
+      "type" : "or",
+      "fields" : [ {
+        "type" : "expression",
+        "expression" : "(strlen(\"j0.unnest\") < 2)"
+      }, {
+        "type" : "selector",
+        "dimension" : "j0.unnest",
+        "value" : "d"
+      } ]
+    }
+  },
+  "intervals" : {
+    "type" : "intervals",
+    "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+  },
+  "resultFormat" : "compactedList",
+  "columns" : [ "j0.unnest" ],
+  "columnTypes" : [ "STRING" ],
+  "granularity" : {
+    "type" : "all"
+  },
+  "legacy" : false
+}
+!nativePlan
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithMultipleOrFiltersOnVariationsOfUnnestedColumns@NullHandling=sql.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithMultipleOrFiltersOnVariationsOfUnnestedColumns@NullHandling=sql.iq
new file mode 100644
index 0000000..e5d8a68
--- /dev/null
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithMultipleOrFiltersOnVariationsOfUnnestedColumns@NullHandling=sql.iq
@@ -0,0 +1,77 @@
+# testUnnestWithMultipleOrFiltersOnVariationsOfUnnestedColumns@NullHandling=sql case-crc:02630011
+# quidem testcase reason: UNNEST_DIFFERENT_RESULTSET
+!set debug true
+!set defaultTimeout 300000
+!set maxScatterGatherBytes 9223372036854775807
+!set plannerStrategy DECOUPLED
+!set sqlCurrentTimestamp 2000-01-01T00:00:00Z
+!set sqlQueryId dummy
+!set sqlStringifyArrays false
+!set outputformat mysql
+!use druidtest:///
+SELECT d3 FROM druid.numfoo, UNNEST(MV_TO_ARRAY(dim3)) as unnested (d3) where strlen(d3) < 2 or d3='d' ;
++----+
+| d3 |
++----+
+|    |
+| a  |
+| b  |
+| b  |
+| c  |
+| d  |
++----+
+(6 rows)
+
+!ok
+LogicalProject(d3=[$18])
+  LogicalUnnest(unnestExpr=[MV_TO_ARRAY($3)], filter=[OR(<(STRLEN($0), 2), =($0, 'd'))])
+    LogicalProject(__time=[$0], dim1=[$1], dim2=[$2], dim3=[$3], dim4=[$4], dim5=[$5], dim6=[$6], d1=[$7], d2=[$8], f1=[$9], f2=[$10], l1=[$11], l2=[$12], cnt=[$13], m1=[$14], m2=[$15], unique_dim1=[$16], __time0=[$0])
+      LogicalTableScan(table=[[druid, numfoo]])
+
+!logicalPlan
+DruidProject(d3=[$18], druid=[logical])
+  DruidUnnest(unnestExpr=[MV_TO_ARRAY($3)], filter=[OR(<(STRLEN($0), 2), =($0, 'd'))])
+    DruidProject(__time=[$0], dim1=[$1], dim2=[$2], dim3=[$3], dim4=[$4], dim5=[$5], dim6=[$6], d1=[$7], d2=[$8], f1=[$9], f2=[$10], l1=[$11], l2=[$12], cnt=[$13], m1=[$14], m2=[$15], unique_dim1=[$16], __time0=[$0], druid=[logical])
+      DruidTableScan(table=[[druid, numfoo]], druid=[logical])
+
+!druidPlan
+{
+  "queryType" : "scan",
+  "dataSource" : {
+    "type" : "unnest",
+    "base" : {
+      "type" : "table",
+      "name" : "numfoo"
+    },
+    "virtualColumn" : {
+      "type" : "expression",
+      "name" : "j0.unnest",
+      "expression" : "mv_to_array(\"dim3\")",
+      "outputType" : "ARRAY<STRING>"
+    },
+    "unnestFilter" : {
+      "type" : "or",
+      "fields" : [ {
+        "type" : "expression",
+        "expression" : "(strlen(\"j0.unnest\") < 2)"
+      }, {
+        "type" : "equals",
+        "column" : "j0.unnest",
+        "matchValueType" : "STRING",
+        "matchValue" : "d"
+      } ]
+    }
+  },
+  "intervals" : {
+    "type" : "intervals",
+    "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+  },
+  "resultFormat" : "compactedList",
+  "columns" : [ "j0.unnest" ],
+  "columnTypes" : [ "STRING" ],
+  "granularity" : {
+    "type" : "all"
+  },
+  "legacy" : false
+}
+!nativePlan
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithNotFiltersOnUnnestedColumn@NullHandling=default.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithNotFiltersOnUnnestedColumn@NullHandling=default.iq
new file mode 100644
index 0000000..84d0c9b
--- /dev/null
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithNotFiltersOnUnnestedColumn@NullHandling=default.iq
@@ -0,0 +1,71 @@
+# testUnnestWithNotFiltersOnUnnestedColumn@NullHandling=default case-crc:5fc83255
+# quidem testcase reason: UNNEST_DIFFERENT_RESULTSET
+!set debug true
+!set defaultTimeout 300000
+!set maxScatterGatherBytes 9223372036854775807
+!set plannerStrategy DECOUPLED
+!set sqlCurrentTimestamp 2000-01-01T00:00:00Z
+!set sqlQueryId dummy
+!set sqlStringifyArrays false
+!set outputformat mysql
+!use druidtest:///
+SELECT d3 FROM druid.numfoo, UNNEST(MV_TO_ARRAY(dim3)) as unnested (d3) where d3!='d' ;
++----+
+| d3 |
++----+
+| a  |
+| b  |
+| b  |
+| c  |
++----+
+(4 rows)
+
+!ok
+LogicalProject(d3=[$18])
+  LogicalUnnest(unnestExpr=[MV_TO_ARRAY($3)], filter=[<>($0, 'd')])
+    LogicalProject(__time=[$0], dim1=[$1], dim2=[$2], dim3=[$3], dim4=[$4], dim5=[$5], dim6=[$6], d1=[$7], d2=[$8], f1=[$9], f2=[$10], l1=[$11], l2=[$12], cnt=[$13], m1=[$14], m2=[$15], unique_dim1=[$16], __time0=[$0])
+      LogicalTableScan(table=[[druid, numfoo]])
+
+!logicalPlan
+DruidProject(d3=[$18], druid=[logical])
+  DruidUnnest(unnestExpr=[MV_TO_ARRAY($3)], filter=[<>($0, 'd')])
+    DruidProject(__time=[$0], dim1=[$1], dim2=[$2], dim3=[$3], dim4=[$4], dim5=[$5], dim6=[$6], d1=[$7], d2=[$8], f1=[$9], f2=[$10], l1=[$11], l2=[$12], cnt=[$13], m1=[$14], m2=[$15], unique_dim1=[$16], __time0=[$0], druid=[logical])
+      DruidTableScan(table=[[druid, numfoo]], druid=[logical])
+
+!druidPlan
+{
+  "queryType" : "scan",
+  "dataSource" : {
+    "type" : "unnest",
+    "base" : {
+      "type" : "table",
+      "name" : "numfoo"
+    },
+    "virtualColumn" : {
+      "type" : "expression",
+      "name" : "j0.unnest",
+      "expression" : "mv_to_array(\"dim3\")",
+      "outputType" : "ARRAY<STRING>"
+    },
+    "unnestFilter" : {
+      "type" : "not",
+      "field" : {
+        "type" : "selector",
+        "dimension" : "j0.unnest",
+        "value" : "d"
+      }
+    }
+  },
+  "intervals" : {
+    "type" : "intervals",
+    "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+  },
+  "resultFormat" : "compactedList",
+  "columns" : [ "j0.unnest" ],
+  "columnTypes" : [ "STRING" ],
+  "granularity" : {
+    "type" : "all"
+  },
+  "legacy" : false
+}
+!nativePlan
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithNotFiltersOnUnnestedColumn@NullHandling=sql.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithNotFiltersOnUnnestedColumn@NullHandling=sql.iq
new file mode 100644
index 0000000..bc02718
--- /dev/null
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteArraysQueryTest/testUnnestWithNotFiltersOnUnnestedColumn@NullHandling=sql.iq
@@ -0,0 +1,73 @@
+# testUnnestWithNotFiltersOnUnnestedColumn@NullHandling=sql case-crc:5fc83255
+# quidem testcase reason: UNNEST_DIFFERENT_RESULTSET
+!set debug true
+!set defaultTimeout 300000
+!set maxScatterGatherBytes 9223372036854775807
+!set plannerStrategy DECOUPLED
+!set sqlCurrentTimestamp 2000-01-01T00:00:00Z
+!set sqlQueryId dummy
+!set sqlStringifyArrays false
+!set outputformat mysql
+!use druidtest:///
+SELECT d3 FROM druid.numfoo, UNNEST(MV_TO_ARRAY(dim3)) as unnested (d3) where d3!='d' ;
++----+
+| d3 |
++----+
+|    |
+| a  |
+| b  |
+| b  |
+| c  |
++----+
+(5 rows)
+
+!ok
+LogicalProject(d3=[$18])
+  LogicalUnnest(unnestExpr=[MV_TO_ARRAY($3)], filter=[<>($0, 'd')])
+    LogicalProject(__time=[$0], dim1=[$1], dim2=[$2], dim3=[$3], dim4=[$4], dim5=[$5], dim6=[$6], d1=[$7], d2=[$8], f1=[$9], f2=[$10], l1=[$11], l2=[$12], cnt=[$13], m1=[$14], m2=[$15], unique_dim1=[$16], __time0=[$0])
+      LogicalTableScan(table=[[druid, numfoo]])
+
+!logicalPlan
+DruidProject(d3=[$18], druid=[logical])
+  DruidUnnest(unnestExpr=[MV_TO_ARRAY($3)], filter=[<>($0, 'd')])
+    DruidProject(__time=[$0], dim1=[$1], dim2=[$2], dim3=[$3], dim4=[$4], dim5=[$5], dim6=[$6], d1=[$7], d2=[$8], f1=[$9], f2=[$10], l1=[$11], l2=[$12], cnt=[$13], m1=[$14], m2=[$15], unique_dim1=[$16], __time0=[$0], druid=[logical])
+      DruidTableScan(table=[[druid, numfoo]], druid=[logical])
+
+!druidPlan
+{
+  "queryType" : "scan",
+  "dataSource" : {
+    "type" : "unnest",
+    "base" : {
+      "type" : "table",
+      "name" : "numfoo"
+    },
+    "virtualColumn" : {
+      "type" : "expression",
+      "name" : "j0.unnest",
+      "expression" : "mv_to_array(\"dim3\")",
+      "outputType" : "ARRAY<STRING>"
+    },
+    "unnestFilter" : {
+      "type" : "not",
+      "field" : {
+        "type" : "equals",
+        "column" : "j0.unnest",
+        "matchValueType" : "STRING",
+        "matchValue" : "d"
+      }
+    }
+  },
+  "intervals" : {
+    "type" : "intervals",
+    "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+  },
+  "resultFormat" : "compactedList",
+  "columns" : [ "j0.unnest" ],
+  "columnTypes" : [ "STRING" ],
+  "granularity" : {
+    "type" : "all"
+  },
+  "legacy" : false
+}
+!nativePlan
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@all_disabled@NullHandling=default.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@all_disabled@NullHandling=default.iq
index d7654db..20ec2ea 100644
--- a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@all_disabled@NullHandling=default.iq
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@all_disabled@NullHandling=default.iq
@@ -1,5 +1,5 @@
-# testNestedGroupByOnInlineDataSourceWithFilter@all_disabled@NullHandling=default case-crc:4c1847a0
-# quidem testcase reason: IRRELEVANT_SCANQUERY
+# testNestedGroupByOnInlineDataSourceWithFilter@all_disabled@NullHandling=default case-crc:cac513c5
+# quidem testcase reason: SCAN_QUERY_ON_FILTERED_DS_DOING_FILTERING
 !set debug true
 !set defaultTimeout 300000
 !set enableJoinFilterRewrite false
@@ -59,29 +59,23 @@
           "query" : {
             "queryType" : "scan",
             "dataSource" : {
-              "type" : "query",
-              "query" : {
-                "queryType" : "scan",
-                "dataSource" : {
-                  "type" : "table",
-                  "name" : "foo"
-                },
-                "intervals" : {
-                  "type" : "intervals",
-                  "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
-                },
-                "resultFormat" : "compactedList",
-                "columns" : [ "dim1" ],
-                "columnTypes" : [ "STRING" ],
-                "granularity" : {
-                  "type" : "all"
-                },
-                "legacy" : false
+              "type" : "filter",
+              "base" : {
+                "type" : "table",
+                "name" : "foo"
+              },
+              "filter" : {
+                "type" : "bound",
+                "dimension" : "__time",
+                "lower" : "978393600000",
+                "ordering" : {
+                  "type" : "numeric"
+                }
               }
             },
             "intervals" : {
               "type" : "intervals",
-              "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+              "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
             },
             "resultFormat" : "compactedList",
             "filter" : {
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@all_disabled@NullHandling=sql.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@all_disabled@NullHandling=sql.iq
index 099cd78..f10f8b5 100644
--- a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@all_disabled@NullHandling=sql.iq
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@all_disabled@NullHandling=sql.iq
@@ -1,5 +1,5 @@
-# testNestedGroupByOnInlineDataSourceWithFilter@all_disabled@NullHandling=sql case-crc:4c1847a0
-# quidem testcase reason: IRRELEVANT_SCANQUERY
+# testNestedGroupByOnInlineDataSourceWithFilter@all_disabled@NullHandling=sql case-crc:cac513c5
+# quidem testcase reason: SCAN_QUERY_ON_FILTERED_DS_DOING_FILTERING
 !set debug true
 !set defaultTimeout 300000
 !set enableJoinFilterRewrite false
@@ -59,29 +59,21 @@
           "query" : {
             "queryType" : "scan",
             "dataSource" : {
-              "type" : "query",
-              "query" : {
-                "queryType" : "scan",
-                "dataSource" : {
-                  "type" : "table",
-                  "name" : "foo"
-                },
-                "intervals" : {
-                  "type" : "intervals",
-                  "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
-                },
-                "resultFormat" : "compactedList",
-                "columns" : [ "dim1" ],
-                "columnTypes" : [ "STRING" ],
-                "granularity" : {
-                  "type" : "all"
-                },
-                "legacy" : false
+              "type" : "filter",
+              "base" : {
+                "type" : "table",
+                "name" : "foo"
+              },
+              "filter" : {
+                "type" : "range",
+                "column" : "__time",
+                "matchValueType" : "LONG",
+                "lower" : 978393600000
               }
             },
             "intervals" : {
               "type" : "intervals",
-              "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+              "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
             },
             "resultFormat" : "compactedList",
             "filter" : {
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@all_enabled@NullHandling=default.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@all_enabled@NullHandling=default.iq
index 7b9e1e8..0b39259 100644
--- a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@all_enabled@NullHandling=default.iq
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@all_enabled@NullHandling=default.iq
@@ -1,5 +1,5 @@
-# testNestedGroupByOnInlineDataSourceWithFilter@all_enabled@NullHandling=default case-crc:d0070228
-# quidem testcase reason: IRRELEVANT_SCANQUERY
+# testNestedGroupByOnInlineDataSourceWithFilter@all_enabled@NullHandling=default case-crc:5eacffa7
+# quidem testcase reason: SCAN_QUERY_ON_FILTERED_DS_DOING_FILTERING
 !set debug true
 !set defaultTimeout 300000
 !set enableJoinFilterRewrite true
@@ -59,29 +59,23 @@
           "query" : {
             "queryType" : "scan",
             "dataSource" : {
-              "type" : "query",
-              "query" : {
-                "queryType" : "scan",
-                "dataSource" : {
-                  "type" : "table",
-                  "name" : "foo"
-                },
-                "intervals" : {
-                  "type" : "intervals",
-                  "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
-                },
-                "resultFormat" : "compactedList",
-                "columns" : [ "dim1" ],
-                "columnTypes" : [ "STRING" ],
-                "granularity" : {
-                  "type" : "all"
-                },
-                "legacy" : false
+              "type" : "filter",
+              "base" : {
+                "type" : "table",
+                "name" : "foo"
+              },
+              "filter" : {
+                "type" : "bound",
+                "dimension" : "__time",
+                "lower" : "978393600000",
+                "ordering" : {
+                  "type" : "numeric"
+                }
               }
             },
             "intervals" : {
               "type" : "intervals",
-              "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+              "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
             },
             "resultFormat" : "compactedList",
             "filter" : {
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@all_enabled@NullHandling=sql.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@all_enabled@NullHandling=sql.iq
index bb208e492..a908f72 100644
--- a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@all_enabled@NullHandling=sql.iq
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@all_enabled@NullHandling=sql.iq
@@ -1,5 +1,5 @@
-# testNestedGroupByOnInlineDataSourceWithFilter@all_enabled@NullHandling=sql case-crc:d0070228
-# quidem testcase reason: IRRELEVANT_SCANQUERY
+# testNestedGroupByOnInlineDataSourceWithFilter@all_enabled@NullHandling=sql case-crc:5eacffa7
+# quidem testcase reason: SCAN_QUERY_ON_FILTERED_DS_DOING_FILTERING
 !set debug true
 !set defaultTimeout 300000
 !set enableJoinFilterRewrite true
@@ -59,29 +59,21 @@
           "query" : {
             "queryType" : "scan",
             "dataSource" : {
-              "type" : "query",
-              "query" : {
-                "queryType" : "scan",
-                "dataSource" : {
-                  "type" : "table",
-                  "name" : "foo"
-                },
-                "intervals" : {
-                  "type" : "intervals",
-                  "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
-                },
-                "resultFormat" : "compactedList",
-                "columns" : [ "dim1" ],
-                "columnTypes" : [ "STRING" ],
-                "granularity" : {
-                  "type" : "all"
-                },
-                "legacy" : false
+              "type" : "filter",
+              "base" : {
+                "type" : "table",
+                "name" : "foo"
+              },
+              "filter" : {
+                "type" : "range",
+                "column" : "__time",
+                "matchValueType" : "LONG",
+                "lower" : 978393600000
               }
             },
             "intervals" : {
               "type" : "intervals",
-              "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+              "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
             },
             "resultFormat" : "compactedList",
             "filter" : {
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@default@NullHandling=default.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@default@NullHandling=default.iq
index 1d931c6..d9d6187 100644
--- a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@default@NullHandling=default.iq
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@default@NullHandling=default.iq
@@ -1,5 +1,5 @@
-# testNestedGroupByOnInlineDataSourceWithFilter@default@NullHandling=default case-crc:af596bbc
-# quidem testcase reason: IRRELEVANT_SCANQUERY
+# testNestedGroupByOnInlineDataSourceWithFilter@default@NullHandling=default case-crc:35936266
+# quidem testcase reason: SCAN_QUERY_ON_FILTERED_DS_DOING_FILTERING
 !set debug true
 !set defaultTimeout 300000
 !set maxScatterGatherBytes 9223372036854775807
@@ -56,29 +56,23 @@
           "query" : {
             "queryType" : "scan",
             "dataSource" : {
-              "type" : "query",
-              "query" : {
-                "queryType" : "scan",
-                "dataSource" : {
-                  "type" : "table",
-                  "name" : "foo"
-                },
-                "intervals" : {
-                  "type" : "intervals",
-                  "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
-                },
-                "resultFormat" : "compactedList",
-                "columns" : [ "dim1" ],
-                "columnTypes" : [ "STRING" ],
-                "granularity" : {
-                  "type" : "all"
-                },
-                "legacy" : false
+              "type" : "filter",
+              "base" : {
+                "type" : "table",
+                "name" : "foo"
+              },
+              "filter" : {
+                "type" : "bound",
+                "dimension" : "__time",
+                "lower" : "978393600000",
+                "ordering" : {
+                  "type" : "numeric"
+                }
               }
             },
             "intervals" : {
               "type" : "intervals",
-              "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+              "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
             },
             "resultFormat" : "compactedList",
             "filter" : {
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@default@NullHandling=sql.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@default@NullHandling=sql.iq
index 3e0dd5a..90488aa 100644
--- a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@default@NullHandling=sql.iq
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@default@NullHandling=sql.iq
@@ -1,5 +1,5 @@
-# testNestedGroupByOnInlineDataSourceWithFilter@default@NullHandling=sql case-crc:af596bbc
-# quidem testcase reason: IRRELEVANT_SCANQUERY
+# testNestedGroupByOnInlineDataSourceWithFilter@default@NullHandling=sql case-crc:35936266
+# quidem testcase reason: SCAN_QUERY_ON_FILTERED_DS_DOING_FILTERING
 !set debug true
 !set defaultTimeout 300000
 !set maxScatterGatherBytes 9223372036854775807
@@ -56,29 +56,21 @@
           "query" : {
             "queryType" : "scan",
             "dataSource" : {
-              "type" : "query",
-              "query" : {
-                "queryType" : "scan",
-                "dataSource" : {
-                  "type" : "table",
-                  "name" : "foo"
-                },
-                "intervals" : {
-                  "type" : "intervals",
-                  "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
-                },
-                "resultFormat" : "compactedList",
-                "columns" : [ "dim1" ],
-                "columnTypes" : [ "STRING" ],
-                "granularity" : {
-                  "type" : "all"
-                },
-                "legacy" : false
+              "type" : "filter",
+              "base" : {
+                "type" : "table",
+                "name" : "foo"
+              },
+              "filter" : {
+                "type" : "range",
+                "column" : "__time",
+                "matchValueType" : "LONG",
+                "lower" : 978393600000
               }
             },
             "intervals" : {
               "type" : "intervals",
-              "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+              "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
             },
             "resultFormat" : "compactedList",
             "filter" : {
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@filter-on-value-column_disabled@NullHandling=default.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@filter-on-value-column_disabled@NullHandling=default.iq
index 8a3ac33..a5fb9af 100644
--- a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@filter-on-value-column_disabled@NullHandling=default.iq
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@filter-on-value-column_disabled@NullHandling=default.iq
@@ -1,5 +1,5 @@
-# testNestedGroupByOnInlineDataSourceWithFilter@filter-on-value-column_disabled@NullHandling=default case-crc:f03f6096
-# quidem testcase reason: IRRELEVANT_SCANQUERY
+# testNestedGroupByOnInlineDataSourceWithFilter@filter-on-value-column_disabled@NullHandling=default case-crc:7c6cef9c
+# quidem testcase reason: SCAN_QUERY_ON_FILTERED_DS_DOING_FILTERING
 !set debug true
 !set defaultTimeout 300000
 !set enableJoinFilterRewrite true
@@ -59,29 +59,23 @@
           "query" : {
             "queryType" : "scan",
             "dataSource" : {
-              "type" : "query",
-              "query" : {
-                "queryType" : "scan",
-                "dataSource" : {
-                  "type" : "table",
-                  "name" : "foo"
-                },
-                "intervals" : {
-                  "type" : "intervals",
-                  "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
-                },
-                "resultFormat" : "compactedList",
-                "columns" : [ "dim1" ],
-                "columnTypes" : [ "STRING" ],
-                "granularity" : {
-                  "type" : "all"
-                },
-                "legacy" : false
+              "type" : "filter",
+              "base" : {
+                "type" : "table",
+                "name" : "foo"
+              },
+              "filter" : {
+                "type" : "bound",
+                "dimension" : "__time",
+                "lower" : "978393600000",
+                "ordering" : {
+                  "type" : "numeric"
+                }
               }
             },
             "intervals" : {
               "type" : "intervals",
-              "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+              "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
             },
             "resultFormat" : "compactedList",
             "filter" : {
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@filter-on-value-column_disabled@NullHandling=sql.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@filter-on-value-column_disabled@NullHandling=sql.iq
index a5fcb79..d904ef9 100644
--- a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@filter-on-value-column_disabled@NullHandling=sql.iq
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@filter-on-value-column_disabled@NullHandling=sql.iq
@@ -1,5 +1,5 @@
-# testNestedGroupByOnInlineDataSourceWithFilter@filter-on-value-column_disabled@NullHandling=sql case-crc:f03f6096
-# quidem testcase reason: IRRELEVANT_SCANQUERY
+# testNestedGroupByOnInlineDataSourceWithFilter@filter-on-value-column_disabled@NullHandling=sql case-crc:7c6cef9c
+# quidem testcase reason: SCAN_QUERY_ON_FILTERED_DS_DOING_FILTERING
 !set debug true
 !set defaultTimeout 300000
 !set enableJoinFilterRewrite true
@@ -59,29 +59,21 @@
           "query" : {
             "queryType" : "scan",
             "dataSource" : {
-              "type" : "query",
-              "query" : {
-                "queryType" : "scan",
-                "dataSource" : {
-                  "type" : "table",
-                  "name" : "foo"
-                },
-                "intervals" : {
-                  "type" : "intervals",
-                  "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
-                },
-                "resultFormat" : "compactedList",
-                "columns" : [ "dim1" ],
-                "columnTypes" : [ "STRING" ],
-                "granularity" : {
-                  "type" : "all"
-                },
-                "legacy" : false
+              "type" : "filter",
+              "base" : {
+                "type" : "table",
+                "name" : "foo"
+              },
+              "filter" : {
+                "type" : "range",
+                "column" : "__time",
+                "matchValueType" : "LONG",
+                "lower" : 978393600000
               }
             },
             "intervals" : {
               "type" : "intervals",
-              "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+              "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
             },
             "resultFormat" : "compactedList",
             "filter" : {
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@filter-rewrites-disabled@NullHandling=default.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@filter-rewrites-disabled@NullHandling=default.iq
index 72706fd..121c272 100644
--- a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@filter-rewrites-disabled@NullHandling=default.iq
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@filter-rewrites-disabled@NullHandling=default.iq
@@ -1,5 +1,5 @@
-# testNestedGroupByOnInlineDataSourceWithFilter@filter-rewrites-disabled@NullHandling=default case-crc:d155bb65
-# quidem testcase reason: IRRELEVANT_SCANQUERY
+# testNestedGroupByOnInlineDataSourceWithFilter@filter-rewrites-disabled@NullHandling=default case-crc:5d06346f
+# quidem testcase reason: SCAN_QUERY_ON_FILTERED_DS_DOING_FILTERING
 !set debug true
 !set defaultTimeout 300000
 !set enableJoinFilterRewrite false
@@ -59,29 +59,23 @@
           "query" : {
             "queryType" : "scan",
             "dataSource" : {
-              "type" : "query",
-              "query" : {
-                "queryType" : "scan",
-                "dataSource" : {
-                  "type" : "table",
-                  "name" : "foo"
-                },
-                "intervals" : {
-                  "type" : "intervals",
-                  "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
-                },
-                "resultFormat" : "compactedList",
-                "columns" : [ "dim1" ],
-                "columnTypes" : [ "STRING" ],
-                "granularity" : {
-                  "type" : "all"
-                },
-                "legacy" : false
+              "type" : "filter",
+              "base" : {
+                "type" : "table",
+                "name" : "foo"
+              },
+              "filter" : {
+                "type" : "bound",
+                "dimension" : "__time",
+                "lower" : "978393600000",
+                "ordering" : {
+                  "type" : "numeric"
+                }
               }
             },
             "intervals" : {
               "type" : "intervals",
-              "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+              "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
             },
             "resultFormat" : "compactedList",
             "filter" : {
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@filter-rewrites-disabled@NullHandling=sql.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@filter-rewrites-disabled@NullHandling=sql.iq
index 2b1f2d9..4090856 100644
--- a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@filter-rewrites-disabled@NullHandling=sql.iq
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@filter-rewrites-disabled@NullHandling=sql.iq
@@ -1,5 +1,5 @@
-# testNestedGroupByOnInlineDataSourceWithFilter@filter-rewrites-disabled@NullHandling=sql case-crc:d155bb65
-# quidem testcase reason: IRRELEVANT_SCANQUERY
+# testNestedGroupByOnInlineDataSourceWithFilter@filter-rewrites-disabled@NullHandling=sql case-crc:5d06346f
+# quidem testcase reason: SCAN_QUERY_ON_FILTERED_DS_DOING_FILTERING
 !set debug true
 !set defaultTimeout 300000
 !set enableJoinFilterRewrite false
@@ -59,29 +59,21 @@
           "query" : {
             "queryType" : "scan",
             "dataSource" : {
-              "type" : "query",
-              "query" : {
-                "queryType" : "scan",
-                "dataSource" : {
-                  "type" : "table",
-                  "name" : "foo"
-                },
-                "intervals" : {
-                  "type" : "intervals",
-                  "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
-                },
-                "resultFormat" : "compactedList",
-                "columns" : [ "dim1" ],
-                "columnTypes" : [ "STRING" ],
-                "granularity" : {
-                  "type" : "all"
-                },
-                "legacy" : false
+              "type" : "filter",
+              "base" : {
+                "type" : "table",
+                "name" : "foo"
+              },
+              "filter" : {
+                "type" : "range",
+                "column" : "__time",
+                "matchValueType" : "LONG",
+                "lower" : 978393600000
               }
             },
             "intervals" : {
               "type" : "intervals",
-              "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+              "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
             },
             "resultFormat" : "compactedList",
             "filter" : {
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@filter-rewrites@NullHandling=default.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@filter-rewrites@NullHandling=default.iq
index 38fa8f5..dede5bf 100644
--- a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@filter-rewrites@NullHandling=default.iq
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@filter-rewrites@NullHandling=default.iq
@@ -1,5 +1,5 @@
-# testNestedGroupByOnInlineDataSourceWithFilter@filter-rewrites@NullHandling=default case-crc:9c16e907
-# quidem testcase reason: IRRELEVANT_SCANQUERY
+# testNestedGroupByOnInlineDataSourceWithFilter@filter-rewrites@NullHandling=default case-crc:1045660d
+# quidem testcase reason: SCAN_QUERY_ON_FILTERED_DS_DOING_FILTERING
 !set debug true
 !set defaultTimeout 300000
 !set enableJoinFilterRewrite true
@@ -59,29 +59,23 @@
           "query" : {
             "queryType" : "scan",
             "dataSource" : {
-              "type" : "query",
-              "query" : {
-                "queryType" : "scan",
-                "dataSource" : {
-                  "type" : "table",
-                  "name" : "foo"
-                },
-                "intervals" : {
-                  "type" : "intervals",
-                  "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
-                },
-                "resultFormat" : "compactedList",
-                "columns" : [ "dim1" ],
-                "columnTypes" : [ "STRING" ],
-                "granularity" : {
-                  "type" : "all"
-                },
-                "legacy" : false
+              "type" : "filter",
+              "base" : {
+                "type" : "table",
+                "name" : "foo"
+              },
+              "filter" : {
+                "type" : "bound",
+                "dimension" : "__time",
+                "lower" : "978393600000",
+                "ordering" : {
+                  "type" : "numeric"
+                }
               }
             },
             "intervals" : {
               "type" : "intervals",
-              "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+              "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
             },
             "resultFormat" : "compactedList",
             "filter" : {
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@filter-rewrites@NullHandling=sql.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@filter-rewrites@NullHandling=sql.iq
index e253673..d9b008e 100644
--- a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@filter-rewrites@NullHandling=sql.iq
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@filter-rewrites@NullHandling=sql.iq
@@ -1,5 +1,5 @@
-# testNestedGroupByOnInlineDataSourceWithFilter@filter-rewrites@NullHandling=sql case-crc:9c16e907
-# quidem testcase reason: IRRELEVANT_SCANQUERY
+# testNestedGroupByOnInlineDataSourceWithFilter@filter-rewrites@NullHandling=sql case-crc:1045660d
+# quidem testcase reason: SCAN_QUERY_ON_FILTERED_DS_DOING_FILTERING
 !set debug true
 !set defaultTimeout 300000
 !set enableJoinFilterRewrite true
@@ -59,29 +59,21 @@
           "query" : {
             "queryType" : "scan",
             "dataSource" : {
-              "type" : "query",
-              "query" : {
-                "queryType" : "scan",
-                "dataSource" : {
-                  "type" : "table",
-                  "name" : "foo"
-                },
-                "intervals" : {
-                  "type" : "intervals",
-                  "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
-                },
-                "resultFormat" : "compactedList",
-                "columns" : [ "dim1" ],
-                "columnTypes" : [ "STRING" ],
-                "granularity" : {
-                  "type" : "all"
-                },
-                "legacy" : false
+              "type" : "filter",
+              "base" : {
+                "type" : "table",
+                "name" : "foo"
+              },
+              "filter" : {
+                "type" : "range",
+                "column" : "__time",
+                "matchValueType" : "LONG",
+                "lower" : 978393600000
               }
             },
             "intervals" : {
               "type" : "intervals",
-              "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+              "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
             },
             "resultFormat" : "compactedList",
             "filter" : {
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@join-to-filter@NullHandling=default.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@join-to-filter@NullHandling=default.iq
index 0e6bb9c..220d7f4 100644
--- a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@join-to-filter@NullHandling=default.iq
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@join-to-filter@NullHandling=default.iq
@@ -1,5 +1,5 @@
-# testNestedGroupByOnInlineDataSourceWithFilter@join-to-filter@NullHandling=default case-crc:34b62ae1
-# quidem testcase reason: IRRELEVANT_SCANQUERY
+# testNestedGroupByOnInlineDataSourceWithFilter@join-to-filter@NullHandling=default case-crc:6cf62e05
+# quidem testcase reason: SCAN_QUERY_ON_FILTERED_DS_DOING_FILTERING
 !set debug true
 !set defaultTimeout 300000
 !set enableJoinFilterRewrite false
@@ -59,29 +59,23 @@
           "query" : {
             "queryType" : "scan",
             "dataSource" : {
-              "type" : "query",
-              "query" : {
-                "queryType" : "scan",
-                "dataSource" : {
-                  "type" : "table",
-                  "name" : "foo"
-                },
-                "intervals" : {
-                  "type" : "intervals",
-                  "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
-                },
-                "resultFormat" : "compactedList",
-                "columns" : [ "dim1" ],
-                "columnTypes" : [ "STRING" ],
-                "granularity" : {
-                  "type" : "all"
-                },
-                "legacy" : false
+              "type" : "filter",
+              "base" : {
+                "type" : "table",
+                "name" : "foo"
+              },
+              "filter" : {
+                "type" : "bound",
+                "dimension" : "__time",
+                "lower" : "978393600000",
+                "ordering" : {
+                  "type" : "numeric"
+                }
               }
             },
             "intervals" : {
               "type" : "intervals",
-              "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+              "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
             },
             "resultFormat" : "compactedList",
             "filter" : {
diff --git a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@join-to-filter@NullHandling=sql.iq b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@join-to-filter@NullHandling=sql.iq
index 043c4d0..8297fc8 100644
--- a/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@join-to-filter@NullHandling=sql.iq
+++ b/sql/src/test/quidem/org.apache.druid.sql.calcite.DecoupledPlanningCalciteJoinQueryTest/testNestedGroupByOnInlineDataSourceWithFilter@join-to-filter@NullHandling=sql.iq
@@ -1,5 +1,5 @@
-# testNestedGroupByOnInlineDataSourceWithFilter@join-to-filter@NullHandling=sql case-crc:34b62ae1
-# quidem testcase reason: IRRELEVANT_SCANQUERY
+# testNestedGroupByOnInlineDataSourceWithFilter@join-to-filter@NullHandling=sql case-crc:6cf62e05
+# quidem testcase reason: SCAN_QUERY_ON_FILTERED_DS_DOING_FILTERING
 !set debug true
 !set defaultTimeout 300000
 !set enableJoinFilterRewrite false
@@ -59,29 +59,21 @@
           "query" : {
             "queryType" : "scan",
             "dataSource" : {
-              "type" : "query",
-              "query" : {
-                "queryType" : "scan",
-                "dataSource" : {
-                  "type" : "table",
-                  "name" : "foo"
-                },
-                "intervals" : {
-                  "type" : "intervals",
-                  "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
-                },
-                "resultFormat" : "compactedList",
-                "columns" : [ "dim1" ],
-                "columnTypes" : [ "STRING" ],
-                "granularity" : {
-                  "type" : "all"
-                },
-                "legacy" : false
+              "type" : "filter",
+              "base" : {
+                "type" : "table",
+                "name" : "foo"
+              },
+              "filter" : {
+                "type" : "range",
+                "column" : "__time",
+                "matchValueType" : "LONG",
+                "lower" : 978393600000
               }
             },
             "intervals" : {
               "type" : "intervals",
-              "intervals" : [ "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z" ]
+              "intervals" : [ "2001-01-02T00:00:00.000Z/146140482-04-24T15:36:27.903Z" ]
             },
             "resultFormat" : "compactedList",
             "filter" : {