Skip to content

Conversation

homar
Copy link
Member

@homar homar commented Oct 10, 2025

Description

There are several things in this PR:

  1. Making metadata.catalogs return all catalogs (included those that didn't load correctly), together with the their status
  2. Adding a test documenting behaviour of catalogs when there is an issue with loading them
  3. Allowing dropping a catalog that was not loaded correctly

Additional context and related issues

Release notes

( ) This is not user-visible or is docs only, and no release notes are required.
( ) Release notes are required. Please propose a release note for me.
(x) Release notes are required, with the following suggested text:

## Section
* Allow to drop catalog that failed to load correctly
* Make metadata.catalogs return all catalogs 

Summary by Sourcery

Track and surface the load state of catalogs by replacing the boolean loaded flag with a CatalogStatus enum, exposing a new state column in system.metadata.catalogs, and adding end-to-end tests for healthy and failed dynamic catalogs.

New Features:

  • Introduce a CatalogStatus enum (LOADED, FAILED_TO_LOAD) to represent catalog load state
  • Add a state column to the system.metadata.catalogs table to report each catalog’s load status
  • Add TestDynamicCatalogs to validate dynamic catalog creation, loading failures, and drops

Enhancements:

  • Replace boolean loaded flags with CatalogStatus across Catalog, CatalogInfo, CatalogConnector, transaction manager, and metadata components
  • Update TestSystemMetadataCatalogTable to assert on the new state column
  • Refine TestConfiguredFeatures to use unified row-based assertions for connector listing

Tests:

  • Updated TestSystemMetadataCatalogTable and TestConfiguredFeatures for catalog state changes
  • Added comprehensive tests in TestDynamicCatalogs for both healthy and unhealthy catalog scenarios

@cla-bot cla-bot bot added the cla-signed label Oct 10, 2025
Copy link

sourcery-ai bot commented Oct 10, 2025

Reviewer's Guide

Introduce explicit catalog load statuses by replacing the boolean loaded flag with a CatalogStatus enum and exposing LOADED/FAILED_TO_LOAD in system.metadata.catalogs, updating related metadata operations and tests accordingly.

Entity relationship diagram for updated Catalog and CatalogInfo data types

erDiagram
    Catalog {
        CatalogName catalogName
        CatalogHandle catalogHandle
        ConnectorName connectorName
        ConnectorServices catalogConnector
        ConnectorServices informationSchemaConnector
        ConnectorServices systemConnector
        CatalogStatus catalogStatus
    }
    CatalogInfo {
        string catalogName
        CatalogHandle catalogHandle
        ConnectorName connectorName
        CatalogStatus catalogStatus
    }
    CatalogStatus {
        enum: LOADED, FAILED_TO_LOAD
    }
    CatalogStatus ||--o| Catalog : "catalogStatus"
    CatalogStatus ||--o| CatalogInfo : "catalogStatus"
    Catalog ||--o| CatalogInfo : "catalogHandle"
    Catalog ||--o| CatalogInfo : "connectorName"
Loading

Class diagram for Catalog, CatalogInfo, and CatalogStatus changes

classDiagram
    class Catalog {
        -CatalogName catalogName
        -CatalogHandle catalogHandle
        -ConnectorName connectorName
        -ConnectorServices catalogConnector
        -ConnectorServices informationSchemaConnector
        -ConnectorServices systemConnector
        -CatalogStatus catalogStatus
        +CatalogStatus getCatalogStatus()
        +boolean isFailed()
        +static Catalog failedCatalog(...)
    }
    class CatalogInfo {
        -String catalogName
        -CatalogHandle catalogHandle
        -ConnectorName connectorName
        -CatalogStatus catalogStatus
    }
    class CatalogStatus {
        <<enum>>
        LOADED
        FAILED_TO_LOAD
    }
    Catalog --> CatalogStatus
    CatalogInfo --> CatalogStatus
Loading

File-Level Changes

Change Details Files
Replace boolean loaded flag with CatalogStatus enum across catalog model and metadata layers
  • add CatalogStatus enum with LOADED and FAILED_TO_LOAD values
  • update Catalog constructors and getCatalogStatus() in Catalog
  • update CatalogInfo record and mapping in transaction and metadata managers
  • update CatalogConnector to pass LOADED status
core/trino-main/src/main/java/io/trino/metadata/CatalogStatus.java
core/trino-main/src/main/java/io/trino/metadata/Catalog.java
core/trino-main/src/main/java/io/trino/metadata/CatalogInfo.java
core/trino-main/src/main/java/io/trino/connector/CatalogConnector.java
core/trino-main/src/main/java/io/trino/transaction/InMemoryTransactionManager.java
core/trino-main/src/main/java/io/trino/metadata/MetadataManager.java
core/trino-main/src/main/java/io/trino/metadata/Metadata.java
Expose catalog status in system.metadata.catalogs table
  • add state column to CatalogSystemTable schema
  • remove filter that excluded failed catalogs
  • include catalogStatus value in each row
core/trino-main/src/main/java/io/trino/connector/system/CatalogSystemTable.java
core/trino-main/src/main/java/io/trino/metadata/Metadata.java
Restrict metadata operations to loaded catalogs on drop
  • check catalogStatus == LOADED before retrieving write metadata in dropCatalog
core/trino-main/src/main/java/io/trino/metadata/MetadataManager.java
Update and add tests for catalog status reporting and dynamic catalogs
  • enhance TestSystemMetadataCatalogTable to assert LOADED/FAILED_TO_LOAD states and broken-catalog scenario
  • refactor TestConfiguredFeatures to use new assertion style for connector names
  • add TestDynamicCatalogs for healthy and unhealthy dynamic catalog workflows
testing/trino-tests/src/test/java/io/trino/connector/system/TestSystemMetadataCatalogTable.java
testing/trino-product-tests/src/main/java/io/trino/tests/product/TestConfiguredFeatures.java
testing/trino-tests/src/test/java/io/trino/connector/TestDynamicCatalogs.java

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@homar homar force-pushed the homar/fix_dynamic_catalogs branch 2 times, most recently from 307c31a to 74678d0 Compare October 11, 2025 17:38
@homar homar marked this pull request as ready for review October 12, 2025 17:26
@homar homar requested review from findepi and kokosing October 12, 2025 17:26
Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes - here's some feedback:

  • Add explicit ORDER BY clauses in system.metadata.catalogs queries in tests to ensure deterministic row ordering and avoid flakiness.
  • Update the Javadoc for Metadata.listCatalogs to clearly state that it returns all catalogs along with their load status (LOADED or FAILED_TO_LOAD).
  • Consider aligning the naming of the "state" column with the CatalogStatus enum (e.g., rename to "status") for consistency across code and metadata schemas.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Add explicit ORDER BY clauses in system.metadata.catalogs queries in tests to ensure deterministic row ordering and avoid flakiness.
- Update the Javadoc for Metadata.listCatalogs to clearly state that it returns all catalogs along with their load status (LOADED or FAILED_TO_LOAD).
- Consider aligning the naming of the "state" column with the CatalogStatus enum (e.g., rename to "status") for consistency across code and metadata schemas.

## Individual Comments

### Comment 1
<location> `core/trino-main/src/main/java/io/trino/metadata/Metadata.java:482` </location>
<code_context>
     Optional<CatalogHandle> getCatalogHandle(Session session, String catalogName);

     /**
-     * Lists all defined catalogs (both loaded properly and failed ones).
+     * Gets all the loaded catalogs
      */
     List<CatalogInfo> listCatalogs(Session session);
</code_context>

<issue_to_address>
**suggestion:** The new comment may be misleading about the method's behavior.

The new comment does not match the method's actual behavior, which returns all catalogs, including those that failed. Please update the comment to accurately describe the method's output.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@homar homar force-pushed the homar/fix_dynamic_catalogs branch from 74678d0 to acc1cb0 Compare October 12, 2025 18:00
informationSchemaConnector,
systemConnector,
true);
systemConnector);
Copy link
Member

Choose a reason for hiding this comment

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

Revert "metadata.catalogs should only list loaded catalogs"

This reverts commit a7d9d91.

Please include rationale for the revert

Comment on lines 45 to 46
Session session = testSessionBuilder().build();
QueryRunner queryRunner = DistributedQueryRunner.builder(session)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Session session = testSessionBuilder().build();
QueryRunner queryRunner = DistributedQueryRunner.builder(session)
QueryRunner queryRunner = DistributedQueryRunner.builder(testSession())

}

@Test
public void testHealthyCatalog()
Copy link
Member

Choose a reason for hiding this comment

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

testNewHealthyCatalog

}

@Test
public void testUnhealthyCatalog()
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
public void testUnhealthyCatalog()
public void testNewUnhealthyCatalog()

connectorServicesProvider.loadInitialCatalogs();

assertQuery("SHOW CATALOGS", "VALUES 'healthy_catalog', '" + catalogName + "', 'system'");
assertQueryFails("CREATE TABLE %s.default.test_table (age INT)".formatted(catalogName), ".*Catalog '%s' failed to initialize and is disabled.*".formatted(catalogName));
Copy link
Member

Choose a reason for hiding this comment

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

assert what's the error for a SELECT statement over such catalog

Comment on lines 18 to 19
LOADED,
FAILED_TO_LOAD,
Copy link
Member

Choose a reason for hiding this comment

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

"loaded catalogs" inuititively means those loaded into the system, aka. defined

maybe we can call these options: OPERATIONAL / FAILING

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure I can try. cc @kokosing

}

@Test
public void testCatalogTableShowsCorrectStatusWhenCatalogIsNotLoadedCorrectly()
Copy link
Member

Choose a reason for hiding this comment

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

testCatalogNotLoadedCorrectly ?

}

@Test
public void testCatalogTableShowsCorrectStatusWhenCatalogsAreLoadedCorrectly()
Copy link
Member

Choose a reason for hiding this comment

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

testNewCatalog / testNewCatalogStatus?

Optional<CatalogMetadata> catalogMetadata = Optional.empty();
if (catalogManager.getCatalog(catalog).isPresent()) {
Optional<Catalog> optionalCatalog = catalogManager.getCatalog(catalog);
if (optionalCatalog.isPresent() && optionalCatalog.get().getCatalogStatus() == LOADED) {
Copy link
Member

Choose a reason for hiding this comment

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

What we do here:

  1. we first read from catalogManager
    1.1. we conditionally re-read something in getCatalogMetadataForWrite
  2. we then issue unconditional drop in catalogManager
  3. depending on the status if the (1) read, systemSecurityMetadata.catalogDropped is called

What we want to guarantee is that:
if a catalog ceased to exist, systemSecurityMetadata.catalogDropped has been called

Which may not be the case when e.g.

  • (pre-existing) catalog did not exist and was created between (1) and (2)
  • (new) catalog did exist but unhealthy and was fixed between (1) and (2)

It's pre-existing problem. Let's file a follow-up issue and link TODO comment here.

assertQueryFails("CREATE CATALOG %s USING memory WITH (\"memory.max-data-per-node\" = '128MB')".formatted(catalogName), ".*Catalog '%s' already exists.*".formatted(catalogName));

catalogManager.dropCatalog(new CatalogName(catalogName), false);
assertUpdate("DROP CATALOG " + catalogName);
Copy link
Member

Choose a reason for hiding this comment

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

this assert the DROP did not fail
assert also it's indeed gone.

@homar homar force-pushed the homar/fix_dynamic_catalogs branch from acc1cb0 to 3b5769e Compare October 13, 2025 09:29
@homar homar force-pushed the homar/fix_dynamic_catalogs branch 2 times, most recently from d759251 to b6f1b79 Compare October 13, 2025 13:22
@homar homar requested a review from findepi October 13, 2025 13:22
@homar homar force-pushed the homar/fix_dynamic_catalogs branch from b6f1b79 to 5da1431 Compare October 13, 2025 14:08
@homar homar force-pushed the homar/fix_dynamic_catalogs branch from 5da1431 to f76079b Compare October 13, 2025 15:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

2 participants