This is an automated email from the ASF dual-hosted git repository.
lzljs3620320 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/paimon.git
The following commit(s) were added to refs/heads/master by this push:
new c4ef18182 [hive] Add hive on tez read table test (#3926)
c4ef18182 is described below
commit c4ef181821f4c0f6b027fb0f1e6c23a557123f33
Author: Kerwin <[email protected]>
AuthorDate: Sun Aug 11 19:45:25 2024 +0800
[hive] Add hive on tez read table test (#3926)
---
.../apache/paimon/hive/Hive23CatalogITCase.java | 3 -
.../apache/paimon/hive/Hive31CatalogITCase.java | 3 -
.../org/apache/paimon/hive/HiveOnMrReadITCase.java | 34 ++++
.../apache/paimon/hive/HiveOnTezReadITCase.java | 46 +++++
.../org/apache/paimon/hive/HiveReadITCase.java | 171 ------------------
...eHandlerITCase.java => HiveReadITCaseBase.java} | 194 +++++++++++++++------
6 files changed, 223 insertions(+), 228 deletions(-)
diff --git
a/paimon-hive/paimon-hive-connector-2.3/src/test/java/org/apache/paimon/hive/Hive23CatalogITCase.java
b/paimon-hive/paimon-hive-connector-2.3/src/test/java/org/apache/paimon/hive/Hive23CatalogITCase.java
index 1f86fa9e3..204f779d7 100644
---
a/paimon-hive/paimon-hive-connector-2.3/src/test/java/org/apache/paimon/hive/Hive23CatalogITCase.java
+++
b/paimon-hive/paimon-hive-connector-2.3/src/test/java/org/apache/paimon/hive/Hive23CatalogITCase.java
@@ -19,7 +19,6 @@
package org.apache.paimon.hive;
import org.apache.paimon.fs.local.LocalFileIO;
-import org.apache.paimon.hive.runner.PaimonEmbeddedHiveRunner;
import org.apache.paimon.schema.SchemaManager;
import com.klarna.hiverunner.annotations.HiveRunnerSetup;
@@ -30,7 +29,6 @@ import
org.apache.flink.table.api.internal.TableEnvironmentImpl;
import org.apache.flink.types.Row;
import org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
import org.junit.Test;
-import org.junit.runner.RunWith;
import java.util.Arrays;
@@ -42,7 +40,6 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
/** IT cases for using Paimon {@link HiveCatalog} together with Paimon Hive
2.3 connector. */
-@RunWith(PaimonEmbeddedHiveRunner.class)
public class Hive23CatalogITCase extends HiveCatalogITCaseBase {
@HiveRunnerSetup
diff --git
a/paimon-hive/paimon-hive-connector-3.1/src/test/java/org/apache/paimon/hive/Hive31CatalogITCase.java
b/paimon-hive/paimon-hive-connector-3.1/src/test/java/org/apache/paimon/hive/Hive31CatalogITCase.java
index 5963faf42..1cd17553f 100644
---
a/paimon-hive/paimon-hive-connector-3.1/src/test/java/org/apache/paimon/hive/Hive31CatalogITCase.java
+++
b/paimon-hive/paimon-hive-connector-3.1/src/test/java/org/apache/paimon/hive/Hive31CatalogITCase.java
@@ -19,7 +19,6 @@
package org.apache.paimon.hive;
import org.apache.paimon.fs.local.LocalFileIO;
-import org.apache.paimon.hive.runner.PaimonEmbeddedHiveRunner;
import org.apache.paimon.schema.SchemaManager;
import com.klarna.hiverunner.annotations.HiveRunnerSetup;
@@ -30,7 +29,6 @@ import
org.apache.flink.table.api.internal.TableEnvironmentImpl;
import org.apache.flink.types.Row;
import org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
import org.junit.Test;
-import org.junit.runner.RunWith;
import java.util.Arrays;
@@ -42,7 +40,6 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
/** IT cases for using Paimon {@link HiveCatalog} together with Paimon Hive
3.1 connector. */
-@RunWith(PaimonEmbeddedHiveRunner.class)
public class Hive31CatalogITCase extends HiveCatalogITCaseBase {
@HiveRunnerSetup
diff --git
a/paimon-hive/paimon-hive-connector-common/src/test/java/org/apache/paimon/hive/HiveOnMrReadITCase.java
b/paimon-hive/paimon-hive-connector-common/src/test/java/org/apache/paimon/hive/HiveOnMrReadITCase.java
new file mode 100644
index 000000000..539ee59b5
--- /dev/null
+++
b/paimon-hive/paimon-hive-connector-common/src/test/java/org/apache/paimon/hive/HiveOnMrReadITCase.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.paimon.hive;
+
+import org.apache.paimon.hive.mapred.PaimonInputFormat;
+import org.apache.paimon.hive.mapred.PaimonRecordReader;
+
+import org.junit.Before;
+
+/** IT cases for {@link PaimonRecordReader} and {@link PaimonInputFormat} with
Hive On MR. */
+public class HiveOnMrReadITCase extends HiveReadITCaseBase {
+
+ @Before
+ public void before() throws Exception {
+ super.before();
+ setHiveExecuteEngineToMR();
+ }
+}
diff --git
a/paimon-hive/paimon-hive-connector-common/src/test/java/org/apache/paimon/hive/HiveOnTezReadITCase.java
b/paimon-hive/paimon-hive-connector-common/src/test/java/org/apache/paimon/hive/HiveOnTezReadITCase.java
new file mode 100644
index 000000000..5d75ba65c
--- /dev/null
+++
b/paimon-hive/paimon-hive-connector-common/src/test/java/org/apache/paimon/hive/HiveOnTezReadITCase.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.paimon.hive;
+
+import org.apache.paimon.hive.mapred.PaimonInputFormat;
+import org.apache.paimon.hive.mapred.PaimonRecordReader;
+
+import org.junit.Before;
+
+/** IT cases for {@link PaimonRecordReader} and {@link PaimonInputFormat} with
Hive On Tez. */
+public class HiveOnTezReadITCase extends HiveReadITCaseBase {
+
+ @Before
+ public void before() throws Exception {
+ super.before();
+ setHiveExecutionEngine();
+ }
+
+ @Override
+ protected void setHiveExecutionEngine() {
+ hiveShell.execute("SET hive.execution.engine=tez");
+ hiveShell.execute("SET tez.local.mode=true");
+ hiveShell.execute("SET hive.jar.directory=" +
folder.getRoot().getAbsolutePath());
+ hiveShell.execute("SET tez.staging-dir=" +
folder.getRoot().getAbsolutePath());
+ // JVM will crash if we do not set this and include
paimon-flink-common as dependency
+ // not sure why
+ // in real use case there won't be any Flink dependency in Hive's
classpath, so it's OK
+ hiveShell.execute("SET hive.tez.exec.inplace.progress=false");
+ }
+}
diff --git
a/paimon-hive/paimon-hive-connector-common/src/test/java/org/apache/paimon/hive/HiveReadITCase.java
b/paimon-hive/paimon-hive-connector-common/src/test/java/org/apache/paimon/hive/HiveReadITCase.java
deleted file mode 100644
index 1f63e07b4..000000000
---
a/paimon-hive/paimon-hive-connector-common/src/test/java/org/apache/paimon/hive/HiveReadITCase.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.apache.paimon.hive;
-
-import org.apache.paimon.CoreOptions;
-import org.apache.paimon.catalog.AbstractCatalog;
-import org.apache.paimon.catalog.Identifier;
-import org.apache.paimon.data.BinaryString;
-import org.apache.paimon.data.GenericRow;
-import org.apache.paimon.data.InternalRow;
-import org.apache.paimon.fs.Path;
-import org.apache.paimon.fs.local.LocalFileIO;
-import org.apache.paimon.hive.mapred.PaimonInputFormat;
-import org.apache.paimon.hive.mapred.PaimonRecordReader;
-import org.apache.paimon.options.CatalogOptions;
-import org.apache.paimon.options.Options;
-import org.apache.paimon.schema.Schema;
-import org.apache.paimon.schema.SchemaChange;
-import org.apache.paimon.schema.SchemaManager;
-import org.apache.paimon.table.Table;
-import org.apache.paimon.table.sink.StreamTableCommit;
-import org.apache.paimon.table.sink.StreamTableWrite;
-import org.apache.paimon.table.sink.StreamWriteBuilder;
-import org.apache.paimon.types.DataField;
-import org.apache.paimon.types.DataTypes;
-import org.apache.paimon.types.RowType;
-
-import org.apache.paimon.shade.guava30.com.google.common.collect.Lists;
-import org.apache.paimon.shade.guava30.com.google.common.collect.Maps;
-
-import org.junit.Test;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatCode;
-
-/** IT cases for {@link PaimonRecordReader} and {@link PaimonInputFormat}. */
-public class HiveReadITCase extends HiveTestBase {
-
- @Test
- public void testReadExternalTableWithEmptyDataAndIgnoreCase() throws
Exception {
- // Create hive external table with paimon table
- String tableName = "with_ignore_case";
-
- // Create a paimon table
- Schema schema =
- new Schema(
- Lists.newArrayList(
- new DataField(0, "col1", DataTypes.INT(),
"first comment"),
- new DataField(1, "Col2", DataTypes.STRING(),
"second comment")),
- Collections.emptyList(),
- Collections.emptyList(),
- Maps.newHashMap(),
- "");
- Identifier identifier = Identifier.create(DATABASE_TEST, tableName);
- Path tablePath = AbstractCatalog.newTableLocation(path, identifier);
- new SchemaManager(LocalFileIO.create(), tablePath).createTable(schema);
-
- // Create hive external table
- String hiveSql =
- String.join(
- "\n",
- Arrays.asList(
- "CREATE EXTERNAL TABLE " + tableName + " ",
- "STORED BY '" +
PaimonStorageHandler.class.getName() + "'",
- "LOCATION '" + tablePath.toUri().toString() +
"'"));
- assertThatCode(() ->
hiveShell.execute(hiveSql)).doesNotThrowAnyException();
- List<String> result = hiveShell.executeQuery("SHOW CREATE TABLE " +
tableName);
- assertThat(result)
- .containsAnyOf(
- "CREATE EXTERNAL TABLE `with_paimon_table`(",
- " `col1` int COMMENT 'first comment', ",
- " `col2` string COMMENT 'second comment')",
- "ROW FORMAT SERDE ",
- " 'org.apache.paimon.hive.PaimonSerDe' ",
- "STORED BY ",
- " 'org.apache.paimon.hive.PaimonStorageHandler' ");
-
- hiveShell.execute("INSERT INTO " + tableName + " VALUES
(1,'Hello'),(2,'Paimon')");
- result = hiveShell.executeQuery("SELECT col2, col1 FROM " + tableName);
- assertThat(result).containsExactly("Hello\t1", "Paimon\t2");
- result = hiveShell.executeQuery("SELECT col2 FROM " + tableName);
- assertThat(result).containsExactly("Hello", "Paimon");
- result = hiveShell.executeQuery("SELECT Col2 FROM " + tableName);
- assertThat(result).containsExactly("Hello", "Paimon");
- result = hiveShell.executeQuery("SELECT * FROM " + tableName + " WHERE
col2 = 'Hello'");
- assertThat(result).containsExactly("1\tHello");
- result =
- hiveShell.executeQuery(
- "SELECT * FROM " + tableName + " WHERE Col2 in
('Hello', 'Paimon')");
- assertThat(result).containsExactly("1\tHello", "2\tPaimon");
- }
-
- @Test
- public void testReadExternalTableWithDataAndIgnoreCase() throws Exception {
- // Create hive external table with paimon table
- String tableName = "with_data_and_ignore_case";
-
- // Create a paimon table
- Identifier identifier = Identifier.create(DATABASE_TEST, tableName);
-
- Options conf = new Options();
- conf.set(CatalogOptions.WAREHOUSE, path);
- conf.set(CoreOptions.FILE_FORMAT, CoreOptions.FILE_FORMAT_AVRO);
- RowType.Builder rowType = RowType.builder();
- rowType.field("col1", DataTypes.INT());
- rowType.field("Col2", DataTypes.STRING());
-
- Table table =
- FileStoreTestUtils.createFileStoreTable(
- conf,
- rowType.build(),
- Collections.emptyList(),
- Collections.emptyList(),
- identifier);
-
- // insert data into paimon table, make sure has some data file use
older schema file.
- List<InternalRow> data =
- Arrays.asList(
- GenericRow.of(1, BinaryString.fromString("Hello")),
- GenericRow.of(2, BinaryString.fromString("Paimon")));
-
- StreamWriteBuilder streamWriteBuilder = table.newStreamWriteBuilder();
- StreamTableWrite write = streamWriteBuilder.newWrite();
- StreamTableCommit commit = streamWriteBuilder.newCommit();
- for (InternalRow rowData : data) {
- write.write(rowData);
- }
- commit.commit(0, write.prepareCommit(true, 0));
- write.close();
- commit.close();
-
- // add column, do some ddl which will generate a new version schema-n
file.
- Path tablePath = AbstractCatalog.newTableLocation(path, identifier);
- SchemaManager schemaManager = new SchemaManager(LocalFileIO.create(),
tablePath);
- schemaManager.commitChanges(SchemaChange.addColumn("N1",
DataTypes.STRING()));
-
- // Create hive external table
- String hiveSql =
- String.join(
- "\n",
- Arrays.asList(
- "CREATE EXTERNAL TABLE " + tableName + " ",
- "STORED BY '" +
PaimonStorageHandler.class.getName() + "'",
- "LOCATION '" + tablePath.toUri().toString() +
"'"));
- assertThatCode(() ->
hiveShell.execute(hiveSql)).doesNotThrowAnyException();
-
- List<String> result =
- hiveShell.executeQuery("SELECT * FROM " + tableName + " WHERE
col2 is not null");
- assertThat(result).containsExactly("1\tHello\tNULL",
"2\tPaimon\tNULL");
- }
-}
diff --git
a/paimon-hive/paimon-hive-connector-common/src/test/java/org/apache/paimon/hive/PaimonStorageHandlerITCase.java
b/paimon-hive/paimon-hive-connector-common/src/test/java/org/apache/paimon/hive/HiveReadITCaseBase.java
similarity index 86%
rename from
paimon-hive/paimon-hive-connector-common/src/test/java/org/apache/paimon/hive/PaimonStorageHandlerITCase.java
rename to
paimon-hive/paimon-hive-connector-common/src/test/java/org/apache/paimon/hive/HiveReadITCaseBase.java
index d0042bf01..4b16788ee 100644
---
a/paimon-hive/paimon-hive-connector-common/src/test/java/org/apache/paimon/hive/PaimonStorageHandlerITCase.java
+++
b/paimon-hive/paimon-hive-connector-common/src/test/java/org/apache/paimon/hive/HiveReadITCaseBase.java
@@ -19,6 +19,7 @@
package org.apache.paimon.hive;
import org.apache.paimon.CoreOptions;
+import org.apache.paimon.catalog.AbstractCatalog;
import org.apache.paimon.catalog.Identifier;
import org.apache.paimon.data.BinaryString;
import org.apache.paimon.data.Decimal;
@@ -26,37 +27,40 @@ import org.apache.paimon.data.GenericMap;
import org.apache.paimon.data.GenericRow;
import org.apache.paimon.data.InternalRow;
import org.apache.paimon.data.Timestamp;
+import org.apache.paimon.fs.Path;
+import org.apache.paimon.fs.local.LocalFileIO;
import org.apache.paimon.hive.mapred.PaimonInputFormat;
+import org.apache.paimon.hive.mapred.PaimonRecordReader;
import org.apache.paimon.hive.objectinspector.PaimonObjectInspectorFactory;
-import org.apache.paimon.hive.runner.PaimonEmbeddedHiveRunner;
import org.apache.paimon.options.CatalogOptions;
import org.apache.paimon.options.Options;
+import org.apache.paimon.schema.Schema;
+import org.apache.paimon.schema.SchemaChange;
+import org.apache.paimon.schema.SchemaManager;
import org.apache.paimon.table.FileStoreTable;
import org.apache.paimon.table.Table;
import org.apache.paimon.table.sink.StreamTableCommit;
import org.apache.paimon.table.sink.StreamTableWrite;
import org.apache.paimon.table.sink.StreamWriteBuilder;
+import org.apache.paimon.types.DataField;
import org.apache.paimon.types.DataType;
import org.apache.paimon.types.DataTypes;
import org.apache.paimon.types.RowKind;
import org.apache.paimon.types.RowType;
-import com.klarna.hiverunner.HiveShell;
-import com.klarna.hiverunner.annotations.HiveSQL;
+import org.apache.paimon.shade.guava30.com.google.common.collect.Lists;
+import org.apache.paimon.shade.guava30.com.google.common.collect.Maps;
+
import org.apache.hadoop.hive.common.type.HiveDecimal;
import org.apache.hadoop.hive.serde2.objectinspector.ListObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.MapObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import
org.apache.hadoop.hive.serde2.objectinspector.primitive.AbstractPrimitiveJavaObjectInspector;
-import org.junit.After;
import org.junit.Before;
-import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
-import org.junit.runner.RunWith;
-import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
@@ -71,64 +75,27 @@ import java.util.concurrent.ThreadLocalRandom;
import static org.apache.paimon.hive.FileStoreTestUtils.DATABASE_NAME;
import static org.apache.paimon.hive.FileStoreTestUtils.TABLE_NAME;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
-/** IT cases for {@link PaimonStorageHandler} and {@link PaimonInputFormat}. */
-@RunWith(PaimonEmbeddedHiveRunner.class)
-public class PaimonStorageHandlerITCase {
+/** IT cases for {@link PaimonRecordReader} and {@link PaimonInputFormat}. */
+public abstract class HiveReadITCaseBase extends HiveTestBase {
@ClassRule public static TemporaryFolder folder = new TemporaryFolder();
- @HiveSQL(files = {})
- private static HiveShell hiveShell;
-
- private static String engine;
-
- private String warehouse;
private String tablePath;
private Identifier identifier;
private String externalTable;
private long commitIdentifier;
- @BeforeClass
- public static void beforeClass() {
- // TODO Currently FlinkEmbeddedHiveRunner can only be used for one
test class,
- // so we have to select engine randomly. Write our own Hive tester in
the future.
- // engine = ThreadLocalRandom.current().nextBoolean() ? "mr" : "tez";
- engine = "mr";
- }
-
@Before
- public void before() throws IOException {
- if ("mr".equals(engine)) {
- hiveShell.execute("SET hive.execution.engine=mr");
- } else if ("tez".equals(engine)) {
- hiveShell.execute("SET hive.execution.engine=tez");
- hiveShell.execute("SET tez.local.mode=true");
- hiveShell.execute("SET hive.jar.directory=" +
folder.getRoot().getAbsolutePath());
- hiveShell.execute("SET tez.staging-dir=" +
folder.getRoot().getAbsolutePath());
- // JVM will crash if we do not set this and include
paimon-flink-common as dependency
- // not sure why
- // in real use case there won't be any Flink dependency in Hive's
classpath, so it's OK
- hiveShell.execute("SET hive.tez.exec.inplace.progress=false");
- } else {
- throw new UnsupportedOperationException("Unsupported engine " +
engine);
- }
-
- hiveShell.execute("CREATE DATABASE IF NOT EXISTS test_db");
- hiveShell.execute("USE test_db");
-
- warehouse = folder.newFolder().toURI().toString();
- tablePath = String.format("%s/test_db.db/%s", warehouse, TABLE_NAME);
+ public void before() throws Exception {
+ super.before();
+ tablePath = String.format("%s/test_db.db/%s", path, TABLE_NAME);
identifier = Identifier.create(DATABASE_NAME, TABLE_NAME);
externalTable = "test_table_" +
UUID.randomUUID().toString().substring(0, 4);
commitIdentifier = 0;
}
- @After
- public void after() {
- hiveShell.execute("DROP DATABASE IF EXISTS test_db CASCADE");
- }
-
@Test
public void testReadExternalTableNoPartitionWithPk() throws Exception {
List<InternalRow> data =
@@ -970,7 +937,7 @@ public class PaimonStorageHandlerITCase {
private Options getBasicConf() {
Options conf = new Options();
- conf.set(CatalogOptions.WAREHOUSE, warehouse);
+ conf.set(CatalogOptions.WAREHOUSE, path);
return conf;
}
@@ -983,4 +950,129 @@ public class PaimonStorageHandlerITCase {
"STORED BY '" +
PaimonStorageHandler.class.getName() + "'",
"LOCATION '" + tablePath + "'")));
}
+
+ protected void setHiveExecutionEngine() {
+ // By default uses hive on mr.
+ }
+
+ protected void setHiveExecuteEngineToMR() {
+ hiveShell.execute("SET hive.execution.engine=mr");
+ }
+
+ @Test
+ public void testReadExternalTableWithEmptyDataAndIgnoreCase() throws
Exception {
+ // Create hive external table with paimon table
+ String tableName = "with_ignore_case";
+
+ // Create a paimon table
+ Schema schema =
+ new Schema(
+ Lists.newArrayList(
+ new DataField(0, "col1", DataTypes.INT(),
"first comment"),
+ new DataField(1, "Col2", DataTypes.STRING(),
"second comment")),
+ Collections.emptyList(),
+ Collections.emptyList(),
+ Maps.newHashMap(),
+ "");
+ Identifier identifier = Identifier.create(DATABASE_TEST, tableName);
+ Path tablePath = AbstractCatalog.newTableLocation(path, identifier);
+ new SchemaManager(LocalFileIO.create(), tablePath).createTable(schema);
+
+ // Create hive external table
+ String hiveSql =
+ String.join(
+ "\n",
+ Arrays.asList(
+ "CREATE EXTERNAL TABLE " + tableName + " ",
+ "STORED BY '" +
PaimonStorageHandler.class.getName() + "'",
+ "LOCATION '" + tablePath.toUri().toString() +
"'"));
+ assertThatCode(() ->
hiveShell.execute(hiveSql)).doesNotThrowAnyException();
+ List<String> result = hiveShell.executeQuery("SHOW CREATE TABLE " +
tableName);
+ assertThat(result)
+ .containsAnyOf(
+ "CREATE EXTERNAL TABLE `with_ignore_case`(",
+ " `col1` int COMMENT 'first comment', ",
+ " `col2` string COMMENT 'second comment')",
+ "ROW FORMAT SERDE ",
+ " 'org.apache.paimon.hive.PaimonSerDe' ",
+ "STORED BY ",
+ " 'org.apache.paimon.hive.PaimonStorageHandler' ");
+
+ // Only support hive on mr to insert data.
+ setHiveExecuteEngineToMR();
+ hiveShell.execute("INSERT INTO " + tableName + " VALUES
(1,'Hello'),(2,'Paimon')");
+
+ setHiveExecutionEngine();
+ result = hiveShell.executeQuery("SELECT col2, col1 FROM " + tableName);
+ assertThat(result).containsExactly("Hello\t1", "Paimon\t2");
+ result = hiveShell.executeQuery("SELECT col2 FROM " + tableName);
+ assertThat(result).containsExactly("Hello", "Paimon");
+ result = hiveShell.executeQuery("SELECT Col2 FROM " + tableName);
+ assertThat(result).containsExactly("Hello", "Paimon");
+ result = hiveShell.executeQuery("SELECT * FROM " + tableName + " WHERE
col2 = 'Hello'");
+ assertThat(result).containsExactly("1\tHello");
+ result =
+ hiveShell.executeQuery(
+ "SELECT * FROM " + tableName + " WHERE Col2 in
('Hello', 'Paimon')");
+ assertThat(result).containsExactly("1\tHello", "2\tPaimon");
+ }
+
+ @Test
+ public void testReadExternalTableWithDataAndIgnoreCase() throws Exception {
+ // Create hive external table with paimon table
+ String tableName = "with_data_and_ignore_case";
+
+ // Create a paimon table
+ Identifier identifier = Identifier.create(DATABASE_TEST, tableName);
+
+ Options conf = new Options();
+ conf.set(CatalogOptions.WAREHOUSE, path);
+ conf.set(CoreOptions.FILE_FORMAT, CoreOptions.FILE_FORMAT_AVRO);
+ RowType.Builder rowType = RowType.builder();
+ rowType.field("col1", DataTypes.INT());
+ rowType.field("Col2", DataTypes.STRING());
+
+ Table table =
+ FileStoreTestUtils.createFileStoreTable(
+ conf,
+ rowType.build(),
+ Collections.emptyList(),
+ Collections.emptyList(),
+ identifier);
+
+ // insert data into paimon table, make sure has some data file use
older schema file.
+ List<InternalRow> data =
+ Arrays.asList(
+ GenericRow.of(1, BinaryString.fromString("Hello")),
+ GenericRow.of(2, BinaryString.fromString("Paimon")));
+
+ StreamWriteBuilder streamWriteBuilder = table.newStreamWriteBuilder();
+ StreamTableWrite write = streamWriteBuilder.newWrite();
+ StreamTableCommit commit = streamWriteBuilder.newCommit();
+ for (InternalRow rowData : data) {
+ write.write(rowData);
+ }
+ commit.commit(0, write.prepareCommit(true, 0));
+ write.close();
+ commit.close();
+
+ // add column, do some ddl which will generate a new version schema-n
file.
+ Path tablePath = AbstractCatalog.newTableLocation(path, identifier);
+ SchemaManager schemaManager = new SchemaManager(LocalFileIO.create(),
tablePath);
+ schemaManager.commitChanges(SchemaChange.addColumn("N1",
DataTypes.STRING()));
+
+ // Create hive external table
+ String hiveSql =
+ String.join(
+ "\n",
+ Arrays.asList(
+ "CREATE EXTERNAL TABLE " + tableName + " ",
+ "STORED BY '" +
PaimonStorageHandler.class.getName() + "'",
+ "LOCATION '" + tablePath.toUri().toString() +
"'"));
+ assertThatCode(() ->
hiveShell.execute(hiveSql)).doesNotThrowAnyException();
+
+ List<String> result =
+ hiveShell.executeQuery("SELECT * FROM " + tableName + " WHERE
col2 is not null");
+ assertThat(result).containsExactly("1\tHello\tNULL",
"2\tPaimon\tNULL");
+ }
}