From df0415333ac8a5b7c03e8b1567db2fa9984c7030 Mon Sep 17 00:00:00 2001 From: zipg Date: Thu, 16 Jul 2026 14:40:54 +0800 Subject: [PATCH] fix(postgres): prioritize root tables in sidebar pagination --- apps/desktop/src/stores/connectionStore.ts | 6 +++--- crates/dbx-core/src/db/postgres.rs | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/apps/desktop/src/stores/connectionStore.ts b/apps/desktop/src/stores/connectionStore.ts index 6f2278133f..25cfe02e59 100644 --- a/apps/desktop/src/stores/connectionStore.ts +++ b/apps/desktop/src/stores/connectionStore.ts @@ -1073,7 +1073,7 @@ export const useConnectionStore = defineStore("connection", () => { } function objectGroupCacheKey(node: TreeNode): string { - return schemaCacheKey(node.connectionId || "", node.database || "", node.schema || "", node.type, "objects-v4"); + return schemaCacheKey(node.connectionId || "", node.database || "", node.schema || "", node.type, "objects-v5"); } function metadataListDriverProfile(connectionId?: string): string | undefined { @@ -3125,7 +3125,7 @@ export const useConnectionStore = defineStore("connection", () => { await ensureConnected(connectionId); if (useCachedChildren(node, options)) return; const simpleObjectDisplay = useSettingsStore().editorSettings.sidebarObjectDisplay === "simple"; - const cacheKey = schemaCacheKey(connectionId, database, schema || "", simpleObjectDisplay ? "objects-simple-v4" : "objects-grouped-v4"); + const cacheKey = schemaCacheKey(connectionId, database, schema || "", simpleObjectDisplay ? "objects-simple-v5" : "objects-grouped-v5"); const searchFilter = activeTreeLoadSearchFilter(options); const isSidebarTableSearch = !!options?.sidebarTableSearchParentId; if (!options?.force && !searchFilter) { @@ -3383,7 +3383,7 @@ export const useConnectionStore = defineStore("connection", () => { if (!canApplyTreeMetadataResult(parent)) return; parent.objectCount = mergedChildren.length; setChildren(parent, nextChildren); - await savePersistedTreeChildren(schemaCacheKey(parentConnectionId, parentDatabase, parent.schema || "", "objects-simple-v4"), nextChildren); + await savePersistedTreeChildren(schemaCacheKey(parentConnectionId, parentDatabase, parent.schema || "", "objects-simple-v5"), nextChildren); parent.isExpanded = true; return; } diff --git a/crates/dbx-core/src/db/postgres.rs b/crates/dbx-core/src/db/postgres.rs index a95603ab25..68761449f5 100644 --- a/crates/dbx-core/src/db/postgres.rs +++ b/crates/dbx-core/src/db/postgres.rs @@ -1696,6 +1696,8 @@ fn postgres_table_comment_sql() -> &'static str { fn postgres_tables_sql() -> &'static str { // PostgreSQL and Redshift can infer different wire types for LIMIT/OFFSET // placeholders. Keep them explicit so the shared i64 parameters serialize reliably. + // Root relations must precede partition descendants so a large partition + // hierarchy cannot push unrelated schema tables into later sidebar pages. "SELECT c.relname AS table_name, \ CASE c.relkind WHEN 'r' THEN 'BASE TABLE' WHEN 'v' THEN 'VIEW' \ WHEN 'm' THEN 'MATERIALIZED_VIEW' WHEN 'f' THEN 'FOREIGN TABLE' \ @@ -1710,7 +1712,7 @@ fn postgres_tables_sql() -> &'static str { LEFT JOIN pg_catalog.pg_namespace pn ON pn.oid = pc.relnamespace \ WHERE n.nspname = $1 AND c.relkind IN ('r','v','m','f','p') \ AND ($2 = '%%' OR c.relname ILIKE $2 ESCAPE '~' OR ($3 <> '' AND c.relname ILIKE $3 ESCAPE '~')) \ - ORDER BY c.relname \ + ORDER BY CASE WHEN pc.relkind = 'p' THEN 1 ELSE 0 END, c.relname \ LIMIT CAST($4 AS BIGINT) OFFSET CAST($5 AS BIGINT)" } @@ -4197,6 +4199,7 @@ mod tests { assert!(sql.contains("ILIKE $2 ESCAPE '~'")); assert!(sql.contains("$3 <> ''")); assert!(sql.contains("ILIKE $3 ESCAPE '~'")); + assert!(sql.contains("ORDER BY CASE WHEN pc.relkind = 'p' THEN 1 ELSE 0 END, c.relname")); assert!(sql.contains("LIMIT CAST($4 AS BIGINT) OFFSET CAST($5 AS BIGINT)")); }