Skip to content

Commit

Permalink
EXPB-3296 Open Calcite PR for lazy Schema lookup
Browse files Browse the repository at this point in the history
  • Loading branch information
kramerul committed Dec 18, 2024
1 parent d3c0e60 commit bdd9a0a
Show file tree
Hide file tree
Showing 26 changed files with 683 additions and 292 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
import org.apache.calcite.schema.Schemas;
import org.apache.calcite.schema.Table;
import org.apache.calcite.schema.impl.AbstractSchema;
import org.apache.calcite.schema.lookup.LikePattern;
import org.apache.calcite.schema.lookup.Lookup;

import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* 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.rel.type.RelProtoDataType;
import org.apache.calcite.schema.Function;
import org.apache.calcite.schema.Schema;
import org.apache.calcite.schema.SchemaPlus;
import org.apache.calcite.schema.SchemaVersion;
import org.apache.calcite.schema.Schemas;
import org.apache.calcite.schema.Table;
import org.apache.calcite.schema.lookup.LikePattern;
import org.apache.calcite.schema.lookup.Lookup;

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

import java.util.Collection;
import java.util.Collections;
import java.util.Set;

import static java.util.Objects.requireNonNull;

/**
* Base class for JDBC schemas.
*/
public abstract class JdbcBaseSchema implements Schema {

public abstract Lookup<Table> tables();


@Deprecated @Override public @Nullable Table getTable(String name) {
return tables().get(name);
}

@Deprecated @Override public Set<String> getTableNames() {
return tables().getNames(LikePattern.any());
}

public abstract Lookup<? extends Schema> subSchemas();

@Deprecated @Override public @Nullable Schema getSubSchema(String name) {
return subSchemas().get(name);
}

@Deprecated @Override public Set<String> getSubSchemaNames() {
return subSchemas().getNames(LikePattern.any());
}


@Override public @Nullable RelProtoDataType getType(String name) {
return null;
}

@Override public Set<String> getTypeNames() {
return Collections.emptySet();
}

@Override public final Collection<Function> getFunctions(String name) {
return Collections.emptyList();
}

@Override public final Set<String> getFunctionNames() {
return Collections.emptySet();
}

@Override public Expression getExpression(@Nullable final SchemaPlus parentSchema,
final String name) {
requireNonNull(parentSchema, "parentSchema");
return Schemas.subSchemaExpression(parentSchema, name, getClass());
}

@Override public boolean isMutable() {
return false;
}

@Override public Schema snapshot(final SchemaVersion version) {
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,33 +16,31 @@
*/
package org.apache.calcite.adapter.jdbc;

import com.google.common.collect.ImmutableSet;

import org.apache.calcite.DataContext;
import org.apache.calcite.linq4j.tree.Expression;
import org.apache.calcite.linq4j.tree.Expressions;
import org.apache.calcite.schema.lookup.LikePattern;
import org.apache.calcite.schema.lookup.Lookup;
import org.apache.calcite.schema.Schema;
import org.apache.calcite.schema.SchemaPlus;
import org.apache.calcite.schema.Schemas;
import org.apache.calcite.schema.Table;
import org.apache.calcite.schema.Wrapper;
import org.apache.calcite.schema.impl.AbstractSchema;
import org.apache.calcite.schema.lookup.CachingLookup;
import org.apache.calcite.schema.lookup.IgnoreCaseLookup;
import org.apache.calcite.schema.lookup.LikePattern;
import org.apache.calcite.schema.lookup.LoadingCacheLookup;
import org.apache.calcite.schema.lookup.Lookup;
import org.apache.calcite.sql.SqlDialect;
import org.apache.calcite.sql.SqlDialectFactory;
import org.apache.calcite.sql.SqlDialectFactoryImpl;
import org.apache.calcite.util.BuiltInMethod;

import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableSet;

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

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;
import javax.sql.DataSource;
Expand All @@ -57,11 +55,11 @@
* an instance of {@link JdbcSchema}.
*
* <p>This schema is lazy: it does not compute the list of schema names until
* the first call to {@link #getSubSchemaMap()}. Then it creates a
* {@link JdbcSchema} for each schema name. Each JdbcSchema will populate its
* the first call to {@link #subSchemas()} and {@link Lookup#get(String)}. Then it creates a
* {@link JdbcSchema} for this schema name. Each JdbcSchema will populate its
* tables on demand.
*/
public class JdbcCatalogSchema extends AbstractSchema implements Wrapper {
public class JdbcCatalogSchema extends JdbcBaseSchema implements Wrapper {
final DataSource dataSource;
public final SqlDialect dialect;
final JdbcConvention convention;
Expand All @@ -80,12 +78,11 @@ public JdbcCatalogSchema(DataSource dataSource, SqlDialect dialect,
this.dialect = requireNonNull(dialect, "dialect");
this.convention = requireNonNull(convention, "convention");
this.catalog = catalog;
this.subSchemas = new CachingLookup<>(new IgnoreCaseLookup<JdbcSchema>() {
@Override
public @Nullable JdbcSchema get(String name) {
this.subSchemas = new LoadingCacheLookup<>(new IgnoreCaseLookup<JdbcSchema>() {
@Override public @Nullable JdbcSchema get(String name) {
try (Connection connection = dataSource.getConnection();
ResultSet resultSet =
connection.getMetaData().getSchemas(catalog, name)) {
ResultSet resultSet =
connection.getMetaData().getSchemas(catalog, name)) {
while (resultSet.next()) {
final String schemaName =
requireNonNull(resultSet.getString(1),
Expand All @@ -98,15 +95,15 @@ public JdbcCatalogSchema(DataSource dataSource, SqlDialect dialect,
return null;
}

@Override
public Set<String> getNames(LikePattern pattern) {
@Override public Set<String> getNames(LikePattern pattern) {
final ImmutableSet.Builder<String> builder =
ImmutableSet.builder();
try (Connection connection = dataSource.getConnection();
ResultSet resultSet =
connection.getMetaData().getSchemas(catalog, pattern.pattern)) {
ResultSet resultSet =
connection.getMetaData().getSchemas(catalog, pattern.pattern)) {
while (resultSet.next()) {
builder.add(requireNonNull(resultSet.getString(1),
builder.add(
requireNonNull(resultSet.getString(1),
"got null schemaName from the database"));
}
} catch (SQLException e) {
Expand Down Expand Up @@ -145,6 +142,10 @@ public static JdbcCatalogSchema create(
return new JdbcCatalogSchema(dataSource, dialect, convention, catalog);
}

@Override public Lookup<Table> tables() {
return Lookup.empty();
}

@Override public Lookup<? extends Schema> subSchemas() {
return subSchemas;
}
Expand All @@ -157,10 +158,6 @@ private String computeDefaultSchemaName() {
}
}

@Override protected Map<String, Schema> getSubSchemaMap() {
throw new UnsupportedOperationException("getSubSchemaMap");
}

/** Returns the name of the default sub-schema. */
public @Nullable String getDefaultSubSchemaName() {
return defaultSchemaName.get();
Expand Down
Loading

0 comments on commit bdd9a0a

Please sign in to comment.