public static void validateMaterializedViewPartitionColumns(
            SemiTransactionalHiveMetastore metastore,
            MetastoreContext metastoreContext,
            Table viewTable,
            MaterializedViewDefinition viewDefinition)
    {
        SchemaTableName viewName = new SchemaTableName(viewTable.getDatabaseName(), viewTable.getTableName());

        Map<String, Map<SchemaTableName, String>> viewToBaseDirectColumnMap = viewDefinition.getDirectColumnMappingsAsMap();
        if (viewToBaseDirectColumnMap.isEmpty()) {
            throw new PrestoException(
                    NOT_SUPPORTED,
                    format("Materialized view %s must have at least one column directly defined by a base table column.", viewName));
        }

        List<Column> viewPartitions = viewTable.getPartitionColumns();
        if (viewPartitions.isEmpty()) {
            throw new PrestoException(NOT_SUPPORTED, "Unpartitioned materialized view is not supported.");
        }

        List<Table> baseTables = viewDefinition.getBaseTables().stream()
                .map(baseTableName -> metastore.getTable(metastoreContext, baseTableName.getSchemaName(), baseTableName.getTableName())
                        .orElseThrow(() -> new TableNotFoundException(baseTableName)))
                .collect(toImmutableList());

        Map<Table, List<Column>> baseTablePartitions = baseTables.stream()
                .collect(toImmutableMap(
                        table -> table,
                        Table::getPartitionColumns));

        for (Table baseTable : baseTablePartitions.keySet()) {
            SchemaTableName schemaBaseTable = new SchemaTableName(baseTable.getDatabaseName(), baseTable.getTableName());
            if (!isCommonPartitionFound(schemaBaseTable, baseTablePartitions.get(baseTable), viewPartitions, viewToBaseDirectColumnMap)) {
                throw new PrestoException(
                        NOT_SUPPORTED,
                        format("Materialized view %s must have at least one partition column that exists in %s as well", viewName, baseTable.getTableName()));
            }
            if (viewDefinition.getBaseTablesOnOuterJoinSide().contains(schemaBaseTable) && viewToBaseTableOnOuterJoinSideIndirectMappedPartitions(viewDefinition, baseTable).get().isEmpty()) {
                throw new PrestoException(
                        NOT_SUPPORTED,
                        format("Outer join conditions in Materialized view %s must have at least one common partition equality constraint", viewName));
            }
        }
    }
@Test(expectedExceptions = PrestoException.class, expectedExceptionsMessageRegExp = "Materialized view schema.table must have at least one column directly defined by a base table column.")
    public void testValidateMaterializedViewPartitionColumnsEmptyBaseColumnMap()
    {
        TestingSemiTransactionalHiveMetastore testMetastore = TestingSemiTransactionalHiveMetastore.create();

        Column dsColumn = new Column("ds", HIVE_STRING, Optional.empty(), Optional.empty());
        Column shipmodeColumn = new Column("shipmode", HIVE_STRING, Optional.empty(), Optional.empty());
        List<Column> partitionColumns = ImmutableList.of(dsColumn, shipmodeColumn);

        SchemaTableName tableName = new SchemaTableName(SCHEMA_NAME, TABLE_NAME);
        Map<String, Map<SchemaTableName, String>> originalColumnMapping = ImmutableMap.of();
        testMetastore.addTable(SCHEMA_NAME, TABLE_NAME, getTable(partitionColumns), ImmutableList.of());
        List<Column> viewPartitionColumns = ImmutableList.of(dsColumn);

        validateMaterializedViewPartitionColumns(testMetastore, metastoreContext, getTable(viewPartitionColumns), getConnectorMaterializedViewDefinition(ImmutableList.of(tableName), originalColumnMapping));
    }