fix(s3tables): answer 404 for a table name that was renamed away (#12258)

* s3tables: answer 404 for a table name that was renamed away

A rename leaves the source directory in place to hold the data under
it, with its catalog attributes cleared. UpdateTable, DeleteTable, the
table policy calls and the table maintenance calls read the metadata
attribute of that directory and reported its absence as an internal
error, so they answered 500, and GetTablePolicy answered NoSuchPolicy.

An absent metadata attribute now reads as a missing entry. tableMetadata
reports it as both filer_pb.ErrNotFound and the attribute error, so
callers that test for either keep working. The policy and maintenance
handlers read the attribute through the new readTableMetadataAttr, which
reports filer_pb.ErrNotFound, so each call answers NoSuchTable.

* s3tables: a view record without its metadata reads absent too

* s3tables: refuse a catalog write that lands on a metadata-less record

---------

Co-authored-by: user.email <chrislusf@users.noreply.github.com>
This commit is contained in:
Nguyễn Lộc Phúcanduser.email authored and GitHub committed 2026-10-30 19:53:57 -07:00
1 parent 468aabc962
commit 7d8b72c2b4
6 files changed
+205 -9

No files matched your search

+5 -2
View File
@@ -1298,14 +1298,17 @@ func (h *S3TablesHandler) readTableMetadata(ctx context.Context, client filer_pb
// tableMetadata extracts the table-metadata xattr from an entry. A view stored
// at the same name is reported absent, the way GetTable and the renamer's
// entry-type check already treat kind mismatches, and so is a record its
// create has not finished writing.
// create has not finished writing. A directory without the record is no table
// either, and reports the same absence.
func tableMetadata(entry *filer_pb.Entry) ([]byte, error) {
if EntryType(entry.Extended) == EntryTypeView || isUnfinishedCreate(entry.Extended) {
return nil, filer_pb.ErrNotFound
}
data, ok := entry.Extended[ExtendedKeyMetadata]
if !ok {
return nil, fmt.Errorf("%w: %s", ErrAttributeNotFound, ExtendedKeyMetadata)
// A directory without the record is not a table (e.g. a renamed-away
// source), so it reads as a missing entry.
return nil, fmt.Errorf("%w: %w: %s", filer_pb.ErrNotFound, ErrAttributeNotFound, ExtendedKeyMetadata)
}
return data, nil
}