Skip to content

Pushdown Prometheus Predicates #8742 #25957

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

jirislav
Copy link

@jirislav jirislav commented Jun 9, 2025

Description

Implements pushdown for Prometheus predicates, as requested in #8742.

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:

## Prometheus Connector
* Support predicate pushdown for equality, non-equality, LIKE & IN operators. (#8742)

Copy link

cla-bot bot commented Jun 9, 2025

Thank you for your pull request and welcome to the Trino community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. Continue to work with us on the review and improvements in this PR, and submit the signed CLA to [email protected]. Photos, scans, or digitally-signed PDF files are all suitable. Processing may take a few days. The CLA needs to be on file before we merge your changes. For more information, see https://github.com/trinodb/cla

Copy link

cla-bot bot commented Jun 9, 2025

Thank you for your pull request and welcome to the Trino community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. Continue to work with us on the review and improvements in this PR, and submit the signed CLA to [email protected]. Photos, scans, or digitally-signed PDF files are all suitable. Processing may take a few days. The CLA needs to be on file before we merge your changes. For more information, see https://github.com/trinodb/cla

@jirislav jirislav force-pushed the pushdown-promql-label-filter branch from 62d8bd7 to dc6eaf4 Compare June 9, 2025 10:12
Copy link

cla-bot bot commented Jun 9, 2025

Thank you for your pull request and welcome to the Trino community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. Continue to work with us on the review and improvements in this PR, and submit the signed CLA to [email protected]. Photos, scans, or digitally-signed PDF files are all suitable. Processing may take a few days. The CLA needs to be on file before we merge your changes. For more information, see https://github.com/trinodb/cla

@jirislav jirislav force-pushed the pushdown-promql-label-filter branch from dc6eaf4 to b2a6f1f Compare June 9, 2025 13:24
Copy link

cla-bot bot commented Jun 9, 2025

Thank you for your pull request and welcome to the Trino community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. Continue to work with us on the review and improvements in this PR, and submit the signed CLA to [email protected]. Photos, scans, or digitally-signed PDF files are all suitable. Processing may take a few days. The CLA needs to be on file before we merge your changes. For more information, see https://github.com/trinodb/cla

@jirislav
Copy link
Author

jirislav commented Jun 9, 2025

Thank you for your pull request and welcome to the Trino community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. Continue to work with us on the review and improvements in this PR, and submit the signed CLA to [email protected]. Photos, scans, or digitally-signed PDF files are all suitable. Processing may take a few days. The CLA needs to be on file before we merge your changes. For more information, see https://github.com/trinodb/cla

I have the CLA signed and sent like 6 hours ago, not sure how long it usually takes to propagate to the related failing CI job.

@jirislav jirislav force-pushed the pushdown-promql-label-filter branch from b2a6f1f to 6028e80 Compare June 23, 2025 18:58
@cla-bot cla-bot bot added the cla-signed label Jun 23, 2025
@jirislav
Copy link
Author

@ebyhr could you please review & merge? I see you made recent changes to Prometheus Connector as well.

@ebyhr ebyhr removed their assignment Jun 24, 2025
Copy link
Member

@ebyhr ebyhr left a comment

Choose a reason for hiding this comment

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

Just skimmed.

@@ -79,6 +79,6 @@ public Optional<ImmutableList<LabelFilterExpression>> rewrite(Call call, Capture
labelName,
labelValue,
false,
call.getFunctionName() == NOT_EQUAL_OPERATOR_FUNCTION_NAME)));
call.getFunctionName().equals(NOT_EQUAL_OPERATOR_FUNCTION_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 change should go to the 1st commit.

@@ -53,13 +53,13 @@ public static String extractLabelName(Captures captures, Capture<Call> captureKe
// This method assumes that
List<ConnectorExpression> arguments = captures.get(captureKey).getArguments();
Object labelNameObject = ((Constant) arguments.getLast()).getValue();
if (!(labelNameObject instanceof Slice)) {
if (!(labelNameObject instanceof Slice slice)) {
Copy link
Member

Choose a reason for hiding this comment

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

This change should go to the 1st commit.

if (labelNameObject == null) {
throw new IllegalArgumentException("Label name cannot be null");
}
throw new IllegalArgumentException("Expected label name to be a Slice, but got: " + labelNameObject.getClass().getSimpleName());
}
return ((Slice) labelNameObject).toStringUtf8();
return slice.toStringUtf8();
Copy link
Member

Choose a reason for hiding this comment

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

This change should go to the 1st commit.

@@ -23,14 +25,15 @@

import static java.util.Objects.requireNonNull;

public record PrometheusTableHandle(String schemaName, String tableName, Optional<TupleDomain<ColumnHandle>> predicate)
public record PrometheusTableHandle(String schemaName, String tableName, Optional<TupleDomain<ColumnHandle>> predicate, ImmutableList<LabelFilterExpression> expressions)
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 record PrometheusTableHandle(String schemaName, String tableName, Optional<TupleDomain<ColumnHandle>> predicate, ImmutableList<LabelFilterExpression> expressions)
public record PrometheusTableHandle(String schemaName, String tableName, Optional<TupleDomain<ColumnHandle>> predicate, List<LabelFilterExpression> expressions)

implements ConnectorTableHandle
{
public PrometheusTableHandle
{
requireNonNull(schemaName, "schemaName is null");
requireNonNull(tableName, "tableName is null");
requireNonNull(predicate, "predicate is null");
requireNonNull(expressions, "expressions is null");
Copy link
Member

Choose a reason for hiding this comment

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

Remove requireNonNull and add ImmutableList.copyOf.

assertThat(request.extractPromQL()).isEqualTo("up{job=\"prometheus\"}[1d]");
});

assertThat(results).hasSizeBetween(1, 2);
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 the result size non-deterministic? Please leave a code comment.

assertThat(request.extractPromQL()).isEqualTo("up[1d]");
});

assertThat(results).hasSize(0);
Copy link
Member

Choose a reason for hiding this comment

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

There is isEmpty() method.

return newTableHandle(schemaName, tableName, Optional.empty(), ImmutableList.of());
}

public static PrometheusTableHandle newTableHandle(String schemaName, String tableName, Optional<TupleDomain<ColumnHandle>> predicate, ImmutableList<LabelFilterExpression> expressions)
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 static PrometheusTableHandle newTableHandle(String schemaName, String tableName, Optional<TupleDomain<ColumnHandle>> predicate, ImmutableList<LabelFilterExpression> expressions)
public static PrometheusTableHandle newTableHandle(String schemaName, String tableName, Optional<TupleDomain<ColumnHandle>> predicate, List<LabelFilterExpression> expressions)


public class TestPrometheusIntegration
@Execution(SAME_THREAD)
Copy link
Member

Choose a reason for hiding this comment

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

Please leave a code comment why specifying SAME_THREAD.

Comment on lines +134 to +140
prometheusContainer.close();

if (proxyContainer != null) {
proxyContainer.close();
}

network.close();
Copy link
Member

Choose a reason for hiding this comment

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

You can use Guava's Closer.

private static final int PROMETHEUS_PORT = 9090;
private static final String DEFAULT_VERSION = "v2.15.1";
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this changes required?

public static final Predicate<Call> LABEL_MAP_CHECK_CORRECT_TYPE = connectorExpression -> {
List<ConnectorExpression> arguments = connectorExpression.getArguments();

if (!(arguments.getFirst() instanceof Variable)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Add a check if arguments is empty or not

List<ConnectorExpression> arguments = captures.get(captureKey).getArguments();
Object labelNameObject = ((Constant) arguments.getLast()).getValue();
if (!(labelNameObject instanceof Slice)) {
if (labelNameObject == null) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we perform this check earlier?

// Extract the label name from the call expression, which is actually the key of the labels map.
// This method assumes that
List<ConnectorExpression> arguments = captures.get(captureKey).getArguments();
Object labelNameObject = ((Constant) arguments.getLast()).getValue();
Copy link
Contributor

Choose a reason for hiding this comment

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

add arguments check if it is empty

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

Successfully merging this pull request may close these issues.

4 participants