Skip to content

Move data-skipping indexes out of schema graph cards and into the detail drawer #179

Description

@BorisTyshkevich

Goal

Keep expanded schema graph cards compact and predictable by removing the inline data-skipping-index list from each card.

Show the complete index metadata in a dedicated section of the bottom detail drawer instead.

Problem

Expanded schema graph cards currently render visible column rows and then append a single inline index line:

idx: event_time_index (minmax), event_time_microseconds_index (minmax), query_id_index (bloom_filter), ...

Even though the number of displayed indexes is capped, the resulting text line can still be very long. Card width is calculated from the widest rendered line, so long index names and types inflate the whole card and distort the graph layout.

This causes several UX problems:

  • a table with indexes becomes much wider than a table with the same columns but no indexes;
  • a few long index names dominate graph spacing;
  • related nodes are pushed far apart;
  • the inline text is too dense to scan;
  • only a capped subset is shown;
  • the bottom detail drawer does not currently provide a structured index view.

The graph card is an overview surface. A flattened index list is detailed metadata and does not belong in card geometry.

Proposed behavior

Schema graph card

Remove the index list from the card entirely.

A card should contain only:

  • table/view title;
  • engine, row count, and size summary;
  • visible columns;
  • key-role badges;
  • the existing +N more column overflow row.

Indexes must not affect:

  • card width;
  • card height;
  • graph layout;
  • node spacing.

No index-count badge is required for the first version. The detail drawer is the place for index metadata after selecting the card.

Bottom detail drawer

Add a dedicated section after Columns:

Data-skipping indexes (4)

Name                         Expression                  Type                    Granularity
event_time_index             event_time                  minmax                  1
query_id_index               query_id                    bloom_filter(0.01)      1
initial_query_id_index       initial_query_id            bloom_filter(0.01)      1
message_token_index          message                     tokenbf_v1(...)         4

The section should show every index for the selected table.

Required fields:

  • Name
  • Expression
  • Type
  • Granularity

Use type_full when available so parameterized index types remain distinguishable:

bloom_filter(0.01)
set(100)
tokenbf_v1(10240, 3, 0)

Optional fields, if already available without expanding scope:

  • creation: explicit or implicit;
  • compressed size;
  • uncompressed size;
  • marks size.

The section should be omitted when the table has no data-skipping indexes.

Data source

Use structured rows from system.data_skipping_indices.

Relevant fields include:

name
expr
type
type_full
granularity
creation
data_compressed_bytes
data_uncompressed_bytes
marks_bytes

The graph-loading path already retrieves skipping-index rows for card construction. Reuse those rows for the detail drawer where practical.

Do not issue an additional metadata query when the selected graph node already carries the required index data.

If the current detail-loading path independently fetches table details, extending that existing query is acceptable only when reuse from the graph payload would create worse coupling. The implementation should still avoid duplicate fetches for the same open detail view.

Rendering rules

The drawer is a detail surface, but index fields can still contain long values.

For index table cells:

  • keep rows single-line;
  • cap column widths;
  • use ellipsis for overflow;
  • expose the complete value through title;
  • allow the drawer body to scroll normally;
  • do not truncate the number of index rows.

The Expression and Type columns should receive most of the available width.

Suggested column behavior:

Column Width behavior
Name medium, ellipsis
Expression flexible, ellipsis
Type flexible, ellipsis
Granularity narrow, numeric
Creation narrow, optional
Size fields narrow, numeric, optional

Implementation outline

src/core/schema-cards.js

Remove index-derived display state from the card model:

  • remove MAX_IDX;
  • remove idxOverflow;
  • remove skipLine;
  • remove index text from cardSize();
  • stop accepting skipIndices in buildCardModel() if they are no longer needed there.

If index rows must remain attached to graph nodes for the drawer, keep them as structured metadata outside the visual card model:

{
  ...node,
  card: buildCardModel(...),
  skipIndices: [...]
}

Do not flatten them into display text.

src/ui/explain-graph.js

Remove rendering of:

idx: ...

Remove any .eg-skipidx layout assumptions.

Ensure card height and width are unchanged by index count or index-name length.

When a node is selected, pass its structured index rows into the detail-opening path.

src/ui/schema-detail.js

Add a Data-skipping indexes (N) section.

Render a table with the required fields.

Use existing formatting helpers for byte counts if size columns are included.

Add native full-value tooltips for capped Name, Expression, and Type cells.

src/net/ch-client.js / app detail loading

Ensure the detail data shape includes:

{
  columns,
  indexes,
  partitions,
  ddl,
  comment,
}

Prefer indexes as a clear public field name in the detail model, even if the underlying query uses system.data_skipping_indices.

Avoid fetching the same index data twice for one detail-open operation.

Acceptance criteria

  • Expanded schema graph cards no longer render an index list.
  • Index count, names, expressions, and types do not affect card width or height.
  • A table with many indexes has the same card geometry as the same table with no indexes, assuming identical title, summary, and columns.
  • Selecting a table with indexes shows a Data-skipping indexes (N) section in the bottom drawer.
  • The drawer shows every index, not a capped subset.
  • Each index shows Name, Expression, full Type, and Granularity.
  • Parameterized types use type_full when available.
  • Long names, expressions, and types do not force the drawer wider; they ellipsize and expose full text on hover.
  • The index section is omitted for tables with no data-skipping indexes.
  • Existing Columns, Partitions, and DDL sections continue to work unchanged.
  • No unnecessary additional network request is introduced.
  • No new runtime dependency.
  • Changed modules retain the repository coverage gate.

Tests

Card model

  • A model built with zero indexes and one built with many long indexes produce identical card size.
  • The model contains no skipLine.
  • Index count does not add a row to card height.
  • Long index names do not affect card width.

Graph rendering

  • No .eg-skipidx element is rendered.
  • A node with many indexes renders the same card dimensions as one without indexes.
  • Selecting the node still opens the detail drawer with its structured index metadata.

Detail drawer

  • A table with indexes shows Data-skipping indexes (N).
  • All indexes are rendered.
  • Required columns are present.
  • type_full is preferred over the base type.
  • Long Expression and Type values are visually capped and preserved in title.
  • A table with no indexes has no index section.
  • Loading and missing-field states degrade safely.

Network/data integration

  • Index rows from system.data_skipping_indices map correctly into the detail model.
  • Existing graph-loaded index data is reused when available.
  • No duplicate index request is made for one detail-open operation.

Non-goals

  • Showing primary-key or sorting-key expressions in this new section; those remain represented by existing column key badges and DDL.
  • Editing, creating, dropping, or materializing indexes.
  • Displaying runtime index usage statistics from EXPLAIN.
  • Adding index metadata to compact schema-tree rows.
  • Keeping a shortened index preview in graph cards.
  • Redesigning the entire detail drawer.

Relationship to #177

This is a separate follow-up to the compact type representation work.

#177 addresses oversized type strings in narrow UI surfaces. This issue addresses misplaced structured metadata: even compacted index text remains unsuitable for schema graph cards because the list itself changes card geometry and is incomplete.

Suggested title

Move data-skipping indexes from schema graph cards to the detail drawer

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    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