You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ORMs that ship their own SQLite dialect (EF Core, NHibernate) don't need the provider to describe itself, so they aren't the right test for this. Code written against DbProviderFactory / DbConnection does need it. Without DataSourceInformation, a generic consumer has no supported way to discover SQLite's parameter marker format, identifier pattern or version, so it has to special-case SQLite by name — the provider-specific code the ADO.NET abstraction exists to remove. Background on the pattern: https://dev.to/pengdows/stop-hardcoding-your-net-data-provider-4jmo
Compatibility
This is additive. GetSchema does not currently return these collections, so no existing caller's behavior changes.
Scope
If the full change is more than the team wants to maintain, I'm happy to reduce it to only the common collections and drop the provider-specific Tables/Columns/Indexes.
Implemented DataSourceInformation, DataTypes, MetaDataCollections, and Restrictions.
Added provider-specific Tables, Columns, and Indexes collections.
If the provider-specific collections are outside the intended scope, I can remove them and leave the four standard collections needed by pengdows.crud: DataSourceInformation, DataTypes, MetaDataCollections, and Restrictions.
Included attached databases with correct schema-qualified metadata.
Added normalized SQLite versions, prefix-free parameter-marker formatting, corrected regex capture groups, standard schema/table/nullability values, and SQLite internal-table filtering.
Added version-gated pragma_table_list support for virtual tables and shadow-table exclusion on SQLite 3.37 and later, with a sqlite_master fallback for older SQLite builds. The fallback cannot distinguish virtual-table shadow tables.
Included virtual-table columns when the module is available; broken views and unavailable virtual-table modules are skipped per object rather than aborting the collection.
Reduced regular-table metadata collection to one query per schema and used the hidden schema argument for table-valued pragmas.
TDD and validation
Tests cover all implemented collections, attached databases, same-name tables across schemas, parameter-marker consumption, normalized versions, regex capture groups, standard metadata values, escaped sqlite_ filtering, broken views, FTS5 virtual tables, shadow tables, empty databases, and version-specific join operators.
Validation:
Build completed with 0 warnings and 0 errors.
Full Microsoft.Data.Sqlite.Tests assembly: 756 passed, 7 expected skips, 0 failed.
The normalized value drops Version.Revision, so four-component SQLite patch releases such as 3.8.7.1 and 3.8.7.2 both become 03.008.0007. Since Microsoft.Data.Sqlite.Core supports custom and system native libraries, this violates the common-schema requirement that normalized versions remain string-comparable across provider versions. Include a fixed-width revision component (using zero when absent) and cover a four-component version.
Marks dynamically typed REAL columns as fixed length
IsFixedLength is set to true for REAL, but SQLite uses dynamic typing: a column declared REAL can still store variable-length text or blobs. The common schema contract defines this flag in terms of columns created by DDL, so generic metadata consumers would incorrectly assume fixed-length storage here.
Reports false signedness for nonnumeric TEXT and BLOB types
These rows return false for IsUnsigned, but the common DataTypes contract requires DBNull.Value when signedness is not applicable. TEXT and BLOB are nonnumeric, so reporting false misrepresents them as signed types to generic consumers.
The reason will be displayed to describe this comment to others. Learn more.
I agree that the ADO.NET schema contract should be the source of truth here. SQLite currently reports zero supported restrictions, so rejecting supplied restrictions is intentional. NHibernate’s expected restriction layout may be useful for future compatibility, but I don’t think we should silently ignore values or advertise restrictions we do not implement. We can add specific restrictions later if we implement their filtering semantics and update the metadata accordingly.
The reason will be displayed to describe this comment to others. Learn more.
rejecting supplied restrictions is intentional
Yes, it was my intention at the time. 😉 But for the sake of pragmatism, it might be worth reconsidering. I think most providers ignore "extra" restrictions--you can append all kinds of nonsense onto the end of the array.
The reason will be displayed to describe this comment to others. Learn more.
I tested this against the advertised ADO.NET metadata: Tables, Columns, and Indexes all report zero supported restrictions, and tests verify that supplying restrictions is rejected rather than silently ignored. I'm keeping that behavior because silently discarding caller-supplied filters would be misleading while the provider does not implement restriction semantics. If compatibility with a specific consumer becomes necessary, we can add explicit restrictions and filtering in a follow-up.
The reason will be displayed to describe this comment to others. Learn more.
It might be confusing to return all of these. The subsequent pragmas only return items for the default database (main). To get items from other attached databases, you need to call them with the database name: PRAGMA attached-db.table_list
The reason will be displayed to describe this comment to others. Learn more.
This is already handled in the current implementation. The table-valued pragmas are invoked with the database name as the schema argument (for example, pragma_table_info(m.name, $schema) and pragma_index_list(m.name, $schema)), and the table-list path filters by m.schema. The existing GetSchema_pragma_collections_include_attached_databases test covers attached database tables, columns, and indexes.
The reason will be displayed to describe this comment to others. Learn more.
Agreed that #23587 represents broader schema-discovery work. The attached-database behavior in this PR is covered and tested; I'm leaving unrelated schema-surface expansion for that follow-up.
The reason will be displayed to describe this comment to others. Learn more.
The current values are the same flag combinations represented by the suggested enum: 3 for INNER | LEFT OUTER before SQLite 3.39, and 15 for all four join operators from SQLite 3.39 onward. The DataTypes metadata column is an integer, so the behavior is covered by the existing version-specific tests.
The reason will be displayed to describe this comment to others. Learn more.
Agreed. I updated the follow-up PR (#39219) in commit 5e7247def6 to use System.Data.Common.SupportedJoinOperators flags instead of raw numeric values, while casting to the required integer for the schema column. The existing version-specific tests now assert the enum values.
Follow-up validation completed in commit 264984bb84:
Added four-component normalized-version coverage and preserved Version.Revision (zero-filled when absent).
Corrected REAL.IsFixedLength to false.
Corrected TEXT and BLOBIsUnsigned to DBNull.Value, as signedness is not applicable.
Added restriction-behavior tests for all advertised zero-restriction collections.
The core project builds cleanly and git diff --check passes. The focused test project could not be restored in this environment because the configured NuGet feeds were unavailable.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Fixes #35917.
The common schema collections (
MetaDataCollections,DataSourceInformation,DataTypes,Restrictions,ReservedWords) are part of the documented ADO.NET provider contract, which describes them as implemented by each managed provider:https://learn.microsoft.com/dotnet/framework/data/adonet/common-schema-collections
ORMs that ship their own SQLite dialect (EF Core, NHibernate) don't need the provider to describe itself, so they aren't the right test for this. Code written against
DbProviderFactory/DbConnectiondoes need it. WithoutDataSourceInformation, a generic consumer has no supported way to discover SQLite's parameter marker format, identifier pattern or version, so it has to special-case SQLite by name — the provider-specific code the ADO.NET abstraction exists to remove. Background on the pattern:https://dev.to/pengdows/stop-hardcoding-your-net-data-provider-4jmo
Compatibility
This is additive.
GetSchemadoes not currently return these collections, so no existing caller's behavior changes.Scope
If the full change is more than the team wants to maintain, I'm happy to reduce it to only the common collections and drop the provider-specific
Tables/Columns/Indexes.References:
What changed
DataSourceInformation,DataTypes,MetaDataCollections, andRestrictions.Tables,Columns, andIndexescollections.pengdows.crud:DataSourceInformation,DataTypes,MetaDataCollections, andRestrictions.pragma_table_listsupport for virtual tables and shadow-table exclusion on SQLite 3.37 and later, with asqlite_masterfallback for older SQLite builds. The fallback cannot distinguish virtual-table shadow tables.TDD and validation
Tests cover all implemented collections, attached databases, same-name tables across schemas, parameter-marker consumption, normalized versions, regex capture groups, standard metadata values, escaped
sqlite_filtering, broken views, FTS5 virtual tables, shadow tables, empty databases, and version-specific join operators.Validation:
Microsoft.Data.Sqlite.Testsassembly: 756 passed, 7 expected skips, 0 failed.