Skip to content

feat(columns): add GET /columns/name/{fqn} endpoint and use it in ColumnDetailPanel#28087

Open
harsh-vador wants to merge 7 commits into
mainfrom
integrate-column-fqn-api
Open

feat(columns): add GET /columns/name/{fqn} endpoint and use it in ColumnDetailPanel#28087
harsh-vador wants to merge 7 commits into
mainfrom
integrate-column-fqn-api

Conversation

@harsh-vador
Copy link
Copy Markdown
Contributor

@harsh-vador harsh-vador commented May 13, 2026

Describe your changes:

Fixes 4082

Summary

  • Performance fix: ColumnDetailPanel previously fetched ALL columns of a table (up to 500) to find the one the user clicked, then discarded the rest. Now it fetches only the target column by its FQN.
  • New API endpoint: GET /v1/columns/name/{fqn}?entityType=table&fields=tags,customMetrics,extension,profile — symmetric with the existing PUT /v1/columns/name/{fqn} update endpoint.
  • Backend: Added getColumnByFQN to ColumnRepository (reuses existing findColumnInHierarchy, extractParentFQN). Added enrichSingleColumnFields to TableRepository (reuses existing private field-enrichment logic for tags, customMetrics, extension, profile). Supports both table and dashboardDataModel entity types.
  • Frontend: Replaced getTableColumnsByFQN(tableFqn, { limit: PAGE_SIZE_LARGE }) + .find() with getColumnByFQN(columnFqn) in ColumnDetailPanel.fetchColumnDetails. Removed the onColumnsUpdate side-effect (was populated as a bonus from the bulk fetch — callers can fetch independently if needed).

Type of change:

  • Bug fix
  • Improvement
  • New feature
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation

High-level design:

N/A — small change.

Tests:

Use cases covered

Unit tests

Backend integration tests

Ingestion integration tests

Playwright (UI) tests

Manual testing performed

UI screen recording / screenshots:

Not applicable.

Checklist:

  • I have read the CONTRIBUTING document.
  • My PR title is Fixes <issue-number>: <short explanation>
  • My PR is linked to a GitHub issue via Fixes #<issue-number> above.
  • I have commented on my code, particularly in hard-to-understand areas.
  • For JSON Schema changes: I updated the migration scripts or explained why it is not needed.
  • For UI changes: I attached a screen recording and/or screenshots above.
  • I have added tests (unit / integration / Playwright as applicable) and listed them above.

Summary by Gitar

  • Performance Optimization:
    • Refactored TableRepository to use batch fetching for customMetrics and columnExtensions in getTableColumnsInternal and searchTableColumnsInternal.
    • Eliminated N+1 query patterns by pre-fetching extensions and metrics for all columns instead of fetching per-column.
  • Backend Improvements:
    • Added batchFetchCustomMetricsByColumn and logic to map extension data via COLUMN_EXTENSION_JSON_SCHEMA for efficient batch processing.
    • Optimized populateEntityFieldTags invocation to avoid redundant execution when tags field is absent.
  • Playwright E2E tests:
    • Updated Table.spec.ts, SchemaTable.spec.ts, and Entity.spec.ts to expect the new GET /api/v1/columns/name/ endpoint instead of the old table-column bulk fetch.
    • Cleaned up redundant columnsProfileResponsePromise references in entity.ts util.

This will update automatically on new commits.

@harsh-vador harsh-vador self-assigned this May 13, 2026
@harsh-vador harsh-vador requested a review from a team as a code owner May 13, 2026 12:01
@harsh-vador harsh-vador added the safe to test Add this label to run secure Github workflows on PRs label May 13, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 13, 2026

Jest test Coverage

UI tests summary

Lines Statements Branches Functions
Coverage: 62%
62.64% (64858/103540) 43.4% (35384/81526) 46.18% (10407/22533)

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 13, 2026

🔴 Playwright Results — 8 failure(s), 15 flaky

✅ 4051 passed · ❌ 8 failed · 🟡 15 flaky · ⏭️ 98 skipped

Shard Passed Failed Flaky Skipped
🟡 Shard 1 298 0 1 4
🔴 Shard 2 742 8 6 20
🟡 Shard 3 779 0 2 7
🟡 Shard 4 787 0 3 18
🟡 Shard 5 708 0 1 41
🟡 Shard 6 737 0 2 8

Genuine Failures (failed on all attempts)

Features/DataQuality/IncidentManagerDateFilter.spec.ts › should show "Created At" as the default sort field label (shard 2)
Error: �[2mexpect(�[22m�[31mreceived�[39m�[2m).�[22mtoBe�[2m(�[22m�[32mexpected�[39m�[2m) // Object.is equality�[22m

Expected: �[32m200�[39m
Received: �[31m400�[39m
Features/DataQuality/IncidentManagerDateFilter.spec.ts › should open sort field dropdown on click (shard 2)
Error: �[2mexpect(�[22m�[31mreceived�[39m�[2m).�[22mtoBe�[2m(�[22m�[32mexpected�[39m�[2m) // Object.is equality�[22m

Expected: �[32m200�[39m
Received: �[31m400�[39m
Features/DataQuality/IncidentManagerDateFilter.spec.ts › should switch to "Updated At" and call API with dateField=updatedAt (shard 2)
Error: �[2mexpect(�[22m�[31mreceived�[39m�[2m).�[22mtoBe�[2m(�[22m�[32mexpected�[39m�[2m) // Object.is equality�[22m

Expected: �[32m200�[39m
Received: �[31m400�[39m
Features/DataQuality/IncidentManagerDateFilter.spec.ts › should switch back to "Created at" and call API with dateField=timestamp (shard 2)
Error: �[2mexpect(�[22m�[31mreceived�[39m�[2m).�[22mtoBe�[2m(�[22m�[32mexpected�[39m�[2m) // Object.is equality�[22m

Expected: �[32m200�[39m
Received: �[31m400�[39m
Features/DataQuality/IncidentManagerDateFilter.spec.ts › should close sort dropdown after selecting an option (shard 2)
Error: �[2mexpect(�[22m�[31mreceived�[39m�[2m).�[22mtoBe�[2m(�[22m�[32mexpected�[39m�[2m) // Object.is equality�[22m

Expected: �[32m200�[39m
Received: �[31m400�[39m
Features/DataQuality/IncidentManagerDateFilter.spec.ts › Date picker shows placeholder by default on Incident Manager page (shard 2)
Error: �[2mexpect(�[22m�[31mreceived�[39m�[2m).�[22mtoBe�[2m(�[22m�[32mexpected�[39m�[2m) // Object.is equality�[22m

Expected: �[32m200�[39m
Received: �[31m400�[39m
Features/DataQuality/IncidentManagerDateFilter.spec.ts › Select and clear date range on Incident Manager page (shard 2)
Error: �[2mexpect(�[22m�[31mreceived�[39m�[2m).�[22mtoBe�[2m(�[22m�[32mexpected�[39m�[2m) // Object.is equality�[22m

Expected: �[32m200�[39m
Received: �[31m400�[39m
Features/IncidentManager.spec.ts › Complete Incident lifecycle with table owner (shard 2)
Error: Wait for incident pw_test_case_73b0badf to appear in Incident Manager

�[2mexpect(�[22m�[31mreceived�[39m�[2m).�[22mtoBe�[2m(�[22m�[32mexpected�[39m�[2m) // Object.is equality�[22m

Expected: �[32mtrue�[39m
Received: �[31mfalse�[39m

Call Log:
- Timeout 60000ms exceeded while waiting on the predicate
🟡 15 flaky test(s) (passed on retry)
  • Pages/Bots.spec.ts › Bots Page should work properly (shard 1, 1 retry)
  • Features/ActivityAPI.spec.ts › creates an activity event when tags are added (shard 2, 1 retry)
  • Features/Glossary/GlossaryWorkflow.spec.ts › should display correct status badge color and icon (shard 2, 1 retry)
  • Features/KnowledgeCenterList.spec.ts › Knowledge Center List - Test infinite scroll/pagination (shard 2, 1 retry)
  • Features/KnowledgeCenterTextEditor.spec.ts › Rich Text Editor - Text Formatting (shard 2, 1 retry)
  • Features/KnowledgeCenterTextEditor.spec.ts › Rich Text Editor - Text Formatting (shard 2, 1 retry)
  • Features/KnowledgeCenterTextEditor.spec.ts › Rich Text Editor - Text Formatting (shard 2, 1 retry)
  • Features/RTL.spec.ts › Verify Following widget functionality (shard 3, 1 retry)
  • Flow/PersonaFlow.spec.ts › Set default persona for team should work properly (shard 3, 1 retry)
  • Pages/CustomProperties.spec.ts › Should clear search and show all properties for apiCollection in right panel (shard 4, 1 retry)
  • Pages/DataContractsSemanticRules.spec.ts › Validate Description Rule Is_Not_Set (shard 4, 1 retry)
  • Pages/DomainAdvanced.spec.ts › Filter assets by domain from explore page (shard 4, 1 retry)
  • Pages/ExplorePageRightPanel_KnowledgeCenter.spec.ts › Should remove user owner for knowledgeCenter (shard 5, 1 retry)
  • Pages/Lineage/LineageFilters.spec.ts › Verify lineage schema filter selection (shard 6, 1 retry)
  • Pages/Tag.spec.ts › Verify Owner Add Delete (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

Comment thread openmetadata-ui/src/main/resources/ui/playwright/utils/entity.ts Outdated
@gitar-bot
Copy link
Copy Markdown

gitar-bot Bot commented May 15, 2026

Code Review ✅ Approved 3 resolved / 3 findings

Optimizes ColumnDetailPanel performance by introducing a targeted GET /columns/name/{fqn} endpoint, replacing inefficient bulk table column fetches. Resolved previous issues regarding field parameter matching, missing entity types, and removal of dead code.

✅ 3 resolved
Bug: fieldsParam.contains() matches substrings, causing false positives

📄 openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/TableRepository.java:2932-2941
In enrichSingleColumnFields, field checks use String.contains() on the raw comma-separated string (e.g., fieldsParam.contains("tags")). This can produce false positives: a field value like "customTags" would incorrectly trigger the "tags" branch. The rest of the codebase uses a parsed Fields object (backed by a Set) for exact matching. This should be split into a Set<String> first.

Bug: Frontend getColumnByFQN does not pass entityType from caller

📄 openmetadata-ui/src/main/resources/ui/src/components/Database/ColumnDetailPanel/ColumnDetailPanel.component.tsx:269-271 📄 openmetadata-ui/src/main/resources/ui/src/rest/tableAPI.ts:371
In ColumnDetailPanel.component.tsx, the call getColumnByFQN(targetFqn, { fields: '...' }) does not pass entityType. The getColumnByFQN helper in tableAPI.ts defaults entityType to 'table' via the spread { entityType: 'table', ...params }. This works for table columns but will silently fail for dashboardDataModel columns opened in the panel, since the component already has an entityType prop available but doesn't forward it.

Quality: Dead code: columnsProfileResponsePromise is always null

📄 openmetadata-ui/src/main/resources/ui/playwright/utils/entity.ts:1076 📄 openmetadata-ui/src/main/resources/ui/playwright/utils/entity.ts:1107-1109
At line 1076, columnsProfileResponsePromise is unconditionally set to null, making the conditional check at line 1107-1109 (if (columnsProfileResponsePromise) { await columnsProfileResponsePromise; }) dead code. The variable declaration, assignment, and the if-block should all be removed for clarity.

Options

Display: compact → Showing less information.

Comment with these commands to change:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@sonarqubecloud
Copy link
Copy Markdown

@sonarqubecloud
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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