Skip to content

Cell detail: type-aware structured content viewer with shared Markdown rendering #214

Description

@BorisTyshkevich

Problem

Clicking a result-table cell opens the right-side cell-detail drawer, but the drawer currently has only limited presentation logic:

  • values that look like HTML get Rendered | Source;
  • strict JSON beginning with { or [ is parsed and reindented;
  • everything else is shown as plain text in a <pre>.

This is inadequate for common ClickHouse result values such as:

  • SQL stored in system.query_log.query;
  • DDL stored in statement, create_table_query, or similar fields;
  • JSON and JSON Lines stored in String, JSON, Object, Array(JSON), or wrapped types;
  • XML;
  • Markdown;
  • large logs and stack traces.

A SQL value such as:

SELECT timestamp, level, source, hostname, component, thread,
       class, line, pid, skeleton, params_str[2] = '8.0'
FROM logbook.logs
WHERE timestamp >= '2026-03-27 05:00:00'
  AND timestamp < '2026-03-28 05:00:00'
ORDER BY timestamp DESC
LIMIT 300

currently appears as an unformatted block of plain text even when:

  • the column is named query;
  • the text begins with a clear SQL statement keyword;
  • the application already has ClickHouse SQL highlighting;
  • the application already has a server-backed formatQuery() path;
  • the application already has a reusable read-only CodeMirror viewer.

The drawer should identify common structured content conservatively and present it using the appropriate renderer.


Goal

Turn the cell-detail drawer into a type-aware structured-content viewer with:

  • conservative automatic detection;
  • explicit user mode override;
  • automatic local JSON formatting;
  • automatic best-effort server-side SQL formatting;
  • read-only CodeMirror source views;
  • exact Raw views;
  • visible parse errors;
  • shared safe Markdown rendering;
  • preserved HTML rendering;
  • correct lifecycle in the main document and detached Data views.

The initial supported modes are:

Auto
Text
JSON
SQL
Markdown
HTML
XML

YAML is explicitly out of scope.


Existing foundation

The application already has:

src/core/cell.js

with:

looksLikeHtml()
prettyValue()

The current prettyValue():

  • attempts JSON.parse() only for text beginning with { or [;
  • returns two-space-indented JSON on success;
  • silently falls back to the original string on failure.

The application also already has:

src/editor/code-viewer.js

with a reusable read-only CodeMirror surface.

Supported language identifiers are currently:

text
json
sql
xml
html
markdown

Current language behavior:

Language CodeMirror behavior
text Plain source
json JSON parsing and syntax highlighting
sql SQL parsing and syntax highlighting
xml XML parsing and syntax highlighting
html XML-style source highlighting
markdown Plain Markdown source

The viewer already provides:

  • line numbers;
  • selection and copy;
  • local search;
  • configurable line wrapping;
  • detached-document mounting;
  • language switching;
  • explicit teardown.

The application injects it through:

app.CodeViewer

The drawer should consume this existing seam rather than constructing another editor/viewer implementation.


Content-analysis model

Replace the current string-only formatting decision with a pure descriptor.

Suggested API:

analyzeCellValue({
  name,
  type,
  value,
  requestedMode: 'auto',
})

Suggested return shape:

{
  mode: 'sql',
  variant: 'sql',
  source: originalText,
  formatted: null,
  valid: true,
  error: null,
  confidence: 'strong',
}

For valid JSON:

{
  mode: 'json',
  variant: 'json',
  source: originalText,
  formatted: prettyJson,
  valid: true,
  error: null,
  confidence: 'strong',
}

For invalid JSON selected through a type hint or manual mode:

{
  mode: 'json',
  variant: 'json',
  source: originalText,
  formatted: null,
  valid: false,
  error: 'Unexpected token ...',
  confidence: 'strong',
}

Requirements:

  • pure function;
  • no DOM;
  • no CodeMirror import;
  • no network request;
  • no mutation of the original value;
  • exact source preserved separately from formatted output;
  • deterministic classification;
  • manual requestedMode overrides Auto detection.

Auto-detection priority

Auto mode must be conservative and deterministic.

Use this priority:

1. strong ClickHouse type hint
2. strict JSON / JSONL parsing
3. strong SQL content with optional column-name support
4. existing HTML heuristic
5. conservative XML heuristic
6. plain text

Do not auto-detect Markdown from arbitrary prose.

Markdown remains available through the explicit mode selector.


ClickHouse type hints

JSON-bearing types

Treat the following as JSON-bearing:

JSON
Object('json')
Array(JSON)
Array(Nullable(JSON))
Nullable(JSON)
LowCardinality(JSON)
Nullable(LowCardinality(JSON))

Support nested transparent wrappers where valid.

Use the existing ClickHouse type-expression parser or a small projection over it.

Do not classify by broad substring matching such as:

type.includes('JSON')

because that can misclassify unrelated type names or malformed expressions.

A JSON-bearing type must stay in JSON mode even when parsing fails.

Do not silently fall back to Text mode.

String-like SQL values

ClickHouse type alone is not enough to identify SQL because SQL commonly arrives as:

String
LowCardinality(String)
Nullable(String)

Use column name and content signals for SQL.


JSON detection and formatting

Strict JSON document

For a single JSON value:

const parsed = JSON.parse(trimmed);
const formatted = JSON.stringify(parsed, null, 2);

Support any valid JSON root:

object
array
string
number
true
false
null

Auto-detection should remain conservative for scalar roots. A scalar should normally require a JSON type hint or manual JSON mode; otherwise ordinary values such as true or 123 should remain Text.

JSON Lines / NDJSON

When the source contains multiple non-empty lines and every line independently parses as JSON:

  • classify as jsonl;
  • format each record independently;
  • preserve record boundaries;
  • retain exact Raw source;
  • ignore blank lines for parsing;
  • do not create phantom records for blank lines.

Suggested formatted output:

{
  "record": 1
}

────────

{
  "record": 2
}

The separator may differ, but records must remain visually distinct.

A single invalid non-empty line makes JSONL parsing fail.

Do not classify arbitrary multi-line prose as JSONL because one line happens to parse.

Invalid JSON

When JSON mode is selected by:

  • a JSON-bearing ClickHouse type;
  • strict Auto classification;
  • manual JSON override;

and parsing fails, show:

  1. a visible error banner;
  2. the complete exact Raw source.

Example:

Invalid JSON — Unexpected token "'" at position 123

Requirements:

  • do not show an empty viewer;
  • do not show partially formatted output;
  • do not repair invalid escapes;
  • do not remove trailing commas;
  • do not alter whitespace or line endings in Raw;
  • do not silently switch to Text;
  • expose the error with role="alert" or equivalent;
  • Copy always returns the exact original value.

SQL detection

SQL Auto detection must combine syntax and context.

Do not detect SQL with a broad regular expression such as:

/select|from|where/i

That would misclassify logs, prose, stack traces, and JSON strings.

Reuse the existing SQL lexical infrastructure:

scanSpans()
splitStatements()
leadingKeyword()

These already understand:

  • ClickHouse single-quoted strings;
  • heredocs;
  • quoted identifiers;
  • line comments;
  • nested block comments;
  • semicolons inside literals;
  • multi-statement scripts.

Strong SQL keywords

Treat the following leading keywords as strong SQL signals:

SELECT
INSERT
CREATE
ALTER
DROP
TRUNCATE
RENAME
ATTACH
DETACH
OPTIMIZE
EXPLAIN
DESCRIBE
DESC
SHOW
EXISTS
SYSTEM
KILL
GRANT
REVOKE
BACKUP
RESTORE
CHECK
WATCH

The exact set may reuse existing keyword tables where appropriate.

Ambiguous SQL keywords

These are valid SQL beginnings but can appear in ordinary text:

WITH
SET
USE
VALUES

Require supporting context for these, such as a recognized SQL-bearing column name.

SQL-bearing column names

Treat these names as strong supporting hints, case-insensitively:

query
sql
statement
query_text
query_sql
view_query
create_query
create_table_query
ddl
definition
command

Also support common suffix patterns conservatively:

*_query
*_sql
*_ddl

Do not allow a column name alone to classify arbitrary prose as SQL.

Recommended rule:

function looksLikeSql({ name, text }) {
  const statements = splitStatements(text);
  if (!statements.length) return false;

  const keyword = leadingKeyword(statements[0]);

  if (STRONG_SQL_KEYWORDS.has(keyword)) return true;

  return isSqlColumnName(name)
    && AMBIGUOUS_SQL_KEYWORDS.has(keyword);
}

A multi-statement script is SQL when every non-empty statement has a recognized SQL leading keyword.


SQL source rendering

SQL mode uses the existing read-only CodeMirror viewer:

app.CodeViewer({
  parent,
  document: targetDocument,
  text,
  language: 'sql',
  wrap,
})

It must provide:

  • syntax highlighting;
  • line numbers;
  • search;
  • selection and copying;
  • configurable wrapping;
  • detached-document support.

Do not make the cell value editable.

Do not reuse the main SQL editor with history, completion, schema loading, hover, or drag/drop.


SQL formatting

There will be no local SQL formatter in this issue.

Do not add:

  • a SQL formatting dependency;
  • a hand-written keyword/newline formatter;
  • client-side SQL AST reserialization;
  • arbitrary whitespace rewriting.

Use ClickHouse itself:

SELECT formatQuery({sql:String}) AS formatted
FORMAT JSON

or the existing equivalent helper.

Behavior

When Auto or manual mode resolves to SQL:

  1. open the drawer immediately;
  2. show the exact raw SQL in a highlighted CodeMirror viewer;
  3. show a non-blocking Formatting… status;
  4. start a best-effort ClickHouse formatting request;
  5. replace the source viewer content with formatted SQL on success;
  6. expose:
Formatted | Raw
  1. retain the exact original Raw source;
  2. if formatting fails, keep Raw SQL visible and show a non-blocking error;
  3. never close or blank the drawer because formatting failed.

Request requirements

The formatting request must:

  • be cancellable;
  • be aborted when the drawer closes;
  • be aborted when another mode is selected;
  • be aborted when a different cell replaces the drawer;
  • use native query parameters instead of interpolating the SQL string where practical;
  • not execute the cell SQL;
  • only pass it as the value to formatQuery();
  • use the current authenticated connection;
  • respect sign-out behavior;
  • not mutate the active editor;
  • not create a result/history entry;
  • not affect the current query execution state.

Query logging

Formatting a system.query_log.query value can itself create another query-log entry.

Where supported, run the formatter with:

log_queries = 0

or an equivalent request-level setting.

If the connected user cannot set it, formatting should still work; failure to suppress query logging must not make the feature fail.

Do not use a separate hidden database connection.

Cache

Cache successful formatted SQL for the current page session.

Suggested key:

raw SQL string

A bounded cache is sufficient.

Suggested bounds:

maximum entries: 100
maximum total source bytes: 5 MiB

Equivalent conservative limits are acceptable.

Do not persist formatted SQL to localStorage or the saved-query Spec.

Size limit

Do not auto-format extremely large SQL values.

Suggested maximum:

1 MiB

For larger values:

  • show highlighted Raw SQL;
  • display Formatting skipped for values over 1 MiB;
  • allow Copy;
  • do not issue the server request.

Formatting result

A successful formatter response must be a non-empty string.

If the server returns:

  • an empty result;
  • malformed result shape;
  • a query error;
  • an authorization error;
  • a cancellation;

retain Raw mode and surface a compact status.


Manual mode selector

Add a local drawer mode selector:

Auto
Text
JSON
SQL
Markdown
HTML
XML

The selected value is local drawer state.

It must not:

  • modify the cell;
  • persist by column;
  • persist by query;
  • update the saved-query Spec;
  • affect other open drawers.

Manual modes always override Auto detection.

Examples:

  • selecting SQL attempts server formatting;
  • selecting JSON parses strictly and shows errors;
  • selecting HTML offers Rendered and Source;
  • selecting XML shows source only;
  • selecting Markdown offers Rendered and Source;
  • selecting Text shows plain source.

Drawer layout

Recommended layout:

query   String                                      ×
Mode: [Auto (SQL) ▾]    [Formatted | Raw]    [Wrap] [Copy]
──────────────────────────────────────────────────────────
[read-only CodeMirror viewer]

The Auto option should expose the resolved mode:

Auto (SQL)
Auto (JSON)
Auto (HTML)
Auto (XML)
Auto (Text)

This makes the classification visible without requiring another status label.

Controls by mode

Mode Available views
Valid JSON Pretty / Raw
Invalid JSON Raw plus error
SQL Formatted / Raw
Markdown Rendered / Source
HTML Rendered / Source
XML Source
Text Source

Copy

Copy always copies:

original raw cell value

It never copies:

  • formatted JSON;
  • formatted SQL;
  • rendered Markdown text;
  • rendered HTML text;
  • XML-normalized text.

Copy must work in the main drawer and detached Data view.

Wrap

Wrap is local drawer state.

Recommended defaults:

Mode Default
Text On
Markdown source On
JSON Pretty Off
JSON Raw Off
SQL Formatted Off
SQL Raw Off
XML Off
HTML source Off

Changing mode may apply the mode default only until the user explicitly changes Wrap during the current drawer session.


HTML

Keep the existing:

Rendered | Source

behavior.

Rendered mode continues using:

<iframe sandbox="">

Source mode must use the shared read-only CodeMirror viewer with:

language: html

Requirements:

  • source remains exact;
  • no script execution;
  • no inherited origin privileges;
  • no iframe for XML;
  • switching Rendered/Source destroys the prior active viewer or iframe cleanly.

The existing looksLikeHtml() heuristic remains an Auto signal.


XML

XML mode is source-only.

Use:

language: xml

Provide:

  • syntax highlighting;
  • line numbers;
  • search;
  • selection;
  • wrap control;
  • exact source.

Do not:

  • render XML as HTML;
  • normalize or pretty-print XML;
  • execute XSLT;
  • fetch referenced schemas or external entities.

XML Auto detection

Auto-detect only strong signals:

  • XML declaration:
<?xml version="1.0"?>
  • or a conservative non-HTML root element with a matching closing tag.

HTML detection takes precedence over XML when the content looks like HTML.


Markdown

Markdown is never auto-detected from arbitrary text.

Manual Markdown mode provides:

Rendered | Source

Rendered mode must reuse the application’s existing safe Markdown implementation.

The application already has:

core/markdown-lite.js

and a DOM renderer currently associated with Text panels.

Extract the renderer to a shared module, for example:

src/ui/markdown-view.js

Suggested exports:

renderMarkdown(blocks)
renderMarkdownText(text)

renderMarkdownText() must call the existing parser.

Then:

  • Text panels use renderMarkdownText();
  • the cell-detail Markdown Rendered view uses renderMarkdownText().

Preserve the current Markdown-lite security and feature contract:

  • headings;
  • paragraphs;
  • ordered and unordered lists;
  • bold and italic;
  • inline code;
  • safe HTTP(S) links;
  • no raw HTML execution;
  • no unsafe URL schemes;
  • no second Markdown parser.

Markdown Source uses the CodeMirror viewer with:

language: markdown

It may remain plain source highlighting unless a dedicated Markdown language package is added separately.


Text

Text mode uses the shared CodeMirror viewer with:

language: text

This covers:

  • logs;
  • stack traces;
  • arbitrary strings;
  • unknown content;
  • manually overridden values.

Do not use a plain <pre> for the new source path.

The viewer provides consistent:

  • search;
  • line numbers;
  • selection;
  • wrapping;
  • detached-document behavior.

Lifecycle

The drawer owns at most:

one active CodeMirror viewer
one active SQL-format request
one active rendered iframe or Markdown root

Before:

  • switching mode;
  • switching Pretty/Raw;
  • switching Formatted/Raw;
  • switching Rendered/Source;
  • replacing drawer content;
  • closing the drawer;

perform the required teardown:

destroy CodeMirror viewer
abort SQL-format request
remove iframe/rendered content
clear transient status

Viewer destruction must be explicit and idempotent.

A late formatting response must not modify a closed drawer or a drawer that has switched to another cell/mode.

Use a generation token or request identity guard in addition to AbortController.


Existing drawer behavior to preserve

Keep the existing:

  • right-side drawer;
  • persisted resize width;
  • drag handle;
  • close button;
  • Escape handling;
  • backdrop click handling;
  • stacked-drawer behavior;
  • topmost-drawer-only Escape behavior;
  • detached Data-view support;
  • document-realm correctness;
  • full original value availability.

No change to table-cell click behavior.


Suggested implementation

src/core/cell.js

Replace or extend prettyValue() with:

analyzeCellValue()
looksLikeSql()
isSqlColumnName()
parseJsonDocument()
parseJsonLines()
looksLikeXml()

Retain looksLikeHtml().

Compatibility helper functions may remain if other callers use them.

src/ui/results.js

Refactor openCellDetail() to own:

  • mode selector;
  • resolved Auto label;
  • mode-specific tabs;
  • CodeMirror viewer lifecycle;
  • SQL formatter request lifecycle;
  • Copy;
  • Wrap;
  • error and status banners;
  • HTML/Markdown rendering.

Avoid putting detection logic directly into this UI module.

src/editor/code-viewer.js

Consume the existing API.

Only extend it if the drawer requires a narrowly reusable capability such as:

getText()

Do not add application state or formatting logic to the viewer.

src/ui/markdown-view.js

Extract the existing safe Markdown DOM renderer.

Both Text panels and cell-detail Markdown rendering must use it.

SQL formatter helper

Add a focused helper in an appropriate network/core boundary, for example:

src/net/ch-client.js

or an app action:

formatSqlValue(sql, { signal })

It must not reuse the active editor action if that action:

  • replaces editor contents;
  • records history;
  • shows editor-specific toast messages;
  • modifies the current result.

The helper should only return:

{
  formatted,
  loggedSuppressionApplied
}

or throw a normal request error.


Error behavior

JSON error

Show:

Invalid JSON — <parse message>

with role="alert".

Keep Raw visible.

SQL formatting error

Show a non-blocking compact message:

Could not format with ClickHouse — showing raw SQL

Do not use role="alert" unless the interaction requires it.

Do not expose the complete authorization/token response body.

Viewer failure

If CodeMirror construction fails unexpectedly:

  • fall back to a plain selectable <pre>;
  • preserve the complete source;
  • keep Copy available;
  • do not close the drawer.

This is a defensive fallback, not the normal path.


Performance

Requirements:

  • analysis is linear in source length;
  • avoid repeated full-string scans where one pass can be shared;
  • do not format SQL above the configured size limit;
  • cancel stale formatter requests;
  • bound the formatter cache;
  • destroy viewers on every transition;
  • do not instantiate both Pretty and Raw viewers simultaneously;
  • keep only the active mode/view mounted.

The drawer must remain responsive for values up to at least 1 MiB.


Accessibility

Requirements:

  • mode selector has an accessible label;
  • Pretty/Raw, Formatted/Raw, and Rendered/Source controls expose selected state;
  • Wrap is a labeled toggle;
  • Copy has an accessible label;
  • close retains its existing accessible behavior;
  • JSON parse errors are announced;
  • formatting status uses role="status" or equivalent;
  • hidden views are removed from the accessibility tree;
  • the CodeMirror source surface remains keyboard reachable;
  • local search remains available through Mod/Ctrl+F while the viewer is focused.

Files

Expected changes:

src/core/cell.js
src/ui/results.js
src/editor/code-viewer.js
src/ui/markdown-view.js
src/ui/panels.js
src/net/ch-client.js
src/styles.css

Expected tests:

tests/unit/cell.test.js
tests/unit/results.test.js
tests/unit/code-viewer.test.js
tests/unit/markdown-view.test.js
tests/unit/panels.test.js
tests/unit/ch-client.test.js

Add focused browser coverage for:

main result table drawer
detached Data-view drawer
SQL auto-format
JSON Pretty/Raw
HTML Rendered/Source

No schema change.

No saved-query migration.

No new runtime dependency.

No local SQL formatter.


Tests

Auto classification

Verify:

  • query + SELECT ... resolves to SQL;
  • statement + CREATE TABLE ... resolves to SQL;
  • view_query + WITH ... SELECT ... resolves to SQL;
  • arbitrary prose containing the word select remains Text;
  • a log line beginning with WITH remains Text unless column context supports SQL;
  • multi-statement SQL resolves to SQL;
  • comments before a SQL keyword are skipped correctly;
  • semicolons inside strings do not break detection;
  • heredocs do not break detection;
  • empty strings resolve to Text.

JSON

Verify:

  • object;
  • array;
  • valid scalar with JSON type hint;
  • nested JSON-bearing ClickHouse types;
  • valid JSONL;
  • blank JSONL lines;
  • invalid JSON;
  • invalid JSONL;
  • truncated JSON;
  • malformed escape sequences;
  • exact Raw preservation;
  • Pretty uses two-space indentation;
  • Copy uses Raw.

SQL formatting

Verify:

  • raw SQL viewer appears synchronously;
  • formatting request starts after render;
  • successful response replaces the Formatted view;
  • Raw remains exact;
  • Formatted/Raw toggle works;
  • failed request retains Raw;
  • empty formatter result retains Raw;
  • close aborts request;
  • mode switch aborts request;
  • stale response cannot repaint;
  • cached SQL does not issue another request;
  • cache is bounded;
  • value above size limit does not issue a request;
  • formatter request does not execute the source SQL;
  • log_queries=0 is attempted where configured;
  • inability to suppress logging does not fail formatting;
  • no editor/history/result state changes occur.

Manual overrides

Verify every selector mode:

Auto
Text
JSON
SQL
Markdown
HTML
XML

Manual selection must override Auto without modifying the source.

CodeMirror

Verify correct language IDs:

text
json
sql
xml
html
markdown

Verify:

  • one active viewer maximum;
  • mode switch destroys prior viewer;
  • tab switch destroys prior viewer;
  • close destroys viewer;
  • detached-document ownership;
  • search;
  • wrapping;
  • selection and copy.

HTML

Verify:

  • Auto HTML detection;
  • sandboxed Rendered mode;
  • CodeMirror Source mode;
  • exact source;
  • switching destroys old content;
  • scripts do not execute.

XML

Verify:

  • declaration-based detection;
  • conservative root detection;
  • HTML wins over XML;
  • source-only behavior;
  • no iframe;
  • no external-resource fetch.

Markdown

Verify:

  • never auto-detected;
  • manual Rendered mode;
  • manual Source mode;
  • Text panel and drawer use the same renderer;
  • unsafe links remain blocked;
  • raw HTML remains inert;
  • no duplicate renderer implementation.

Existing drawer behavior

Verify:

  • resize persistence;
  • Escape;
  • backdrop close;
  • close button;
  • stacked drawers;
  • only top drawer closes;
  • detached Data view;
  • exact column name and ClickHouse type remain shown.

Non-goals

Do not include:

  • local SQL formatting;
  • third-party SQL formatter packages;
  • hand-written SQL whitespace formatting;
  • editable cell values;
  • executing cell SQL;
  • opening SQL automatically in a new editor tab;
  • persisting drawer mode by column;
  • persisting formatted content;
  • YAML;
  • CSV/TSV table previews;
  • XML rendering;
  • XSLT;
  • full CommonMark or GFM expansion;
  • JSON repair;
  • JSON5;
  • per-format user preferences;
  • semantic SQL validation;
  • schema-aware SQL completion in the drawer.

Acceptance criteria

  • Cell detail offers Auto, Text, JSON, SQL, Markdown, HTML, and XML modes.
  • Auto mode visibly reports its resolved format.
  • JSON-bearing ClickHouse types are recognized through structured type analysis.
  • Valid JSON supports Pretty and exact Raw views.
  • Valid JSONL supports formatted and exact Raw views.
  • Invalid JSON remains in JSON mode and shows an error plus complete Raw source.
  • SQL is conservatively auto-detected using lexical syntax and optional column-name evidence.
  • SQL values open immediately in a read-only highlighted viewer.
  • SQL is formatted only through ClickHouse formatQuery().
  • No local SQL formatter or new formatting dependency is added.
  • SQL formatting is cancellable, bounded, cached, and best-effort.
  • SQL formatting failure leaves exact Raw SQL visible.
  • Formatted/Raw SQL toggle is available after successful formatting.
  • Copy always returns the original raw cell value.
  • HTML keeps sandboxed Rendered mode and gains CodeMirror Source.
  • XML is source-only.
  • Markdown is manual-only and shares the existing safe renderer with Text panels.
  • Text, JSON, SQL, XML, HTML source, and Markdown source use the shared CodeMirror viewer.
  • Only one active viewer exists per drawer.
  • Active viewer and formatting request are destroyed/aborted on every transition and close.
  • Main and detached document behavior remains correct.
  • Existing resize, Escape, backdrop, close, and stacking behavior remains correct.
  • No schema or saved-query migration is required.
  • No new runtime dependency is added.
  • Relevant unit and browser tests pass.
  • npm test passes.
  • npm run build succeeds.

Definition of done

Clicking a result-table cell opens a structured-content drawer that automatically recognizes common JSON, SQL, HTML, XML, and plain-text values.

JSON is formatted locally. SQL is highlighted immediately and formatted best-effort by the connected ClickHouse server, with exact Raw source always available. The drawer uses the existing read-only CodeMirror viewer, preserves all current drawer lifecycle behavior, and introduces no local SQL formatter.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions