This is an automated email from the ASF dual-hosted git repository.

cwylie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git


The following commit(s) were added to refs/heads/master by this push:
     new 392f0ca  refactor sql authorization to get resource type from schema, 
resource type to be string (#11692)
392f0ca is described below

commit 392f0ca1b52ee66aa8b3affed58eb117bb44d910
Author: Clint Wylie <[email protected]>
AuthorDate: Fri Sep 17 09:53:25 2021 -0700

    refactor sql authorization to get resource type from schema, resource type 
to be string (#11692)
    
    * refactor sql authorization to get resource type from schema, refactor 
resource type from enum to string
    
    * information schema auth filtering adjustments
    
    * refactor
    
    * minor stuff
    
    * Update SqlResourceCollectorShuttle.java
---
 .../apache/druid/benchmark/query/SqlBenchmark.java |   4 +-
 .../benchmark/query/SqlExpressionBenchmark.java    |   4 +-
 .../benchmark/query/SqlVsNativeBenchmark.java      |   4 +-
 .../authorization/BasicRoleBasedAuthorizer.java    |   3 +-
 .../apache/druid/security/BasicAuthUtilsTest.java  |  16 +--
 .../ranger/authorizer/RangerAuthorizer.java        |   2 +-
 .../druid/server/security/AuthorizationUtils.java  |  61 +++------
 .../org/apache/druid/server/security/Resource.java |  14 +--
 .../apache/druid/server/security/ResourceType.java |  48 +++++--
 .../server/security/AuthorizationUtilsTest.java    |  15 ++-
 .../druid/sql/calcite/planner/DruidPlanner.java    |   2 +-
 .../druid/sql/calcite/planner/PlannerContext.java  |  13 ++
 .../druid/sql/calcite/planner/PlannerFactory.java  |   7 +-
 .../planner/SqlResourceCollectorShuttle.java       |  15 ++-
 .../calcite/schema/DruidCalciteSchemaModule.java   |   7 +-
 .../sql/calcite/schema/DruidSchemaCatalog.java     | 138 +++++++++++++++++++++
 .../sql/calcite/schema/InformationSchema.java      |  72 ++++++-----
 .../druid/sql/calcite/schema/NamedDruidSchema.java |  11 +-
 .../sql/calcite/schema/NamedLookupSchema.java      |   4 +-
 .../druid/sql/calcite/schema/NamedSchema.java      |  13 ++
 .../sql/calcite/schema/NamedSystemSchema.java      |   6 +-
 .../druid/sql/calcite/schema/NamedViewSchema.java  |   9 +-
 .../sql/calcite/schema/RootSchemaProvider.java     |  31 ++---
 .../druid/sql/avatica/DruidAvaticaHandlerTest.java |  15 ++-
 .../druid/sql/avatica/DruidStatementTest.java      |   4 +-
 .../druid/sql/calcite/BaseCalciteQueryTest.java    |   4 +-
 .../calcite/SqlVectorizedExpressionSanityTest.java |   4 +-
 .../calcite/expression/ExpressionTestHelper.java   |  14 +++
 .../calcite/planner/CalcitePlannerModuleTest.java  |  12 +-
 .../schema/DruidCalciteSchemaModuleTest.java       |  17 ++-
 .../sql/calcite/schema/RootSchemaProviderTest.java |   7 +-
 .../druid/sql/calcite/util/CalciteTests.java       |  69 +++++++----
 .../org/apache/druid/sql/http/SqlResourceTest.java |   4 +-
 33 files changed, 441 insertions(+), 208 deletions(-)

diff --git 
a/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlBenchmark.java 
b/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlBenchmark.java
index 7d9a55d..12b717e 100644
--- 
a/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlBenchmark.java
+++ 
b/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlBenchmark.java
@@ -21,7 +21,6 @@ package org.apache.druid.benchmark.query;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
-import org.apache.calcite.schema.SchemaPlus;
 import org.apache.druid.common.config.NullHandling;
 import org.apache.druid.java.util.common.granularity.Granularities;
 import org.apache.druid.java.util.common.guava.Sequence;
@@ -46,6 +45,7 @@ import org.apache.druid.sql.calcite.planner.DruidPlanner;
 import org.apache.druid.sql.calcite.planner.PlannerConfig;
 import org.apache.druid.sql.calcite.planner.PlannerFactory;
 import org.apache.druid.sql.calcite.planner.PlannerResult;
+import org.apache.druid.sql.calcite.schema.DruidSchemaCatalog;
 import org.apache.druid.sql.calcite.util.CalciteTests;
 import org.apache.druid.sql.calcite.util.SpecificSegmentsQuerySegmentWalker;
 import org.apache.druid.timeline.DataSegment;
@@ -421,7 +421,7 @@ public class SqlBenchmark
     );
     closer.register(walker);
 
-    final SchemaPlus rootSchema =
+    final DruidSchemaCatalog rootSchema =
         CalciteTests.createMockRootSchema(conglomerate, walker, plannerConfig, 
AuthTestUtils.TEST_AUTHORIZER_MAPPER);
     plannerFactory = new PlannerFactory(
         rootSchema,
diff --git 
a/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlExpressionBenchmark.java
 
b/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlExpressionBenchmark.java
index cb5ce5f..3f99b24 100644
--- 
a/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlExpressionBenchmark.java
+++ 
b/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlExpressionBenchmark.java
@@ -21,7 +21,6 @@ package org.apache.druid.benchmark.query;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
-import org.apache.calcite.schema.SchemaPlus;
 import org.apache.druid.common.config.NullHandling;
 import org.apache.druid.java.util.common.granularity.Granularities;
 import org.apache.druid.java.util.common.guava.Sequence;
@@ -42,6 +41,7 @@ import org.apache.druid.sql.calcite.planner.DruidPlanner;
 import org.apache.druid.sql.calcite.planner.PlannerConfig;
 import org.apache.druid.sql.calcite.planner.PlannerFactory;
 import org.apache.druid.sql.calcite.planner.PlannerResult;
+import org.apache.druid.sql.calcite.schema.DruidSchemaCatalog;
 import org.apache.druid.sql.calcite.util.CalciteTests;
 import org.apache.druid.sql.calcite.util.SpecificSegmentsQuerySegmentWalker;
 import org.apache.druid.timeline.DataSegment;
@@ -264,7 +264,7 @@ public class SqlExpressionBenchmark
     );
     closer.register(walker);
 
-    final SchemaPlus rootSchema =
+    final DruidSchemaCatalog rootSchema =
         CalciteTests.createMockRootSchema(conglomerate, walker, plannerConfig, 
AuthTestUtils.TEST_AUTHORIZER_MAPPER);
     plannerFactory = new PlannerFactory(
         rootSchema,
diff --git 
a/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlVsNativeBenchmark.java
 
b/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlVsNativeBenchmark.java
index dda14ff..9e805d8 100644
--- 
a/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlVsNativeBenchmark.java
+++ 
b/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlVsNativeBenchmark.java
@@ -19,7 +19,6 @@
 
 package org.apache.druid.benchmark.query;
 
-import org.apache.calcite.schema.SchemaPlus;
 import org.apache.druid.common.config.NullHandling;
 import org.apache.druid.java.util.common.Intervals;
 import org.apache.druid.java.util.common.granularity.Granularities;
@@ -43,6 +42,7 @@ import org.apache.druid.sql.calcite.planner.DruidPlanner;
 import org.apache.druid.sql.calcite.planner.PlannerConfig;
 import org.apache.druid.sql.calcite.planner.PlannerFactory;
 import org.apache.druid.sql.calcite.planner.PlannerResult;
+import org.apache.druid.sql.calcite.schema.DruidSchemaCatalog;
 import org.apache.druid.sql.calcite.util.CalciteTests;
 import org.apache.druid.sql.calcite.util.SpecificSegmentsQuerySegmentWalker;
 import org.apache.druid.timeline.DataSegment;
@@ -111,7 +111,7 @@ public class SqlVsNativeBenchmark
     final PlannerConfig plannerConfig = new PlannerConfig();
 
     this.walker = closer.register(new 
SpecificSegmentsQuerySegmentWalker(conglomerate).add(dataSegment, index));
-    final SchemaPlus rootSchema =
+    final DruidSchemaCatalog rootSchema =
         CalciteTests.createMockRootSchema(conglomerate, walker, plannerConfig, 
AuthTestUtils.TEST_AUTHORIZER_MAPPER);
     plannerFactory = new PlannerFactory(
         rootSchema,
diff --git 
a/extensions-core/druid-basic-security/src/main/java/org/apache/druid/security/basic/authorization/BasicRoleBasedAuthorizer.java
 
b/extensions-core/druid-basic-security/src/main/java/org/apache/druid/security/basic/authorization/BasicRoleBasedAuthorizer.java
index f307b9e..206e895 100644
--- 
a/extensions-core/druid-basic-security/src/main/java/org/apache/druid/security/basic/authorization/BasicRoleBasedAuthorizer.java
+++ 
b/extensions-core/druid-basic-security/src/main/java/org/apache/druid/security/basic/authorization/BasicRoleBasedAuthorizer.java
@@ -36,6 +36,7 @@ import org.apache.druid.server.security.Resource;
 
 import java.util.HashSet;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -116,7 +117,7 @@ public class BasicRoleBasedAuthorizer implements Authorizer
     }
 
     Resource permissionResource = permission.getResourceAction().getResource();
-    if (permissionResource.getType() != resource.getType()) {
+    if (!Objects.equals(permissionResource.getType(), resource.getType())) {
       return false;
     }
 
diff --git 
a/extensions-core/druid-basic-security/src/test/java/org/apache/druid/security/BasicAuthUtilsTest.java
 
b/extensions-core/druid-basic-security/src/test/java/org/apache/druid/security/BasicAuthUtilsTest.java
index 7bcb1e2..60235fb 100644
--- 
a/extensions-core/druid-basic-security/src/test/java/org/apache/druid/security/BasicAuthUtilsTest.java
+++ 
b/extensions-core/druid-basic-security/src/test/java/org/apache/druid/security/BasicAuthUtilsTest.java
@@ -60,6 +60,7 @@ public class BasicAuthUtilsTest
     final String thirdRoleName = "third-role";
     final ResourceAction fooRead = new ResourceAction(new Resource("foo", 
ResourceType.DATASOURCE), Action.READ);
     final ResourceAction barRead = new ResourceAction(new Resource("bar", 
ResourceType.DATASOURCE), Action.READ);
+    final ResourceAction customRead = new ResourceAction(new Resource("bar", 
"CUSTOM"), Action.READ);
 
     final ObjectMapper mapper = TestHelper.makeJsonMapper();
     mapper.registerModules(new BasicSecurityDruidModule().getJacksonModules());
@@ -76,7 +77,7 @@ public class BasicAuthUtilsTest
           )
       )
     );
-    // bad ResourceType
+    // custom ResourceType
     rawMap.put(
         otherRoleName,
         ImmutableMap.of(
@@ -89,12 +90,7 @@ public class BasicAuthUtilsTest
                     "resourceNamePattern", "foo"
                 ),
                 ImmutableMap.of(
-                    "resourceAction",
-                    ImmutableMap.of(
-                        "resource",
-                        ImmutableMap.of("name", "bar", "type", "UNKNOWN"),
-                        "action", "READ"
-                    ),
+                    "resourceAction", customRead,
                     "resourceNamePattern", "bar"
                 )
             )
@@ -141,11 +137,11 @@ public class BasicAuthUtilsTest
         roleMap.get(someRoleName).getPermissions()
     );
 
-    // this one has an unknown ResourceType, expect only 1 permission to 
deserialize correctly and failure ignored
+    // this one has custom resource type... this test is somewhat pointless, 
it made more sense when type was an enum
     Assert.assertTrue(roleMap.containsKey(otherRoleName));
-    Assert.assertEquals(1, roleMap.get(otherRoleName).getPermissions().size());
+    Assert.assertEquals(2, roleMap.get(otherRoleName).getPermissions().size());
     Assert.assertEquals(
-        
BasicAuthorizerPermission.makePermissionList(ImmutableList.of(fooRead)),
+        BasicAuthorizerPermission.makePermissionList(ImmutableList.of(fooRead, 
customRead)),
         roleMap.get(otherRoleName).getPermissions()
     );
 
diff --git 
a/extensions-core/druid-ranger-security/src/main/java/org/apache/druid/security/ranger/authorizer/RangerAuthorizer.java
 
b/extensions-core/druid-ranger-security/src/main/java/org/apache/druid/security/ranger/authorizer/RangerAuthorizer.java
index 330a7c0..1d4bf15 100644
--- 
a/extensions-core/druid-ranger-security/src/main/java/org/apache/druid/security/ranger/authorizer/RangerAuthorizer.java
+++ 
b/extensions-core/druid-ranger-security/src/main/java/org/apache/druid/security/ranger/authorizer/RangerAuthorizer.java
@@ -126,7 +126,7 @@ class RangerDruidResource extends RangerAccessResourceImpl
 {
   public RangerDruidResource(Resource resource)
   {
-    setValue(resource.getType().name().toLowerCase(Locale.ENGLISH), 
resource.getName());
+    setValue(resource.getType().toLowerCase(Locale.ENGLISH), 
resource.getName());
   }
 }
 
diff --git 
a/server/src/main/java/org/apache/druid/server/security/AuthorizationUtils.java 
b/server/src/main/java/org/apache/druid/server/security/AuthorizationUtils.java
index 6ba34f6..2b44498 100644
--- 
a/server/src/main/java/org/apache/druid/server/security/AuthorizationUtils.java
+++ 
b/server/src/main/java/org/apache/druid/server/security/AuthorizationUtils.java
@@ -25,6 +25,7 @@ import com.google.common.collect.Lists;
 import org.apache.druid.java.util.common.ISE;
 
 import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -359,49 +360,27 @@ public class AuthorizationUtils
     return filteredResources;
   }
 
+  /**
+   * This method constructs a 'superuser' set of permissions composed of 
{@link Action#READ} and {@link Action#WRITE}
+   * permissions for all known {@link ResourceType#knownTypes()} for any 
{@link Authorizer} implementation which is
+   * built on pattern matching with a regex.
+   *
+   * Note that if any {@link Resource} exist that use custom types not 
registered with
+   * {@link ResourceType#registerResourceType}, those permissions will not be 
included in this list and will need to
+   * be added manually.
+   */
   public static List<ResourceAction> makeSuperUserPermissions()
   {
-    ResourceAction datasourceR = new ResourceAction(
-        new Resource(".*", ResourceType.DATASOURCE),
-        Action.READ
-    );
-
-    ResourceAction datasourceW = new ResourceAction(
-        new Resource(".*", ResourceType.DATASOURCE),
-        Action.WRITE
-    );
-
-    ResourceAction viewR = new ResourceAction(
-        new Resource(".*", ResourceType.VIEW),
-        Action.READ
-    );
-
-    ResourceAction viewW = new ResourceAction(
-        new Resource(".*", ResourceType.VIEW),
-        Action.WRITE
-    );
-
-    ResourceAction configR = new ResourceAction(
-        new Resource(".*", ResourceType.CONFIG),
-        Action.READ
-    );
-
-    ResourceAction configW = new ResourceAction(
-        new Resource(".*", ResourceType.CONFIG),
-        Action.WRITE
-    );
-
-    ResourceAction stateR = new ResourceAction(
-        new Resource(".*", ResourceType.STATE),
-        Action.READ
-    );
-
-    ResourceAction stateW = new ResourceAction(
-        new Resource(".*", ResourceType.STATE),
-        Action.WRITE
-    );
-
-    return Lists.newArrayList(datasourceR, datasourceW, viewR, viewW, configR, 
configW, stateR, stateW);
+    List<ResourceAction> allReadAndWrite = new 
ArrayList<>(ResourceType.knownTypes().size() * 2);
+    for (String type : ResourceType.knownTypes()) {
+      allReadAndWrite.add(
+          new ResourceAction(new Resource(".*", type), Action.READ)
+      );
+      allReadAndWrite.add(
+          new ResourceAction(new Resource(".*", type), Action.WRITE)
+      );
+    }
+    return allReadAndWrite;
   }
 
   /**
diff --git 
a/server/src/main/java/org/apache/druid/server/security/Resource.java 
b/server/src/main/java/org/apache/druid/server/security/Resource.java
index 6770bda..710673f 100644
--- a/server/src/main/java/org/apache/druid/server/security/Resource.java
+++ b/server/src/main/java/org/apache/druid/server/security/Resource.java
@@ -22,17 +22,19 @@ package org.apache.druid.server.security;
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
+import java.util.Objects;
+
 public class Resource
 {
   public static final Resource STATE_RESOURCE = new Resource("STATE", 
ResourceType.STATE);
 
   private final String name;
-  private final ResourceType type;
+  private final String type;
 
   @JsonCreator
   public Resource(
       @JsonProperty("name") String name,
-      @JsonProperty("type") ResourceType type
+      @JsonProperty("type") String type
   )
   {
     this.name = name;
@@ -46,7 +48,7 @@ public class Resource
   }
 
   @JsonProperty
-  public ResourceType getType()
+  public String getType()
   {
     return type;
   }
@@ -66,16 +68,14 @@ public class Resource
     if (!name.equals(resource.name)) {
       return false;
     }
-    return type == resource.type;
+    return Objects.equals(type, resource.type);
 
   }
 
   @Override
   public int hashCode()
   {
-    int result = name.hashCode();
-    result = 31 * result + type.hashCode();
-    return result;
+    return Objects.hash(name, type);
   }
 
   @Override
diff --git 
a/server/src/main/java/org/apache/druid/server/security/ResourceType.java 
b/server/src/main/java/org/apache/druid/server/security/ResourceType.java
index 04cf43a..0e02572 100644
--- a/server/src/main/java/org/apache/druid/server/security/ResourceType.java
+++ b/server/src/main/java/org/apache/druid/server/security/ResourceType.java
@@ -19,22 +19,44 @@
 
 package org.apache.druid.server.security;
 
-import com.fasterxml.jackson.annotation.JsonCreator;
-import org.apache.druid.java.util.common.StringUtils;
+import com.google.common.collect.Sets;
 
-public enum ResourceType
+import java.util.Set;
+
+/**
+ * Set of built-in and 'registered' {@link Resource} types for use by {@link 
Authorizer}
+ */
+public class ResourceType
 {
-  DATASOURCE,
-  VIEW,
-  CONFIG,
-  STATE;
+  public static final String DATASOURCE = "DATASOURCE";
+  public static final String VIEW = "VIEW";
+  public static final String CONFIG = "CONFIG";
+  public static final String STATE = "STATE";
+
+  private static final Set<String> KNOWN_TYPES = Sets.newConcurrentHashSet();
+
+  // initialize built-ins
+  static {
+    registerResourceType(DATASOURCE);
+    registerResourceType(VIEW);
+    registerResourceType(CONFIG);
+    registerResourceType(STATE);
+  }
+
+  /**
+   * Set of 'known' {@link Resource} types which have been registered with 
{@link #registerResourceType}, for use by
+   * utility methods looking to construct permission sets for all types (e.g. 
'superuser' permission set)
+   */
+  public static Set<String> knownTypes()
+  {
+    return KNOWN_TYPES;
+  }
 
-  @JsonCreator
-  public static ResourceType fromString(String name)
+  /**
+   * 'register' a 'known' type of {@link Resource} to make available via 
{@link #knownTypes()}
+   */
+  public static void registerResourceType(String type)
   {
-    if (name == null) {
-      return null;
-    }
-    return valueOf(StringUtils.toUpperCase(name));
+    KNOWN_TYPES.add(type);
   }
 }
diff --git 
a/server/src/test/java/org/apache/druid/server/security/AuthorizationUtilsTest.java
 
b/server/src/test/java/org/apache/druid/server/security/AuthorizationUtilsTest.java
index 8c6ec81..a9d87a4 100644
--- 
a/server/src/test/java/org/apache/druid/server/security/AuthorizationUtilsTest.java
+++ 
b/server/src/test/java/org/apache/druid/server/security/AuthorizationUtilsTest.java
@@ -30,6 +30,7 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 
 public class AuthorizationUtilsTest
 {
@@ -88,16 +89,26 @@ public class AuthorizationUtilsTest
   @Test
   public void testMakeSuperuserPermissions()
   {
+    final String customType = "CUSTOM";
+    ResourceType.registerResourceType(customType);
     final List<ResourceAction> permissions = 
AuthorizationUtils.makeSuperUserPermissions();
     // every type and action should have a wildcard pattern
-    for (ResourceType type : ResourceType.values()) {
+    for (String type : ResourceType.knownTypes()) {
       for (Action action : Action.values()) {
         Assert.assertTrue(
             permissions.stream()
-                       .filter(ra -> type == ra.getResource().getType())
+                       .filter(ra -> Objects.equals(type, 
ra.getResource().getType()))
                        .anyMatch(ra -> action == ra.getAction() && 
".*".equals(ra.getResource().getName()))
         );
       }
     }
+    // custom type should be there too
+    for (Action action : Action.values()) {
+      Assert.assertTrue(
+          permissions.stream()
+                     .filter(ra -> Objects.equals(customType, 
ra.getResource().getType()))
+                     .anyMatch(ra -> action == ra.getAction() && 
".*".equals(ra.getResource().getName()))
+      );
+    }
   }
 }
diff --git 
a/sql/src/main/java/org/apache/druid/sql/calcite/planner/DruidPlanner.java 
b/sql/src/main/java/org/apache/druid/sql/calcite/planner/DruidPlanner.java
index 1618e61..a1b9149 100644
--- a/sql/src/main/java/org/apache/druid/sql/calcite/planner/DruidPlanner.java
+++ b/sql/src/main/java/org/apache/druid/sql/calcite/planner/DruidPlanner.java
@@ -120,7 +120,7 @@ public class DruidPlanner implements Closeable
       throw new ValidationException(e);
     }
     SqlResourceCollectorShuttle resourceCollectorShuttle =
-        new SqlResourceCollectorShuttle(validator, 
frameworkConfig.getDefaultSchema().getName());
+        new SqlResourceCollectorShuttle(validator, plannerContext);
     validated.accept(resourceCollectorShuttle);
     plannerContext.setResources(resourceCollectorShuttle.getResources());
     return new ValidationResult(resourceCollectorShuttle.getResources());
diff --git 
a/sql/src/main/java/org/apache/druid/sql/calcite/planner/PlannerContext.java 
b/sql/src/main/java/org/apache/druid/sql/calcite/planner/PlannerContext.java
index 59d4bd8..0ec442e 100644
--- a/sql/src/main/java/org/apache/druid/sql/calcite/planner/PlannerContext.java
+++ b/sql/src/main/java/org/apache/druid/sql/calcite/planner/PlannerContext.java
@@ -33,10 +33,12 @@ import org.apache.druid.math.expr.ExprMacroTable;
 import org.apache.druid.server.security.Access;
 import org.apache.druid.server.security.AuthenticationResult;
 import org.apache.druid.server.security.Resource;
+import org.apache.druid.sql.calcite.schema.DruidSchemaCatalog;
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.joda.time.Interval;
 
+import javax.annotation.Nullable;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -68,6 +70,7 @@ public class PlannerContext
   private final ExprMacroTable macroTable;
   private final PlannerConfig plannerConfig;
   private final DateTime localNow;
+  private final DruidSchemaCatalog rootSchema;
   private final Map<String, Object> queryContext;
   private final String sqlQueryId;
   private final boolean stringifyArrays;
@@ -87,12 +90,14 @@ public class PlannerContext
       final PlannerConfig plannerConfig,
       final DateTime localNow,
       final boolean stringifyArrays,
+      final DruidSchemaCatalog rootSchema,
       final Map<String, Object> queryContext
   )
   {
     this.operatorTable = operatorTable;
     this.macroTable = macroTable;
     this.plannerConfig = Preconditions.checkNotNull(plannerConfig, 
"plannerConfig");
+    this.rootSchema = rootSchema;
     this.queryContext = queryContext != null ? new HashMap<>(queryContext) : 
new HashMap<>();
     this.localNow = Preconditions.checkNotNull(localNow, "localNow");
     this.stringifyArrays = stringifyArrays;
@@ -109,6 +114,7 @@ public class PlannerContext
       final DruidOperatorTable operatorTable,
       final ExprMacroTable macroTable,
       final PlannerConfig plannerConfig,
+      final DruidSchemaCatalog rootSchema,
       final Map<String, Object> queryContext
   )
   {
@@ -150,6 +156,7 @@ public class PlannerContext
         plannerConfig.withOverrides(queryContext),
         utcNow.withZone(timeZone),
         stringifyArrays,
+        rootSchema,
         queryContext
     );
   }
@@ -179,6 +186,12 @@ public class PlannerContext
     return localNow.getZone();
   }
 
+  @Nullable
+  public String getSchemaResourceType(String schema, String resourceName)
+  {
+    return rootSchema.getResourceType(schema, resourceName);
+  }
+
   public Map<String, Object> getQueryContext()
   {
     return queryContext;
diff --git 
a/sql/src/main/java/org/apache/druid/sql/calcite/planner/PlannerFactory.java 
b/sql/src/main/java/org/apache/druid/sql/calcite/planner/PlannerFactory.java
index 9f86eda..a96818e 100644
--- a/sql/src/main/java/org/apache/druid/sql/calcite/planner/PlannerFactory.java
+++ b/sql/src/main/java/org/apache/druid/sql/calcite/planner/PlannerFactory.java
@@ -29,7 +29,6 @@ import org.apache.calcite.config.CalciteConnectionConfigImpl;
 import org.apache.calcite.plan.Context;
 import org.apache.calcite.plan.ConventionTraitDef;
 import org.apache.calcite.rel.RelCollationTraitDef;
-import org.apache.calcite.schema.SchemaPlus;
 import org.apache.calcite.sql.parser.SqlParseException;
 import org.apache.calcite.sql.parser.SqlParser;
 import org.apache.calcite.sql.validate.SqlConformance;
@@ -44,6 +43,7 @@ import org.apache.druid.server.security.Access;
 import org.apache.druid.server.security.AuthorizerMapper;
 import org.apache.druid.server.security.NoopEscalator;
 import org.apache.druid.sql.calcite.rel.QueryMaker;
+import org.apache.druid.sql.calcite.schema.DruidSchemaCatalog;
 import org.apache.druid.sql.calcite.schema.DruidSchemaName;
 
 import java.util.Map;
@@ -60,7 +60,7 @@ public class PlannerFactory
       .setConformance(DruidConformance.instance())
       .build();
 
-  private final SchemaPlus rootSchema;
+  private final DruidSchemaCatalog rootSchema;
   private final QueryLifecycleFactory queryLifecycleFactory;
   private final DruidOperatorTable operatorTable;
   private final ExprMacroTable macroTable;
@@ -71,7 +71,7 @@ public class PlannerFactory
 
   @Inject
   public PlannerFactory(
-      final SchemaPlus rootSchema,
+      final DruidSchemaCatalog rootSchema,
       final QueryLifecycleFactory queryLifecycleFactory,
       final DruidOperatorTable operatorTable,
       final ExprMacroTable macroTable,
@@ -100,6 +100,7 @@ public class PlannerFactory
         operatorTable,
         macroTable,
         plannerConfig,
+        rootSchema,
         queryContext
     );
     final QueryMaker queryMaker = new QueryMaker(queryLifecycleFactory, 
plannerContext, jsonMapper);
diff --git 
a/sql/src/main/java/org/apache/druid/sql/calcite/planner/SqlResourceCollectorShuttle.java
 
b/sql/src/main/java/org/apache/druid/sql/calcite/planner/SqlResourceCollectorShuttle.java
index aba6689..a333b03 100644
--- 
a/sql/src/main/java/org/apache/druid/sql/calcite/planner/SqlResourceCollectorShuttle.java
+++ 
b/sql/src/main/java/org/apache/druid/sql/calcite/planner/SqlResourceCollectorShuttle.java
@@ -28,7 +28,6 @@ import org.apache.calcite.sql.validate.SqlValidatorNamespace;
 import org.apache.calcite.sql.validate.SqlValidatorTable;
 import org.apache.druid.server.security.Resource;
 import org.apache.druid.server.security.ResourceType;
-import org.apache.druid.sql.calcite.schema.NamedViewSchema;
 
 import java.util.HashSet;
 import java.util.List;
@@ -45,14 +44,14 @@ import java.util.Set;
 public class SqlResourceCollectorShuttle extends SqlShuttle
 {
   private final Set<Resource> resources;
+  private final PlannerContext plannerContext;
   private final SqlValidator validator;
-  private final String druidSchemaName;
 
-  public SqlResourceCollectorShuttle(SqlValidator validator, String 
druidSchemaName)
+  public SqlResourceCollectorShuttle(SqlValidator validator, PlannerContext 
plannerContext)
   {
     this.validator = validator;
     this.resources = new HashSet<>();
-    this.druidSchemaName = druidSchemaName;
+    this.plannerContext = plannerContext;
   }
 
   @Override
@@ -69,10 +68,10 @@ public class SqlResourceCollectorShuttle extends SqlShuttle
         // 'schema'.'identifier'
         if (qualifiedNameParts.size() == 2) {
           final String schema = qualifiedNameParts.get(0);
-          if (druidSchemaName.equals(schema)) {
-            resources.add(new Resource(qualifiedNameParts.get(1), 
ResourceType.DATASOURCE));
-          } else if (NamedViewSchema.NAME.equals(schema)) {
-            resources.add(new Resource(qualifiedNameParts.get(1), 
ResourceType.VIEW));
+          final String resourceName = qualifiedNameParts.get(1);
+          final String resourceType = 
plannerContext.getSchemaResourceType(schema, resourceName);
+          if (resourceType != null) {
+            resources.add(new Resource(resourceName, resourceType));
           }
         }
       }
diff --git 
a/sql/src/main/java/org/apache/druid/sql/calcite/schema/DruidCalciteSchemaModule.java
 
b/sql/src/main/java/org/apache/druid/sql/calcite/schema/DruidCalciteSchemaModule.java
index 43e8ad7..0a8de29 100644
--- 
a/sql/src/main/java/org/apache/druid/sql/calcite/schema/DruidCalciteSchemaModule.java
+++ 
b/sql/src/main/java/org/apache/druid/sql/calcite/schema/DruidCalciteSchemaModule.java
@@ -26,7 +26,6 @@ import com.google.inject.Scopes;
 import com.google.inject.Singleton;
 import com.google.inject.name.Named;
 import com.google.inject.name.Names;
-import org.apache.calcite.schema.SchemaPlus;
 import org.apache.druid.guice.LifecycleModule;
 import org.apache.druid.sql.guice.SqlBindings;
 
@@ -45,7 +44,7 @@ public class DruidCalciteSchemaModule implements Module
     
binder.bind(String.class).annotatedWith(DruidSchemaName.class).toInstance(DRUID_SCHEMA_NAME);
 
     // Should only be used by the information schema
-    binder.bind(SchemaPlus.class)
+    binder.bind(DruidSchemaCatalog.class)
           .annotatedWith(Names.named(INCOMPLETE_SCHEMA))
           .toProvider(RootSchemaProvider.class)
           .in(Scopes.SINGLETON);
@@ -65,9 +64,9 @@ public class DruidCalciteSchemaModule implements Module
 
   @Provides
   @Singleton
-  private SchemaPlus getRootSchema(@Named(INCOMPLETE_SCHEMA) SchemaPlus 
rootSchema, InformationSchema informationSchema)
+  private DruidSchemaCatalog getRootSchema(@Named(INCOMPLETE_SCHEMA) 
DruidSchemaCatalog rootSchema, InformationSchema informationSchema)
   {
-    rootSchema.add(INFORMATION_SCHEMA_NAME, informationSchema);
+    rootSchema.getRootSchema().add(INFORMATION_SCHEMA_NAME, informationSchema);
     return rootSchema;
   }
 }
diff --git 
a/sql/src/main/java/org/apache/druid/sql/calcite/schema/DruidSchemaCatalog.java 
b/sql/src/main/java/org/apache/druid/sql/calcite/schema/DruidSchemaCatalog.java
new file mode 100644
index 0000000..34f15af
--- /dev/null
+++ 
b/sql/src/main/java/org/apache/druid/sql/calcite/schema/DruidSchemaCatalog.java
@@ -0,0 +1,138 @@
+/*
+ * 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.druid.sql.calcite.schema;
+
+import org.apache.calcite.schema.SchemaPlus;
+
+import javax.annotation.Nullable;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * The Druid 'catalog', containing information about all Druid schemas which 
are available. This packages both the 'root
+ * level' Calcite {@link SchemaPlus} and a map of the {@link NamedSchema} 
which were used to populate it, keyed by
+ * {@link NamedSchema#getSchemaName()}.
+ *
+ * The {@link #rootSchema} is a top level Calcite schema, which contains all 
{@link NamedSchema#getSchema()} and
+ * {@link InformationSchema} added as sub-schemas, and this class provides 
convenience methods to do things like
+ * fetch a specific {@link SchemaPlus} by name or list the set of all schemas 
available, and is used during query
+ * planning and execution.
+ *
+ * {@link #namedSchemas} contains all {@link NamedSchema}, which should be 
everything except {@link InformationSchema}.
+ * These are used primarily for {@link #getResourceType(String, String)}, 
which given the name of a table or function
+ * that belongs to some {@link NamedSchema}, lookup the most appropriate value 
to use for
+ * {@link org.apache.druid.server.security.Resource#getType()} to use for 
authorization.
+ */
+public class DruidSchemaCatalog
+{
+  private final SchemaPlus rootSchema;
+  private final Map<String, NamedSchema> namedSchemas;
+
+  public DruidSchemaCatalog(
+      SchemaPlus rootSchema,
+      Map<String, NamedSchema> schemas
+  )
+  {
+    this.rootSchema = rootSchema;
+    this.namedSchemas = schemas;
+  }
+
+  /**
+   * Root calcite schema, used to plan and execute queries
+   */
+  public SchemaPlus getRootSchema()
+  {
+    return rootSchema;
+  }
+
+  /**
+   * Get all {@link NamedSchema} which belong to the Druid catalog
+   */
+  public Map<String, NamedSchema> getNamedSchemas()
+  {
+    return namedSchemas;
+  }
+
+  /**
+   * Get a {@link NamedSchema} by {@link NamedSchema#getSchemaName()}
+   */
+  public NamedSchema getNamedSchema(String schemaName)
+  {
+    return namedSchemas.get(schemaName);
+  }
+
+  /**
+   * Get a specific {@link SchemaPlus} by {@link NamedSchema#getSchemaName()}
+   */
+  public SchemaPlus getSubSchema(String name)
+  {
+    return rootSchema.getSubSchema(name);
+  }
+
+  /**
+   * Get all sub-schemas defined on {@link #rootSchema}
+   */
+  public Set<String> getSubSchemaNames()
+  {
+    return rootSchema.getSubSchemaNames();
+  }
+
+  /**
+   * Given the name of a {@link NamedSchema} and the name of a table or 
function that belongs to that schema, return
+   * the appropriate value to use for {@link 
org.apache.druid.server.security.Resource#getType()} during authorization
+   */
+  @Nullable
+  public String getResourceType(String schema, String resourceName)
+  {
+    if (namedSchemas.containsKey(schema)) {
+      return namedSchemas.get(schema).getSchemaResourceType(resourceName);
+    }
+    return null;
+  }
+
+
+  @Override
+  public boolean equals(Object o)
+  {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    DruidSchemaCatalog that = (DruidSchemaCatalog) o;
+    return rootSchema.equals(that.rootSchema) && 
namedSchemas.equals(that.namedSchemas);
+  }
+
+  @Override
+  public int hashCode()
+  {
+    return Objects.hash(rootSchema, namedSchemas);
+  }
+
+  @Override
+  public String toString()
+  {
+    return "DruidSchemaCatalog{" +
+           "schemas=" + getSubSchemaNames() +
+           '}';
+  }
+}
diff --git 
a/sql/src/main/java/org/apache/druid/sql/calcite/schema/InformationSchema.java 
b/sql/src/main/java/org/apache/druid/sql/calcite/schema/InformationSchema.java
index 9aa411b..96fe42c 100644
--- 
a/sql/src/main/java/org/apache/druid/sql/calcite/schema/InformationSchema.java
+++ 
b/sql/src/main/java/org/apache/druid/sql/calcite/schema/InformationSchema.java
@@ -23,7 +23,6 @@ import com.google.common.base.Function;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Predicates;
 import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
@@ -49,9 +48,11 @@ import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.druid.java.util.emitter.EmittingLogger;
 import org.apache.druid.segment.column.RowSignature;
 import org.apache.druid.segment.column.ValueType;
+import org.apache.druid.server.security.Action;
 import org.apache.druid.server.security.AuthenticationResult;
 import org.apache.druid.server.security.AuthorizationUtils;
 import org.apache.druid.server.security.AuthorizerMapper;
+import org.apache.druid.server.security.Resource;
 import org.apache.druid.server.security.ResourceAction;
 import org.apache.druid.sql.calcite.planner.PlannerContext;
 import org.apache.druid.sql.calcite.table.DruidTable;
@@ -111,26 +112,18 @@ public class InformationSchema extends AbstractSchema
       .add("JDBC_TYPE", ValueType.LONG)
       .build();
   private static final RelDataTypeSystem TYPE_SYSTEM = 
RelDataTypeSystem.DEFAULT;
-  private static final Function<String, Iterable<ResourceAction>> 
DRUID_TABLE_RA_GENERATOR = datasourceName -> {
-    return 
Collections.singletonList(AuthorizationUtils.DATASOURCE_READ_RA_GENERATOR.apply(datasourceName));
-  };
-  private static final Function<String, Iterable<ResourceAction>> 
VIEW_TABLE_RA_GENERATOR = viewName -> {
-    return 
Collections.singletonList(AuthorizationUtils.VIEW_READ_RA_GENERATOR.apply(viewName));
-  };
 
   private static final String INFO_TRUE = "YES";
   private static final String INFO_FALSE = "NO";
 
-  private final SchemaPlus rootSchema;
+  private final DruidSchemaCatalog rootSchema;
   private final Map<String, Table> tableMap;
   private final AuthorizerMapper authorizerMapper;
-  private final String druidSchemaName;
 
   @Inject
   public InformationSchema(
-      @Named(DruidCalciteSchemaModule.INCOMPLETE_SCHEMA) final SchemaPlus 
rootSchema,
-      final AuthorizerMapper authorizerMapper,
-      @DruidSchemaName String druidSchemaName
+      @Named(DruidCalciteSchemaModule.INCOMPLETE_SCHEMA) final 
DruidSchemaCatalog rootSchema,
+      final AuthorizerMapper authorizerMapper
   )
   {
     this.rootSchema = Preconditions.checkNotNull(rootSchema, "rootSchema");
@@ -140,7 +133,6 @@ public class InformationSchema extends AbstractSchema
         COLUMNS_TABLE, new ColumnsTable()
     );
     this.authorizerMapper = authorizerMapper;
-    this.druidSchemaName = druidSchemaName;
   }
 
   @Override
@@ -364,7 +356,7 @@ public class InformationSchema extends AbstractSchema
                                         return generateColumnMetadata(
                                             schemaName,
                                             functionName,
-                                            
viewMacro.apply(ImmutableList.of()),
+                                            
viewMacro.apply(Collections.emptyList()),
                                             typeFactory
                                         );
                                       }
@@ -483,20 +475,11 @@ public class InformationSchema extends AbstractSchema
       final AuthenticationResult authenticationResult
   )
   {
-    if (druidSchemaName.equals(subSchema.getName())) {
-      // The "druid" schema's tables represent Druid datasources which require 
authorization
-      return ImmutableSet.copyOf(
-          AuthorizationUtils.filterAuthorizedResources(
-              authenticationResult,
-              subSchema.getTableNames(),
-              DRUID_TABLE_RA_GENERATOR,
-              authorizerMapper
-          )
-      );
-    } else {
-      // for non "druid" schema, we don't filter anything
-      return subSchema.getTableNames();
-    }
+    return getAuthorizedNamesFromNamedSchema(
+        authenticationResult,
+        rootSchema.getNamedSchema(subSchema.getName()),
+        subSchema.getTableNames()
+    );
   }
 
   private Set<String> getAuthorizedFunctionNamesFromSubSchema(
@@ -504,19 +487,40 @@ public class InformationSchema extends AbstractSchema
       final AuthenticationResult authenticationResult
   )
   {
-    if (NamedViewSchema.NAME.equals(subSchema.getName())) {
-      // The "view" subschema functions represent views on Druid datasources
+    return getAuthorizedNamesFromNamedSchema(
+        authenticationResult,
+        rootSchema.getNamedSchema(subSchema.getName()),
+        subSchema.getFunctionNames()
+    );
+  }
+
+  private Set<String> getAuthorizedNamesFromNamedSchema(
+      final AuthenticationResult authenticationResult,
+      final NamedSchema schema,
+      final Set<String> names
+  )
+  {
+    if (schema != null) {
       return ImmutableSet.copyOf(
           AuthorizationUtils.filterAuthorizedResources(
               authenticationResult,
-              subSchema.getFunctionNames(),
-              VIEW_TABLE_RA_GENERATOR,
+              names,
+              name -> {
+                final String resoureType = schema.getSchemaResourceType(name);
+                if (resoureType != null) {
+                  return Collections.singletonList(
+                      new ResourceAction(new Resource(name, resoureType), 
Action.READ)
+                  );
+                } else {
+                  return Collections.emptyList();
+                }
+              },
               authorizerMapper
           )
       );
     } else {
-      // for non "druid" schema, we don't filter anything
-      return subSchema.getFunctionNames();
+      // for schemas with no resource type, or that are not named schemas, we 
don't filter anything
+      return names;
     }
   }
 }
diff --git 
a/sql/src/main/java/org/apache/druid/sql/calcite/schema/NamedDruidSchema.java 
b/sql/src/main/java/org/apache/druid/sql/calcite/schema/NamedDruidSchema.java
index a48ccf2..2e8de70 100644
--- 
a/sql/src/main/java/org/apache/druid/sql/calcite/schema/NamedDruidSchema.java
+++ 
b/sql/src/main/java/org/apache/druid/sql/calcite/schema/NamedDruidSchema.java
@@ -21,17 +21,18 @@ package org.apache.druid.sql.calcite.schema;
 
 import com.google.inject.Inject;
 import org.apache.calcite.schema.Schema;
+import org.apache.druid.server.security.ResourceType;
 
 /**
  * The schema for Druid tables to be accessible via SQL.
  */
-class NamedDruidSchema implements NamedSchema
+public class NamedDruidSchema implements NamedSchema
 {
   private final DruidSchema druidSchema;
   private final String druidSchemaName;
 
   @Inject
-  NamedDruidSchema(DruidSchema druidSchema, @DruidSchemaName String 
druidSchemaName)
+  public NamedDruidSchema(DruidSchema druidSchema, @DruidSchemaName String 
druidSchemaName)
   {
     this.druidSchema = druidSchema;
     this.druidSchemaName = druidSchemaName;
@@ -44,6 +45,12 @@ class NamedDruidSchema implements NamedSchema
   }
 
   @Override
+  public String getSchemaResourceType(String resourceName)
+  {
+    return ResourceType.DATASOURCE;
+  }
+
+  @Override
   public Schema getSchema()
   {
     return druidSchema;
diff --git 
a/sql/src/main/java/org/apache/druid/sql/calcite/schema/NamedLookupSchema.java 
b/sql/src/main/java/org/apache/druid/sql/calcite/schema/NamedLookupSchema.java
index a144866..eb91949 100644
--- 
a/sql/src/main/java/org/apache/druid/sql/calcite/schema/NamedLookupSchema.java
+++ 
b/sql/src/main/java/org/apache/druid/sql/calcite/schema/NamedLookupSchema.java
@@ -27,12 +27,12 @@ import org.apache.calcite.schema.Schema;
  */
 public class NamedLookupSchema implements NamedSchema
 {
-  private static final String NAME = "lookup";
+  public static final String NAME = "lookup";
 
   private final LookupSchema lookupSchema;
 
   @Inject
-  NamedLookupSchema(LookupSchema lookupSchema)
+  public NamedLookupSchema(LookupSchema lookupSchema)
   {
     this.lookupSchema = lookupSchema;
   }
diff --git 
a/sql/src/main/java/org/apache/druid/sql/calcite/schema/NamedSchema.java 
b/sql/src/main/java/org/apache/druid/sql/calcite/schema/NamedSchema.java
index c4ba827..da951aa 100644
--- a/sql/src/main/java/org/apache/druid/sql/calcite/schema/NamedSchema.java
+++ b/sql/src/main/java/org/apache/druid/sql/calcite/schema/NamedSchema.java
@@ -21,6 +21,8 @@ package org.apache.druid.sql.calcite.schema;
 
 import org.apache.calcite.schema.Schema;
 
+import javax.annotation.Nullable;
+
 /**
  * This interface provides everything that is needed to register a {@link 
Schema} as a sub schema to the root schema
  * of Druid SQL. The {@link #getSchemaName()} will be used to access the 
provided {@link Schema} via SQL.
@@ -33,6 +35,17 @@ public interface NamedSchema
   String getSchemaName();
 
   /**
+   * For a given name of a table, function, etc of this schema, return the 
value most appropriate to use for
+   * {@link org.apache.druid.server.security.Resource#getType()} for the 
resource, used during authorization. If this
+   * method returns null then the resource does not need any authorization.
+   */
+  @Nullable
+  default String getSchemaResourceType(String resourceName)
+  {
+    return null;
+  }
+
+  /**
    * @return The Schema that Calcite should use.
    */
   Schema getSchema();
diff --git 
a/sql/src/main/java/org/apache/druid/sql/calcite/schema/NamedSystemSchema.java 
b/sql/src/main/java/org/apache/druid/sql/calcite/schema/NamedSystemSchema.java
index 1bb0223..3d42f47 100644
--- 
a/sql/src/main/java/org/apache/druid/sql/calcite/schema/NamedSystemSchema.java
+++ 
b/sql/src/main/java/org/apache/druid/sql/calcite/schema/NamedSystemSchema.java
@@ -25,14 +25,14 @@ import org.apache.calcite.schema.Schema;
 /**
  * The schema for Druid system tables to be accessible via SQL.
  */
-class NamedSystemSchema implements NamedSchema
+public class NamedSystemSchema implements NamedSchema
 {
-  private static final String NAME = "sys";
+  public static final String NAME = "sys";
 
   private final SystemSchema systemSchema;
 
   @Inject
-  NamedSystemSchema(SystemSchema systemSchema)
+  public NamedSystemSchema(SystemSchema systemSchema)
   {
     this.systemSchema = systemSchema;
   }
diff --git 
a/sql/src/main/java/org/apache/druid/sql/calcite/schema/NamedViewSchema.java 
b/sql/src/main/java/org/apache/druid/sql/calcite/schema/NamedViewSchema.java
index 06959af..fb6ae9c 100644
--- a/sql/src/main/java/org/apache/druid/sql/calcite/schema/NamedViewSchema.java
+++ b/sql/src/main/java/org/apache/druid/sql/calcite/schema/NamedViewSchema.java
@@ -21,6 +21,7 @@ package org.apache.druid.sql.calcite.schema;
 
 import com.google.inject.Inject;
 import org.apache.calcite.schema.Schema;
+import org.apache.druid.server.security.ResourceType;
 
 public class NamedViewSchema implements NamedSchema
 {
@@ -28,7 +29,7 @@ public class NamedViewSchema implements NamedSchema
   private final ViewSchema viewSchema;
 
   @Inject
-  NamedViewSchema(ViewSchema viewSchema)
+  public NamedViewSchema(ViewSchema viewSchema)
   {
     this.viewSchema = viewSchema;
   }
@@ -40,6 +41,12 @@ public class NamedViewSchema implements NamedSchema
   }
 
   @Override
+  public String getSchemaResourceType(String resourceName)
+  {
+    return ResourceType.VIEW;
+  }
+
+  @Override
   public Schema getSchema()
   {
     return viewSchema;
diff --git 
a/sql/src/main/java/org/apache/druid/sql/calcite/schema/RootSchemaProvider.java 
b/sql/src/main/java/org/apache/druid/sql/calcite/schema/RootSchemaProvider.java
index 595e7ae..0c61763 100644
--- 
a/sql/src/main/java/org/apache/druid/sql/calcite/schema/RootSchemaProvider.java
+++ 
b/sql/src/main/java/org/apache/druid/sql/calcite/schema/RootSchemaProvider.java
@@ -19,14 +19,15 @@
 
 package org.apache.druid.sql.calcite.schema;
 
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import org.apache.calcite.jdbc.CalciteSchema;
 import org.apache.calcite.schema.SchemaPlus;
 import org.apache.druid.java.util.common.ISE;
 
-import java.util.HashSet;
-import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
 
@@ -37,7 +38,7 @@ import java.util.stream.Collectors;
  *
  * All the provided schema are added to the rootSchema.
  */
-public class RootSchemaProvider implements Provider<SchemaPlus>
+public class RootSchemaProvider implements Provider<DruidSchemaCatalog>
 {
   private final Set<NamedSchema> namedSchemas;
 
@@ -48,18 +49,20 @@ public class RootSchemaProvider implements 
Provider<SchemaPlus>
   }
 
   @Override
-  public SchemaPlus get()
+  public DruidSchemaCatalog get()
   {
-    SchemaPlus rootSchema = CalciteSchema.createRootSchema(false, 
false).plus();
-    List<String> schemaNames = namedSchemas.stream()
-                                           .map(NamedSchema::getSchemaName)
-                                           .collect(Collectors.toList());
-    Set<String> uniqueSchemaNames = new HashSet<>(schemaNames);
-    if (uniqueSchemaNames.size() < schemaNames.size()) {
-      throw new ISE("Found multiple schemas registered to the same name. "
-                    + "The list of registered schemas are %s", schemaNames);
+    final SchemaPlus rootSchema = CalciteSchema.createRootSchema(false, 
false).plus();
+    final Map<String, NamedSchema> schemasByName = 
Maps.newHashMapWithExpectedSize(namedSchemas.size());
+    for (NamedSchema schema : namedSchemas) {
+      if (schemasByName.containsKey(schema.getSchemaName())) {
+        throw new ISE(
+            "Found multiple schemas registered to the same name. The list of 
registered schemas are %s",
+            
namedSchemas.stream().map(NamedSchema::getSchemaName).collect(Collectors.toList())
+        );
+      }
+      schemasByName.put(schema.getSchemaName(), schema);
+      rootSchema.add(schema.getSchemaName(), schema.getSchema());
     }
-    namedSchemas.forEach(schema -> rootSchema.add(schema.getSchemaName(), 
schema.getSchema()));
-    return rootSchema;
+    return new DruidSchemaCatalog(rootSchema, 
ImmutableMap.copyOf(schemasByName));
   }
 }
diff --git 
a/sql/src/test/java/org/apache/druid/sql/avatica/DruidAvaticaHandlerTest.java 
b/sql/src/test/java/org/apache/druid/sql/avatica/DruidAvaticaHandlerTest.java
index 3278bb6..3934665 100644
--- 
a/sql/src/test/java/org/apache/druid/sql/avatica/DruidAvaticaHandlerTest.java
+++ 
b/sql/src/test/java/org/apache/druid/sql/avatica/DruidAvaticaHandlerTest.java
@@ -30,13 +30,13 @@ import com.google.common.util.concurrent.MoreExecutors;
 import com.google.inject.Binder;
 import com.google.inject.Injector;
 import com.google.inject.Module;
+import com.google.inject.multibindings.Multibinder;
 import com.google.inject.name.Names;
 import org.apache.calcite.avatica.AvaticaClientRuntimeException;
 import org.apache.calcite.avatica.Meta;
 import org.apache.calcite.avatica.MissingResultsException;
 import org.apache.calcite.avatica.NoSuchStatementException;
 import org.apache.calcite.avatica.server.AbstractAvaticaHandler;
-import org.apache.calcite.schema.SchemaPlus;
 import org.apache.druid.common.config.NullHandling;
 import org.apache.druid.guice.GuiceInjectors;
 import org.apache.druid.guice.LazySingleton;
@@ -64,7 +64,9 @@ import org.apache.druid.sql.calcite.planner.Calcites;
 import org.apache.druid.sql.calcite.planner.DruidOperatorTable;
 import org.apache.druid.sql.calcite.planner.PlannerConfig;
 import org.apache.druid.sql.calcite.planner.PlannerFactory;
+import org.apache.druid.sql.calcite.schema.DruidSchemaCatalog;
 import org.apache.druid.sql.calcite.schema.DruidSchemaName;
+import org.apache.druid.sql.calcite.schema.NamedSchema;
 import org.apache.druid.sql.calcite.util.CalciteTestBase;
 import org.apache.druid.sql.calcite.util.CalciteTests;
 import org.apache.druid.sql.calcite.util.QueryLogHook;
@@ -168,7 +170,7 @@ public abstract class DruidAvaticaHandlerTest extends 
CalciteTestBase
     final PlannerConfig plannerConfig = new PlannerConfig();
     final DruidOperatorTable operatorTable = 
CalciteTests.createOperatorTable();
     final ExprMacroTable macroTable = CalciteTests.createExprMacroTable();
-    final SchemaPlus rootSchema =
+    final DruidSchemaCatalog rootSchema =
         CalciteTests.createMockRootSchema(conglomerate, walker, plannerConfig, 
CalciteTests.TEST_AUTHORIZER_MAPPER);
     testRequestLogger = new TestRequestLogger();
 
@@ -187,7 +189,10 @@ public abstract class DruidAvaticaHandlerTest extends 
CalciteTestBase
                 
binder.bind(AuthorizerMapper.class).toInstance(CalciteTests.TEST_AUTHORIZER_MAPPER);
                 
binder.bind(Escalator.class).toInstance(CalciteTests.TEST_AUTHENTICATOR_ESCALATOR);
                 binder.bind(RequestLogger.class).toInstance(testRequestLogger);
-                binder.bind(SchemaPlus.class).toInstance(rootSchema);
+                binder.bind(DruidSchemaCatalog.class).toInstance(rootSchema);
+                for (NamedSchema schema : 
rootSchema.getNamedSchemas().values()) {
+                  Multibinder.newSetBinder(binder, 
NamedSchema.class).addBinding().toInstance(schema);
+                }
                 binder.bind(QueryLifecycleFactory.class)
                       
.toInstance(CalciteTests.createMockQueryLifecycleFactory(walker, conglomerate));
                 
binder.bind(DruidOperatorTable.class).toInstance(operatorTable);
@@ -865,7 +870,7 @@ public abstract class DruidAvaticaHandlerTest extends 
CalciteTestBase
     final DruidOperatorTable operatorTable = 
CalciteTests.createOperatorTable();
     final ExprMacroTable macroTable = CalciteTests.createExprMacroTable();
     final List<Meta.Frame> frames = new ArrayList<>();
-    SchemaPlus rootSchema =
+    DruidSchemaCatalog rootSchema =
         CalciteTests.createMockRootSchema(conglomerate, walker, plannerConfig, 
AuthTestUtils.TEST_AUTHORIZER_MAPPER);
     DruidMeta smallFrameDruidMeta = new DruidMeta(
         CalciteTests.createSqlLifecycleFactory(
@@ -954,7 +959,7 @@ public abstract class DruidAvaticaHandlerTest extends 
CalciteTestBase
     final DruidOperatorTable operatorTable = 
CalciteTests.createOperatorTable();
     final ExprMacroTable macroTable = CalciteTests.createExprMacroTable();
     final List<Meta.Frame> frames = new ArrayList<>();
-    SchemaPlus rootSchema =
+    DruidSchemaCatalog rootSchema =
         CalciteTests.createMockRootSchema(conglomerate, walker, plannerConfig, 
AuthTestUtils.TEST_AUTHORIZER_MAPPER);
     DruidMeta smallFrameDruidMeta = new DruidMeta(
         CalciteTests.createSqlLifecycleFactory(
diff --git 
a/sql/src/test/java/org/apache/druid/sql/avatica/DruidStatementTest.java 
b/sql/src/test/java/org/apache/druid/sql/avatica/DruidStatementTest.java
index 4400286..fbfc2f1 100644
--- a/sql/src/test/java/org/apache/druid/sql/avatica/DruidStatementTest.java
+++ b/sql/src/test/java/org/apache/druid/sql/avatica/DruidStatementTest.java
@@ -23,7 +23,6 @@ import com.google.common.base.Function;
 import com.google.common.collect.Lists;
 import org.apache.calcite.avatica.ColumnMetaData;
 import org.apache.calcite.avatica.Meta;
-import org.apache.calcite.schema.SchemaPlus;
 import org.apache.druid.common.config.NullHandling;
 import org.apache.druid.java.util.common.DateTimes;
 import org.apache.druid.java.util.common.io.Closer;
@@ -36,6 +35,7 @@ import org.apache.druid.sql.SqlLifecycleFactory;
 import org.apache.druid.sql.calcite.planner.DruidOperatorTable;
 import org.apache.druid.sql.calcite.planner.PlannerConfig;
 import org.apache.druid.sql.calcite.planner.PlannerFactory;
+import org.apache.druid.sql.calcite.schema.DruidSchemaCatalog;
 import org.apache.druid.sql.calcite.util.CalciteTestBase;
 import org.apache.druid.sql.calcite.util.CalciteTests;
 import org.apache.druid.sql.calcite.util.QueryLogHook;
@@ -87,7 +87,7 @@ public class DruidStatementTest extends CalciteTestBase
     final PlannerConfig plannerConfig = new PlannerConfig();
     final DruidOperatorTable operatorTable = 
CalciteTests.createOperatorTable();
     final ExprMacroTable macroTable = CalciteTests.createExprMacroTable();
-    SchemaPlus rootSchema =
+    DruidSchemaCatalog rootSchema =
         CalciteTests.createMockRootSchema(conglomerate, walker, plannerConfig, 
AuthTestUtils.TEST_AUTHORIZER_MAPPER);
     final PlannerFactory plannerFactory = new PlannerFactory(
         rootSchema,
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/BaseCalciteQueryTest.java 
b/sql/src/test/java/org/apache/druid/sql/calcite/BaseCalciteQueryTest.java
index 876ea5c..45f0eb1 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/BaseCalciteQueryTest.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/BaseCalciteQueryTest.java
@@ -23,7 +23,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import org.apache.calcite.plan.RelOptPlanner;
-import org.apache.calcite.schema.SchemaPlus;
 import org.apache.druid.annotations.UsedByJUnitParamsRunner;
 import org.apache.druid.common.config.NullHandling;
 import org.apache.druid.hll.VersionOneHyperLogLogCollector;
@@ -80,6 +79,7 @@ import 
org.apache.druid.sql.calcite.planner.DruidOperatorTable;
 import org.apache.druid.sql.calcite.planner.PlannerConfig;
 import org.apache.druid.sql.calcite.planner.PlannerContext;
 import org.apache.druid.sql.calcite.planner.PlannerFactory;
+import org.apache.druid.sql.calcite.schema.DruidSchemaCatalog;
 import org.apache.druid.sql.calcite.util.CalciteTestBase;
 import org.apache.druid.sql.calcite.util.CalciteTests;
 import org.apache.druid.sql.calcite.util.QueryLogHook;
@@ -896,7 +896,7 @@ public class BaseCalciteQueryTest extends CalciteTestBase
   {
     final InProcessViewManager viewManager =
         new InProcessViewManager(CalciteTests.TEST_AUTHENTICATOR_ESCALATOR, 
CalciteTests.DRUID_VIEW_MACRO_FACTORY);
-    SchemaPlus rootSchema = CalciteTests.createMockRootSchema(
+    DruidSchemaCatalog rootSchema = CalciteTests.createMockRootSchema(
         conglomerate,
         walker,
         plannerConfig,
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/SqlVectorizedExpressionSanityTest.java
 
b/sql/src/test/java/org/apache/druid/sql/calcite/SqlVectorizedExpressionSanityTest.java
index de788fa..337ffd2 100644
--- 
a/sql/src/test/java/org/apache/druid/sql/calcite/SqlVectorizedExpressionSanityTest.java
+++ 
b/sql/src/test/java/org/apache/druid/sql/calcite/SqlVectorizedExpressionSanityTest.java
@@ -21,7 +21,6 @@ package org.apache.druid.sql.calcite;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
-import org.apache.calcite.schema.SchemaPlus;
 import org.apache.calcite.sql.parser.SqlParseException;
 import org.apache.calcite.tools.RelConversionException;
 import org.apache.calcite.tools.ValidationException;
@@ -45,6 +44,7 @@ import org.apache.druid.sql.calcite.planner.DruidPlanner;
 import org.apache.druid.sql.calcite.planner.PlannerConfig;
 import org.apache.druid.sql.calcite.planner.PlannerFactory;
 import org.apache.druid.sql.calcite.planner.PlannerResult;
+import org.apache.druid.sql.calcite.schema.DruidSchemaCatalog;
 import org.apache.druid.sql.calcite.util.CalciteTests;
 import org.apache.druid.sql.calcite.util.SpecificSegmentsQuerySegmentWalker;
 import org.apache.druid.testing.InitializedNullHandlingTest;
@@ -128,7 +128,7 @@ public class SqlVectorizedExpressionSanityTest extends 
InitializedNullHandlingTe
     CLOSER.register(WALKER);
 
     final PlannerConfig plannerConfig = new PlannerConfig();
-    final SchemaPlus rootSchema =
+    final DruidSchemaCatalog rootSchema =
         CalciteTests.createMockRootSchema(CONGLOMERATE, WALKER, plannerConfig, 
AuthTestUtils.TEST_AUTHORIZER_MAPPER);
     PLANNER_FACTORY = new PlannerFactory(
         rootSchema,
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/expression/ExpressionTestHelper.java
 
b/sql/src/test/java/org/apache/druid/sql/calcite/expression/ExpressionTestHelper.java
index dc56fe7..3c049b4 100644
--- 
a/sql/src/test/java/org/apache/druid/sql/calcite/expression/ExpressionTestHelper.java
+++ 
b/sql/src/test/java/org/apache/druid/sql/calcite/expression/ExpressionTestHelper.java
@@ -26,6 +26,7 @@ import org.apache.calcite.rel.type.RelDataTypeFactory;
 import org.apache.calcite.rex.RexBuilder;
 import org.apache.calcite.rex.RexLiteral;
 import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.schema.SchemaPlus;
 import org.apache.calcite.sql.SqlIntervalQualifier;
 import org.apache.calcite.sql.SqlOperator;
 import org.apache.calcite.sql.type.SqlTypeName;
@@ -45,8 +46,14 @@ import org.apache.druid.sql.calcite.planner.Calcites;
 import org.apache.druid.sql.calcite.planner.PlannerConfig;
 import org.apache.druid.sql.calcite.planner.PlannerContext;
 import org.apache.druid.sql.calcite.rel.VirtualColumnRegistry;
+import org.apache.druid.sql.calcite.schema.DruidSchema;
+import org.apache.druid.sql.calcite.schema.DruidSchemaCatalog;
+import org.apache.druid.sql.calcite.schema.NamedDruidSchema;
+import org.apache.druid.sql.calcite.schema.NamedViewSchema;
+import org.apache.druid.sql.calcite.schema.ViewSchema;
 import org.apache.druid.sql.calcite.table.RowSignatures;
 import org.apache.druid.sql.calcite.util.CalciteTests;
+import org.easymock.EasyMock;
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.junit.Assert;
@@ -67,6 +74,13 @@ class ExpressionTestHelper
       CalciteTests.createOperatorTable(),
       CalciteTests.createExprMacroTable(),
       new PlannerConfig(),
+      new DruidSchemaCatalog(
+          EasyMock.createMock(SchemaPlus.class),
+          ImmutableMap.of(
+              "druid", new 
NamedDruidSchema(EasyMock.createMock(DruidSchema.class), "druid"),
+              NamedViewSchema.NAME, new 
NamedViewSchema(EasyMock.createMock(ViewSchema.class))
+          )
+      ),
       ImmutableMap.of()
   );
 
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/planner/CalcitePlannerModuleTest.java
 
b/sql/src/test/java/org/apache/druid/sql/calcite/planner/CalcitePlannerModuleTest.java
index e081e1f..90dfcba 100644
--- 
a/sql/src/test/java/org/apache/druid/sql/calcite/planner/CalcitePlannerModuleTest.java
+++ 
b/sql/src/test/java/org/apache/druid/sql/calcite/planner/CalcitePlannerModuleTest.java
@@ -26,14 +26,15 @@ import com.google.inject.Key;
 import com.google.inject.Scopes;
 import com.google.inject.TypeLiteral;
 import org.apache.calcite.schema.Schema;
-import org.apache.calcite.schema.SchemaPlus;
 import org.apache.druid.guice.LazySingleton;
 import org.apache.druid.jackson.JacksonModule;
 import org.apache.druid.math.expr.ExprMacroTable;
 import org.apache.druid.server.QueryLifecycleFactory;
 import org.apache.druid.server.security.AuthorizerMapper;
+import org.apache.druid.server.security.ResourceType;
 import org.apache.druid.sql.calcite.aggregation.SqlAggregator;
 import org.apache.druid.sql.calcite.expression.SqlOperatorConversion;
+import org.apache.druid.sql.calcite.schema.DruidSchemaCatalog;
 import org.apache.druid.sql.calcite.schema.DruidSchemaName;
 import org.apache.druid.sql.calcite.schema.NamedSchema;
 import org.apache.druid.sql.calcite.util.CalciteTestBase;
@@ -71,11 +72,10 @@ public class CalcitePlannerModuleTest extends 
CalciteTestBase
   @Mock
   private AuthorizerMapper authorizerMapper;
   @Mock
-  private SchemaPlus rootSchema;
+  private DruidSchemaCatalog rootSchema;
 
   private Set<SqlAggregator> aggregators;
   private Set<SqlOperatorConversion> operatorConversions;
-  private Set<NamedSchema> calciteSchemas;
 
   private CalcitePlannerModule target;
   private Injector injector;
@@ -87,8 +87,9 @@ public class CalcitePlannerModuleTest extends CalciteTestBase
     EasyMock.expect(druidSchema2.getSchema()).andStubReturn(schema2);
     EasyMock.expect(druidSchema1.getSchemaName()).andStubReturn(SCHEMA_1);
     EasyMock.expect(druidSchema2.getSchemaName()).andStubReturn(SCHEMA_2);
+    
EasyMock.expect(druidSchema1.getSchemaResourceType(EasyMock.anyString())).andStubReturn(ResourceType.DATASOURCE);
+    
EasyMock.expect(druidSchema2.getSchemaResourceType(EasyMock.anyString())).andStubReturn("test");
     EasyMock.replay(druidSchema1, druidSchema2);
-    calciteSchemas = ImmutableSet.of(druidSchema1, druidSchema2);
     aggregators = ImmutableSet.of();
     operatorConversions = ImmutableSet.of();
     target = new CalcitePlannerModule();
@@ -97,14 +98,13 @@ public class CalcitePlannerModuleTest extends 
CalciteTestBase
         binder -> {
           
binder.bind(Validator.class).toInstance(Validation.buildDefaultValidatorFactory().getValidator());
           binder.bindScope(LazySingleton.class, Scopes.SINGLETON);
-          binder.bind(Key.get(new 
TypeLiteral<Set<NamedSchema>>(){})).toInstance(calciteSchemas);
           
binder.bind(QueryLifecycleFactory.class).toInstance(queryLifecycleFactory);
           binder.bind(ExprMacroTable.class).toInstance(macroTable);
           binder.bind(AuthorizerMapper.class).toInstance(authorizerMapper);
           
binder.bind(String.class).annotatedWith(DruidSchemaName.class).toInstance(DRUID_SCHEMA_NAME);
           binder.bind(Key.get(new 
TypeLiteral<Set<SqlAggregator>>(){})).toInstance(aggregators);
           binder.bind(Key.get(new 
TypeLiteral<Set<SqlOperatorConversion>>(){})).toInstance(operatorConversions);
-          binder.bind(SchemaPlus.class).toInstance(rootSchema);
+          binder.bind(DruidSchemaCatalog.class).toInstance(rootSchema);
         },
         target
     );
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/schema/DruidCalciteSchemaModuleTest.java
 
b/sql/src/test/java/org/apache/druid/sql/calcite/schema/DruidCalciteSchemaModuleTest.java
index f225fe6..451e16f 100644
--- 
a/sql/src/test/java/org/apache/druid/sql/calcite/schema/DruidCalciteSchemaModuleTest.java
+++ 
b/sql/src/test/java/org/apache/druid/sql/calcite/schema/DruidCalciteSchemaModuleTest.java
@@ -28,7 +28,6 @@ import com.google.inject.Key;
 import com.google.inject.Scopes;
 import com.google.inject.TypeLiteral;
 import com.google.inject.name.Names;
-import org.apache.calcite.schema.SchemaPlus;
 import org.apache.druid.client.InventoryView;
 import org.apache.druid.client.TimelineServerView;
 import org.apache.druid.client.coordinator.Coordinator;
@@ -203,12 +202,12 @@ public class DruidCalciteSchemaModuleTest extends 
CalciteTestBase
   @Test
   public void testRootSchemaAnnotatedIsInjectedAsSingleton()
   {
-    SchemaPlus rootSchema = injector.getInstance(
-        Key.get(SchemaPlus.class, 
Names.named(DruidCalciteSchemaModule.INCOMPLETE_SCHEMA))
+    DruidSchemaCatalog rootSchema = injector.getInstance(
+        Key.get(DruidSchemaCatalog.class, 
Names.named(DruidCalciteSchemaModule.INCOMPLETE_SCHEMA))
     );
     Assert.assertNotNull(rootSchema);
-    SchemaPlus other = injector.getInstance(
-        Key.get(SchemaPlus.class, 
Names.named(DruidCalciteSchemaModule.INCOMPLETE_SCHEMA))
+    DruidSchemaCatalog other = injector.getInstance(
+        Key.get(DruidSchemaCatalog.class, 
Names.named(DruidCalciteSchemaModule.INCOMPLETE_SCHEMA))
     );
     Assert.assertSame(other, rootSchema);
   }
@@ -216,10 +215,10 @@ public class DruidCalciteSchemaModuleTest extends 
CalciteTestBase
   @Test
   public void testRootSchemaIsInjectedAsSingleton()
   {
-    SchemaPlus rootSchema = injector.getInstance(Key.get(SchemaPlus.class));
+    DruidSchemaCatalog rootSchema = 
injector.getInstance(Key.get(DruidSchemaCatalog.class));
     Assert.assertNotNull(rootSchema);
-    SchemaPlus other = injector.getInstance(
-        Key.get(SchemaPlus.class, 
Names.named(DruidCalciteSchemaModule.INCOMPLETE_SCHEMA))
+    DruidSchemaCatalog other = injector.getInstance(
+        Key.get(DruidSchemaCatalog.class, 
Names.named(DruidCalciteSchemaModule.INCOMPLETE_SCHEMA))
     );
     Assert.assertSame(other, rootSchema);
   }
@@ -227,7 +226,7 @@ public class DruidCalciteSchemaModuleTest extends 
CalciteTestBase
   @Test
   public void testRootSchemaIsInjectedAndHasInformationSchema()
   {
-    SchemaPlus rootSchema = injector.getInstance(Key.get(SchemaPlus.class));
+    DruidSchemaCatalog rootSchema = 
injector.getInstance(Key.get(DruidSchemaCatalog.class));
     InformationSchema expectedSchema = 
injector.getInstance(InformationSchema.class);
     Assert.assertNotNull(rootSchema);
     Assert.assertSame(expectedSchema, 
rootSchema.getSubSchema("INFORMATION_SCHEMA").unwrap(InformationSchema.class));
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/schema/RootSchemaProviderTest.java
 
b/sql/src/test/java/org/apache/druid/sql/calcite/schema/RootSchemaProviderTest.java
index 71f1169..6cfe3f2 100644
--- 
a/sql/src/test/java/org/apache/druid/sql/calcite/schema/RootSchemaProviderTest.java
+++ 
b/sql/src/test/java/org/apache/druid/sql/calcite/schema/RootSchemaProviderTest.java
@@ -21,7 +21,6 @@ package org.apache.druid.sql.calcite.schema;
 
 import com.google.common.collect.ImmutableSet;
 import org.apache.calcite.schema.Schema;
-import org.apache.calcite.schema.SchemaPlus;
 import org.apache.druid.java.util.common.ISE;
 import org.apache.druid.sql.calcite.util.CalciteTestBase;
 import org.easymock.EasyMock;
@@ -72,9 +71,9 @@ public class RootSchemaProviderTest extends CalciteTestBase
   @Test
   public void testGetShouldReturnRootSchemaWithProvidedSchemasRegistered()
   {
-    SchemaPlus rootSchema = target.get();
-    Assert.assertEquals("", rootSchema.getName());
-    Assert.assertFalse(rootSchema.isCacheEnabled());
+    DruidSchemaCatalog rootSchema = target.get();
+    Assert.assertEquals("", rootSchema.getRootSchema().getName());
+    Assert.assertFalse(rootSchema.getRootSchema().isCacheEnabled());
     // metadata schema should not be added
     Assert.assertEquals(druidSchemas.size(), 
rootSchema.getSubSchemaNames().size());
 
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/util/CalciteTests.java 
b/sql/src/test/java/org/apache/druid/sql/calcite/util/CalciteTests.java
index 4e39482..a5e493d 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/util/CalciteTests.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/util/CalciteTests.java
@@ -115,9 +115,15 @@ import 
org.apache.druid.sql.calcite.planner.DruidOperatorTable;
 import org.apache.druid.sql.calcite.planner.PlannerConfig;
 import org.apache.druid.sql.calcite.planner.PlannerFactory;
 import org.apache.druid.sql.calcite.schema.DruidSchema;
+import org.apache.druid.sql.calcite.schema.DruidSchemaCatalog;
 import org.apache.druid.sql.calcite.schema.InformationSchema;
 import org.apache.druid.sql.calcite.schema.LookupSchema;
 import org.apache.druid.sql.calcite.schema.MetadataSegmentView;
+import org.apache.druid.sql.calcite.schema.NamedDruidSchema;
+import org.apache.druid.sql.calcite.schema.NamedLookupSchema;
+import org.apache.druid.sql.calcite.schema.NamedSchema;
+import org.apache.druid.sql.calcite.schema.NamedSystemSchema;
+import org.apache.druid.sql.calcite.schema.NamedViewSchema;
 import org.apache.druid.sql.calcite.schema.SystemSchema;
 import org.apache.druid.sql.calcite.schema.ViewSchema;
 import org.apache.druid.sql.calcite.view.DruidViewMacroFactory;
@@ -131,7 +137,6 @@ import org.joda.time.Duration;
 import org.joda.time.chrono.ISOChronology;
 
 import javax.annotation.Nullable;
-
 import java.io.File;
 import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
@@ -165,9 +170,6 @@ public class CalciteTests
   public static final String USERVISITDATASOURCE = "visits";
   public static final String DRUID_SCHEMA_NAME = "druid";
   public static final String INFORMATION_SCHEMA_NAME = "INFORMATION_SCHEMA";
-  public static final String SYSTEM_SCHEMA_NAME = "sys";
-  public static final String LOOKUP_SCHEMA_NAME = "lookup";
-  public static final String VIEW_SCHEMA_NAME = "view";
 
   public static final String TEST_SUPERUSER_NAME = "testSuperuser";
   public static final AuthorizerMapper TEST_AUTHORIZER_MAPPER = new 
AuthorizerMapper(null)
@@ -180,9 +182,9 @@ public class CalciteTests
           return Access.OK;
         }
 
-        if (resource.getType() == ResourceType.DATASOURCE && 
resource.getName().equals(FORBIDDEN_DATASOURCE)) {
+        if (ResourceType.DATASOURCE.equals(resource.getType()) && 
resource.getName().equals(FORBIDDEN_DATASOURCE)) {
           return new Access(false);
-        } else if (resource.getType() == ResourceType.VIEW && 
resource.getName().equals("forbiddenView")) {
+        } else if (ResourceType.VIEW.equals(resource.getType()) && 
resource.getName().equals("forbiddenView")) {
           return new Access(false);
         } else {
           return Access.OK;
@@ -1123,7 +1125,7 @@ public class CalciteTests
     );
   }
 
-  public static SchemaPlus createMockRootSchema(
+  public static DruidSchemaCatalog createMockRootSchema(
       final QueryRunnerFactoryConglomerate conglomerate,
       final SpecificSegmentsQuerySegmentWalker walker,
       final PlannerConfig plannerConfig,
@@ -1134,22 +1136,31 @@ public class CalciteTests
     SystemSchema systemSchema =
         CalciteTests.createMockSystemSchema(druidSchema, walker, 
plannerConfig, authorizerMapper);
 
+    LookupSchema lookupSchema = CalciteTests.createMockLookupSchema();
     SchemaPlus rootSchema = CalciteSchema.createRootSchema(false, 
false).plus();
+    Set<NamedSchema> namedSchemas = ImmutableSet.of(
+        new NamedDruidSchema(druidSchema, CalciteTests.DRUID_SCHEMA_NAME),
+        new NamedSystemSchema(systemSchema),
+        new NamedLookupSchema(lookupSchema)
+    );
+    DruidSchemaCatalog catalog = new DruidSchemaCatalog(
+        rootSchema,
+        
namedSchemas.stream().collect(Collectors.toMap(NamedSchema::getSchemaName, x -> 
x))
+    );
     InformationSchema informationSchema =
         new InformationSchema(
-            rootSchema,
-            authorizerMapper,
-            CalciteTests.DRUID_SCHEMA_NAME
+            catalog,
+            authorizerMapper
         );
-    LookupSchema lookupSchema = CalciteTests.createMockLookupSchema();
     rootSchema.add(CalciteTests.DRUID_SCHEMA_NAME, druidSchema);
     rootSchema.add(CalciteTests.INFORMATION_SCHEMA_NAME, informationSchema);
-    rootSchema.add(CalciteTests.SYSTEM_SCHEMA_NAME, systemSchema);
-    rootSchema.add(CalciteTests.LOOKUP_SCHEMA_NAME, lookupSchema);
-    return rootSchema;
+    rootSchema.add(NamedSystemSchema.NAME, systemSchema);
+    rootSchema.add(NamedLookupSchema.NAME, lookupSchema);
+
+    return catalog;
   }
 
-  public static SchemaPlus createMockRootSchema(
+  public static DruidSchemaCatalog createMockRootSchema(
       final QueryRunnerFactoryConglomerate conglomerate,
       final SpecificSegmentsQuerySegmentWalker walker,
       final PlannerConfig plannerConfig,
@@ -1160,20 +1171,32 @@ public class CalciteTests
     DruidSchema druidSchema = createMockSchema(conglomerate, walker, 
plannerConfig, viewManager);
     SystemSchema systemSchema =
         CalciteTests.createMockSystemSchema(druidSchema, walker, 
plannerConfig, authorizerMapper);
+
+    LookupSchema lookupSchema = CalciteTests.createMockLookupSchema();
+    ViewSchema viewSchema = new ViewSchema(viewManager);
+
     SchemaPlus rootSchema = CalciteSchema.createRootSchema(false, 
false).plus();
+    Set<NamedSchema> namedSchemas = ImmutableSet.of(
+        new NamedDruidSchema(druidSchema, CalciteTests.DRUID_SCHEMA_NAME),
+        new NamedSystemSchema(systemSchema),
+        new NamedLookupSchema(lookupSchema),
+        new NamedViewSchema(viewSchema)
+    );
+    DruidSchemaCatalog catalog = new DruidSchemaCatalog(
+        rootSchema,
+        
namedSchemas.stream().collect(Collectors.toMap(NamedSchema::getSchemaName, x -> 
x))
+    );
     InformationSchema informationSchema =
         new InformationSchema(
-            rootSchema,
-            authorizerMapper,
-            CalciteTests.DRUID_SCHEMA_NAME
+            catalog,
+            authorizerMapper
         );
-    LookupSchema lookupSchema = CalciteTests.createMockLookupSchema();
     rootSchema.add(CalciteTests.DRUID_SCHEMA_NAME, druidSchema);
     rootSchema.add(CalciteTests.INFORMATION_SCHEMA_NAME, informationSchema);
-    rootSchema.add(CalciteTests.SYSTEM_SCHEMA_NAME, systemSchema);
-    rootSchema.add(CalciteTests.LOOKUP_SCHEMA_NAME, lookupSchema);
-    rootSchema.add(CalciteTests.VIEW_SCHEMA_NAME, new ViewSchema(viewManager));
-    return rootSchema;
+    rootSchema.add(NamedSystemSchema.NAME, systemSchema);
+    rootSchema.add(NamedLookupSchema.NAME, lookupSchema);
+    rootSchema.add(NamedViewSchema.NAME, viewSchema);
+    return catalog;
   }
 
   /**
diff --git a/sql/src/test/java/org/apache/druid/sql/http/SqlResourceTest.java 
b/sql/src/test/java/org/apache/druid/sql/http/SqlResourceTest.java
index 870342a..c7387ac 100644
--- a/sql/src/test/java/org/apache/druid/sql/http/SqlResourceTest.java
+++ b/sql/src/test/java/org/apache/druid/sql/http/SqlResourceTest.java
@@ -28,7 +28,6 @@ import com.google.common.collect.Maps;
 import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
 import org.apache.calcite.avatica.SqlType;
-import org.apache.calcite.schema.SchemaPlus;
 import org.apache.calcite.tools.RelConversionException;
 import org.apache.druid.common.config.NullHandling;
 import org.apache.druid.common.guava.SettableSupplier;
@@ -71,6 +70,7 @@ import 
org.apache.druid.sql.calcite.planner.DruidOperatorTable;
 import org.apache.druid.sql.calcite.planner.PlannerConfig;
 import org.apache.druid.sql.calcite.planner.PlannerContext;
 import org.apache.druid.sql.calcite.planner.PlannerFactory;
+import org.apache.druid.sql.calcite.schema.DruidSchemaCatalog;
 import org.apache.druid.sql.calcite.util.CalciteTestBase;
 import org.apache.druid.sql.calcite.util.CalciteTests;
 import org.apache.druid.sql.calcite.util.QueryLogHook;
@@ -184,7 +184,7 @@ public class SqlResourceTest extends CalciteTestBase
         return false;
       }
     };
-    final SchemaPlus rootSchema = CalciteTests.createMockRootSchema(
+    final DruidSchemaCatalog rootSchema = CalciteTests.createMockRootSchema(
         conglomerate,
         walker,
         plannerConfig,

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to