Skip to content

Extend syntax for Dynamic Catalogs #22188

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

ssheikin
Copy link
Contributor

@ssheikin ssheikin commented May 29, 2024

Description

  • Add ALTER CATALOG commands to change name, properties and owner with security checks
    RENAME, SET PROPERTIES implemented
    catalog owner is not supported yet.
    catalog comment is not supported yet.

Additional context and related issues

Trino epic #12709

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
* Add support for ALTER CATALOG RENAME statement. ({issue}`22188`)
* Add support for ALTER CATALOG SET PROPERTIES statement. ({issue}`22188`) 

@cla-bot cla-bot bot added the cla-signed label May 29, 2024
@ssheikin ssheikin changed the title Improve usability of Dynamic Catologs Extend syntax for Dynamic Catologs May 29, 2024
@ssheikin ssheikin changed the title Extend syntax for Dynamic Catologs Extend syntax for Dynamic Catalogs May 29, 2024
@ssheikin
Copy link
Contributor Author

ssheikin commented Jun 3, 2024

@martint @dain @kokosing @nineinchnick @SemionPar please review

@@ -155,6 +162,7 @@ statement
| EXPLAIN ANALYZE VERBOSE? statement #explainAnalyze
| SHOW CREATE TABLE qualifiedName #showCreateTable
| SHOW CREATE SCHEMA qualifiedName #showCreateSchema
| SHOW CREATE CATALOG identifier #showCreateCatalog
Copy link
Member

Choose a reason for hiding this comment

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

The current implementation exposes all properties even if it's marked as @ConfigHidden or @ConfigSecuritySensitive. I think we should hide or redact such properties.

Copy link
Member

Choose a reason for hiding this comment

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

@ssheikin could you maybe extract SHOW CREATE CATALOG to a separate PR? @martint would that help with getting the less controversial parts merged sooner?

Copy link
Member

Choose a reason for hiding this comment

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

I have removed SHOW CREATE CATALOG from this PR. It should be possible to re-add it once the following are merged:

I'm not sure if we want to introduce CREATE CATALOG LIKE (at least not at this stage). One question that comes to mind is how to define access rules for it. According to the SQL specification for CREATE TABLE LIKE:

If a <like clause> is contained in a <table definition>, then the applicable privileges for A shall include
SELECT privilege on the table identified in the <like clause>.

The issue is that we don’t have a SELECT privilege for catalogs.
I’m also not aware of any databases that provide CREATE ... LIKE functionality for anything other than tables. This makes it difficult to infer whether there’s a common approach we could adopt in this scenario.

Copy link

This pull request has gone a while without any activity. Tagging the Trino developer relations team: @bitsondatadev @colebow @mosabua

@github-actions github-actions bot added the stale label Jul 15, 2024
@mosabua
Copy link
Member

mosabua commented Jul 15, 2024

I am adding the stale-ignore label under the assumption that you are still driving this PR to completion @ssheikin

@mosabua mosabua added stale-ignore Use this label on PRs that should be ignored by the stale bot so they are not flagged or closed. and removed stale labels Jul 15, 2024
Comment on lines 57 to 61
Session session = stateMachine.getSession();

accessControl.checkCanRenameCatalog(session.toSecurityContext(), statement.getSource().getValue(), statement.getTarget().getValue());

catalogManager.renameCatalog(new CatalogName(statement.getSource().getValue()), new CatalogName(statement.getTarget().getValue()));
Copy link
Member

Choose a reason for hiding this comment

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

Did you omit lowercase intentionally?

trino> CREATE CATALOG test USING memory;
CREATE CATALOG
trino> ALTER CATALOG test RENAME TO TEST;
RENAME CATALOG
trino> show catalogs;
 Catalog
---------
 TEST
 memory
 system
 tpch
(4 rows)

Copy link
Member

Choose a reason for hiding this comment

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

I think it was unintentional. I updated it to match how other catalog statements work.

@hashhar hashhar mentioned this pull request Jul 31, 2024
21 tasks
@piotrrzysko piotrrzysko force-pushed the ssheikin/90/trino/dc branch 2 times, most recently from 93954a1 to 315ed4d Compare January 6, 2025 20:09
@piotrrzysko
Copy link
Member

Current status of this PR: it will no longer include SHOW CREATE CATALOG and CREATE CATALOG LIKE. The former will likely be re-added once redacting security-sensitive information (#24563) is merged. The latter probably needs more discussion. I don’t have permissions to update the PR description. Could one of the maintainers or @ssheikin update it?

@kokosing
Copy link
Member

kokosing commented Jan 7, 2025

I have updated the description

Comment on lines 308 to 322
createCatalogLikeInternal(catalogName, newCatalogName, ImmutableMap.of());
catalogStore.removeCatalog(catalogName);
activeCatalogs.remove(catalogName);
Copy link
Member

Choose a reason for hiding this comment

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

how do we ensure this is "transactional"?

Copy link
Member

Choose a reason for hiding this comment

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

There was a bug that caused activeCatalogs to be updated even when persisting the catalog specification failed. I’ve fixed this.

Currently, I see one problematic scenario:

  1. catalogStore.addOrReplaceCatalog(newCatalog) succeeds.
  2. catalogStore.removeCatalog(oldCatalog) fails.

If this happens, we end up with two catalogs, and the only way to recover is to manually DROP the old one.

To address this, we might need to extend the SPI by adding CatalogStore.replace(oldCatalog, newCatalog) and requiring implementations to perform this operation transactionally.

Copy link
Member

Choose a reason for hiding this comment

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

the replace would probably also allow implementing ALTER CATALOG ... RENAME properly instead of as DROP + CREATE.

Let's skip for now and discuss it later.

@hashhar
Copy link
Member

hashhar commented Jan 15, 2025

@martint @kasiafi do you want to take a look?

The original concerns were addressed by removing both SHOW CREATE CATALOG AND CREATE CATALOG LIKE....

/**
* Check if identity is allowed to set properties to the specified catalog.
*
* @throws AccessDeniedException if not allowed
Copy link
Member

Choose a reason for hiding this comment

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

If any of the listed properties are not allowed?

Copy link
Member

Choose a reason for hiding this comment

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

I see that this follows the pattern used for other methods in this file. I believe the idea is that this exception is thrown when accessing a given resource is not allowed.

throw new TrinoException(ALREADY_EXISTS, format("Catalog '%s' already exists", newCatalogName));
}

createCatalogLikeInternal(catalogName, newCatalogName, ImmutableMap.of());
Copy link
Member

Choose a reason for hiding this comment

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

Why is rename modeled as "clone the catalog into a new one, drop the old one" vs adding proper support for renaming catalogs? I'm concerned about the impact of any state that needs to be dropped and re-created, caches, etc., that would otherwise not be necessary to manage with a proper rename.

Copy link
Member

Choose a reason for hiding this comment

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

Renaming requires the following steps:

  1. Creating a new connector instance, with the catalog name passed to ConnectorFactory::create.
  2. Updating in-memory data structures in CoordinatorDynamicCatalogManager (activeCatalogs and allCatalogs).
  3. Persisting the updated catalog name and version via CatalogStore.
  4. Marking the old catalog as inactive and eventually pruning it.

It looks like this is exactly what clone and drop do. Do you think there's a less invasive way to implement rename?

Copy link
Member

Choose a reason for hiding this comment

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

Got it. It's not ideal, though. It shouldn't be necessary to re-create the catalog just to give it a new name.

I guess the underlying problem is that ConnectorFactory::create takes a name. We should look into (for a future improvement) what it would take to decouple the instance from its name so that the name is just an entry in the catalog maps.

Copy link
Member

@piotrrzysko piotrrzysko left a comment

Choose a reason for hiding this comment

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

I've addressed all the comments. Along the way, I discovered two bugs that should now be fixed:

  1. Previously, duplicated properties in ALTER CATALOG ... SET PROPERTIES caused an exception that could expose potentially security-sensitive property values. Now, only the last value is used, matching the behavior of CREATE CATALOG and ALTER TABLE ... SET PROPERTIES.
  2. The in-memory state (activeCatalogs) was being updated even when persisting the catalog specification failed. Now, it is updated only when the corresponding CatalogStore operation succeeds.

/**
* Check if identity is allowed to set properties to the specified catalog.
*
* @throws AccessDeniedException if not allowed
Copy link
Member

Choose a reason for hiding this comment

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

I see that this follows the pattern used for other methods in this file. I believe the idea is that this exception is thrown when accessing a given resource is not allowed.

throw new TrinoException(ALREADY_EXISTS, format("Catalog '%s' already exists", newCatalogName));
}

createCatalogLikeInternal(catalogName, newCatalogName, ImmutableMap.of());
Copy link
Member

Choose a reason for hiding this comment

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

Renaming requires the following steps:

  1. Creating a new connector instance, with the catalog name passed to ConnectorFactory::create.
  2. Updating in-memory data structures in CoordinatorDynamicCatalogManager (activeCatalogs and allCatalogs).
  3. Persisting the updated catalog name and version via CatalogStore.
  4. Marking the old catalog as inactive and eventually pruning it.

It looks like this is exactly what clone and drop do. Do you think there's a less invasive way to implement rename?

}
}

private CatalogConnector createCatalogLikeInternal(CatalogName oldCatalogName, CatalogName catalogName, Map<String, Optional<String>> properties)
Copy link
Member

Choose a reason for hiding this comment

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

I've inlined this. The logic for rename and alter differs slightly, and I believe it's easier to follow the flow of these operations when all the steps are in one place.

Comment on lines 308 to 322
createCatalogLikeInternal(catalogName, newCatalogName, ImmutableMap.of());
catalogStore.removeCatalog(catalogName);
activeCatalogs.remove(catalogName);
Copy link
Member

Choose a reason for hiding this comment

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

There was a bug that caused activeCatalogs to be updated even when persisting the catalog specification failed. I’ve fixed this.

Currently, I see one problematic scenario:

  1. catalogStore.addOrReplaceCatalog(newCatalog) succeeds.
  2. catalogStore.removeCatalog(oldCatalog) fails.

If this happens, we end up with two catalogs, and the only way to recover is to manually DROP the old one.

To address this, we might need to extend the SPI by adding CatalogStore.replace(oldCatalog, newCatalog) and requiring implementations to perform this operation transactionally.

@piotrrzysko piotrrzysko force-pushed the ssheikin/90/trino/dc branch 2 times, most recently from db7c4b6 to c3cc7db Compare January 21, 2025 14:10
@piotrrzysko piotrrzysko requested a review from martint January 21, 2025 15:22
Copy link
Member

@martint martint left a comment

Choose a reason for hiding this comment

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

A couple of minor comments.

Also, you should squash the first and second commits. Otherwise, the first commit is "broken", since there's no handling of the new statements in the analyzer. Either, it should fail with a proper error saying "RENAME not yet supported" or implement the functionality.

@piotrrzysko
Copy link
Member

I've addressed the latest comments.

@piotrrzysko piotrrzysko requested a review from martint February 2, 2025 20:36
ssheikin and others added 2 commits February 5, 2025 13:44
Co-authored-by: Jan Waś <[email protected]>
- RENAME
- SET PROPERTIES
@piotrrzysko
Copy link
Member

@martint Could you please take a look? I addressed your recent comments.

@mosabua
Copy link
Member

mosabua commented Feb 11, 2025

This will also need docs before merge. Please work with @jhlodin and myself to get that added here or in a separate PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla-signed stale-ignore Use this label on PRs that should be ignored by the stale bot so they are not flagged or closed. syntax-needs-review
Development

Successfully merging this pull request may close these issues.

8 participants