|
| 1 | +# pg_catalog and information_schema Coverage — V 1.60 |
| 2 | + |
| 3 | +**SharpCoreDB Server** intercepts PostgreSQL catalog queries and returns live schema metadata, enabling GUI tools to introspect tables, columns, types, and schemas without requiring native catalog storage. |
| 4 | + |
| 5 | +--- |
| 6 | + |
| 7 | +## Architecture |
| 8 | + |
| 9 | +The `PgCatalogService` (`src/SharpCoreDB.Server.Core/Catalog/PgCatalogService.cs`) intercepts catalog queries **before** they reach the database engine: |
| 10 | + |
| 11 | +``` |
| 12 | +Client SQL → BinaryProtocolHandler |
| 13 | + │ |
| 14 | + ├── PgCatalogService.TryHandleCatalogQuery() |
| 15 | + │ ↓ matched → synthetic result rows → client |
| 16 | + │ ↓ not matched → engine.ExecuteQuery() |
| 17 | + └── SharpCoreDB Engine |
| 18 | +``` |
| 19 | + |
| 20 | +Both the simple query path (`Q` message) and the extended query path (`P`/`B`/`E` messages) are intercepted. |
| 21 | + |
| 22 | +--- |
| 23 | + |
| 24 | +## Supported Scalar Functions |
| 25 | + |
| 26 | +| Expression | Returns | |
| 27 | +|---|---| |
| 28 | +| `current_database()` | Active database name | |
| 29 | +| `version()` | `SharpCoreDB 1.6.0 on .NET 10 (PostgreSQL protocol compatible)` | |
| 30 | +| `current_user` | Authenticated user name | |
| 31 | +| `session_user` | Authenticated user name | |
| 32 | +| `current_schema()` | `public` | |
| 33 | +| `pg_postmaster_start_time()` | Server start time (UTC) | |
| 34 | + |
| 35 | +--- |
| 36 | + |
| 37 | +## Supported Views |
| 38 | + |
| 39 | +### information_schema |
| 40 | + |
| 41 | +| View | Key Columns | Notes | |
| 42 | +|---|---|---| |
| 43 | +| `information_schema.tables` | `table_catalog`, `table_schema`, `table_name`, `table_type` | Returns `BASE TABLE` for all user tables in `public` schema. WHERE `table_schema` filter supported. | |
| 44 | +| `information_schema.columns` | `table_name`, `column_name`, `ordinal_position`, `data_type`, `is_nullable`, `collation_name` | WHERE `table_name` and `table_schema` filters supported. | |
| 45 | +| `information_schema.schemata` | `catalog_name`, `schema_name`, `schema_owner` | Returns `public`, `pg_catalog`, `information_schema`. | |
| 46 | +| `information_schema.table_constraints` | All constraint columns | Returns empty set (no constraints stored yet). | |
| 47 | +| `information_schema.key_column_usage` | All columns | Returns empty set. | |
| 48 | +| `information_schema.referential_constraints` | All columns | Returns empty set. | |
| 49 | +| `information_schema.constraint_column_usage` | All columns | Returns empty set. | |
| 50 | + |
| 51 | +### pg_catalog |
| 52 | + |
| 53 | +| View | Key Columns | Notes | |
| 54 | +|---|---|---| |
| 55 | +| `pg_tables` / `pg_catalog.pg_tables` | `schemaname`, `tablename`, `tableowner` | WHERE `schemaname` filter supported. | |
| 56 | +| `pg_class` / `pg_catalog.pg_class` | `oid`, `relname`, `relkind`, `relnamespace` | All user tables as `relkind='r'`. | |
| 57 | +| `pg_attribute` / `pg_catalog.pg_attribute` | `attrelid`, `attname`, `atttypid`, `attnum`, `attnotnull` | One row per column across all tables. | |
| 58 | +| `pg_namespace` / `pg_catalog.pg_namespace` | `oid`, `nspname`, `nspowner` | Returns `public` (2200), `pg_catalog` (11), `information_schema` (12387). | |
| 59 | +| `pg_type` / `pg_catalog.pg_type` | `oid`, `typname`, `typtype`, `typcategory` | 13 base types: text, int4, int8, float8, bool, timestamp, timestamptz, date, uuid, bytea, numeric, json, jsonb. | |
| 60 | +| `pg_roles` / `pg_catalog.pg_roles` | `oid`, `rolname`, `rolsuper` | Returns current user as superuser. | |
| 61 | +| `pg_user` / `pg_catalog.pg_user` | Same as pg_roles | Alias. | |
| 62 | +| `pg_am` / `pg_catalog.pg_am` | `oid`, `amname`, `amtype` | Returns `btree` and `hash`. | |
| 63 | +| `pg_index` / `pg_catalog.pg_index` | All index columns | Returns empty set (no index catalog). | |
| 64 | +| `pg_indexes` / `pg_catalog.pg_indexes` | All index columns | Returns empty set. | |
| 65 | +| `pg_constraint` / `pg_catalog.pg_constraint` | All constraint columns | Returns empty set. | |
| 66 | +| `pg_proc` / `pg_catalog.pg_proc` | All proc columns | Returns empty set. | |
| 67 | +| `pg_trigger` / `pg_catalog.pg_trigger` | All trigger columns | Returns empty set. | |
| 68 | +| `pg_description` / `pg_catalog.pg_description` | All description columns | Returns empty set. | |
| 69 | +| `pg_stat_user_tables` | All stat columns | Returns empty set. | |
| 70 | +| `pg_sequence` | All sequence columns | Returns empty set. | |
| 71 | +| `pg_attrdef` | All attrdef columns | Returns empty set. | |
| 72 | +| `pg_depend` | All depend columns | Returns empty set. | |
| 73 | + |
| 74 | +--- |
| 75 | + |
| 76 | +## Type Mapping |
| 77 | + |
| 78 | +SharpCoreDB engine types are mapped to standard SQL and PostgreSQL type names: |
| 79 | + |
| 80 | +| Engine Type | SQL Type | pg OID | UDT Name | |
| 81 | +|---|---|---|---| |
| 82 | +| INTEGER / INT / INT4 / INT32 | integer | 23 | int4 | |
| 83 | +| BIGINT / INT8 / INT64 | bigint | 20 | int8 | |
| 84 | +| SMALLINT / INT2 / INT16 | smallint | 21 | int2 | |
| 85 | +| FLOAT / REAL / FLOAT4 | real | 700 | float4 | |
| 86 | +| DOUBLE / FLOAT8 | double precision | 701 | float8 | |
| 87 | +| DECIMAL / NUMERIC | numeric | 1700 | numeric | |
| 88 | +| BOOLEAN / BOOL | boolean | 16 | bool | |
| 89 | +| TEXT / STRING / VARCHAR / NVARCHAR / CHAR | text | 25 | text | |
| 90 | +| BLOB / BYTEA / BINARY | bytea | 17 | bytea | |
| 91 | +| TIMESTAMP / DATETIME | timestamp without time zone | 1114 | timestamp | |
| 92 | +| TIMESTAMPTZ | timestamp with time zone | 1184 | timestamptz | |
| 93 | +| DATE | date | 1082 | date | |
| 94 | +| UUID / GUID | uuid | 2950 | uuid | |
| 95 | +| JSON | json | 114 | json | |
| 96 | +| JSONB | jsonb | 3802 | jsonb | |
| 97 | + |
| 98 | +--- |
| 99 | + |
| 100 | +## Known Limitations |
| 101 | + |
| 102 | +| Gap | Impact | Workaround | |
| 103 | +|---|---|---| |
| 104 | +| No index catalog (`pg_index`) | Tools cannot show index details | Partial — tools fall back gracefully | |
| 105 | +| No constraint catalog (`pg_constraint`) | PK/FK not shown in GUI | Table structure visible, FK arrows missing | |
| 106 | +| No trigger catalog (`pg_trigger`) | Triggers not visible | Not applicable — no trigger support | |
| 107 | +| Complex multi-join catalog queries | May not match simple patterns | Tools receive empty rows without error | |
| 108 | +| `WHERE` clause parsing | Only equality filters on `table_name`, `table_schema`, `schemaname` | Other filters return all rows | |
| 109 | + |
| 110 | +See `TOOL_COMPATIBILITY_LIMITATIONS_v1.6.0.md` for full gap list and workarounds. |
| 111 | + |
| 112 | +--- |
| 113 | + |
| 114 | +## Test Coverage |
| 115 | + |
| 116 | +`tests/SharpCoreDB.Server.IntegrationTests/PgCatalogServiceTests.cs` — 15 tests: |
| 117 | + |
| 118 | +| Test | Validates | |
| 119 | +|---|---| |
| 120 | +| `TryHandleCatalogQuery_CurrentDatabase_ReturnsDatabaseName` | `current_database()` scalar | |
| 121 | +| `TryHandleCatalogQuery_Version_ReturnsVersionString` | `version()` scalar | |
| 122 | +| `TryHandleCatalogQuery_CurrentUser_ReturnsUserName` | `current_user` scalar | |
| 123 | +| `TryHandleCatalogQuery_InformationSchemaTables_ReturnsUserTables` | Full table list from live schema | |
| 124 | +| `TryHandleCatalogQuery_InformationSchemaTables_FilterByPublicSchema_ReturnsRows` | Schema filter pass-through | |
| 125 | +| `TryHandleCatalogQuery_InformationSchemaTables_FilterByNonPublicSchema_ReturnsEmpty` | Non-public schema returns empty | |
| 126 | +| `TryHandleCatalogQuery_InformationSchemaColumns_ReturnsColumnsForTable` | Column list for specific table | |
| 127 | +| `TryHandleCatalogQuery_InformationSchemaColumns_HasOrdinalPosition` | Ordinal position populated | |
| 128 | +| `TryHandleCatalogQuery_PgTables_ReturnsUserTables` | `pg_tables` with schema filter | |
| 129 | +| `TryHandleCatalogQuery_PgClass_ReturnsRelations` | `pg_class` relkind='r' | |
| 130 | +| `TryHandleCatalogQuery_PgNamespace_ContainsPublicSchema` | Three schemas returned | |
| 131 | +| `TryHandleCatalogQuery_PgType_ContainsBaseTypes` | Base type catalog | |
| 132 | +| `TryHandleCatalogQuery_PgAttribute_ReturnsColumnsForAllTables` | Column attributes | |
| 133 | +| `TryHandleCatalogQuery_UserTableQuery_ReturnsFalse` | Non-catalog queries passed through | |
| 134 | +| `TryHandleCatalogQuery_InformationSchemaSchemata_ContainsPublic` | Schemata view | |
| 135 | + |
| 136 | +--- |
| 137 | + |
| 138 | +*Phase 02 of admin-console roadmap — implemented in SharpCoreDB V 1.60* |
0 commit comments