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

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

commit fb8961528ff559e109612465cdef3e62eee852e2
Author: Stamatis Zampetakis <zabe...@gmail.com>
AuthorDate: Wed Sep 2 13:54:17 2020 +0300

    [CALCITE-4221] Update stale integration tests in Druid adapter
    
    Update doc of DruidAdapterIT and DruidAdapter2IT to reflect the
    new dockerized Druid setup.
    
    The changes in the following tests are due to CALCITE-4202:
    
    * testSelectDistinctWiki
    * testSelectDistinctWikiNoColumns
    * testSelectDistinctWikiNoTables
    * testSelectDistinct
    * testFilterUnionPlan
    * testDistinctCount
    * testPushComplexFilter
    * testCountOnMetric
    * testCountOnMetricRenamed
    * testPushEqualsCastDimension
    * testPushNotEqualsCastDimension
    * testComplexExpressionsIsNull
    
    The changes in the following tests are due to CALCITE-4212:
    
    * testSelectTimestampColumnNoTables1
    * testUnionPlan
    * testProject
    * testTimeExtractThatCannotBePushed
    * testSubStringExpressionFilter
    
    The changes in the following tests are due to both CALCITE-4212 and
    CALCITE-4202:
    
    * testUnionPlan
    * testDistinctCountOnMetric
    * testDistinctCountOnMetricRenamed
    * testDistinctCountWhenApproxResultsNotAccepted
    * testFilterClauseWithMetricRefAndAggregates
    
    The rest of the changes are normal improvements of the optimizer.
    
    Problematic tests are skipped with the appropriate JIRA references
    describing the problem.
---
 .../src/main/java/org/apache/calcite/util/Bug.java |  15 +
 .../org/apache/calcite/test/DruidAdapter2IT.java   | 368 ++++++++++-----------
 .../org/apache/calcite/test/DruidAdapterIT.java    | 347 ++++++++++---------
 3 files changed, 375 insertions(+), 355 deletions(-)

diff --git a/core/src/main/java/org/apache/calcite/util/Bug.java 
b/core/src/main/java/org/apache/calcite/util/Bug.java
index a7a502a..85531a2 100644
--- a/core/src/main/java/org/apache/calcite/util/Bug.java
+++ b/core/src/main/java/org/apache/calcite/util/Bug.java
@@ -186,6 +186,21 @@ public abstract class Bug {
    * Incomplete validation of operands in JSON functions</a> is fixed. */
   public static final boolean CALCITE_3243_FIXED = false;
 
+  /** Whether
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-4204";>[CALCITE-4204]
+   * Intermittent precision in Druid results when using aggregation functions 
over columns of type
+   * DOUBLE</a> is fixed. */
+  public static final boolean CALCITE_4204_FIXED = false;
+  /** Whether
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-4205";>[CALCITE-4205]
+   * DruidAdapterIT#testDruidTimeFloorAndTimeParseExpressions2 fails</a> is 
fixed. */
+  public static final boolean CALCITE_4205_FIXED = false;
+  /** Whether
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-4213";>[CALCITE-4213]
+   * Druid plans with small intervals should be chosen over full interval scan 
plus filter</a> is
+   * fixed. */
+  public static final boolean CALCITE_4213_FIXED = false;
+
   /**
    * Use this to flag temporary code.
    */
diff --git a/druid/src/test/java/org/apache/calcite/test/DruidAdapter2IT.java 
b/druid/src/test/java/org/apache/calcite/test/DruidAdapter2IT.java
index 4d6d069..a2bcf78 100644
--- a/druid/src/test/java/org/apache/calcite/test/DruidAdapter2IT.java
+++ b/druid/src/test/java/org/apache/calcite/test/DruidAdapter2IT.java
@@ -24,12 +24,14 @@ import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.schema.impl.AbstractSchema;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.calcite.util.Bug;
 import org.apache.calcite.util.TestUtil;
 
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Multimap;
 
+import org.junit.jupiter.api.Assumptions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
@@ -48,15 +50,9 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue;
 /**
  * Tests for the {@code org.apache.calcite.adapter.druid} package.
  *
- * <p>Before calling this test, you need to populate Druid, as follows:
- *
- * <blockquote><code>
- * git clone https://github.com/vlsi/calcite-test-dataset<br>
- * cd calcite-test-dataset<br>
- * mvn install
- * </code></blockquote>
- *
- * <p>This will create a virtual machine with Druid and test data set.
+ * <p>Druid must be up and running with foodmart and wikipedia datasets 
loaded. Follow the
+ * instructions on <a 
href="https://github.com/zabetak/calcite-druid-dataset";>calcite-druid-dataset
+ * </a> to setup Druid before launching these tests.</p>
  *
  * <p>Features not yet implemented:
  * <ul>
@@ -146,7 +142,7 @@ public class DruidAdapter2IT {
   @Test void testSelectDistinct() {
     final String explain = "PLAN="
         + "EnumerableInterpreter\n"
-        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], groups=[{30}], 
aggs=[[]])";
+        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
projects=[[$30]], groups=[{0}], aggs=[[]])";
     final String sql = "select distinct \"state_province\" from \"foodmart\"";
     final String druidQuery = 
"{'queryType':'groupBy','dataSource':'foodmart','granularity':'all',"
         + 
"'dimensions':[{'type':'default','dimension':'state_province','outputName':'state_province'"
@@ -621,10 +617,11 @@ public class DruidAdapter2IT {
         + "union all\n"
         + "select distinct \"marital_status\" from \"foodmart\"";
     final String explain = "PLAN="
-        + "EnumerableInterpreter\n"
-        + "  BindableUnion(all=[true])\n"
-        + "    DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], groups=[{39}], 
aggs=[[]])\n"
-        + "    DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], groups=[{37}], 
aggs=[[]])";
+        + "EnumerableUnion(all=[true])\n"
+        + "  EnumerableInterpreter\n"
+        + "    DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
projects=[[$39]], groups=[{0}], aggs=[[]])\n"
+        + "  EnumerableInterpreter\n"
+        + "    DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
projects=[[$37]], groups=[{0}], aggs=[[]])";
     sql(sql)
         .explainContains(explain)
         .returnsUnordered(
@@ -644,8 +641,8 @@ public class DruidAdapter2IT {
         + "EnumerableInterpreter\n"
         + "  BindableFilter(condition=[=($0, 'M')])\n"
         + "    BindableUnion(all=[true])\n"
-        + "      DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], groups=[{39}], 
aggs=[[]])\n"
-        + "      DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], groups=[{37}], 
aggs=[[]])";
+        + "      DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
projects=[[$39]], groups=[{0}], aggs=[[]])\n"
+        + "      DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
projects=[[$37]], groups=[{0}], aggs=[[]])";
     sql(sql)
         .explainContains(explain)
         .returnsUnordered("gender=M",
@@ -659,8 +656,7 @@ public class DruidAdapter2IT {
         + "'intervals':['1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z'],"
         + "'context':{'skipEmptyBuckets':false}}";
     final String explain = "PLAN=EnumerableInterpreter\n"
-        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
-        + "2992-01-10T00:00:00.000Z]], projects=[[0]], groups=[{}], 
aggs=[[COUNT()]])";
+        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], groups=[{}], 
aggs=[[COUNT()]])";
     final String sql = "select count(*) from \"foodmart\"";
     sql(sql)
         .returns("EXPR$0=86829\n")
@@ -988,14 +984,12 @@ public class DruidAdapter2IT {
     final String explain = "PLAN=EnumerableInterpreter\n"
         + "  BindableSort(sort0=[$1], dir0=[DESC], fetch=[2])\n"
         + "    BindableProject(state_province=[$0], CDC=[FLOOR($1)])\n"
-        + "      BindableAggregate(group=[{1}], agg#0=[COUNT($0)])\n"
-        + "        DruidQuery(table=[[foodmart, foodmart]], "
-        + "intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
groups=[{29, 30}], "
-        + "aggs=[[]])";
+        + "      BindableAggregate(group=[{0}], agg#0=[COUNT($1)])\n"
+        + "        DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
projects=[[$30, $29]], groups=[{0, 1}], aggs=[[]])";
     final String druidQuery = "{'queryType':'groupBy','dataSource':'foodmart',"
-        + 
"'granularity':'all','dimensions':[{'type':'default','dimension':'city','outputName':'city'"
-        + ",'outputType':'STRING'},"
-        + 
"{'type':'default','dimension':'state_province','outputName':'state_province','outputType':'STRING'}],"
+        + "'granularity':'all','dimensions':["
+        + 
"{'type':'default','dimension':'state_province','outputName':'state_province','outputType':'STRING'},"
+        + 
"{'type':'default','dimension':'city','outputName':'city','outputType':'STRING'}],"
         + "'limitSpec':{'type':'default'},'aggregations':[],"
         + "'intervals':['1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z']}";
     sql(sql)
@@ -1012,10 +1006,10 @@ public class DruidAdapter2IT {
     final String sql = "select \"product_name\", 0 as zero\n"
         + "from \"foodmart\"\n"
         + "order by \"product_name\"";
-    final String explain = "PLAN=EnumerableInterpreter\n"
-        + "  BindableSort(sort0=[$0], dir0=[ASC])\n"
-        + "    DruidQuery(table=[[foodmart, foodmart]], "
-        + "intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
projects=[[$3, 0]])";
+    final String explain = "PLAN="
+        + "EnumerableSort(sort0=[$0], dir0=[ASC])\n"
+        + "  EnumerableInterpreter\n"
+        + "    DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], projects=[[$3, 
0]])";
     sql(sql)
         .limit(2)
         .returnsUnordered("product_name=ADJ Rosy Sunglasses; ZERO=0",
@@ -1121,9 +1115,10 @@ public class DruidAdapter2IT {
         + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1997-04-01T00:00:00.000Z/"
         + "1997-05-01T00:00:00.000Z, 
1997-06-01T00:00:00.000Z/1997-07-01T00:00:00.000Z]],"
         + " projects=[[0]], groups=[{}], aggs=[[COUNT()]])";
-    sql(sql)
-        .returnsUnordered("C=13500")
-        .explainContains(explain);
+    CalciteAssert.AssertQuery q = sql(sql)
+        .returnsUnordered("C=13500");
+    Assumptions.assumeTrue(Bug.CALCITE_4213_FIXED, "CALCITE-4213");
+    q.explainContains(explain);
   }
 
   @Test void testFilterSwapped() {
@@ -1344,11 +1339,7 @@ public class DruidAdapter2IT {
         + "1998-01-01T00:00:00.000Z'],'context':{'skipEmptyBuckets':false}}";
     sql(sql)
         .explainContains("PLAN=EnumerableInterpreter\n"
-            + "  DruidQuery(table=[[foodmart, foodmart]], "
-            + 
"intervals=[[1997-01-01T00:00:00.000Z/1998-01-01T00:00:00.000Z]], "
-            + "filter=[AND(>=(CAST($11):INTEGER, 8), <=(CAST($11):INTEGER, 
10), "
-            + "<(CAST($10):INTEGER, 15))], groups=[{}], "
-            + "aggs=[[SUM($90)]])\n")
+            + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1997-01-01T00:00:00.000Z/1998-01-01T00:00:00.000Z]], 
filter=[AND(>=(CAST($11):INTEGER, 8), <=(CAST($11):INTEGER, 10), 
<(CAST($10):INTEGER, 15))], projects=[[$90]], groups=[{}], aggs=[[SUM($0)]])")
         .returnsUnordered("EXPR$0=75364.1")
         .queryContains(new DruidChecker(druidQuery));
   }
@@ -1642,12 +1633,11 @@ public class DruidAdapter2IT {
   @Test void testTimeExtractThatCannotBePushed() {
     final String sql = "SELECT extract(CENTURY from \"timestamp\") from 
\"foodmart\" where "
         + "\"product_id\" = 1558 group by extract(CENTURY from \"timestamp\")";
-    final String plan = "PLAN=EnumerableInterpreter\n"
-        + "  BindableAggregate(group=[{0}])\n"
+    final String plan = "PLAN="
+        + "EnumerableAggregate(group=[{0}])\n"
+        + "  EnumerableInterpreter\n"
         + "    BindableProject(EXPR$0=[EXTRACT(FLAG(CENTURY), $0)])\n"
-        + "      DruidQuery(table=[[foodmart, foodmart]], "
-        + "intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], "
-        + "filter=[=(CAST($1):INTEGER, 1558)], projects=[[$0]])\n";
+        + "      DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
filter=[=(CAST($1):INTEGER, 1558)], projects=[[$0]])";
     sql(sql).explainContains(plan).queryContains(new 
DruidChecker("'queryType':'scan'"))
         .returnsUnordered("EXPR$0=20");
   }
@@ -1739,12 +1729,13 @@ public class DruidAdapter2IT {
         + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
         + "2992-01-10T00:00:00.000Z]], projects=[[$63, $90, $91]], 
groups=[{0}], "
         + "aggs=[[SUM($1), SUM($2)]], post_projects=[[+($1, $2), $0]], 
sort0=[0], dir0=[DESC])";
-    sql(sqlQuery, FOODMART)
-        .returnsOrdered("A=369117.52790000016; store_state=WA",
-            "A=222698.26509999996; store_state=CA",
-            "A=199049.57059999998; store_state=OR")
+    CalciteAssert.AssertQuery q = sql(sqlQuery, FOODMART)
         .explainContains(plan)
         .queryContains(new DruidChecker(postAggString));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("A=369117.52790000016; store_state=WA",
+        "A=222698.26509999996; store_state=CA",
+        "A=199049.57059999998; store_state=OR");
   }
 
   @Test void testDivideArithmeticOperation() {
@@ -1755,12 +1746,13 @@ public class DruidAdapter2IT {
         + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
         + "2992-01-10T00:00:00.000Z]], projects=[[$63, $90, $91]], 
groups=[{0}], "
         + "aggs=[[SUM($1), SUM($2)]], post_projects=[[$0, /($1, $2)]], 
sort0=[1], dir0=[DESC])";
-    sql(sqlQuery, FOODMART)
-        .returnsOrdered("store_state=OR; A=2.506091302943239",
-            "store_state=CA; A=2.505379741272971",
-            "store_state=WA; A=2.5045806163801996")
+    CalciteAssert.AssertQuery q = sql(sqlQuery, FOODMART)
         .explainContains(plan)
         .queryContains(new DruidChecker(postAggString));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("store_state=OR; A=2.506091302943239",
+        "store_state=CA; A=2.505379741272971",
+        "store_state=WA; A=2.5045806163801996");
   }
 
   @Test void testMultiplyArithmeticOperation() {
@@ -1771,12 +1763,13 @@ public class DruidAdapter2IT {
         + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
         + "2992-01-10T00:00:00.000Z]], projects=[[$63, $90, $91]], 
groups=[{0}], aggs=[[SUM($1),"
         + " SUM($2)]], post_projects=[[$0, *($1, $2)]], sort0=[1], 
dir0=[DESC])";
-    sql(sqlQuery, FOODMART)
-        .returnsOrdered("store_state=WA; A=2.7783838325212463E10",
-            "store_state=CA; A=1.0112000537448784E10",
-            "store_state=OR; A=8.077425041941243E9")
+    CalciteAssert.AssertQuery q = sql(sqlQuery, FOODMART)
         .explainContains(plan)
         .queryContains(new DruidChecker(postAggString));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("store_state=WA; A=2.7783838325212463E10",
+        "store_state=CA; A=1.0112000537448784E10",
+        "store_state=OR; A=8.077425041941243E9");
   }
 
   @Test void testMinusArithmeticOperation() {
@@ -1788,12 +1781,13 @@ public class DruidAdapter2IT {
         + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
         + "2992-01-10T00:00:00.000Z]], projects=[[$63, $90, $91]], 
groups=[{0}], aggs=[[SUM($1), "
         + "SUM($2)]], post_projects=[[$0, -($1, $2)]], sort0=[1], 
dir0=[DESC])";
-    sql(sqlQuery, FOODMART)
-        .returnsOrdered("store_state=WA; A=158468.91210000002",
-            "store_state=CA; A=95637.41489999992",
-            "store_state=OR; A=85504.56939999988")
+    CalciteAssert.AssertQuery q = sql(sqlQuery, FOODMART)
         .explainContains(plan)
         .queryContains(new DruidChecker(postAggString));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("store_state=WA; A=158468.91210000002",
+        "store_state=CA; A=95637.41489999992",
+        "store_state=OR; A=85504.56939999988");
   }
 
   @Test void testConstantPostAggregator() {
@@ -1804,12 +1798,14 @@ public class DruidAdapter2IT {
         + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
         + "2992-01-10T00:00:00.000Z]], projects=[[$63, $90]], groups=[{0}], 
aggs=[[SUM($1)]], "
         + "post_projects=[[$0, +($1, 100)]], sort0=[1], dir0=[DESC])";
-    sql(sqlQuery, FOODMART)
-        .returnsOrdered("store_state=WA; A=263893.2200000001",
-            "store_state=CA; A=159267.83999999994",
-            "store_state=OR; A=142377.06999999992")
+    CalciteAssert.AssertQuery q = sql(sqlQuery, FOODMART)
         .explainContains(plan)
         .queryContains(new DruidChecker(postAggString));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered(
+        "store_state=WA; A=263893.2200000001",
+        "store_state=CA; A=159267.83999999994",
+        "store_state=OR; A=142377.06999999992");
   }
 
   @Test void testRecursiveArithmeticOperation() {
@@ -1820,10 +1816,7 @@ public class DruidAdapter2IT {
     String postAggString = 
"'postAggregations':[{'type':'expression','name':'C','expression':"
         + "'(-1 * (((\\'$f1\\' - \\'$f2\\') / (\\'$f3\\' * 3)) + \\'B\\'))'}]";
     final String plan = "PLAN=EnumerableInterpreter\n"
-        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
-        + "2992-01-10T00:00:00.000Z]], projects=[[$63, $89, $90, $91]], 
groups=[{0}], "
-        + "aggs=[[SUM($2), SUM($3), COUNT(), SUM($1)]], post_projects=[[$0, 
*(-1, +(/(-($1, $2), "
-        + "*($3, 3)), $4))]], sort0=[1], dir0=[DESC])";
+        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
projects=[[$63, $90, $91, $89]], groups=[{0}], aggs=[[SUM($1), SUM($2), 
COUNT(), SUM($3)]], post_projects=[[$0, *(-1, +(/(-($1, $2), *($3, 3)), $4))]], 
sort0=[1], dir0=[DESC])";
     sql(sqlQuery, FOODMART)
         .returnsOrdered("store_state=OR; C=-67660.31890435601",
             "store_state=CA; C=-74749.30433035882",
@@ -1839,9 +1832,7 @@ public class DruidAdapter2IT {
     final String postAggString = "[{'type':'expression','name':'A',"
         + "'expression':'(\\'$f1\\' / \\'$f2\\')'}]";
     final String plan = "PLAN=EnumerableInterpreter\n"
-        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
-        + "2992-01-10T00:00:00.000Z]], projects=[[$2, $63, $91]], 
groups=[{1}], aggs=[[SUM($2), "
-        + "COUNT(DISTINCT $0)]], post_projects=[[$0, /($1, $2)]], sort0=[1], 
dir0=[DESC])";
+        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
projects=[[$63, $91, $2]], groups=[{0}], aggs=[[SUM($1), COUNT(DISTINCT $2)]], 
post_projects=[[$0, /($1, $2)]], sort0=[1], dir0=[DESC])";
     foodmartApprox(sqlQuery)
         .runs()
         .explainContains(plan)
@@ -1895,12 +1886,13 @@ public class DruidAdapter2IT {
         + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
         + "2992-01-10T00:00:00.000Z]], projects=[[$63, $91]], groups=[{0}], "
         + "aggs=[[SUM($1), COUNT()]], post_projects=[[$0, /($1, $2)]], 
sort0=[1], dir0=[DESC])";
-    sql(sqlQuery, FOODMART)
-        .returnsOrdered("store_state=OR; A=2.6271402406293403",
-            "store_state=CA; A=2.599338206292706",
-            "store_state=WA; A=2.5828708592868717")
+    CalciteAssert.AssertQuery q = sql(sqlQuery, FOODMART)
         .explainContains(plan)
         .queryContains(new DruidChecker(postAggString));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("store_state=OR; A=2.6271402406293403",
+        "store_state=CA; A=2.599338206292706",
+        "store_state=WA; A=2.5828708592868717");
   }
 
   @Test void testPartiallyPostAggregation() {
@@ -1910,18 +1902,16 @@ public class DruidAdapter2IT {
     final String postAggString = 
"'postAggregations':[{'type':'expression','name':'A',"
         + "'expression':'(\\'$f1\\' / 
\\'$f2\\')'},{'type':'expression','name':'B',"
         + "'expression':'case_searched((\\'$f3\\' == 0),1.0,CAST(\\'$f3\\'";
-    final String plan =
-        "PLAN=EnumerableInterpreter\n"
-            + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
-            + "2992-01-10T00:00:00.000Z]], projects=[[$63, $89, $90, $91]], 
groups=[{0}], "
-            + "aggs=[[SUM($2), SUM($3), SUM($1)]], post_projects=[[$0, /($1, 
$2), CASE(=($3, 0), "
-            + "1.0:DECIMAL(19, 0), CAST($3):DECIMAL(19, 0))]], sort0=[1], 
dir0=[DESC])\n";
-    sql(sqlQuery, FOODMART)
-        .returnsOrdered("store_state=OR; A=2.506091302943239; B=67659.0",
-            "store_state=CA; A=2.505379741272971; B=74748.0",
-            "store_state=WA; A=2.5045806163801996; B=124366.0")
+    final String plan = "PLAN="
+            + "EnumerableInterpreter\n"
+            + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
projects=[[$63, $90, $91, $89]], groups=[{0}], aggs=[[SUM($1), SUM($2), 
SUM($3)]], post_projects=[[$0, /($1, $2), CASE(=($3, 0), 1.0:DECIMAL(19, 0), 
CAST($3):DECIMAL(19, 0))]], sort0=[1], dir0=[DESC])\n";
+    CalciteAssert.AssertQuery q = sql(sqlQuery, FOODMART)
         .explainContains(plan)
         .queryContains(new DruidChecker(postAggString));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("store_state=OR; A=2.506091302943239; B=67659.0",
+        "store_state=CA; A=2.505379741272971; B=74748.0",
+        "store_state=WA; A=2.5045806163801996; B=124366.0");
   }
 
   @Test void testDuplicateReferenceOnPostAggregation() {
@@ -1935,12 +1925,13 @@ public class DruidAdapter2IT {
         + "2992-01-10T00:00:00.000Z]], projects=[[$63, $90, $91]], 
groups=[{0}], "
         + "aggs=[[SUM($1), SUM($2)]], post_projects=[[$0, +($1, 100), "
         + "-(+($1, 100), $2)]], sort0=[1], dir0=[DESC])";
-    sql(sqlQuery, FOODMART)
-        .returnsOrdered("store_state=WA; A=263893.2200000001; 
C=158568.91210000002",
-            "store_state=CA; A=159267.83999999994; C=95737.41489999992",
-            "store_state=OR; A=142377.06999999992; C=85604.56939999988")
+    CalciteAssert.AssertQuery q = sql(sqlQuery, FOODMART)
         .explainContains(plan)
         .queryContains(new DruidChecker(postAggString));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("store_state=WA; A=263893.2200000001; 
C=158568.91210000002",
+        "store_state=CA; A=159267.83999999994; C=95737.41489999992",
+        "store_state=OR; A=142377.06999999992; C=85604.56939999988");
   }
 
   @Test void testDivideByZeroDoubleTypeInfinity() {
@@ -2020,17 +2011,16 @@ public class DruidAdapter2IT {
     String postAggString = 
"\"postAggregations\":[{\"type\":\"expression\",\"name\":\"A\","
         + "\"expression\":\"(\\\"$f2\\\" - \\\"$f3\\\")\"}";
     final String plan = "PLAN=EnumerableInterpreter\n"
-        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
-        + "2992-01-10T00:00:00.000Z]], groups=[{2, 63}], aggs=[[SUM($90), 
SUM($91)]], "
-        + "post_projects=[[$1, $0, -($2, $3)]], sort0=[2], dir0=[ASC], 
fetch=[5])";
-    sql(sqlQuery, FOODMART)
-        .returnsOrdered("store_state=CA; brand_name=King; A=21.4632",
-            "store_state=OR; brand_name=Symphony; A=32.176",
-            "store_state=CA; brand_name=Toretti; A=32.24650000000001",
-            "store_state=WA; brand_name=King; A=34.6104",
-            "store_state=OR; brand_name=Toretti; A=36.3")
+        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
projects=[[$63, $2, $90, $91]], groups=[{0, 1}], aggs=[[SUM($2), SUM($3)]], 
post_projects=[[$0, $1, -($2, $3)]], sort0=[2], dir0=[ASC], fetch=[5])";
+    CalciteAssert.AssertQuery q = sql(sqlQuery, FOODMART)
         .explainContains(plan)
         .queryContains(new DruidChecker(postAggString));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("store_state=CA; brand_name=King; A=21.4632",
+        "store_state=OR; brand_name=Symphony; A=32.176",
+        "store_state=CA; brand_name=Toretti; A=32.24650000000001",
+        "store_state=WA; brand_name=King; A=34.6104",
+        "store_state=OR; brand_name=Toretti; A=36.3");
   }
 
   @Test void testInterleaveBetweenAggregateAndGroupOrderByOnDimension() {
@@ -2041,17 +2031,16 @@ public class DruidAdapter2IT {
     final String postAggString = 
"'postAggregations':[{'type':'expression','name':'A',"
         + "'expression':'(\\'$f2\\' + \\'$f3\\')'}]";
     final String plan = "PLAN=EnumerableInterpreter\n"
-        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
-        + "2992-01-10T00:00:00.000Z]], groups=[{2, 63}], aggs=[[SUM($90), 
SUM($91)]], post_projects"
-        + "=[[$1, $0, +($2, $3)]], sort0=[1], sort1=[0], dir0=[ASC], 
dir1=[ASC], fetch=[5])";
-    sql(sqlQuery, FOODMART)
-        .returnsOrdered("store_state=CA; brand_name=ADJ; A=222.1524",
-            "store_state=OR; brand_name=ADJ; A=186.60359999999997",
-            "store_state=WA; brand_name=ADJ; A=216.9912",
-            "store_state=CA; brand_name=Akron; A=250.349",
-            "store_state=OR; brand_name=Akron; A=278.69720000000007")
+        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
projects=[[$63, $2, $90, $91]], groups=[{0, 1}], aggs=[[SUM($2), SUM($3)]], 
post_projects=[[$0, $1, +($2, $3)]], sort0=[1], sort1=[0], dir0=[ASC], 
dir1=[ASC], fetch=[5])";
+    CalciteAssert.AssertQuery q = sql(sqlQuery, FOODMART)
         .explainContains(plan)
         .queryContains(new DruidChecker(postAggString));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("store_state=CA; brand_name=ADJ; A=222.1524",
+        "store_state=OR; brand_name=ADJ; A=186.60359999999997",
+        "store_state=WA; brand_name=ADJ; A=216.9912",
+        "store_state=CA; brand_name=Akron; A=250.349",
+        "store_state=OR; brand_name=Akron; A=278.69720000000007");
   }
 
   @Test void testOrderByOnMetricsInSelectDruidQuery() {
@@ -2395,22 +2384,21 @@ public class DruidAdapter2IT {
   @Test void testFilterClauseWithMetricRefAndAggregates() {
     String sql = "select sum(\"store_sales\"), \"product_id\" "
         + "from \"foodmart\" where \"product_id\" > 1553 and \"store_cost\" > 
5 group by \"product_id\"";
-    String expectedSubExplain =
-        "PLAN=EnumerableInterpreter\n"
-            + "  BindableProject(EXPR$0=[$1], product_id=[$0])\n"
-            + "    DruidQuery(table=[[foodmart, foodmart]], "
-            + 
"intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], filter=[AND(>"
-            + "(CAST($1):INTEGER, 1553), >($91, 5))], groups=[{1}], 
aggs=[[SUM($90)]])";
+    String expectedSubExplain = "PLAN="
+        + "EnumerableCalc(expr#0..1=[{inputs}], EXPR$0=[$t1], 
product_id=[$t0])\n"
+        + "  EnumerableInterpreter\n"
+        + "    DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
filter=[AND(>(CAST($1):INTEGER, 1553), >($91, 5))], projects=[[$1, $90]], 
groups=[{0}], aggs=[[SUM($1)]])";
 
-    sql(sql)
+    CalciteAssert.AssertQuery q = sql(sql)
         .explainContains(expectedSubExplain)
         .queryContains(
             new DruidChecker("\"queryType\":\"groupBy\"", 
"{\"type\":\"bound\","
                 + 
"\"dimension\":\"store_cost\",\"lower\":\"5\",\"lowerStrict\":true,"
-                + "\"ordering\":\"numeric\"}"))
-        .returnsUnordered("EXPR$0=10.16; product_id=1554\n"
-            + "EXPR$0=45.05; product_id=1556\n"
-            + "EXPR$0=88.5; product_id=1555");
+                + "\"ordering\":\"numeric\"}"));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsUnordered("EXPR$0=10.16; product_id=1554\n"
+        + "EXPR$0=45.05; product_id=1556\n"
+        + "EXPR$0=88.5; product_id=1555");
   }
 
   @Test void testFilterClauseWithMetricAndTimeAndAggregates() {
@@ -2523,10 +2511,10 @@ public class DruidAdapter2IT {
    * when approximate results are not acceptable. */
   @Test void testDistinctCountWhenApproxResultsNotAccepted() {
     String sql = "select count(distinct \"store_state\") from \"foodmart\"";
-    String expectedSubExplain = "  BindableAggregate(group=[{}], 
EXPR$0=[COUNT($0)])\n"
-        + "    DruidQuery(table=[[foodmart, foodmart]], "
-        + "intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], "
-        + "groups=[{63}], aggs=[[]])";
+    String expectedSubExplain = ""
+        + "EnumerableAggregate(group=[{}], EXPR$0=[COUNT($0)])\n"
+        + "  EnumerableInterpreter\n"
+        + "    DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
projects=[[$63]], groups=[{0}], aggs=[[]])";
 
     testCountWithApproxDistinct(false, sql, expectedSubExplain);
   }
@@ -2534,15 +2522,12 @@ public class DruidAdapter2IT {
   @Test void testDistinctCountOnMetric() {
     final String sql = "select count(distinct \"store_sales\") from 
\"foodmart\" "
         + "where \"store_state\" = 'WA'";
-    final String expectedSubExplainNoApprox = "PLAN=EnumerableInterpreter\n"
-        + "  BindableAggregate(group=[{}], EXPR$0=[COUNT($0)])\n"
-        + "    DruidQuery(table=[[foodmart, foodmart]], "
-        + "intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
filter=[=($63, 'WA')"
-        + "], groups=[{90}], aggs=[[]])";
+    final String expectedSubExplainNoApprox = "PLAN="
+        + "EnumerableAggregate(group=[{}], EXPR$0=[COUNT($0)])\n"
+        + "  EnumerableInterpreter\n"
+        + "    DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], filter=[=($63, 
'WA')], projects=[[$90]], groups=[{0}], aggs=[[]])";
     final String expectedSubPlanWithApprox = "PLAN=EnumerableInterpreter\n"
-        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
-        + "2992-01-10T00:00:00.000Z]], filter=[=($63, 'WA')], groups=[{}], "
-        + "aggs=[[COUNT(DISTINCT $90)]])";
+        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], filter=[=($63, 
'WA')], projects=[[$90]], groups=[{}], aggs=[[COUNT(DISTINCT $0)]])";
 
     testCountWithApproxDistinct(true, sql, expectedSubPlanWithApprox, 
"'queryType':'timeseries'");
     testCountWithApproxDistinct(false, sql, expectedSubExplainNoApprox, 
"'queryType':'groupBy'");
@@ -2553,7 +2538,7 @@ public class DruidAdapter2IT {
     String sql = "select \"brand_name\", count(\"store_sales\") from 
\"foodmart\" "
         + "group by \"brand_name\"";
     String expectedSubExplain = "PLAN=EnumerableInterpreter\n"
-        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], groups=[{2}], 
aggs=[[COUNT($90)]])";
+        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], projects=[[$2, 
$90]], groups=[{0}], aggs=[[COUNT($1)]])";
 
     testCountWithApproxDistinct(true, sql, expectedSubExplain, 
"\"queryType\":\"groupBy\"");
     testCountWithApproxDistinct(false, sql, expectedSubExplain, 
"\"queryType\":\"groupBy\"");
@@ -2563,8 +2548,7 @@ public class DruidAdapter2IT {
   @Test void testCountStar() {
     String sql = "select count(*) from \"foodmart\"";
     String expectedSubExplain = "PLAN=EnumerableInterpreter\n"
-        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
-        + "2992-01-10T00:00:00.000Z]], projects=[[0]], groups=[{}], 
aggs=[[COUNT()]])";
+        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], groups=[{}], 
aggs=[[COUNT()]])";
 
     sql(sql).explainContains(expectedSubExplain);
   }
@@ -2575,8 +2559,7 @@ public class DruidAdapter2IT {
         + "(select \"unit_sales\" as \"A\", \"store_state\" as \"B\" from 
\"foodmart\") "
         + "group by \"B\"";
     String expectedSubExplain = "PLAN=EnumerableInterpreter\n"
-        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
-        + "2992-01-10T00:00:00.000Z]], groups=[{63}], aggs=[[COUNT($89)]])";
+        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
projects=[[$63, $89]], groups=[{0}], aggs=[[COUNT($1)]])";
 
     testCountWithApproxDistinct(true, sql, expectedSubExplain);
     testCountWithApproxDistinct(false, sql, expectedSubExplain);
@@ -2586,13 +2569,13 @@ public class DruidAdapter2IT {
     final String sql = "select \"B\", count(distinct \"A\") from "
         + "(select \"unit_sales\" as \"A\", \"store_state\" as \"B\" from 
\"foodmart\") "
         + "group by \"B\"";
-    final String expectedSubExplainNoApprox = "PLAN=EnumerableInterpreter\n"
-        + "  BindableAggregate(group=[{0}], EXPR$1=[COUNT($1)])\n"
-        + "    DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
-        + "2992-01-10T00:00:00.000Z]], projects=[[$63, $89]], groups=[{0, 1}], 
aggs=[[]])";
-    final String expectedPlanWithApprox = "PLAN=EnumerableInterpreter\n"
-        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
-        + "2992-01-10T00:00:00.000Z]], groups=[{63}], aggs=[[COUNT(DISTINCT 
$89)]])";
+    final String expectedSubExplainNoApprox = "PLAN="
+        + "EnumerableAggregate(group=[{0}], EXPR$1=[COUNT($1)])\n"
+        + "  EnumerableInterpreter\n"
+        + "    DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
projects=[[$63, $89]], groups=[{0, 1}], aggs=[[]])";
+    final String expectedPlanWithApprox = "PLAN="
+        + "EnumerableInterpreter\n"
+        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
projects=[[$63, $89]], groups=[{0}], aggs=[[COUNT(DISTINCT $1)]])";
 
     testCountWithApproxDistinct(true, sql, expectedPlanWithApprox, 
"'queryType':'groupBy'");
     testCountWithApproxDistinct(false, sql, expectedSubExplainNoApprox, 
"'queryType':'groupBy'");
@@ -2649,8 +2632,7 @@ public class DruidAdapter2IT {
         + "from \"foodmart\" "
         + "where cast(\"product_id\" as double) = 1016.0";
     final String plan = "PLAN=EnumerableInterpreter\n"
-        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], "
-        + "filter=[=(CAST($1):DOUBLE, 1016.0)], groups=[{}], 
aggs=[[SUM($91)]])";
+        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
filter=[=(CAST($1):DOUBLE, 1016.0)], projects=[[$91]], groups=[{}], 
aggs=[[SUM($0)]])";
     final String druidQuery =
         
"{'queryType':'timeseries','dataSource':'foodmart','descending':false,'granularity':'all',"
             + 
"'filter':{'type':'bound','dimension':'product_id','lower':'1016.0',"
@@ -2676,8 +2658,7 @@ public class DruidAdapter2IT {
         + "from \"foodmart\" "
         + "where cast(\"product_id\" as double) <> 1016.0";
     final String plan = "PLAN=EnumerableInterpreter\n"
-        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], "
-        + "filter=[<>(CAST($1):DOUBLE, 1016.0)], groups=[{}], 
aggs=[[SUM($91)]])";
+        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
filter=[<>(CAST($1):DOUBLE, 1016.0)], projects=[[$91]], groups=[{}], 
aggs=[[SUM($0)]])";
     final String druidQuery =
         
"{'queryType':'timeseries','dataSource':'foodmart','descending':false,'granularity':'all',"
             + 
"'filter':{'type':'not','field':{'type':'bound','dimension':'product_id','"
@@ -2911,9 +2892,7 @@ public class DruidAdapter2IT {
         + "(\"city\" as INTEGER)) IS NULL";
     sql(sql, FOODMART)
         .explainContains("PLAN=EnumerableInterpreter\n"
-            + "  DruidQuery(table=[[foodmart, foodmart]], "
-            + 
"intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], "
-            + "projects=[[0]], groups=[{}], aggs=[[COUNT()]])")
+            + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], groups=[{}], 
aggs=[[COUNT()]])")
         .queryContains(
             new DruidChecker(
                 
"{\"queryType\":\"timeseries\",\"dataSource\":\"foodmart\",\"descending\":false,"
@@ -3078,12 +3057,13 @@ public class DruidAdapter2IT {
     sql(sql, FOODMART)
         .returnsOrdered("timestamp=1997-01-01 00:00:00; EXPR$1=117")
         .queryContains(
-            new 
DruidChecker("\"filter\":{\"type\":\"expression\",\"expression\":\""
-                    + "(timestamp_floor(timestamp_parse(concat(concat(",
-                "== timestamp_floor(\\\"__time\\\""));
+            new DruidChecker(
+                
"\"filter\":{\"type\":\"expression\",\"expression\":\"(852076800000 == "
+                    + "timestamp_floor"));
   }
 
   @Test void testDruidTimeFloorAndTimeParseExpressions2() {
+    Assumptions.assumeTrue(Bug.CALCITE_4205_FIXED, "CALCITE-4205");
     final String sql = "SELECT \"timestamp\", count(*) "
         + "from \"foodmart\" WHERE "
         + "CAST(('1997' || '-01' || '-01') AS TIMESTAMP) = CAST(\"timestamp\" 
AS TIMESTAMP) "
@@ -3226,14 +3206,10 @@ public class DruidAdapter2IT {
             + " AND CAST(SUBSTRING(\"product_id\" from 4 for 1) AS INTEGER) = 
7"
             + " AND CAST(SUBSTRING(\"product_id\" from 4) AS INTEGER) = 7"
             + " Group by SUBSTRING(\"product_id\" from 1 for 4)";
-    final String plan = "PLAN=EnumerableInterpreter\n"
-        + "  BindableProject(C=[$1], EXPR$1=[$0])\n"
-        + "    DruidQuery(table=[[foodmart, foodmart]], "
-        + "intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], "
-        + "filter=[AND(LIKE(SUBSTRING($1, 1, 4), '12%'), =(CHAR_LENGTH($1), 
4), "
-        + "=(SUBSTRING($1, 3, 1), '2'), =(CAST(SUBSTRING($1, 2, 1)):INTEGER, 
2), "
-        + "=(CAST(SUBSTRING($1, 4, 1)):INTEGER, 7), =(CAST(SUBSTRING($1, 
4)):INTEGER, 7))], "
-        + "projects=[[SUBSTRING($1, 1, 4)]], groups=[{0}], aggs=[[COUNT()]])";
+    final String plan = "PLAN="
+        + "EnumerableCalc(expr#0..1=[{inputs}], C=[$t1], EXPR$1=[$t0])\n"
+        + "  EnumerableInterpreter\n"
+        + "    DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
filter=[AND(LIKE(SUBSTRING($1, 1, 4), '12%'), =(CHAR_LENGTH($1), 4), 
=(SUBSTRING($1, 3, 1), '2'), =(CAST(SUBSTRING($1, 2, 1)):INTEGER, 2), 
=(CAST(SUBSTRING($1, 4, 1)):INTEGER, 7), =(CAST(SUBSTRING($1, 4)):INTEGER, 
7))], projects=[[SUBSTRING($1, 1, 4)]], groups=[{0}], aggs=[[COUNT()]])";
     sql(sql, FOODMART)
         .returnsOrdered("C=60; EXPR$1=1227")
         .explainContains(plan)
@@ -3319,11 +3295,10 @@ public class DruidAdapter2IT {
     sql(sql, FOODMART)
         .returnsOrdered("EXPR$0=2")
         .explainContains("PLAN=EnumerableInterpreter\n"
-            + "  DruidQuery(table=[[foodmart, foodmart]], "
-            + 
"intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], "
-            + "filter=[AND(>(SIN($91), SIN(20)), >(COS($90), COS(20)), 
=(FLOOR(TAN($91)), 2), "
-            + "<(ABS(-(TAN($91), /(SIN($91), COS($91)))), 1.0E-6))], "
-            + "groups=[{}], aggs=[[COUNT()]])");
+            + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00"
+            + ".000Z/2992-01-10T00:00:00.000Z]], filter=[AND(>(SIN($91), 
9.129452507276277E-1), >"
+            + "(COS($90), 4.08082061813392E-1), =(FLOOR(TAN($91)), 2), 
<(ABS(-(TAN($91), /(SIN"
+            + "($91), COS($91)))), 1.0E-6))], groups=[{}], aggs=[[COUNT()]])");
   }
 
   @Test void testCastLiteralToTimestamp() {
@@ -3351,11 +3326,7 @@ public class DruidAdapter2IT {
     sql(sql, FOODMART)
         .returnsOrdered(result)
         .explainContains("PLAN=EnumerableInterpreter\n"
-            + "  DruidQuery(table=[[foodmart, foodmart]], "
-            + 
"intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], "
-            + "filter=[AND(IS NOT TRUE(=(CAST($1):INTEGER, 1020)), 
<>(CAST($1):INTEGER, 1020))], "
-            + "groups=[{}], "
-            + "aggs=[[COUNT()]])");
+            + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
filter=[<>(CAST($1):INTEGER, 1020)], groups=[{}], aggs=[[COUNT()]])");
     final String sql2 = "SELECT COUNT(*) FROM " + FOODMART_TABLE + "WHERE "
         + "\"product_id\" <> 1020";
     sql(sql2, FOODMART).returnsOrdered(result);
@@ -3566,9 +3537,7 @@ public class DruidAdapter2IT {
         + "\"timeZone\":\"UTC\",\"locale\":\"en-US\"}}";
 
     final String extract_expression = 
"\"expression\":\"(((timestamp_extract(\\\"__time\\\",";
-    sql(sql, FOODMART)
-        .returnsOrdered(
-            "QR_TIMESTAMP_OK=1; SUM_STORE_SALES=139628.34999999971; 
YR_TIMESTAMP_OK=1997")
+    CalciteAssert.AssertQuery q = sql(sql, FOODMART)
         .queryContains(
             new DruidChecker("\"queryType\":\"groupBy\"", extract_year, 
extract_expression))
         .explainContains("PLAN=EnumerableInterpreter\n"
@@ -3576,6 +3545,8 @@ public class DruidAdapter2IT {
             + "    DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
             + "2992-01-10T00:00:00.000Z]], 
projects=[[+(/(-(EXTRACT(FLAG(MONTH), $0), 1), 3), 1), "
             + "EXTRACT(FLAG(YEAR), $0), $90]], groups=[{0, 1}], 
aggs=[[SUM($2)]], fetch=[1])");
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("QR_TIMESTAMP_OK=1; SUM_STORE_SALES=139628.34999999971; 
YR_TIMESTAMP_OK=1997");
   }
 
   @Test void testTableauQueryExtractMonthDayYear() {
@@ -3604,9 +3575,7 @@ public class DruidAdapter2IT {
         + " AS hr_t_timestamp_ok2 FROM  \"foodmart\" GROUP BY "
         + " CAST(SUBSTRING(CAST(\"foodmart\".\"timestamp\" AS VARCHAR) from 12 
for 2 ) AS INT),"
         + "  MINUTE(\"foodmart\".\"timestamp\"), EXTRACT(HOUR FROM 
\"timestamp\")) LIMIT 1";
-    sql(sql, FOODMART)
-        .returnsOrdered("HR_T_TIMESTAMP_OK=0; MI_T_TIMESTAMP_OK=0; "
-            + "SUM_T_OTHER_OK=565238.1299999986; HR_T_TIMESTAMP_OK2=0")
+    CalciteAssert.AssertQuery q = sql(sql, FOODMART)
         .explainContains("BindableProject(HR_T_TIMESTAMP_OK=[$0], 
MI_T_TIMESTAMP_OK=[$1], "
             + "SUM_T_OTHER_OK=[$3], HR_T_TIMESTAMP_OK2=[$2])\n"
             + "    DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
@@ -3615,6 +3584,9 @@ public class DruidAdapter2IT {
             + "NOT NULL, 12, 2)):INTEGER NOT NULL, EXTRACT(FLAG(MINUTE), $0), "
             + "EXTRACT(FLAG(HOUR), $0), $90]], groups=[{0, 1, 2}], 
aggs=[[SUM($3)]], fetch=[1])")
         .queryContains(new DruidChecker("\"queryType\":\"groupBy\""));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("HR_T_TIMESTAMP_OK=0; MI_T_TIMESTAMP_OK=0; "
+        + "SUM_T_OTHER_OK=565238.1299999986; HR_T_TIMESTAMP_OK2=0");
   }
 
   @Test void testTableauQueryMinutesSecondsExtract() {
@@ -3622,14 +3594,14 @@ public class DruidAdapter2IT {
         + "MINUTE(\"timestamp\") AS mi_t_timestamp_ok,  SUM(\"store_sales\") 
AS sum_store_sales "
         + " FROM \"foodmart\" GROUP BY SECOND(\"timestamp\"), 
MINUTE(\"timestamp\"))"
         + " LIMIT_ZERO LIMIT 1";
-    sql(sql, FOODMART)
-        .returnsOrdered(
-            "SC_T_TIMESTAMP_OK=0; MI_T_TIMESTAMP_OK=0; 
SUM_STORE_SALES=565238.1299999986")
+    CalciteAssert.AssertQuery q = sql(sql, FOODMART)
         .explainContains("PLAN=EnumerableInterpreter\n"
             + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
             + "2992-01-10T00:00:00.000Z]], projects=[[EXTRACT(FLAG(SECOND), 
$0), "
             + "EXTRACT(FLAG(MINUTE), $0), $90]], groups=[{0, 1}], 
aggs=[[SUM($2)]], fetch=[1])")
         .queryContains(new DruidChecker("\"queryType\":\"groupBy\""));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("SC_T_TIMESTAMP_OK=0; MI_T_TIMESTAMP_OK=0; 
SUM_STORE_SALES=565238.1299999986");
   }
 
   @Test void testCastConcatOverPostAggregates() {
@@ -3648,8 +3620,7 @@ public class DruidAdapter2IT {
   @Test void testHavingSpecs() {
     final String sql = "SELECT \"product_id\" AS P, SUM(\"store_sales\") AS S 
FROM \"foodmart\" "
         + " GROUP BY  \"product_id\" HAVING  SUM(\"store_sales\") > 220  ORDER 
BY P LIMIT 2";
-    sql(sql, FOODMART)
-        .returnsOrdered("P=1; S=236.55", "P=10; S=230.04")
+    CalciteAssert.AssertQuery q = sql(sql, FOODMART)
         .explainContains("PLAN=EnumerableInterpreter\n"
             + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
             + "2992-01-10T00:00:00.000Z]], projects=[[$1, $90]], groups=[{0}], 
aggs=[[SUM($1)]], "
@@ -3657,20 +3628,23 @@ public class DruidAdapter2IT {
         .queryContains(
             new 
DruidChecker("'having':{'type':'filter','filter':{'type':'bound',"
                 + 
"'dimension':'S','lower':'220','lowerStrict':true,'ordering':'numeric'}}"));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("P=1; S=236.55", "P=10; S=230.04");
   }
 
   @Test void testTransposableHavingFilter() {
     final String sql = "SELECT \"product_id\" AS P, SUM(\"store_sales\") AS S 
FROM \"foodmart\" "
         + " GROUP BY  \"product_id\" HAVING  SUM(\"store_sales\") > 220 AND 
\"product_id\" > '10'"
         + "  ORDER BY P LIMIT 2";
-    sql(sql, FOODMART)
-        .returnsOrdered("P=100; S=343.19999999999993", "P=1000; S=532.62")
+    CalciteAssert.AssertQuery q = sql(sql, FOODMART)
         .explainContains("PLAN=EnumerableInterpreter\n"
             + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
             + "2992-01-10T00:00:00.000Z]], filter=[>($1, '10')], 
projects=[[$1, $90]], groups=[{0}],"
             + " aggs=[[SUM($1)]], filter=[>($1, 220)], sort0=[0], dir0=[ASC], 
fetch=[2])\n")
         .queryContains(
             new 
DruidChecker("{'queryType':'groupBy','dataSource':'foodmart','granularity':'all'"));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("P=100; S=343.19999999999993", "P=1000; S=532.62");
   }
 
   @Test void testProjectSameColumnMultipleTimes() {
@@ -3718,21 +3692,21 @@ public class DruidAdapter2IT {
         "SELECT \"product_id\" as prod_id1, \"product_id\" as prod_id2, "
             + "SUM(\"store_sales\") as S1, SUM(\"store_sales\") as S2 FROM " + 
FOODMART_TABLE
             + " GROUP BY \"product_id\" ORDER BY prod_id2 LIMIT 1";
-    sql(sql, FOODMART)
+    CalciteAssert.AssertQuery q = sql(sql, FOODMART)
         .explainContains("BindableProject(PROD_ID1=[$0], PROD_ID2=[$0], 
S1=[$1], S2=[$1])\n"
             + "    DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
             + "2992-01-10T00:00:00.000Z]], projects=[[$1, $90]], groups=[{0}], 
aggs=[[SUM($1)]], "
             + "sort0=[0], dir0=[ASC], fetch=[1])")
         .queryContains(
-            new DruidChecker("\"queryType\":\"groupBy\""))
-        .returnsOrdered("PROD_ID1=1; PROD_ID2=1; S1=236.55; S2=236.55");
+            new DruidChecker("\"queryType\":\"groupBy\""));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("PROD_ID1=1; PROD_ID2=1; S1=236.55; S2=236.55");
   }
 
   @Test void testGroupBy1() {
     final String sql = "SELECT SUM(\"store_sales\") FROM \"foodmart\" "
         + "GROUP BY 1 HAVING (COUNT(1) > 0)";
-    sql(sql, FOODMART)
-        .returnsOrdered("EXPR$0=565238.1299999986")
+    CalciteAssert.AssertQuery q = sql(sql, FOODMART)
         .queryContains(
             new 
DruidChecker("{'queryType':'groupBy','dataSource':'foodmart','granularity':'all',"
                 + 
"'dimensions':[{'type':'default','dimension':'vc','outputName':'vc','outputType':'LONG'}],"
@@ -3742,6 +3716,8 @@ public class DruidAdapter2IT {
                 + 
"['1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z'],'having':"
                 + 
"{'type':'filter','filter':{'type':'bound','dimension':'$f2','lower':'0',"
                 + "'lowerStrict':true,'ordering':'numeric'}}}"));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("EXPR$0=565238.1299999986");
   }
 
   @Test void testFloorQuarter() {
@@ -3781,10 +3757,7 @@ public class DruidAdapter2IT {
             + " WHERE \"product_id\" = 1"
             + " GROUP BY EXTRACT(quarter from \"timestamp\"), \"product_id\"";
 
-    sql(sql, FOODMART).returnsOrdered("EXPR$0=1; product_id=1; 
EXPR$2=37.050000000000004\n"
-        + "EXPR$0=2; product_id=1; EXPR$2=62.7\n"
-        + "EXPR$0=3; product_id=1; EXPR$2=88.35\n"
-        + "EXPR$0=4; product_id=1; EXPR$2=48.45")
+    CalciteAssert.AssertQuery q = sql(sql, FOODMART)
         .queryContains(
             new DruidChecker(
                 
"{\"queryType\":\"groupBy\",\"dataSource\":\"foodmart\",\"granularity\":\"all\",\"dimensions\":"
@@ -3792,6 +3765,11 @@ public class DruidAdapter2IT {
                     + 
"{\"type\":\"default\",\"dimension\":\"product_id\",\"outputName\":\"product_id\",\"outputType\":\"STRING\"}],"
                     + 
"\"virtualColumns\":[{\"type\":\"expression\",\"name\":\"vc\",\"expression\":\"timestamp_extract(\\\"__time\\\",",
                 "QUARTER"));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("EXPR$0=1; product_id=1; EXPR$2=37.050000000000004\n"
+        + "EXPR$0=2; product_id=1; EXPR$2=62.7\n"
+        + "EXPR$0=3; product_id=1; EXPR$2=88.35\n"
+        + "EXPR$0=4; product_id=1; EXPR$2=48.45");
   }
 
   @Test void testExtractQuarter() {
@@ -3799,16 +3777,18 @@ public class DruidAdapter2IT {
         + FOODMART_TABLE
         + " GROUP BY EXTRACT(quarter from \"timestamp\")";
 
-    sql(sql, FOODMART).returnsOrdered("EXPR$0=1; EXPR$1=139628.34999999971\n"
-        + "EXPR$0=2; EXPR$1=132666.26999999944\n"
-        + "EXPR$0=3; EXPR$1=140271.88999999964\n"
-        + "EXPR$0=4; EXPR$1=152671.61999999985")
+    CalciteAssert.AssertQuery q = sql(sql, FOODMART)
         .queryContains(
             new DruidChecker(
                 
"{\"queryType\":\"groupBy\",\"dataSource\":\"foodmart\",\"granularity\":\"all\","
                     + 
"\"dimensions\":[{\"type\":\"default\",\"dimension\":\"vc\",\"outputName\":\"vc\",\"outputType\":\"LONG\"}],"
                     + 
"\"virtualColumns\":[{\"type\":\"expression\",\"name\":\"vc\",\"expression\":\"timestamp_extract(\\\"__time\\\",",
                 "QUARTER"));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("EXPR$0=1; EXPR$1=139628.34999999971\n"
+        + "EXPR$0=2; EXPR$1=132666.26999999944\n"
+        + "EXPR$0=3; EXPR$1=140271.88999999964\n"
+        + "EXPR$0=4; EXPR$1=152671.61999999985");
   }
 
   @Test void testCastTimestamp1() {
diff --git a/druid/src/test/java/org/apache/calcite/test/DruidAdapterIT.java 
b/druid/src/test/java/org/apache/calcite/test/DruidAdapterIT.java
index 72ebf98..be2b8fb 100644
--- a/druid/src/test/java/org/apache/calcite/test/DruidAdapterIT.java
+++ b/druid/src/test/java/org/apache/calcite/test/DruidAdapterIT.java
@@ -24,12 +24,14 @@ import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.schema.impl.AbstractSchema;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.calcite.util.Bug;
 import org.apache.calcite.util.TestUtil;
 
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Multimap;
 
+import org.junit.jupiter.api.Assumptions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
@@ -48,15 +50,9 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue;
 /**
  * Tests for the {@code org.apache.calcite.adapter.druid} package.
  *
- * <p>Before calling this test, you need to populate Druid, as follows:
- *
- * <blockquote><code>
- * git clone https://github.com/vlsi/calcite-test-dataset<br>
- * cd calcite-test-dataset<br>
- * mvn install
- * </code></blockquote>
- *
- * <p>This will create a virtual machine with Druid and test data set.
+ * <p>Druid must be up and running with foodmart and wikipedia datasets 
loaded. Follow the
+ * instructions on <a 
href="https://github.com/zabetak/calcite-druid-dataset";>calcite-druid-dataset
+ * </a> to setup Druid before launching these tests.</p>
  *
  * <p>Features not yet implemented:
  * <ul>
@@ -146,7 +142,7 @@ public class DruidAdapterIT {
         + "EnumerableInterpreter\n"
         + "  DruidQuery(table=[[wiki, wiki]], "
         + "intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], "
-        + "filter=[=($13, 'Jeremy Corbyn')], groups=[{5}], aggs=[[]])\n";
+        + "filter=[=($13, 'Jeremy Corbyn')], projects=[[$5]], groups=[{0}], 
aggs=[[]])\n";
     checkSelectDistinctWiki(WIKI, "wiki")
         .explainContains(explain);
   }
@@ -156,7 +152,7 @@ public class DruidAdapterIT {
         + "EnumerableInterpreter\n"
         + "  DruidQuery(table=[[wiki, wiki]], "
         + "intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], "
-        + "filter=[=($16, 'Jeremy Corbyn')], groups=[{6}], aggs=[[]])\n";
+        + "filter=[=($16, 'Jeremy Corbyn')], projects=[[$6]], groups=[{0}], 
aggs=[[]])\n";
     checkSelectDistinctWiki(WIKI_AUTO, "wiki")
         .explainContains(explain);
   }
@@ -173,7 +169,7 @@ public class DruidAdapterIT {
         + "EnumerableInterpreter\n"
         + "  DruidQuery(table=[[wiki, wikipedia]], "
         + "intervals=[[1900-01-01T00:00:00.000Z/3000-01-01T00:00:00.000Z]], "
-        + "filter=[=($16, 'Jeremy Corbyn')], groups=[{6}], aggs=[[]])\n";
+        + "filter=[=($16, 'Jeremy Corbyn')], projects=[[$6]], groups=[{0}], 
aggs=[[]])\n";
     final String druidQuery = "{'queryType':'groupBy',"
         + "'dataSource':'wikipedia','granularity':'all',"
         + 
"'dimensions':[{'type':'default','dimension':'countryName','outputName':'countryName',"
@@ -198,8 +194,8 @@ public class DruidAdapterIT {
         + "from \"wikipedia\"\n"
         + "group by floor(\"__time\" to DAY)";
     final String explain = "PLAN="
-        + "EnumerableInterpreter\n"
-        + "  BindableProject(EXPR$0=[$1])\n"
+        + "EnumerableCalc(expr#0..1=[{inputs}], EXPR$0=[$t1])\n"
+        + "  EnumerableInterpreter\n"
         + "    DruidQuery(table=[[wiki, wikipedia]], 
intervals=[[1900-01-01T00:00:00.000Z/3000-01-01T00:00:00.000Z]], 
projects=[[FLOOR($0, FLAG(DAY)), $1]], groups=[{0}], aggs=[[SUM($1)]])\n";
     final String druidQuery = "{'queryType':'timeseries',"
         + 
"'dataSource':'wikipedia','descending':false,'granularity':{'type':'period','period':'P1D','timeZone':'UTC'},"
@@ -384,7 +380,7 @@ public class DruidAdapterIT {
   @Test void testSelectDistinct() {
     final String explain = "PLAN="
         + "EnumerableInterpreter\n"
-        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], groups=[{30}], 
aggs=[[]])";
+        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
projects=[[$30]], groups=[{0}], aggs=[[]])";
     final String sql = "select distinct \"state_province\" from \"foodmart\"";
     final String druidQuery = 
"{'queryType':'groupBy','dataSource':'foodmart','granularity':'all',"
         + 
"'dimensions':[{'type':'default','dimension':'state_province','outputName':'state_province'"
@@ -880,10 +876,11 @@ public class DruidAdapterIT {
         + "union all\n"
         + "select distinct \"marital_status\" from \"foodmart\"";
     final String explain = "PLAN="
-        + "EnumerableInterpreter\n"
-        + "  BindableUnion(all=[true])\n"
-        + "    DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], groups=[{39}], 
aggs=[[]])\n"
-        + "    DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], groups=[{37}], 
aggs=[[]])";
+        + "EnumerableUnion(all=[true])\n"
+        + "  EnumerableInterpreter\n"
+        + "    DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
projects=[[$39]], groups=[{0}], aggs=[[]])\n"
+        + "  EnumerableInterpreter\n"
+        + "    DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
projects=[[$37]], groups=[{0}], aggs=[[]])\n";
     sql(sql)
         .explainContains(explain)
         .returnsUnordered(
@@ -903,8 +900,8 @@ public class DruidAdapterIT {
         + "EnumerableInterpreter\n"
         + "  BindableFilter(condition=[=($0, 'M')])\n"
         + "    BindableUnion(all=[true])\n"
-        + "      DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], groups=[{39}], 
aggs=[[]])\n"
-        + "      DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], groups=[{37}], 
aggs=[[]])";
+        + "      DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
projects=[[$39]], groups=[{0}], aggs=[[]])\n"
+        + "      DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
projects=[[$37]], groups=[{0}], aggs=[[]])";
     sql(sql)
         .explainContains(explain)
         .returnsUnordered("gender=M",
@@ -919,7 +916,7 @@ public class DruidAdapterIT {
         + "'context':{'skipEmptyBuckets':false}}";
     final String explain = "PLAN=EnumerableInterpreter\n"
         + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
-        + "2992-01-10T00:00:00.000Z]], projects=[[0]], groups=[{}], 
aggs=[[COUNT()]])";
+        + "2992-01-10T00:00:00.000Z]], groups=[{}], aggs=[[COUNT()]])";
     final String sql = "select count(*) from \"foodmart\"";
     sql(sql)
         .returns("EXPR$0=86829\n")
@@ -1248,14 +1245,14 @@ public class DruidAdapterIT {
     final String explain = "PLAN=EnumerableInterpreter\n"
         + "  BindableSort(sort0=[$1], dir0=[DESC], fetch=[2])\n"
         + "    BindableProject(state_province=[$0], CDC=[FLOOR($1)])\n"
-        + "      BindableAggregate(group=[{1}], agg#0=[COUNT($0)])\n"
+        + "      BindableAggregate(group=[{0}], agg#0=[COUNT($1)])\n"
         + "        DruidQuery(table=[[foodmart, foodmart]], "
-        + "intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
groups=[{29, 30}], "
-        + "aggs=[[]])";
+        + "intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], "
+        + "projects=[[$30, $29]], groups=[{0, 1}], aggs=[[]])";
     final String druidQuery = "{'queryType':'groupBy','dataSource':'foodmart',"
-        + 
"'granularity':'all','dimensions':[{'type':'default','dimension':'city','outputName':'city'"
-        + ",'outputType':'STRING'},"
-        + 
"{'type':'default','dimension':'state_province','outputName':'state_province','outputType':'STRING'}],"
+        + "'granularity':'all','dimensions':["
+        + 
"{'type':'default','dimension':'state_province','outputName':'state_province','outputType':'STRING'},"
+        + 
"{'type':'default','dimension':'city','outputName':'city','outputType':'STRING'}],"
         + "'limitSpec':{'type':'default'},'aggregations':[],"
         + "'intervals':['1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z']}";
     sql(sql)
@@ -1272,8 +1269,8 @@ public class DruidAdapterIT {
     final String sql = "select \"product_name\", 0 as zero\n"
         + "from \"foodmart\"\n"
         + "order by \"product_name\"";
-    final String explain = "PLAN=EnumerableInterpreter\n"
-        + "  BindableSort(sort0=[$0], dir0=[ASC])\n"
+    final String explain = "PLAN=EnumerableSort(sort0=[$0], dir0=[ASC])\n"
+        + "  EnumerableInterpreter\n"
         + "    DruidQuery(table=[[foodmart, foodmart]], "
         + "intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
projects=[[$3, 0]])";
     sql(sql)
@@ -1381,9 +1378,10 @@ public class DruidAdapterIT {
         + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1997-04-01T00:00:00.000Z/"
         + "1997-05-01T00:00:00.000Z, 
1997-06-01T00:00:00.000Z/1997-07-01T00:00:00.000Z]],"
         + " projects=[[0]], groups=[{}], aggs=[[COUNT()]])";
-    sql(sql)
-        .returnsUnordered("C=13500")
-        .explainContains(explain);
+    CalciteAssert.AssertQuery q = sql(sql)
+        .returnsUnordered("C=13500");
+    Assumptions.assumeTrue(Bug.CALCITE_4213_FIXED, "CALCITE-4213");
+    q.explainContains(explain);
   }
 
   @Test void testFilterSwapped() {
@@ -1624,8 +1622,7 @@ public class DruidAdapterIT {
             + "  DruidQuery(table=[[foodmart, foodmart]], "
             + 
"intervals=[[1997-01-01T00:00:00.000Z/1998-01-01T00:00:00.000Z]], "
             + "filter=[AND(>=(CAST($11):INTEGER, 8), <=(CAST($11):INTEGER, 
10), "
-            + "<(CAST($10):INTEGER, 15))], groups=[{}], "
-            + "aggs=[[SUM($90)]])\n")
+            + "<(CAST($10):INTEGER, 15))], projects=[[$90]], groups=[{}], 
aggs=[[SUM($0)]])\n")
         .returnsUnordered("EXPR$0=75364.1")
         .queryContains(new DruidChecker(druidQuery));
   }
@@ -1920,8 +1917,9 @@ public class DruidAdapterIT {
   @Test void testTimeExtractThatCannotBePushed() {
     final String sql = "SELECT extract(CENTURY from \"timestamp\") from 
\"foodmart\" where "
         + "\"product_id\" = 1558 group by extract(CENTURY from \"timestamp\")";
-    final String plan = "PLAN=EnumerableInterpreter\n"
-        + "  BindableAggregate(group=[{0}])\n"
+    final String plan = "PLAN="
+        + "EnumerableAggregate(group=[{0}])\n"
+        + "  EnumerableInterpreter\n"
         + "    BindableProject(EXPR$0=[EXTRACT(FLAG(CENTURY), $0)])\n"
         + "      DruidQuery(table=[[foodmart, foodmart]], "
         + "intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], "
@@ -2017,12 +2015,13 @@ public class DruidAdapterIT {
         + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
         + "2992-01-10T00:00:00.000Z]], projects=[[$63, $90, $91]], 
groups=[{0}], "
         + "aggs=[[SUM($1), SUM($2)]], post_projects=[[+($1, $2), $0]], 
sort0=[0], dir0=[DESC])";
-    sql(sqlQuery, FOODMART)
-        .returnsOrdered("A=369117.52790000016; store_state=WA",
-            "A=222698.26509999996; store_state=CA",
-            "A=199049.57059999998; store_state=OR")
+    CalciteAssert.AssertQuery q = sql(sqlQuery, FOODMART)
         .explainContains(plan)
         .queryContains(new DruidChecker(postAggString));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("A=369117.52790000016; store_state=WA",
+        "A=222698.26509999996; store_state=CA",
+        "A=199049.57059999998; store_state=OR");
   }
 
   @Test void testDivideArithmeticOperation() {
@@ -2033,12 +2032,13 @@ public class DruidAdapterIT {
         + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
         + "2992-01-10T00:00:00.000Z]], projects=[[$63, $90, $91]], 
groups=[{0}], "
         + "aggs=[[SUM($1), SUM($2)]], post_projects=[[$0, /($1, $2)]], 
sort0=[1], dir0=[DESC])";
-    sql(sqlQuery, FOODMART)
-        .returnsOrdered("store_state=OR; A=2.506091302943239",
-            "store_state=CA; A=2.505379741272971",
-            "store_state=WA; A=2.5045806163801996")
+    CalciteAssert.AssertQuery q = sql(sqlQuery, FOODMART)
         .explainContains(plan)
         .queryContains(new DruidChecker(postAggString));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("store_state=OR; A=2.506091302943239",
+        "store_state=CA; A=2.505379741272971",
+        "store_state=WA; A=2.5045806163801996");
   }
 
   @Test void testMultiplyArithmeticOperation() {
@@ -2049,12 +2049,13 @@ public class DruidAdapterIT {
         + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
         + "2992-01-10T00:00:00.000Z]], projects=[[$63, $90, $91]], 
groups=[{0}], aggs=[[SUM($1),"
         + " SUM($2)]], post_projects=[[$0, *($1, $2)]], sort0=[1], 
dir0=[DESC])";
-    sql(sqlQuery, FOODMART)
-        .returnsOrdered("store_state=WA; A=2.7783838325212463E10",
-            "store_state=CA; A=1.0112000537448784E10",
-            "store_state=OR; A=8.077425041941243E9")
+    CalciteAssert.AssertQuery q = sql(sqlQuery, FOODMART)
         .explainContains(plan)
         .queryContains(new DruidChecker(postAggString));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("store_state=WA; A=2.7783838325212463E10",
+        "store_state=CA; A=1.0112000537448784E10",
+        "store_state=OR; A=8.077425041941243E9");
   }
 
   @Test void testMinusArithmeticOperation() {
@@ -2066,12 +2067,13 @@ public class DruidAdapterIT {
         + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
         + "2992-01-10T00:00:00.000Z]], projects=[[$63, $90, $91]], 
groups=[{0}], aggs=[[SUM($1), "
         + "SUM($2)]], post_projects=[[$0, -($1, $2)]], sort0=[1], 
dir0=[DESC])";
-    sql(sqlQuery, FOODMART)
-        .returnsOrdered("store_state=WA; A=158468.91210000002",
-            "store_state=CA; A=95637.41489999992",
-            "store_state=OR; A=85504.56939999988")
+    CalciteAssert.AssertQuery q = sql(sqlQuery, FOODMART)
         .explainContains(plan)
         .queryContains(new DruidChecker(postAggString));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("store_state=WA; A=158468.91210000002",
+        "store_state=CA; A=95637.41489999992",
+        "store_state=OR; A=85504.56939999988");
   }
 
   @Test void testConstantPostAggregator() {
@@ -2082,12 +2084,13 @@ public class DruidAdapterIT {
         + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
         + "2992-01-10T00:00:00.000Z]], projects=[[$63, $90]], groups=[{0}], 
aggs=[[SUM($1)]], "
         + "post_projects=[[$0, +($1, 100)]], sort0=[1], dir0=[DESC])";
-    sql(sqlQuery, FOODMART)
-        .returnsOrdered("store_state=WA; A=263893.2200000001",
-            "store_state=CA; A=159267.83999999994",
-            "store_state=OR; A=142377.06999999992")
+    CalciteAssert.AssertQuery q = sql(sqlQuery, FOODMART)
         .explainContains(plan)
         .queryContains(new DruidChecker(postAggString));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("store_state=WA; A=263893.2200000001",
+        "store_state=CA; A=159267.83999999994",
+        "store_state=OR; A=142377.06999999992");
   }
 
   @Test void testRecursiveArithmeticOperation() {
@@ -2099,8 +2102,8 @@ public class DruidAdapterIT {
         + "'(-1 * (((\\'$f1\\' - \\'$f2\\') / (\\'$f3\\' * 3)) + \\'B\\'))'}]";
     final String plan = "PLAN=EnumerableInterpreter\n"
         + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
-        + "2992-01-10T00:00:00.000Z]], projects=[[$63, $89, $90, $91]], 
groups=[{0}], "
-        + "aggs=[[SUM($2), SUM($3), COUNT(), SUM($1)]], post_projects=[[$0, 
*(-1, +(/(-($1, $2), "
+        + "2992-01-10T00:00:00.000Z]], projects=[[$63, $90, $91, $89]], 
groups=[{0}], "
+        + "aggs=[[SUM($1), SUM($2), COUNT(), SUM($3)]], post_projects=[[$0, 
*(-1, +(/(-($1, $2), "
         + "*($3, 3)), $4))]], sort0=[1], dir0=[DESC])";
     sql(sqlQuery, FOODMART)
         .returnsOrdered("store_state=OR; C=-67660.31890435601",
@@ -2118,8 +2121,8 @@ public class DruidAdapterIT {
         + "'expression':'(\\'$f1\\' / \\'$f2\\')'}]";
     final String plan = "PLAN=EnumerableInterpreter\n"
         + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
-        + "2992-01-10T00:00:00.000Z]], projects=[[$2, $63, $91]], 
groups=[{1}], aggs=[[SUM($2), "
-        + "COUNT(DISTINCT $0)]], post_projects=[[$0, /($1, $2)]], sort0=[1], 
dir0=[DESC])";
+        + "2992-01-10T00:00:00.000Z]], projects=[[$63, $91, $2]], 
groups=[{0}], aggs=[[SUM($1), "
+        + "COUNT(DISTINCT $2)]], post_projects=[[$0, /($1, $2)]], sort0=[1], 
dir0=[DESC])";
     foodmartApprox(sqlQuery)
         .runs()
         .explainContains(plan)
@@ -2172,12 +2175,13 @@ public class DruidAdapterIT {
         + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
         + "2992-01-10T00:00:00.000Z]], projects=[[$63, $91]], groups=[{0}], "
         + "aggs=[[SUM($1), COUNT()]], post_projects=[[$0, /($1, $2)]], 
sort0=[1], dir0=[DESC])";
-    sql(sqlQuery, FOODMART)
-        .returnsOrdered("store_state=OR; A=2.6271402406293403",
-            "store_state=CA; A=2.599338206292706",
-            "store_state=WA; A=2.5828708592868717")
+    CalciteAssert.AssertQuery q = sql(sqlQuery, FOODMART)
         .explainContains(plan)
         .queryContains(new DruidChecker(postAggString));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("store_state=OR; A=2.6271402406293403",
+        "store_state=CA; A=2.599338206292706",
+        "store_state=WA; A=2.5828708592868717");
   }
 
   @Test void testPartiallyPostAggregation() {
@@ -2189,15 +2193,16 @@ public class DruidAdapterIT {
         + "'expression':'case_searched((\\'$f3\\' == 0),1.0,CAST(\\'$f3\\'";
     final String plan =
         "DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
-            + "2992-01-10T00:00:00.000Z]], projects=[[$63, $89, $90, $91]], 
groups=[{0}], "
-            + "aggs=[[SUM($2), SUM($3), SUM($1)]], post_projects=[[$0, /($1, 
$2), "
+            + "2992-01-10T00:00:00.000Z]], projects=[[$63, $90, $91, $89]], 
groups=[{0}], "
+            + "aggs=[[SUM($1), SUM($2), SUM($3)]], post_projects=[[$0, /($1, 
$2), "
             + "CASE(=($3, 0), 1.0:DECIMAL(19, 0), CAST($3):DECIMAL(19, 0))]], 
sort0=[1], dir0=[DESC])";
-    sql(sqlQuery, FOODMART)
-        .returnsOrdered("store_state=OR; A=2.506091302943239; B=67659.0",
-            "store_state=CA; A=2.505379741272971; B=74748.0",
-            "store_state=WA; A=2.5045806163801996; B=124366.0")
+    CalciteAssert.AssertQuery q = sql(sqlQuery, FOODMART)
         .explainContains(plan)
         .queryContains(new DruidChecker(postAggString));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("store_state=OR; A=2.506091302943239; B=67659.0",
+        "store_state=CA; A=2.505379741272971; B=74748.0",
+        "store_state=WA; A=2.5045806163801996; B=124366.0");
   }
 
   @Test void testDuplicateReferenceOnPostAggregation() {
@@ -2211,12 +2216,13 @@ public class DruidAdapterIT {
         + "intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], "
         + "projects=[[$63, $90, $91]], groups=[{0}], aggs=[[SUM($1), 
SUM($2)]], "
         + "post_projects=[[$0, +($1, 100), -(+($1, 100), $2)]], sort0=[1], 
dir0=[DESC])";
-    sql(sqlQuery, FOODMART)
-        .returnsOrdered("store_state=WA; A=263893.2200000001; 
C=158568.91210000002",
-            "store_state=CA; A=159267.83999999994; C=95737.41489999992",
-            "store_state=OR; A=142377.06999999992; C=85604.56939999988")
+    CalciteAssert.AssertQuery q = sql(sqlQuery, FOODMART)
         .explainContains(plan)
         .queryContains(new DruidChecker(postAggString));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("store_state=WA; A=263893.2200000001; 
C=158568.91210000002",
+        "store_state=CA; A=159267.83999999994; C=95737.41489999992",
+        "store_state=OR; A=142377.06999999992; C=85604.56939999988");
   }
 
   @Test void testDivideByZeroDoubleTypeInfinity() {
@@ -2296,16 +2302,18 @@ public class DruidAdapterIT {
         + "\"expression\":\"(\\\"$f2\\\" - \\\"$f3\\\")\"}";
     final String plan = "PLAN=EnumerableInterpreter\n"
         + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
-        + "2992-01-10T00:00:00.000Z]], groups=[{2, 63}], aggs=[[SUM($90), 
SUM($91)]], "
-        + "post_projects=[[$1, $0, -($2, $3)]], sort0=[2], dir0=[ASC], 
fetch=[5])";
-    sql(sqlQuery, FOODMART)
-        .returnsOrdered("store_state=CA; brand_name=King; A=21.4632",
-            "store_state=OR; brand_name=Symphony; A=32.176",
-            "store_state=CA; brand_name=Toretti; A=32.24650000000001",
-            "store_state=WA; brand_name=King; A=34.6104",
-            "store_state=OR; brand_name=Toretti; A=36.3")
+        + "2992-01-10T00:00:00.000Z]], projects=[[$63, $2, $90, $91]], 
groups=[{0, 1}], "
+        + "aggs=[[SUM($2), SUM($3)]], post_projects=[[$0, $1, -($2, $3)]], 
sort0=[2], dir0=[ASC], "
+        + "fetch=[5])";
+    CalciteAssert.AssertQuery q = sql(sqlQuery, FOODMART)
         .explainContains(plan)
         .queryContains(new DruidChecker(postAggString));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("store_state=CA; brand_name=King; A=21.4632",
+        "store_state=OR; brand_name=Symphony; A=32.176",
+        "store_state=CA; brand_name=Toretti; A=32.24650000000001",
+        "store_state=WA; brand_name=King; A=34.6104",
+        "store_state=OR; brand_name=Toretti; A=36.3");
   }
 
   @Test void testInterleaveBetweenAggregateAndGroupOrderByOnDimension() {
@@ -2317,16 +2325,18 @@ public class DruidAdapterIT {
         + "'expression':'(\\'$f2\\' + \\'$f3\\')'}]";
     final String plan = "PLAN=EnumerableInterpreter\n"
         + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
-        + "2992-01-10T00:00:00.000Z]], groups=[{2, 63}], aggs=[[SUM($90), 
SUM($91)]], post_projects"
-        + "=[[$1, $0, +($2, $3)]], sort0=[1], sort1=[0], dir0=[ASC], 
dir1=[ASC], fetch=[5])";
-    sql(sqlQuery, FOODMART)
-        .returnsOrdered("store_state=CA; brand_name=ADJ; A=222.1524",
-            "store_state=OR; brand_name=ADJ; A=186.60359999999997",
-            "store_state=WA; brand_name=ADJ; A=216.9912",
-            "store_state=CA; brand_name=Akron; A=250.349",
-            "store_state=OR; brand_name=Akron; A=278.69720000000007")
-            .explainContains(plan)
-            .queryContains(new DruidChecker(postAggString));
+        + "2992-01-10T00:00:00.000Z]], projects=[[$63, $2, $90, $91]], 
groups=[{0, 1}], "
+        + "aggs=[[SUM($2), SUM($3)]], post_projects=[[$0, $1, +($2, $3)]], "
+        + "sort0=[1], sort1=[0], dir0=[ASC], dir1=[ASC], fetch=[5])";
+    CalciteAssert.AssertQuery q = sql(sqlQuery, FOODMART)
+        .explainContains(plan)
+        .queryContains(new DruidChecker(postAggString));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("store_state=CA; brand_name=ADJ; A=222.1524",
+        "store_state=OR; brand_name=ADJ; A=186.60359999999997",
+        "store_state=WA; brand_name=ADJ; A=216.9912",
+        "store_state=CA; brand_name=Akron; A=250.349",
+        "store_state=OR; brand_name=Akron; A=278.69720000000007");
   }
 
   @Test void testOrderByOnMetricsInSelectDruidQuery() {
@@ -2667,20 +2677,21 @@ public class DruidAdapterIT {
   @Test void testFilterClauseWithMetricRefAndAggregates() {
     String sql = "select sum(\"store_sales\"), \"product_id\" "
         + "from \"foodmart\" where \"product_id\" > 1553 and \"store_cost\" > 
5 group by \"product_id\"";
-    String expectedSubExplain =
-        "PLAN=EnumerableInterpreter\n"
-            + "  BindableProject(EXPR$0=[$1], product_id=[$0])\n"
-            + "    DruidQuery(table=[[foodmart, foodmart]], "
-            + 
"intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], filter=[AND(>"
-            + "(CAST($1):INTEGER, 1553), >($91, 5))], groups=[{1}], 
aggs=[[SUM($90)]])";
+    String expectedSubExplain = "PLAN="
+        + "EnumerableCalc(expr#0..1=[{inputs}], EXPR$0=[$t1], 
product_id=[$t0])\n"
+        + "  EnumerableInterpreter\n"
+        + "    DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00"
+        + ".000Z/2992-01-10T00:00:00.000Z]], filter=[AND(>(CAST($1):INTEGER, 
1553), >($91, 5))], "
+        + "projects=[[$1, $90]], groups=[{0}], aggs=[[SUM($1)]])";
 
-    sql(sql)
+    CalciteAssert.AssertQuery q = sql(sql)
         .explainContains(expectedSubExplain)
         .queryContains(
             new DruidChecker("\"queryType\":\"groupBy\"", 
"{\"type\":\"bound\","
                 + 
"\"dimension\":\"store_cost\",\"lower\":\"5\",\"lowerStrict\":true,"
-                + "\"ordering\":\"numeric\"}"))
-        .returnsUnordered("EXPR$0=10.16; product_id=1554\n"
+                + "\"ordering\":\"numeric\"}"));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsUnordered("EXPR$0=10.16; product_id=1554\n"
             + "EXPR$0=45.05; product_id=1556\n"
             + "EXPR$0=88.5; product_id=1555");
   }
@@ -2834,26 +2845,27 @@ public class DruidAdapterIT {
    * approximate results are not acceptable. */
   @Test void testDistinctCountWhenApproxResultsNotAccepted() {
     String sql = "select count(distinct \"store_state\") from \"foodmart\"";
-    String expectedSubExplain = "  BindableAggregate(group=[{}], 
EXPR$0=[COUNT($0)])\n"
-        + "    DruidQuery(table=[[foodmart, foodmart]], "
-        + "intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], "
-        + "groups=[{63}], aggs=[[]])";
-
+    String expectedSubExplain = "PLAN="
+        + "EnumerableAggregate(group=[{}], EXPR$0=[COUNT($0)])\n"
+        + "  EnumerableInterpreter\n"
+        + "    DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00"
+        + ".000Z/2992-01-10T00:00:00.000Z]], projects=[[$63]], groups=[{0}], 
aggs=[[]])\n";
     testCountWithApproxDistinct(false, sql, expectedSubExplain);
   }
 
   @Test void testDistinctCountOnMetric() {
     final String sql = "select count(distinct \"store_sales\") from 
\"foodmart\" "
         + "where \"store_state\" = 'WA'";
-    final String expectedSubExplainNoApprox = "PLAN=EnumerableInterpreter\n"
-        + "  BindableAggregate(group=[{}], EXPR$0=[COUNT($0)])\n"
-        + "    DruidQuery(table=[[foodmart, foodmart]], "
-        + "intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], 
filter=[=($63, 'WA')"
-        + "], groups=[{90}], aggs=[[]])";
+    final String expectedSubExplainNoApprox = "PLAN="
+        + "EnumerableAggregate(group=[{}], EXPR$0=[COUNT($0)])\n"
+        + "  EnumerableInterpreter\n"
+        + "    DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00"
+        + ".000Z/2992-01-10T00:00:00.000Z]], filter=[=($63, 'WA')], 
projects=[[$90]], "
+        + "groups=[{0}], aggs=[[]])";
     final String expectedSubPlanWithApprox = "PLAN=EnumerableInterpreter\n"
-        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
-        + "2992-01-10T00:00:00.000Z]], filter=[=($63, 'WA')], groups=[{}], "
-        + "aggs=[[COUNT(DISTINCT $90)]])";
+        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00"
+        + ".000Z/2992-01-10T00:00:00.000Z]], filter=[=($63, 'WA')], 
projects=[[$90]], "
+        + "groups=[{}], aggs=[[COUNT(DISTINCT $0)]])";
 
     testCountWithApproxDistinct(true, sql, expectedSubPlanWithApprox, 
"'queryType':'timeseries'");
     testCountWithApproxDistinct(false, sql, expectedSubExplainNoApprox, 
"'queryType':'groupBy'");
@@ -2864,7 +2876,7 @@ public class DruidAdapterIT {
     String sql = "select \"brand_name\", count(\"store_sales\") from 
\"foodmart\" "
         + "group by \"brand_name\"";
     String expectedSubExplain = "PLAN=EnumerableInterpreter\n"
-        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], groups=[{2}], 
aggs=[[COUNT($90)]])";
+        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], projects=[[$2, 
$90]], groups=[{0}], aggs=[[COUNT($1)]])";
 
     testCountWithApproxDistinct(true, sql, expectedSubExplain, 
"\"queryType\":\"groupBy\"");
     testCountWithApproxDistinct(false, sql, expectedSubExplain, 
"\"queryType\":\"groupBy\"");
@@ -2875,7 +2887,7 @@ public class DruidAdapterIT {
     String sql = "select count(*) from \"foodmart\"";
     String expectedSubExplain = "PLAN=EnumerableInterpreter\n"
         + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
-        + "2992-01-10T00:00:00.000Z]], projects=[[0]], groups=[{}], 
aggs=[[COUNT()]])";
+        + "2992-01-10T00:00:00.000Z]], groups=[{}], aggs=[[COUNT()]])";
 
     sql(sql).explainContains(expectedSubExplain);
   }
@@ -2887,7 +2899,7 @@ public class DruidAdapterIT {
         + "group by \"B\"";
     String expectedSubExplain = "PLAN=EnumerableInterpreter\n"
         + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
-        + "2992-01-10T00:00:00.000Z]], groups=[{63}], aggs=[[COUNT($89)]])";
+        + "2992-01-10T00:00:00.000Z]], projects=[[$63, $89]], groups=[{0}], 
aggs=[[COUNT($1)]])";
 
     testCountWithApproxDistinct(true, sql, expectedSubExplain);
     testCountWithApproxDistinct(false, sql, expectedSubExplain);
@@ -2897,13 +2909,16 @@ public class DruidAdapterIT {
     final String sql = "select \"B\", count(distinct \"A\") from "
         + "(select \"unit_sales\" as \"A\", \"store_state\" as \"B\" from 
\"foodmart\") "
         + "group by \"B\"";
-    final String expectedSubExplainNoApprox = "PLAN=EnumerableInterpreter\n"
-        + "  BindableAggregate(group=[{0}], EXPR$1=[COUNT($1)])\n"
+    final String expectedSubExplainNoApprox = "PLAN="
+        + "EnumerableAggregate(group=[{0}], EXPR$1=[COUNT($1)])\n"
+        + "  EnumerableInterpreter\n"
         + "    DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
         + "2992-01-10T00:00:00.000Z]], projects=[[$63, $89]], groups=[{0, 1}], 
aggs=[[]])";
-    final String expectedPlanWithApprox = "PLAN=EnumerableInterpreter\n"
-        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
-        + "2992-01-10T00:00:00.000Z]], groups=[{63}], aggs=[[COUNT(DISTINCT 
$89)]])";
+    final String expectedPlanWithApprox = "PLAN="
+        + "EnumerableInterpreter\n"
+        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00"
+        + ".000Z/2992-01-10T00:00:00.000Z]], projects=[[$63, $89]], 
groups=[{0}], aggs=[[COUNT"
+        + "(DISTINCT $1)]])\n";
 
     testCountWithApproxDistinct(true, sql, expectedPlanWithApprox, 
"'queryType':'groupBy'");
     testCountWithApproxDistinct(false, sql, expectedSubExplainNoApprox, 
"'queryType':'groupBy'");
@@ -3078,7 +3093,7 @@ public class DruidAdapterIT {
         + "where cast(\"product_id\" as double) = 1016.0";
     final String plan = "PLAN=EnumerableInterpreter\n"
         + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], "
-        + "filter=[=(CAST($1):DOUBLE, 1016.0)], groups=[{}], 
aggs=[[SUM($91)]])";
+        + "filter=[=(CAST($1):DOUBLE, 1016.0)], projects=[[$91]], groups=[{}], 
aggs=[[SUM($0)]])";
     final String druidQuery =
         
"{'queryType':'timeseries','dataSource':'foodmart','descending':false,'granularity':'all',"
             + 
"'filter':{'type':'bound','dimension':'product_id','lower':'1016.0',"
@@ -3105,7 +3120,7 @@ public class DruidAdapterIT {
         + "where cast(\"product_id\" as double) <> 1016.0";
     final String plan = "PLAN=EnumerableInterpreter\n"
         + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], "
-        + "filter=[<>(CAST($1):DOUBLE, 1016.0)], groups=[{}], 
aggs=[[SUM($91)]])";
+        + "filter=[<>(CAST($1):DOUBLE, 1016.0)], projects=[[$91]], 
groups=[{}], aggs=[[SUM($0)]])";
     final String druidQuery =
         
"{'queryType':'timeseries','dataSource':'foodmart','descending':false,'granularity':'all',"
             + 
"'filter':{'type':'not','field':{'type':'bound','dimension':'product_id','"
@@ -3415,7 +3430,7 @@ public class DruidAdapterIT {
         .explainContains("PLAN=EnumerableInterpreter\n"
             + "  DruidQuery(table=[[foodmart, foodmart]], "
             + 
"intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], "
-            + "projects=[[0]], groups=[{}], aggs=[[COUNT()]])")
+            + "groups=[{}], aggs=[[COUNT()]])")
         .queryContains(
             new DruidChecker(
                 "{\"queryType\":\"timeseries\",\"dataSource\":\"foodmart\","
@@ -3658,11 +3673,11 @@ public class DruidAdapterIT {
         .returnsOrdered("EXPR$0=1997-01-01 00:00:00; EXPR$1=117")
         .queryContains(
             new 
DruidChecker("\"filter\":{\"type\":\"expression\",\"expression\":\""
-                    + "(timestamp_floor(timestamp_parse(concat(concat(",
-                "== timestamp_floor("));
+                    + "(852076800000 == 
timestamp_floor(timestamp_parse(timestamp_format("));
   }
 
   @Test void testDruidTimeFloorAndTimeParseExpressions2() {
+    Assumptions.assumeTrue(Bug.CALCITE_4205_FIXED, "CALCITE-4205");
     final String sql = "SELECT CAST(\"timestamp\" AS TIMESTAMP), count(*) "
         + "from \"foodmart\" WHERE "
         + "CAST(('1997' || '-01' || '-01') AS TIMESTAMP) = CAST(\"timestamp\" 
AS TIMESTAMP) "
@@ -3811,14 +3826,14 @@ public class DruidAdapterIT {
             + " AND CAST(SUBSTRING(\"product_id\" from 4 for 1) AS INTEGER) = 
7"
             + " AND CAST(SUBSTRING(\"product_id\" from 4) AS INTEGER) = 7"
             + " Group by SUBSTRING(\"product_id\" from 1 for 4)";
-    final String plan = "PLAN=EnumerableInterpreter\n"
-        + "  BindableProject(C=[$1], EXPR$1=[$0])\n"
-        + "    DruidQuery(table=[[foodmart, foodmart]], "
-        + "intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], "
-        + "filter=[AND(LIKE(SUBSTRING($1, 1, 4), '12%'), =(CHAR_LENGTH($1), 
4), "
-        + "=(SUBSTRING($1, 3, 1), '2'), =(CAST(SUBSTRING($1, 2, 1)):INTEGER, 
2), "
-        + "=(CAST(SUBSTRING($1, 4, 1)):INTEGER, 7), =(CAST(SUBSTRING($1, 
4)):INTEGER, 7))], "
-        + "projects=[[SUBSTRING($1, 1, 4)]], groups=[{0}], aggs=[[COUNT()]])";
+    final String plan = "PLAN="
+        + "EnumerableCalc(expr#0..1=[{inputs}], C=[$t1], EXPR$1=[$t0])\n"
+        + "  EnumerableInterpreter\n"
+        + "    DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00"
+        + ".000Z/2992-01-10T00:00:00.000Z]], filter=[AND(LIKE(SUBSTRING($1, 1, 
4), '12%'), ="
+        + "(CHAR_LENGTH($1), 4), =(SUBSTRING($1, 3, 1), '2'), 
=(CAST(SUBSTRING($1, 2, 1))"
+        + ":INTEGER, 2), =(CAST(SUBSTRING($1, 4, 1)):INTEGER, 7), 
=(CAST(SUBSTRING($1, 4))"
+        + ":INTEGER, 7))], projects=[[SUBSTRING($1, 1, 4)]], groups=[{0}], 
aggs=[[COUNT()]])\n";
     sql(sql, FOODMART)
         .returnsOrdered("C=60; EXPR$1=1227")
         .explainContains(plan)
@@ -3906,7 +3921,7 @@ public class DruidAdapterIT {
         .explainContains("PLAN=EnumerableInterpreter\n"
             + "  DruidQuery(table=[[foodmart, foodmart]], "
             + 
"intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], "
-            + "filter=[AND(>(SIN($91), SIN(20)), >(COS($90), COS(20)), 
=(FLOOR(TAN($91)), 2), "
+            + "filter=[AND(>(SIN($91), 9.129452507276277E-1), >(COS($90), 
4.08082061813392E-1), =(FLOOR(TAN($91)), 2), "
             + "<(ABS(-(TAN($91), /(SIN($91), COS($91)))), 1.0E-6))], "
             + "groups=[{}], aggs=[[COUNT()]])");
   }
@@ -3938,7 +3953,7 @@ public class DruidAdapterIT {
         .explainContains("PLAN=EnumerableInterpreter\n"
             + "  DruidQuery(table=[[foodmart, foodmart]], "
             + 
"intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], "
-            + "filter=[AND(IS NOT TRUE(=(CAST($1):INTEGER, 1020)), 
<>(CAST($1):INTEGER, 1020))],"
+            + "filter=[<>(CAST($1):INTEGER, 1020)],"
             + " groups=[{}], aggs=[[COUNT()]])");
     final String sql2 = "SELECT COUNT(*) FROM " + FOODMART_TABLE + "WHERE "
         + "\"product_id\" <> 1020";
@@ -4160,9 +4175,7 @@ public class DruidAdapterIT {
         + "\"timeZone\":\"UTC\",\"locale\":\"en-US\"}}";
 
     final String extract_expression = 
"\"expression\":\"(((timestamp_extract(\\\"__time\\\",";
-    sql(sql, FOODMART)
-        .returnsOrdered(
-            "QR_TIMESTAMP_OK=1; SUM_STORE_SALES=139628.34999999971; 
YR_TIMESTAMP_OK=1997")
+    CalciteAssert.AssertQuery q = sql(sql, FOODMART)
         .queryContains(
             new DruidChecker("\"queryType\":\"groupBy\"", extract_year, 
extract_expression))
         .explainContains("PLAN=EnumerableInterpreter\n"
@@ -4170,6 +4183,9 @@ public class DruidAdapterIT {
             + "    DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
             + "2992-01-10T00:00:00.000Z]], 
projects=[[+(/(-(EXTRACT(FLAG(MONTH), $0), 1), 3), 1), "
             + "EXTRACT(FLAG(YEAR), $0), $90]], groups=[{0, 1}], 
aggs=[[SUM($2)]], fetch=[1])");
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered(
+        "QR_TIMESTAMP_OK=1; SUM_STORE_SALES=139628.34999999971; 
YR_TIMESTAMP_OK=1997");
   }
 
   @Test void testTableauQueryExtractMonthDayYear() {
@@ -4198,9 +4214,7 @@ public class DruidAdapterIT {
         + " AS hr_t_timestamp_ok2 FROM  \"foodmart\" GROUP BY "
         + " CAST(SUBSTRING(CAST(CAST(\"foodmart\".\"timestamp\" AS TIMESTAMP) 
AS VARCHAR) from 12 for 2 ) AS INT),"
         + "  MINUTE(\"foodmart\".\"timestamp\"), EXTRACT(HOUR FROM 
\"timestamp\")) LIMIT 1";
-    sql(sql, FOODMART)
-        .returnsOrdered("HR_T_TIMESTAMP_OK=0; MI_T_TIMESTAMP_OK=0; "
-            + "SUM_T_OTHER_OK=565238.1299999986; HR_T_TIMESTAMP_OK2=0")
+    CalciteAssert.AssertQuery q = sql(sql, FOODMART)
         .explainContains("BindableProject(HR_T_TIMESTAMP_OK=[$0], 
MI_T_TIMESTAMP_OK=[$1], "
             + "SUM_T_OTHER_OK=[$3], HR_T_TIMESTAMP_OK2=[$2])\n"
             + "    DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
@@ -4209,6 +4223,9 @@ public class DruidAdapterIT {
             + "NOT NULL, 12, 2)):INTEGER NOT NULL, EXTRACT(FLAG(MINUTE), $0), "
             + "EXTRACT(FLAG(HOUR), $0), $90]], groups=[{0, 1, 2}], 
aggs=[[SUM($3)]], fetch=[1])")
         .queryContains(new DruidChecker("\"queryType\":\"groupBy\""));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("HR_T_TIMESTAMP_OK=0; MI_T_TIMESTAMP_OK=0; "
+        + "SUM_T_OTHER_OK=565238.1299999986; HR_T_TIMESTAMP_OK2=0");
   }
 
   @Test void testTableauQueryMinutesSecondsExtract() {
@@ -4216,14 +4233,15 @@ public class DruidAdapterIT {
         + "MINUTE(\"timestamp\") AS mi_t_timestamp_ok,  SUM(\"store_sales\") 
AS sum_store_sales "
         + " FROM \"foodmart\" GROUP BY SECOND(\"timestamp\"), 
MINUTE(\"timestamp\"))"
         + " LIMIT_ZERO LIMIT 1";
-    sql(sql, FOODMART)
-        .returnsOrdered(
-            "SC_T_TIMESTAMP_OK=0; MI_T_TIMESTAMP_OK=0; 
SUM_STORE_SALES=565238.1299999986")
+    CalciteAssert.AssertQuery q = sql(sql, FOODMART)
         .explainContains("PLAN=EnumerableInterpreter\n"
             + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
             + "2992-01-10T00:00:00.000Z]], projects=[[EXTRACT(FLAG(SECOND), 
$0), "
             + "EXTRACT(FLAG(MINUTE), $0), $90]], groups=[{0, 1}], 
aggs=[[SUM($2)]], fetch=[1])")
         .queryContains(new DruidChecker("\"queryType\":\"groupBy\""));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered(
+        "SC_T_TIMESTAMP_OK=0; MI_T_TIMESTAMP_OK=0; 
SUM_STORE_SALES=565238.1299999986");
   }
 
   @Test void testQueryWithExtractsTimes() {
@@ -4264,8 +4282,7 @@ public class DruidAdapterIT {
   @Test void testHavingSpecs() {
     final String sql = "SELECT \"product_id\" AS P, SUM(\"store_sales\") AS S 
FROM \"foodmart\" "
         + " GROUP BY  \"product_id\" HAVING  SUM(\"store_sales\") > 220  ORDER 
BY P LIMIT 2";
-    sql(sql, FOODMART)
-        .returnsOrdered("P=1; S=236.55", "P=10; S=230.04")
+    CalciteAssert.AssertQuery q = sql(sql, FOODMART)
         .explainContains("PLAN=EnumerableInterpreter\n"
             + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
             + "2992-01-10T00:00:00.000Z]], projects=[[$1, $90]], groups=[{0}], 
aggs=[[SUM($1)]], "
@@ -4273,20 +4290,23 @@ public class DruidAdapterIT {
         .queryContains(
             new 
DruidChecker("'having':{'type':'filter','filter':{'type':'bound',"
                 + 
"'dimension':'S','lower':'220','lowerStrict':true,'ordering':'numeric'}}"));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("P=1; S=236.55", "P=10; S=230.04");
   }
 
   @Test void testTransposableHavingFilter() {
     final String sql = "SELECT \"product_id\" AS P, SUM(\"store_sales\") AS S 
FROM \"foodmart\" "
         + " GROUP BY  \"product_id\" HAVING  SUM(\"store_sales\") > 220 AND 
\"product_id\" > '10'"
         + "  ORDER BY P LIMIT 2";
-    sql(sql, FOODMART)
-        .returnsOrdered("P=100; S=343.19999999999993", "P=1000; S=532.62")
+    CalciteAssert.AssertQuery q = sql(sql, FOODMART)
         .explainContains("PLAN=EnumerableInterpreter\n"
             + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000Z/"
             + "2992-01-10T00:00:00.000Z]], filter=[>($1, '10')], 
projects=[[$1, $90]], groups=[{0}],"
             + " aggs=[[SUM($1)]], filter=[>($1, 220)], sort0=[0], dir0=[ASC], 
fetch=[2])\n")
         .queryContains(
             new 
DruidChecker("{'queryType':'groupBy','dataSource':'foodmart','granularity':'all'"));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("P=100; S=343.19999999999993", "P=1000; S=532.62");
   }
 
   @Test void testProjectSameColumnMultipleTimes() {
@@ -4347,8 +4367,7 @@ public class DruidAdapterIT {
   @Test void testGroupBy1() {
     final String sql = "SELECT SUM(\"store_sales\") FROM \"foodmart\" "
         + "GROUP BY 1 HAVING (COUNT(1) > 0)";
-    sql(sql, FOODMART)
-        .returnsOrdered("EXPR$0=565238.1299999986")
+    CalciteAssert.AssertQuery q = sql(sql, FOODMART)
         .queryContains(
             new 
DruidChecker("{'queryType':'groupBy','dataSource':'foodmart','granularity':'all',"
                 + 
"'dimensions':[{'type':'default','dimension':'vc','outputName':'vc','outputType':'LONG'}],"
@@ -4358,6 +4377,8 @@ public class DruidAdapterIT {
                 + 
"['1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z'],'having':"
                 + 
"{'type':'filter','filter':{'type':'bound','dimension':'$f2','lower':'0',"
                 + "'lowerStrict':true,'ordering':'numeric'}}}"));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "XLAKY");
+    q.returnsOrdered("EXPR$0=565238.1299999986");
   }
 
   @Test void testFloorQuarter() {
@@ -4397,10 +4418,7 @@ public class DruidAdapterIT {
             + " WHERE \"product_id\" = 1"
             + " GROUP BY EXTRACT(quarter from \"timestamp\"), \"product_id\"";
 
-    sql(sql, FOODMART).returnsOrdered("EXPR$0=1; product_id=1; 
EXPR$2=37.050000000000004\n"
-        + "EXPR$0=2; product_id=1; EXPR$2=62.7\n"
-        + "EXPR$0=3; product_id=1; EXPR$2=88.35\n"
-        + "EXPR$0=4; product_id=1; EXPR$2=48.45")
+    CalciteAssert.AssertQuery q = sql(sql, FOODMART)
         .queryContains(
             new DruidChecker(
                 
"{\"queryType\":\"groupBy\",\"dataSource\":\"foodmart\",\"granularity\":\"all\",\"dimensions\":"
@@ -4408,6 +4426,11 @@ public class DruidAdapterIT {
                     + 
"{\"type\":\"default\",\"dimension\":\"product_id\",\"outputName\":\"product_id\",\"outputType\":\"STRING\"}],"
                     + 
"\"virtualColumns\":[{\"type\":\"expression\",\"name\":\"vc\",\"expression\":\"timestamp_extract(\\\"__time\\\",",
                 "QUARTER"));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("EXPR$0=1; product_id=1; EXPR$2=37.050000000000004\n"
+        + "EXPR$0=2; product_id=1; EXPR$2=62.7\n"
+        + "EXPR$0=3; product_id=1; EXPR$2=88.35\n"
+        + "EXPR$0=4; product_id=1; EXPR$2=48.45");
   }
 
   @Test void testExtractQuarter() {
@@ -4415,16 +4438,18 @@ public class DruidAdapterIT {
         + FOODMART_TABLE
         + " GROUP BY EXTRACT(quarter from \"timestamp\")";
 
-    sql(sql, FOODMART).returnsOrdered("EXPR$0=1; EXPR$1=139628.34999999971\n"
-        + "EXPR$0=2; EXPR$1=132666.26999999944\n"
-        + "EXPR$0=3; EXPR$1=140271.88999999964\n"
-        + "EXPR$0=4; EXPR$1=152671.61999999985")
+    CalciteAssert.AssertQuery q = sql(sql, FOODMART)
         .queryContains(
             new DruidChecker(
                 
"{\"queryType\":\"groupBy\",\"dataSource\":\"foodmart\",\"granularity\":\"all\","
                     + 
"\"dimensions\":[{\"type\":\"default\",\"dimension\":\"vc\",\"outputName\":\"vc\",\"outputType\":\"LONG\"}],"
                     + 
"\"virtualColumns\":[{\"type\":\"expression\",\"name\":\"vc\",\"expression\":\"timestamp_extract(\\\"__time\\\",",
                 "QUARTER"));
+    Assumptions.assumeTrue(Bug.CALCITE_4204_FIXED, "CALCITE-4204");
+    q.returnsOrdered("EXPR$0=1; EXPR$1=139628.34999999971\n"
+        + "EXPR$0=2; EXPR$1=132666.26999999944\n"
+        + "EXPR$0=3; EXPR$1=140271.88999999964\n"
+        + "EXPR$0=4; EXPR$1=152671.61999999985");
   }
 
 

Reply via email to