/**
  * Resolves a multi-part identifier such as "SCHEMA.EMP.EMPNO" to a namespace. The returned
  * namespace may represent a schema, table, column, etc.
  *
  * @pre names.size() > 0
  * @post return != null
  */
 public static SqlValidatorNamespace lookup(SqlValidatorScope scope, List<String> names) {
   Util.pre(names.size() > 0, "names.size() > 0");
   SqlValidatorNamespace namespace = null;
   for (int i = 0; i < names.size(); i++) {
     String name = names.get(i);
     if (i == 0) {
       namespace = scope.resolve(name, null, null);
     } else {
       namespace = namespace.lookupChild(name);
     }
   }
   Util.permAssert(namespace != null, "post: namespace != null");
   return namespace;
 }
 /**
  * Converts a {@link SqlValidatorScope} into a {@link RelOptTable}. This is only possible if the
  * scope represents an identifier, such as "sales.emp". Otherwise, returns null.
  *
  * @param namespace Namespace
  * @param catalogReader Schema
  * @param datasetName Name of sample dataset to substitute, or null to use the regular table
  * @param usedDataset Output parameter which is set to true if a sample dataset is found; may be
  *     null
  */
 public static RelOptTable getRelOptTable(
     SqlValidatorNamespace namespace,
     Prepare.CatalogReader catalogReader,
     String datasetName,
     boolean[] usedDataset) {
   if (namespace.isWrapperFor(IdentifierNamespace.class)) {
     IdentifierNamespace identifierNamespace = namespace.unwrap(IdentifierNamespace.class);
     final List<String> names = identifierNamespace.getId().names;
     if ((datasetName != null) && (catalogReader instanceof RelOptSchemaWithSampling)) {
       return ((RelOptSchemaWithSampling) catalogReader)
           .getTableForMember(names, datasetName, usedDataset);
     } else {
       // Schema does not support substitution. Ignore the dataset,
       // if any.
       return catalogReader.getTableForMember(names);
     }
   } else {
     return null;
   }
 }