Skip to content
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

Accelerate system.metadata.table_comments with Iceberg Glue catalog #18517

Merged
merged 6 commits into from
Aug 8, 2023

Conversation

findepi
Copy link
Member

@findepi findepi commented Aug 3, 2023

With Glue, table listing already pulls a lot information about tables.
For Trino-managed Iceberg tables this is sufficient information to
answer system.metadata.table_comments queries, without having to fetch
Glue tables again, one-by-one. Trino-manged Iceberg tables keep table
comment up to date in Glue (along with additional information sufficient
to verify it's indeed up to date). The approach can be generalized to
Iceberg's own GlueCatalog later if the community is interested.

Builds on #18315

release notes

# Iceberg
* Improve performance of `system.metadata.table_comments` when querying Iceberg tabes
  backed by Glue Catalog.

findepi added 2 commits August 3, 2023 13:07
Apply whatever IntelliJ wants to have applied so that class reformat
doesn't change the code.
Left over from unoptimized implementation of
`testInformationSchemaColumns`.
@findepi findepi force-pushed the findepi/table-comments branch from 8a3ed54 to cca95db Compare August 3, 2023 11:09
@github-actions github-actions bot added the iceberg Iceberg connector label Aug 3, 2023
@findepi findepi force-pushed the findepi/table-comments branch from cca95db to ce1caf9 Compare August 3, 2023 14:31
{
if (prefix.getTable().isPresent()) {
// For single name referenced the default implementation is good enough
return ConnectorMetadata.super.streamRelationComments(session, prefix);
Copy link
Member

Choose a reason for hiding this comment

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

I'd personally prefer to continue passing the prefix's table down to the TrinoGlueCatalog implementation and have it handle this case. It's the same number of API calls as going back to the super's implementation, but only because of caching.

Copy link
Member

Choose a reason for hiding this comment

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

Similarly, do we have a test that exercises the path where both schema and table are provided in the prefix?

Copy link
Member Author

Choose a reason for hiding this comment

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

Similarly, do we have a test that exercises the path where both schema and table are provided in the prefix?

adding test for this case, search for // Pointed lookup.

but only because of caching.

i didn't want to optimize this path as i haven't seen this in the wild.

I couldn't get rid of reliance on caching because of how GlueCatalog and GlueTableOperations interact, so even the optimized path had this unfortunate dependency on the cache.

i don't want to pass prefix's down to the TrinoGlueCatalog implementation, to save complexity at least here. the biggest downside of this approach is complexity. some of the complexity seems unavoidable...

Copy link
Member Author

Choose a reason for hiding this comment

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

i decided to go into opposite direction. see adjust iceberg to Fixup simplify streamRelationComments: take Optional<String> schemaName instead of SchemaTablePrefix commit. I don't think tablePrefix abstraction buys us anything, and it just pushes more complexity into connectors.

@@ -545,8 +545,7 @@ public void testSystemMetadataTableComments()
session,
"SELECT * FROM system.metadata.table_comments WHERE schema_name = CURRENT_SCHEMA AND table_name LIKE 'test_select_s_m_t_comments%'",
ImmutableMultiset.<GlueMetastoreMethod>builder()
.addCopies(GET_TABLES, 3)
.addCopies(GET_TABLE, tables * 2)
.addCopies(GET_TABLES, 1)
Copy link
Member Author

Choose a reason for hiding this comment

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

- .addCopies(GET_TABLES, 3)
- .addCopies(GET_TABLE, tables * 2)
+ .addCopies(GET_TABLES, 1)

looks like a nice change. thank you @ebyhr for your hint #18315 (review)
cc @kokosing @atanasenko @alexjo2144

findepi added 2 commits August 4, 2023 12:55
By general rule, the engine should not call plugins asking for
information that it can derive on its own. Here, engine should not need
to call the plugin to filter empty list of entities.
@findepi findepi force-pushed the findepi/table-comments branch from ce1caf9 to 0153dfb Compare August 4, 2023 11:39
@findepi
Copy link
Member Author

findepi commented Aug 4, 2023

TrinoGlueCatalog cleanup extracted to #18543.

@findepi findepi force-pushed the findepi/table-comments branch 2 times, most recently from 503b8ff to b633c4e Compare August 4, 2023 15:16
}
}
else {
List<RelationCommentMetadata> relationComments = metadata.listRelationComments(
Copy link
Member

Choose a reason for hiding this comment

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

Should probably run access control checks again here in case the connector does not behave well in filtering out tables that should not be accessible.

I also saw there's an access control filterColumns method, do we need to be applying that here?

Copy link
Member Author

Choose a reason for hiding this comment

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

I also saw there's an access control filterColumns method, do we need to be applying that here?

i don't think it's applicable.

Should probably run access control checks again here in case the connector does not behave well in filtering out tables that should not be accessible.

if we want that, we would need to let the connector declare whether AC was consulted or not. otherwise we would be calling AC twice, which is redundant, and considerable cost (in case of many relations).

i had this in this PR, see before Fixup simplify streamRelationComments: require relationFilter to be applied commit. i didn't like the additional complexity though.

Note also that this is a matter of defining contract. We do not expect connectors to ignore schemaName parameter (tablePrefix in other methods). So we can choose not to expect connectors to ignore relationFilters.

Copy link
Member

@alexjo2144 alexjo2144 left a comment

Choose a reason for hiding this comment

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

I think it's looking pretty close

Comment on lines +439 to +443
return Optional.of(Stream.concat(
unfilteredResultList.stream()
.filter(commentMetadata -> availableNames.contains(commentMetadata.name())),
filteredResult.build().stream())
.iterator());
Copy link
Member

Choose a reason for hiding this comment

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

We're doing a lot of eager work here. It doesn't matter yet because all the streams/iterators are collected to Lists farther up but if we switch the engine to do more of that lazily we'll want to come back to this.

Copy link
Member Author

Choose a reason for hiding this comment

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

agreed. however, i didn't see a clean way to to this somewhat non-trivial logic, where we want to filter tables after capturing comments for cases where we have comment information at hand, and we want to filter tables before going to file system. Doing it more lazy would mean we consult access control more times, which is going to be more expensive.
(previous table_comments implementation would gather even more state in-memory)

@ebyhr
Copy link
Member

ebyhr commented Aug 7, 2023

The result order differs before/after this change. I'm not sure whether the order was ensured, but it returned in alphabetical order as far as I confirmed. Can we keep the original order?

Order in DefaultIcebergQueryRunnerMain after this change:

 catalog_name |    schema_name     |    table_name    | comment
--------------+--------------------+------------------+---------
 tpch         | information_schema | tables           | NULL
 tpch         | information_schema | table_privileges | NULL
 tpch         | information_schema | schemata         | NULL
 tpch         | information_schema | columns          | NULL
 tpch         | information_schema | roles            | NULL
 tpch         | information_schema | enabled_roles    | NULL
 tpch         | information_schema | views            | NULL
 tpch         | information_schema | applicable_roles | NULL
 tpch         | sf1000             | supplier         | NULL
 tpch         | sf10000            | lineitem         | NULL
 tpch         | sf3000             | nation           | NULL
 tpch         | sf30000            | orders           | NULL
 tpch         | tiny               | orders           | NULL
 tpch         | tiny               | part             | NULL
 tpch         | sf30000            | part             | NULL
...

@findepi
Copy link
Member Author

findepi commented Aug 7, 2023

The result order differs before/after this change. I'm not sure whether the order was ensured, but it returned in alphabetical order as far as I confirmed. Can we keep the original order?

table_comments is a relation and relations do not define ordering over tuples they contain. In mathematical terms, an SQL relation is a multiset of tuples. The previously existing deterministic ordering was a side effect of listTables call being (apparently) ordered, but users should not rely on that. We could add explicit ordering, however (a) that would be unnecessary cost for users that do not need ordering, (b) that wouldn't free users from having explicit ORDER BY for cases where ordering is desired. I am tempted to ignore this aspect for now. @ebyhr wdyt?

@findepi findepi force-pushed the findepi/table-comments branch from 73edb2e to 67ed8fd Compare August 7, 2023 10:45
@findepi
Copy link
Member Author

findepi commented Aug 7, 2023

(squashed and renamed (per #18517 (comment)))

/**
* Gets comments for all relations (tables, views, materialized views) that match the specified prefix
* (e.g. for all relations that would be returned by {@link #listTables(ConnectorSession, Optional)} when
* {@code prefix} does not represent relation name).
Copy link
Member

Choose a reason for hiding this comment

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

This method doesn't take "prefix" as the method argument. Should we reword the sentence?

Copy link
Member Author

Choose a reason for hiding this comment

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

thanks, that's a left over. good catch!

findepi added 2 commits August 8, 2023 11:14
Refactor implementation of the `system.metadata.table_comments` table to
avoid`ConnectorMetadata.getTableMetadata` on per-table basis, which
adds up and becomes expensive.

This also allows avoiding separate listings for views and materialized
views, and retrieval of unnecessary information (e.g. involving view
text translation for Hive views).
With Glue, table listing already pulls a lot information about tables.
For Trino-managed Iceberg tables this is sufficient information to
answer `system.metadata.table_comments` queries, without having to fetch
Glue tables again, one-by-one. Trino-manged Iceberg tables keep table
comment up to date in Glue (along with additional information sufficient
to verify it's indeed up to date). The approach can be generalized to
Iceberg's own `GlueCatalog` later if the community is interested.
@findepi findepi force-pushed the findepi/table-comments branch from 67ed8fd to afe1bd5 Compare August 8, 2023 09:14
@findepi
Copy link
Member Author

findepi commented Aug 8, 2023

pushed javadoc fix (for #18517 (comment))
build green before push (https://github.com/trinodb/trino/actions/runs/5784144502)

@findepi findepi merged commit 69f8d74 into master Aug 8, 2023
@findepi findepi deleted the findepi/table-comments branch August 8, 2023 09:26
@github-actions github-actions bot added this to the 423 milestone Aug 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla-signed iceberg Iceberg connector
Development

Successfully merging this pull request may close these issues.

3 participants