diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/DaterangeSelect.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/DaterangeSelectOrFilter.java similarity index 85% rename from backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/DaterangeSelect.java rename to backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/DaterangeSelectOrFilter.java index 20b60c26e8..e0d0a39623 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/DaterangeSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/DaterangeSelectOrFilter.java @@ -6,7 +6,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import io.dropwizard.validation.ValidationMethod; -public interface DaterangeSelect { +public interface DaterangeSelectOrFilter { Column getColumn(); @@ -14,6 +14,11 @@ public interface DaterangeSelect { Column getEndColumn(); + @JsonIgnore + default boolean isSingleColumnDaterange() { + return getColumn() != null; + } + @JsonIgnore default Table getTable() { if (getColumn() != null) { @@ -25,7 +30,7 @@ default Table getTable() { @JsonIgnore @ValidationMethod(message = "Single column date range (set via column) and two column date range (set via startColumn and endColumn) are exclusive.") - default boolean isExclusiveValidityDates() { + default boolean isExclusiveDateRange() { if (getColumn() == null) { return getStartColumn() != null && getEndColumn() != null; } @@ -43,7 +48,7 @@ default boolean isOfSameTable() { @JsonIgnore @ValidationMethod(message = "Both columns of a two-column daterange have to be of type DATE.") - default boolean isValidTwoColumnDaterange() { + default boolean isValidTwoColumnDaterangeSelect() { if (getStartColumn() == null || getEndColumn() == null) { return true; } @@ -52,7 +57,7 @@ default boolean isValidTwoColumnDaterange() { @JsonIgnore @ValidationMethod(message = "Column is not of type DATE or DATE_RANGE.") - default boolean isValidValidityDatesSingleColumn() { + default boolean isValidSingleColumnDateSelect() { if (getColumn() == null) { return true; } diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/ValidityDate.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/ValidityDate.java index 8e38982494..36b99ca826 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/ValidityDate.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/ValidityDate.java @@ -25,7 +25,7 @@ @Setter @NoArgsConstructor @Slf4j -public class ValidityDate extends Labeled implements NamespacedIdentifiable, DaterangeSelect { +public class ValidityDate extends Labeled implements NamespacedIdentifiable, DaterangeSelectOrFilter { @NsIdRef @Nullable diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/filters/specific/CountQuartersFilter.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/filters/specific/CountQuartersFilter.java index 76d4b5c4e1..e25cc8371e 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/filters/specific/CountQuartersFilter.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/filters/specific/CountQuartersFilter.java @@ -1,14 +1,18 @@ package com.bakdata.conquery.models.datasets.concepts.filters.specific; -import java.util.EnumSet; +import java.util.List; + +import javax.annotation.Nullable; import com.bakdata.conquery.apiv1.frontend.FrontendFilterConfiguration; import com.bakdata.conquery.apiv1.frontend.FrontendFilterType; import com.bakdata.conquery.io.cps.CPSType; +import com.bakdata.conquery.io.jackson.serializer.NsIdRef; import com.bakdata.conquery.models.common.Range; import com.bakdata.conquery.models.config.ConqueryConfig; +import com.bakdata.conquery.models.datasets.Column; +import com.bakdata.conquery.models.datasets.concepts.DaterangeSelectOrFilter; import com.bakdata.conquery.models.datasets.concepts.filters.Filter; -import com.bakdata.conquery.models.datasets.concepts.filters.SingleColumnFilter; import com.bakdata.conquery.models.events.MajorTypeId; import com.bakdata.conquery.models.query.filter.RangeFilterNode; import com.bakdata.conquery.models.query.queryplan.aggregators.specific.CountQuartersOfDateRangeAggregator; @@ -22,12 +26,17 @@ @Setter @Getter @CPSType(id = "COUNT_QUARTERS", base = Filter.class) -public class CountQuartersFilter extends SingleColumnFilter { +public class CountQuartersFilter extends Filter implements DaterangeSelectOrFilter { - @Override - public EnumSet getAcceptedColumnTypes() { - return EnumSet.of(MajorTypeId.DATE, MajorTypeId.DATE_RANGE); - } + @NsIdRef + @Nullable + private Column column; + @NsIdRef + @Nullable + private Column startColumn; + @NsIdRef + @Nullable + private Column endColumn; @Override public void configureFrontend(FrontendFilterConfiguration.Top f, ConqueryConfig conqueryConfig) { @@ -35,6 +44,14 @@ public void configureFrontend(FrontendFilterConfiguration.Top f, ConqueryConfig f.setMin(1); } + @Override + public List getRequiredColumns() { + if (isSingleColumnDaterange()) { + return List.of(column); + } + return List.of(startColumn, endColumn); + } + @Override public FilterNode createFilterNode(Range.LongRange value) { if (getColumn().getType() == MajorTypeId.DATE_RANGE) { @@ -47,4 +64,5 @@ public FilterNode createFilterNode(Range.LongRange value) { public FilterConverter createConverter() { return new CountQuartersSqlAggregator(); } + } diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/CountQuartersSelect.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/CountQuartersSelect.java index 29a36531db..1927fd3108 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/CountQuartersSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/CountQuartersSelect.java @@ -1,13 +1,14 @@ package com.bakdata.conquery.models.datasets.concepts.select.connector.specific; -import java.util.EnumSet; +import java.util.List; + +import javax.annotation.Nullable; import com.bakdata.conquery.io.cps.CPSType; import com.bakdata.conquery.io.jackson.serializer.NsIdRef; import com.bakdata.conquery.models.datasets.Column; +import com.bakdata.conquery.models.datasets.concepts.DaterangeSelectOrFilter; import com.bakdata.conquery.models.datasets.concepts.select.Select; -import com.bakdata.conquery.models.datasets.concepts.select.connector.SingleColumnSelect; -import com.bakdata.conquery.models.events.MajorTypeId; import com.bakdata.conquery.models.query.queryplan.aggregators.Aggregator; import com.bakdata.conquery.models.query.queryplan.aggregators.specific.CountQuartersOfDateRangeAggregator; import com.bakdata.conquery.models.query.queryplan.aggregators.specific.CountQuartersOfDatesAggregator; @@ -15,22 +16,36 @@ import com.bakdata.conquery.sql.conversion.model.aggregator.CountQuartersSqlAggregator; import com.bakdata.conquery.sql.conversion.model.select.SelectConverter; import com.fasterxml.jackson.annotation.JsonCreator; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; /** * Entity is included when the number of distinct quarters for all events is within a given range. * Implementation is specific for DateRanges */ +@Setter +@Getter +@NoArgsConstructor(onConstructor_ = @JsonCreator) @CPSType(id = "COUNT_QUARTERS", base = Select.class) -public class CountQuartersSelect extends SingleColumnSelect { +public class CountQuartersSelect extends Select implements DaterangeSelectOrFilter { - @Override - public EnumSet getAcceptedColumnTypes() { - return EnumSet.of(MajorTypeId.DATE, MajorTypeId.DATE_RANGE); - } + @NsIdRef + @Nullable + private Column column; + @NsIdRef + @Nullable + private Column startColumn; + @NsIdRef + @Nullable + private Column endColumn; - @JsonCreator - public CountQuartersSelect(@NsIdRef Column column) { - super(column); + @Override + public List getRequiredColumns() { + if (isSingleColumnDaterange()) { + return List.of(column); + } + return List.of(startColumn, endColumn); } @Override @@ -44,12 +59,12 @@ public Aggregator createAggregator() { } @Override - public SelectConverter createConverter() { - return new CountQuartersSqlAggregator(); + public ResultType getResultType() { + return ResultType.IntegerT.INSTANCE; } @Override - public ResultType getResultType() { - return ResultType.IntegerT.INSTANCE; + public SelectConverter createConverter() { + return new CountQuartersSqlAggregator(); } } diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/DateUnionSelect.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/DateUnionSelect.java index 5ffda35f4c..2d1ff6246c 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/DateUnionSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/DateUnionSelect.java @@ -7,7 +7,7 @@ import com.bakdata.conquery.io.cps.CPSType; import com.bakdata.conquery.io.jackson.serializer.NsIdRef; import com.bakdata.conquery.models.datasets.Column; -import com.bakdata.conquery.models.datasets.concepts.DaterangeSelect; +import com.bakdata.conquery.models.datasets.concepts.DaterangeSelectOrFilter; import com.bakdata.conquery.models.datasets.concepts.select.Select; import com.bakdata.conquery.models.query.queryplan.aggregators.Aggregator; import com.bakdata.conquery.models.query.queryplan.aggregators.specific.DateUnionAggregator; @@ -23,7 +23,7 @@ @NoArgsConstructor(onConstructor_ = @JsonCreator) @CPSType(id = "DATE_UNION", base = Select.class) @JsonIgnoreProperties("categorical") -public class DateUnionSelect extends Select implements DaterangeSelect { +public class DateUnionSelect extends Select implements DaterangeSelectOrFilter { @NsIdRef @Nullable diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/DurationSumSelect.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/DurationSumSelect.java index e1743b34be..8e32141534 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/DurationSumSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/DurationSumSelect.java @@ -7,7 +7,7 @@ import com.bakdata.conquery.io.cps.CPSType; import com.bakdata.conquery.io.jackson.serializer.NsIdRef; import com.bakdata.conquery.models.datasets.Column; -import com.bakdata.conquery.models.datasets.concepts.DaterangeSelect; +import com.bakdata.conquery.models.datasets.concepts.DaterangeSelectOrFilter; import com.bakdata.conquery.models.datasets.concepts.select.Select; import com.bakdata.conquery.models.query.queryplan.aggregators.Aggregator; import com.bakdata.conquery.models.query.queryplan.aggregators.specific.DurationSumAggregator; @@ -23,7 +23,7 @@ @NoArgsConstructor(onConstructor_ = @JsonCreator) @CPSType(id = "DURATION_SUM", base = Select.class) @JsonIgnoreProperties("categorical") -public class DurationSumSelect extends Select implements DaterangeSelect { +public class DurationSumSelect extends Select implements DaterangeSelectOrFilter { @NsIdRef @Nullable diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/forms/Interval.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/Interval.java similarity index 87% rename from backend/src/main/java/com/bakdata/conquery/sql/conversion/forms/Interval.java rename to backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/Interval.java index 3a72c32d58..20eece3642 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/forms/Interval.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/Interval.java @@ -1,11 +1,11 @@ -package com.bakdata.conquery.sql.conversion.forms; +package com.bakdata.conquery.sql.conversion.dialect; import lombok.Getter; import lombok.RequiredArgsConstructor; @Getter @RequiredArgsConstructor -enum Interval { +public enum Interval { ONE_YEAR_INTERVAL(1), YEAR_AS_DAYS_INTERVAL(365), diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/forms/HanaStratificationFunctions.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/forms/HanaStratificationFunctions.java index 62938726e1..5db759fe1b 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/forms/HanaStratificationFunctions.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/forms/HanaStratificationFunctions.java @@ -1,12 +1,13 @@ package com.bakdata.conquery.sql.conversion.forms; -import static com.bakdata.conquery.sql.conversion.forms.Interval.MONTHS_PER_QUARTER; +import static com.bakdata.conquery.sql.conversion.dialect.Interval.MONTHS_PER_QUARTER; import java.sql.Date; import java.time.temporal.ChronoUnit; import com.bakdata.conquery.apiv1.query.concept.specific.temporal.TemporalSamplerFactory; import com.bakdata.conquery.sql.conversion.dialect.HanaSqlFunctionProvider; +import com.bakdata.conquery.sql.conversion.dialect.Interval; import com.bakdata.conquery.sql.conversion.model.ColumnDateRange; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -14,7 +15,6 @@ import org.jooq.Record; import org.jooq.Table; import org.jooq.impl.DSL; -import org.jooq.impl.QOM; import org.jooq.impl.SQLDataType; @Getter @@ -32,7 +32,7 @@ class HanaStratificationFunctions extends StratificationFunctions { private final HanaSqlFunctionProvider functionProvider; @Override - protected Field lower(ColumnDateRange dateRange) { + public Field lower(ColumnDateRange dateRange) { // HANA does not support single-column ranges, so we can return start and end directly return dateRange.getStart(); } @@ -96,7 +96,7 @@ public Field lowerBoundQuarterStart(ColumnDateRange dateRange) { } @Override - protected Field jumpToQuarterStart(Field date) { + public Field jumpToQuarterStart(Field date) { Field yearStart = jumpToYearStart(date); Field quartersInMonths = getQuartersInMonths(date, Offset.MINUS_ONE); return addMonths(yearStart, quartersInMonths); @@ -108,7 +108,7 @@ public Field upperBoundQuarterEnd(ColumnDateRange dateRange) { } @Override - protected Field jumpToNextQuarterStart(Field date) { + public Field jumpToNextQuarterStart(Field date) { Field yearStart = jumpToYearStart(date); Field quartersInMonths = getQuartersInMonths(date, Offset.NONE); return addMonths(yearStart, quartersInMonths); diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/forms/PostgresStratificationFunctions.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/forms/PostgresStratificationFunctions.java index 4be86a1576..7eee85e755 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/forms/PostgresStratificationFunctions.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/forms/PostgresStratificationFunctions.java @@ -9,6 +9,7 @@ import java.util.Map; import com.bakdata.conquery.apiv1.query.concept.specific.temporal.TemporalSamplerFactory; +import com.bakdata.conquery.sql.conversion.dialect.Interval; import com.bakdata.conquery.sql.conversion.dialect.PostgreSqlFunctionProvider; import com.bakdata.conquery.sql.conversion.model.ColumnDateRange; import lombok.Getter; @@ -83,7 +84,7 @@ public Field lowerBoundQuarterStart(ColumnDateRange dateRange) { } @Override - protected Field jumpToQuarterStart(Field date) { + public Field jumpToQuarterStart(Field date) { Field quarter = functionProvider.extract(DatePart.QUARTER, date); return addQuarters(jumpToYearStart(date), quarter, Offset.MINUS_ONE); } @@ -95,7 +96,7 @@ public Field upperBoundQuarterEnd(ColumnDateRange dateRange) { } @Override - protected Field jumpToNextQuarterStart(Field date) { + public Field jumpToNextQuarterStart(Field date) { Field yearStart = dateTruncate(DSL.val("year"), date); Field quarter = functionProvider.extract(DatePart.QUARTER, date); return addQuarters(yearStart, quarter, Offset.NONE); @@ -137,7 +138,7 @@ public Field shiftByInterval(Field startDate, Interval interval, Fie } @Override - protected Field lower(ColumnDateRange dateRange) { + public Field lower(ColumnDateRange dateRange) { checkIsSingleColumnRange(dateRange); return DSL.function("lower", Date.class, dateRange.getRange()); } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/forms/RelativeStratification.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/forms/RelativeStratification.java index baaa89b7f6..d7915f52ba 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/forms/RelativeStratification.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/forms/RelativeStratification.java @@ -19,6 +19,7 @@ import com.bakdata.conquery.models.forms.util.CalendarUnit; import com.bakdata.conquery.models.forms.util.Resolution; import com.bakdata.conquery.sql.conversion.SharedAliases; +import com.bakdata.conquery.sql.conversion.dialect.Interval; import com.bakdata.conquery.sql.conversion.dialect.SqlFunctionProvider; import com.bakdata.conquery.sql.conversion.model.ColumnDateRange; import com.bakdata.conquery.sql.conversion.model.QueryStep; @@ -278,7 +279,7 @@ private static Range toGenerateSeriesBounds(RelativeFormQuery relativeF } return Range.of( - - timeCountBefore, + -timeCountBefore, timeCountAfter ); } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/forms/StratificationFunctions.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/forms/StratificationFunctions.java index a997cf7dc9..ab57a6dcfc 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/forms/StratificationFunctions.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/forms/StratificationFunctions.java @@ -1,5 +1,8 @@ package com.bakdata.conquery.sql.conversion.forms; +import static com.bakdata.conquery.sql.conversion.dialect.Interval.DAYS_PER_QUARTER; +import static com.bakdata.conquery.sql.conversion.dialect.Interval.DAYS_PER_YEAR; +import static com.bakdata.conquery.sql.conversion.dialect.Interval.MONTHS_PER_QUARTER; import static com.bakdata.conquery.sql.conversion.forms.FormConstants.DAY_ALIGNED_COUNT; import static com.bakdata.conquery.sql.conversion.forms.FormConstants.INDEX_SELECTOR; import static com.bakdata.conquery.sql.conversion.forms.FormConstants.INDEX_START; @@ -10,9 +13,6 @@ import static com.bakdata.conquery.sql.conversion.forms.FormConstants.YEAR_END; import static com.bakdata.conquery.sql.conversion.forms.FormConstants.YEAR_END_QUARTER_ALIGNED; import static com.bakdata.conquery.sql.conversion.forms.FormConstants.YEAR_START; -import static com.bakdata.conquery.sql.conversion.forms.Interval.DAYS_PER_QUARTER; -import static com.bakdata.conquery.sql.conversion.forms.Interval.DAYS_PER_YEAR; -import static com.bakdata.conquery.sql.conversion.forms.Interval.MONTHS_PER_QUARTER; import java.sql.Date; import java.time.temporal.ChronoUnit; @@ -29,6 +29,7 @@ import com.bakdata.conquery.sql.conversion.SharedAliases; import com.bakdata.conquery.sql.conversion.cqelement.ConversionContext; import com.bakdata.conquery.sql.conversion.dialect.HanaSqlFunctionProvider; +import com.bakdata.conquery.sql.conversion.dialect.Interval; import com.bakdata.conquery.sql.conversion.dialect.PostgreSqlFunctionProvider; import com.bakdata.conquery.sql.conversion.dialect.SqlFunctionProvider; import com.bakdata.conquery.sql.conversion.model.ColumnDateRange; @@ -39,9 +40,9 @@ import org.jooq.Table; import org.jooq.impl.DSL; -abstract class StratificationFunctions { +public abstract class StratificationFunctions { - static StratificationFunctions create(ConversionContext context) { + public static StratificationFunctions create(ConversionContext context) { SqlFunctionProvider functionProvider = context.getSqlDialect().getFunctionProvider(); return switch (context.getConfig().getDialect()) { case POSTGRESQL -> new PostgresStratificationFunctions((PostgreSqlFunctionProvider) functionProvider); @@ -58,7 +59,7 @@ public ColumnDateRange ofStartAndEnd(Field start, Field end) { /** * Extract the lower bounds from a given daterange. */ - protected abstract Field lower(ColumnDateRange dateRange); + public abstract Field lower(ColumnDateRange dateRange); /** * Extract the inclusive upper bound from a given daterange. @@ -104,7 +105,7 @@ public ColumnDateRange ofStartAndEnd(Field start, Field end) { /** * Calculates the start of the quarter of the given date. */ - protected abstract Field jumpToQuarterStart(Field date); + public abstract Field jumpToQuarterStart(Field date); /** * Calculates the exclusive end (first day of the next quarter) of the upper bound of the provided date range. @@ -114,7 +115,7 @@ public ColumnDateRange ofStartAndEnd(Field start, Field end) { /** * Calculates the start of the next quarter of the given date. */ - protected abstract Field jumpToNextQuarterStart(Field date); + public abstract Field jumpToNextQuarterStart(Field date); /** * The int field generated by the {@link #generateIntSeries(int, int)} diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/CommonAggregationSelect.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/CommonAggregationSelect.java index ab79e7c7b4..20661511b9 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/CommonAggregationSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/CommonAggregationSelect.java @@ -7,8 +7,8 @@ import com.bakdata.conquery.models.datasets.concepts.select.Select; import com.bakdata.conquery.sql.conversion.model.QueryStep; import com.bakdata.conquery.sql.conversion.model.select.ConnectorSqlSelects; -import com.bakdata.conquery.sql.conversion.model.select.ExtractingSqlSelect; import com.bakdata.conquery.sql.conversion.model.select.FieldWrapper; +import com.bakdata.conquery.sql.conversion.model.select.SingleColumnSqlSelect; import com.bakdata.conquery.sql.conversion.model.select.SqlSelect; import lombok.Builder; import lombok.Singular; @@ -28,7 +28,7 @@ class CommonAggregationSelect { @Singular - List> rootSelects; + List rootSelects; FieldWrapper groupBy; diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/CountQuartersSqlAggregator.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/CountQuartersSqlAggregator.java index 79d667bcf8..7dd3494050 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/CountQuartersSqlAggregator.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/CountQuartersSqlAggregator.java @@ -1,16 +1,22 @@ package com.bakdata.conquery.sql.conversion.model.aggregator; +import java.math.BigDecimal; import java.sql.Date; +import java.time.temporal.ChronoUnit; import com.bakdata.conquery.models.common.Range; import com.bakdata.conquery.models.datasets.Column; import com.bakdata.conquery.models.datasets.concepts.Connector; import com.bakdata.conquery.models.datasets.concepts.filters.specific.CountQuartersFilter; import com.bakdata.conquery.models.datasets.concepts.select.connector.specific.CountQuartersSelect; +import com.bakdata.conquery.models.events.MajorTypeId; import com.bakdata.conquery.sql.conversion.cqelement.concept.ConceptCteStep; import com.bakdata.conquery.sql.conversion.cqelement.concept.ConnectorSqlTables; import com.bakdata.conquery.sql.conversion.cqelement.concept.FilterContext; +import com.bakdata.conquery.sql.conversion.dialect.Interval; import com.bakdata.conquery.sql.conversion.dialect.SqlFunctionProvider; +import com.bakdata.conquery.sql.conversion.forms.StratificationFunctions; +import com.bakdata.conquery.sql.conversion.model.ColumnDateRange; import com.bakdata.conquery.sql.conversion.model.filter.CountCondition; import com.bakdata.conquery.sql.conversion.model.filter.FilterConverter; import com.bakdata.conquery.sql.conversion.model.filter.SqlFilters; @@ -25,20 +31,31 @@ import org.jooq.Param; import org.jooq.impl.DSL; -public class CountQuartersSqlAggregator implements SelectConverter, FilterConverter { +public class CountQuartersSqlAggregator implements SelectConverter, FilterConverter, SqlAggregator { @Override public ConnectorSqlSelects connectorSelect(CountQuartersSelect countQuartersSelect, SelectContext selectContext) { - Column countColumn = countQuartersSelect.getColumn(); String alias = selectContext.getNameGenerator().selectName(countQuartersSelect); ConnectorSqlTables tables = selectContext.getTables(); SqlFunctionProvider functionProvider = selectContext.getFunctionProvider(); - - CommonAggregationSelect countAggregationSelect = createCountQuartersAggregationSelect(countColumn, alias, tables, functionProvider); + StratificationFunctions stratificationFunctions = StratificationFunctions.create(selectContext.getConversionContext()); + + CommonAggregationSelect countAggregationSelect; + if (countQuartersSelect.isSingleColumnDaterange()) { + Column countColumn = countQuartersSelect.getColumn(); + countAggregationSelect = countColumn.getType() == MajorTypeId.DATE_RANGE + ? createSingleDaterangeColumnAggregationSelect(countColumn, alias, tables, functionProvider, stratificationFunctions) + : createSingleDateColumnAggregationSelect(countColumn, alias, tables, functionProvider); + } + else { + Column startColumn = countQuartersSelect.getStartColumn(); + Column endColumn = countQuartersSelect.getEndColumn(); + countAggregationSelect = createTwoDateColumnAggregationSelect(startColumn, endColumn, alias, tables, functionProvider, stratificationFunctions); + } String finalPredecessor = tables.getPredecessor(ConceptCteStep.AGGREGATION_FILTER); - ExtractingSqlSelect finalSelect = countAggregationSelect.getGroupBy().qualify(finalPredecessor); + ExtractingSqlSelect finalSelect = countAggregationSelect.getGroupBy().qualify(finalPredecessor); return ConnectorSqlSelects.builder() .preprocessingSelects(countAggregationSelect.getRootSelects()) @@ -50,18 +67,30 @@ public ConnectorSqlSelects connectorSelect(CountQuartersSelect countQuartersSele @Override public SqlFilters convertToSqlFilter(CountQuartersFilter countQuartersFilter, FilterContext filterContext) { - Column countColumn = countQuartersFilter.getColumn(); String alias = filterContext.getNameGenerator().selectName(countQuartersFilter); ConnectorSqlTables tables = filterContext.getTables(); - SqlFunctionProvider functionProvider = filterContext.getSqlDialect().getFunctionProvider(); - - CommonAggregationSelect countAggregationSelect = createCountQuartersAggregationSelect(countColumn, alias, tables, functionProvider); + SqlFunctionProvider functionProvider = filterContext.getFunctionProvider(); + StratificationFunctions stratificationFunctions = StratificationFunctions.create(filterContext.getConversionContext()); + + CommonAggregationSelect countAggregationSelect; + if (countQuartersFilter.isSingleColumnDaterange()) { + Column countColumn = countQuartersFilter.getColumn(); + countAggregationSelect = countColumn.getType() == MajorTypeId.DATE_RANGE + ? createSingleDaterangeColumnAggregationSelect(countColumn, alias, tables, functionProvider, stratificationFunctions) + : createSingleDateColumnAggregationSelect(countColumn, alias, tables, functionProvider); + } + else { + Column startColumn = countQuartersFilter.getStartColumn(); + Column endColumn = countQuartersFilter.getEndColumn(); + countAggregationSelect = createTwoDateColumnAggregationSelect(startColumn, endColumn, alias, tables, functionProvider, stratificationFunctions); + } ConnectorSqlSelects selects = ConnectorSqlSelects.builder() .preprocessingSelects(countAggregationSelect.getRootSelects()) .aggregationSelect(countAggregationSelect.getGroupBy()) .build(); - Field qualifiedCountSelect = countAggregationSelect.getGroupBy().qualify(tables.getPredecessor(ConceptCteStep.AGGREGATION_FILTER)).select(); + String predecessorTableName = tables.getPredecessor(ConceptCteStep.AGGREGATION_FILTER); + Field qualifiedCountSelect = countAggregationSelect.getGroupBy().qualify(predecessorTableName).select(); CountCondition countCondition = new CountCondition(qualifiedCountSelect, filterContext.getValue()); WhereClauses whereClauses = WhereClauses.builder() .groupFilter(countCondition) @@ -76,7 +105,7 @@ public Condition convertForTableExport(CountQuartersFilter filter, FilterContext return new CountCondition(field, filterContext.getValue()).condition(); } - private CommonAggregationSelect createCountQuartersAggregationSelect( + private static CommonAggregationSelect createSingleDateColumnAggregationSelect( Column countColumn, String alias, ConnectorSqlTables tables, @@ -96,4 +125,62 @@ private CommonAggregationSelect createCountQuartersAggregationSelect( .build(); } + private static CommonAggregationSelect createSingleDaterangeColumnAggregationSelect( + Column countColumn, + String alias, + ConnectorSqlTables tables, + SqlFunctionProvider functionProvider, + StratificationFunctions stratificationFunctions + ) { + String rootTable = tables.getRootTable(); + ColumnDateRange daterange = ColumnDateRange.of(DSL.field(DSL.name(rootTable, countColumn.getName()))); + + Field quarterStart = stratificationFunctions.lowerBoundQuarterStart(daterange); + Field nextQuarterStart = stratificationFunctions.upperBoundQuarterEnd(daterange); + + return sumQuarterCount(quarterStart, nextQuarterStart, alias, tables, functionProvider); + } + + private static CommonAggregationSelect createTwoDateColumnAggregationSelect( + Column startColumn, + Column endColumn, + String alias, + ConnectorSqlTables tables, + SqlFunctionProvider functionProvider, + StratificationFunctions stratificationFunctions + ) { + String rootTable = tables.getRootTable(); + Field startDate = DSL.field(DSL.name(rootTable, startColumn.getName()), Date.class); + Field endDate = DSL.field(DSL.name(rootTable, endColumn.getName()), Date.class); + + Field quarterStart = stratificationFunctions.jumpToQuarterStart(startDate); + Field nextQuarterStart = stratificationFunctions.jumpToNextQuarterStart(endDate); + return sumQuarterCount(quarterStart, nextQuarterStart, alias, tables, functionProvider); + } + + private static CommonAggregationSelect sumQuarterCount( + Field quarterStart, + Field nextQuarterStart, + String alias, + ConnectorSqlTables tables, + SqlFunctionProvider functionProvider + ) { + Field quarterCount = calcQuarterCount(quarterStart, nextQuarterStart, alias, functionProvider); + FieldWrapper quarterCountWrapper = new FieldWrapper<>(quarterCount); + + Field qualifiedQuarterCount = quarterCountWrapper.qualify(tables.cteName(ConceptCteStep.EVENT_FILTER)).select(); + FieldWrapper quarterCountAggregation = new FieldWrapper<>(DSL.sum(qualifiedQuarterCount).as(alias)); + + return CommonAggregationSelect.builder() + .rootSelect(quarterCountWrapper) + .groupBy(quarterCountAggregation) + .build(); + } + + private static Field calcQuarterCount(Field quarterStart, Field nextQuarterStart, String alias, SqlFunctionProvider functionProvider) { + return functionProvider.dateDistance(ChronoUnit.MONTHS, quarterStart, nextQuarterStart) + .divide(Interval.QUARTER_INTERVAL.getAmount()) + .as(alias); + } + } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/DateDistanceSqlAggregator.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/DateDistanceSqlAggregator.java index e2b9cbcc7a..9545d3b39b 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/DateDistanceSqlAggregator.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/DateDistanceSqlAggregator.java @@ -16,6 +16,7 @@ import com.bakdata.conquery.sql.conversion.cqelement.concept.ConnectorSqlTables; import com.bakdata.conquery.sql.conversion.cqelement.concept.FilterContext; import com.bakdata.conquery.sql.conversion.dialect.SqlFunctionProvider; +import com.bakdata.conquery.sql.conversion.forms.StratificationFunctions; import com.bakdata.conquery.sql.conversion.model.ColumnDateRange; import com.bakdata.conquery.sql.conversion.model.SqlTables; import com.bakdata.conquery.sql.conversion.model.filter.DateDistanceCondition; @@ -98,11 +99,16 @@ private FieldWrapper createDateDistanceSelect( SqlTables tables, ConversionContext conversionContext ) { - if (column.getType() != MajorTypeId.DATE) { - throw new UnsupportedOperationException("Can't calculate date distance to column of type " + column.getType()); + Field startDate; + if (column.getType() == MajorTypeId.DATE) { + startDate = DSL.field(DSL.name(tables.getRootTable(), column.getName()), Date.class); + } + else { + StratificationFunctions stratificationFunctions = StratificationFunctions.create(conversionContext); + Field daterangeColumn = DSL.field(DSL.name(tables.getRootTable(), column.getName()), Date.class); + startDate = stratificationFunctions.lower(ColumnDateRange.of(daterangeColumn)); } - Field startDate = DSL.field(DSL.name(tables.getRootTable(), column.getName()), Date.class); Field endDate = getEndDate(conversionContext); SqlFunctionProvider functionProvider = conversionContext.getSqlDialect().getFunctionProvider(); diff --git a/backend/src/test/resources/tests/sql/filter/count_quarters/date_range/content.csv b/backend/src/test/resources/tests/sql/filter/count_quarters/date_range/content.csv new file mode 100644 index 0000000000..b18754ec50 --- /dev/null +++ b/backend/src/test/resources/tests/sql/filter/count_quarters/date_range/content.csv @@ -0,0 +1,6 @@ +pid,datum_start,datum_end +1,2015-01-01,2015-12-31 +2,2015-01-01,2015-01-31 +3,2015-01-01,2015-06-30 +4,2015-06-01,2015-06-30 +4,2015-01-01,2015-01-31 diff --git a/backend/src/test/resources/tests/sql/filter/count_quarters/date_range/count_quarters.json b/backend/src/test/resources/tests/sql/filter/count_quarters/date_range/count_quarters.json new file mode 100644 index 0000000000..43d3417c62 --- /dev/null +++ b/backend/src/test/resources/tests/sql/filter/count_quarters/date_range/count_quarters.json @@ -0,0 +1,76 @@ +{ + "label": "COUNT_QUARTERS on date range", + "type": "QUERY_TEST", + "sqlSpec": { + "isEnabled": true + }, + "expectedCsv": "tests/sql/filter/count_quarters/date_range/expected.csv", + "query": { + "type": "CONCEPT_QUERY", + "root": { + "type": "AND", + "children": [ + { + "ids": [ + "count" + ], + "type": "CONCEPT", + "label": "count", + "tables": [ + { + "id": "count.count_connector", + "filters": { + "filter": "count.count_connector.count_quarters_filter", + "type": "INTEGER_RANGE", + "value": { + "min": 2, + "max": 3 + } + } + } + ] + } + ] + } + }, + "concepts": [ + { + "label": "count", + "type": "TREE", + "connectors": [ + { + "label": "count_connector", + "table": "table1", + "filters": { + "name": "count_quarters_filter", + "type": "COUNT_QUARTERS", + "startColumn": "table1.datum_start", + "endColumn": "table1.datum_end" + } + } + ] + } + ], + "content": { + "tables": [ + { + "csv": "tests/sql/filter/count_quarters/date_range/content.csv", + "name": "table1", + "primaryColumn": { + "name": "pid", + "type": "STRING" + }, + "columns": [ + { + "name": "datum_start", + "type": "DATE" + }, + { + "name": "datum_end", + "type": "DATE" + } + ] + } + ] + } +} diff --git a/backend/src/test/resources/tests/sql/filter/count_quarters/date_range/expected.csv b/backend/src/test/resources/tests/sql/filter/count_quarters/date_range/expected.csv new file mode 100644 index 0000000000..23859bb09d --- /dev/null +++ b/backend/src/test/resources/tests/sql/filter/count_quarters/date_range/expected.csv @@ -0,0 +1,3 @@ +result,dates +3,{} +4,{} diff --git a/backend/src/test/resources/tests/sql/filter/count_quarters/postgres/content.csv b/backend/src/test/resources/tests/sql/filter/count_quarters/postgres/content.csv new file mode 100644 index 0000000000..8bb87b9b84 --- /dev/null +++ b/backend/src/test/resources/tests/sql/filter/count_quarters/postgres/content.csv @@ -0,0 +1,6 @@ +pid,datum +1,"2015-01-01/2016-01-01" +2,"2015-01-01/2015-02-01" +3,"2015-01-01/2015-07-01" +4,"2015-06-01/2015-07-01" +4,"2015-01-01/2015-02-01" diff --git a/backend/src/test/resources/tests/sql/filter/count_quarters/postgres/daterange_column.spec.json b/backend/src/test/resources/tests/sql/filter/count_quarters/postgres/daterange_column.spec.json new file mode 100644 index 0000000000..8abe667031 --- /dev/null +++ b/backend/src/test/resources/tests/sql/filter/count_quarters/postgres/daterange_column.spec.json @@ -0,0 +1,74 @@ +{ + "type": "QUERY_TEST", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, + "label": "COUNT_QUARTERS filter on single postgres daterange column", + "expectedCsv": "tests/sql/filter/count_quarters/postgres/expected.csv", + "query": { + "type": "CONCEPT_QUERY", + "root": { + "type": "AND", + "children": [ + { + "ids": [ + "count" + ], + "type": "CONCEPT", + "label": "count", + "tables": [ + { + "id": "count.count_connector", + "filters": { + "filter": "count.count_connector.count_quarters_filter", + "type": "INTEGER_RANGE", + "value": { + "min": 2, + "max": 3 + } + } + } + ] + } + ] + } + }, + "concepts": [ + { + "label": "count", + "type": "TREE", + "connectors": [ + { + "label": "count_connector", + "table": "table1", + "filters": { + "name": "count_quarters_filter", + "type": "COUNT_QUARTERS", + "column": "table1.datum" + } + } + ] + } + ], + "content": { + "tables": [ + { + "csv": "tests/sql/filter/count_quarters/postgres/content.csv", + "name": "table1", + "primaryColumn": { + "name": "pid", + "type": "STRING" + }, + "columns": [ + { + "name": "datum", + "type": "DATE_RANGE" + } + ] + } + ] + } +} diff --git a/backend/src/test/resources/tests/sql/filter/count_quarters/postgres/expected.csv b/backend/src/test/resources/tests/sql/filter/count_quarters/postgres/expected.csv new file mode 100644 index 0000000000..23859bb09d --- /dev/null +++ b/backend/src/test/resources/tests/sql/filter/count_quarters/postgres/expected.csv @@ -0,0 +1,3 @@ +result,dates +3,{} +4,{} diff --git a/backend/src/test/resources/tests/sql/filter/count_quarters/content.csv b/backend/src/test/resources/tests/sql/filter/count_quarters/single_date/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/count_quarters/content.csv rename to backend/src/test/resources/tests/sql/filter/count_quarters/single_date/content.csv diff --git a/backend/src/test/resources/tests/sql/filter/count_quarters/count_quarters.json b/backend/src/test/resources/tests/sql/filter/count_quarters/single_date/count_quarters.json similarity index 90% rename from backend/src/test/resources/tests/sql/filter/count_quarters/count_quarters.json rename to backend/src/test/resources/tests/sql/filter/count_quarters/single_date/count_quarters.json index 422dd9823e..52249e6352 100644 --- a/backend/src/test/resources/tests/sql/filter/count_quarters/count_quarters.json +++ b/backend/src/test/resources/tests/sql/filter/count_quarters/single_date/count_quarters.json @@ -4,7 +4,7 @@ "sqlSpec": { "isEnabled": true }, - "expectedCsv": "tests/sql/filter/count_quarters/expected.csv", + "expectedCsv": "tests/sql/filter/count_quarters/single_date/expected.csv", "query": { "type": "CONCEPT_QUERY", "root": { @@ -53,7 +53,7 @@ "content": { "tables": [ { - "csv": "tests/sql/filter/count_quarters/content.csv", + "csv": "tests/sql/filter/count_quarters/single_date/content.csv", "name": "table1", "primaryColumn": { "name": "pid", diff --git a/backend/src/test/resources/tests/sql/filter/count_quarters/expected.csv b/backend/src/test/resources/tests/sql/filter/count_quarters/single_date/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/count_quarters/expected.csv rename to backend/src/test/resources/tests/sql/filter/count_quarters/single_date/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/count_quarters/date_range/content.csv b/backend/src/test/resources/tests/sql/selects/count_quarters/date_range/content.csv new file mode 100644 index 0000000000..b18754ec50 --- /dev/null +++ b/backend/src/test/resources/tests/sql/selects/count_quarters/date_range/content.csv @@ -0,0 +1,6 @@ +pid,datum_start,datum_end +1,2015-01-01,2015-12-31 +2,2015-01-01,2015-01-31 +3,2015-01-01,2015-06-30 +4,2015-06-01,2015-06-30 +4,2015-01-01,2015-01-31 diff --git a/backend/src/test/resources/tests/sql/selects/count_quarters/date_range/count_quarters.json b/backend/src/test/resources/tests/sql/selects/count_quarters/date_range/count_quarters.json new file mode 100644 index 0000000000..ad3bdb510b --- /dev/null +++ b/backend/src/test/resources/tests/sql/selects/count_quarters/date_range/count_quarters.json @@ -0,0 +1,71 @@ +{ + "label": "COUNT_QUARTERS on date range with start and end column", + "type": "QUERY_TEST", + "sqlSpec": { + "isEnabled": true + }, + "expectedCsv": "tests/sql/selects/count_quarters/date_range/expected.csv", + "query": { + "type": "CONCEPT_QUERY", + "root": { + "type": "AND", + "children": [ + { + "ids": [ + "count" + ], + "type": "CONCEPT", + "label": "count", + "tables": [ + { + "id": "count.count_connector", + "selects": [ + "count.count_connector.count_quarters_select" + ] + } + ] + } + ] + } + }, + "concepts": [ + { + "label": "count", + "type": "TREE", + "connectors": [ + { + "label": "count_connector", + "table": "table1", + "selects": { + "name": "count_quarters_select", + "type": "COUNT_QUARTERS", + "startColumn": "table1.datum_start", + "endColumn": "table1.datum_end" + } + } + ] + } + ], + "content": { + "tables": [ + { + "csv": "tests/sql/selects/count_quarters/date_range/content.csv", + "name": "table1", + "primaryColumn": { + "name": "pid", + "type": "STRING" + }, + "columns": [ + { + "name": "datum_start", + "type": "DATE" + }, + { + "name": "datum_end", + "type": "DATE" + } + ] + } + ] + } +} diff --git a/backend/src/test/resources/tests/sql/selects/count_quarters/date_range/expected.csv b/backend/src/test/resources/tests/sql/selects/count_quarters/date_range/expected.csv new file mode 100644 index 0000000000..08b584fec0 --- /dev/null +++ b/backend/src/test/resources/tests/sql/selects/count_quarters/date_range/expected.csv @@ -0,0 +1,5 @@ +result,dates,count count_quarters_select +1,{},4 +2,{},1 +3,{},2 +4,{},2 diff --git a/backend/src/test/resources/tests/sql/selects/count_quarters/postgres/content.csv b/backend/src/test/resources/tests/sql/selects/count_quarters/postgres/content.csv new file mode 100644 index 0000000000..8bb87b9b84 --- /dev/null +++ b/backend/src/test/resources/tests/sql/selects/count_quarters/postgres/content.csv @@ -0,0 +1,6 @@ +pid,datum +1,"2015-01-01/2016-01-01" +2,"2015-01-01/2015-02-01" +3,"2015-01-01/2015-07-01" +4,"2015-06-01/2015-07-01" +4,"2015-01-01/2015-02-01" diff --git a/backend/src/test/resources/tests/sql/selects/count_quarters/postgres/daterange_column.spec.json b/backend/src/test/resources/tests/sql/selects/count_quarters/postgres/daterange_column.spec.json new file mode 100644 index 0000000000..2b24868233 --- /dev/null +++ b/backend/src/test/resources/tests/sql/selects/count_quarters/postgres/daterange_column.spec.json @@ -0,0 +1,69 @@ +{ + "type": "QUERY_TEST", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, + "label": "COUNT_QUARTERS on single postgres daterange column", + "expectedCsv": "tests/sql/selects/count_quarters/postgres/expected.csv", + "query": { + "type": "CONCEPT_QUERY", + "root": { + "type": "AND", + "children": [ + { + "ids": [ + "count" + ], + "type": "CONCEPT", + "label": "count", + "tables": [ + { + "id": "count.count_connector", + "selects": [ + "count.count_connector.count_quarters_select" + ] + } + ] + } + ] + } + }, + "concepts": [ + { + "label": "count", + "type": "TREE", + "connectors": [ + { + "label": "count_connector", + "table": "table1", + "selects": { + "name": "count_quarters_select", + "type": "COUNT_QUARTERS", + "column": "table1.datum" + } + } + ] + } + ], + "content": { + "tables": [ + { + "csv": "tests/sql/selects/count_quarters/postgres/content.csv", + "name": "table1", + "primaryColumn": { + "name": "pid", + "type": "STRING" + }, + "columns": [ + { + "name": "datum", + "type": "DATE_RANGE" + } + ] + } + ] + } +} diff --git a/backend/src/test/resources/tests/sql/selects/count_quarters/postgres/expected.csv b/backend/src/test/resources/tests/sql/selects/count_quarters/postgres/expected.csv new file mode 100644 index 0000000000..08b584fec0 --- /dev/null +++ b/backend/src/test/resources/tests/sql/selects/count_quarters/postgres/expected.csv @@ -0,0 +1,5 @@ +result,dates,count count_quarters_select +1,{},4 +2,{},1 +3,{},2 +4,{},2 diff --git a/backend/src/test/resources/tests/sql/selects/count_quarters/content.csv b/backend/src/test/resources/tests/sql/selects/count_quarters/single_date/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/count_quarters/content.csv rename to backend/src/test/resources/tests/sql/selects/count_quarters/single_date/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/count_quarters/count_quarters.json b/backend/src/test/resources/tests/sql/selects/count_quarters/single_date/count_quarters.json similarity index 88% rename from backend/src/test/resources/tests/sql/selects/count_quarters/count_quarters.json rename to backend/src/test/resources/tests/sql/selects/count_quarters/single_date/count_quarters.json index 0748005e7e..0f1613d856 100644 --- a/backend/src/test/resources/tests/sql/selects/count_quarters/count_quarters.json +++ b/backend/src/test/resources/tests/sql/selects/count_quarters/single_date/count_quarters.json @@ -4,7 +4,7 @@ "sqlSpec": { "isEnabled": true }, - "expectedCsv": "tests/sql/selects/count_quarters/expected.csv", + "expectedCsv": "tests/sql/selects/count_quarters/single_date/expected.csv", "query": { "type": "CONCEPT_QUERY", "root": { @@ -48,7 +48,7 @@ "content": { "tables": [ { - "csv": "tests/sql/selects/count_quarters/content.csv", + "csv": "tests/sql/selects/count_quarters/single_date/content.csv", "name": "table1", "primaryColumn": { "name": "pid", diff --git a/backend/src/test/resources/tests/sql/selects/count_quarters/expected.csv b/backend/src/test/resources/tests/sql/selects/count_quarters/single_date/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/count_quarters/expected.csv rename to backend/src/test/resources/tests/sql/selects/count_quarters/single_date/expected.csv