You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2015/01/23 05:33:11 UTC
[2/4] incubator-calcite git commit: Fix up some class names and URLs
in HOWTO, MODEL, TUTORIAL
Fix up some class names and URLs in HOWTO, MODEL, TUTORIAL
Project: http://git-wip-us.apache.org/repos/asf/incubator-calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-calcite/commit/b66ff933
Tree: http://git-wip-us.apache.org/repos/asf/incubator-calcite/tree/b66ff933
Diff: http://git-wip-us.apache.org/repos/asf/incubator-calcite/diff/b66ff933
Branch: refs/heads/master
Commit: b66ff933741c0e66d57ad5316330c8728861327e
Parents: cb53378
Author: Julian Hyde <jh...@apache.org>
Authored: Thu Jan 22 16:16:34 2015 -0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Thu Jan 22 16:16:34 2015 -0800
----------------------------------------------------------------------
doc/HOWTO.md | 111 +++++++++----------
doc/MODEL.md | 6 +-
doc/TUTORIAL.md | 91 +++++++--------
.../apache/calcite/adapter/csv/CsvSchema.java | 30 ++---
4 files changed, 119 insertions(+), 119 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/b66ff933/doc/HOWTO.md
----------------------------------------------------------------------
diff --git a/doc/HOWTO.md b/doc/HOWTO.md
index 499eb3a..5e53ba2 100644
--- a/doc/HOWTO.md
+++ b/doc/HOWTO.md
@@ -13,8 +13,8 @@ Unpack the source distribution `.tar.gz` or `.zip` file,
then build using maven:
```bash
-$ tar xvfz calcite-0.9.2-incubating-source.tar.gz
-$ cd calcite-0.9.2-incubating
+$ tar xvfz calcite-1.0.0-incubating-source.tar.gz
+$ cd calcite-1.0.0-incubating
$ mvn install
```
@@ -45,7 +45,8 @@ The test suite will run by default when you build, unless you specify
`-DskipTests`:
```bash
-$ mvn -DskipTests clean install
+$ mvn clean
+$ mvn -DskipTests install
```
There are other options that control which tests are run, and in what
@@ -123,19 +124,18 @@ framework. Put the following into core/src/test/resources/logging.properties:
```properties
handlers= java.util.logging.ConsoleHandler
.level= INFO
-org.eigenbase.relopt.RelOptPlanner.level=FINER
+org.apache.calcite.plan.RelOptPlanner.level=FINER
java.util.logging.ConsoleHandler.level=ALL
```
-The line org.eigenbase.relopt.RelOptPlanner.level=FINER tells the planner to produce
-fairly verbose outout. You can modify the file to enable other loggers, or to change levels.
-For instance, if you change FINER to FINEST the planner will give you an account of the
+The line `org.apache.calcite.plan.RelOptPlanner.level=FINER` tells the planner to produce
+fairly verbose output. You can modify the file to enable other loggers, or to change levels.
+For instance, if you change `FINER` to `FINEST` the planner will give you an account of the
planning process so detailed that it might fill up your hard drive.
## CSV adapter
-See <a href="https://github.com/julianhyde/optiq-csv/blob/master/TUTORIAL.md">optiq-csv
-tutorial</a>.
+See the <a href="TUTORIAL.md">tutorial</a>.
## MongoDB adapter
@@ -172,8 +172,8 @@ Calcite model:
$ ./sqlline
sqlline> !connect jdbc:calcite:model=mongodb/target/test-classes/mongo-zips-model.json admin admin
Connecting to jdbc:calcite:model=mongodb/target/test-classes/mongo-zips-model.json
-Connected to: Calcite (version 0.9.x)
-Driver: Calcite JDBC Driver (version 0.9.x)
+Connected to: Calcite (version 1.x.x)
+Driver: Calcite JDBC Driver (version 1.x.x)
Autocommit status: true
Transaction isolation: TRANSACTION_REPEATABLE_READ
sqlline> !tables
@@ -210,68 +210,65 @@ queries. It is also necessary if you intend to run the test suite, using
## Implementing an adapter
-New adapters can be created by implementing `OptiqPrepare.Context`:
+New adapters can be created by implementing `CalcitePrepare.Context`:
```java
-import net.hydromatic.optiq.Schema;
-import net.hydromatic.optiq.impl.java.JavaTypeFactory;
-import net.hydromatic.optiq.jdbc.OptiqPrepare;
-public class AdapterContext implements OptiqPrepare.Context {
-
- @Override
- public JavaTypeFactory getTypeFactory() {
- // adapter implementation
- return typeFactory;
- }
-
- @Override
- public Schema getRootSchema() {
- // adapter implementation
- return rootSchema;
- }
-
+import org.apache.calcite.adapter.java.JavaTypeFactory;
+import org.apache.calcite.jdbc.CalcitePrepare;
+import org.apache.calcite.jdbc.CalciteRootSchema;
+
+public class AdapterContext implements CalcitePrepare.Context {
+ @Override
+ public JavaTypeFactory getTypeFactory() {
+ // adapter implementation
+ return typeFactory;
+ }
+
+ @Override
+ public CalciteRootSchema getRootSchema() {
+ // adapter implementation
+ return rootSchema;
+ }
}
```
### Testing adapter in Java
The example below shows how SQL query can be submitted to
-`OptiqPrepare` with a custom context (`AdapterContext` in this
+`CalcitePrepare` with a custom context (`AdapterContext` in this
case). Calcite prepares and implements the query execution, using the
-resources provided by the `Context`. `OptiqPrepare.PrepareResult`
+resources provided by the `Context`. `CalcitePrepare.PrepareResult`
provides access to the underlying enumerable and methods for
enumeration. The enumerable itself can naturally be some adapter
specific implementation.
```java
-import net.hydromatic.optiq.jdbc.OptiqPrepare;
-import net.hydromatic.optiq.prepare.OptiqPrepareImpl;
+import org.apache.calcite.jdbc.CalcitePrepare;
+import org.apache.calcite.prepare.CalcitePrepareImpl;
import org.junit.Test;
public class AdapterContextTest {
-
- @Test
- public void testSelectAllFromTable() {
- AdapterContext ctx = new AdapterContext();
- String sql = "SELECT * FROM TABLENAME";
- Type elementType = Object[].class;
- OptiqPrepare.PrepareResult<Object> prepared = new OptiqPrepareImpl()
- .prepareSql(ctx, sql, null, elementType, -1);
- Object enumerable = prepared.getExecutable();
- // etc.
- }
-
+ @Test
+ public void testSelectAllFromTable() {
+ AdapterContext ctx = new AdapterContext();
+ String sql = "SELECT * FROM TABLENAME";
+ Class elementType = Object[].class;
+ CalcitePrepare.PrepareResult<Object> prepared =
+ new CalcitePrepareImpl().prepareSql(ctx, sql, null, elementType, -1);
+ Object enumerable = prepared.getExecutable();
+ // etc.
+ }
}
```
-## JavaTypeFactory
+### JavaTypeFactory
-When Calcite compares `Type` instances, it requires them to be the same
-object. If there are two distinct `Type` instances that refer to the
+When Calcite compares types (instances of `RelDataType`), it requires them to be the same
+object. If there are two distinct type instances that refer to the
same Java type, Calcite may fail to recognize that they match. It is
recommended to:
-- Use a single instance of `JavaTypeFactory` within the calcite context
-- Store the `Type` instances so that the same object is always returned for the same `Type`.
+* Use a single instance of `JavaTypeFactory` within the calcite context;
+* Store the types so that the same object is always returned for the same type.
## Set up PGP signing keys (for Calcite committers)
@@ -291,12 +288,13 @@ Before you start:
```bash
# set passphrase variable without putting it into shell history
-read GPG_PASSPHRASE
+read -s GPG_PASSPHRASE
# make sure that there are no junk files in the sandbox
-git clean -x
+git clean -xn
+mvn clean
-mvn -Papache-release -Dgpg.passphrase=${GPG_PASSPHRASE} clean install
+mvn -Papache-release -Dgpg.passphrase=${GPG_PASSPHRASE} install
```
When the dry-run has succeeded, change `install` to `deploy`.
@@ -306,7 +304,7 @@ When the dry-run has succeeded, change `install` to `deploy`.
Before you start:
* Set up signing keys as described above.
* Make sure you are using JDK 1.7 (not 1.6 or 1.8).
-* Check that README and README.md have the correct version number.
+* Check that README, README.md and HOWTO.md have the correct version number.
* Make sure build and tests succeed, including with
-Dcalcite.test.db={mysql,hsqldb}, -Dcalcite.test.slow=true,
-Dcalcite.test.mongodb=true, -Dcalcite.test.splunk=true.
@@ -329,10 +327,11 @@ start again from the top.
```bash
# Set passphrase variable without putting it into shell history
-read GPG_PASSPHRASE
+read -s GPG_PASSPHRASE
# Make sure that there are no junk files in the sandbox
git clean -xn
+mvn clean
# Do a dry run of the release:prepare step, which sets version numbers.
mvn -DdryRun=true -DskipTests -DreleaseVersion=X.Y.Z-incubating -DdevelopmentVersion=X.Y.Z+1-incubating-SNAPSHOT -Papache-release -Darguments="-Dgpg.passphrase=${GPG_PASSPHRASE}" clean release:prepare 2>&1 | tee /tmp/prepare-dry.log
@@ -362,7 +361,7 @@ Check the artifacts:
`mongodb/target/calcite-mongodb-X.Y.Z-incubating-sources.jar`), check
that the `META-INF` directory contains `DEPENDENCIES`, `LICENSE`,
`NOTICE` and `git.properties`
-* In each .jar, check that `net-hydromatic-optiq-jdbc.properties` is
+* In each .jar, check that `org-apache-calcite-jdbc.properties` is
present and does not contain un-substituted `${...}` variables
* Check PGP, per https://httpd.apache.org/dev/verification.html
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/b66ff933/doc/MODEL.md
----------------------------------------------------------------------
diff --git a/doc/MODEL.md b/doc/MODEL.md
index e9febf2..f533e75 100644
--- a/doc/MODEL.md
+++ b/doc/MODEL.md
@@ -108,7 +108,7 @@ Like base class <a href="#schema">Schema</a>, occurs within `root.schemas`.
{
name: 'mongo',
type: 'custom',
- factory: 'net.hydromatic.optiq.impl.mongodb.MongoSchemaFactory',
+ factory: 'org.apache.calcite.adapter.mongodb.MongoSchemaFactory',
operand: {
host: 'localhost',
database: 'test'
@@ -120,7 +120,7 @@ Like base class <a href="#schema">Schema</a>, occurs within `root.schemas`.
<a href="#schema">Schema</a>.
`factory` (required string) is the name of the factory class for this
-schema. Must implement interface `net.hydromatic.optiq.SchemaFactory`
+schema. Must implement interface `org.apache.calcite.schema.SchemaFactory`
and have a public default constructor.
`operand` (optional map) contains attributes to be passed to the
@@ -238,7 +238,7 @@ Like base class <a href="#table">Table</a>, occurs within `root.schemas.tables`.
`name`, `type`, `columns` inherited from <a href="#table">Table</a>.
`factory` (required string) is the name of the factory class for this
-table. Must implement interface `net.hydromatic.optiq.TableFactory`
+table. Must implement interface `org.apache.calcite.schema.TableFactory`
and have a public default constructor.
`operand` (optional map) contains attributes to be passed to the
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/b66ff933/doc/TUTORIAL.md
----------------------------------------------------------------------
diff --git a/doc/TUTORIAL.md b/doc/TUTORIAL.md
index 4519db3..40a5982 100644
--- a/doc/TUTORIAL.md
+++ b/doc/TUTORIAL.md
@@ -150,7 +150,7 @@ format. Here is the model:
{
name: 'SALES',
type: 'custom',
- factory: 'net.hydromatic.optiq.impl.csv.CsvSchemaFactory',
+ factory: 'org.apache.calcite.adapter.csv.CsvSchemaFactory',
operand: {
directory: 'target/test-classes/sales'
}
@@ -161,9 +161,11 @@ format. Here is the model:
The model defines a single schema called 'SALES'. The schema is
powered by a plugin class,
-<a href="src/main/java/net/hydromatic/optiq/impl/csv/CsvSchemaFactory.java">net.hydromatic.optiq.impl.csv.CsvSchemaFactory</a>, which is part of the
+<a href="../example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvSchemaFactory.java">org.apache.calcite.adapter.csv.CsvSchemaFactory</a>,
+which is part of the
calcite-example-csv project and implements the Calcite interface
-<a href="http://www.hydromatic.net/calcite/apidocs/net/hydromatic/optiq/SchemaFactory.html">SchemaFactory</a>. Its <code>create</code> method instantiates a
+<a href="http://www.hydromatic.net/calcite/apidocs/org/apache/calcite/schema/SchemaFactory.html">SchemaFactory</a>.
+Its <code>create</code> method instantiates a
schema, passing in the <code>directory</code> argument from the model file:
```java
@@ -185,20 +187,20 @@ public Schema create(SchemaPlus parentSchema, String name,
Driven by the model, the schema factory instantiates a single schema
called 'SALES'. The schema is an instance of
-<a href="src/main/java/net/hydromatic/optiq/impl/csv/CsvSchema.java">net.hydromatic.optiq.impl.csv.CsvSchema</a>
+<a href="../example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvSchema.java">org.apache.calcite.adapter.csv.CsvSchema</a>
and implements the Calcite interface <a
-href="http://www.hydromatic.net/calcite/apidocs/net/hydromatic/optiq/Schema.html">Schema</a>.
+href="http://www.hydromatic.net/calcite/apidocs/org/apache/calcite/schema/Schema.html">Schema</a>.
A schema's job is to produce a list of tables. (It can also list sub-schemas and
table-functions, but these are advanced features and calcite-example-csv does
not support them.) The tables implement Calcite's
-<a href="http://www.hydromatic.net/calcite/apidocs/net/hydromatic/optiq/Table.html">Table</a>
+<a href="http://www.hydromatic.net/calcite/apidocs/org/apache/calcite/schema/Table.html">Table</a>
interface. <code>CsvSchema</code> produces tables that are instances of
-<a href="src/main/java/net/hydromatic/optiq/impl/csv/CsvTable.java">CsvTable</a>
+<a href="../example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvTable.java">CsvTable</a>
and its sub-classes.
Here is the relevant code from <code>CsvSchema</code>, overriding the
-<code><a href="http://www.hydromatic.net/calcite/apidocs/net/hydromatic/optiq/impl/AbstractSchema.html#getTableMap()">getTableMap()</a></code>
+<code><a href="http://www.hydromatic.net/calcite/apidocs/org/apache/calcite/schema/impl/AbstractSchema.html#getTableMap()">getTableMap()</a></code>
method in the <code>AbstractSchema</code> base class.
```java
@@ -228,26 +230,25 @@ protected Map<String, Table> getTableMap() {
continue;
}
tableName = trim(tableName, ".csv");
-
- // Create different sub-types of table based on the "flavor" attribute.
- final Table table;
- switch (flavor) {
- case SCANNABLE:
- table = new CsvScannableTable(file, null);
- break;
- case FILTERABLE:
- table = new CsvFilterableTable(file, null);
- break;
- case TRANSLATABLE:
- table = new CsvTranslatableTable(file, null);
- break;
- default:
- throw new AssertionError("Unknown flavor " + flavor);
- }
+ final Table table = createTable(file);
builder.put(tableName, table);
}
return builder.build();
}
+
+/** Creates different sub-type of table based on the "flavor" attribute. */
+private Table createTable(File file) {
+ switch (flavor) {
+ case TRANSLATABLE:
+ return new CsvTranslatableTable(file, null);
+ case SCANNABLE:
+ return new CsvScannableTable(file, null);
+ case FILTERABLE:
+ return new CsvFilterableTable(file, null);
+ default:
+ throw new AssertionError("Unknown flavor " + flavor);
+ }
+}
```
The schema scans the directory and finds all files whose name ends
@@ -284,7 +285,7 @@ Here is a schema that defines a view:
{
name: 'SALES',
type: 'custom',
- factory: 'net.hydromatic.optiq.impl.csv.CsvSchemaFactory',
+ factory: 'org.apache.calcite.adapter.csv.CsvSchemaFactory',
operand: {
directory: 'target/test-classes/sales'
},
@@ -349,7 +350,7 @@ There is an example in <code>model-with-custom-table.json</code>:
{
name: 'EMPS',
type: 'custom',
- factory: 'net.hydromatic.optiq.impl.csv.CsvTableFactory',
+ factory: 'org.apache.calcite.adapter.csv.CsvTableFactory',
operand: {
file: 'target/test-classes/sales/EMPS.csv.gz',
flavor: "scannable"
@@ -378,9 +379,9 @@ sqlline> SELECT empno, name FROM custom_table.emps;
```
The schema is a regular one, and contains a custom table powered by
-<a href="src/main/java/net/hydromatic/optiq/impl/csv/CsvTableFactory.java">net.hydromatic.optiq.impl.csv.CsvTableFactory</a>,
+<a href="../example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvTableFactory.java">org.apache.calcite.adapter.csv.CsvTableFactory</a>,
which implements the Calcite interface
-<a href="http://www.hydromatic.net/calcite/apidocs/net/hydromatic/optiq/TableFactory.html">TableFactory</a>.
+<a href="http://www.hydromatic.net/calcite/apidocs/org/apache/calcite/schema/TableFactory.html">TableFactory</a>.
Its <code>create</code> method instantiates a <code>CsvScannableTable</code>,
passing in the <code>file</code> argument from the model file:
@@ -475,35 +476,35 @@ flavor: "translatable"
This causes a <code>CsvSchema</code> to be created with
<code>flavor = TRANSLATABLE</code>,
and its <code>createTable</code> method creates instances of
-<a href="src/main/java/net/hydromatic/optiq/impl/csv/CsvSmartTable.java">CsvSmartTable</a>
+<a href="../example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvTranslatableTable.java">CsvTranslatableTable</a>
rather than a <code>CsvScannableTable</code>.
-<code>CsvSmartTable</code> overrides the
-<code><a href="http://www.hydromatic.net/calcite/apidocs/net/hydromatic/optiq/TranslatableTable#toRel()">TranslatableTable.toRel()</a></code>
+<code>CsvTranslatableTable</code> implements the
+<code><a href="http://www.hydromatic.net/calcite/apidocs/org/apache/calcite/schema/TranslatableTable.html#toRel()">TranslatableTable.toRel()</a></code>
method to create
-<a href="src/main/java/net/hydromatic/optiq/impl/csv/CsvTableScan.java">CsvTableScan</a>.
+<a href="../example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvTableScan.java">CsvTableScan</a>.
Table scans are the leaves of a query operator tree.
The usual implementation is
-<code><a href="http://www.hydromatic.net/calcite/apidocs/net/hydromatic/optiq/impl/java/JavaRules.EnumerableTableAccessRel.html">EnumerableTableAccessRel</a></code>,
+<code><a href="http://www.hydromatic.net/calcite/apidocs/org/apache/calcite/adapter/enumerable/EnumerableTableScan.html">EnumerableTableScan</a></code>,
but we have created a distinctive sub-type that will cause rules to fire.
Here is the rule in its entirety:
```java
-public class CsvPushProjectOntoTableRule extends RelOptRule {
- public static final CsvPushProjectOntoTableRule INSTANCE =
- new CsvPushProjectOntoTableRule();
+public class CsvProjectTableScanRule extends RelOptRule {
+ public static final CsvProjectTableScanRule INSTANCE =
+ new CsvProjectTableScanRule();
- private CsvPushProjectOntoTableRule() {
+ private CsvProjectTableScanRule() {
super(
- operand(ProjectRel.class,
+ operand(Project.class,
operand(CsvTableScan.class, none())),
- "CsvPushProjectOntoTableRule");
+ "CsvProjectTableScanRule");
}
@Override
public void onMatch(RelOptRuleCall call) {
- final ProjectRel project = call.rel(0);
+ final Project project = call.rel(0);
final CsvTableScan scan = call.rel(1);
int[] fields = getProjectFields(project.getProjects());
if (fields == null) {
@@ -537,7 +538,7 @@ The constructor declares the pattern of relational expressions that will cause
the rule to fire.
The <code>onMatch</code> method generates a new relational expression and calls
-<code><a href="http://www.hydromatic.net/calcite/apidocs/org/eigenbase/relopt/RelOptRuleCall.html#transformTo(org.eigenbase.rel.RelNode)">RelOptRuleCall.transformTo()</a></code>
+<code><a href="http://www.hydromatic.net/calcite/apidocs/org/apache/calcite/plan/RelOptRuleCall.html#transformTo(org.apache.calcite.rel.RelNode)">RelOptRuleCall.transformTo()</a></code>
to indicate that the rule has fired successfully.
## The query optimization process
@@ -589,7 +590,7 @@ For example, this schema reads from a MySQL "foodmart" database:
{
name: 'FOODMART',
type: 'custom',
- factory: 'net.hydromatic.optiq.impl.jdbc.JdbcSchema$Factory',
+ factory: 'org.apache.calcite.adapter.jdbc.JdbcSchema$Factory',
operand: {
jdbcDriver: 'com.mysql.jdbc.Driver',
jdbcUrl: 'jdbc:mysql://localhost/foodmart',
@@ -635,7 +636,7 @@ For example, the following model reads tables from a MySQL
{
name: 'FOODMART_CLONE',
type: 'custom',
- factory: 'net.hydromatic.optiq.impl.clone.CloneSchema$Factory',
+ factory: 'org.apache.calcite.adapter.clone.CloneSchema$Factory',
operand: {
jdbcDriver: 'com.mysql.jdbc.Driver',
jdbcUrl: 'jdbc:mysql://localhost/foodmart',
@@ -659,7 +660,7 @@ defined earlier in the model, like this:
{
name: 'FOODMART',
type: 'custom',
- factory: 'net.hydromatic.optiq.impl.jdbc.JdbcSchema$Factory',
+ factory: 'org.apache.calcite.adapter.jdbc.JdbcSchema$Factory',
operand: {
jdbcDriver: 'com.mysql.jdbc.Driver',
jdbcUrl: 'jdbc:mysql://localhost/foodmart',
@@ -670,7 +671,7 @@ defined earlier in the model, like this:
{
name: 'FOODMART_CLONE',
type: 'custom',
- factory: 'net.hydromatic.optiq.impl.clone.CloneSchema$Factory',
+ factory: 'org.apache.calcite.adapter.clone.CloneSchema$Factory',
operand: {
source: 'FOODMART'
}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/b66ff933/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvSchema.java
----------------------------------------------------------------------
diff --git a/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvSchema.java b/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvSchema.java
index f4e6a5d..521987b 100644
--- a/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvSchema.java
+++ b/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvSchema.java
@@ -90,25 +90,25 @@ public class CsvSchema extends AbstractSchema {
}
tableName = trim(tableName, ".csv");
- // Create different sub-types of table based on the "flavor" attribute.
- final Table table;
- switch (flavor) {
- case TRANSLATABLE:
- table = new CsvTranslatableTable(file, null);
- break;
- case SCANNABLE:
- table = new CsvScannableTable(file, null);
- break;
- case FILTERABLE:
- table = new CsvFilterableTable(file, null);
- break;
- default:
- throw new AssertionError("Unknown flavor " + flavor);
- }
+ final Table table = createTable(file);
builder.put(tableName, table);
}
return builder.build();
}
+
+ /** Creates different sub-type of table based on the "flavor" attribute. */
+ private Table createTable(File file) {
+ switch (flavor) {
+ case TRANSLATABLE:
+ return new CsvTranslatableTable(file, null);
+ case SCANNABLE:
+ return new CsvScannableTable(file, null);
+ case FILTERABLE:
+ return new CsvFilterableTable(file, null);
+ default:
+ throw new AssertionError("Unknown flavor " + flavor);
+ }
+ }
}
// End CsvSchema.java