Problem
#87 and #103 each found the same class of defect in a Rust catalog handler, fixed it by moving the relation to a SQLite view, and deleted the handler. Six information_schema handlers remain, and there is no reason to think they differ:
key_column_usage
table_constraints
referential_constraints
routines
views
schemata
The pattern to look for
Measured on information_schema.tables before #103 fixed it:
| Query |
Result |
SELECT table_name FROM information_schema.tables ORDER BY 1 |
29 rows, unsorted — ORDER BY silently ignored |
SELECT count(*) FROM information_schema.tables WHERE table_schema='public' |
0 rows — aggregates unsupported |
SELECT count(*) FROM information_schema.tables WHERE table_type='BASE TABLE' |
0 rows |
SELECT DISTINCT table_name FROM information_schema.columns |
60 rows, DISTINCT ignored |
The root cause is structural: these handlers parse a narrow subset of the query (typically equality on one column via a bespoke filter extractor), build rows in Rust, and silently drop everything they don't understand rather than erroring. A client asking for sorted, filtered, or aggregated results gets a wrong answer with no indication anything was ignored.
The related failure is staleness: a handler and its corresponding SQLite view drift apart, and which one answers depends on which code path the query takes. #103 found information_schema.tables and information_schema.columns answering differently on the same database depending on whether the query went through the interceptor or the JOIN-rewrite path.
Suggested approach
Audit each of the six with the four probe queries above, then apply the #87/#103 treatment where warranted: back the relation with a SQLite view, route it via SchemaPrefixTranslator, delete the handler.
The infrastructure is now in place — __pgsqlite_relnamespace and the four type UDFs from #103 are registered on every connection, and the translator rewrite is literal-safe and case-insensitive as of #103 — so each conversion should be considerably cheaper than the first two were.
Caution
src/query/extended.rs holds Describe-time RowDescription fallbacks for SELECT * prepared statements against these relations. They look like duplicate data handlers and are not — deleting the information_schema.tables one during #103 caused an UnexpectedMessage protocol desync. Any conversion needs a matching static column list there, in the view's exact column order.
Umbrella issue; split out of #88 / #103.
Problem
#87 and #103 each found the same class of defect in a Rust catalog handler, fixed it by moving the relation to a SQLite view, and deleted the handler. Six
information_schemahandlers remain, and there is no reason to think they differ:key_column_usagetable_constraintsreferential_constraintsroutinesviewsschemataThe pattern to look for
Measured on
information_schema.tablesbefore #103 fixed it:SELECT table_name FROM information_schema.tables ORDER BY 1ORDER BYsilently ignoredSELECT count(*) FROM information_schema.tables WHERE table_schema='public'SELECT count(*) FROM information_schema.tables WHERE table_type='BASE TABLE'SELECT DISTINCT table_name FROM information_schema.columnsDISTINCTignoredThe root cause is structural: these handlers parse a narrow subset of the query (typically equality on one column via a bespoke filter extractor), build rows in Rust, and silently drop everything they don't understand rather than erroring. A client asking for sorted, filtered, or aggregated results gets a wrong answer with no indication anything was ignored.
The related failure is staleness: a handler and its corresponding SQLite view drift apart, and which one answers depends on which code path the query takes. #103 found
information_schema.tablesandinformation_schema.columnsanswering differently on the same database depending on whether the query went through the interceptor or the JOIN-rewrite path.Suggested approach
Audit each of the six with the four probe queries above, then apply the #87/#103 treatment where warranted: back the relation with a SQLite view, route it via
SchemaPrefixTranslator, delete the handler.The infrastructure is now in place —
__pgsqlite_relnamespaceand the four type UDFs from #103 are registered on every connection, and the translator rewrite is literal-safe and case-insensitive as of #103 — so each conversion should be considerably cheaper than the first two were.Caution
src/query/extended.rsholds Describe-timeRowDescriptionfallbacks forSELECT *prepared statements against these relations. They look like duplicate data handlers and are not — deleting theinformation_schema.tablesone during #103 caused anUnexpectedMessageprotocol desync. Any conversion needs a matching static column list there, in the view's exact column order.Umbrella issue; split out of #88 / #103.