http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/core/src/main/java/org/apache/calcite/adapter/enumerable/impl/package-info.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/impl/package-info.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/impl/package-info.java deleted file mode 100644 index b1b2aad..0000000 --- a/core/src/main/java/org/apache/calcite/adapter/enumerable/impl/package-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Calcite-specific classes for implementation of regular and window aggregates. - */ -@PackageMarker -package org.apache.calcite.adapter.enumerable.impl; - -import org.apache.calcite.avatica.util.PackageMarker; - -// End package-info.java
http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/core/src/main/java/org/apache/calcite/adapter/enumerable/package-info.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/package-info.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/package-info.java deleted file mode 100644 index 5d29f8b..0000000 --- a/core/src/main/java/org/apache/calcite/adapter/enumerable/package-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Query optimizer rules for Java calling convention. - */ -@PackageMarker -package org.apache.calcite.adapter.enumerable; - -import org.apache.calcite.avatica.util.PackageMarker; - -// End package-info.java http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/core/src/main/java/org/apache/calcite/adapter/java/AbstractQueryableTable.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/adapter/java/AbstractQueryableTable.java b/core/src/main/java/org/apache/calcite/adapter/java/AbstractQueryableTable.java deleted file mode 100644 index 5cb7b82..0000000 --- a/core/src/main/java/org/apache/calcite/adapter/java/AbstractQueryableTable.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.calcite.adapter.java; - -import org.apache.calcite.linq4j.tree.Expression; -import org.apache.calcite.schema.QueryableTable; -import org.apache.calcite.schema.SchemaPlus; -import org.apache.calcite.schema.Schemas; -import org.apache.calcite.schema.impl.AbstractTable; - -import java.lang.reflect.Type; - -/** - * Abstract base class for implementing {@link org.apache.calcite.schema.Table}. - */ -public abstract class AbstractQueryableTable extends AbstractTable - implements QueryableTable { - protected final Type elementType; - - protected AbstractQueryableTable(Type elementType) { - super(); - this.elementType = elementType; - } - - public Type getElementType() { - return elementType; - } - - public Expression getExpression(SchemaPlus schema, String tableName, - Class clazz) { - return Schemas.tableExpression(schema, elementType, tableName, clazz); - } -} - -// End AbstractQueryableTable.java http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/core/src/main/java/org/apache/calcite/adapter/java/Array.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/adapter/java/Array.java b/core/src/main/java/org/apache/calcite/adapter/java/Array.java deleted file mode 100644 index 07b75b6..0000000 --- a/core/src/main/java/org/apache/calcite/adapter/java/Array.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.calcite.adapter.java; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import static java.lang.annotation.ElementType.FIELD; - -/** - * Annotation that indicates that a field is an array type. - */ -@Target({FIELD }) -@Retention(RetentionPolicy.RUNTIME) -public @interface Array { - /** Component type. */ - Class component(); - - /** Whether components may be null. */ - boolean componentIsNullable() default false; - - /** Maximum number of elements in the array. -1 means no maximum. */ - long maximumCardinality() default -1L; -} - -// End Array.java http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/core/src/main/java/org/apache/calcite/adapter/java/JavaTypeFactory.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/adapter/java/JavaTypeFactory.java b/core/src/main/java/org/apache/calcite/adapter/java/JavaTypeFactory.java deleted file mode 100644 index 205b391..0000000 --- a/core/src/main/java/org/apache/calcite/adapter/java/JavaTypeFactory.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.calcite.adapter.java; - -import org.apache.calcite.rel.type.RelDataType; -import org.apache.calcite.rel.type.RelDataTypeFactory; - -import java.lang.reflect.Type; -import java.util.List; - -/** - * Type factory that can register Java classes as record types. - */ -public interface JavaTypeFactory extends RelDataTypeFactory { - /** - * Creates a record type based upon the public fields of a Java class. - * - * @param clazz Java class - * @return Record type that remembers its Java class - */ - RelDataType createStructType(Class clazz); - - /** - * Creates a type, deducing whether a record, scalar or primitive type - * is needed. - * - * @param type Java type, such as a {@link Class} - * @return Record or scalar type - */ - RelDataType createType(Type type); - - Type getJavaClass(RelDataType type); - - /** Creates a synthetic Java class whose fields have the given Java - * types. */ - Type createSyntheticType(List<Type> types); - - /** Converts a type in Java format to a SQL-oriented type. */ - RelDataType toSql(RelDataType type); -} - -// End JavaTypeFactory.java http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/core/src/main/java/org/apache/calcite/adapter/java/Map.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/adapter/java/Map.java b/core/src/main/java/org/apache/calcite/adapter/java/Map.java deleted file mode 100644 index 10bfa57..0000000 --- a/core/src/main/java/org/apache/calcite/adapter/java/Map.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.calcite.adapter.java; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import static java.lang.annotation.ElementType.FIELD; - -/** - * Annotation that indicates that a field is a map type. - */ -@Target({FIELD }) -@Retention(RetentionPolicy.RUNTIME) -public @interface Map { - /** Key type. */ - Class key(); - - /** Value type. */ - Class value(); - - /** Whether keys may be null. */ - boolean keyIsNullable() default true; - - /** Whether values may be null. */ - boolean valueIsNullable() default true; -} - -// End Map.java http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/core/src/main/java/org/apache/calcite/adapter/java/ReflectiveSchema.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/adapter/java/ReflectiveSchema.java b/core/src/main/java/org/apache/calcite/adapter/java/ReflectiveSchema.java deleted file mode 100644 index 91fe3e7..0000000 --- a/core/src/main/java/org/apache/calcite/adapter/java/ReflectiveSchema.java +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.calcite.adapter.java; - -import org.apache.calcite.DataContext; -import org.apache.calcite.linq4j.Enumerable; -import org.apache.calcite.linq4j.Enumerator; -import org.apache.calcite.linq4j.Linq4j; -import org.apache.calcite.linq4j.QueryProvider; -import org.apache.calcite.linq4j.Queryable; -import org.apache.calcite.linq4j.function.Function1; -import org.apache.calcite.linq4j.tree.Expression; -import org.apache.calcite.linq4j.tree.Expressions; -import org.apache.calcite.linq4j.tree.Primitive; -import org.apache.calcite.linq4j.tree.Types; -import org.apache.calcite.rel.type.RelDataType; -import org.apache.calcite.rel.type.RelDataTypeFactory; -import org.apache.calcite.schema.Function; -import org.apache.calcite.schema.ScannableTable; -import org.apache.calcite.schema.Schema; -import org.apache.calcite.schema.SchemaFactory; -import org.apache.calcite.schema.SchemaPlus; -import org.apache.calcite.schema.Schemas; -import org.apache.calcite.schema.Statistic; -import org.apache.calcite.schema.Statistics; -import org.apache.calcite.schema.Table; -import org.apache.calcite.schema.TableMacro; -import org.apache.calcite.schema.TranslatableTable; -import org.apache.calcite.schema.impl.AbstractSchema; -import org.apache.calcite.schema.impl.AbstractTableQueryable; -import org.apache.calcite.schema.impl.ReflectiveFunctionBase; -import org.apache.calcite.util.BuiltInMethod; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.Multimap; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Type; -import java.util.List; -import java.util.Map; - -/** - * Implementation of {@link org.apache.calcite.schema.Schema} that exposes the - * public fields and methods in a Java object. - */ -public class ReflectiveSchema - extends AbstractSchema { - private final Class clazz; - private Object target; - - /** - * Creates a ReflectiveSchema. - * - * @param target Object whose fields will be sub-objects of the schema - */ - public ReflectiveSchema(Object target) { - super(); - this.clazz = target.getClass(); - this.target = target; - } - - @Override public String toString() { - return "ReflectiveSchema(target=" + target + ")"; - } - - /** Returns the wrapped object. - * - * <p>May not appear to be used, but is used in generated code via - * {@link org.apache.calcite.util.BuiltInMethod#REFLECTIVE_SCHEMA_GET_TARGET}. - */ - public Object getTarget() { - return target; - } - - @Override protected Map<String, Table> getTableMap() { - final ImmutableMap.Builder<String, Table> builder = ImmutableMap.builder(); - for (Field field : clazz.getFields()) { - final String fieldName = field.getName(); - final Table table = fieldRelation(field); - if (table == null) { - continue; - } - builder.put(fieldName, table); - } - return builder.build(); - } - - @Override protected Multimap<String, Function> getFunctionMultimap() { - final ImmutableMultimap.Builder<String, Function> builder = - ImmutableMultimap.builder(); - for (Method method : clazz.getMethods()) { - final String methodName = method.getName(); - if (method.getDeclaringClass() == Object.class - || methodName.equals("toString")) { - continue; - } - if (TranslatableTable.class.isAssignableFrom(method.getReturnType())) { - final TableMacro tableMacro = - new MethodTableMacro(this, method); - builder.put(methodName, tableMacro); - } - } - return builder.build(); - } - - /** Returns an expression for the object wrapped by this schema (not the - * schema itself). */ - Expression getTargetExpression(SchemaPlus parentSchema, String name) { - return Types.castIfNecessary( - target.getClass(), - Expressions.call( - Schemas.unwrap( - getExpression(parentSchema, name), - ReflectiveSchema.class), - BuiltInMethod.REFLECTIVE_SCHEMA_GET_TARGET.method)); - } - - /** Returns a table based on a particular field of this schema. If the - * field is not of the right type to be a relation, returns null. */ - private <T> Table fieldRelation(final Field field) { - final Type elementType = getElementType(field.getType()); - if (elementType == null) { - return null; - } - Object o; - try { - o = field.get(target); - } catch (IllegalAccessException e) { - throw new RuntimeException( - "Error while accessing field " + field, e); - } - @SuppressWarnings("unchecked") - final Enumerable<T> enumerable = toEnumerable(o); - return new FieldTable<>(field, elementType, enumerable); - } - - /** Deduces the element type of a collection; - * same logic as {@link #toEnumerable} */ - private static Type getElementType(Class clazz) { - if (clazz.isArray()) { - return clazz.getComponentType(); - } - if (Iterable.class.isAssignableFrom(clazz)) { - return Object.class; - } - return null; // not a collection/array/iterable - } - - private static Enumerable toEnumerable(final Object o) { - if (o.getClass().isArray()) { - if (o instanceof Object[]) { - return Linq4j.asEnumerable((Object[]) o); - } else { - return Linq4j.asEnumerable(Primitive.asList(o)); - } - } - if (o instanceof Iterable) { - return Linq4j.asEnumerable((Iterable) o); - } - throw new RuntimeException( - "Cannot convert " + o.getClass() + " into a Enumerable"); - } - - /** Table that is implemented by reading from a Java object. */ - private static class ReflectiveTable - extends AbstractQueryableTable - implements Table, ScannableTable { - private final Type elementType; - private final Enumerable enumerable; - - ReflectiveTable(Type elementType, Enumerable enumerable) { - super(elementType); - this.elementType = elementType; - this.enumerable = enumerable; - } - - public RelDataType getRowType(RelDataTypeFactory typeFactory) { - return ((JavaTypeFactory) typeFactory).createType(elementType); - } - - public Statistic getStatistic() { - return Statistics.UNKNOWN; - } - - public Enumerable<Object[]> scan(DataContext root) { - if (elementType == Object[].class) { - //noinspection unchecked - return enumerable; - } else { - //noinspection unchecked - return enumerable.select(new FieldSelector((Class) elementType)); - } - } - - public <T> Queryable<T> asQueryable(QueryProvider queryProvider, - SchemaPlus schema, String tableName) { - return new AbstractTableQueryable<T>(queryProvider, schema, this, - tableName) { - @SuppressWarnings("unchecked") - public Enumerator<T> enumerator() { - return (Enumerator<T>) enumerable.enumerator(); - } - }; - } - } - - /** Factory that creates a schema by instantiating an object and looking at - * its public fields. - * - * <p>The following example instantiates a {@code FoodMart} object as a schema - * that contains tables called {@code EMPS} and {@code DEPTS} based on the - * object's fields.</p> - * - * <pre> - * {@code schemas: [ - * { - * name: "foodmart", - * type: "custom", - * factory: "org.apache.calcite.adapter.java.ReflectiveSchema$Factory", - * operand: { - * class: "com.acme.FoodMart", - * staticMethod: "instance" - * } - * } - * ] - * - * class FoodMart { - * public static final FoodMart instance() { - * return new FoodMart(); - * } - * - * Employee[] EMPS; - * Department[] DEPTS; - * } - * }</pre> - * */ - public static class Factory implements SchemaFactory { - public Schema create(SchemaPlus parentSchema, String name, - Map<String, Object> operand) { - Class<?> clazz; - Object target; - final Object className = operand.get("class"); - if (className != null) { - try { - clazz = Class.forName((String) className); - } catch (ClassNotFoundException e) { - throw new RuntimeException("Error loading class " + className, e); - } - } else { - throw new RuntimeException("Operand 'class' is required"); - } - final Object methodName = operand.get("staticMethod"); - if (methodName != null) { - try { - //noinspection unchecked - Method method = clazz.getMethod((String) methodName); - target = method.invoke(null); - } catch (Exception e) { - throw new RuntimeException("Error invoking method " + methodName, e); - } - } else { - try { - final Constructor<?> constructor = clazz.getConstructor(); - target = constructor.newInstance(); - } catch (Exception e) { - throw new RuntimeException("Error instantiating class " + className, - e); - } - } - return new ReflectiveSchema(target); - } - } - - /** Table macro based on a Java method. */ - private static class MethodTableMacro extends ReflectiveFunctionBase - implements TableMacro { - private final ReflectiveSchema schema; - - MethodTableMacro(ReflectiveSchema schema, Method method) { - super(method); - this.schema = schema; - assert TranslatableTable.class.isAssignableFrom(method.getReturnType()) - : "Method should return TranslatableTable so the macro can be " - + "expanded"; - } - - public String toString() { - return "Member {method=" + method + "}"; - } - - public TranslatableTable apply(final List<Object> arguments) { - try { - final Object o = method.invoke(schema.getTarget(), arguments.toArray()); - return (TranslatableTable) o; - } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); - } - } - } - - /** Table based on a Java field. */ - private static class FieldTable<T> extends ReflectiveTable { - private final Field field; - - FieldTable(Field field, Type elementType, Enumerable<T> enumerable) { - super(elementType, enumerable); - this.field = field; - } - - public String toString() { - return "Relation {field=" + field.getName() + "}"; - } - - @Override public Expression getExpression(SchemaPlus schema, - String tableName, Class clazz) { - return Expressions.field( - schema.unwrap(ReflectiveSchema.class).getTargetExpression( - schema.getParentSchema(), schema.getName()), field); - } - } - - /** Function that returns an array of a given object's field values. */ - private static class FieldSelector implements Function1<Object, Object[]> { - private final Field[] fields; - - FieldSelector(Class elementType) { - this.fields = elementType.getFields(); - } - - public Object[] apply(Object o) { - try { - final Object[] objects = new Object[fields.length]; - for (int i = 0; i < fields.length; i++) { - objects[i] = fields[i].get(o); - } - return objects; - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } - } -} - -// End ReflectiveSchema.java http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/core/src/main/java/org/apache/calcite/adapter/java/package-info.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/adapter/java/package-info.java b/core/src/main/java/org/apache/calcite/adapter/java/package-info.java deleted file mode 100644 index 58da953..0000000 --- a/core/src/main/java/org/apache/calcite/adapter/java/package-info.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Query provider based on Java in-memory data - * structures. - */ -@PackageMarker -package org.apache.calcite.adapter.java; - -import org.apache.calcite.avatica.util.PackageMarker; - -// End package-info.java http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcConvention.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcConvention.java b/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcConvention.java deleted file mode 100644 index 670c6cd..0000000 --- a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcConvention.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.calcite.adapter.jdbc; - -import org.apache.calcite.linq4j.tree.Expression; -import org.apache.calcite.plan.Convention; -import org.apache.calcite.plan.RelOptPlanner; -import org.apache.calcite.plan.RelOptRule; -import org.apache.calcite.rel.rules.FilterSetOpTransposeRule; -import org.apache.calcite.rel.rules.ProjectRemoveRule; -import org.apache.calcite.sql.SqlDialect; - -/** - * Calling convention for relational operations that occur in a JDBC - * database. - * - * <p>The convention is a slight misnomer. The operations occur in whatever - * data-flow architecture the database uses internally. Nevertheless, the result - * pops out in JDBC.</p> - * - * <p>This is the only convention, thus far, that is not a singleton. Each - * instance contains a JDBC schema (and therefore a data source). If Calcite is - * working with two different databases, it would even make sense to convert - * from "JDBC#A" convention to "JDBC#B", even though we don't do it currently. - * (That would involve asking database B to open a database link to database - * A.)</p> - * - * <p>As a result, converter rules from and two this convention need to be - * instantiated, at the start of planning, for each JDBC database in play.</p> - */ -public class JdbcConvention extends Convention.Impl { - /** Cost of a JDBC node versus implementing an equivalent node in a "typical" - * calling convention. */ - public static final double COST_MULTIPLIER = 0.8d; - - public final SqlDialect dialect; - public final Expression expression; - - public JdbcConvention(SqlDialect dialect, Expression expression, - String name) { - super("JDBC." + name, JdbcRel.class); - this.dialect = dialect; - this.expression = expression; - } - - public static JdbcConvention of(SqlDialect dialect, Expression expression, - String name) { - return new JdbcConvention(dialect, expression, name); - } - - @Override public void register(RelOptPlanner planner) { - for (RelOptRule rule : JdbcRules.rules(this)) { - planner.addRule(rule); - } - planner.addRule(FilterSetOpTransposeRule.INSTANCE); - planner.addRule(ProjectRemoveRule.INSTANCE); - } -} - -// End JdbcConvention.java http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcImplementor.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcImplementor.java b/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcImplementor.java deleted file mode 100644 index 79ec62f..0000000 --- a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcImplementor.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.calcite.adapter.jdbc; - -import org.apache.calcite.adapter.java.JavaTypeFactory; -import org.apache.calcite.rel.RelNode; -import org.apache.calcite.rel.rel2sql.RelToSqlConverter; -import org.apache.calcite.sql.SqlDialect; -import org.apache.calcite.util.Util; - -import com.google.common.collect.ImmutableList; - -/** - * State for generating a SQL statement. - */ -public class JdbcImplementor extends RelToSqlConverter { - public JdbcImplementor(SqlDialect dialect, JavaTypeFactory typeFactory) { - super(dialect); - Util.discard(typeFactory); - } - - /** @see #dispatch */ - public Result visit(JdbcTableScan scan) { - return result(scan.jdbcTable.tableName(), - ImmutableList.of(Clause.FROM), scan, null); - } - - public Result implement(RelNode node) { - return dispatch(node); - } -} - -// End JdbcImplementor.java http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcQueryProvider.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcQueryProvider.java b/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcQueryProvider.java deleted file mode 100644 index 14c9282..0000000 --- a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcQueryProvider.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.calcite.adapter.jdbc; - -import org.apache.calcite.linq4j.Enumerator; -import org.apache.calcite.linq4j.QueryProvider; -import org.apache.calcite.linq4j.QueryProviderImpl; -import org.apache.calcite.linq4j.Queryable; - -/** - * Implementation of {@link QueryProvider} that talks to JDBC databases. - */ -public final class JdbcQueryProvider extends QueryProviderImpl { - public static final JdbcQueryProvider INSTANCE = new JdbcQueryProvider(); - - private JdbcQueryProvider() { - } - - public <T> Enumerator<T> executeQuery(Queryable<T> queryable) { - return null; - } -} - -// End JdbcQueryProvider.java http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRel.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRel.java b/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRel.java deleted file mode 100644 index ba91d1b..0000000 --- a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRel.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.calcite.adapter.jdbc; - -import org.apache.calcite.rel.RelNode; - -/** - * Relational expression that uses JDBC calling convention. - */ -public interface JdbcRel extends RelNode { - JdbcImplementor.Result implement(JdbcImplementor implementor); -} - -// End JdbcRel.java http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRules.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRules.java b/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRules.java deleted file mode 100644 index 885ff0c..0000000 --- a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRules.java +++ /dev/null @@ -1,813 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.calcite.adapter.jdbc; - -import org.apache.calcite.linq4j.Queryable; -import org.apache.calcite.linq4j.tree.Expression; -import org.apache.calcite.plan.Convention; -import org.apache.calcite.plan.RelOptCluster; -import org.apache.calcite.plan.RelOptCost; -import org.apache.calcite.plan.RelOptPlanner; -import org.apache.calcite.plan.RelOptRule; -import org.apache.calcite.plan.RelOptTable; -import org.apache.calcite.plan.RelTrait; -import org.apache.calcite.plan.RelTraitSet; -import org.apache.calcite.prepare.Prepare; -import org.apache.calcite.rel.InvalidRelException; -import org.apache.calcite.rel.RelCollation; -import org.apache.calcite.rel.RelNode; -import org.apache.calcite.rel.RelWriter; -import org.apache.calcite.rel.SingleRel; -import org.apache.calcite.rel.convert.ConverterRule; -import org.apache.calcite.rel.core.Aggregate; -import org.apache.calcite.rel.core.AggregateCall; -import org.apache.calcite.rel.core.CorrelationId; -import org.apache.calcite.rel.core.Filter; -import org.apache.calcite.rel.core.Intersect; -import org.apache.calcite.rel.core.Join; -import org.apache.calcite.rel.core.JoinRelType; -import org.apache.calcite.rel.core.Minus; -import org.apache.calcite.rel.core.Project; -import org.apache.calcite.rel.core.Sort; -import org.apache.calcite.rel.core.TableModify; -import org.apache.calcite.rel.core.Union; -import org.apache.calcite.rel.core.Values; -import org.apache.calcite.rel.logical.LogicalAggregate; -import org.apache.calcite.rel.logical.LogicalCalc; -import org.apache.calcite.rel.logical.LogicalFilter; -import org.apache.calcite.rel.logical.LogicalIntersect; -import org.apache.calcite.rel.logical.LogicalJoin; -import org.apache.calcite.rel.logical.LogicalMinus; -import org.apache.calcite.rel.logical.LogicalProject; -import org.apache.calcite.rel.logical.LogicalTableModify; -import org.apache.calcite.rel.logical.LogicalUnion; -import org.apache.calcite.rel.logical.LogicalValues; -import org.apache.calcite.rel.metadata.RelMdUtil; -import org.apache.calcite.rel.metadata.RelMetadataQuery; -import org.apache.calcite.rel.rel2sql.SqlImplementor; -import org.apache.calcite.rel.type.RelDataType; -import org.apache.calcite.rex.RexCall; -import org.apache.calcite.rex.RexInputRef; -import org.apache.calcite.rex.RexLiteral; -import org.apache.calcite.rex.RexMultisetUtil; -import org.apache.calcite.rex.RexNode; -import org.apache.calcite.rex.RexProgram; -import org.apache.calcite.schema.ModifiableTable; -import org.apache.calcite.sql.SqlAggFunction; -import org.apache.calcite.sql.SqlDialect; -import org.apache.calcite.sql.SqlKind; -import org.apache.calcite.util.ImmutableBitSet; -import org.apache.calcite.util.Util; -import org.apache.calcite.util.trace.CalciteTrace; - -import com.google.common.collect.ImmutableList; - -import org.slf4j.Logger; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -/** - * Rules and relational operators for - * {@link JdbcConvention} - * calling convention. - */ -public class JdbcRules { - private JdbcRules() { - } - - protected static final Logger LOGGER = CalciteTrace.getPlannerTracer(); - - public static List<RelOptRule> rules(JdbcConvention out) { - return ImmutableList.<RelOptRule>of( - new JdbcToEnumerableConverterRule(out), - new JdbcJoinRule(out), - new JdbcCalcRule(out), - new JdbcProjectRule(out), - new JdbcFilterRule(out), - new JdbcAggregateRule(out), - new JdbcSortRule(out), - new JdbcUnionRule(out), - new JdbcIntersectRule(out), - new JdbcMinusRule(out), - new JdbcTableModificationRule(out), - new JdbcValuesRule(out)); - } - - static final ImmutableList<SqlKind> AGG_FUNCS; - static final ImmutableList<SqlKind> MYSQL_AGG_FUNCS; - - static { - ImmutableList.Builder<SqlKind> builder = ImmutableList.builder(); - builder.add(SqlKind.COUNT); - builder.add(SqlKind.SUM); - builder.add(SqlKind.SUM0); - builder.add(SqlKind.MIN); - builder.add(SqlKind.MAX); - AGG_FUNCS = builder.build(); - builder.add(SqlKind.SINGLE_VALUE); - MYSQL_AGG_FUNCS = builder.build(); - } - - /** Abstract base class for rule that converts to JDBC. */ - abstract static class JdbcConverterRule extends ConverterRule { - protected final JdbcConvention out; - - public JdbcConverterRule(Class<? extends RelNode> clazz, RelTrait in, - JdbcConvention out, String description) { - super(clazz, in, out, description); - this.out = out; - } - } - - /** Rule that converts a join to JDBC. */ - private static class JdbcJoinRule extends JdbcConverterRule { - private JdbcJoinRule(JdbcConvention out) { - super(LogicalJoin.class, Convention.NONE, out, "JdbcJoinRule"); - } - - @Override public RelNode convert(RelNode rel) { - LogicalJoin join = (LogicalJoin) rel; - final List<RelNode> newInputs = new ArrayList<>(); - for (RelNode input : join.getInputs()) { - if (!(input.getConvention() == getOutTrait())) { - input = - convert(input, - input.getTraitSet().replace(out)); - } - newInputs.add(input); - } - if (!canJoinOnCondition(join.getCondition())) { - return null; - } - try { - return new JdbcJoin( - join.getCluster(), - join.getTraitSet().replace(out), - newInputs.get(0), - newInputs.get(1), - join.getCondition(), - join.getVariablesSet(), - join.getJoinType()); - } catch (InvalidRelException e) { - LOGGER.debug(e.toString()); - return null; - } - } - - /** - * Returns whether a condition is supported by {@link JdbcJoin}. - * - * <p>Corresponds to the capabilities of - * {@link SqlImplementor#convertConditionToSqlNode}. - * - * @param node Condition - * @return Whether condition is supported - */ - private boolean canJoinOnCondition(RexNode node) { - final List<RexNode> operands; - switch (node.getKind()) { - case AND: - case OR: - operands = ((RexCall) node).getOperands(); - for (RexNode operand : operands) { - if (!canJoinOnCondition(operand)) { - return false; - } - } - return true; - - case EQUALS: - case IS_NOT_DISTINCT_FROM: - case NOT_EQUALS: - case GREATER_THAN: - case GREATER_THAN_OR_EQUAL: - case LESS_THAN: - case LESS_THAN_OR_EQUAL: - operands = ((RexCall) node).getOperands(); - if ((operands.get(0) instanceof RexInputRef) - && (operands.get(1) instanceof RexInputRef)) { - return true; - } - // fall through - - default: - return false; - } - } - } - - /** Join operator implemented in JDBC convention. */ - public static class JdbcJoin extends Join implements JdbcRel { - /** Creates a JdbcJoin. */ - protected JdbcJoin(RelOptCluster cluster, RelTraitSet traitSet, - RelNode left, RelNode right, RexNode condition, - Set<CorrelationId> variablesSet, JoinRelType joinType) - throws InvalidRelException { - super(cluster, traitSet, left, right, condition, variablesSet, joinType); - } - - @Deprecated // to be removed before 2.0 - protected JdbcJoin( - RelOptCluster cluster, - RelTraitSet traitSet, - RelNode left, - RelNode right, - RexNode condition, - JoinRelType joinType, - Set<String> variablesStopped) - throws InvalidRelException { - this(cluster, traitSet, left, right, condition, - CorrelationId.setOf(variablesStopped), joinType); - } - - @Override public JdbcJoin copy(RelTraitSet traitSet, RexNode condition, - RelNode left, RelNode right, JoinRelType joinType, - boolean semiJoinDone) { - try { - return new JdbcJoin(getCluster(), traitSet, left, right, - condition, variablesSet, joinType); - } catch (InvalidRelException e) { - // Semantic error not possible. Must be a bug. Convert to - // internal error. - throw new AssertionError(e); - } - } - - @Override public RelOptCost computeSelfCost(RelOptPlanner planner, - RelMetadataQuery mq) { - // We always "build" the - double rowCount = mq.getRowCount(this); - - return planner.getCostFactory().makeCost(rowCount, 0, 0); - } - - @Override public double estimateRowCount(RelMetadataQuery mq) { - final double leftRowCount = left.estimateRowCount(mq); - final double rightRowCount = right.estimateRowCount(mq); - return Math.max(leftRowCount, rightRowCount); - } - - public JdbcImplementor.Result implement(JdbcImplementor implementor) { - return implementor.implement(this); - } - } - - /** - * Rule to convert a {@link org.apache.calcite.rel.logical.LogicalCalc} to an - * {@link org.apache.calcite.adapter.jdbc.JdbcRules.JdbcCalc}. - */ - private static class JdbcCalcRule extends JdbcConverterRule { - private JdbcCalcRule(JdbcConvention out) { - super(LogicalCalc.class, Convention.NONE, out, "JdbcCalcRule"); - } - - public RelNode convert(RelNode rel) { - final LogicalCalc calc = (LogicalCalc) rel; - - // If there's a multiset, let FarragoMultisetSplitter work on it - // first. - if (RexMultisetUtil.containsMultiset(calc.getProgram())) { - return null; - } - - return new JdbcCalc(rel.getCluster(), rel.getTraitSet().replace(out), - convert(calc.getInput(), calc.getTraitSet().replace(out)), - calc.getProgram()); - } - } - - /** Calc operator implemented in JDBC convention. - * - * @see org.apache.calcite.rel.core.Calc */ - public static class JdbcCalc extends SingleRel implements JdbcRel { - private final RexProgram program; - - public JdbcCalc(RelOptCluster cluster, - RelTraitSet traitSet, - RelNode input, - RexProgram program) { - super(cluster, traitSet, input); - assert getConvention() instanceof JdbcConvention; - this.program = program; - this.rowType = program.getOutputRowType(); - } - - @Deprecated // to be removed before 2.0 - public JdbcCalc(RelOptCluster cluster, RelTraitSet traitSet, RelNode input, - RexProgram program, int flags) { - this(cluster, traitSet, input, program); - Util.discard(flags); - } - - public RelWriter explainTerms(RelWriter pw) { - return program.explainCalc(super.explainTerms(pw)); - } - - @Override public double estimateRowCount(RelMetadataQuery mq) { - return RelMdUtil.estimateFilteredRows(getInput(), program, mq); - } - - public RelOptCost computeSelfCost(RelOptPlanner planner, - RelMetadataQuery mq) { - double dRows = mq.getRowCount(this); - double dCpu = mq.getRowCount(getInput()) - * program.getExprCount(); - double dIo = 0; - return planner.getCostFactory().makeCost(dRows, dCpu, dIo); - } - - public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) { - return new JdbcCalc(getCluster(), traitSet, sole(inputs), program); - } - - public JdbcImplementor.Result implement(JdbcImplementor implementor) { - return implementor.implement(this); - } - } - - /** - * Rule to convert a {@link org.apache.calcite.rel.logical.LogicalProject} to - * an {@link org.apache.calcite.adapter.jdbc.JdbcRules.JdbcProject}. - */ - private static class JdbcProjectRule extends JdbcConverterRule { - private JdbcProjectRule(JdbcConvention out) { - super(LogicalProject.class, Convention.NONE, out, "JdbcProjectRule"); - } - - public RelNode convert(RelNode rel) { - final LogicalProject project = (LogicalProject) rel; - - return new JdbcProject( - rel.getCluster(), - rel.getTraitSet().replace(out), - convert( - project.getInput(), - project.getInput().getTraitSet().replace(out)), - project.getProjects(), - project.getRowType()); - } - } - - /** Implementation of {@link org.apache.calcite.rel.logical.LogicalProject} in - * {@link JdbcConvention jdbc calling convention}. */ - public static class JdbcProject - extends Project - implements JdbcRel { - public JdbcProject( - RelOptCluster cluster, - RelTraitSet traitSet, - RelNode input, - List<? extends RexNode> projects, - RelDataType rowType) { - super(cluster, traitSet, input, projects, rowType); - assert getConvention() instanceof JdbcConvention; - } - - @Deprecated // to be removed before 2.0 - public JdbcProject(RelOptCluster cluster, RelTraitSet traitSet, - RelNode input, List<RexNode> projects, RelDataType rowType, int flags) { - this(cluster, traitSet, input, projects, rowType); - Util.discard(flags); - } - - @Override public JdbcProject copy(RelTraitSet traitSet, RelNode input, - List<RexNode> projects, RelDataType rowType) { - return new JdbcProject(getCluster(), traitSet, input, projects, rowType); - } - - @Override public RelOptCost computeSelfCost(RelOptPlanner planner, - RelMetadataQuery mq) { - return super.computeSelfCost(planner, mq) - .multiplyBy(JdbcConvention.COST_MULTIPLIER); - } - - public JdbcImplementor.Result implement(JdbcImplementor implementor) { - return implementor.implement(this); - } - } - - /** - * Rule to convert a {@link org.apache.calcite.rel.logical.LogicalFilter} to - * an {@link org.apache.calcite.adapter.jdbc.JdbcRules.JdbcFilter}. - */ - private static class JdbcFilterRule extends JdbcConverterRule { - private JdbcFilterRule(JdbcConvention out) { - super(LogicalFilter.class, Convention.NONE, out, "JdbcFilterRule"); - } - - public RelNode convert(RelNode rel) { - final LogicalFilter filter = (LogicalFilter) rel; - - return new JdbcFilter( - rel.getCluster(), - rel.getTraitSet().replace(out), - convert(filter.getInput(), - filter.getInput().getTraitSet().replace(out)), - filter.getCondition()); - } - } - - /** Implementation of {@link org.apache.calcite.rel.core.Filter} in - * {@link JdbcConvention jdbc calling convention}. */ - public static class JdbcFilter extends Filter implements JdbcRel { - public JdbcFilter( - RelOptCluster cluster, - RelTraitSet traitSet, - RelNode input, - RexNode condition) { - super(cluster, traitSet, input, condition); - assert getConvention() instanceof JdbcConvention; - } - - public JdbcFilter copy(RelTraitSet traitSet, RelNode input, - RexNode condition) { - return new JdbcFilter(getCluster(), traitSet, input, condition); - } - - public JdbcImplementor.Result implement(JdbcImplementor implementor) { - return implementor.implement(this); - } - } - - /** - * Rule to convert a {@link org.apache.calcite.rel.logical.LogicalAggregate} - * to a {@link org.apache.calcite.adapter.jdbc.JdbcRules.JdbcAggregate}. - */ - private static class JdbcAggregateRule extends JdbcConverterRule { - private JdbcAggregateRule(JdbcConvention out) { - super(LogicalAggregate.class, Convention.NONE, out, "JdbcAggregateRule"); - } - - public RelNode convert(RelNode rel) { - final LogicalAggregate agg = (LogicalAggregate) rel; - if (agg.getGroupSets().size() != 1) { - // GROUPING SETS not supported; see - // [CALCITE-734] Push GROUPING SETS to underlying SQL via JDBC adapter - return null; - } - final RelTraitSet traitSet = - agg.getTraitSet().replace(out); - try { - return new JdbcAggregate(rel.getCluster(), traitSet, - convert(agg.getInput(), out), agg.indicator, agg.getGroupSet(), - agg.getGroupSets(), agg.getAggCallList()); - } catch (InvalidRelException e) { - LOGGER.debug(e.toString()); - return null; - } - } - } - - /** Returns whether this JDBC data source can implement a given aggregate - * function. */ - private static boolean canImplement(SqlAggFunction aggregation, SqlDialect sqlDialect) { - switch (sqlDialect.getDatabaseProduct()) { - case MYSQL: - return MYSQL_AGG_FUNCS.contains(aggregation.getKind()); - default: - return AGG_FUNCS.contains(aggregation.getKind()); - } - } - - /** Aggregate operator implemented in JDBC convention. */ - public static class JdbcAggregate extends Aggregate implements JdbcRel { - public JdbcAggregate( - RelOptCluster cluster, - RelTraitSet traitSet, - RelNode input, - boolean indicator, - ImmutableBitSet groupSet, - List<ImmutableBitSet> groupSets, - List<AggregateCall> aggCalls) - throws InvalidRelException { - super(cluster, traitSet, input, indicator, groupSet, groupSets, aggCalls); - assert getConvention() instanceof JdbcConvention; - assert this.groupSets.size() == 1 : "Grouping sets not supported"; - assert !this.indicator; - final SqlDialect dialect = ((JdbcConvention) getConvention()).dialect; - for (AggregateCall aggCall : aggCalls) { - if (!canImplement(aggCall.getAggregation(), dialect)) { - throw new InvalidRelException("cannot implement aggregate function " - + aggCall.getAggregation()); - } - } - } - - @Override public JdbcAggregate copy(RelTraitSet traitSet, RelNode input, - boolean indicator, ImmutableBitSet groupSet, - List<ImmutableBitSet> groupSets, List<AggregateCall> aggCalls) { - try { - return new JdbcAggregate(getCluster(), traitSet, input, indicator, - groupSet, groupSets, aggCalls); - } catch (InvalidRelException e) { - // Semantic error not possible. Must be a bug. Convert to - // internal error. - throw new AssertionError(e); - } - } - - public JdbcImplementor.Result implement(JdbcImplementor implementor) { - return implementor.implement(this); - } - } - - /** - * Rule to convert a {@link org.apache.calcite.rel.core.Sort} to an - * {@link org.apache.calcite.adapter.jdbc.JdbcRules.JdbcSort}. - */ - private static class JdbcSortRule extends JdbcConverterRule { - private JdbcSortRule(JdbcConvention out) { - super(Sort.class, Convention.NONE, out, "JdbcSortRule"); - } - - public RelNode convert(RelNode rel) { - final Sort sort = (Sort) rel; - if (sort.offset != null || sort.fetch != null) { - // Cannot implement "OFFSET n FETCH n" currently. - return null; - } - final RelTraitSet traitSet = sort.getTraitSet().replace(out); - return new JdbcSort(rel.getCluster(), traitSet, - convert(sort.getInput(), traitSet), sort.getCollation()); - } - } - - /** Sort operator implemented in JDBC convention. */ - public static class JdbcSort - extends Sort - implements JdbcRel { - public JdbcSort( - RelOptCluster cluster, - RelTraitSet traitSet, - RelNode input, - RelCollation collation) { - super(cluster, traitSet, input, collation); - assert getConvention() instanceof JdbcConvention; - assert getConvention() == input.getConvention(); - } - - @Override public JdbcSort copy(RelTraitSet traitSet, RelNode newInput, - RelCollation newCollation, RexNode offset, RexNode fetch) { - if (offset != null || fetch != null) { - throw new IllegalArgumentException("not supported: offset or fetch"); - } - return new JdbcSort(getCluster(), traitSet, newInput, newCollation); - } - - public JdbcImplementor.Result implement(JdbcImplementor implementor) { - return implementor.implement(this); - } - } - - /** - * Rule to convert an {@link org.apache.calcite.rel.logical.LogicalUnion} to a - * {@link org.apache.calcite.adapter.jdbc.JdbcRules.JdbcUnion}. - */ - private static class JdbcUnionRule extends JdbcConverterRule { - private JdbcUnionRule(JdbcConvention out) { - super(LogicalUnion.class, Convention.NONE, out, "JdbcUnionRule"); - } - - public RelNode convert(RelNode rel) { - final LogicalUnion union = (LogicalUnion) rel; - final RelTraitSet traitSet = - union.getTraitSet().replace(out); - return new JdbcUnion(rel.getCluster(), traitSet, - convertList(union.getInputs(), out), union.all); - } - } - - /** Union operator implemented in JDBC convention. */ - public static class JdbcUnion extends Union implements JdbcRel { - public JdbcUnion( - RelOptCluster cluster, - RelTraitSet traitSet, - List<RelNode> inputs, - boolean all) { - super(cluster, traitSet, inputs, all); - } - - public JdbcUnion copy( - RelTraitSet traitSet, List<RelNode> inputs, boolean all) { - return new JdbcUnion(getCluster(), traitSet, inputs, all); - } - - @Override public RelOptCost computeSelfCost(RelOptPlanner planner, - RelMetadataQuery mq) { - return super.computeSelfCost(planner, mq).multiplyBy(.1); - } - - public JdbcImplementor.Result implement(JdbcImplementor implementor) { - return implementor.implement(this); - } - } - - /** - * Rule to convert a {@link org.apache.calcite.rel.logical.LogicalIntersect} - * to a {@link org.apache.calcite.adapter.jdbc.JdbcRules.JdbcIntersect}. - */ - private static class JdbcIntersectRule extends JdbcConverterRule { - private JdbcIntersectRule(JdbcConvention out) { - super(LogicalIntersect.class, Convention.NONE, out, "JdbcIntersectRule"); - } - - public RelNode convert(RelNode rel) { - final LogicalIntersect intersect = (LogicalIntersect) rel; - if (intersect.all) { - return null; // INTERSECT ALL not implemented - } - final RelTraitSet traitSet = - intersect.getTraitSet().replace(out); - return new JdbcIntersect(rel.getCluster(), traitSet, - convertList(intersect.getInputs(), out), false); - } - } - - /** Intersect operator implemented in JDBC convention. */ - public static class JdbcIntersect - extends Intersect - implements JdbcRel { - public JdbcIntersect( - RelOptCluster cluster, - RelTraitSet traitSet, - List<RelNode> inputs, - boolean all) { - super(cluster, traitSet, inputs, all); - assert !all; - } - - public JdbcIntersect copy( - RelTraitSet traitSet, List<RelNode> inputs, boolean all) { - return new JdbcIntersect(getCluster(), traitSet, inputs, all); - } - - public JdbcImplementor.Result implement(JdbcImplementor implementor) { - return implementor.implement(this); - } - } - - /** - * Rule to convert a {@link org.apache.calcite.rel.logical.LogicalMinus} to a - * {@link org.apache.calcite.adapter.jdbc.JdbcRules.JdbcMinus}. - */ - private static class JdbcMinusRule extends JdbcConverterRule { - private JdbcMinusRule(JdbcConvention out) { - super(LogicalMinus.class, Convention.NONE, out, "JdbcMinusRule"); - } - - public RelNode convert(RelNode rel) { - final LogicalMinus minus = (LogicalMinus) rel; - if (minus.all) { - return null; // EXCEPT ALL not implemented - } - final RelTraitSet traitSet = - rel.getTraitSet().replace(out); - return new JdbcMinus(rel.getCluster(), traitSet, - convertList(minus.getInputs(), out), false); - } - } - - /** Minus operator implemented in JDBC convention. */ - public static class JdbcMinus extends Minus implements JdbcRel { - public JdbcMinus(RelOptCluster cluster, RelTraitSet traitSet, - List<RelNode> inputs, boolean all) { - super(cluster, traitSet, inputs, all); - assert !all; - } - - public JdbcMinus copy(RelTraitSet traitSet, List<RelNode> inputs, - boolean all) { - return new JdbcMinus(getCluster(), traitSet, inputs, all); - } - - public JdbcImplementor.Result implement(JdbcImplementor implementor) { - return implementor.implement(this); - } - } - - /** Rule that converts a table-modification to JDBC. */ - public static class JdbcTableModificationRule extends JdbcConverterRule { - private JdbcTableModificationRule(JdbcConvention out) { - super( - LogicalTableModify.class, - Convention.NONE, - out, - "JdbcTableModificationRule"); - } - - @Override public RelNode convert(RelNode rel) { - final LogicalTableModify modify = - (LogicalTableModify) rel; - final ModifiableTable modifiableTable = - modify.getTable().unwrap(ModifiableTable.class); - if (modifiableTable == null - /* || modifiableTable.getExpression(tableInSchema) == null */) { - return null; - } - final RelTraitSet traitSet = - modify.getTraitSet().replace(out); - return new JdbcTableModify( - modify.getCluster(), traitSet, - modify.getTable(), - modify.getCatalogReader(), - convert(modify.getInput(), traitSet), - modify.getOperation(), - modify.getUpdateColumnList(), - modify.getSourceExpressionList(), - modify.isFlattened()); - } - } - - /** Table-modification operator implemented in JDBC convention. */ - public static class JdbcTableModify extends TableModify implements JdbcRel { - private final Expression expression; - - public JdbcTableModify(RelOptCluster cluster, - RelTraitSet traitSet, - RelOptTable table, - Prepare.CatalogReader catalogReader, - RelNode input, - Operation operation, - List<String> updateColumnList, - List<RexNode> sourceExpressionList, - boolean flattened) { - super(cluster, traitSet, table, catalogReader, input, operation, - updateColumnList, sourceExpressionList, flattened); - assert input.getConvention() instanceof JdbcConvention; - assert getConvention() instanceof JdbcConvention; - final ModifiableTable modifiableTable = - table.unwrap(ModifiableTable.class); - if (modifiableTable == null) { - throw new AssertionError(); // TODO: user error in validator - } - this.expression = table.getExpression(Queryable.class); - if (expression == null) { - throw new AssertionError(); // TODO: user error in validator - } - } - - @Override public RelOptCost computeSelfCost(RelOptPlanner planner, - RelMetadataQuery mq) { - return super.computeSelfCost(planner, mq).multiplyBy(.1); - } - - @Override public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) { - return new JdbcTableModify( - getCluster(), traitSet, getTable(), getCatalogReader(), - sole(inputs), getOperation(), getUpdateColumnList(), - getSourceExpressionList(), isFlattened()); - } - - public JdbcImplementor.Result implement(JdbcImplementor implementor) { - return implementor.implement(this); - } - } - - /** Rule that converts a values operator to JDBC. */ - public static class JdbcValuesRule extends JdbcConverterRule { - private JdbcValuesRule(JdbcConvention out) { - super(LogicalValues.class, Convention.NONE, out, "JdbcValuesRule"); - } - - @Override public RelNode convert(RelNode rel) { - LogicalValues values = (LogicalValues) rel; - return new JdbcValues(values.getCluster(), values.getRowType(), - values.getTuples(), values.getTraitSet().replace(out)); - } - } - - /** Values operator implemented in JDBC convention. */ - public static class JdbcValues extends Values implements JdbcRel { - JdbcValues(RelOptCluster cluster, RelDataType rowType, - ImmutableList<ImmutableList<RexLiteral>> tuples, RelTraitSet traitSet) { - super(cluster, rowType, tuples, traitSet); - } - - @Override public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) { - assert inputs.isEmpty(); - return new JdbcValues(getCluster(), rowType, tuples, traitSet); - } - - public JdbcImplementor.Result implement(JdbcImplementor implementor) { - return implementor.implement(this); - } - } -} - -// End JdbcRules.java http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcSchema.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcSchema.java b/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcSchema.java deleted file mode 100644 index faf0e94..0000000 --- a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcSchema.java +++ /dev/null @@ -1,440 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.calcite.adapter.jdbc; - -import org.apache.calcite.avatica.AvaticaUtils; -import org.apache.calcite.avatica.SqlType; -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.RelDataTypeImpl; -import org.apache.calcite.rel.type.RelDataTypeSystem; -import org.apache.calcite.rel.type.RelProtoDataType; -import org.apache.calcite.schema.Function; -import org.apache.calcite.schema.Schema; -import org.apache.calcite.schema.SchemaFactory; -import org.apache.calcite.schema.SchemaPlus; -import org.apache.calcite.schema.Schemas; -import org.apache.calcite.schema.Table; -import org.apache.calcite.sql.SqlDialect; -import org.apache.calcite.sql.type.SqlTypeFactoryImpl; -import org.apache.calcite.sql.type.SqlTypeName; -import org.apache.calcite.util.Util; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Multimap; - -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Collection; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import javax.sql.DataSource; - -/** - * Implementation of {@link Schema} that is backed by a JDBC data source. - * - * <p>The tables in the JDBC data source appear to be tables in this schema; - * queries against this schema are executed against those tables, pushing down - * as much as possible of the query logic to SQL.</p> - */ -public class JdbcSchema implements Schema { - final DataSource dataSource; - final String catalog; - final String schema; - public final SqlDialect dialect; - final JdbcConvention convention; - private ImmutableMap<String, JdbcTable> tableMap; - - /** - * Creates a JDBC schema. - * - * @param dataSource Data source - * @param dialect SQL dialect - * @param convention Calling convention - * @param catalog Catalog name, or null - * @param schema Schema name pattern - */ - public JdbcSchema(DataSource dataSource, SqlDialect dialect, - JdbcConvention convention, String catalog, String schema) { - super(); - this.dataSource = dataSource; - this.dialect = dialect; - this.convention = convention; - this.catalog = catalog; - this.schema = schema; - assert dialect != null; - assert dataSource != null; - } - - public static JdbcSchema create( - SchemaPlus parentSchema, - String name, - DataSource dataSource, - String catalog, - String schema) { - final Expression expression = - Schemas.subSchemaExpression(parentSchema, name, JdbcSchema.class); - final SqlDialect dialect = createDialect(dataSource); - final JdbcConvention convention = - JdbcConvention.of(dialect, expression, name); - return new JdbcSchema(dataSource, dialect, convention, catalog, schema); - } - - /** - * Creates a JdbcSchema, taking credentials from a map. - * - * @param parentSchema Parent schema - * @param name Name - * @param operand Map of property/value pairs - * @return A JdbcSchema - */ - public static JdbcSchema create( - SchemaPlus parentSchema, - String name, - Map<String, Object> operand) { - DataSource dataSource; - try { - final String dataSourceName = (String) operand.get("dataSource"); - if (dataSourceName != null) { - dataSource = - AvaticaUtils.instantiatePlugin(DataSource.class, dataSourceName); - } else { - final String jdbcUrl = (String) operand.get("jdbcUrl"); - final String jdbcDriver = (String) operand.get("jdbcDriver"); - final String jdbcUser = (String) operand.get("jdbcUser"); - final String jdbcPassword = (String) operand.get("jdbcPassword"); - dataSource = dataSource(jdbcUrl, jdbcDriver, jdbcUser, jdbcPassword); - } - } catch (Exception e) { - throw new RuntimeException("Error while reading dataSource", e); - } - String jdbcCatalog = (String) operand.get("jdbcCatalog"); - String jdbcSchema = (String) operand.get("jdbcSchema"); - return JdbcSchema.create( - parentSchema, name, dataSource, jdbcCatalog, jdbcSchema); - } - - /** Returns a suitable SQL dialect for the given data source. */ - public static SqlDialect createDialect(DataSource dataSource) { - return JdbcUtils.DialectPool.INSTANCE.get(dataSource); - } - - /** Creates a JDBC data source with the given specification. */ - public static DataSource dataSource(String url, String driverClassName, - String username, String password) { - if (url.startsWith("jdbc:hsqldb:")) { - // Prevent hsqldb from screwing up java.util.logging. - System.setProperty("hsqldb.reconfig_logging", "false"); - } - return JdbcUtils.DataSourcePool.INSTANCE.get(url, driverClassName, username, - password); - } - - public boolean isMutable() { - return false; - } - - public boolean contentsHaveChangedSince(long lastCheck, long now) { - return false; - } - - // Used by generated code. - public DataSource getDataSource() { - return dataSource; - } - - public Expression getExpression(SchemaPlus parentSchema, String name) { - return Schemas.subSchemaExpression(parentSchema, name, JdbcSchema.class); - } - - protected Multimap<String, Function> getFunctions() { - // TODO: populate map from JDBC metadata - return ImmutableMultimap.of(); - } - - public final Collection<Function> getFunctions(String name) { - return getFunctions().get(name); // never null - } - - public final Set<String> getFunctionNames() { - return getFunctions().keySet(); - } - - private ImmutableMap<String, JdbcTable> computeTables() { - Connection connection = null; - ResultSet resultSet = null; - try { - connection = dataSource.getConnection(); - DatabaseMetaData metaData = connection.getMetaData(); - resultSet = metaData.getTables( - catalog, - schema, - null, - null); - final ImmutableMap.Builder<String, JdbcTable> builder = - ImmutableMap.builder(); - while (resultSet.next()) { - final String tableName = resultSet.getString(3); - final String catalogName = resultSet.getString(1); - final String schemaName = resultSet.getString(2); - final String tableTypeName = resultSet.getString(4); - // Clean up table type. In particular, this ensures that 'SYSTEM TABLE', - // returned by Phoenix among others, maps to TableType.SYSTEM_TABLE. - // We know enum constants are upper-case without spaces, so we can't - // make things worse. - // - // PostgreSQL returns tableTypeName==null for pg_toast* tables - // This can happen if you start JdbcSchema off a "public" PG schema - // The tables are not designed to be queried by users, however we do - // not filter them as we keep all the other table types. - final String tableTypeName2 = - tableTypeName == null - ? null - : tableTypeName.toUpperCase(Locale.ROOT).replace(' ', '_'); - final TableType tableType = - Util.enumVal(TableType.OTHER, tableTypeName2); - if (tableType == TableType.OTHER && tableTypeName2 != null) { - System.out.println("Unknown table type: " + tableTypeName2); - } - final JdbcTable table = - new JdbcTable(this, catalogName, schemaName, tableName, tableType); - builder.put(tableName, table); - } - return builder.build(); - } catch (SQLException e) { - throw new RuntimeException( - "Exception while reading tables", e); - } finally { - close(connection, null, resultSet); - } - } - - public Table getTable(String name) { - return getTableMap(false).get(name); - } - - private synchronized ImmutableMap<String, JdbcTable> getTableMap( - boolean force) { - if (force || tableMap == null) { - tableMap = computeTables(); - } - return tableMap; - } - - RelProtoDataType getRelDataType(String catalogName, String schemaName, - String tableName) throws SQLException { - Connection connection = null; - try { - connection = dataSource.getConnection(); - DatabaseMetaData metaData = connection.getMetaData(); - return getRelDataType(metaData, catalogName, schemaName, tableName); - } finally { - close(connection, null, null); - } - } - - RelProtoDataType getRelDataType(DatabaseMetaData metaData, String catalogName, - String schemaName, String tableName) throws SQLException { - final ResultSet resultSet = - metaData.getColumns(catalogName, schemaName, tableName, null); - - // Temporary type factory, just for the duration of this method. Allowable - // because we're creating a proto-type, not a type; before being used, the - // proto-type will be copied into a real type factory. - final RelDataTypeFactory typeFactory = - new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT); - final RelDataTypeFactory.FieldInfoBuilder fieldInfo = typeFactory.builder(); - while (resultSet.next()) { - final String columnName = resultSet.getString(4); - final int dataType = resultSet.getInt(5); - final String typeString = resultSet.getString(6); - final int precision; - final int scale; - switch (SqlType.valueOf(dataType)) { - case TIMESTAMP: - case TIME: - precision = resultSet.getInt(9); // SCALE - scale = 0; - break; - default: - precision = resultSet.getInt(7); // SIZE - scale = resultSet.getInt(9); // SCALE - break; - } - RelDataType sqlType = - sqlType(typeFactory, dataType, precision, scale, typeString); - boolean nullable = resultSet.getInt(11) != DatabaseMetaData.columnNoNulls; - fieldInfo.add(columnName, sqlType).nullable(nullable); - } - resultSet.close(); - return RelDataTypeImpl.proto(fieldInfo.build()); - } - - private RelDataType sqlType(RelDataTypeFactory typeFactory, int dataType, - int precision, int scale, String typeString) { - // Fall back to ANY if type is unknown - final SqlTypeName sqlTypeName = - Util.first(SqlTypeName.getNameForJdbcType(dataType), SqlTypeName.ANY); - switch (sqlTypeName) { - case ARRAY: - RelDataType component = null; - if (typeString != null && typeString.endsWith(" ARRAY")) { - // E.g. hsqldb gives "INTEGER ARRAY", so we deduce the component type - // "INTEGER". - final String remaining = typeString.substring(0, - typeString.length() - " ARRAY".length()); - component = parseTypeString(typeFactory, remaining); - } - if (component == null) { - component = typeFactory.createTypeWithNullability( - typeFactory.createSqlType(SqlTypeName.ANY), true); - } - return typeFactory.createArrayType(component, -1); - } - if (precision >= 0 - && scale >= 0 - && sqlTypeName.allowsPrecScale(true, true)) { - return typeFactory.createSqlType(sqlTypeName, precision, scale); - } else if (precision >= 0 && sqlTypeName.allowsPrecNoScale()) { - return typeFactory.createSqlType(sqlTypeName, precision); - } else { - assert sqlTypeName.allowsNoPrecNoScale(); - return typeFactory.createSqlType(sqlTypeName); - } - } - - /** Given "INTEGER", returns BasicSqlType(INTEGER). - * Given "VARCHAR(10)", returns BasicSqlType(VARCHAR, 10). - * Given "NUMERIC(10, 2)", returns BasicSqlType(NUMERIC, 10, 2). */ - private RelDataType parseTypeString(RelDataTypeFactory typeFactory, - String typeString) { - int precision = -1; - int scale = -1; - int open = typeString.indexOf("("); - if (open >= 0) { - int close = typeString.indexOf(")", open); - if (close >= 0) { - String rest = typeString.substring(open + 1, close); - typeString = typeString.substring(0, open); - int comma = rest.indexOf(","); - if (comma >= 0) { - precision = Integer.parseInt(rest.substring(0, comma)); - scale = Integer.parseInt(rest.substring(comma)); - } else { - precision = Integer.parseInt(rest); - } - } - } - try { - final SqlTypeName typeName = SqlTypeName.valueOf(typeString); - return typeName.allowsPrecScale(true, true) - ? typeFactory.createSqlType(typeName, precision, scale) - : typeName.allowsPrecScale(true, false) - ? typeFactory.createSqlType(typeName, precision) - : typeFactory.createSqlType(typeName); - } catch (IllegalArgumentException e) { - return typeFactory.createTypeWithNullability( - typeFactory.createSqlType(SqlTypeName.ANY), true); - } - } - - public Set<String> getTableNames() { - // This method is called during a cache refresh. We can take it as a signal - // that we need to re-build our own cache. - return getTableMap(true).keySet(); - } - - public Schema getSubSchema(String name) { - // JDBC does not support sub-schemas. - return null; - } - - public Set<String> getSubSchemaNames() { - return ImmutableSet.of(); - } - - private static void close( - Connection connection, Statement statement, ResultSet resultSet) { - if (resultSet != null) { - try { - resultSet.close(); - } catch (SQLException e) { - // ignore - } - } - if (statement != null) { - try { - statement.close(); - } catch (SQLException e) { - // ignore - } - } - if (connection != null) { - try { - connection.close(); - } catch (SQLException e) { - // ignore - } - } - } - - /** Schema factory that creates a - * {@link org.apache.calcite.adapter.jdbc.JdbcSchema}. - * This allows you to create a jdbc schema inside a model.json file. - * - * <pre>{@code - * { - * version: '1.0', - * defaultSchema: 'FOODMART_CLONE', - * schemas: [ - * { - * name: 'FOODMART_CLONE', - * type: 'custom', - * factory: 'org.apache.calcite.adapter.jdbc.JdbcSchema$Factory', - * operand: { - * jdbcDriver: 'com.mysql.jdbc.Driver', - * jdbcUrl: 'jdbc:mysql://localhost/foodmart', - * jdbcUser: 'foodmart', - * jdbcPassword: 'foodmart' - * } - * } - * ] - * } - * }</pre> - */ - public static class Factory implements SchemaFactory { - public static final Factory INSTANCE = new Factory(); - - private Factory() {} - - public Schema create( - SchemaPlus parentSchema, - String name, - Map<String, Object> operand) { - return JdbcSchema.create(parentSchema, name, operand); - } - } -} - -// End JdbcSchema.java
