diff --git a/presto-hive/src/test/java/com/facebook/presto/hive/hudi/HudiTestUtils.java b/presto-hive/src/test/java/com/facebook/presto/hive/hudi/HudiTestUtils.java new file mode 100644 index 000000000000..8a1a45b2c777 --- /dev/null +++ b/presto-hive/src/test/java/com/facebook/presto/hive/hudi/HudiTestUtils.java @@ -0,0 +1,87 @@ +/* + * Licensed 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 com.facebook.presto.hive.hudi; + +import com.facebook.airlift.log.Logger; +import com.facebook.presto.Session; +import com.facebook.presto.hive.HdfsConfiguration; +import com.facebook.presto.hive.HdfsConfigurationInitializer; +import com.facebook.presto.hive.HdfsEnvironment; +import com.facebook.presto.hive.HiveClientConfig; +import com.facebook.presto.hive.HiveHdfsConfiguration; +import com.facebook.presto.hive.MetastoreClientConfig; +import com.facebook.presto.hive.authentication.NoHdfsAuthentication; +import com.facebook.presto.hive.metastore.ExtendedHiveMetastore; +import com.facebook.presto.hive.metastore.file.FileHiveMetastore; +import com.facebook.presto.spi.Plugin; +import com.facebook.presto.tests.DistributedQueryRunner; +import com.google.common.collect.ImmutableSet; + +import java.nio.file.Path; +import java.util.Map; +import java.util.Optional; +import java.util.function.Function; + +import static com.facebook.presto.testing.TestingSession.testSessionBuilder; + +public class HudiTestUtils +{ + private static final Logger log = Logger.get(HudiTestUtils.class); + + public static final String DATA_DIR = "data"; + + private HudiTestUtils() {} + + public static DistributedQueryRunner createQueryRunner( + Map serverConfig, + Map connectorConfig, + Function, Plugin> connectorPluginFactory, + String connectorName, + String catalogName, + String defaultSchema) + throws Exception + { + Session session = testSessionBuilder().setCatalog(catalogName).setSchema(defaultSchema).build(); + DistributedQueryRunner queryRunner = DistributedQueryRunner.builder(session).setExtraProperties(serverConfig).build(); + + // setup file metastore + Path catalogDir = queryRunner.getCoordinator().getBaseDataDir().resolve("catalog"); + ExtendedHiveMetastore metastore = createFileHiveMetastore(catalogDir.toString()); + + // prepare testing data + Path testingDataDir = queryRunner.getCoordinator().getBaseDataDir().resolve(DATA_DIR); + HudiTestingDataGenerator generator = new HudiTestingDataGenerator(metastore, defaultSchema, testingDataDir); + generator.generateData(); + generator.generateMetadata(); + + queryRunner.installPlugin(connectorPluginFactory.apply(Optional.of(metastore))); + queryRunner.createCatalog(catalogName, connectorName, connectorConfig); + + log.info("Using %s as catalog directory ", catalogDir); + log.info("Using %s as testing data directory", testingDataDir); + return queryRunner; + } + + private static ExtendedHiveMetastore createFileHiveMetastore(String catalogDir) + { + HiveClientConfig hiveClientConfig = new HiveClientConfig(); + MetastoreClientConfig metastoreClientConfig = new MetastoreClientConfig(); + HdfsConfiguration hdfsConfiguration = new HiveHdfsConfiguration( + new HdfsConfigurationInitializer(hiveClientConfig, metastoreClientConfig), + ImmutableSet.of()); + HdfsEnvironment hdfsEnvironment = new HdfsEnvironment(hdfsConfiguration, metastoreClientConfig, new NoHdfsAuthentication()); + return new FileHiveMetastore(hdfsEnvironment, catalogDir, "test"); + } +} diff --git a/presto-hive/src/test/java/com/facebook/presto/hive/hudi/HudiTestingDataGenerator.java b/presto-hive/src/test/java/com/facebook/presto/hive/hudi/HudiTestingDataGenerator.java new file mode 100644 index 000000000000..b85ccbfeae52 --- /dev/null +++ b/presto-hive/src/test/java/com/facebook/presto/hive/hudi/HudiTestingDataGenerator.java @@ -0,0 +1,231 @@ +/* + * Licensed 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 com.facebook.presto.hive.hudi; + +import com.facebook.presto.hive.HiveColumnConverterProvider; +import com.facebook.presto.hive.HiveType; +import com.facebook.presto.hive.metastore.Column; +import com.facebook.presto.hive.metastore.Database; +import com.facebook.presto.hive.metastore.ExtendedHiveMetastore; +import com.facebook.presto.hive.metastore.MetastoreContext; +import com.facebook.presto.hive.metastore.Partition; +import com.facebook.presto.hive.metastore.PartitionStatistics; +import com.facebook.presto.hive.metastore.PartitionWithStatistics; +import com.facebook.presto.hive.metastore.PrestoTableType; +import com.facebook.presto.hive.metastore.PrincipalPrivileges; +import com.facebook.presto.hive.metastore.Storage; +import com.facebook.presto.hive.metastore.StorageFormat; +import com.facebook.presto.hive.metastore.Table; +import com.facebook.presto.spi.security.PrincipalType; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.Streams; +import com.google.common.io.Resources; +import org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat; +import org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe; +import org.apache.hudi.common.model.HoodieTableType; +import org.apache.hudi.hadoop.HoodieParquetInputFormat; +import org.apache.hudi.hadoop.realtime.HoodieParquetRealtimeInputFormat; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import static com.facebook.presto.hive.HiveType.HIVE_DOUBLE; +import static com.facebook.presto.hive.HiveType.HIVE_INT; +import static com.facebook.presto.hive.HiveType.HIVE_LONG; +import static com.facebook.presto.hive.HiveType.HIVE_STRING; +import static com.facebook.presto.hive.metastore.MetastoreUtil.extractPartitionValues; +import static java.nio.file.Files.createDirectories; +import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; +import static java.util.Objects.requireNonNull; +import static org.apache.hudi.common.model.HoodieTableType.COPY_ON_WRITE; +import static org.apache.hudi.common.model.HoodieTableType.MERGE_ON_READ; + +public class HudiTestingDataGenerator +{ + private static final String OWNER_PUBLIC = "public"; + private static final MetastoreContext METASTORE_CONTEXT = new MetastoreContext("test_user", "test_queryId", Optional.empty(), Optional.empty(), Optional.empty(), false, HiveColumnConverterProvider.DEFAULT_COLUMN_CONVERTER_PROVIDER); + private static final PrincipalPrivileges PRINCIPAL_PRIVILEGES = new PrincipalPrivileges(ImmutableMultimap.of(), ImmutableMultimap.of()); + + private static final StorageFormat STORAGE_FORMAT_COPY_ON_WRITE = StorageFormat.create( + ParquetHiveSerDe.class.getName(), + HoodieParquetInputFormat.class.getName(), + MapredParquetOutputFormat.class.getName()); + private static final StorageFormat STORAGE_FORMAT_MERGE_ON_READ = StorageFormat.create( + ParquetHiveSerDe.class.getName(), + HoodieParquetRealtimeInputFormat.class.getName(), + MapredParquetOutputFormat.class.getName()); + + public static final List DATA_COLUMNS = ImmutableList.of( + column("volume", HIVE_LONG), + column("ts", HIVE_STRING), + column("symbol", HIVE_STRING), + column("year", HIVE_INT), + column("month", HIVE_STRING), + column("high", HIVE_DOUBLE), + column("low", HIVE_DOUBLE), + column("key", HIVE_STRING), + column("date", HIVE_STRING), + column("close", HIVE_DOUBLE), + column("open", HIVE_DOUBLE), + column("day", HIVE_STRING)); + public static final List PARTITION_COLUMNS = ImmutableList.of(column("dt", HIVE_STRING)); + public static final List HUDI_META_COLUMNS = ImmutableList.of( + column("_hoodie_commit_time", HiveType.HIVE_STRING), + column("_hoodie_commit_seqno", HiveType.HIVE_STRING), + column("_hoodie_record_key", HiveType.HIVE_STRING), + column("_hoodie_partition_path", HiveType.HIVE_STRING), + column("_hoodie_file_name", HiveType.HIVE_STRING)); + + private final Path dataDirectory; + private final ExtendedHiveMetastore metastore; + private final String schemaName; + + public HudiTestingDataGenerator(ExtendedHiveMetastore metastore, String schemaName, Path dataDirectory) + { + this.metastore = requireNonNull(metastore, "metastore is null"); + this.schemaName = requireNonNull(schemaName, "catalogName is null"); + this.dataDirectory = requireNonNull(dataDirectory, "dataDirectory is null"); + } + + public void generateData() + { + // Check `hudi-testing-data.md` for more about the testing data. + try (InputStream stream = Resources.getResource("hudi-testing-data.zip").openStream()) { + unzip(stream, dataDirectory); + } + catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void generateMetadata() + { + // create database + Database database = Database.builder() + .setDatabaseName(schemaName) + .setOwnerName(OWNER_PUBLIC) + .setOwnerType(PrincipalType.ROLE) + .build(); + metastore.createDatabase(METASTORE_CONTEXT, database); + + // create partition tables + createTable(COPY_ON_WRITE, "stock_ticks_cow", "stock_ticks_cow", true); + addPartition(COPY_ON_WRITE, "stock_ticks_cow", ImmutableList.of("dt=2018-08-31"), "stock_ticks_cow/2018/08/31"); + createTable(COPY_ON_WRITE, "stock_ticks_mor_ro", "stock_ticks_mor", true); + addPartition(COPY_ON_WRITE, "stock_ticks_mor_ro", ImmutableList.of("dt=2018-08-31"), "stock_ticks_mor/2018/08/31"); + createTable(MERGE_ON_READ, "stock_ticks_mor_rt", "stock_ticks_mor", true); + addPartition(MERGE_ON_READ, "stock_ticks_mor_rt", ImmutableList.of("dt=2018-08-31"), "stock_ticks_mor/2018/08/31"); + + // non partition tables + createTable(COPY_ON_WRITE, "stock_ticks_cown", dataDirectory.resolve("stock_ticks_cown").toString(), false); + createTable(COPY_ON_WRITE, "stock_ticks_morn_ro", dataDirectory.resolve("stock_ticks_morn").toString(), false); + createTable(MERGE_ON_READ, "stock_ticks_morn_rt", dataDirectory.resolve("stock_ticks_morn").toString(), false); + } + + private void createTable(HoodieTableType type, String name, String relativePath, boolean partitioned) + { + // ref: org.apache.hudi.hive.ddl.HMSDDLExecutor#createTable + Table table = Table.builder() + .setDatabaseName(schemaName) + .setTableName(name) + .setTableType(PrestoTableType.EXTERNAL_TABLE) + .setOwner(OWNER_PUBLIC) + .setDataColumns(allDataColumns()) + .setPartitionColumns(partitioned ? PARTITION_COLUMNS : ImmutableList.of()) + .setParameters(ImmutableMap.of("serialization.format", "1", "EXTERNAL", "TRUE")) + .withStorage(buildingStorage(type, "file://" + dataDirectory.resolve(relativePath))) + .build(); + metastore.createTable(METASTORE_CONTEXT, table, PRINCIPAL_PRIVILEGES); + } + + private void addPartition(HoodieTableType type, String tableName, List partitionNames, String relativePath) + { + List partitions = new ArrayList<>(); + for (String partitionName : partitionNames) { + Partition partition = Partition.builder() + .setDatabaseName(schemaName) + .setTableName(tableName) + .setValues(extractPartitionValues(partitionName)) + .withStorage(buildingStorage(type, "file://" + dataDirectory.resolve(relativePath))) + .setColumns(allDataColumns()) + .setCreateTime(0) + .build(); + partitions.add(new PartitionWithStatistics(partition, partitionName, PartitionStatistics.empty())); + } + metastore.addPartitions(METASTORE_CONTEXT, schemaName, tableName, partitions); + } + + private List allDataColumns() + { + return Streams.concat(HUDI_META_COLUMNS.stream(), DATA_COLUMNS.stream()).collect(Collectors.toList()); + } + + private static Column column(String name, HiveType type) + { + return new Column(name, type, Optional.empty(), Optional.empty()); + } + + private static Consumer buildingStorage(HoodieTableType tableType, String location) + { + return storageBuilder -> storageBuilder.setStorageFormat(getStorageFormat(tableType)).setLocation(location); + } + + private static StorageFormat getStorageFormat(HoodieTableType tableType) + { + if (tableType == HoodieTableType.COPY_ON_WRITE) { + return STORAGE_FORMAT_COPY_ON_WRITE; + } + if (tableType == HoodieTableType.MERGE_ON_READ) { + return STORAGE_FORMAT_MERGE_ON_READ; + } + throw new IllegalArgumentException("Unsupported table type " + tableType); + } + + private static void unzip(InputStream inputStream, Path destination) + throws IOException + { + createDirectories(destination); + try (ZipInputStream zipStream = new ZipInputStream(inputStream)) { + while (true) { + ZipEntry zipEntry = zipStream.getNextEntry(); + if (zipEntry == null) { + break; + } + + Path entryPath = destination.resolve(zipEntry.getName()); + if (zipEntry.isDirectory()) { + createDirectories(entryPath); + } + else { + createDirectories(entryPath.getParent()); + Files.copy(zipStream, entryPath, REPLACE_EXISTING); + } + zipStream.closeEntry(); + } + } + } +} diff --git a/presto-hive/src/test/java/com/facebook/presto/hive/hudi/TestHudiIntegration.java b/presto-hive/src/test/java/com/facebook/presto/hive/hudi/TestHudiIntegration.java new file mode 100644 index 000000000000..5abee8081412 --- /dev/null +++ b/presto-hive/src/test/java/com/facebook/presto/hive/hudi/TestHudiIntegration.java @@ -0,0 +1,152 @@ +/* + * Licensed 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 com.facebook.presto.hive.hudi; + +import com.facebook.presto.common.type.TypeManager; +import com.facebook.presto.hive.HivePlugin; +import com.facebook.presto.hive.metastore.Column; +import com.facebook.presto.metadata.FunctionAndTypeManager; +import com.facebook.presto.testing.QueryRunner; +import com.facebook.presto.tests.AbstractTestQueryFramework; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Streams; +import org.intellij.lang.annotations.Language; +import org.testng.annotations.Test; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static com.facebook.presto.hive.hudi.HudiTestingDataGenerator.DATA_COLUMNS; +import static com.facebook.presto.hive.hudi.HudiTestingDataGenerator.HUDI_META_COLUMNS; +import static com.facebook.presto.hive.hudi.HudiTestingDataGenerator.PARTITION_COLUMNS; +import static java.lang.String.format; + +public class TestHudiIntegration + extends AbstractTestQueryFramework +{ + @Override + protected QueryRunner createQueryRunner() + throws Exception + { + return HudiTestUtils.createQueryRunner( + ImmutableMap.of(), + ImmutableMap.of(), + metastore -> new HivePlugin("hive", metastore), + "hive", + "hive", + "testing"); + } + + @Test + public void testMetadata() + { + assertQuery("show tables", + "SELECT * FROM VALUES " + + "('stock_ticks_cow'), " + + "('stock_ticks_cown'), " + + "('stock_ticks_mor_ro'), " + + "('stock_ticks_mor_rt')," + + "('stock_ticks_morn_ro')," + + "('stock_ticks_morn_rt')"); + + FunctionAndTypeManager typeManager = getQueryRunner().getMetadata().getFunctionAndTypeManager(); + + // partition tables + @Language("SQL") String sql = generateDescribeIdenticalQuery(typeManager, HUDI_META_COLUMNS, DATA_COLUMNS, PARTITION_COLUMNS); + assertQuery("DESCRIBE stock_ticks_cow", sql); + assertQuery("DESCRIBE stock_ticks_mor_ro", sql); + assertQuery("DESCRIBE stock_ticks_mor_rt", sql); + + // non-partition tables + @Language("SQL") String sql2 = generateDescribeIdenticalQuery(typeManager, HUDI_META_COLUMNS, DATA_COLUMNS, ImmutableList.of()); + assertQuery("DESCRIBE stock_ticks_cown", sql2); + assertQuery("DESCRIBE stock_ticks_morn_ro", sql2); + assertQuery("DESCRIBE stock_ticks_morn_rt", sql2); + } + + @Test + public void testDemoQuery1() + { + @Language("SQL") String sqlTemplate = "SELECT symbol, max(ts) FROM %s GROUP BY symbol HAVING symbol = 'GOOG'"; + @Language("SQL") String sqlResult = "SELECT 'GOOG', '2018-08-31 10:59:00'"; + @Language("SQL") String sqlResultReadOptimized = "SELECT 'GOOG', '2018-08-31 10:29:00'"; + + assertQuery(format(sqlTemplate, "stock_ticks_cow"), sqlResult); + assertQuery(format(sqlTemplate, "stock_ticks_cown"), sqlResult); + assertQuery(format(sqlTemplate, "stock_ticks_mor_ro"), sqlResultReadOptimized); + assertQuery(format(sqlTemplate, "stock_ticks_mor_rt"), sqlResult); + assertQuery(format(sqlTemplate, "stock_ticks_morn_ro"), sqlResultReadOptimized); + assertQuery(format(sqlTemplate, "stock_ticks_morn_rt"), sqlResult); + } + + @Test + public void testDemoQuery2() + { + // Column _hoodie_commit_time changed to _hoodie_record_key + @Language("SQL") String sqlTemplate = "SELECT \"_hoodie_record_key\", symbol, ts, volume, open, close FROM %s WHERE symbol = 'GOOG'"; + @Language("SQL") String sqlResult = "SELECT * FROM VALUES " + + "('GOOG_2018-08-31 09', 'GOOG', '2018-08-31 09:59:00', 6330, 1230.5, 1230.02), " + + "('GOOG_2018-08-31 10', 'GOOG', '2018-08-31 10:59:00', 9021, 1227.1993, 1227.215)"; + @Language("SQL") String sqlResultReadOptimized = "SELECT * FROM VALUES " + + "('GOOG_2018-08-31 09', 'GOOG', '2018-08-31 09:59:00', 6330, 1230.5, 1230.02), " + + "('GOOG_2018-08-31 10', 'GOOG', '2018-08-31 10:29:00', 3391, 1230.1899, 1230.085)"; + + assertQuery(format(sqlTemplate, "stock_ticks_cow"), sqlResult); + assertQuery(format(sqlTemplate, "stock_ticks_cown"), sqlResult); + assertQuery(format(sqlTemplate, "stock_ticks_mor_ro"), sqlResultReadOptimized); + assertQuery(format(sqlTemplate, "stock_ticks_mor_rt"), sqlResult); + assertQuery(format(sqlTemplate, "stock_ticks_morn_ro"), sqlResultReadOptimized); + assertQuery(format(sqlTemplate, "stock_ticks_morn_rt"), sqlResult); + } + + @Test + public void testQueryWithPartitionColumn() + { + @Language("SQL") String sqlTemplate = "SELECT symbol, ts, dt FROM %s WHERE symbol = 'GOOG' AND dt = '2018-08-31'"; + @Language("SQL") String sqlResult = "SELECT * FROM VALUES " + + "('GOOG', '2018-08-31 09:59:00', '2018-08-31')," + + "('GOOG', '2018-08-31 10:59:00', '2018-08-31')"; + @Language("SQL") String sqlResultReadOptimized = "SELECT * FROM VALUES " + + "('GOOG', '2018-08-31 09:59:00', '2018-08-31')," + + "('GOOG', '2018-08-31 10:29:00', '2018-08-31')"; + + assertQuery(format(sqlTemplate, "stock_ticks_cow"), sqlResult); + assertQuery(format(sqlTemplate, "stock_ticks_mor_ro"), sqlResultReadOptimized); + assertQuery(format(sqlTemplate, "stock_ticks_mor_rt"), sqlResult); + } + + @Test + public void testQueryOnUnavailablePartition() + { + @Language("SQL") String sqlTemplate = "SELECT symbol, ts, dt FROM %s WHERE symbol = 'GOOG' AND dt = '2018-08-30'"; + @Language("SQL") String sqlResult = "SELECT * FROM VALUES ('', '', '') LIMIT 0"; + + assertQuery(format(sqlTemplate, "stock_ticks_cow"), sqlResult); + assertQuery(format(sqlTemplate, "stock_ticks_mor_ro"), sqlResult); + assertQuery(format(sqlTemplate, "stock_ticks_mor_rt"), sqlResult); + } + + private static String generateDescribeIdenticalQuery(TypeManager typeManager, List metaColumns, List dataColumns, List partitionColumns) + { + Stream regularRows = Streams.concat(metaColumns.stream(), dataColumns.stream()) + .map(column -> format("('%s', '%s', '', '')", column.getName(), column.getType().getType(typeManager).getDisplayName())); + Stream partitionRows = partitionColumns.stream() + .map(column -> format("('%s', '%s', 'partition key', '')", column.getName(), column.getType().getType(typeManager).getDisplayName())); + String rows = Streams.concat(regularRows, partitionRows).collect(Collectors.joining(",")); + return "SELECT * FROM VALUES " + rows; + } +} diff --git a/presto-hive/src/test/resources/hudi-testing-data.md b/presto-hive/src/test/resources/hudi-testing-data.md new file mode 100644 index 000000000000..1182277a8fba --- /dev/null +++ b/presto-hive/src/test/resources/hudi-testing-data.md @@ -0,0 +1,33 @@ +## About hudi-testing-data.zip + +The archive file `hudi-testing-data.zip` contains data files for 4 Hudi tables. + +- `stock_ticks_cow`: a partitioned copy-on-write table +- `stock_ticks_cow`: a non-partitioned copy-on-write table, +- `stock_ticks_mor`: a partitioned merge-on-read table +- `stock_ticks_morn`: a non-partitioned merge-on-read table; + +In `HudiTestingDataGenerator`, each merge-on-read table creates two table entries into hive metastore +(one table name suffixed `_ro` and the other suffixed `_rt`), as hudi-hive-sync tool does. + +The table data is generated following the doc at https://hudi.apache.org/docs/docker_demo/ + +All the tables have the same data columns: + +| Name | Type | +|--------|---------| +| volume | bigint | +| ts | varchar | +| symbol | varchar | +| year | integer | +| month | varchar | +| high | double | +| low | double | +| key | varchar | +| date | varchar | +| close | double | +| open | double | +| day | varchar | + +Each partitioned table has a partition column, named `dt`, of type `varchar`, +and has partition named `dt=2018-08-31` at the subdirectory `2018/08/31`. diff --git a/presto-hive/src/test/resources/hudi-testing-data.zip b/presto-hive/src/test/resources/hudi-testing-data.zip new file mode 100644 index 000000000000..00c789892684 Binary files /dev/null and b/presto-hive/src/test/resources/hudi-testing-data.zip differ