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 <vrustx@vrustxdeMac-mini.local> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
23 files changed
+284
-2
No files matched your search
@@ -116,6 +116,7 @@ const editAppLayout = ref(settingsStore.editorSettings.appLayout);
|
||||
const editShowTrayIcon = ref(settingsStore.desktopSettings.show_tray_icon);
|
||||
const editIconTheme = ref<DesktopIconTheme>(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(
|
||||
</div>
|
||||
<Switch id="show-column-comments-in-header" v-model="editShowColumnCommentsInHeader" />
|
||||
</div>
|
||||
<div class="flex items-center justify-between gap-4 rounded-md border bg-muted/20 px-3 py-2">
|
||||
<div class="space-y-1">
|
||||
<Label for="show-column-types-in-header">
|
||||
{{ t("settings.showColumnTypesInHeader") }}
|
||||
</Label>
|
||||
<p class="text-xs text-muted-foreground">
|
||||
{{ t("settings.showColumnTypesInHeaderDescription") }}
|
||||
</p>
|
||||
</div>
|
||||
<Switch id="show-column-types-in-header" v-model="editShowColumnTypesInHeader" />
|
||||
</div>
|
||||
<div class="flex items-center justify-between gap-4 rounded-md border bg-muted/20 px-3 py-2">
|
||||
<div class="space-y-1">
|
||||
<Label for="compact-column-header-actions">
|
||||
|
||||
@@ -83,6 +83,7 @@ import { createColumnDrafts } from "@/lib/tableStructureEditorState";
|
||||
import type { BuildSingleColumnAlterSqlOptions } from "@/lib/tableStructureEditorSql";
|
||||
import { buildTableSelectSql, quoteTableIdentifier } from "@/lib/tableSelectSql";
|
||||
import { uuid } from "@/lib/utils";
|
||||
import { resolveHeaderColumnType } from "@/lib/dataGridColumnType";
|
||||
import {
|
||||
canEditExistingTableRows,
|
||||
hiveTablePropertiesIndicateTransactional,
|
||||
@@ -341,6 +342,7 @@ const columnCommentMap = computed(() => {
|
||||
return map;
|
||||
});
|
||||
const showColumnCommentsInHeader = computed(() => settingsStore.editorSettings.showColumnCommentsInHeader);
|
||||
const showColumnTypesInHeader = computed(() => settingsStore.editorSettings.showColumnTypesInHeader);
|
||||
const compactColumnHeaderActions = computed(() => settingsStore.editorSettings.compactColumnHeaderActions);
|
||||
const dataGridRenderMode = computed(() => settingsStore.editorSettings.dataGridRenderMode);
|
||||
|
||||
@@ -349,6 +351,16 @@ function headerColumnComment(column: string): string {
|
||||
return columnCommentMap.value.get(column) || "";
|
||||
}
|
||||
|
||||
function headerColumnType(column: string, actualColIdx: number): string {
|
||||
if (!showColumnTypesInHeader.value) return "";
|
||||
const resolved = resolveHeaderColumnType({
|
||||
tableColumnType: columnTypeMap.value.get(column),
|
||||
resultColumnTypes: props.result.column_types,
|
||||
actualColIdx,
|
||||
});
|
||||
return resolved ? shortTypeName(resolved) : "";
|
||||
}
|
||||
|
||||
function shortTypeName(t: string): string {
|
||||
const s = t.toLowerCase();
|
||||
if (s === "character varying") return "varchar";
|
||||
@@ -6505,6 +6517,14 @@ const gridContextMenuItems = computed<ContextMenuItem[]>(() => {
|
||||
<span class="min-w-0 truncate leading-4">
|
||||
{{ col.name }}
|
||||
</span>
|
||||
<span
|
||||
v-if="headerColumnType(col.name, col.actualColIdx)"
|
||||
class="min-w-0 truncate text-[10px] font-normal leading-3"
|
||||
:class="typeColorClass(headerColumnType(col.name, col.actualColIdx))"
|
||||
:title="headerColumnType(col.name, col.actualColIdx)"
|
||||
>
|
||||
{{ headerColumnType(col.name, col.actualColIdx) }}
|
||||
</span>
|
||||
<span
|
||||
v-if="headerColumnComment(col.name)"
|
||||
class="min-w-0 truncate text-[10px] font-normal leading-3 text-muted-foreground"
|
||||
|
||||
Reference in new issue
Block a user