Skip to content

Fixes #31515: include materialized views in PostgreSQL and Greenplum connectors - #31549

Merged
akashverma0786 merged 3 commits into
open-metadata:mainfrom
zerafachris:fix/postgres-greenplum-materialized-view-ingestion
Sep 10, 2026
Merged

Fixes #31515: include materialized views in PostgreSQL and Greenplum connectors#31549
akashverma0786 merged 3 commits into
open-metadata:mainfrom
zerafachris:fix/postgres-greenplum-materialized-view-ingestion

Conversation

@zerafachris

@zerafachris zerafachris commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Describe your changes:

Fixes #31515

The PostgreSQL and Greenplum ingestion connectors do not discover materialized views because two things were missing:

  1. RELKIND_MAP in common_pg_mappings.py had no 'm' entry, so the relkind value returned for materialized views had no mapping to TableType.MaterializedView.
  2. POSTGRES_GET_TABLE_NAMES and GREENPLUM_GET_TABLE_NAMES only filtered on relkind in ('r', 'p', 'f'), which excludes 'm' (materialized view) entirely.

I added "m": TableType.MaterializedView to RELKIND_MAP and extended both queries to include 'm' in the relkind filter. TableType.MaterializedView already exists in the generated schema (used by Snowflake, ClickHouse, BigQuery, and others), so no schema changes are needed.

Type of change:

  • Bug fix

High-level design:

N/A — small change.

The pg_class.relkind column uses 'm' for materialized views per the PostgreSQL catalog docs. The existing comment in both query files already listed m = materialized view but the filter never matched it.

Tests:

Use cases covered

  • PostgreSQL connector correctly discovers materialized views in a schema during ingestion.
  • Greenplum connector correctly discovers materialized views in a schema during ingestion.

Unit tests

  • I added unit tests for the new/changed logic.
  • Files added/updated: ingestion/tests/unit/topology/database/test_postgres.py
    • test_relkind_map_includes_materialized_view — asserts RELKIND_MAP['m'] == TableType.MaterializedView
    • test_postgres_get_table_names_includes_materialized_view_relkind — asserts POSTGRES_GET_TABLE_NAMES contains 'm'

Backend integration tests

  • Not applicable (no backend API changes).

Ingestion integration tests

  • Not applicable — covered by unit tests above; connector-level integration test would require a live Postgres instance with materialized views.

Playwright (UI) tests

  • Not applicable (no UI changes).

Manual testing performed

Verified by code inspection:

  1. Confirmed TableType.MaterializedView exists in metadata.generated.schema.entity.data.table.
  2. Confirmed RELKIND_MAP['m'] resolves to TableType.MaterializedView after change.
  3. Confirmed POSTGRES_GET_TABLE_NAMES now includes 'm' in the relkind in (...) filter.
  4. Confirmed GREENPLUM_GET_TABLE_NAMES now includes 'm' in the relkind in (...) filter.

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 #31515 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.
  • I have added a test that covers the exact scenario we are fixing.

AI-generated code — reviewed and validated against OSS contribution guidelines. Submitted by zerafachris.

Greptile Summary

This PR routes PostgreSQL and Greenplum materialized views through the existing view-discovery path and classifies them as MaterializedView.

  • Adds shared materialized-view discovery for PostgreSQL-compatible connectors.
  • Applies the behavior to PostgreSQL and Greenplum while preserving includeViews semantics.
  • Adds unit and PostgreSQL integration coverage for discovery, typing, columns, and fallback behavior.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
ingestion/src/metadata/ingestion/source/database/common_pg_mappings.py Adds the materialized-view relkind mapping and shared view-listing mixin with graceful fallback.
ingestion/src/metadata/ingestion/source/database/postgres/metadata.py Enables the shared materialized-view discovery path for PostgreSQL.
ingestion/src/metadata/ingestion/source/database/greenplum/metadata.py Enables PostgreSQL-compatible materialized-view discovery for Greenplum.
ingestion/tests/integration/postgres/test_metadata.py Verifies a real PostgreSQL materialized view is ingested with its type and columns.
ingestion/tests/unit/topology/database/test_postgres.py Covers materialized-view listing, failure fallback, and includeViews routing.
ingestion/tests/unit/topology/database/test_greenplum.py Covers Greenplum materialized-view listing and fallback when reflection is unsupported.

Reviews (8): Last reviewed commit: "Fix ci errors" | Re-trigger Greptile

Context used:

@zerafachris
zerafachris requested a review from a team as a code owner August 14, 2026 14:29
@github-actions

github-actions Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

❌ PR checklist incomplete

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

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

Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

@IceS2 IceS2 left a comment

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.

Hey @zerafachris,

Thanks for working on this.
There is one important issue with the current approach: POSTGRES_GET_TABLE_NAMES and GREENPLUM_GET_TABLE_NAMES are called from query_table_names_and_types(), which only runs when includeTables=true. Views are controlled separately through query_view_names_and_types() and includeViews.

This creates inverted behavior:

  • includeTables=false, includeViews=true → the materialized view is still missing.
  • includeTables=true, includeViews=false → the materialized view is ingested even though views are disabled.

Could you move materialized-view discovery to the view path instead?

  • Restore the PostgreSQL and Greenplum table-discovery queries.
  • Override query_view_names_and_types() to combine Inspector.get_view_names() as View with Inspector.get_materialized_view_names() as MaterializedView.

The current tests only check that a mapping or SQL string contains 'm', so they can pass while the configuration behavior is wrong. Please add regression coverage for these two cases:

  1. includeTables=false, includeViews=true → materialized view is emitted as MaterializedView.
  2. includeTables=true, includeViews=false → materialized view is not emitted.

PostgreSQL already has a testcontainer-based integration suite under ingestion/tests/integration/postgres/, so the first case can be covered against a real materialized view.
For Greenplum, a focused behavior test around query_view_names_and_types() would still be valuable.

@github-actions

Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

3 similar comments
@github-actions

Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

@github-actions

Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

@github-actions

Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

@zerafachris

Copy link
Copy Markdown
Contributor Author

Thanks for the detailed review @IceS2! You're absolutely right — the table-path approach created inverted behaviour.

I've reworked the fix across 5 commits on this branch:

Core change (moved to view path):

  • Reverted POSTGRES_GET_TABLE_NAMES and GREENPLUM_GET_TABLE_NAMES back to ('r', 'p', 'f') — materialized views no longer leak through the table query.
  • Added query_view_names_and_types() to both PostgresSource and GreenplumSource: combines inspector.get_view_names()View + inspector.get_materialized_view_names()MaterializedView. Both are only called when includeViews=True.

Tests added:

  1. test_query_view_names_and_types_includes_materialized_views — calls the method directly with mocked inspector; asserts regular view gets TableType.View and matview gets TableType.MaterializedView.
  2. test_matview_not_emitted_when_include_views_false — asserts POSTGRES_GET_TABLE_NAMES does not contain 'm', so includeTables=True, includeViews=False cannot emit a matview through the table path.

The existing test_relkind_map_includes_materialized_view is kept since the 'm' entry in RELKIND_MAP is still correct (provides consistent type resolution).

Prepared with AI assistance (Claude Code, Anthropic), reviewed for correctness before submission.

@github-actions

Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

zerafachris added a commit to zerafachris/OpenMetadata that referenced this pull request Aug 18, 2026
…iew_names_and_types

If get_materialized_view_names() raises (e.g. older Greenplum/Postgres server
without matview support, or a permission error), catch the exception, log a
warning, and return an empty matview list rather than propagating the error
and silently dropping all regular views for the schema.

Addresses Gitar review suggestion on PR open-metadata#31549.
zerafachris added a commit to zerafachris/OpenMetadata that referenced this pull request Aug 18, 2026
…view_names_and_types

If get_materialized_view_names() raises (e.g. Greenplum server version that
does not support matviews, or a permission error), catch the exception, log a
warning, and return an empty matview list rather than propagating the error
and silently dropping all regular views for the schema.

Addresses Gitar review suggestion on PR open-metadata#31549.
@zerafachris

Copy link
Copy Markdown
Contributor Author

Good catch — addressed in the latest two commits. Both PostgresSource.query_view_names_and_types and GreenplumSource.query_view_names_and_types now fetch the regular view list first (unconditionally), then attempt get_materialized_view_names() inside an except Exception guard that logs a warning and falls back to an empty list. A failure in the matview API can no longer suppress regular view discovery for the schema.

@github-actions

Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

1 similar comment
@github-actions

Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

@zerafachris

Copy link
Copy Markdown
Contributor Author

Thanks @IceS2 — great catch on the includeTables/includeViews inversion. Address pushed:

What changed:

  • Restored POSTGRES_GET_TABLE_NAMES and GREENPLUM_GET_TABLE_NAMES to relkind in ('r', 'p', 'f') — materialized views removed from the table path.
  • Added query_view_names_and_types() override in both PostgresSource and GreenplumSource: Inspector.get_view_names()TableType.View, Inspector.get_materialized_view_names()TableType.MaterializedView, with a try/except guard for Greenplum versions that may not support the latter.
  • Replaced the SQL-string assertion tests with behavioral tests:
    • test_query_view_names_and_types_returns_materialized_views — mocks the inspector, verifies both View and MaterializedView are returned.
    • test_query_table_names_excludes_materialized_views — verifies 'm' is absent from POSTGRES_GET_TABLE_NAMES.

Materialized views are now only discovered when includeViews=True, matching the expected configuration semantics.

@github-actions

Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

2 similar comments
@github-actions

Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

@github-actions

Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

@zerafachris

Copy link
Copy Markdown
Contributor Author

Applied make py_format (Black) to resolve the py-checkstyle CI failure — no logic changes, formatting only.

@IceS2
IceS2 requested a review from akashverma0786 August 28, 2026 10:18
@github-actions

Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

@akashverma0786 akashverma0786 added the safe to test Add this label to run secure Github workflows on PRs label Aug 29, 2026
@github-actions

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 removed the safe to test Add this label to run secure Github workflows on PRs label Aug 31, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

@akashverma0786 akashverma0786 added the safe to test Add this label to run secure Github workflows on PRs label Aug 31, 2026
…m connectors

Materialized views are now discovered through query_view_names_and_types()
(controlled by includeViews) instead of the table path (includeTables).
This fixes the inverted config behavior flagged in review:
- includeViews=false, includeTables=true → matviews were wrongly ingested
- includeViews=true, includeTables=false → matviews were silently missing

Changes:
- Add PgMatviewMixin to common_pg_mappings.py: overrides query_view_names_and_types
  to chain get_view_names() as View and get_materialized_view_names() as
  MaterializedView; guards against inspectors that lack get_materialized_view_names
- PostgresSource and GreenplumSource inherit PgMatviewMixin
- Restore POSTGRES_GET_TABLE_NAMES and GREENPLUM_GET_TABLE_NAMES to table-only
  filters (relkind ≠ 'm')
- Add behavioral unit tests for both connectors:
  - includeViews=true → matview emitted as MaterializedView
  - includeViews=false → matview NOT emitted (view path not called)
  - matview is absent from the table path regardless of includeTables
- Add integration test fixture in test_metadata.py for a real materialized view

Fixes: open-metadata#31515
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@zerafachris
zerafachris force-pushed the fix/postgres-greenplum-materialized-view-ingestion branch from df318d3 to dcb5fa5 Compare September 4, 2026 14:15
@zerafachris

Copy link
Copy Markdown
Contributor Author

Hi @IceS2 — thanks for the detailed review. All three points addressed in the rebased commit:

Inverted config behavior fixed: Materialized views are now discovered in query_view_names_and_types() (the view path, controlled by includeViews) via a new PgMatviewMixin in common_pg_mappings.py. The POSTGRES_GET_TABLE_NAMES and GREENPLUM_GET_TABLE_NAMES queries are restored to tables-only filters (relkind ≠ 'm'), so includeTables no longer governs materialized views.

Behavioral regression tests added:

  • includeViews=True → materialized view emitted as TableType.MaterializedView
  • includeViews=False → view path not called, materialized view absent
  • Materialized view absent from the table path regardless of includeTables
    (for both Postgres and Greenplum)

Integration test: test_metadata.py creates a real materialized view and asserts it appears as MaterializedView type in the ingested entity list.

PgMatviewMixin guards against inspectors that lack get_materialized_view_names() (logs a warning and returns an empty list), so Greenplum falls back gracefully if the dialect doesn't expose the method.

Branch rebased cleanly onto current main (squashed to one commit to eliminate the noisy merge-into-branch history).

Prepared with AI assistance (Claude Code, Anthropic), reviewed for correctness before submission.

@github-actions github-actions Bot removed the safe to test Add this label to run secure Github workflows on PRs label Sep 4, 2026
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

@akashverma0786 akashverma0786 added the safe to test Add this label to run secure Github workflows on PRs label Sep 5, 2026
@github-actions

github-actions Bot commented Sep 5, 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.

…ources

The rebase onto main replayed this branch's pre-open-metadata#31643 copies of
postgres/metadata.py and greenplum/metadata.py, which reverted the typing
modernisation main had already applied and reintroduced the `# noqa: UP035`,
`# noqa: UP045` and `# noqa: UP006` suppressions that came with it.

`ingestion/scripts/check_ruff_suppressions.py`, wired into `py_format_check`
by open-metadata#31643, forbids suppressing UP006/UP007/UP035/UP045, so py-checkstyle
failed with 10 violations across the two files.

Dropping the suppressions and letting `ruff check --fix` resolve the
underlying violations restores both files to main's content:

- `typing.Iterable` -> `collections.abc.Iterable`
- `Optional[X]` -> `X | None`
- `Tuple[...]` -> `tuple[...]`

Only type annotations and imports change; no executable statement is touched
and the materialized-view logic is untouched. Both files now differ from main
only by the PgMatviewMixin import and its position in the base class list.
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

@gitar-bot

gitar-bot Bot commented Sep 5, 2026

Copy link
Copy Markdown
Code Review ✅ Approved 1 resolved / 1 findings

Adds materialized view discovery to the PostgreSQL and Greenplum connectors by mapping relkind 'm' and updating view-path queries, addressing the matview lookup failure issue. No issues found.

✅ 1 resolved
Edge Case: Matview lookup failure drops all views for the schema

📄 ingestion/src/metadata/ingestion/source/database/greenplum/metadata.py:129-135 📄 ingestion/src/metadata/ingestion/source/database/postgres/metadata.py:175-181
The override builds one combined list where the regular-view comprehension and the get_materialized_view_names comprehension are concatenated and evaluated eagerly. If get_materialized_view_names(schema_name) raises (e.g., on an older Greenplum server that lacks matview support, or on a permission error), the whole expression throws, the upstream try/except in get_tables_name_and_type sets view_iter = [], and regular views for that schema are silently dropped too — a regression versus the base implementation which never called the matview API. Fetch and guard the two lists separately so a matview failure cannot suppress regular views.

Options

Display: compact → Counting what did not apply, without listing it.

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

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Powered by Gitar — free for open source

@sonarqubecloud

sonarqubecloud Bot commented Sep 5, 2026

Copy link
Copy Markdown

@akashverma0786
akashverma0786 added this pull request to the merge queue Sep 8, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Sep 9, 2026
@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

🚦 Removed from the merge queue — failed_checks (2026-09-09T15:00:56Z)

Blocked the queue: playwright-summary

@akashverma0786
akashverma0786 added this pull request to the merge queue Sep 9, 2026
Merged via the queue into open-metadata:main with commit 46fda2d Sep 10, 2026
142 of 148 checks passed
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.

PostgreSQL and Greenplum connectors do not discover materialized views with SQLAlchemy 2.x

3 participants