From 3b10d26150f600ec559debda9b1c4ad9f3358da9 Mon Sep 17 00:00:00 2001 From: Fabian Kovacs Date: Wed, 4 Feb 2026 10:02:53 +0100 Subject: [PATCH] Adds test for RelativeFormQuery with no elements actually producing dates also reduces logging, in case a line does not contain any dates. --- .../conquery/models/error/ConqueryError.java | 9 ++++++- .../conquery/models/error/ErrorMessages.java | 4 +++ .../forms/managed/RelativeFormQuery.java | 27 ++++++++++++++++--- .../forms/managed/RelativeFormQueryPlan.java | 6 ++--- 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/backend/src/main/java/com/bakdata/conquery/models/error/ConqueryError.java b/backend/src/main/java/com/bakdata/conquery/models/error/ConqueryError.java index 78b898f5cb..c2fa62366b 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/error/ConqueryError.java +++ b/backend/src/main/java/com/bakdata/conquery/models/error/ConqueryError.java @@ -278,7 +278,14 @@ public static class SqlError extends ConqueryError { public String getMessageTemplate(ErrorMessages errorMessages) { return errorMessages.sqlError(error); } + } - + @CPSType(base = ConqueryError.class, id = "CQ_RELATIVE_NO_DATES") + @RequiredArgsConstructor(onConstructor_ = {@JsonCreator}) + public static class RelativeFormMissingDatesError extends ConqueryError { + @Override + public String getMessageTemplate(ErrorMessages errorMessages) { + return errorMessages.relativeFormMissingDates(); + } } } diff --git a/backend/src/main/java/com/bakdata/conquery/models/error/ErrorMessages.java b/backend/src/main/java/com/bakdata/conquery/models/error/ErrorMessages.java index 7684594aa9..6ddfe2baff 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/error/ErrorMessages.java +++ b/backend/src/main/java/com/bakdata/conquery/models/error/ErrorMessages.java @@ -68,4 +68,8 @@ public interface ErrorMessages { @En("The id {0} could not be resolved'.") @De("Die id {0} konnte nicht aufgelöst werden.") String idUnresolvable(Id id); + + @En("The selected query does not contain any dates.") + @De("Die ausgewählte Anfrage enthält keine Zeiträume.") + String relativeFormMissingDates(); } diff --git a/backend/src/main/java/com/bakdata/conquery/models/forms/managed/RelativeFormQuery.java b/backend/src/main/java/com/bakdata/conquery/models/forms/managed/RelativeFormQuery.java index 80568db532..e6976e9d75 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/forms/managed/RelativeFormQuery.java +++ b/backend/src/main/java/com/bakdata/conquery/models/forms/managed/RelativeFormQuery.java @@ -15,7 +15,10 @@ import com.bakdata.conquery.apiv1.query.QueryDescription; import com.bakdata.conquery.apiv1.query.ResultHeaders; import com.bakdata.conquery.apiv1.query.TemporalSamplerFactory; +import com.bakdata.conquery.apiv1.query.concept.specific.CQConcept; +import com.bakdata.conquery.apiv1.query.concept.specific.external.CQExternal; import com.bakdata.conquery.io.cps.CPSType; +import com.bakdata.conquery.models.error.ConqueryError; import com.bakdata.conquery.models.forms.util.CalendarUnit; import com.bakdata.conquery.models.identifiable.ids.specific.ManagedExecutionId; import com.bakdata.conquery.models.query.DateAggregationMode; @@ -29,13 +32,15 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; -@CPSType(id="RELATIVE_FORM_QUERY", base=QueryDescription.class) +@CPSType(id = "RELATIVE_FORM_QUERY", base = QueryDescription.class) @Getter @RequiredArgsConstructor(onConstructor_ = {@JsonCreator}) public class RelativeFormQuery extends Query { - @NotNull @Valid + @NotNull + @Valid private final Query query; - @NotNull @Valid + @NotNull + @Valid private final ArrayConceptQuery features; @NotNull private final TemporalSamplerFactory indexSelector; @@ -54,6 +59,20 @@ public class RelativeFormQuery extends Query { public void resolve(QueryResolveContext context) { query.resolve(context.withDateAggregationMode(DateAggregationMode.MERGE)); features.resolve(context.withDateAggregationMode(DateAggregationMode.NONE)); + + boolean noDates = Visitable.stream(query) + .noneMatch(v -> + switch (v) { + case CQConcept cqConcept -> cqConcept.isAggregateEventDates(); + case CQExternal external -> external.containsDates(); + default -> false; + } + ); + + if (noDates) { + throw new ConqueryError.RelativeFormMissingDatesError(); + } + } @Override @@ -71,7 +90,7 @@ public void collectRequiredQueries(Set requiredQueries) { query.collectRequiredQueries(requiredQueries); features.collectRequiredQueries(requiredQueries); } - + @Override public List getResultInfos() { List resultInfos = new ArrayList<>(); diff --git a/backend/src/main/java/com/bakdata/conquery/models/forms/managed/RelativeFormQueryPlan.java b/backend/src/main/java/com/bakdata/conquery/models/forms/managed/RelativeFormQueryPlan.java index 5920ca9873..a1da6bcc8a 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/forms/managed/RelativeFormQueryPlan.java +++ b/backend/src/main/java/com/bakdata/conquery/models/forms/managed/RelativeFormQueryPlan.java @@ -60,6 +60,8 @@ public class RelativeFormQueryPlan implements QueryPlan { @Override public void init(QueryExecutionContext ctxt, Entity entity) { query.init(ctxt, entity); + + featurePlan.init(ctxt, entity); indexSelector = indexSelectorFactory.sampler(ctxt.getToday()); @@ -70,9 +72,7 @@ public void init(QueryExecutionContext ctxt, Entity entity) { @Override public Optional execute(QueryExecutionContext ctx, Entity entity) { - // Don't set the query date aggregator here because the subqueries should set their aggregator independently - Optional preResult = query.execute(ctx, entity); if (preResult.isEmpty()) { @@ -88,7 +88,7 @@ public Optional execute(QueryExecutionContext ctx, Entity // dateset is empty or sampling failed. if (sampled.isEmpty()) { - log.warn("Sampled empty result for Entity[{}]: `{}({})`", contained.getEntityId(), indexSelector, dateSet); + log.trace("Sampled empty result for Entity[{}]: `{}({})`", contained.getEntityId(), indexSelector, dateSet); List results = new ArrayList<>(); results.add(new Object[size]); return Optional.of(