From 54de28d583440404818b0e5d8e9a995580fa481f Mon Sep 17 00:00:00 2001 From: vrustx <279631638@qq.com> Date: Sun, 7 Jun 2026 22:45:46 +0800 Subject: [PATCH] feat(grid): show column data types in result header (#669) (#820) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The data grid header only showed column names, and column types were available only via tableMeta (open-table view). Arbitrary query results (e.g. `select * from pg_depend`) therefore showed no type at all, which is exactly the case the reporter hit. Backend: add `column_types` to QueryResult (serde-default, backward compatible) and populate it for the native drivers where the type is readily available — PostgreSQL, MySQL, SQL Server, ClickHouse. Other drivers leave it empty for now (no behavior change); schemaless stores (Mongo/Redis/ES) have no column types. Frontend: render a type row under each column name in the grid header, color-coded by type. The type is resolved from tableMeta first (richer, includes precision) and falls back to the query result's column_types by index. Add a `showColumnTypesInHeader` setting (default on) and keep the msgpack tab-result cache compatible. The source-selection logic is extracted to lib/dataGridColumnType.ts with unit tests. Co-authored-by: vrustx Co-authored-by: Claude Opus 4.8 (1M context) --- .../editor/EditorSettingsDialog.vue | 16 +++++ apps/desktop/src/components/grid/DataGrid.vue | 20 +++++++ apps/desktop/src/i18n/locales/en.ts | 2 + apps/desktop/src/i18n/locales/es.ts | 3 + apps/desktop/src/i18n/locales/it.ts | 3 + apps/desktop/src/i18n/locales/pt-BR.ts | 3 + apps/desktop/src/i18n/locales/zh-CN.ts | 2 + apps/desktop/src/i18n/locales/zh-TW.ts | 2 + apps/desktop/src/lib/dataGridColumnType.ts | 33 +++++++++++ apps/desktop/src/lib/tabResultCache.ts | 4 ++ apps/desktop/src/stores/settingsStore.ts | 5 ++ apps/desktop/src/types/database.ts | 6 ++ crates/dbx-core/src/db/clickhouse_driver.rs | 13 ++++- .../dbx-core/src/db/elasticsearch_driver.rs | 4 ++ crates/dbx-core/src/db/mysql.rs | 58 +++++++++++++++++++ crates/dbx-core/src/db/postgres.rs | 4 ++ crates/dbx-core/src/db/rqlite_driver.rs | 2 + crates/dbx-core/src/db/sqlite.rs | 2 + crates/dbx-core/src/db/sqlserver.rs | 24 +++++++- crates/dbx-core/src/query.rs | 15 +++++ crates/dbx-core/src/transfer.rs | 2 + crates/dbx-core/src/types.rs | 5 ++ packages/app-tests/dataGridColumnType.test.ts | 58 +++++++++++++++++++ 23 files changed, 284 insertions(+), 2 deletions(-) create mode 100644 apps/desktop/src/lib/dataGridColumnType.ts create mode 100644 packages/app-tests/dataGridColumnType.test.ts diff --git a/apps/desktop/src/components/editor/EditorSettingsDialog.vue b/apps/desktop/src/components/editor/EditorSettingsDialog.vue index 2f0fbaeea..a0f52e939 100644 --- a/apps/desktop/src/components/editor/EditorSettingsDialog.vue +++ b/apps/desktop/src/components/editor/EditorSettingsDialog.vue @@ -116,6 +116,7 @@ const editAppLayout = ref(settingsStore.editorSettings.appLayout); const editShowTrayIcon = ref(settingsStore.desktopSettings.show_tray_icon); const editIconTheme = ref(settingsStore.desktopSettings.icon_theme); const editShowColumnCommentsInHeader = ref(settingsStore.editorSettings.showColumnCommentsInHeader); +const editShowColumnTypesInHeader = ref(settingsStore.editorSettings.showColumnTypesInHeader); const editCompactColumnHeaderActions = ref(settingsStore.editorSettings.compactColumnHeaderActions); const editRedisScanPageSize = ref(settingsStore.editorSettings.redisScanPageSize); const editShortcuts = ref(normalizeShortcutSettings(settingsStore.editorSettings.shortcuts)); @@ -273,6 +274,7 @@ watch( editShowTrayIcon.value = settingsStore.desktopSettings.show_tray_icon; editIconTheme.value = settingsStore.desktopSettings.icon_theme; editShowColumnCommentsInHeader.value = settingsStore.editorSettings.showColumnCommentsInHeader; + editShowColumnTypesInHeader.value = settingsStore.editorSettings.showColumnTypesInHeader; editCompactColumnHeaderActions.value = settingsStore.editorSettings.compactColumnHeaderActions; editRedisScanPageSize.value = settingsStore.editorSettings.redisScanPageSize; editShortcuts.value = normalizeShortcutSettings(settingsStore.editorSettings.shortcuts); @@ -320,6 +322,7 @@ function hasChanges(): boolean { editShowTrayIcon.value !== settingsStore.desktopSettings.show_tray_icon || editIconTheme.value !== settingsStore.desktopSettings.icon_theme || editShowColumnCommentsInHeader.value !== settingsStore.editorSettings.showColumnCommentsInHeader || + editShowColumnTypesInHeader.value !== settingsStore.editorSettings.showColumnTypesInHeader || editCompactColumnHeaderActions.value !== settingsStore.editorSettings.compactColumnHeaderActions || editRedisScanPageSize.value !== settingsStore.editorSettings.redisScanPageSize || JSON.stringify(editShortcuts.value) !== JSON.stringify(settingsStore.editorSettings.shortcuts) || @@ -354,6 +357,7 @@ async function persistSettings() { confirmDangerousSqlExecution: editConfirmDangerousSqlExecution.value, appLayout: editAppLayout.value, showColumnCommentsInHeader: editShowColumnCommentsInHeader.value, + showColumnTypesInHeader: editShowColumnTypesInHeader.value, compactColumnHeaderActions: editCompactColumnHeaderActions.value, redisScanPageSize: editRedisScanPageSize.value, shortcuts: editShortcuts.value, @@ -401,6 +405,7 @@ function resetDefaults() { editShowTrayIcon.value = DEFAULT_DESKTOP_SETTINGS.show_tray_icon; editIconTheme.value = DEFAULT_DESKTOP_SETTINGS.icon_theme; editShowColumnCommentsInHeader.value = DEFAULT_EDITOR_SETTINGS.showColumnCommentsInHeader; + editShowColumnTypesInHeader.value = DEFAULT_EDITOR_SETTINGS.showColumnTypesInHeader; editCompactColumnHeaderActions.value = DEFAULT_EDITOR_SETTINGS.compactColumnHeaderActions; editRedisScanPageSize.value = DEFAULT_EDITOR_SETTINGS.redisScanPageSize; editShortcuts.value = normalizeShortcutSettings(DEFAULT_EDITOR_SETTINGS.shortcuts); @@ -1569,6 +1574,17 @@ watch( +
+
+ +

+ {{ t("settings.showColumnTypesInHeaderDescription") }} +

+
+ +