diff --git a/presto-native-execution/pom.xml b/presto-native-execution/pom.xml index 3aa22e7e78d9c..a0ec5407b287b 100644 --- a/presto-native-execution/pom.xml +++ b/presto-native-execution/pom.xml @@ -351,7 +351,7 @@ org.apache.maven.plugins maven-surefire-plugin - writer,parquet,remote-function,textfile_reader,no_textfile_reader,async_data_cache + writer,parquet,remote-function,textfile_reader,async_data_cache diff --git a/presto-native-execution/presto_cpp/main/CMakeLists.txt b/presto-native-execution/presto_cpp/main/CMakeLists.txt index 2d3137691c5e2..ae38c9617d653 100644 --- a/presto-native-execution/presto_cpp/main/CMakeLists.txt +++ b/presto-native-execution/presto_cpp/main/CMakeLists.txt @@ -64,6 +64,8 @@ target_link_libraries( velox_dwio_orc_reader velox_dwio_parquet_reader velox_dwio_parquet_writer + velox_dwio_text_reader_register + velox_dwio_text_writer_register velox_dynamic_library_loader velox_encode velox_exec diff --git a/presto-native-execution/presto_cpp/main/PrestoServer.cpp b/presto-native-execution/presto_cpp/main/PrestoServer.cpp index e6eca5ff4ccbf..baee62f4883dd 100644 --- a/presto-native-execution/presto_cpp/main/PrestoServer.cpp +++ b/presto-native-execution/presto_cpp/main/PrestoServer.cpp @@ -58,6 +58,8 @@ #include "velox/dwio/orc/reader/OrcReader.h" #include "velox/dwio/parquet/RegisterParquetReader.h" #include "velox/dwio/parquet/RegisterParquetWriter.h" +#include "velox/dwio/text/RegisterTextReader.h" +#include "velox/dwio/text/RegisterTextWriter.h" #include "velox/exec/OutputBufferManager.h" #include "velox/functions/prestosql/aggregates/RegisterAggregateFunctions.h" #include "velox/functions/prestosql/registration/RegistrationFunctions.h" @@ -1397,6 +1399,8 @@ void PrestoServer::registerFileReadersAndWriters() { velox::orc::registerOrcReaderFactory(); velox::parquet::registerParquetReaderFactory(); velox::parquet::registerParquetWriterFactory(); + velox::text::registerTextReaderFactory(); + velox::text::registerTextWriterFactory(); } void PrestoServer::unregisterFileReadersAndWriters() { @@ -1404,6 +1408,8 @@ void PrestoServer::unregisterFileReadersAndWriters() { velox::dwrf::unregisterDwrfWriterFactory(); velox::parquet::unregisterParquetReaderFactory(); velox::parquet::unregisterParquetWriterFactory(); + velox::text::unregisterTextReaderFactory(); + velox::text::unregisterTextWriterFactory(); } void PrestoServer::registerStatsCounters() { diff --git a/presto-native-execution/presto_cpp/main/connectors/PrestoToVeloxConnector.cpp b/presto-native-execution/presto_cpp/main/connectors/PrestoToVeloxConnector.cpp index 4e308f7eb0031..9f5f4acf0824f 100644 --- a/presto-native-execution/presto_cpp/main/connectors/PrestoToVeloxConnector.cpp +++ b/presto-native-execution/presto_cpp/main/connectors/PrestoToVeloxConnector.cpp @@ -910,6 +910,8 @@ dwio::common::FileFormat toFileFormat( case protocol::hive::HiveStorageFormat::ALPHA: // This has been renamed in Velox from ALPHA to NIMBLE. return dwio::common::FileFormat::NIMBLE; + case protocol::hive::HiveStorageFormat::TEXTFILE: + return dwio::common::FileFormat::TEXT; default: VELOX_UNSUPPORTED( "Unsupported file format in {}: {}.", diff --git a/presto-native-execution/src/test/java/com/facebook/presto/nativeworker/AbstractTestNativeGeneralQueries.java b/presto-native-execution/src/test/java/com/facebook/presto/nativeworker/AbstractTestNativeGeneralQueries.java index 05488c208d5e0..fa90200118c69 100644 --- a/presto-native-execution/src/test/java/com/facebook/presto/nativeworker/AbstractTestNativeGeneralQueries.java +++ b/presto-native-execution/src/test/java/com/facebook/presto/nativeworker/AbstractTestNativeGeneralQueries.java @@ -403,6 +403,64 @@ public void testDateFilter() } } + @Test(groups = {"textfile_reader"}) + public void testTableWrite() + { + String tmpTableName = generateRandomTableName(); + try { + getQueryRunner().execute(String.format( + "CREATE TABLE %s (" + + "id BIGINT," + + "name VARCHAR," + + "is_active BOOLEAN," + + "score DOUBLE," + + "created_at TIMESTAMP," + + "tags ARRAY," + + "metrics ARRAY," + + "properties MAP," + + "flags MAP," + + "nested_struct ROW(sub_id INTEGER, sub_name VARCHAR, sub_scores ARRAY, sub_map MAP)," + + "ds VARCHAR" + + ") WITH (format = 'TEXTFILE', oncall = 'presto', partitioned_by = ARRAY['ds'], retention_days = 30)", tmpTableName)); + + getQueryRunner().execute(String.format( + "INSERT INTO %s (" + + "id," + + "name," + + "is_active," + + "score," + + "created_at," + + "tags," + + "metrics," + + "properties," + + "flags," + + "nested_struct," + + "ds" + + ") VALUES (" + + "1001," + + "'Jane Doe'," + + "TRUE," + + "88.5," + + "TIMESTAMP '2025-07-23 10:00:00'," + + "ARRAY['alpha', 'beta', 'gamma']," + + "ARRAY[3.14, 2.71, 1.41]," + + "MAP(ARRAY['color', 'size'], ARRAY['blue', 'large'])," + + "MAP(ARRAY[TINYINT '1', TINYINT '2'], ARRAY[TRUE, FALSE])," + + "ROW(" + + "42," + + "'sub_jane'," + + "ARRAY[REAL '1.1', REAL '2.2', REAL '3.3']," + + "MAP(ARRAY[SMALLINT '10', SMALLINT '20'], ARRAY['foo', 'bar'])" + + ")," + + "'2025-07-01'" + + ")", tmpTableName)); + assertQueryResultCount(String.format("SELECT count(*) FROM %s", tmpTableName), 1); + } + finally { + dropTableIfExists(tmpTableName); + } + } + @Test public void testOrderBy() { @@ -1259,18 +1317,6 @@ public void testReadTableWithUnsupportedJsonFormat() assertQueryFails("SELECT * FROM nation_json", ".*ReaderFactory is not registered for format json.*"); } - @Test(groups = {"no_textfile_reader"}) - public void testReadTableWithUnsupportedTextfileFormat() - { - assertQueryFails("SELECT * FROM nation_text", ".*ReaderFactory is not registered for format text.*"); - } - - @Test(groups = {"textfile_reader"}) - public void testReadTableWithTextfileFormat() - { - assertQuery("SELECT * FROM nation_text"); - } - private void dropTableIfExists(String tableName) { // An ugly workaround for the lack of getExpectedQueryRunner() @@ -1671,10 +1717,10 @@ public void testSelectFieldsWithCapitalLetters() ColumnMetadata.builder() .setName("col") .setType(RowType.from(ImmutableList.of( - new RowType.Field(Optional.of("NationKey"), BIGINT), - new RowType.Field(Optional.of("NAME"), VARCHAR), - new RowType.Field(Optional.of("ReGiOnKeY"), BIGINT), - new RowType.Field(Optional.of("commenT"), VARCHAR)))) + new RowType.Field(Optional.of("NationKey"), BIGINT), + new RowType.Field(Optional.of("NAME"), VARCHAR), + new RowType.Field(Optional.of("ReGiOnKeY"), BIGINT), + new RowType.Field(Optional.of("commenT"), VARCHAR)))) .build()), tableProperties); transaction(queryRunner.getTransactionManager(), queryRunner.getAccessControl()) @@ -1830,15 +1876,16 @@ public void testUnicodeInJson() { // Test casting to JSON returning the same results for all unicode characters in the // entire range. - List unicodeRanges = new ArrayList() { + List unicodeRanges = new ArrayList() + { { - add(new int[]{0, 0x7F}); - add(new int[]{0x80, 0xD7FF}); - add(new int[]{0xE000, 0xFFFF}); + add(new int[] {0, 0x7F}); + add(new int[] {0x80, 0xD7FF}); + add(new int[] {0xE000, 0xFFFF}); } }; for (int start = 0x10000; start < 0x110000; start += 0x10000) { - unicodeRanges.add(new int[]{start, start + 0xFFFF}); + unicodeRanges.add(new int[] {start, start + 0xFFFF}); } List unicodeStrings = unicodeRanges.stream().map(range -> { StringBuilder unicodeString = new StringBuilder(); diff --git a/presto-native-execution/src/test/java/com/facebook/presto/spark/TestPrestoSparkNativeGeneralQueries.java b/presto-native-execution/src/test/java/com/facebook/presto/spark/TestPrestoSparkNativeGeneralQueries.java index 902de47b2fd79..8a62081a09779 100644 --- a/presto-native-execution/src/test/java/com/facebook/presto/spark/TestPrestoSparkNativeGeneralQueries.java +++ b/presto-native-execution/src/test/java/com/facebook/presto/spark/TestPrestoSparkNativeGeneralQueries.java @@ -66,9 +66,9 @@ public void testUnicodeInJson() @Ignore public void testDistributedSortSingleNode() {} - // Disable: Text file reader is not supported. This test is also disabled in pom.xml through disabling groups "textfile_reader". + // Disable: Text file reader and writer is not supported. @Override - public void testReadTableWithTextfileFormat() {} + public void testTableWrite() {} // Disable: Not supporte by POS @Override