Refactor RelToSqlConverterTest
diff --git a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterStructsTest.java b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterStructsTest.java
index bbbadb8..284bc10 100644
--- a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterStructsTest.java
+++ b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterStructsTest.java
@@ -16,32 +16,15 @@
  */
 package org.apache.calcite.rel.rel2sql;
 
-import org.apache.calcite.config.CalciteConnectionConfig;
-import org.apache.calcite.jdbc.CalciteSchema;
-import org.apache.calcite.linq4j.tree.Expression;
-import org.apache.calcite.rel.type.RelDataType;
-import org.apache.calcite.rel.type.RelDataTypeFactory;
-import org.apache.calcite.rel.type.RelProtoDataType;
-import org.apache.calcite.schema.Function;
-import org.apache.calcite.schema.Schema;
-import org.apache.calcite.schema.SchemaPlus;
-import org.apache.calcite.schema.SchemaVersion;
-import org.apache.calcite.schema.Statistic;
-import org.apache.calcite.schema.Table;
-import org.apache.calcite.sql.SqlCall;
-import org.apache.calcite.sql.SqlNode;
 import org.apache.calcite.sql.dialect.CalciteSqlDialect;
 import org.apache.calcite.sql.parser.SqlParser;
-import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.calcite.test.CalciteAssert;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 
-import org.checkerframework.checker.nullness.qual.Nullable;
 import org.junit.jupiter.api.Test;
 
-import java.util.Collection;
-import java.util.Set;
 import java.util.function.UnaryOperator;
 
 /**
@@ -50,120 +33,8 @@
  */
 class RelToSqlConverterStructsTest {
 
-  private static final Schema SCHEMA = new Schema() {
-    @Override public Table getTable(String name) {
-      return TABLE;
-    }
-
-    @Override public Set<String> getTableNames() {
-      return ImmutableSet.of("myTable");
-    }
-
-    @Override public RelProtoDataType getType(String name) {
-      return null;
-    }
-
-    @Override public Set<String> getTypeNames() {
-      return ImmutableSet.of();
-    }
-
-    @Override public Collection<Function> getFunctions(String name) {
-      return null;
-    }
-
-    @Override public Set<String> getFunctionNames() {
-      return ImmutableSet.of();
-    }
-
-    @Override public Schema getSubSchema(String name) {
-      return null;
-    }
-
-    @Override public Set<String> getSubSchemaNames() {
-      return ImmutableSet.of();
-    }
-
-    @Override public Expression getExpression(@Nullable SchemaPlus parentSchema, String name) {
-      return null;
-    }
-
-    @Override public boolean isMutable() {
-      return false;
-    }
-
-    @Override public Schema snapshot(SchemaVersion version) {
-      return null;
-    }
-  };
-
-  private static final Table TABLE = new Table() {
-    /**
-     * {@inheritDoc}
-     *
-     * <p>Table schema is as follows:
-     *
-     * <blockquote>
-     * <pre>
-     *  myTable(
-     *          a: BIGINT,
-     *          n1: STRUCT&lt;
-     *                n11: STRUCT&lt;b: BIGINT&gt;,
-     *                n12: STRUCT&lt;c: BIGINT&gt;
-     *              &gt;,
-     *          n2: STRUCT&lt;d: BIGINT&gt;,
-     *          e: BIGINT)
-     * </pre>
-     * </blockquote>
-     */
-    @Override public RelDataType getRowType(RelDataTypeFactory tf) {
-      RelDataType bigint = tf.createSqlType(SqlTypeName.BIGINT);
-      RelDataType n1Type = tf.createStructType(
-          ImmutableList.of(
-              tf.createStructType(ImmutableList.of(bigint),
-                  ImmutableList.of("b")),
-              tf.createStructType(ImmutableList.of(bigint),
-                  ImmutableList.of("c"))),
-          ImmutableList.of("n11", "n12"));
-      RelDataType n2Type = tf.createStructType(
-          ImmutableList.of(bigint),
-          ImmutableList.of("d"));
-      return tf.createStructType(
-          ImmutableList.of(bigint, n1Type, n2Type, bigint),
-          ImmutableList.of("a", "n1", "n2", "e"));
-    }
-
-    @Override public Statistic getStatistic() {
-      return STATS;
-    }
-
-    @Override public Schema.TableType getJdbcTableType() {
-      return null;
-    }
-
-    @Override public boolean isRolledUp(String column) {
-      return false;
-    }
-
-    @Override public boolean rolledUpColumnValidInsideAgg(
-        String column,
-        SqlCall call,
-        @Nullable SqlNode parent,
-        @Nullable CalciteConnectionConfig config) {
-      return false;
-    }
-  };
-
-  private static final Statistic STATS = new Statistic() {
-    @Override public Double getRowCount() {
-      return 0D;
-    }
-  };
-
-  private static final SchemaPlus ROOT_SCHEMA = CalciteSchema
-      .createRootSchema(false).add("myDb", SCHEMA).plus();
-
   private RelToSqlConverterTest.Sql sql(String sql) {
-    return new RelToSqlConverterTest.Sql(ROOT_SCHEMA, sql,
+    return new RelToSqlConverterTest.Sql(CalciteAssert.SchemaSpec.MY_DB, sql,
         CalciteSqlDialect.DEFAULT, SqlParser.Config.DEFAULT, ImmutableSet.of(),
         UnaryOperator.identity(), null, ImmutableList.of());
   }
diff --git a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
index 3db6777..b41c9ad 100644
--- a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
+++ b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
@@ -119,7 +119,9 @@
 
   /** Initiates a test case with a given {@link RelNode} supplier. */
   private Sql relFn(Function<RelBuilder, RelNode> relFn) {
-    return sql("?").relFn(relFn);
+    return sql("?")
+        .schema(CalciteAssert.SchemaSpec.SCOTT_WITH_TEMPORAL)
+        .relFn(relFn);
   }
 
   private static Planner getPlanner(List<RelTraitDef> traitDefs,
@@ -5854,7 +5856,7 @@
 
   /** Fluid interface to run tests. */
   static class Sql {
-    private final SchemaPlus schema;
+    private final CalciteAssert.SchemaSpec schemaSpec;
     private final String sql;
     private final SqlDialect dialect;
     private final Set<SqlLibrary> librarySet;
@@ -5868,23 +5870,7 @@
         UnaryOperator<SqlToRelConverter.Config> config,
         @Nullable Function<RelBuilder, RelNode> relFn,
         List<Function<RelNode, RelNode>> transforms) {
-      final SchemaPlus rootSchema = Frameworks.createRootSchema(true);
-      this.schema = CalciteAssert.addSchema(rootSchema, schemaSpec);
-      this.sql = sql;
-      this.dialect = dialect;
-      this.librarySet = librarySet;
-      this.relFn = relFn;
-      this.transforms = ImmutableList.copyOf(transforms);
-      this.parserConfig = parserConfig;
-      this.config = config;
-    }
-
-    Sql(SchemaPlus schema, String sql, SqlDialect dialect,
-        SqlParser.Config parserConfig, Set<SqlLibrary> librarySet,
-        UnaryOperator<SqlToRelConverter.Config> config,
-        Function<RelBuilder, RelNode> relFn,
-        List<Function<RelNode, RelNode>> transforms) {
-      this.schema = schema;
+      this.schemaSpec = schemaSpec;
       this.sql = sql;
       this.dialect = dialect;
       this.librarySet = librarySet;
@@ -5895,12 +5881,12 @@
     }
 
     Sql dialect(SqlDialect dialect) {
-      return new Sql(schema, sql, dialect, parserConfig, librarySet, config,
+      return new Sql(schemaSpec, sql, dialect, parserConfig, librarySet, config,
           relFn, transforms);
     }
 
     Sql relFn(Function<RelBuilder, RelNode> relFn) {
-      return new Sql(schema, sql, dialect, parserConfig, librarySet, config,
+      return new Sql(schemaSpec, sql, dialect, parserConfig, librarySet, config,
           relFn, transforms);
     }
 
@@ -6027,12 +6013,12 @@
     }
 
     Sql parserConfig(SqlParser.Config parserConfig) {
-      return new Sql(schema, sql, dialect, parserConfig, librarySet, config,
+      return new Sql(schemaSpec, sql, dialect, parserConfig, librarySet, config,
           relFn, transforms);
     }
 
     Sql withConfig(UnaryOperator<SqlToRelConverter.Config> config) {
-      return new Sql(schema, sql, dialect, parserConfig, librarySet, config,
+      return new Sql(schemaSpec, sql, dialect, parserConfig, librarySet, config,
           relFn, transforms);
     }
 
@@ -6041,7 +6027,7 @@
     }
 
     Sql withLibrarySet(Iterable<? extends SqlLibrary> librarySet) {
-      return new Sql(schema, sql, dialect, parserConfig,
+      return new Sql(schemaSpec, sql, dialect, parserConfig,
           ImmutableSet.copyOf(librarySet), config, relFn, transforms);
     }
 
@@ -6058,7 +6044,7 @@
             return program.run(p, r, r.getTraitSet(),
                 ImmutableList.of(), ImmutableList.of());
           });
-      return new Sql(schema, sql, dialect, parserConfig, librarySet, config,
+      return new Sql(schemaSpec, sql, dialect, parserConfig, librarySet, config,
           relFn, transforms);
     }
 
@@ -6080,14 +6066,21 @@
 
     String exec() {
       try {
+        final SchemaPlus rootSchema = Frameworks.createRootSchema(true);
+        final SchemaPlus defaultSchema =
+            CalciteAssert.addSchema(rootSchema, schemaSpec);
         RelNode rel;
         if (relFn != null) {
-          rel = relFn.apply(relBuilder());
+          final FrameworkConfig frameworkConfig = RelBuilderTest.config()
+              .defaultSchema(defaultSchema)
+              .build();
+          final RelBuilder relBuilder = RelBuilder.create(frameworkConfig);
+          rel = relFn.apply(relBuilder);
         } else {
           final SqlToRelConverter.Config config = this.config.apply(SqlToRelConverter.config()
               .withTrimUnusedFields(false));
           final Planner planner =
-              getPlanner(null, parserConfig, schema, config, librarySet);
+              getPlanner(null, parserConfig, defaultSchema, config, librarySet);
           SqlNode parse = planner.parse(sql);
           SqlNode validate = planner.validate(parse);
           rel = planner.rel(validate).rel;
diff --git a/core/src/test/java/org/apache/calcite/test/CalciteAssert.java b/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
index 88e3cea..fcc3f66 100644
--- a/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
+++ b/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
@@ -30,6 +30,7 @@
 import org.apache.calcite.jdbc.CalciteMetaImpl;
 import org.apache.calcite.jdbc.CalcitePrepare;
 import org.apache.calcite.jdbc.CalciteSchema;
+import org.apache.calcite.linq4j.tree.Expression;
 import org.apache.calcite.materialize.Lattice;
 import org.apache.calcite.model.ModelHandler;
 import org.apache.calcite.plan.Contexts;
@@ -39,12 +40,16 @@
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeFactory;
 import org.apache.calcite.rel.type.RelDataTypeImpl;
+import org.apache.calcite.rel.type.RelProtoDataType;
 import org.apache.calcite.runtime.CalciteException;
 import org.apache.calcite.runtime.FlatLists;
 import org.apache.calcite.runtime.GeoFunctions;
 import org.apache.calcite.runtime.Hook;
 import org.apache.calcite.schema.Schema;
 import org.apache.calcite.schema.SchemaPlus;
+import org.apache.calcite.schema.SchemaVersion;
+import org.apache.calcite.schema.Statistic;
+import org.apache.calcite.schema.Table;
 import org.apache.calcite.schema.TableFunction;
 import org.apache.calcite.schema.Wrapper;
 import org.apache.calcite.schema.impl.AbstractSchema;
@@ -52,8 +57,10 @@
 import org.apache.calcite.schema.impl.TableFunctionImpl;
 import org.apache.calcite.schema.impl.ViewTable;
 import org.apache.calcite.schema.impl.ViewTableMacro;
+import org.apache.calcite.sql.SqlCall;
 import org.apache.calcite.sql.SqlDialect;
 import org.apache.calcite.sql.SqlExplainLevel;
+import org.apache.calcite.sql.SqlNode;
 import org.apache.calcite.sql.fun.SqlGeoFunctions;
 import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.calcite.sql.validate.SqlConformanceEnum;
@@ -61,6 +68,7 @@
 import org.apache.calcite.tools.FrameworkConfig;
 import org.apache.calcite.tools.Frameworks;
 import org.apache.calcite.tools.RelBuilder;
+import org.apache.calcite.tools.TpchSchema;
 import org.apache.calcite.util.Closer;
 import org.apache.calcite.util.Holder;
 import org.apache.calcite.util.JsonBuilder;
@@ -77,6 +85,7 @@
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableMultiset;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 
 import net.hydromatic.foodmart.data.hsqldb.FoodmartHsqldb;
@@ -107,6 +116,7 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Properties;
+import java.util.Set;
 import java.util.TreeSet;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Consumer;
@@ -793,6 +803,10 @@
                   + "join \"foodmart\".\"product_class\" as pc on p.\"product_class_id\" = pc.\"product_class_id\"",
               true));
       return foodmart;
+
+    case MY_DB:
+      return rootSchema.add(schema.schemaName, MY_DB_SCHEMA);
+
     case SCOTT:
       jdbcScott = addSchemaIfNotExists(rootSchema, SchemaSpec.JDBC_SCOTT);
       return rootSchema.add(schema.schemaName, new CloneSchema(jdbcScott));
@@ -803,6 +817,11 @@
           new StreamTest.OrdersHistoryTable(
               StreamTest.OrdersStreamTableFactory.getRowList()));
       return scott;
+
+    case TPCH:
+      return rootSchema.add(schema.schemaName,
+          new ReflectiveSchema(new TpchSchema()));
+
     case CLONE_FOODMART:
       foodmart = addSchemaIfNotExists(rootSchema, SchemaSpec.JDBC_FOODMART);
       return rootSchema.add("foodmart2", new CloneSchema(foodmart));
@@ -2065,9 +2084,11 @@
     JDBC_FOODMART_WITH_LATTICE("lattice"),
     GEO("GEO"),
     HR("hr"),
+    MY_DB("myDb"),
     JDBC_SCOTT("JDBC_SCOTT"),
     SCOTT("scott"),
     SCOTT_WITH_TEMPORAL("scott_temporal"),
+    TPCH("tpch"),
     BLANK("BLANK"),
     LINGUAL("SALES"),
     POST("POST"),
@@ -2237,4 +2258,108 @@
       }
     }
   }
+
+  /** Schema instance for {@link SchemaSpec#MY_DB}. */
+  private static final Schema MY_DB_SCHEMA = new Schema() {
+
+    final Table table = new Table() {
+      /**
+       * {@inheritDoc}
+       *
+       * <p>Table schema is as follows:
+       *
+       * <pre>{@code
+       * myTable(
+       *      a: BIGINT,
+       *      n1: STRUCT<
+       *            n11: STRUCT<b: BIGINT>,
+       *            n12: STRUCT<c: BIGINT>
+       *          >,
+       *      n2: STRUCT<d: BIGINT>,
+       *      e: BIGINT)
+       * }</pre>
+       */
+      @Override public RelDataType getRowType(RelDataTypeFactory typeFactory) {
+        RelDataType bigint = typeFactory.createSqlType(SqlTypeName.BIGINT);
+        return typeFactory.builder()
+            .add("a", bigint)
+            .add("n1",
+                typeFactory.builder()
+                    .add("n11", typeFactory.builder().add("b", bigint).build())
+                    .add("n12", typeFactory.builder().add("c", bigint).build())
+                    .build())
+            .add("n2", typeFactory.builder().add("d", bigint).build())
+            .add("e", bigint)
+            .build();
+      }
+
+      @Override public Statistic getStatistic() {
+        return new Statistic() {
+          @Override public Double getRowCount() {
+            return 0D;
+          }
+        };
+      }
+
+      @Override public Schema.TableType getJdbcTableType() {
+        return null;
+      }
+
+      @Override public boolean isRolledUp(String column) {
+        return false;
+      }
+
+      @Override public boolean rolledUpColumnValidInsideAgg(String column,
+          SqlCall call, @Nullable SqlNode parent,
+          @Nullable CalciteConnectionConfig config) {
+        return false;
+      }
+    };
+
+    @Override public Table getTable(String name) {
+      return table;
+    }
+
+    @Override public Set<String> getTableNames() {
+      return ImmutableSet.of("myTable");
+    }
+
+    @Override public RelProtoDataType getType(String name) {
+      return null;
+    }
+
+    @Override public Set<String> getTypeNames() {
+      return ImmutableSet.of();
+    }
+
+    @Override public Collection<org.apache.calcite.schema.Function>
+      getFunctions(String name) {
+      return null;
+    }
+
+    @Override public Set<String> getFunctionNames() {
+      return ImmutableSet.of();
+    }
+
+    @Override public Schema getSubSchema(String name) {
+      return null;
+    }
+
+    @Override public Set<String> getSubSchemaNames() {
+      return ImmutableSet.of();
+    }
+
+    @Override public Expression getExpression(@Nullable SchemaPlus parentSchema,
+        String name) {
+      return null;
+    }
+
+    @Override public boolean isMutable() {
+      return false;
+    }
+
+    @Override public Schema snapshot(SchemaVersion version) {
+      return null;
+    }
+  };
 }
diff --git a/core/src/test/java/org/apache/calcite/tools/TpchSchema.java b/core/src/test/java/org/apache/calcite/tools/TpchSchema.java
index 1312238..13900d0 100644
--- a/core/src/test/java/org/apache/calcite/tools/TpchSchema.java
+++ b/core/src/test/java/org/apache/calcite/tools/TpchSchema.java
@@ -20,18 +20,55 @@
  * TPC-H table schema.
  */
 public class TpchSchema {
+  public final Customer[] customer = { c(1), c(2) };
+  public final LineItem[] lineitem = { li(1), li(2) };
   public final Part[] part = { p(1), p(2) };
   public final PartSupp[] partsupp = { ps(1, 250), ps(2, 100) };
 
   /**
+   * Customer in TPC-H.
+   */
+  public static class Customer {
+    public final int custId;
+    // CHECKSTYLE: IGNORE 1
+    public final String nation_name;
+
+    public Customer(int custId) {
+      this.custId = custId;
+      this.nation_name = "USA";
+    }
+
+    @Override public String toString() {
+      return "Customer [custId=" + custId + "]";
+    }
+  }
+
+  /**
+   * Line Item in TPC-H.
+   */
+  public static class LineItem {
+    public final int custId;
+
+    public LineItem(int custId) {
+      this.custId = custId;
+    }
+
+    @Override public String toString() {
+      return "LineItem [custId=" + custId + "]";
+    }
+  }
+
+  /**
    * Part in TPC-H.
    */
   public static class Part {
-    public int pPartkey;
-
+    public final int pPartkey;
+    // CHECKSTYLE: IGNORE 1
+    public final String p_brand;
 
     public Part(int pPartkey) {
       this.pPartkey = pPartkey;
+      this.p_brand = "brand" + pPartkey;
     }
 
     @Override public String toString() {
@@ -57,6 +94,14 @@
     }
   }
 
+  public static Customer c(int custId) {
+    return new Customer(custId);
+  }
+
+  public static LineItem li(int custId) {
+    return new LineItem(custId);
+  }
+
   public static PartSupp ps(int pPartkey, int pSupplyCost) {
     return new PartSupp(pPartkey, pSupplyCost);
   }