Skip to content

Trino - Optimize visibility filtering using Iceberg metadata - #10837

Open
andresdantereng wants to merge 11 commits into
locationtech:mainfrom
andresdantereng:feature/10818-optimize-visibility-filtering-using-iceberg-metadata
Open

andresdantereng wants to merge 11 commits into
locationtech:mainfrom
andresdantereng:feature/10818-optimize-visibility-filtering-using-iceberg-metadata

Conversation

@andresdantereng

@andresdantereng andresdantereng commented Sep 21, 2026 •

Copy link
Copy Markdown

This optimizes filtering based on visibility values by filtering Iceberg files based on visibility min-max values in metadata. Two new properties are required:

  • geomesa.security.enable-visibility-expression-pruning: False by default. This gates the entire feature. If set to true, it applies the optimization.
  • geomesa.security.visibility-expressions: A comma-separated list of possible visibility expressions, such as FOO,FOO&BAR.

closes #10818

@elahrvivaz elahrvivaz changed the title Feature/10818 optimize visibility filtering using iceberg metadata Trino - Optimize visibility filtering using Iceberg metadata Sep 21, 2026
@cwdobbins

Copy link
Copy Markdown
Contributor

docs/user/trino/security.rst needs the new flag documented

@@ -0,0 +1,205 @@
/***********************************************************************

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.

IcebergVisibilityPruningMechanismTest's tests cover only emptyAuthsDomain and tokenDomain. There is no expressionDomain case at all. Worth adding:

  • A file with __vis__ = "admin&ops" survives under expressionDomain({"admin&ops"}, {"admin","ops"}) where tokenDomain prunes it. This is the entire justification for the PR and is currently only asserted at the Domain level (expressionDomainFixesTokenDomainsCompoundExpressionGap), never through the manifest evaluator.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This is done.

@cwdobbins

cwdobbins commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Edge case (unlikely to occur in prod, but should be fixed):

The isVisible UDF treats empty vis entries ("" \ length() == 0) as unrestricted, so the code anticipates "" occurring in the column. But parseVisibilityExpressions drops blank entries, so "" can never be declared; the domain admits NULL only. If any row carries "" rather than NULL, files holding only empty __vis__ entries are pruned rather than returned.

@elahrvivaz

Copy link
Copy Markdown
Contributor

could you add the new properties to docs/user/trino/security.rst ? (they are connector properties, i think?)

@elahrvivaz

elahrvivaz commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Edge case (unlikely to occur in prod, but should be fixed):

The isVisible UDF treats empty vis entries ("" \ length() == 0) as unrestricted, so the code anticipates "" occurring in the column. But parseVisibilityExpressions drops blank entries, so "" can never be declared; the domain admits NULL only. If any row carries "" rather than NULL, files holding only empty __vis__ entries are pruned rather than returned.

If it simplifies things, I think we could just assume that if vis are being used, then no vis are empty/null - in practice, if vis are enabled then it is likely to be an error if a vis is empty/null. in other stores, we actually have a sys prop to enforce setting vis at write time - we may want to add that to trino as well.

@andresdantereng
andresdantereng force-pushed the feature/10818-optimize-visibility-filtering-using-iceberg-metadata branch from c9c4d33 to 8ac5c84 Compare September 21, 2026 16:56
@andresdantereng

Copy link
Copy Markdown
Author

docs/user/trino/security.rst needs the new flag documented

This is also done, but let me know if I added too much documentation.

@andresdantereng

Copy link
Copy Markdown
Author

could you add the new properties to docs/user/trino/security.rst ? (they are connector properties, i think?)

Done

@cwdobbins

Copy link
Copy Markdown
Contributor

Edge case (unlikely to occur in prod, but should be fixed):
The isVisible UDF treats empty vis entries ("" \ length() == 0) as unrestricted, so the code anticipates "" occurring in the column. But parseVisibilityExpressions drops blank entries, so "" can never be declared; the domain admits NULL only. If any row carries "" rather than NULL, files holding only empty __vis__ entries are pruned rather than returned.

If it simplifies things, I think we could just assume that if vis are being used, then no vis are empty/null - in practice, if vis are enabled then it is likely to be an error if a vis is empty/null. in other stores, we actually have a sys prop to enforce setting vis at write time - we may want to add that to trino as well.

Ok, after offline discussion, we are going to fail-closed on rows with null/empty vis, when a vis column is present and visibility filtering is flagged as enabled, so we would 1) return no rows lacking an empty vis, and thus 2) prune out any files whose contents contain solely empty/null vis

Comment thread docs/user/trino/security.rst Outdated
Comment thread docs/user/trino/security.rst
<skipITs>true</skipITs>
<opentelemetry.version>1.65.0</opentelemetry.version> <!-- note: trino bundles 1.61.0, but that triggers a CVE in our scanning -->
<!-- The geomesa parent pins jetty to 9.4 for its own server stack, but Trino 483's
embedded test HTTP server (DistributedQueryRunner, used only by the end-to-end

@elahrvivaz elahrvivaz Sep 23, 2026 •

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.

this is ok for now, but we should prefer using trino through testcontainers instead of embedded test frameworks, for the very reason that embedded frameworks complicate the classpath and don't always accurately reflect a real instance. (we have an example in TrinoDataStoreTest of using testcontainers)

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.

actually, I didn't realize the test framework was being added in this PR - I think we should switch to using testcontainers instead.

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.

you could move the IT into the trino data store module, or otherwise you'll just need to make sure that the plugin is packaged and available to load into the trino image when the tests run - i.e. just make sure the maven lifecycle is correct.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Sounds like moving the IT into the Trino datastore module is the right thing to do. I definitely chose the wrong path on this one. The changes have been pushed, but I'm seeing errors when I run it locally, so I'm not out of the woods on this one yet. I'll update when I have dealt with all the issues.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This should be okay now. I was consistently able to run this:

mvn -pl geomesa-trino/geomesa-trino-datastore -am verify \
-DskipITs=false \
-Dit.test=VisibilityPruningEndToEndIT \
-Dtest=NONE \
-Dsurefire.failIfNoSpecifiedTests=false \
-Dfailsafe.failIfNoSpecifiedTests=false

@elahrvivaz

Copy link
Copy Markdown
Contributor

looks like there are test failures in CI, also

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Optimize trino count queries that include visibility checks

3 participants