All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.org.apache.calcite.adapter.clone.CloneSchema Maven / Gradle / Ivy

There is a newer version: 5.5.0
Show newest version
/*
 * 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 com.hazelcast.org.apache.calcite.adapter.clone;

import com.hazelcast.org.apache.calcite.adapter.java.JavaTypeFactory;
import com.hazelcast.org.apache.calcite.adapter.jdbc.JdbcSchema;
import com.hazelcast.org.apache.calcite.avatica.ColumnMetaData;
import com.hazelcast.org.apache.calcite.jdbc.CalciteConnection;
import com.hazelcast.org.apache.calcite.linq4j.Enumerable;
import com.hazelcast.org.apache.calcite.linq4j.QueryProvider;
import com.hazelcast.org.apache.calcite.linq4j.Queryable;
import com.hazelcast.org.apache.calcite.rel.RelCollation;
import com.hazelcast.org.apache.calcite.rel.RelCollations;
import com.hazelcast.org.apache.calcite.rel.type.RelProtoDataType;
import com.hazelcast.org.apache.calcite.schema.QueryableTable;
import com.hazelcast.org.apache.calcite.schema.Schema;
import com.hazelcast.org.apache.calcite.schema.SchemaFactory;
import com.hazelcast.org.apache.calcite.schema.SchemaPlus;
import com.hazelcast.org.apache.calcite.schema.Schemas;
import com.hazelcast.org.apache.calcite.schema.Table;
import com.hazelcast.org.apache.calcite.schema.impl.AbstractSchema;

import com.hazelcast.com.google.common.base.Suppliers;
import com.hazelcast.com.google.common.collect.ImmutableList;

import com.hazelcast.org.checkerframework.checker.nullness.qual.Nullable;

import java.lang.reflect.Type;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import static com.hazelcast.org.apache.calcite.schema.impl.MaterializedViewTable.MATERIALIZATION_CONNECTION;

/**
 * Schema that contains in-memory copies of tables from a JDBC schema.
 */
public class CloneSchema extends AbstractSchema {
  // TODO: implement 'driver' property
  // TODO: implement 'source' property
  // TODO: test Factory

  private final SchemaPlus sourceSchema;

  /**
   * Creates a CloneSchema.
   *
   * @param sourceSchema JDBC data source
   */
  public CloneSchema(SchemaPlus sourceSchema) {
    super();
    this.sourceSchema = sourceSchema;
  }

  @Override protected Map getTableMap() {
    final Map map = new LinkedHashMap<>();
    for (String name : sourceSchema.getTableNames()) {
      final Table table = sourceSchema.getTable(name);
      if (table instanceof QueryableTable) {
        final QueryableTable sourceTable = (QueryableTable) table;
        map.put(name,
            createCloneTable(MATERIALIZATION_CONNECTION, sourceTable, name));
      }
    }
    return map;
  }

  private Table createCloneTable(QueryProvider queryProvider,
      QueryableTable sourceTable, String name) {
    final Queryable queryable =
        sourceTable.asQueryable(queryProvider, sourceSchema, name);
    final JavaTypeFactory typeFactory =
        ((CalciteConnection) queryProvider).getTypeFactory();
    return createCloneTable(typeFactory, Schemas.proto(sourceTable),
        ImmutableList.of(), null, queryable);
  }

  @Deprecated // to be removed before 2.0
  public static  Table createCloneTable(final JavaTypeFactory typeFactory,
      final RelProtoDataType protoRowType,
      final @Nullable List repList,
      final Enumerable source) {
    return createCloneTable(typeFactory, protoRowType, ImmutableList.of(),
        repList, source);
  }

  public static  Table createCloneTable(final JavaTypeFactory typeFactory,
      final RelProtoDataType protoRowType, final List collations,
      final @Nullable List repList, final Enumerable source) {
    final Type elementType;
    if (source instanceof QueryableTable) {
      elementType = ((QueryableTable) source).getElementType();
    } else if (protoRowType.apply(typeFactory).getFieldCount() == 1) {
      if (repList != null) {
        elementType = repList.get(0).clazz;
      } else {
        elementType = Object.class;
      }
    } else {
      elementType = Object[].class;
    }
    return new ArrayTable(
        elementType,
        protoRowType,
        Suppliers.memoize(() -> {
          final ColumnLoader loader =
              new ColumnLoader<>(typeFactory, source, protoRowType,
                  repList);
          final List collation2 =
              collations.isEmpty()
                  && loader.sortField >= 0
                  ? RelCollations.createSingleton(loader.sortField)
                  : collations;
          return new ArrayTable.Content(loader.representationValues,
              loader.size(), collation2);
        }));
  }

  /** Schema factory that creates a
   * {@link com.hazelcast.org.apache.calcite.adapter.clone.CloneSchema}.
   * This allows you to create a clone schema inside a model.json file.
   *
   * 
   * {
   *   version: '1.0',
   *   defaultSchema: 'FOODMART_CLONE',
   *   schemas: [
   *     {
   *       name: 'FOODMART_CLONE',
   *       type: 'custom',
   *       factory: 'com.hazelcast.org.apache.calcite.adapter.clone.CloneSchema$Factory',
   *       operand: {
   *         jdbcDriver: 'com.mysql.jdbc.Driver',
   *         jdbcUrl: 'jdbc:mysql://localhost/foodmart',
   *         jdbcUser: 'foodmart',
   *         jdbcPassword: 'foodmart'
   *       }
   *     }
   *   ]
   * }
*/ public static class Factory implements SchemaFactory { @Override public Schema create( SchemaPlus parentSchema, String name, Map operand) { SchemaPlus schema = parentSchema.add(name, JdbcSchema.create(parentSchema, name + "$source", operand)); return new CloneSchema(schema); } } }