Skip to content

fix(table): server-side column tag filter across all pages (#25063) (#29324) [1.13 backport]#29844

Merged
sonika-shah merged 1 commit into
1.13from
cherry-pick/29324-1.13
Jul 8, 2026
Merged

fix(table): server-side column tag filter across all pages (#25063) (#29324) [1.13 backport]#29844
sonika-shah merged 1 commit into
1.13from
cherry-pick/29324-1.13

Conversation

@sonika-shah

@sonika-shah sonika-shah commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Cherry-picks #29324 into 1.13.

Original: fix(table): server-side column tag filter across all pages (#25063) — merge commit 3a66dae8eb9ea1dc60ae45e9d8e9e73a829af167 on main.

Why

On the table Schema view, columns paginate server-side but tag filtering ran client-side over the loaded page only, so matches on later pages were hidden. This moves tag / glossary-term filtering into the same server-side layer as pagination, so it spans the whole table.

What changed (identical to #29324)

  • Backend: tags + glossaryTerms query params on both /columns/search endpoints; server-side tree pruning that keeps matches at their real nested depth; total counts top-level columns containing a match; within-group OR, across-group AND semantics.
  • Frontend: Schema table filters call the server search and reset to page 1; dropdown options sourced from the full table; ancestors of matches auto-expand.

Verification

  • Cherry-pick applied cleanly (no conflicts).
  • git diff 3a66dae8 HEAD over the 6 changed source files is empty — byte-identical to the original.
  • mvn clean install -pl openmetadata-service,openmetadata-integration-tests -am -DskipTestsBUILD SUCCESS (both modules SUCCESS).

🤖 Generated with Claude Code

Greptile Summary

This PR moves schema-column tag filtering into the server-side column search path.

  • Adds tags and glossaryTerms query params to both column search endpoints.
  • Prunes matching column trees on the backend before pagination.
  • Updates the schema table UI to call server search for tag filters.
  • Adds integration and UI tests for cross-page tag filtering.

Confidence Score: 4/5

The backend column search path needs fixes before merging.

  • Text-only column search can now return parent roots instead of flat matching child columns.
  • Derived-tag lookup failures can return successful but incomplete filtered results.
  • The UI expansion change can hurt large nested schemas, but it is contained to filtered or searched views.

openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/TableRepository.java

Important Files Changed

Filename Overview
openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/TableRepository.java Adds the core server-side column filter logic, with issues around text-search compatibility and derived-tag failure handling.
openmetadata-service/src/main/java/org/openmetadata/service/resources/databases/TableResource.java Adds tag and glossary query parameters and passes parsed filter sets into the repository.
openmetadata-ui/src/main/resources/ui/src/components/Database/SchemaTable/SchemaTable.component.tsx Replaces client-side tag filtering with server search state and expands filtered result trees.
openmetadata-ui/src/main/resources/ui/src/rest/tableAPI.ts Extends column search params with optional tag and glossary filter strings.
openmetadata-integration-tests/src/test/java/org/openmetadata/it/tests/TableResourceIT.java Adds backend tests for tag, glossary, derived tag, AND, and nested filtering behavior.
openmetadata-ui/src/main/resources/ui/src/components/Database/SchemaTable/SchemaTable.test.tsx Adds UI coverage for sourcing filter options from the full table column list.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
  participant UI as SchemaTable UI
  participant API as TableResource columns/search
  participant Repo as TableRepository
  participant Tags as tag usage and derived tags

  UI->>API: q, limit, offset, tags, glossaryTerms
  API->>Repo: ColumnTagFilter
  Repo->>Tags: load direct column tags
  Repo->>Tags: load derived tags
  Repo->>Repo: prune matching column tree
  Repo-->>API: TableColumnList with paging
  API-->>UI: filtered columns
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
  participant UI as SchemaTable UI
  participant API as TableResource columns/search
  participant Repo as TableRepository
  participant Tags as tag usage and derived tags

  UI->>API: q, limit, offset, tags, glossaryTerms
  API->>Repo: ColumnTagFilter
  Repo->>Tags: load direct column tags
  Repo->>Tags: load derived tags
  Repo->>Repo: prune matching column tree
  Repo-->>API: TableColumnList with paging
  API-->>UI: filtered columns
Loading

Reviews (1): Last reviewed commit: "fix(table): server-side column tag filte..." | Re-trigger Greptile

Greptile also left 3 inline comments on this PR.

Context used:

  • Context used - CLAUDE.md (source)
  • Context used - openmetadata-ui-core-components/CLAUDE.md (source)

…29324)

* fix(table): server-side column tag filter across all pages (#25063)

Column tag filtering ran client-side on the loaded page only, so columns
matching a tag on a later page stayed hidden once columns paginate
server-side. Push the filter down to the same layer as pagination.

Backend: add tags/glossaryTerms query params to the existing
/columns/search endpoints (matching the /columns/grid vocabulary) and
filter the full matching column set before sort/pagination in
searchTableColumnsInternal. Matching uses a single tag_usage prefix
lookup (getTagsByPrefix) instead of hydrating tags onto every column.

Frontend: route the SchemaTable tag/glossary dropdown through the search
call, reset to page 1 on change, drop the client-side onFilter, and
source the dropdown options from the full table columns so every tag is
selectable regardless of page.

* fix(table): update delegating overloads and TagSource import for tag filter

The shorter searchTableColumns* overloads still called the new arity
without the filterTagFQNs argument (openmetadata-service compile failure),
and the IT used the wrong TagSource package. Pass null through the
delegators and import the nested TagLabel.TagSource.

* fix(table): match column tag filter to UI tag set (derived + certification tags)

filterColumnsByTags resolved column tags via getTagsByPrefix, which returns
only direct tag_usage rows and strips certification-classification tags. The
column tag filter dropdown is built from column.tags (direct + glossary-derived
tags), so selecting a derived or certification tag returned zero matches.

Resolve column tags the same way the column list responses do: raw tag_usage
prefix query (no certification stripping) enriched with glossary-derived tags
via batchFetchDerivedTags. Derived-tag fetch failures degrade to direct tags.

Add an IT covering the glossaryTerms param, the derived classification tag, and
the by-id /columns/search endpoint.

* fix(table): AND tags and glossaryTerms column filters instead of OR

parseColumnTagFilters unioned tags and glossaryTerms into one set, so a column
matched if it had either filter's tag (OR). The UI exposes these as two
independent AntD column filters, which AntD combines with AND across columns —
matching the pre-existing client-side onFilter behavior. Selecting both a
classification tag and a glossary term therefore returned a superset.

Thread the two groups separately via a ColumnTagFilter holder and match
(any tag in tags) AND (any term in glossaryTerms), OR-ing within each group.

Add an IT asserting tags-only and glossaryTerms-only each match their columns
while the combination matches only the column carrying both.

* fix(ui): use null filteredValue when no column tag filter is active

Match the convention used by every sibling columns table (TopicSchema,
ContainerDataModel, FileColumnsTable, etc.) which pass filteredValue ?? null.
Passing an always-present array deviated from that pattern.

* fix(ui): use number-based pagination for tag-filtered columns

A tag/glossary filter uses the same offset-based /columns/search endpoint
(with paging.total) as text search, but isNumberBased was derived from
searchText only, so a tag-only filter fell back to cursor-based pagination
and could disable Next/Previous. Include hasTagFilter in the check.

* fix(table): preserve column tree nesting in server-side tag filter

Column tag/glossary filtering routes through /columns/search, which
previously flattened the column tree and returned matching nested columns
as top-level rows, dropping their ancestor path. Reconstruct a pruned tree
server-side instead: keep every matched column at its real depth together
with its ancestor chain, pruning siblings/children that do not match
(mirrors the UI's getFilteredTagsData, now applied across all pages).

The search path operates on a deep copy of the column tree so pruning and
field population never mutate the loaded entity object as a side effect of
a read.

Semantic change for reviewers: filtered `paging.total` now counts
top-level columns that contain a match rather than the flattened count of
matching columns. This is the correct unit once rows are nested, and it is
what the number-based pager renders.

UI:
- Expand all ancestors of matches while a search/tag filter is active so
  deep matches are visible at their level.
- Source the Tags/Glossary filter options from the union of the full table
  columns and the loaded page, so a tag applied to a column on the current
  page appears as a filter option immediately (the context table.columns is
  not refreshed on a column-level tag edit). getAllTags dedupes by tag.

Isolated in one commit so it can be reverted wholesale if reviewers prefer
the flattened behaviour.

(cherry picked from commit 3a66dae)
@sonika-shah
sonika-shah requested a review from a team as a code owner July 8, 2026 12:01
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

❌ PR checklist incomplete

This PR cannot be merged until the following are addressed on its linked issue:

  • No GitHub issue is linked. Link an issue in the Development section of the PR (or add Fixes #12345 to the description). For a same-org cross-repo issue, add Fixes open-metadata/<repo>#123 to the description.

The fields live on the linked issue in the Shipping project (open the issue → right sidebar → Projects). After you set them, re-run this check (or push a commit) — issue/project changes do not re-trigger it automatically.

Maintainers can bypass this check by adding the skip-pr-checks label.

@github-actions github-actions Bot added backend safe to test Add this label to run secure Github workflows on PRs labels Jul 8, 2026
Comment on lines 938 to +946

useEffect(() => {
setExpandedRowKeys((prev) => {
const autoKeys = getExpandAllKeysToDepth(tableColumns ?? [], 1);
const depth = searchText || hasTagFilter ? Number.MAX_SAFE_INTEGER : 1;
const autoKeys = getExpandAllKeysToDepth(tableColumns ?? [], depth);

return [...new Set([...autoKeys, ...prev])];
});
}, [tableColumns]);
}, [tableColumns, searchText, hasTagFilter]);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Filtered Views Expand Entire Trees

When a schema has a large or deeply nested struct column, any search or tag filter now expands every returned descendant by using Number.MAX_SAFE_INTEGER as the depth. A broad filter that returns a large nested root can generate thousands of expanded row keys and make the schema table slow or unresponsive even though only matched ancestor paths need to open.

@gitar-bot

gitar-bot Bot commented Jul 8, 2026

Copy link
Copy Markdown
Code Review ✅ Approved

Backports the server-side column tag filter fix to the 1.13 release, ensuring consistent search results across all paginated table pages. No issues found in this cherry-picked change.

Options

Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

The Python checkstyle failed.

Please run make py_format and py_format_check in the root of your repository and commit the changes to this PR.
You can also use pre-commit to automate the Python code formatting.

You can install the pre-commit hooks with make install_test precommit_install.

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

❌ UI Checkstyle Failed

❌ I18n Sync

Translation locale files are out of sync with en-us.json.

Affected files
  • openmetadata-ui/src/main/resources/ui/src/locale/languages/ar-sa.json
    • openmetadata-ui/src/main/resources/ui/src/locale/languages/de-de.json
    • openmetadata-ui/src/main/resources/ui/src/locale/languages/es-es.json
    • openmetadata-ui/src/main/resources/ui/src/locale/languages/fr-fr.json
    • openmetadata-ui/src/main/resources/ui/src/locale/languages/gl-es.json
    • openmetadata-ui/src/main/resources/ui/src/locale/languages/he-he.json
    • openmetadata-ui/src/main/resources/ui/src/locale/languages/ja-jp.json
    • openmetadata-ui/src/main/resources/ui/src/locale/languages/ko-kr.json
    • openmetadata-ui/src/main/resources/ui/src/locale/languages/mr-in.json
    • openmetadata-ui/src/main/resources/ui/src/locale/languages/nl-nl.json
    • openmetadata-ui/src/main/resources/ui/src/locale/languages/pr-pr.json
    • openmetadata-ui/src/main/resources/ui/src/locale/languages/pt-br.json
    • openmetadata-ui/src/main/resources/ui/src/locale/languages/pt-pt.json
    • openmetadata-ui/src/main/resources/ui/src/locale/languages/ru-ru.json
    • openmetadata-ui/src/main/resources/ui/src/locale/languages/th-th.json
    • openmetadata-ui/src/main/resources/ui/src/locale/languages/tr-tr.json
    • openmetadata-ui/src/main/resources/ui/src/locale/languages/zh-cn.json
    • openmetadata-ui/src/main/resources/ui/src/locale/languages/zh-tw.json

Fix locally (fast - only checks files changed in this branch):

make ui-checkstyle-changed

@sonarqubecloud

sonarqubecloud Bot commented Jul 8, 2026

Copy link
Copy Markdown

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

🟡 Playwright Results — all passed (12 flaky)

✅ 3674 passed · ❌ 0 failed · 🟡 12 flaky · ⏭️ 26 skipped

Shard Passed Failed Flaky Skipped
🟡 Shard 2 736 0 1 7
🟡 Shard 3 780 0 1 2
🟡 Shard 4 752 0 5 9
🟡 Shard 5 692 0 1 0
🟡 Shard 6 714 0 4 8
🟡 12 flaky test(s) (passed on retry)
  • Features/BulkEditEntity.spec.ts › Database Schema (shard 2, 1 retry)
  • Features/Permissions/GlossaryPermissions.spec.ts › Team-based permissions work correctly (shard 3, 1 retry)
  • Pages/CustomProperties.spec.ts › Set & Update all CP types on topic (shard 4, 1 retry)
  • Pages/CustomProperties.spec.ts › Timestamp (shard 4, 1 retry)
  • Pages/CustomProperties.spec.ts › Integer (shard 4, 1 retry)
  • Pages/Domains.spec.ts › Rename domain with tags and glossary terms preserves associations (shard 4, 1 retry)
  • Pages/Entity.spec.ts › Tag and Glossary Selector should close vice versa (shard 4, 1 retry)
  • Pages/Entity.spec.ts › Tier Add, Update and Remove (shard 5, 1 retry)
  • Pages/Glossary.spec.ts › Async Delete - single delete success (shard 6, 1 retry)
  • Pages/Lineage/LineageFilters.spec.ts › Verify lineage schema filter selection (shard 6, 1 retry)
  • Pages/Lineage/LineageRightPanel.spec.ts › Verify custom properties tab IS visible for supported type: searchIndex (shard 6, 1 retry)
  • Pages/Users.spec.ts › Permissions for table details page for Data Consumer (shard 6, 1 retry)

📦 Download artifacts

How to debug locally
# Download playwright-test-results-<shard> artifact and unzip
npx playwright show-trace path/to/trace.zip    # view trace

@sonika-shah
sonika-shah merged commit fd708bc into 1.13 Jul 8, 2026
45 of 70 checks passed
@sonika-shah
sonika-shah deleted the cherry-pick/29324-1.13 branch July 8, 2026 14:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend safe to test Add this label to run secure Github workflows on PRs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant