@@ -189,9 +189,10 @@ Status RestCatalog::DropNamespace(const Namespace& ns) {
189189 ICEBERG_RETURN_UNEXPECTED (
190190 CheckEndpoint (supported_endpoints_, Endpoint::DropNamespace ()));
191191 ICEBERG_ASSIGN_OR_RAISE (auto path, paths_->Namespace_ (ns));
192- ICEBERG_ASSIGN_OR_RAISE (
193- const auto response,
194- client_->Delete (path, /* headers=*/ {}, *DropNamespaceErrorHandler::Instance ()));
192+
193+ ICEBERG_ASSIGN_OR_RAISE (const auto response,
194+ client_->Delete (path, /* params=*/ {}, /* headers=*/ {},
195+ *DropNamespaceErrorHandler::Instance ()));
195196 return {};
196197}
197198
@@ -204,17 +205,16 @@ Result<bool> RestCatalog::NamespaceExists(const Namespace& ns) const {
204205 return false ;
205206 }
206207 ICEBERG_RETURN_UNEXPECTED (result);
207- // GET succeeded, namespace exists
208+ // GetNamespaceProperties succeeded, namespace exists
208209 return true ;
209210 }
210211
211212 ICEBERG_ASSIGN_OR_RAISE (auto path, paths_->Namespace_ (ns));
212213 auto response_or_error =
213214 client_->Head (path, /* headers=*/ {}, *NamespaceErrorHandler::Instance ());
214215 if (!response_or_error.has_value ()) {
215- const auto & error = response_or_error.error ();
216216 // catch NoSuchNamespaceException/404 and return false
217- if (error.kind == ErrorKind::kNoSuchNamespace ) {
217+ if (response_or_error. error () .kind == ErrorKind::kNoSuchNamespace ) {
218218 return false ;
219219 }
220220 ICEBERG_RETURN_UNEXPECTED (response_or_error);
@@ -294,14 +294,44 @@ Result<std::shared_ptr<Transaction>> RestCatalog::StageCreateTable(
294294 return NotImplemented (" Not implemented" );
295295}
296296
297- Status RestCatalog::DropTable ([[maybe_unused]] const TableIdentifier& identifier,
298- [[maybe_unused]] bool purge) {
299- return NotImplemented (" Not implemented" );
297+ Status RestCatalog::DropTable (const TableIdentifier& identifier, bool purge) {
298+ ICEBERG_RETURN_UNEXPECTED (CheckEndpoint (supported_endpoints_, Endpoint::DeleteTable ()));
299+ ICEBERG_ASSIGN_OR_RAISE (auto path, paths_->Table (identifier));
300+
301+ std::unordered_map<std::string, std::string> params;
302+ if (purge) {
303+ params[" purgeRequested" ] = " true" ;
304+ }
305+ ICEBERG_ASSIGN_OR_RAISE (
306+ const auto response,
307+ client_->Delete (path, params, /* headers=*/ {}, *TableErrorHandler::Instance ()));
308+ return {};
300309}
301310
302- Result<bool > RestCatalog::TableExists (
303- [[maybe_unused]] const TableIdentifier& identifier) const {
304- return NotImplemented (" Not implemented" );
311+ Result<bool > RestCatalog::TableExists (const TableIdentifier& identifier) const {
312+ auto check = CheckEndpoint (supported_endpoints_, Endpoint::TableExists ());
313+ if (!check.has_value ()) {
314+ // Fall back to LoadTable endpoint (GET)
315+ auto result = LoadTable (identifier);
316+ if (!result.has_value () && result.error ().kind == ErrorKind::kNoSuchTable ) {
317+ return false ;
318+ }
319+ ICEBERG_RETURN_UNEXPECTED (result);
320+ // LoadTable succeeded, table exists
321+ return true ;
322+ }
323+
324+ ICEBERG_ASSIGN_OR_RAISE (auto path, paths_->Table (identifier));
325+ auto response_or_error =
326+ client_->Head (path, /* headers=*/ {}, *TableErrorHandler::Instance ());
327+ if (!response_or_error.has_value ()) {
328+ // catch NoSuchTableException/404 and return false
329+ if (response_or_error.error ().kind == ErrorKind::kNoSuchTable ) {
330+ return false ;
331+ }
332+ ICEBERG_RETURN_UNEXPECTED (response_or_error);
333+ }
334+ return true ;
305335}
306336
307337Status RestCatalog::RenameTable ([[maybe_unused]] const TableIdentifier& from,
@@ -310,8 +340,22 @@ Status RestCatalog::RenameTable([[maybe_unused]] const TableIdentifier& from,
310340}
311341
312342Result<std::shared_ptr<Table>> RestCatalog::LoadTable (
313- [[maybe_unused]] const TableIdentifier& identifier) {
314- return NotImplemented (" Not implemented" );
343+ const TableIdentifier& identifier) const {
344+ ICEBERG_RETURN_UNEXPECTED (CheckEndpoint (supported_endpoints_, Endpoint::LoadTable ()));
345+ ICEBERG_ASSIGN_OR_RAISE (auto path, paths_->Table (identifier));
346+
347+ ICEBERG_ASSIGN_OR_RAISE (
348+ const auto response,
349+ client_->Get (path, /* params=*/ {}, /* headers=*/ {}, *TableErrorHandler::Instance ()));
350+
351+ // TODO(Feiyang Li): support load metadata table
352+ ICEBERG_ASSIGN_OR_RAISE (auto json, FromJsonString (response.body ()));
353+ ICEBERG_ASSIGN_OR_RAISE (auto load_result, LoadTableResultFromJson (json));
354+ // Cast away const since Table needs non-const Catalog pointer for mutations
355+ auto non_const_catalog = std::const_pointer_cast<RestCatalog>(shared_from_this ());
356+ return Table::Make (identifier, load_result.metadata ,
357+ std::move (load_result.metadata_location ), file_io_,
358+ non_const_catalog);
315359}
316360
317361Result<std::shared_ptr<Table>> RestCatalog::RegisterTable (
0 commit comments