From 92a68f705a808115beeb0de96fc38e7416896fc5 Mon Sep 17 00:00:00 2001 From: Eugene Date: Fri, 12 Jun 2026 16:58:51 -0400 Subject: [PATCH] polish: address PR #172 review follow-ups for EXPLAIN plan view Minor review items from PR #172 (merged), applied as a follow-up: - ResultsTable: clarify `planAvailable` precedence (`explainPlan != null`) - ExplainPlan: truncate long `attached_condition` to 120 chars with a `title` tooltip carrying the full value, so complex WHERE/JOIN clauses no longer overflow the stats row - ExplainPlan: drop the dead `'block'` member from `NodeRender['kind']` (never emitted by `buildNode`) Skipped the nonce item: the Explain button is disabled while explaining, so `Date.now()` cannot collide today. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/components/ExplainPlan.tsx | 14 ++++++++------ src/components/ResultsTable.tsx | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/components/ExplainPlan.tsx b/src/components/ExplainPlan.tsx index b17dfc8..977fb82 100644 --- a/src/components/ExplainPlan.tsx +++ b/src/components/ExplainPlan.tsx @@ -88,10 +88,10 @@ function collectWarnings(node: Node): Severity[] { } interface NodeRender { - kind: 'block' | 'table' | 'nested_loop' | 'ordering' | 'grouping' | 'union' | 'attached' | 'materialized' | 'duplicates' | 'unknown'; + kind: 'table' | 'nested_loop' | 'ordering' | 'grouping' | 'union' | 'attached' | 'materialized' | 'duplicates' | 'unknown'; title: string; - /** Lines of "label: value" rendered below the title. */ - stats: { label: string; value: string }[]; + /** Lines of "label: value" rendered below the title. `title` holds the full value when `value` is truncated. */ + stats: { label: string; value: string; title?: string }[]; warnings: Severity[]; children: NodeRender[]; } @@ -114,7 +114,7 @@ function buildTable(t: Node): NodeRender { const cond = getStr(t, 'attached_condition'); const ref = Array.isArray(t['ref']) ? (t['ref'] as unknown[]).join(', ') : undefined; - const stats: { label: string; value: string }[] = []; + const stats: { label: string; value: string; title?: string }[] = []; if (access) stats.push({ label: 'access_type', value: access }); if (key) stats.push({ label: 'key', value: key }); else if (possible) stats.push({ label: 'possible_keys', value: possible }); @@ -123,7 +123,9 @@ function buildTable(t: Node): NodeRender { if (produced !== undefined) stats.push({ label: 'rows produced', value: produced.toLocaleString() }); if (filtered) stats.push({ label: 'filtered', value: `${filtered}%` }); if (cost) stats.push({ label: 'cost', value: cost }); - if (cond) stats.push({ label: 'condition', value: cond }); + if (cond) stats.push(cond.length > 120 + ? { label: 'condition', value: `${cond.slice(0, 120)}…`, title: cond } + : { label: 'condition', value: cond }); const children: NodeRender[] = []; const attached = t['attached_subqueries']; @@ -379,7 +381,7 @@ function PlanTree({ node, t, depth }: PlanTreeProps) { {node.stats.map((st, i) => ( {st.label}: - {st.value} + {st.value} ))} diff --git a/src/components/ResultsTable.tsx b/src/components/ResultsTable.tsx index d444d4d..7e63421 100644 --- a/src/components/ResultsTable.tsx +++ b/src/components/ResultsTable.tsx @@ -358,7 +358,7 @@ export function ResultsTable({ results, resultSets, activeResultIndex = 0, onSel if (!explainPlan && !explainError && !isExplaining) setPlanVisible(false); }, [explainPlan, explainError, isExplaining]); - const planAvailable = isExplaining || explainPlan !== undefined && explainPlan !== null || !!explainError; + const planAvailable = isExplaining || explainPlan != null || !!explainError; // Column layout: order and widths const [colOrder, setColOrder] = useState([]);