Summary
CreateIndex.where() is available on the SQLSpec DDL builder, but the predicate is not emitted when rendering a SQL Server / T-SQL index. This means filtered unique indexes still need raw SQL even though the builder already models both if_not_exists() and where().
Environment
- SQLSpec: 0.54.2
- Python: 3.14.4
- Dialect:
tsql
Reproduction
from sqlspec import sql
stmt = (
sql.create_index("ix_queue_tasks_task_key")
.if_not_exists()
.unique()
.on_table("queue_tasks")
.columns("task_key")
.where("task_key IS NOT NULL")
)
print(stmt.build(dialect="tsql").sql)
Actual output
IF NOT EXISTS (SELECT * FROM sys.indexes WHERE object_id = object_id('queue_tasks') AND name = 'ix_queue_tasks_task_key') EXEC('CREATE UNIQUE INDEX [ix_queue_tasks_task_key] ON [queue_tasks]([task_key])')
The T-SQL IF NOT EXISTS ... EXEC(...) guard is rendered, but the filtered-index predicate is missing. Rendering without if_not_exists() also omits the predicate:
stmt = (
sql.create_index("ix_queue_tasks_task_key")
.unique()
.on_table("queue_tasks")
.columns("task_key")
.where("task_key IS NOT NULL")
)
print(stmt.build(dialect="tsql").sql)
Actual:
CREATE UNIQUE INDEX [ix_queue_tasks_task_key] ON [queue_tasks]([task_key])
Expected output
For T-SQL, the generated index DDL should include the predicate, for example:
IF NOT EXISTS (SELECT * FROM sys.indexes WHERE object_id = object_id('queue_tasks') AND name = 'ix_queue_tasks_task_key') EXEC('CREATE UNIQUE INDEX [ix_queue_tasks_task_key] ON [queue_tasks]([task_key]) WHERE [task_key] IS NOT NULL')
For the non-guarded case:
CREATE UNIQUE INDEX [ix_queue_tasks_task_key] ON [queue_tasks]([task_key]) WHERE [task_key] IS NOT NULL
Use case
litestar-queues needs a nullable unique task key on SQL Server. SQL Server requires a filtered unique index (WHERE task_key IS NOT NULL) to allow multiple rows with NULL task keys while enforcing uniqueness for keyed tasks. Because the T-SQL builder drops .where(...), that backend still has to carry hand-written raw T-SQL for this DDL.
Summary
CreateIndex.where()is available on the SQLSpec DDL builder, but the predicate is not emitted when rendering a SQL Server / T-SQL index. This means filtered unique indexes still need raw SQL even though the builder already models bothif_not_exists()andwhere().Environment
tsqlReproduction
Actual output
The T-SQL
IF NOT EXISTS ... EXEC(...)guard is rendered, but the filtered-index predicate is missing. Rendering withoutif_not_exists()also omits the predicate:Actual:
CREATE UNIQUE INDEX [ix_queue_tasks_task_key] ON [queue_tasks]([task_key])Expected output
For T-SQL, the generated index DDL should include the predicate, for example:
For the non-guarded case:
Use case
litestar-queuesneeds a nullable unique task key on SQL Server. SQL Server requires a filtered unique index (WHERE task_key IS NOT NULL) to allow multiple rows withNULLtask keys while enforcing uniqueness for keyed tasks. Because the T-SQL builder drops.where(...), that backend still has to carry hand-written raw T-SQL for this DDL.