From 1fc3c96c396ebdc27b5f2ef38194869fd5877f25 Mon Sep 17 00:00:00 2001 From: Kevin Liu Date: Wed, 9 Sep 2026 23:53:08 -0700 Subject: [PATCH 1/5] Docs: Describe hive.hive2-compatible as the Hive 2 setting Co-Authored-By: Claude Fable 5.1 --- mkdocs/docs/configuration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkdocs/docs/configuration.md b/mkdocs/docs/configuration.md index 54d33dd00e..852142aa1f 100644 --- a/mkdocs/docs/configuration.md +++ b/mkdocs/docs/configuration.md @@ -746,12 +746,12 @@ catalog: | Key | Example | Description | |------------------------------| ------- | ------------------------------------ | -| hive.hive2-compatible | true | Using Hive 2.x compatibility mode | +| hive.hive2-compatible | true | Set to `true` when using a Hive 2.x metastore | | hive.kerberos-authentication | true | Using authentication via Kerberos | | hive.kerberos-service-name | hive | Kerberos service name (default hive) | | ugi | t-1234:secret | Hadoop UGI for Hive client. | -When using Hive 2.x, make sure to set the compatibility flag: +Hive 3 and newer need no extra configuration. When using a Hive 2.x metastore, set the compatibility flag: ```yaml catalog: From 0fb0179b022822b61b15b67733cd641e3f5d1640 Mon Sep 17 00:00:00 2001 From: Kevin Liu Date: Wed, 9 Sep 2026 23:53:11 -0700 Subject: [PATCH 2/5] Hive: Mark the commit lock as non-transactional Hive 2.1.0 rejects a lock component whose operation type arrives as the default UNSET, and the generated Thrift client always sends that default. The commit lock is not part of a metastore transaction, so send NO_TXN, which every Hive release accepts. Verified against Hive 2.0.0, 2.1.0, 2.3.2, 3.1.3, 4.0.0, 4.0.1, 4.1.0 and 4.2.1 metastores. Co-Authored-By: Claude Fable 5.1 --- pyiceberg/catalog/hive.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pyiceberg/catalog/hive.py b/pyiceberg/catalog/hive.py index 94213c8332..939f20662f 100644 --- a/pyiceberg/catalog/hive.py +++ b/pyiceberg/catalog/hive.py @@ -30,6 +30,7 @@ from hive_metastore.ttypes import ( AlreadyExistsException, CheckLockRequest, + DataOperationType, EnvironmentContext, FieldSchema, GetTableRequest, @@ -506,8 +507,15 @@ def load_view(self, identifier: str | Identifier) -> View: raise NotImplementedError def _create_lock_request(self, database_name: str, table_name: str) -> LockRequest: + # Iceberg commits do not open a metastore transaction, so the lock is marked NO_TXN. Setting it explicitly + # also matters for Hive 2.1, which rejects a lock component left at the default UNSET operation type. lock_component: LockComponent = LockComponent( - level=LockLevel.TABLE, type=LockType.EXCLUSIVE, dbname=database_name, tablename=table_name, isTransactional=True + level=LockLevel.TABLE, + type=LockType.EXCLUSIVE, + dbname=database_name, + tablename=table_name, + operationType=DataOperationType.NO_TXN, + isTransactional=True, ) lock_request: LockRequest = LockRequest(component=[lock_component], user=getpass.getuser(), hostname=socket.gethostname()) From 641c7eca65d1ea137654e1f1d76d73d996de30b5 Mon Sep 17 00:00:00 2001 From: Kevin Liu Date: Wed, 9 Sep 2026 23:53:13 -0700 Subject: [PATCH 3/5] Hive: Name the Hive versions that lack get_table_req Co-Authored-By: Claude Fable 5.1 --- pyiceberg/catalog/hive.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyiceberg/catalog/hive.py b/pyiceberg/catalog/hive.py index 939f20662f..57a03e7bce 100644 --- a/pyiceberg/catalog/hive.py +++ b/pyiceberg/catalog/hive.py @@ -384,7 +384,7 @@ def _create_hive_table(self, open_client: Client, hive_table: HiveTable) -> None raise TableAlreadyExistsError(f"Table {hive_table.dbName}.{hive_table.tableName} already exists") from e def _fetch_hive_table(self, open_client: Client, database_name: str, table_name: str) -> HiveTable: - # Hive 4.0.1 removed get_table, and Hive 2 does not have get_table_req + # Hive 4.0.1 removed get_table, and Hive 2.2 and older do not have get_table_req if self._hive2_compatible: return open_client.get_table(dbname=database_name, tbl_name=table_name) return open_client.get_table_req(GetTableRequest(dbName=database_name, tblName=table_name)).table From 7562860ba66eb665352143a6b4d3a231d08e7758 Mon Sep 17 00:00:00 2001 From: Kevin Liu Date: Thu, 10 Sep 2026 10:34:55 -0700 Subject: [PATCH 4/5] Clarify comments on lock request operation type Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- pyiceberg/catalog/hive.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyiceberg/catalog/hive.py b/pyiceberg/catalog/hive.py index 57a03e7bce..4e3a7e2a23 100644 --- a/pyiceberg/catalog/hive.py +++ b/pyiceberg/catalog/hive.py @@ -507,8 +507,8 @@ def load_view(self, identifier: str | Identifier) -> View: raise NotImplementedError def _create_lock_request(self, database_name: str, table_name: str) -> LockRequest: - # Iceberg commits do not open a metastore transaction, so the lock is marked NO_TXN. Setting it explicitly - # also matters for Hive 2.1, which rejects a lock component left at the default UNSET operation type. + # Iceberg commits are not executed within a Hive transaction, so the lock component uses operationType=NO_TXN. + # Setting it explicitly also matters for Hive 2.1, which rejects a lock component left at the default UNSET operation type. lock_component: LockComponent = LockComponent( level=LockLevel.TABLE, type=LockType.EXCLUSIVE, From 8cdf4505ec391835e86249d93d1e3bbfc55f7c6f Mon Sep 17 00:00:00 2001 From: Kevin Liu Date: Thu, 10 Sep 2026 11:05:49 -0700 Subject: [PATCH 5/5] Wrap lock request comment to fit line length Co-Authored-By: Claude Fable 5.1 --- pyiceberg/catalog/hive.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyiceberg/catalog/hive.py b/pyiceberg/catalog/hive.py index 4e3a7e2a23..a6dcd8196e 100644 --- a/pyiceberg/catalog/hive.py +++ b/pyiceberg/catalog/hive.py @@ -508,7 +508,8 @@ def load_view(self, identifier: str | Identifier) -> View: def _create_lock_request(self, database_name: str, table_name: str) -> LockRequest: # Iceberg commits are not executed within a Hive transaction, so the lock component uses operationType=NO_TXN. - # Setting it explicitly also matters for Hive 2.1, which rejects a lock component left at the default UNSET operation type. + # Setting it explicitly also matters for Hive 2.1, which rejects a lock component left at the default UNSET + # operation type. lock_component: LockComponent = LockComponent( level=LockLevel.TABLE, type=LockType.EXCLUSIVE,