Skip to content

Fix logical-table resolution and eliminate redundant catalog scans for cached tables and HASH buckets #79

Description

@hsballoon

Problem

LanceSession._open_disk_table() currently resolves a logical table by scanning physical table names with:

if full_table_name.startswith(table_name):

This is unsafe when logical table names share a prefix, for example:

  • aaaa
  • aaaa_legacy
  • aaaa_backup

The selected physical table can depend on the ordering returned by list_tables(). This may cause dldb to infer the wrong partition type and lead to assertion failures or unstable table-opening behavior.

There is also an avoidable performance issue in the HASH table path: opening a partition calls list_tables() before checking whether the physical bucket wrapper is already cached. Repeated queries against the same bucket therefore continue to perform catalog requests even when the table and bucket have already been opened.

These behaviors should be fixed in dldb because dldb owns logical-to-physical table resolution, wrapper lifecycle, catalog access, and cache invalidation. SDK clients should not need to inspect or bypass dldb internals.

Proposal

1. Resolve logical tables exactly

session.filter(logical_table_name, ...) should first perform an exact lookup in the dldb information schema:

record = schema_table.get(table_name)
table = open_table_by_partition_type(
    db_conn,
    schema_table,
    table_name,
    record.partition_type,
    partition,
)

Physical table and bucket discovery should remain inside the corresponding table wrapper. Logical-table resolution must not depend on physical table-name prefix matching.

2. Cache logical-table wrappers in the session

After resolving a logical table, LanceSession should cache and reuse its wrapper for subsequent reads and writes in the same session.

3. Reuse cached HASH bucket wrappers without catalog scans

When a requested HASH bucket is already present in the wrapper’s physical-bucket cache, dldb should return it before calling list_tables().

A catalog scan should only be necessary when the requested bucket has not yet been opened or its cached entry has been invalidated.

4. Invalidate caches on catalog mutations

Creating, dropping, replacing, or recreating a logical or physical table should automatically invalidate the affected logical-table and physical-bucket cache entries.

Callers should not need to manually clear internal dldb caches after operations performed through dldb.

Expected behavior

  • Logical tables are always resolved using exact information-schema records.
  • Overlapping logical table-name prefixes cannot affect resolution.
  • Repeated operations reuse the same logical-table wrapper.
  • Repeated access to an already opened HASH bucket does not call list_tables().
  • Catalog mutations cannot leave stale wrappers or bucket objects in use.
  • Existing snapshot and checkout_latest behavior remains unchanged.

Please add regression tests covering:

  • Logical tables with overlapping prefixes.
  • Overlapping names using different partition types.
  • Repeated access to the same logical table and HASH bucket.
  • Cache invalidation after create, drop, and replace operations.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions