Skip to content

Commit d741601

Browse files
jackye1995claude
andcommitted
fix: implement dropTable and fix deregisterTable semantics for hive2/hive3
- Add dropTable() method that deletes both metadata and data (deleteData=true) - Fix deregisterTable() to only remove metadata without deleting data (deleteData=false) - Update both Java and Python implementations for hive2 and hive3 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 14f1b51 commit d741601

4 files changed

Lines changed: 95 additions & 13 deletions

File tree

java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/Hive2Namespace.java

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import org.lance.namespace.model.DescribeTableResponse;
3535
import org.lance.namespace.model.DropNamespaceRequest;
3636
import org.lance.namespace.model.DropNamespaceResponse;
37+
import org.lance.namespace.model.DropTableRequest;
38+
import org.lance.namespace.model.DropTableResponse;
3739
import org.lance.namespace.model.ListNamespacesRequest;
3840
import org.lance.namespace.model.ListNamespacesResponse;
3941
import org.lance.namespace.model.ListTablesRequest;
@@ -312,14 +314,29 @@ public DeclareTableResponse declareTable(DeclareTableRequest request) {
312314
return response;
313315
}
314316

317+
@Override
318+
public DropTableResponse dropTable(DropTableRequest request) {
319+
ObjectIdentifier tableId = ObjectIdentifier.of(request.getId());
320+
321+
ValidationUtil.checkArgument(
322+
tableId.levels() == 2, "Expect 2-level table identifier but get %s", tableId);
323+
324+
String location = doDropTable(tableId, true);
325+
326+
DropTableResponse response = new DropTableResponse();
327+
response.setId(request.getId());
328+
response.setLocation(location);
329+
return response;
330+
}
331+
315332
@Override
316333
public DeregisterTableResponse deregisterTable(DeregisterTableRequest request) {
317334
ObjectIdentifier tableId = ObjectIdentifier.of(request.getId());
318335

319336
ValidationUtil.checkArgument(
320337
tableId.levels() == 2, "Expect 2-level table identifier but get %s", tableId);
321338

322-
String location = doDropTable(tableId);
339+
String location = doDropTable(tableId, false);
323340

324341
DeregisterTableResponse response = new DeregisterTableResponse();
325342
response.setId(request.getId());
@@ -525,7 +542,7 @@ protected List<String> doListTables(String db) {
525542
}
526543
}
527544

528-
protected String doDropTable(ObjectIdentifier id) {
545+
protected String doDropTable(ObjectIdentifier id, boolean deleteData) {
529546
String db = id.levelAtListPos(0).toLowerCase();
530547
String tableName = id.levelAtListPos(1).toLowerCase();
531548

@@ -541,11 +558,9 @@ protected String doDropTable(ObjectIdentifier id) {
541558
Hive2Util.validateLanceTable(hmsTable.get());
542559
String location = hmsTable.get().getSd().getLocation();
543560

544-
final boolean deleteData = true;
545-
final boolean ignoreUnknownTable = true;
546561
clientPool.run(
547562
client -> {
548-
client.dropTable(db, tableName, deleteData, ignoreUnknownTable);
563+
client.dropTable(db, tableName, deleteData, true /* ignoreUnknownTable */);
549564
return null;
550565
});
551566

java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/Hive3Namespace.java

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
import org.lance.namespace.model.DescribeTableResponse;
3636
import org.lance.namespace.model.DropNamespaceRequest;
3737
import org.lance.namespace.model.DropNamespaceResponse;
38+
import org.lance.namespace.model.DropTableRequest;
39+
import org.lance.namespace.model.DropTableResponse;
3840
import org.lance.namespace.model.ListNamespacesRequest;
3941
import org.lance.namespace.model.ListNamespacesResponse;
4042
import org.lance.namespace.model.ListTablesRequest;
@@ -329,14 +331,29 @@ public DeclareTableResponse declareTable(DeclareTableRequest request) {
329331
return response;
330332
}
331333

334+
@Override
335+
public DropTableResponse dropTable(DropTableRequest request) {
336+
ObjectIdentifier tableId = ObjectIdentifier.of(request.getId());
337+
338+
ValidationUtil.checkArgument(
339+
tableId.levels() == 3, "Expect 3-level table identifier but get %s", tableId);
340+
341+
String location = doDropTable(tableId, true);
342+
343+
DropTableResponse response = new DropTableResponse();
344+
response.setId(request.getId());
345+
response.setLocation(location);
346+
return response;
347+
}
348+
332349
@Override
333350
public DeregisterTableResponse deregisterTable(DeregisterTableRequest request) {
334351
ObjectIdentifier tableId = ObjectIdentifier.of(request.getId());
335352

336353
ValidationUtil.checkArgument(
337354
tableId.levels() == 3, "Expect 3-level table identifier but get %s", tableId);
338355

339-
String location = doDropTable(tableId);
356+
String location = doDropTable(tableId, false);
340357

341358
DeregisterTableResponse response = new DeregisterTableResponse();
342359
response.setId(request.getId());
@@ -581,7 +598,7 @@ protected List<String> doListTables(String catalog, String db) {
581598
}
582599
}
583600

584-
protected String doDropTable(ObjectIdentifier id) {
601+
protected String doDropTable(ObjectIdentifier id, boolean deleteData) {
585602
String catalog = id.levelAtListPos(0).toLowerCase();
586603
String db = id.levelAtListPos(1).toLowerCase();
587604
String tableName = id.levelAtListPos(2).toLowerCase();
@@ -596,11 +613,9 @@ protected String doDropTable(ObjectIdentifier id) {
596613
Hive3Util.validateLanceTable(hmsTable.get());
597614
String location = hmsTable.get().getSd().getLocation();
598615

599-
final boolean deleteData = true;
600-
final boolean ignoreUnknownTable = true;
601616
clientPool.run(
602617
client -> {
603-
client.dropTable(catalog, db, tableName, deleteData, ignoreUnknownTable);
618+
client.dropTable(catalog, db, tableName, deleteData, true /* ignoreUnknownTable */);
604619
return null;
605620
});
606621

python/src/lance_namespace_impls/hive2.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@
7272
CreateNamespaceResponse,
7373
DropNamespaceRequest,
7474
DropNamespaceResponse,
75+
DropTableRequest,
76+
DropTableResponse,
7577
ListTablesRequest,
7678
ListTablesResponse,
7779
DeclareTableRequest,
@@ -397,6 +399,31 @@ def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse
397399
logger.error(f"Failed to describe table {request.id}: {e}")
398400
raise
399401

402+
def drop_table(self, request: DropTableRequest) -> DropTableResponse:
403+
"""Drop a table from the Hive Metastore and delete its data."""
404+
try:
405+
database, table_name = self._normalize_identifier(request.id)
406+
407+
with self.client as client:
408+
table = client.get_table(database, table_name)
409+
410+
if not table.parameters:
411+
raise ValueError(f"Table {request.id} is not a Lance table")
412+
table_type = table.parameters.get(TABLE_TYPE_KEY, "").lower()
413+
if table_type != LANCE_TABLE_FORMAT:
414+
raise ValueError(f"Table {request.id} is not a Lance table")
415+
416+
location = table.sd.location if table.sd else None
417+
418+
client.drop_table(database, table_name, deleteData=True)
419+
420+
return DropTableResponse(location=location)
421+
except Exception as e:
422+
if NoSuchObjectException and isinstance(e, NoSuchObjectException):
423+
raise ValueError(f"Table {request.id} does not exist")
424+
logger.error(f"Failed to drop table {request.id}: {e}")
425+
raise
426+
400427
def deregister_table(
401428
self, request: DeregisterTableRequest
402429
) -> DeregisterTableResponse:
@@ -405,10 +432,8 @@ def deregister_table(
405432
database, table_name = self._normalize_identifier(request.id)
406433

407434
with self.client as client:
408-
# Get table to check if it's a Lance table
409435
table = client.get_table(database, table_name)
410436

411-
# Check if it's a Lance table (case insensitive)
412437
if not table.parameters:
413438
raise ValueError(f"Table {request.id} is not a Lance table")
414439
table_type = table.parameters.get(TABLE_TYPE_KEY, "").lower()
@@ -417,7 +442,6 @@ def deregister_table(
417442

418443
location = table.sd.location if table.sd else None
419444

420-
# Drop the table metadata only (don't delete data)
421445
client.drop_table(database, table_name, deleteData=False)
422446

423447
return DeregisterTableResponse(location=location)

python/src/lance_namespace_impls/hive3.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@
7474
CreateNamespaceResponse,
7575
DropNamespaceRequest,
7676
DropNamespaceResponse,
77+
DropTableRequest,
78+
DropTableResponse,
7779
ListTablesRequest,
7880
ListTablesResponse,
7981
DeclareTableRequest,
@@ -477,6 +479,32 @@ def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse
477479
logger.error(f"Failed to describe table {request.id}: {e}")
478480
raise
479481

482+
def drop_table(self, request: DropTableRequest) -> DropTableResponse:
483+
"""Drop a table and delete its data."""
484+
try:
485+
catalog, database, table_name = self._normalize_identifier(request.id)
486+
487+
with self.client as client:
488+
table = client.get_table(database, table_name)
489+
490+
if not table.parameters:
491+
raise ValueError(f"Table {request.id} is not a Lance table")
492+
table_type = table.parameters.get(TABLE_TYPE_KEY, "").lower()
493+
if table_type != LANCE_TABLE_FORMAT:
494+
raise ValueError(f"Table {request.id} is not a Lance table")
495+
496+
location = table.sd.location if table.sd else None
497+
498+
client.drop_table(database, table_name, deleteData=True)
499+
500+
return DropTableResponse(location=location)
501+
502+
except Exception as e:
503+
if NoSuchObjectException and isinstance(e, NoSuchObjectException):
504+
raise ValueError(f"Table {request.id} does not exist")
505+
logger.error(f"Failed to drop table {request.id}: {e}")
506+
raise
507+
480508
def deregister_table(
481509
self, request: DeregisterTableRequest
482510
) -> DeregisterTableResponse:

0 commit comments

Comments
 (0)