Java tutorial
/* // Licensed to Julian Hyde under one or more contributor license // agreements. See the NOTICE file distributed with this work for // additional information regarding copyright ownership. // // Julian Hyde 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 net.hydromatic.optiq.prepare; import net.hydromatic.linq4j.expressions.Primitive; import net.hydromatic.optiq.*; import net.hydromatic.optiq.impl.java.JavaTypeFactory; import net.hydromatic.optiq.jdbc.OptiqSchema; import org.eigenbase.relopt.RelOptPlanner; import org.eigenbase.reltype.*; import org.eigenbase.sql.*; import org.eigenbase.sql.type.*; import org.eigenbase.sql.validate.*; import org.eigenbase.util.Util; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import java.util.*; /** * Implementation of {@link net.hydromatic.optiq.prepare.Prepare.CatalogReader} * and also {@link org.eigenbase.sql.SqlOperatorTable} based on tables and * functions defined schemas. */ class OptiqCatalogReader implements Prepare.CatalogReader, SqlOperatorTable { final OptiqSchema rootSchema; final JavaTypeFactory typeFactory; private final List<String> defaultSchema; private final boolean caseSensitive; public OptiqCatalogReader(OptiqSchema rootSchema, boolean caseSensitive, List<String> defaultSchema, JavaTypeFactory typeFactory) { super(); assert rootSchema != defaultSchema; this.rootSchema = rootSchema; this.caseSensitive = caseSensitive; this.defaultSchema = defaultSchema; this.typeFactory = typeFactory; } public OptiqCatalogReader withSchemaPath(List<String> schemaPath) { return new OptiqCatalogReader(rootSchema, caseSensitive, schemaPath, typeFactory); } public OptiqPrepareImpl.RelOptTableImpl getTable(final List<String> names) { // First look in the default schema, if any. if (defaultSchema != null) { OptiqPrepareImpl.RelOptTableImpl table = getTableFrom(names, defaultSchema); if (table != null) { return table; } } // If not found, look in the root schema return getTableFrom(names, ImmutableList.<String>of()); } private OptiqPrepareImpl.RelOptTableImpl getTableFrom(List<String> names, List<String> schemaNames) { OptiqSchema schema = getSchema(Iterables.concat(schemaNames, Util.skipLast(names))); if (schema == null) { return null; } final String name = Util.last(names); final Table table = schema.compositeTableMap.get(name); if (table != null) { return new OptiqPrepareImpl.RelOptTableImpl(this, table.getRowType(typeFactory), schema.add(name, table)); } return null; } private Collection<TableFunction> getTableFunctionsFrom(List<String> names, List<String> schemaNames) { OptiqSchema schema = getSchema(Iterables.concat(schemaNames, Util.skipLast(names))); if (schema == null) { return ImmutableList.of(); } final String name = Util.last(names); return schema.compositeTableFunctionMap.get(name); } private OptiqSchema getSchema(Iterable<String> schemaNames) { OptiqSchema schema = rootSchema; for (String schemaName : schemaNames) { schema = schema.getSubSchema(schemaName); if (schema == null) { return null; } } return schema; } public RelDataType getNamedType(SqlIdentifier typeName) { return null; } public List<SqlMoniker> getAllSchemaObjectNames(List<String> names) { return null; } public String getSchemaName() { return null; } public OptiqPrepareImpl.RelOptTableImpl getTableForMember(List<String> names) { return getTable(names); } public RelDataTypeField field(RelDataType rowType, String alias) { return SqlValidatorUtil.lookupField(caseSensitive, rowType, alias); } public int fieldOrdinal(RelDataType rowType, String alias) { RelDataTypeField field = field(rowType, alias); return field != null ? field.getIndex() : -1; } public int match(List<String> strings, String name) { return Util.match2(strings, name, caseSensitive); } public RelDataType createTypeFromProjection(final RelDataType type, final List<String> columnNameList) { return SqlValidatorUtil.createTypeFromProjection(type, columnNameList, typeFactory, caseSensitive); } public List<SqlOperator> lookupOperatorOverloads(SqlIdentifier opName, SqlFunctionCategory category, SqlSyntax syntax) { if (syntax != SqlSyntax.FUNCTION) { return ImmutableList.of(); } final Collection<TableFunction> tableFunctions = getTableFunctionsFrom(opName.names, ImmutableList.<String>of()); if (tableFunctions.isEmpty()) { return ImmutableList.of(); } final String name = Util.last(opName.names); return toOps(name, ImmutableList.copyOf(tableFunctions)); } private List<SqlOperator> toOps(final String name, final ImmutableList<TableFunction> tableFunctions) { return new AbstractList<SqlOperator>() { public SqlOperator get(int index) { return toOp(name, tableFunctions.get(index)); } public int size() { return tableFunctions.size(); } }; } private SqlOperator toOp(String name, TableFunction tableFunction) { List<RelDataType> argTypes = new ArrayList<RelDataType>(); List<SqlTypeFamily> typeFamilies = new ArrayList<SqlTypeFamily>(); List<Object> dummyArguments = new ArrayList<Object>(); for (net.hydromatic.optiq.Parameter o : tableFunction.getParameters()) { final RelDataType type = o.getType(typeFactory); argTypes.add(type); typeFamilies.add(SqlTypeFamily.ANY); dummyArguments.add(zero(type)); } final Table table; final RelDataType returnType; if (tableFunction instanceof ScalarFunction) { returnType = ((ScalarFunction) tableFunction).getReturnType(typeFactory); table = null; } else { // Make a call with dummy arguments, to get the table, so get its row // type. table = tableFunction.apply(dummyArguments); returnType = typeFactory.createSqlType(SqlTypeName.CURSOR); } return new SqlUserDefinedFunction(name, returnType, argTypes, typeFamilies, tableFunction, table); } private Object zero(RelDataType type) { if (type instanceof RelDataTypeFactoryImpl.JavaType) { RelDataTypeFactoryImpl.JavaType javaType = (RelDataTypeFactoryImpl.JavaType) type; Primitive primitive = Primitive.of(javaType.getJavaClass()); if (primitive != null) { return primitive.defaultValue; } } return null; } public List<SqlOperator> getOperatorList() { return null; } public RelDataTypeFactory getTypeFactory() { return typeFactory; } public void registerRules(RelOptPlanner planner) throws Exception { } } // End OptiqCatalogReader.java