Skip to content

Skip indexes on expressions when reverse engineering SQLite - #39577

Merged
cincuranet merged 2 commits into
dotnet:mainfrom
ajcvickers:fix/39573-sqlite-expression-index-scaffold
Nov 10, 2026
Merged

cincuranet merged 2 commits into
dotnet:mainfrom
ajcvickers:fix/39573-sqlite-expression-index-scaffold

Conversation

@ajcvickers

Copy link
Copy Markdown
Contributor

Fixes #39573

Problem

Reverse engineering a SQLite database with an index on an expression, for example CREATE INDEX IX ON T (lower(Name)), threw InvalidOperationException: The data is NULL at ordinal 0. pragma_index_xinfo returns a NULL name (with cid = -2) for a key that is an expression, and SqliteDatabaseModelFactory.GetIndexes called GetString(0) on it.

Fix

GetIndexes now skips any index that has an expression key, including indexes that mix columns and expressions, and logs a warning. Indexes on expressions can't be represented in the model (#28360). The rest of the table, including its other indexes, is scaffolded as usual.

The warning is a new scaffolding event, SqliteEventId.ExpressionIndexSkippedWarning, registered the same way as the existing FormatWarning and OutOfRangeWarning events (event id, logging definition, resource string, logger extension and API baseline entry):

Skipping index '{indexName}' on table '{tableName}', since it is defined on an expression and indexes on expressions are not supported.

No other code path needs the change: NULL names only occur for expression keys, and SQLite does not allow expressions in UNIQUE or PRIMARY KEY constraints, so the unique-constraint and primary-key readers can't hit this.

Tests

New SqliteDatabaseModelFactoryTest tests cover an expression index next to a regular index, an expression index between two regular indexes (so skipping can't stop processing the table), a mixed column-and-expression index, tables with only expression indexes (including a unique one and an unusual name, one warning each), and an expression index alongside a unique constraint.

🤖 Generated with Claude Code

ajcvickers and others added 2 commits November 9, 2026 12:43
pragma_index_xinfo returns a NULL column name for a key that is an expression
(for example CREATE INDEX IX ON T (lower(Name))), and the SQLite database model
factory called GetString on it, so scaffolding failed with an
InvalidOperationException. Indexes on expressions can't be represented in the
model, so skip them and log a warning (SqliteEventId.ExpressionIndexSkippedWarning)
instead.

Fixes dotnet#39573

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Cover an expression index between regular indexes (so skipping must not stop
processing the table), tables with only expression indexes including a unique one
and an unusual name, and an expression index next to a unique constraint.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@ajcvickers
ajcvickers requested a review from a team as a code owner November 9, 2026 13:54
Copilot AI balanced review requested due to automatic review settings November 9, 2026 13:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

@cincuranet
cincuranet merged commit 01c8eeb into dotnet:main Nov 10, 2026
20 checks passed
@github-actions github-actions Bot added the api-review This PR or issue is introducing public API changes that need to be reviewed label Nov 10, 2026
@github-actions

Copy link
Copy Markdown
Contributor

API review baseline changes for src/EFCore.Sqlite.Core/EFCore.Sqlite.Core.baseline.json

Show diff

The diff below was generated by ApiChief between the base and the PR.

  static class Microsoft.EntityFrameworkCore.Diagnostics.SqliteEventId
+ static readonly Microsoft.Extensions.Logging.EventId ExpressionIndexSkippedWarning

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

Labels

api-review This PR or issue is introducing public API changes that need to be reviewed community-contribution

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SQLite reverse engineering throws InvalidOperationException for indexes on expressions

3 participants