Skip to content

SqlCatalog: namespace_exists matches parent namespaces case-insensitively on SQLite #4163

Description

@DG47

Apache Iceberg version

main (development)

Please describe the bug 🐞

SqlCatalog.namespace_exists treats a namespace as existing when a child namespace exists, and checks that with LIKE '<namespace>.%'. SQLite evaluates LIKE case-insensitively for ASCII characters, so on SQLite a namespace that differs only in case from the parent of an existing namespace is reported as existing. The exact-match lookups elsewhere in the catalog (==) are case-sensitive, so the catalog ends up inconsistent with itself, and the result differs from PostgreSQL, where LIKE is case-sensitive.

Because create_table, register_table, rename_table, drop_namespace, list_tables, list_namespaces and the namespace property methods all go through namespace_exists, the effects show up across the API:

import tempfile
from pyiceberg.catalog.sql import SqlCatalog
from pyiceberg.schema import Schema
from pyiceberg.types import NestedField, LongType

w = tempfile.mkdtemp()
cat = SqlCatalog("t", uri=f"sqlite:///{w}/c.db", warehouse=f"file://{w}")
cat.create_namespace("sales.eu")

print(cat.namespace_exists("SALES"))  # True, expected False
print(cat.create_table("SALES.orders", schema=Schema(NestedField(1, "id", LongType()))).name())
# ('SALES', 'orders'), expected NoSuchNamespaceError

On a fresh catalog with only sales.eu, cat.create_namespace("SALES") raises NamespaceAlreadyExistsError: Namespace SALES already exists, and cat.load_namespace_properties("SALES") returns {} instead of raising NoSuchNamespaceError.

Expected: namespace_exists("SALES") returns False when only sales / sales.eu exist, matching the case-sensitive exact lookups and the PostgreSQL behaviour. create_table("SALES.orders") raises NoSuchNamespaceError and create_namespace("SALES") succeeds.

Without a nested namespace the check is correct (namespace_exists("SALES") is False when only sales exists), because only the LIKE branch is affected.

Environment: pyiceberg main (0.12.0 dev), SQLAlchemy 2.0.54, SQLite 3.50.4, Python 3.12, macOS arm64.

Willingness to contribute

  • I can contribute a fix for this bug independently
  • I would be willing to contribute a fix for this bug with guidance from the Iceberg community
  • I cannot contribute a fix for this bug at this time

Activity

  1. Shahzeb-DataEngineer commented on Oct 28, 2026

    @Shahzeb-DataEngineer
    Contributor

    Thanks for the clear repro. I would like to take this one: the fix should make the child-namespace LIKE check case-sensitive so it matches the exact lookups and the PostgreSQL behaviour. I will open a PR shortly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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