Skip to content

Fix case-insensitive parent namespace match in SqlCatalog.namespace_exists - #4164

Open
DG47 wants to merge 1 commit into
apache:mainfrom
DG47:fix/sql-namespace-exists-case-sensitive
Open

DG47 wants to merge 1 commit into
apache:mainfrom
DG47:fix/sql-namespace-exists-case-sensitive

Conversation

@DG47

@DG47 DG47 commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

Closes #4163

Rationale for this change

SqlCatalog.namespace_exists also reports a namespace as existing when a child namespace exists, using LIKE '<namespace>.%'. SQLite evaluates LIKE case-insensitively for ASCII characters, so with only sales.eu in the catalog, namespace_exists("SALES") returned True. As a result create_table("SALES.orders") succeeded in a namespace that does not exist, and create_namespace("SALES") failed with NamespaceAlreadyExistsError. The exact-match comparisons elsewhere in the catalog are case-sensitive, and PostgreSQL's LIKE is case-sensitive too.

This keeps the LIKE filter in the query and re-checks the matched namespace names with a case-sensitive prefix comparison in Python. list_namespaces already filters the same way after its LIKE query. The queries now select only the namespace column with DISTINCT instead of whole rows with LIMIT 1, because a row whose case differs could come back first.

Are these changes tested?

Yes. test_namespace_exists in tests/catalog/test_catalog_behaviors.py now also checks that DB2 and db3.NS1 are not reported as existing when db2.ns1 and db3.ns1.ns2 exist. It fails on main for the memory, sql and sql_without_rowcount catalogs and passes with this change. make test and make lint pass.

Are there any user-facing changes?

On SQLite, namespace_exists and the operations that depend on it no longer treat a namespace as existing just because a child namespace with a different case exists.

…xists

The parent-namespace check uses LIKE, which SQLite evaluates
case-insensitively for ASCII. With only `sales.eu` present,
`namespace_exists("SALES")` returned True, so `create_table("SALES.t")`
succeeded in a namespace that does not exist and `create_namespace("SALES")`
failed with NamespaceAlreadyExistsError. Re-check the LIKE matches with a
case-sensitive prefix comparison so the result matches the exact-equality
lookups used elsewhere in the catalog.

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SqlCatalog: namespace_exists matches parent namespaces case-insensitively on SQLite

1 participant