-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Add tables with authorization information to system.metadata #25907
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
Add tables with authorization information to system.metadata #25907
Conversation
a7392e0 to
2ff0516
Compare
2ff0516 to
d6e48b8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: put schema first, then tables and functions last?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I'd say All infix is redundant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: just combine maps instead of extracting this method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this method actually needed if all it does is delegating to listCatalogNames and listSchemas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it only does delegation BUT i would need to reuse this code in 3 places so I decided it is a good idea to actually extract it to a separated method
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the only test using blackhole catalog instead of memory_test, why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because I was not able to create a function in blackhole catalog so functions are tested using memory (and memory_test to check that table returns functions from different catalogs).
I can change this to also use memory
core/trino-main/src/main/java/io/trino/metadata/SystemSecurityMetadata.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: This javadocs does not say more that the method name. I would drop it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is odd to pass QualifiedTablePrefix as it is not a table. I mean if one passed schema_name parameter then you should return just that schema.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when schema name is passed then it is easy, but this is an optimization for situation when only catalog is known, instead of returning all schemas from all catalogs when can just get schemas for a specific catalog
d6e48b8 to
4bdaae9
Compare
4bdaae9 to
91ca0d7
Compare
91ca0d7 to
21bc502
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do you know what is domain 0?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't, I saw it in other places like
trino/core/trino-main/src/main/java/io/trino/connector/system/TableCommentSystemTable.java
Line 99 in 0f360f7
| Domain catalogDomain = constraint.getDomain(0, VARCHAR); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be nice to enumerate only functions that in constraint
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be nice to enumerate only schemas that in constraint
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be nice to enumerate only tables that in constraint
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should not use QualifiedTablePrefix here as table has no sense
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I believe it is a naming problem, I can copy code of QualifiedTablePrefix and name it QualifiedObjectPrefix but would that really make sense?
I may rename QualifiedTablePrefix to QualifiedObjectPrefix but I don't believe it is a big deal actually
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I believe it is a naming problem, I can copy code of QualifiedTablePrefix and name it QualifiedObjectPrefix but would that really make sense?
Yes. Please. Also you may want them to become records. So then there is not that much copying :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should not use QualifiedTablePrefix here as table has no sense
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
core/trino-main/src/main/java/io/trino/metadata/MetadataListing.java
Outdated
Show resolved
Hide resolved
core/trino-main/src/main/java/io/trino/metadata/SystemSecurityMetadata.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add test for VIEW and MATERIALIZED VIEW
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
VIEWS are covered in testViewColumnAccessControl, unfortunately there is no available connector in TestAccessControl that can create MATERIALIZED VIEWs.. So testing that is nor feasible right now
21bc502 to
b78b694
Compare
b78b694 to
e94721b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: extracting this as variable would make the code more readable. I need to go up and down to understand what 0 or 2 means.
core/trino-main/src/main/java/io/trino/connector/system/FunctionsAuthorization.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm.... maybe I was wrong. Now when I see this code I think we don't need to do it as it will be filtered anyway. When I requested filtering I wanted to avoid metadata calls, but once the call is done filtering more is not useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is better this way
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it unnecessarly complicates the logic here. I wanted to try eliminate the number of metadata calls. Filtering the set here does not improve the performance much and makes code here complex.
Please apply the same comment in other places.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ping
core/trino-main/src/main/java/io/trino/connector/system/SchemasAuthorization.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same comments. It could be a set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: extract variable for it too
core/trino-main/src/main/java/io/trino/connector/system/TablesAuthorization.java
Outdated
Show resolved
Hide resolved
core/trino-main/src/main/java/io/trino/metadata/DisabledSystemSecurityMetadata.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not record? So much boilerplate..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
throw?
e94721b to
d44f577
Compare
core/trino-main/src/main/java/io/trino/connector/system/FunctionsAuthorization.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it unnecessarly complicates the logic here. I wanted to try eliminate the number of metadata calls. Filtering the set here does not improve the performance much and makes code here complex.
Please apply the same comment in other places.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of passing QualifiedObjectPrefix, pass String catalog, Optional<String> schema, or some QualifiedSchemaPrefix
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry but I don't agree. I believe QualifiedObjectPrefix should be treated as generic and could be used in any scenario - can represent as short path as the one to catalog and as long as the one to table. Currently it is kind of hardcoded but I believe it can be reimplemented to support prefixes of any length if necessary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you need this if you use record. Same for getters.
d44f577 to
56e8649
Compare
56e8649 to
98e94f5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is wrong. See e9b931f
It is obvious that query on system catalog in Trino fails in this case. We care here about the catalog from constraint.getDomain(0, VARCHAR);.
However ownership is taken from SystemSecurityMetadata not a connector metadata so we could potentially skip that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ping
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no need to filter it. You already passed schema filter to getSchemasAuthorizationInfo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
schemaName is taken from the constraint, it can be empty, in that case getSchemasAuthorizationInfo will return all schemas so I still need to filter. In case it is provided there will be only 1 result so it is fine
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same with filtering. You already passed prefix to getTablesAuthorizationInfo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same answer, that filtering may not happen as the source of that value is in constraint TupleDomain which may be empty
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
requireNonNull(prefix, "prefix is null");
Optional<CatalogMetadata> catalog = getOptionalCatalogMetadata(session, prefix.getCatalogName());
if (catalog.filter(SYSTEM::equals).present) {
return systemSecurityMetadata.getSchemasAuthorizationInfo(session, prefix);
}
return ImmutableSet.of();
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is no need to write getters for record
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ehh i used copilot and it failed miserably.. (i did fail to as I didn't check what it did..)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ping
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is no need to assign things in record constructor.
You can call requireNonNull if you like
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, right, again copilot generated too much
98e94f5 to
00ee142
Compare
00ee142 to
44971df
Compare
44971df to
f3d1e5f
Compare
…25907 Trino supports ALTER (TABLE | FUNCTION | SCHEMA) SET AUTHORIZATION for quite some time. However there is no way to retrieve this information. This commit fixes this by introducing system.metadata.(tables | schemas | functions)_authorization tables.
f3d1e5f to
2df7e83
Compare
kokosing
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All good, the last part is to make sure that we use access control properly and we do have tests for the access control filterring.
|
|
||
|
|
||
| @Test | ||
| public void testSchemasAuthorization() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have a test where user has no access to a schema so they cannot see it in schemas_authorization?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check last assertion in this test
| } | ||
|
|
||
| @Test | ||
| public void testTablesAuthorization() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have a test where user has no access to a table/view so they cannot see it in tables_authorization?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check last assertion in this test
| } | ||
|
|
||
| @Test | ||
| public void testFunctionsAuthorization() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have a test where user has no access to a schema so they cannot see it in function_authorization?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check last assertion in this test
| try { | ||
| return doGetFunctionsAuthorization(session, constraint); | ||
| } | ||
| catch (RuntimeException exception) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if RuntimeException is already TrinoException?
| Map<String, Set<CatalogSchemaName>> groupedByCatalog = availableSchemas.stream() | ||
| .collect(groupingBy(CatalogSchemaName::getCatalogName, Collectors.toSet())); | ||
| ImmutableList.Builder<CatalogSchemaAuthorization> result = ImmutableList.builder(); | ||
| for (String catalog : groupedByCatalog.keySet()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see io.trino.security.AccessControl#filterSchemas called below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's good because it is not here :) It is called above inside io.trino.metadata.MetadataListing#listAllAvailableSchemas
| { | ||
| Domain catalogDomain = constraint.getDomain(0, VARCHAR); | ||
| Domain schemaDomain = constraint.getDomain(1, VARCHAR); | ||
| Set<CatalogSchemaName> availableSchemas = listAllAvailableSchemas( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this using io.trino.security.AccessControl#filterCatalogs or io.trino.security.AccessControl#filterSchemas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
both
| Session session, | ||
| TupleDomain<Integer> constraint) | ||
| { | ||
| Set<CatalogSchemaName> availableSchemas = listAllAvailableSchemas(session, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this using io.trino.security.AccessControl#filterCatalogs or io.trino.security.AccessControl#filterSchemas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
both
| ImmutableList.Builder<CatalogTableAuthorization> result = ImmutableList.builder(); | ||
| availableSchemas.forEach(catalogSchemaName -> { | ||
| QualifiedTablePrefix prefix = new QualifiedTablePrefix(catalogSchemaName.getCatalogName(), Optional.of(catalogSchemaName.getSchemaName()), tableName); | ||
| Set<SchemaTableName> accessibleNames = listTables(session, metadata, accessControl, prefix); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see io.trino.security.AccessControl#filterTables called here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good, it is called inside io.trino.metadata.MetadataListing#listTables
| public QualifiedSchemaPrefix(String catalogName, Optional<String> schemaName) | ||
| { | ||
| this.catalogName = checkCatalogName(catalogName); | ||
| this.schemaName = schemaName; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: no need to assign anything here :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ping
…25907 Trino supports ALTER (TABLE | FUNCTION | SCHEMA) SET AUTHORIZATION for quite some time. However there is no way to retrieve this information. This commit fixes this by introducing system.metadata.(tables | schemas | functions)_authorization tables.
2df7e83 to
56f5b80
Compare
|
Thank you! |
…25907 Trino supports ALTER (TABLE | FUNCTION | SCHEMA) SET AUTHORIZATION for quite some time. However there is no way to retrieve this information. This commit fixes this by introducing system.metadata.(tables | schemas | functions)_authorization tables.
Description
Add tables with authorization information to system.metadata #25907
Trino supports ALTER (TABLE | FUNCTION | SCHEMA) SET AUTHORIZATION for quite some time.
However there is no way to retrieve this information. This commit fixes this by
introducing system.metadata.(tables | schemas | functions)_authorization tables.
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: