Use Optiq's new "model" connect-string parameter to pass in a JSON model for the DONUTS schema. It just contains one table with one column. (Now we can remove hackery in the driver doing a similar thing.)
Signed-off-by: Jacques Nadeau <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/incubator-drill/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-drill/commit/6a0cf9c3 Tree: http://git-wip-us.apache.org/repos/asf/incubator-drill/tree/6a0cf9c3 Diff: http://git-wip-us.apache.org/repos/asf/incubator-drill/diff/6a0cf9c3 Branch: refs/heads/execwork Commit: 6a0cf9c310fb0e0ed85596bf44f4ce5ebcd2871c Parents: 7c292dd Author: Julian Hyde <[email protected]> Authored: Mon Mar 4 20:43:00 2013 -0800 Committer: Jacques Nadeau <[email protected]> Committed: Thu Jun 6 11:06:42 2013 -0700 ---------------------------------------------------------------------- .../java/org/apache/drill/jdbc/DrillTable.java | 44 ++++++++++--- .../main/java/org/apache/drill/jdbc/Driver.java | 48 ++++---------- .../java/org/apache/drill/jdbc/test/JdbcTest.java | 38 +++++++++-- 3 files changed, 78 insertions(+), 52 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/6a0cf9c3/sandbox/prototype/sqlparser/src/main/java/org/apache/drill/jdbc/DrillTable.java ---------------------------------------------------------------------- diff --git a/sandbox/prototype/sqlparser/src/main/java/org/apache/drill/jdbc/DrillTable.java b/sandbox/prototype/sqlparser/src/main/java/org/apache/drill/jdbc/DrillTable.java index cb0512d..e98cfaa 100644 --- a/sandbox/prototype/sqlparser/src/main/java/org/apache/drill/jdbc/DrillTable.java +++ b/sandbox/prototype/sqlparser/src/main/java/org/apache/drill/jdbc/DrillTable.java @@ -26,16 +26,17 @@ import net.hydromatic.linq4j.Linq4j; import net.hydromatic.linq4j.expressions.Expression; import net.hydromatic.linq4j.expressions.Expressions; import net.hydromatic.linq4j.expressions.MethodCallExpression; -import net.hydromatic.optiq.BuiltinMethod; -import net.hydromatic.optiq.DataContext; -import net.hydromatic.optiq.MutableSchema; -import net.hydromatic.optiq.Schema; -import net.hydromatic.optiq.TranslatableTable; + +import net.hydromatic.optiq.*; +import net.hydromatic.optiq.impl.java.JavaTypeFactory; import org.apache.drill.common.logical.StorageEngineConfig; +import org.apache.drill.exec.ref.rops.DataWriter; +import org.apache.drill.exec.ref.rse.ClasspathRSE; import org.apache.drill.exec.ref.rse.ClasspathRSE.ClasspathInputConfig; import org.apache.drill.optiq.DrillOptiq; import org.apache.drill.optiq.DrillScan; + import org.eigenbase.rel.RelNode; import org.eigenbase.relopt.RelOptTable; import org.eigenbase.reltype.RelDataType; @@ -68,8 +69,12 @@ public class DrillTable extends BaseQueryable<Object> this.selection = selection; } - static void addTable(RelDataTypeFactory typeFactory, MutableSchema schema, - String name, StorageEngineConfig storageEngineConfig, Object selection) { + private static DrillTable createTable( + RelDataTypeFactory typeFactory, + MutableSchema schema, + String name, + StorageEngineConfig storageEngineConfig, + Object selection) { final MethodCallExpression call = Expressions.call(schema.getExpression(), BuiltinMethod.DATA_CONTEXT_GET_TABLE.method, Expressions.constant(name), @@ -81,10 +86,8 @@ public class DrillTable extends BaseQueryable<Object> typeFactory.createSqlType(SqlTypeName.VARCHAR), typeFactory.createSqlType(SqlTypeName.ANY))), Collections.singletonList("_MAP")); - final DrillTable table = - new DrillTable(schema, Object.class, call, rowType, name, - storageEngineConfig, selection); - schema.addTable(name, table); + return new DrillTable(schema, Object.class, call, rowType, name, + storageEngineConfig, selection); } @Override @@ -107,6 +110,25 @@ public class DrillTable extends BaseQueryable<Object> context.getCluster().traitSetOf(DrillOptiq.CONVENTION), table); } + + /** Factory for custom tables in Optiq schema. */ + @SuppressWarnings("UnusedDeclaration") + public static class Factory implements TableFactory<DrillTable> { + public DrillTable create( + JavaTypeFactory typeFactory, + Schema schema, + String name, + Object operand, + RelDataType rowType) { + final ClasspathRSE.ClasspathRSEConfig rseConfig = + new ClasspathRSE.ClasspathRSEConfig("donuts-json"); + final ClasspathInputConfig inputConfig = new ClasspathInputConfig(); + inputConfig.path = "/donuts.json"; + inputConfig.type = DataWriter.ConverterType.JSON; + return createTable(typeFactory, (MutableSchema) schema, name, rseConfig, + inputConfig); + } + } } // End DrillTable.java http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/6a0cf9c3/sandbox/prototype/sqlparser/src/main/java/org/apache/drill/jdbc/Driver.java ---------------------------------------------------------------------- diff --git a/sandbox/prototype/sqlparser/src/main/java/org/apache/drill/jdbc/Driver.java b/sandbox/prototype/sqlparser/src/main/java/org/apache/drill/jdbc/Driver.java index 0a0594c..1155f31 100644 --- a/sandbox/prototype/sqlparser/src/main/java/org/apache/drill/jdbc/Driver.java +++ b/sandbox/prototype/sqlparser/src/main/java/org/apache/drill/jdbc/Driver.java @@ -17,20 +17,15 @@ ******************************************************************************/ package org.apache.drill.jdbc; +import java.io.IOException; import java.sql.SQLException; -import java.util.Collections; -import net.hydromatic.optiq.MutableSchema; -import net.hydromatic.optiq.impl.java.MapSchema; import net.hydromatic.optiq.jdbc.DriverVersion; import net.hydromatic.optiq.jdbc.Handler; import net.hydromatic.optiq.jdbc.HandlerImpl; import net.hydromatic.optiq.jdbc.OptiqConnection; import net.hydromatic.optiq.jdbc.UnregisteredDriver; - -import org.apache.drill.exec.ref.rops.DataWriter.ConverterType; -import org.apache.drill.exec.ref.rse.ClasspathRSE.ClasspathInputConfig; -import org.apache.drill.exec.ref.rse.ClasspathRSE.ClasspathRSEConfig; +import net.hydromatic.optiq.model.ModelHandler; /** * JDBC driver for Apache Drill. @@ -61,36 +56,21 @@ public class Driver extends UnregisteredDriver { { super.onConnectionInit(connection); + final String model = connection.getProperties().getProperty("model"); + if (model != null) { + try { + new ModelHandler(connection, model); + } catch (IOException e) { + throw new SQLException(e); + } + } + // The "schema" parameter currently gives a name to the schema. In future // it will choose a schema that (presumably) already exists. final String schemaName = connection.getProperties().getProperty("schema"); - if (schemaName == null) { - throw new SQLException("schema connection property must be specified"); - } - final MutableSchema rootSchema = connection.getRootSchema(); - final MapSchema schema = - MapSchema.create(connection, rootSchema, schemaName); - - connection.setSchema(schemaName); - final ClasspathRSEConfig rseConfig = new ClasspathRSEConfig("donuts-json"); - final ClasspathInputConfig inputConfig = new ClasspathInputConfig(); - inputConfig.path = "/donuts.json"; - inputConfig.type = ConverterType.JSON; - - - - // "tables" is a temporary parameter. We should replace with - // "schemaUri", which is the URI of a schema.json file, or the name of a - // schema from a server, if drill is running in a server. - final String tables = connection.getProperties().getProperty("tables"); - if (tables == null) { - throw new SQLException("tables connection property must be specified"); - } - final String[] tables2 = tables.split(","); - for (String table : tables2) { - DrillTable.addTable(connection.getTypeFactory(), schema, table, - rseConfig, inputConfig); + if (schemaName != null) { + connection.setSchema(schemaName); } } } @@ -102,7 +82,7 @@ optiq work 1. todo: test can cast(<any> as varchar) (or indeed to any type) -2. We declare a variant record by adding a '_extra any' field. It's nice that +2. We declare a variant record by adding a '_MAP any' field. It's nice that there can be some declared fields, and some undeclared. todo: Better syntactic sugar. http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/6a0cf9c3/sandbox/prototype/sqlparser/src/test/java/org/apache/drill/jdbc/test/JdbcTest.java ---------------------------------------------------------------------- diff --git a/sandbox/prototype/sqlparser/src/test/java/org/apache/drill/jdbc/test/JdbcTest.java b/sandbox/prototype/sqlparser/src/test/java/org/apache/drill/jdbc/test/JdbcTest.java index 24aa707..206d6f6 100644 --- a/sandbox/prototype/sqlparser/src/test/java/org/apache/drill/jdbc/test/JdbcTest.java +++ b/sandbox/prototype/sqlparser/src/test/java/org/apache/drill/jdbc/test/JdbcTest.java @@ -18,11 +18,30 @@ package org.apache.drill.jdbc.test; import junit.framework.TestCase; +import org.apache.drill.jdbc.DrillTable; import java.sql.*; +import java.util.Properties; /** Unit tests for Drill's JDBC driver. */ public class JdbcTest extends TestCase { + private static final String MODEL = + "{\n" + + " version: '1.0',\n" + + " schemas: [\n" + + " {\n" + + " name: 'DONUTS',\n" + + " tables: [\n" + + " {\n" + + " name: 'DONUTS',\n" + + " type: 'custom',\n" + + " factory: '" + DrillTable.Factory.class.getName() + "'\n" + + " }\n" + + " ]\n" + + " }\n" + + " ]\n" + + "}"; + private static final String EXPECTED = "_MAP={donuts={batters={batter=[{id=1001, type=Regular}, {id=1002, type=Chocolate}, {id=1003, type=Blueberry}, {id=1004, type=Devil's Food}]}, id=0001, name=Cake, ppu=0.55, sales=35, topping=[{id=5001, type=None}, {id=5002, type=Glazed}, {id=5005, type=Sugar}, {id=5007, type=Powdered Sugar}, {id=5006, type=Chocolate with Sprinkles}, {id=5003, type=Chocolate}, {id=5004, type=Maple}], type=donut}}\n" + "_MAP={donuts={batters={batter=[{id=1001, type=Regular}]}, id=0002, name=Raised, ppu=0.69, sales=145, topping=[{id=5001, type=None}, {id=5002, type=Glazed}, {id=5005, type=Sugar}, {id=5003, type=Chocolate}, {id=5004, type=Maple}], type=donut}}\n" @@ -57,8 +76,11 @@ public class JdbcTest extends TestCase { /** Simple query against JSON. */ public void testSelectJson() throws Exception { Class.forName("org.apache.drill.jdbc.Driver"); - final Connection connection = DriverManager.getConnection( - "jdbc:drill:schema=DONUTS;tables=DONUTS"); + final Properties info = new Properties(); + info.setProperty("schema", "DONUTS"); + info.setProperty("model", "inline:" + MODEL); + final Connection connection = + DriverManager.getConnection("jdbc:drill:", info); final Statement statement = connection.createStatement(); final ResultSet resultSet = statement.executeQuery( "select * from donuts"); @@ -125,12 +147,14 @@ public class JdbcTest extends TestCase { EXPECTED); } - private void assertSqlReturns(String sql, - String expected) throws ClassNotFoundException, SQLException - { + private void assertSqlReturns(String sql, String expected) + throws ClassNotFoundException, SQLException { Class.forName("org.apache.drill.jdbc.Driver"); - final Connection connection = DriverManager.getConnection( - "jdbc:drill:schema=DONUTS;tables=DONUTS"); + final Properties info = new Properties(); + info.setProperty("schema", "DONUTS"); + info.setProperty("model", "inline:" + MODEL); + final Connection connection = + DriverManager.getConnection("jdbc:drill:", info); try (Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(sql)) { assertEquals(expected, toString(resultSet));
