feat(db): PostgreSQL 外部表与物化视图纳入树、动作与转储 - #266
Merged
Merged
Conversation
PG 连接的表目录写死 `c.relkind = 'r'`,外部表('f')和分区表('p')根本列不出来,
物化视图也找不到入口(视图走 `information_schema.views`,它不含物化视图)——与
Navicat 的行为不一致,用户已经建好的外部表在 Navop 里等于不存在。
- 列表:`list_tables` / `list_tables_view` 放开 relkind 到 `'r','p','f'`,按 relkind
映射对象类型('f' → ForeignTable,'p'/'r' → Table),对象列表「类型」列分别显示
Table / Partitioned Table / Foreign Table;新增 `list_materialized_views`(走
`pg_class` relkind='m' + `pg_get_viewdef`),物化视图从普通视图里彻底分离。
- 树:新增 `DbNodeType::{ForeignTable, MaterializedViewsFolder, MaterializedView}`,
外部表与普通表/分区表同处「表」目录(对齐 Navicat),物化视图单独一个目录;目录由
`supports_materialized_views` 能力位控制,MySQL 等其它驱动不受影响。
- 动作:外部表与物化视图按 node_type 各自 scope 出菜单(Open / Rename / Truncate /
Drop / Dump / Import / Export 等),删除与重命名按类型分派到 `drop_foreign_table`
/ `rename_foreign_table` / `drop_materialized_view`——不能把 `DROP TABLE` 打到外部表
上。设计表 / 复制表 / 结构转储等尚无实现的动作不注册,因此不会出现点了没反应的项。
- 结构比较与结构转储:新增 `TableObjectType::ForeignTable`,`is_ddl_comparable()` 只让
普通表参与,外部表自动从结构比较、数据比较、ER 图、整库 DDL 转储中排除(数据转储
仍可用);`resolve_sql_dump_target` 补上新类型的映射,避免 Dump 静默报错。
- schema 限定:`rename_foreign_table` / `drop_materialized_view` 接受 schema 并生成
schema 限定名——执行会话不会切 search_path,非 public schema 下的 DDL 原先会打错
对象(或直接报错)。
验证:
- `cargo test -p db --lib` 1305 passed / 0 failed;`cargo test -p db_view --lib`
703 passed / 0 failed / 1 ignored;`cargo check --workspace --all-targets` 无
error/warning;对新增行做 clippy 比对,无新增告警。
- 新增真实库集成测试 `crates/db/tests/real_databases/postgres/foreign_matview.rs`
(设置 `ONETCLI_TEST_POSTGRES_PASSWORD` 后才运行):在非 public schema 下真建外部表
(postgres_fdw)、分区表与物化视图,断言列表类型、对象面板类型与树的归属,并真实
执行 rename / drop 外部表和 drop 物化视图,最后校验 `list_views` 不混入物化视图。
`cargo test -p db --test real_postgres` 5 passed;测试自带清理,不在库里留 schema、
外部服务器或扩展。
- 未验证:GUI 端到端(右键菜单实际点击路径)没有真机回归,只覆盖到事件与 SQL 生成层。
4 tasks
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Description
PostgreSQL connections only ever listed base tables: the listing SQL was hardcoded to
c.relkind = 'r', so foreign tables ('f') and partitioned tables ('p') were invisible, and materialized views had no entry point at all (plain views were resolved throughinformation_schema.views, which excludes matviews). A user who had already created foreign tables with Navicat could not see them in Navop.This PR aligns the PostgreSQL object tree with Navicat and makes the actions correct, not just visible:
list_tables/list_tables_viewnow accept'r','p','f'and map relkind to an object type ('f'→ForeignTable,'p'/'r'→Table). The object list "type" column showsTable/Partitioned Table/Foreign Table. Newlist_materialized_viewsreadspg_class(relkind = 'm') pluspg_get_viewdef, so materialized views no longer mix into plain views.DbNodeType::{ForeignTable, MaterializedViewsFolder, MaterializedView}. Foreign, base and partitioned tables share one "Tables" folder (Navicat behavior); materialized views get their own folder, gated by a newsupports_materialized_viewscapability flag (defaults tofalse, so MySQL and other drivers are unaffected).drop_foreign_table/rename_foreign_table/drop_materialized_view, so a plainDROP TABLEcan never be sent to a foreign table. Actions without an implementation (design foreign table, copy table, foreign-table structure dump) are simply not registered, so no dead menu entries appear.TableObjectType::ForeignTable;is_ddl_comparable()keeps only plain tables, so foreign tables are automatically excluded from schema compare, data compare, ER diagram and whole-database DDL dump (data dump still works).resolve_sql_dump_targetlearns the new types so "Dump SQL File" no longer fails silently.rename_foreign_table/drop_materialized_viewnow take a schema and emit schema-qualified names. The execution session never switchessearch_path, so on non-publicschemas the previous DDL would have hit the wrong relation or errored out.How to Test
The new
crates/db/tests/real_databases/postgres/foreign_matview.rscreates a non-publicschema with a real postgres_fdw foreign table (own foreign server + user mapping), a partitioned table and a materialized view, then asserts listing types, object-list types and tree placement, and actually executes rename/drop on the foreign table and drop on the materialized view. It also verifieslist_viewsdoes not leak materialized views. The test cleans up after itself — no schema, foreign server or extension is left behind in the target database.Manual smoke test: connect to a PostgreSQL database; the Tables folder now shows base, partitioned and foreign tables together with correct type labels, and a Materialized Views folder lists matviews with working Open Data / Dump / Delete.
Checklist
cargo runfor story tests related to the changes. — not run: the story gallery is an interactive GUI; the touched views are covered bycargo test -p db_viewinstead, and the right-click menu click path has no automated regression yet.