private Optional<Table> loadTable(HiveTableName hiveTableName) throws Exception {
   try {
     return retry()
         .stopOn(NoSuchObjectException.class, HiveViewNotSupportedException.class)
         .stopOnIllegalExceptions()
         .run(
             "getTable",
             stats
                 .getGetTable()
                 .wrap(
                     () -> {
                       try (HiveMetastoreClient client = clientProvider.createMetastoreClient()) {
                         Table table =
                             client.getTable(
                                 hiveTableName.getDatabaseName(), hiveTableName.getTableName());
                         if (table.getTableType().equals(TableType.VIRTUAL_VIEW.name())
                             && (!isPrestoView(table))) {
                           throw new HiveViewNotSupportedException(
                               new SchemaTableName(
                                   hiveTableName.getDatabaseName(), hiveTableName.getTableName()));
                         }
                         return Optional.of(table);
                       }
                     }));
   } catch (NoSuchObjectException e) {
     return Optional.empty();
   } catch (TException e) {
     throw new PrestoException(HIVE_METASTORE_ERROR, e);
   }
 }
  @Override
  public synchronized void createTable(Table table) {
    SchemaTableName schemaTableName = new SchemaTableName(table.getDbName(), table.getTableName());
    Table tableCopy = table.deepCopy();
    if (tableCopy.getSd() == null) {
      tableCopy.setSd(new StorageDescriptor());
    } else if (tableCopy.getSd().getLocation() != null) {
      File directory = new File(new Path(tableCopy.getSd().getLocation()).toUri());
      checkArgument(directory.exists(), "Table directory does not exist");
      checkArgument(
          isParentDir(directory, baseDirectory),
          "Table directory must be inside of the metastore base directory");
    }

    if (relations.putIfAbsent(schemaTableName, tableCopy) != null) {
      throw new TableAlreadyExistsException(schemaTableName);
    }

    if (tableCopy.getTableType().equals(TableType.VIRTUAL_VIEW.name())) {
      views.put(schemaTableName, tableCopy);
    }

    PrincipalPrivilegeSet privileges = table.getPrivileges();
    if (privileges != null) {
      for (Entry<String, List<PrivilegeGrantInfo>> entry :
          privileges.getUserPrivileges().entrySet()) {
        String user = entry.getKey();
        Set<HivePrivilegeInfo> userPrivileges =
            entry
                .getValue()
                .stream()
                .map(HivePrivilegeInfo::parsePrivilege)
                .flatMap(Collection::stream)
                .collect(toImmutableSet());
        setTablePrivileges(user, USER, table.getDbName(), table.getTableName(), userPrivileges);
      }
      for (Entry<String, List<PrivilegeGrantInfo>> entry :
          privileges.getRolePrivileges().entrySet()) {
        String role = entry.getKey();
        Set<HivePrivilegeInfo> rolePrivileges =
            entry
                .getValue()
                .stream()
                .map(HivePrivilegeInfo::parsePrivilege)
                .flatMap(Collection::stream)
                .collect(toImmutableSet());
        setTablePrivileges(role, ROLE, table.getDbName(), table.getTableName(), rolePrivileges);
      }
    }
  }
 private ConnectorTableMetadata getTableMetadata(SchemaTableName tableName) {
   try {
     Table table = metastore.getTable(tableName.getSchemaName(), tableName.getTableName());
     if (table.getTableType().equals(TableType.VIRTUAL_VIEW.name())) {
       throw new TableNotFoundException(tableName);
     }
     List<HiveColumnHandle> handles = hiveColumnHandles(typeManager, connectorId, table, false);
     List<ColumnMetadata> columns =
         ImmutableList.copyOf(transform(handles, columnMetadataGetter(table, typeManager)));
     return new ConnectorTableMetadata(tableName, columns, table.getOwner());
   } catch (NoSuchObjectException e) {
     throw new TableNotFoundException(tableName);
   }
 }
  @Override
  public void createView(
      ConnectorSession session, SchemaTableName viewName, String viewData, boolean replace) {
    if (replace) {
      try {
        dropView(session, viewName);
      } catch (ViewNotFoundException ignored) {
      }
    }

    Map<String, String> properties =
        ImmutableMap.<String, String>builder()
            .put("comment", "Presto View")
            .put(PRESTO_VIEW_FLAG, "true")
            .build();

    FieldSchema dummyColumn = new FieldSchema("dummy", STRING_TYPE_NAME, null);

    StorageDescriptor sd = new StorageDescriptor();
    sd.setCols(ImmutableList.of(dummyColumn));
    sd.setSerdeInfo(new SerDeInfo());

    Table table = new Table();
    table.setDbName(viewName.getSchemaName());
    table.setTableName(viewName.getTableName());
    table.setOwner(session.getUser());
    table.setTableType(TableType.VIRTUAL_VIEW.name());
    table.setParameters(properties);
    table.setViewOriginalText(encodeViewData(viewData));
    table.setViewExpandedText("/* Presto View */");
    table.setSd(sd);

    try {
      metastore.createTable(table);
    } catch (TableAlreadyExistsException e) {
      throw new ViewAlreadyExistsException(e.getTableName());
    }
  }