Skip to content

fix(plugin-postgresql): list Redshift external schemas and their tables - #2028

Merged
datlechin merged 2 commits into
mainfrom
fix/redshift-external-schemas-3880
Aug 6, 2026
Merged

fix(plugin-postgresql): list Redshift external schemas and their tables#2028
datlechin merged 2 commits into
mainfrom
fix/redshift-external-schemas-3880

Conversation

@datlechin

@datlechindatlechin commented Aug 6, 2026

Copy link
Copy Markdown
Member

Redshift external schemas showed up in the sidebar but always expanded to nothing.

Root cause

Two separate facts:

  1. The schemas already listed.CREATE EXTERNAL SCHEMA does create a pg_namespace row (AWS builds SVV_EXTERNAL_SCHEMAS by joining PG_EXTERNAL_SCHEMA to pg_namespace), so the schema list was never the problem.
  2. The tables never listed.RedshiftPluginDriver.fetchTables read only information_schema.tables, where external tables are never rows. They exist only in SVV_EXTERNAL_TABLES. fetchColumns had the same gap via information_schema.columns.

So the schema node rendered and expanded empty. This covers Redshift Spectrum over S3/Glue, federated query to Aurora, RDS and MySQL, cross-database references, and datashare consumers.

The reporter's own query returned 26 rows the sidebar could not show:

SELECT schemaname, tablename FROM svv_external_tables;

What changed

Listing. A probe reads svv_external_schemas once per connection to classify which schemas are external. Only for those schemas does table listing additionally read svv_external_tables, and column listing read svv_external_columns. Local objects keep their existing information_schema path untouched, so a cluster with no external catalog pays one cheap query and nothing else.

Routing local browsing through an SVV view was deliberately avoided: that is what broke DBeaver 25.3.1, where every non-superuser got permission denied for relation svv_table_info just expanding a schema.

Read-only. Redshift rejects UPDATE and DELETE on external tables, and they have no primary key and no ctid to target a row with. A new TableInfo.TableType.externalTable carries an allowsRowEditing property that now feeds the grid's editability flag, from both the sidebar and the Quick Switcher. Truncate and Import are hidden. Every read path stays: browse, filter, sort, export.

Tree shape. External schemas stay in the normal schema list with an "External" marker, and their tables sit in the existing Tables group with their own icon. This matches DBeaver, AWS Redshift Query Editor v2, Postico, and Beekeeper's accepted design; only Aqua Data Studio splits them into a separate hierarchy, and doing that here would mean removing schemas from where they already appear.

Redshift traps handled

  • Leader-node-only functions.has_schema_privilege, substr, current_schema, and version() cannot appear in a query that touches an svv_ view, because that query is distributed to the compute nodes. A test asserts none of them ever appear in the generated SQL.
  • Cross-database rows.SVV_EXTERNAL_TABLES and SVV_EXTERNAL_COLUMNS carry rows for every database on the cluster, so both are filtered by redshift_database_name. Without it, two databases each holding a schema named spectrum would list duplicate tables with colliding ids.
  • Blank tabletype. The column can be " " when the external catalog reports nothing. It is kept as a table rather than dropped.
  • Hive type strings.external_type reaches the UI unparsed, so struct<given:varchar(20),family:varchar(20)> survives. Splitting it on , or < to find a length is how Postico ended up treating every external column as text.
  • svv_table_info. Superuser-only and local-tables-only, so it is skipped for external schemas instead of being queried and returning nothing.
  • Failed probe. Leaves the previous classification in place rather than replacing it with an empty one, and degrades to listing local tables only.
  • Pseudocolumns.$path, $size, and $spectrum_oid are never added to a generated SELECT; reading them scans S3 and costs money.

PluginKit ABI

Additive, no version bump. One new PluginDatabaseDriver requirement with a default implementation; no requirement removed, no existing public init or signature changed, no frozen type touched. scripts/check-pluginkit-abi.sh against the merge base reports only added lines, so this needs the abi-additive label per its own instructions.

Tests

  • RedshiftExternalObjectsTests covers the generated SQL and the row classifiers, including the leader-node-only guard, the database scoping, the blank tabletype, and the three-state is_nullable.
  • ExternalSchemaTrackerTests covers classification, per-database scoping, fetch dedup, failure degradation, and reset.
  • New cases in TableInfoTests (allowsRowEditing per kind), PluginDriverAdapterTableTypeMappingTests, PluginKitABIResilienceTests, TableRowLogicTests, SidebarContextMenuLogicTests, and TableOperationSQLBuilderTests.

swiftlint --strict is clean repo-wide. The SQL builders were additionally verified by compiling them standalone and running 40 assertions against the real functions.

Not verified

No live Redshift cluster was available, so the queries are verified against AWS documentation and by unit tests over the generated SQL, not by execution. The Xcode build has not been run.

@mintlify

mintlifyBot commented Aug 6, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

ProjectStatusPreviewUpdated (UTC)
TablePro🟢 ReadyView PreviewAug 6, 2026, 4:12 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@datlechindatlechin added the abi-additive PluginKit ABI diff reviewed as additive; no version bump needed label Aug 6, 2026
Signed-off-by: Ngô Quốc Đạt <datlechin@gmail.com>
@datlechin
datlechin merged commit 754723e into mainAug 6, 2026
2 of 3 checks passed
@datlechin
datlechin deleted the fix/redshift-external-schemas-3880 branch August 6, 2026 16:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

abi-additivePluginKit ABI diff reviewed as additive; no version bump needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@datlechin