From 1ac568b1c566648e71bba0c76ed7a131f10a418e Mon Sep 17 00:00:00 2001 From: awildturtok <1553491+awildturtok@users.noreply.github.com> Date: Wed, 29 Apr 2026 11:30:36 +0200 Subject: [PATCH 1/8] Test SQL modes against all Tests (#3746) Makes SQL Integration Tests be run against all the entire suite and not just custom tests. Also fixes a lot of Bugs that were caught this way. Disables a lot of tests for Hana. Co-authored-by: Jonas Arnhold --- .../apiv1/query/ArrayConceptQuery.java | 2 + .../conquery/apiv1/query/ResultHeaders.java | 41 +++ .../query/concept/filter/FilterValue.java | 3 - .../apiv1/query/concept/specific/CQAnd.java | 6 + .../query/concept/specific/CQNegation.java | 7 +- .../apiv1/query/concept/specific/CQOr.java | 6 + .../query/concept/specific/CQTemporal.java | 6 + .../conquery/io/result/csv/CsvRenderer.java | 26 +- .../mode/local/LocalNamespaceHandler.java | 3 +- .../mode/local/SqlEntityResolver.java | 24 +- .../models/config/IdColumnConfig.java | 6 + .../filters/specific/DurationSumFilter.java | 87 +++--- .../datasets/concepts/select/Select.java | 3 + .../select/concept/ConceptColumnSelect.java | 8 + .../specific/EventDateUnionSelect.java | 9 + .../specific/EventDurationSumSelect.java | 9 + .../select/concept/specific/ExistsSelect.java | 8 + .../concept/specific/QuarterSelect.java | 9 + .../select/connector/DistinctSelect.java | 17 +- .../select/connector/FirstValueSelect.java | 5 + .../select/connector/SingleColumnSelect.java | 2 +- .../specific/CountQuartersSelect.java | 8 + .../connector/specific/CountSelect.java | 5 + .../specific/DateDistanceSelect.java | 8 + .../connector/specific/DateUnionSelect.java | 8 + .../connector/specific/DurationSumSelect.java | 24 +- .../select/connector/specific/FlagSelect.java | 8 + .../specific/MappableSingleColumnSelect.java | 58 +++- .../connector/specific/PrefixSelect.java | 8 + .../specific/QuartersInYearSelect.java | 8 + .../select/connector/specific/SumSelect.java | 8 + .../parser/specific/BooleanParser.java | 6 + .../models/query/DateAggregationMode.java | 2 +- .../TwoColumnDurationSumAggregator.java | 74 +++++ .../specific/value/AllValuesAggregator.java | 25 +- .../specific/temporal/TemporalQueryNode.java | 7 +- .../query/resultinfo/ColumnResultInfo.java | 6 + .../query/resultinfo/ExternalResultInfo.java | 10 + .../models/query/resultinfo/ResultInfo.java | 3 + .../resultinfo/SecondaryIdResultInfo.java | 6 + .../query/resultinfo/SelectResultInfo.java | 6 + .../common/DateRangeStringPrinter.java | 4 + .../printers/common/ListResultInfo.java | 6 + .../conquery/sql/conversion/Conversions.java | 23 +- .../cqelement/CQExternalConverter.java | 114 ++++--- .../cqelement/CQNegationConverter.java | 35 +-- .../conversion/cqelement/CQYesConverter.java | 14 +- .../cqelement/ConversionContext.java | 3 +- .../aggregation/AnsiSqlDateAggregator.java | 25 +- .../aggregation/DateAggregationCte.java | 9 +- .../aggregation/DateAggregationDates.java | 32 +- .../aggregation/IntermediateTableCte.java | 2 +- .../cqelement/aggregation/InvertCte.java | 2 +- .../cqelement/aggregation/MergeCte.java | 2 +- .../aggregation/NodeNoOverlapCte.java | 2 +- .../cqelement/aggregation/OverlapCte.java | 4 +- .../aggregation/PostgreSqlDateAggregator.java | 31 +- .../cqelement/aggregation/RowNumberCte.java | 2 +- .../cqelement/concept/CQConceptConverter.java | 197 ++++++------ .../cqelement/concept/ConnectorSqlTables.java | 9 +- .../cqelement/concept/EventFilterCte.java | 10 +- .../cqelement/concept/JoinBranchesCte.java | 7 +- .../cqelement/concept/PreprocessingCte.java | 10 +- .../cqelement/concept/TablePath.java | 19 +- .../AnsiSqlIntervalPacker.java | 2 +- .../sql/conversion/dialect/DialectBundle.java | 8 +- .../conversion/dialect/HanaDialectBundle.java | 34 ++- .../dialect/HanaSqlFunctionProvider.java | 124 ++++---- .../dialect/PostgreDialectBundle.java | 37 ++- .../dialect/PostgreSqlFunctionProvider.java | 198 ++++++------ .../conversion/dialect/SqlDateAggregator.java | 3 + .../dialect/SqlFunctionProvider.java | 81 ++--- .../forms/AbsoluteStratification.java | 6 +- .../forms/HanaStratificationFunctions.java | 10 +- .../PostgresStratificationFunctions.java | 18 +- .../forms/RelativeStratification.java | 12 +- .../forms/StratificationFunctions.java | 4 +- .../sql/conversion/model/ColumnDateRange.java | 22 +- .../sql/conversion/model/QueryStep.java | 6 + .../sql/conversion/model/QueryStepJoiner.java | 207 +++++++++++-- .../sql/conversion/model/Selects.java | 9 + .../sql/conversion/model/SqlIdColumns.java | 4 +- .../model/StratificationSqlIdColumns.java | 4 +- .../CountQuartersSqlAggregator.java | 202 ++++++------ .../model/aggregator/CountSqlAggregator.java | 50 ++- .../aggregator/DateDistanceSqlAggregator.java | 2 +- .../aggregator/DurationSumSqlAggregator.java | 73 +++++ .../model/aggregator/FlagSqlAggregator.java | 89 +++--- .../model/aggregator/SumSqlAggregator.java | 210 +++++++------ .../model/filter/NumberFilterConverter.java | 4 +- .../conversion/model/filter/WhereClauses.java | 8 - .../select/DateUnionSelectConverter.java | 4 +- .../model/select/DaterangeSelectUtil.java | 98 ++++-- .../model/select/DistinctSelectConverter.java | 19 +- .../select/DurationSumSelectConverter.java | 21 -- .../select/EventDateUnionSelectConverter.java | 8 +- .../EventDurationSumSelectConverter.java | 2 +- .../model/select/ExistsSqlSelect.java | 13 +- .../select/FirstValueSelectConverter.java | 4 +- .../select/LastValueSelectConverter.java | 2 +- .../conversion/model/select/SqlSelect.java | 8 + .../model/select/ValueSelectUtil.java | 13 +- .../query/ConceptQueryConverter.java | 64 ++-- .../query/FormConversionHelper.java | 23 +- .../query/TableExportQueryConverter.java | 21 +- .../sql/execution/DefaultCDateSetParser.java | 113 +++++++ .../execution/DefaultResultSetProcessor.java | 63 ++-- .../execution/DefaultSqlCDateSetParser.java | 108 ------- .../sql/execution/HanaSqlCDateSetParser.java | 38 +++ .../sql/execution/PgSqlCDateSetParser.java | 36 +++ .../sql/execution/ResultSetProcessor.java | 32 ++ .../execution/ResultSetProcessorFactory.java | 12 - .../sql/execution/SqlExecutionService.java | 11 +- .../DefaultSqlCDateSetParserTest.java | 11 +- .../integration/ConqueryIntegrationTests.java | 2 +- .../integration/IntegrationTests.java | 2 +- .../integration/common/LoadingUtil.java | 4 +- .../integration/json/ConqueryTestSpec.java | 1 + .../conquery/integration/json/SqlSpec.java | 5 +- .../integration/json/SqlTestDataImporter.java | 39 +-- .../json/WorkerTestDataImporter.java | 13 +- .../integration/sql/CsvTableImporter.java | 118 ++++--- .../dialect/PostgreSqlIntegrationTests.java | 3 +- .../integration/tests/ReusedQueryTest.java | 2 + .../conquery/io/result/ResultTestUtil.java | 5 + .../models/query/DefaultColumnNameTest.java | 6 + .../and/different_concept/and.test.json} | 0 .../and/different_concept/content_1.csv | 0 .../and/different_concept/content_2.csv | 0 .../and/different_concept/expected.csv | 0 .../same_concept/and_same_concept.test.json} | 0 .../and/same_concept/content_1.csv | 0 .../and/same_concept/expected.csv | 0 .../combined/combined.test.json} | 0 .../sql => EXCLUDED_sql}/combined/content.csv | 0 .../combined/content2.csv | 0 .../combined/expected.csv | 0 .../date_restriction_date_column/content.csv | 0 .../date_restriction_date_column.test.json} | 0 .../date_restriction_date_column/expected.csv | 0 .../content.csv | 0 ...te_restriction_no_validity_date.test.json} | 0 .../expected.csv | 0 .../date_restriction/daterange/content.csv | 0 .../daterange/daterange_column.test.json} | 0 .../date_restriction/daterange/expected.csv | 0 .../date_restriction/only_max/content.csv | 0 .../date_restriction/only_max/expected.csv | 0 .../only_max/only_max.test.json} | 0 .../date_restriction/only_min/content.csv | 0 .../date_restriction/only_min/expected.csv | 0 .../only_min/only_min.test.json} | 0 .../postgres_daterange/content.csv | 0 .../daterange_column.test.json} | 0 .../postgres_daterange/expected.csv | 0 .../date_restriction/simple_date/content.csv | 0 .../date_restriction_simple_date.test.json} | 0 .../date_restriction/simple_date/expected.csv | 0 .../SIMPLE_CQEXTERNAL_QUERY.test.json | 0 .../sql => EXCLUDED_sql}/external/content.csv | 0 .../external/expected.csv | 0 .../big_multi_select.test.json} | 0 .../filter/big_multi_select/content.csv | 0 .../filter/big_multi_select/expected.csv | 0 .../filter/count/content.csv | 0 .../filter/count/count.test.json} | 0 .../filter/count/expected.csv | 0 .../filter/count_distinct/content.csv | 0 .../count_distinct/count_distinct.test.json} | 0 .../filter/count_distinct/expected.csv | 0 .../count_quarters/date_range/content.csv | 0 .../date_range/count_quarters.test.json} | 0 .../count_quarters/date_range/expected.csv | 0 .../count_quarters/postgres/content.csv | 0 .../postgres/daterange_column.test.json} | 0 .../count_quarters/postgres/expected.csv | 0 .../count_quarters/single_date/content.csv | 0 .../single_date/count_quarters.test.json} | 0 .../count_quarters/single_date/expected.csv | 0 .../centuries/centuries.test.json} | 0 .../date_distance/centuries/content.csv | 0 .../date_distance/centuries/expected.csv | 0 .../days_with_date_restriction/content.csv | 0 .../days_with_date_restriction.test.json} | 0 .../days_with_date_restriction/expected.csv | 0 .../days_without_date_restriction/content.csv | 0 .../days_without_date_restriction.test.json} | 0 .../expected.csv | 0 .../filter/date_distance/decades/content.csv | 0 .../date_distance/decades/decades.test.json} | 0 .../filter/date_distance/decades/expected.csv | 0 .../filter/date_distance/months/content.csv | 0 .../filter/date_distance/months/expected.csv | 0 .../date_distance/months/months.test.json} | 0 .../filter/date_distance/years/content.csv | 0 .../filter/date_distance/years/expected.csv | 0 .../date_distance/years/years.test.json} | 0 .../filter/flag/content.csv | 0 .../filter/flag/expected.csv | 0 .../filter/flag/flag.test.json} | 0 .../filter/multi_select/content.csv | 0 .../filter/multi_select/expected.csv | 0 .../multi_select/multi_select.test.json} | 0 .../filter/number/content.csv | 0 .../filter/number/expected.csv | 0 .../filter/number/number.test.json} | 0 .../number_money/integer_range/content.csv | 2 +- .../number_money/integer_range/expected.csv | 0 .../integer_range/number_money.test.json} | 0 .../filter/number_only_max/content.csv | 0 .../filter/number_only_max/expected.csv | 0 .../number_only_max.test.json} | 0 .../filter/number_only_min/content.csv | 0 .../filter/number_only_min/expected.csv | 0 .../number_only_min.test.json} | 0 .../filter/single_select/content.csv | 0 .../filter/single_select/expected.csv | 0 .../single_select/single_select.test.json} | 0 .../filter/sum/content.csv | 0 .../filter/sum/diffsum/content.csv | 0 .../filter/sum/diffsum/diffsum.test.json} | 0 .../filter/sum/diffsum/expected.csv | 0 .../filter/sum/distinct/content.csv | 0 .../sum/distinct/distinct-sum.test.json} | 0 .../filter/sum/distinct/expected.csv | 0 .../filter/sum/expected.csv | 0 .../filter/sum/sum.test.json} | 0 .../ABSOLUT/ALIGNMENT/QUARTER YEAR.test.json} | 0 .../ABSOLUT/ALIGNMENT/QUARTER_DAY.test.json} | 0 .../ABSOLUT/ALIGNMENT/YEAR QUARTER.test.json} | 0 .../ABSOLUT/ALIGNMENT/YEAR YEAR.test.json} | 0 .../form/ABSOLUT/ALIGNMENT/quarter_day.csv | 0 .../form/ABSOLUT/ALIGNMENT/quarter_year.csv | 0 .../ALIGNMENT/year_quarter_expected.csv | 0 .../ABSOLUT/ALIGNMENT/year_year_expected.csv | 0 .../MULTIPLE_FEATURES.test.json} | 0 ...MULTIPLE_FEATURES_AND_CONNECTOR.test.json} | 0 .../MULTIPLE_FEATURES_OR_CONNECTOR.test.json} | 0 .../ABSOLUT/MULTIPLE_FEATURES/expected.csv | 0 .../expected_and_connector.csv | 0 .../expected_or_connector.csv | 0 .../ABS_EXPORT_FORM_SECONDARY_ID.test.json} | 0 .../ABSOLUT/SIMPLE/ABS_EXPORT_FORM.test.json} | 0 .../ABS_EXPORT_FORM_WITH_SELECT.test.json} | 0 .../LOGICAL/ABS_EXPORT_FORM.test.json} | 0 .../ABS_EXPORT_FORM.test.json} | 0 .../SECONDARY_ID/SECONDARY_ID.test.json} | 0 .../SIMPLE/ABS_EXPORT_FORM.test.json} | 0 .../ABS_EXPORT_FORM_WITH_SELECT.test.json} | 0 .../FULL_EXPORT_FORM_SECONDARY_ID.test.json} | 0 .../form/FULL_EXPORT_FORM/expected.csv | 0 .../RELATIVE/DAYS_NEUTRAL/DAYS.test.json} | 3 +- .../form/RELATIVE/DAYS_NEUTRAL/expected.csv | 0 .../QUARTERS_AFTER/REL_EXPORT_FORM.test.json} | 3 +- .../form/RELATIVE/QUARTERS_AFTER/expected.csv | 0 .../REL_EXPORT_FORM.test.json} | 3 +- .../RELATIVE/QUARTERS_NEUTRAL/expected.csv | 0 .../SECONDARY_ID/SECONDARY_ID.test.json} | 0 .../SIMPLE/REL_EXPORT_FORM.test.json} | 3 +- .../multiple_tables/au-content.csv | 0 .../multiple_tables/expected.csv | 0 .../multiple_tables/kh-content.csv | 0 .../multiple_tables.test.json} | 0 .../sql => EXCLUDED_sql}/nested/content1.csv | 0 .../sql => EXCLUDED_sql}/nested/content2.csv | 0 .../sql => EXCLUDED_sql}/nested/expected.csv | 0 .../nested/nested.test.json} | 0 .../sql => EXCLUDED_sql}/not/content.csv | 0 .../sql => EXCLUDED_sql}/not/expected.csv | 0 .../not/not.test.json} | 0 .../not/with_sibling/content.csv | 0 .../not/with_sibling/expected.csv | 0 .../not/with_sibling/not.test.json} | 0 .../or/different_concept/content_1.csv | 0 .../or/different_concept/content_2.csv | 0 .../or/different_concept/expected.csv | 0 .../or/different_concept/or.test.json} | 0 .../or/same_concept/content_1.csv | 0 .../or/same_concept/expected.csv | 0 .../same_concept/or_same_concept.test.json} | 0 .../secondary_id/SECONDARY_IDS.test.json} | 0 .../secondary_id/content.csv | 0 .../secondary_id/content2.csv | 0 .../SECONDARY_IDS.test.json} | 0 .../date_mode_logical/content.csv | 0 .../date_mode_logical/content2.csv | 0 .../date_mode_logical/expected.csv | 0 .../SECONDARY_IDS_EXCLUDED.test.json} | 0 .../secondary_id/expected.csv | 0 .../mixed/SECONDARY_IDS_MIXED.test.json} | 0 .../secondary_id/mixed/content.csv | 0 .../secondary_id/mixed/content2.csv | 0 .../secondary_id/mixed/expected.csv | 0 .../selects/concept_values/content.csv | 0 .../selects/concept_values/content2.csv | 0 .../selects/concept_values/expected.csv | 0 .../single_connector.test.json} | 0 .../concept_values/two_connectors.test.json} | 0 .../selects/count/content.csv | 0 .../selects/count/count.test.json} | 0 .../selects/count/expected.csv | 0 .../selects/count_distinct/content.csv | 0 .../count_distinct/count_distinct.test.json} | 0 .../selects/count_distinct/expected.csv | 0 .../count_quarters/date_range/content.csv | 0 .../date_range/count_quarters.test.json} | 0 .../count_quarters/date_range/expected.csv | 0 .../count_quarters/postgres/content.csv | 0 .../postgres/daterange_column.test.json} | 0 .../count_quarters/postgres/expected.csv | 0 .../count_quarters/single_date/content.csv | 0 .../single_date/count_quarters.test.json} | 0 .../count_quarters/single_date/expected.csv | 0 .../centuries/centuries.test.json} | 0 .../date_distance/centuries/content.csv | 0 .../date_distance/centuries/expected.csv | 0 .../days_with_date_restriction/content.csv | 0 .../days_with_date_restriction.test.json} | 0 .../days_with_date_restriction/expected.csv | 0 .../days_without_date_restriction/content.csv | 0 .../days_without_date_restriction.test.json} | 0 .../expected.csv | 0 .../selects/date_distance/decades/content.csv | 0 .../date_distance/decades/decades.test.json} | 0 .../date_distance/decades/expected.csv | 0 .../selects/date_distance/months/content.csv | 0 .../selects/date_distance/months/expected.csv | 0 .../date_distance/months/months.test.json} | 0 .../selects/date_distance/years/content.csv | 0 .../selects/date_distance/years/expected.csv | 0 .../date_distance/years/years.test.json} | 0 .../selects/date_union/content.csv | 0 .../selects/date_union/date_union.test.json} | 0 .../selects/date_union/expected.csv | 0 .../selects/distinct/content.csv | 0 .../selects/distinct/distinct.test.json} | 0 .../selects/distinct/expected.csv | 0 .../exists/exists_on_connector/content_1.csv | 0 .../exists/exists_on_connector/content_2.csv | 0 .../exists/exists_on_connector/content_3.csv | 0 .../exists_on_connector/exists.test.json} | 0 .../exists/exists_on_connector/expected.csv | 0 .../exists_with_other_selects/content.csv | 0 .../exists_with_other_selects.test.json} | 0 .../exists_with_other_selects/expected.csv | 0 .../selects/exists/single_exists/content.csv | 0 .../exists/single_exists/exists.test.json} | 0 .../selects/exists/single_exists/expected.csv | 0 .../selects/first/date/content.csv | 0 .../selects/first/date/expected.csv | 0 .../selects/first/date/number_date.test.json} | 0 .../selects/first/money/content.csv | 2 +- .../selects/first/money/expected.csv | 0 .../first/money/number_money.test.json} | 0 .../selects/first/number/content.csv | 0 .../selects/first/number/expected.csv | 0 .../selects/first/number/first.test.json} | 0 .../selects/flag/content.csv | 0 .../selects/flag/expected.csv | 0 .../selects/flag/flag.test.json} | 0 .../selects/last/content.csv | 0 .../selects/last/expected.csv | 0 .../selects/last/last.test.json} | 0 .../selects/random/content.csv | 0 .../selects/random/expected.csv | 0 .../selects/random/random.test.json} | 0 .../selects/same_select_2_times/content.csv | 0 .../selects/same_select_2_times/expected.csv | 0 .../same_select.test.json} | 0 .../selects/sum/content.csv | 0 .../selects/sum/diffsum/content.csv | 0 .../selects/sum/diffsum/diffsum.test.json} | 0 .../selects/sum/diffsum/expected.csv | 0 .../selects/sum/distinct/content.csv | 0 .../sum/distinct/distinct-sum.test.json} | 0 .../selects/sum/distinct/expected.csv | 0 .../selects/sum/duration_sum/content.csv | 0 .../sum/duration_sum/duration_sum.test.json} | 0 .../selects/sum/duration_sum/expected.csv | 0 .../sum/event_duration_sum/content.csv | 0 .../duration_sum.test.json} | 0 .../sum/event_duration_sum/expected.csv | 0 .../selects/sum/expected.csv | 0 .../selects/sum/sum.test.json} | 0 .../aggregation/block/and/content_1.csv | 0 .../aggregation/block/and/content_2.csv | 0 .../aggregation/block/and/expected.csv | 0 .../aggregation/block/and/none.test.json} | 0 .../aggregation/block/not/content_1.csv | 0 .../aggregation/block/not/expected.csv | 0 .../aggregation/block/not/negate.test.json} | 0 .../aggregation/intersect/content_1.csv | 0 .../aggregation/intersect/content_2.csv | 0 .../aggregation/intersect/expected.csv | 0 .../intersect/intersect.test.json} | 0 .../aggregation/merge/content_1.csv | 0 .../aggregation/merge/content_2.csv | 0 .../aggregation/merge/expected.csv | 0 .../aggregation/merge/merge.test.json} | 0 .../aggregation/negate/content_1.csv | 0 .../aggregation/negate/expected.csv | 0 .../aggregation/negate/negate.test.json} | 0 .../no_validity_date/content_1.csv | 0 .../no_validity_date/content_2.csv | 0 .../aggregation/no_validity_date/expected.csv | 0 .../no_validity_date.test.json} | 0 .../aggregation/only_1_date/content_1.csv | 0 .../aggregation/only_1_date/content_2.csv | 0 .../aggregation/only_1_date/expected.csv | 0 .../only_1_date/only_1_date.test.json} | 0 .../selects/validity_date/default/content.csv | 0 .../validity_date/default/expected.csv | 0 .../default/validity_date_default.test.json} | 0 ..._DATE_AGGREGATOR_NO_RESTRICTION.test.json} | 0 ...ENT_DATE_AGGREGATOR_RESTRICTION.test.json} | 0 .../event_date_union/content.csv | 0 .../expected_no_restriction.csv | 0 .../event_date_union/expected_restriction.csv | 0 .../content.csv | 0 .../expected.csv | 0 .../validity_date_excluded.test.json} | 0 .../validity_date/multirange/content.csv | 0 .../validity_date/multirange/expected.csv | 0 .../multirange/multi_range.test.json} | 0 .../tree/nested/content.csv | 0 .../tree/nested/expected.csv | 0 .../tree/nested/nested.test.json} | 0 .../tree/prefix_range/expected.csv | 0 .../tree/prefix_range/kh-content.csv | 0 .../tree/prefix_range/prefix_range.test.json} | 0 .../tree/with_parent/content.csv | 0 .../tree/with_parent/expected.csv | 0 .../tree/with_parent/with_parent.test.json} | 0 .../yes/cqyes.test.json} | 2 +- .../resources/EXCLUDED_sql/yes/entities.csv | 8 + .../sql => EXCLUDED_sql}/yes/expected.csv | 0 .../src/test/resources/shared/entities.csv | 16 +- .../test/resources/shared/entities.table.json | 4 +- .../CONCEPT_VALUES.test.json | 3 + .../CONCEPT_VALUES_RESOLVED.test.json | 3 + .../SIMPLE_VIRTUAL_CONCEPT_Query.test.json | 6 + .../DATE_DISTANCE.test.json | 11 +- .../DATE_DISTANCE2.test.json | 11 +- .../DATE_DISTANCE_AGGREGATOR/content.csv | 22 +- .../DURATION_SUM.test.json | 6 + .../DURATION_SUM.test.json | 8 +- ...T_DATE_AGGREGATOR_NO_RESTRICTION.test.json | 6 + ...VENT_DATE_AGGREGATOR_RESTRICTION.test.json | 6 + .../EXISTS_AGGREGATOR/NUMBER.test.json | 6 + .../AND.test.json | 3 + .../EXISTS_AGGREGATOR_OR/NUMBER.test.json | 6 + .../SIMPLE_VIRTUAL_CONCEPT_Query.test.json | 6 + .../aggregator/FIRST_AGGREGATOR/content.csv | 2 - .../FLAGS_AGGREGATOR.test.json | 48 ++- .../aggregator/FLAGS_AGGREGATOR/content.csv | 16 +- .../aggregator/FLAGS_AGGREGATOR/expected.csv | 14 +- .../SIMPLE_VIRTUAL_CONCEPT_Query.test.json | 6 + .../SIMPLE_VIRTUAL_CONCEPT_Query.test.json | 6 + .../SIMPLE_VIRTUAL_CONCEPT_Query.test.json | 8 +- .../SIMPLE_VIRTUAL_CONCEPT_Query.test.json | 140 +++++---- .../SIMPLE_VIRTUAL_CONCEPT_Query.test.json | 6 + .../SIMPLE_VIRTUAL_CONCEPT_Query.test.json | 3 + .../SIMPLE_VIRTUAL_CONCEPT_Query.test.json | 6 + .../SIMPLE_VIRTUAL_CONCEPT_Query.test.json | 6 + .../SUBSTRING/DISTINCT/MAPPED.test.json | 6 + .../SUBSTRING/DISTINCT/SIMPLE.test.json | 6 + .../SUBSTRING/DISTINCT/expected-mapped.csv | 2 +- .../SUBSTRING/DISTINCT/expected-simple.csv | 2 +- .../SUBSTRING/DISTINCT_MULTI/MAPPED.test.json | 6 + .../SUBSTRING/DISTINCT_MULTI/expected.csv | 2 +- .../SUBSTRING/FIRST/MAPPED.test.json | 148 ++++----- .../SUBSTRING/FIRST/SIMPLE.test.json | 6 + .../tests/aggregator/SUBSTRING/content.csv | 4 +- .../aggregator/VALUES_AGGREGATOR/expected.csv | 2 +- .../tests/filter/COUNT/COUNT.test.json | 2 +- .../filter/COUNT/content_COUNT_Filter.csv | 72 ++--- .../filter/COUNT/expected_COUNT_Filter.csv | 4 +- .../filter/COUNT_DISTINCT/COUNT.test.json | 2 +- .../COUNT_DISTINCT/content_COUNT_Filter.csv | 72 ++--- .../COUNT_DISTINCT/expected_COUNT_Filter.csv | 4 +- .../COUNT_DISTINCT_MULTI/COUNT.test.json | 8 +- .../content_COUNT_Filter.csv | 64 ++-- .../expected_COUNT_Filter.csv | 4 +- .../COUNT_QUARTERS/COUNT_QUARTERS.test.json | 2 +- .../content_COUNT_QUARTERS_Filter.csv | 76 ++--- .../expected_COUNT_QUARTERS_Filter.csv | 12 +- .../COUNT_QUARTERS.test.json | 6 + .../tests/filter/COUNTfalse/COUNT.test.json | 6 + .../COUNTfalse/content_COUNT_Filter.csv | 72 ++--- .../COUNTfalse/expected_COUNT_Filter.csv | 4 +- .../DURATION_SUM/DURATION_SUM.test.json | 6 + .../DURATION_SUM_2/DURATION_SUM_2.test.json | 6 + .../DURATION_SUM.test.json | 6 + .../FLAGS_FILTER/FLAGS_FILTER.test.json | 18 +- .../tests/filter/FLAGS_FILTER/content.csv | 16 +- .../tests/filter/FLAGS_FILTER/expected.csv | 10 +- .../filter/NUMBER_INTEGER2/NUMBER.test.json | 41 --- .../NUMBER_INTEGER2/content_NUMBER_Filter.csv | 2 - .../expected_NUMBER_Filter.csv | 2 - .../NUMBER_REAL_MISSING/NUMBER.test.json | 2 +- .../content_NUMBER_Filter.csv | 4 +- .../expected_NUMBER_Filter.csv | 2 +- .../tests/filter/PREFIX/PREFIX.test.json | 3 + .../QUARTERS_IN_YEAR.test.json | 5 + .../content_QUARTERS_IN_YEAR_Filter.csv | 98 +++--- .../expected_QUARTERS_IN_YEAR_Filter.csv | 14 +- .../filter/SELECT_SUBSTRING/SELECT.test.json | 5 + .../ABS_EXPORT_FORM_SECONDARY_ID.test.json | 160 +++++----- .../ABSOLUT/SIMPLE/ABS_EXPORT_FORM.test.json | 92 +++--- .../ABS_EXPORT_FORM_WITH_SELECT.test.json | 102 ++++--- .../SIMPLE_DATE_RESTRICTION/AND_DR.test.json | 6 + .../SIMPLE_DATE_RESTRICTION/DR_AND.test.json | 6 + .../LOGICAL/ABS_EXPORT_FORM.test.json | 6 + .../ABS_EXPORT_FORM.test.json | 6 + .../SECONDARY_ID/SECONDARY_ID.test.json | 6 + .../SIMPLE/ABS_EXPORT_FORM.test.json | 6 + .../ABS_EXPORT_FORM_WITH_SELECT.test.json | 6 + .../SECONDARY_ID/SECONDARY_ID.test.json | 6 + .../RELATIVE/SIMPLE/REL_EXPORT_FORM.test.json | 6 + .../FULL_EXPORT_FORM_SECONDARY_ID.test.json | 6 + .../tests/form/shared/vers_stamm.csv | 2 +- .../ARRAY_CONCEPT_QUERY/ARRAY_Query.test.json | 199 ++++++------ ...ATE_RESTRICTION_OR_CONCEPT_QUERY.test.json | 165 +++++----- .../SIMPLE_TREECONCEPT_Query.test.json | 13 +- .../CONCEPT_RESTRICTION.test.json | 6 + ...RESTRICTION_WITHOUT_VALIDITYDATE.test.json | 172 ++++++----- .../CONCEPT_RESTRICTION.test.json | 6 + .../CONCEPT_WITHOUT_VALIDITYDATE.test.json | 149 ++++----- .../SIMPLE_CQEXTERNAL_QUERY.test.json | 6 + .../tests/query/CQYES/CQYES.test.json | 6 + .../DATE_DISTANCE/DATE_DISTANCE.test.json | 198 ++++++------ .../DATE_DISTANCE_ERSTER.test.json | 45 ++- .../DATE_DISTANCE_LETZTER.test.json | 6 + .../DATE_DISTANCE.test.json | 6 + .../DATE_DISTANCE_ERSTER.test.json | 6 + .../DATE_DISTANCE_LETZTER.test.json | 6 + .../DATE_DISTANCE.test.json | 6 + .../DATE_DISTANCE_ERSTER.test.json | 6 + .../DATE_DISTANCE_LETZTER.test.json | 6 + ...ION_SUM_EMPTY_DATE_CONCEPT_QUERY.test.json | 6 + .../SIMPLE_TREECONCEPT_Query.json | 4 +- .../query/ENTITY_EXPORT_TESTS/expected.csv | 3 +- .../SIMPLE_CQEXTERNAL_QUERY.test.json | 34 +-- .../content.csv | 3 - .../expected.csv | 0 .../SIMPLE_TREECONCEPT_Query.test.json | 6 + .../SIMPLE_TREECONCEPT_Query.test.json | 6 + .../SIMPLE_TREECONCEPT_Query.test.json | 6 + .../SIMPLE_TREECONCEPT_Query.test.json | 6 + .../SIMPLE_TREECONCEPT_Query.test.json | 6 + .../SIMPLE_TREECONCEPT_Query.test.json | 84 +++++ .../LOGICAL/NEGATION_LOGICAL/content.csv | 13 + .../LOGICAL/NEGATION_LOGICAL/expected.csv | 3 + .../SIMPLE_TREECONCEPT_Query.test.json | 105 +++++++ .../OR_NEGATION_DATE_LOGICAL/content.csv | 17 ++ .../OR_NEGATION_DATE_LOGICAL/expected.csv | 6 + ...ABLES_ICD_KH_AU_QUERY_ohneFilter.test.json | 6 + ...ATE_RESTRICTION_OR_CONCEPT_QUERY.test.json | 6 + ...ATE_RESTRICTION_OR_CONCEPT_QUERY.test.json | 171 +++++------ .../tests/query/NUMBER/NUMBER.test.json | 6 + .../query/NUMBER_MISSING/NUMBER.test.json | 6 + .../NUMBER.test.json | 6 + .../NUMBER2.test.json | 6 + .../query/NUMBER_NEGATION/NUMBER.test.json | 170 ++++++----- .../query/NUMBER_SEMICOLON/NUMBER.test.json | 3 + .../NUMBER_STRING_PARSER/NUMBER.test.json | 6 + .../NUMBER.test.json | 6 + .../SIMPLE_TREECONCEPT_Query.json | 9 +- .../REL_EXPORT_Query.test.json | 288 +++++++++--------- .../query/REUSED_QUERY/REUSED_Query.test.json | 46 +-- .../tests/query/REUSED_QUERY/content.csv | 44 +-- .../SECONDARY_ID/SECONDARY_IDS.test.json | 6 + .../SECONDARY_IDS.test.json | 6 + .../SECONDARY_IDS_EXCLUDED.test.json | 6 + .../SECONDARY_IDS.test.json | 6 + .../SECONDARY_IDS_MIXED.test.json | 6 + .../SIMPLE_CQEXTERNAL_QUERY.test.json | 109 ++++--- ...IMPLE_CQEXTERNAL_QUERY_START_END.test.json | 6 + ..._TREECONCEPT_GROOVY_Query_groovy.test.json | 162 +++++----- .../SUM_EMPTY_DATE_CONCEPT_QUERY.test.json | 164 +++++----- .../TABLE_EXPORT/RAW_TABLE_EXPORT.test.json | 6 + .../query/TABLE_EXPORT/TABLE_EXPORT.test.json | 3 + .../TEMPORAL/AFTER/ALL/ALL/query.test.json | 6 + .../TEMPORAL/AFTER/ALL/ANY/query.test.json | 6 + .../AFTER/ALL/EARLIEST/query.test.json | 6 + .../TEMPORAL/AFTER/ALL/LATEST/query.test.json | 6 + .../TEMPORAL/AFTER/ANY/ALL/query.test.json | 6 + .../TEMPORAL/AFTER/ANY/ANY/query.test.json | 6 + .../AFTER/ANY/EARLIEST/query.test.json | 6 + .../TEMPORAL/AFTER/ANY/LATEST/query.test.json | 6 + .../AFTER/EARLIEST/ALL/query.test.json | 6 + .../AFTER/EARLIEST/ANY/query.test.json | 6 + .../AFTER/EARLIEST/EARLIEST/query.test.json | 6 + .../AFTER/EARLIEST/LATEST/query.test.json | 6 + .../TEMPORAL/AFTER/LATEST/ALL/query.test.json | 6 + .../TEMPORAL/AFTER/LATEST/ANY/query.test.json | 6 + .../AFTER/LATEST/EARLIEST/query.test.json | 6 + .../AFTER/LATEST/LATEST/query.test.json | 6 + .../TEMPORAL/AGGREGATION/query.test.json | 6 + .../TEMPORAL/BEFORE/ALL/ALL/query.test.json | 6 + .../TEMPORAL/BEFORE/ALL/ANY/query.test.json | 6 + .../BEFORE/ALL/EARLIEST/query.test.json | 6 + .../BEFORE/ALL/LATEST/query.test.json | 6 + .../TEMPORAL/BEFORE/ANY/ALL/query.test.json | 6 + .../TEMPORAL/BEFORE/ANY/ANY/query.test.json | 6 + .../BEFORE/ANY/EARLIEST/query.test.json | 6 + .../BEFORE/ANY/LATEST/query.test.json | 6 + .../BEFORE/EARLIEST/ALL/query.test.json | 6 + .../BEFORE/EARLIEST/ANY/query.test.json | 6 + .../BEFORE/EARLIEST/EARLIEST/query.test.json | 6 + .../BEFORE/EARLIEST/LATEST/query.test.json | 6 + .../BEFORE/LATEST/ALL/query.test.json | 6 + .../BEFORE/LATEST/ANY/query.test.json | 6 + .../BEFORE/LATEST/EARLIEST/query.test.json | 6 + .../BEFORE/LATEST/LATEST/query.test.json | 6 + .../TEMPORAL/WHILE/ALL/ALL/query.test.json | 6 + .../TEMPORAL/WHILE/ALL/ANY/query.test.json | 6 + .../WHILE/ALL/EARLIEST/query.test.json | 6 + .../TEMPORAL/WHILE/ALL/LATEST/query.test.json | 6 + .../TEMPORAL/WHILE/ANY/ALL/query.test.json | 6 + .../TEMPORAL/WHILE/ANY/ANY/query.test.json | 6 + .../WHILE/ANY/EARLIEST/query.test.json | 6 + .../TEMPORAL/WHILE/ANY/LATEST/query.test.json | 6 + .../WHILE/EARLIEST/ALL/query.test.json | 6 + .../WHILE/EARLIEST/ANY/query.test.json | 6 + .../WHILE/EARLIEST/EARLIEST/query.test.json | 6 + .../WHILE/EARLIEST/LATEST/query.test.json | 6 + .../TEMPORAL/WHILE/LATEST/ALL/query.test.json | 6 + .../TEMPORAL/WHILE/LATEST/ANY/query.test.json | 6 + .../WHILE/LATEST/EARLIEST/query.test.json | 6 + .../WHILE/LATEST/LATEST/query.test.json | 6 + .../VIRTUAL_CONCEPT_REUSED_Query.test.json | 6 + .../SIMPLE_VIRTUAL_CONCEPT_Query.test.json | 8 +- .../SIMPLE_VIRTUAL_CONCEPT_Query.test.json | 6 + .../test/resources/tests/sql/yes/no-op.csv | 2 - 635 files changed, 5021 insertions(+), 3017 deletions(-) create mode 100644 backend/src/main/java/com/bakdata/conquery/models/query/queryplan/aggregators/specific/TwoColumnDurationSumAggregator.java create mode 100644 backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/DurationSumSqlAggregator.java delete mode 100644 backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/DurationSumSelectConverter.java create mode 100644 backend/src/main/java/com/bakdata/conquery/sql/execution/DefaultCDateSetParser.java delete mode 100644 backend/src/main/java/com/bakdata/conquery/sql/execution/DefaultSqlCDateSetParser.java create mode 100644 backend/src/main/java/com/bakdata/conquery/sql/execution/HanaSqlCDateSetParser.java create mode 100644 backend/src/main/java/com/bakdata/conquery/sql/execution/PgSqlCDateSetParser.java delete mode 100644 backend/src/main/java/com/bakdata/conquery/sql/execution/ResultSetProcessorFactory.java rename backend/src/test/resources/{tests/sql/and/different_concept/and.json => EXCLUDED_sql/and/different_concept/and.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/and/different_concept/content_1.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/and/different_concept/content_2.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/and/different_concept/expected.csv (100%) rename backend/src/test/resources/{tests/sql/and/same_concept/and_same_concept.json => EXCLUDED_sql/and/same_concept/and_same_concept.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/and/same_concept/content_1.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/and/same_concept/expected.csv (100%) rename backend/src/test/resources/{tests/sql/combined/combined.json => EXCLUDED_sql/combined/combined.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/combined/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/combined/content2.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/combined/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/date_restriction/date_restriction_date_column/content.csv (100%) rename backend/src/test/resources/{tests/sql/date_restriction/date_restriction_date_column/date_restriction_date_column.json => EXCLUDED_sql/date_restriction/date_restriction_date_column/date_restriction_date_column.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/date_restriction/date_restriction_date_column/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/date_restriction/date_restriction_no_validity_date/content.csv (100%) rename backend/src/test/resources/{tests/sql/date_restriction/date_restriction_no_validity_date/date_restriction_no_validity_date.json => EXCLUDED_sql/date_restriction/date_restriction_no_validity_date/date_restriction_no_validity_date.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/date_restriction/date_restriction_no_validity_date/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/date_restriction/daterange/content.csv (100%) rename backend/src/test/resources/{tests/sql/date_restriction/daterange/daterange_column.spec.json => EXCLUDED_sql/date_restriction/daterange/daterange_column.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/date_restriction/daterange/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/date_restriction/only_max/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/date_restriction/only_max/expected.csv (100%) rename backend/src/test/resources/{tests/sql/date_restriction/only_max/only_max.spec.json => EXCLUDED_sql/date_restriction/only_max/only_max.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/date_restriction/only_min/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/date_restriction/only_min/expected.csv (100%) rename backend/src/test/resources/{tests/sql/date_restriction/only_min/only_min.spec.json => EXCLUDED_sql/date_restriction/only_min/only_min.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/date_restriction/postgres_daterange/content.csv (100%) rename backend/src/test/resources/{tests/sql/date_restriction/postgres_daterange/daterange_column.spec.json => EXCLUDED_sql/date_restriction/postgres_daterange/daterange_column.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/date_restriction/postgres_daterange/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/date_restriction/simple_date/content.csv (100%) rename backend/src/test/resources/{tests/sql/date_restriction/simple_date/date_restriction_simple_date.json => EXCLUDED_sql/date_restriction/simple_date/date_restriction_simple_date.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/date_restriction/simple_date/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/external/SIMPLE_CQEXTERNAL_QUERY.test.json (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/external/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/external/expected.csv (100%) rename backend/src/test/resources/{tests/sql/filter/big_multi_select/big_multi_select.spec.json => EXCLUDED_sql/filter/big_multi_select/big_multi_select.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/big_multi_select/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/big_multi_select/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/count/content.csv (100%) rename backend/src/test/resources/{tests/sql/filter/count/count.json => EXCLUDED_sql/filter/count/count.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/count/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/count_distinct/content.csv (100%) rename backend/src/test/resources/{tests/sql/filter/count_distinct/count_distinct.json => EXCLUDED_sql/filter/count_distinct/count_distinct.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/count_distinct/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/count_quarters/date_range/content.csv (100%) rename backend/src/test/resources/{tests/sql/filter/count_quarters/date_range/count_quarters.json => EXCLUDED_sql/filter/count_quarters/date_range/count_quarters.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/count_quarters/date_range/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/count_quarters/postgres/content.csv (100%) rename backend/src/test/resources/{tests/sql/filter/count_quarters/postgres/daterange_column.spec.json => EXCLUDED_sql/filter/count_quarters/postgres/daterange_column.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/count_quarters/postgres/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/count_quarters/single_date/content.csv (100%) rename backend/src/test/resources/{tests/sql/filter/count_quarters/single_date/count_quarters.json => EXCLUDED_sql/filter/count_quarters/single_date/count_quarters.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/count_quarters/single_date/expected.csv (100%) rename backend/src/test/resources/{tests/sql/filter/date_distance/centuries/centuries.spec.json => EXCLUDED_sql/filter/date_distance/centuries/centuries.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/date_distance/centuries/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/date_distance/centuries/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/date_distance/days_with_date_restriction/content.csv (100%) rename backend/src/test/resources/{tests/sql/filter/date_distance/days_with_date_restriction/days_with_date_restriction.spec.json => EXCLUDED_sql/filter/date_distance/days_with_date_restriction/days_with_date_restriction.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/date_distance/days_with_date_restriction/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/date_distance/days_without_date_restriction/content.csv (100%) rename backend/src/test/resources/{tests/sql/filter/date_distance/days_without_date_restriction/days_without_date_restriction.json => EXCLUDED_sql/filter/date_distance/days_without_date_restriction/days_without_date_restriction.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/date_distance/days_without_date_restriction/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/date_distance/decades/content.csv (100%) rename backend/src/test/resources/{tests/sql/filter/date_distance/decades/decades.spec.json => EXCLUDED_sql/filter/date_distance/decades/decades.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/date_distance/decades/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/date_distance/months/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/date_distance/months/expected.csv (100%) rename backend/src/test/resources/{tests/sql/filter/date_distance/months/months.spec.json => EXCLUDED_sql/filter/date_distance/months/months.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/date_distance/years/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/date_distance/years/expected.csv (100%) rename backend/src/test/resources/{tests/sql/filter/date_distance/years/years.spec.json => EXCLUDED_sql/filter/date_distance/years/years.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/flag/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/flag/expected.csv (100%) rename backend/src/test/resources/{tests/sql/filter/flag/flag.spec.json => EXCLUDED_sql/filter/flag/flag.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/multi_select/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/multi_select/expected.csv (100%) rename backend/src/test/resources/{tests/sql/filter/multi_select/multi_select.spec.json => EXCLUDED_sql/filter/multi_select/multi_select.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/number/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/number/expected.csv (100%) rename backend/src/test/resources/{tests/sql/filter/number/number.spec.json => EXCLUDED_sql/filter/number/number.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/number_money/integer_range/content.csv (91%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/number_money/integer_range/expected.csv (100%) rename backend/src/test/resources/{tests/sql/filter/number_money/integer_range/number_money.spec.json => EXCLUDED_sql/filter/number_money/integer_range/number_money.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/number_only_max/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/number_only_max/expected.csv (100%) rename backend/src/test/resources/{tests/sql/filter/number_only_max/number_only_max.spec.json => EXCLUDED_sql/filter/number_only_max/number_only_max.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/number_only_min/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/number_only_min/expected.csv (100%) rename backend/src/test/resources/{tests/sql/filter/number_only_min/number_only_min.spec.json => EXCLUDED_sql/filter/number_only_min/number_only_min.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/single_select/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/single_select/expected.csv (100%) rename backend/src/test/resources/{tests/sql/filter/single_select/single_select.spec.json => EXCLUDED_sql/filter/single_select/single_select.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/sum/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/sum/diffsum/content.csv (100%) rename backend/src/test/resources/{tests/sql/filter/sum/diffsum/diffsum.spec.json => EXCLUDED_sql/filter/sum/diffsum/diffsum.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/sum/diffsum/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/sum/distinct/content.csv (100%) rename backend/src/test/resources/{tests/sql/filter/sum/distinct/distinct-sum.spec.json => EXCLUDED_sql/filter/sum/distinct/distinct-sum.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/sum/distinct/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/filter/sum/expected.csv (100%) rename backend/src/test/resources/{tests/sql/filter/sum/sum.json => EXCLUDED_sql/filter/sum/sum.test.json} (100%) rename backend/src/test/resources/{tests/sql/form/ABSOLUT/ALIGNMENT/QUARTER YEAR.json => EXCLUDED_sql/form/ABSOLUT/ALIGNMENT/QUARTER YEAR.test.json} (100%) rename backend/src/test/resources/{tests/sql/form/ABSOLUT/ALIGNMENT/QUARTER_DAY.json => EXCLUDED_sql/form/ABSOLUT/ALIGNMENT/QUARTER_DAY.test.json} (100%) rename backend/src/test/resources/{tests/sql/form/ABSOLUT/ALIGNMENT/YEAR QUARTER.json => EXCLUDED_sql/form/ABSOLUT/ALIGNMENT/YEAR QUARTER.test.json} (100%) rename backend/src/test/resources/{tests/sql/form/ABSOLUT/ALIGNMENT/YEAR YEAR.json => EXCLUDED_sql/form/ABSOLUT/ALIGNMENT/YEAR YEAR.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/form/ABSOLUT/ALIGNMENT/quarter_day.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/form/ABSOLUT/ALIGNMENT/quarter_year.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/form/ABSOLUT/ALIGNMENT/year_quarter_expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/form/ABSOLUT/ALIGNMENT/year_year_expected.csv (100%) rename backend/src/test/resources/{tests/sql/form/ABSOLUT/MULTIPLE_FEATURES/MULTIPLE_FEATURES.json => EXCLUDED_sql/form/ABSOLUT/MULTIPLE_FEATURES/MULTIPLE_FEATURES.test.json} (100%) rename backend/src/test/resources/{tests/sql/form/ABSOLUT/MULTIPLE_FEATURES/MULTIPLE_FEATURES_AND_CONNECTOR.json => EXCLUDED_sql/form/ABSOLUT/MULTIPLE_FEATURES/MULTIPLE_FEATURES_AND_CONNECTOR.test.json} (100%) rename backend/src/test/resources/{tests/sql/form/ABSOLUT/MULTIPLE_FEATURES/MULTIPLE_FEATURES_OR_CONNECTOR.json => EXCLUDED_sql/form/ABSOLUT/MULTIPLE_FEATURES/MULTIPLE_FEATURES_OR_CONNECTOR.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/form/ABSOLUT/MULTIPLE_FEATURES/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/form/ABSOLUT/MULTIPLE_FEATURES/expected_and_connector.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/form/ABSOLUT/MULTIPLE_FEATURES/expected_or_connector.csv (100%) rename backend/src/test/resources/{tests/sql/form/ABSOLUT/SECONDARY_ID/ABS_EXPORT_FORM_SECONDARY_ID.json => EXCLUDED_sql/form/ABSOLUT/SECONDARY_ID/ABS_EXPORT_FORM_SECONDARY_ID.test.json} (100%) rename backend/src/test/resources/{tests/sql/form/ABSOLUT/SIMPLE/ABS_EXPORT_FORM.json => EXCLUDED_sql/form/ABSOLUT/SIMPLE/ABS_EXPORT_FORM.test.json} (100%) rename backend/src/test/resources/{tests/sql/form/ABSOLUT/SIMPLE/ABS_EXPORT_FORM_WITH_SELECT.json => EXCLUDED_sql/form/ABSOLUT/SIMPLE/ABS_EXPORT_FORM_WITH_SELECT.test.json} (100%) rename backend/src/test/resources/{tests/sql/form/ENTITY_DATE/LOGICAL/ABS_EXPORT_FORM.json => EXCLUDED_sql/form/ENTITY_DATE/LOGICAL/ABS_EXPORT_FORM.test.json} (100%) rename backend/src/test/resources/{tests/sql/form/ENTITY_DATE/LOGICAL_WITH_EXCLUDE/ABS_EXPORT_FORM.json => EXCLUDED_sql/form/ENTITY_DATE/LOGICAL_WITH_EXCLUDE/ABS_EXPORT_FORM.test.json} (100%) rename backend/src/test/resources/{tests/sql/form/ENTITY_DATE/SECONDARY_ID/SECONDARY_ID.json => EXCLUDED_sql/form/ENTITY_DATE/SECONDARY_ID/SECONDARY_ID.test.json} (100%) rename backend/src/test/resources/{tests/sql/form/ENTITY_DATE/SIMPLE/ABS_EXPORT_FORM.json => EXCLUDED_sql/form/ENTITY_DATE/SIMPLE/ABS_EXPORT_FORM.test.json} (100%) rename backend/src/test/resources/{tests/sql/form/ENTITY_DATE/SIMPLE/ABS_EXPORT_FORM_WITH_SELECT.json => EXCLUDED_sql/form/ENTITY_DATE/SIMPLE/ABS_EXPORT_FORM_WITH_SELECT.test.json} (100%) rename backend/src/test/resources/{tests/sql/form/FULL_EXPORT_FORM/FULL_EXPORT_FORM_SECONDARY_ID.json => EXCLUDED_sql/form/FULL_EXPORT_FORM/FULL_EXPORT_FORM_SECONDARY_ID.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/form/FULL_EXPORT_FORM/expected.csv (100%) rename backend/src/test/resources/{tests/sql/form/RELATIVE/DAYS_NEUTRAL/DAYS.json => EXCLUDED_sql/form/RELATIVE/DAYS_NEUTRAL/DAYS.test.json} (92%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/form/RELATIVE/DAYS_NEUTRAL/expected.csv (100%) rename backend/src/test/resources/{tests/sql/form/RELATIVE/QUARTERS_AFTER/REL_EXPORT_FORM.json => EXCLUDED_sql/form/RELATIVE/QUARTERS_AFTER/REL_EXPORT_FORM.test.json} (92%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/form/RELATIVE/QUARTERS_AFTER/expected.csv (100%) rename backend/src/test/resources/{tests/sql/form/RELATIVE/QUARTERS_NEUTRAL/REL_EXPORT_FORM.json => EXCLUDED_sql/form/RELATIVE/QUARTERS_NEUTRAL/REL_EXPORT_FORM.test.json} (92%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/form/RELATIVE/QUARTERS_NEUTRAL/expected.csv (100%) rename backend/src/test/resources/{tests/sql/form/RELATIVE/SECONDARY_ID/SECONDARY_ID.json => EXCLUDED_sql/form/RELATIVE/SECONDARY_ID/SECONDARY_ID.test.json} (100%) rename backend/src/test/resources/{tests/sql/form/RELATIVE/SIMPLE/REL_EXPORT_FORM.json => EXCLUDED_sql/form/RELATIVE/SIMPLE/REL_EXPORT_FORM.test.json} (92%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/multiple_tables/au-content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/multiple_tables/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/multiple_tables/kh-content.csv (100%) rename backend/src/test/resources/{tests/sql/multiple_tables/multiple_tables.spec.json => EXCLUDED_sql/multiple_tables/multiple_tables.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/nested/content1.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/nested/content2.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/nested/expected.csv (100%) rename backend/src/test/resources/{tests/sql/nested/nested.spec.json => EXCLUDED_sql/nested/nested.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/not/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/not/expected.csv (100%) rename backend/src/test/resources/{tests/sql/not/not.spec.json => EXCLUDED_sql/not/not.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/not/with_sibling/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/not/with_sibling/expected.csv (100%) rename backend/src/test/resources/{tests/sql/not/with_sibling/not.spec.json => EXCLUDED_sql/not/with_sibling/not.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/or/different_concept/content_1.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/or/different_concept/content_2.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/or/different_concept/expected.csv (100%) rename backend/src/test/resources/{tests/sql/or/different_concept/or.spec.json => EXCLUDED_sql/or/different_concept/or.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/or/same_concept/content_1.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/or/same_concept/expected.csv (100%) rename backend/src/test/resources/{tests/sql/or/same_concept/or_same_concept.spec.json => EXCLUDED_sql/or/same_concept/or_same_concept.test.json} (100%) rename backend/src/test/resources/{tests/sql/secondary_id/SECONDARY_IDS.json => EXCLUDED_sql/secondary_id/SECONDARY_IDS.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/secondary_id/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/secondary_id/content2.csv (100%) rename backend/src/test/resources/{tests/sql/secondary_id/date_mode_logical/SECONDARY_IDS.json => EXCLUDED_sql/secondary_id/date_mode_logical/SECONDARY_IDS.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/secondary_id/date_mode_logical/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/secondary_id/date_mode_logical/content2.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/secondary_id/date_mode_logical/expected.csv (100%) rename backend/src/test/resources/{tests/sql/secondary_id/excluded/SECONDARY_IDS_EXCLUDED.json => EXCLUDED_sql/secondary_id/excluded/SECONDARY_IDS_EXCLUDED.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/secondary_id/expected.csv (100%) rename backend/src/test/resources/{tests/sql/secondary_id/mixed/SECONDARY_IDS_MIXED.json => EXCLUDED_sql/secondary_id/mixed/SECONDARY_IDS_MIXED.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/secondary_id/mixed/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/secondary_id/mixed/content2.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/secondary_id/mixed/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/concept_values/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/concept_values/content2.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/concept_values/expected.csv (100%) rename backend/src/test/resources/{tests/sql/selects/concept_values/single_connector.json => EXCLUDED_sql/selects/concept_values/single_connector.test.json} (100%) rename backend/src/test/resources/{tests/sql/selects/concept_values/two_connectors.json => EXCLUDED_sql/selects/concept_values/two_connectors.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/count/content.csv (100%) rename backend/src/test/resources/{tests/sql/selects/count/count.json => EXCLUDED_sql/selects/count/count.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/count/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/count_distinct/content.csv (100%) rename backend/src/test/resources/{tests/sql/selects/count_distinct/count_distinct.json => EXCLUDED_sql/selects/count_distinct/count_distinct.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/count_distinct/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/count_quarters/date_range/content.csv (100%) rename backend/src/test/resources/{tests/sql/selects/count_quarters/date_range/count_quarters.json => EXCLUDED_sql/selects/count_quarters/date_range/count_quarters.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/count_quarters/date_range/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/count_quarters/postgres/content.csv (100%) rename backend/src/test/resources/{tests/sql/selects/count_quarters/postgres/daterange_column.spec.json => EXCLUDED_sql/selects/count_quarters/postgres/daterange_column.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/count_quarters/postgres/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/count_quarters/single_date/content.csv (100%) rename backend/src/test/resources/{tests/sql/selects/count_quarters/single_date/count_quarters.json => EXCLUDED_sql/selects/count_quarters/single_date/count_quarters.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/count_quarters/single_date/expected.csv (100%) rename backend/src/test/resources/{tests/sql/selects/date_distance/centuries/centuries.spec.json => EXCLUDED_sql/selects/date_distance/centuries/centuries.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/date_distance/centuries/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/date_distance/centuries/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/date_distance/days_with_date_restriction/content.csv (100%) rename backend/src/test/resources/{tests/sql/selects/date_distance/days_with_date_restriction/days_with_date_restriction.spec.json => EXCLUDED_sql/selects/date_distance/days_with_date_restriction/days_with_date_restriction.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/date_distance/days_with_date_restriction/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/date_distance/days_without_date_restriction/content.csv (100%) rename backend/src/test/resources/{tests/sql/selects/date_distance/days_without_date_restriction/days_without_date_restriction.json => EXCLUDED_sql/selects/date_distance/days_without_date_restriction/days_without_date_restriction.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/date_distance/days_without_date_restriction/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/date_distance/decades/content.csv (100%) rename backend/src/test/resources/{tests/sql/selects/date_distance/decades/decades.spec.json => EXCLUDED_sql/selects/date_distance/decades/decades.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/date_distance/decades/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/date_distance/months/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/date_distance/months/expected.csv (100%) rename backend/src/test/resources/{tests/sql/selects/date_distance/months/months.spec.json => EXCLUDED_sql/selects/date_distance/months/months.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/date_distance/years/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/date_distance/years/expected.csv (100%) rename backend/src/test/resources/{tests/sql/selects/date_distance/years/years.spec.json => EXCLUDED_sql/selects/date_distance/years/years.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/date_union/content.csv (100%) rename backend/src/test/resources/{tests/sql/selects/date_union/date_union.json => EXCLUDED_sql/selects/date_union/date_union.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/date_union/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/distinct/content.csv (100%) rename backend/src/test/resources/{tests/sql/selects/distinct/distinct.json => EXCLUDED_sql/selects/distinct/distinct.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/distinct/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/exists/exists_on_connector/content_1.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/exists/exists_on_connector/content_2.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/exists/exists_on_connector/content_3.csv (100%) rename backend/src/test/resources/{tests/sql/selects/exists/exists_on_connector/exists.spec.json => EXCLUDED_sql/selects/exists/exists_on_connector/exists.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/exists/exists_on_connector/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/exists/exists_with_other_selects/content.csv (100%) rename backend/src/test/resources/{tests/sql/selects/exists/exists_with_other_selects/exists_with_other_selects.spec.json => EXCLUDED_sql/selects/exists/exists_with_other_selects/exists_with_other_selects.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/exists/exists_with_other_selects/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/exists/single_exists/content.csv (100%) rename backend/src/test/resources/{tests/sql/selects/exists/single_exists/exists.spec.json => EXCLUDED_sql/selects/exists/single_exists/exists.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/exists/single_exists/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/first/date/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/first/date/expected.csv (100%) rename backend/src/test/resources/{tests/sql/selects/first/date/number_date.spec.json => EXCLUDED_sql/selects/first/date/number_date.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/first/money/content.csv (88%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/first/money/expected.csv (100%) rename backend/src/test/resources/{tests/sql/selects/first/money/number_money.spec.json => EXCLUDED_sql/selects/first/money/number_money.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/first/number/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/first/number/expected.csv (100%) rename backend/src/test/resources/{tests/sql/selects/first/number/first.spec.json => EXCLUDED_sql/selects/first/number/first.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/flag/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/flag/expected.csv (100%) rename backend/src/test/resources/{tests/sql/selects/flag/flag.spec.json => EXCLUDED_sql/selects/flag/flag.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/last/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/last/expected.csv (100%) rename backend/src/test/resources/{tests/sql/selects/last/last.spec.json => EXCLUDED_sql/selects/last/last.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/random/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/random/expected.csv (100%) rename backend/src/test/resources/{tests/sql/selects/random/random.spec.json => EXCLUDED_sql/selects/random/random.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/same_select_2_times/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/same_select_2_times/expected.csv (100%) rename backend/src/test/resources/{tests/sql/selects/same_select_2_times/same_select.json => EXCLUDED_sql/selects/same_select_2_times/same_select.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/sum/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/sum/diffsum/content.csv (100%) rename backend/src/test/resources/{tests/sql/selects/sum/diffsum/diffsum.spec.json => EXCLUDED_sql/selects/sum/diffsum/diffsum.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/sum/diffsum/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/sum/distinct/content.csv (100%) rename backend/src/test/resources/{tests/sql/selects/sum/distinct/distinct-sum.spec.json => EXCLUDED_sql/selects/sum/distinct/distinct-sum.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/sum/distinct/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/sum/duration_sum/content.csv (100%) rename backend/src/test/resources/{tests/sql/selects/sum/duration_sum/duration_sum.json => EXCLUDED_sql/selects/sum/duration_sum/duration_sum.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/sum/duration_sum/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/sum/event_duration_sum/content.csv (100%) rename backend/src/test/resources/{tests/sql/selects/sum/event_duration_sum/duration_sum.json => EXCLUDED_sql/selects/sum/event_duration_sum/duration_sum.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/sum/event_duration_sum/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/sum/expected.csv (100%) rename backend/src/test/resources/{tests/sql/selects/sum/sum.json => EXCLUDED_sql/selects/sum/sum.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/aggregation/block/and/content_1.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/aggregation/block/and/content_2.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/aggregation/block/and/expected.csv (100%) rename backend/src/test/resources/{tests/sql/selects/validity_date/aggregation/block/and/none.spec.json => EXCLUDED_sql/selects/validity_date/aggregation/block/and/none.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/aggregation/block/not/content_1.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/aggregation/block/not/expected.csv (100%) rename backend/src/test/resources/{tests/sql/selects/validity_date/aggregation/block/not/negate.spec.json => EXCLUDED_sql/selects/validity_date/aggregation/block/not/negate.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/aggregation/intersect/content_1.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/aggregation/intersect/content_2.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/aggregation/intersect/expected.csv (100%) rename backend/src/test/resources/{tests/sql/selects/validity_date/aggregation/intersect/intersect.spec.json => EXCLUDED_sql/selects/validity_date/aggregation/intersect/intersect.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/aggregation/merge/content_1.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/aggregation/merge/content_2.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/aggregation/merge/expected.csv (100%) rename backend/src/test/resources/{tests/sql/selects/validity_date/aggregation/merge/merge.spec.json => EXCLUDED_sql/selects/validity_date/aggregation/merge/merge.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/aggregation/negate/content_1.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/aggregation/negate/expected.csv (100%) rename backend/src/test/resources/{tests/sql/selects/validity_date/aggregation/negate/negate.spec.json => EXCLUDED_sql/selects/validity_date/aggregation/negate/negate.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/aggregation/no_validity_date/content_1.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/aggregation/no_validity_date/content_2.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/aggregation/no_validity_date/expected.csv (100%) rename backend/src/test/resources/{tests/sql/selects/validity_date/aggregation/no_validity_date/no_validity_date.spec.json => EXCLUDED_sql/selects/validity_date/aggregation/no_validity_date/no_validity_date.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/aggregation/only_1_date/content_1.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/aggregation/only_1_date/content_2.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/aggregation/only_1_date/expected.csv (100%) rename backend/src/test/resources/{tests/sql/selects/validity_date/aggregation/only_1_date/only_1_date.spec.json => EXCLUDED_sql/selects/validity_date/aggregation/only_1_date/only_1_date.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/default/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/default/expected.csv (100%) rename backend/src/test/resources/{tests/sql/selects/validity_date/default/validity_date_default.json => EXCLUDED_sql/selects/validity_date/default/validity_date_default.test.json} (100%) rename backend/src/test/resources/{tests/sql/selects/validity_date/event_date_union/EVENT_DATE_AGGREGATOR_NO_RESTRICTION.json => EXCLUDED_sql/selects/validity_date/event_date_union/EVENT_DATE_AGGREGATOR_NO_RESTRICTION.test.json} (100%) rename backend/src/test/resources/{tests/sql/selects/validity_date/event_date_union/EVENT_DATE_AGGREGATOR_RESTRICTION.json => EXCLUDED_sql/selects/validity_date/event_date_union/EVENT_DATE_AGGREGATOR_RESTRICTION.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/event_date_union/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/event_date_union/expected_no_restriction.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/event_date_union/expected_restriction.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/excluded_from_time_aggregation/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/excluded_from_time_aggregation/expected.csv (100%) rename backend/src/test/resources/{tests/sql/selects/validity_date/excluded_from_time_aggregation/validity_date_excluded.json => EXCLUDED_sql/selects/validity_date/excluded_from_time_aggregation/validity_date_excluded.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/multirange/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/selects/validity_date/multirange/expected.csv (100%) rename backend/src/test/resources/{tests/sql/selects/validity_date/multirange/multi_range.spec.json => EXCLUDED_sql/selects/validity_date/multirange/multi_range.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/tree/nested/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/tree/nested/expected.csv (100%) rename backend/src/test/resources/{tests/sql/tree/nested/nested.spec.json => EXCLUDED_sql/tree/nested/nested.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/tree/prefix_range/expected.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/tree/prefix_range/kh-content.csv (100%) rename backend/src/test/resources/{tests/sql/tree/prefix_range/prefix_range.spec.json => EXCLUDED_sql/tree/prefix_range/prefix_range.test.json} (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/tree/with_parent/content.csv (100%) rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/tree/with_parent/expected.csv (100%) rename backend/src/test/resources/{tests/sql/tree/with_parent/with_parent.spec.json => EXCLUDED_sql/tree/with_parent/with_parent.test.json} (100%) rename backend/src/test/resources/{tests/sql/yes/cqyes.json => EXCLUDED_sql/yes/cqyes.test.json} (91%) create mode 100644 backend/src/test/resources/EXCLUDED_sql/yes/entities.csv rename backend/src/test/resources/{tests/sql => EXCLUDED_sql}/yes/expected.csv (100%) delete mode 100644 backend/src/test/resources/tests/filter/NUMBER_INTEGER2/NUMBER.test.json delete mode 100644 backend/src/test/resources/tests/filter/NUMBER_INTEGER2/content_NUMBER_Filter.csv delete mode 100644 backend/src/test/resources/tests/filter/NUMBER_INTEGER2/expected_NUMBER_Filter.csv rename backend/src/test/resources/tests/query/{CQEXTERNAL_ONLY_IDS => EXTERNAL_NEGATION}/SIMPLE_CQEXTERNAL_QUERY.test.json (69%) rename backend/src/test/resources/tests/query/{CQEXTERNAL_ONLY_IDS => EXTERNAL_NEGATION}/content.csv (55%) rename backend/src/test/resources/tests/query/{CQEXTERNAL_ONLY_IDS => EXTERNAL_NEGATION}/expected.csv (100%) create mode 100644 backend/src/test/resources/tests/query/LOGICAL/NEGATION_LOGICAL/SIMPLE_TREECONCEPT_Query.test.json create mode 100644 backend/src/test/resources/tests/query/LOGICAL/NEGATION_LOGICAL/content.csv create mode 100644 backend/src/test/resources/tests/query/LOGICAL/NEGATION_LOGICAL/expected.csv create mode 100644 backend/src/test/resources/tests/query/LOGICAL/OR_NEGATION_DATE_LOGICAL/SIMPLE_TREECONCEPT_Query.test.json create mode 100644 backend/src/test/resources/tests/query/LOGICAL/OR_NEGATION_DATE_LOGICAL/content.csv create mode 100644 backend/src/test/resources/tests/query/LOGICAL/OR_NEGATION_DATE_LOGICAL/expected.csv delete mode 100644 backend/src/test/resources/tests/sql/yes/no-op.csv diff --git a/backend/src/main/java/com/bakdata/conquery/apiv1/query/ArrayConceptQuery.java b/backend/src/main/java/com/bakdata/conquery/apiv1/query/ArrayConceptQuery.java index 05884083f2..ed1cac3541 100644 --- a/backend/src/main/java/com/bakdata/conquery/apiv1/query/ArrayConceptQuery.java +++ b/backend/src/main/java/com/bakdata/conquery/apiv1/query/ArrayConceptQuery.java @@ -26,6 +26,7 @@ import lombok.NoArgsConstructor; import lombok.NonNull; import lombok.Setter; +import lombok.ToString; import lombok.extern.slf4j.Slf4j; /** @@ -38,6 +39,7 @@ @CPSType(id = "ARRAY_CONCEPT_QUERY", base = QueryDescription.class) @Slf4j @NoArgsConstructor(access = AccessLevel.PRIVATE, onConstructor_ = {@JsonCreator}) +@ToString public class ArrayConceptQuery extends Query { @NotEmpty diff --git a/backend/src/main/java/com/bakdata/conquery/apiv1/query/ResultHeaders.java b/backend/src/main/java/com/bakdata/conquery/apiv1/query/ResultHeaders.java index 53aec081b8..3394c7e101 100644 --- a/backend/src/main/java/com/bakdata/conquery/apiv1/query/ResultHeaders.java +++ b/backend/src/main/java/com/bakdata/conquery/apiv1/query/ResultHeaders.java @@ -14,6 +14,7 @@ import com.bakdata.conquery.models.query.resultinfo.printers.common.LocalizedEnumPrinter; import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.models.types.SemanticType; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import lombok.experimental.UtilityClass; @UtilityClass @@ -27,6 +28,11 @@ public static ResultInfo datesInfo() { public String userColumnName(PrintSettings printSettings) { return C10nCache.getLocalized(ResultHeadersC10n.class, printSettings.getLocale()).dates(); } + + @Override + public ResultSetProcessor.Reader createReader(ResultSetProcessor resultSetProcessor) { + return resultSetProcessor::getDateRangeList; + } }; } @@ -39,6 +45,11 @@ public static ResultInfo historyDatesInfo() { public String userColumnName(PrintSettings printSettings) { return C10nCache.getLocalized(ResultHeadersC10n.class, printSettings.getLocale()).dates(); } + + @Override + public ResultSetProcessor.Reader createReader(ResultSetProcessor resultSetProcessor) { + return resultSetProcessor::getDateRangeList; + } }; } @@ -48,6 +59,11 @@ public static ResultInfo sourceInfo() { public String userColumnName(PrintSettings printSettings) { return C10nCache.getLocalized(ResultHeadersC10n.class, printSettings.getLocale()).source(); } + + @Override + public ResultSetProcessor.Reader createReader(ResultSetProcessor resultSetProcessor) { + return resultSetProcessor::getString; + } }; } @@ -58,6 +74,11 @@ public static ResultInfo formContextInfo() { public String userColumnName(PrintSettings printSettings) { return C10nCache.getLocalized(ResultHeadersC10n.class, printSettings.getLocale()).index(); } + + @Override + public ResultSetProcessor.Reader createReader(ResultSetProcessor resultSetProcessor) { + return resultSetProcessor::getInteger; + } }; } @@ -68,6 +89,11 @@ public static ResultInfo formDateRangeInfo() { public String userColumnName(PrintSettings printSettings) { return C10nCache.getLocalized(ResultHeadersC10n.class, printSettings.getLocale()).dateRange(); } + + @Override + public ResultSetProcessor.Reader createReader(ResultSetProcessor resultSetProcessor) { + return resultSetProcessor::getDateRange; + } }; } @@ -83,6 +109,11 @@ public Printer createPrinter(PrinterFactory printerFactory, PrintSettings printS public String userColumnName(PrintSettings printSettings) { return C10nCache.getLocalized(ResultHeadersC10n.class, printSettings.getLocale()).resolution(); } + + @Override + public ResultSetProcessor.Reader createReader(ResultSetProcessor resultSetProcessor) { + return resultSetProcessor::getString; + } }; } @@ -93,6 +124,11 @@ public static ResultInfo formEventDateInfo() { public String userColumnName(PrintSettings printSettings) { return C10nCache.getLocalized(ResultHeadersC10n.class, printSettings.getLocale()).eventDate(); } + + @Override + public ResultSetProcessor.Reader createReader(ResultSetProcessor resultSetProcessor) { + return resultSetProcessor::getDate; + } }; } @@ -108,6 +144,11 @@ public Printer createPrinter(PrinterFactory printerFactory, PrintSettings printS public String userColumnName(PrintSettings printSettings) { return C10nCache.getLocalized(ResultHeadersC10n.class, printSettings.getLocale()).observationScope(); } + + @Override + public ResultSetProcessor.Reader createReader(ResultSetProcessor resultSetProcessor) { + return resultSetProcessor::getString; + } }; } } diff --git a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/filter/FilterValue.java b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/filter/FilterValue.java index 449dd899c7..beb1fe2ae0 100644 --- a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/filter/FilterValue.java +++ b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/filter/FilterValue.java @@ -68,9 +68,6 @@ public SqlFilters convertToSqlFilter(SqlIdColumns ids, ConversionContext context FilterContext filterContext = FilterContext.forConceptConversion(ids, readValue(), context, tables); final Filter resolve = (Filter) filter.resolve(); SqlFilters sqlFilters = resolve.createConverter().convertToSqlFilter(resolve, filterContext); - if (context.isNegation()) { - return new SqlFilters(sqlFilters.getSelects(), sqlFilters.getWhereClauses().negated()); - } return sqlFilters; } diff --git a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQAnd.java b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQAnd.java index acd27bf8d1..cf9577ff15 100644 --- a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQAnd.java +++ b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQAnd.java @@ -31,6 +31,7 @@ import com.bakdata.conquery.models.query.resultinfo.FixedLabelResultInfo; import com.bakdata.conquery.models.query.resultinfo.ResultInfo; import com.bakdata.conquery.models.types.ResultType; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.bakdata.conquery.util.QueryUtils; import com.fasterxml.jackson.annotation.JsonView; import com.google.common.base.Preconditions; @@ -129,6 +130,11 @@ public String userColumnName(PrintSettings printSettings) { public String defaultColumnName(PrintSettings printSettings) { return defaultLabel(printSettings.getLocale()); } + + @Override + public ResultSetProcessor.Reader createReader(ResultSetProcessor resultSetProcessor) { + return resultSetProcessor::getBoolean; + } }); } return resultInfos; diff --git a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQNegation.java b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQNegation.java index f164832c1d..190b021d50 100644 --- a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQNegation.java +++ b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQNegation.java @@ -10,6 +10,7 @@ import com.bakdata.conquery.io.cps.CPSType; import com.bakdata.conquery.io.jackson.View; import com.bakdata.conquery.models.identifiable.ids.specific.ManagedExecutionId; +import com.bakdata.conquery.models.query.DateAggregationMode; import com.bakdata.conquery.models.query.QueryPlanContext; import com.bakdata.conquery.models.query.QueryResolveContext; import com.bakdata.conquery.models.query.Visitable; @@ -50,12 +51,12 @@ public void collectRequiredQueries(Set requiredQueries) { public void resolve(QueryResolveContext context) { Preconditions.checkNotNull(context.getDateAggregationMode()); - dateAction = determineDateAction(context); + dateAction = determineDateAction(context.getDateAggregationMode()); child.resolve(context); } - private DateAggregationAction determineDateAction(QueryResolveContext context) { - return switch (context.getDateAggregationMode()) { + public static DateAggregationAction determineDateAction(DateAggregationMode dateAggregationMode) { + return switch (dateAggregationMode) { case MERGE, NONE, INTERSECT -> DateAggregationAction.BLOCK; case LOGICAL -> DateAggregationAction.NEGATE; }; diff --git a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQOr.java b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQOr.java index eea5f58c7f..cb019ee307 100644 --- a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQOr.java +++ b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQOr.java @@ -31,6 +31,7 @@ import com.bakdata.conquery.models.query.resultinfo.FixedLabelResultInfo; import com.bakdata.conquery.models.query.resultinfo.ResultInfo; import com.bakdata.conquery.models.types.ResultType; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.bakdata.conquery.util.QueryUtils; import com.fasterxml.jackson.annotation.JsonView; import com.google.common.base.Preconditions; @@ -134,6 +135,11 @@ public String userColumnName(PrintSettings printSettings) { public String defaultColumnName(PrintSettings printSettings) { return defaultLabel(printSettings.getLocale()); } + + @Override + public ResultSetProcessor.Reader createReader(ResultSetProcessor resultSetProcessor) { + return resultSetProcessor::getBoolean; + } }); } diff --git a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQTemporal.java b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQTemporal.java index 710ac89ba9..2b1c725aee 100644 --- a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQTemporal.java +++ b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQTemporal.java @@ -32,6 +32,7 @@ import com.bakdata.conquery.models.query.resultinfo.ResultInfo; import com.bakdata.conquery.models.query.resultinfo.printers.common.ListResultInfo; import com.bakdata.conquery.models.types.ResultType; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.fasterxml.jackson.annotation.JsonView; import lombok.Data; import lombok.Setter; @@ -188,6 +189,11 @@ public List getResultInfos() { public String userColumnName(PrintSettings printSettings) { return C10N.get(ResultHeadersC10n.class, printSettings.getLocale()).temporalCompareLabel(compare.userLabel(printSettings.getLocale())); } + + @Override + public ResultSetProcessor.Reader createReader(ResultSetProcessor resultSetProcessor) { + return resultSetProcessor::getDateRangeList; + } }); } diff --git a/backend/src/main/java/com/bakdata/conquery/io/result/csv/CsvRenderer.java b/backend/src/main/java/com/bakdata/conquery/io/result/csv/CsvRenderer.java index f7d7a9422b..4da2d4f7d8 100644 --- a/backend/src/main/java/com/bakdata/conquery/io/result/csv/CsvRenderer.java +++ b/backend/src/main/java/com/bakdata/conquery/io/result/csv/CsvRenderer.java @@ -36,8 +36,9 @@ public void toCSV(List idHeaders, List infos, Stream infos, Stream results, PrintSettings printSettings, - PrinterFactory printerFactory) { + private void createCSVBody( + PrintSettings cfg, List infos, Stream results, PrintSettings printSettings, + PrinterFactory printerFactory) { final Printer[] printers = infos.stream().map(info -> info.createPrinter(printerFactory, printSettings)).toArray(Printer[]::new); results.map(result -> Pair.of(cfg.getIdMapper().map(result), result)) @@ -52,20 +53,19 @@ private void createCSVBody(PrintSettings cfg, List infos, Stream resolveIds(String[][] values, List rowIndex = field(name(ROW_INDEX), Integer.class); Field externalPrimaryColumn = field(name(SharedAliases.PRIMARY_COLUMN.getAlias()), String.class); Field innerPrimaryColumn = field(name(idColumns.findPrimaryIdColumn().getField()), String.class); - Field isResolved = when(innerPrimaryColumn.isNotNull(), val(true)) - .otherwise(false) - .as(IS_RESOLVED_ALIAS); + Field isResolved = innerPrimaryColumn.isNotNull().as(IS_RESOLVED_ALIAS); Table allIdsTable = table(name(idColumns.getTable())); + SelectConditionStep> resolveIdsQuery = context.with(unresolvedCte) .select(rowIndex, externalPrimaryColumn, isResolved) @@ -187,8 +179,8 @@ private CommonTableExpression createUnresolvedCte(String[][] values, List rowIndex = val(i).as(ROW_INDEX); - Field externalPrimaryColumn = val(resolvedId).as(SharedAliases.PRIMARY_COLUMN.getAlias()); + Field rowIndex = inline(i).as(ROW_INDEX); + Field externalPrimaryColumn = inline(resolvedId).as(SharedAliases.PRIMARY_COLUMN.getAlias()); Select> externalIdSelect = context.select(rowIndex, externalPrimaryColumn) // some dialects can't just select static values without FROM clause .from(dialect.getFunctionProvider().getNoOpTable()); diff --git a/backend/src/main/java/com/bakdata/conquery/models/config/IdColumnConfig.java b/backend/src/main/java/com/bakdata/conquery/models/config/IdColumnConfig.java index c757481494..28e0e7beb5 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/config/IdColumnConfig.java +++ b/backend/src/main/java/com/bakdata/conquery/models/config/IdColumnConfig.java @@ -17,6 +17,7 @@ import com.bakdata.conquery.models.query.resultinfo.ResultInfo; import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.models.types.SemanticType; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.fasterxml.jackson.annotation.JsonIgnore; import com.google.common.base.Functions; import com.google.common.collect.MoreCollectors; @@ -139,6 +140,11 @@ public String userColumnName(PrintSettings printSettings) { labels.size() == 1 ? labels.values().stream().collect(MoreCollectors.onlyElement()) : col.getField() ), col.getField()); } + + @Override + public ResultSetProcessor.Reader createReader(ResultSetProcessor resultSetProcessor) { + return resultSetProcessor::getString; + } }; }).collect(Collectors.toUnmodifiableList()); } diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/filters/specific/DurationSumFilter.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/filters/specific/DurationSumFilter.java index 4e2b0c9350..47d666535b 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/filters/specific/DurationSumFilter.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/filters/specific/DurationSumFilter.java @@ -1,11 +1,9 @@ package com.bakdata.conquery.models.datasets.concepts.filters.specific; import java.util.ArrayList; -import java.util.EnumSet; import java.util.List; import javax.annotation.Nullable; import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; import com.bakdata.conquery.apiv1.frontend.FrontendFilterConfiguration; import com.bakdata.conquery.apiv1.frontend.FrontendFilterType; @@ -13,6 +11,7 @@ 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.events.MajorTypeId; import com.bakdata.conquery.models.exceptions.ConceptConfigurationException; @@ -21,8 +20,10 @@ import com.bakdata.conquery.models.query.queryplan.aggregators.ColumnAggregator; import com.bakdata.conquery.models.query.queryplan.aggregators.DistinctValuesWrapperAggregator; import com.bakdata.conquery.models.query.queryplan.aggregators.specific.DurationSumAggregator; +import com.bakdata.conquery.models.query.queryplan.aggregators.specific.TwoColumnDurationSumAggregator; import com.bakdata.conquery.models.query.queryplan.filter.FilterNode; -import com.fasterxml.jackson.annotation.JsonAlias; +import com.bakdata.conquery.sql.conversion.model.aggregator.DurationSumSqlAggregator; +import com.bakdata.conquery.sql.conversion.model.filter.FilterConverter; import com.fasterxml.jackson.annotation.JsonIgnore; import io.dropwizard.validation.ValidationMethod; import lombok.Data; @@ -31,31 +32,39 @@ @Data @Slf4j @CPSType(id = "DURATION_SUM", base = Filter.class) -public class DurationSumFilter extends Filter { - - @Valid - @NotNull - @JsonAlias("column") - private final ColumnId dateRangeColumn; +public class DurationSumFilter extends Filter implements DaterangeSelectOrFilter { @Valid @Nullable - private final List distinctBy; + private List distinctBy; + @Nullable + private ColumnId column; + @Nullable + private ColumnId startColumn; + @Nullable + private ColumnId endColumn; @JsonIgnore - public EnumSet getAcceptedColumnTypes() { - return EnumSet.of(MajorTypeId.DATE_RANGE); + @Override + public List getRequiredColumns() { + List required = new ArrayList<>(); + + if (hasDistinct()) { + required.addAll(distinctBy); + } + if (column != null) { + required.add(column); + } + else { + required.add(startColumn); + required.add(endColumn); + } + return required; + } @Override public void configureFrontend(FrontendFilterConfiguration.Top f, ConqueryConfig conqueryConfig) throws ConceptConfigurationException { - MajorTypeId type = getDateRangeColumn().resolve().getType(); - if (type != MajorTypeId.DATE_RANGE) { - throw new ConceptConfigurationException(getConnector(), "DURATION_SUM filter is incompatible with columns of type " - + type - ); - } - f.setType(FrontendFilterType.Fields.INTEGER_RANGE); f.setMin(0); } @@ -67,7 +76,8 @@ private boolean hasDistinct() { @Override public FilterNode createFilterNode(Range.LongRange value) { - ColumnAggregator aggregator = new DurationSumAggregator(getDateRangeColumn().resolve()); + ColumnAggregator aggregator = getColumn() != null ? new DurationSumAggregator(getColumn().resolve()) + : new TwoColumnDurationSumAggregator(startColumn.resolve(), endColumn.resolve()); if (hasDistinct()) { aggregator = new DistinctValuesWrapperAggregator<>(aggregator, distinctBy.stream().map(ColumnId::resolve).toList()); @@ -77,29 +87,36 @@ public FilterNode createFilterNode(Range.LongRange value) { } @Override - public List getRequiredColumns() { - List required = new ArrayList<>(); - - if (hasDistinct()) { - required.addAll(distinctBy); - } - - required.add(dateRangeColumn); - return required; - + public FilterConverter createConverter() { + return new DurationSumSqlAggregator(); } + @JsonIgnore @ValidationMethod(message = "Columns do not match required Type.") public boolean isValidColumnType() { - final Column resolved = getDateRangeColumn().resolve(); - final boolean acceptable = getAcceptedColumnTypes().contains(resolved.getType()); + if (column != null) { + final Column resolved = getColumn().resolve(); + + if (!(resolved.getType().equals(MajorTypeId.DATE) || resolved.getType().equals(MajorTypeId.DATE_RANGE))) { + log.error("Column {} of type {} is not date compatible", resolved.getId(), resolved.getType()); + return false; + } + return true; + } + + if (!startColumn.resolve().getType().equals(MajorTypeId.DATE)) { + log.error("startColumn {} is not of type DATE", startColumn); + return false; + } - if (!acceptable) { - log.error("Column[{}] is of Type[{}]. Not one of [{}]", resolved.getId(), resolved.getType(), getAcceptedColumnTypes()); + if (!endColumn.resolve().getType().equals(MajorTypeId.DATE)) { + log.error("startColumn {} is not of type DATE", endColumn); + return false; } - return acceptable; + + return true; } } diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/Select.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/Select.java index d726ec4282..4a1828699e 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/Select.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/Select.java @@ -21,6 +21,7 @@ import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.sql.conversion.model.select.SelectConverter; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.fasterxml.jackson.annotation.JsonBackReference; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; @@ -121,6 +122,8 @@ public Printer createPrinter(PrinterFactory printerFactory, PrintSettings printS return printerFactory.printerFor(getResultType(), printSettings); } + public abstract ResultSetProcessor.Reader createResultSetReader(ResultSetProcessor processor); + @JsonIgnore public abstract ResultType getResultType(); diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/concept/ConceptColumnSelect.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/concept/ConceptColumnSelect.java index bdb7bbe71a..c803aaea20 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/concept/ConceptColumnSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/concept/ConceptColumnSelect.java @@ -1,5 +1,7 @@ package com.bakdata.conquery.models.datasets.concepts.select.concept; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.Set; import com.bakdata.conquery.apiv1.query.concept.specific.CQConcept; @@ -19,6 +21,7 @@ import com.bakdata.conquery.models.types.SemanticType; import com.bakdata.conquery.sql.conversion.model.select.ConceptColumnSelectConverter; import com.bakdata.conquery.sql.conversion.model.select.SelectConverter; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.fasterxml.jackson.annotation.JsonIgnore; import io.dropwizard.validation.ValidationMethod; import lombok.Data; @@ -79,4 +82,9 @@ public SelectConverter createConverter() { //TODO bind Select to converter here return new ConceptColumnSelectConverter(); } + + @Override + public ResultSetProcessor.Reader createResultSetReader(ResultSetProcessor processor) { + return processor::getString; + } } diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/concept/specific/EventDateUnionSelect.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/concept/specific/EventDateUnionSelect.java index 85ae7d8d34..1b7d1f43a4 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/concept/specific/EventDateUnionSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/concept/specific/EventDateUnionSelect.java @@ -1,5 +1,8 @@ package com.bakdata.conquery.models.datasets.concepts.select.concept.specific; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; import java.util.stream.Collectors; import com.bakdata.conquery.io.cps.CPSType; @@ -12,6 +15,7 @@ import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.sql.conversion.model.select.EventDateUnionSelectConverter; import com.bakdata.conquery.sql.conversion.model.select.SelectConverter; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; /** * Collects the event dates that are corresponding to an enclosing {@link Connector} or {@link Concept} provided in a query. @@ -48,4 +52,9 @@ public SelectConverter createConverter() { public ResultType getResultType() { return new ResultType.ListT<>(ResultType.Primitive.DATE_RANGE); } + + @Override + public ResultSetProcessor.Reader>> createResultSetReader(ResultSetProcessor processor) { + return processor::getDateRangeList; + } } diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/concept/specific/EventDurationSumSelect.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/concept/specific/EventDurationSumSelect.java index 8511f43ead..d5bb67b5c5 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/concept/specific/EventDurationSumSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/concept/specific/EventDurationSumSelect.java @@ -1,5 +1,8 @@ package com.bakdata.conquery.models.datasets.concepts.select.concept.specific; +import java.sql.ResultSet; +import java.sql.SQLException; + import com.bakdata.conquery.io.cps.CPSType; import com.bakdata.conquery.models.datasets.concepts.select.Select; import com.bakdata.conquery.models.datasets.concepts.select.concept.UniversalSelect; @@ -8,6 +11,7 @@ import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.sql.conversion.model.select.EventDurationSumSelectConverter; import com.bakdata.conquery.sql.conversion.model.select.SelectConverter; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.google.common.base.Preconditions; import lombok.AccessLevel; import lombok.NoArgsConstructor; @@ -35,6 +39,11 @@ public boolean isEventDateSelect() { return true; } + @Override + public ResultSetProcessor.Reader createResultSetReader(ResultSetProcessor processor) { + return processor::getInteger; + } + @Override public SelectConverter createConverter() { return new EventDurationSumSelectConverter(); diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/concept/specific/ExistsSelect.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/concept/specific/ExistsSelect.java index 7e66cf24a9..f02a41fd63 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/concept/specific/ExistsSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/concept/specific/ExistsSelect.java @@ -1,5 +1,7 @@ package com.bakdata.conquery.models.datasets.concepts.select.concept.specific; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.Set; import java.util.stream.Collectors; @@ -12,6 +14,7 @@ import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.sql.conversion.model.select.ExistsSelectConverter; import com.bakdata.conquery.sql.conversion.model.select.SelectConverter; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Getter; @@ -27,6 +30,11 @@ public ExistsAggregator createAggregator() { return new ExistsAggregator(getRequiredTables()); } + @Override + public ResultSetProcessor.Reader createResultSetReader(ResultSetProcessor processor) { + return processor::getBoolean; + } + @Override public SelectConverter createConverter() { return new ExistsSelectConverter(); diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/concept/specific/QuarterSelect.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/concept/specific/QuarterSelect.java index 26269c27e5..b46624ef86 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/concept/specific/QuarterSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/concept/specific/QuarterSelect.java @@ -1,5 +1,8 @@ package com.bakdata.conquery.models.datasets.concepts.select.concept.specific; +import java.sql.ResultSet; +import java.sql.SQLException; + import com.bakdata.conquery.apiv1.query.TemporalSamplerFactory; import com.bakdata.conquery.io.cps.CPSType; import com.bakdata.conquery.models.datasets.concepts.select.Select; @@ -7,6 +10,7 @@ import com.bakdata.conquery.models.query.queryplan.aggregators.Aggregator; import com.bakdata.conquery.models.query.queryplan.aggregators.specific.QuarterAggregator; import com.bakdata.conquery.models.types.ResultType; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.fasterxml.jackson.annotation.JsonCreator; import jakarta.validation.constraints.NotNull; import lombok.Data; @@ -32,4 +36,9 @@ public Aggregator createAggregator() { public ResultType getResultType() { return ResultType.Primitive.STRING; } + + @Override + public ResultSetProcessor.Reader createResultSetReader(ResultSetProcessor processor) { + return processor::getString; + } } diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/DistinctSelect.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/DistinctSelect.java index fa7fa3061f..a014283044 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/DistinctSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/DistinctSelect.java @@ -19,6 +19,7 @@ import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.sql.conversion.model.select.DistinctSelectConverter; import com.bakdata.conquery.sql.conversion.model.select.SelectConverter; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.fasterxml.jackson.annotation.JsonCreator; @CPSType(id = "DISTINCT", base = Select.class) @@ -31,7 +32,7 @@ public DistinctSelect(ColumnId column, InternToExternMapperId mapping, Range.Int @Override public Aggregator createAggregator() { - return new AllValuesAggregator<>(getColumn().resolve(), getSubstringRange()); + return new AllValuesAggregator(getColumn().resolve(), getSubstringRange()); } @Override @@ -50,14 +51,20 @@ public Printer createPrinter(PrinterFactory printerFactory, PrintSettings pri } @Override - public ResultType getResultType() { - if (getMapping() == null) { - return new ResultType.ListT<>(ResultType.resolveResultType(getColumn().resolve().getType())); + public ResultSetProcessor.Reader createResultSetReader(ResultSetProcessor processor) { + if (getMapping() != null) { + return processor::getStringList; } - return new ResultType.ListT<>(ResultType.Primitive.STRING); + return ResultSetProcessor.readerForType(getResultType(), processor); } + @Override + public ResultType getResultType() { + return new ResultType.ListT<>(ResultType.resolveResultType(getColumn().resolve().getType())); + } + + /** * Ensures that mapped values are still distinct. */ diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/FirstValueSelect.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/FirstValueSelect.java index cf74afa985..aa43ede5ae 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/FirstValueSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/FirstValueSelect.java @@ -1,5 +1,7 @@ package com.bakdata.conquery.models.datasets.concepts.select.connector; +import java.sql.ResultSet; + import com.bakdata.conquery.io.cps.CPSType; import com.bakdata.conquery.models.common.Range; import com.bakdata.conquery.models.datasets.concepts.select.Select; @@ -10,6 +12,7 @@ import com.bakdata.conquery.models.query.queryplan.aggregators.specific.value.FirstValueAggregator; import com.bakdata.conquery.sql.conversion.model.select.FirstValueSelectConverter; import com.bakdata.conquery.sql.conversion.model.select.SelectConverter; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.fasterxml.jackson.annotation.JsonCreator; @CPSType(id = "FIRST", base = Select.class) @@ -29,6 +32,8 @@ public Aggregator createAggregator() { return new FirstValueAggregator<>(getColumn().resolve(), getSubstringRange()); } + + @Override public SelectConverter createConverter() { return new FirstValueSelectConverter(); diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/SingleColumnSelect.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/SingleColumnSelect.java index cd8109782a..237e2358da 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/SingleColumnSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/SingleColumnSelect.java @@ -72,7 +72,7 @@ public boolean isValidColumnType() { return true; } - log.error("Column[{}] is of Type[{}]. Not one of [{}]", column, type, getAcceptedColumnTypes()); + log.error("Column[{}] is of Type[{}]. Not one of {} for {}", column, type, getAcceptedColumnTypes(), getClass().getSimpleName()); return false; } 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 a03861dd07..e21b695ef7 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,5 +1,7 @@ package com.bakdata.conquery.models.datasets.concepts.select.connector.specific; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.List; import javax.annotation.Nullable; @@ -15,6 +17,7 @@ import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.sql.conversion.model.aggregator.CountQuartersSqlAggregator; import com.bakdata.conquery.sql.conversion.model.select.SelectConverter; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.fasterxml.jackson.annotation.JsonCreator; import lombok.Getter; import lombok.NoArgsConstructor; @@ -61,6 +64,11 @@ public ResultType getResultType() { return ResultType.Primitive.INTEGER; } + @Override + public ResultSetProcessor.Reader createResultSetReader(ResultSetProcessor processor) { + return processor::getInteger; + } + @Override public SelectConverter createConverter() { return new CountQuartersSqlAggregator(); diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/CountSelect.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/CountSelect.java index 0c20e77498..6812eddb0a 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/CountSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/CountSelect.java @@ -15,6 +15,7 @@ import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.sql.conversion.model.aggregator.CountSqlAggregator; import com.bakdata.conquery.sql.conversion.model.select.SelectConverter; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import lombok.Data; import lombok.NoArgsConstructor; import org.jetbrains.annotations.Nullable; @@ -65,6 +66,10 @@ public SelectConverter createConverter() { return new CountSqlAggregator(); } + @Override + public ResultSetProcessor.Reader createResultSetReader(ResultSetProcessor processor) { + return processor::getInteger; + } @Override public ResultType getResultType() { diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/DateDistanceSelect.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/DateDistanceSelect.java index 4747fef16c..76bb598163 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/DateDistanceSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/DateDistanceSelect.java @@ -1,5 +1,7 @@ package com.bakdata.conquery.models.datasets.concepts.select.connector.specific; +import java.sql.ResultSet; +import java.sql.SQLException; import java.time.temporal.ChronoUnit; import java.util.EnumSet; import jakarta.validation.constraints.NotNull; @@ -14,6 +16,7 @@ import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.sql.conversion.model.aggregator.DateDistanceSqlAggregator; import com.bakdata.conquery.sql.conversion.model.select.SelectConverter; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.fasterxml.jackson.annotation.JsonCreator; import lombok.Getter; import lombok.Setter; @@ -46,6 +49,11 @@ public SelectConverter createConverter() { return new DateDistanceSqlAggregator(); } + @Override + public ResultSetProcessor.Reader createResultSetReader(ResultSetProcessor processor) { + return processor::getInteger; + } + @Override public ResultType getResultType() { return ResultType.Primitive.INTEGER; 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 127fa40e1e..43399ac6b2 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 @@ -1,5 +1,7 @@ package com.bakdata.conquery.models.datasets.concepts.select.connector.specific; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.List; import javax.annotation.Nullable; @@ -12,6 +14,7 @@ import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.sql.conversion.model.select.DateUnionSelectConverter; import com.bakdata.conquery.sql.conversion.model.select.SelectConverter; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Getter; @@ -51,6 +54,11 @@ public ResultType getResultType() { return new ResultType.ListT<>(ResultType.Primitive.DATE_RANGE); } + @Override + public ResultSetProcessor.Reader>> createResultSetReader(ResultSetProcessor processor) { + return processor::getDateRangeList; + } + @Override public SelectConverter createConverter() { return new DateUnionSelectConverter(); 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 f0397b6888..638e0738d3 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 @@ -1,5 +1,7 @@ package com.bakdata.conquery.models.datasets.concepts.select.connector.specific; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import javax.annotation.Nullable; @@ -9,14 +11,18 @@ import com.bakdata.conquery.models.datasets.concepts.select.Select; import com.bakdata.conquery.models.identifiable.ids.specific.ColumnId; import com.bakdata.conquery.models.query.queryplan.aggregators.Aggregator; +import com.bakdata.conquery.models.query.queryplan.aggregators.ColumnAggregator; import com.bakdata.conquery.models.query.queryplan.aggregators.DistinctValuesWrapperAggregator; import com.bakdata.conquery.models.query.queryplan.aggregators.specific.DurationSumAggregator; +import com.bakdata.conquery.models.query.queryplan.aggregators.specific.TwoColumnDurationSumAggregator; import com.bakdata.conquery.models.types.ResultType; -import com.bakdata.conquery.sql.conversion.model.select.DurationSumSelectConverter; +import com.bakdata.conquery.sql.conversion.model.aggregator.DurationSumSqlAggregator; import com.bakdata.conquery.sql.conversion.model.select.SelectConverter; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Data; +import lombok.NoArgsConstructor; @Data @CPSType(id = "DURATION_SUM", base = Select.class) @@ -24,12 +30,12 @@ public class DurationSumSelect extends Select implements DaterangeSelectOrFilter { @Nullable - private final ColumnId column; + private ColumnId column; @Nullable - private final ColumnId startColumn, endColumn; + private ColumnId startColumn, endColumn; - private final List distinctBy; + private List distinctBy; @Override public List getRequiredColumns() { @@ -49,6 +55,11 @@ public List getRequiredColumns() { return out; } + @Override + public ResultSetProcessor.Reader createResultSetReader(ResultSetProcessor processor) { + return processor::getInteger; + } + @JsonIgnore private boolean hasDistinct() { return distinctBy != null && !distinctBy.isEmpty(); @@ -56,7 +67,8 @@ private boolean hasDistinct() { @Override public Aggregator createAggregator() { - DurationSumAggregator aggregator = new DurationSumAggregator(getColumn().resolve()); + ColumnAggregator aggregator = getColumn() != null ? new DurationSumAggregator(getColumn().resolve()) + : new TwoColumnDurationSumAggregator(startColumn.resolve(), endColumn.resolve()); if (!hasDistinct()) { return aggregator; @@ -73,6 +85,6 @@ public ResultType getResultType() { @Override public SelectConverter createConverter() { //TODO apply distinctBy (though needs to be done once other branches are merged) - return new DurationSumSelectConverter(); + return new DurationSumSqlAggregator(); } } diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/FlagSelect.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/FlagSelect.java index 2f79121b10..2679f75364 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/FlagSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/FlagSelect.java @@ -1,5 +1,7 @@ package com.bakdata.conquery.models.datasets.concepts.select.connector.specific; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -15,6 +17,7 @@ import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.sql.conversion.model.aggregator.FlagSqlAggregator; import com.bakdata.conquery.sql.conversion.model.select.SelectConverter; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import io.dropwizard.validation.ValidationMethod; @@ -42,6 +45,11 @@ public List getRequiredColumns() { return flags.values().stream().toList(); } + @Override + public ResultSetProcessor.Reader> createResultSetReader(ResultSetProcessor processor) { + return processor::getStringList; + } + @Override public Aggregator createAggregator() { final Map collect = flags.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().resolve())); diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/MappableSingleColumnSelect.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/MappableSingleColumnSelect.java index fb2f0a8e1d..2617629536 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/MappableSingleColumnSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/MappableSingleColumnSelect.java @@ -1,5 +1,9 @@ package com.bakdata.conquery.models.datasets.concepts.select.connector.specific; +import static com.bakdata.conquery.models.types.ResultType.Primitive.STRING; +import static com.bakdata.conquery.models.types.ResultType.resolveResultType; +import static org.jooq.impl.DSL.*; + import java.util.Collections; import java.util.Set; import javax.annotation.Nullable; @@ -7,7 +11,9 @@ import com.bakdata.conquery.apiv1.query.concept.specific.CQConcept; import com.bakdata.conquery.io.jackson.View; +import com.bakdata.conquery.io.result.ResultRender.ResultRendererProvider; import com.bakdata.conquery.models.common.Range; +import com.bakdata.conquery.models.datasets.Column; import com.bakdata.conquery.models.datasets.concepts.select.connector.SingleColumnSelect; import com.bakdata.conquery.models.events.MajorTypeId; import com.bakdata.conquery.models.identifiable.ids.specific.ColumnId; @@ -19,15 +25,21 @@ import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.models.types.SemanticType; +import com.bakdata.conquery.sql.conversion.cqelement.concept.ConnectorSqlTables; +import com.bakdata.conquery.sql.conversion.model.select.FieldWrapper; +import com.bakdata.conquery.sql.conversion.model.select.SelectContext; +import com.bakdata.conquery.sql.conversion.model.select.SingleColumnSqlSelect; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.fasterxml.jackson.annotation.JsonIgnore; import io.dropwizard.validation.ValidationMethod; import lombok.Getter; +import org.jooq.Field; @Getter public abstract class MappableSingleColumnSelect extends SingleColumnSelect { /** - * If a mapping was provided the mapping changes the aggregator result before it is processed by a {@link com.bakdata.conquery.io.result.ResultRender.ResultRendererProvider}. + * If a mapping was provided the mapping changes the aggregator result before it is processed by a {@link ResultRendererProvider}. */ @Valid @Nullable @@ -45,6 +57,34 @@ public MappableSingleColumnSelect(ColumnId column, @Nullable InternToExternMappe this.substringRange = substringRange; } + public static SingleColumnSqlSelect getSubstringSelect( + Column column, Range.IntegerRange substringRange, SelectContext selectContext, + String alias) { + Field field; + + if (substringRange == null || substringRange.isAll()) { + field = field(name(selectContext.getTables().getRootTable(), column.getName()), String.class); + } + else { + field = field(name(selectContext.getTables().getRootTable(), column.getName()), String.class); + if (substringRange.isAtLeast()) { + field = substring(field, 1 + substringRange.getMin()); + } + else if (substringRange.isAtMost()) { + field = substring(field, 1, substringRange.getMax()); + } + else { + field = substring(field, 1 + substringRange.getMin(), substringRange.getMax() - substringRange.getMin()); + } + } + + if (alias != null) { + field = field.as(alias); + } + + return new FieldWrapper<>(field, column.getName()); + } + @Override public Printer createPrinter(PrinterFactory printerFactory, PrintSettings printSettings) { if (mapping == null) { @@ -69,16 +109,16 @@ public SelectResultInfo getResultInfo(CQConcept cqConcept) { @Override public ResultType getResultType() { if (mapping == null) { - return ResultType.resolveResultType(getColumn().resolve().getType()); + return resolveResultType(getColumn().resolve().getType()); } InternToExternMapper resolved = mapping.resolve(); if (resolved.isAllowMultiple()) { - return new ResultType.ListT<>(ResultType.Primitive.STRING); + return new ResultType.ListT<>(STRING); } - return ResultType.Primitive.STRING; + return STRING; } public void loadMapping() { @@ -119,4 +159,14 @@ public boolean isMinPositive() { return getSubstringRange().getMin() >= 0; } + + @Override + public ResultSetProcessor.Reader createResultSetReader(ResultSetProcessor processor) { + if (mapping != null) { + return processor::getString; + } + + return ResultSetProcessor.readerForType(getResultType(), processor); + } + } diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/PrefixSelect.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/PrefixSelect.java index 5fb858be2b..d098c9d796 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/PrefixSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/PrefixSelect.java @@ -1,5 +1,7 @@ package com.bakdata.conquery.models.datasets.concepts.select.connector.specific; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.EnumSet; import com.bakdata.conquery.io.cps.CPSType; @@ -10,6 +12,7 @@ import com.bakdata.conquery.models.query.queryplan.aggregators.Aggregator; import com.bakdata.conquery.models.query.queryplan.aggregators.specific.PrefixTextAggregator; import com.bakdata.conquery.models.types.ResultType; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.fasterxml.jackson.annotation.JsonCreator; import lombok.Getter; import lombok.Setter; @@ -37,6 +40,11 @@ public Aggregator createAggregator() { return new PrefixTextAggregator(getColumn().resolve(), prefix); } + @Override + public ResultSetProcessor.Reader createResultSetReader(ResultSetProcessor processor) { + throw new IllegalStateException("PREFIX select is not implemented for SQL mode."); + } + @Override public ResultType getResultType() { return new ResultType.ListT<>(ResultType.Primitive.STRING); diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/QuartersInYearSelect.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/QuartersInYearSelect.java index 1d3dbaf693..70f5385c5a 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/QuartersInYearSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/QuartersInYearSelect.java @@ -1,5 +1,7 @@ package com.bakdata.conquery.models.datasets.concepts.select.connector.specific; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.EnumSet; import com.bakdata.conquery.io.cps.CPSType; @@ -10,6 +12,7 @@ import com.bakdata.conquery.models.query.queryplan.aggregators.Aggregator; import com.bakdata.conquery.models.query.queryplan.aggregators.specific.QuartersInYearAggregator; import com.bakdata.conquery.models.types.ResultType; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.fasterxml.jackson.annotation.JsonCreator; /** @@ -33,6 +36,11 @@ public Aggregator createAggregator() { return new QuartersInYearAggregator(getColumn().resolve()); } + @Override + public ResultSetProcessor.Reader createResultSetReader(ResultSetProcessor processor) { + return processor::getInteger; + } + @Override public ResultType getResultType() { return ResultType.Primitive.INTEGER; diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/SumSelect.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/SumSelect.java index bc50b24deb..c620a327a8 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/SumSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/SumSelect.java @@ -1,5 +1,7 @@ package com.bakdata.conquery.models.datasets.concepts.select.connector.specific; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; @@ -25,6 +27,7 @@ import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.sql.conversion.model.aggregator.SumSqlAggregator; import com.bakdata.conquery.sql.conversion.model.select.SelectConverter; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import io.dropwizard.validation.ValidationMethod; @@ -110,6 +113,11 @@ public List getRequiredColumns() { return out; } + @Override + public ResultSetProcessor.Reader createResultSetReader(ResultSetProcessor processor) { + return processor::getInteger; + } + @Override public SelectConverter createConverter() { return new SumSqlAggregator<>(); diff --git a/backend/src/main/java/com/bakdata/conquery/models/preproc/parser/specific/BooleanParser.java b/backend/src/main/java/com/bakdata/conquery/models/preproc/parser/specific/BooleanParser.java index d974ed2c72..048127c22d 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/preproc/parser/specific/BooleanParser.java +++ b/backend/src/main/java/com/bakdata/conquery/models/preproc/parser/specific/BooleanParser.java @@ -9,6 +9,7 @@ import com.bakdata.conquery.models.preproc.parser.ColumnValues; import com.bakdata.conquery.models.preproc.parser.Parser; import lombok.ToString; +import org.jetbrains.annotations.NotNull; @ToString(callSuper = true) public class BooleanParser extends Parser { @@ -19,6 +20,11 @@ public BooleanParser(ConqueryConfig config) { @Override protected Boolean parseValue(@Nonnull String value) throws ParsingException { + return parseBoolean(value); + } + + @NotNull + public static Boolean parseBoolean(@NotNull String value) { return switch (value) { case "J", "true", "1" -> true; case "N", "false", "0" -> false; diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/DateAggregationMode.java b/backend/src/main/java/com/bakdata/conquery/models/query/DateAggregationMode.java index 604c0f0b6a..d54bf4242f 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/DateAggregationMode.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/DateAggregationMode.java @@ -24,5 +24,5 @@ public enum DateAggregationMode { * Merge or intersect the dates depending on certain nodes in the query plan (OR -> MERGE, AND -> INTERSECT, * NOT -> INVERT) */ - LOGICAL; + LOGICAL } diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/queryplan/aggregators/specific/TwoColumnDurationSumAggregator.java b/backend/src/main/java/com/bakdata/conquery/models/query/queryplan/aggregators/specific/TwoColumnDurationSumAggregator.java new file mode 100644 index 0000000000..a36bf62cdc --- /dev/null +++ b/backend/src/main/java/com/bakdata/conquery/models/query/queryplan/aggregators/specific/TwoColumnDurationSumAggregator.java @@ -0,0 +1,74 @@ +package com.bakdata.conquery.models.query.queryplan.aggregators.specific; + +import java.util.List; + +import com.bakdata.conquery.models.common.CDate; +import com.bakdata.conquery.models.common.CDateSet; +import com.bakdata.conquery.models.common.daterange.CDateRange; +import com.bakdata.conquery.models.datasets.Column; +import com.bakdata.conquery.models.datasets.Table; +import com.bakdata.conquery.models.events.Bucket; +import com.bakdata.conquery.models.query.QueryExecutionContext; +import com.bakdata.conquery.models.query.entity.Entity; +import com.bakdata.conquery.models.query.queryplan.aggregators.Aggregator; +import com.bakdata.conquery.models.query.queryplan.aggregators.ColumnAggregator; +import lombok.Data; +import lombok.ToString; + +/** + * Aggregator, counting the number of days present. + */ +@Data +@ToString(onlyExplicitlyIncluded = true) +public class TwoColumnDurationSumAggregator extends ColumnAggregator { + + @ToString.Include + private final Column startColumn, endColumn; + + private CDateSet set = CDateSet.createEmpty(); + private CDateSet dateRestriction; + + private int realUpperBound; + + + @Override + public void init(Entity entity, QueryExecutionContext context) { + set.clear(); + realUpperBound = context.getToday(); + } + + @Override + public void nextTable(QueryExecutionContext ctx, Table currentTable) { + dateRestriction = ctx.getDateRestriction(); + } + + @Override + public List getRequiredColumns() { + return List.of(startColumn, endColumn); + } + + @Override + public void consumeEvent(Bucket bucket, int event) { + if (!bucket.has(event, startColumn)) { + return; + } + + if (!bucket.has(event, endColumn)) { + return; + } + + final int begin = bucket.getDate(event, startColumn); + final int end = bucket.getDate(event, endColumn); + + set.maskedAdd(CDateRange.of(begin, end), dateRestriction, realUpperBound); + } + + @Override + public Long createAggregationResult() { + if (set.isEmpty() || CDate.isNegativeInfinity(set.getMinValue())) { + return null; + } + return set.countDays(); + } + +} diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/queryplan/aggregators/specific/value/AllValuesAggregator.java b/backend/src/main/java/com/bakdata/conquery/models/query/queryplan/aggregators/specific/value/AllValuesAggregator.java index f6b99783e8..8aae5ba413 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/queryplan/aggregators/specific/value/AllValuesAggregator.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/queryplan/aggregators/specific/value/AllValuesAggregator.java @@ -3,7 +3,9 @@ import static com.bakdata.conquery.models.query.StringUtils.getSubstringFromRange; import java.util.HashSet; +import java.util.List; import java.util.Set; +import java.util.stream.Collectors; import com.bakdata.conquery.models.common.Range; import com.bakdata.conquery.models.datasets.Column; @@ -11,19 +13,17 @@ import com.bakdata.conquery.models.query.QueryExecutionContext; import com.bakdata.conquery.models.query.entity.Entity; import com.bakdata.conquery.models.query.queryplan.aggregators.SingleColumnAggregator; -import com.google.common.collect.ImmutableSet; +import joptsimple.internal.Strings; import lombok.ToString; /** * Aggregator gathering all unique values in a column, into a Set. - * - * @param Value type of the column. */ @ToString(callSuper = true, onlyExplicitlyIncluded = true) -public class AllValuesAggregator extends SingleColumnAggregator> { +public class AllValuesAggregator extends SingleColumnAggregator> { private final Range.IntegerRange substring; - private final Set entries = new HashSet<>(); + private final Set entries = new HashSet<>(); public AllValuesAggregator(Column column, Range.IntegerRange substring) { super(column); @@ -43,16 +43,23 @@ public void consumeEvent(Bucket bucket, int event) { if (substring != null) { String string = bucket.getString(event, getColumn()); - entries.add((VALUE) getSubstringFromRange(string, substring)); + String extract = getSubstringFromRange(string, substring); + + if (Strings.isNullOrEmpty(extract)) { + return; + } + + entries.add(extract); return; } - entries.add((VALUE) bucket.createScriptValue(event, getColumn())); + entries.add(bucket.createScriptValue(event, getColumn())); } @Override - public Set createAggregationResult() { - return entries.isEmpty() ? null : ImmutableSet.copyOf(entries); + public List createAggregationResult() { + List rendered = entries.stream().sorted().collect(Collectors.toList()); + return rendered.isEmpty() ? null : rendered; } } diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/queryplan/specific/temporal/TemporalQueryNode.java b/backend/src/main/java/com/bakdata/conquery/models/query/queryplan/specific/temporal/TemporalQueryNode.java index 9659fdc01e..0c5987ca46 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/queryplan/specific/temporal/TemporalQueryNode.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/queryplan/specific/temporal/TemporalQueryNode.java @@ -133,7 +133,8 @@ public boolean evaluateTemporalQuery(QueryExecutionContext ctx, Entity entity) { return false; } - final CDateRange[] periods = indexSelector.sample(indexQueryPlan.getDateAggregator().createAggregationResult()); + CDateSet indexDates = indexQueryPlan.getDateAggregator().createAggregationResult(); + final CDateRange[] periods = indexSelector.sample(indexDates); final CDateRange[] indexPeriods = indexMode.convert(periods, indexSelector); final boolean[] results = new boolean[indexPeriods.length]; @@ -181,14 +182,14 @@ public boolean evaluateTemporalQuery(QueryExecutionContext ctx, Entity entity) { satisfies ); + results[current] = satisfies; + // If compare's selector is satisfied, we append current to the results and collect the aggregation results if (!satisfies) { continue; } - results[current] = true; indexDateResult.add(periods[current]); - addAggregationResults(compareContained, compareDates, compareAggregationResults); } diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/ColumnResultInfo.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/ColumnResultInfo.java index 30047a847a..a55cae4aad 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/ColumnResultInfo.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/ColumnResultInfo.java @@ -9,6 +9,7 @@ import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; import com.bakdata.conquery.models.query.resultinfo.printers.common.ConceptIdPrinter; import com.bakdata.conquery.models.types.ResultType; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.ToString; @@ -51,4 +52,9 @@ public Printer createPrinter(PrinterFactory printerFactory, PrintSettings printS return printerFactory.printerFor(type, printSettings); } + @Override + public ResultSetProcessor.Reader createReader(ResultSetProcessor resultSetProcessor) { + return ResultSetProcessor.readerForType(getType(), resultSetProcessor); + } + } diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/ExternalResultInfo.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/ExternalResultInfo.java index f5900aae5a..cac31827c6 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/ExternalResultInfo.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/ExternalResultInfo.java @@ -6,6 +6,7 @@ import com.bakdata.conquery.models.query.resultinfo.printers.Printer; import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; import com.bakdata.conquery.models.types.ResultType; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -41,4 +42,13 @@ public String getDescription() { public Printer createPrinter(PrinterFactory printerFactory, PrintSettings printSettings) { return printerFactory.printerFor(type, printSettings); } + + @Override + public ResultSetProcessor.Reader createReader(ResultSetProcessor resultSetProcessor) { + if (type instanceof ResultType.ListT list && list.getElementType().equals(ResultType.Primitive.STRING)) { + return resultSetProcessor::getStringList; + } + + return resultSetProcessor::getString; + } } diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/ResultInfo.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/ResultInfo.java index 9774dbe390..e48f129540 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/ResultInfo.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/ResultInfo.java @@ -11,6 +11,7 @@ import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.models.types.SemanticType; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.google.common.collect.ImmutableSet; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -63,4 +64,6 @@ public Set getSemantics() { public abstract String getDescription(); public abstract Printer createPrinter(PrinterFactory printerFactory, PrintSettings printSettings); + + public abstract ResultSetProcessor.Reader createReader(ResultSetProcessor resultSetProcessor); } diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/SecondaryIdResultInfo.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/SecondaryIdResultInfo.java index e38aa8a941..a41b03b6c1 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/SecondaryIdResultInfo.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/SecondaryIdResultInfo.java @@ -8,6 +8,7 @@ import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.models.types.SemanticType; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import lombok.Getter; import lombok.ToString; @@ -47,4 +48,9 @@ public String userColumnName(PrintSettings printSettings) { public String defaultColumnName(PrintSettings printSettings) { return userColumnName(printSettings); } + + @Override + public ResultSetProcessor.Reader createReader(ResultSetProcessor resultSetProcessor) { + return resultSetProcessor::getString; + } } diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/SelectResultInfo.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/SelectResultInfo.java index 1d8348764d..c40af179bf 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/SelectResultInfo.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/SelectResultInfo.java @@ -9,6 +9,7 @@ import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.models.types.SemanticType; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.google.common.collect.Sets; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -39,6 +40,11 @@ public Printer createPrinter(PrinterFactory printerFactory, PrintSettings printS return select.createPrinter(printerFactory, printSettings); } + @Override + public ResultSetProcessor.Reader createReader(ResultSetProcessor resultSetProcessor) { + return select.createResultSetReader(resultSetProcessor); + } + @Override public ResultType getType() { return select.getResultType(); diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/DateRangeStringPrinter.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/DateRangeStringPrinter.java index 8c4003ff5c..74c474d0b1 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/DateRangeStringPrinter.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/DateRangeStringPrinter.java @@ -20,6 +20,10 @@ public DateRangeStringPrinter(PrintSettings printSettings, String negativeInf, S @Override public String apply(@NotNull List f) { + if (f.isEmpty()) { + return null; + } + Preconditions.checkArgument(f.size() == 2, "Expected a list with 2 elements, one min, one max. The list was: %s ", f); final Integer min = f.get(0); diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/ListResultInfo.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/ListResultInfo.java index 11d7589f18..b138be9b08 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/ListResultInfo.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/ListResultInfo.java @@ -5,6 +5,7 @@ import com.bakdata.conquery.models.query.resultinfo.printers.Printer; import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; import com.bakdata.conquery.models.types.ResultType; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; /** * Simple wrapper to turn results into Lists. @@ -42,4 +43,9 @@ public String getDescription() { public Printer createPrinter(PrinterFactory printerFactory, PrintSettings printSettings) { return printerFactory.getListPrinter(resultInfo.createPrinter(printerFactory, printSettings), printSettings); } + + @Override + public ResultSetProcessor.Reader createReader(ResultSetProcessor resultSetProcessor) { + return resultInfo.createReader(resultSetProcessor); //TODO not sure if this is correct + } } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/Conversions.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/Conversions.java index d8c64532bb..50116dea6e 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/Conversions.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/Conversions.java @@ -1,8 +1,8 @@ package com.bakdata.conquery.sql.conversion; import java.util.List; +import java.util.Optional; -import com.google.common.collect.MoreCollectors; import lombok.Getter; /** @@ -23,9 +23,24 @@ protected Conversions(List> converters) { } public R convert(C node, X context) { - return converters.stream() - .flatMap(converter -> converter.tryConvert(node, context).stream()) - .collect(MoreCollectors.onlyElement()); + R converted = null; + for (Converter converter : converters) { + Optional maybeConverted = converter.tryConvert(node, context); + if (maybeConverted.isPresent()) { + if (converted == null) { + converted = maybeConverted.get(); + } + else { + throw new IllegalStateException("Multiple Converters for %s".formatted(node)); + } + } + } + + if (converted == null) { + throw new IllegalStateException("No converter found for %s".formatted(node)); + } + + return converted; } } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/CQExternalConverter.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/CQExternalConverter.java index c3d69f1a3b..ea148c4583 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/CQExternalConverter.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/CQExternalConverter.java @@ -1,8 +1,13 @@ package com.bakdata.conquery.sql.conversion.cqelement; import static com.bakdata.conquery.sql.conversion.dialect.SqlFunctionProvider.SQL_UNIT_SEPARATOR; +import static org.jooq.impl.DSL.*; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; import com.bakdata.conquery.apiv1.query.concept.specific.external.CQExternal; @@ -30,42 +35,29 @@ public class CQExternalConverter implements NodeConverter { private static final String UNDERSCORE = "_"; private static final String WHITESPACE = " "; - @Override - public Class getConversionClass() { - return CQExternal.class; - } - - @Override - public ConversionContext convert(CQExternal external, ConversionContext context) { - SqlFunctionProvider functionProvider = context.getFunctionProvider(); - QueryStep externalIdsCte = createExternalIdsCte(external, functionProvider); - ConversionContext withExternalIdCte = context.withQueryStep(externalIdsCte); - if (!external.isWithExtras()) { - return withExternalIdCte; - } - QueryStep externalExtrasCte = createExternalExtrasCte(external, functionProvider); - return withExternalIdCte.withExternalExtras(externalExtrasCte); - } - - private static QueryStep createExternalIdsCte(CQExternal external, SqlFunctionProvider functionProvider) { + private static QueryStep createExternalIdsCte(CQExternal external, SqlFunctionProvider functionProvider, ConversionContext context) { List unions = new ArrayList<>(); for (Map.Entry entry : external.getValuesResolved().entrySet()) { List rowSelects = createRowSelects(entry, functionProvider); unions.addAll(rowSelects); } Preconditions.checkArgument(!unions.isEmpty(), "Expecting at least 1 converted resolved row when converting a CQExternal"); - return QueryStep.createUnionAllStep(unions, CQ_EXTERNAL_IDS_CTE_NAME, Collections.emptyList()); - } + QueryStep allStep = QueryStep.createUnionAllStep(unions, CQ_EXTERNAL_IDS_CTE_NAME, Collections.emptyList()); - private QueryStep createExternalExtrasCte(CQExternal external, SqlFunctionProvider functionProvider) { - List unions = new ArrayList<>(); - for (Map.Entry entry : external.getValuesResolved().entrySet()) { - List>> extrasForId = external.getExtrasForId(entry.getKey()); - QueryStep rowSelects = createRowSelects(entry, extrasForId, functionProvider); - unions.add(rowSelects); + Optional maybeValidityDate = allStep.getSelects().getValidityDate(); + + if (maybeValidityDate.isEmpty() || !context.dateRestrictionActive()) { + return allStep; } - Preconditions.checkArgument(!unions.isEmpty(), "Expecting at least 1 converted resolved row when converting a CQExternal"); - return QueryStep.createUnionAllStep(unions, CQ_EXTERNAL_EXTRAS_CTE_NAME, Collections.emptyList()); + + return QueryStep.builder() + .predecessors(List.of(allStep)) + .conditions(List.of(functionProvider.dateRestriction(functionProvider.forCDateRange(context.getDateRestrictionRange()), maybeValidityDate.get()))) + .selects(allStep.getQualifiedSelects()) + .fromTable(table(name(allStep.getCteName()))) + .cteName(CQ_EXTERNAL_IDS_CTE_NAME + "_date_restriction") + .build(); + } /** @@ -80,21 +72,8 @@ private static List createRowSelects(Map.Entry entr .toList(); } - /** - * For each entry, we need to create a SELECT statement of static values for each pid -> extras. - */ - private QueryStep createRowSelects( - Map.Entry entry, - List>> extra, - SqlFunctionProvider functionProvider - ) { - SqlIdColumns ids = createIdSelect(entry); - List extraSelects = extra.stream().map(CQExternalConverter::createExtraColumnValue).collect(Collectors.toList()); - return createExtraRowSelect(ids, extraSelects, functionProvider); - } - private static SqlIdColumns createIdSelect(Map.Entry entry) { - Field primaryColumn = DSL.val(entry.getKey()).coerce(Object.class).as(SharedAliases.PRIMARY_COLUMN.getAlias()); + Field primaryColumn = DSL.inline(entry.getKey()).coerce(Object.class).as(SharedAliases.PRIMARY_COLUMN.getAlias()); return new SqlIdColumns(primaryColumn); } @@ -103,8 +82,8 @@ private static FieldWrapper createExtraColumnValue(Map.Entry withAlias = DSL.field(extraValues).as(alias); + final Name alias = name(extraEntry.getKey().replace(WHITESPACE, UNDERSCORE)); + final Field withAlias = field(extraValues).as(alias); return new FieldWrapper<>(withAlias); } @@ -152,4 +131,49 @@ private static QueryStep wrapInQueryStep(Selects selects, SqlFunctionProvider fu .build(); } + @Override + public Class getConversionClass() { + return CQExternal.class; + } + + @Override + public ConversionContext convert(CQExternal external, ConversionContext context) { + SqlFunctionProvider functionProvider = context.getDialectBundle().getFunctionProvider(); + + QueryStep externalIdsCte = createExternalIdsCte(external, functionProvider, context); + ConversionContext withExternalIdCte = context.withQueryStep(externalIdsCte); + + + if (!external.isWithExtras()) { + return withExternalIdCte; + } + + QueryStep externalExtrasCte = createExternalExtrasCte(external, functionProvider); + return withExternalIdCte.withExternalExtras(externalExtrasCte); + } + + private QueryStep createExternalExtrasCte(CQExternal external, SqlFunctionProvider functionProvider) { + List unions = new ArrayList<>(); + for (Map.Entry entry : external.getValuesResolved().entrySet()) { + List>> extrasForId = external.getExtrasForId(entry.getKey()); + QueryStep rowSelects = createRowSelects(entry, extrasForId, functionProvider); + unions.add(rowSelects); + } + Preconditions.checkArgument(!unions.isEmpty(), "Expecting at least 1 converted resolved row when converting a CQExternal"); + return QueryStep.createUnionAllStep(unions, CQ_EXTERNAL_EXTRAS_CTE_NAME, Collections.emptyList()); + } + + /** + * For each entry, we need to create a SELECT statement of static values for each pid -> extras. + */ + private QueryStep createRowSelects( + Map.Entry entry, + List>> extra, + SqlFunctionProvider functionProvider + ) { + SqlIdColumns ids = createIdSelect(entry); + List extraSelects = extra.stream().map(CQExternalConverter::createExtraColumnValue).collect(Collectors.toList()); + return createExtraRowSelect(ids, extraSelects, functionProvider); + } + } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/CQNegationConverter.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/CQNegationConverter.java index d9aed3a432..2bb90a6d62 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/CQNegationConverter.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/CQNegationConverter.java @@ -1,36 +1,21 @@ package com.bakdata.conquery.sql.conversion.cqelement; import com.bakdata.conquery.apiv1.query.concept.specific.CQNegation; -import com.bakdata.conquery.models.query.queryplan.DateAggregationAction; import com.bakdata.conquery.sql.conversion.NodeConverter; -import com.bakdata.conquery.sql.conversion.model.QueryStep; public class CQNegationConverter implements NodeConverter { - @Override - public Class getConversionClass() { - return CQNegation.class; - } + @Override + public Class getConversionClass() { + return CQNegation.class; + } - @Override - public ConversionContext convert(CQNegation negationNode, ConversionContext context) { - - ConversionContext converted = context.getNodeConversions() - .convert(negationNode.getChild(), context.withNegation(true)) - .withNegation(false); - - QueryStep queryStep = converted.getLastConvertedStep(); - if (negationNode.getDateAction() != DateAggregationAction.NEGATE) { - QueryStep withBlockedValidityDate = queryStep.toBuilder() - .selects(queryStep.getSelects().blockValidityDate()) - .build(); - return context.toBuilder().queryStep(withBlockedValidityDate).build(); - } - QueryStep withInvertedValidityDate = converted.getDialectBundle() - .getDateAggregator() - .invertAggregatedIntervals(queryStep, context); - return context.toBuilder().queryStep(withInvertedValidityDate).build(); - } + @Override + public ConversionContext convert(CQNegation negationNode, ConversionContext context) { + return context.getNodeConversions() + .convert(negationNode.getChild(), context.withNegation(true)) + .withNegation(false); + } } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/CQYesConverter.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/CQYesConverter.java index eaa8dfaa86..eb6c8a234f 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/CQYesConverter.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/CQYesConverter.java @@ -1,14 +1,18 @@ package com.bakdata.conquery.sql.conversion.cqelement; +import static org.jooq.impl.DSL.*; + +import java.util.Optional; + import com.bakdata.conquery.apiv1.query.CQYes; import com.bakdata.conquery.models.config.ColumnConfig; import com.bakdata.conquery.sql.conversion.NodeConverter; +import com.bakdata.conquery.sql.conversion.model.ColumnDateRange; import com.bakdata.conquery.sql.conversion.model.QueryStep; import com.bakdata.conquery.sql.conversion.model.Selects; import com.bakdata.conquery.sql.conversion.model.SqlIdColumns; import org.jooq.Field; import org.jooq.Record; -import org.jooq.impl.DSL; public class CQYesConverter implements NodeConverter { @@ -23,11 +27,13 @@ public Class getConversionClass() { public ConversionContext convert(CQYes cqYes, ConversionContext context) { ColumnConfig primaryColumnConfig = context.getIdColumns().findPrimaryIdColumn(); - Field primaryColumn = DSL.field(DSL.name(primaryColumnConfig.getField())); + Field primaryColumn = field(name(primaryColumnConfig.getField())); SqlIdColumns ids = new SqlIdColumns(primaryColumn); - Selects selects = Selects.builder().ids(ids).build(); - org.jooq.Table fromTable = DSL.table(DSL.name(context.getIdColumns().getTable())); + Selects selects = Selects.builder().ids(ids) + .validityDate(Optional.of(context.getFunctionProvider().emptyColumnDateRange().asValidityDateRange(ALL_IDS_CTE))) + .build(); + org.jooq.Table fromTable = table(name(context.getIdColumns().getTable())); QueryStep cqYesTep = QueryStep.builder() .cteName(ALL_IDS_CTE) diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/ConversionContext.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/ConversionContext.java index 685e4c5f28..a2973ec90d 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/ConversionContext.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/ConversionContext.java @@ -25,6 +25,7 @@ import lombok.Value; import lombok.With; +//TODO this class is less context and more state. It's also incredibly dangerous because it hides a lot of moving parts and creates indirections. @Value @With @Builder(toBuilder = true) @@ -100,7 +101,7 @@ public ConversionContext getConversionContext() { * Get the last query {@link QueryStep} that has been added to this context query steps. */ public QueryStep getLastConvertedStep() { - return this.querySteps.get(this.querySteps.size() - 1); + return this.querySteps.getLast(); } } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/AnsiSqlDateAggregator.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/AnsiSqlDateAggregator.java index 6a0561a531..8656cd9bf4 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/AnsiSqlDateAggregator.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/AnsiSqlDateAggregator.java @@ -1,5 +1,9 @@ package com.bakdata.conquery.sql.conversion.cqelement.aggregation; +import static org.jooq.impl.DSL.field; +import static org.jooq.impl.DSL.inline; + +import java.sql.Date; import java.util.List; import com.bakdata.conquery.models.query.queryplan.DateAggregationAction; @@ -8,18 +12,21 @@ import com.bakdata.conquery.sql.conversion.cqelement.intervalpacking.IntervalPackingCteStep; import com.bakdata.conquery.sql.conversion.dialect.IntervalPacker; import com.bakdata.conquery.sql.conversion.dialect.SqlDateAggregator; +import com.bakdata.conquery.sql.conversion.dialect.SqlFunctionProvider; +import com.bakdata.conquery.sql.conversion.model.ColumnDateRange; import com.bakdata.conquery.sql.conversion.model.QueryStep; import com.bakdata.conquery.sql.conversion.model.Selects; import com.bakdata.conquery.sql.conversion.model.SqlTables; import com.bakdata.conquery.sql.conversion.model.select.SqlSelect; +import lombok.Data; +import org.jooq.Field; +@Data public class AnsiSqlDateAggregator implements SqlDateAggregator { private final IntervalPacker intervalPacker; + private final SqlFunctionProvider functionProvider; - public AnsiSqlDateAggregator(IntervalPacker intervalPacker) { - this.intervalPacker = intervalPacker; - } @Override public QueryStep apply( @@ -66,6 +73,18 @@ public QueryStep apply( return this.intervalPacker.aggregateAsValidityDate(intervalPackingContext); } + @Override + public ColumnDateRange getAggregatedValidityDate(DateAggregationDates dateAggregationDates, DateAggregationAction dateAggregationAction) { + //TODO(FK): i think this is only ever relevant with dateMode=Logical which i want to remove + Field rangeStart = functionProvider.least(dateAggregationDates.allStarts()); + Field rangeEnd = functionProvider.greatest(dateAggregationDates.allEnds()); + + return ColumnDateRange.of( + rangeStart.as(DateAggregationCte.RANGE_START), + rangeEnd.as(DateAggregationCte.RANGE_END) + ); + } + @Override public QueryStep invertAggregatedIntervals(QueryStep baseStep, ConversionContext conversionContext) { diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/DateAggregationCte.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/DateAggregationCte.java index 478d8d90c0..721d99c84f 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/DateAggregationCte.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/DateAggregationCte.java @@ -19,22 +19,23 @@ public QueryStep convert(DateAggregationContext context, QueryStep previous) { SqlTables dateAggregationTables = context.getDateAggregationTables(); // this way all selects are already qualified, and we don't need to care for that in the respective steps - context = context.qualify(dateAggregationTables.getPredecessor(cteStep)); + String predecessor = dateAggregationTables.getPredecessor(cteStep); + context = context.qualify(predecessor); - QueryStep.QueryStepBuilder builder = this.convertStep(context); + QueryStep.QueryStepBuilder builder = this.convertStep(context, predecessor); if (cteStep != DateAggregationCteStep.NODE_NO_OVERLAP) { builder = builder.cteName(dateAggregationTables.cteName(cteStep)) .predecessors(List.of(previous)); } if (cteStep != DateAggregationCteStep.INVERT && cteStep != DateAggregationCteStep.NODE_NO_OVERLAP) { - builder = builder.fromTable(QueryStep.toTableLike(dateAggregationTables.getPredecessor(cteStep))); + builder = builder.fromTable(QueryStep.toTableLike(predecessor)); } return builder.build(); } - protected abstract QueryStep.QueryStepBuilder convertStep(DateAggregationContext context); + protected abstract QueryStep.QueryStepBuilder convertStep(DateAggregationContext context, String predecessor); public abstract DateAggregationCteStep getCteStep(); diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/DateAggregationDates.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/DateAggregationDates.java index 64e78fb98f..c3c7e708e6 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/DateAggregationDates.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/DateAggregationDates.java @@ -3,6 +3,7 @@ import java.sql.Date; import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; @@ -22,10 +23,16 @@ @AllArgsConstructor(access = AccessLevel.PRIVATE) public class DateAggregationDates { - private static final String RANGE_START = "RANGE_START"; - private static final String RANGE_END = "RANGE_END"; private final List validityDates; + public static DateAggregationDates forValidityDates(final List> validityDates) { + final List filtered = validityDates.stream() + .filter(Optional::isPresent) + .map(Optional::get) + .toList(); + return new DateAggregationDates(filtered); + } + public static DateAggregationDates forSingleStep(QueryStep queryStep) { List validityDates = queryStep.getSelects() .getValidityDate() @@ -35,11 +42,9 @@ public static DateAggregationDates forSingleStep(QueryStep queryStep) { } public static DateAggregationDates forSteps(List querySteps) { - AtomicInteger validityDateCounter = new AtomicInteger(0); - List validityDates = querySteps.stream() - .filter(queryStep -> queryStep.getSelects().getValidityDate().isPresent()) - .map(queryStep -> numerateValidityDate(queryStep, validityDateCounter)) - .toList(); + final List validityDates = querySteps.stream() + .flatMap(queryStep -> queryStep.getQualifiedSelects().getValidityDate().stream()) + .toList(); return new DateAggregationDates(validityDates); } @@ -70,17 +75,4 @@ public DateAggregationDates qualify(String qualifier) { return new DateAggregationDates(qualified); } - private static ColumnDateRange numerateValidityDate(QueryStep queryStep, AtomicInteger validityDateCounter) { - ColumnDateRange validityDate = queryStep.getQualifiedSelects().getValidityDate().get(); - - if (validityDate.isSingleColumnRange()) { - return validityDate; - } - - Field rangeStart = validityDate.getStart().as("%s_%s".formatted(RANGE_START, validityDateCounter.get())); - Field rangeEnd = validityDate.getEnd().as("%s_%s".formatted(RANGE_END, validityDateCounter.getAndIncrement())); - - return ColumnDateRange.of(rangeStart, rangeEnd); - } - } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/IntermediateTableCte.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/IntermediateTableCte.java index f32b391f4e..d7ccea9966 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/IntermediateTableCte.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/IntermediateTableCte.java @@ -22,7 +22,7 @@ public IntermediateTableCte(DateAggregationCteStep cteStep) { } @Override - protected QueryStep.QueryStepBuilder convertStep(DateAggregationContext context) { + protected QueryStep.QueryStepBuilder convertStep(DateAggregationContext context, String predecessor) { List intermediateTableSelects = context.getSqlAggregationAction().getIntermediateTableSelects( diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/InvertCte.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/InvertCte.java index 5d6207c03b..30ef3a59b3 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/InvertCte.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/InvertCte.java @@ -35,7 +35,7 @@ public InvertCte(DateAggregationCteStep cteStep) { } @Override - protected QueryStep.QueryStepBuilder convertStep(DateAggregationContext context) { + protected QueryStep.QueryStepBuilder convertStep(DateAggregationContext context, String predecessor) { QueryStep rowNumberStep = context.getStep(DateAggregationCteStep.ROW_NUMBER); diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/MergeCte.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/MergeCte.java index a0afe130b8..4fd1bc36cf 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/MergeCte.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/MergeCte.java @@ -16,7 +16,7 @@ public MergeCte(DateAggregationCteStep cteStep) { } @Override - protected QueryStep.QueryStepBuilder convertStep(DateAggregationContext context) { + protected QueryStep.QueryStepBuilder convertStep(DateAggregationContext context, String predecessor) { SqlAggregationAction aggregationAction = context.getSqlAggregationAction(); List noOverlapSteps = aggregationAction.getNoOverlapSelects(context); diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/NodeNoOverlapCte.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/NodeNoOverlapCte.java index 9af31b6d89..0da7709148 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/NodeNoOverlapCte.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/NodeNoOverlapCte.java @@ -24,7 +24,7 @@ public NodeNoOverlapCte(DateAggregationCteStep cteStep) { } @Override - protected QueryStep.QueryStepBuilder convertStep(DateAggregationContext context) { + protected QueryStep.QueryStepBuilder convertStep(DateAggregationContext context, String predecessor) { // we create a no-overlap node for each query step we need to aggregate DateAggregationDates dateAggregationDates = context.getDateAggregationDates(); diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/OverlapCte.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/OverlapCte.java index 45c8e728b2..1d6790ea23 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/OverlapCte.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/OverlapCte.java @@ -22,7 +22,7 @@ public OverlapCte(DateAggregationCteStep cteStep) { } @Override - protected QueryStep.QueryStepBuilder convertStep(DateAggregationContext context) { + protected QueryStep.QueryStepBuilder convertStep(DateAggregationContext context, String predecessor) { SqlFunctionProvider functionProvider = context.getFunctionProvider(); @@ -33,7 +33,7 @@ protected QueryStep.QueryStepBuilder convertStep(DateAggregationContext context) ColumnDateRange overlapValidityDate = context.getSqlAggregationAction().getOverlapValidityDate(context.getDateAggregationDates(), functionProvider); Selects overlapSelects = Selects.builder() .ids(context.getIds()) - .validityDate(Optional.of(overlapValidityDate)) + .validityDate(Optional.of(overlapValidityDate.asValidityDateRange(predecessor))) .sqlSelects(context.getCarryThroughSelects()) .build(); diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/PostgreSqlDateAggregator.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/PostgreSqlDateAggregator.java index 8386331d4f..08e74dfcf8 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/PostgreSqlDateAggregator.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/PostgreSqlDateAggregator.java @@ -1,5 +1,8 @@ package com.bakdata.conquery.sql.conversion.cqelement.aggregation; +import static org.jooq.impl.DSL.field; +import static org.jooq.impl.DSL.keyword; + import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @@ -14,9 +17,13 @@ import com.bakdata.conquery.sql.conversion.model.QueryStep; import com.bakdata.conquery.sql.conversion.model.Selects; import com.bakdata.conquery.sql.conversion.model.select.SqlSelect; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; import lombok.Getter; import lombok.RequiredArgsConstructor; import org.jooq.Field; +import org.jooq.Keyword; import org.jooq.impl.DSL; public class PostgreSqlDateAggregator implements SqlDateAggregator { @@ -46,8 +53,10 @@ public QueryStep apply( ConversionContext conversionContext ) { String joinedStepCteName = joinedStep.getCteName(); + DateAggregationDates qualified = dateAggregationDates.qualify(joinedStepCteName); - ColumnDateRange aggregatedValidityDate = getAggregatedValidityDate(dateAggregationDates, dateAggregationAction, joinedStepCteName); + ColumnDateRange aggregatedValidityDate = getAggregatedValidityDate(qualified, dateAggregationAction) + .asValidityDateRange(joinedStepCteName); Selects dateAggregationSelects = Selects.builder() .ids(joinedStep.getQualifiedSelects().getIds()) @@ -77,16 +86,16 @@ public QueryStep invertAggregatedIntervals(QueryStep baseStep, ConversionContext Object.class, this.functionProvider.toDateField(this.functionProvider.getMinDateExpression()), this.functionProvider.toDateField(this.functionProvider.getMaxDateExpression()), - DSL.val("[]") + DSL.inline("[]") ); // see https://www.postgresql.org/docs/current/functions-range.html // {[-infinity,infinity]} - {multirange} computes the inverse of a {multirange} - Field invertedValidityDate = DSL.field( + Field invertedValidityDate = field( "{0}::{1} - {2}", Object.class, maxDateRange, - DSL.keyword("datemultirange"), + keyword("datemultirange"), validityDate.get().getRange() ).as(PostgresDateAggregationCteStep.DATES_INVERTED.getSuffix()); @@ -98,28 +107,26 @@ public QueryStep invertAggregatedIntervals(QueryStep baseStep, ConversionContext .build(); } - private ColumnDateRange getAggregatedValidityDate(DateAggregationDates dateAggregationDates, DateAggregationAction dateAggregationAction, String joinedStepCteName) { + public ColumnDateRange getAggregatedValidityDate(DateAggregationDates dateAggregationDates, DateAggregationAction dateAggregationAction) { // see https://www.postgresql.org/docs/current/functions-range.html String aggregatingOperator = switch (dateAggregationAction) { case MERGE -> " + "; case INTERSECT -> " * "; - default -> throw new IllegalStateException("Unexpected aggregation mode: " + dateAggregationAction); + case BLOCK, NEGATE -> throw new IllegalStateException("Unexpected aggregation mode: " + dateAggregationAction); }; - String aggregatedExpression = dateAggregationDates.qualify(joinedStepCteName) - .getValidityDates().stream() + String aggregatedExpression = dateAggregationDates.getValidityDates().stream() .flatMap(validityDate -> validityDate.toFields().stream()) .map(PostgreSqlDateAggregator::createEmptyRangeForNullValues) .collect(Collectors.joining(aggregatingOperator)); - return ColumnDateRange.of(DSL.field(aggregatedExpression)) - .asValidityDateRange(joinedStepCteName); + return ColumnDateRange.of(field(aggregatedExpression)); } private static String createEmptyRangeForNullValues(Field field) { - return DSL.when(field.isNull(), DSL.field("'{}'::{0}", DSL.keyword("datemultirange"))) - .otherwise(field) + Keyword datemultirange = keyword("datemultirange"); + return DSL.coalesce(field("{0}::{1}", field, datemultirange), field("'{}'::{0}", datemultirange)) .toString(); } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/RowNumberCte.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/RowNumberCte.java index 53492f0982..01c1dd5299 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/RowNumberCte.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/RowNumberCte.java @@ -27,7 +27,7 @@ public RowNumberCte(DateAggregationCteStep cteStep) { } @Override - protected QueryStep.QueryStepBuilder convertStep(DateAggregationContext context) { + protected QueryStep.QueryStepBuilder convertStep(DateAggregationContext context, String predecessor) { SqlIdColumns ids = context.getIds(); diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/CQConceptConverter.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/CQConceptConverter.java index 7d26ca0017..17bc77eefe 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/CQConceptConverter.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/CQConceptConverter.java @@ -2,14 +2,11 @@ import java.util.ArrayList; import java.util.List; -import java.util.Objects; import java.util.Optional; import java.util.function.Predicate; -import java.util.stream.Collectors; import java.util.stream.Stream; import com.bakdata.conquery.apiv1.query.concept.filter.CQTable; -import com.bakdata.conquery.apiv1.query.concept.filter.FilterValue; import com.bakdata.conquery.apiv1.query.concept.specific.CQConcept; import com.bakdata.conquery.models.datasets.Column; import com.bakdata.conquery.models.datasets.Table; @@ -20,7 +17,6 @@ import com.bakdata.conquery.models.datasets.concepts.select.concept.ConceptColumnSelect; import com.bakdata.conquery.models.datasets.concepts.tree.ConceptTreeChild; import com.bakdata.conquery.models.identifiable.ids.specific.ConceptElementId; -import com.bakdata.conquery.models.identifiable.ids.specific.ConnectorSelectId; import com.bakdata.conquery.models.identifiable.ids.specific.SelectId; import com.bakdata.conquery.models.query.queryplan.DateAggregationAction; import com.bakdata.conquery.sql.conversion.NodeConverter; @@ -34,7 +30,6 @@ import com.bakdata.conquery.sql.conversion.model.Selects; import com.bakdata.conquery.sql.conversion.model.SqlIdColumns; import com.bakdata.conquery.sql.conversion.model.filter.ConditionUtil; -import com.bakdata.conquery.sql.conversion.model.filter.ConditionWrappingWhereCondition; import com.bakdata.conquery.sql.conversion.model.filter.SqlFilters; import com.bakdata.conquery.sql.conversion.model.filter.WhereClauses; import com.bakdata.conquery.sql.conversion.model.filter.WhereCondition; @@ -45,7 +40,6 @@ import com.bakdata.conquery.sql.conversion.model.select.SqlSelect; import com.bakdata.conquery.util.TablePrimaryColumnUtil; import com.google.common.base.Preconditions; -import org.jooq.Condition; import org.jooq.Field; import org.jooq.Record; import org.jooq.TableLike; @@ -122,6 +116,7 @@ private static QueryStep finishConceptConversion(QueryStep predecessor, CQConcep .fromTable(joinedTable) .groupBy(groupByFields) .predecessors(queriesToJoin) + .negate(context.isNegation()) .build(); } @@ -151,127 +146,111 @@ public static SqlIdColumns convertIds(CQConcept cqConcept, CQTable cqTable, Conv return new SqlIdColumns(primaryColumn, secondaryId).withAlias(); } - private static Optional convertValidityDate(ValidityDate selected, String connectorLabel, ConversionContext context) { - if (Objects.isNull(selected)) { - return Optional.empty(); - } + private static Optional convertValidityDate(CQTable cqTable, String connectorLabel, ConversionContext context) { SqlFunctionProvider functionProvider = context.getFunctionProvider(); + ValidityDate validityDate = cqTable.findValidityDate(); + ColumnDateRange sqlValidityDate; - if (context.getDateRestrictionRange() != null) { - return Optional.of(functionProvider.forValidityDate(selected, context.getDateRestrictionRange()).asValidityDateRange(connectorLabel)); - } + boolean hasValidityDate = validityDate != null; + boolean hasDateRestriction = context.getDateRestrictionRange() != null; - return Optional.of(functionProvider.forValidityDate(selected).asValidityDateRange(connectorLabel)); - } + if (hasValidityDate) { + if (hasDateRestriction) { + sqlValidityDate = functionProvider.forValidityDate(validityDate, context.getDateRestrictionRange()); + } + else { + sqlValidityDate = functionProvider.forValidityDate(validityDate); + } + } + else { + if (hasDateRestriction) { + sqlValidityDate = functionProvider.forCDateRange(context.getDateRestrictionRange()); + } + else { + return Optional.empty(); + } + } - private static boolean dateRestrictionApplicable(boolean dateRestrictionRequired, Optional validityDateSelect) { - return dateRestrictionRequired && validityDateSelect.isPresent(); + return Optional.of(sqlValidityDate.asValidityDateRange(connectorLabel)); } - private static SqlFilters collectConceptConditions( - List> conceptElements, CQTable cqTable, SqlFunctionProvider functionProvider, - SqlIdColumns ids) { - WhereCondition collected = collectConditions(conceptElements, cqTable, functionProvider, ids); - return new SqlFilters( - ConnectorSqlSelects.none(), - WhereClauses.builder().preprocessingCondition(collected).build() - ); + private static Optional collectConditionFilters(List> conceptElements, CQTable cqTable, SqlFunctionProvider functionProvider) { + return collectConditions(conceptElements, cqTable, functionProvider) + .stream() + .reduce(WhereCondition::and) + .map(whereCondition -> new SqlFilters( + ConnectorSqlSelects.none(), + WhereClauses.builder().preprocessingCondition(whereCondition).build() + )); } - private static WhereCondition collectConditions( - List> conceptElements, CQTable cqTable, SqlFunctionProvider functionProvider, - SqlIdColumns ids) { - WhereCondition connectorCondition = convertConnectorCondition(cqTable, functionProvider, ids); + private static List collectConditions(List> conceptElements, CQTable cqTable, SqlFunctionProvider functionProvider) { List conditions = new ArrayList<>(); + convertConnectorCondition(cqTable, functionProvider).ifPresent(conditions::add); for (ConceptElement conceptElement : conceptElements) { - conditions.add(convertConceptElementCondition(conceptElement, cqTable, functionProvider)); + collectConditions(cqTable, conceptElement, functionProvider) + .reduce(WhereCondition::and) + .ifPresent(conditions::add); } - Optional maybeElementConditions = conditions.stream().reduce(WhereCondition::or); - - if (maybeElementConditions.isEmpty()) { - return connectorCondition; - } - - return connectorCondition.and(maybeElementConditions.get()); - - } - - private static WhereCondition connectorPrerequisites(SqlIdColumns ids, ValidityDate validityDate, SqlFunctionProvider functionProvider) { - List conditions = new ArrayList<>(); - if (validityDate != null) { - conditions.add(functionProvider.validityDateFilter(validityDate)); - } - - for (Field field : ids.getPredecessor().get().toFields()) { - conditions.add(field.isNotNull()); - } - - return new ConditionWrappingWhereCondition(DSL.and(conditions)); + return conditions; } /** - * Collects all conditions of a given {@link ConceptTreeChild} by resolving the condition of the given node and all of its parent nodes. + * Collects all conditions of a given {@link ConceptElement} by resolving the condition of the given node and all of its parent nodes. */ - private static WhereCondition convertConceptElementCondition(ConceptElement conceptElement, CQTable cqTable, SqlFunctionProvider functionProvider) { - if (!(conceptElement instanceof ConceptTreeChild)) { - return new ConditionWrappingWhereCondition(DSL.noCondition()); + private static Stream collectConditions(CQTable cqTable, ConceptElement conceptElement, SqlFunctionProvider functionProvider) { + if (!(conceptElement instanceof ConceptTreeChild child)) { + return Stream.empty(); } - - ConceptTreeChild child = (ConceptTreeChild) conceptElement; - WhereCondition childCondition = child.getCondition().convertToSqlCondition(CTConditionContext.create(cqTable.getConnector().resolve(), functionProvider)); - WhereCondition parentCondition = convertConceptElementCondition(child.getParent(), cqTable, functionProvider); - - return parentCondition.and(childCondition); + return Stream.concat( + collectConditions(cqTable, child.getParent(), functionProvider), + Stream.of(childCondition) + ); } - private static WhereCondition convertConnectorCondition(CQTable cqTable, SqlFunctionProvider functionProvider, SqlIdColumns ids) { - + private static Optional convertConnectorCondition(CQTable cqTable, SqlFunctionProvider functionProvider) { final Connector connector = cqTable.getConnector().resolve(); - WhereCondition prerequisites = connectorPrerequisites(ids, cqTable.findValidityDate(), functionProvider); - - if (connector.getCondition() == null) { - return prerequisites; - } - WhereCondition converted = connector.getCondition().convertToSqlCondition(CTConditionContext.create(connector, functionProvider)); - - return converted.and(prerequisites); + return Optional.ofNullable(connector.getCondition()) + .map(condition -> condition.convertToSqlCondition(CTConditionContext.create(connector, functionProvider))); } - private static Optional getDateRestriction(ConversionContext context, Optional validityDate) { + private static SqlFilters dateRestrictionFilter(ConversionContext context, ColumnDateRange validityDate) { - if (!dateRestrictionApplicable(context.dateRestrictionActive(), validityDate)) { - return Optional.empty(); - } + List dateRestrictionSelects = new ArrayList<>(); + List conditions = new ArrayList<>(); - SqlFunctionProvider functionProvider = context.getFunctionProvider(); - ColumnDateRange dateRestriction = functionProvider.forCDateRange(context.getDateRestrictionRange()).as(SharedAliases.DATE_RESTRICTION.getAlias()); + conditions.add(ConditionUtil.wrap(validityDate.isNotEmpty())); - List dateRestrictionSelects = dateRestriction.toFields().stream() - .map(FieldWrapper::new) - .collect(Collectors.toList()); + if (context.getDateRestrictionRange() != null) { + SqlFunctionProvider functionProvider = context.getFunctionProvider(); + ColumnDateRange dateRestriction = functionProvider.forCDateRange(context.getDateRestrictionRange()).as(SharedAliases.DATE_RESTRICTION.getAlias()); + conditions.add(ConditionUtil.wrap(functionProvider.dateRestriction(dateRestriction, validityDate))); - Condition dateRestrictionCondition = functionProvider.dateRestriction(dateRestriction, validityDate.get()); + dateRestrictionSelects.addAll(dateRestriction.toFields().stream() + .map(FieldWrapper::new) + .toList()); + } - return Optional.of(new SqlFilters( + return new SqlFilters( ConnectorSqlSelects.builder().preprocessingSelects(dateRestrictionSelects).build(), - WhereClauses.builder().eventFilter(ConditionUtil.wrap(dateRestrictionCondition)).build() - )); + WhereClauses.builder() + .eventFilters(conditions) + .build() + ); } private static ConnectorSqlSelects createConceptColumnConnectorSqlSelects(CQConcept cqConcept, SelectContext selectContext) { - for (SelectId selectId : cqConcept.getSelects()) { - Select resolve = selectId.resolve(); - if (resolve instanceof ConceptColumnSelect select) { - return select.createConverter().connectorSelect(select, selectContext); - } - } - - return ConnectorSqlSelects.none(); + return cqConcept.getSelects().stream() + .map(SelectId::resolve) + .filter(select -> select instanceof ConceptColumnSelect) + .findFirst() + .map(select -> select.createConverter().connectorSelect(select, selectContext)) + .orElse(ConnectorSqlSelects.none()); } @Override @@ -308,38 +287,32 @@ private Optional convertCqTable(TablePath tablePath, CQConcept cqConc private CQTableContext createTableContext(TablePath tablePath, CQConcept cqConcept, CQTable cqTable, ConversionContext conversionContext) { - ConnectorSqlTables connectorTables = tablePath.getConnectorTables(cqTable); - - // Convert Ids SqlIdColumns ids = convertIds(cqConcept, cqTable, conversionContext); - - // Convert ValidityDate - Optional tablesValidityDate = convertValidityDate(cqTable.findValidityDate(), connectorTables.getLabel(), conversionContext); + ConnectorSqlTables connectorTables = tablePath.getConnectorTables(cqTable); + Optional tablesValidityDate = convertValidityDate(cqTable, connectorTables.getLabel(), conversionContext); // convert filters SqlFunctionProvider functionProvider = conversionContext.getFunctionProvider(); List allSqlFiltersForTable = new ArrayList<>(); - - for (FilterValue filterValue : cqTable.getFilters()) { - allSqlFiltersForTable.add(filterValue.convertToSqlFilter(ids, conversionContext, connectorTables)); + cqTable.getFilters().stream() + .map(filterValue -> filterValue.convertToSqlFilter(ids, conversionContext, connectorTables)) + .forEach(allSqlFiltersForTable::add); + collectConditionFilters(cqConcept.getElements().stream().>map(ConceptElementId::resolve).toList(), cqTable, functionProvider).ifPresent( + allSqlFiltersForTable::add); + if (tablesValidityDate.isPresent()) { + allSqlFiltersForTable.add(dateRestrictionFilter(conversionContext, tablesValidityDate.get())); } - List> resolvedConceptElements = cqConcept.getElements().stream().>map(ConceptElementId::resolve).toList(); - allSqlFiltersForTable.add(collectConceptConditions(resolvedConceptElements, cqTable, functionProvider, ids)); - - getDateRestriction(conversionContext, tablesValidityDate).ifPresent(allSqlFiltersForTable::add); - // convert selects SelectContext selectContext = SelectContext.create(ids, tablesValidityDate, connectorTables, conversionContext); List allSelectsForTable = new ArrayList<>(); ConnectorSqlSelects conceptColumnSelect = createConceptColumnConnectorSqlSelects(cqConcept, selectContext); allSelectsForTable.add(conceptColumnSelect); - - for (ConnectorSelectId connectorSelectId : cqTable.getSelects()) { - Select select = connectorSelectId.resolve(); - ConnectorSqlSelects connectorSqlSelects = select.createConverter().connectorSelect(select, selectContext); - allSelectsForTable.add(connectorSqlSelects); - } + cqTable.getSelects() + .stream() + .map(SelectId::resolve) + .map(select -> select.createConverter().connectorSelect(select, selectContext)) + .forEach(allSelectsForTable::add); return CQTableContext.builder() .ids(ids) diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/ConnectorSqlTables.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/ConnectorSqlTables.java index fe9443edc1..e88c60c3cf 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/ConnectorSqlTables.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/ConnectorSqlTables.java @@ -21,6 +21,11 @@ public class ConnectorSqlTables extends SqlTables { */ private final boolean withIntervalPacking; + /** + * True if these tables should not propagate a present validity date. + */ + private final boolean excludedFromTimeAggregation; + /** * Corresponding {@link Connector} of these {@link SqlTables}. */ @@ -32,12 +37,14 @@ public ConnectorSqlTables( String rootTable, Map cteNameMap, Map predecessorMap, - boolean containsIntervalPacking + boolean containsIntervalPacking, + boolean excludedFromTimeAggregation ) { super(rootTable, cteNameMap, predecessorMap); this.connector = connector; this.label = conceptConnectorLabel; this.withIntervalPacking = containsIntervalPacking; + this.excludedFromTimeAggregation = excludedFromTimeAggregation; } } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/EventFilterCte.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/EventFilterCte.java index 10e13d61bd..18551f789d 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/EventFilterCte.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/EventFilterCte.java @@ -1,5 +1,6 @@ package com.bakdata.conquery.sql.conversion.cqelement.concept; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.stream.Stream; @@ -22,10 +23,17 @@ class EventFilterCte extends ConnectorCte { @Override public QueryStep.QueryStepBuilder convertStep(CQTableContext tableContext) { + List conditions = new ArrayList<>(); + + if (tableContext.getIds().getSecondaryId().isPresent()) { + conditions.add(tableContext.getIds().getSecondaryId().get().isNotNull()); + } + + conditions.addAll(collectEventFilterConditions(tableContext)); return QueryStep.builder() .selects(collectSelects(tableContext)) - .conditions(collectEventFilterConditions(tableContext)); + .conditions(conditions); } @Override diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/JoinBranchesCte.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/JoinBranchesCte.java index 49cdb8e9d4..da826be3a0 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/JoinBranchesCte.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/JoinBranchesCte.java @@ -58,7 +58,7 @@ protected QueryStep.QueryStepBuilder convertStep(CQTableContext tableContext) { // validity date aggregation Optional validityDate; - if (!tableContext.getConnectorTables().isWithIntervalPacking()) { + if (tableContext.getValidityDate().isEmpty() || !tableContext.getConnectorTables().isWithIntervalPacking()) { validityDate = Optional.empty(); } else { @@ -72,6 +72,11 @@ protected QueryStep.QueryStepBuilder convertStep(CQTableContext tableContext) { if (intervalPackingSelectsStep != lastIntervalPackingStep) { queriesToJoin.add(intervalPackingSelectsStep); } + + // interval packing was required for event date selects, but we won't propagate it + if (tableContext.getConnectorTables().isExcludedFromTimeAggregation()) { + validityDate = Optional.empty(); + } } // additional preceding tables diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/PreprocessingCte.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/PreprocessingCte.java index 305d89eead..80f377a025 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/PreprocessingCte.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/PreprocessingCte.java @@ -35,7 +35,6 @@ public QueryStep.QueryStepBuilder convertStep(CQTableContext tableContext) { .validityDate(tableContext.getValidityDate()) .sqlSelects(forPreprocessing) .build(); - // all where clauses that don't require any preprocessing (connector/child conditions) List conditions = new ArrayList<>(); @@ -50,12 +49,13 @@ public QueryStep.QueryStepBuilder convertStep(CQTableContext tableContext) { .selects(preprocessingSelects) .conditions(conditions); - if (!tableContext.getConversionContext().isWithStratification()) { - TableLike rootTable = QueryStep.toTableLike(tableContext.getConnectorTables().getPredecessor(ConceptCteStep.PREPROCESSING)); - return builder.fromTable(rootTable); + if (tableContext.getConversionContext().isWithStratification()) { + return joinWithStratificationTable(forPreprocessing, conditions, tableContext); } - return joinWithStratificationTable(forPreprocessing, conditions, tableContext); + TableLike rootTable = QueryStep.toTableLike(tableContext.getConnectorTables().getPredecessor(ConceptCteStep.PREPROCESSING)); + return builder.fromTable(rootTable); + } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/TablePath.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/TablePath.java index 3488de7d65..dba9c97022 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/TablePath.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/TablePath.java @@ -57,7 +57,8 @@ private static ConnectorSqlTables createConnectorTables(CQConcept cqConcept, CQT tableInfo.getRootTable(), cteNameMap, tableInfo.getMappings(), - tableInfo.isContainsIntervalPacking() + tableInfo.isContainsIntervalPacking(), + tableInfo.isExcludedFromTimeAggregation() ); } @@ -83,15 +84,20 @@ private static TablePathInfo collectConnectorTables(CQConcept cqConcept, CQTable tableInfo.addWithDefaultMapping(MANDATORY_STEPS); boolean eventDateSelectsPresent = cqTable.getSelects().stream().map(SelectId::resolve).anyMatch(Select::isEventDateSelect); - // no validity date aggregation possible nor necessary - if (cqTable.findValidityDate() == null || (!cqConcept.isAggregateEventDates() && !eventDateSelectsPresent)) { + // no validity date aggregation necessary + if (!cqConcept.isAggregateEventDates() && !eventDateSelectsPresent) { return tableInfo; } - // interval packing required + // interval packing requiredw tableInfo.setContainsIntervalPacking(true); tableInfo.addMappings(IntervalPackingCteStep.getMappings(EVENT_FILTER, context.getDialectBundle())); + // validity date propagation not necessary + if (!cqConcept.isAggregateEventDates()) { + tableInfo.setExcludedFromTimeAggregation(true); + } + if (!eventDateSelectsPresent) { return tableInfo; } @@ -160,6 +166,11 @@ private static class TablePathInfo { */ private boolean containsIntervalPacking; + /** + * True if these tables should not propagate a present validity date. + */ + private boolean excludedFromTimeAggregation; + public TablePathInfo() { this.mappings = new HashMap<>(); } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/intervalpacking/AnsiSqlIntervalPacker.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/intervalpacking/AnsiSqlIntervalPacker.java index aa18433443..178136ea1a 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/intervalpacking/AnsiSqlIntervalPacker.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/intervalpacking/AnsiSqlIntervalPacker.java @@ -74,7 +74,7 @@ private QueryStep createRangeIndexStep(QueryStep previousEndStep, IntervalPackin Field rangeIndex = DSL.sum( - DSL.when(daterange.getStart().greaterThan(previousEnd), DSL.val(1)) + DSL.when(daterange.getStart().greaterThan(previousEnd), DSL.inline(1)) .otherwise(DSL.inline(null, Integer.class))) .over(DSL.partitionBy(ids.toFields()) .orderBy(daterange.getStart(), daterange.getEnd()) diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/DialectBundle.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/DialectBundle.java index 0b229b03db..e66402d491 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/DialectBundle.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/DialectBundle.java @@ -5,6 +5,7 @@ import java.util.function.Function; import java.util.stream.Collectors; +import com.bakdata.conquery.models.config.ConqueryConfig; import com.bakdata.conquery.models.config.Dialect; import com.bakdata.conquery.models.events.MajorTypeId; import com.bakdata.conquery.models.query.Visitable; @@ -27,6 +28,7 @@ import com.bakdata.conquery.sql.conversion.query.RelativFormQueryConverter; import com.bakdata.conquery.sql.conversion.query.SecondaryIdQueryConverter; import com.bakdata.conquery.sql.conversion.query.TableExportQueryConverter; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.bakdata.conquery.sql.execution.SqlCDateSetParser; import org.jooq.DSLContext; import org.jooq.Field; @@ -35,8 +37,6 @@ //TODO unify with com.bakdata.conquery.models.config.Dialect public interface DialectBundle { - Dialect getDialect(); - private static > List customize(List defaults, List substitutes) { Map, C> substituteMap = getSubstituteMap(substitutes); return defaults.stream() @@ -52,6 +52,10 @@ public interface DialectBundle { )); } + ResultSetProcessor getResultSetProcessor(ConqueryConfig config); + + Dialect getDialect(); + int getNameMaxLength(); String getConnectionTestString(); diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/HanaDialectBundle.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/HanaDialectBundle.java index 215df68c6c..ef12b04e98 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/HanaDialectBundle.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/HanaDialectBundle.java @@ -2,6 +2,7 @@ import java.util.List; +import com.bakdata.conquery.models.config.ConqueryConfig; import com.bakdata.conquery.models.config.Dialect; import com.bakdata.conquery.models.events.MajorTypeId; import com.bakdata.conquery.models.query.Visitable; @@ -10,7 +11,9 @@ import com.bakdata.conquery.sql.conversion.cqelement.intervalpacking.AnsiSqlIntervalPacker; import com.bakdata.conquery.sql.conversion.forms.HanaStratificationFunctions; import com.bakdata.conquery.sql.conversion.forms.StratificationFunctions; -import com.bakdata.conquery.sql.execution.DefaultSqlCDateSetParser; +import com.bakdata.conquery.sql.execution.DefaultResultSetProcessor; +import com.bakdata.conquery.sql.execution.HanaSqlCDateSetParser; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.bakdata.conquery.sql.execution.SqlCDateSetParser; import org.jooq.DSLContext; import org.jooq.Field; @@ -18,16 +21,21 @@ public class HanaDialectBundle implements DialectBundle { - private final SqlFunctionProvider hanaSqlFunctionProvider; - private final IntervalPacker hanaIntervalPacker; - private final SqlDateAggregator hanaSqlDateAggregator; - private final DefaultSqlCDateSetParser defaultNotationParser; + private final SqlFunctionProvider functionProvider; + private final IntervalPacker intervalPacker; + private final SqlDateAggregator dateAggregator; + private final SqlCDateSetParser dateSetParser; public HanaDialectBundle() { - this.hanaSqlFunctionProvider = new HanaSqlFunctionProvider(); - this.hanaIntervalPacker = new AnsiSqlIntervalPacker(); - this.hanaSqlDateAggregator = new AnsiSqlDateAggregator(this.hanaIntervalPacker); - this.defaultNotationParser = new DefaultSqlCDateSetParser(); + this.functionProvider = new HanaSqlFunctionProvider(); + this.intervalPacker = new AnsiSqlIntervalPacker(); + this.dateAggregator = new AnsiSqlDateAggregator(this.intervalPacker, functionProvider); + this.dateSetParser = new HanaSqlCDateSetParser(); + } + + @Override + public ResultSetProcessor getResultSetProcessor(ConqueryConfig config) { + return new DefaultResultSetProcessor(config, getCDateSetParser()); } @Override @@ -52,7 +60,7 @@ public SQLDialect getJooqDialect() { @Override public SqlCDateSetParser getCDateSetParser() { - return this.defaultNotationParser; + return this.dateSetParser; } @Override @@ -81,17 +89,17 @@ public boolean isTypeCompatible(Field field, MajorTypeId type) { @Override public SqlFunctionProvider getFunctionProvider() { - return this.hanaSqlFunctionProvider; + return this.functionProvider; } @Override public IntervalPacker getIntervalPacker() { - return this.hanaIntervalPacker; + return this.intervalPacker; } @Override public SqlDateAggregator getDateAggregator() { - return this.hanaSqlDateAggregator; + return this.dateAggregator; } } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/HanaSqlFunctionProvider.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/HanaSqlFunctionProvider.java index 99831de70c..a2221f2091 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/HanaSqlFunctionProvider.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/HanaSqlFunctionProvider.java @@ -1,6 +1,7 @@ package com.bakdata.conquery.sql.conversion.dialect; -import static org.jooq.impl.DSL.nullif; +import static com.bakdata.conquery.sql.execution.ResultSetProcessor.UNIT_SEPARATOR; +import static org.jooq.impl.DSL.*; import java.sql.Date; import java.time.LocalDate; @@ -31,9 +32,11 @@ public class HanaSqlFunctionProvider implements SqlFunctionProvider { - private static final char DELIMITER = ','; - private static final String MAX_DATE_VALUE = "9999-12-31"; - private static final String MIN_DATE_VALUE = "0001-01-01"; + public static final String MAX_DATE_VALUE = "9999-12-31"; + public static final String MIN_DATE_VALUE = "0001-01-01"; + public static final String DATERANGE_SEPARATOR = "/"; + + public static final char DATE_SET_SEPARATOR = UNIT_SEPARATOR; private static final String ANY_CHAR_REGEX = ".*"; private static final String NOP_TABLE = "DUMMY"; @@ -45,7 +48,7 @@ public String getAnyCharRegex() { @Override public Table getNoOpTable() { // see https://help.sap.com/docs/SAP_DATA_HUB/e8d3e271a4554a35a5a6136d3d6af3f8/4d4b939b37b84bea8b2aa2ada640c392.html - return DSL.table(DSL.name(NOP_TABLE)); + return table(name(NOP_TABLE)); } @Override @@ -58,7 +61,7 @@ public Condition dateRestriction(ColumnDateRange dateRestriction, ColumnDateRang Condition dateRestrictionStartsBeforeDate = dateRestriction.getStart().lessThan(daterange.getEnd()); Condition dateRestrictionEndsAfterDate = dateRestriction.getEnd().greaterThan(daterange.getStart()); - return DSL.condition(dateRestrictionStartsBeforeDate.and(dateRestrictionEndsAfterDate)); + return condition(dateRestrictionStartsBeforeDate.and(dateRestrictionEndsAfterDate)); } @Override @@ -93,20 +96,30 @@ public ColumnDateRange forCDateRange(CDateRange daterange) { @Override public Field toDateField(String dateExpression) { - return DSL.function( + return function( "TO_DATE", Date.class, - DSL.val(dateExpression), - DSL.val(DEFAULT_DATE_FORMAT) + inline(dateExpression), + inline(DEFAULT_DATE_FORMAT) ); } + @Override + public ColumnDateRange emptyColumnDateRange() { + return ColumnDateRange.of(field(inline(null, Date.class)), field(inline(null, Date.class))); + } + @Override public ColumnDateRange forValidityDate(ValidityDate validityDate) { return toColumnDateRange(validityDate); } + @Override + public ColumnDateRange allRange() { + return ColumnDateRange.of(toDateField(MIN_DATE_VALUE).as("all_range_start"), toDateField(MAX_DATE_VALUE).as("all_range_end")); + } + private ColumnDateRange toColumnDateRange(ValidityDate validityDate) { String tableName = validityDate.getConnector().resolveTableId().getTable(); @@ -130,14 +143,14 @@ private ColumnDateRange toColumnDateRange(ValidityDate validityDate) { private ColumnDateRange ofStartAndEnd(String tableName, Column startColumn, Column endColumn) { - Field rangeStart = DSL.coalesce( - DSL.field(DSL.name(tableName, startColumn.getName()), Date.class), + Field rangeStart = coalesce( + field(name(tableName, startColumn.getName()), Date.class), toDateField(MIN_DATE_VALUE) ); // when aggregating date ranges, we want to treat the last day of the range as excluded, // so when using the date value of the end column, we add +1 day as end of the date range - Field rangeEnd = DSL.coalesce( - addDays(DSL.field(DSL.name(tableName, endColumn.getName()), Date.class), DSL.val(1)), + Field rangeEnd = coalesce( + addDays(field(name(tableName, endColumn.getName()), Date.class), inline(1)), toDateField(MAX_DATE_VALUE) ); @@ -146,7 +159,7 @@ private ColumnDateRange ofStartAndEnd(String tableName, Column startColumn, Colu @Override public Field addDays(Field dateColumn, Field amountOfDays) { - return DSL.function( + return function( "ADD_DAYS", Date.class, dateColumn, @@ -154,19 +167,28 @@ public Field addDays(Field dateColumn, Field amountOfDays) ); } + @Override + public ColumnDateRange allRangeIf(Condition condition) { + return ColumnDateRange.of( + when(condition.isTrue(), + allRange() + ) + ); + } + @Override public ColumnDateRange forValidityDate(ValidityDate validityDate, CDateRange dateRestriction) { ColumnDateRange validityDateRange = toColumnDateRange(validityDate); ColumnDateRange restriction = toColumnDateRange(dateRestriction); - Field lowerBound = DSL.when(validityDateRange.getStart().lessThan(restriction.getStart()), restriction.getStart()) - .otherwise(validityDateRange.getStart()); + Field lowerBound = when(validityDateRange.getStart().lessThan(restriction.getStart()), restriction.getStart()) + .otherwise(validityDateRange.getStart()); Field maxDate = toDateField(MAX_DATE_VALUE); // we want to add +1 day to the end date - except when it's the max date already - Field restrictionUpperBound = DSL.when(restriction.getEnd().eq(maxDate), maxDate).otherwise(addDays(restriction.getEnd(), DSL.val(1))); - Field upperBound = DSL.when(validityDateRange.getEnd().greaterThan(restriction.getEnd()), restrictionUpperBound) - .otherwise(validityDateRange.getEnd()); + Field restrictionUpperBound = when(restriction.getEnd().eq(maxDate), maxDate).otherwise(addDays(restriction.getEnd(), inline(1))); + Field upperBound = when(validityDateRange.getEnd().greaterThan(restriction.getEnd()), restrictionUpperBound) + .otherwise(validityDateRange.getEnd()); return ColumnDateRange.of(lowerBound, upperBound); } @@ -221,8 +243,8 @@ public ColumnDateRange forArbitraryDateRange(DaterangeSelectOrFilter daterangeSe @Override public ColumnDateRange aggregated(ColumnDateRange columnDateRange) { return ColumnDateRange.of( - DSL.min(columnDateRange.getStart()), - DSL.max(columnDateRange.getEnd()) + min(columnDateRange.getStart()), + max(columnDateRange.getEnd()) ) .as(columnDateRange.getAlias()); } @@ -247,53 +269,43 @@ public QueryStep unnestDaterange(ColumnDateRange nested, QueryStep predecessor, } @Override - public Field daterangeStringAggregation(ColumnDateRange columnDateRange) { + public Field dateRangeAggregation(ColumnDateRange columnDateRange) { Field stringAggregation = stringAggregation( - daterangeStringExpression(columnDateRange), - DSL.toChar(DELIMITER), + dateRangeToField(columnDateRange), + toChar(DATE_SET_SEPARATOR), List.of(columnDateRange.getStart()) ); // encapsulate all ranges (including empty ranges) within curly braces - return DSL.when(stringAggregation.isNull(), DSL.val("{}")) - .otherwise(encloseInCurlyBraces(stringAggregation)); + return stringAggregation; } @Override - public Field daterangeStringExpression(ColumnDateRange columnDateRange) { + public Field dateRangeToField(ColumnDateRange columnDateRange) { if (columnDateRange.isSingleColumnRange()) { throw new UnsupportedOperationException("HANA does not support single-column date ranges."); } - Field startDate = columnDateRange.getStart(); - Field endDate = columnDateRange.getEnd(); - - Field startDateExpression = cast(startDate, SQLDataType.VARCHAR); - Field endDateExpression = cast(endDate, SQLDataType.VARCHAR); - - Field withMinDateReplaced = replace(startDateExpression, MIN_DATE_VALUE, MINUS_INFINITY_SIGN); - Field withMaxDateReplaced = replace(endDateExpression, MAX_DATE_VALUE, INFINITY_SIGN); - - // add interval braces to ranges: start is allways included, end is allways excluded except if it's the maximum/infinity date - Field enclosedMinDate = DSL.field("'[' || {0}", String.class, withMinDateReplaced); - Field enclosedMaxDate = DSL.when(withMaxDateReplaced.like(INFINITY_SIGN), DSL.field("{0} || ']'", String.class, withMaxDateReplaced)) - .otherwise(DSL.field("{0} || ')'", String.class, withMaxDateReplaced)); - - return DSL.field("{0} || ',' || {1}", String.class, enclosedMinDate, enclosedMaxDate); + // translation is handled in printer + return field("'[' || {0} || {2} || {1} || ')'", String.class, + cast(columnDateRange.getStart(), SQLDataType.VARCHAR), + cast(columnDateRange.getEnd(), SQLDataType.VARCHAR), + DATERANGE_SEPARATOR + ); } @Override public Field cast(Field field, DataType type) { // HANA would require an explicit length param when using CAST with varchar type, TO_VARCHAR does not require this if (type == SQLDataType.VARCHAR) { - return DSL.function("TO_VARCHAR", type.getType(), field); + return function("TO_VARCHAR", type.getType(), field); } - return DSL.function( + return function( "CAST", type.getType(), - DSL.field("%s AS %s".formatted(field, type.getName())) + field("{0} AS {1}", field, keyword(type.getName())) ); } @@ -307,7 +319,7 @@ public Field dateDistance(ChronoUnit datePart, Field startDate, F default -> throw new UnsupportedOperationException("Given ChronoUnit %s is not supported."); }; - Field dateDistance = DSL.function(betweenFunction, Integer.class, startDate, endDate); + Field dateDistance = function(betweenFunction, Integer.class, startDate, endDate); // HANA does not support decades or centuries directly dateDistance = switch (datePart) { @@ -320,26 +332,36 @@ public Field dateDistance(ChronoUnit datePart, Field startDate, F return dateDistance.cast(Integer.class); } + @Override + public Field lower(Field daterange) { + throw new UnsupportedOperationException("HANA does not support single-column date ranges."); + } + + @Override + public Field upper(Field daterange) { + throw new UnsupportedOperationException("HANA does not support single-column date ranges."); + } + @Override public Field random(Field column) { - return DSL.field( + return field( "{0}({1} {2})", column.getType(), - DSL.keyword("FIRST_VALUE"), + keyword("FIRST_VALUE"), column, - DSL.orderBy(DSL.function("RAND", Object.class)) + orderBy(function("RAND", Object.class)) ); } @Override public Condition likeRegex(Field field, String pattern) { - return DSL.condition("{0} {1} {2}", field, DSL.keyword("LIKE_REGEXPR"), pattern); + return condition("{0} {1} {2}", field, keyword("LIKE_REGEXPR"), pattern); } @Override public Field yearQuarter(Field dateField) { - return DSL.function("QUARTER", String.class, dateField); + return function("QUARTER", String.class, dateField); } } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/PostgreDialectBundle.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/PostgreDialectBundle.java index f7e672541b..d145f61d3b 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/PostgreDialectBundle.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/PostgreDialectBundle.java @@ -2,6 +2,7 @@ import java.util.List; +import com.bakdata.conquery.models.config.ConqueryConfig; import com.bakdata.conquery.models.config.Dialect; import com.bakdata.conquery.models.events.MajorTypeId; import com.bakdata.conquery.models.query.Visitable; @@ -10,19 +11,25 @@ import com.bakdata.conquery.sql.conversion.cqelement.intervalpacking.PostgreSqlIntervalPacker; import com.bakdata.conquery.sql.conversion.forms.PostgresStratificationFunctions; import com.bakdata.conquery.sql.conversion.forms.StratificationFunctions; -import com.bakdata.conquery.sql.execution.DefaultSqlCDateSetParser; +import com.bakdata.conquery.sql.execution.DefaultResultSetProcessor; +import com.bakdata.conquery.sql.execution.PgSqlCDateSetParser; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.bakdata.conquery.sql.execution.SqlCDateSetParser; -import lombok.Getter; import org.jooq.DSLContext; import org.jooq.Field; import org.jooq.SQLDialect; public class PostgreDialectBundle implements DialectBundle { - private final SqlFunctionProvider postgresqlFunctionProvider; - private final IntervalPacker postgresqlIntervalPacker; - private final SqlDateAggregator postgresqlDateAggregator; - private final DefaultSqlCDateSetParser defaultNotationParser; + private final SqlFunctionProvider functionProvider; + private final IntervalPacker intervalPacker; + private final SqlDateAggregator dateAggregator; + private final SqlCDateSetParser dateSetParser; + + @Override + public ResultSetProcessor getResultSetProcessor(ConqueryConfig config) { + return new DefaultResultSetProcessor(config, getCDateSetParser()); + } @Override public Dialect getDialect() { @@ -45,15 +52,17 @@ public SQLDialect getJooqDialect() { } public PostgreDialectBundle() { - this.postgresqlFunctionProvider = new PostgreSqlFunctionProvider(); - this.postgresqlIntervalPacker = new PostgreSqlIntervalPacker(this.postgresqlFunctionProvider); - this.postgresqlDateAggregator = new PostgreSqlDateAggregator(this.postgresqlFunctionProvider); - this.defaultNotationParser = new DefaultSqlCDateSetParser(); + this.functionProvider = new PostgreSqlFunctionProvider(); + this.intervalPacker = new PostgreSqlIntervalPacker(this.functionProvider); + this.dateAggregator = new PostgreSqlDateAggregator(this.functionProvider); + this.dateSetParser = new PgSqlCDateSetParser(); } + + @Override public SqlCDateSetParser getCDateSetParser() { - return this.defaultNotationParser; + return this.dateSetParser; } @Override @@ -87,17 +96,17 @@ public boolean isTypeCompatible(Field field, MajorTypeId type) { @Override public SqlFunctionProvider getFunctionProvider() { - return this.postgresqlFunctionProvider; + return this.functionProvider; } @Override public IntervalPacker getIntervalPacker() { - return this.postgresqlIntervalPacker; + return this.intervalPacker; } @Override public SqlDateAggregator getDateAggregator() { - return this.postgresqlDateAggregator; + return this.dateAggregator; } } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/PostgreSqlFunctionProvider.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/PostgreSqlFunctionProvider.java index 1d49274a89..716c52b5fe 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/PostgreSqlFunctionProvider.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/PostgreSqlFunctionProvider.java @@ -1,7 +1,6 @@ package com.bakdata.conquery.sql.conversion.dialect; -import static org.jooq.impl.DSL.field; -import static org.jooq.impl.DSL.nullif; +import static org.jooq.impl.DSL.*; import java.sql.Date; import java.time.temporal.ChronoUnit; @@ -37,15 +36,19 @@ * * @see PostgreSQL Documentation */ -public class -PostgreSqlFunctionProvider implements SqlFunctionProvider { +public class PostgreSqlFunctionProvider implements SqlFunctionProvider { - private static final String OPEN_RANGE = "[)"; - private static final String CLOSED_RANGE = "[]"; - private static final String INFINITY_DATE_VALUE = "infinity"; - private static final String MINUS_INFINITY_DATE_VALUE = "-infinity"; + public static final Field EMPTY_RANGE = field("{0}::daterange", inline("empty"), Object.class); + public static final String INFINITY_DATE_VALUE = "infinity"; + public static final String NEGATIVE_INFINITY_DATE_VALUE = "-infinity"; + public static final String OPEN_RANGE = "[)"; + public static final String CLOSED_RANGE = "[]"; private static final String ANY_CHAR_REGEX = "%"; + private static Field unnest(Field multirange) { + return function("unnest", Object.class, multirange); + } + @Override public String getMaxDateExpression() { return INFINITY_DATE_VALUE; @@ -58,7 +61,7 @@ public String getAnyCharRegex() { @Override public Table getNoOpTable() { - return DSL.table(DSL.select(DSL.val(1))).as(DSL.name(SharedAliases.NOP_TABLE.getAlias())); + return table(select(inline(1))).as(name(SharedAliases.NOP_TABLE.getAlias())); } @NotNull @@ -74,34 +77,32 @@ public Collection> orderByValidityDates( .toList(); } + public Field emptyDateRange() { + return field("{0}::daterange", inline("empty")); + } + @Override public String getMinDateExpression() { - return MINUS_INFINITY_DATE_VALUE; + return NEGATIVE_INFINITY_DATE_VALUE; } @Override public Condition dateRestriction(ColumnDateRange dateRestriction, ColumnDateRange daterange) { // the && operator checks if two ranges overlap (see https://www.postgresql.org/docs/15/functions-range.html) - return DSL.condition( + return condition( "{0} && {1}", ensureIsSingleColumnRange(dateRestriction).getRange(), ensureIsSingleColumnRange(daterange).getRange() ); } - private ColumnDateRange ensureIsSingleColumnRange(ColumnDateRange daterange) { - return daterange.isSingleColumnRange() - ? daterange - : ColumnDateRange.of(daterange(daterange.getStart(), daterange.getEnd(), OPEN_RANGE)); // end is already exclusive - } - public Field daterange(Field startColumn, Field endColumn, String bounds) { - return DSL.function( + return function( "daterange", Object.class, startColumn, endColumn, - DSL.val(bounds) + inline(bounds) ); } @@ -119,7 +120,7 @@ public List forCDateSet(CDateSet dateset, SharedAliases alias) @Override public ColumnDateRange forCDateRange(CDateRange daterange) { - String startDateExpression = MINUS_INFINITY_DATE_VALUE; + String startDateExpression = NEGATIVE_INFINITY_DATE_VALUE; String endDateExpression = INFINITY_DATE_VALUE; if (daterange.hasLowerBound()) { @@ -129,23 +130,24 @@ public ColumnDateRange forCDateRange(CDateRange daterange) { endDateExpression = daterange.getMax().toString(); } - Field daterangeField = daterange(DSL.val(startDateExpression), DSL.val(endDateExpression), CLOSED_RANGE); + Field daterangeField = daterange(inline(startDateExpression), inline(endDateExpression), CLOSED_RANGE); return ColumnDateRange.of(daterangeField); } private Field datemultirange(Field... fields) { - return DSL.function("datemultirange", Object.class, fields); + return function("datemultirange", Object.class, fields); } @Override public ColumnDateRange forValidityDate(ValidityDate validityDate) { // if there is no validity date, each entity has the max range {-inf/inf} as validity date - return validityDate == null ? maxRange() : toColumnDateRange(validityDate); + return validityDate == null ? allRange() : toColumnDateRange(validityDate); } - private ColumnDateRange maxRange() { - return ColumnDateRange.of(daterange(toDateField(MINUS_INFINITY_DATE_VALUE), toDateField(INFINITY_DATE_VALUE), CLOSED_RANGE)); + @Override + public ColumnDateRange allRange() { + return ColumnDateRange.of(daterange(toDateField(NEGATIVE_INFINITY_DATE_VALUE), toDateField(INFINITY_DATE_VALUE), CLOSED_RANGE)); } private ColumnDateRange toColumnDateRange(ValidityDate validityDate) { @@ -158,11 +160,6 @@ private ColumnDateRange toColumnDateRange(ValidityDate validityDate) { return ofStartAndEnd(tableName, validityDate.getStartColumn().resolve(), validityDate.getEndColumn().resolve()); } - @Override - public Field toDateField(String dateValue) { - return DSL.field("{0}::{1}", Date.class, DSL.val(dateValue), DSL.keyword("date")); - } - private ColumnDateRange ofSingleColumn(String tableName, Column column) { Field dateRange; @@ -170,19 +167,19 @@ private ColumnDateRange ofSingleColumn(String tableName, Column column) { dateRange = switch (column.getType()) { // if validityDateColumn is a DATE_RANGE we can make use of Postgres' integrated daterange type, but the upper bound is exclusive by default case DATE_RANGE -> { - Field daterange = DSL.field(DSL.name(column.getName())); - Field withOpenLowerEnd = DSL.coalesce(lower(daterange), toDateField(MINUS_INFINITY_DATE_VALUE)); - Field withOpenUpperEnd = DSL.coalesce(upper(daterange), toDateField(INFINITY_DATE_VALUE)); - yield DSL.when(daterange.isNull(), emptyDateRange()) - .otherwise(daterange(withOpenLowerEnd, withOpenUpperEnd, OPEN_RANGE)); + Field daterange = field(name(column.getName())); + Field withOpenLowerEnd = coalesce(lower(daterange), toDateField(NEGATIVE_INFINITY_DATE_VALUE)); + Field withOpenUpperEnd = coalesce(upper(daterange), toDateField(INFINITY_DATE_VALUE)); + yield when(daterange.isNull(), emptyDateRange()) + .otherwise(daterange(withOpenLowerEnd, withOpenUpperEnd, OPEN_RANGE)); } // if the validity date column is not of daterange type, we construct it manually case DATE -> { - Field singleDate = DSL.field(DSL.name(tableName, column.getName()), Date.class); - Field withOpenLowerEnd = DSL.coalesce(singleDate, toDateField(MINUS_INFINITY_DATE_VALUE)); - Field withOpenUpperEnd = DSL.coalesce(singleDate, toDateField(INFINITY_DATE_VALUE)); - yield DSL.when(singleDate.isNull(), emptyDateRange()) - .otherwise(daterange(withOpenLowerEnd, withOpenUpperEnd, CLOSED_RANGE)); + Field singleDate = field(name(tableName, column.getName()), Date.class); + Field withOpenLowerEnd = coalesce(singleDate, toDateField(NEGATIVE_INFINITY_DATE_VALUE)); + Field withOpenUpperEnd = coalesce(singleDate, toDateField(INFINITY_DATE_VALUE)); + yield when(singleDate.isNull(), emptyDateRange()) + .otherwise(daterange(withOpenLowerEnd, withOpenUpperEnd, CLOSED_RANGE)); } default -> throw new IllegalArgumentException( "Given column type '%s' can't be converted to a proper date restriction.".formatted(column.getType()) @@ -194,39 +191,45 @@ private ColumnDateRange ofSingleColumn(String tableName, Column column) { private ColumnDateRange ofStartAndEnd(String tableName, Column startColumn, Column endColumn) { - Field startField = DSL.field(DSL.name(tableName, startColumn.getName())); - Field withOpenLowerEnd = DSL.coalesce(startField, toDateField(MINUS_INFINITY_DATE_VALUE)); - Field endField = DSL.field(DSL.name(tableName, endColumn.getName())); - Field withOpenUpperEnd = DSL.coalesce(endField, toDateField(INFINITY_DATE_VALUE)); + Field startField = field(name(tableName, startColumn.getName())); + Field withOpenLowerEnd = coalesce(startField, toDateField(NEGATIVE_INFINITY_DATE_VALUE)); + Field endField = field(name(tableName, endColumn.getName())); + Field withOpenUpperEnd = coalesce(endField, toDateField(INFINITY_DATE_VALUE)); return ColumnDateRange.of( - DSL.when(startField.isNull().and(endField.isNull()), emptyDateRange()) - .otherwise(this.daterange(withOpenLowerEnd, withOpenUpperEnd, CLOSED_RANGE)) + when(startField.isNull().and(endField.isNull()), emptyDateRange()) + .otherwise(this.daterange(withOpenLowerEnd, withOpenUpperEnd, CLOSED_RANGE)) ); } - private static Field lower(Field daterange) { - return DSL.function("lower", Date.class, daterange); - } - - private static Field upper(Field daterange) { - return DSL.function("upper", Date.class, daterange); - } - - public Field emptyDateRange() { - return DSL.field("{0}::daterange", DSL.val("empty")); + @Override + public ColumnDateRange allRangeIf(Condition condition) { + return ColumnDateRange.of( + when(condition.isTrue(), + datemultirange(daterange(toDateField(NEGATIVE_INFINITY_DATE_VALUE), toDateField(INFINITY_DATE_VALUE), CLOSED_RANGE)) + ) + ); } @Override public ColumnDateRange forValidityDate(ValidityDate validityDate, CDateRange dateRestriction) { // if there is no validity date, each entity has the max range {-inf/inf} as validity date - ColumnDateRange validityDateRange = validityDate == null ? maxRange() : toColumnDateRange(validityDate); + ColumnDateRange validityDateRange = validityDate == null ? allRange() : toColumnDateRange(validityDate); ColumnDateRange restriction = toColumnDateRange(dateRestriction); return intersection(validityDateRange, restriction); } + @Override + public ColumnDateRange intersection(ColumnDateRange left, ColumnDateRange right) { + return ColumnDateRange.of(field( + "{0} * {1}", + ensureIsSingleColumnRange(right).getRange(), + ensureIsSingleColumnRange(left).getRange() + )); + } + private ColumnDateRange toColumnDateRange(CDateRange dateRestriction) { - String startDateExpression = MINUS_INFINITY_DATE_VALUE; + String startDateExpression = NEGATIVE_INFINITY_DATE_VALUE; String endDateExpression = INFINITY_DATE_VALUE; if (dateRestriction.hasLowerBound()) { @@ -240,15 +243,6 @@ private ColumnDateRange toColumnDateRange(CDateRange dateRestriction) { return ColumnDateRange.of(dateRestrictionRange); } - @Override - public ColumnDateRange intersection(ColumnDateRange left, ColumnDateRange right) { - return ColumnDateRange.of(DSL.field( - "{0} * {1}", - ensureIsSingleColumnRange(left).getRange(), - ensureIsSingleColumnRange(right).getRange() - )); - } - @Override public ColumnDateRange forArbitraryDateRange(DaterangeSelectOrFilter daterangeSelectOrFilter) { String tableName = daterangeSelectOrFilter.getTable().getName(); @@ -266,14 +260,14 @@ public ColumnDateRange aggregated(ColumnDateRange columnDateRange) { } private Field rangeAgg(ColumnDateRange columnDateRange) { - return DSL.function("range_agg", Object.class, columnDateRange.getRange()); + return function("range_agg", Object.class, columnDateRange.getRange()); } @Override public ColumnDateRange toDualColumn(ColumnDateRange columnDateRange) { Field daterange = columnDateRange.getRange(); - Field start = DSL.function("lower", Date.class, daterange); - Field end = DSL.function("upper", Date.class, daterange); + Field start = lower(daterange); + Field end = upper(daterange); return ColumnDateRange.of(start, end); } @@ -281,7 +275,8 @@ public ColumnDateRange toDualColumn(ColumnDateRange columnDateRange) { public QueryStep unnestDaterange(ColumnDateRange nested, QueryStep predecessor, String cteName) { ColumnDateRange qualifiedRange = nested.qualify(predecessor.getCteName()); - ColumnDateRange unnested = ColumnDateRange.of(unnest(qualifiedRange.getRange()).as(qualifiedRange.getAlias())); + + ColumnDateRange unnested = ColumnDateRange.of(unnest(qualifiedRange.getRange()).as(qualifiedRange.getAlias()), qualifiedRange.getAlias()); Selects selects = Selects.builder() .ids(predecessor.getQualifiedSelects().getIds()) @@ -295,23 +290,17 @@ public QueryStep unnestDaterange(ColumnDateRange nested, QueryStep predecessor, .build(); } - private static Field unnest(Field multirange) { - return DSL.function("unnest", Object.class, multirange); - } - @Override - public Field daterangeStringAggregation(ColumnDateRange columnDateRange) { - Field asMultirange = rangeAgg(columnDateRange); - return daterangeStringExpression(ColumnDateRange.of(asMultirange)); + public Field dateRangeAggregation(ColumnDateRange columnDateRange) { + return rangeAgg(columnDateRange); } @Override - public Field daterangeStringExpression(ColumnDateRange columnDateRange) { + public Field dateRangeToField(ColumnDateRange columnDateRange) { if (!columnDateRange.isSingleColumnRange()) { throw new UnsupportedOperationException("All column date ranges should have been converted to single column ranges."); } - Field aggregatedValidityDate = DSL.field("({0})::{1}", String.class, columnDateRange.getRange(), DSL.keyword("varchar")); - return replace(aggregatedValidityDate, INFINITY_DATE_VALUE, INFINITY_SIGN); + return columnDateRange.getRange(); } @Override @@ -321,7 +310,7 @@ public Field dateDistance(ChronoUnit datePart, Field startDate, F return cast(endDate.minus(startDate), SQLDataType.INTEGER); } - Field age = DSL.function("age", Integer.class, endDate, startDate); + Field age = function("age", Integer.class, endDate, startDate); return switch (datePart) { case MONTHS -> extract(DatePart.YEAR, age).multiply(12).plus(extract(DatePart.MONTH, age)); case YEARS -> extract(DatePart.YEAR, age); @@ -337,12 +326,12 @@ public Field cast(Field field, DataType type) { } public Field extract(DatePart datePart, Field timeInterval) { - return DSL.field( + return field( "{0}({1} {2} {3})", Integer.class, - DSL.keyword("extract"), - DSL.keyword(datePart.toSQL()), - DSL.keyword("from"), + keyword("extract"), + keyword(datePart.toSQL()), + keyword("from"), timeInterval ); } @@ -354,13 +343,13 @@ public Field addDays(Field dateColumn, Field amountOfDays) @Override public Field random(Field column) { - ArrayAggOrderByStep arrayAgg = DSL.arrayAgg(DSL.field( + ArrayAggOrderByStep arrayAgg = arrayAgg(field( "{0} {1} {2}", column, - DSL.keyword("ORDER BY"), - DSL.function("random", Object.class) + keyword("ORDER BY"), + function("random", Object.class) )); - return DSL.field("({0})[1]", column.getType(), arrayAgg); + return field("({0})[1]", column.getType(), arrayAgg); } @Override @@ -370,7 +359,7 @@ public Condition likeRegex(Field field, String pattern) { @Override public Field yearQuarter(Field dateField) { - return DSL.field( + return field( "{0}::varchar || '-Q' || {1}::varchar", String.class, DSL.extract(dateField, DatePart.YEAR), @@ -378,4 +367,31 @@ public Field yearQuarter(Field dateField) { ); } + @Override + public Field toDateField(String dateValue) { + return field("{0}::{1}", Date.class, inline(dateValue), keyword("date")); + } + + @Override + public ColumnDateRange emptyColumnDateRange() { + return ColumnDateRange.of(EMPTY_RANGE); + } + + @Override + public Field upper(Field daterange) { + return function("upper", Date.class, daterange); + } + + @Override + public Field lower(Field daterange) { + return function("lower", Date.class, daterange); + } + + + private ColumnDateRange ensureIsSingleColumnRange(ColumnDateRange daterange) { + return daterange.isSingleColumnRange() + ? daterange + : ColumnDateRange.of(daterange(daterange.getStart(), daterange.getEnd(), OPEN_RANGE)); // end is already exclusive + } + } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/SqlDateAggregator.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/SqlDateAggregator.java index 6ae2919930..175ca894a5 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/SqlDateAggregator.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/SqlDateAggregator.java @@ -5,6 +5,7 @@ import com.bakdata.conquery.models.query.queryplan.DateAggregationAction; import com.bakdata.conquery.sql.conversion.cqelement.ConversionContext; import com.bakdata.conquery.sql.conversion.cqelement.aggregation.DateAggregationDates; +import com.bakdata.conquery.sql.conversion.model.ColumnDateRange; import com.bakdata.conquery.sql.conversion.model.QueryStep; import com.bakdata.conquery.sql.conversion.model.select.SqlSelect; @@ -23,6 +24,8 @@ QueryStep apply( ConversionContext conversionContext ); + ColumnDateRange getAggregatedValidityDate(DateAggregationDates dateAggregationDates, DateAggregationAction dateAggregationAction); + /** * Inverts the validity date of the given base step. */ diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/SqlFunctionProvider.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/SqlFunctionProvider.java index c8b606088a..d3f6a76fe5 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/SqlFunctionProvider.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/SqlFunctionProvider.java @@ -1,11 +1,12 @@ package com.bakdata.conquery.sql.conversion.dialect; +import static org.jooq.impl.DSL.*; + import java.sql.Date; import java.time.temporal.ChronoUnit; import java.util.Collection; import java.util.List; -import java.util.Optional; import java.util.function.Function; import java.util.stream.Collectors; @@ -27,7 +28,6 @@ import org.jooq.SortField; import org.jooq.Table; import org.jooq.TableOnConditionStep; -import org.jooq.impl.DSL; /** * Provider of SQL functions. @@ -86,6 +86,11 @@ Collection> orderByValidityDates( ColumnDateRange forValidityDate(ValidityDate validityDate); + /** + * Creates a {@link ColumnDateRange} of maximum range. + */ + ColumnDateRange allRange(); + /** * Creates a {@link ColumnDateRange} for a tables {@link CQTable}s validity date. The validity dates bounds will be restricted by the given date * restriction. @@ -127,20 +132,30 @@ Collection> orderByValidityDates( *

* Example: {[-∞,2013-11-11),[2015-11-10,∞)} */ - Field daterangeStringAggregation(ColumnDateRange columnDateRange); + Field dateRangeAggregation(ColumnDateRange columnDateRange); /** * Combines the start and end column of a validity date entry into one compound string expression. *

* Example: [2013-11-10,2013-11-11) */ - Field daterangeStringExpression(ColumnDateRange columnDateRange); + Field dateRangeToField(ColumnDateRange columnDateRange); /** * Calculates the date distance in the given {@link ChronoUnit} between an exclusive end date and an inclusive start date. */ Field dateDistance(ChronoUnit datePart, Field startDate, Field endDate); + /** + * Extract the lower inclusive bound of a daterange field. Not supported for dialects without range type support. + */ + Field lower(Field daterange); + + /** + * Extract the upper exclusive bound of a daterange field. Not supported for dialects without range type support. + */ + Field upper(Field daterange); + Field addDays(Field dateColumn, Field amountOfDays); Field random(Field column); @@ -153,24 +168,27 @@ Collection> orderByValidityDates( Field yearQuarter(Field dateField); default Field stringAggregation(Field stringField, Field delimiter, List> orderByFields) { - return DSL.field( + return field( "{0}({1}, {2} {3})", String.class, - DSL.keyword("string_agg"), + keyword("string_agg"), stringField, delimiter, - DSL.orderBy(orderByFields) + orderBy(orderByFields) ); } + ColumnDateRange allRangeIf(Condition condition); + default Field concat(List> fields) { - String concatenated = fields.stream() - // if a field is null, the whole concatenation would be null - but we just want to skip this field in this case, - // thus concat an empty string - .map(field -> DSL.when(field.isNull(), DSL.val("")).otherwise(field)) - .map(Field::toString) - .collect(Collectors.joining(SQL_UNIT_SEPARATOR)); - return DSL.field(concatenated, String.class); + String concatenated = + fields.stream() + // if a field is null, the whole concatenation would be null - but we just want to skip this field in this case, + // thus concat an empty string + .map(field -> field) + .map(Field::toString) + .collect(Collectors.joining(SQL_UNIT_SEPARATOR)); + return field(concatenated, String.class); } default Field least(List> fields) { @@ -179,7 +197,7 @@ default Field least(List> fields) { } Field[] fieldArray = fields.toArray(Field[]::new); // signature only accepts arrays/varargs - return DSL.function("least", fieldArray[0].getType(), fieldArray); + return function("least", fieldArray[0].getType(), fieldArray); } default Field greatest(List> fields) { @@ -188,7 +206,7 @@ default Field greatest(List> fields) { } Field[] fieldArray = fields.toArray(Field[]::new); // signature only accepts arrays/varargs - return DSL.function("greatest", fieldArray[0].getType(), fieldArray); + return function("greatest", fieldArray[0].getType(), fieldArray); } default Condition in(Field column, String[] values) { @@ -208,41 +226,24 @@ default TableOnConditionStep leftJoin(Table leftPart, Table rightP } default Field toDateField(String dateExpression) { - return DSL.toDate(dateExpression, DEFAULT_DATE_FORMAT); - } - - default Field replace(Field target, String old, String _new) { - return DSL.function("replace", String.class, target, DSL.val(old), DSL.val(_new)); - } - - default Field encloseInCurlyBraces(Field stringExpression) { - return DSL.field("'{' || {0} || '}'", String.class, stringExpression); + return toDate(dateExpression, DEFAULT_DATE_FORMAT); } - default Field prefixStringAggregation(Field field, String prefix) { - return DSL.field( - "'[' || {0}({1}, {2}) || ']'", - String.class, - DSL.keyword("STRING_AGG"), - DSL.when(field.like(DSL.inline(prefix + "%")), field), - DSL.val(", ") - ); - } - - default - Condition validityDateFilter(ValidityDate validityDate) { + default Condition validityDateFilter(ValidityDate validityDate) { if (validityDate.isSingleColumnDaterange()) { Column column = validityDate.getColumn().resolve(); - return DSL.field(DSL.name(column.getName())).isNotNull(); + return field(name(column.getName())).isNotNull(); } Column startColumn = validityDate.getStartColumn().resolve(); Column endColumn = validityDate.getEndColumn().resolve(); - return DSL.or(DSL.field(DSL.name(startColumn.getName())).isNotNull(), - DSL.field(DSL.name(endColumn.getName())).isNotNull() + return or(field(name(startColumn.getName())).isNotNull(), + field(name(endColumn.getName())).isNotNull() ); } + ColumnDateRange emptyColumnDateRange(); + } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/forms/AbsoluteStratification.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/forms/AbsoluteStratification.java index d151fc6b93..0a9153dc2c 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/forms/AbsoluteStratification.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/forms/AbsoluteStratification.java @@ -1,5 +1,7 @@ package com.bakdata.conquery.sql.conversion.forms; +import static org.jooq.impl.DSL.*; + import java.sql.Date; import java.util.List; import java.util.Optional; @@ -46,7 +48,7 @@ public QueryStep createStratificationTable(List rowNumber = DSL.rowNumber().over().coerce(Object.class); + Field rowNumber = rowNumber().over().coerce(Object.class); SqlIdColumns ids = new SqlIdColumns(rowNumber); FieldWrapper seriesIndex = new FieldWrapper<>(stratificationFunctions.intSeriesField()); @@ -116,7 +118,7 @@ private QueryStep createCompleteTable() { // complete range shall have a null index because it spans the complete range, but we set it to 1 to ensure we can join tables on index, // because a condition involving null in a join (e.g., null = some_value or null = null) always evaluates to false - Field index = DSL.field(DSL.val(1, Integer.class)).as(SharedAliases.INDEX.getAlias()); + Field index = field(inline(1)).as(SharedAliases.INDEX.getAlias()); SqlIdColumns ids = baseStepSelects.getIds().withAbsoluteStratification(Resolution.COMPLETE, index); ColumnDateRange completeRange = baseStepSelects.getStratificationDate().get(); 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 c877218e9e..7f89ae3fe4 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 @@ -39,7 +39,7 @@ public Field lower(ColumnDateRange dateRange) { @Override protected Field inclusiveUpper(ColumnDateRange dateRange) { - return functionProvider.addDays(exclusiveUpper(dateRange), DSL.val(-1)); + return functionProvider.addDays(exclusiveUpper(dateRange), DSL.inline(-1)); } @Override @@ -72,7 +72,7 @@ public Field upperBoundYearEnd(ColumnDateRange dateRange) { "SERIES_ROUND({0}, {1}, {2})", Date.class, dateRange.getEnd(), - DSL.val("INTERVAL 1 YEAR"), + DSL.inline("INTERVAL 1 YEAR"), DSL.keyword("ROUND_UP") ); } @@ -85,7 +85,7 @@ public Field upperBoundYearEndQuarterAligned(ColumnDateRange dateRange) { // we add +1 year to the quarter aligned end if it is less than the upper bound we want to align return DSL.when( yearEndQuarterAligned.lessThan(dateRange.getEnd()), - shiftByInterval(yearEndQuarterAligned, Interval.ONE_YEAR_INTERVAL, DSL.val(1), Offset.NONE) + shiftByInterval(yearEndQuarterAligned, Interval.ONE_YEAR_INTERVAL, DSL.inline(1), Offset.NONE) ) .otherwise(yearEndQuarterAligned); } @@ -182,14 +182,14 @@ private static Field jumpToYearStart(Field date) { "SERIES_ROUND({0}, {1}, {2})", Date.class, date, - DSL.val("INTERVAL 1 YEAR"), + DSL.inline("INTERVAL 1 YEAR"), DSL.keyword("ROUND_DOWN") ); } private Field getQuartersInMonths(Field date, Offset offset) { Field quarterExpression = functionProvider.yearQuarter(date); - Field rightMostCharacter = DSL.function("RIGHT", String.class, quarterExpression, DSL.val(1)); + Field rightMostCharacter = DSL.function("RIGHT", String.class, quarterExpression, DSL.inline(1)); Field amountOfQuarters = functionProvider.cast(rightMostCharacter, SQLDataType.INTEGER) .plus(offset.getOffset()); return amountOfQuarters.times(MONTHS_PER_QUARTER); 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 459ea14dfe..e67c7a82c9 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 @@ -27,11 +27,11 @@ public class PostgresStratificationFunctions extends StratificationFunctions { private static final Map> INTERVAL_MAP = Map.of( - Interval.ONE_YEAR_INTERVAL, DSL.val("1 year"), - Interval.YEAR_AS_DAYS_INTERVAL, DSL.val("365 days"), - Interval.QUARTER_INTERVAL, DSL.val("3 months"), - Interval.NINETY_DAYS_INTERVAL, DSL.val("90 days"), - Interval.ONE_DAY_INTERVAL, DSL.val("1 day") + Interval.ONE_YEAR_INTERVAL, DSL.inline("1 year"), + Interval.YEAR_AS_DAYS_INTERVAL, DSL.inline("365 days"), + Interval.QUARTER_INTERVAL, DSL.inline("3 months"), + Interval.NINETY_DAYS_INTERVAL, DSL.inline("90 days"), + Interval.ONE_DAY_INTERVAL, DSL.inline("1 day") ); private static final Keyword INTERVAL_KEYWORD = DSL.keyword("interval"); @@ -60,7 +60,7 @@ public Field upperBoundYearEnd(ColumnDateRange dateRange) { return DSL.field( "{0} + {1} {2}", Date.class, - dateTruncate(DSL.val("year"), inclusiveUpper(dateRange)), + dateTruncate(DSL.inline("year"), inclusiveUpper(dateRange)), INTERVAL_KEYWORD, INTERVAL_MAP.get(Interval.ONE_YEAR_INTERVAL) ); @@ -75,7 +75,7 @@ public Field upperBoundYearEndQuarterAligned(ColumnDateRange dateRange) { // we add +1 year to the quarter aligned end if it is less than the upper bound we want to align return DSL.when( yearEndQuarterAligned.lessThan(upperBound), - shiftByInterval(yearEndQuarterAligned, Interval.ONE_YEAR_INTERVAL, DSL.val(1), Offset.NONE) + shiftByInterval(yearEndQuarterAligned, Interval.ONE_YEAR_INTERVAL, DSL.inline(1), Offset.NONE) ) .otherwise(yearEndQuarterAligned); } @@ -99,7 +99,7 @@ public Field upperBoundQuarterEnd(ColumnDateRange dateRange) { @Override public Field jumpToNextQuarterStart(Field date) { - Field yearStart = dateTruncate(DSL.val("year"), date); + Field yearStart = dateTruncate(DSL.inline("year"), date); Field quarter = functionProvider.extract(DatePart.QUARTER, date); return addQuarters(yearStart, quarter, Offset.NONE); } @@ -199,7 +199,7 @@ private Field addQuarters(Field start, Field jumpToYearStart(Field date) { - return dateTruncate(DSL.val("year"), date); + return dateTruncate(DSL.inline("year"), date); } private static Field castExpressionToDate(Field shiftedDate) { 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 a08aa6b7d0..728599ba2c 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 @@ -122,8 +122,8 @@ private QueryStep createTotalBoundsStep(RelativeFormQuery form, QueryStep indexS Interval interval = getInterval(form.getTimeUnit(), Resolution.COMPLETE); Range intRange = toGenerateSeriesBounds(form, Resolution.COMPLETE); - Field minStratificationDate = stratificationFunctions.shiftByInterval(INDEX_START_NEGATIVE, interval, DSL.val(intRange.getMin()), Offset.NONE); - Field maxStratificationDate = stratificationFunctions.shiftByInterval(INDEX_START_POSITIVE, interval, DSL.val(intRange.getMax()), Offset.NONE); + Field minStratificationDate = stratificationFunctions.shiftByInterval(INDEX_START_NEGATIVE, interval, DSL.inline(intRange.getMin()), Offset.NONE); + Field maxStratificationDate = stratificationFunctions.shiftByInterval(INDEX_START_POSITIVE, interval, DSL.inline(intRange.getMax()), Offset.NONE); ColumnDateRange minAndMaxStratificationDate = stratificationFunctions.ofStartAndEnd(minStratificationDate, maxStratificationDate) .as(SharedAliases.STRATIFICATION_BOUNDS.getAlias()); @@ -164,16 +164,16 @@ private QueryStep createCompleteTable(QueryStep totalBoundsStep, RelativeFormQue } private QueryStep createCompleteFeatureTable(Selects predecessorSelects, Interval interval, Range intRange, QueryStep totalBoundsStep) { - Field featureIndex = DSL.field(DSL.val(-1)).as(SharedAliases.INDEX.getAlias()); + Field featureIndex = DSL.field(DSL.inline(-1)).as(SharedAliases.INDEX.getAlias()); SqlIdColumns featureIds = predecessorSelects.getIds().withRelativeStratification(Resolution.COMPLETE, featureIndex, INDEX_SELECTOR); - Field rangeStart = stratificationFunctions.shiftByInterval(INDEX_START_NEGATIVE, interval, DSL.val(intRange.getMin()), Offset.NONE); + Field rangeStart = stratificationFunctions.shiftByInterval(INDEX_START_NEGATIVE, interval, DSL.inline(intRange.getMin()), Offset.NONE); return createIntervalStep(featureIds, rangeStart, INDEX_START_NEGATIVE, Optional.empty(), totalBoundsStep); } private QueryStep createCompleteOutcomeTable(Selects predecessorSelects, Interval interval, Range intRange, QueryStep totalBoundsStep) { - Field outcomeIndex = DSL.field(DSL.val(1)).as(SharedAliases.INDEX.getAlias()); + Field outcomeIndex = DSL.field(DSL.inline(1)).as(SharedAliases.INDEX.getAlias()); SqlIdColumns outcomeIds = predecessorSelects.getIds().withRelativeStratification(Resolution.COMPLETE, outcomeIndex, INDEX_SELECTOR); - Field rangeEnd = stratificationFunctions.shiftByInterval(INDEX_START_POSITIVE, interval, DSL.val(intRange.getMax()), Offset.NONE); + Field rangeEnd = stratificationFunctions.shiftByInterval(INDEX_START_POSITIVE, interval, DSL.inline(intRange.getMax()), Offset.NONE); return createIntervalStep(outcomeIds, INDEX_START_POSITIVE, rangeEnd, Optional.empty(), totalBoundsStep); } 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 29d0d480f2..1a2478b4f1 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 @@ -161,7 +161,7 @@ public List> indexStartFields(IndexPlacement indexPlacement, Calenda negativeStart = INDEX_SELECTOR; } case NEUTRAL -> { - positiveStart = getFunctionProvider().addDays(INDEX_SELECTOR, DSL.val(1)); + positiveStart = getFunctionProvider().addDays(INDEX_SELECTOR, DSL.inline(1)); negativeStart = INDEX_SELECTOR; } default -> throw new CombinationNotSupportedException(indexPlacement, timeUnit); @@ -185,7 +185,7 @@ public List> indexStartFields(IndexPlacement indexPlacement, Calenda public Field calculateResolutionWindowCount(ExportForm.ResolutionAndAlignment resolutionAndAlignment, ColumnDateRange bounds) { SqlFunctionProvider functionProvider = getFunctionProvider(); return switch (resolutionAndAlignment.getResolution()) { - case COMPLETE -> DSL.val(1); + case COMPLETE -> DSL.inline(1); case YEARS -> calculateResolutionWindowForYearResolution(resolutionAndAlignment, bounds, functionProvider); case QUARTERS -> calculateResolutionWindowForQuarterResolution(resolutionAndAlignment, bounds, functionProvider); case DAYS -> functionProvider.dateDistance(ChronoUnit.DAYS, lower(bounds), exclusiveUpper(bounds)) diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/ColumnDateRange.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/ColumnDateRange.java index 5cc417d988..6be9ada893 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/ColumnDateRange.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/ColumnDateRange.java @@ -1,16 +1,20 @@ package com.bakdata.conquery.sql.conversion.model; +import static org.jooq.impl.DSL.field; + import java.sql.Date; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; +import com.bakdata.conquery.sql.conversion.dialect.PostgreSqlFunctionProvider; import com.bakdata.conquery.sql.conversion.model.select.SqlSelect; import lombok.Getter; import org.jooq.Condition; import org.jooq.Field; import org.jooq.impl.DSL; +//TODO split this class up into Dialect specific versions. @Getter public class ColumnDateRange implements SqlSelect { @@ -18,7 +22,7 @@ public class ColumnDateRange implements SqlSelect { private static final String START_SUFFIX = "_start"; private static final String END_SUFFIX = "_end"; - private final Field range; + private final Field range; private final Field start; private final Field end; private final String alias; @@ -31,7 +35,7 @@ protected ColumnDateRange(Field startColumn, Field endColumn, String } protected ColumnDateRange(Field range, String alias) { - this.range = range; + this.range = (Field) range; this.start = null; this.end = null; this.alias = alias; @@ -53,11 +57,6 @@ public static ColumnDateRange of(Field startColumn, Field endColumn, return new ColumnDateRange(startColumn, endColumn, alias); } - public static ColumnDateRange empty() { - Field emptyRange = DSL.field(DSL.val("{}")); - return ColumnDateRange.of(emptyRange); - } - public ColumnDateRange asValidityDateRange(String alias) { return this.as(alias + VALIDITY_DATE_COLUMN_NAME_SUFFIX); } @@ -130,6 +129,15 @@ public Condition join(ColumnDateRange right) { return this.start.eq(right.getStart()).and(end.eq(right.getEnd())); } + public Condition isNotEmpty() { + if (this.isSingleColumnRange()) { + return this.range.notEqual(PostgreSqlFunctionProvider.EMPTY_RANGE); + } + + //this is weird + return this.start.isNotNull().and(this.end.isNotNull()); + } + public Condition isNotNull() { if (this.isSingleColumnRange()) { return this.range.isNotNull(); diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/QueryStep.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/QueryStep.java index 204bdd59e4..f137558281 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/QueryStep.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/QueryStep.java @@ -41,6 +41,12 @@ public class QueryStep { */ @Builder.Default boolean unionAll = true; + + /** + * If the query should be negated or not. + */ + @Builder.Default + boolean negate = false; /** * Determines if the select should be distinct. */ diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/QueryStepJoiner.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/QueryStepJoiner.java index 56318e8d6e..8270c05f88 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/QueryStepJoiner.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/QueryStepJoiner.java @@ -1,13 +1,19 @@ package com.bakdata.conquery.sql.conversion.model; +import static org.jooq.impl.DSL.*; + import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; import com.bakdata.conquery.apiv1.query.CQElement; +import com.bakdata.conquery.models.config.ColumnConfig; +import com.bakdata.conquery.models.config.IdColumnConfig; import com.bakdata.conquery.models.query.queryplan.DateAggregationAction; +import com.bakdata.conquery.sql.conversion.SharedAliases; import com.bakdata.conquery.sql.conversion.cqelement.ConversionContext; import com.bakdata.conquery.sql.conversion.cqelement.aggregation.DateAggregationDates; import com.bakdata.conquery.sql.conversion.dialect.SqlDateAggregator; @@ -15,6 +21,8 @@ import com.bakdata.conquery.sql.conversion.model.select.SqlSelect; import com.google.common.base.Preconditions; import org.jooq.Condition; +import org.jooq.Field; +import org.jooq.Function3; import org.jooq.Record; import org.jooq.Table; import org.jooq.TableLike; @@ -23,6 +31,47 @@ public class QueryStepJoiner { + private static final String NEGATED_CTE_SUFFIX = "_negated"; + + /** + * Implements an antijoin against the allIdsTable defined in {@link IdColumnConfig#getTable()}, for negation without siblings. + */ + public static QueryStep antiJoinWithAllIdsTable(QueryStep queryStep, ConversionContext context, DateAggregationAction dateAggregationAction) { + + SqlFunctionProvider functionProvider = context.getConversionContext().getDialectBundle().getFunctionProvider(); + + Field queryStepPrimaryColumn = queryStep.getQualifiedSelects().getIds().getPrimaryColumn(); + ColumnConfig idColumnConfig = context.getIdColumns().findPrimaryIdColumn(); + + String allIdsTable = context.getIdColumns().getTable(); + + Field allIdsPrimaryColumn = field(name(allIdsTable, idColumnConfig.getField())); + + Table table = table(name(allIdsTable)) + .leftOuterJoin(table(name(queryStep.getCteName()))) + .on(allIdsPrimaryColumn.eq(queryStepPrimaryColumn)); + + String cteName = queryStep.getCteName() + NEGATED_CTE_SUFFIX; + + Optional validityDate = switch (dateAggregationAction) { + case BLOCK, MERGE, INTERSECT -> Optional.of(functionProvider.emptyColumnDateRange()); + case NEGATE -> Optional.of(functionProvider.allRange()); + }; + + Selects selects = Selects.builder() + .ids(new SqlIdColumns(allIdsPrimaryColumn)) + .validityDate(validityDate.map(cdr -> cdr.asValidityDateRange(cteName))) + .build(); + + return QueryStep.builder() + .cteName(cteName) + .selects(selects) + .fromTable(table) + .conditions(List.of(queryStepPrimaryColumn.isNull())) + .predecessor(queryStep) + .build(); + } + public static QueryStep joinChildren( Iterable children, ConversionContext context, @@ -45,9 +94,23 @@ public static QueryStep joinSteps( DateAggregationAction dateAggregationAction, ConversionContext context ) { + // keep all entries from group A (non-negate steps), whose entity has no matching entry in group B (negate steps) + if (queriesToJoin.stream().anyMatch(QueryStep::isNegate)) { + return joinStepsContainingNegation(queriesToJoin, logicalOperation, dateAggregationAction, context); + } + + // splitting out the actual join to be able to recur here + return doJoin(queriesToJoin, logicalOperation, dateAggregationAction, context); + } + + private static QueryStep doJoin( + List queriesToJoin, + ConqueryJoinType logicalOperation, + DateAggregationAction dateAggregationAction, + ConversionContext context) { // no join required if (queriesToJoin.size() == 1) { - return queriesToJoin.get(0); + return queriesToJoin.getFirst(); } String joinedNodeName = context.getNameGenerator().joinedNodeName(logicalOperation); @@ -62,6 +125,7 @@ public static QueryStep joinSteps( .predecessors(queriesToJoin); DateAggregationDates dateAggregationDates = DateAggregationDates.forSteps(queriesToJoin); + if (dateAggregationAction == DateAggregationAction.BLOCK || dateAggregationDates.dateAggregationImpossible()) { // for forms, date aggregation is allways blocked, but dates need to be coalesced in case we do a fulll outer join Optional stratificationDate = coalesceStratificationDates(queriesToJoin); @@ -69,7 +133,7 @@ public static QueryStep joinSteps( } // if there is only 1 child node containing a validity date, we just keep it as overall validity date for the joined node else if (dateAggregationDates.getValidityDates().size() == 1) { - ColumnDateRange validityDate = dateAggregationDates.getValidityDates().get(0); + ColumnDateRange validityDate = dateAggregationDates.getValidityDates().getFirst(); joinedStep = buildJoinedStep(ids, mergedSelects, Optional.of(validityDate), Optional.empty(), joinedStepBuilder); } else { @@ -78,15 +142,107 @@ else if (dateAggregationDates.getValidityDates().size() == 1) { return joinedStep; } + /** + * If queriesToJoin contains any negated queries, they will be used in an antijoin against their siblings. + * + * That means the negation works by removing the entities in the negated portion from the unnegated ones. + */ + private static QueryStep joinStepsContainingNegation( + List queriesToJoin, + ConqueryJoinType logicalOperation, + DateAggregationAction dateAggregationAction, + ConversionContext context + ) { + Map> byNegation = queriesToJoin.stream().collect(Collectors.groupingBy(QueryStep::isNegate)); + + List withoutNegation = byNegation.get(false); + List withNegation = byNegation.get(true); + + if (withoutNegation == null) { + QueryStep negateJoined = doJoin(withNegation, logicalOperation, dateAggregationAction, context); + return antiJoinWithAllIdsTable(negateJoined, context, dateAggregationAction); + } + + String cteName = context.getNameGenerator().joinedNodeName(logicalOperation) + NEGATED_CTE_SUFFIX; + QueryStep nonNegateJoined = doJoin(withoutNegation, logicalOperation, dateAggregationAction, context); + QueryStep negateJoined = doJoin(withNegation, logicalOperation, dateAggregationAction, context); + + Selects.SelectsBuilder selects = nonNegateJoined.getQualifiedSelects() + .toBuilder() + .sqlSelects(mergeSelects(List.of(nonNegateJoined, negateJoined))); + + + if (logicalOperation == ConqueryJoinType.INNER_JOIN) { + Table table = table(name(nonNegateJoined.getCteName())) + .leftOuterJoin(table(name(negateJoined.getCteName()))) + .on(nonNegateJoined.getQualifiedSelects().getIds().getPrimaryColumn() + .eq(negateJoined.getQualifiedSelects().getIds().getPrimaryColumn())); + + return QueryStep.builder() + .cteName(cteName) + .selects(selects.build()) + .fromTable(table) + .conditions(List.of(negateJoined.getQualifiedSelects().getIds().getPrimaryColumn().isNull())) + .predecessors(List.of(nonNegateJoined, negateJoined)) + .build(); + } + + // first, invert dates of negated step + SqlDateAggregator dateAggregator = context.getDialectBundle().getDateAggregator(); + negateJoined = dateAggregator.invertAggregatedIntervals(negateJoined, context); + + // join with all-ids table necessary + ColumnConfig columnConfig = context.getIdColumns().findPrimaryIdColumn(); + Field allIdsPrimaryColumn = field(name(columnConfig.getField())); + Field negatePrimaryColumn = negateJoined.getQualifiedSelects().getIds().getPrimaryColumn(); + Field nonNegatePrimaryColumn = nonNegateJoined.getQualifiedSelects().getIds().getPrimaryColumn(); + + // prepare date aggregation + Condition infinityRangeCondition = negatePrimaryColumn.isNull().or(nonNegatePrimaryColumn.isNull()); + DateAggregationDates aggregationDates = DateAggregationDates.forValidityDates(List.of( + nonNegateJoined.getQualifiedSelects().getValidityDate(), + negateJoined.getQualifiedSelects().getValidityDate(), + Optional.of(context.getDialectBundle().getFunctionProvider().allRangeIf(infinityRangeCondition)) + )); + ColumnDateRange merged = + dateAggregator.getAggregatedValidityDate(aggregationDates, DateAggregationAction.MERGE) + .as(cteName + SharedAliases.DATES_COLUMN.getAlias()); + + Field coalescedId = DSL.coalesce(nonNegatePrimaryColumn, allIdsPrimaryColumn) + .as(SharedAliases.PRIMARY_COLUMN.getAlias()); + + selects = selects + .ids(new SqlIdColumns(coalescedId)) + .validityDate(Optional.of(merged)); + + Table table = table(name(context.getIdColumns().getTable())) + .leftOuterJoin(table(name(negateJoined.getCteName()))) + .on(allIdsPrimaryColumn.eq(negatePrimaryColumn)) + .leftOuterJoin(table(name(nonNegateJoined.getCteName()))) + .on(allIdsPrimaryColumn.eq(nonNegatePrimaryColumn)); + + return QueryStep.builder() + .cteName(cteName) + .selects(selects.build()) + .fromTable(table) + .conditions(List.of(negatePrimaryColumn.isNull().or(nonNegatePrimaryColumn.isNotNull()))) + .predecessors(List.of(nonNegateJoined, negateJoined)) + .build(); + + } + public static TableLike constructJoinedTable(List queriesToJoin, ConqueryJoinType logicalOperation, ConversionContext context) { - Table joinedQuery = getIntitialJoinTable(queriesToJoin); SqlFunctionProvider functionProvider = context.getFunctionProvider(); - JoinType joinType = switch (logicalOperation) { - case INNER_JOIN -> functionProvider::innerJoin; - case OUTER_JOIN -> functionProvider::fullOuterJoin; - case LEFT_JOIN -> functionProvider::leftJoin; - }; + + Function3, Table, List, TableOnConditionStep> joinType = + switch (logicalOperation) { + case INNER_JOIN -> functionProvider::innerJoin; + case OUTER_JOIN -> functionProvider::fullOuterJoin; + case LEFT_JOIN -> functionProvider::leftJoin; + }; + + Table joinedQuery = getIntitialJoinTable(queriesToJoin); for (int i = 0; i < queriesToJoin.size() - 1; i++) { @@ -98,23 +254,32 @@ public static TableLike constructJoinedTable(List queriesToJo List joinIdsCondition = leftIds.join(rightIds); - Condition joinDateCondition = DSL.noCondition(); - // join on stratification date if present - if (leftPartQS.getSelects().getStratificationDate().isPresent() && rightPartQS.getSelects().getStratificationDate().isPresent()) { - ColumnDateRange leftStratificationDate = leftPartQS.getQualifiedSelects().getStratificationDate().get(); - ColumnDateRange rightStratificationDate = rightPartQS.getQualifiedSelects().getStratificationDate().get(); - joinDateCondition = leftStratificationDate.join(rightStratificationDate); - } + Condition joinDateCondition = joinOnStratification(leftPartQS, rightPartQS); List joinConditions = Stream.concat(joinIdsCondition.stream(), Stream.of(joinDateCondition)).collect(Collectors.toList()); - Table rightPartTable = DSL.table(DSL.name(rightPartQS.getCteName())); - joinedQuery = joinType.join(joinedQuery, rightPartTable, joinConditions); + Table rightPartTable = table(name(rightPartQS.getCteName())); + joinedQuery = joinType.apply(joinedQuery, rightPartTable, joinConditions); } return joinedQuery; } + /** + * join on stratification date if present + */ + private static Condition joinOnStratification(QueryStep leftPartQS, QueryStep rightPartQS) { + if (leftPartQS.getSelects().getStratificationDate().isEmpty() || rightPartQS.getSelects().getStratificationDate().isEmpty()) { + //TODO use unconditionalJoin in the future. Hana does not like noCondition joins + return DSL.noCondition(); + } + + ColumnDateRange leftStratificationDate = leftPartQS.getQualifiedSelects().getStratificationDate().get(); + ColumnDateRange rightStratificationDate = rightPartQS.getQualifiedSelects().getStratificationDate().get(); + + return leftStratificationDate.join(rightStratificationDate); + } + public static List mergeSelects(List querySteps) { return querySteps.stream() .flatMap(queryStep -> queryStep.getQualifiedSelects().getSqlSelects().stream()) @@ -124,11 +289,11 @@ public static List mergeSelects(List querySteps) { public static SqlIdColumns coalesceIds(List querySteps) { List ids = querySteps.stream().map(QueryStep::getQualifiedSelects).map(Selects::getIds).toList(); Preconditions.checkArgument(!ids.isEmpty(), "Need at least 1 query step in the list to coalesce Ids"); - return ids.get(0).coalesce(ids.subList(1, ids.size())); + return ids.getFirst().coalesce(ids.subList(1, ids.size())); } private static Table getIntitialJoinTable(List queriesToJoin) { - return DSL.table(DSL.name(queriesToJoin.get(0).getCteName())); + return table(name(queriesToJoin.getFirst().getCteName())); } private static QueryStep buildJoinedStep( @@ -178,9 +343,5 @@ private static Optional coalesceStratificationDates(List join(Table leftPart, Table rightPart, List joinConditions); - } } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/Selects.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/Selects.java index b8361ea940..e9a7aee838 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/Selects.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/Selects.java @@ -25,6 +25,15 @@ public class Selects { @Singular List sqlSelects; + public Selects toFinalRepresentation() { + return builder() + .ids(this.ids) + .validityDate(this.validityDate) + .stratificationDate(this.stratificationDate) + .sqlSelects(this.sqlSelects.stream().map(SqlSelect::toFinalRepresentation).toList()) + .build(); + } + public Selects withValidityDate(ColumnDateRange validityDate) { return this.toBuilder() .validityDate(Optional.of(validityDate)) diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/SqlIdColumns.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/SqlIdColumns.java index f80ebf8d35..32eafba282 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/SqlIdColumns.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/SqlIdColumns.java @@ -65,7 +65,7 @@ public SqlIdColumns qualify(String qualifier) { } public SqlIdColumns withAbsoluteStratification(Resolution resolution, Field index) { - Field resolutionField = DSL.val(resolution.toString()).as(SharedAliases.RESOLUTION.getAlias()); + Field resolutionField = DSL.inline(resolution.toString()).as(SharedAliases.RESOLUTION.getAlias()); return StratificationSqlIdColumns.builder() .primaryColumn(this.primaryColumn) .secondaryId(this.secondaryId) @@ -76,7 +76,7 @@ public SqlIdColumns withAbsoluteStratification(Resolution resolution, Field index, Field eventDate) { - Field resolutionField = DSL.val(resolution.toString()).as(SharedAliases.RESOLUTION.getAlias()); + Field resolutionField = DSL.inline(resolution.toString()).as(SharedAliases.RESOLUTION.getAlias()); return StratificationSqlIdColumns.builder() .primaryColumn(this.primaryColumn) .secondaryId(this.secondaryId) diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/StratificationSqlIdColumns.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/StratificationSqlIdColumns.java index ba392784c8..abe02451b0 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/StratificationSqlIdColumns.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/StratificationSqlIdColumns.java @@ -59,8 +59,8 @@ public SqlIdColumns qualify(String qualifier) { public SqlIdColumns forFinalSelect() { Field withNulledCompleteIndex = DSL.when( - this.resolution.eq(DSL.val(Resolution.COMPLETE.toString().toUpperCase())), - DSL.val(null, Integer.class) + this.resolution.eq(DSL.inline(Resolution.COMPLETE.toString().toUpperCase())), + DSL.inline(null, Integer.class) ) .otherwise(this.index) .as(SharedAliases.INDEX.getAlias()); 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 c41f730bd4..2c922e348e 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 @@ -9,6 +9,7 @@ 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.models.identifiable.ids.specific.ColumnId; 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; @@ -33,96 +34,19 @@ //TODO(FK): this needs a rework. Current implementation makes a sum of the quarters and doesn't take overlapping events into account. public class CountQuartersSqlAggregator implements SelectConverter, FilterConverter, SqlAggregator { - @Override - public ConnectorSqlSelects connectorSelect(CountQuartersSelect countQuartersSelect, SelectContext selectContext) { - - String alias = selectContext.getNameGenerator().selectName(countQuartersSelect); - ConnectorSqlTables tables = selectContext.getTables(); - SqlFunctionProvider functionProvider = selectContext.getFunctionProvider(); - StratificationFunctions stratificationFunctions = selectContext.getConversionContext().getStratificationFunctions(); - - CommonAggregationSelect countAggregationSelect; - if (countQuartersSelect.isSingleColumnDaterange()) { - Column countColumn = countQuartersSelect.getColumn().resolve(); - countAggregationSelect = countColumn.getType() == MajorTypeId.DATE_RANGE - ? createSingleDaterangeColumnAggregationSelect(countColumn, alias, tables, functionProvider, stratificationFunctions) - : createSingleDateColumnAggregationSelect(countColumn, alias, tables, functionProvider); - } - else { - Column startColumn = countQuartersSelect.getStartColumn().resolve(); - Column endColumn = countQuartersSelect.getEndColumn().resolve(); - countAggregationSelect = createTwoDateColumnAggregationSelect(startColumn, endColumn, alias, tables, functionProvider, stratificationFunctions); - } - - String finalPredecessor = tables.getPredecessor(ConceptCteStep.AGGREGATION_FILTER); - ExtractingSqlSelect finalSelect = countAggregationSelect.getGroupBy().qualify(finalPredecessor); - - return ConnectorSqlSelects.builder() - .preprocessingSelects(countAggregationSelect.getRootSelects()) - .aggregationSelect(countAggregationSelect.getGroupBy()) - .finalSelect(finalSelect) - .build(); - } - - @Override - public SqlFilters convertToSqlFilter(CountQuartersFilter countQuartersFilter, FilterContext filterContext) { - - String alias = filterContext.getNameGenerator().selectName(countQuartersFilter); - ConnectorSqlTables tables = filterContext.getTables(); - SqlFunctionProvider functionProvider = filterContext.getFunctionProvider(); - StratificationFunctions stratificationFunctions = filterContext.getConversionContext().getStratificationFunctions(); - - CommonAggregationSelect countAggregationSelect; - if (countQuartersFilter.isSingleColumnDaterange()) { - Column countColumn = countQuartersFilter.getColumn().resolve(); - countAggregationSelect = countColumn.getType() == MajorTypeId.DATE_RANGE - ? createSingleDaterangeColumnAggregationSelect(countColumn, alias, tables, functionProvider, stratificationFunctions) - : createSingleDateColumnAggregationSelect(countColumn, alias, tables, functionProvider); - } - else { - Column startColumn = countQuartersFilter.getStartColumn().resolve(); - Column endColumn = countQuartersFilter.getEndColumn().resolve(); - countAggregationSelect = createTwoDateColumnAggregationSelect(startColumn, endColumn, alias, tables, functionProvider, stratificationFunctions); - } - ConnectorSqlSelects selects = ConnectorSqlSelects.builder() - .preprocessingSelects(countAggregationSelect.getRootSelects()) - .aggregationSelect(countAggregationSelect.getGroupBy()) - .build(); - - 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) - .build(); - - return new SqlFilters(selects, whereClauses); - } - - @Override - public Condition convertForTableExport(CountQuartersFilter filter, FilterContext filterContext) { - Param field = DSL.val(1); // no grouping, count is always 1 per row - return new CountCondition(field, filterContext.getValue()).condition(); - } - private static CommonAggregationSelect createSingleDateColumnAggregationSelect( Column countColumn, String alias, ConnectorSqlTables tables, - SqlFunctionProvider functionProvider - ) { + SqlFunctionProvider functionProvider) { + ExtractingSqlSelect rootSelect = new ExtractingSqlSelect<>(tables.getRootTable(), countColumn.getName(), Date.class); Field qualifiedRootSelect = rootSelect.qualify(tables.cteName(ConceptCteStep.EVENT_FILTER)).select(); - FieldWrapper countQuartersAggregation = new FieldWrapper<>( - DSL.countDistinct(functionProvider.yearQuarter(qualifiedRootSelect)).as(alias), - countColumn.getName() - ); - - return CommonAggregationSelect.builder() - .rootSelect(rootSelect) - .groupBy(countQuartersAggregation) - .build(); + FieldWrapper countQuartersAggregation = + new FieldWrapper<>(DSL.nullif(DSL.countDistinct(functionProvider.yearQuarter(qualifiedRootSelect)), 0).as(alias), countColumn.getName()); + + return CommonAggregationSelect.builder().rootSelect(rootSelect).groupBy(countQuartersAggregation).build(); } private static CommonAggregationSelect createSingleDaterangeColumnAggregationSelect( @@ -130,10 +54,9 @@ private static CommonAggregationSelect createSingleDaterangeColumnAg String alias, ConnectorSqlTables tables, SqlFunctionProvider functionProvider, - StratificationFunctions stratificationFunctions - ) { - String rootTable = tables.getRootTable(); - ColumnDateRange daterange = ColumnDateRange.of(DSL.field(DSL.name(rootTable, countColumn.getName()))); + StratificationFunctions stratificationFunctions) { + + ColumnDateRange daterange = ColumnDateRange.of(DSL.field(DSL.name(tables.getRootTable(), countColumn.getName()))); Field quarterStart = stratificationFunctions.lowerBoundQuarterStart(daterange); Field nextQuarterStart = stratificationFunctions.upperBoundQuarterEnd(daterange); @@ -147,14 +70,14 @@ private static CommonAggregationSelect createTwoDateColumnAggregatio 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); + StratificationFunctions stratificationFunctions) { + + Field startDate = DSL.field(DSL.name(tables.getRootTable(), startColumn.getName()), Date.class); + Field endDate = DSL.field(DSL.name(tables.getRootTable(), endColumn.getName()), Date.class); Field quarterStart = stratificationFunctions.jumpToQuarterStart(startDate); Field nextQuarterStart = stratificationFunctions.jumpToNextQuarterStart(endDate); + return sumQuarterCount(quarterStart, nextQuarterStart, alias, tables, functionProvider); } @@ -163,24 +86,99 @@ private static CommonAggregationSelect sumQuarterCount( Field nextQuarterStart, String alias, ConnectorSqlTables tables, - SqlFunctionProvider functionProvider - ) { + 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)); + FieldWrapper quarterCountAggregation = new FieldWrapper<>(DSL.nullif(DSL.sum(qualifiedQuarterCount), BigDecimal.ZERO).as(alias)); - return CommonAggregationSelect.builder() - .rootSelect(quarterCountWrapper) - .groupBy(quarterCountAggregation) - .build(); + 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); + return functionProvider.dateDistance(ChronoUnit.MONTHS, quarterStart, nextQuarterStart).divide(Interval.QUARTER_INTERVAL.getAmount()).as(alias); + } + + private static CommonAggregationSelect buildSqlSelect( + ColumnId column, + ColumnId startColumn, + ColumnId endColumn, + String alias, + ConnectorSqlTables tables, + SqlFunctionProvider functionProvider, + StratificationFunctions stratificationFunctions) { + + if (column == null) { + return createTwoDateColumnAggregationSelect(startColumn.resolve(), endColumn.resolve(), alias, tables, functionProvider, stratificationFunctions); + } + + Column countColumn = column.resolve(); + if (countColumn.getType() == MajorTypeId.DATE_RANGE) { + return createSingleDaterangeColumnAggregationSelect(countColumn, + alias, + tables, + functionProvider, + stratificationFunctions + ); + } + + return createSingleDateColumnAggregationSelect(countColumn, alias, tables, functionProvider); + } + + @Override + public ConnectorSqlSelects connectorSelect(CountQuartersSelect countQuartersSelect, SelectContext selectContext) { + + CommonAggregationSelect countAggregationSelect = + buildSqlSelect(countQuartersSelect.getColumn(), + countQuartersSelect.getStartColumn(), + countQuartersSelect.getEndColumn(), + selectContext.getNameGenerator().selectName(countQuartersSelect), + selectContext.getTables(), + selectContext.getFunctionProvider(), + selectContext.getDialectBundle().getStratificationFunctions() + ); + + String finalPredecessor = selectContext.getTables().getPredecessor(ConceptCteStep.AGGREGATION_FILTER); + ExtractingSqlSelect finalSelect = countAggregationSelect.getGroupBy().qualify(finalPredecessor); + + return ConnectorSqlSelects.builder() + .preprocessingSelects(countAggregationSelect.getRootSelects()) + .aggregationSelect(countAggregationSelect.getGroupBy()) + .finalSelect(finalSelect) + .build(); + } + + @Override + public SqlFilters convertToSqlFilter(CountQuartersFilter countQuartersFilter, FilterContext filterContext) { + + CommonAggregationSelect countAggregationSelect = + buildSqlSelect(countQuartersFilter.getColumn(), + countQuartersFilter.getStartColumn(), + countQuartersFilter.getEndColumn(), + filterContext.getNameGenerator().selectName(countQuartersFilter), + filterContext.getTables(), + filterContext.getFunctionProvider(), + filterContext.getDialectBundle().getStratificationFunctions() + ); + + ConnectorSqlSelects selects = ConnectorSqlSelects.builder() + .preprocessingSelects(countAggregationSelect.getRootSelects()) + .aggregationSelect(countAggregationSelect.getGroupBy()) + .build(); + + String predecessorTableName = filterContext.getTables().getPredecessor(ConceptCteStep.AGGREGATION_FILTER); + Field qualifiedCountSelect = countAggregationSelect.getGroupBy().qualify(predecessorTableName).select(); + CountCondition countCondition = new CountCondition(qualifiedCountSelect, filterContext.getValue()); + WhereClauses whereClauses = WhereClauses.builder().groupFilter(countCondition).build(); + + return new SqlFilters(selects, whereClauses); + } + + @Override + public Condition convertForTableExport(CountQuartersFilter filter, FilterContext filterContext) { + Param field = DSL.inline(1); // no grouping, count is always 1 per row + return new CountCondition(field, filterContext.getValue()).condition(); } } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/CountSqlAggregator.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/CountSqlAggregator.java index 9e519583e2..b1bc5222e8 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/CountSqlAggregator.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/CountSqlAggregator.java @@ -25,24 +25,15 @@ @NoArgsConstructor public class CountSqlAggregator implements SelectConverter, FilterConverter, SqlAggregator { - public enum CountType { - DEFAULT, - DISTINCT; - - public static CountType fromBoolean(boolean value) { - return value ? DISTINCT : DEFAULT; - } - } - @Override public ConnectorSqlSelects connectorSelect(CountSelect countSelect, SelectContext selectContext) { ConnectorSqlTables tables = selectContext.getTables(); - CountType countType = CountType.fromBoolean(countSelect.isDistinct()); + boolean distinct = countSelect.isDistinct(); Column countColumn = countSelect.getColumn().resolve(); String alias = selectContext.getNameGenerator().selectName(countSelect); - CommonAggregationSelect countAggregationSelect = createCountAggregationSelect(countColumn, countType, alias, tables); + CommonAggregationSelect countAggregationSelect = createCountAggregationSelect(countColumn, distinct, alias, tables); String finalPredecessor = tables.getPredecessor(ConceptCteStep.AGGREGATION_FILTER); ExtractingSqlSelect finalSelect = countAggregationSelect.getGroupBy().qualify(finalPredecessor); @@ -54,15 +45,32 @@ public ConnectorSqlSelects connectorSelect(CountSelect countSelect, SelectContex .build(); } + private CommonAggregationSelect createCountAggregationSelect(Column countColumn, boolean distinct, String alias, ConnectorSqlTables tables) { + + ExtractingSqlSelect rootSelect = new ExtractingSqlSelect<>(tables.getRootTable(), countColumn.getName(), Object.class); + + + Field qualifiedRootSelect = rootSelect.qualify(tables.getPredecessor(ConceptCteStep.AGGREGATION_SELECT)).select(); + Field countField = distinct + ? DSL.countDistinct(qualifiedRootSelect) + : DSL.count(qualifiedRootSelect); + FieldWrapper countGroupBy = new FieldWrapper<>(DSL.nullif(countField, 0).as(alias), countColumn.getName()); + + return CommonAggregationSelect.builder() + .rootSelect(rootSelect) + .groupBy(countGroupBy) + .build(); + } + @Override public SqlFilters convertToSqlFilter(CountFilter countFilter, FilterContext filterContext) { ConnectorSqlTables tables = filterContext.getTables(); - CountType countType = CountType.fromBoolean(countFilter.isDistinct()); + boolean distinct = countFilter.isDistinct(); Column countColumn = countFilter.getColumn().resolve(); String alias = filterContext.getNameGenerator().selectName(countFilter); - CommonAggregationSelect countAggregationSelect = createCountAggregationSelect(countColumn, countType, alias, tables); + CommonAggregationSelect countAggregationSelect = createCountAggregationSelect(countColumn, distinct, alias, tables); ConnectorSqlSelects selects = ConnectorSqlSelects.builder() .preprocessingSelects(countAggregationSelect.getRootSelects()) .aggregationSelect(countAggregationSelect.getGroupBy()) @@ -79,24 +87,10 @@ public SqlFilters convertToSqlFilter(CountFilter countFilter, FilterContext filterContext) { - Param field = DSL.val(1); // no grouping, count is always 1 per row + Param field = DSL.inline(1); // no grouping, count is always 1 per row return new CountCondition(field, filterContext.getValue()).condition(); } - private CommonAggregationSelect createCountAggregationSelect(Column countColumn, CountType countType, String alias, ConnectorSqlTables tables) { - - ExtractingSqlSelect rootSelect = new ExtractingSqlSelect<>(tables.getRootTable(), countColumn.getName(), Object.class); - - Field qualifiedRootSelect = rootSelect.qualify(tables.getPredecessor(ConceptCteStep.AGGREGATION_SELECT)).select(); - Field countField = countType == CountType.DISTINCT - ? DSL.countDistinct(qualifiedRootSelect) - : DSL.count(qualifiedRootSelect); - FieldWrapper countGroupBy = new FieldWrapper<>(countField.as(alias), countColumn.getName()); - return CommonAggregationSelect.builder() - .rootSelect(rootSelect) - .groupBy(countGroupBy) - .build(); - } } 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 3df6cf0de0..5d798027f9 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 @@ -121,7 +121,7 @@ private Field getEndDate(ConversionContext conversionContext) { ColumnDateRange stratificationDate = conversionContext.getStratificationTable().getQualifiedSelects().getStratificationDate().get(); ColumnDateRange dualColumn = functionProvider.toDualColumn(stratificationDate); // end date is allways treated exclusive, so we get the actual end date when subtracting 1 day - return functionProvider.addDays(dualColumn.getEnd(), DSL.val(-1)); + return functionProvider.addDays(dualColumn.getEnd(), DSL.inline(-1)); } LocalDate endDate; diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/DurationSumSqlAggregator.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/DurationSumSqlAggregator.java new file mode 100644 index 0000000000..9e14d2b99f --- /dev/null +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/DurationSumSqlAggregator.java @@ -0,0 +1,73 @@ +package com.bakdata.conquery.sql.conversion.model.aggregator; + +import com.bakdata.conquery.models.common.Range; +import com.bakdata.conquery.models.common.Range.LongRange; +import com.bakdata.conquery.models.datasets.Column; +import com.bakdata.conquery.models.datasets.concepts.filters.specific.DurationSumFilter; +import com.bakdata.conquery.models.datasets.concepts.select.connector.specific.DurationSumSelect; +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.model.ColumnDateRange; +import com.bakdata.conquery.sql.conversion.model.filter.DateDistanceCondition; +import com.bakdata.conquery.sql.conversion.model.filter.FilterConverter; +import com.bakdata.conquery.sql.conversion.model.filter.SqlFilters; +import com.bakdata.conquery.sql.conversion.model.filter.SumCondition; +import com.bakdata.conquery.sql.conversion.model.select.ConnectorSqlSelects; +import com.bakdata.conquery.sql.conversion.model.select.DaterangeSelectUtil; +import com.bakdata.conquery.sql.conversion.model.select.DaterangeSelectUtil.AggregationFunction; +import com.bakdata.conquery.sql.conversion.model.select.SelectContext; +import com.bakdata.conquery.sql.conversion.model.select.SelectConverter; +import java.sql.Date; +import java.time.temporal.ChronoUnit; +import org.jooq.Condition; +import org.jooq.Field; +import org.jooq.impl.DSL; + +public class DurationSumSqlAggregator implements SelectConverter, FilterConverter, SqlAggregator { + + @Override + public ConnectorSqlSelects connectorSelect(DurationSumSelect select, SelectContext selectContext) { + return DaterangeSelectUtil.createForSelect(select, durationSumSelectFunction(), selectContext); + } + + @Override + public SqlFilters convertToSqlFilter(DurationSumFilter filter, FilterContext context) { + return DaterangeSelectUtil.createForFilter( + filter, + durationSumSelectFunction(), + (aggregationField -> new SumCondition((Field) aggregationField, context.getValue())), + context); + } + + @Override + public Condition convertForTableExport(DurationSumFilter filter, FilterContext filterContext) { + SqlFunctionProvider functionProvider = filterContext.getFunctionProvider(); + + Field startDateField; + Field endDateField; + if (!filter.isSingleColumnDaterange()) { + Column startColumn = filter.getStartColumn().resolve(); + Column endColumn = filter.getEndColumn().resolve(); + String tableName = startColumn.getTable().getName(); + startDateField = DSL.field(DSL.name(tableName, startColumn.getName()), Date.class); + endDateField = DSL.field(DSL.name(tableName, endColumn.getName()), Date.class); + } else { + Column column = filter.getColumn().resolve(); + String tableName = column.getTable().getName(); + Field daterangeField = DSL.field(DSL.name(tableName, column.getName()), Date.class); + startDateField = functionProvider.lower(daterangeField); + endDateField = functionProvider.upper(daterangeField); + } + Field dateDistance = functionProvider.dateDistance(ChronoUnit.DAYS, startDateField, endDateField); + // no need so compute a sum here - the duration sum of a single row is simply the date distance + return new DateDistanceCondition(dateDistance, filterContext.getValue()).condition(); + } + + private static AggregationFunction durationSumSelectFunction() { + return (daterange, alias, functionProvider) -> { + ColumnDateRange asDualColumn = functionProvider.toDualColumn(daterange); + return DaterangeSelectUtil.createDurationSumSqlSelect(alias, asDualColumn, functionProvider); + }; + } +} diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/FlagSqlAggregator.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/FlagSqlAggregator.java index 82a23779a5..bbb1978f9e 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/FlagSqlAggregator.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/FlagSqlAggregator.java @@ -1,5 +1,7 @@ package com.bakdata.conquery.sql.conversion.model.aggregator; +import static org.jooq.impl.DSL.*; + import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -24,11 +26,10 @@ import com.bakdata.conquery.sql.conversion.model.select.FieldWrapper; import com.bakdata.conquery.sql.conversion.model.select.SelectContext; import com.bakdata.conquery.sql.conversion.model.select.SelectConverter; +import com.bakdata.conquery.sql.conversion.model.select.SingleColumnSqlSelect; import org.jooq.Condition; import org.jooq.Field; import org.jooq.Param; -import org.jooq.impl.DSL; -import org.jooq.impl.SQLDataType; /** * {@link FlagSelect} conversion aggregates the keys of the flags of a {@link FlagSelect} into an array. @@ -70,37 +71,20 @@ */ public class FlagSqlAggregator implements SelectConverter, FilterConverter>, SqlAggregator { - private static final Param NUMERIC_TRUE_VAL = DSL.val(1); - - @Override - public ConnectorSqlSelects connectorSelect(FlagSelect flagSelect, SelectContext selectContext) { - - SqlFunctionProvider functionProvider = selectContext.getFunctionProvider(); - SqlTables connectorTables = selectContext.getTables(); - - Map> rootSelects = createFlagRootSelectMap(flagSelect, connectorTables.getRootTable()); - - String alias = selectContext.getNameGenerator().selectName(flagSelect); - FieldWrapper flagAggregation = createFlagSelect(alias, connectorTables, functionProvider, rootSelects); - - ExtractingSqlSelect finalSelect = flagAggregation.qualify(connectorTables.getPredecessor(ConceptCteStep.AGGREGATION_FILTER)); - - return ConnectorSqlSelects.builder() - .preprocessingSelects(rootSelects.values()) - .aggregationSelect(flagAggregation) - .finalSelect(finalSelect) - .build(); - } - /** * @return A mapping between a flags key and the corresponding {@link ExtractingSqlSelect} that will be created to reference the flag's column. */ - private static Map> createFlagRootSelectMap(FlagSelect flagSelect, String rootTable) { + private static Map createFlagRootSelectMap(FlagSelect flagSelect, String rootTable) { return flagSelect.getFlags() .entrySet().stream() .collect(Collectors.toMap( Map.Entry::getKey, - entry -> new ExtractingSqlSelect<>(rootTable, entry.getValue().resolve().getName(), Boolean.class) + entry -> { + Column column = entry.getValue().resolve(); + Field field = field(name(rootTable, column.getName())); + return new FieldWrapper<>(field.as(column.getName()), column.getName() + ); + } )); } @@ -108,7 +92,7 @@ private static FieldWrapper createFlagSelect( String alias, SqlTables connectorTables, SqlFunctionProvider functionProvider, - Map> flagRootSelectMap + Map flagRootSelectMap ) { Map> flagFieldsMap = createRootSelectReferences(connectorTables, flagRootSelectMap); @@ -116,11 +100,10 @@ private static FieldWrapper createFlagSelect( List> flagAggregations = new ArrayList<>(); for (Map.Entry> entry : flagFieldsMap.entrySet()) { Field boolColumn = entry.getValue(); - Condition anyTrue = DSL.max(functionProvider.cast(boolColumn, SQLDataType.INTEGER)) - .eq(NUMERIC_TRUE_VAL); + Condition anyTrue = condition(boolOr(boolColumn)); String flagName = entry.getKey(); - Field flag = DSL.when(anyTrue, DSL.val(flagName)); // else null is implicit in SQL + Field flag = when(anyTrue, inline(flagName)).otherwise(""); // else null is implicit in SQL flagAggregations.add(flag); } @@ -133,15 +116,45 @@ private static FieldWrapper createFlagSelect( private static Map> createRootSelectReferences( SqlTables connectorTables, - Map> flagRootSelectMap + Map flagRootSelectMap ) { return flagRootSelectMap.entrySet().stream() .collect(Collectors.toMap( Map.Entry::getKey, - entry -> entry.getValue().qualify(connectorTables.getPredecessor(ConceptCteStep.AGGREGATION_SELECT)).select() + entry -> (Field) entry.getValue().qualify(connectorTables.getPredecessor(ConceptCteStep.AGGREGATION_SELECT)).select() )); } + /** + * @return Columns names of a given flags map that match the selected flags of the filter value. + */ + private static List getRequiredColumns(Map flags, Set selectedFlags) { + return selectedFlags.stream() + .map(flags::get) + .map(ColumnId::resolve) + .toList(); + } + + @Override + public ConnectorSqlSelects connectorSelect(FlagSelect flagSelect, SelectContext selectContext) { + + SqlFunctionProvider functionProvider = selectContext.getConversionContext().getDialectBundle().getFunctionProvider(); + SqlTables connectorTables = selectContext.getTables(); + + Map rootSelects = createFlagRootSelectMap(flagSelect, connectorTables.getRootTable()); + + String alias = selectContext.getNameGenerator().selectName(flagSelect); + FieldWrapper flagAggregation = createFlagSelect(alias, connectorTables, functionProvider, rootSelects); + + ExtractingSqlSelect finalSelect = flagAggregation.qualify(connectorTables.getPredecessor(ConceptCteStep.AGGREGATION_FILTER)); + + return ConnectorSqlSelects.builder() + .preprocessingSelects(rootSelects.values()) + .aggregationSelect(flagAggregation) + .finalSelect(finalSelect) + .build(); + } + @Override public SqlFilters convertToSqlFilter(FlagFilter flagFilter, FilterContext> filterContext) { SqlTables connectorTables = filterContext.getTables(); @@ -168,22 +181,12 @@ public SqlFilters convertToSqlFilter(FlagFilter flagFilter, FilterContext getRequiredColumns(Map flags, Set selectedFlags) { - return selectedFlags.stream() - .map(flags::get) - .map(ColumnId::resolve) - .toList(); - } - @Override public Condition convertForTableExport(FlagFilter filter, FilterContext> filterContext) { List> flagFields = getRequiredColumns(filter.getFlags(), filterContext.getValue()) .stream() - .map(column -> DSL.field(DSL.name(column.getTable().getName(), column.getName()), Boolean.class)) + .map(column -> field(name(column.getTable().getName(), column.getName()), Boolean.class)) .toList(); return new FlagCondition(flagFields).condition(); diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/SumSqlAggregator.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/SumSqlAggregator.java index 684544bb4a..2b4644f750 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/SumSqlAggregator.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/aggregator/SumSqlAggregator.java @@ -81,17 +81,6 @@ public class SumSqlAggregator> impleme FilterConverter, RANGE>, SqlAggregator { - @Getter - @RequiredArgsConstructor - private enum SumDistinctCteStep implements CteStep { - - ROW_NUMBER_ASSIGNED("row_number_assigned", null), - ROW_NUMBER_FILTERED("row_number_filtered", ROW_NUMBER_ASSIGNED); - - private final String suffix; - private final SumDistinctCteStep predecessor; - } - private static final String ROW_NUMBER_ALIAS = "row_number"; private static final String SUM_DISTINCT_SUFFIX = "sum_distinct"; @@ -131,64 +120,41 @@ public ConnectorSqlSelects connectorSelect(SumSelect sumSelect, SelectContext sumFilter, FilterContext filterContext) { - - Column sumColumn = sumFilter.getColumn().resolve(); - Column subtractColumn = sumFilter.getSubtractColumn() != null ? sumFilter.getSubtractColumn().resolve() : null; - List distinctByColumns = sumFilter.getDistinctByColumn().stream().map(ColumnId::resolve).toList(); - String alias = filterContext.getNameGenerator().selectName(sumFilter); - ConnectorSqlTables tables = filterContext.getTables(); - - CommonAggregationSelect sumAggregationSelect; - ConnectorSqlSelects selects; + private CommonAggregationSelect createDistinctSumAggregationSelect( + Column sumColumn, + List distinctByColumns, + String alias, + SqlIdColumns ids, + ConnectorSqlTables tables, + NameGenerator nameGenerator + ) { + List> preprocessingSelects = new ArrayList<>(); - if (!distinctByColumns.isEmpty()) { - sumAggregationSelect = - createDistinctSumAggregationSelect(sumColumn, distinctByColumns, alias, filterContext.getIds(), tables, filterContext.getNameGenerator()); - selects = ConnectorSqlSelects.builder() - .preprocessingSelects(sumAggregationSelect.getRootSelects()) - .additionalPredecessor(sumAggregationSelect.getAdditionalPredecessor()) - .build(); - } - else { - sumAggregationSelect = createSumAggregationSelect(sumColumn, subtractColumn, alias, tables); - selects = ConnectorSqlSelects.builder() - .preprocessingSelects(sumAggregationSelect.getRootSelects()) - .additionalPredecessor(sumAggregationSelect.getAdditionalPredecessor()) - .aggregationSelect(sumAggregationSelect.getGroupBy()) - .build(); - } + Class numberClass = NumberMapUtil.getType(sumColumn); + ExtractingSqlSelect rootSelect = new ExtractingSqlSelect<>(tables.getRootTable(), sumColumn.getName(), numberClass); + preprocessingSelects.add(rootSelect); - Field qualifiedSumSelect = sumAggregationSelect.getGroupBy().qualify(tables.getPredecessor(ConceptCteStep.AGGREGATION_FILTER)).select(); - SumCondition sumCondition = new SumCondition(qualifiedSumSelect, filterContext.getValue()); - WhereClauses whereClauses = WhereClauses.builder() - .groupFilter(sumCondition) - .build(); + List> distinctByRootSelects = + distinctByColumns.stream() + .map(column -> new ExtractingSqlSelect<>(tables.getRootTable(), column.getName(), Object.class)) + .collect(Collectors.toList()); + preprocessingSelects.addAll(distinctByRootSelects); - return new SqlFilters(selects, whereClauses); + QueryStep rowNumberCte = createRowNumberCte(ids, rootSelect, distinctByRootSelects, alias, tables, nameGenerator); + Field rootSelectQualified = rootSelect.qualify(rowNumberCte.getCteName()).select(); + FieldWrapper sumGroupBy = new FieldWrapper<>(DSL.sum(DSL.coalesce(rootSelectQualified, DSL.inline(0))).as(alias)); + QueryStep rowNumberFilteredCte = createRowNumberFilteredCte(rowNumberCte, sumGroupBy, alias, nameGenerator); + return CommonAggregationSelect.builder() + .rootSelects(preprocessingSelects) + .additionalPredecessor(rowNumberFilteredCte) + .groupBy(sumGroupBy) + .build(); } - @Override - public Condition convertForTableExport(SumFilter filter, FilterContext filterContext) { - - Column column = filter.getColumn().resolve(); - String tableName = column.getTable().getName(); - String columnName = column.getName(); - Class numberClass = NumberMapUtil.getType(column); - Field field = DSL.field(DSL.name(tableName, columnName), numberClass); - - ColumnId subtractColumn = filter.getSubtractColumn(); - if (subtractColumn == null) { - return new SumCondition(field, filterContext.getValue()).condition(); - } - - Column resolvedSubtractionColumn = subtractColumn.resolve(); - String subtractColumnName = resolvedSubtractionColumn.getName(); - String subtractTableName = resolvedSubtractionColumn.getTable().getName(); - Field subtractField = DSL.field(DSL.name(subtractTableName, subtractColumnName), numberClass); - return new SumCondition(field.minus(subtractField), filterContext.getValue()).condition(); + private static ExtractingSqlSelect createFinalSelect(CommonAggregationSelect sumAggregationSelect, ConnectorSqlTables tables) { + String finalPredecessor = tables.getPredecessor(ConceptCteStep.AGGREGATION_FILTER); + return sumAggregationSelect.getGroupBy().qualify(finalPredecessor); } private CommonAggregationSelect createSumAggregationSelect(Column sumColumn, Column subtractColumn, String alias, ConnectorSqlTables tables) { @@ -204,6 +170,7 @@ private CommonAggregationSelect createSumAggregationSelect(Column su FieldWrapper sumGroupBy; + if (subtractColumn != null) { ExtractingSqlSelect subtractColumnRootSelect = new ExtractingSqlSelect<>( tables.getRootTable(), @@ -213,7 +180,16 @@ private CommonAggregationSelect createSumAggregationSelect(Column su preprocessingSelects.add(subtractColumnRootSelect); Field subtractField = subtractColumnRootSelect.qualify(eventFilterCte).select(); - sumGroupBy = new FieldWrapper<>(DSL.sum(sumField.minus(subtractField)).as(alias), sumColumn.getName(), subtractColumn.getName()); + + + // This expression ensures that if there's any non-null field, we get a 0. But if there's only nulls we get a null: + // COALESCE would always result in 0 which is undesired to differentiate between missing-values and 0 sums. + Field zeroIfAnyNonNull = DSL.coalesce(sumField.multiply(0), subtractField.multiply(0)); + + sumGroupBy = new FieldWrapper<>(DSL.sum(DSL.coalesce(sumField, zeroIfAnyNonNull).minus(DSL.coalesce(subtractField, zeroIfAnyNonNull))).as(alias), + sumColumn.getName(), + subtractColumn.getName() + ); } else { sumGroupBy = new FieldWrapper<>(DSL.sum(sumField).as(alias), sumColumn.getName()); @@ -225,38 +201,6 @@ private CommonAggregationSelect createSumAggregationSelect(Column su .build(); } - private CommonAggregationSelect createDistinctSumAggregationSelect( - Column sumColumn, - List distinctByColumns, - String alias, - SqlIdColumns ids, - ConnectorSqlTables tables, - NameGenerator nameGenerator - ) { - List> preprocessingSelects = new ArrayList<>(); - - Class numberClass = NumberMapUtil.getType(sumColumn); - ExtractingSqlSelect rootSelect = new ExtractingSqlSelect<>(tables.getRootTable(), sumColumn.getName(), numberClass); - preprocessingSelects.add(rootSelect); - - List> distinctByRootSelects = - distinctByColumns.stream() - .map(column -> new ExtractingSqlSelect<>(tables.getRootTable(), column.getName(), Object.class)) - .collect(Collectors.toList()); - preprocessingSelects.addAll(distinctByRootSelects); - - QueryStep rowNumberCte = createRowNumberCte(ids, rootSelect, distinctByRootSelects, alias, tables, nameGenerator); - Field rootSelectQualified = rootSelect.qualify(rowNumberCte.getCteName()).select(); - FieldWrapper sumGroupBy = new FieldWrapper<>(DSL.sum(rootSelectQualified).as(alias)); - QueryStep rowNumberFilteredCte = createRowNumberFilteredCte(rowNumberCte, sumGroupBy, alias, nameGenerator); - - return CommonAggregationSelect.builder() - .rootSelects(preprocessingSelects) - .additionalPredecessor(rowNumberFilteredCte) - .groupBy(sumGroupBy) - .build(); - } - /** * Assigns row numbers for each partition over the pid and the distinct by columns. If the values per pid in the distinct by columns are duplicated, * the row number will be incremented for each duplicated entry. @@ -312,7 +256,7 @@ private static QueryStep createRowNumberFilteredCte( .build(); Condition firstOccurrence = DSL.field(DSL.name(rowNumberCte.getCteName(), ROW_NUMBER_ALIAS)) - .eq(DSL.val(1)); + .eq(DSL.inline(1)); return QueryStep.builder() .cteName(nameGenerator.cteStepName(SumDistinctCteStep.ROW_NUMBER_FILTERED, alias)) @@ -324,9 +268,75 @@ private static QueryStep createRowNumberFilteredCte( .build(); } - private static ExtractingSqlSelect createFinalSelect(CommonAggregationSelect sumAggregationSelect, ConnectorSqlTables tables) { - String finalPredecessor = tables.getPredecessor(ConceptCteStep.AGGREGATION_FILTER); - return sumAggregationSelect.getGroupBy().qualify(finalPredecessor); + @Override + public SqlFilters convertToSqlFilter(SumFilter sumFilter, FilterContext filterContext) { + + Column sumColumn = sumFilter.getColumn().resolve(); + Column subtractColumn = sumFilter.getSubtractColumn() != null ? sumFilter.getSubtractColumn().resolve() : null; + List distinctByColumns = sumFilter.getDistinctByColumn().stream().map(ColumnId::resolve).toList(); + String alias = filterContext.getNameGenerator().selectName(sumFilter); + ConnectorSqlTables tables = filterContext.getTables(); + + CommonAggregationSelect sumAggregationSelect; + ConnectorSqlSelects selects; + + if (!distinctByColumns.isEmpty()) { + sumAggregationSelect = + createDistinctSumAggregationSelect(sumColumn, distinctByColumns, alias, filterContext.getIds(), tables, filterContext.getNameGenerator()); + selects = ConnectorSqlSelects.builder() + .preprocessingSelects(sumAggregationSelect.getRootSelects()) + .additionalPredecessor(sumAggregationSelect.getAdditionalPredecessor()) + .build(); + } + else { + sumAggregationSelect = createSumAggregationSelect(sumColumn, subtractColumn, alias, tables); + selects = ConnectorSqlSelects.builder() + .preprocessingSelects(sumAggregationSelect.getRootSelects()) + .additionalPredecessor(sumAggregationSelect.getAdditionalPredecessor()) + .aggregationSelect(sumAggregationSelect.getGroupBy()) + .build(); + } + + Field qualifiedSumSelect = sumAggregationSelect.getGroupBy().qualify(tables.getPredecessor(ConceptCteStep.AGGREGATION_FILTER)).select(); + SumCondition sumCondition = new SumCondition(qualifiedSumSelect, filterContext.getValue()); + WhereClauses whereClauses = WhereClauses.builder() + .groupFilter(sumCondition) + .build(); + + return new SqlFilters(selects, whereClauses); + + } + + @Override + public Condition convertForTableExport(SumFilter filter, FilterContext filterContext) { + + Column column = filter.getColumn().resolve(); + String tableName = column.getTable().getName(); + String columnName = column.getName(); + Class numberClass = NumberMapUtil.getType(column); + Field field = DSL.field(DSL.name(tableName, columnName), numberClass); + + ColumnId subtractColumn = filter.getSubtractColumn(); + if (subtractColumn == null) { + return new SumCondition(field, filterContext.getValue()).condition(); + } + + Column resolvedSubtractionColumn = subtractColumn.resolve(); + String subtractColumnName = resolvedSubtractionColumn.getName(); + String subtractTableName = resolvedSubtractionColumn.getTable().getName(); + Field subtractField = DSL.field(DSL.name(subtractTableName, subtractColumnName), numberClass); + return new SumCondition(field.minus(subtractField), filterContext.getValue()).condition(); + } + + @Getter + @RequiredArgsConstructor + private enum SumDistinctCteStep implements CteStep { + + ROW_NUMBER_ASSIGNED("row_number_assigned", null), + ROW_NUMBER_FILTERED("row_number_filtered", ROW_NUMBER_ASSIGNED); + + private final String suffix; + private final SumDistinctCteStep predecessor; } } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/filter/NumberFilterConverter.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/filter/NumberFilterConverter.java index f360f7f7f1..051e6d4ff9 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/filter/NumberFilterConverter.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/filter/NumberFilterConverter.java @@ -42,7 +42,9 @@ public Condition convertForTableExport(NumberFilter filter, FilterContext Column column = filter.getColumn().resolve(); String tableName = column.getTable().getName(); String columnName = column.getName(); - Field field = DSL.field(DSL.name(tableName, columnName), Number.class); + Class numberClass = NumberMapUtil.getType(column); + + Field field = DSL.field(DSL.name(tableName, columnName), numberClass); IRange range = filterContext.getValue(); return new NumberCondition(field, range).condition(); diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/filter/WhereClauses.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/filter/WhereClauses.java index fa3f1b9901..ddc4198017 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/filter/WhereClauses.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/filter/WhereClauses.java @@ -17,14 +17,6 @@ public class WhereClauses { @Singular List groupFilters; - public WhereClauses negated() { - return new WhereClauses( - preprocessingConditions.stream().map(WhereCondition::negate).toList(), - eventFilters.stream().map(WhereCondition::negate).toList(), - groupFilters.stream().map(WhereCondition::negate).toList() - ); - } - public static WhereClauses empty() { return WhereClauses.builder().build(); } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/DateUnionSelectConverter.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/DateUnionSelectConverter.java index b479b6859b..a03f853483 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/DateUnionSelectConverter.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/DateUnionSelectConverter.java @@ -7,9 +7,9 @@ public class DateUnionSelectConverter implements SelectConverter selectContext) { - return DaterangeSelectUtil.createConnectorSqlSelects( + return DaterangeSelectUtil.createForSelect( select, - (daterange, alias, functionProvider) -> new FieldWrapper<>(functionProvider.daterangeStringAggregation(daterange).as(alias)), + (daterange, alias, functionProvider) -> new FieldWrapper<>(functionProvider.dateRangeAggregation(daterange).as(alias)), selectContext ); } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/DaterangeSelectUtil.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/DaterangeSelectUtil.java index a133dc84f0..c8fecc732b 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/DaterangeSelectUtil.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/DaterangeSelectUtil.java @@ -10,42 +10,45 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.function.Function; import java.util.stream.Collectors; import com.bakdata.conquery.models.datasets.concepts.DaterangeSelectOrFilter; import com.bakdata.conquery.models.datasets.concepts.select.Select; +import com.bakdata.conquery.models.identifiable.LabeledNamespaceIdentifiable; +import com.bakdata.conquery.sql.conversion.Context; 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.cqelement.concept.IntervalPackingSelectsCte; import com.bakdata.conquery.sql.conversion.cqelement.intervalpacking.IntervalPackingContext; import com.bakdata.conquery.sql.conversion.cqelement.intervalpacking.IntervalPackingCteStep; +import com.bakdata.conquery.sql.conversion.dialect.DialectBundle; import com.bakdata.conquery.sql.conversion.dialect.SqlFunctionProvider; import com.bakdata.conquery.sql.conversion.model.ColumnDateRange; import com.bakdata.conquery.sql.conversion.model.CteStep; import com.bakdata.conquery.sql.conversion.model.QueryStep; +import com.bakdata.conquery.sql.conversion.model.SqlIdColumns; import com.bakdata.conquery.sql.conversion.model.SqlTables; +import com.bakdata.conquery.sql.conversion.model.filter.SqlFilters; +import com.bakdata.conquery.sql.conversion.model.filter.WhereClauses; +import com.bakdata.conquery.sql.conversion.model.filter.WhereCondition; import org.jooq.Condition; import org.jooq.Field; import org.jooq.impl.DSL; -class DaterangeSelectUtil { - - @FunctionalInterface - public interface AggregationFunction { - FieldWrapper apply(ColumnDateRange daterange, String alias, SqlFunctionProvider functionProvider); - } +public class DaterangeSelectUtil { /** * Aggregates the daterange of a corresponding {@link DaterangeSelectOrFilter} and applies the respective converted aggregation via * {@link IntervalPackingSelectsCte}s using additional predecessor tables. */ - public static ConnectorSqlSelects createConnectorSqlSelects( + public static ConnectorSqlSelects createForSelect( S select, AggregationFunction aggregationFunction, SelectContext context ) { String alias = context.getNameGenerator().selectName(select); - ConnectorSqlTables tables = context.getTables(); SqlFunctionProvider functionProvider = context.getFunctionProvider(); ColumnDateRange daterange = functionProvider.forArbitraryDateRange(select).as(alias); @@ -53,8 +56,8 @@ public static ConnectorSqlSelects c .map(FieldWrapper::new) .collect(Collectors.toList()); - SqlTables daterangeSelectTables = createTables(alias, context); - QueryStep lastIntervalPackingStep = applyIntervalPacking(daterange, daterangeSelectTables, context); + SqlTables daterangeSelectTables = createTables(alias, context.getTables(), context); + QueryStep lastIntervalPackingStep = applyIntervalPacking(daterange, daterangeSelectTables, context.getIds(), context.getTables(), context.getDialectBundle()); ColumnDateRange qualified = daterange.qualify(daterangeSelectTables.getPredecessor(INTERVAL_PACKING_SELECTS)); FieldWrapper aggregationField = aggregationFunction.apply(qualified, alias, functionProvider); @@ -67,6 +70,7 @@ public static ConnectorSqlSelects c context.getDialectBundle() ); + ConnectorSqlTables tables = context.getTables(); ExtractingSqlSelect finalSelect = aggregationField.qualify(tables.getPredecessor(ConceptCteStep.AGGREGATION_FILTER)); return ConnectorSqlSelects.builder() @@ -76,10 +80,54 @@ public static ConnectorSqlSelects c .build(); } + /** + * Aggregates the daterange of a corresponding {@link DaterangeSelectOrFilter} and applies the respective converted aggregation via + * {@link IntervalPackingSelectsCte}s using additional predecessor tables. Finally, the filter condition is created. + */ + public static SqlFilters createForFilter( + DaterangeSelectOrFilter filter, + AggregationFunction aggregationFunction, + Function , WhereCondition> filterFunction, + FilterContext context + ) { + String alias = context.getNameGenerator().selectName((LabeledNamespaceIdentifiable) filter); + SqlFunctionProvider functionProvider = context.getDialectBundle().getFunctionProvider(); + + ColumnDateRange daterange = functionProvider.forArbitraryDateRange(filter).as(alias); + List rootSelects = daterange.toFields().stream() + .map(FieldWrapper::new) + .collect(Collectors.toList()); + + SqlTables daterangeSelectTables = createTables(alias, context.getTables(), context); + QueryStep lastIntervalPackingStep = applyIntervalPacking(daterange, daterangeSelectTables, context.getIds(), context.getTables(), context.getDialectBundle()); + + ColumnDateRange qualified = daterange.qualify(daterangeSelectTables.getPredecessor(INTERVAL_PACKING_SELECTS)); + FieldWrapper aggregationField = aggregationFunction.apply(qualified, alias, functionProvider); + + QueryStep intervalPackingSelectsStep = IntervalPackingSelectsCte.forSelect( + lastIntervalPackingStep, + qualified, + aggregationField, + daterangeSelectTables, + context.getDialectBundle() + ); + + ConnectorSqlSelects sqlSelects = ConnectorSqlSelects.builder() + .preprocessingSelects(rootSelects) + .additionalPredecessor(Optional.of(intervalPackingSelectsStep)) + .build(); + + ConnectorSqlTables tables = context.getTables(); + Field qualifiedAggregationField = aggregationField.qualify(tables.getPredecessor(ConceptCteStep.AGGREGATION_FILTER)).select(); + WhereClauses whereClauses = WhereClauses.builder().groupFilter(filterFunction.apply(qualifiedAggregationField)).build(); + + return new SqlFilters(sqlSelects, whereClauses); + } + public static FieldWrapper createDurationSumSqlSelect(String alias, ColumnDateRange validityDate, SqlFunctionProvider functionProvider) { Field dateDistanceInDays = functionProvider.dateDistance(ChronoUnit.DAYS, validityDate.getStart(), validityDate.getEnd()); Field durationSum = DSL.sum( - DSL.when(containsInfinityDate(validityDate, functionProvider), DSL.val(null, Integer.class)) + DSL.when(containsInfinityDate(validityDate, functionProvider), DSL.inline(null, Integer.class)) .otherwise(dateDistanceInDays) ) .as(alias); @@ -92,9 +140,9 @@ private static Condition containsInfinityDate(ColumnDateRange validityDate, SqlF return validityDate.getStart().eq(negativeInfinity).or(validityDate.getEnd().eq(positiveInfinity)); } - private static SqlTables createTables(String alias, SelectContext context) { + private static SqlTables createTables(String alias, ConnectorSqlTables connectorTables, Context context) { Map predecessorMapping = new HashMap<>(); - String eventFilterCteName = context.getTables().cteName(EVENT_FILTER); + String eventFilterCteName = connectorTables.cteName(EVENT_FILTER); predecessorMapping.putAll(IntervalPackingCteStep.getMappings(context.getDialectBundle())); if (context.getDialectBundle().supportsSingleColumnRanges()) { predecessorMapping.put(UNNEST_DATE, INTERVAL_COMPLETE); @@ -107,18 +155,28 @@ private static SqlTables createTables(String alias, SelectContext context) { - - String eventFilterCteName = context.getTables().cteName(EVENT_FILTER); + private static QueryStep applyIntervalPacking( + ColumnDateRange daterange, + SqlTables dateUnionTables, + SqlIdColumns idColumns, + ConnectorSqlTables connectorSqlTables, + DialectBundle sqlDialect + ) { + String eventFilterCteName = connectorSqlTables.cteName(EVENT_FILTER); IntervalPackingContext intervalPackingContext = IntervalPackingContext.builder() - .ids(context.getIds().qualify(eventFilterCteName)) + .ids(idColumns.qualify(eventFilterCteName)) .daterange(daterange.qualify(eventFilterCteName)) .tables(dateUnionTables) .build(); - return context.getDialectBundle() - .getIntervalPacker() - .aggregateAsArbitrarySelect(intervalPackingContext); + return sqlDialect + .getIntervalPacker() + .aggregateAsArbitrarySelect(intervalPackingContext); + } + + @FunctionalInterface + public interface AggregationFunction { + FieldWrapper apply(ColumnDateRange daterange, String alias, SqlFunctionProvider functionProvider); } } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/DistinctSelectConverter.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/DistinctSelectConverter.java index 2c86a617e1..0526f5126b 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/DistinctSelectConverter.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/DistinctSelectConverter.java @@ -1,15 +1,17 @@ package com.bakdata.conquery.sql.conversion.model.select; -import static org.jooq.impl.DSL.field; -import static org.jooq.impl.DSL.name; +import static org.jooq.impl.DSL.*; +import java.util.Collections; import java.util.List; import java.util.Optional; import com.bakdata.conquery.models.datasets.concepts.select.connector.DistinctSelect; +import com.bakdata.conquery.models.datasets.concepts.select.connector.specific.MappableSingleColumnSelect; import com.bakdata.conquery.sql.conversion.cqelement.concept.ConceptCteStep; import com.bakdata.conquery.sql.conversion.cqelement.concept.ConnectorSqlTables; import com.bakdata.conquery.sql.conversion.dialect.SqlFunctionProvider; +import com.bakdata.conquery.sql.conversion.model.ColumnDateRange; import com.bakdata.conquery.sql.conversion.model.CteStep; import com.bakdata.conquery.sql.conversion.model.QueryStep; import com.bakdata.conquery.sql.conversion.model.Selects; @@ -17,6 +19,8 @@ import com.bakdata.conquery.sql.execution.ResultSetProcessor; import lombok.Getter; import lombok.RequiredArgsConstructor; +import org.jetbrains.annotations.NotNull; +import org.jooq.Condition; import org.jooq.Field; import org.jooq.impl.DSL; import org.jooq.impl.SQLDataType; @@ -68,12 +72,12 @@ public ConnectorSqlSelects connectorSelect(DistinctSelect distinctSelect, Select String alias = selectContext.getNameGenerator().selectName(distinctSelect); ConnectorSqlTables tables = selectContext.getTables(); - FieldWrapper preprocessingSelect = new FieldWrapper<>(field(name(tables.getRootTable(), distinctSelect.getColumn().getColumn())).as(alias)); + SingleColumnSqlSelect preprocessingSelect = MappableSingleColumnSelect.getSubstringSelect(distinctSelect.getColumn().get(), distinctSelect.getSubstringRange(), selectContext, alias); QueryStep distinctSelectCte = createDistinctSelectCte(preprocessingSelect, alias, selectContext); QueryStep aggregatedCte = createAggregationCte(selectContext, preprocessingSelect, distinctSelectCte, alias); - ExtractingSqlSelect finalSelect = preprocessingSelect.qualify(tables.cteName(ConceptCteStep.AGGREGATION_FILTER)); + SingleColumnSqlSelect finalSelect = preprocessingSelect.qualify(tables.cteName(ConceptCteStep.AGGREGATION_FILTER)); return ConnectorSqlSelects.builder() .preprocessingSelect(preprocessingSelect) @@ -84,7 +88,7 @@ public ConnectorSqlSelects connectorSelect(DistinctSelect distinctSelect, Select private static QueryStep createAggregationCte( SelectContext selectContext, - FieldWrapper preprocessingSelect, + SingleColumnSqlSelect preprocessingSelect, QueryStep distinctSelectCte, String alias ) { @@ -110,13 +114,14 @@ private static QueryStep createAggregationCte( } private static QueryStep createDistinctSelectCte( - FieldWrapper preprocessingSelect, + SingleColumnSqlSelect preprocessingSelect, String alias, SelectContext selectContext ) { // values to aggregate must be event-filtered first String eventFilterTable = selectContext.getTables().cteName(ConceptCteStep.EVENT_FILTER); - ExtractingSqlSelect qualified = preprocessingSelect.qualify(eventFilterTable); + SingleColumnSqlSelect qualified = preprocessingSelect.qualify(eventFilterTable); + SqlIdColumns ids = selectContext.getIds().qualify(eventFilterTable); Selects selects = Selects.builder() diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/DurationSumSelectConverter.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/DurationSumSelectConverter.java deleted file mode 100644 index de8ec3496f..0000000000 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/DurationSumSelectConverter.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.bakdata.conquery.sql.conversion.model.select; - -import com.bakdata.conquery.models.datasets.concepts.select.connector.specific.DurationSumSelect; -import com.bakdata.conquery.sql.conversion.cqelement.concept.ConnectorSqlTables; -import com.bakdata.conquery.sql.conversion.model.ColumnDateRange; - -public class DurationSumSelectConverter implements SelectConverter { - - @Override - public ConnectorSqlSelects connectorSelect(DurationSumSelect select, SelectContext selectContext) { - return DaterangeSelectUtil.createConnectorSqlSelects( - select, - (daterange, alias, functionProvider) -> { - ColumnDateRange asDualColumn = functionProvider.toDualColumn(daterange); - return DaterangeSelectUtil.createDurationSumSqlSelect(alias, asDualColumn, functionProvider); - }, - selectContext - ); - } - -} diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/EventDateUnionSelectConverter.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/EventDateUnionSelectConverter.java index 852960ead1..73cd607ae0 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/EventDateUnionSelectConverter.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/EventDateUnionSelectConverter.java @@ -13,7 +13,7 @@ public class EventDateUnionSelectConverter implements SelectConverter selectContext) { - FieldWrapper stringAggregation = createEventDateUnionAggregation(select, selectContext); + FieldWrapper stringAggregation = createEventDateUnionAggregation(select, selectContext); ExtractingSqlSelect finalSelect = stringAggregation.qualify(selectContext.getTables().getPredecessor(ConceptCteStep.AGGREGATION_FILTER)); return ConnectorSqlSelects.builder() @@ -25,7 +25,7 @@ public ConnectorSqlSelects connectorSelect(EventDateUnionSelect select, SelectCo @Override public ConceptSqlSelects conceptSelect(EventDateUnionSelect select, SelectContext selectContext) { - FieldWrapper stringAggregation = createEventDateUnionAggregation(select, selectContext); + FieldWrapper stringAggregation = createEventDateUnionAggregation(select, selectContext); ExtractingSqlSelect finalSelect = stringAggregation.qualify(selectContext.getTables().getPredecessor(ConceptCteStep.UNIVERSAL_SELECTS)); return ConceptSqlSelects.builder() @@ -34,7 +34,7 @@ public ConceptSqlSelects conceptSelect(EventDateUnionSelect select, SelectContex .build(); } - private static FieldWrapper createEventDateUnionAggregation(EventDateUnionSelect select, SelectContext selectContext) { + private static FieldWrapper createEventDateUnionAggregation(EventDateUnionSelect select, SelectContext selectContext) { Preconditions.checkArgument(selectContext.getValidityDate().isPresent(), "Can't convert an EventDateUnionSelect without a validity date being present"); ColumnDateRange validityDate = selectContext.getValidityDate().get(); @@ -43,7 +43,7 @@ private static FieldWrapper createEventDateUnionAggregation(EventDateUni String alias = selectContext.getNameGenerator().selectName(select); ColumnDateRange qualified = validityDate.qualify(selectContext.getTables().getPredecessor(ConceptCteStep.INTERVAL_PACKING_SELECTS)); - return new FieldWrapper<>(functionProvider.daterangeStringAggregation(qualified).as(alias)); + return new FieldWrapper<>(functionProvider.dateRangeAggregation(qualified).as(alias)); } } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/EventDurationSumSelectConverter.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/EventDurationSumSelectConverter.java index 369f4f8489..e7e8bbd88d 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/EventDurationSumSelectConverter.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/EventDurationSumSelectConverter.java @@ -52,7 +52,7 @@ private FieldWrapper createEventDurationSumAggregation(EventDuration String alias = selectContext.getNameGenerator().selectName(select); Field durationSum = DSL.sum( - DSL.when(containsInfinityDate(asDualColumn, functionProvider), DSL.val(null, Integer.class)) + DSL.when(containsInfinityDate(asDualColumn, functionProvider), DSL.inline(null, Integer.class)) .otherwise(functionProvider.dateDistance(ChronoUnit.DAYS, asDualColumn.getStart(), asDualColumn.getEnd())) ) .as(alias); diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/ExistsSqlSelect.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/ExistsSqlSelect.java index a9a279115b..f6729273ef 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/ExistsSqlSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/ExistsSqlSelect.java @@ -11,7 +11,7 @@ @RequiredArgsConstructor(access = AccessLevel.PRIVATE) public class ExistsSqlSelect implements SingleColumnSqlSelect { - private static final Field EXISTS = DSL.val(1); + private static final Field EXISTS = DSL.inline(1); private final Field exists; private final Name alias; @@ -48,6 +48,15 @@ public SingleColumnSqlSelect qualify(final String qualifier) { @Override public SqlSelect connectorAggregate() { - return new ExistsSqlSelect(DSL.max(select()).as(alias), alias); + return new ExistsSqlSelect(DSL.max(coalesceWithZero()).as(alias), alias); + } + + @Override + public SqlSelect toFinalRepresentation() { + return new ExistsSqlSelect(coalesceWithZero().as(alias), alias); + } + + private Field coalesceWithZero() { + return DSL.coalesce(select(), DSL.value(0)); } } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/FirstValueSelectConverter.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/FirstValueSelectConverter.java index ff827c5173..f4e29c5431 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/FirstValueSelectConverter.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/FirstValueSelectConverter.java @@ -11,7 +11,9 @@ public ConnectorSqlSelects connectorSelect(FirstValueSelect select, SelectContex return ValueSelectUtil.createValueSelect( select.getColumn().resolve(), selectContext.getNameGenerator().selectName(select), - Field::asc, selectContext + Field::asc, + select.getSubstringRange(), + selectContext ); } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/LastValueSelectConverter.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/LastValueSelectConverter.java index b3c9543a7d..a98a8aa9e4 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/LastValueSelectConverter.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/LastValueSelectConverter.java @@ -11,7 +11,7 @@ public ConnectorSqlSelects connectorSelect(LastValueSelect select, SelectContext return ValueSelectUtil.createValueSelect( select.getColumn().resolve(), selectContext.getNameGenerator().selectName(select), - Field::desc, selectContext + Field::desc, select.getSubstringRange(), selectContext ); } } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/SqlSelect.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/SqlSelect.java index 519e5668bc..882925284c 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/SqlSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/SqlSelect.java @@ -29,4 +29,12 @@ default SqlSelect connectorAggregate() { return this; } + /** + * Special selects like {@link ExistsSelect} require to be converted into a specific format before executing the + * final query. + */ + default SqlSelect toFinalRepresentation() { + return this; + } + } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/ValueSelectUtil.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/ValueSelectUtil.java index e54d1487af..fce8fb56be 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/ValueSelectUtil.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/select/ValueSelectUtil.java @@ -6,7 +6,9 @@ import java.util.Optional; import java.util.function.Function; +import com.bakdata.conquery.models.common.Range; import com.bakdata.conquery.models.datasets.Column; +import com.bakdata.conquery.models.datasets.concepts.select.connector.specific.MappableSingleColumnSelect; import com.bakdata.conquery.sql.conversion.cqelement.concept.ConceptCteStep; import com.bakdata.conquery.sql.conversion.cqelement.concept.ConnectorSqlTables; import com.bakdata.conquery.sql.conversion.dialect.SqlFunctionProvider; @@ -29,9 +31,10 @@ public static ConnectorSqlSelects createValueSelect( Column column, String alias, Function, ? extends SortField> ordering, - SelectContext selectContext) { + Range.IntegerRange substringRange, SelectContext selectContext) { + - ExtractingSqlSelect rootSelect = new ExtractingSqlSelect<>(selectContext.getTables().getRootTable(), column.getName(), Object.class); + SingleColumnSqlSelect rootSelect = MappableSingleColumnSelect.getSubstringSelect(column, substringRange, selectContext, null); // create a CTE, that per row makes a window calculation to select for the rank of the validity date. // Further down below, we select the values with rank=1, which is FIRST/LAST depending on sort order supplied by the creator. @@ -54,7 +57,7 @@ public static ConnectorSqlSelects createValueSelect( } private static QueryStep buildRowNumberStep( - ExtractingSqlSelect rootSelect, Function, ? extends SortField> ordering, String alias, + SingleColumnSqlSelect rootSelect, Function, ? extends SortField> ordering, String alias, SelectContext selectContext) { String predecessor = selectContext.getTables().getPredecessor(ConceptCteStep.AGGREGATION_SELECT); @@ -72,7 +75,7 @@ private static QueryStep buildRowNumberStep( )) .build()) .cteName(ValueSelectCteStep.ROW_NUMBER_STEP.cteName(alias)) - .conditions(List.of(qualifiedRootSelect.isNotNull())) + .conditions(List.of(qualifiedRootSelect.isNotNull(), selectContext.getValidityDate().map(ColumnDateRange::isNotEmpty).orElse(noCondition()))) .fromTable(table(name(predecessor))) .build(); } @@ -86,7 +89,7 @@ private static QueryStep buildRowFilterStep(QueryStep rowNumberStep, String alia .select(field(name(alias)), field(name("select-result", "row-number"))) .from(table(name(ValueSelectCteStep.ROW_NUMBER_STEP.cteName(alias))) .as("select-result")) - .where(or(rowNumber.equal(val(1)), rowNumber.isNull())); + .where(or(rowNumber.equal(inline(1)), rowNumber.isNull())); return QueryStep.builder() diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/ConceptQueryConverter.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/ConceptQueryConverter.java index 5773cbc4f8..09916a17aa 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/ConceptQueryConverter.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/ConceptQueryConverter.java @@ -5,6 +5,7 @@ import java.util.stream.Stream; import com.bakdata.conquery.apiv1.query.ConceptQuery; +import com.bakdata.conquery.apiv1.query.concept.specific.CQNegation; import com.bakdata.conquery.models.query.DateAggregationMode; import com.bakdata.conquery.sql.conversion.NodeConverter; import com.bakdata.conquery.sql.conversion.SharedAliases; @@ -29,32 +30,6 @@ public class ConceptQueryConverter implements NodeConverter { private final QueryStepTransformer queryStepTransformer; - @Override - public Class getConversionClass() { - return ConceptQuery.class; - } - - @Override - public ConversionContext convert(ConceptQuery conceptQuery, ConversionContext context) { - - ConversionContext contextAfterConversion = context.getNodeConversions().convert(conceptQuery.getRoot(), context); - - QueryStep preFinalStep = contextAfterConversion.getLastConvertedStep(); - Selects preFinalSelects = getPreFinalSelects(preFinalStep, contextAfterConversion); - List predecessors = Stream.concat(Stream.of(preFinalStep), Stream.ofNullable(contextAfterConversion.getExternalExtras())).toList(); - - QueryStep finalStep = QueryStep.builder() - .cteName(null) // the final QueryStep won't be converted to a CTE - .selects(getFinalSelects(conceptQuery, preFinalSelects, context.getDialectBundle().getFunctionProvider())) - .fromTable(getFinalTable(preFinalStep, contextAfterConversion)) - .groupBy(getFinalGroupBySelects(preFinalSelects)) - .predecessors(predecessors) - .build(); - - Select finalQuery = this.queryStepTransformer.toSelectQuery(finalStep); - return contextAfterConversion.withFinalQuery(new SqlQuery(finalQuery, conceptQuery.getResultInfos())); - } - private static Selects getPreFinalSelects(QueryStep preFinalStep, ConversionContext context) { Selects preFinalStepSelects = preFinalStep.getQualifiedSelects(); QueryStep externalExtras = context.getExternalExtras(); @@ -81,20 +56,53 @@ private static TableLike getFinalTable(QueryStep preFinalStep, Conversio ); } + @Override + public Class getConversionClass() { + return ConceptQuery.class; + } + + @Override + public ConversionContext convert(ConceptQuery conceptQuery, ConversionContext context) { + + SqlFunctionProvider functionProvider = context.getDialectBundle().getFunctionProvider(); + ConversionContext contextAfterConversion = context.getNodeConversions().convert(conceptQuery.getRoot(), context); + + QueryStep preFinalStep = contextAfterConversion.getLastConvertedStep(); + // negation of a single node results in an anti-join with all ids table + if (preFinalStep.isNegate()) { + preFinalStep = QueryStepJoiner.antiJoinWithAllIdsTable(preFinalStep, contextAfterConversion, CQNegation.determineDateAction(conceptQuery.getDateAggregationMode())); + } + + Selects preFinalSelects = getPreFinalSelects(preFinalStep, contextAfterConversion); + List predecessors = Stream.concat(Stream.of(preFinalStep), Stream.ofNullable(contextAfterConversion.getExternalExtras())).toList(); + + QueryStep finalStep = QueryStep.builder() + .cteName(null) // the final QueryStep won't be converted to a CTE + .selects(getFinalSelects(conceptQuery, preFinalSelects, functionProvider).toFinalRepresentation()) + .fromTable(getFinalTable(preFinalStep, contextAfterConversion)) + .groupBy(getFinalGroupBySelects(preFinalSelects)) + .predecessors(predecessors) + .build(); + + Select finalQuery = this.queryStepTransformer.toSelectQuery(finalStep); + return contextAfterConversion.withFinalQuery(new SqlQuery(finalQuery, conceptQuery.getResultInfos())); + } + private Selects getFinalSelects(ConceptQuery conceptQuery, Selects preFinalSelects, SqlFunctionProvider functionProvider) { if (conceptQuery.getDateAggregationMode() == DateAggregationMode.NONE) { return preFinalSelects.blockValidityDate(); } else if (preFinalSelects.getValidityDate().isEmpty()) { - return preFinalSelects.withValidityDate(ColumnDateRange.empty()); + return preFinalSelects.withValidityDate(functionProvider.allRange()); } - Field validityDateStringAggregation = functionProvider.daterangeStringAggregation(preFinalSelects.getValidityDate().get()); + Field validityDateStringAggregation = functionProvider.dateRangeAggregation(preFinalSelects.getValidityDate().get()); return preFinalSelects.withValidityDate(ColumnDateRange.of(validityDateStringAggregation).as(SharedAliases.DATES_COLUMN.getAlias())); } private List> getFinalGroupBySelects(Selects preFinalSelects) { List> groupBySelects = new ArrayList<>(); groupBySelects.addAll(preFinalSelects.getIds().toFields()); + // TODO instead us any_value selects groupBySelects.addAll(preFinalSelects.explicitSelects()); return groupBySelects; } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/FormConversionHelper.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/FormConversionHelper.java index 599f5f09ce..d9977af200 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/FormConversionHelper.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/FormConversionHelper.java @@ -1,5 +1,7 @@ package com.bakdata.conquery.sql.conversion.query; +import static org.jooq.impl.DSL.*; + import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @@ -32,7 +34,6 @@ import org.jooq.Record; import org.jooq.Select; import org.jooq.TableLike; -import org.jooq.impl.DSL; @RequiredArgsConstructor public class FormConversionHelper { @@ -63,7 +64,15 @@ public QueryStep convertPrerequisite(Query query, ConversionContext context) { .collect(Collectors.toList()); // filter out entries with a null validity date - Condition dateNotNullCondition = prerequisiteSelects.getValidityDate().get().isNotNull(); + Optional columnDateRange = prerequisiteSelects.getValidityDate(); + Condition dateNotNullCondition; + + if (columnDateRange.isPresent()) { + dateNotNullCondition = columnDateRange.get().isNotNull(); + } + else { + dateNotNullCondition = falseCondition(); + } return QueryStep.builder() .cteName(FormCteStep.EXTRACT_IDS.getSuffix()) @@ -119,7 +128,7 @@ private ConversionContext createFinalSelect( QueryStep finalStep = QueryStep.builder() .cteName(null) // the final QueryStep won't be converted to a CTE - .selects(getFinalSelects(formType, stratificationTable, convertedFeatures, functionProvider)) + .selects(getFinalSelects(formType, stratificationTable, convertedFeatures, functionProvider).toFinalRepresentation()) .fromTable(joinedTable) .predecessors(queriesToJoin) .build(); @@ -142,7 +151,7 @@ private static Selects getFinalSelects( Selects stratificationSelects = stratificationTable.getQualifiedSelects(); SqlIdColumns ids = stratificationSelects.getIds().forFinalSelect(); - Field daterangeConcatenated = functionProvider.daterangeStringExpression(stratificationSelects.getStratificationDate().get()) + Field daterangeConcatenated = functionProvider.dateRangeToField(stratificationSelects.getStratificationDate().get()) .as(SharedAliases.STRATIFICATION_BOUNDS.getAlias()); Selects.SelectsBuilder selects = Selects.builder() @@ -155,9 +164,9 @@ private static Selects getFinalSelects( } // relative forms have FeatureGroup information after the stratification date and before all other selects - Field indexField = DSL.field(DSL.name(stratificationTable.getCteName(), SharedAliases.INDEX.getAlias()), Integer.class); - Field scope = DSL.when(indexField.isNull().or(indexField.lessThan(0)), DSL.val(FeatureGroup.FEATURE.toString())) - .otherwise(DSL.val(FeatureGroup.OUTCOME.toString())) + Field indexField = field(name(stratificationTable.getCteName(), SharedAliases.INDEX.getAlias()), Integer.class); + Field scope = when(indexField.isNull().or(indexField.lessThan(0)), inline(FeatureGroup.FEATURE.toString())) + .otherwise(inline(FeatureGroup.OUTCOME.toString())) .as(SharedAliases.OBSERVATION_SCOPE.getAlias()); return selects.sqlSelect(new FieldWrapper<>(scope)) diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/TableExportQueryConverter.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/TableExportQueryConverter.java index e68472855d..22bf0ebb30 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/TableExportQueryConverter.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/TableExportQueryConverter.java @@ -1,12 +1,5 @@ package com.bakdata.conquery.sql.conversion.query; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.stream.Collectors; -import java.util.stream.Stream; - import com.bakdata.conquery.apiv1.query.Query; import com.bakdata.conquery.apiv1.query.TableExportQuery; import com.bakdata.conquery.apiv1.query.concept.filter.CQTable; @@ -28,6 +21,12 @@ import com.bakdata.conquery.sql.conversion.model.select.FieldWrapper; import com.bakdata.conquery.util.TablePrimaryColumnUtil; import com.google.common.base.Preconditions; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; import lombok.RequiredArgsConstructor; import org.jooq.Condition; import org.jooq.Field; @@ -144,13 +143,11 @@ private static QueryStep convertTable( private static Optional convertTablesValidityDate(CQTable table, String alias, ConversionContext context) { if (table.findValidityDate() == null) { - return Optional.of(ColumnDateRange.empty()); + return Optional.of(context.getFunctionProvider().emptyColumnDateRange()); } final SqlFunctionProvider functionProvider = context.getFunctionProvider(); final ColumnDateRange validityDate = functionProvider.forValidityDate(table.findValidityDate()); - // when exporting tables, we want the validity date as a single-column daterange string expression straightaway - final Field asStringExpression = functionProvider.encloseInCurlyBraces(functionProvider.daterangeStringExpression(validityDate)); - return Optional.of(ColumnDateRange.of(asStringExpression).asValidityDateRange(alias)); + return Optional.of(validityDate.asValidityDateRange(alias)); } private static List> initializeFields(CQTable cqTable, Map positions) { @@ -207,7 +204,7 @@ private static Field[] createPlaceholders(Map positions) { private static Field createSourceInfoSelect(CQTable cqTable) { final String tableName = cqTable.getConnector().resolve().resolveTableId().getTable(); - return DSL.val(tableName).as(SharedAliases.SOURCE.getAlias()); + return DSL.inline(tableName).as(SharedAliases.SOURCE.getAlias()); } private static Field createColumnSelect(Column column, int position) { diff --git a/backend/src/main/java/com/bakdata/conquery/sql/execution/DefaultCDateSetParser.java b/backend/src/main/java/com/bakdata/conquery/sql/execution/DefaultCDateSetParser.java new file mode 100644 index 0000000000..a42d827300 --- /dev/null +++ b/backend/src/main/java/com/bakdata/conquery/sql/execution/DefaultCDateSetParser.java @@ -0,0 +1,113 @@ +package com.bakdata.conquery.sql.execution; + +import java.io.StringReader; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Scanner; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.bakdata.conquery.models.common.CDate; +import com.bakdata.conquery.models.common.daterange.CDateRange; +import com.bakdata.conquery.util.DateReader; +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; +import lombok.Data; +import lombok.RequiredArgsConstructor; + +@Data +@RequiredArgsConstructor +public class DefaultCDateSetParser implements SqlCDateSetParser { + private final DateReader dateReader; + + private final String dateSetSep; + private final String dateRangeSep; + private final String dateRangeMinValue; + private final String dateRangeMaxValue; + + private final String dateRangeEndExclusive; + private final String dateRangeEndInclusive; + private final String dateRangeBeginInclusive; + + private final String dateSetStart; + private final String dateSetEnd; + private final String emptyDateSet; + + //TODO clean this up and use provided dateReader instead of Date.valueOf + //TODO can probably be unified with Hana implementation by supplying separators as fields + + @Override + public List> toEpochDayRangeList(String multiDateRange) { + + if (Strings.isNullOrEmpty(multiDateRange) || emptyDateSet.equals(multiDateRange)) { + return Collections.emptyList(); + } + + StringReader reader = new StringReader(multiDateRange); + + Scanner scanner = new Scanner(reader) + // ) and ] are handled manually to determine real end-date + .useDelimiter(Pattern.compile("[%s]+".formatted(Stream.of(dateSetSep, dateRangeSep, dateSetStart, dateSetEnd, dateRangeBeginInclusive) + .map(Pattern::quote) + .collect(Collectors.joining())))); + + + ArrayList> out = new ArrayList<>(); + + while (scanner.hasNext()) { + String start = scanner.next(); + String end = scanner.next(); + + out.add(tupleFromStrings(start, end)); + } + + + return out; + } + + @Override + public List toEpochDayRange(String daterange) { + if (daterange == null) { + return Collections.emptyList(); + } + + String[] dates = daterange.split(dateRangeSep); + + Preconditions.checkArgument(dates.length == 2, "Dateranges must have a start and end."); + + return tupleFromStrings(dates[0].substring(1), dates[1]); + } + + private List tupleFromStrings(String begin, String end) { + // the dateranges have always an included start date marked by a [ + int startDate; + + if (begin.equals(dateRangeMinValue)) { + startDate = CDateRange.NEGATIVE_INFINITY; + } + else { + startDate = CDate.ofLocalDate(dateReader.parseToLocalDate(begin)); + } + + String endDateExpression = end.substring(0, end.length() - 1); + int endDate; + + if (endDateExpression.equals(dateRangeMaxValue)) { + endDate = CDateRange.POSITIVE_INFINITY; + } + else { + LocalDate dateValue = dateReader.parseToLocalDate(endDateExpression); + endDate = CDate.ofLocalDate(dateValue); + if (end.endsWith(dateRangeEndExclusive)) { + endDate -= 1; + } + } + + return List.of(startDate, endDate); + } + + +} diff --git a/backend/src/main/java/com/bakdata/conquery/sql/execution/DefaultResultSetProcessor.java b/backend/src/main/java/com/bakdata/conquery/sql/execution/DefaultResultSetProcessor.java index b17d3db261..51430b486c 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/execution/DefaultResultSetProcessor.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/execution/DefaultResultSetProcessor.java @@ -7,17 +7,30 @@ import java.util.Arrays; import java.util.List; import java.util.function.Function; -import java.util.function.Predicate; import com.bakdata.conquery.models.config.ConqueryConfig; import com.bakdata.conquery.util.DateReader; import lombok.RequiredArgsConstructor; +import org.apache.logging.log4j.util.Strings; @RequiredArgsConstructor -class DefaultResultSetProcessor implements ResultSetProcessor { +public class DefaultResultSetProcessor implements ResultSetProcessor { - private final ConqueryConfig config; - private final SqlCDateSetParser sqlCDateSetParser; + protected final ConqueryConfig config; + protected final SqlCDateSetParser dateSetParser; + + /** + * Use to keep null values for primitive data types. + *

+ * For example, calling a primitives' ResultSet getter like getDouble, getInt etc. straightaway will never return null. + */ + private static T checkForNullElseGet(ResultSet resultSet, int columnIndex, Getter getter, Class resultType) throws SQLException { + + if (resultSet.getObject(columnIndex) == null) { + return null; + } + return resultType.cast(getter.getFromResultSet(columnIndex)); + } @Override public String getString(ResultSet resultSet, int columnIndex) throws SQLException { @@ -60,37 +73,37 @@ public Integer getDate(ResultSet resultSet, int columnIndex) throws SQLException @Override public List getDateRange(ResultSet resultSet, int columnIndex) throws SQLException { - return this.sqlCDateSetParser.toEpochDayRange(resultSet.getString(columnIndex)); + return this.dateSetParser.toEpochDayRange(resultSet.getString(columnIndex)); } @Override public List> getDateRangeList(ResultSet resultSet, int columnIndex) throws SQLException { - return this.sqlCDateSetParser.toEpochDayRangeList(resultSet.getString(columnIndex)); + return this.dateSetParser.toEpochDayRangeList(resultSet.getString(columnIndex)); } @Override public List getStringList(ResultSet resultSet, int columnIndex) throws SQLException { - return fromString(resultSet, columnIndex, (string) -> string); + return list(resultSet, columnIndex, (string) -> string); } @Override public List getBooleanList(ResultSet resultSet, int columnIndex) throws SQLException { - return fromString(resultSet, columnIndex, Boolean::valueOf); + return list(resultSet, columnIndex, Boolean::valueOf); } @Override public List getIntegerList(ResultSet resultSet, int columnIndex) throws SQLException { - return fromString(resultSet, columnIndex, Integer::valueOf); + return list(resultSet, columnIndex, Integer::valueOf); } @Override public List getDoubleList(ResultSet resultSet, int columnIndex) throws SQLException { - return fromString(resultSet, columnIndex, Double::valueOf); + return list(resultSet, columnIndex, Double::valueOf); } @Override public List getMoneyList(ResultSet resultSet, int columnIndex) throws SQLException { - return fromString( + return list( resultSet, columnIndex, (string) -> BigDecimal.valueOf(Double.parseDouble(string)) @@ -100,22 +113,25 @@ public List getMoneyList(ResultSet resultSet, int columnIndex) throw @Override public List getDateList(ResultSet resultSet, int columnIndex) throws SQLException { - return fromString(resultSet, columnIndex, this::parseWithDateReader); + return list(resultSet, columnIndex, this::parseWithDateReader); } private Number parseWithDateReader(String string) { return config.getLocale().getDateReader().parseToLocalDate(string).toEpochDay(); } - private List fromString(ResultSet resultSet, int columnIndex, Function parseFunction) throws SQLException { + private List list(ResultSet resultSet, int columnIndex, Function parseFunction) throws SQLException { String arrayExpression = resultSet.getString(columnIndex); if (arrayExpression == null) { return null; + } - return Arrays.stream(arrayExpression.split(String.valueOf(ResultSetProcessor.UNIT_SEPARATOR))) - .filter(Predicate.not(String::isBlank)) - .map(parseFunction) - .toList(); + + List result = Arrays.stream(arrayExpression.split(String.valueOf(UNIT_SEPARATOR))) + .filter(Strings::isNotBlank) + .map(parseFunction) + .toList(); + return result.isEmpty() ? null : result; } @FunctionalInterface @@ -123,17 +139,4 @@ private interface Getter { Object getFromResultSet(int columnIndex) throws SQLException; } - /** - * Use to keep null values for primitive data types. - *

- * For example, calling a primitives' ResultSet getter like getDouble, getInt etc. straightaway will never return null. - */ - private static T checkForNullElseGet(ResultSet resultSet, int columnIndex, Getter getter, Class resultType) throws SQLException { - - if (resultSet.getObject(columnIndex) == null) { - return null; - } - return resultType.cast(getter.getFromResultSet(columnIndex)); - } - } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/execution/DefaultSqlCDateSetParser.java b/backend/src/main/java/com/bakdata/conquery/sql/execution/DefaultSqlCDateSetParser.java deleted file mode 100644 index 820a81e9bb..0000000000 --- a/backend/src/main/java/com/bakdata/conquery/sql/execution/DefaultSqlCDateSetParser.java +++ /dev/null @@ -1,108 +0,0 @@ -package com.bakdata.conquery.sql.execution; - -import java.sql.Date; -import java.time.LocalDate; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import com.bakdata.conquery.models.common.daterange.CDateRange; -import com.bakdata.conquery.sql.conversion.dialect.SqlFunctionProvider; -import com.google.common.base.Preconditions; - -public class DefaultSqlCDateSetParser implements SqlCDateSetParser { - - public static final String EMPTY_RANGE_BRACES = "{}"; - public static final String DATE_SEPARATOR = ","; - public static final String INCLUDED_START_CHAR = "["; - public static final String EXCLUDED_END_CHAR = ")"; - - @Override - public List> toEpochDayRangeList(String multiDateRange) { - - if (multiDateRange == null || multiDateRange.equals(EMPTY_RANGE_BRACES)) { - return Collections.emptyList(); - } - - List> result = new ArrayList<>(); - List dateranges = parse(multiDateRange); - - for (String daterange : dateranges) { - result.add(toEpochDayRange(daterange)); - } - - return result; - } - - @Override - public List toEpochDayRange(String daterange) { - - if (daterange == null) { - return Collections.emptyList(); - } - - String[] dates = daterange.split(DATE_SEPARATOR); - Preconditions.checkArgument(dates.length == 2, "Dateranges must have a start and end."); - - // the dateranges have always an included start date marked by a [ - String startDateExpression = dates[0]; - int startDate; - if (startDateExpression.contains(SqlFunctionProvider.MINUS_INFINITY_SIGN)) { - startDate = CDateRange.NEGATIVE_INFINITY; - } - else { - startDate = Math.toIntExact(Date.valueOf(startDateExpression.substring(1)).toLocalDate().toEpochDay()); - } - - String endDateExpression = dates[1]; - int endDate; - if (endDateExpression.contains(SqlFunctionProvider.INFINITY_SIGN)) { - endDate = CDateRange.POSITIVE_INFINITY; - } - else { - LocalDate dateValue = Date.valueOf(endDateExpression.substring(0, endDateExpression.length() - 1)).toLocalDate(); - - dateValue = endDateExpression.endsWith(EXCLUDED_END_CHAR) - ? dateValue.minusDays(1) - : dateValue; - endDate = Math.toIntExact(dateValue.toEpochDay()); - } - - return List.of(startDate, endDate); - } - - /** - * Captures any datemultirange interval-notation. - * - *

- * From {@code {[2012-01-01,2013-01-01),[2015-01-01,2016-01-01]}}, it would capture: - *

    - *
  • [2012-01-01,2013-01-01)
  • - *
  • [2015-01-01,2016-01-01)
  • - *
- */ - private List parse(String multiDateRange) { - - List dateranges = new ArrayList<>(); - - // strip of curly braces - String current = multiDateRange.substring(1, multiDateRange.length() - 1); - - int daterangeStart = current.indexOf(INCLUDED_START_CHAR); - while (daterangeStart != -1) { - int nextDaterangeStart = current.indexOf(INCLUDED_START_CHAR, 1); - if (nextDaterangeStart == -1) { - dateranges.add(current); - } - else { - // if there is a following daterange, we also strip of the comma - dateranges.add(current.substring(0, nextDaterangeStart - 1)); - current = current.substring(nextDaterangeStart); - } - daterangeStart = nextDaterangeStart; - } - - return dateranges; - } - -} diff --git a/backend/src/main/java/com/bakdata/conquery/sql/execution/HanaSqlCDateSetParser.java b/backend/src/main/java/com/bakdata/conquery/sql/execution/HanaSqlCDateSetParser.java new file mode 100644 index 0000000000..6f8912b556 --- /dev/null +++ b/backend/src/main/java/com/bakdata/conquery/sql/execution/HanaSqlCDateSetParser.java @@ -0,0 +1,38 @@ +package com.bakdata.conquery.sql.execution; + +import static com.bakdata.conquery.sql.conversion.dialect.HanaSqlFunctionProvider.DATE_SET_SEPARATOR; + +import java.util.Collections; +import java.util.Set; + +import com.bakdata.conquery.sql.conversion.dialect.HanaSqlFunctionProvider; +import com.bakdata.conquery.util.DateReader; + +public class HanaSqlCDateSetParser extends DefaultCDateSetParser { + private static final String DATE_RANGE_SEP = "/"; + + private static final String DATE_RANGE_END_EXCLUSIVE = ")"; + private static final String DATE_RANGE_END_INCLUSIVE = "]"; + private static final String DATE_RANGE_BEGIN_INCLUSIVE = "["; + + private static final String DATE_SET_START = "{"; + private static final String DATE_SET_END = "}"; + private static final String EMPTY_DATE_SET = "{}"; + + public HanaSqlCDateSetParser() { + super( + new DateReader(Set.of("yyyy-M-dd"), Collections.emptyList(), Collections.emptyList()), + Character.toString(DATE_SET_SEPARATOR), + DATE_RANGE_SEP, + HanaSqlFunctionProvider.MIN_DATE_VALUE, + HanaSqlFunctionProvider.MAX_DATE_VALUE, + DATE_RANGE_END_EXCLUSIVE, + DATE_RANGE_END_INCLUSIVE, + DATE_RANGE_BEGIN_INCLUSIVE, + DATE_SET_START, + DATE_SET_END, + EMPTY_DATE_SET + ); + } + +} diff --git a/backend/src/main/java/com/bakdata/conquery/sql/execution/PgSqlCDateSetParser.java b/backend/src/main/java/com/bakdata/conquery/sql/execution/PgSqlCDateSetParser.java new file mode 100644 index 0000000000..253a7db001 --- /dev/null +++ b/backend/src/main/java/com/bakdata/conquery/sql/execution/PgSqlCDateSetParser.java @@ -0,0 +1,36 @@ +package com.bakdata.conquery.sql.execution; + +import java.util.Collections; +import java.util.Set; + +import com.bakdata.conquery.sql.conversion.dialect.PostgreSqlFunctionProvider; +import com.bakdata.conquery.util.DateReader; + +public class PgSqlCDateSetParser extends DefaultCDateSetParser { + private static final String DATE_RANGE_SEP = ","; + + private static final String DATE_RANGE_END_EXCLUSIVE = ")"; + private static final String DATE_RANGE_END_INCLUSIVE = "]"; + private static final String DATE_RANGE_BEGIN_INCLUSIVE = "["; + + private static final String DATE_SET_START = "{"; + private static final String DATE_SET_END = "}"; + private static final String EMPTY_DATE_SET = "empty"; + + public PgSqlCDateSetParser() { + super( + new DateReader(Set.of("yyyy-MM-dd"), Collections.emptyList(), Collections.emptyList()), + DATE_RANGE_SEP, + DATE_RANGE_SEP, + PostgreSqlFunctionProvider.NEGATIVE_INFINITY_DATE_VALUE, + PostgreSqlFunctionProvider.INFINITY_DATE_VALUE, + DATE_RANGE_END_EXCLUSIVE, + DATE_RANGE_END_INCLUSIVE, + DATE_RANGE_BEGIN_INCLUSIVE, + DATE_SET_START, + DATE_SET_END, + EMPTY_DATE_SET + ); + } + +} diff --git a/backend/src/main/java/com/bakdata/conquery/sql/execution/ResultSetProcessor.java b/backend/src/main/java/com/bakdata/conquery/sql/execution/ResultSetProcessor.java index 074716073d..6dbc880030 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/execution/ResultSetProcessor.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/execution/ResultSetProcessor.java @@ -5,10 +5,36 @@ import java.sql.SQLException; import java.util.List; +import com.bakdata.conquery.models.types.ResultType; + public interface ResultSetProcessor { char UNIT_SEPARATOR = (char) 31; // https://www.ascii-code.com/character/%E2%90%9F + static Reader readerForType(ResultType type, ResultSetProcessor processor) { + if (type instanceof ResultType.ListT listT) { + return switch ((ResultType.Primitive) listT.getElementType()) { + case STRING -> processor::getStringList; + case BOOLEAN -> processor::getBooleanList; + case INTEGER -> processor::getIntegerList; + case NUMERIC -> processor::getDoubleList; + case DATE -> processor::getDateList; + case DATE_RANGE -> processor::getDateRangeList; + case MONEY -> processor::getMoneyList; + }; + } + + return switch (((ResultType.Primitive) type)) { + case STRING -> processor::getString; + case BOOLEAN -> processor::getBoolean; + case INTEGER -> processor::getInteger; + case NUMERIC -> processor::getDouble; + case DATE -> processor::getDate; + case DATE_RANGE -> processor::getDateRange; + case MONEY -> processor::getMoney; + }; + } + String getString(ResultSet resultSet, int columnIndex) throws SQLException; Integer getInteger(ResultSet resultSet, int columnIndex) throws SQLException; @@ -36,4 +62,10 @@ public interface ResultSetProcessor { List getMoneyList(ResultSet resultSet, int columnIndex) throws SQLException; List getDateList(ResultSet resultSet, int columnIndex) throws SQLException; + + @FunctionalInterface + interface Reader { + T read(ResultSet resultSet, int columnIndex) + throws SQLException; + } } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/execution/ResultSetProcessorFactory.java b/backend/src/main/java/com/bakdata/conquery/sql/execution/ResultSetProcessorFactory.java deleted file mode 100644 index 8ebb32ce56..0000000000 --- a/backend/src/main/java/com/bakdata/conquery/sql/execution/ResultSetProcessorFactory.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.bakdata.conquery.sql.execution; - -import com.bakdata.conquery.models.config.ConqueryConfig; -import com.bakdata.conquery.sql.conversion.dialect.DialectBundle; - -public class ResultSetProcessorFactory { - - public static ResultSetProcessor create(ConqueryConfig config, DialectBundle dialectBundle) { - return new DefaultResultSetProcessor(config, dialectBundle.getCDateSetParser()); - } - -} diff --git a/backend/src/main/java/com/bakdata/conquery/sql/execution/SqlExecutionService.java b/backend/src/main/java/com/bakdata/conquery/sql/execution/SqlExecutionService.java index 5e25a983fd..883ef9d1ef 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/execution/SqlExecutionService.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/execution/SqlExecutionService.java @@ -16,7 +16,6 @@ import com.bakdata.conquery.models.execution.ExecutionState; import com.bakdata.conquery.models.query.resultinfo.ResultInfo; import com.bakdata.conquery.models.query.results.EntityResult; -import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.sql.conversion.model.SqlQuery; import lombok.Data; import lombok.Getter; @@ -50,7 +49,9 @@ private SqlExecutionExecutionInfo createStatementAndExecute(SqlQuery sqlQuery, C final String sqlString = sqlQuery.getSql(); List resultInfos = sqlQuery.getResultInfos(); - final List resultTypes = resultInfos.stream().map(ResultInfo::getType).collect(Collectors.toList()); + final List> resultTypes = resultInfos.stream() + .map(resultInfo -> resultInfo.createReader(resultSetProcessor)) + .collect(Collectors.toList()); log.info("Executing query: \n{}", sqlString); @@ -75,7 +76,7 @@ private List getColumnNames(ResultSet resultSet, int columnCount) { .toList(); } - private List createResultTable(ResultSet resultSet, List resultTypes, int columnCount) throws SQLException { + private List createResultTable(ResultSet resultSet, List> resultTypes, int columnCount) throws SQLException { final List resultTable = new ArrayList<>(resultSet.getFetchSize()); while (resultSet.next()) { final SqlEntityResult resultRow = getResultRow(resultSet, resultTypes, columnCount); @@ -93,14 +94,14 @@ private String getColumnName(ResultSet resultSet, int columnIndex) { } } - private SqlEntityResult getResultRow(ResultSet resultSet, List resultTypes, int columnCount) throws SQLException { + private SqlEntityResult getResultRow(ResultSet resultSet, List> resultTypes, int columnCount) throws SQLException { final String id = resultSet.getString(PID_COLUMN_INDEX); final Object[] resultRow = new Object[columnCount - 1]; for (int resultSetIndex = VALUES_OFFSET_INDEX; resultSetIndex <= columnCount; resultSetIndex++) { final int resultTypeIndex = resultSetIndex - VALUES_OFFSET_INDEX; - resultRow[resultTypeIndex] = resultTypes.get(resultTypeIndex).getFromResultSet(resultSet, resultSetIndex, resultSetProcessor); + resultRow[resultTypeIndex] = resultTypes.get(resultTypeIndex).read(resultSet, resultSetIndex); } return new SqlEntityResult(id, resultRow); diff --git a/backend/src/test/java/com/bakdata/conquery/execution/DefaultSqlCDateSetParserTest.java b/backend/src/test/java/com/bakdata/conquery/execution/DefaultSqlCDateSetParserTest.java index aa5e93c05a..897f65bd4f 100644 --- a/backend/src/test/java/com/bakdata/conquery/execution/DefaultSqlCDateSetParserTest.java +++ b/backend/src/test/java/com/bakdata/conquery/execution/DefaultSqlCDateSetParserTest.java @@ -5,7 +5,8 @@ import com.bakdata.conquery.models.common.CDateSet; import com.bakdata.conquery.models.common.daterange.CDateRange; import com.bakdata.conquery.models.config.LocaleConfig; -import com.bakdata.conquery.sql.execution.DefaultSqlCDateSetParser; +import com.bakdata.conquery.sql.execution.PgSqlCDateSetParser; +import com.bakdata.conquery.sql.execution.SqlCDateSetParser; import com.bakdata.conquery.util.DateReader; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.params.ParameterizedTest; @@ -14,17 +15,17 @@ class DefaultSqlCDateSetParserTest { - private static final DefaultSqlCDateSetParser DATE_SET_PARSER = new DefaultSqlCDateSetParser(); + private static final SqlCDateSetParser DATE_SET_PARSER = new PgSqlCDateSetParser(); private static final DateReader DATE_READER = new LocaleConfig().getDateReader(); public static Stream testToEpochDayRangeListProvider() { return Stream.of( - Arguments.of("{}", "{}", "Empty datemultirange"), - Arguments.of("{[-∞,∞]}", "{/}", "Infinity datemultirange"), + Arguments.of("empty", "{}", "Empty datemultirange"), + Arguments.of("{[-infinity,infinity]}", "{/}", "Infinity datemultirange"), Arguments.of("{[2012-01-01,2013-01-01)}", "{2012-01-01/2012-12-31}", "datemultirange with 1 daterange"), - Arguments.of("{[-∞,2013-01-01),[2015-01-01,∞]}", "{/2012-12-31,2015-01-01/}", "datemultirange with multiple ranges and infinity start and end value"), + Arguments.of("{[-infinity,2013-01-01),[2015-01-01,infinity]}", "{/2012-12-31,2015-01-01/}", "datemultirange with multiple ranges and infinity start and end value"), Arguments.of("{[2014-01-01,2015-01-01),[2015-06-01,2016-01-01),[2017-01-01,2018-01-01)}", "{2014-01-01/2014-12-31,2015-06-01/2015-12-31,2017-01-01/2017-12-31}", "datemultirange with multiple ranges" diff --git a/backend/src/test/java/com/bakdata/conquery/integration/ConqueryIntegrationTests.java b/backend/src/test/java/com/bakdata/conquery/integration/ConqueryIntegrationTests.java index 89ddb15661..023b056d21 100644 --- a/backend/src/test/java/com/bakdata/conquery/integration/ConqueryIntegrationTests.java +++ b/backend/src/test/java/com/bakdata/conquery/integration/ConqueryIntegrationTests.java @@ -13,7 +13,7 @@ public class ConqueryIntegrationTests extends IntegrationTests { - public static final String DEFAULT_SQL_TEST_ROOT = "tests/sql/"; + public static final String DEFAULT_SQL_TEST_ROOT = "tests/"; public static final TestDataImporter WORKER_TEST_DATA_IMPORTER = new WorkerTestDataImporter(); public ConqueryIntegrationTests() { diff --git a/backend/src/test/java/com/bakdata/conquery/integration/IntegrationTests.java b/backend/src/test/java/com/bakdata/conquery/integration/IntegrationTests.java index 6423c98443..fc3773a5c7 100644 --- a/backend/src/test/java/com/bakdata/conquery/integration/IntegrationTests.java +++ b/backend/src/test/java/com/bakdata/conquery/integration/IntegrationTests.java @@ -52,7 +52,7 @@ public class IntegrationTests { public static final ObjectMapper MAPPER; public static final String JSON_TEST_PATTERN = ".*\\.test\\.json$"; - public static final String SQL_TEST_PATTERN = ".*\\.json$"; + public static final String SQL_TEST_PATTERN = ".*\\.test\\.json$"; private static final ObjectWriter CONFIG_WRITER; static { diff --git a/backend/src/test/java/com/bakdata/conquery/integration/common/LoadingUtil.java b/backend/src/test/java/com/bakdata/conquery/integration/common/LoadingUtil.java index ff2820d014..fb915fb365 100644 --- a/backend/src/test/java/com/bakdata/conquery/integration/common/LoadingUtil.java +++ b/backend/src/test/java/com/bakdata/conquery/integration/common/LoadingUtil.java @@ -177,9 +177,7 @@ public static void uploadConcept(StandaloneSupport support, DatasetId dataset, C } public static void importTableContents(StandaloneSupport support, Collection tables) throws Exception { - List cqpps = generateCqpp(support, tables); - - importCqppFiles(support, cqpps); + support.getTestImporter().importTableContents(support, tables); } public static List generateCqpp(StandaloneSupport support, Collection tables) throws Exception { diff --git a/backend/src/test/java/com/bakdata/conquery/integration/json/ConqueryTestSpec.java b/backend/src/test/java/com/bakdata/conquery/integration/json/ConqueryTestSpec.java index 9e4d837a27..12c5d8917d 100644 --- a/backend/src/test/java/com/bakdata/conquery/integration/json/ConqueryTestSpec.java +++ b/backend/src/test/java/com/bakdata/conquery/integration/json/ConqueryTestSpec.java @@ -32,6 +32,7 @@ public abstract class ConqueryTestSpec { private static final ObjectReader TEST_SPEC_READER = Jackson.MAPPER.readerFor(ConqueryTestSpec.class); + @Nullable SqlSpec sqlSpec; private String label; diff --git a/backend/src/test/java/com/bakdata/conquery/integration/json/SqlSpec.java b/backend/src/test/java/com/bakdata/conquery/integration/json/SqlSpec.java index f5333f19bb..a4013c596e 100644 --- a/backend/src/test/java/com/bakdata/conquery/integration/json/SqlSpec.java +++ b/backend/src/test/java/com/bakdata/conquery/integration/json/SqlSpec.java @@ -1,7 +1,6 @@ package com.bakdata.conquery.integration.json; import java.util.List; - import javax.annotation.Nullable; import com.bakdata.conquery.models.config.Dialect; @@ -15,6 +14,10 @@ public class SqlSpec { @Nullable List supportedDialects; + // This does nothing, it's just a convenience field for describing why tests are disabled in certain dialects or cases + @Nullable + String comment; + /** * @return True if a test spec is allowed for a specific dialect. */ diff --git a/backend/src/test/java/com/bakdata/conquery/integration/json/SqlTestDataImporter.java b/backend/src/test/java/com/bakdata/conquery/integration/json/SqlTestDataImporter.java index da8a728435..e35413b497 100644 --- a/backend/src/test/java/com/bakdata/conquery/integration/json/SqlTestDataImporter.java +++ b/backend/src/test/java/com/bakdata/conquery/integration/json/SqlTestDataImporter.java @@ -9,7 +9,6 @@ import com.bakdata.conquery.integration.common.LoadingUtil; import com.bakdata.conquery.integration.common.RequiredData; import com.bakdata.conquery.integration.common.RequiredTable; -import com.bakdata.conquery.integration.json.filter.FilterTest; import com.bakdata.conquery.integration.sql.CsvTableImporter; import com.bakdata.conquery.models.datasets.Dataset; import com.bakdata.conquery.models.exceptions.JSONException; @@ -20,53 +19,23 @@ @Slf4j @Data -public class SqlTestDataImporter implements TestDataImporter { - - private static final RequiredTable ALL_IDS_TABLE = readRequiredTable("/shared/entities.table.json"); +public class SqlTestDataImporter extends WorkerTestDataImporter { private final CsvTableImporter csvTableImporter; - @Override - public void importQueryTestData(StandaloneSupport support, QueryTest test) throws Exception { - RequiredData content = test.getContent(); - - content.getTables().add(ALL_IDS_TABLE); - importSecondaryIds(support, content.getSecondaryIds()); - importTables(support, content.getTables(), true); - importConcepts(support, test.getRawConcepts()); - importTableContents(support, content.getTables()); - - importSearchIndexes(support, test.getSearchIndexes()); - importIdMapping(support, content); - } - - @Override - public void importFormTestData(StandaloneSupport support, FormTest test) throws Exception { - RequiredData content = test.getContent(); - content.getTables().add(ALL_IDS_TABLE); - importSecondaryIds(support, content.getSecondaryIds()); - importTables(support, content.getTables(), true); - importConcepts(support, test.getRawConcepts()); - importTableContents(support, content.getTables()); - importIdMapping(support, content); - importPreviousQueries(support, content); - } - - @Override - public void importFilterTestData(StandaloneSupport support, FilterTest filterTest) { - throw new UnsupportedOperationException("Not implemented yet."); - } @Override public void importTables(StandaloneSupport support, List tables, boolean autoConcept) throws JSONException { for (RequiredTable table : tables) { csvTableImporter.createTable(table); } - TestDataImporter.super.importTables(support, tables, autoConcept); + super.importTables(support, tables, autoConcept); } @Override public void importTableContents(StandaloneSupport support, Collection tables) throws Exception { + csvTableImporter.importAllIds(tables); + for (RequiredTable table : tables) { csvTableImporter.importTableIntoDatabase(table); } diff --git a/backend/src/test/java/com/bakdata/conquery/integration/json/WorkerTestDataImporter.java b/backend/src/test/java/com/bakdata/conquery/integration/json/WorkerTestDataImporter.java index c3a0ae33b2..133390a881 100644 --- a/backend/src/test/java/com/bakdata/conquery/integration/json/WorkerTestDataImporter.java +++ b/backend/src/test/java/com/bakdata/conquery/integration/json/WorkerTestDataImporter.java @@ -1,11 +1,13 @@ package com.bakdata.conquery.integration.json; -import static com.bakdata.conquery.integration.common.LoadingUtil.importInternToExternMappers; +import static com.bakdata.conquery.integration.common.LoadingUtil.*; +import java.io.File; import java.util.Collection; import java.util.Collections; import jakarta.ws.rs.client.Client; import jakarta.ws.rs.core.UriBuilder; +import java.util.List; import com.bakdata.conquery.integration.common.LoadingUtil; import com.bakdata.conquery.integration.common.RequiredData; @@ -29,7 +31,7 @@ public void importQueryTestData(StandaloneSupport support, QueryTest test) throw importSearchIndexes(support, test.getSearchIndexes()); importTables(support, content.getTables(), content.isAutoConcept()); importConcepts(support, test.getRawConcepts()); - waitUntilDone(support, () -> LoadingUtil.importTableContents(support, content.getTables())); + waitUntilDone(support, () -> importTableContents(support, content.getTables())); importIdMapping(support, content); importPreviousQueries(support, content); waitUntilDone(support, () -> LoadingUtil.updateMatchingStats(support)); @@ -43,7 +45,7 @@ public void importFormTestData(StandaloneSupport support, FormTest test) throws importSecondaryIds(support, content.getSecondaryIds()); importTables(support, content.getTables(), content.isAutoConcept()); importConcepts(support, test.getRawConcepts()); - waitUntilDone(support, () -> LoadingUtil.importTableContents(support, content.getTables())); + waitUntilDone(support, () -> importTableContents(support, content.getTables())); importIdMapping(support, content); importPreviousQueries(support, content); } @@ -72,14 +74,15 @@ public void importFilterTestData(StandaloneSupport support, FilterTest test) thr test.getConcept().setConnectors(Collections.singletonList((ConceptTreeConnector) test.getConnector())); waitUntilDone(support, () -> LoadingUtil.uploadConcept(support, support.getDataset(), test.getConcept())); - waitUntilDone(support, () -> LoadingUtil.importTableContents(support, content.getTables())); + waitUntilDone(support, () -> importTableContents(support, content.getTables())); waitUntilDone(support, () -> LoadingUtil.updateMatchingStats(support)); } @Override public void importTableContents(StandaloneSupport support, Collection tables) throws Exception { - waitUntilDone(support, () -> LoadingUtil.importTableContents(support, tables)); + List cqpps = generateCqpp(support, tables); + importCqppFiles(support, cqpps); } @Override diff --git a/backend/src/test/java/com/bakdata/conquery/integration/sql/CsvTableImporter.java b/backend/src/test/java/com/bakdata/conquery/integration/sql/CsvTableImporter.java index f7a90a5c10..7b9af73b18 100644 --- a/backend/src/test/java/com/bakdata/conquery/integration/sql/CsvTableImporter.java +++ b/backend/src/test/java/com/bakdata/conquery/integration/sql/CsvTableImporter.java @@ -1,13 +1,19 @@ package com.bakdata.conquery.integration.sql; -import java.math.BigDecimal; +import static org.jooq.impl.DSL.field; +import static org.jooq.impl.DSL.name; + import java.sql.Connection; import java.sql.Date; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.stream.Collectors; import com.bakdata.conquery.integration.common.RequiredColumn; @@ -16,14 +22,14 @@ import com.bakdata.conquery.integration.sql.dialect.TestDialectBundle; import com.bakdata.conquery.models.common.daterange.CDateRange; import com.bakdata.conquery.models.config.CSVConfig; -import com.bakdata.conquery.models.config.ConqueryConfig; import com.bakdata.conquery.models.config.DatabaseConnectionConfig; +import com.bakdata.conquery.models.config.LocaleConfig; import com.bakdata.conquery.models.events.MajorTypeId; -import com.bakdata.conquery.models.preproc.parser.specific.DateRangeParser; -import com.google.common.base.Strings; +import com.bakdata.conquery.util.DateReader; import com.univocity.parsers.csv.CsvParser; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; +import org.apache.parquet.Strings; import org.jooq.DSLContext; import org.jooq.DataType; import org.jooq.Field; @@ -40,21 +46,62 @@ public class CsvTableImporter { private static final int DEFAULT_VARCHAR_LENGTH = 25; // HANA will use 1 as default otherwise private final DSLContext dslContext; - private final DateRangeParser dateRangeParser; + private final DateReader dateReader; private final CsvParser csvReader; private final TestDialectBundle testSqlDialect; private final DatabaseConnectionConfig databaseConfig; public CsvTableImporter(DSLContext dslContext, TestDialectBundle testSqlDialect, DatabaseConnectionConfig databaseConfig) { this.dslContext = dslContext; - this.dateRangeParser = new DateRangeParser(new ConqueryConfig()); - this.csvReader = new CSVConfig().withSkipHeader(true).createParser(); + this.dateReader = new LocaleConfig().getDateReader(); + this.csvReader = new CSVConfig().withParseHeaders(true).createParser(); this.testSqlDialect = testSqlDialect; this.databaseConfig = databaseConfig; } + @SneakyThrows + public Set collectAllIds(ResourceFile csvFile, RequiredColumn idColumn) { + Set allIds = new HashSet<>(); + + List records = csvReader.parseAllRecords(csvFile.stream()); + + for (com.univocity.parsers.common.record.Record record : records) { + + String raw = record.getString(idColumn.getName()); + + allIds.add(raw); + } + + return allIds; + } + + public void importAllIds(Collection tables) { + + Set allIds = tables.stream() + .flatMap(table -> collectAllIds(table.getCsv(), table.getPrimaryColumn()).stream()) + .collect(Collectors.toSet()); + + Table table = DSL.table(name("entities")); + List> columns = List.of(field(name("pid"), SQLDataType.VARCHAR(20))); + + + List content = allIds.stream() + .map(Collections::singletonList) + .map(DSL::row) + .toList(); + + // we directly use JDBC because JOOQ can't cope with some custom types like daterange + dslContext.connection((Connection connection) -> { + try (Statement statement = connection.createStatement()) { + dropTable(table, statement); + createTable(table, columns, statement); + insertValuesIntoTable(table, columns, content, statement); + } + }); + } + public void createTable(RequiredTable requiredTable) { - Table table = DSL.table(DSL.name(requiredTable.getName())); + Table table = DSL.table(name(requiredTable.getName())); List allRequiredColumns = getAllRequiredColumns(requiredTable); List> columns = createFieldsForColumns(allRequiredColumns); @@ -97,6 +144,7 @@ private void createTable(Table table, List> columns, Statement statement.execute(createTableStatement); } + private Field createField(RequiredColumn requiredColumn) { DataType dataType = switch (requiredColumn.getType()) { case STRING -> SQLDataType.VARCHAR(DEFAULT_VARCHAR_LENGTH); @@ -113,7 +161,7 @@ private Field createField(RequiredColumn requiredColumn) { dataType = dataType.nullable(true); } - return DSL.field(DSL.name(requiredColumn.getName()), dataType); + return DSL.field(name(requiredColumn.getName()), dataType); } /** @@ -122,7 +170,7 @@ private Field createField(RequiredColumn requiredColumn) { */ public void importTableIntoDatabase(RequiredTable requiredTable) { - Table table = DSL.table(DSL.name(requiredTable.getName())); + Table table = DSL.table(name(requiredTable.getName())); List allRequiredColumns = getAllRequiredColumns(requiredTable); List> columns = createFieldsForColumns(allRequiredColumns); List content = getTablesContentFromCSV(requiredTable.getCsv(), allRequiredColumns); @@ -137,8 +185,9 @@ public void importTableIntoDatabase(RequiredTable requiredTable) { @SneakyThrows private List getTablesContentFromCSV(ResourceFile csvFile, List requiredColumns) { - List rawContent = this.csvReader.parseAll(csvFile.stream()); - List> castedContent = this.castContent(rawContent, requiredColumns); + csvReader.beginParsing(csvFile.stream()); + List records = csvReader.parseAllRecords(); + List> castedContent = readRecords(records, requiredColumns); return castedContent.stream() .map(DSL::row) .toList(); @@ -156,40 +205,41 @@ private void insertValuesIntoTable(Table table, List> columns, /** * Casts all values of each row to the corresponding type of the column the value refers to. */ - private List> castContent(List rawContent, List requiredColumns) { - List> castedContent = new ArrayList<>(rawContent.size()); - for (String[] row : rawContent) { - List castEntriesOfRow = new ArrayList<>(row.length); - for (int i = 0; i < row.length; i++) { - MajorTypeId type = requiredColumns.get(i).getType(); - castEntriesOfRow.add(this.castEntryAccordingToColumnType(row[i], type)); + private List> readRecords(List rawContent, List requiredColumns) { + List> castedContent = new ArrayList<>(); + rawContent.forEach(row -> { + List castEntriesOfRow = new ArrayList<>(requiredColumns.size()); + for (RequiredColumn col : requiredColumns) { + try { + castEntriesOfRow.add(this.readAccordingToColumnType(row, col.getName(), col.getType())); + } + catch (Exception e) { + throw new IllegalArgumentException("Failed to read value %s for %s".formatted(row.getString(col.getName()), col), e); + } } castedContent.add(castEntriesOfRow); - } + }); return castedContent; } - private Object castEntryAccordingToColumnType(String entry, MajorTypeId type) { + private Object readAccordingToColumnType(com.univocity.parsers.common.record.Record record, String column, MajorTypeId type) { // if the entry from the CSV is empty, the value in the database should be null - if (Strings.isNullOrEmpty(entry)) { + if (Strings.isNullOrEmpty(record.getString(column))) { return null; } return switch (type) { - case STRING -> entry; - case BOOLEAN -> Boolean.valueOf(entry); - case INTEGER -> Integer.valueOf(entry); - case REAL -> Float.valueOf(entry); - case DECIMAL, MONEY -> new BigDecimal(entry); - case DATE -> Date.valueOf(entry); + case STRING -> record.getString(column); + case BOOLEAN -> record.getBoolean(column); + case INTEGER -> record.getInt(column); + case REAL -> record.getDouble(column); + case DECIMAL, MONEY -> record.getBigDecimal(column); + case DATE -> dateReader.parseToLocalDate(record.getString(column)); case DATE_RANGE -> { - CDateRange dateRange = this.dateRangeParser.parse(entry); - yield DateRange.dateRange( - Date.valueOf(dateRange.getMin()), - true, - Date.valueOf(dateRange.getMax()), - true + CDateRange dateRange = dateReader.parseToCDateRange(record.getString(column)); + yield DateRange.dateRange(dateRange.getMin() != null ? Date.valueOf(dateRange.getMin()) : null, true, + dateRange.getMax() != null ? Date.valueOf(dateRange.getMax()) : null, true ); } }; diff --git a/backend/src/test/java/com/bakdata/conquery/integration/sql/dialect/PostgreSqlIntegrationTests.java b/backend/src/test/java/com/bakdata/conquery/integration/sql/dialect/PostgreSqlIntegrationTests.java index 82a874d17c..0675bd21f7 100644 --- a/backend/src/test/java/com/bakdata/conquery/integration/sql/dialect/PostgreSqlIntegrationTests.java +++ b/backend/src/test/java/com/bakdata/conquery/integration/sql/dialect/PostgreSqlIntegrationTests.java @@ -16,7 +16,6 @@ import com.bakdata.conquery.sql.conversion.dialect.PostgreDialectBundle; import com.bakdata.conquery.sql.conversion.model.SqlQuery; import com.bakdata.conquery.sql.execution.ResultSetProcessor; -import com.bakdata.conquery.sql.execution.ResultSetProcessorFactory; import com.bakdata.conquery.sql.execution.SqlExecutionService; import com.google.common.base.Strings; import lombok.Getter; @@ -93,7 +92,7 @@ static void after() throws Exception { public void shouldThrowException() { // This can be removed as soon as we switch to a full integration test including the REST API I18n.init(); - ResultSetProcessor resultSetProcessor = ResultSetProcessorFactory.create(config, testSqlDialect); + ResultSetProcessor resultSetProcessor = testSqlDialect.getResultSetProcessor(config); SqlExecutionService executionService = new SqlExecutionService(dslContext, resultSetProcessor); SqlQuery validQuery = new TestSqlQuery(Dialect.POSTGRESQL.getDialectBundle().getConnectionTestString()); Assertions.assertThatNoException().isThrownBy(() -> executionService.execute(validQuery)); diff --git a/backend/src/test/java/com/bakdata/conquery/integration/tests/ReusedQueryTest.java b/backend/src/test/java/com/bakdata/conquery/integration/tests/ReusedQueryTest.java index 4d2e7d5277..c5d5d7dcd9 100644 --- a/backend/src/test/java/com/bakdata/conquery/integration/tests/ReusedQueryTest.java +++ b/backend/src/test/java/com/bakdata/conquery/integration/tests/ReusedQueryTest.java @@ -56,6 +56,8 @@ public Set forModes() { return Set.of(StandaloneSupport.Mode.WORKER, StandaloneSupport.Mode.SQL); } + + @Override public void execute(String name, TestConquery testConquery) throws Exception { diff --git a/backend/src/test/java/com/bakdata/conquery/io/result/ResultTestUtil.java b/backend/src/test/java/com/bakdata/conquery/io/result/ResultTestUtil.java index 4a7b9adee7..b3a62ec159 100644 --- a/backend/src/test/java/com/bakdata/conquery/io/result/ResultTestUtil.java +++ b/backend/src/test/java/com/bakdata/conquery/io/result/ResultTestUtil.java @@ -29,6 +29,7 @@ import com.bakdata.conquery.models.query.results.SinglelineEntityResult; import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.models.types.SemanticType; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.bakdata.conquery.util.NonPersistentStoreFactory; import com.bakdata.conquery.util.TestNamespacedStorageProvider; import lombok.Getter; @@ -166,6 +167,10 @@ public List getRequiredColumns() { return Collections.emptyList(); } + @Override + public ResultSetProcessor.Reader createResultSetReader(ResultSetProcessor processor) { + throw new IllegalStateException("This should not be called"); + } @Override public Aggregator createAggregator() { diff --git a/backend/src/test/java/com/bakdata/conquery/models/query/DefaultColumnNameTest.java b/backend/src/test/java/com/bakdata/conquery/models/query/DefaultColumnNameTest.java index 77ec2b94d0..90d643a195 100644 --- a/backend/src/test/java/com/bakdata/conquery/models/query/DefaultColumnNameTest.java +++ b/backend/src/test/java/com/bakdata/conquery/models/query/DefaultColumnNameTest.java @@ -37,6 +37,7 @@ import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.models.worker.LocalNamespace; import com.bakdata.conquery.models.worker.Namespace; +import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.bakdata.conquery.util.NonPersistentStoreFactory; import com.bakdata.conquery.util.TestNamespacedStorageProvider; import io.dropwizard.jersey.validation.Validators; @@ -307,6 +308,11 @@ public Aggregator createAggregator() { return null; } + @Override + public ResultSetProcessor.Reader createResultSetReader(ResultSetProcessor processor) { + return processor::getString; + } + @Override public ResultType getResultType() { return ResultType.Primitive.STRING; diff --git a/backend/src/test/resources/tests/sql/and/different_concept/and.json b/backend/src/test/resources/EXCLUDED_sql/and/different_concept/and.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/and/different_concept/and.json rename to backend/src/test/resources/EXCLUDED_sql/and/different_concept/and.test.json diff --git a/backend/src/test/resources/tests/sql/and/different_concept/content_1.csv b/backend/src/test/resources/EXCLUDED_sql/and/different_concept/content_1.csv similarity index 100% rename from backend/src/test/resources/tests/sql/and/different_concept/content_1.csv rename to backend/src/test/resources/EXCLUDED_sql/and/different_concept/content_1.csv diff --git a/backend/src/test/resources/tests/sql/and/different_concept/content_2.csv b/backend/src/test/resources/EXCLUDED_sql/and/different_concept/content_2.csv similarity index 100% rename from backend/src/test/resources/tests/sql/and/different_concept/content_2.csv rename to backend/src/test/resources/EXCLUDED_sql/and/different_concept/content_2.csv diff --git a/backend/src/test/resources/tests/sql/and/different_concept/expected.csv b/backend/src/test/resources/EXCLUDED_sql/and/different_concept/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/and/different_concept/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/and/different_concept/expected.csv diff --git a/backend/src/test/resources/tests/sql/and/same_concept/and_same_concept.json b/backend/src/test/resources/EXCLUDED_sql/and/same_concept/and_same_concept.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/and/same_concept/and_same_concept.json rename to backend/src/test/resources/EXCLUDED_sql/and/same_concept/and_same_concept.test.json diff --git a/backend/src/test/resources/tests/sql/and/same_concept/content_1.csv b/backend/src/test/resources/EXCLUDED_sql/and/same_concept/content_1.csv similarity index 100% rename from backend/src/test/resources/tests/sql/and/same_concept/content_1.csv rename to backend/src/test/resources/EXCLUDED_sql/and/same_concept/content_1.csv diff --git a/backend/src/test/resources/tests/sql/and/same_concept/expected.csv b/backend/src/test/resources/EXCLUDED_sql/and/same_concept/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/and/same_concept/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/and/same_concept/expected.csv diff --git a/backend/src/test/resources/tests/sql/combined/combined.json b/backend/src/test/resources/EXCLUDED_sql/combined/combined.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/combined/combined.json rename to backend/src/test/resources/EXCLUDED_sql/combined/combined.test.json diff --git a/backend/src/test/resources/tests/sql/combined/content.csv b/backend/src/test/resources/EXCLUDED_sql/combined/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/combined/content.csv rename to backend/src/test/resources/EXCLUDED_sql/combined/content.csv diff --git a/backend/src/test/resources/tests/sql/combined/content2.csv b/backend/src/test/resources/EXCLUDED_sql/combined/content2.csv similarity index 100% rename from backend/src/test/resources/tests/sql/combined/content2.csv rename to backend/src/test/resources/EXCLUDED_sql/combined/content2.csv diff --git a/backend/src/test/resources/tests/sql/combined/expected.csv b/backend/src/test/resources/EXCLUDED_sql/combined/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/combined/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/combined/expected.csv diff --git a/backend/src/test/resources/tests/sql/date_restriction/date_restriction_date_column/content.csv b/backend/src/test/resources/EXCLUDED_sql/date_restriction/date_restriction_date_column/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/date_restriction/date_restriction_date_column/content.csv rename to backend/src/test/resources/EXCLUDED_sql/date_restriction/date_restriction_date_column/content.csv diff --git a/backend/src/test/resources/tests/sql/date_restriction/date_restriction_date_column/date_restriction_date_column.json b/backend/src/test/resources/EXCLUDED_sql/date_restriction/date_restriction_date_column/date_restriction_date_column.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/date_restriction/date_restriction_date_column/date_restriction_date_column.json rename to backend/src/test/resources/EXCLUDED_sql/date_restriction/date_restriction_date_column/date_restriction_date_column.test.json diff --git a/backend/src/test/resources/tests/sql/date_restriction/date_restriction_date_column/expected.csv b/backend/src/test/resources/EXCLUDED_sql/date_restriction/date_restriction_date_column/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/date_restriction/date_restriction_date_column/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/date_restriction/date_restriction_date_column/expected.csv diff --git a/backend/src/test/resources/tests/sql/date_restriction/date_restriction_no_validity_date/content.csv b/backend/src/test/resources/EXCLUDED_sql/date_restriction/date_restriction_no_validity_date/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/date_restriction/date_restriction_no_validity_date/content.csv rename to backend/src/test/resources/EXCLUDED_sql/date_restriction/date_restriction_no_validity_date/content.csv diff --git a/backend/src/test/resources/tests/sql/date_restriction/date_restriction_no_validity_date/date_restriction_no_validity_date.json b/backend/src/test/resources/EXCLUDED_sql/date_restriction/date_restriction_no_validity_date/date_restriction_no_validity_date.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/date_restriction/date_restriction_no_validity_date/date_restriction_no_validity_date.json rename to backend/src/test/resources/EXCLUDED_sql/date_restriction/date_restriction_no_validity_date/date_restriction_no_validity_date.test.json diff --git a/backend/src/test/resources/tests/sql/date_restriction/date_restriction_no_validity_date/expected.csv b/backend/src/test/resources/EXCLUDED_sql/date_restriction/date_restriction_no_validity_date/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/date_restriction/date_restriction_no_validity_date/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/date_restriction/date_restriction_no_validity_date/expected.csv diff --git a/backend/src/test/resources/tests/sql/date_restriction/daterange/content.csv b/backend/src/test/resources/EXCLUDED_sql/date_restriction/daterange/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/date_restriction/daterange/content.csv rename to backend/src/test/resources/EXCLUDED_sql/date_restriction/daterange/content.csv diff --git a/backend/src/test/resources/tests/sql/date_restriction/daterange/daterange_column.spec.json b/backend/src/test/resources/EXCLUDED_sql/date_restriction/daterange/daterange_column.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/date_restriction/daterange/daterange_column.spec.json rename to backend/src/test/resources/EXCLUDED_sql/date_restriction/daterange/daterange_column.test.json diff --git a/backend/src/test/resources/tests/sql/date_restriction/daterange/expected.csv b/backend/src/test/resources/EXCLUDED_sql/date_restriction/daterange/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/date_restriction/daterange/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/date_restriction/daterange/expected.csv diff --git a/backend/src/test/resources/tests/sql/date_restriction/only_max/content.csv b/backend/src/test/resources/EXCLUDED_sql/date_restriction/only_max/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/date_restriction/only_max/content.csv rename to backend/src/test/resources/EXCLUDED_sql/date_restriction/only_max/content.csv diff --git a/backend/src/test/resources/tests/sql/date_restriction/only_max/expected.csv b/backend/src/test/resources/EXCLUDED_sql/date_restriction/only_max/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/date_restriction/only_max/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/date_restriction/only_max/expected.csv diff --git a/backend/src/test/resources/tests/sql/date_restriction/only_max/only_max.spec.json b/backend/src/test/resources/EXCLUDED_sql/date_restriction/only_max/only_max.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/date_restriction/only_max/only_max.spec.json rename to backend/src/test/resources/EXCLUDED_sql/date_restriction/only_max/only_max.test.json diff --git a/backend/src/test/resources/tests/sql/date_restriction/only_min/content.csv b/backend/src/test/resources/EXCLUDED_sql/date_restriction/only_min/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/date_restriction/only_min/content.csv rename to backend/src/test/resources/EXCLUDED_sql/date_restriction/only_min/content.csv diff --git a/backend/src/test/resources/tests/sql/date_restriction/only_min/expected.csv b/backend/src/test/resources/EXCLUDED_sql/date_restriction/only_min/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/date_restriction/only_min/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/date_restriction/only_min/expected.csv diff --git a/backend/src/test/resources/tests/sql/date_restriction/only_min/only_min.spec.json b/backend/src/test/resources/EXCLUDED_sql/date_restriction/only_min/only_min.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/date_restriction/only_min/only_min.spec.json rename to backend/src/test/resources/EXCLUDED_sql/date_restriction/only_min/only_min.test.json diff --git a/backend/src/test/resources/tests/sql/date_restriction/postgres_daterange/content.csv b/backend/src/test/resources/EXCLUDED_sql/date_restriction/postgres_daterange/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/date_restriction/postgres_daterange/content.csv rename to backend/src/test/resources/EXCLUDED_sql/date_restriction/postgres_daterange/content.csv diff --git a/backend/src/test/resources/tests/sql/date_restriction/postgres_daterange/daterange_column.spec.json b/backend/src/test/resources/EXCLUDED_sql/date_restriction/postgres_daterange/daterange_column.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/date_restriction/postgres_daterange/daterange_column.spec.json rename to backend/src/test/resources/EXCLUDED_sql/date_restriction/postgres_daterange/daterange_column.test.json diff --git a/backend/src/test/resources/tests/sql/date_restriction/postgres_daterange/expected.csv b/backend/src/test/resources/EXCLUDED_sql/date_restriction/postgres_daterange/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/date_restriction/postgres_daterange/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/date_restriction/postgres_daterange/expected.csv diff --git a/backend/src/test/resources/tests/sql/date_restriction/simple_date/content.csv b/backend/src/test/resources/EXCLUDED_sql/date_restriction/simple_date/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/date_restriction/simple_date/content.csv rename to backend/src/test/resources/EXCLUDED_sql/date_restriction/simple_date/content.csv diff --git a/backend/src/test/resources/tests/sql/date_restriction/simple_date/date_restriction_simple_date.json b/backend/src/test/resources/EXCLUDED_sql/date_restriction/simple_date/date_restriction_simple_date.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/date_restriction/simple_date/date_restriction_simple_date.json rename to backend/src/test/resources/EXCLUDED_sql/date_restriction/simple_date/date_restriction_simple_date.test.json diff --git a/backend/src/test/resources/tests/sql/date_restriction/simple_date/expected.csv b/backend/src/test/resources/EXCLUDED_sql/date_restriction/simple_date/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/date_restriction/simple_date/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/date_restriction/simple_date/expected.csv diff --git a/backend/src/test/resources/tests/sql/external/SIMPLE_CQEXTERNAL_QUERY.test.json b/backend/src/test/resources/EXCLUDED_sql/external/SIMPLE_CQEXTERNAL_QUERY.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/external/SIMPLE_CQEXTERNAL_QUERY.test.json rename to backend/src/test/resources/EXCLUDED_sql/external/SIMPLE_CQEXTERNAL_QUERY.test.json diff --git a/backend/src/test/resources/tests/sql/external/content.csv b/backend/src/test/resources/EXCLUDED_sql/external/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/external/content.csv rename to backend/src/test/resources/EXCLUDED_sql/external/content.csv diff --git a/backend/src/test/resources/tests/sql/external/expected.csv b/backend/src/test/resources/EXCLUDED_sql/external/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/external/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/external/expected.csv diff --git a/backend/src/test/resources/tests/sql/filter/big_multi_select/big_multi_select.spec.json b/backend/src/test/resources/EXCLUDED_sql/filter/big_multi_select/big_multi_select.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/filter/big_multi_select/big_multi_select.spec.json rename to backend/src/test/resources/EXCLUDED_sql/filter/big_multi_select/big_multi_select.test.json diff --git a/backend/src/test/resources/tests/sql/filter/big_multi_select/content.csv b/backend/src/test/resources/EXCLUDED_sql/filter/big_multi_select/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/big_multi_select/content.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/big_multi_select/content.csv diff --git a/backend/src/test/resources/tests/sql/filter/big_multi_select/expected.csv b/backend/src/test/resources/EXCLUDED_sql/filter/big_multi_select/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/big_multi_select/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/big_multi_select/expected.csv diff --git a/backend/src/test/resources/tests/sql/filter/count/content.csv b/backend/src/test/resources/EXCLUDED_sql/filter/count/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/count/content.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/count/content.csv diff --git a/backend/src/test/resources/tests/sql/filter/count/count.json b/backend/src/test/resources/EXCLUDED_sql/filter/count/count.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/filter/count/count.json rename to backend/src/test/resources/EXCLUDED_sql/filter/count/count.test.json diff --git a/backend/src/test/resources/tests/sql/filter/count/expected.csv b/backend/src/test/resources/EXCLUDED_sql/filter/count/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/count/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/count/expected.csv diff --git a/backend/src/test/resources/tests/sql/filter/count_distinct/content.csv b/backend/src/test/resources/EXCLUDED_sql/filter/count_distinct/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/count_distinct/content.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/count_distinct/content.csv diff --git a/backend/src/test/resources/tests/sql/filter/count_distinct/count_distinct.json b/backend/src/test/resources/EXCLUDED_sql/filter/count_distinct/count_distinct.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/filter/count_distinct/count_distinct.json rename to backend/src/test/resources/EXCLUDED_sql/filter/count_distinct/count_distinct.test.json diff --git a/backend/src/test/resources/tests/sql/filter/count_distinct/expected.csv b/backend/src/test/resources/EXCLUDED_sql/filter/count_distinct/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/count_distinct/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/count_distinct/expected.csv diff --git a/backend/src/test/resources/tests/sql/filter/count_quarters/date_range/content.csv b/backend/src/test/resources/EXCLUDED_sql/filter/count_quarters/date_range/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/count_quarters/date_range/content.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/count_quarters/date_range/content.csv diff --git a/backend/src/test/resources/tests/sql/filter/count_quarters/date_range/count_quarters.json b/backend/src/test/resources/EXCLUDED_sql/filter/count_quarters/date_range/count_quarters.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/filter/count_quarters/date_range/count_quarters.json rename to backend/src/test/resources/EXCLUDED_sql/filter/count_quarters/date_range/count_quarters.test.json diff --git a/backend/src/test/resources/tests/sql/filter/count_quarters/date_range/expected.csv b/backend/src/test/resources/EXCLUDED_sql/filter/count_quarters/date_range/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/count_quarters/date_range/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/count_quarters/date_range/expected.csv diff --git a/backend/src/test/resources/tests/sql/filter/count_quarters/postgres/content.csv b/backend/src/test/resources/EXCLUDED_sql/filter/count_quarters/postgres/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/count_quarters/postgres/content.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/count_quarters/postgres/content.csv diff --git a/backend/src/test/resources/tests/sql/filter/count_quarters/postgres/daterange_column.spec.json b/backend/src/test/resources/EXCLUDED_sql/filter/count_quarters/postgres/daterange_column.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/filter/count_quarters/postgres/daterange_column.spec.json rename to backend/src/test/resources/EXCLUDED_sql/filter/count_quarters/postgres/daterange_column.test.json diff --git a/backend/src/test/resources/tests/sql/filter/count_quarters/postgres/expected.csv b/backend/src/test/resources/EXCLUDED_sql/filter/count_quarters/postgres/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/count_quarters/postgres/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/count_quarters/postgres/expected.csv diff --git a/backend/src/test/resources/tests/sql/filter/count_quarters/single_date/content.csv b/backend/src/test/resources/EXCLUDED_sql/filter/count_quarters/single_date/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/count_quarters/single_date/content.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/count_quarters/single_date/content.csv diff --git a/backend/src/test/resources/tests/sql/filter/count_quarters/single_date/count_quarters.json b/backend/src/test/resources/EXCLUDED_sql/filter/count_quarters/single_date/count_quarters.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/filter/count_quarters/single_date/count_quarters.json rename to backend/src/test/resources/EXCLUDED_sql/filter/count_quarters/single_date/count_quarters.test.json diff --git a/backend/src/test/resources/tests/sql/filter/count_quarters/single_date/expected.csv b/backend/src/test/resources/EXCLUDED_sql/filter/count_quarters/single_date/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/count_quarters/single_date/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/count_quarters/single_date/expected.csv diff --git a/backend/src/test/resources/tests/sql/filter/date_distance/centuries/centuries.spec.json b/backend/src/test/resources/EXCLUDED_sql/filter/date_distance/centuries/centuries.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/filter/date_distance/centuries/centuries.spec.json rename to backend/src/test/resources/EXCLUDED_sql/filter/date_distance/centuries/centuries.test.json diff --git a/backend/src/test/resources/tests/sql/filter/date_distance/centuries/content.csv b/backend/src/test/resources/EXCLUDED_sql/filter/date_distance/centuries/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/date_distance/centuries/content.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/date_distance/centuries/content.csv diff --git a/backend/src/test/resources/tests/sql/filter/date_distance/centuries/expected.csv b/backend/src/test/resources/EXCLUDED_sql/filter/date_distance/centuries/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/date_distance/centuries/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/date_distance/centuries/expected.csv diff --git a/backend/src/test/resources/tests/sql/filter/date_distance/days_with_date_restriction/content.csv b/backend/src/test/resources/EXCLUDED_sql/filter/date_distance/days_with_date_restriction/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/date_distance/days_with_date_restriction/content.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/date_distance/days_with_date_restriction/content.csv diff --git a/backend/src/test/resources/tests/sql/filter/date_distance/days_with_date_restriction/days_with_date_restriction.spec.json b/backend/src/test/resources/EXCLUDED_sql/filter/date_distance/days_with_date_restriction/days_with_date_restriction.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/filter/date_distance/days_with_date_restriction/days_with_date_restriction.spec.json rename to backend/src/test/resources/EXCLUDED_sql/filter/date_distance/days_with_date_restriction/days_with_date_restriction.test.json diff --git a/backend/src/test/resources/tests/sql/filter/date_distance/days_with_date_restriction/expected.csv b/backend/src/test/resources/EXCLUDED_sql/filter/date_distance/days_with_date_restriction/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/date_distance/days_with_date_restriction/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/date_distance/days_with_date_restriction/expected.csv diff --git a/backend/src/test/resources/tests/sql/filter/date_distance/days_without_date_restriction/content.csv b/backend/src/test/resources/EXCLUDED_sql/filter/date_distance/days_without_date_restriction/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/date_distance/days_without_date_restriction/content.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/date_distance/days_without_date_restriction/content.csv diff --git a/backend/src/test/resources/tests/sql/filter/date_distance/days_without_date_restriction/days_without_date_restriction.json b/backend/src/test/resources/EXCLUDED_sql/filter/date_distance/days_without_date_restriction/days_without_date_restriction.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/filter/date_distance/days_without_date_restriction/days_without_date_restriction.json rename to backend/src/test/resources/EXCLUDED_sql/filter/date_distance/days_without_date_restriction/days_without_date_restriction.test.json diff --git a/backend/src/test/resources/tests/sql/filter/date_distance/days_without_date_restriction/expected.csv b/backend/src/test/resources/EXCLUDED_sql/filter/date_distance/days_without_date_restriction/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/date_distance/days_without_date_restriction/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/date_distance/days_without_date_restriction/expected.csv diff --git a/backend/src/test/resources/tests/sql/filter/date_distance/decades/content.csv b/backend/src/test/resources/EXCLUDED_sql/filter/date_distance/decades/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/date_distance/decades/content.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/date_distance/decades/content.csv diff --git a/backend/src/test/resources/tests/sql/filter/date_distance/decades/decades.spec.json b/backend/src/test/resources/EXCLUDED_sql/filter/date_distance/decades/decades.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/filter/date_distance/decades/decades.spec.json rename to backend/src/test/resources/EXCLUDED_sql/filter/date_distance/decades/decades.test.json diff --git a/backend/src/test/resources/tests/sql/filter/date_distance/decades/expected.csv b/backend/src/test/resources/EXCLUDED_sql/filter/date_distance/decades/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/date_distance/decades/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/date_distance/decades/expected.csv diff --git a/backend/src/test/resources/tests/sql/filter/date_distance/months/content.csv b/backend/src/test/resources/EXCLUDED_sql/filter/date_distance/months/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/date_distance/months/content.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/date_distance/months/content.csv diff --git a/backend/src/test/resources/tests/sql/filter/date_distance/months/expected.csv b/backend/src/test/resources/EXCLUDED_sql/filter/date_distance/months/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/date_distance/months/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/date_distance/months/expected.csv diff --git a/backend/src/test/resources/tests/sql/filter/date_distance/months/months.spec.json b/backend/src/test/resources/EXCLUDED_sql/filter/date_distance/months/months.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/filter/date_distance/months/months.spec.json rename to backend/src/test/resources/EXCLUDED_sql/filter/date_distance/months/months.test.json diff --git a/backend/src/test/resources/tests/sql/filter/date_distance/years/content.csv b/backend/src/test/resources/EXCLUDED_sql/filter/date_distance/years/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/date_distance/years/content.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/date_distance/years/content.csv diff --git a/backend/src/test/resources/tests/sql/filter/date_distance/years/expected.csv b/backend/src/test/resources/EXCLUDED_sql/filter/date_distance/years/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/date_distance/years/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/date_distance/years/expected.csv diff --git a/backend/src/test/resources/tests/sql/filter/date_distance/years/years.spec.json b/backend/src/test/resources/EXCLUDED_sql/filter/date_distance/years/years.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/filter/date_distance/years/years.spec.json rename to backend/src/test/resources/EXCLUDED_sql/filter/date_distance/years/years.test.json diff --git a/backend/src/test/resources/tests/sql/filter/flag/content.csv b/backend/src/test/resources/EXCLUDED_sql/filter/flag/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/flag/content.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/flag/content.csv diff --git a/backend/src/test/resources/tests/sql/filter/flag/expected.csv b/backend/src/test/resources/EXCLUDED_sql/filter/flag/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/flag/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/flag/expected.csv diff --git a/backend/src/test/resources/tests/sql/filter/flag/flag.spec.json b/backend/src/test/resources/EXCLUDED_sql/filter/flag/flag.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/filter/flag/flag.spec.json rename to backend/src/test/resources/EXCLUDED_sql/filter/flag/flag.test.json diff --git a/backend/src/test/resources/tests/sql/filter/multi_select/content.csv b/backend/src/test/resources/EXCLUDED_sql/filter/multi_select/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/multi_select/content.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/multi_select/content.csv diff --git a/backend/src/test/resources/tests/sql/filter/multi_select/expected.csv b/backend/src/test/resources/EXCLUDED_sql/filter/multi_select/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/multi_select/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/multi_select/expected.csv diff --git a/backend/src/test/resources/tests/sql/filter/multi_select/multi_select.spec.json b/backend/src/test/resources/EXCLUDED_sql/filter/multi_select/multi_select.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/filter/multi_select/multi_select.spec.json rename to backend/src/test/resources/EXCLUDED_sql/filter/multi_select/multi_select.test.json diff --git a/backend/src/test/resources/tests/sql/filter/number/content.csv b/backend/src/test/resources/EXCLUDED_sql/filter/number/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/number/content.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/number/content.csv diff --git a/backend/src/test/resources/tests/sql/filter/number/expected.csv b/backend/src/test/resources/EXCLUDED_sql/filter/number/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/number/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/number/expected.csv diff --git a/backend/src/test/resources/tests/sql/filter/number/number.spec.json b/backend/src/test/resources/EXCLUDED_sql/filter/number/number.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/filter/number/number.spec.json rename to backend/src/test/resources/EXCLUDED_sql/filter/number/number.test.json diff --git a/backend/src/test/resources/tests/sql/filter/number_money/integer_range/content.csv b/backend/src/test/resources/EXCLUDED_sql/filter/number_money/integer_range/content.csv similarity index 91% rename from backend/src/test/resources/tests/sql/filter/number_money/integer_range/content.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/number_money/integer_range/content.csv index 1cb67fbcf4..7c12a957cb 100644 --- a/backend/src/test/resources/tests/sql/filter/number_money/integer_range/content.csv +++ b/backend/src/test/resources/EXCLUDED_sql/filter/number_money/integer_range/content.csv @@ -1,4 +1,4 @@ -pid,nr +pid,money 1,50 2,250 3,150 diff --git a/backend/src/test/resources/tests/sql/filter/number_money/integer_range/expected.csv b/backend/src/test/resources/EXCLUDED_sql/filter/number_money/integer_range/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/number_money/integer_range/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/number_money/integer_range/expected.csv diff --git a/backend/src/test/resources/tests/sql/filter/number_money/integer_range/number_money.spec.json b/backend/src/test/resources/EXCLUDED_sql/filter/number_money/integer_range/number_money.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/filter/number_money/integer_range/number_money.spec.json rename to backend/src/test/resources/EXCLUDED_sql/filter/number_money/integer_range/number_money.test.json diff --git a/backend/src/test/resources/tests/sql/filter/number_only_max/content.csv b/backend/src/test/resources/EXCLUDED_sql/filter/number_only_max/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/number_only_max/content.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/number_only_max/content.csv diff --git a/backend/src/test/resources/tests/sql/filter/number_only_max/expected.csv b/backend/src/test/resources/EXCLUDED_sql/filter/number_only_max/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/number_only_max/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/number_only_max/expected.csv diff --git a/backend/src/test/resources/tests/sql/filter/number_only_max/number_only_max.spec.json b/backend/src/test/resources/EXCLUDED_sql/filter/number_only_max/number_only_max.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/filter/number_only_max/number_only_max.spec.json rename to backend/src/test/resources/EXCLUDED_sql/filter/number_only_max/number_only_max.test.json diff --git a/backend/src/test/resources/tests/sql/filter/number_only_min/content.csv b/backend/src/test/resources/EXCLUDED_sql/filter/number_only_min/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/number_only_min/content.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/number_only_min/content.csv diff --git a/backend/src/test/resources/tests/sql/filter/number_only_min/expected.csv b/backend/src/test/resources/EXCLUDED_sql/filter/number_only_min/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/number_only_min/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/number_only_min/expected.csv diff --git a/backend/src/test/resources/tests/sql/filter/number_only_min/number_only_min.spec.json b/backend/src/test/resources/EXCLUDED_sql/filter/number_only_min/number_only_min.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/filter/number_only_min/number_only_min.spec.json rename to backend/src/test/resources/EXCLUDED_sql/filter/number_only_min/number_only_min.test.json diff --git a/backend/src/test/resources/tests/sql/filter/single_select/content.csv b/backend/src/test/resources/EXCLUDED_sql/filter/single_select/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/single_select/content.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/single_select/content.csv diff --git a/backend/src/test/resources/tests/sql/filter/single_select/expected.csv b/backend/src/test/resources/EXCLUDED_sql/filter/single_select/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/single_select/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/single_select/expected.csv diff --git a/backend/src/test/resources/tests/sql/filter/single_select/single_select.spec.json b/backend/src/test/resources/EXCLUDED_sql/filter/single_select/single_select.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/filter/single_select/single_select.spec.json rename to backend/src/test/resources/EXCLUDED_sql/filter/single_select/single_select.test.json diff --git a/backend/src/test/resources/tests/sql/filter/sum/content.csv b/backend/src/test/resources/EXCLUDED_sql/filter/sum/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/sum/content.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/sum/content.csv diff --git a/backend/src/test/resources/tests/sql/filter/sum/diffsum/content.csv b/backend/src/test/resources/EXCLUDED_sql/filter/sum/diffsum/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/sum/diffsum/content.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/sum/diffsum/content.csv diff --git a/backend/src/test/resources/tests/sql/filter/sum/diffsum/diffsum.spec.json b/backend/src/test/resources/EXCLUDED_sql/filter/sum/diffsum/diffsum.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/filter/sum/diffsum/diffsum.spec.json rename to backend/src/test/resources/EXCLUDED_sql/filter/sum/diffsum/diffsum.test.json diff --git a/backend/src/test/resources/tests/sql/filter/sum/diffsum/expected.csv b/backend/src/test/resources/EXCLUDED_sql/filter/sum/diffsum/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/sum/diffsum/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/sum/diffsum/expected.csv diff --git a/backend/src/test/resources/tests/sql/filter/sum/distinct/content.csv b/backend/src/test/resources/EXCLUDED_sql/filter/sum/distinct/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/sum/distinct/content.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/sum/distinct/content.csv diff --git a/backend/src/test/resources/tests/sql/filter/sum/distinct/distinct-sum.spec.json b/backend/src/test/resources/EXCLUDED_sql/filter/sum/distinct/distinct-sum.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/filter/sum/distinct/distinct-sum.spec.json rename to backend/src/test/resources/EXCLUDED_sql/filter/sum/distinct/distinct-sum.test.json diff --git a/backend/src/test/resources/tests/sql/filter/sum/distinct/expected.csv b/backend/src/test/resources/EXCLUDED_sql/filter/sum/distinct/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/sum/distinct/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/sum/distinct/expected.csv diff --git a/backend/src/test/resources/tests/sql/filter/sum/expected.csv b/backend/src/test/resources/EXCLUDED_sql/filter/sum/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/filter/sum/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/filter/sum/expected.csv diff --git a/backend/src/test/resources/tests/sql/filter/sum/sum.json b/backend/src/test/resources/EXCLUDED_sql/filter/sum/sum.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/filter/sum/sum.json rename to backend/src/test/resources/EXCLUDED_sql/filter/sum/sum.test.json diff --git a/backend/src/test/resources/tests/sql/form/ABSOLUT/ALIGNMENT/QUARTER YEAR.json b/backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/ALIGNMENT/QUARTER YEAR.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/form/ABSOLUT/ALIGNMENT/QUARTER YEAR.json rename to backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/ALIGNMENT/QUARTER YEAR.test.json diff --git a/backend/src/test/resources/tests/sql/form/ABSOLUT/ALIGNMENT/QUARTER_DAY.json b/backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/ALIGNMENT/QUARTER_DAY.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/form/ABSOLUT/ALIGNMENT/QUARTER_DAY.json rename to backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/ALIGNMENT/QUARTER_DAY.test.json diff --git a/backend/src/test/resources/tests/sql/form/ABSOLUT/ALIGNMENT/YEAR QUARTER.json b/backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/ALIGNMENT/YEAR QUARTER.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/form/ABSOLUT/ALIGNMENT/YEAR QUARTER.json rename to backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/ALIGNMENT/YEAR QUARTER.test.json diff --git a/backend/src/test/resources/tests/sql/form/ABSOLUT/ALIGNMENT/YEAR YEAR.json b/backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/ALIGNMENT/YEAR YEAR.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/form/ABSOLUT/ALIGNMENT/YEAR YEAR.json rename to backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/ALIGNMENT/YEAR YEAR.test.json diff --git a/backend/src/test/resources/tests/sql/form/ABSOLUT/ALIGNMENT/quarter_day.csv b/backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/ALIGNMENT/quarter_day.csv similarity index 100% rename from backend/src/test/resources/tests/sql/form/ABSOLUT/ALIGNMENT/quarter_day.csv rename to backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/ALIGNMENT/quarter_day.csv diff --git a/backend/src/test/resources/tests/sql/form/ABSOLUT/ALIGNMENT/quarter_year.csv b/backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/ALIGNMENT/quarter_year.csv similarity index 100% rename from backend/src/test/resources/tests/sql/form/ABSOLUT/ALIGNMENT/quarter_year.csv rename to backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/ALIGNMENT/quarter_year.csv diff --git a/backend/src/test/resources/tests/sql/form/ABSOLUT/ALIGNMENT/year_quarter_expected.csv b/backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/ALIGNMENT/year_quarter_expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/form/ABSOLUT/ALIGNMENT/year_quarter_expected.csv rename to backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/ALIGNMENT/year_quarter_expected.csv diff --git a/backend/src/test/resources/tests/sql/form/ABSOLUT/ALIGNMENT/year_year_expected.csv b/backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/ALIGNMENT/year_year_expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/form/ABSOLUT/ALIGNMENT/year_year_expected.csv rename to backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/ALIGNMENT/year_year_expected.csv diff --git a/backend/src/test/resources/tests/sql/form/ABSOLUT/MULTIPLE_FEATURES/MULTIPLE_FEATURES.json b/backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/MULTIPLE_FEATURES/MULTIPLE_FEATURES.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/form/ABSOLUT/MULTIPLE_FEATURES/MULTIPLE_FEATURES.json rename to backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/MULTIPLE_FEATURES/MULTIPLE_FEATURES.test.json diff --git a/backend/src/test/resources/tests/sql/form/ABSOLUT/MULTIPLE_FEATURES/MULTIPLE_FEATURES_AND_CONNECTOR.json b/backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/MULTIPLE_FEATURES/MULTIPLE_FEATURES_AND_CONNECTOR.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/form/ABSOLUT/MULTIPLE_FEATURES/MULTIPLE_FEATURES_AND_CONNECTOR.json rename to backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/MULTIPLE_FEATURES/MULTIPLE_FEATURES_AND_CONNECTOR.test.json diff --git a/backend/src/test/resources/tests/sql/form/ABSOLUT/MULTIPLE_FEATURES/MULTIPLE_FEATURES_OR_CONNECTOR.json b/backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/MULTIPLE_FEATURES/MULTIPLE_FEATURES_OR_CONNECTOR.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/form/ABSOLUT/MULTIPLE_FEATURES/MULTIPLE_FEATURES_OR_CONNECTOR.json rename to backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/MULTIPLE_FEATURES/MULTIPLE_FEATURES_OR_CONNECTOR.test.json diff --git a/backend/src/test/resources/tests/sql/form/ABSOLUT/MULTIPLE_FEATURES/expected.csv b/backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/MULTIPLE_FEATURES/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/form/ABSOLUT/MULTIPLE_FEATURES/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/MULTIPLE_FEATURES/expected.csv diff --git a/backend/src/test/resources/tests/sql/form/ABSOLUT/MULTIPLE_FEATURES/expected_and_connector.csv b/backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/MULTIPLE_FEATURES/expected_and_connector.csv similarity index 100% rename from backend/src/test/resources/tests/sql/form/ABSOLUT/MULTIPLE_FEATURES/expected_and_connector.csv rename to backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/MULTIPLE_FEATURES/expected_and_connector.csv diff --git a/backend/src/test/resources/tests/sql/form/ABSOLUT/MULTIPLE_FEATURES/expected_or_connector.csv b/backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/MULTIPLE_FEATURES/expected_or_connector.csv similarity index 100% rename from backend/src/test/resources/tests/sql/form/ABSOLUT/MULTIPLE_FEATURES/expected_or_connector.csv rename to backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/MULTIPLE_FEATURES/expected_or_connector.csv diff --git a/backend/src/test/resources/tests/sql/form/ABSOLUT/SECONDARY_ID/ABS_EXPORT_FORM_SECONDARY_ID.json b/backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/SECONDARY_ID/ABS_EXPORT_FORM_SECONDARY_ID.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/form/ABSOLUT/SECONDARY_ID/ABS_EXPORT_FORM_SECONDARY_ID.json rename to backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/SECONDARY_ID/ABS_EXPORT_FORM_SECONDARY_ID.test.json diff --git a/backend/src/test/resources/tests/sql/form/ABSOLUT/SIMPLE/ABS_EXPORT_FORM.json b/backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/SIMPLE/ABS_EXPORT_FORM.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/form/ABSOLUT/SIMPLE/ABS_EXPORT_FORM.json rename to backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/SIMPLE/ABS_EXPORT_FORM.test.json diff --git a/backend/src/test/resources/tests/sql/form/ABSOLUT/SIMPLE/ABS_EXPORT_FORM_WITH_SELECT.json b/backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/SIMPLE/ABS_EXPORT_FORM_WITH_SELECT.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/form/ABSOLUT/SIMPLE/ABS_EXPORT_FORM_WITH_SELECT.json rename to backend/src/test/resources/EXCLUDED_sql/form/ABSOLUT/SIMPLE/ABS_EXPORT_FORM_WITH_SELECT.test.json diff --git a/backend/src/test/resources/tests/sql/form/ENTITY_DATE/LOGICAL/ABS_EXPORT_FORM.json b/backend/src/test/resources/EXCLUDED_sql/form/ENTITY_DATE/LOGICAL/ABS_EXPORT_FORM.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/form/ENTITY_DATE/LOGICAL/ABS_EXPORT_FORM.json rename to backend/src/test/resources/EXCLUDED_sql/form/ENTITY_DATE/LOGICAL/ABS_EXPORT_FORM.test.json diff --git a/backend/src/test/resources/tests/sql/form/ENTITY_DATE/LOGICAL_WITH_EXCLUDE/ABS_EXPORT_FORM.json b/backend/src/test/resources/EXCLUDED_sql/form/ENTITY_DATE/LOGICAL_WITH_EXCLUDE/ABS_EXPORT_FORM.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/form/ENTITY_DATE/LOGICAL_WITH_EXCLUDE/ABS_EXPORT_FORM.json rename to backend/src/test/resources/EXCLUDED_sql/form/ENTITY_DATE/LOGICAL_WITH_EXCLUDE/ABS_EXPORT_FORM.test.json diff --git a/backend/src/test/resources/tests/sql/form/ENTITY_DATE/SECONDARY_ID/SECONDARY_ID.json b/backend/src/test/resources/EXCLUDED_sql/form/ENTITY_DATE/SECONDARY_ID/SECONDARY_ID.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/form/ENTITY_DATE/SECONDARY_ID/SECONDARY_ID.json rename to backend/src/test/resources/EXCLUDED_sql/form/ENTITY_DATE/SECONDARY_ID/SECONDARY_ID.test.json diff --git a/backend/src/test/resources/tests/sql/form/ENTITY_DATE/SIMPLE/ABS_EXPORT_FORM.json b/backend/src/test/resources/EXCLUDED_sql/form/ENTITY_DATE/SIMPLE/ABS_EXPORT_FORM.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/form/ENTITY_DATE/SIMPLE/ABS_EXPORT_FORM.json rename to backend/src/test/resources/EXCLUDED_sql/form/ENTITY_DATE/SIMPLE/ABS_EXPORT_FORM.test.json diff --git a/backend/src/test/resources/tests/sql/form/ENTITY_DATE/SIMPLE/ABS_EXPORT_FORM_WITH_SELECT.json b/backend/src/test/resources/EXCLUDED_sql/form/ENTITY_DATE/SIMPLE/ABS_EXPORT_FORM_WITH_SELECT.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/form/ENTITY_DATE/SIMPLE/ABS_EXPORT_FORM_WITH_SELECT.json rename to backend/src/test/resources/EXCLUDED_sql/form/ENTITY_DATE/SIMPLE/ABS_EXPORT_FORM_WITH_SELECT.test.json diff --git a/backend/src/test/resources/tests/sql/form/FULL_EXPORT_FORM/FULL_EXPORT_FORM_SECONDARY_ID.json b/backend/src/test/resources/EXCLUDED_sql/form/FULL_EXPORT_FORM/FULL_EXPORT_FORM_SECONDARY_ID.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/form/FULL_EXPORT_FORM/FULL_EXPORT_FORM_SECONDARY_ID.json rename to backend/src/test/resources/EXCLUDED_sql/form/FULL_EXPORT_FORM/FULL_EXPORT_FORM_SECONDARY_ID.test.json diff --git a/backend/src/test/resources/tests/sql/form/FULL_EXPORT_FORM/expected.csv b/backend/src/test/resources/EXCLUDED_sql/form/FULL_EXPORT_FORM/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/form/FULL_EXPORT_FORM/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/form/FULL_EXPORT_FORM/expected.csv diff --git a/backend/src/test/resources/tests/sql/form/RELATIVE/DAYS_NEUTRAL/DAYS.json b/backend/src/test/resources/EXCLUDED_sql/form/RELATIVE/DAYS_NEUTRAL/DAYS.test.json similarity index 92% rename from backend/src/test/resources/tests/sql/form/RELATIVE/DAYS_NEUTRAL/DAYS.json rename to backend/src/test/resources/EXCLUDED_sql/form/RELATIVE/DAYS_NEUTRAL/DAYS.test.json index 82054082ed..7dec9628c2 100644 --- a/backend/src/test/resources/tests/sql/form/RELATIVE/DAYS_NEUTRAL/DAYS.json +++ b/backend/src/test/resources/EXCLUDED_sql/form/RELATIVE/DAYS_NEUTRAL/DAYS.test.json @@ -36,7 +36,8 @@ ], "content": { "tables": [ - "/shared/vers_stamm.table.json" + "/shared/vers_stamm.table.json", + "/shared/entities.table.json" ], "previousQueryResults": [ "tests/form/EXPORT_FORM/RELATIVE/SIMPLE/query_results_1.csv" diff --git a/backend/src/test/resources/tests/sql/form/RELATIVE/DAYS_NEUTRAL/expected.csv b/backend/src/test/resources/EXCLUDED_sql/form/RELATIVE/DAYS_NEUTRAL/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/form/RELATIVE/DAYS_NEUTRAL/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/form/RELATIVE/DAYS_NEUTRAL/expected.csv diff --git a/backend/src/test/resources/tests/sql/form/RELATIVE/QUARTERS_AFTER/REL_EXPORT_FORM.json b/backend/src/test/resources/EXCLUDED_sql/form/RELATIVE/QUARTERS_AFTER/REL_EXPORT_FORM.test.json similarity index 92% rename from backend/src/test/resources/tests/sql/form/RELATIVE/QUARTERS_AFTER/REL_EXPORT_FORM.json rename to backend/src/test/resources/EXCLUDED_sql/form/RELATIVE/QUARTERS_AFTER/REL_EXPORT_FORM.test.json index 708ecc5a77..bbecd2ee47 100644 --- a/backend/src/test/resources/tests/sql/form/RELATIVE/QUARTERS_AFTER/REL_EXPORT_FORM.json +++ b/backend/src/test/resources/EXCLUDED_sql/form/RELATIVE/QUARTERS_AFTER/REL_EXPORT_FORM.test.json @@ -36,7 +36,8 @@ ], "content": { "tables": [ - "/shared/vers_stamm.table.json" + "/shared/vers_stamm.table.json", + "/shared/entities.table.json" ], "previousQueryResults": [ "tests/form/EXPORT_FORM/RELATIVE/SIMPLE/query_results_1.csv" diff --git a/backend/src/test/resources/tests/sql/form/RELATIVE/QUARTERS_AFTER/expected.csv b/backend/src/test/resources/EXCLUDED_sql/form/RELATIVE/QUARTERS_AFTER/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/form/RELATIVE/QUARTERS_AFTER/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/form/RELATIVE/QUARTERS_AFTER/expected.csv diff --git a/backend/src/test/resources/tests/sql/form/RELATIVE/QUARTERS_NEUTRAL/REL_EXPORT_FORM.json b/backend/src/test/resources/EXCLUDED_sql/form/RELATIVE/QUARTERS_NEUTRAL/REL_EXPORT_FORM.test.json similarity index 92% rename from backend/src/test/resources/tests/sql/form/RELATIVE/QUARTERS_NEUTRAL/REL_EXPORT_FORM.json rename to backend/src/test/resources/EXCLUDED_sql/form/RELATIVE/QUARTERS_NEUTRAL/REL_EXPORT_FORM.test.json index 11bff2e768..23978ec5c8 100644 --- a/backend/src/test/resources/tests/sql/form/RELATIVE/QUARTERS_NEUTRAL/REL_EXPORT_FORM.json +++ b/backend/src/test/resources/EXCLUDED_sql/form/RELATIVE/QUARTERS_NEUTRAL/REL_EXPORT_FORM.test.json @@ -36,7 +36,8 @@ ], "content": { "tables": [ - "/shared/vers_stamm.table.json" + "/shared/vers_stamm.table.json", + "/shared/entities.table.json" ], "previousQueryResults": [ "tests/form/EXPORT_FORM/RELATIVE/SIMPLE/query_results_1.csv" diff --git a/backend/src/test/resources/tests/sql/form/RELATIVE/QUARTERS_NEUTRAL/expected.csv b/backend/src/test/resources/EXCLUDED_sql/form/RELATIVE/QUARTERS_NEUTRAL/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/form/RELATIVE/QUARTERS_NEUTRAL/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/form/RELATIVE/QUARTERS_NEUTRAL/expected.csv diff --git a/backend/src/test/resources/tests/sql/form/RELATIVE/SECONDARY_ID/SECONDARY_ID.json b/backend/src/test/resources/EXCLUDED_sql/form/RELATIVE/SECONDARY_ID/SECONDARY_ID.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/form/RELATIVE/SECONDARY_ID/SECONDARY_ID.json rename to backend/src/test/resources/EXCLUDED_sql/form/RELATIVE/SECONDARY_ID/SECONDARY_ID.test.json diff --git a/backend/src/test/resources/tests/sql/form/RELATIVE/SIMPLE/REL_EXPORT_FORM.json b/backend/src/test/resources/EXCLUDED_sql/form/RELATIVE/SIMPLE/REL_EXPORT_FORM.test.json similarity index 92% rename from backend/src/test/resources/tests/sql/form/RELATIVE/SIMPLE/REL_EXPORT_FORM.json rename to backend/src/test/resources/EXCLUDED_sql/form/RELATIVE/SIMPLE/REL_EXPORT_FORM.test.json index 32a5bc3e57..10b50e2328 100644 --- a/backend/src/test/resources/tests/sql/form/RELATIVE/SIMPLE/REL_EXPORT_FORM.json +++ b/backend/src/test/resources/EXCLUDED_sql/form/RELATIVE/SIMPLE/REL_EXPORT_FORM.test.json @@ -36,7 +36,8 @@ ], "content": { "tables": [ - "/shared/vers_stamm.table.json" + "/shared/vers_stamm.table.json", + "/shared/entities.table.json" ], "previousQueryResults": [ "tests/form/EXPORT_FORM/RELATIVE/SIMPLE/query_results_1.csv" diff --git a/backend/src/test/resources/tests/sql/multiple_tables/au-content.csv b/backend/src/test/resources/EXCLUDED_sql/multiple_tables/au-content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/multiple_tables/au-content.csv rename to backend/src/test/resources/EXCLUDED_sql/multiple_tables/au-content.csv diff --git a/backend/src/test/resources/tests/sql/multiple_tables/expected.csv b/backend/src/test/resources/EXCLUDED_sql/multiple_tables/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/multiple_tables/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/multiple_tables/expected.csv diff --git a/backend/src/test/resources/tests/sql/multiple_tables/kh-content.csv b/backend/src/test/resources/EXCLUDED_sql/multiple_tables/kh-content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/multiple_tables/kh-content.csv rename to backend/src/test/resources/EXCLUDED_sql/multiple_tables/kh-content.csv diff --git a/backend/src/test/resources/tests/sql/multiple_tables/multiple_tables.spec.json b/backend/src/test/resources/EXCLUDED_sql/multiple_tables/multiple_tables.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/multiple_tables/multiple_tables.spec.json rename to backend/src/test/resources/EXCLUDED_sql/multiple_tables/multiple_tables.test.json diff --git a/backend/src/test/resources/tests/sql/nested/content1.csv b/backend/src/test/resources/EXCLUDED_sql/nested/content1.csv similarity index 100% rename from backend/src/test/resources/tests/sql/nested/content1.csv rename to backend/src/test/resources/EXCLUDED_sql/nested/content1.csv diff --git a/backend/src/test/resources/tests/sql/nested/content2.csv b/backend/src/test/resources/EXCLUDED_sql/nested/content2.csv similarity index 100% rename from backend/src/test/resources/tests/sql/nested/content2.csv rename to backend/src/test/resources/EXCLUDED_sql/nested/content2.csv diff --git a/backend/src/test/resources/tests/sql/nested/expected.csv b/backend/src/test/resources/EXCLUDED_sql/nested/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/nested/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/nested/expected.csv diff --git a/backend/src/test/resources/tests/sql/nested/nested.spec.json b/backend/src/test/resources/EXCLUDED_sql/nested/nested.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/nested/nested.spec.json rename to backend/src/test/resources/EXCLUDED_sql/nested/nested.test.json diff --git a/backend/src/test/resources/tests/sql/not/content.csv b/backend/src/test/resources/EXCLUDED_sql/not/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/not/content.csv rename to backend/src/test/resources/EXCLUDED_sql/not/content.csv diff --git a/backend/src/test/resources/tests/sql/not/expected.csv b/backend/src/test/resources/EXCLUDED_sql/not/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/not/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/not/expected.csv diff --git a/backend/src/test/resources/tests/sql/not/not.spec.json b/backend/src/test/resources/EXCLUDED_sql/not/not.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/not/not.spec.json rename to backend/src/test/resources/EXCLUDED_sql/not/not.test.json diff --git a/backend/src/test/resources/tests/sql/not/with_sibling/content.csv b/backend/src/test/resources/EXCLUDED_sql/not/with_sibling/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/not/with_sibling/content.csv rename to backend/src/test/resources/EXCLUDED_sql/not/with_sibling/content.csv diff --git a/backend/src/test/resources/tests/sql/not/with_sibling/expected.csv b/backend/src/test/resources/EXCLUDED_sql/not/with_sibling/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/not/with_sibling/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/not/with_sibling/expected.csv diff --git a/backend/src/test/resources/tests/sql/not/with_sibling/not.spec.json b/backend/src/test/resources/EXCLUDED_sql/not/with_sibling/not.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/not/with_sibling/not.spec.json rename to backend/src/test/resources/EXCLUDED_sql/not/with_sibling/not.test.json diff --git a/backend/src/test/resources/tests/sql/or/different_concept/content_1.csv b/backend/src/test/resources/EXCLUDED_sql/or/different_concept/content_1.csv similarity index 100% rename from backend/src/test/resources/tests/sql/or/different_concept/content_1.csv rename to backend/src/test/resources/EXCLUDED_sql/or/different_concept/content_1.csv diff --git a/backend/src/test/resources/tests/sql/or/different_concept/content_2.csv b/backend/src/test/resources/EXCLUDED_sql/or/different_concept/content_2.csv similarity index 100% rename from backend/src/test/resources/tests/sql/or/different_concept/content_2.csv rename to backend/src/test/resources/EXCLUDED_sql/or/different_concept/content_2.csv diff --git a/backend/src/test/resources/tests/sql/or/different_concept/expected.csv b/backend/src/test/resources/EXCLUDED_sql/or/different_concept/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/or/different_concept/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/or/different_concept/expected.csv diff --git a/backend/src/test/resources/tests/sql/or/different_concept/or.spec.json b/backend/src/test/resources/EXCLUDED_sql/or/different_concept/or.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/or/different_concept/or.spec.json rename to backend/src/test/resources/EXCLUDED_sql/or/different_concept/or.test.json diff --git a/backend/src/test/resources/tests/sql/or/same_concept/content_1.csv b/backend/src/test/resources/EXCLUDED_sql/or/same_concept/content_1.csv similarity index 100% rename from backend/src/test/resources/tests/sql/or/same_concept/content_1.csv rename to backend/src/test/resources/EXCLUDED_sql/or/same_concept/content_1.csv diff --git a/backend/src/test/resources/tests/sql/or/same_concept/expected.csv b/backend/src/test/resources/EXCLUDED_sql/or/same_concept/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/or/same_concept/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/or/same_concept/expected.csv diff --git a/backend/src/test/resources/tests/sql/or/same_concept/or_same_concept.spec.json b/backend/src/test/resources/EXCLUDED_sql/or/same_concept/or_same_concept.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/or/same_concept/or_same_concept.spec.json rename to backend/src/test/resources/EXCLUDED_sql/or/same_concept/or_same_concept.test.json diff --git a/backend/src/test/resources/tests/sql/secondary_id/SECONDARY_IDS.json b/backend/src/test/resources/EXCLUDED_sql/secondary_id/SECONDARY_IDS.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/secondary_id/SECONDARY_IDS.json rename to backend/src/test/resources/EXCLUDED_sql/secondary_id/SECONDARY_IDS.test.json diff --git a/backend/src/test/resources/tests/sql/secondary_id/content.csv b/backend/src/test/resources/EXCLUDED_sql/secondary_id/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/secondary_id/content.csv rename to backend/src/test/resources/EXCLUDED_sql/secondary_id/content.csv diff --git a/backend/src/test/resources/tests/sql/secondary_id/content2.csv b/backend/src/test/resources/EXCLUDED_sql/secondary_id/content2.csv similarity index 100% rename from backend/src/test/resources/tests/sql/secondary_id/content2.csv rename to backend/src/test/resources/EXCLUDED_sql/secondary_id/content2.csv diff --git a/backend/src/test/resources/tests/sql/secondary_id/date_mode_logical/SECONDARY_IDS.json b/backend/src/test/resources/EXCLUDED_sql/secondary_id/date_mode_logical/SECONDARY_IDS.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/secondary_id/date_mode_logical/SECONDARY_IDS.json rename to backend/src/test/resources/EXCLUDED_sql/secondary_id/date_mode_logical/SECONDARY_IDS.test.json diff --git a/backend/src/test/resources/tests/sql/secondary_id/date_mode_logical/content.csv b/backend/src/test/resources/EXCLUDED_sql/secondary_id/date_mode_logical/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/secondary_id/date_mode_logical/content.csv rename to backend/src/test/resources/EXCLUDED_sql/secondary_id/date_mode_logical/content.csv diff --git a/backend/src/test/resources/tests/sql/secondary_id/date_mode_logical/content2.csv b/backend/src/test/resources/EXCLUDED_sql/secondary_id/date_mode_logical/content2.csv similarity index 100% rename from backend/src/test/resources/tests/sql/secondary_id/date_mode_logical/content2.csv rename to backend/src/test/resources/EXCLUDED_sql/secondary_id/date_mode_logical/content2.csv diff --git a/backend/src/test/resources/tests/sql/secondary_id/date_mode_logical/expected.csv b/backend/src/test/resources/EXCLUDED_sql/secondary_id/date_mode_logical/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/secondary_id/date_mode_logical/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/secondary_id/date_mode_logical/expected.csv diff --git a/backend/src/test/resources/tests/sql/secondary_id/excluded/SECONDARY_IDS_EXCLUDED.json b/backend/src/test/resources/EXCLUDED_sql/secondary_id/excluded/SECONDARY_IDS_EXCLUDED.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/secondary_id/excluded/SECONDARY_IDS_EXCLUDED.json rename to backend/src/test/resources/EXCLUDED_sql/secondary_id/excluded/SECONDARY_IDS_EXCLUDED.test.json diff --git a/backend/src/test/resources/tests/sql/secondary_id/expected.csv b/backend/src/test/resources/EXCLUDED_sql/secondary_id/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/secondary_id/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/secondary_id/expected.csv diff --git a/backend/src/test/resources/tests/sql/secondary_id/mixed/SECONDARY_IDS_MIXED.json b/backend/src/test/resources/EXCLUDED_sql/secondary_id/mixed/SECONDARY_IDS_MIXED.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/secondary_id/mixed/SECONDARY_IDS_MIXED.json rename to backend/src/test/resources/EXCLUDED_sql/secondary_id/mixed/SECONDARY_IDS_MIXED.test.json diff --git a/backend/src/test/resources/tests/sql/secondary_id/mixed/content.csv b/backend/src/test/resources/EXCLUDED_sql/secondary_id/mixed/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/secondary_id/mixed/content.csv rename to backend/src/test/resources/EXCLUDED_sql/secondary_id/mixed/content.csv diff --git a/backend/src/test/resources/tests/sql/secondary_id/mixed/content2.csv b/backend/src/test/resources/EXCLUDED_sql/secondary_id/mixed/content2.csv similarity index 100% rename from backend/src/test/resources/tests/sql/secondary_id/mixed/content2.csv rename to backend/src/test/resources/EXCLUDED_sql/secondary_id/mixed/content2.csv diff --git a/backend/src/test/resources/tests/sql/secondary_id/mixed/expected.csv b/backend/src/test/resources/EXCLUDED_sql/secondary_id/mixed/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/secondary_id/mixed/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/secondary_id/mixed/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/concept_values/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/concept_values/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/concept_values/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/concept_values/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/concept_values/content2.csv b/backend/src/test/resources/EXCLUDED_sql/selects/concept_values/content2.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/concept_values/content2.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/concept_values/content2.csv diff --git a/backend/src/test/resources/tests/sql/selects/concept_values/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/concept_values/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/concept_values/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/concept_values/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/concept_values/single_connector.json b/backend/src/test/resources/EXCLUDED_sql/selects/concept_values/single_connector.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/concept_values/single_connector.json rename to backend/src/test/resources/EXCLUDED_sql/selects/concept_values/single_connector.test.json diff --git a/backend/src/test/resources/tests/sql/selects/concept_values/two_connectors.json b/backend/src/test/resources/EXCLUDED_sql/selects/concept_values/two_connectors.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/concept_values/two_connectors.json rename to backend/src/test/resources/EXCLUDED_sql/selects/concept_values/two_connectors.test.json diff --git a/backend/src/test/resources/tests/sql/selects/count/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/count/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/count/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/count/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/count/count.json b/backend/src/test/resources/EXCLUDED_sql/selects/count/count.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/count/count.json rename to backend/src/test/resources/EXCLUDED_sql/selects/count/count.test.json diff --git a/backend/src/test/resources/tests/sql/selects/count/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/count/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/count/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/count/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/count_distinct/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/count_distinct/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/count_distinct/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/count_distinct/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/count_distinct/count_distinct.json b/backend/src/test/resources/EXCLUDED_sql/selects/count_distinct/count_distinct.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/count_distinct/count_distinct.json rename to backend/src/test/resources/EXCLUDED_sql/selects/count_distinct/count_distinct.test.json diff --git a/backend/src/test/resources/tests/sql/selects/count_distinct/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/count_distinct/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/count_distinct/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/count_distinct/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/count_quarters/date_range/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/count_quarters/date_range/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/count_quarters/date_range/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/count_quarters/date_range/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/count_quarters/date_range/count_quarters.json b/backend/src/test/resources/EXCLUDED_sql/selects/count_quarters/date_range/count_quarters.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/count_quarters/date_range/count_quarters.json rename to backend/src/test/resources/EXCLUDED_sql/selects/count_quarters/date_range/count_quarters.test.json diff --git a/backend/src/test/resources/tests/sql/selects/count_quarters/date_range/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/count_quarters/date_range/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/count_quarters/date_range/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/count_quarters/date_range/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/count_quarters/postgres/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/count_quarters/postgres/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/count_quarters/postgres/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/count_quarters/postgres/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/count_quarters/postgres/daterange_column.spec.json b/backend/src/test/resources/EXCLUDED_sql/selects/count_quarters/postgres/daterange_column.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/count_quarters/postgres/daterange_column.spec.json rename to backend/src/test/resources/EXCLUDED_sql/selects/count_quarters/postgres/daterange_column.test.json diff --git a/backend/src/test/resources/tests/sql/selects/count_quarters/postgres/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/count_quarters/postgres/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/count_quarters/postgres/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/count_quarters/postgres/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/count_quarters/single_date/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/count_quarters/single_date/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/count_quarters/single_date/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/count_quarters/single_date/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/count_quarters/single_date/count_quarters.json b/backend/src/test/resources/EXCLUDED_sql/selects/count_quarters/single_date/count_quarters.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/count_quarters/single_date/count_quarters.json rename to backend/src/test/resources/EXCLUDED_sql/selects/count_quarters/single_date/count_quarters.test.json diff --git a/backend/src/test/resources/tests/sql/selects/count_quarters/single_date/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/count_quarters/single_date/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/count_quarters/single_date/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/count_quarters/single_date/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/date_distance/centuries/centuries.spec.json b/backend/src/test/resources/EXCLUDED_sql/selects/date_distance/centuries/centuries.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/date_distance/centuries/centuries.spec.json rename to backend/src/test/resources/EXCLUDED_sql/selects/date_distance/centuries/centuries.test.json diff --git a/backend/src/test/resources/tests/sql/selects/date_distance/centuries/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/date_distance/centuries/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/date_distance/centuries/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/date_distance/centuries/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/date_distance/centuries/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/date_distance/centuries/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/date_distance/centuries/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/date_distance/centuries/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/date_distance/days_with_date_restriction/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/date_distance/days_with_date_restriction/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/date_distance/days_with_date_restriction/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/date_distance/days_with_date_restriction/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/date_distance/days_with_date_restriction/days_with_date_restriction.spec.json b/backend/src/test/resources/EXCLUDED_sql/selects/date_distance/days_with_date_restriction/days_with_date_restriction.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/date_distance/days_with_date_restriction/days_with_date_restriction.spec.json rename to backend/src/test/resources/EXCLUDED_sql/selects/date_distance/days_with_date_restriction/days_with_date_restriction.test.json diff --git a/backend/src/test/resources/tests/sql/selects/date_distance/days_with_date_restriction/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/date_distance/days_with_date_restriction/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/date_distance/days_with_date_restriction/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/date_distance/days_with_date_restriction/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/date_distance/days_without_date_restriction/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/date_distance/days_without_date_restriction/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/date_distance/days_without_date_restriction/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/date_distance/days_without_date_restriction/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/date_distance/days_without_date_restriction/days_without_date_restriction.json b/backend/src/test/resources/EXCLUDED_sql/selects/date_distance/days_without_date_restriction/days_without_date_restriction.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/date_distance/days_without_date_restriction/days_without_date_restriction.json rename to backend/src/test/resources/EXCLUDED_sql/selects/date_distance/days_without_date_restriction/days_without_date_restriction.test.json diff --git a/backend/src/test/resources/tests/sql/selects/date_distance/days_without_date_restriction/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/date_distance/days_without_date_restriction/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/date_distance/days_without_date_restriction/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/date_distance/days_without_date_restriction/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/date_distance/decades/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/date_distance/decades/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/date_distance/decades/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/date_distance/decades/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/date_distance/decades/decades.spec.json b/backend/src/test/resources/EXCLUDED_sql/selects/date_distance/decades/decades.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/date_distance/decades/decades.spec.json rename to backend/src/test/resources/EXCLUDED_sql/selects/date_distance/decades/decades.test.json diff --git a/backend/src/test/resources/tests/sql/selects/date_distance/decades/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/date_distance/decades/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/date_distance/decades/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/date_distance/decades/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/date_distance/months/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/date_distance/months/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/date_distance/months/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/date_distance/months/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/date_distance/months/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/date_distance/months/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/date_distance/months/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/date_distance/months/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/date_distance/months/months.spec.json b/backend/src/test/resources/EXCLUDED_sql/selects/date_distance/months/months.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/date_distance/months/months.spec.json rename to backend/src/test/resources/EXCLUDED_sql/selects/date_distance/months/months.test.json diff --git a/backend/src/test/resources/tests/sql/selects/date_distance/years/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/date_distance/years/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/date_distance/years/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/date_distance/years/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/date_distance/years/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/date_distance/years/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/date_distance/years/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/date_distance/years/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/date_distance/years/years.spec.json b/backend/src/test/resources/EXCLUDED_sql/selects/date_distance/years/years.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/date_distance/years/years.spec.json rename to backend/src/test/resources/EXCLUDED_sql/selects/date_distance/years/years.test.json diff --git a/backend/src/test/resources/tests/sql/selects/date_union/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/date_union/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/date_union/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/date_union/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/date_union/date_union.json b/backend/src/test/resources/EXCLUDED_sql/selects/date_union/date_union.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/date_union/date_union.json rename to backend/src/test/resources/EXCLUDED_sql/selects/date_union/date_union.test.json diff --git a/backend/src/test/resources/tests/sql/selects/date_union/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/date_union/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/date_union/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/date_union/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/distinct/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/distinct/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/distinct/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/distinct/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/distinct/distinct.json b/backend/src/test/resources/EXCLUDED_sql/selects/distinct/distinct.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/distinct/distinct.json rename to backend/src/test/resources/EXCLUDED_sql/selects/distinct/distinct.test.json diff --git a/backend/src/test/resources/tests/sql/selects/distinct/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/distinct/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/distinct/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/distinct/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/exists/exists_on_connector/content_1.csv b/backend/src/test/resources/EXCLUDED_sql/selects/exists/exists_on_connector/content_1.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/exists/exists_on_connector/content_1.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/exists/exists_on_connector/content_1.csv diff --git a/backend/src/test/resources/tests/sql/selects/exists/exists_on_connector/content_2.csv b/backend/src/test/resources/EXCLUDED_sql/selects/exists/exists_on_connector/content_2.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/exists/exists_on_connector/content_2.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/exists/exists_on_connector/content_2.csv diff --git a/backend/src/test/resources/tests/sql/selects/exists/exists_on_connector/content_3.csv b/backend/src/test/resources/EXCLUDED_sql/selects/exists/exists_on_connector/content_3.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/exists/exists_on_connector/content_3.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/exists/exists_on_connector/content_3.csv diff --git a/backend/src/test/resources/tests/sql/selects/exists/exists_on_connector/exists.spec.json b/backend/src/test/resources/EXCLUDED_sql/selects/exists/exists_on_connector/exists.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/exists/exists_on_connector/exists.spec.json rename to backend/src/test/resources/EXCLUDED_sql/selects/exists/exists_on_connector/exists.test.json diff --git a/backend/src/test/resources/tests/sql/selects/exists/exists_on_connector/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/exists/exists_on_connector/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/exists/exists_on_connector/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/exists/exists_on_connector/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/exists/exists_with_other_selects/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/exists/exists_with_other_selects/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/exists/exists_with_other_selects/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/exists/exists_with_other_selects/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/exists/exists_with_other_selects/exists_with_other_selects.spec.json b/backend/src/test/resources/EXCLUDED_sql/selects/exists/exists_with_other_selects/exists_with_other_selects.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/exists/exists_with_other_selects/exists_with_other_selects.spec.json rename to backend/src/test/resources/EXCLUDED_sql/selects/exists/exists_with_other_selects/exists_with_other_selects.test.json diff --git a/backend/src/test/resources/tests/sql/selects/exists/exists_with_other_selects/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/exists/exists_with_other_selects/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/exists/exists_with_other_selects/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/exists/exists_with_other_selects/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/exists/single_exists/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/exists/single_exists/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/exists/single_exists/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/exists/single_exists/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/exists/single_exists/exists.spec.json b/backend/src/test/resources/EXCLUDED_sql/selects/exists/single_exists/exists.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/exists/single_exists/exists.spec.json rename to backend/src/test/resources/EXCLUDED_sql/selects/exists/single_exists/exists.test.json diff --git a/backend/src/test/resources/tests/sql/selects/exists/single_exists/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/exists/single_exists/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/exists/single_exists/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/exists/single_exists/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/first/date/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/first/date/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/first/date/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/first/date/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/first/date/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/first/date/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/first/date/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/first/date/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/first/date/number_date.spec.json b/backend/src/test/resources/EXCLUDED_sql/selects/first/date/number_date.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/first/date/number_date.spec.json rename to backend/src/test/resources/EXCLUDED_sql/selects/first/date/number_date.test.json diff --git a/backend/src/test/resources/tests/sql/selects/first/money/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/first/money/content.csv similarity index 88% rename from backend/src/test/resources/tests/sql/selects/first/money/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/first/money/content.csv index c2833413b3..ebc4f56650 100644 --- a/backend/src/test/resources/tests/sql/selects/first/money/content.csv +++ b/backend/src/test/resources/EXCLUDED_sql/selects/first/money/content.csv @@ -1,4 +1,4 @@ -pid,nr +pid,money 1,50 2,250 3,150 diff --git a/backend/src/test/resources/tests/sql/selects/first/money/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/first/money/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/first/money/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/first/money/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/first/money/number_money.spec.json b/backend/src/test/resources/EXCLUDED_sql/selects/first/money/number_money.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/first/money/number_money.spec.json rename to backend/src/test/resources/EXCLUDED_sql/selects/first/money/number_money.test.json diff --git a/backend/src/test/resources/tests/sql/selects/first/number/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/first/number/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/first/number/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/first/number/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/first/number/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/first/number/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/first/number/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/first/number/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/first/number/first.spec.json b/backend/src/test/resources/EXCLUDED_sql/selects/first/number/first.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/first/number/first.spec.json rename to backend/src/test/resources/EXCLUDED_sql/selects/first/number/first.test.json diff --git a/backend/src/test/resources/tests/sql/selects/flag/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/flag/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/flag/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/flag/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/flag/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/flag/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/flag/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/flag/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/flag/flag.spec.json b/backend/src/test/resources/EXCLUDED_sql/selects/flag/flag.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/flag/flag.spec.json rename to backend/src/test/resources/EXCLUDED_sql/selects/flag/flag.test.json diff --git a/backend/src/test/resources/tests/sql/selects/last/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/last/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/last/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/last/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/last/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/last/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/last/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/last/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/last/last.spec.json b/backend/src/test/resources/EXCLUDED_sql/selects/last/last.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/last/last.spec.json rename to backend/src/test/resources/EXCLUDED_sql/selects/last/last.test.json diff --git a/backend/src/test/resources/tests/sql/selects/random/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/random/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/random/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/random/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/random/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/random/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/random/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/random/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/random/random.spec.json b/backend/src/test/resources/EXCLUDED_sql/selects/random/random.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/random/random.spec.json rename to backend/src/test/resources/EXCLUDED_sql/selects/random/random.test.json diff --git a/backend/src/test/resources/tests/sql/selects/same_select_2_times/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/same_select_2_times/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/same_select_2_times/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/same_select_2_times/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/same_select_2_times/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/same_select_2_times/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/same_select_2_times/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/same_select_2_times/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/same_select_2_times/same_select.json b/backend/src/test/resources/EXCLUDED_sql/selects/same_select_2_times/same_select.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/same_select_2_times/same_select.json rename to backend/src/test/resources/EXCLUDED_sql/selects/same_select_2_times/same_select.test.json diff --git a/backend/src/test/resources/tests/sql/selects/sum/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/sum/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/sum/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/sum/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/sum/diffsum/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/sum/diffsum/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/sum/diffsum/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/sum/diffsum/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/sum/diffsum/diffsum.spec.json b/backend/src/test/resources/EXCLUDED_sql/selects/sum/diffsum/diffsum.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/sum/diffsum/diffsum.spec.json rename to backend/src/test/resources/EXCLUDED_sql/selects/sum/diffsum/diffsum.test.json diff --git a/backend/src/test/resources/tests/sql/selects/sum/diffsum/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/sum/diffsum/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/sum/diffsum/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/sum/diffsum/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/sum/distinct/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/sum/distinct/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/sum/distinct/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/sum/distinct/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/sum/distinct/distinct-sum.spec.json b/backend/src/test/resources/EXCLUDED_sql/selects/sum/distinct/distinct-sum.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/sum/distinct/distinct-sum.spec.json rename to backend/src/test/resources/EXCLUDED_sql/selects/sum/distinct/distinct-sum.test.json diff --git a/backend/src/test/resources/tests/sql/selects/sum/distinct/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/sum/distinct/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/sum/distinct/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/sum/distinct/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/sum/duration_sum/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/sum/duration_sum/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/sum/duration_sum/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/sum/duration_sum/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/sum/duration_sum/duration_sum.json b/backend/src/test/resources/EXCLUDED_sql/selects/sum/duration_sum/duration_sum.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/sum/duration_sum/duration_sum.json rename to backend/src/test/resources/EXCLUDED_sql/selects/sum/duration_sum/duration_sum.test.json diff --git a/backend/src/test/resources/tests/sql/selects/sum/duration_sum/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/sum/duration_sum/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/sum/duration_sum/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/sum/duration_sum/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/sum/event_duration_sum/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/sum/event_duration_sum/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/sum/event_duration_sum/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/sum/event_duration_sum/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/sum/event_duration_sum/duration_sum.json b/backend/src/test/resources/EXCLUDED_sql/selects/sum/event_duration_sum/duration_sum.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/sum/event_duration_sum/duration_sum.json rename to backend/src/test/resources/EXCLUDED_sql/selects/sum/event_duration_sum/duration_sum.test.json diff --git a/backend/src/test/resources/tests/sql/selects/sum/event_duration_sum/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/sum/event_duration_sum/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/sum/event_duration_sum/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/sum/event_duration_sum/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/sum/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/sum/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/sum/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/sum/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/sum/sum.json b/backend/src/test/resources/EXCLUDED_sql/selects/sum/sum.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/sum/sum.json rename to backend/src/test/resources/EXCLUDED_sql/selects/sum/sum.test.json diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/aggregation/block/and/content_1.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/block/and/content_1.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/aggregation/block/and/content_1.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/block/and/content_1.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/aggregation/block/and/content_2.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/block/and/content_2.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/aggregation/block/and/content_2.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/block/and/content_2.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/aggregation/block/and/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/block/and/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/aggregation/block/and/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/block/and/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/aggregation/block/and/none.spec.json b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/block/and/none.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/aggregation/block/and/none.spec.json rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/block/and/none.test.json diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/aggregation/block/not/content_1.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/block/not/content_1.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/aggregation/block/not/content_1.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/block/not/content_1.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/aggregation/block/not/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/block/not/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/aggregation/block/not/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/block/not/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/aggregation/block/not/negate.spec.json b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/block/not/negate.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/aggregation/block/not/negate.spec.json rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/block/not/negate.test.json diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/aggregation/intersect/content_1.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/intersect/content_1.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/aggregation/intersect/content_1.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/intersect/content_1.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/aggregation/intersect/content_2.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/intersect/content_2.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/aggregation/intersect/content_2.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/intersect/content_2.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/aggregation/intersect/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/intersect/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/aggregation/intersect/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/intersect/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/aggregation/intersect/intersect.spec.json b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/intersect/intersect.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/aggregation/intersect/intersect.spec.json rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/intersect/intersect.test.json diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/aggregation/merge/content_1.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/merge/content_1.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/aggregation/merge/content_1.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/merge/content_1.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/aggregation/merge/content_2.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/merge/content_2.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/aggregation/merge/content_2.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/merge/content_2.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/aggregation/merge/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/merge/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/aggregation/merge/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/merge/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/aggregation/merge/merge.spec.json b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/merge/merge.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/aggregation/merge/merge.spec.json rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/merge/merge.test.json diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/aggregation/negate/content_1.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/negate/content_1.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/aggregation/negate/content_1.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/negate/content_1.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/aggregation/negate/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/negate/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/aggregation/negate/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/negate/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/aggregation/negate/negate.spec.json b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/negate/negate.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/aggregation/negate/negate.spec.json rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/negate/negate.test.json diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/aggregation/no_validity_date/content_1.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/no_validity_date/content_1.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/aggregation/no_validity_date/content_1.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/no_validity_date/content_1.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/aggregation/no_validity_date/content_2.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/no_validity_date/content_2.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/aggregation/no_validity_date/content_2.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/no_validity_date/content_2.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/aggregation/no_validity_date/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/no_validity_date/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/aggregation/no_validity_date/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/no_validity_date/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/aggregation/no_validity_date/no_validity_date.spec.json b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/no_validity_date/no_validity_date.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/aggregation/no_validity_date/no_validity_date.spec.json rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/no_validity_date/no_validity_date.test.json diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/aggregation/only_1_date/content_1.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/only_1_date/content_1.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/aggregation/only_1_date/content_1.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/only_1_date/content_1.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/aggregation/only_1_date/content_2.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/only_1_date/content_2.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/aggregation/only_1_date/content_2.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/only_1_date/content_2.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/aggregation/only_1_date/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/only_1_date/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/aggregation/only_1_date/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/only_1_date/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/aggregation/only_1_date/only_1_date.spec.json b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/only_1_date/only_1_date.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/aggregation/only_1_date/only_1_date.spec.json rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/aggregation/only_1_date/only_1_date.test.json diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/default/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/default/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/default/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/default/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/default/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/default/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/default/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/default/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/default/validity_date_default.json b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/default/validity_date_default.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/default/validity_date_default.json rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/default/validity_date_default.test.json diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/event_date_union/EVENT_DATE_AGGREGATOR_NO_RESTRICTION.json b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/event_date_union/EVENT_DATE_AGGREGATOR_NO_RESTRICTION.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/event_date_union/EVENT_DATE_AGGREGATOR_NO_RESTRICTION.json rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/event_date_union/EVENT_DATE_AGGREGATOR_NO_RESTRICTION.test.json diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/event_date_union/EVENT_DATE_AGGREGATOR_RESTRICTION.json b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/event_date_union/EVENT_DATE_AGGREGATOR_RESTRICTION.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/event_date_union/EVENT_DATE_AGGREGATOR_RESTRICTION.json rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/event_date_union/EVENT_DATE_AGGREGATOR_RESTRICTION.test.json diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/event_date_union/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/event_date_union/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/event_date_union/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/event_date_union/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/event_date_union/expected_no_restriction.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/event_date_union/expected_no_restriction.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/event_date_union/expected_no_restriction.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/event_date_union/expected_no_restriction.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/event_date_union/expected_restriction.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/event_date_union/expected_restriction.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/event_date_union/expected_restriction.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/event_date_union/expected_restriction.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/excluded_from_time_aggregation/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/excluded_from_time_aggregation/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/excluded_from_time_aggregation/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/excluded_from_time_aggregation/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/excluded_from_time_aggregation/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/excluded_from_time_aggregation/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/excluded_from_time_aggregation/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/excluded_from_time_aggregation/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/excluded_from_time_aggregation/validity_date_excluded.json b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/excluded_from_time_aggregation/validity_date_excluded.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/excluded_from_time_aggregation/validity_date_excluded.json rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/excluded_from_time_aggregation/validity_date_excluded.test.json diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/multirange/content.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/multirange/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/multirange/content.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/multirange/content.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/multirange/expected.csv b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/multirange/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/multirange/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/multirange/expected.csv diff --git a/backend/src/test/resources/tests/sql/selects/validity_date/multirange/multi_range.spec.json b/backend/src/test/resources/EXCLUDED_sql/selects/validity_date/multirange/multi_range.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/selects/validity_date/multirange/multi_range.spec.json rename to backend/src/test/resources/EXCLUDED_sql/selects/validity_date/multirange/multi_range.test.json diff --git a/backend/src/test/resources/tests/sql/tree/nested/content.csv b/backend/src/test/resources/EXCLUDED_sql/tree/nested/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/tree/nested/content.csv rename to backend/src/test/resources/EXCLUDED_sql/tree/nested/content.csv diff --git a/backend/src/test/resources/tests/sql/tree/nested/expected.csv b/backend/src/test/resources/EXCLUDED_sql/tree/nested/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/tree/nested/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/tree/nested/expected.csv diff --git a/backend/src/test/resources/tests/sql/tree/nested/nested.spec.json b/backend/src/test/resources/EXCLUDED_sql/tree/nested/nested.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/tree/nested/nested.spec.json rename to backend/src/test/resources/EXCLUDED_sql/tree/nested/nested.test.json diff --git a/backend/src/test/resources/tests/sql/tree/prefix_range/expected.csv b/backend/src/test/resources/EXCLUDED_sql/tree/prefix_range/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/tree/prefix_range/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/tree/prefix_range/expected.csv diff --git a/backend/src/test/resources/tests/sql/tree/prefix_range/kh-content.csv b/backend/src/test/resources/EXCLUDED_sql/tree/prefix_range/kh-content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/tree/prefix_range/kh-content.csv rename to backend/src/test/resources/EXCLUDED_sql/tree/prefix_range/kh-content.csv diff --git a/backend/src/test/resources/tests/sql/tree/prefix_range/prefix_range.spec.json b/backend/src/test/resources/EXCLUDED_sql/tree/prefix_range/prefix_range.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/tree/prefix_range/prefix_range.spec.json rename to backend/src/test/resources/EXCLUDED_sql/tree/prefix_range/prefix_range.test.json diff --git a/backend/src/test/resources/tests/sql/tree/with_parent/content.csv b/backend/src/test/resources/EXCLUDED_sql/tree/with_parent/content.csv similarity index 100% rename from backend/src/test/resources/tests/sql/tree/with_parent/content.csv rename to backend/src/test/resources/EXCLUDED_sql/tree/with_parent/content.csv diff --git a/backend/src/test/resources/tests/sql/tree/with_parent/expected.csv b/backend/src/test/resources/EXCLUDED_sql/tree/with_parent/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/tree/with_parent/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/tree/with_parent/expected.csv diff --git a/backend/src/test/resources/tests/sql/tree/with_parent/with_parent.spec.json b/backend/src/test/resources/EXCLUDED_sql/tree/with_parent/with_parent.test.json similarity index 100% rename from backend/src/test/resources/tests/sql/tree/with_parent/with_parent.spec.json rename to backend/src/test/resources/EXCLUDED_sql/tree/with_parent/with_parent.test.json diff --git a/backend/src/test/resources/tests/sql/yes/cqyes.json b/backend/src/test/resources/EXCLUDED_sql/yes/cqyes.test.json similarity index 91% rename from backend/src/test/resources/tests/sql/yes/cqyes.json rename to backend/src/test/resources/EXCLUDED_sql/yes/cqyes.test.json index e5d28e42d0..213c64f0dc 100644 --- a/backend/src/test/resources/tests/sql/yes/cqyes.json +++ b/backend/src/test/resources/EXCLUDED_sql/yes/cqyes.test.json @@ -13,7 +13,7 @@ "content": { "tables": [ { - "csv": "tests/sql/yes/no-op.csv", + "csv": "tests/sql/yes/entities.csv", "name": "no-op", "primaryColumn": { "name": "pid", diff --git a/backend/src/test/resources/EXCLUDED_sql/yes/entities.csv b/backend/src/test/resources/EXCLUDED_sql/yes/entities.csv new file mode 100644 index 0000000000..0ddcb9f291 --- /dev/null +++ b/backend/src/test/resources/EXCLUDED_sql/yes/entities.csv @@ -0,0 +1,8 @@ +pid,datum +1, +2, +23, +3, +4, +5, +6, diff --git a/backend/src/test/resources/tests/sql/yes/expected.csv b/backend/src/test/resources/EXCLUDED_sql/yes/expected.csv similarity index 100% rename from backend/src/test/resources/tests/sql/yes/expected.csv rename to backend/src/test/resources/EXCLUDED_sql/yes/expected.csv diff --git a/backend/src/test/resources/shared/entities.csv b/backend/src/test/resources/shared/entities.csv index 514b00398a..f796a72611 100644 --- a/backend/src/test/resources/shared/entities.csv +++ b/backend/src/test/resources/shared/entities.csv @@ -1,8 +1,8 @@ -pid,datum -1,2012-01-01 -2,2013-11-10 -3,2013-11-10 -4,2013-11-10 -5,2013-11-10 -6,2013-11-10 -23,2014-01-01 +pid,empty +1, +2, +3, +4, +5, +6, +23, diff --git a/backend/src/test/resources/shared/entities.table.json b/backend/src/test/resources/shared/entities.table.json index c6a2561f58..8941d9bc95 100644 --- a/backend/src/test/resources/shared/entities.table.json +++ b/backend/src/test/resources/shared/entities.table.json @@ -7,8 +7,8 @@ }, "columns": [ { - "name": "datum", - "type": "DATE" + "name": "empty", + "type": "STRING" } ] } diff --git a/backend/src/test/resources/tests/aggregator/CONCEPT_COLUMN_SELECTS/CONCEPT_VALUES.test.json b/backend/src/test/resources/tests/aggregator/CONCEPT_COLUMN_SELECTS/CONCEPT_VALUES.test.json index c6f657ad22..77ac2578ba 100644 --- a/backend/src/test/resources/tests/aggregator/CONCEPT_COLUMN_SELECTS/CONCEPT_VALUES.test.json +++ b/backend/src/test/resources/tests/aggregator/CONCEPT_COLUMN_SELECTS/CONCEPT_VALUES.test.json @@ -1,6 +1,9 @@ { "type": "QUERY_TEST", "label": "CONCEPT_VALUES Test", + "sqlSpec": { + "isEnabled": false + }, "expectedCsv": "tests/aggregator/CONCEPT_COLUMN_SELECTS/expected_raw.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/aggregator/CONCEPT_COLUMN_SELECTS/CONCEPT_VALUES_RESOLVED.test.json b/backend/src/test/resources/tests/aggregator/CONCEPT_COLUMN_SELECTS/CONCEPT_VALUES_RESOLVED.test.json index a98482ec1c..26e835b5b9 100644 --- a/backend/src/test/resources/tests/aggregator/CONCEPT_COLUMN_SELECTS/CONCEPT_VALUES_RESOLVED.test.json +++ b/backend/src/test/resources/tests/aggregator/CONCEPT_COLUMN_SELECTS/CONCEPT_VALUES_RESOLVED.test.json @@ -1,6 +1,9 @@ { "type": "QUERY_TEST", "label": "CONCEPT_VALUES (Resolved) Test", + "sqlSpec": { + "isEnabled": false + }, "expectedCsv": "tests/aggregator/CONCEPT_COLUMN_SELECTS/expected_resolved.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/aggregator/COUNT_QUARTERS_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json b/backend/src/test/resources/tests/aggregator/COUNT_QUARTERS_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json index d0281c15a4..955fa02f2f 100644 --- a/backend/src/test/resources/tests/aggregator/COUNT_QUARTERS_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json +++ b/backend/src/test/resources/tests/aggregator/COUNT_QUARTERS_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "COUNT_QUARTERS_AGGREGATOR Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/aggregator/COUNT_QUARTERS_AGGREGATOR/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/aggregator/DATE_DISTANCE_AGGREGATOR/DATE_DISTANCE.test.json b/backend/src/test/resources/tests/aggregator/DATE_DISTANCE_AGGREGATOR/DATE_DISTANCE.test.json index 2255eac608..eb6d2ecd64 100644 --- a/backend/src/test/resources/tests/aggregator/DATE_DISTANCE_AGGREGATOR/DATE_DISTANCE.test.json +++ b/backend/src/test/resources/tests/aggregator/DATE_DISTANCE_AGGREGATOR/DATE_DISTANCE.test.json @@ -34,7 +34,8 @@ "table": "table", "validityDates": { "label": "indexdatum", - "column": "table.indexdatum" + "startColumn": "table.start", + "endColumn": "table.end" }, "selects": { "name": "select", @@ -56,8 +57,12 @@ }, "columns": [ { - "name": "indexdatum", - "type": "DATE_RANGE" + "name": "start", + "type": "DATE" + }, + { + "name": "end", + "type": "DATE" }, { "name": "datum", diff --git a/backend/src/test/resources/tests/aggregator/DATE_DISTANCE_AGGREGATOR/DATE_DISTANCE2.test.json b/backend/src/test/resources/tests/aggregator/DATE_DISTANCE_AGGREGATOR/DATE_DISTANCE2.test.json index 6ec9fd4f80..bf5c1064c3 100644 --- a/backend/src/test/resources/tests/aggregator/DATE_DISTANCE_AGGREGATOR/DATE_DISTANCE2.test.json +++ b/backend/src/test/resources/tests/aggregator/DATE_DISTANCE_AGGREGATOR/DATE_DISTANCE2.test.json @@ -34,7 +34,8 @@ "table": "table", "validityDates": { "label": "indexdatum", - "column": "table.indexdatum" + "startColumn": "table.start", + "endColumn": "table.end" }, "selects": { "name": "select", @@ -56,8 +57,12 @@ }, "columns": [ { - "name": "indexdatum", - "type": "DATE_RANGE" + "name": "start", + "type": "DATE" + }, + { + "name": "end", + "type": "DATE" }, { "name": "datum", diff --git a/backend/src/test/resources/tests/aggregator/DATE_DISTANCE_AGGREGATOR/content.csv b/backend/src/test/resources/tests/aggregator/DATE_DISTANCE_AGGREGATOR/content.csv index d0e88a7db7..57a385386d 100644 --- a/backend/src/test/resources/tests/aggregator/DATE_DISTANCE_AGGREGATOR/content.csv +++ b/backend/src/test/resources/tests/aggregator/DATE_DISTANCE_AGGREGATOR/content.csv @@ -1,11 +1,11 @@ -pid,indexdatum,datum -1,"2010-01-01/2010-03-31",2010-01-31 -2,"2010-01-01/2010-03-31",1998-01-01 -3,"2010-01-01/2010-03-31",1997-12-31 -4,"2010-01-01/2010-03-31", -5,"2010-01-01/2010-03-31",2011-01-01 -6,"2010-01-01/2010-03-31",1998-03-01 -7,"2010-01-01/2010-03-31",2010-01-31 -8,"2010-01-01/2010-03-31",1998-03-01 -9,"2010-01-01/2010-03-31",1998-04-01 -10,"2010-01-01/2010-03-31",2012-01-01 \ No newline at end of file +pid,start,end,datum +1,2010-01-01,2010-03-31,2010-01-31 +2,2010-01-01,2010-03-31,1998-01-01 +3,2010-01-01,2010-03-31,1997-12-31 +4,2010-01-01,2010-03-31, +5,2010-01-01,2010-03-31,2011-01-01 +6,2010-01-01,2010-03-31,1998-03-01 +7,2010-01-01,2010-03-31,2010-01-31 +8,2010-01-01,2010-03-31,1998-03-01 +9,2010-01-01,2010-03-31,1998-04-01 +10,2010-01-01,2010-03-31,2012-01-01 \ No newline at end of file diff --git a/backend/src/test/resources/tests/aggregator/DURATION_SUM_AGGREGATOR/DURATION_SUM.test.json b/backend/src/test/resources/tests/aggregator/DURATION_SUM_AGGREGATOR/DURATION_SUM.test.json index 4c3ef4ea25..3a54197372 100644 --- a/backend/src/test/resources/tests/aggregator/DURATION_SUM_AGGREGATOR/DURATION_SUM.test.json +++ b/backend/src/test/resources/tests/aggregator/DURATION_SUM_AGGREGATOR/DURATION_SUM.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "DURATION_SUM_AGGREGATOR Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/aggregator/DURATION_SUM_AGGREGATOR/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/aggregator/DURATION_SUM_DISTINCT_AGGREGATOR/DURATION_SUM.test.json b/backend/src/test/resources/tests/aggregator/DURATION_SUM_DISTINCT_AGGREGATOR/DURATION_SUM.test.json index 9cfb2d6fd7..51b3429c18 100644 --- a/backend/src/test/resources/tests/aggregator/DURATION_SUM_DISTINCT_AGGREGATOR/DURATION_SUM.test.json +++ b/backend/src/test/resources/tests/aggregator/DURATION_SUM_DISTINCT_AGGREGATOR/DURATION_SUM.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", - "label": "DURATION_SUM_AGGREGATOR Test", + "label": "DURATION_SUM (distinctBy)", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/aggregator/DURATION_SUM_DISTINCT_AGGREGATOR/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/aggregator/EVENT_DATE_AGGREGATOR/EVENT_DATE_AGGREGATOR_NO_RESTRICTION.test.json b/backend/src/test/resources/tests/aggregator/EVENT_DATE_AGGREGATOR/EVENT_DATE_AGGREGATOR_NO_RESTRICTION.test.json index d12d5cc0d5..692fcca436 100644 --- a/backend/src/test/resources/tests/aggregator/EVENT_DATE_AGGREGATOR/EVENT_DATE_AGGREGATOR_NO_RESTRICTION.test.json +++ b/backend/src/test/resources/tests/aggregator/EVENT_DATE_AGGREGATOR/EVENT_DATE_AGGREGATOR_NO_RESTRICTION.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "EVENT_DATE_AGGREGATOR_NO_RESTRICTION Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/aggregator/EVENT_DATE_AGGREGATOR/expected_no_restriction.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/aggregator/EVENT_DATE_AGGREGATOR/EVENT_DATE_AGGREGATOR_RESTRICTION.test.json b/backend/src/test/resources/tests/aggregator/EVENT_DATE_AGGREGATOR/EVENT_DATE_AGGREGATOR_RESTRICTION.test.json index 9924999ef5..e420c4fc6b 100644 --- a/backend/src/test/resources/tests/aggregator/EVENT_DATE_AGGREGATOR/EVENT_DATE_AGGREGATOR_RESTRICTION.test.json +++ b/backend/src/test/resources/tests/aggregator/EVENT_DATE_AGGREGATOR/EVENT_DATE_AGGREGATOR_RESTRICTION.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "EVENT_DATE_AGGREGATOR_RESTRICTION Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/aggregator/EVENT_DATE_AGGREGATOR/expected_restriction.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/aggregator/EXISTS_AGGREGATOR/NUMBER.test.json b/backend/src/test/resources/tests/aggregator/EXISTS_AGGREGATOR/NUMBER.test.json index be8fc8abba..85e69af173 100644 --- a/backend/src/test/resources/tests/aggregator/EXISTS_AGGREGATOR/NUMBER.test.json +++ b/backend/src/test/resources/tests/aggregator/EXISTS_AGGREGATOR/NUMBER.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "EXISTS_AGGREGATOR & NUMBER Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/aggregator/EXISTS_AGGREGATOR/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/aggregator/EXISTS_AGGREGATOR_AGGREGATED/AND.test.json b/backend/src/test/resources/tests/aggregator/EXISTS_AGGREGATOR_AGGREGATED/AND.test.json index e64e06c75d..f67cb03e5b 100644 --- a/backend/src/test/resources/tests/aggregator/EXISTS_AGGREGATOR_AGGREGATED/AND.test.json +++ b/backend/src/test/resources/tests/aggregator/EXISTS_AGGREGATOR_AGGREGATED/AND.test.json @@ -2,6 +2,9 @@ "type": "QUERY_TEST", "label": "EXISTS_AGGREGATOR & NUMBER Test", "expectedCsv": "tests/aggregator/EXISTS_AGGREGATOR_AGGREGATED/expected.csv", + "sqlSpec": { + "isEnabled": false + }, "query": { "type": "ARRAY_CONCEPT_QUERY", "dateAggregationMode": "MERGE", diff --git a/backend/src/test/resources/tests/aggregator/EXISTS_AGGREGATOR_OR/NUMBER.test.json b/backend/src/test/resources/tests/aggregator/EXISTS_AGGREGATOR_OR/NUMBER.test.json index 9dbabdbbb3..28c87d6bf5 100644 --- a/backend/src/test/resources/tests/aggregator/EXISTS_AGGREGATOR_OR/NUMBER.test.json +++ b/backend/src/test/resources/tests/aggregator/EXISTS_AGGREGATOR_OR/NUMBER.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "EXISTS_AGGREGATOR & NUMBER Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/aggregator/EXISTS_AGGREGATOR_OR/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/aggregator/FIRST_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json b/backend/src/test/resources/tests/aggregator/FIRST_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json index f62636d356..fba3354bf6 100644 --- a/backend/src/test/resources/tests/aggregator/FIRST_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json +++ b/backend/src/test/resources/tests/aggregator/FIRST_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "FIRST_AGGREGATOR Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/aggregator/FIRST_AGGREGATOR/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/aggregator/FIRST_AGGREGATOR/content.csv b/backend/src/test/resources/tests/aggregator/FIRST_AGGREGATOR/content.csv index 4ac80c5fe1..c1de39e465 100644 --- a/backend/src/test/resources/tests/aggregator/FIRST_AGGREGATOR/content.csv +++ b/backend/src/test/resources/tests/aggregator/FIRST_AGGREGATOR/content.csv @@ -1,9 +1,7 @@ pid,datum,value 1,2012-01-01,"f" 1,2012-01-02,"m" - 2,2010-07-15, - 3,2012-01-01, 3,2012-01-02,"f" 4,,"f" diff --git a/backend/src/test/resources/tests/aggregator/FLAGS_AGGREGATOR/FLAGS_AGGREGATOR.test.json b/backend/src/test/resources/tests/aggregator/FLAGS_AGGREGATOR/FLAGS_AGGREGATOR.test.json index 49db5e0887..02364f081b 100644 --- a/backend/src/test/resources/tests/aggregator/FLAGS_AGGREGATOR/FLAGS_AGGREGATOR.test.json +++ b/backend/src/test/resources/tests/aggregator/FLAGS_AGGREGATOR/FLAGS_AGGREGATOR.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "FLAGS_AGGREGATOR Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/aggregator/FLAGS_AGGREGATOR/expected.csv", "query": { "type": "CONCEPT_QUERY", @@ -25,35 +31,45 @@ "type": "TREE", "connectors": [ { - "name" : "connector", - "table" : "table", + "name": "connector", + "table": "table", "selects": { - "name" : "select", + "name": "select", "type": "FLAGS", "flags": { "A": "table.a", "B": "table.b", "C": "table.c" } - } + }, + "validityDates": [ + { + "name": "date", + "column": "table.date" + } + ] } ] } ], "content": { "tables": { - "name": "table", - "csv": "tests/aggregator/FLAGS_AGGREGATOR/content.csv", - "primaryColumn": { - "name": "id", - "type": "STRING" - }, - "columns": [ - { - "name": "a", - "type": "BOOLEAN" - }, - { + "name": "table", + "csv": "tests/aggregator/FLAGS_AGGREGATOR/content.csv", + "primaryColumn": { + "name": "id", + "type": "STRING" + }, + "columns": [ + { + "name": "date", + "type": "DATE" + }, + { + "name": "a", + "type": "BOOLEAN" + }, + { "name": "b", "type": "BOOLEAN" }, diff --git a/backend/src/test/resources/tests/aggregator/FLAGS_AGGREGATOR/content.csv b/backend/src/test/resources/tests/aggregator/FLAGS_AGGREGATOR/content.csv index cb29726bb7..2e911ef186 100644 --- a/backend/src/test/resources/tests/aggregator/FLAGS_AGGREGATOR/content.csv +++ b/backend/src/test/resources/tests/aggregator/FLAGS_AGGREGATOR/content.csv @@ -1,8 +1,8 @@ -id,a,b,c -1,J,N,N -2,N,J,N -3,N,N,J -4,1,1,0 -5,false,false,true -7,,,J -6,,, +id,date,a,b,c +1,2000-01-01,true,false,false +2,2000-01-01,false,true,false +3,2000-01-01,false,false,true +4,2000-01-01,true,true,false +5,2000-01-01,false,false,true +7,2000-01-01,,,true +6,2000-01-01,,, diff --git a/backend/src/test/resources/tests/aggregator/FLAGS_AGGREGATOR/expected.csv b/backend/src/test/resources/tests/aggregator/FLAGS_AGGREGATOR/expected.csv index 10c6e12893..283bbc422a 100644 --- a/backend/src/test/resources/tests/aggregator/FLAGS_AGGREGATOR/expected.csv +++ b/backend/src/test/resources/tests/aggregator/FLAGS_AGGREGATOR/expected.csv @@ -1,8 +1,8 @@ result,dates,concept select -1,{-∞/+∞},{A} -2,{-∞/+∞},{B} -3,{-∞/+∞},{C} -4,{-∞/+∞},"{A,B}" -5,{-∞/+∞},{C} -6,{-∞/+∞}, -7,{-∞/+∞},{C} \ No newline at end of file +1,{2000-01-01/2000-01-01},{A} +2,{2000-01-01/2000-01-01},{B} +3,{2000-01-01/2000-01-01},{C} +4,{2000-01-01/2000-01-01},"{A,B}" +5,{2000-01-01/2000-01-01},{C} +6,{2000-01-01/2000-01-01}, +7,{2000-01-01/2000-01-01},{C} \ No newline at end of file diff --git a/backend/src/test/resources/tests/aggregator/LAST_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json b/backend/src/test/resources/tests/aggregator/LAST_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json index 30d31ac028..c08a548044 100644 --- a/backend/src/test/resources/tests/aggregator/LAST_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json +++ b/backend/src/test/resources/tests/aggregator/LAST_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "LAST_AGGREGATOR Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/aggregator/LAST_AGGREGATOR/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/aggregator/MAPPED/DISTINCT/SIMPLE_VIRTUAL_CONCEPT_Query.test.json b/backend/src/test/resources/tests/aggregator/MAPPED/DISTINCT/SIMPLE_VIRTUAL_CONCEPT_Query.test.json index b1ad5d40c6..ecc5110997 100644 --- a/backend/src/test/resources/tests/aggregator/MAPPED/DISTINCT/SIMPLE_VIRTUAL_CONCEPT_Query.test.json +++ b/backend/src/test/resources/tests/aggregator/MAPPED/DISTINCT/SIMPLE_VIRTUAL_CONCEPT_Query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "DISTINCT_MAPPED_AGGREGATOR Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/aggregator/MAPPED/DISTINCT/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/aggregator/MAPPED/DISTINCT_MULTI/SIMPLE_VIRTUAL_CONCEPT_Query.test.json b/backend/src/test/resources/tests/aggregator/MAPPED/DISTINCT_MULTI/SIMPLE_VIRTUAL_CONCEPT_Query.test.json index 29667a4ef3..19bcea3b42 100644 --- a/backend/src/test/resources/tests/aggregator/MAPPED/DISTINCT_MULTI/SIMPLE_VIRTUAL_CONCEPT_Query.test.json +++ b/backend/src/test/resources/tests/aggregator/MAPPED/DISTINCT_MULTI/SIMPLE_VIRTUAL_CONCEPT_Query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "DISTINCT MULTI MAPPED AGGREGATOR Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/aggregator/MAPPED/DISTINCT_MULTI/expected.csv", "query": { "type": "CONCEPT_QUERY", @@ -24,7 +30,7 @@ "type": "CSV_MAP", "internalColumn": "internal", "externalTemplate": "{{external}}", - "allowMultiple" : true, + "allowMultiple": true, "csv": "classpath:/tests/aggregator/MAPPED/mapping.csv" }, "concepts": [ diff --git a/backend/src/test/resources/tests/aggregator/MAPPED/FIRST/SIMPLE_VIRTUAL_CONCEPT_Query.test.json b/backend/src/test/resources/tests/aggregator/MAPPED/FIRST/SIMPLE_VIRTUAL_CONCEPT_Query.test.json index 354bc8a395..86ed03ad78 100644 --- a/backend/src/test/resources/tests/aggregator/MAPPED/FIRST/SIMPLE_VIRTUAL_CONCEPT_Query.test.json +++ b/backend/src/test/resources/tests/aggregator/MAPPED/FIRST/SIMPLE_VIRTUAL_CONCEPT_Query.test.json @@ -1,73 +1,79 @@ { - "type": "QUERY_TEST", - "label": "FIRST_MAPPED_AGGREGATOR Test", - "expectedCsv": "tests/aggregator/MAPPED/FIRST/expected.csv", - "query": { - "type": "CONCEPT_QUERY", - "root": { - "ids": [ - "concept" - ], - "type": "CONCEPT", - "tables": [ - { - "id": "concept.connector", - "selects": [ - "concept.connector.select" - ] - } - ] + "type": "QUERY_TEST", + "label": "FIRST_MAPPED_AGGREGATOR Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, + "expectedCsv": "tests/aggregator/MAPPED/FIRST/expected.csv", + "query": { + "type": "CONCEPT_QUERY", + "root": { + "ids": [ + "concept" + ], + "type": "CONCEPT", + "tables": [ + { + "id": "concept.connector", + "selects": [ + "concept.connector.select" + ] } - }, - "internToExternMappings": { - "name": "test_map", - "type": "CSV_MAP", - "internalColumn": "internal", - "externalTemplate": "External: {{external}} {{external2}}", - "csv": "classpath:/tests/aggregator/MAPPED/mapping.csv" - }, - "concepts": [ + ] + } + }, + "internToExternMappings": { + "name": "test_map", + "type": "CSV_MAP", + "internalColumn": "internal", + "externalTemplate": "External: {{external}} {{external2}}", + "csv": "classpath:/tests/aggregator/MAPPED/mapping.csv" + }, + "concepts": [ + { + "label": "concept", + "type": "TREE", + "connectors": [ { - "label": "concept", - "type": "TREE", - "connectors": [ - { - "label": "connector", - "table": "table", - "validityDates": { - "label": "datum", - "column": "table.datum" - }, - "selects": { - "name": "select", - "type": "FIRST", - "column": "table.value", - "mapping": "test_map" - } - } - ] + "label": "connector", + "table": "table", + "validityDates": { + "label": "datum", + "column": "table.datum" + }, + "selects": { + "name": "select", + "type": "FIRST", + "column": "table.value", + "mapping": "test_map" + } } - ], - "content": { - "tables": [ - { - "csv": "tests/aggregator/MAPPED/content.csv", - "name": "table", - "primaryColumn": { - "name": "pid", - "type": "STRING" - }, - "columns": [ - { - "name": "datum", - "type": "DATE" - }, - { - "name": "value", - "type": "STRING" - } - ] - } - ] + ] } + ], + "content": { + "tables": [ + { + "csv": "tests/aggregator/MAPPED/content.csv", + "name": "table", + "primaryColumn": { + "name": "pid", + "type": "STRING" + }, + "columns": [ + { + "name": "datum", + "type": "DATE" + }, + { + "name": "value", + "type": "STRING" + } + ] + } + ] + } } diff --git a/backend/src/test/resources/tests/aggregator/MAPPED/FIRST_MULTI/SIMPLE_VIRTUAL_CONCEPT_Query.test.json b/backend/src/test/resources/tests/aggregator/MAPPED/FIRST_MULTI/SIMPLE_VIRTUAL_CONCEPT_Query.test.json index 424c9e855e..9ef8481673 100644 --- a/backend/src/test/resources/tests/aggregator/MAPPED/FIRST_MULTI/SIMPLE_VIRTUAL_CONCEPT_Query.test.json +++ b/backend/src/test/resources/tests/aggregator/MAPPED/FIRST_MULTI/SIMPLE_VIRTUAL_CONCEPT_Query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "FIRST_MULTI_MAPPED_AGGREGATOR Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/aggregator/MAPPED/FIRST_MULTI/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/aggregator/PREFIX_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json b/backend/src/test/resources/tests/aggregator/PREFIX_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json index 1b06a5c362..ae2eb30053 100644 --- a/backend/src/test/resources/tests/aggregator/PREFIX_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json +++ b/backend/src/test/resources/tests/aggregator/PREFIX_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json @@ -2,6 +2,9 @@ "type": "QUERY_TEST", "label": "PREFIX_AGGREGATOR Test", "expectedCsv": "tests/aggregator/PREFIX_AGGREGATOR/expected.csv", + "sqlSpec": { + "isEnabled": false + }, "query": { "type": "CONCEPT_QUERY", "root": { diff --git a/backend/src/test/resources/tests/aggregator/QUARTER_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json b/backend/src/test/resources/tests/aggregator/QUARTER_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json index 2219901b5e..e1b97554f2 100644 --- a/backend/src/test/resources/tests/aggregator/QUARTER_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json +++ b/backend/src/test/resources/tests/aggregator/QUARTER_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "QUARTER_AGGREGATOR", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/aggregator/QUARTER_AGGREGATOR/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/aggregator/RANDOM_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json b/backend/src/test/resources/tests/aggregator/RANDOM_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json index 8d0033ea59..f7472b1d89 100644 --- a/backend/src/test/resources/tests/aggregator/RANDOM_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json +++ b/backend/src/test/resources/tests/aggregator/RANDOM_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "RANDOM_AGGREGATOR Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/aggregator/RANDOM_AGGREGATOR/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/aggregator/SUBSTRING/DISTINCT/MAPPED.test.json b/backend/src/test/resources/tests/aggregator/SUBSTRING/DISTINCT/MAPPED.test.json index 292c79ceeb..2bc93f414f 100644 --- a/backend/src/test/resources/tests/aggregator/SUBSTRING/DISTINCT/MAPPED.test.json +++ b/backend/src/test/resources/tests/aggregator/SUBSTRING/DISTINCT/MAPPED.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "DISTINCT Substring Mapped", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/aggregator/SUBSTRING/DISTINCT/expected-mapped.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/aggregator/SUBSTRING/DISTINCT/SIMPLE.test.json b/backend/src/test/resources/tests/aggregator/SUBSTRING/DISTINCT/SIMPLE.test.json index 5fd2badbac..88a8bcf908 100644 --- a/backend/src/test/resources/tests/aggregator/SUBSTRING/DISTINCT/SIMPLE.test.json +++ b/backend/src/test/resources/tests/aggregator/SUBSTRING/DISTINCT/SIMPLE.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "DISTINCT Substring", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/aggregator/SUBSTRING/DISTINCT/expected-simple.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/aggregator/SUBSTRING/DISTINCT/expected-mapped.csv b/backend/src/test/resources/tests/aggregator/SUBSTRING/DISTINCT/expected-mapped.csv index aa0fbd878e..9716ddef9d 100644 --- a/backend/src/test/resources/tests/aggregator/SUBSTRING/DISTINCT/expected-mapped.csv +++ b/backend/src/test/resources/tests/aggregator/SUBSTRING/DISTINCT/expected-mapped.csv @@ -1,6 +1,6 @@ result,dates,concept select 1,{2012-01-01/2012-01-02},"{hello,t2}" 2,{2010-07-15/2010-07-15}, -3,{2012-01-01/2012-01-02},{} +3,{2012-01-01/2012-01-02}, 5,{2012-01-01/2012-01-01},{in} 6,{2012-01-01/2012-01-01},"{hello,t2}" \ No newline at end of file diff --git a/backend/src/test/resources/tests/aggregator/SUBSTRING/DISTINCT/expected-simple.csv b/backend/src/test/resources/tests/aggregator/SUBSTRING/DISTINCT/expected-simple.csv index b3a03376ed..e4f3864d9e 100644 --- a/backend/src/test/resources/tests/aggregator/SUBSTRING/DISTINCT/expected-simple.csv +++ b/backend/src/test/resources/tests/aggregator/SUBSTRING/DISTINCT/expected-simple.csv @@ -1,6 +1,6 @@ result,dates,concept select 1,{2012-01-01/2012-01-02},"{t1,t2}" 2,{2010-07-15/2010-07-15}, -3,{2012-01-01/2012-01-02},{} +3,{2012-01-01/2012-01-02}, 5,{2012-01-01/2012-01-01},{in} 6,{2012-01-01/2012-01-01},"{t1,t2}" \ No newline at end of file diff --git a/backend/src/test/resources/tests/aggregator/SUBSTRING/DISTINCT_MULTI/MAPPED.test.json b/backend/src/test/resources/tests/aggregator/SUBSTRING/DISTINCT_MULTI/MAPPED.test.json index 014f6bcbe4..e04a99cee2 100644 --- a/backend/src/test/resources/tests/aggregator/SUBSTRING/DISTINCT_MULTI/MAPPED.test.json +++ b/backend/src/test/resources/tests/aggregator/SUBSTRING/DISTINCT_MULTI/MAPPED.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "DISTINCT Substring MULTI MAPPED", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/aggregator/SUBSTRING/DISTINCT_MULTI/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/aggregator/SUBSTRING/DISTINCT_MULTI/expected.csv b/backend/src/test/resources/tests/aggregator/SUBSTRING/DISTINCT_MULTI/expected.csv index 8a11426720..23b2e9a8a6 100644 --- a/backend/src/test/resources/tests/aggregator/SUBSTRING/DISTINCT_MULTI/expected.csv +++ b/backend/src/test/resources/tests/aggregator/SUBSTRING/DISTINCT_MULTI/expected.csv @@ -1,6 +1,6 @@ result,dates,concept select 1,{2012-01-01/2012-01-02},"{goodbye,hello,t2}" 2,{2010-07-15/2010-07-15}, -3,{2012-01-01/2012-01-02},{} +3,{2012-01-01/2012-01-02}, 5,{2012-01-01/2012-01-01},{in} 6,{2012-01-01/2012-01-01},"{goodbye,hello,t2}" \ No newline at end of file diff --git a/backend/src/test/resources/tests/aggregator/SUBSTRING/FIRST/MAPPED.test.json b/backend/src/test/resources/tests/aggregator/SUBSTRING/FIRST/MAPPED.test.json index 9b900a2d87..bd867a63b0 100644 --- a/backend/src/test/resources/tests/aggregator/SUBSTRING/FIRST/MAPPED.test.json +++ b/backend/src/test/resources/tests/aggregator/SUBSTRING/FIRST/MAPPED.test.json @@ -1,77 +1,83 @@ { - "type": "QUERY_TEST", - "label": "FIRST Substring Mapped", - "expectedCsv": "tests/aggregator/SUBSTRING/FIRST/expected-mapped.csv", - "query": { - "type": "CONCEPT_QUERY", - "root": { - "ids": [ - "concept" - ], - "type": "CONCEPT", - "tables": [ - { - "id": "concept.connector", - "selects": [ - "concept.connector.select" - ] - } - ] - } - }, - "internToExternMappings": { - "name": "test_map", - "type": "CSV_MAP", - "internalColumn": "internal", - "externalTemplate": "External: {{external}} {{external2}}", - "csv": "classpath:/tests/aggregator/SUBSTRING/mapping.csv" - }, - "concepts": [ + "type": "QUERY_TEST", + "label": "FIRST Substring Mapped", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, + "expectedCsv": "tests/aggregator/SUBSTRING/FIRST/expected-mapped.csv", + "query": { + "type": "CONCEPT_QUERY", + "root": { + "ids": [ + "concept" + ], + "type": "CONCEPT", + "tables": [ { - "label": "concept", - "type": "TREE", - "connectors": [ - { - "label": "connector", - "table": "table", - "validityDates": { - "label": "datum", - "column": "table.datum" - }, - "selects": { - "name": "select", - "type": "FIRST", - "column": "table.value", - "mapping": "test_map", - "substringRange" : { - "min" : 2, - "max" : 4 - } - } - } - ] + "id": "concept.connector", + "selects": [ + "concept.connector.select" + ] } - ], - "content": { - "tables": [ - { - "csv": "tests/aggregator/SUBSTRING/content.csv", - "name": "table", - "primaryColumn": { - "name": "pid", - "type": "STRING" - }, - "columns": [ - { - "name": "datum", - "type": "DATE" - }, - { - "name": "value", - "type": "STRING" - } - ] + ] + } + }, + "internToExternMappings": { + "name": "test_map", + "type": "CSV_MAP", + "internalColumn": "internal", + "externalTemplate": "External: {{external}} {{external2}}", + "csv": "classpath:/tests/aggregator/SUBSTRING/mapping.csv" + }, + "concepts": [ + { + "label": "concept", + "type": "TREE", + "connectors": [ + { + "label": "connector", + "table": "table", + "validityDates": { + "label": "datum", + "column": "table.datum" + }, + "selects": { + "name": "select", + "type": "FIRST", + "column": "table.value", + "mapping": "test_map", + "substringRange": { + "min": 2, + "max": 4 } - ] + } + } + ] } + ], + "content": { + "tables": [ + { + "csv": "tests/aggregator/SUBSTRING/content.csv", + "name": "table", + "primaryColumn": { + "name": "pid", + "type": "STRING" + }, + "columns": [ + { + "name": "datum", + "type": "DATE" + }, + { + "name": "value", + "type": "STRING" + } + ] + } + ] + } } diff --git a/backend/src/test/resources/tests/aggregator/SUBSTRING/FIRST/SIMPLE.test.json b/backend/src/test/resources/tests/aggregator/SUBSTRING/FIRST/SIMPLE.test.json index 64fa58ac1e..a1f6e3452f 100644 --- a/backend/src/test/resources/tests/aggregator/SUBSTRING/FIRST/SIMPLE.test.json +++ b/backend/src/test/resources/tests/aggregator/SUBSTRING/FIRST/SIMPLE.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "FIRST Substring", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/aggregator/SUBSTRING/FIRST/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/aggregator/SUBSTRING/content.csv b/backend/src/test/resources/tests/aggregator/SUBSTRING/content.csv index bf132cc95e..d5cbb1b238 100644 --- a/backend/src/test/resources/tests/aggregator/SUBSTRING/content.csv +++ b/backend/src/test/resources/tests/aggregator/SUBSTRING/content.csv @@ -7,7 +7,7 @@ pid,datum,value 3,2012-01-01, 3,2012-01-02,t1 4,,int1 -5,2012-01-01," int2" -5,,"int1 " +5,2012-01-01,__int2 +5,,int1__ 6,2012-01-01,int2 6,2012-01-01,int1 \ No newline at end of file diff --git a/backend/src/test/resources/tests/aggregator/VALUES_AGGREGATOR/expected.csv b/backend/src/test/resources/tests/aggregator/VALUES_AGGREGATOR/expected.csv index 56e632dfff..93fed2ef79 100644 --- a/backend/src/test/resources/tests/aggregator/VALUES_AGGREGATOR/expected.csv +++ b/backend/src/test/resources/tests/aggregator/VALUES_AGGREGATOR/expected.csv @@ -3,4 +3,4 @@ result,dates,concept select 2,{2010-07-15/2010-07-15}, 3,{2012-01-01/2012-01-02},"{f,m}" 4,{2012-01-01/2012-01-04},"{f,m}" -5,{2012-01-01/2012-01-04},"{m ,f,f ,m}" \ No newline at end of file +5,{2012-01-01/2012-01-04},"{f,f ,m,m }" \ No newline at end of file diff --git a/backend/src/test/resources/tests/filter/COUNT/COUNT.test.json b/backend/src/test/resources/tests/filter/COUNT/COUNT.test.json index a5cb6bd44e..40eb722546 100644 --- a/backend/src/test/resources/tests/filter/COUNT/COUNT.test.json +++ b/backend/src/test/resources/tests/filter/COUNT/COUNT.test.json @@ -35,7 +35,7 @@ }, { "name": "datum", - "type": "DATE_RANGE" + "type": "DATE" } ] } diff --git a/backend/src/test/resources/tests/filter/COUNT/content_COUNT_Filter.csv b/backend/src/test/resources/tests/filter/COUNT/content_COUNT_Filter.csv index 6304a96f51..4868d571f8 100644 --- a/backend/src/test/resources/tests/filter/COUNT/content_COUNT_Filter.csv +++ b/backend/src/test/resources/tests/filter/COUNT/content_COUNT_Filter.csv @@ -1,37 +1,37 @@ pid,nr,datum -1,1,"2010-01-01/2010-01-31" -2,2,"2010-01-01/2010-01-31" -2,3,"2010-01-01/2010-01-31" -2,4,"2010-01-01/2010-01-31" -2,5,"2010-01-01/2010-01-31" -2,6,"2010-01-01/2010-01-31" -2,6,"2010-01-01/2010-01-31" -3,6,"2010-01-01/2010-01-31" -3,7,"2010-01-01/2010-01-31" -3,8,"2010-01-01/2010-01-31" -3,9,"2010-01-01/2010-01-31" -3,10,"2010-01-01/2010-01-31" -3,11,"2010-01-01/2010-01-31" -3,8,"2010-01-01/2010-01-31" -3,10,"2010-01-01/2010-01-31" -3,10,"2010-01-01/2010-01-31" -3,8,"2010-01-01/2010-01-31" -4,6,"2010-01-01/2010-01-31" -4,12,"2010-01-01/2010-01-31" -4,6,"2010-01-01/2010-01-31" -4,13,"2010-01-01/2010-01-31" -4,13,"2010-01-01/2010-01-31" -4,6,"2010-01-01/2010-01-31" -5,14,"2010-01-01/2010-01-31" -5,15,"2010-01-01/2010-01-31" -5,16,"2010-01-01/2010-01-31" -5,17,"2010-01-01/2010-01-31" -5,18,"2010-01-01/2010-01-31" -5,19,"2010-01-01/2010-01-31" -5,20,"2010-01-01/2010-01-31" -5,17,"2010-01-01/2010-01-31" -5,17,"2010-01-01/2010-01-31" -5,20,"2010-01-01/2010-01-31" -5,21,"2010-01-01/2010-01-31" -5,22,"2010-01-01/2010-01-31" -5,23,"2010-01-01/2010-01-31" \ No newline at end of file +1,1,"2010-01-01" +2,2,"2010-01-01" +2,3,"2010-01-01" +2,4,"2010-01-01" +2,5,"2010-01-01" +2,6,"2010-01-01" +2,6,"2010-01-01" +3,6,"2010-01-01" +3,7,"2010-01-01" +3,8,"2010-01-01" +3,9,"2010-01-01" +3,10,"2010-01-01" +3,11,"2010-01-01" +3,8,"2010-01-01" +3,10,"2010-01-01" +3,10,"2010-01-01" +3,8,"2010-01-01" +4,6,"2010-01-01" +4,12,"2010-01-01" +4,6,"2010-01-01" +4,13,"2010-01-01" +4,13,"2010-01-01" +4,6,"2010-01-01" +5,14,"2010-01-01" +5,15,"2010-01-01" +5,16,"2010-01-01" +5,17,"2010-01-01" +5,18,"2010-01-01" +5,19,"2010-01-01" +5,20,"2010-01-01" +5,17,"2010-01-01" +5,17,"2010-01-01" +5,20,"2010-01-01" +5,21,"2010-01-01" +5,22,"2010-01-01" +5,23,"2010-01-01" \ No newline at end of file diff --git a/backend/src/test/resources/tests/filter/COUNT/expected_COUNT_Filter.csv b/backend/src/test/resources/tests/filter/COUNT/expected_COUNT_Filter.csv index 944bad7c3b..5e8c473f54 100644 --- a/backend/src/test/resources/tests/filter/COUNT/expected_COUNT_Filter.csv +++ b/backend/src/test/resources/tests/filter/COUNT/expected_COUNT_Filter.csv @@ -1,3 +1,3 @@ result,dates -2,{2010-01-01/2010-01-31} -4,{2010-01-01/2010-01-31} \ No newline at end of file +2,{2010-01-01/2010-01-01} +4,{2010-01-01/2010-01-01} \ No newline at end of file diff --git a/backend/src/test/resources/tests/filter/COUNT_DISTINCT/COUNT.test.json b/backend/src/test/resources/tests/filter/COUNT_DISTINCT/COUNT.test.json index c94850b8ba..55bc08f2e9 100644 --- a/backend/src/test/resources/tests/filter/COUNT_DISTINCT/COUNT.test.json +++ b/backend/src/test/resources/tests/filter/COUNT_DISTINCT/COUNT.test.json @@ -16,7 +16,7 @@ }, { "name": "datum", - "type": "DATE_RANGE" + "type": "DATE" } ] } diff --git a/backend/src/test/resources/tests/filter/COUNT_DISTINCT/content_COUNT_Filter.csv b/backend/src/test/resources/tests/filter/COUNT_DISTINCT/content_COUNT_Filter.csv index 6304a96f51..4868d571f8 100644 --- a/backend/src/test/resources/tests/filter/COUNT_DISTINCT/content_COUNT_Filter.csv +++ b/backend/src/test/resources/tests/filter/COUNT_DISTINCT/content_COUNT_Filter.csv @@ -1,37 +1,37 @@ pid,nr,datum -1,1,"2010-01-01/2010-01-31" -2,2,"2010-01-01/2010-01-31" -2,3,"2010-01-01/2010-01-31" -2,4,"2010-01-01/2010-01-31" -2,5,"2010-01-01/2010-01-31" -2,6,"2010-01-01/2010-01-31" -2,6,"2010-01-01/2010-01-31" -3,6,"2010-01-01/2010-01-31" -3,7,"2010-01-01/2010-01-31" -3,8,"2010-01-01/2010-01-31" -3,9,"2010-01-01/2010-01-31" -3,10,"2010-01-01/2010-01-31" -3,11,"2010-01-01/2010-01-31" -3,8,"2010-01-01/2010-01-31" -3,10,"2010-01-01/2010-01-31" -3,10,"2010-01-01/2010-01-31" -3,8,"2010-01-01/2010-01-31" -4,6,"2010-01-01/2010-01-31" -4,12,"2010-01-01/2010-01-31" -4,6,"2010-01-01/2010-01-31" -4,13,"2010-01-01/2010-01-31" -4,13,"2010-01-01/2010-01-31" -4,6,"2010-01-01/2010-01-31" -5,14,"2010-01-01/2010-01-31" -5,15,"2010-01-01/2010-01-31" -5,16,"2010-01-01/2010-01-31" -5,17,"2010-01-01/2010-01-31" -5,18,"2010-01-01/2010-01-31" -5,19,"2010-01-01/2010-01-31" -5,20,"2010-01-01/2010-01-31" -5,17,"2010-01-01/2010-01-31" -5,17,"2010-01-01/2010-01-31" -5,20,"2010-01-01/2010-01-31" -5,21,"2010-01-01/2010-01-31" -5,22,"2010-01-01/2010-01-31" -5,23,"2010-01-01/2010-01-31" \ No newline at end of file +1,1,"2010-01-01" +2,2,"2010-01-01" +2,3,"2010-01-01" +2,4,"2010-01-01" +2,5,"2010-01-01" +2,6,"2010-01-01" +2,6,"2010-01-01" +3,6,"2010-01-01" +3,7,"2010-01-01" +3,8,"2010-01-01" +3,9,"2010-01-01" +3,10,"2010-01-01" +3,11,"2010-01-01" +3,8,"2010-01-01" +3,10,"2010-01-01" +3,10,"2010-01-01" +3,8,"2010-01-01" +4,6,"2010-01-01" +4,12,"2010-01-01" +4,6,"2010-01-01" +4,13,"2010-01-01" +4,13,"2010-01-01" +4,6,"2010-01-01" +5,14,"2010-01-01" +5,15,"2010-01-01" +5,16,"2010-01-01" +5,17,"2010-01-01" +5,18,"2010-01-01" +5,19,"2010-01-01" +5,20,"2010-01-01" +5,17,"2010-01-01" +5,17,"2010-01-01" +5,20,"2010-01-01" +5,21,"2010-01-01" +5,22,"2010-01-01" +5,23,"2010-01-01" \ No newline at end of file diff --git a/backend/src/test/resources/tests/filter/COUNT_DISTINCT/expected_COUNT_Filter.csv b/backend/src/test/resources/tests/filter/COUNT_DISTINCT/expected_COUNT_Filter.csv index fc0d69adc1..08cd9c91da 100644 --- a/backend/src/test/resources/tests/filter/COUNT_DISTINCT/expected_COUNT_Filter.csv +++ b/backend/src/test/resources/tests/filter/COUNT_DISTINCT/expected_COUNT_Filter.csv @@ -1,3 +1,3 @@ result,dates -2,{2010-01-01/2010-01-31} -3,{2010-01-01/2010-01-31} \ No newline at end of file +2,{2010-01-01/2010-01-01} +3,{2010-01-01/2010-01-01} \ No newline at end of file diff --git a/backend/src/test/resources/tests/filter/COUNT_DISTINCT_MULTI/COUNT.test.json b/backend/src/test/resources/tests/filter/COUNT_DISTINCT_MULTI/COUNT.test.json index bd87716806..581a0b2451 100644 --- a/backend/src/test/resources/tests/filter/COUNT_DISTINCT_MULTI/COUNT.test.json +++ b/backend/src/test/resources/tests/filter/COUNT_DISTINCT_MULTI/COUNT.test.json @@ -1,6 +1,12 @@ { "type": "FILTER_TEST", "label": "COUNT multi distinct Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/filter/COUNT_DISTINCT_MULTI/expected_COUNT_Filter.csv", "content": { "tables": { @@ -16,7 +22,7 @@ }, { "name": "datum", - "type": "DATE_RANGE" + "type": "DATE" }, { "name": "a", diff --git a/backend/src/test/resources/tests/filter/COUNT_DISTINCT_MULTI/content_COUNT_Filter.csv b/backend/src/test/resources/tests/filter/COUNT_DISTINCT_MULTI/content_COUNT_Filter.csv index 59733e4e20..96a9292824 100644 --- a/backend/src/test/resources/tests/filter/COUNT_DISTINCT_MULTI/content_COUNT_Filter.csv +++ b/backend/src/test/resources/tests/filter/COUNT_DISTINCT_MULTI/content_COUNT_Filter.csv @@ -1,33 +1,33 @@ pid,datum,nr,a,b -1,"2010-01-01/2010-01-31",1,"1","2" -2,"2010-01-01/2010-01-31",5,"1","2" -2,"2010-01-01/2010-01-31",2,"2","1" -2,"2010-01-01/2010-01-31",3,,"2" -2,"2010-01-01/2010-01-31",6,,"2" -2,"2010-01-01/2010-01-31",4,"1", -2,"2010-01-01/2010-01-31",6,, -3,"2010-01-01/2010-01-31",6,"1","2" -3,"2010-01-01/2010-01-31",7,"2","1" -3,"2010-01-01/2010-01-31",8,"3","2" -3,"2010-01-01/2010-01-31",9,"4","2" -3,"2010-01-01/2010-01-31",10,"4","2" -3,"2010-01-01/2010-01-31",11,"2","4" -4,"2010-01-01/2010-01-31",6,"1","2" -4,"2010-01-01/2010-01-31",12,"2","2" -4,"2010-01-01/2010-01-31",6,"1","2" -4,"2010-01-01/2010-01-31",13,"3","2" -4,"2010-01-01/2010-01-31",13,"3","2" -4,"2010-01-01/2010-01-31",6,"1","2" -5,"2010-01-01/2010-01-31",14,"2","2" -5,"2010-01-01/2010-01-31",15,"3","2" -5,"2010-01-01/2010-01-31",16,"4","2" -5,"2010-01-01/2010-01-31",17,"5","2" -5,"2010-01-01/2010-01-31",18,"6","2" -5,"2010-01-01/2010-01-31",19,"7","2" -5,"2010-01-01/2010-01-31",20,"8","2" -5,"2010-01-01/2010-01-31",17,"9","2" -5,"2010-01-01/2010-01-31",17,"10","2" -5,"2010-01-01/2010-01-31",20,"11","2" -5,"2010-01-01/2010-01-31",21,"12","2" -5,"2010-01-01/2010-01-31",22,"13","2" -5,"2010-01-01/2010-01-31",23,"14","2" +1,"2010-01-01",1,"1","2" +2,"2010-01-01",5,"1","2" +2,"2010-01-01",2,"2","1" +2,"2010-01-01",3,,"2" +2,"2010-01-01",6,,"2" +2,"2010-01-01",4,"1", +2,"2010-01-01",6,, +3,"2010-01-01",6,"1","2" +3,"2010-01-01",7,"2","1" +3,"2010-01-01",8,"3","2" +3,"2010-01-01",9,"4","2" +3,"2010-01-01",10,"4","2" +3,"2010-01-01",11,"2","4" +4,"2010-01-01",6,"1","2" +4,"2010-01-01",12,"2","2" +4,"2010-01-01",6,"1","2" +4,"2010-01-01",13,"3","2" +4,"2010-01-01",13,"3","2" +4,"2010-01-01",6,"1","2" +5,"2010-01-01",14,"2","2" +5,"2010-01-01",15,"3","2" +5,"2010-01-01",16,"4","2" +5,"2010-01-01",17,"5","2" +5,"2010-01-01",18,"6","2" +5,"2010-01-01",19,"7","2" +5,"2010-01-01",20,"8","2" +5,"2010-01-01",17,"9","2" +5,"2010-01-01",17,"10","2" +5,"2010-01-01",20,"11","2" +5,"2010-01-01",21,"12","2" +5,"2010-01-01",22,"13","2" +5,"2010-01-01",23,"14","2" diff --git a/backend/src/test/resources/tests/filter/COUNT_DISTINCT_MULTI/expected_COUNT_Filter.csv b/backend/src/test/resources/tests/filter/COUNT_DISTINCT_MULTI/expected_COUNT_Filter.csv index fc0d69adc1..08cd9c91da 100644 --- a/backend/src/test/resources/tests/filter/COUNT_DISTINCT_MULTI/expected_COUNT_Filter.csv +++ b/backend/src/test/resources/tests/filter/COUNT_DISTINCT_MULTI/expected_COUNT_Filter.csv @@ -1,3 +1,3 @@ result,dates -2,{2010-01-01/2010-01-31} -3,{2010-01-01/2010-01-31} \ No newline at end of file +2,{2010-01-01/2010-01-01} +3,{2010-01-01/2010-01-01} \ No newline at end of file diff --git a/backend/src/test/resources/tests/filter/COUNT_QUARTERS/COUNT_QUARTERS.test.json b/backend/src/test/resources/tests/filter/COUNT_QUARTERS/COUNT_QUARTERS.test.json index 53fba02e62..3a4589ec32 100644 --- a/backend/src/test/resources/tests/filter/COUNT_QUARTERS/COUNT_QUARTERS.test.json +++ b/backend/src/test/resources/tests/filter/COUNT_QUARTERS/COUNT_QUARTERS.test.json @@ -16,7 +16,7 @@ }, { "name": "datum", - "type": "DATE_RANGE" + "type": "DATE" } ] } diff --git a/backend/src/test/resources/tests/filter/COUNT_QUARTERS/content_COUNT_QUARTERS_Filter.csv b/backend/src/test/resources/tests/filter/COUNT_QUARTERS/content_COUNT_QUARTERS_Filter.csv index 79b572281a..8e362a7fff 100644 --- a/backend/src/test/resources/tests/filter/COUNT_QUARTERS/content_COUNT_QUARTERS_Filter.csv +++ b/backend/src/test/resources/tests/filter/COUNT_QUARTERS/content_COUNT_QUARTERS_Filter.csv @@ -1,39 +1,39 @@ pid,behandlungsdatum,datum -1,2015-03-16,"2015-01-01/2016-12-31" -1,2015-03-17,"2015-01-01/2016-12-31" -2,2015-03-31,"2015-01-01/2016-12-31" -2,2015-04-01,"2015-01-01/2016-12-31" -3,2015-02-01,"2015-01-01/2016-12-31" -3,2015-04-01,"2015-01-01/2016-12-31" -3,2015-07-01,"2015-01-01/2016-12-31" -3,2015-11-01,"2015-01-01/2016-12-31" -4,2015-03-31,"2015-01-01/2016-12-31" -4,2015-04-01,"2015-01-01/2016-12-31" -4,2015-07-01,"2015-01-01/2016-12-31" -5,2015-11-12,"2015-01-01/2016-12-31" -6,2015-03-31,"2015-01-01/2016-12-31" -6,2015-04-01,"2015-01-01/2016-12-31" -6,2015-04-02,"2015-01-01/2016-12-31" -7,2015-01-01,"2015-01-01/2016-12-31" -7,2015-02-01,"2015-01-01/2016-12-31" -7,2015-03-01,"2015-01-01/2016-12-31" -7,2015-04-01,"2015-01-01/2016-12-31" -8,2015-11-11,"2015-01-01/2016-12-31" -8,2015-11-12,"2015-01-01/2016-12-31" -8,2015-11-13,"2015-01-01/2016-12-31" -8,2015-11-14,"2015-01-01/2016-12-31" -9,2015-04-14,"2015-01-01/2016-12-31" -9,2015-11-12,"2015-01-01/2016-12-31" -9,2015-09-14,"2015-01-01/2016-12-31" -9,2016-04-14,"2015-01-01/2016-12-31" -9,2016-11-12,"2015-01-01/2016-12-31" -9,2016-09-14,"2015-01-01/2016-12-31" -10,2015-09-14,"2015-01-01/2016-12-31" -10,2016-09-14,"2015-01-01/2016-12-31" -11,2015-09-14,"2015-01-01/2016-12-31" -11,2016-09-14,"2015-01-01/2016-12-31" -11,2016-11-12,"2015-01-01/2016-12-31" -12,2015-09-14,"2015-01-01/2016-12-31" -12,2015-11-12,"2015-01-01/2016-12-31" -12,2016-09-14,"2015-01-01/2016-12-31" -12,2016-11-12,"2015-01-01/2016-12-31" \ No newline at end of file +1,2015-03-16,"2010-01-01" +1,2015-03-17,"2010-01-01" +2,2015-03-31,"2010-01-01" +2,2015-04-01,"2010-01-01" +3,2015-02-01,"2010-01-01" +3,2015-04-01,"2010-01-01" +3,2015-07-01,"2010-01-01" +3,2015-11-01,"2010-01-01" +4,2015-03-31,"2010-01-01" +4,2015-04-01,"2010-01-01" +4,2015-07-01,"2010-01-01" +5,2015-11-12,"2010-01-01" +6,2015-03-31,"2010-01-01" +6,2015-04-01,"2010-01-01" +6,2015-04-02,"2010-01-01" +7,2015-01-01,"2010-01-01" +7,2015-02-01,"2010-01-01" +7,2015-03-01,"2010-01-01" +7,2015-04-01,"2010-01-01" +8,2015-11-11,"2010-01-01" +8,2015-11-12,"2010-01-01" +8,2015-11-13,"2010-01-01" +8,2015-11-14,"2010-01-01" +9,2015-04-14,"2010-01-01" +9,2015-11-12,"2010-01-01" +9,2015-09-14,"2010-01-01" +9,2016-04-14,"2010-01-01" +9,2016-11-12,"2010-01-01" +9,2016-09-14,"2010-01-01" +10,2015-09-14,"2010-01-01" +10,2016-09-14,"2010-01-01" +11,2015-09-14,"2010-01-01" +11,2016-09-14,"2010-01-01" +11,2016-11-12,"2010-01-01" +12,2015-09-14,"2010-01-01" +12,2015-11-12,"2010-01-01" +12,2016-09-14,"2010-01-01" +12,2016-11-12,"2010-01-01" \ No newline at end of file diff --git a/backend/src/test/resources/tests/filter/COUNT_QUARTERS/expected_COUNT_QUARTERS_Filter.csv b/backend/src/test/resources/tests/filter/COUNT_QUARTERS/expected_COUNT_QUARTERS_Filter.csv index e681a27fe8..e0ac3c7e0b 100644 --- a/backend/src/test/resources/tests/filter/COUNT_QUARTERS/expected_COUNT_QUARTERS_Filter.csv +++ b/backend/src/test/resources/tests/filter/COUNT_QUARTERS/expected_COUNT_QUARTERS_Filter.csv @@ -1,7 +1,7 @@ result,dates -2,{2015-01-01/2016-12-31} -4,{2015-01-01/2016-12-31} -6,{2015-01-01/2016-12-31} -7,{2015-01-01/2016-12-31} -10,{2015-01-01/2016-12-31} -11,{2015-01-01/2016-12-31} \ No newline at end of file +2,{2010-01-01/2010-01-01} +4,{2010-01-01/2010-01-01} +6,{2010-01-01/2010-01-01} +7,{2010-01-01/2010-01-01} +10,{2010-01-01/2010-01-01} +11,{2010-01-01/2010-01-01} \ No newline at end of file diff --git a/backend/src/test/resources/tests/filter/COUNT_QUARTERS_RANGE/COUNT_QUARTERS.test.json b/backend/src/test/resources/tests/filter/COUNT_QUARTERS_RANGE/COUNT_QUARTERS.test.json index 1d1c43fb78..570455eaea 100644 --- a/backend/src/test/resources/tests/filter/COUNT_QUARTERS_RANGE/COUNT_QUARTERS.test.json +++ b/backend/src/test/resources/tests/filter/COUNT_QUARTERS_RANGE/COUNT_QUARTERS.test.json @@ -1,6 +1,12 @@ { "type": "FILTER_TEST", "label": "COUNT_QUARTERS Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/filter/COUNT_QUARTERS_RANGE/expected_COUNT_QUARTERS_Filter.csv", "content": { "tables": { diff --git a/backend/src/test/resources/tests/filter/COUNTfalse/COUNT.test.json b/backend/src/test/resources/tests/filter/COUNTfalse/COUNT.test.json index 5f3c186acf..764f9e34a4 100644 --- a/backend/src/test/resources/tests/filter/COUNTfalse/COUNT.test.json +++ b/backend/src/test/resources/tests/filter/COUNTfalse/COUNT.test.json @@ -1,6 +1,12 @@ { "type": "FILTER_TEST", "label": "COUNTfalse Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/filter/COUNTfalse/expected_COUNT_Filter.csv", "content": { "tables": { diff --git a/backend/src/test/resources/tests/filter/COUNTfalse/content_COUNT_Filter.csv b/backend/src/test/resources/tests/filter/COUNTfalse/content_COUNT_Filter.csv index 67aca7ec58..ae05b86346 100644 --- a/backend/src/test/resources/tests/filter/COUNTfalse/content_COUNT_Filter.csv +++ b/backend/src/test/resources/tests/filter/COUNTfalse/content_COUNT_Filter.csv @@ -1,37 +1,37 @@ pid,nr,datum -1,1,"2010-01-01/2010-01-31" -2,2,"2010-01-01/2010-01-31" -2,3,"2010-01-01/2010-01-31" -2,4,"2010-01-01/2010-01-31" -2,5,"2010-01-01/2010-01-31" -2,6,"2010-01-01/2010-01-31" -2,6,"2010-01-01/2010-01-31" -3,6,"2010-01-01/2010-01-31" -3,7,"2010-01-01/2010-01-31" -3,8,"2010-01-01/2010-01-31" -3,9,"2010-01-01/2010-01-31" -3,10,"2010-01-01/2010-01-31" -3,11,"2010-01-01/2010-01-31" -3,8,"2010-01-01/2010-01-31" -3,10,"2010-01-01/2010-01-31" -3,10,"2010-01-01/2010-01-31" -3,8,"2010-01-01/2010-01-31" -4,6,"2010-01-01/2010-01-31" -4,12,"2010-01-01/2010-01-31" -4,6,"2010-01-01/2010-01-31" -4,13,"2010-01-01/2010-01-31" -4,13,"2010-01-01/2010-01-31" -4,6,"2010-01-01/2010-01-31" -5,14,"2010-01-01/2010-01-31" -5,15,"2010-01-01/2010-01-31" -5,16,"2010-01-01/2010-01-31" -5,17,"2010-01-01/2010-01-31" -5,18,"2010-01-01/2010-01-31" -5,19,"2010-01-01/2010-01-31" -5,20,"2010-01-01/2010-01-31" -5,17,"2010-01-01/2010-01-31" -5,17,"2010-01-01/2010-01-31" -5,20,"2010-01-01/2010-01-31" -5,21,"2010-01-01/2010-01-31" -5,22,"2010-01-01/2010-01-31" -5,23,"2010-01-01/2010-01-31" +1,1,"2010-01-01" +2,2,"2010-01-01" +2,3,"2010-01-01" +2,4,"2010-01-01" +2,5,"2010-01-01" +2,6,"2010-01-01" +2,6,"2010-01-01" +3,6,"2010-01-01" +3,7,"2010-01-01" +3,8,"2010-01-01" +3,9,"2010-01-01" +3,10,"2010-01-01" +3,11,"2010-01-01" +3,8,"2010-01-01" +3,10,"2010-01-01" +3,10,"2010-01-01" +3,8,"2010-01-01" +4,6,"2010-01-01" +4,12,"2010-01-01" +4,6,"2010-01-01" +4,13,"2010-01-01" +4,13,"2010-01-01" +4,6,"2010-01-01" +5,14,"2010-01-01" +5,15,"2010-01-01" +5,16,"2010-01-01" +5,17,"2010-01-01" +5,18,"2010-01-01" +5,19,"2010-01-01" +5,20,"2010-01-01" +5,17,"2010-01-01" +5,17,"2010-01-01" +5,20,"2010-01-01" +5,21,"2010-01-01" +5,22,"2010-01-01" +5,23,"2010-01-01" diff --git a/backend/src/test/resources/tests/filter/COUNTfalse/expected_COUNT_Filter.csv b/backend/src/test/resources/tests/filter/COUNTfalse/expected_COUNT_Filter.csv index 944bad7c3b..5e8c473f54 100644 --- a/backend/src/test/resources/tests/filter/COUNTfalse/expected_COUNT_Filter.csv +++ b/backend/src/test/resources/tests/filter/COUNTfalse/expected_COUNT_Filter.csv @@ -1,3 +1,3 @@ result,dates -2,{2010-01-01/2010-01-31} -4,{2010-01-01/2010-01-31} \ No newline at end of file +2,{2010-01-01/2010-01-01} +4,{2010-01-01/2010-01-01} \ No newline at end of file diff --git a/backend/src/test/resources/tests/filter/DURATION_SUM/DURATION_SUM.test.json b/backend/src/test/resources/tests/filter/DURATION_SUM/DURATION_SUM.test.json index 10ee06a49e..ee863aef04 100644 --- a/backend/src/test/resources/tests/filter/DURATION_SUM/DURATION_SUM.test.json +++ b/backend/src/test/resources/tests/filter/DURATION_SUM/DURATION_SUM.test.json @@ -1,6 +1,12 @@ { "type": "FILTER_TEST", "label": "DURATION_SUM Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/filter/DURATION_SUM/expected_DURATION_SUM_Filter.csv", "content": { "tables": { diff --git a/backend/src/test/resources/tests/filter/DURATION_SUM_2/DURATION_SUM_2.test.json b/backend/src/test/resources/tests/filter/DURATION_SUM_2/DURATION_SUM_2.test.json index cd9bc3f9f6..ed0ad8188e 100644 --- a/backend/src/test/resources/tests/filter/DURATION_SUM_2/DURATION_SUM_2.test.json +++ b/backend/src/test/resources/tests/filter/DURATION_SUM_2/DURATION_SUM_2.test.json @@ -1,6 +1,12 @@ { "type": "FILTER_TEST", "label": "DURATION_SUM_2 Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/filter/DURATION_SUM_2/expected_DURATION_SUM_2_Filter.csv", "content": { "tables": { diff --git a/backend/src/test/resources/tests/filter/DURATION_SUM_DISTINCT_FILTER/DURATION_SUM.test.json b/backend/src/test/resources/tests/filter/DURATION_SUM_DISTINCT_FILTER/DURATION_SUM.test.json index b19e8b3a86..d969b24905 100644 --- a/backend/src/test/resources/tests/filter/DURATION_SUM_DISTINCT_FILTER/DURATION_SUM.test.json +++ b/backend/src/test/resources/tests/filter/DURATION_SUM_DISTINCT_FILTER/DURATION_SUM.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "DURATION_SUM_AGGREGATOR Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/filter/DURATION_SUM_DISTINCT_FILTER/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/filter/FLAGS_FILTER/FLAGS_FILTER.test.json b/backend/src/test/resources/tests/filter/FLAGS_FILTER/FLAGS_FILTER.test.json index 5101dd2810..84273b61c9 100644 --- a/backend/src/test/resources/tests/filter/FLAGS_FILTER/FLAGS_FILTER.test.json +++ b/backend/src/test/resources/tests/filter/FLAGS_FILTER/FLAGS_FILTER.test.json @@ -1,6 +1,12 @@ { "type": "FILTER_TEST", "label": "FLAGS FILTER Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/filter/FLAGS_FILTER/expected.csv", "content": { "tables": { @@ -10,6 +16,10 @@ "type": "STRING" }, "columns": [ + { + "name": "date", + "type": "DATE" + }, { "name": "a", "type": "BOOLEAN" @@ -33,7 +43,13 @@ "B": "table.b", "C": "table.c" } - } + }, + "validityDates": [ + { + "name": "date", + "column": "table.date" + } + ] }, "filterValue": { "type": "MULTI_SELECT", diff --git a/backend/src/test/resources/tests/filter/FLAGS_FILTER/content.csv b/backend/src/test/resources/tests/filter/FLAGS_FILTER/content.csv index 1ada2585f2..98537c4209 100644 --- a/backend/src/test/resources/tests/filter/FLAGS_FILTER/content.csv +++ b/backend/src/test/resources/tests/filter/FLAGS_FILTER/content.csv @@ -1,8 +1,8 @@ -id,a,b,c -1,J,N,N -2,N,J,N -3,N,N,J -4,1,1,0 -5,false,false,true -6,,, -7,,,J +id,date,a,b,c +1,2000-01-01,true,false,false +2,2000-01-01,false,true,false +3,2000-01-01,false,false,true +4,2000-01-01,true,true,false +5,2000-01-01,false,false,true +6,2000-01-01,,, +7,2000-01-01,,,true diff --git a/backend/src/test/resources/tests/filter/FLAGS_FILTER/expected.csv b/backend/src/test/resources/tests/filter/FLAGS_FILTER/expected.csv index 190464565d..cf1b7ce482 100644 --- a/backend/src/test/resources/tests/filter/FLAGS_FILTER/expected.csv +++ b/backend/src/test/resources/tests/filter/FLAGS_FILTER/expected.csv @@ -1,6 +1,6 @@ result,dates -2,{-∞/+∞} -3,{-∞/+∞} -4,{-∞/+∞} -5,{-∞/+∞} -7,{-∞/+∞} +2,{2000-01-01/2000-01-01} +3,{2000-01-01/2000-01-01} +4,{2000-01-01/2000-01-01} +5,{2000-01-01/2000-01-01} +7,{2000-01-01/2000-01-01} diff --git a/backend/src/test/resources/tests/filter/NUMBER_INTEGER2/NUMBER.test.json b/backend/src/test/resources/tests/filter/NUMBER_INTEGER2/NUMBER.test.json deleted file mode 100644 index 26d4cdd9f2..0000000000 --- a/backend/src/test/resources/tests/filter/NUMBER_INTEGER2/NUMBER.test.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "type": "FILTER_TEST", - "label": "NUMBER_INTEGER Test", - "expectedCsv": "tests/filter/NUMBER_INTEGER2/expected_NUMBER_Filter.csv", - "content": { - "tables": { - "csv": "tests/filter/NUMBER_INTEGER2/content_NUMBER_Filter.csv", - "primaryColumn": { - "name": "pid", - "type": "STRING" - }, - "columns": [ - { - "name": "nr", - "type": "INTEGER" - }, - { - "name": "datum", - "type": "DATE_RANGE" - } - ] - } - }, - "connector": { - "validityDates": { - "label": "Datum", - "column": "table.datum" - }, - "filters": { - "type": "NUMBER", - "column": "table.nr" - } - }, - "filterValue": { - "type": "INTEGER_RANGE", - "value": { - "min": 50, - "max": 50 - } - } -} diff --git a/backend/src/test/resources/tests/filter/NUMBER_INTEGER2/content_NUMBER_Filter.csv b/backend/src/test/resources/tests/filter/NUMBER_INTEGER2/content_NUMBER_Filter.csv deleted file mode 100644 index f5c480e52b..0000000000 --- a/backend/src/test/resources/tests/filter/NUMBER_INTEGER2/content_NUMBER_Filter.csv +++ /dev/null @@ -1,2 +0,0 @@ -pid,nr,datum -1,50,"2015-03-17/2015-12-31" \ No newline at end of file diff --git a/backend/src/test/resources/tests/filter/NUMBER_INTEGER2/expected_NUMBER_Filter.csv b/backend/src/test/resources/tests/filter/NUMBER_INTEGER2/expected_NUMBER_Filter.csv deleted file mode 100644 index 5305f53f05..0000000000 --- a/backend/src/test/resources/tests/filter/NUMBER_INTEGER2/expected_NUMBER_Filter.csv +++ /dev/null @@ -1,2 +0,0 @@ -result,dates -1,{2015-03-17/2015-12-31} \ No newline at end of file diff --git a/backend/src/test/resources/tests/filter/NUMBER_REAL_MISSING/NUMBER.test.json b/backend/src/test/resources/tests/filter/NUMBER_REAL_MISSING/NUMBER.test.json index 742a097dd2..7e9d13967a 100644 --- a/backend/src/test/resources/tests/filter/NUMBER_REAL_MISSING/NUMBER.test.json +++ b/backend/src/test/resources/tests/filter/NUMBER_REAL_MISSING/NUMBER.test.json @@ -16,7 +16,7 @@ }, { "name": "datum", - "type": "DATE_RANGE" + "type": "DATE" } ] } diff --git a/backend/src/test/resources/tests/filter/NUMBER_REAL_MISSING/content_NUMBER_Filter.csv b/backend/src/test/resources/tests/filter/NUMBER_REAL_MISSING/content_NUMBER_Filter.csv index a6955866af..764a23a928 100644 --- a/backend/src/test/resources/tests/filter/NUMBER_REAL_MISSING/content_NUMBER_Filter.csv +++ b/backend/src/test/resources/tests/filter/NUMBER_REAL_MISSING/content_NUMBER_Filter.csv @@ -1,3 +1,3 @@ pid,nr,datum -1,0,"2015-03-17/2015-03-31" -2,,"2017-05-06/2017-05-15" \ No newline at end of file +1,0,"2010-01-01" +2,,"2010-01-01" \ No newline at end of file diff --git a/backend/src/test/resources/tests/filter/NUMBER_REAL_MISSING/expected_NUMBER_Filter.csv b/backend/src/test/resources/tests/filter/NUMBER_REAL_MISSING/expected_NUMBER_Filter.csv index 3799e57909..6aff01c4d8 100644 --- a/backend/src/test/resources/tests/filter/NUMBER_REAL_MISSING/expected_NUMBER_Filter.csv +++ b/backend/src/test/resources/tests/filter/NUMBER_REAL_MISSING/expected_NUMBER_Filter.csv @@ -1,2 +1,2 @@ result,dates -1,{2015-03-17/2015-03-31} \ No newline at end of file +1,{2010-01-01/2010-01-01} \ No newline at end of file diff --git a/backend/src/test/resources/tests/filter/PREFIX/PREFIX.test.json b/backend/src/test/resources/tests/filter/PREFIX/PREFIX.test.json index 5967186ce5..e57bf6aa57 100644 --- a/backend/src/test/resources/tests/filter/PREFIX/PREFIX.test.json +++ b/backend/src/test/resources/tests/filter/PREFIX/PREFIX.test.json @@ -1,5 +1,8 @@ { "type": "FILTER_TEST", + "sqlSpec": { + "isEnabled": false + }, "label": "Prefix Test", "expectedCsv": "tests/filter/PREFIX/expected_SELECT_Filter.csv", "content": { diff --git a/backend/src/test/resources/tests/filter/QUARTERS_IN_YEAR/QUARTERS_IN_YEAR.test.json b/backend/src/test/resources/tests/filter/QUARTERS_IN_YEAR/QUARTERS_IN_YEAR.test.json index b3428e47d7..a700dc7b69 100644 --- a/backend/src/test/resources/tests/filter/QUARTERS_IN_YEAR/QUARTERS_IN_YEAR.test.json +++ b/backend/src/test/resources/tests/filter/QUARTERS_IN_YEAR/QUARTERS_IN_YEAR.test.json @@ -1,6 +1,11 @@ { "type": "FILTER_TEST", "label": "QUARTERS_IN_YEAR Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + ] + }, "expectedCsv": "tests/filter/QUARTERS_IN_YEAR/expected_QUARTERS_IN_YEAR_Filter.csv", "content": { "tables": { diff --git a/backend/src/test/resources/tests/filter/QUARTERS_IN_YEAR/content_QUARTERS_IN_YEAR_Filter.csv b/backend/src/test/resources/tests/filter/QUARTERS_IN_YEAR/content_QUARTERS_IN_YEAR_Filter.csv index 7689c1449c..2d4be2bb41 100644 --- a/backend/src/test/resources/tests/filter/QUARTERS_IN_YEAR/content_QUARTERS_IN_YEAR_Filter.csv +++ b/backend/src/test/resources/tests/filter/QUARTERS_IN_YEAR/content_QUARTERS_IN_YEAR_Filter.csv @@ -1,50 +1,50 @@ pid,behandlungsdatum,datum -1,2015-03-16,"2015-01-01/2015-12-31" -1,2015-03-17,"2015-01-01/2015-12-31" - -2,2015-03-31,"2015-01-01/2015-12-31" -2,2015-04-01,"2015-01-01/2015-12-31" - -3,2015-02-01,"2015-01-01/2015-12-31" -3,2015-04-01,"2015-01-01/2015-12-31" -3,2015-07-01,"2015-01-01/2015-12-31" -3,2015-11-01,"2015-01-01/2015-12-31" - -4,2015-03-31,"2015-01-01/2015-12-31" -4,2015-04-01,"2015-01-01/2015-12-31" -4,2015-07-01,"2015-01-01/2015-12-31" - -5,2015-11-12,"2015-01-01/2015-12-31" - -6,2015-03-31,"2015-01-01/2015-12-31" -6,2015-04-01,"2015-01-01/2015-12-31" -6,2015-04-02,"2015-01-01/2015-12-31" - -7,2015-01-01,"2015-01-01/2015-12-31" -7,2015-02-01,"2015-01-01/2015-12-31" -7,2015-03-01,"2015-01-01/2015-12-31" -7,2015-04-01,"2015-01-01/2015-12-31" - -8,2015-11-11,"2015-01-01/2015-12-31" -8,2015-11-12,"2015-01-01/2015-12-31" -8,2015-11-13,"2015-01-01/2015-12-31" -8,2015-11-14,"2015-01-01/2015-12-31" - -9,2015-04-14,"2015-01-01/2015-12-31" -9,2015-11-12,"2015-01-01/2015-12-31" -9,2015-09-14,"2015-01-01/2015-12-31" -9,2016-04-14,"2016-01-01/2016-12-31" -9,2016-11-12,"2016-01-01/2016-12-31" -9,2016-09-14,"2016-01-01/2016-12-31" - -10,2015-09-14,"2015-01-01/2015-12-31" -10,2016-09-14,"2016-01-01/2016-12-31" - -11,2015-09-14,"2015-01-01/2015-12-31" -11,2016-09-14,"2016-01-01/2016-12-31" -11,2016-11-12,"2016-01-01/2016-12-31" - -12,2015-09-14,"2015-01-01/2015-12-31" -12,2015-11-12,"2015-01-01/2015-12-31" -12,2016-09-14,"2016-01-01/2016-12-31" -12,2016-11-12,"2016-01-01/2016-12-31" \ No newline at end of file +1,2015-03-16,"2010-01-01" +1,2015-03-17,"2010-01-01" + +2,2015-03-31,"2010-01-01" +2,2015-04-01,"2010-01-01" + +3,2015-02-01,"2010-01-01" +3,2015-04-01,"2010-01-01" +3,2015-07-01,"2010-01-01" +3,2015-11-01,"2010-01-01" + +4,2015-03-31,"2010-01-01" +4,2015-04-01,"2010-01-01" +4,2015-07-01,"2010-01-01" + +5,2015-11-12,"2010-01-01" + +6,2015-03-31,"2010-01-01" +6,2015-04-01,"2010-01-01" +6,2015-04-02,"2010-01-01" + +7,2015-01-01,"2010-01-01" +7,2015-02-01,"2010-01-01" +7,2015-03-01,"2010-01-01" +7,2015-04-01,"2010-01-01" + +8,2015-11-11,"2010-01-01" +8,2015-11-12,"2010-01-01" +8,2015-11-13,"2010-01-01" +8,2015-11-14,"2010-01-01" + +9,2015-04-14,"2010-01-01" +9,2015-11-12,"2010-01-01" +9,2015-09-14,"2010-01-01" +9,2016-04-14,"2010-01-02" +9,2016-11-12,"2010-01-02" +9,2016-09-14,"2010-01-02" + +10,2015-09-14,"2010-01-01" +10,2016-09-14,"2010-01-02" + +11,2015-09-14,"2010-01-01" +11,2016-09-14,"2010-01-02" +11,2016-11-12,"2010-01-02" + +12,2015-09-14,"2010-01-01" +12,2015-11-12,"2010-01-01" +12,2016-09-14,"2010-01-02" +12,2016-11-12,"2010-01-02" \ No newline at end of file diff --git a/backend/src/test/resources/tests/filter/QUARTERS_IN_YEAR/expected_QUARTERS_IN_YEAR_Filter.csv b/backend/src/test/resources/tests/filter/QUARTERS_IN_YEAR/expected_QUARTERS_IN_YEAR_Filter.csv index 8845f4e8f7..25976c8d13 100644 --- a/backend/src/test/resources/tests/filter/QUARTERS_IN_YEAR/expected_QUARTERS_IN_YEAR_Filter.csv +++ b/backend/src/test/resources/tests/filter/QUARTERS_IN_YEAR/expected_QUARTERS_IN_YEAR_Filter.csv @@ -1,8 +1,8 @@ result,dates -2,{2015-01-01/2015-12-31} -4,{2015-01-01/2015-12-31} -6,{2015-01-01/2015-12-31} -7,{2015-01-01/2015-12-31} -9,{2015-01-01/2016-12-31} -11,{2015-01-01/2016-12-31} -12,{2015-01-01/2016-12-31} \ No newline at end of file +2,{2010-01-01/2010-01-01} +4,{2010-01-01/2010-01-01} +6,{2010-01-01/2010-01-01} +7,{2010-01-01/2010-01-01} +9,{2010-01-01/2010-01-02} +11,{2010-01-01/2010-01-02} +12,{2010-01-01/2010-01-02} \ No newline at end of file diff --git a/backend/src/test/resources/tests/filter/SELECT_SUBSTRING/SELECT.test.json b/backend/src/test/resources/tests/filter/SELECT_SUBSTRING/SELECT.test.json index 0bd45dab76..7d01786f15 100644 --- a/backend/src/test/resources/tests/filter/SELECT_SUBSTRING/SELECT.test.json +++ b/backend/src/test/resources/tests/filter/SELECT_SUBSTRING/SELECT.test.json @@ -1,6 +1,11 @@ { "type": "FILTER_TEST", "label": "SELECT Substring", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + ] + }, "expectedCsv": "tests/filter/SELECT_SUBSTRING/expected.csv", "content": { "tables": diff --git a/backend/src/test/resources/tests/form/EXPORT_FORM/ABSOLUT/SECONDARY_ID/ABS_EXPORT_FORM_SECONDARY_ID.test.json b/backend/src/test/resources/tests/form/EXPORT_FORM/ABSOLUT/SECONDARY_ID/ABS_EXPORT_FORM_SECONDARY_ID.test.json index 33917a9312..139ba38898 100644 --- a/backend/src/test/resources/tests/form/EXPORT_FORM/ABSOLUT/SECONDARY_ID/ABS_EXPORT_FORM_SECONDARY_ID.test.json +++ b/backend/src/test/resources/tests/form/EXPORT_FORM/ABSOLUT/SECONDARY_ID/ABS_EXPORT_FORM_SECONDARY_ID.test.json @@ -1,79 +1,85 @@ { - "type": "FORM_TEST", - "label": "ABS-EXPORT-FORM SECONDARY_ID", - "expectedCsv": { - "results": "/tests/form/EXPORT_FORM/ABSOLUT/SECONDARY_ID/expected.csv" - }, - "form": { - "type": "EXPORT_FORM", - "queryGroup": "00000000-0000-0000-0000-000000000001", - "resolution": "QUARTERS", - "alsoCreateCoarserSubdivisions": true, - "features": [ - { - "ids": [ - "two_connector" - ], - "type": "CONCEPT", - "label": "explicitly set select", - "tables": [ - { - "id": "two_connector.table1", - "selects": "two_connector.table1.alter_select" - }, - { - "id": "two_connector.table2" - } - ] - } - ], - "timeMode": { - "value": "ABSOLUTE", - "dateRange": { - "min": "2012-01-16", - "max": "2012-12-17" - } - } - }, - "concepts": [ - "/tests/form/shared/two_connector.concept.json", - "/tests/form/shared/abc.concept.json" - ], - "content": { - "secondaryIds": [ - { - "name": "secondary" - }, - { - "name": "ignored" - } - ], - "tables": [ - "/tests/form/shared/vers_stamm.table.json", - "/tests/form/shared/abc.table.json" - ], - "previousQueries": [ - { - "type": "SECONDARY_ID_QUERY", - "secondaryId": "secondary", - "root": { - "type": "AND", - "children": [ - { - "type": "CONCEPT", - "excludeFromSecondaryId": false, - "ids": [ - "abc-concept.a" - ], - "tables": [ - { - "id": "abc-concept.connector" - } - ] - } - ] - } - } - ] - } + "type": "FORM_TEST", + "label": "ABS-EXPORT-FORM SECONDARY_ID", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, + "expectedCsv": { + "results": "/tests/form/EXPORT_FORM/ABSOLUT/SECONDARY_ID/expected.csv" + }, + "form": { + "type": "EXPORT_FORM", + "queryGroup": "00000000-0000-0000-0000-000000000001", + "resolution": "QUARTERS", + "alsoCreateCoarserSubdivisions": true, + "features": [ + { + "ids": [ + "two_connector" + ], + "type": "CONCEPT", + "label": "explicitly set select", + "tables": [ + { + "id": "two_connector.table1", + "selects": "two_connector.table1.alter_select" + }, + { + "id": "two_connector.table2" + } + ] + } + ], + "timeMode": { + "value": "ABSOLUTE", + "dateRange": { + "min": "2012-01-16", + "max": "2012-12-17" + } + } + }, + "concepts": [ + "/tests/form/shared/two_connector.concept.json", + "/tests/form/shared/abc.concept.json" + ], + "content": { + "secondaryIds": [ + { + "name": "secondary" + }, + { + "name": "ignored" + } + ], + "tables": [ + "/tests/form/shared/vers_stamm.table.json", + "/tests/form/shared/abc.table.json" + ], + "previousQueries": [ + { + "type": "SECONDARY_ID_QUERY", + "secondaryId": "secondary", + "root": { + "type": "AND", + "children": [ + { + "type": "CONCEPT", + "excludeFromSecondaryId": false, + "ids": [ + "abc-concept.a" + ], + "tables": [ + { + "id": "abc-concept.connector" + } + ] + } + ] + } + } + ] + } } \ No newline at end of file diff --git a/backend/src/test/resources/tests/form/EXPORT_FORM/ABSOLUT/SIMPLE/ABS_EXPORT_FORM.test.json b/backend/src/test/resources/tests/form/EXPORT_FORM/ABSOLUT/SIMPLE/ABS_EXPORT_FORM.test.json index b8af655753..35f6a220f2 100644 --- a/backend/src/test/resources/tests/form/EXPORT_FORM/ABSOLUT/SIMPLE/ABS_EXPORT_FORM.test.json +++ b/backend/src/test/resources/tests/form/EXPORT_FORM/ABSOLUT/SIMPLE/ABS_EXPORT_FORM.test.json @@ -1,45 +1,51 @@ { - "type": "FORM_TEST", - "label": "ABS-EXPORT-FORM ADD DEFAULT SELECT Test", - "expectedCsv": { - "results": "tests/form/EXPORT_FORM/ABSOLUT/SIMPLE/expected.csv" - }, - "form": { - "type": "EXPORT_FORM", - "queryGroup": "00000000-0000-0000-0000-000000000001", - "resolution": "QUARTERS", - "alsoCreateCoarserSubdivisions": true, - "features": [ - { - "ids": [ - "alter" - ], - "type": "CONCEPT", - "tables": [ - { - "id": "alter.alter", - "filters": [] - } - ] - } - ], - "timeMode": { - "value": "ABSOLUTE", - "dateRange": { - "min": "2012-01-16", - "max": "2012-12-17" - } - } - }, - "concepts": [ - "/tests/form/shared/alter.concept.json" - ], - "content": { - "tables": [ - "/tests/form/shared/vers_stamm.table.json" - ], - "previousQueryResults": [ - "tests/form/EXPORT_FORM/ABSOLUT/SIMPLE/query_results_1.csv" - ] - } + "type": "FORM_TEST", + "label": "ABS-EXPORT-FORM ADD DEFAULT SELECT Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, + "expectedCsv": { + "results": "tests/form/EXPORT_FORM/ABSOLUT/SIMPLE/expected.csv" + }, + "form": { + "type": "EXPORT_FORM", + "queryGroup": "00000000-0000-0000-0000-000000000001", + "resolution": "QUARTERS", + "alsoCreateCoarserSubdivisions": true, + "features": [ + { + "ids": [ + "alter" + ], + "type": "CONCEPT", + "tables": [ + { + "id": "alter.alter", + "filters": [] + } + ] + } + ], + "timeMode": { + "value": "ABSOLUTE", + "dateRange": { + "min": "2012-01-16", + "max": "2012-12-17" + } + } + }, + "concepts": [ + "/tests/form/shared/alter.concept.json" + ], + "content": { + "tables": [ + "/tests/form/shared/vers_stamm.table.json" + ], + "previousQueryResults": [ + "tests/form/EXPORT_FORM/ABSOLUT/SIMPLE/query_results_1.csv" + ] + } } \ No newline at end of file diff --git a/backend/src/test/resources/tests/form/EXPORT_FORM/ABSOLUT/SIMPLE/ABS_EXPORT_FORM_WITH_SELECT.test.json b/backend/src/test/resources/tests/form/EXPORT_FORM/ABSOLUT/SIMPLE/ABS_EXPORT_FORM_WITH_SELECT.test.json index 2e835c9445..0ccb786c60 100644 --- a/backend/src/test/resources/tests/form/EXPORT_FORM/ABSOLUT/SIMPLE/ABS_EXPORT_FORM_WITH_SELECT.test.json +++ b/backend/src/test/resources/tests/form/EXPORT_FORM/ABSOLUT/SIMPLE/ABS_EXPORT_FORM_WITH_SELECT.test.json @@ -1,50 +1,56 @@ { - "type": "FORM_TEST", - "label": "ABS-EXPORT-FORM WITH SELECT SET Test", - "expectedCsv": { - "results": "tests/form/EXPORT_FORM/ABSOLUT/SIMPLE/expected_with_select.csv" - }, - "form": { - "type": "EXPORT_FORM", - "queryGroup": "00000000-0000-0000-0000-000000000001", - "resolution": "QUARTERS", - "alsoCreateCoarserSubdivisions": true, - "features": [ - { - "ids": [ - "two_connector" - ], - "type": "CONCEPT", - "label": "explicitly set select", - "tables": [ - { - "id": "two_connector.table1", - "selects": "two_connector.table1.liste_geburtsdatum" - }, - { - "id": "two_connector.table2" - } - ] - } - ], - "timeMode": { - "value": "ABSOLUTE", - "dateRange": { - "min": "2012-01-16", - "max": "2012-12-17" - } - }, - "values": "Some arbitrary data that is frontend/user provided" - }, - "concepts": [ - "/tests/form/shared/two_connector.concept.json" - ], - "content": { - "tables": [ - "/tests/form/shared/vers_stamm.table.json" - ], - "previousQueryResults": [ - "tests/form/EXPORT_FORM/ABSOLUT/SIMPLE/query_results_1.csv" - ] - } + "type": "FORM_TEST", + "label": "ABS-EXPORT-FORM WITH SELECT SET Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, + "expectedCsv": { + "results": "tests/form/EXPORT_FORM/ABSOLUT/SIMPLE/expected_with_select.csv" + }, + "form": { + "type": "EXPORT_FORM", + "queryGroup": "00000000-0000-0000-0000-000000000001", + "resolution": "QUARTERS", + "alsoCreateCoarserSubdivisions": true, + "features": [ + { + "ids": [ + "two_connector" + ], + "type": "CONCEPT", + "label": "explicitly set select", + "tables": [ + { + "id": "two_connector.table1", + "selects": "two_connector.table1.liste_geburtsdatum" + }, + { + "id": "two_connector.table2" + } + ] + } + ], + "timeMode": { + "value": "ABSOLUTE", + "dateRange": { + "min": "2012-01-16", + "max": "2012-12-17" + } + }, + "values": "Some arbitrary data that is frontend/user provided" + }, + "concepts": [ + "/tests/form/shared/two_connector.concept.json" + ], + "content": { + "tables": [ + "/tests/form/shared/vers_stamm.table.json" + ], + "previousQueryResults": [ + "tests/form/EXPORT_FORM/ABSOLUT/SIMPLE/query_results_1.csv" + ] + } } \ No newline at end of file diff --git a/backend/src/test/resources/tests/form/EXPORT_FORM/ABSOLUT/SIMPLE_DATE_RESTRICTION/AND_DR.test.json b/backend/src/test/resources/tests/form/EXPORT_FORM/ABSOLUT/SIMPLE_DATE_RESTRICTION/AND_DR.test.json index 4af1fd8628..f87df4f78d 100644 --- a/backend/src/test/resources/tests/form/EXPORT_FORM/ABSOLUT/SIMPLE_DATE_RESTRICTION/AND_DR.test.json +++ b/backend/src/test/resources/tests/form/EXPORT_FORM/ABSOLUT/SIMPLE_DATE_RESTRICTION/AND_DR.test.json @@ -1,6 +1,12 @@ { "type": "FORM_TEST", "label": "ABS-EXPORT-FORM WITH NESTING AND -> DATE_RESTRICTION", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": { "results": "tests/form/EXPORT_FORM/ABSOLUT/SIMPLE_DATE_RESTRICTION/expected.csv" }, diff --git a/backend/src/test/resources/tests/form/EXPORT_FORM/ABSOLUT/SIMPLE_DATE_RESTRICTION/DR_AND.test.json b/backend/src/test/resources/tests/form/EXPORT_FORM/ABSOLUT/SIMPLE_DATE_RESTRICTION/DR_AND.test.json index 946fc9ae21..5b8985c467 100644 --- a/backend/src/test/resources/tests/form/EXPORT_FORM/ABSOLUT/SIMPLE_DATE_RESTRICTION/DR_AND.test.json +++ b/backend/src/test/resources/tests/form/EXPORT_FORM/ABSOLUT/SIMPLE_DATE_RESTRICTION/DR_AND.test.json @@ -1,6 +1,12 @@ { "type": "FORM_TEST", "label": "ABS-EXPORT-FORM WITH NESTING DATE_RESTRICTION -> AND", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": { "results": "tests/form/EXPORT_FORM/ABSOLUT/SIMPLE_DATE_RESTRICTION/expected.csv" }, diff --git a/backend/src/test/resources/tests/form/EXPORT_FORM/ENTITY_DATE/LOGICAL/ABS_EXPORT_FORM.test.json b/backend/src/test/resources/tests/form/EXPORT_FORM/ENTITY_DATE/LOGICAL/ABS_EXPORT_FORM.test.json index 521806b95b..727d90dcf4 100644 --- a/backend/src/test/resources/tests/form/EXPORT_FORM/ENTITY_DATE/LOGICAL/ABS_EXPORT_FORM.test.json +++ b/backend/src/test/resources/tests/form/EXPORT_FORM/ENTITY_DATE/LOGICAL/ABS_EXPORT_FORM.test.json @@ -1,6 +1,12 @@ { "type": "FORM_TEST", "label": "ADD DEFAULT SELECT Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": { "results": "tests/form/EXPORT_FORM/ENTITY_DATE/LOGICAL/expected.csv" }, diff --git a/backend/src/test/resources/tests/form/EXPORT_FORM/ENTITY_DATE/LOGICAL_WITH_EXCLUDE/ABS_EXPORT_FORM.test.json b/backend/src/test/resources/tests/form/EXPORT_FORM/ENTITY_DATE/LOGICAL_WITH_EXCLUDE/ABS_EXPORT_FORM.test.json index 3c82d33a12..65d3827d68 100644 --- a/backend/src/test/resources/tests/form/EXPORT_FORM/ENTITY_DATE/LOGICAL_WITH_EXCLUDE/ABS_EXPORT_FORM.test.json +++ b/backend/src/test/resources/tests/form/EXPORT_FORM/ENTITY_DATE/LOGICAL_WITH_EXCLUDE/ABS_EXPORT_FORM.test.json @@ -1,6 +1,12 @@ { "type": "FORM_TEST", "label": "ADD DEFAULT SELECT Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": { "results": "tests/form/EXPORT_FORM/ENTITY_DATE/LOGICAL_WITH_EXCLUDE/expected.csv" }, diff --git a/backend/src/test/resources/tests/form/EXPORT_FORM/ENTITY_DATE/SECONDARY_ID/SECONDARY_ID.test.json b/backend/src/test/resources/tests/form/EXPORT_FORM/ENTITY_DATE/SECONDARY_ID/SECONDARY_ID.test.json index 2d96b60d1b..300b7cf3aa 100644 --- a/backend/src/test/resources/tests/form/EXPORT_FORM/ENTITY_DATE/SECONDARY_ID/SECONDARY_ID.test.json +++ b/backend/src/test/resources/tests/form/EXPORT_FORM/ENTITY_DATE/SECONDARY_ID/SECONDARY_ID.test.json @@ -1,6 +1,12 @@ { "type": "FORM_TEST", "label": "ENTITY-DATE-EXPORT-FORM SECONDARY_ID", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": { "results": "/tests/form/EXPORT_FORM/ENTITY_DATE/SECONDARY_ID/expected.csv" }, diff --git a/backend/src/test/resources/tests/form/EXPORT_FORM/ENTITY_DATE/SIMPLE/ABS_EXPORT_FORM.test.json b/backend/src/test/resources/tests/form/EXPORT_FORM/ENTITY_DATE/SIMPLE/ABS_EXPORT_FORM.test.json index 048ceb8388..2fc9c4215b 100644 --- a/backend/src/test/resources/tests/form/EXPORT_FORM/ENTITY_DATE/SIMPLE/ABS_EXPORT_FORM.test.json +++ b/backend/src/test/resources/tests/form/EXPORT_FORM/ENTITY_DATE/SIMPLE/ABS_EXPORT_FORM.test.json @@ -1,6 +1,12 @@ { "type": "FORM_TEST", "label": "ADD DEFAULT SELECT Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": { "results": "tests/form/EXPORT_FORM/ENTITY_DATE/SIMPLE/expected.csv" }, diff --git a/backend/src/test/resources/tests/form/EXPORT_FORM/ENTITY_DATE/SIMPLE/ABS_EXPORT_FORM_WITH_SELECT.test.json b/backend/src/test/resources/tests/form/EXPORT_FORM/ENTITY_DATE/SIMPLE/ABS_EXPORT_FORM_WITH_SELECT.test.json index 8e6db7bf04..4eb14c811f 100644 --- a/backend/src/test/resources/tests/form/EXPORT_FORM/ENTITY_DATE/SIMPLE/ABS_EXPORT_FORM_WITH_SELECT.test.json +++ b/backend/src/test/resources/tests/form/EXPORT_FORM/ENTITY_DATE/SIMPLE/ABS_EXPORT_FORM_WITH_SELECT.test.json @@ -1,6 +1,12 @@ { "type": "FORM_TEST", "label": "WITH SELECT SET Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": { "results": "tests/form/EXPORT_FORM/ENTITY_DATE/SIMPLE/expected_with_select.csv" }, diff --git a/backend/src/test/resources/tests/form/EXPORT_FORM/RELATIVE/SECONDARY_ID/SECONDARY_ID.test.json b/backend/src/test/resources/tests/form/EXPORT_FORM/RELATIVE/SECONDARY_ID/SECONDARY_ID.test.json index a49c93b477..06385a0387 100644 --- a/backend/src/test/resources/tests/form/EXPORT_FORM/RELATIVE/SECONDARY_ID/SECONDARY_ID.test.json +++ b/backend/src/test/resources/tests/form/EXPORT_FORM/RELATIVE/SECONDARY_ID/SECONDARY_ID.test.json @@ -1,6 +1,12 @@ { "type": "FORM_TEST", "label": "REL-EXPORT-FORM SECONDARY_ID", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": { "results": "/tests/form/EXPORT_FORM/RELATIVE/SECONDARY_ID/expected.csv" }, diff --git a/backend/src/test/resources/tests/form/EXPORT_FORM/RELATIVE/SIMPLE/REL_EXPORT_FORM.test.json b/backend/src/test/resources/tests/form/EXPORT_FORM/RELATIVE/SIMPLE/REL_EXPORT_FORM.test.json index 705d6af418..b9cc2becb4 100644 --- a/backend/src/test/resources/tests/form/EXPORT_FORM/RELATIVE/SIMPLE/REL_EXPORT_FORM.test.json +++ b/backend/src/test/resources/tests/form/EXPORT_FORM/RELATIVE/SIMPLE/REL_EXPORT_FORM.test.json @@ -1,6 +1,12 @@ { "type": "FORM_TEST", "label": "REL-EXPORT-FORM Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": { "results": "tests/form/EXPORT_FORM/RELATIVE/SIMPLE/expected.csv" }, diff --git a/backend/src/test/resources/tests/form/FULL_EXPORT_FORM/FULL_EXPORT_FORM_SECONDARY_ID.test.json b/backend/src/test/resources/tests/form/FULL_EXPORT_FORM/FULL_EXPORT_FORM_SECONDARY_ID.test.json index 370b7b90c7..475001960d 100644 --- a/backend/src/test/resources/tests/form/FULL_EXPORT_FORM/FULL_EXPORT_FORM_SECONDARY_ID.test.json +++ b/backend/src/test/resources/tests/form/FULL_EXPORT_FORM/FULL_EXPORT_FORM_SECONDARY_ID.test.json @@ -1,6 +1,12 @@ { "type": "FORM_TEST", "label": "FULL_EXPORT_FORM", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": { "results": "/tests/form/FULL_EXPORT_FORM//expected.csv" }, diff --git a/backend/src/test/resources/tests/form/shared/vers_stamm.csv b/backend/src/test/resources/tests/form/shared/vers_stamm.csv index 6fbfaf7db5..ca5b4ef931 100644 --- a/backend/src/test/resources/tests/form/shared/vers_stamm.csv +++ b/backend/src/test/resources/tests/form/shared/vers_stamm.csv @@ -20,4 +20,4 @@ pid,date,date_start,date_end,geburtsdatum,geschlecht 19,2012-01-01/2012-12-31,2012-01-01,2012-12-31,1991-10-01,1 20,2012-01-01/2012-12-31,2012-01-01,2012-12-31,1987-01-01,2 21,2012-01-01/2012-12-31,2012-01-01,2012-12-31,1952-01-01,1 -22,2012-01-01/2012-10-01,2012-01-01,2012-10-01,1955-01-01,2 \ No newline at end of file +22,2012-01-01/2012-10-01,2012-01-01,2012-10-01,1955-01-01,2 diff --git a/backend/src/test/resources/tests/query/ARRAY_CONCEPT_QUERY/ARRAY_Query.test.json b/backend/src/test/resources/tests/query/ARRAY_CONCEPT_QUERY/ARRAY_Query.test.json index cd7d10e1ed..72c220d9a4 100644 --- a/backend/src/test/resources/tests/query/ARRAY_CONCEPT_QUERY/ARRAY_Query.test.json +++ b/backend/src/test/resources/tests/query/ARRAY_CONCEPT_QUERY/ARRAY_Query.test.json @@ -1,108 +1,111 @@ { - "type": "QUERY_TEST", - "label": "ARRAY_CONCEPT_QUERY Test", - "expectedCsv": "tests/query/ARRAY_CONCEPT_QUERY/expected.csv", - "query": { - "type": "ARRAY_CONCEPT_QUERY", - "dateAggregationMode": "MERGE", - "childQueries": [ + "type": "QUERY_TEST", + "label": "ARRAY_CONCEPT_QUERY Test", + "expectedCsv": "tests/query/ARRAY_CONCEPT_QUERY/expected.csv", + "sqlSpec": { + "isEnabled": false + }, + "query": { + "type": "ARRAY_CONCEPT_QUERY", + "dateAggregationMode": "MERGE", + "childQueries": [ + { + "type": "CONCEPT_QUERY", + "root": { + "ids": [ + "select" + ], + "type": "CONCEPT", + "label": "select", + "tables": [ { - "type": "CONCEPT_QUERY", - "root": { - "ids": [ - "select" - ], - "type": "CONCEPT", - "label": "select", - "tables": [ - { - "id": "select.connector", - "selects": [ - "select.connector.count_genders" - ] - } - ] - } - }, - { - "type": "CONCEPT_QUERY", - "root": { - "ids": [ - "select" - ], - "type": "CONCEPT", - "label": "select", - "tables": [ - { - "id": "select.connector", - "filters":[ - { - "type": "INTEGER_RANGE", - "filter":"select.connector.geschlecht", - "value": { - "min": 2, - "max": 6 - } - } - ], - "selects": [ - "select.connector.count_genders" - ] - } - ] - } + "id": "select.connector", + "selects": [ + "select.connector.count_genders" + ] } - ] - }, - "concepts": [ - { - "label": "select", - "type": "TREE", - "connectors": [ + ] + } + }, + { + "type": "CONCEPT_QUERY", + "root": { + "ids": [ + "select" + ], + "type": "CONCEPT", + "label": "select", + "tables": [ + { + "id": "select.connector", + "filters": [ { - "label": "connector", - "table": "table1", - "validityDates": { - "label": "datum", - "column": "table1.datum" - }, - "filters": { - "label": "geschlecht", - "type": "COUNT", - "column": "table1.geschlecht", - "distinct": false - }, - "selects": [ - { - "name": "count_genders", - "type": "COUNT", - "column": "table1.geschlecht" - } - ] + "type": "INTEGER_RANGE", + "filter": "select.connector.geschlecht", + "value": { + "min": 2, + "max": 6 + } } - ] + ], + "selects": [ + "select.connector.count_genders" + ] + } + ] } - ], - "content": { - "tables": [ + } + ] + }, + "concepts": [ + { + "label": "select", + "type": "TREE", + "connectors": [ + { + "label": "connector", + "table": "table1", + "validityDates": { + "label": "datum", + "column": "table1.datum" + }, + "filters": { + "label": "geschlecht", + "type": "COUNT", + "column": "table1.geschlecht", + "distinct": false + }, + "selects": [ { - "csv": "tests/query/ARRAY_CONCEPT_QUERY/content.csv", - "name": "table1", - "primaryColumn": { - "name": "pid", - "type": "STRING" - }, - "columns": [ - { - "name": "datum", - "type": "DATE" - }, - { - "name": "geschlecht", - "type": "STRING" - } - ] + "name": "count_genders", + "type": "COUNT", + "column": "table1.geschlecht" } - ] + ] + } + ] } + ], + "content": { + "tables": [ + { + "csv": "tests/query/ARRAY_CONCEPT_QUERY/content.csv", + "name": "table1", + "primaryColumn": { + "name": "pid", + "type": "STRING" + }, + "columns": [ + { + "name": "datum", + "type": "DATE" + }, + { + "name": "geschlecht", + "type": "STRING" + } + ] + } + ] + } } \ No newline at end of file diff --git a/backend/src/test/resources/tests/query/BIG_MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY/BIG_MULTI_SELECT_DATE_RESTRICTION_OR_CONCEPT_QUERY.test.json b/backend/src/test/resources/tests/query/BIG_MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY/BIG_MULTI_SELECT_DATE_RESTRICTION_OR_CONCEPT_QUERY.test.json index 7a0d71c533..86f38559ff 100644 --- a/backend/src/test/resources/tests/query/BIG_MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY/BIG_MULTI_SELECT_DATE_RESTRICTION_OR_CONCEPT_QUERY.test.json +++ b/backend/src/test/resources/tests/query/BIG_MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY/BIG_MULTI_SELECT_DATE_RESTRICTION_OR_CONCEPT_QUERY.test.json @@ -1,92 +1,81 @@ -{ - "type":"QUERY_TEST", - "label":"BIG_MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY Test", - "expectedCsv":"tests/query/BIG_MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY/expected.csv", - "query":{ - "type":"CONCEPT_QUERY", - "root":{ - "type":"NEGATION", - "child":{ - "type":"DATE_RESTRICTION", - "dateRange":{ - "min":"2012-01-01", - "max":"2012-11-11" - }, - "child": - { - "type":"OR", - "children": - [ - { - "ids":[ - "geschlecht_select" - ], - "type":"CONCEPT", - "label":"Geschlecht SELECT", - "tables":[ - { - "id":"geschlecht_select.geschlecht_connector", - "filters":[ - { - "filter":"geschlecht_select.geschlecht_connector.geschlecht", - "type":"BIG_MULTI_SELECT", - "value":[ - "f" - ] - } - ] - } - ] - } - ] - - } - - } - } - }, - "concepts":[ - { - "label":"geschlecht_select", - "type":"TREE", - "connectors":[ - { - "label":"geschlecht_connector", - "table":"table1", - "validityDates":{ - "label":"datum", - "column":"table1.datum" - }, - "filters":{ - "label":"geschlecht", - "description":"Geschlecht zur gegebenen Datumseinschränkung", - "column":"table1.geschlecht", - "type":"SELECT" - } +{ + "type": "QUERY_TEST", + "label": "BIG_MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY Test", + "expectedCsv": "tests/query/BIG_MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY/expected.csv", + "query": { + "type": "CONCEPT_QUERY", + "root": { + "type": "NEGATION", + "child": { + "type": "DATE_RESTRICTION", + "dateRange": { + "min": "2012-01-01", + "max": "2012-11-11" + }, + "child": { + "ids": [ + "geschlecht_select" + ], + "type": "CONCEPT", + "tables": [ + { + "id": "geschlecht_select.geschlecht_connector", + "filters": [ + { + "filter": "geschlecht_select.geschlecht_connector.geschlecht", + "type": "BIG_MULTI_SELECT", + "value": [ + "f" + ] + } + ] } - ] + ] + } } - ], - "content":{ - "tables":[ - { - "csv":"tests/query/BIG_MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY/content.csv", - "name":"table1", - "primaryColumn":{ - "name":"pid", - "type":"STRING" - }, - "columns":[ - { - "name":"datum", - "type":"DATE" - }, - { - "name":"geschlecht", - "type":"STRING" - } - ] - } + } + }, + "concepts": [ + { + "label": "geschlecht_select", + "type": "TREE", + "connectors": [ + { + "label": "geschlecht_connector", + "table": "table1", + "validityDates": { + "label": "datum", + "column": "table1.datum" + }, + "filters": { + "label": "geschlecht", + "column": "table1.geschlecht", + "type": "SELECT" + } + } ] - } + } + ], + "content": { + "tables": [ + { + "csv": "tests/query/BIG_MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY/content.csv", + "name": "table1", + "primaryColumn": { + "name": "pid", + "type": "STRING" + }, + "columns": [ + { + "name": "datum", + "type": "DATE" + }, + { + "name": "geschlecht", + "type": "STRING" + } + ] + } + ] + } } diff --git a/backend/src/test/resources/tests/query/COMPOUND_DATERANGE_TEST/SIMPLE_TREECONCEPT_Query.test.json b/backend/src/test/resources/tests/query/COMPOUND_DATERANGE_TEST/SIMPLE_TREECONCEPT_Query.test.json index 1b2cf8ed1e..3d100c2a94 100644 --- a/backend/src/test/resources/tests/query/COMPOUND_DATERANGE_TEST/SIMPLE_TREECONCEPT_Query.test.json +++ b/backend/src/test/resources/tests/query/COMPOUND_DATERANGE_TEST/SIMPLE_TREECONCEPT_Query.test.json @@ -1,5 +1,8 @@ { "type": "QUERY_TEST", + "sqlSpec": { + "isEnabled": false + }, "label": "COMPOUND_DATERANGE Test", "expectedCsv": "tests/query/COMPOUND_DATERANGE_TEST/expected.csv", "query": { @@ -56,11 +59,11 @@ "name": "behandlung", "type": "DATE_RANGE", "outputDescription": { - "allowOpen": true, - "startColumn": "behandlung_start", - "endColumn": "behandlung_ende", - "name": "behandlung", - "operation": "COMPOUND_DATE_RANGE" + "allowOpen": true, + "startColumn": "behandlung_start", + "endColumn": "behandlung_ende", + "name": "behandlung", + "operation": "COMPOUND_DATE_RANGE" } } ] diff --git a/backend/src/test/resources/tests/query/CONCEPT_DATE_RESTRICTION_OPEN/CONCEPT_RESTRICTION.test.json b/backend/src/test/resources/tests/query/CONCEPT_DATE_RESTRICTION_OPEN/CONCEPT_RESTRICTION.test.json index 3040949209..77822fc2eb 100644 --- a/backend/src/test/resources/tests/query/CONCEPT_DATE_RESTRICTION_OPEN/CONCEPT_RESTRICTION.test.json +++ b/backend/src/test/resources/tests/query/CONCEPT_DATE_RESTRICTION_OPEN/CONCEPT_RESTRICTION.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "CONCEPT_RESTRICTION Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/CONCEPT_DATE_RESTRICTION_OPEN/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/CONCEPT_DATE_RESTRICTION_WITHOUT_VALIDITYDATE/CONCEPT_DATE_RESTRICTION_WITHOUT_VALIDITYDATE.test.json b/backend/src/test/resources/tests/query/CONCEPT_DATE_RESTRICTION_WITHOUT_VALIDITYDATE/CONCEPT_DATE_RESTRICTION_WITHOUT_VALIDITYDATE.test.json index 42e0e2dfff..c2fb4becfe 100644 --- a/backend/src/test/resources/tests/query/CONCEPT_DATE_RESTRICTION_WITHOUT_VALIDITYDATE/CONCEPT_DATE_RESTRICTION_WITHOUT_VALIDITYDATE.test.json +++ b/backend/src/test/resources/tests/query/CONCEPT_DATE_RESTRICTION_WITHOUT_VALIDITYDATE/CONCEPT_DATE_RESTRICTION_WITHOUT_VALIDITYDATE.test.json @@ -1,88 +1,94 @@ { - "type": "QUERY_TEST", - "label": "CONCEPT_DATE_RESTRICTION_WITHOUT_VALIDITYDATE Test", - "expectedCsv": "tests/query/CONCEPT_DATE_RESTRICTION_WITHOUT_VALIDITYDATE/expected.csv", - "query": { - "type": "CONCEPT_QUERY", - "root": { - "type": "DATE_RESTRICTION", - "dateRange": { - "min": "2017-01-01", - "max": "2017-12-31" - }, - "child": { - "type": "CONCEPT", - "ids": [ - "test_tree.test_child1" - ], - "tables": [ - { - "id": "test_tree.test_column", - "filters": [], - "selects": [ - "test_tree.test_column.test_select" - ] - } - ] - } - } - }, - "concepts": [ - { - "label": "test_tree", - "type": "TREE", - "connectors": { - "label": "tree_label", - "name": "test_column", - "column": "test_table.test_column", - "selects": [ - { - "column": "test_table.test_column", - "default": true, - "label": "Ausgabe test", - "name": "test_select", - "type": "FIRST" - } - ] - }, - "children": [ - { - "label": "test_child1", - "description": " ", - "condition": { - "type": "PREFIX_LIST", - "prefixes": "A1" - }, - "children": [] - }, - { - "label": "test_child2", - "description": " ", - "condition": { - "type": "PREFIX_LIST", - "prefixes": "B2" - }, - "children": [] - } - ] - } - ], - "content": { + "type": "QUERY_TEST", + "label": "CONCEPT_DATE_RESTRICTION_WITHOUT_VALIDITYDATE Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, + "expectedCsv": "tests/query/CONCEPT_DATE_RESTRICTION_WITHOUT_VALIDITYDATE/expected.csv", + "query": { + "type": "CONCEPT_QUERY", + "root": { + "type": "DATE_RESTRICTION", + "dateRange": { + "min": "2017-01-01", + "max": "2017-12-31" + }, + "child": { + "type": "CONCEPT", + "ids": [ + "test_tree.test_child1" + ], "tables": [ - { - "csv": "tests/query/CONCEPT_DATE_RESTRICTION_WITHOUT_VALIDITYDATE/content.csv", - "name": "test_table", - "primaryColumn": { - "name": "pid", - "type": "STRING" - }, - "columns": [ - { - "name": "test_column", - "type": "STRING" - } - ] - } + { + "id": "test_tree.test_column", + "filters": [], + "selects": [ + "test_tree.test_column.test_select" + ] + } ] + } } + }, + "concepts": [ + { + "label": "test_tree", + "type": "TREE", + "connectors": { + "label": "tree_label", + "name": "test_column", + "column": "test_table.test_column", + "selects": [ + { + "column": "test_table.test_column", + "default": true, + "label": "Ausgabe test", + "name": "test_select", + "type": "FIRST" + } + ] + }, + "children": [ + { + "label": "test_child1", + "description": " ", + "condition": { + "type": "PREFIX_LIST", + "prefixes": "A1" + }, + "children": [] + }, + { + "label": "test_child2", + "description": " ", + "condition": { + "type": "PREFIX_LIST", + "prefixes": "B2" + }, + "children": [] + } + ] + } + ], + "content": { + "tables": [ + { + "csv": "tests/query/CONCEPT_DATE_RESTRICTION_WITHOUT_VALIDITYDATE/content.csv", + "name": "test_table", + "primaryColumn": { + "name": "pid", + "type": "STRING" + }, + "columns": [ + { + "name": "test_column", + "type": "STRING" + } + ] + } + ] + } } \ No newline at end of file diff --git a/backend/src/test/resources/tests/query/CONCEPT_RESTRICTION_QUERY/CONCEPT_RESTRICTION.test.json b/backend/src/test/resources/tests/query/CONCEPT_RESTRICTION_QUERY/CONCEPT_RESTRICTION.test.json index 5694da7ee3..ad63360ba1 100644 --- a/backend/src/test/resources/tests/query/CONCEPT_RESTRICTION_QUERY/CONCEPT_RESTRICTION.test.json +++ b/backend/src/test/resources/tests/query/CONCEPT_RESTRICTION_QUERY/CONCEPT_RESTRICTION.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "CONCEPT_RESTRICTION Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/CONCEPT_RESTRICTION_QUERY/expected-kh.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/CONCEPT_WITHOUT_VALIDITYDATE/CONCEPT_WITHOUT_VALIDITYDATE.test.json b/backend/src/test/resources/tests/query/CONCEPT_WITHOUT_VALIDITYDATE/CONCEPT_WITHOUT_VALIDITYDATE.test.json index 835f61610d..117e0fb4fd 100644 --- a/backend/src/test/resources/tests/query/CONCEPT_WITHOUT_VALIDITYDATE/CONCEPT_WITHOUT_VALIDITYDATE.test.json +++ b/backend/src/test/resources/tests/query/CONCEPT_WITHOUT_VALIDITYDATE/CONCEPT_WITHOUT_VALIDITYDATE.test.json @@ -1,75 +1,86 @@ { - "type": "QUERY_TEST", - "label": "CONCEPT_WITHOUT_VALIDITYDATE Test", - "expectedCsv": "tests/query/CONCEPT_WITHOUT_VALIDITYDATE/expected.csv", - "query": { - "type": "CONCEPT_QUERY", - "root": { - "type": "CONCEPT", - "ids": [ - "test_tree.test_child1" - ], - "tables": [ - { - "id": "test_tree.test_column", - "filters": [], - "selects": [ - "test_tree.test_column.test_select" - ] - } - ] + "type": "QUERY_TEST", + "label": "CONCEPT_WITHOUT_VALIDITYDATE Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, + "expectedCsv": "tests/query/CONCEPT_WITHOUT_VALIDITYDATE/expected.csv", + "query": { + "type": "CONCEPT_QUERY", + "root": { + "type": "CONCEPT", + "ids": [ + "test_tree.test_child1" + ], + "tables": [ + { + "id": "test_tree.test_column", + "selects": [ + "test_tree.test_column.test_select" + ] } - }, - "concepts": [ + ] + } + }, + "concepts": [ + { + "label": "test_tree", + "type": "TREE", + "connectors": { + "label": "tree_label", + "name": "test_column", + "column": "test_table.test_column", + "selects": [ + { + "column": "test_table.test_column", + "default": true, + "label": "Ausgabe test", + "name": "test_select", + "type": "FIRST" + } + ] + }, + "children": [ + { + "label": "test_child1", + "description": " ", + "condition": { + "type": "PREFIX_LIST", + "prefixes": "A1" + }, + "children": [] + }, { - "label": "test_tree", - "type":"TREE", - "connectors": { - "label": "tree_label", - "name": "test_column", - "column": "test_table.test_column", - "selects": [ - { - "column": "test_table.test_column", - "default": true, - "label": "Ausgabe test", - "name": "test_select", - "type": "FIRST" - } - ] - }, - "children": [ - { - "label": "test_child1", - "description": " ", - "condition": {"type": "PREFIX_LIST", "prefixes": "A1"}, - "children": [] - }, - { - "label": "test_child2", - "description": " ", - "condition": {"type": "PREFIX_LIST", "prefixes": "B2"}, - "children": [] - } - ] + "label": "test_child2", + "description": " ", + "condition": { + "type": "PREFIX_LIST", + "prefixes": "B2" + }, + "children": [] } - ], - "content": { - "tables": [ - { - "csv": "tests/query/CONCEPT_WITHOUT_VALIDITYDATE/content.csv", - "name": "test_table", - "primaryColumn" : { - "name": "pid", - "type": "STRING" - }, - "columns": [ - { - "name": "test_column", - "type": "STRING" - } - ] - } - ] + ] } + ], + "content": { + "tables": [ + { + "csv": "tests/query/CONCEPT_WITHOUT_VALIDITYDATE/content.csv", + "name": "test_table", + "primaryColumn": { + "name": "pid", + "type": "STRING" + }, + "columns": [ + { + "name": "test_column", + "type": "STRING" + } + ] + } + ] + } } \ No newline at end of file diff --git a/backend/src/test/resources/tests/query/CQEXTERNAL_EXTRA_DATA/SIMPLE_CQEXTERNAL_QUERY.test.json b/backend/src/test/resources/tests/query/CQEXTERNAL_EXTRA_DATA/SIMPLE_CQEXTERNAL_QUERY.test.json index 0a4c61f0b7..95e681e27d 100644 --- a/backend/src/test/resources/tests/query/CQEXTERNAL_EXTRA_DATA/SIMPLE_CQEXTERNAL_QUERY.test.json +++ b/backend/src/test/resources/tests/query/CQEXTERNAL_EXTRA_DATA/SIMPLE_CQEXTERNAL_QUERY.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "CQExternal Extra Data Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/CQEXTERNAL_EXTRA_DATA/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/CQYES/CQYES.test.json b/backend/src/test/resources/tests/query/CQYES/CQYES.test.json index 23aafee084..95f56918e8 100644 --- a/backend/src/test/resources/tests/query/CQYES/CQYES.test.json +++ b/backend/src/test/resources/tests/query/CQYES/CQYES.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "CQYES Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/CQYES/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/DATE_DISTANCE/DATE_DISTANCE.test.json b/backend/src/test/resources/tests/query/DATE_DISTANCE/DATE_DISTANCE.test.json index 060b83c022..3438b18284 100644 --- a/backend/src/test/resources/tests/query/DATE_DISTANCE/DATE_DISTANCE.test.json +++ b/backend/src/test/resources/tests/query/DATE_DISTANCE/DATE_DISTANCE.test.json @@ -1,101 +1,105 @@ -{ - "type":"QUERY_TEST", - "label":"DATE_DISTANCE_VERSICHERTENZEIT Test", - "expectedCsv":"tests/query/DATE_DISTANCE/expected-versichertenzeit.csv", - "query":{ - "type":"CONCEPT_QUERY", - "root":{ - "type":"DATE_RESTRICTION", - "dateRange":{ - "min":"2011-01-01", - "max":"2011-01-01" - }, - "child":{ - "type":"OR", - "children":[ - { - "type":"CONCEPT", - "ids":[ - "alter" - ], - "label":"Alter", - "excludeFromTimeAggregation":false, - "tables":[ - { - "id":"alter.alterxy", - "selects":[ - - ], - "filters":[ - { - "filter":"alter.alterxy.alterseinschrankung", - "type":"INTEGER_RANGE", - "value":{ - "min":"11", - "max":"11" - } - } - ] - } - ], - "selects":[ - - ] +{ + "type": "QUERY_TEST", + "label": "DATE_DISTANCE_VERSICHERTENZEIT Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, + "expectedCsv": "tests/query/DATE_DISTANCE/expected-versichertenzeit.csv", + "query": { + "type": "CONCEPT_QUERY", + "root": { + "type": "DATE_RESTRICTION", + "dateRange": { + "min": "2011-01-01", + "max": "2011-01-01" + }, + "child": { + "type": "OR", + "children": [ + { + "type": "CONCEPT", + "ids": [ + "alter" + ], + "label": "Alter", + "excludeFromTimeAggregation": false, + "tables": [ + { + "id": "alter.alterxy", + "selects": [ + ], + "filters": [ + { + "filter": "alter.alterxy.alterseinschrankung", + "type": "INTEGER_RANGE", + "value": { + "min": "11", + "max": "11" + } } - ] - } - } - }, - "concepts":[ - { - "label":"alter", - "type":"TREE", - "connectors":[ - { - "label":"alterxy", - "table":"table1", - "validityDates":{ - "label":"versichertenzeit", - "column":"table1.versichertenzeit" - }, - "filters":{ - "label":"alterseinschrankung", - "description":"Geburtsdatum", - "column":"table1.geburtsdatum", - "type":"DATE_DISTANCE" - } - } - ] - } - ], - "content":{ - "tables":[ - { - "csv":"tests/query/DATE_DISTANCE/content.csv", - "name":"table1", - "primaryColumn":{ - "name":"pid", - "type":"STRING" - }, - "columns":[ - { - "name":"geburtsdatum", - "type":"DATE" - }, - { - "name":"erster", - "type":"DATE" - }, - { - "name":"letzter", - "type":"DATE" - }, - { - "name":"versichertenzeit", - "type":"DATE_RANGE" - } + ] + } + ], + "selects": [ ] - } + } + ] + } + } + }, + "concepts": [ + { + "label": "alter", + "type": "TREE", + "connectors": [ + { + "label": "alterxy", + "table": "table1", + "validityDates": { + "label": "versichertenzeit", + "column": "table1.versichertenzeit" + }, + "filters": { + "label": "alterseinschrankung", + "description": "Geburtsdatum", + "column": "table1.geburtsdatum", + "type": "DATE_DISTANCE" + } + } ] - } + } + ], + "content": { + "tables": [ + { + "csv": "tests/query/DATE_DISTANCE/content.csv", + "name": "table1", + "primaryColumn": { + "name": "pid", + "type": "STRING" + }, + "columns": [ + { + "name": "geburtsdatum", + "type": "DATE" + }, + { + "name": "erster", + "type": "DATE" + }, + { + "name": "letzter", + "type": "DATE" + }, + { + "name": "versichertenzeit", + "type": "DATE_RANGE" + } + ] + } + ] + } } \ No newline at end of file diff --git a/backend/src/test/resources/tests/query/DATE_DISTANCE/DATE_DISTANCE_ERSTER.test.json b/backend/src/test/resources/tests/query/DATE_DISTANCE/DATE_DISTANCE_ERSTER.test.json index 6463c02a38..f27cdad5bc 100644 --- a/backend/src/test/resources/tests/query/DATE_DISTANCE/DATE_DISTANCE_ERSTER.test.json +++ b/backend/src/test/resources/tests/query/DATE_DISTANCE/DATE_DISTANCE_ERSTER.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "DATE_DISTANCE_ERSTER Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/DATE_DISTANCE/expected-erster.csv", "query": { "type": "CONCEPT_QUERY", @@ -11,35 +17,26 @@ "max": "2011-01-01" }, "child": { - "type": "OR", - "children": [ + "type": "CONCEPT", + "ids": [ + "alter" + ], + "tables": [ { - "type": "CONCEPT", - "ids": [ - "alter" - ], - "label": "Alter", - "excludeFromTimeAggregation": false, - "tables": [ + "id": "alter.alterxy", + "filters": [ { - "id": "alter.alterxy", - "selects": [ - ], - "filters": [ - { - "filter": "alter.alterxy.alterseinschrankung", - "type": "INTEGER_RANGE", - "value": { - "min": "11", - "max": "11" - } - } - ] + "filter": "alter.alterxy.alterseinschrankung", + "type": "INTEGER_RANGE", + "value": { + "min": "11", + "max": "11" + } } - ], - "selects": [ ] } + ], + "selects": [ ] } } diff --git a/backend/src/test/resources/tests/query/DATE_DISTANCE/DATE_DISTANCE_LETZTER.test.json b/backend/src/test/resources/tests/query/DATE_DISTANCE/DATE_DISTANCE_LETZTER.test.json index e75dca26f3..0456915a86 100644 --- a/backend/src/test/resources/tests/query/DATE_DISTANCE/DATE_DISTANCE_LETZTER.test.json +++ b/backend/src/test/resources/tests/query/DATE_DISTANCE/DATE_DISTANCE_LETZTER.test.json @@ -1,6 +1,12 @@ { "type":"QUERY_TEST", "label":"DATE_DISTANCE_LETZTER Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv":"tests/query/DATE_DISTANCE/expected-letzter.csv", "query":{ "type":"CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/DATE_DISTANCE_AGE_SPAN/DATE_DISTANCE.test.json b/backend/src/test/resources/tests/query/DATE_DISTANCE_AGE_SPAN/DATE_DISTANCE.test.json index 8169dc645d..f325fe9be7 100644 --- a/backend/src/test/resources/tests/query/DATE_DISTANCE_AGE_SPAN/DATE_DISTANCE.test.json +++ b/backend/src/test/resources/tests/query/DATE_DISTANCE_AGE_SPAN/DATE_DISTANCE.test.json @@ -1,6 +1,12 @@ { "type":"QUERY_TEST", "label":"DATE_DISTANCE_AGE_SPAN_VERSICHERTENZEIT Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv":"tests/query/DATE_DISTANCE_AGE_SPAN/expected-versichertenzeit.csv", "query":{ "type":"CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/DATE_DISTANCE_AGE_SPAN/DATE_DISTANCE_ERSTER.test.json b/backend/src/test/resources/tests/query/DATE_DISTANCE_AGE_SPAN/DATE_DISTANCE_ERSTER.test.json index 1e60cf69db..510b426a83 100644 --- a/backend/src/test/resources/tests/query/DATE_DISTANCE_AGE_SPAN/DATE_DISTANCE_ERSTER.test.json +++ b/backend/src/test/resources/tests/query/DATE_DISTANCE_AGE_SPAN/DATE_DISTANCE_ERSTER.test.json @@ -1,6 +1,12 @@ { "type":"QUERY_TEST", "label":"DATE_DISTANCE_AGE_SPAN_ERSTER Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv":"tests/query/DATE_DISTANCE_AGE_SPAN/expected-erster.csv", "query":{ "type":"CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/DATE_DISTANCE_AGE_SPAN/DATE_DISTANCE_LETZTER.test.json b/backend/src/test/resources/tests/query/DATE_DISTANCE_AGE_SPAN/DATE_DISTANCE_LETZTER.test.json index 5dcd15f7d8..feb6852c47 100644 --- a/backend/src/test/resources/tests/query/DATE_DISTANCE_AGE_SPAN/DATE_DISTANCE_LETZTER.test.json +++ b/backend/src/test/resources/tests/query/DATE_DISTANCE_AGE_SPAN/DATE_DISTANCE_LETZTER.test.json @@ -1,6 +1,12 @@ { "type":"QUERY_TEST", "label":"DATE_DISTANCE_AGE_SPAN_LETZTER Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv":"tests/query/DATE_DISTANCE_AGE_SPAN/expected-letzter.csv", "query":{ "type":"CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/DATE_DISTANCE_NEGATION/DATE_DISTANCE.test.json b/backend/src/test/resources/tests/query/DATE_DISTANCE_NEGATION/DATE_DISTANCE.test.json index a00611ff4f..671114bcf1 100644 --- a/backend/src/test/resources/tests/query/DATE_DISTANCE_NEGATION/DATE_DISTANCE.test.json +++ b/backend/src/test/resources/tests/query/DATE_DISTANCE_NEGATION/DATE_DISTANCE.test.json @@ -1,6 +1,12 @@ { "type":"QUERY_TEST", "label":"DATE_DISTANCE_NEGATION_VERSICHERTENZEIT Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv":"tests/query/DATE_DISTANCE_NEGATION/expected-versichertenzeit.csv", "query":{ "type":"CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/DATE_DISTANCE_NEGATION/DATE_DISTANCE_ERSTER.test.json b/backend/src/test/resources/tests/query/DATE_DISTANCE_NEGATION/DATE_DISTANCE_ERSTER.test.json index 8a92e780f7..855850c88c 100644 --- a/backend/src/test/resources/tests/query/DATE_DISTANCE_NEGATION/DATE_DISTANCE_ERSTER.test.json +++ b/backend/src/test/resources/tests/query/DATE_DISTANCE_NEGATION/DATE_DISTANCE_ERSTER.test.json @@ -1,6 +1,12 @@ { "type":"QUERY_TEST", "label":"DATE_DISTANCE_NEGATION_ERSTER Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv":"tests/query/DATE_DISTANCE_NEGATION/expected-erster.csv", "query":{ "type":"CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/DATE_DISTANCE_NEGATION/DATE_DISTANCE_LETZTER.test.json b/backend/src/test/resources/tests/query/DATE_DISTANCE_NEGATION/DATE_DISTANCE_LETZTER.test.json index ed1b69959e..51b3b1c279 100644 --- a/backend/src/test/resources/tests/query/DATE_DISTANCE_NEGATION/DATE_DISTANCE_LETZTER.test.json +++ b/backend/src/test/resources/tests/query/DATE_DISTANCE_NEGATION/DATE_DISTANCE_LETZTER.test.json @@ -1,6 +1,12 @@ { "type":"QUERY_TEST", "label":"DATE_DISTANCE_NEGATION_LETZTER Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv":"tests/query/DATE_DISTANCE_NEGATION/expected-letzter.csv", "query":{ "type":"CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/DURATION_SUM_EMPTY_DATE_CONCEPT_QUERY/DURATION_SUM_EMPTY_DATE_CONCEPT_QUERY.test.json b/backend/src/test/resources/tests/query/DURATION_SUM_EMPTY_DATE_CONCEPT_QUERY/DURATION_SUM_EMPTY_DATE_CONCEPT_QUERY.test.json index 051cdf289b..63de4ea517 100644 --- a/backend/src/test/resources/tests/query/DURATION_SUM_EMPTY_DATE_CONCEPT_QUERY/DURATION_SUM_EMPTY_DATE_CONCEPT_QUERY.test.json +++ b/backend/src/test/resources/tests/query/DURATION_SUM_EMPTY_DATE_CONCEPT_QUERY/DURATION_SUM_EMPTY_DATE_CONCEPT_QUERY.test.json @@ -1,6 +1,12 @@ { "type":"QUERY_TEST", "label":"DURATION_SUM_EMPTY_DATE_CONCEPT_QUERY Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv":"tests/query/DURATION_SUM_EMPTY_DATE_CONCEPT_QUERY/expected-zeitspanne.csv", "query":{ "type":"CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/ENTITY_EXPORT_TESTS/SIMPLE_TREECONCEPT_Query.json b/backend/src/test/resources/tests/query/ENTITY_EXPORT_TESTS/SIMPLE_TREECONCEPT_Query.json index 0a4989dd63..dffd6a986d 100644 --- a/backend/src/test/resources/tests/query/ENTITY_EXPORT_TESTS/SIMPLE_TREECONCEPT_Query.json +++ b/backend/src/test/resources/tests/query/ENTITY_EXPORT_TESTS/SIMPLE_TREECONCEPT_Query.json @@ -7,11 +7,11 @@ "root": { "type": "CONCEPT", "ids": [ - "tree1.child1" + "tree1.child_a" ], "tables": [ { - "id": "tree1.connectors", + "id": "tree1.connector", "filters": [] } ] diff --git a/backend/src/test/resources/tests/query/ENTITY_EXPORT_TESTS/expected.csv b/backend/src/test/resources/tests/query/ENTITY_EXPORT_TESTS/expected.csv index 7fefa3e585..907f60e27c 100644 --- a/backend/src/test/resources/tests/query/ENTITY_EXPORT_TESTS/expected.csv +++ b/backend/src/test/resources/tests/query/ENTITY_EXPORT_TESTS/expected.csv @@ -1 +1,2 @@ -FILE IS UNUSED! \ No newline at end of file +result,dates +1,{2013-11-10/2013-11-10} \ No newline at end of file diff --git a/backend/src/test/resources/tests/query/CQEXTERNAL_ONLY_IDS/SIMPLE_CQEXTERNAL_QUERY.test.json b/backend/src/test/resources/tests/query/EXTERNAL_NEGATION/SIMPLE_CQEXTERNAL_QUERY.test.json similarity index 69% rename from backend/src/test/resources/tests/query/CQEXTERNAL_ONLY_IDS/SIMPLE_CQEXTERNAL_QUERY.test.json rename to backend/src/test/resources/tests/query/EXTERNAL_NEGATION/SIMPLE_CQEXTERNAL_QUERY.test.json index 3c591d8ca3..e4eee66e6f 100644 --- a/backend/src/test/resources/tests/query/CQEXTERNAL_ONLY_IDS/SIMPLE_CQEXTERNAL_QUERY.test.json +++ b/backend/src/test/resources/tests/query/EXTERNAL_NEGATION/SIMPLE_CQEXTERNAL_QUERY.test.json @@ -1,7 +1,13 @@ { "type": "QUERY_TEST", "label": "CQExternal Extra Data Test", - "expectedCsv": "tests/query/CQEXTERNAL_ONLY_IDS/expected.csv", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, + "expectedCsv": "tests/query/EXTERNAL_NEGATION/expected.csv", "query": { "type": "CONCEPT_QUERY", "root": { @@ -25,21 +31,15 @@ } }, { - "type": "DATE_RESTRICTION", - "dateRange": { - "max": "2010-12-31" - }, - "child": { - "type": "CONCEPT", - "ids": [ - "test_tree" - ], - "tables": [ - { - "id": "test_tree.connector" - } - ] - } + "type": "CONCEPT", + "ids": [ + "test_tree" + ], + "tables": [ + { + "id": "test_tree.connector" + } + ] } ] } @@ -61,7 +61,7 @@ "content": { "tables": [ { - "csv": "tests/query/CQEXTERNAL_ONLY_IDS/content.csv", + "csv": "tests/query/EXTERNAL_NEGATION/content.csv", "name": "test_table", "primaryColumn": { "name": "pid", diff --git a/backend/src/test/resources/tests/query/CQEXTERNAL_ONLY_IDS/content.csv b/backend/src/test/resources/tests/query/EXTERNAL_NEGATION/content.csv similarity index 55% rename from backend/src/test/resources/tests/query/CQEXTERNAL_ONLY_IDS/content.csv rename to backend/src/test/resources/tests/query/EXTERNAL_NEGATION/content.csv index 38f68cb1b3..ce75c00557 100644 --- a/backend/src/test/resources/tests/query/CQEXTERNAL_ONLY_IDS/content.csv +++ b/backend/src/test/resources/tests/query/EXTERNAL_NEGATION/content.csv @@ -2,6 +2,3 @@ pid,datum 1,2010-01-01 2,2010-01-01 3,2010-01-01 -4,2011-01-01 -5,2011-01-01 -6,2011-01-01 diff --git a/backend/src/test/resources/tests/query/CQEXTERNAL_ONLY_IDS/expected.csv b/backend/src/test/resources/tests/query/EXTERNAL_NEGATION/expected.csv similarity index 100% rename from backend/src/test/resources/tests/query/CQEXTERNAL_ONLY_IDS/expected.csv rename to backend/src/test/resources/tests/query/EXTERNAL_NEGATION/expected.csv diff --git a/backend/src/test/resources/tests/query/LOGICAL/AND_DATE_LOGICAL/SIMPLE_TREECONCEPT_Query.test.json b/backend/src/test/resources/tests/query/LOGICAL/AND_DATE_LOGICAL/SIMPLE_TREECONCEPT_Query.test.json index c40e2d09a6..ca584b9cca 100644 --- a/backend/src/test/resources/tests/query/LOGICAL/AND_DATE_LOGICAL/SIMPLE_TREECONCEPT_Query.test.json +++ b/backend/src/test/resources/tests/query/LOGICAL/AND_DATE_LOGICAL/SIMPLE_TREECONCEPT_Query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "AND DATE LOGIC Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/LOGICAL/AND_DATE_LOGICAL/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/LOGICAL/AND_DURATION_SUM/SIMPLE_TREECONCEPT_Query.test.json b/backend/src/test/resources/tests/query/LOGICAL/AND_DURATION_SUM/SIMPLE_TREECONCEPT_Query.test.json index fc9084888c..f211dc1e8f 100644 --- a/backend/src/test/resources/tests/query/LOGICAL/AND_DURATION_SUM/SIMPLE_TREECONCEPT_Query.test.json +++ b/backend/src/test/resources/tests/query/LOGICAL/AND_DURATION_SUM/SIMPLE_TREECONCEPT_Query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "AND DURATION SUM Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/LOGICAL/AND_DURATION_SUM/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/LOGICAL/AND_DURATION_SUM_MULTI_CONCEPT/SIMPLE_TREECONCEPT_Query.test.json b/backend/src/test/resources/tests/query/LOGICAL/AND_DURATION_SUM_MULTI_CONCEPT/SIMPLE_TREECONCEPT_Query.test.json index bdddac323b..8f9194ef73 100644 --- a/backend/src/test/resources/tests/query/LOGICAL/AND_DURATION_SUM_MULTI_CONCEPT/SIMPLE_TREECONCEPT_Query.test.json +++ b/backend/src/test/resources/tests/query/LOGICAL/AND_DURATION_SUM_MULTI_CONCEPT/SIMPLE_TREECONCEPT_Query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "AND DURATION SUM Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/LOGICAL/AND_DURATION_SUM_MULTI_CONCEPT/expected.csv", "query": { "type": "SECONDARY_ID_QUERY", diff --git a/backend/src/test/resources/tests/query/LOGICAL/AND_NEGATION_DATE_LOGICAL/SIMPLE_TREECONCEPT_Query.test.json b/backend/src/test/resources/tests/query/LOGICAL/AND_NEGATION_DATE_LOGICAL/SIMPLE_TREECONCEPT_Query.test.json index db05c8b364..5f604ea1d4 100644 --- a/backend/src/test/resources/tests/query/LOGICAL/AND_NEGATION_DATE_LOGICAL/SIMPLE_TREECONCEPT_Query.test.json +++ b/backend/src/test/resources/tests/query/LOGICAL/AND_NEGATION_DATE_LOGICAL/SIMPLE_TREECONCEPT_Query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "AND NEGATION DATE LOGIC Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/LOGICAL/AND_NEGATION_DATE_LOGICAL/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/LOGICAL/AND_NEGATION_RESTRICTION_DATE_LOGICAL/SIMPLE_TREECONCEPT_Query.test.json b/backend/src/test/resources/tests/query/LOGICAL/AND_NEGATION_RESTRICTION_DATE_LOGICAL/SIMPLE_TREECONCEPT_Query.test.json index 56f6533671..8799fe23cc 100644 --- a/backend/src/test/resources/tests/query/LOGICAL/AND_NEGATION_RESTRICTION_DATE_LOGICAL/SIMPLE_TREECONCEPT_Query.test.json +++ b/backend/src/test/resources/tests/query/LOGICAL/AND_NEGATION_RESTRICTION_DATE_LOGICAL/SIMPLE_TREECONCEPT_Query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "AND NEGATION DATE LOGIC Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/LOGICAL/AND_NEGATION_RESTRICTION_DATE_LOGICAL/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/LOGICAL/NEGATION_LOGICAL/SIMPLE_TREECONCEPT_Query.test.json b/backend/src/test/resources/tests/query/LOGICAL/NEGATION_LOGICAL/SIMPLE_TREECONCEPT_Query.test.json new file mode 100644 index 0000000000..330015c9b1 --- /dev/null +++ b/backend/src/test/resources/tests/query/LOGICAL/NEGATION_LOGICAL/SIMPLE_TREECONCEPT_Query.test.json @@ -0,0 +1,84 @@ +{ + "type": "QUERY_TEST", + "label": "AND NEGATION DATE LOGIC Test", + "expectedCsv": "tests/query/LOGICAL/NEGATION_LOGICAL/expected.csv", + "query": { + "type": "CONCEPT_QUERY", + "dateAggregationMode": "LOGICAL", + "root": { + "type": "NEGATION", + "child": { + "type": "CONCEPT", + "ids": [ + "tree.a" + ], + "tables": [ + { + "id": "tree.connector" + } + ] + } + } + }, + "concepts": [ + { + "name": "tree", + "type": "TREE", + "connectors": { + "name": "connector", + "column": "table.column", + "validityDates": [ + { + "name": "datum", + "startColumn": "table.start", + "endColumn": "table.end" + } + ] + }, + "children": [ + { + "name": "a", + "condition": { + "type": "EQUAL", + "values": "A" + }, + "children": [] + }, + { + "name": "b", + "condition": { + "type": "EQUAL", + "values": "B" + }, + "children": [] + } + ] + } + ], + "content": { + "tables": [ + { + "csv": "tests/query/LOGICAL/NEGATION_LOGICAL/content.csv", + "name": "table", + "primaryColumn": { + "name": "pid", + "type": "STRING" + }, + "columns": [ + { + "name": "start", + "type": "DATE" + }, + { + "name": "end", + "type": "DATE" + }, + { + "name": "column", + "type": "STRING" + } + ] + } + ] + } +} diff --git a/backend/src/test/resources/tests/query/LOGICAL/NEGATION_LOGICAL/content.csv b/backend/src/test/resources/tests/query/LOGICAL/NEGATION_LOGICAL/content.csv new file mode 100644 index 0000000000..31188b3c16 --- /dev/null +++ b/backend/src/test/resources/tests/query/LOGICAL/NEGATION_LOGICAL/content.csv @@ -0,0 +1,13 @@ +pid,start,end,column +1,2012-01-01,2012-01-01,A +1,2012-01-01,2012-01-01, + +2,2012-01-01,2012-06-30,B + +3,2012-01-01,2012-01-01,A +3,2012-01-02,2012-01-02,B + +4,2012-01-02,2012-01-02,A +4,2012-01-02,2012-01-02,B + +5,2012-01-01,2012-01-01,B diff --git a/backend/src/test/resources/tests/query/LOGICAL/NEGATION_LOGICAL/expected.csv b/backend/src/test/resources/tests/query/LOGICAL/NEGATION_LOGICAL/expected.csv new file mode 100644 index 0000000000..7d346d9947 --- /dev/null +++ b/backend/src/test/resources/tests/query/LOGICAL/NEGATION_LOGICAL/expected.csv @@ -0,0 +1,3 @@ +result,dates +2,{-∞/+∞} +5,{-∞/+∞} diff --git a/backend/src/test/resources/tests/query/LOGICAL/OR_NEGATION_DATE_LOGICAL/SIMPLE_TREECONCEPT_Query.test.json b/backend/src/test/resources/tests/query/LOGICAL/OR_NEGATION_DATE_LOGICAL/SIMPLE_TREECONCEPT_Query.test.json new file mode 100644 index 0000000000..c0a02b05e7 --- /dev/null +++ b/backend/src/test/resources/tests/query/LOGICAL/OR_NEGATION_DATE_LOGICAL/SIMPLE_TREECONCEPT_Query.test.json @@ -0,0 +1,105 @@ +{ + "type": "QUERY_TEST", + "label": "OR NEGATION DATE LOGIC Test", + "expectedCsv": "tests/query/LOGICAL/OR_NEGATION_DATE_LOGICAL/expected.csv", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, + "query": { + "type": "CONCEPT_QUERY", + "dateAggregationMode": "LOGICAL", + "root": { + "type": "OR", + "createExists": true, + "children": [ + { + "type": "NEGATION", + "child": { + "type": "CONCEPT", + "ids": [ + "tree.a" + ], + "tables": [ + { + "id": "tree.connector" + } + ] + } + }, + { + "type": "CONCEPT", + "ids": [ + "tree.b" + ], + "tables": [ + { + "id": "tree.connector" + } + ] + } + ] + } + }, + "concepts": [ + { + "name": "tree", + "type": "TREE", + "connectors": { + "name": "connector", + "column": "table.column", + "validityDates": { + "name": "datum", + "startColumn": "table.start", + "endColumn": "table.end" + } + }, + "children": [ + { + "name": "a", + "condition": { + "type": "EQUAL", + "values": "A" + }, + "children": [] + }, + { + "name": "b", + "condition": { + "type": "EQUAL", + "values": "B" + }, + "children": [] + } + ] + } + ], + "content": { + "tables": [ + { + "csv": "tests/query/LOGICAL/OR_NEGATION_DATE_LOGICAL/content.csv", + "name": "table", + "primaryColumn": { + "name": "pid", + "type": "STRING" + }, + "columns": [ + { + "name": "start", + "type": "DATE" + }, + { + "name": "end", + "type": "DATE" + }, + { + "name": "column", + "type": "STRING" + } + ] + } + ] + } +} diff --git a/backend/src/test/resources/tests/query/LOGICAL/OR_NEGATION_DATE_LOGICAL/content.csv b/backend/src/test/resources/tests/query/LOGICAL/OR_NEGATION_DATE_LOGICAL/content.csv new file mode 100644 index 0000000000..fca303be6d --- /dev/null +++ b/backend/src/test/resources/tests/query/LOGICAL/OR_NEGATION_DATE_LOGICAL/content.csv @@ -0,0 +1,17 @@ +pid,start,end,column +1,2012-01-01,2012-01-01,A +1,2012-01-01,2012-01-01, + +2,2012-01-01,2012-06-30,A +2,2013-01-01,2013-12-31,B + +3,2012-01-01,2012-01-01,A +3,2012-01-02,2012-01-02,B + +4,2012-01-02,2012-01-02,A +4,2012-01-02,2012-01-02,B + +5,2012-01-03,2012-01-03,B +5,2012-01-05,2012-01-05,B + +6,2012-01-01,2012-01-01, diff --git a/backend/src/test/resources/tests/query/LOGICAL/OR_NEGATION_DATE_LOGICAL/expected.csv b/backend/src/test/resources/tests/query/LOGICAL/OR_NEGATION_DATE_LOGICAL/expected.csv new file mode 100644 index 0000000000..6715c2c996 --- /dev/null +++ b/backend/src/test/resources/tests/query/LOGICAL/OR_NEGATION_DATE_LOGICAL/expected.csv @@ -0,0 +1,6 @@ +result,dates,NEGATION or tree b exists +2,"{-∞/2011-12-31,2012-07-01/+∞}",1 +3,"{-∞/2011-12-31,2012-01-02/+∞}",1 +4,{-∞/+∞},1 +5,{-∞/+∞},1 +6,{-∞/+∞},1 diff --git a/backend/src/test/resources/tests/query/MULTIPLE_TABLES_ICD_QUERY2/MULTIPLE_TABLES_ICD_KH_AU_QUERY_ohneFilter.test.json b/backend/src/test/resources/tests/query/MULTIPLE_TABLES_ICD_QUERY2/MULTIPLE_TABLES_ICD_KH_AU_QUERY_ohneFilter.test.json index 5236855788..81a9101b2f 100644 --- a/backend/src/test/resources/tests/query/MULTIPLE_TABLES_ICD_QUERY2/MULTIPLE_TABLES_ICD_KH_AU_QUERY_ohneFilter.test.json +++ b/backend/src/test/resources/tests/query/MULTIPLE_TABLES_ICD_QUERY2/MULTIPLE_TABLES_ICD_KH_AU_QUERY_ohneFilter.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "MULTIPLE_TABLES_ICD_QUERY2 Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/MULTIPLE_TABLES_ICD_QUERY2/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY/MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY.test.json b/backend/src/test/resources/tests/query/MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY/MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY.test.json index 5a340d7d72..a38bffee8f 100644 --- a/backend/src/test/resources/tests/query/MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY/MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY.test.json +++ b/backend/src/test/resources/tests/query/MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY/MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY2/MULTI_SELECT_DATE_RESTRICTION_OR_CONCEPT_QUERY.test.json b/backend/src/test/resources/tests/query/MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY2/MULTI_SELECT_DATE_RESTRICTION_OR_CONCEPT_QUERY.test.json index e0f4a47597..1fabb7fd07 100644 --- a/backend/src/test/resources/tests/query/MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY2/MULTI_SELECT_DATE_RESTRICTION_OR_CONCEPT_QUERY.test.json +++ b/backend/src/test/resources/tests/query/MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY2/MULTI_SELECT_DATE_RESTRICTION_OR_CONCEPT_QUERY.test.json @@ -1,92 +1,87 @@ -{ - "type":"QUERY_TEST", - "label":"MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY2 Test", - "expectedCsv":"tests/query/MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY2/expected.csv", - "query":{ - "type":"CONCEPT_QUERY", - "root":{ - "type":"NEGATION", - "child":{ - "type":"DATE_RESTRICTION", - "dateRange":{ - "min":"2012-01-01", - "max":"2012-11-11" - }, - "child": - { - "type":"OR", - "children": - [ - { - "ids":[ - "geschlecht_select" - ], - "type":"CONCEPT", - "label":"Geschlecht SELECT", - "tables":[ - { - "id":"geschlecht_select.geschlecht_connector", - "filters":[ - { - "filter":"geschlecht_select.geschlecht_connector.geschlecht", - "type":"MULTI_SELECT", - "value":[ - "f" - ] - } - ] - } - ] - } - ] - - } - - } - } - }, - "concepts":[ - { - "label":"geschlecht_select", - "type":"TREE", - "connectors":[ - { - "label":"geschlecht_connector", - "table":"table1", - "validityDates":{ - "label":"datum", - "column":"table1.datum" - }, - "filters":{ - "label":"geschlecht", - "description":"Geschlecht zur gegebenen Datumseinschränkung", - "column":"table1.geschlecht", - "type":"SELECT" - } +{ + "type": "QUERY_TEST", + "label": "MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY2 Test", + "expectedCsv": "tests/query/MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY2/expected.csv", + "query": { + "type": "CONCEPT_QUERY", + "root": { + "type": "NEGATION", + "child": { + "type": "DATE_RESTRICTION", + "dateRange": { + "min": "2012-01-01", + "max": "2012-11-11" + }, + "child": { + "type": "OR", + "children": [ + { + "ids": [ + "geschlecht_select" + ], + "type": "CONCEPT", + "tables": [ + { + "id": "geschlecht_select.geschlecht_connector", + "filters": [ + { + "filter": "geschlecht_select.geschlecht_connector.geschlecht", + "type": "MULTI_SELECT", + "value": [ + "f" + ] + } + ] + } + ] } - ] + ] + } } - ], - "content":{ - "tables":[ - { - "csv":"tests/query/MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY2/content.csv", - "name":"table1", - "primaryColumn":{ - "name":"pid", - "type":"STRING" - }, - "columns":[ - { - "name":"datum", - "type":"DATE" - }, - { - "name":"geschlecht", - "type":"STRING" - } - ] - } + } + }, + "concepts": [ + { + "label": "geschlecht_select", + "type": "TREE", + "connectors": [ + { + "label": "geschlecht_connector", + "table": "table1", + "validityDates": { + "label": "datum", + "column": "table1.datum" + }, + "filters": { + "label": "geschlecht", + "description": "Geschlecht zur gegebenen Datumseinschränkung", + "column": "table1.geschlecht", + "type": "SELECT" + } + } ] - } + } + ], + "content": { + "tables": [ + { + "csv": "tests/query/MULTI_SELECT_NEGATION_DATE_RESTRICTION_OR_CONCEPT_QUERY2/content.csv", + "name": "table1", + "primaryColumn": { + "name": "pid", + "type": "STRING" + }, + "columns": [ + { + "name": "datum", + "type": "DATE" + }, + { + "name": "geschlecht", + "type": "STRING" + } + ] + } + ] + } } diff --git a/backend/src/test/resources/tests/query/NUMBER/NUMBER.test.json b/backend/src/test/resources/tests/query/NUMBER/NUMBER.test.json index 414f5be39f..e20454e971 100644 --- a/backend/src/test/resources/tests/query/NUMBER/NUMBER.test.json +++ b/backend/src/test/resources/tests/query/NUMBER/NUMBER.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "NUMBER_QUERY Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/NUMBER/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/NUMBER_MISSING/NUMBER.test.json b/backend/src/test/resources/tests/query/NUMBER_MISSING/NUMBER.test.json index c30a242014..3047d62b66 100644 --- a/backend/src/test/resources/tests/query/NUMBER_MISSING/NUMBER.test.json +++ b/backend/src/test/resources/tests/query/NUMBER_MISSING/NUMBER.test.json @@ -1,6 +1,12 @@ { "type":"QUERY_TEST", "label":"NUMBER_MISSING_QUERY Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv":"tests/query/NUMBER_MISSING/expected.csv", "query":{ "type":"CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/NUMBER_MISSING_NO_RESTRICTION/NUMBER.test.json b/backend/src/test/resources/tests/query/NUMBER_MISSING_NO_RESTRICTION/NUMBER.test.json index a274244f9e..5d0cdf7453 100644 --- a/backend/src/test/resources/tests/query/NUMBER_MISSING_NO_RESTRICTION/NUMBER.test.json +++ b/backend/src/test/resources/tests/query/NUMBER_MISSING_NO_RESTRICTION/NUMBER.test.json @@ -1,6 +1,12 @@ { "type":"QUERY_TEST", "label":"NUMBER_MISSING_NO_FILTER_RESTRICTION_QUERY Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv":"tests/query/NUMBER_MISSING_NO_RESTRICTION/expected.csv", "query":{ "type":"CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/NUMBER_MISSING_NO_RESTRICTION/NUMBER2.test.json b/backend/src/test/resources/tests/query/NUMBER_MISSING_NO_RESTRICTION/NUMBER2.test.json index e27c16f6c8..54657c85c1 100644 --- a/backend/src/test/resources/tests/query/NUMBER_MISSING_NO_RESTRICTION/NUMBER2.test.json +++ b/backend/src/test/resources/tests/query/NUMBER_MISSING_NO_RESTRICTION/NUMBER2.test.json @@ -1,6 +1,12 @@ { "type":"QUERY_TEST", "label":"NUMBER_MISSING_NO_RESTRICTION_QUERY Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv":"tests/query/NUMBER_MISSING_NO_RESTRICTION/expected2.csv", "query":{ "type":"CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/NUMBER_NEGATION/NUMBER.test.json b/backend/src/test/resources/tests/query/NUMBER_NEGATION/NUMBER.test.json index 2774a22864..fbf1cf7845 100644 --- a/backend/src/test/resources/tests/query/NUMBER_NEGATION/NUMBER.test.json +++ b/backend/src/test/resources/tests/query/NUMBER_NEGATION/NUMBER.test.json @@ -1,91 +1,95 @@ -{ - "type":"QUERY_TEST", - "label":"NUMBER_NEGATION_QUERY Test", - "expectedCsv":"tests/query/NUMBER_NEGATION/expected.csv", - "query":{ - "type":"CONCEPT_QUERY", +{ + "type": "QUERY_TEST", + "label": "NUMBER_NEGATION_QUERY Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, + "expectedCsv": "tests/query/NUMBER_NEGATION/expected.csv", + "query": { + "type": "CONCEPT_QUERY", "root": { - "type":"NEGATION", - "child":{ - "type": "AND", - "children": [ - { - "type":"DATE_RESTRICTION", - "dateRange":{ - "min":"2014-02-12", - "max":"2014-12-13" + "type": "NEGATION", + "child": { + "type": "AND", + "children": [ + { + "type": "DATE_RESTRICTION", + "dateRange": { + "min": "2014-02-12", + "max": "2014-12-13" }, - "child":{ - - "ids":[ - "number" - ], - "type":"CONCEPT", - "label":"vs", - "tables":[ - { - "id":"number.number_connector", - "filters":[ - { - "filter":"number.number_connector.value", - "type":"REAL_RANGE", - "value":{ - "min": 1, - "max": 1 - } - } - ] - } - ] - - } - } - ] - } - } - }, - "concepts":[ - { - "label":"number", - "type":"TREE", - "connectors":[ - { - "label":"number_connector", - "table":"table1", - "validityDates":{ - "label":"datum", - "column":"table1.datum" - }, - "filters":{ - "label":"value", - "description":"xy", - "column":"table1.value", - "type":"NUMBER" - } + "child": { + "ids": [ + "number" + ], + "type": "CONCEPT", + "label": "vs", + "tables": [ + { + "id": "number.number_connector", + "filters": [ + { + "filter": "number.number_connector.value", + "type": "REAL_RANGE", + "value": { + "min": 1, + "max": 1 + } + } + ] + } + ] } - ] + } + ] } - ], - "content":{ - "tables":[ - { - "csv":"tests/query/NUMBER_NEGATION/content.csv", - "name":"table1", - "primaryColumn":{ - "name":"pid", - "type":"STRING" - }, - "columns": [ + } + }, + "concepts": [ + { + "label": "number", + "type": "TREE", + "connectors": [ { - "name": "value", - "type": "REAL" - }, - { - "name": "datum", - "type": "DATE_RANGE" + "label": "number_connector", + "table": "table1", + "validityDates": { + "label": "datum", + "column": "table1.datum" + }, + "filters": { + "label": "value", + "description": "xy", + "column": "table1.value", + "type": "NUMBER" + } } ] - } - ] - } + } + ], + "content": { + "tables": [ + { + "csv": "tests/query/NUMBER_NEGATION/content.csv", + "name": "table1", + "primaryColumn": { + "name": "pid", + "type": "STRING" + }, + "columns": [ + { + "name": "value", + "type": "REAL" + }, + { + "name": "datum", + "type": "DATE_RANGE" + } + ] + } + ] + } } \ No newline at end of file diff --git a/backend/src/test/resources/tests/query/NUMBER_SEMICOLON/NUMBER.test.json b/backend/src/test/resources/tests/query/NUMBER_SEMICOLON/NUMBER.test.json index 44e8ebc0de..36906c8126 100644 --- a/backend/src/test/resources/tests/query/NUMBER_SEMICOLON/NUMBER.test.json +++ b/backend/src/test/resources/tests/query/NUMBER_SEMICOLON/NUMBER.test.json @@ -4,6 +4,9 @@ "delimeter" : ";" } }, + "sqlSpec": { + "isEnabled": false + }, "type": "QUERY_TEST", "label": "NUMBER_QUERY Test", "expectedCsv": "tests/query/NUMBER_SEMICOLON/expected.csv", diff --git a/backend/src/test/resources/tests/query/NUMBER_STRING_PARSER/NUMBER.test.json b/backend/src/test/resources/tests/query/NUMBER_STRING_PARSER/NUMBER.test.json index d5bff5538f..bae2f930e0 100644 --- a/backend/src/test/resources/tests/query/NUMBER_STRING_PARSER/NUMBER.test.json +++ b/backend/src/test/resources/tests/query/NUMBER_STRING_PARSER/NUMBER.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "STRING NUMBER PARSER Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/NUMBER_STRING_PARSER/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/NUMBER_STRING_PREFIXED_PARSER/NUMBER.test.json b/backend/src/test/resources/tests/query/NUMBER_STRING_PREFIXED_PARSER/NUMBER.test.json index 151dcdefc0..6b0f76bd31 100644 --- a/backend/src/test/resources/tests/query/NUMBER_STRING_PREFIXED_PARSER/NUMBER.test.json +++ b/backend/src/test/resources/tests/query/NUMBER_STRING_PREFIXED_PARSER/NUMBER.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "STRING NUMBER PARSER Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/NUMBER_STRING_PREFIXED_PARSER/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/QUERY_STATISTICS_TESTS/SIMPLE_TREECONCEPT_Query.json b/backend/src/test/resources/tests/query/QUERY_STATISTICS_TESTS/SIMPLE_TREECONCEPT_Query.json index cad17eed49..1af111a74b 100644 --- a/backend/src/test/resources/tests/query/QUERY_STATISTICS_TESTS/SIMPLE_TREECONCEPT_Query.json +++ b/backend/src/test/resources/tests/query/QUERY_STATISTICS_TESTS/SIMPLE_TREECONCEPT_Query.json @@ -2,6 +2,9 @@ "type": "QUERY_TEST", "label": "QUERY_STATISTICS_TESTS Test", "expectedCsv": "tests/query/QUERY_STATISTICS_TESTS/expected.csv", + "sqlSpec": { + "isEnabled": false + }, "query": { "type": "CONCEPT_QUERY", "root": { @@ -13,7 +16,7 @@ { "id": "concept.connector", "filters": [], - "selects" : [ + "selects": [ "concept.connector.date", "concept.connector.string", "concept.connector.mapped", @@ -51,7 +54,7 @@ "name": "date", "column": "table.date", "type": "DISTINCT", - "description" : "This is a Description!" + "description": "This is a Description!" }, { "name": "string", @@ -62,7 +65,7 @@ "name": "mapped", "column": "table.string", "type": "DISTINCT", - "mapping" : "mapping" + "mapping": "mapping" }, { "name": "int", diff --git a/backend/src/test/resources/tests/query/REL_EXPORT/PREREQUISITE_WITHOUT_DATES/REL_EXPORT_Query.test.json b/backend/src/test/resources/tests/query/REL_EXPORT/PREREQUISITE_WITHOUT_DATES/REL_EXPORT_Query.test.json index 5bbc1e1e24..70cf9a41dc 100644 --- a/backend/src/test/resources/tests/query/REL_EXPORT/PREREQUISITE_WITHOUT_DATES/REL_EXPORT_Query.test.json +++ b/backend/src/test/resources/tests/query/REL_EXPORT/PREREQUISITE_WITHOUT_DATES/REL_EXPORT_Query.test.json @@ -1,154 +1,158 @@ { - "type": "QUERY_TEST", - "label": "REL_EXPORT WITHOUT DATES Test", - "expectedCsv": "tests/query/REL_EXPORT/PREREQUISITE_WITHOUT_DATES/expected.csv", + "type": "QUERY_TEST", + "label": "REL_EXPORT WITHOUT DATES Test", + "expectedCsv": "tests/query/REL_EXPORT/PREREQUISITE_WITHOUT_DATES/expected.csv", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + ] + }, + "query": { + "type": "RELATIVE_FORM_QUERY", + "resolutionsAndAlignmentMap": [ + { + "resolution": "COMPLETE", + "alignment": "NO_ALIGN" + }, + { + "resolution": "YEARS", + "alignment": "QUARTER" + } + ], "query": { - "type": "RELATIVE_FORM_QUERY", - - "resolutionsAndAlignmentMap": [ - { - "resolution": "COMPLETE", - "alignment": "NO_ALIGN" - }, - { - "resolution": "YEARS", - "alignment": "QUARTER" - } + "type": "CONCEPT_QUERY", + "root": { + "type": "CONCEPT", + "ids": [ + "concept_dateless.child1" ], - "query": { - "type": "CONCEPT_QUERY", - "root": { - "type": "CONCEPT", - "ids": [ - "concept_dateless.child1" - ], - "tables": [ - { - "id": "concept_dateless.connector" - } - ] - } - }, - "features": { - "type": "ARRAY_CONCEPT_QUERY", - "childQueries": { - "type": "CONCEPT_QUERY", - "root": { - "type": "CONCEPT", - "ids": [ - "concept.child1" - ], - "selects": [ - "concept.exists" - ], - "tables": [ - { - "id": "concept.connector" - } - ] - } + "tables": [ + { + "id": "concept_dateless.connector" + } + ] + } + }, + "features": { + "type": "ARRAY_CONCEPT_QUERY", + "childQueries": { + "type": "CONCEPT_QUERY", + "root": { + "type": "CONCEPT", + "ids": [ + "concept.child1" + ], + "selects": [ + "concept.exists" + ], + "tables": [ + { + "id": "concept.connector" } + ] + } + } + }, + "indexSelector": "EARLIEST", + "indexPlacement": "BEFORE", + "timeCountBefore": 4, + "timeCountAfter": 4, + "timeUnit": "QUARTERS" + }, + "concepts": [ + { + "name": "concept", + "type": "TREE", + "connectors": { + "name": "connector", + "column": "table.column", + "validityDates": { + "label": "datum", + "column": "table.datum" + } + }, + "selects": [ + { + "type": "EXISTS", + "name": "exists" + } + ], + "children": [ + { + "label": "child1", + "description": " ", + "condition": { + "type": "PREFIX_LIST", + "prefixes": "A1" + }, + "children": [] }, - "indexSelector": "EARLIEST", - "indexPlacement": "BEFORE", - "timeCountBefore": 4, - "timeCountAfter": 4, - "timeUnit": "QUARTERS" + { + "label": "child2", + "description": " ", + "condition": { + "type": "PREFIX_LIST", + "prefixes": "B2" + }, + "children": [] + } + ] }, - "concepts": [ + { + "label": "concept_dateless", + "type": "TREE", + "connectors": { + "name": "connector", + "column": "table.column" + }, + "selects": [ { - "name": "concept", - "type": "TREE", - "connectors": { - "name": "connector", - "column": "table.column", - "validityDates": { - "label": "datum", - "column": "table.datum" - } - }, - "selects": [ - { - "type": "EXISTS", - "name": "exists" - } - ], - "children": [ - { - "label": "child1", - "description": " ", - "condition": { - "type": "PREFIX_LIST", - "prefixes": "A1" - }, - "children": [] - }, - { - "label": "child2", - "description": " ", - "condition": { - "type": "PREFIX_LIST", - "prefixes": "B2" - }, - "children": [] - } - ] + "type": "EXISTS", + "name": "exists" + } + ], + "children": [ + { + "label": "child1", + "description": " ", + "condition": { + "type": "PREFIX_LIST", + "prefixes": "A1" + }, + "children": [] }, { - "label": "concept_dateless", - "type": "TREE", - "connectors": { - "name": "connector", - "column": "table.column" - }, - "selects": [ - { - "type": "EXISTS", - "name": "exists" - } - ], - "children": [ - { - "label": "child1", - "description": " ", - "condition": { - "type": "PREFIX_LIST", - "prefixes": "A1" - }, - "children": [] - }, - { - "label": "child2", - "description": " ", - "condition": { - "type": "PREFIX_LIST", - "prefixes": "B2" - }, - "children": [] - } - ] + "label": "child2", + "description": " ", + "condition": { + "type": "PREFIX_LIST", + "prefixes": "B2" + }, + "children": [] } - ], - "content": { - "tables": [ - { - "csv": "tests/query/REL_EXPORT/PREREQUISITE_WITHOUT_DATES/content.csv", - "name": "table", - "primaryColumn": { - "name": "pid", - "type": "STRING" - }, - "columns": [ - { - "name": "datum", - "type": "DATE" - }, - { - "name": "column", - "type": "STRING" - } - ] - } - ] + ] } + ], + "content": { + "tables": [ + { + "csv": "tests/query/REL_EXPORT/PREREQUISITE_WITHOUT_DATES/content.csv", + "name": "table", + "primaryColumn": { + "name": "pid", + "type": "STRING" + }, + "columns": [ + { + "name": "datum", + "type": "DATE" + }, + { + "name": "column", + "type": "STRING" + } + ] + } + ] + } } \ No newline at end of file diff --git a/backend/src/test/resources/tests/query/REUSED_QUERY/REUSED_Query.test.json b/backend/src/test/resources/tests/query/REUSED_QUERY/REUSED_Query.test.json index fca4406e36..94935042b7 100644 --- a/backend/src/test/resources/tests/query/REUSED_QUERY/REUSED_Query.test.json +++ b/backend/src/test/resources/tests/query/REUSED_QUERY/REUSED_Query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "REUSED_QUERY Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/REUSED_QUERY/expected.csv", "query": { "type": "CONCEPT_QUERY", @@ -10,39 +16,7 @@ } }, "concepts": [ - { - "label": "test_tree", - "type": "TREE", - "connectors": { - "label": "tree_label", - "name": "test_column", - "column": "test_table.test_column", - "validityDates": { - "label": "datum", - "column": "test_table.datum" - } - }, - "children": [ - { - "label": "test_child1", - "description": " ", - "condition": { - "type": "PREFIX_LIST", - "prefixes": "A1" - }, - "children": [] - }, - { - "label": "test_child2", - "description": " ", - "condition": { - "type": "PREFIX_LIST", - "prefixes": "B2" - }, - "children": [] - } - ] - } + ], "content": { "tables": [ @@ -55,11 +29,7 @@ }, "columns": [ { - "name": "datum", - "type": "DATE" - }, - { - "name": "test_column", + "name": "empty_column", "type": "STRING" } ] diff --git a/backend/src/test/resources/tests/query/REUSED_QUERY/content.csv b/backend/src/test/resources/tests/query/REUSED_QUERY/content.csv index 6d8efde058..781a199354 100644 --- a/backend/src/test/resources/tests/query/REUSED_QUERY/content.csv +++ b/backend/src/test/resources/tests/query/REUSED_QUERY/content.csv @@ -1,22 +1,22 @@ -pid,datum,test_column -15,2001-01-01,a -2,2001-01-01,a -5,2001-01-01,a -6,2001-01-01,a -27,2001-01-01,a -31,2001-01-01,a -32,2001-01-01,a -40,2001-01-01,a -58,2001-01-01,a -64,2001-01-01,a -68,2001-01-01,a -9978,2001-01-01,a -9977,2001-01-01,a -9974,2001-01-01,a -9969,2001-01-01,a -9962,2001-01-01,a -9944,2001-01-01,a -9926,2001-01-01,a -9896,2001-01-01,a -9893,2001-01-01,a -9886,2001-01-01,a \ No newline at end of file +pid,empty_column +15, +2, +5, +6, +27, +31, +32, +40, +58, +64, +68, +9978, +9977, +9974, +9969, +9962, +9944, +9926, +9896, +9893, +9886, \ No newline at end of file diff --git a/backend/src/test/resources/tests/query/SECONDARY_ID/SECONDARY_IDS.test.json b/backend/src/test/resources/tests/query/SECONDARY_ID/SECONDARY_IDS.test.json index 2fbdf0b287..f6aaec366e 100644 --- a/backend/src/test/resources/tests/query/SECONDARY_ID/SECONDARY_IDS.test.json +++ b/backend/src/test/resources/tests/query/SECONDARY_ID/SECONDARY_IDS.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "SECONDARY_ID Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/SECONDARY_ID/expected.csv", "query": { "type": "SECONDARY_ID_QUERY", diff --git a/backend/src/test/resources/tests/query/SECONDARY_ID_DATEMODE_LOGICAL/SECONDARY_IDS.test.json b/backend/src/test/resources/tests/query/SECONDARY_ID_DATEMODE_LOGICAL/SECONDARY_IDS.test.json index 9b3c11e0c8..65a834c256 100644 --- a/backend/src/test/resources/tests/query/SECONDARY_ID_DATEMODE_LOGICAL/SECONDARY_IDS.test.json +++ b/backend/src/test/resources/tests/query/SECONDARY_ID_DATEMODE_LOGICAL/SECONDARY_IDS.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "SECONDARY_ID Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/SECONDARY_ID_DATEMODE_LOGICAL/expected.csv", "query": { "type": "SECONDARY_ID_QUERY", diff --git a/backend/src/test/resources/tests/query/SECONDARY_ID_EXCLUDED/SECONDARY_IDS_EXCLUDED.test.json b/backend/src/test/resources/tests/query/SECONDARY_ID_EXCLUDED/SECONDARY_IDS_EXCLUDED.test.json index 43dced8cbe..4946887995 100644 --- a/backend/src/test/resources/tests/query/SECONDARY_ID_EXCLUDED/SECONDARY_IDS_EXCLUDED.test.json +++ b/backend/src/test/resources/tests/query/SECONDARY_ID_EXCLUDED/SECONDARY_IDS_EXCLUDED.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "SECONDARY_ID_EXCLUDED Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/SECONDARY_ID_EXCLUDED/expected.csv", "query": { "type": "SECONDARY_ID_QUERY", diff --git a/backend/src/test/resources/tests/query/SECONDARY_ID_EXTERNAL_LOGICAL/SECONDARY_IDS.test.json b/backend/src/test/resources/tests/query/SECONDARY_ID_EXTERNAL_LOGICAL/SECONDARY_IDS.test.json index 518c0df3be..d9949527da 100644 --- a/backend/src/test/resources/tests/query/SECONDARY_ID_EXTERNAL_LOGICAL/SECONDARY_IDS.test.json +++ b/backend/src/test/resources/tests/query/SECONDARY_ID_EXTERNAL_LOGICAL/SECONDARY_IDS.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "SECONDARY_ID Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/SECONDARY_ID_EXTERNAL_LOGICAL/expected.csv", "query": { "type": "SECONDARY_ID_QUERY", diff --git a/backend/src/test/resources/tests/query/SECONDARY_ID_MIXED/SECONDARY_IDS_MIXED.test.json b/backend/src/test/resources/tests/query/SECONDARY_ID_MIXED/SECONDARY_IDS_MIXED.test.json index 7e2c2190b8..fa1d2ced8d 100644 --- a/backend/src/test/resources/tests/query/SECONDARY_ID_MIXED/SECONDARY_IDS_MIXED.test.json +++ b/backend/src/test/resources/tests/query/SECONDARY_ID_MIXED/SECONDARY_IDS_MIXED.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "SECONDARY_ID_MIXED Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/SECONDARY_ID_MIXED/expected.csv", "query": { "type": "SECONDARY_ID_QUERY", diff --git a/backend/src/test/resources/tests/query/SIMPLE_CQEXTERNAL_QUERY/SIMPLE_CQEXTERNAL_QUERY.test.json b/backend/src/test/resources/tests/query/SIMPLE_CQEXTERNAL_QUERY/SIMPLE_CQEXTERNAL_QUERY.test.json index 75dce85ed8..5174e6edfb 100644 --- a/backend/src/test/resources/tests/query/SIMPLE_CQEXTERNAL_QUERY/SIMPLE_CQEXTERNAL_QUERY.test.json +++ b/backend/src/test/resources/tests/query/SIMPLE_CQEXTERNAL_QUERY/SIMPLE_CQEXTERNAL_QUERY.test.json @@ -1,49 +1,68 @@ { - "type": "QUERY_TEST", - "label": "SIMPLE_CQEXTERNAL_QUERY Test", - "expectedCsv": "tests/query/SIMPLE_CQEXTERNAL_QUERY/expected.csv", - "query": { - "type": "CONCEPT_QUERY", - "root": { - "type": "EXTERNAL", - "format": [ - "ID","EVENT_DATE" - ], - "values": [ - ["result","dates"], - [1,"2012-01-01"], - [3,"2013-11-10"] - ] - } - }, - "concepts": [ - { - "label": "test_tree", - "type":"TREE", - "connectors": { - "label": "tree_label", - "name": "test_concept", - "table": "test_table", - "validityDates": {"label": "datum" ,"column": "test_table.datum"} - } + "type": "QUERY_TEST", + "label": "SIMPLE_CQEXTERNAL_QUERY Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, + "expectedCsv": "tests/query/SIMPLE_CQEXTERNAL_QUERY/expected.csv", + "query": { + "type": "CONCEPT_QUERY", + "root": { + "type": "EXTERNAL", + "format": [ + "ID", + "EVENT_DATE" + ], + "values": [ + [ + "result", + "dates" + ], + [ + 1, + "2012-01-01" + ], + [ + 3, + "2013-11-10" + ] + ] + } + }, + "concepts": [ + { + "label": "test_tree", + "type": "TREE", + "connectors": { + "label": "tree_label", + "name": "test_concept", + "table": "test_table", + "validityDates": { + "label": "datum", + "column": "test_table.datum" } - ], - "content": { - "tables": [ - { - "csv": "tests/query/SIMPLE_CQEXTERNAL_QUERY/content.csv", - "name": "test_table", - "primaryColumn" : { - "name": "pid", - "type": "STRING" - }, - "columns": [ - { - "name": "datum", - "type": "DATE" - } - ] - } - ] + } } + ], + "content": { + "tables": [ + { + "csv": "tests/query/SIMPLE_CQEXTERNAL_QUERY/content.csv", + "name": "test_table", + "primaryColumn": { + "name": "pid", + "type": "STRING" + }, + "columns": [ + { + "name": "datum", + "type": "DATE" + } + ] + } + ] + } } diff --git a/backend/src/test/resources/tests/query/SIMPLE_CQEXTERNAL_QUERY/SIMPLE_CQEXTERNAL_QUERY_START_END.test.json b/backend/src/test/resources/tests/query/SIMPLE_CQEXTERNAL_QUERY/SIMPLE_CQEXTERNAL_QUERY_START_END.test.json index de24f8f045..46cb3d2421 100644 --- a/backend/src/test/resources/tests/query/SIMPLE_CQEXTERNAL_QUERY/SIMPLE_CQEXTERNAL_QUERY_START_END.test.json +++ b/backend/src/test/resources/tests/query/SIMPLE_CQEXTERNAL_QUERY/SIMPLE_CQEXTERNAL_QUERY_START_END.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "SIMPLE_CQEXTERNAL_QUERY Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/SIMPLE_CQEXTERNAL_QUERY/expected_start_end.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/SIMPLE_TREECONCEPT_GROOVY_QUERY/SIMPLE_TREECONCEPT_GROOVY_Query_groovy.test.json b/backend/src/test/resources/tests/query/SIMPLE_TREECONCEPT_GROOVY_QUERY/SIMPLE_TREECONCEPT_GROOVY_Query_groovy.test.json index e61362405c..90be0925b7 100644 --- a/backend/src/test/resources/tests/query/SIMPLE_TREECONCEPT_GROOVY_QUERY/SIMPLE_TREECONCEPT_GROOVY_Query_groovy.test.json +++ b/backend/src/test/resources/tests/query/SIMPLE_TREECONCEPT_GROOVY_QUERY/SIMPLE_TREECONCEPT_GROOVY_Query_groovy.test.json @@ -1,79 +1,95 @@ { - "type": "QUERY_TEST", - "label": "SIMPLE_TREECONCEPT_GROOVY_QUERY Test", - "expectedCsv": "tests/query/SIMPLE_TREECONCEPT_GROOVY_QUERY/expected.csv", - "query": { - "type": "CONCEPT_QUERY", - "root": { - "type": "CONCEPT", - "ids": [ - "test_tree.test_child1.test_child1_1" - ], - "label": "test_child1_1", - "tables": [ - { - "id": "test_tree.test_column", - "filters": [] - } - ] + "type": "QUERY_TEST", + "label": "SIMPLE_TREECONCEPT_GROOVY_QUERY Test", + "expectedCsv": "tests/query/SIMPLE_TREECONCEPT_GROOVY_QUERY/expected.csv", + "sqlSpec": { + "isEnabled": false + }, + "query": { + "type": "CONCEPT_QUERY", + "root": { + "type": "CONCEPT", + "ids": [ + "test_tree.test_child1.test_child1_1" + ], + "label": "test_child1_1", + "tables": [ + { + "id": "test_tree.test_column", + "filters": [] + } + ] + } + }, + "concepts": [ + { + "label": "test_tree", + "type": "TREE", + "connectors": { + "label": "tree_label", + "name": "test_column", + "column": "test_table_groovy.test_column", + "validityDates": { + "label": "datum", + "column": "test_table_groovy.datum" } - }, - "concepts": [ + }, + "children": [ + { + "label": "test_child1", + "description": " ", + "condition": { + "type": "GROOVY", + "script": "row['groovy_column']==1" + }, + "children": [ + { + "label": "test_child1_1", + "description": " ", + "condition": { + "type": "PREFIX_LIST", + "prefixes": "2" + }, + "children": [] + } + ] + }, { - "label": "test_tree", - "type":"TREE", - "connectors": { - "label": "tree_label", - "name": "test_column", - "column": "test_table_groovy.test_column", - "validityDates": {"label": "datum" ,"column": "test_table_groovy.datum"} - }, - "children": [ - { - "label": "test_child1", - "description": " ", - "condition": {"type": "GROOVY", "script": "row['groovy_column']==1"}, - "children": [ - { - "label": "test_child1_1", - "description": " ", - "condition": {"type": "PREFIX_LIST", "prefixes": "2"}, - "children": [] - }] - }, - { - "label": "test_child2", - "description": " ", - "condition": {"type": "PREFIX_LIST", "prefixes": "3"}, - "children": [] - } - ] + "label": "test_child2", + "description": " ", + "condition": { + "type": "PREFIX_LIST", + "prefixes": "3" + }, + "children": [] } - ], - "content": { - "tables": [ - { - "csv": "tests/query/SIMPLE_TREECONCEPT_GROOVY_QUERY/content.csv", - "name": "test_table_groovy", - "primaryColumn": { - "name": "pid", - "type": "STRING" - }, - "columns": [ - { - "name": "datum", - "type": "DATE" - }, - { - "name": "test_column", - "type": "STRING" - }, - { - "name": "groovy_column", - "type": "INTEGER" - } - ] - } - ] + ] } + ], + "content": { + "tables": [ + { + "csv": "tests/query/SIMPLE_TREECONCEPT_GROOVY_QUERY/content.csv", + "name": "test_table_groovy", + "primaryColumn": { + "name": "pid", + "type": "STRING" + }, + "columns": [ + { + "name": "datum", + "type": "DATE" + }, + { + "name": "test_column", + "type": "STRING" + }, + { + "name": "groovy_column", + "type": "INTEGER" + } + ] + } + ] + } } diff --git a/backend/src/test/resources/tests/query/SUM_EMPTY_DATE_CONCEPT_QUERY/SUM_EMPTY_DATE_CONCEPT_QUERY.test.json b/backend/src/test/resources/tests/query/SUM_EMPTY_DATE_CONCEPT_QUERY/SUM_EMPTY_DATE_CONCEPT_QUERY.test.json index 7389547f56..58baa2536b 100644 --- a/backend/src/test/resources/tests/query/SUM_EMPTY_DATE_CONCEPT_QUERY/SUM_EMPTY_DATE_CONCEPT_QUERY.test.json +++ b/backend/src/test/resources/tests/query/SUM_EMPTY_DATE_CONCEPT_QUERY/SUM_EMPTY_DATE_CONCEPT_QUERY.test.json @@ -1,88 +1,92 @@ -{ - "type":"QUERY_TEST", - "label":"SUM_EMPTY_DATE_CONCEPT_QUERY Test", - "expectedCsv":"tests/query/SUM_EMPTY_DATE_CONCEPT_QUERY/expected.csv", - "query":{ - "type":"CONCEPT_QUERY", +{ + "type": "QUERY_TEST", + "label": "SUM_EMPTY_DATE_CONCEPT_QUERY Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, + "expectedCsv": "tests/query/SUM_EMPTY_DATE_CONCEPT_QUERY/expected.csv", + "query": { + "type": "CONCEPT_QUERY", "root": { "type": "AND", "children": [ { - "type":"DATE_RESTRICTION", - "dateRange":{ - "min":"2010-01-01", - "max":"2010-01-31" - }, - "child":{ - - "ids":[ - "sum" - ], - "type":"CONCEPT", - "label":"vs", - "tables":[ - { - "id":"sum.sum_connector", - "filters":[ - { - "filter":"sum.sum_connector.value", - "type":"REAL_RANGE", - "value":{ - "min": 2, - "max": 2 - } - } - ] - } - ] - - } - } - ] - } - }, - "concepts":[ - { - "label":"sum", - "type":"TREE", - "connectors":[ - { - "label":"sum_connector", - "table":"table1", - "validityDates":{ - "label":"datum", - "column":"table1.datum" - }, - "filters":{ - "label":"value", - "description":"xy", - "column":"table1.value", - "type":"SUM" - } - } - ] - } - ], - "content":{ - "tables":[ - { - "csv":"tests/query/SUM_EMPTY_DATE_CONCEPT_QUERY/content.csv", - "name":"table1", - "primaryColumn":{ - "name":"pid", - "type":"STRING" - }, - "columns": [ - { - "name": "value", - "type": "REAL" - }, - { - "name": "datum", - "type": "DATE" + "type": "DATE_RESTRICTION", + "dateRange": { + "min": "2010-01-01", + "max": "2010-01-31" + }, + "child": { + "ids": [ + "sum" + ], + "type": "CONCEPT", + "label": "vs", + "tables": [ + { + "id": "sum.sum_connector", + "filters": [ + { + "filter": "sum.sum_connector.value", + "type": "REAL_RANGE", + "value": { + "min": 2, + "max": 2 + } + } + ] + } + ] + } } ] - } + } + }, + "concepts": [ + { + "label": "sum", + "type": "TREE", + "connectors": [ + { + "label": "sum_connector", + "table": "table1", + "validityDates": { + "label": "datum", + "column": "table1.datum" + }, + "filters": { + "label": "value", + "description": "xy", + "column": "table1.value", + "type": "SUM" + } + } ] - } + } + ], + "content": { + "tables": [ + { + "csv": "tests/query/SUM_EMPTY_DATE_CONCEPT_QUERY/content.csv", + "name": "table1", + "primaryColumn": { + "name": "pid", + "type": "STRING" + }, + "columns": [ + { + "name": "value", + "type": "REAL" + }, + { + "name": "datum", + "type": "DATE" + } + ] + } + ] + } } \ No newline at end of file diff --git a/backend/src/test/resources/tests/query/TABLE_EXPORT/RAW_TABLE_EXPORT.test.json b/backend/src/test/resources/tests/query/TABLE_EXPORT/RAW_TABLE_EXPORT.test.json index bf49129fca..2a8be93bcb 100644 --- a/backend/src/test/resources/tests/query/TABLE_EXPORT/RAW_TABLE_EXPORT.test.json +++ b/backend/src/test/resources/tests/query/TABLE_EXPORT/RAW_TABLE_EXPORT.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "RAW_TABLE_EXPORT Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TABLE_EXPORT/raw_expected.csv", "query": { "type": "TABLE_EXPORT", diff --git a/backend/src/test/resources/tests/query/TABLE_EXPORT/TABLE_EXPORT.test.json b/backend/src/test/resources/tests/query/TABLE_EXPORT/TABLE_EXPORT.test.json index 4b78d2cf0b..d1917c2762 100644 --- a/backend/src/test/resources/tests/query/TABLE_EXPORT/TABLE_EXPORT.test.json +++ b/backend/src/test/resources/tests/query/TABLE_EXPORT/TABLE_EXPORT.test.json @@ -1,6 +1,9 @@ { "type": "QUERY_TEST", "label": "TABLE_EXPORT Test", + "sqlSpec": { + "isEnabled": false + }, "expectedCsv": "tests/query/TABLE_EXPORT/expected.csv", "query": { "type": "TABLE_EXPORT", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ALL/ALL/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ALL/ALL/query.test.json index 57767bcbc3..25a2627e97 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ALL/ALL/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ALL/ALL/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/AFTER/ALL/ALL/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ALL/ANY/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ALL/ANY/query.test.json index bb52bac3f9..0c4505974a 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ALL/ANY/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ALL/ANY/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/AFTER/ALL/ANY/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ALL/EARLIEST/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ALL/EARLIEST/query.test.json index 5fdbd0a145..85f8d795d4 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ALL/EARLIEST/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ALL/EARLIEST/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/AFTER/ALL/EARLIEST/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ALL/LATEST/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ALL/LATEST/query.test.json index 84f2ccb6a8..9b984b15f6 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ALL/LATEST/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ALL/LATEST/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/AFTER/ALL/LATEST/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ANY/ALL/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ANY/ALL/query.test.json index ec3ba982fd..01259b2214 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ANY/ALL/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ANY/ALL/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/AFTER/ANY/ALL/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ANY/ANY/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ANY/ANY/query.test.json index b0f835ae0b..d8d334398c 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ANY/ANY/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ANY/ANY/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/AFTER/ANY/ANY/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ANY/EARLIEST/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ANY/EARLIEST/query.test.json index bd8d24182a..a957f63754 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ANY/EARLIEST/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ANY/EARLIEST/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/AFTER/ANY/EARLIEST/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ANY/LATEST/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ANY/LATEST/query.test.json index 209696169a..6873fc1594 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ANY/LATEST/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/ANY/LATEST/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/AFTER/ANY/LATEST/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/EARLIEST/ALL/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/EARLIEST/ALL/query.test.json index 83e136bdeb..bc4dc58248 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/EARLIEST/ALL/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/EARLIEST/ALL/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/AFTER/EARLIEST/ALL/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/EARLIEST/ANY/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/EARLIEST/ANY/query.test.json index ff8aa62147..d04770c5a8 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/EARLIEST/ANY/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/EARLIEST/ANY/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/AFTER/EARLIEST/ANY/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/EARLIEST/EARLIEST/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/EARLIEST/EARLIEST/query.test.json index 078daf8bf2..8284fa8992 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/EARLIEST/EARLIEST/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/EARLIEST/EARLIEST/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/AFTER/EARLIEST/EARLIEST/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/EARLIEST/LATEST/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/EARLIEST/LATEST/query.test.json index 9c324657a4..1229e6c11a 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/EARLIEST/LATEST/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/EARLIEST/LATEST/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/AFTER/EARLIEST/LATEST/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/LATEST/ALL/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/LATEST/ALL/query.test.json index 4a73d0b8a7..e39034076d 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/LATEST/ALL/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/LATEST/ALL/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/AFTER/LATEST/ALL/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/LATEST/ANY/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/LATEST/ANY/query.test.json index 3df802237c..59c7c11de8 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/LATEST/ANY/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/LATEST/ANY/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/AFTER/LATEST/ANY/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/LATEST/EARLIEST/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/LATEST/EARLIEST/query.test.json index 992fc11e69..c189fb5be6 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/LATEST/EARLIEST/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/LATEST/EARLIEST/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/AFTER/LATEST/EARLIEST/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/LATEST/LATEST/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/LATEST/LATEST/query.test.json index 596963b111..0cc099fbbe 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/AFTER/LATEST/LATEST/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/AFTER/LATEST/LATEST/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/AFTER/LATEST/LATEST/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/AGGREGATION/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/AGGREGATION/query.test.json index 765db5128c..57acb351a8 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/AGGREGATION/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/AGGREGATION/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/AGGREGATION/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ALL/ALL/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ALL/ALL/query.test.json index e661dcdf12..6c1ed4b11d 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ALL/ALL/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ALL/ALL/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/BEFORE/ALL/ALL/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ALL/ANY/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ALL/ANY/query.test.json index f04609be34..b9a2b278be 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ALL/ANY/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ALL/ANY/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/BEFORE/ALL/ANY/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ALL/EARLIEST/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ALL/EARLIEST/query.test.json index d7a0666d05..ad71445d22 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ALL/EARLIEST/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ALL/EARLIEST/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/BEFORE/ALL/EARLIEST/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ALL/LATEST/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ALL/LATEST/query.test.json index d6d6f72a54..2b7f905ca6 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ALL/LATEST/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ALL/LATEST/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/BEFORE/ALL/LATEST/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ANY/ALL/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ANY/ALL/query.test.json index 1db373a844..36b3f6ab8a 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ANY/ALL/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ANY/ALL/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/BEFORE/ANY/ALL/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ANY/ANY/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ANY/ANY/query.test.json index 5c155fc89b..6772cf2426 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ANY/ANY/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ANY/ANY/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/BEFORE/ANY/ANY/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ANY/EARLIEST/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ANY/EARLIEST/query.test.json index 51bb1e5039..c54e4aafee 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ANY/EARLIEST/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ANY/EARLIEST/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/BEFORE/ANY/EARLIEST/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ANY/LATEST/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ANY/LATEST/query.test.json index a5282ab55a..52fa609a09 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ANY/LATEST/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/ANY/LATEST/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/BEFORE/ANY/LATEST/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/EARLIEST/ALL/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/EARLIEST/ALL/query.test.json index bcae176190..3bafde26de 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/EARLIEST/ALL/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/EARLIEST/ALL/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/BEFORE/EARLIEST/ALL/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/EARLIEST/ANY/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/EARLIEST/ANY/query.test.json index be220fb041..87b4e51e3f 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/EARLIEST/ANY/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/EARLIEST/ANY/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/BEFORE/EARLIEST/ANY/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/EARLIEST/EARLIEST/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/EARLIEST/EARLIEST/query.test.json index f8d566bce7..6fb1ed76d1 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/EARLIEST/EARLIEST/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/EARLIEST/EARLIEST/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/BEFORE/EARLIEST/EARLIEST/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/EARLIEST/LATEST/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/EARLIEST/LATEST/query.test.json index 0127dffda1..a139f74c9c 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/EARLIEST/LATEST/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/EARLIEST/LATEST/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/BEFORE/EARLIEST/LATEST/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/LATEST/ALL/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/LATEST/ALL/query.test.json index 28ccf30568..afa2865beb 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/LATEST/ALL/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/LATEST/ALL/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/BEFORE/LATEST/ALL/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/LATEST/ANY/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/LATEST/ANY/query.test.json index d50ec241b0..a5df8a7379 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/LATEST/ANY/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/LATEST/ANY/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/BEFORE/LATEST/ANY/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/LATEST/EARLIEST/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/LATEST/EARLIEST/query.test.json index 44c6020c8f..f670bcf591 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/LATEST/EARLIEST/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/LATEST/EARLIEST/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/BEFORE/LATEST/EARLIEST/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/LATEST/LATEST/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/LATEST/LATEST/query.test.json index 2c6797b80f..82ee9004ba 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/LATEST/LATEST/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/BEFORE/LATEST/LATEST/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/BEFORE/LATEST/LATEST/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ALL/ALL/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ALL/ALL/query.test.json index 172312efff..73ce24ef71 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ALL/ALL/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ALL/ALL/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/WHILE/ALL/ALL/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ALL/ANY/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ALL/ANY/query.test.json index 1e8110c55b..600ef55cdd 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ALL/ANY/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ALL/ANY/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/WHILE/ALL/ANY/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ALL/EARLIEST/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ALL/EARLIEST/query.test.json index fdc86b3fdd..38cc7d9d0d 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ALL/EARLIEST/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ALL/EARLIEST/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/WHILE/ALL/EARLIEST/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ALL/LATEST/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ALL/LATEST/query.test.json index 055502d1c1..06de13d9ea 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ALL/LATEST/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ALL/LATEST/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/WHILE/ALL/LATEST/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ANY/ALL/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ANY/ALL/query.test.json index 49152e42c9..3bb02194d6 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ANY/ALL/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ANY/ALL/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/WHILE/ANY/ALL/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ANY/ANY/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ANY/ANY/query.test.json index 44b4698706..c2e019e76a 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ANY/ANY/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ANY/ANY/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/WHILE/ANY/ANY/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ANY/EARLIEST/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ANY/EARLIEST/query.test.json index c512696a19..8c967c362c 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ANY/EARLIEST/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ANY/EARLIEST/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/WHILE/ANY/EARLIEST/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ANY/LATEST/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ANY/LATEST/query.test.json index 123e99ccfb..b2afa17da1 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ANY/LATEST/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/ANY/LATEST/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/WHILE/ANY/LATEST/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/EARLIEST/ALL/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/EARLIEST/ALL/query.test.json index 2d8a3c88b8..43bc76f200 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/EARLIEST/ALL/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/EARLIEST/ALL/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/WHILE/EARLIEST/ALL/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/EARLIEST/ANY/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/EARLIEST/ANY/query.test.json index 5aac7f92e7..de4af3c533 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/EARLIEST/ANY/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/EARLIEST/ANY/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/WHILE/EARLIEST/ANY/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/EARLIEST/EARLIEST/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/EARLIEST/EARLIEST/query.test.json index 96df1837a8..f752a2ea65 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/EARLIEST/EARLIEST/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/EARLIEST/EARLIEST/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/WHILE/EARLIEST/EARLIEST/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/EARLIEST/LATEST/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/EARLIEST/LATEST/query.test.json index d7831a694a..a978c71772 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/EARLIEST/LATEST/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/EARLIEST/LATEST/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/WHILE/EARLIEST/LATEST/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/LATEST/ALL/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/LATEST/ALL/query.test.json index 0f8daa14e2..b1d36ab1f5 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/LATEST/ALL/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/LATEST/ALL/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/WHILE/LATEST/ALL/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/LATEST/ANY/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/LATEST/ANY/query.test.json index 1c8e5abac2..fd250e630b 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/LATEST/ANY/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/LATEST/ANY/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/WHILE/LATEST/ANY/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/LATEST/EARLIEST/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/LATEST/EARLIEST/query.test.json index f026efef99..e9cfbb4626 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/LATEST/EARLIEST/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/LATEST/EARLIEST/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/WHILE/LATEST/EARLIEST/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/LATEST/LATEST/query.test.json b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/LATEST/LATEST/query.test.json index 3cae5f7c40..57c1595e82 100644 --- a/backend/src/test/resources/tests/query/TEMPORAL/WHILE/LATEST/LATEST/query.test.json +++ b/backend/src/test/resources/tests/query/TEMPORAL/WHILE/LATEST/LATEST/query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "Temporal Test", + "sqlSpec": { + "isEnabled": false, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/TEMPORAL/WHILE/LATEST/LATEST/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/query/VIRTUAL_CONCEPT_REUSED_QUERY/VIRTUAL_CONCEPT_REUSED_Query.test.json b/backend/src/test/resources/tests/query/VIRTUAL_CONCEPT_REUSED_QUERY/VIRTUAL_CONCEPT_REUSED_Query.test.json index 9ad5747ddf..1571d2808f 100644 --- a/backend/src/test/resources/tests/query/VIRTUAL_CONCEPT_REUSED_QUERY/VIRTUAL_CONCEPT_REUSED_Query.test.json +++ b/backend/src/test/resources/tests/query/VIRTUAL_CONCEPT_REUSED_QUERY/VIRTUAL_CONCEPT_REUSED_Query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "VIRTUAL_CONCEPT_REUSED_QUERY Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/query/VIRTUAL_CONCEPT_REUSED_QUERY/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/sql/selects/first/FIRST_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json b/backend/src/test/resources/tests/sql/selects/first/FIRST_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json index a49f1cfca3..7aba42855a 100644 --- a/backend/src/test/resources/tests/sql/selects/first/FIRST_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json +++ b/backend/src/test/resources/tests/sql/selects/first/FIRST_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "FIRST_AGGREGATOR Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/sql/selects/first/FIRST_AGGREGATOR/expected.csv", "query": { "type": "CONCEPT_QUERY", @@ -32,7 +38,7 @@ "column": "table.datum" }, "selects": { - "name" : "select", + "name": "select", "type": "FIRST", "column": "table.value" } diff --git a/backend/src/test/resources/tests/sql/selects/first/LAST_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json b/backend/src/test/resources/tests/sql/selects/first/LAST_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json index cdd9f58798..8a8fbd524e 100644 --- a/backend/src/test/resources/tests/sql/selects/first/LAST_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json +++ b/backend/src/test/resources/tests/sql/selects/first/LAST_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json @@ -1,6 +1,12 @@ { "type": "QUERY_TEST", "label": "LAST_AGGREGATOR Test", + "sqlSpec": { + "isEnabled": true, + "supportedDialects": [ + "POSTGRESQL" + ] + }, "expectedCsv": "tests/sql/selects/first/LAST_AGGREGATOR/expected.csv", "query": { "type": "CONCEPT_QUERY", diff --git a/backend/src/test/resources/tests/sql/yes/no-op.csv b/backend/src/test/resources/tests/sql/yes/no-op.csv deleted file mode 100644 index d9a4329883..0000000000 --- a/backend/src/test/resources/tests/sql/yes/no-op.csv +++ /dev/null @@ -1,2 +0,0 @@ -pid,datum -irrelevant_id_for_cqyes,2013-11-10 From 07956fee36cbaebb119367a5713727dbfd7314fe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 May 2026 11:35:34 +0200 Subject: [PATCH 2/8] Bump axios from 1.15.0 to 1.16.0 in /frontend (#3888) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- frontend/package-lock.json | 16 ++++++++-------- frontend/package.json | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 7346c1329c..9889042a89 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -23,7 +23,7 @@ "@vitejs/plugin-react": "^4.4.1", "apache-arrow": "^17.0.0", "autoprefixer": "^10.4.19", - "axios": "^1.15.0", + "axios": "^1.16.0", "chance": "^1.1.11", "chart.js": "^4.4.4", "compression": "^1.7.4", @@ -4980,12 +4980,12 @@ } }, "node_modules/axios": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.0.tgz", - "integrity": "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.16.0.tgz", + "integrity": "sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==", "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.11", + "follow-redirects": "^1.16.0", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" } @@ -7174,9 +7174,9 @@ "license": "ISC" }, "node_modules/follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", "funding": [ { "type": "individual", diff --git a/frontend/package.json b/frontend/package.json index b8c55f6b4d..1901937fc9 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -37,7 +37,7 @@ "@vitejs/plugin-react": "^4.4.1", "apache-arrow": "^17.0.0", "autoprefixer": "^10.4.19", - "axios": "^1.15.0", + "axios": "^1.16.0", "chance": "^1.1.11", "chart.js": "^4.4.4", "compression": "^1.7.4", From 483476bf73a83eb50447e4b59f5e4baa566ecbfa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 May 2026 05:31:17 +0000 Subject: [PATCH 3/8] Bump @tootallnate/once from 2.0.0 to 2.0.1 in /frontend Bumps [@tootallnate/once](https://github.com/TooTallNate/once) from 2.0.0 to 2.0.1. - [Release notes](https://github.com/TooTallNate/once/releases) - [Changelog](https://github.com/TooTallNate/once/blob/v2.0.1/CHANGELOG.md) - [Commits](https://github.com/TooTallNate/once/compare/2.0.0...v2.0.1) --- updated-dependencies: - dependency-name: "@tootallnate/once" dependency-version: 2.0.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- frontend/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 9889042a89..fcdc4a5ab4 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -3590,9 +3590,9 @@ } }, "node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.1.tgz", + "integrity": "sha512-HqmEUIGRJ5fSXchkVgR5F7qn48bDBzv0kWj/Kfu5e6uci4UlEeng4331LnBkWffb++Ei3FOVLxo8JJWMFBDMeQ==", "dev": true, "license": "MIT", "engines": { From d086f06429a66fe896fab0beaa4b2ac97ccc2d09 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 May 2026 09:22:35 +0000 Subject: [PATCH 4/8] Bump alpine/git from 2.52.0 to v2.52.0 Bumps alpine/git from 2.52.0 to v2.52.0. --- updated-dependencies: - dependency-name: alpine/git dependency-version: v2.52.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- backend.Dockerfile | 2 +- frontend.Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend.Dockerfile b/backend.Dockerfile index 25a6f69eae..35272b989a 100644 --- a/backend.Dockerfile +++ b/backend.Dockerfile @@ -1,5 +1,5 @@ # Version Extractor -FROM alpine/git:2.52.0 AS version-extractor +FROM alpine/git:v2.52.0 AS version-extractor WORKDIR /app COPY .git . diff --git a/frontend.Dockerfile b/frontend.Dockerfile index 3060e59906..aa25d60b5e 100644 --- a/frontend.Dockerfile +++ b/frontend.Dockerfile @@ -1,5 +1,5 @@ # Version Extractor -FROM alpine/git:2.52.0@sha256:d453f54c83320412aa89c391b076930bd8569bc1012285e8c68ce2d4435826a3 AS version-extractor +FROM alpine/git:v2.52.0@sha256:3136372ed3c9e112d5a2620c66a6803e1b0b7f14a428fcbd0c5028bec4256430 AS version-extractor WORKDIR /app COPY .git . From 5371287fda8a474babea7d17c66124199a44b007 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 May 2026 09:03:17 +0000 Subject: [PATCH 5/8] Bump nginxinc/nginx-unprivileged from 1.29-alpine to 1.31-alpine Bumps nginxinc/nginx-unprivileged from 1.29-alpine to 1.31-alpine. --- updated-dependencies: - dependency-name: nginxinc/nginx-unprivileged dependency-version: 1.31-alpine dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- frontend.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend.Dockerfile b/frontend.Dockerfile index aa25d60b5e..1df815cd57 100644 --- a/frontend.Dockerfile +++ b/frontend.Dockerfile @@ -23,7 +23,7 @@ COPY --from=version-extractor /app/git_describe.txt . RUN PUBLIC_URL=/ npm run build # The final image is just an nginx with a webroot -FROM nginxinc/nginx-unprivileged:1.29-alpine@sha256:ccbac1a4c20a8b41c5dd1691bd91d63eda3b7989d643a33fd47841838519bfb9 +FROM nginxinc/nginx-unprivileged:1.31-alpine@sha256:8122337ed6c475bb486bc9340da453d4599f225e6b920ff0d92ca2267486b9b5 # This will be used by nginx's templating mechanism # NGINX_PORT sets the container port on which nginx is listening From 7e683a4c91037787b23bb7f1b29462034731ce82 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 May 2026 03:01:51 +0000 Subject: [PATCH 6/8] Bump tmp from 0.2.4 to 0.2.7 Bumps [tmp](https://github.com/raszi/node-tmp) from 0.2.4 to 0.2.7. - [Changelog](https://github.com/raszi/node-tmp/blob/master/CHANGELOG.md) - [Commits](https://github.com/raszi/node-tmp/compare/v0.2.4...v0.2.7) --- updated-dependencies: - dependency-name: tmp dependency-version: 0.2.7 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3e8ea45e9f..c4432fc291 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1657,9 +1657,9 @@ "license": "MIT" }, "node_modules/tmp": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.4.tgz", - "integrity": "sha512-UdiSoX6ypifLmrfQ/XfiawN6hkjSBpCjhKxxZcWlUUmoXLaCKQU0bx4HF/tdDK2uzRuchf1txGvrWBzYREssoQ==", + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.7.tgz", + "integrity": "sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==", "license": "MIT", "engines": { "node": ">=14.14" From 8cd8a8cd380978038e757e5c0e5e1fa8146711a5 Mon Sep 17 00:00:00 2001 From: awildturtok <1553491+awildturtok@users.noreply.github.com> Date: Thu, 28 May 2026 15:27:49 +0200 Subject: [PATCH 7/8] Adds Clickhouse support Implements support for Clickhouse, also extends support for Hana Enables a lot of tests and fixes bugs related to them for all 3 support DBMS --- backend/pom.xml | 11 + .../mode/local/SqlEntityResolver.java | 4 +- .../conquery/models/config/Dialect.java | 12 +- .../models/config/ExcelResultProvider.java | 4 + .../specific/MappableSingleColumnSelect.java | 11 +- .../conquery/models/events/CBlock.java | 23 +- .../printers/common/ListStringPrinter.java | 3 +- .../cqelement/CQExternalConverter.java | 33 +- .../conversion/cqelement/CQYesConverter.java | 2 +- .../cqelement/aggregation/InvertCte.java | 17 +- .../aggregation/PostgreSqlDateAggregator.java | 11 +- .../cqelement/concept/CQConceptConverter.java | 155 ++++--- .../cqelement/concept/CQTableContext.java | 2 +- .../cqelement/concept/JoinBranchesCte.java | 4 +- .../cqelement/concept/PreprocessingCte.java | 5 +- .../sql/conversion/dialect/DialectBundle.java | 19 +- .../dialect/SqlFunctionProvider.java | 76 +++- .../clickhouse/ClickhouseDialectBundle.java | 100 +++++ .../ClickhouseDistinctSelectConverter.java | 45 ++ .../ClickhouseFunctionProvider.java | 369 ++++++++++++++++ .../ClickhouseResultSetProcessor.java | 163 +++++++ .../ClickhouseStratificationFunctions.java | 178 ++++++++ .../dialect/{ => hana}/HanaDialectBundle.java | 14 +- .../{ => hana}/HanaSqlFunctionProvider.java | 40 +- .../hana}/HanaStratificationFunctions.java | 5 +- .../dialect/pg/PgDistinctSelectConverter.java | 42 ++ .../dialect/pg/PgResultSetProcessor.java | 140 ++++++ .../{ => pg}/PostgreDialectBundle.java | 23 +- .../{ => pg}/PostgreSqlFunctionProvider.java | 37 +- .../pg}/PostgresStratificationFunctions.java | 66 +-- .../forms/AbsoluteStratification.java | 11 +- .../sql/conversion/forms/FormConstants.java | 2 +- .../conquery/sql/conversion/forms/Offset.java | 2 +- .../forms/RelativeStratification.java | 25 +- .../forms/StratificationTableFactory.java | 13 +- .../sql/conversion/model/ColumnDateRange.java | 26 +- .../sql/conversion/model/QueryStep.java | 11 +- .../sql/conversion/model/QueryStepJoiner.java | 12 +- .../sql/conversion/model/SqlIdColumns.java | 29 +- .../model/StratificationSqlIdColumns.java | 4 +- .../aggregator/DurationSumSqlAggregator.java | 24 +- .../model/aggregator/FlagSqlAggregator.java | 11 +- .../select/ConceptColumnSelectConverter.java | 2 +- .../model/select/DaterangeSelectUtil.java | 18 +- .../EventDurationSumSelectConverter.java | 4 +- .../model/select/ValueSelectUtil.java | 8 +- .../query/AbsoluteFormQueryConverter.java | 2 +- .../query/ConceptQueryConverter.java | 1 + .../query/EntityDateQueryConverter.java | 2 +- .../query/FormConversionHelper.java | 2 +- .../query/RelativFormQueryConverter.java | 2 +- .../query/TableExportQueryConverter.java | 108 ++--- .../execution/DefaultResultSetProcessor.java | 1 - .../sql/execution/HanaSqlCDateSetParser.java | 4 +- .../sql/execution/PgSqlCDateSetParser.java | 2 +- .../sql/execution/SqlExecutionService.java | 1 + .../conquery/util/TablePrimaryColumnUtil.java | 4 +- .../integration/IntegrationTests.java | 22 +- .../integration/sql/CsvTableImporter.java | 4 +- .../ClickhouseSqlIntegrationTests.java | 178 ++++++++ .../sql/dialect/HanaSqlIntegrationTests.java | 2 +- .../dialect/PostgreSqlIntegrationTests.java | 2 +- .../tests/SqlSchemaValidationTest.java | 8 + .../postgres/daterange_column.test.json | 2 +- .../postgres/daterange_column.test.json | 2 +- .../SIMPLE_VIRTUAL_CONCEPT_Query.test.json | 22 +- .../COUNT_QUARTERS_AGGREGATOR/content.csv | 26 +- .../SIMPLE_VIRTUAL_CONCEPT_Query.test.json | 72 +++ .../COUNT_QUARTERS_RANGE/content.csv | 13 + .../COUNT_QUARTERS_RANGE/expected.csv | 6 + .../DURATION_SUM.test.json | 20 +- .../DURATION_SUM_AGGREGATOR/content.csv | 16 +- .../DURATION_SUM.test.json | 4 +- ...T_DATE_AGGREGATOR_NO_RESTRICTION.test.json | 41 +- ...VENT_DATE_AGGREGATOR_RESTRICTION.test.json | 21 +- .../EVENT_DATE_AGGREGATOR/content.csv | 22 +- .../EXISTS_AGGREGATOR/NUMBER.test.json | 17 +- .../aggregator/EXISTS_AGGREGATOR/content.csv | 16 +- .../EXISTS_AGGREGATOR_OR/NUMBER.test.json | 17 +- .../EXISTS_AGGREGATOR_OR/content.csv | 16 +- .../SIMPLE_VIRTUAL_CONCEPT_Query.test.json | 8 +- .../aggregator/FIRST_AGGREGATOR/content.csv | 1 - .../FLAGS_AGGREGATOR.test.json | 6 - .../SIMPLE_VIRTUAL_CONCEPT_Query.test.json | 6 - .../aggregator/LAST_AGGREGATOR/content.csv | 2 - .../aggregator/LAST_AGGREGATOR/expected.csv | 1 - .../SIMPLE_VIRTUAL_CONCEPT_Query.test.json | 6 - .../aggregator/MAPPED/DISTINCT/expected.csv | 1 - .../SIMPLE_VIRTUAL_CONCEPT_Query.test.json | 6 - .../MAPPED/DISTINCT_MULTI/expected.csv | 1 - .../SIMPLE_VIRTUAL_CONCEPT_Query.test.json | 6 - .../aggregator/MAPPED/FIRST/expected.csv | 1 - .../SIMPLE_VIRTUAL_CONCEPT_Query.test.json | 6 - .../MAPPED/FIRST_MULTI/expected.csv | 1 - .../tests/aggregator/MAPPED/content.csv | 2 - .../SIMPLE_VIRTUAL_CONCEPT_Query.test.json | 4 +- .../SIMPLE_VIRTUAL_CONCEPT_Query.test.json | 6 - .../aggregator/RANDOM_AGGREGATOR/content.csv | 1 - .../SUBSTRING/DISTINCT/MAPPED.test.json | 6 - .../SUBSTRING/DISTINCT/SIMPLE.test.json | 6 - .../SUBSTRING/DISTINCT/expected-mapped.csv | 1 - .../SUBSTRING/DISTINCT/expected-simple.csv | 1 - .../SUBSTRING/DISTINCT_MULTI/MAPPED.test.json | 6 - .../SUBSTRING/DISTINCT_MULTI/expected.csv | 1 - .../SUBSTRING/FIRST/MAPPED.test.json | 6 - .../SUBSTRING/FIRST/SIMPLE.test.json | 6 - .../SUBSTRING/FIRST/expected-mapped.csv | 1 - .../SUBSTRING/FIRST/expected-multi.csv | 1 - .../aggregator/SUBSTRING/FIRST/expected.csv | 1 - .../tests/aggregator/SUBSTRING/content.csv | 2 - .../COUNT_DISTINCT_MULTI/COUNT.test.json | 6 - .../COUNT_QUARTERS/COUNT_QUARTERS.test.json | 4 +- ..._COUNT_QUARTERS_Filter.csv => content.csv} | 0 ...COUNT_QUARTERS_Filter.csv => expected.csv} | 0 .../COUNT_QUARTERS.test.json | 7 +- ..._COUNT_QUARTERS_Filter.csv => content.csv} | 0 ...COUNT_QUARTERS_Filter.csv => expected.csv} | 0 .../tests/filter/COUNTfalse/COUNT.test.json | 8 +- .../DURATION_SUM/DURATION_SUM.test.json | 22 +- .../content_DURATION_SUM_Filter.csv | 14 +- .../DURATION_SUM_2/DURATION_SUM_2.test.json | 22 +- .../content_DURATION_SUM_2_Filter.csv | 16 +- .../DURATION_SUM.test.json | 1 + .../FLAGS_FILTER/FLAGS_FILTER.test.json | 6 - .../ABS_EXPORT_FORM_SECONDARY_ID.test.json | 2 +- .../ABSOLUT/SIMPLE/ABS_EXPORT_FORM.test.json | 2 +- .../ABS_EXPORT_FORM_WITH_SELECT.test.json | 2 +- .../SIMPLE_DATE_RESTRICTION/AND_DR.test.json | 2 +- .../SIMPLE_DATE_RESTRICTION/DR_AND.test.json | 2 +- .../LOGICAL/ABS_EXPORT_FORM.test.json | 2 +- .../ABS_EXPORT_FORM.test.json | 2 +- .../SECONDARY_ID/SECONDARY_ID.test.json | 2 +- .../SIMPLE/ABS_EXPORT_FORM.test.json | 2 +- .../ABS_EXPORT_FORM_WITH_SELECT.test.json | 2 +- .../SECONDARY_ID/SECONDARY_ID.test.json | 2 +- .../RELATIVE/SIMPLE/REL_EXPORT_FORM.test.json | 2 +- .../FULL_EXPORT_FORM_SECONDARY_ID.test.json | 2 +- .../tests/form/FULL_EXPORT_FORM/expected.csv | 16 +- .../tests/form/shared/alter.concept.json | 99 +++-- .../tests/form/shared/geschlecht.concept.json | 93 ++-- .../form/shared/two_connector.concept.json | 100 ++--- .../tests/form/shared/vers_stamm.table.json | 4 - .../form/shared/vers_tage_range.table.json | 4 - .../form/shared/versicherten_tage.table.json | 26 +- .../form/shared/versichertentage.concept.json | 96 ++-- .../ABS_EXPORT/ABS_EXPORT_Query.test.json | 8 + .../CONCEPT_RESTRICTION.test.json | 56 ++- .../CONCEPT_DATE_RESTRICTION_OPEN/content.csv | 16 +- ...RESTRICTION_WITHOUT_VALIDITYDATE.test.json | 6 - .../CONCEPT_RESTRICTION.test.json | 410 +++++++++--------- .../CONCEPT_WITHOUT_VALIDITYDATE.test.json | 6 - .../SIMPLE_CQEXTERNAL_QUERY.test.json | 6 - .../tests/query/CQYES/CQYES.test.json | 6 - .../DATE_DISTANCE/DATE_DISTANCE.test.json | 49 +-- .../DATE_DISTANCE_ERSTER.test.json | 27 +- .../DATE_DISTANCE_LETZTER.test.json | 107 ----- .../tests/query/DATE_DISTANCE/content.csv | 54 +-- .../query/DATE_DISTANCE/expected-letzter.csv | 3 - .../DATE_DISTANCE.test.json | 107 ----- .../DATE_DISTANCE_ERSTER.test.json | 107 ----- .../DATE_DISTANCE_LETZTER.test.json | 107 ----- .../query/DATE_DISTANCE_AGE_SPAN/content.csv | 27 -- .../expected-erster.csv | 5 - .../expected-letzter.csv | 5 - .../expected-versichertenzeit.csv | 9 - .../DATE_DISTANCE.test.json | 201 ++++----- .../DATE_DISTANCE_ERSTER.test.json | 196 ++++----- .../DATE_DISTANCE_LETZTER.test.json | 110 ----- ...ION_SUM_EMPTY_DATE_CONCEPT_QUERY.test.json | 163 ++++--- .../SIMPLE_CQEXTERNAL_QUERY.test.json | 6 - .../SIMPLE_TREECONCEPT_Query.test.json | 5 +- .../SIMPLE_TREECONCEPT_Query.test.json | 2 +- .../SIMPLE_TREECONCEPT_Query.test.json | 2 +- .../SIMPLE_TREECONCEPT_Query.test.json | 2 +- .../SIMPLE_TREECONCEPT_Query.test.json | 2 +- .../SIMPLE_TREECONCEPT_Query.test.json | 8 + .../OR/SIMPLE_TREECONCEPT_Query.test.json | 8 + .../OR_AND/SIMPLE_TREECONCEPT_Query.test.json | 8 + .../SIMPLE_TREECONCEPT_Query.test.json | 8 + .../SIMPLE_TREECONCEPT_Query.test.json | 5 +- .../SIMPLE_TREECONCEPT_Query.test.json | 18 +- ...ABLES_ICD_KH_AU_QUERY_ohneFilter.test.json | 6 - ...ATE_RESTRICTION_OR_CONCEPT_QUERY.test.json | 6 - ...ATE_RESTRICTION_OR_CONCEPT_QUERY.test.json | 27 +- .../tests/query/NUMBER/NUMBER.test.json | 92 ---- .../resources/tests/query/NUMBER/content.csv | 13 - .../resources/tests/query/NUMBER/expected.csv | 5 - .../query/NUMBER_MISSING/NUMBER.test.json | 164 ++++--- .../tests/query/NUMBER_MISSING/content.csv | 8 +- .../tests/query/NUMBER_MISSING/expected.csv | 2 +- .../NUMBER.test.json | 85 ---- .../NUMBER2.test.json | 83 ---- .../NUMBER_MISSING_NO_RESTRICTION/content.csv | 5 - .../expected.csv | 3 - .../expected2.csv | 5 - .../query/NUMBER_NEGATION/NUMBER.test.json | 59 +-- .../tests/query/NUMBER_NEGATION/content.csv | 24 +- .../NUMBER_STRING_PARSER/NUMBER.test.json | 17 +- .../query/NUMBER_STRING_PARSER/content.csv | 8 +- .../NUMBER.test.json | 17 +- .../NUMBER_STRING_PREFIXED_PARSER/content.csv | 8 +- .../REL_EXPORT_Query.test.json | 234 +++++----- .../query/REUSED_QUERY/REUSED_Query.test.json | 7 - .../SECONDARY_ID/SECONDARY_IDS.test.json | 86 ++-- .../tests/query/SECONDARY_ID/content.csv | 14 +- .../tests/query/SECONDARY_ID/content2.csv | 14 +- .../SECONDARY_IDS.test.json | 32 +- .../SECONDARY_ID_DATEMODE_LOGICAL/content.csv | 10 +- .../content2.csv | 10 +- .../SECONDARY_IDS_EXCLUDED.test.json | 6 - .../SECONDARY_IDS.test.json | 199 +++++---- .../SECONDARY_ID_EXTERNAL_LOGICAL/content.csv | 12 +- .../SECONDARY_IDS_MIXED.test.json | 6 - .../SIMPLE_CQEXTERNAL_QUERY.test.json | 6 - ...IMPLE_CQEXTERNAL_QUERY_START_END.test.json | 6 - .../SUM_EMPTY_DATE_CONCEPT_QUERY.test.json | 2 +- .../TABLE_EXPORT/RAW_TABLE_EXPORT.test.json | 28 +- .../tests/query/TABLE_EXPORT/content.csv | 14 +- .../tests/query/TABLE_EXPORT/content2.csv | 16 +- .../TEMPORAL/AFTER/ALL/ALL/query.test.json | 1 - .../TEMPORAL/AFTER/ALL/ANY/query.test.json | 2 +- .../AFTER/ALL/EARLIEST/query.test.json | 2 +- .../TEMPORAL/AFTER/ALL/LATEST/query.test.json | 2 +- .../TEMPORAL/AFTER/ANY/ALL/query.test.json | 2 +- .../TEMPORAL/AFTER/ANY/ANY/query.test.json | 2 +- .../AFTER/ANY/EARLIEST/query.test.json | 2 +- .../TEMPORAL/AFTER/ANY/LATEST/query.test.json | 2 +- .../AFTER/EARLIEST/ALL/query.test.json | 2 +- .../AFTER/EARLIEST/ANY/query.test.json | 2 +- .../AFTER/EARLIEST/EARLIEST/query.test.json | 2 +- .../AFTER/EARLIEST/LATEST/query.test.json | 2 +- .../TEMPORAL/AFTER/LATEST/ALL/query.test.json | 2 +- .../TEMPORAL/AFTER/LATEST/ANY/query.test.json | 2 +- .../AFTER/LATEST/EARLIEST/query.test.json | 2 +- .../AFTER/LATEST/LATEST/query.test.json | 2 +- .../TEMPORAL/AGGREGATION/query.test.json | 2 +- .../TEMPORAL/BEFORE/ALL/ALL/query.test.json | 2 +- .../TEMPORAL/BEFORE/ALL/ANY/query.test.json | 2 +- .../BEFORE/ALL/EARLIEST/query.test.json | 2 +- .../BEFORE/ALL/LATEST/query.test.json | 2 +- .../TEMPORAL/BEFORE/ANY/ALL/query.test.json | 2 +- .../TEMPORAL/BEFORE/ANY/ANY/query.test.json | 2 +- .../BEFORE/ANY/EARLIEST/query.test.json | 2 +- .../BEFORE/ANY/LATEST/query.test.json | 2 +- .../BEFORE/EARLIEST/ALL/query.test.json | 2 +- .../BEFORE/EARLIEST/ANY/query.test.json | 2 +- .../BEFORE/EARLIEST/EARLIEST/query.test.json | 2 +- .../BEFORE/EARLIEST/LATEST/query.test.json | 2 +- .../BEFORE/LATEST/ALL/query.test.json | 2 +- .../BEFORE/LATEST/ANY/query.test.json | 2 +- .../BEFORE/LATEST/EARLIEST/query.test.json | 2 +- .../BEFORE/LATEST/LATEST/query.test.json | 2 +- .../TEMPORAL/WHILE/ALL/ALL/query.test.json | 2 +- .../TEMPORAL/WHILE/ALL/ANY/query.test.json | 2 +- .../WHILE/ALL/EARLIEST/query.test.json | 2 +- .../TEMPORAL/WHILE/ALL/LATEST/query.test.json | 2 +- .../TEMPORAL/WHILE/ANY/ALL/query.test.json | 2 +- .../TEMPORAL/WHILE/ANY/ANY/query.test.json | 2 +- .../WHILE/ANY/EARLIEST/query.test.json | 2 +- .../TEMPORAL/WHILE/ANY/LATEST/query.test.json | 2 +- .../WHILE/EARLIEST/ALL/query.test.json | 2 +- .../WHILE/EARLIEST/ANY/query.test.json | 2 +- .../WHILE/EARLIEST/EARLIEST/query.test.json | 2 +- .../WHILE/EARLIEST/LATEST/query.test.json | 2 +- .../TEMPORAL/WHILE/LATEST/ALL/query.test.json | 2 +- .../TEMPORAL/WHILE/LATEST/ANY/query.test.json | 2 +- .../WHILE/LATEST/EARLIEST/query.test.json | 2 +- .../WHILE/LATEST/LATEST/query.test.json | 2 +- .../VIRTUAL_CONCEPT_REUSED_Query.test.json | 6 - .../SIMPLE_VIRTUAL_CONCEPT_Query.test.json | 6 - .../SIMPLE_VIRTUAL_CONCEPT_Query.test.json | 6 - .../selects/first/LAST_AGGREGATOR/content.csv | 2 - .../first/LAST_AGGREGATOR/expected.csv | 1 - 273 files changed, 3408 insertions(+), 3081 deletions(-) create mode 100644 backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/clickhouse/ClickhouseDialectBundle.java create mode 100644 backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/clickhouse/ClickhouseDistinctSelectConverter.java create mode 100644 backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/clickhouse/ClickhouseFunctionProvider.java create mode 100644 backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/clickhouse/ClickhouseResultSetProcessor.java create mode 100644 backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/clickhouse/ClickhouseStratificationFunctions.java rename backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/{ => hana}/HanaDialectBundle.java (88%) rename backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/{ => hana}/HanaSqlFunctionProvider.java (91%) rename backend/src/main/java/com/bakdata/conquery/sql/conversion/{forms => dialect/hana}/HanaStratificationFunctions.java (97%) create mode 100644 backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/pg/PgDistinctSelectConverter.java create mode 100644 backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/pg/PgResultSetProcessor.java rename backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/{ => pg}/PostgreDialectBundle.java (78%) rename backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/{ => pg}/PostgreSqlFunctionProvider.java (93%) rename backend/src/main/java/com/bakdata/conquery/sql/conversion/{forms => dialect/pg}/PostgresStratificationFunctions.java (82%) create mode 100644 backend/src/test/java/com/bakdata/conquery/integration/sql/dialect/ClickhouseSqlIntegrationTests.java create mode 100644 backend/src/test/resources/tests/aggregator/COUNT_QUARTERS_RANGE/SIMPLE_VIRTUAL_CONCEPT_Query.test.json create mode 100644 backend/src/test/resources/tests/aggregator/COUNT_QUARTERS_RANGE/content.csv create mode 100644 backend/src/test/resources/tests/aggregator/COUNT_QUARTERS_RANGE/expected.csv rename backend/src/test/resources/tests/filter/COUNT_QUARTERS/{content_COUNT_QUARTERS_Filter.csv => content.csv} (100%) rename backend/src/test/resources/tests/filter/COUNT_QUARTERS/{expected_COUNT_QUARTERS_Filter.csv => expected.csv} (100%) rename backend/src/test/resources/tests/filter/COUNT_QUARTERS_RANGE/{content_COUNT_QUARTERS_Filter.csv => content.csv} (100%) rename backend/src/test/resources/tests/filter/COUNT_QUARTERS_RANGE/{expected_COUNT_QUARTERS_Filter.csv => expected.csv} (100%) delete mode 100644 backend/src/test/resources/tests/query/DATE_DISTANCE/DATE_DISTANCE_LETZTER.test.json delete mode 100644 backend/src/test/resources/tests/query/DATE_DISTANCE/expected-letzter.csv delete mode 100644 backend/src/test/resources/tests/query/DATE_DISTANCE_AGE_SPAN/DATE_DISTANCE.test.json delete mode 100644 backend/src/test/resources/tests/query/DATE_DISTANCE_AGE_SPAN/DATE_DISTANCE_ERSTER.test.json delete mode 100644 backend/src/test/resources/tests/query/DATE_DISTANCE_AGE_SPAN/DATE_DISTANCE_LETZTER.test.json delete mode 100644 backend/src/test/resources/tests/query/DATE_DISTANCE_AGE_SPAN/content.csv delete mode 100644 backend/src/test/resources/tests/query/DATE_DISTANCE_AGE_SPAN/expected-erster.csv delete mode 100644 backend/src/test/resources/tests/query/DATE_DISTANCE_AGE_SPAN/expected-letzter.csv delete mode 100644 backend/src/test/resources/tests/query/DATE_DISTANCE_AGE_SPAN/expected-versichertenzeit.csv delete mode 100644 backend/src/test/resources/tests/query/DATE_DISTANCE_NEGATION/DATE_DISTANCE_LETZTER.test.json delete mode 100644 backend/src/test/resources/tests/query/NUMBER/NUMBER.test.json delete mode 100644 backend/src/test/resources/tests/query/NUMBER/content.csv delete mode 100644 backend/src/test/resources/tests/query/NUMBER/expected.csv delete mode 100644 backend/src/test/resources/tests/query/NUMBER_MISSING_NO_RESTRICTION/NUMBER.test.json delete mode 100644 backend/src/test/resources/tests/query/NUMBER_MISSING_NO_RESTRICTION/NUMBER2.test.json delete mode 100644 backend/src/test/resources/tests/query/NUMBER_MISSING_NO_RESTRICTION/content.csv delete mode 100644 backend/src/test/resources/tests/query/NUMBER_MISSING_NO_RESTRICTION/expected.csv delete mode 100644 backend/src/test/resources/tests/query/NUMBER_MISSING_NO_RESTRICTION/expected2.csv diff --git a/backend/pom.xml b/backend/pom.xml index b31ca86ca3..5d5b69d9f8 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -373,6 +373,11 @@ testcontainers-postgresql test + + org.testcontainers + testcontainers-clickhouse + test + org.testcontainers testcontainers-solr @@ -383,6 +388,12 @@ ngdbc 2.17.10 + + com.clickhouse + clickhouse-jdbc + 0.9.8 + all + io.prometheus simpleclient_dropwizard diff --git a/backend/src/main/java/com/bakdata/conquery/mode/local/SqlEntityResolver.java b/backend/src/main/java/com/bakdata/conquery/mode/local/SqlEntityResolver.java index 74d4966d5f..8768f24c98 100644 --- a/backend/src/main/java/com/bakdata/conquery/mode/local/SqlEntityResolver.java +++ b/backend/src/main/java/com/bakdata/conquery/mode/local/SqlEntityResolver.java @@ -33,6 +33,7 @@ import org.jooq.Select; import org.jooq.SelectConditionStep; import org.jooq.Table; +import org.jooq.impl.DSL; @RequiredArgsConstructor public class SqlEntityResolver implements EntityResolver { @@ -144,7 +145,8 @@ private Map resolveIds(String[][] values, List rowIndex = field(name(ROW_INDEX), Integer.class); Field externalPrimaryColumn = field(name(SharedAliases.PRIMARY_COLUMN.getAlias()), String.class); Field innerPrimaryColumn = field(name(idColumns.findPrimaryIdColumn().getField()), String.class); - Field isResolved = innerPrimaryColumn.isNotNull().as(IS_RESOLVED_ALIAS); + // Would prefer this to be `is not null`, but hana does not support that for fields + Field isResolved = case_().when(innerPrimaryColumn.isNull(), inline(false)).otherwise(inline(true)).as(IS_RESOLVED_ALIAS); Table allIdsTable = table(name(idColumns.getTable())); diff --git a/backend/src/main/java/com/bakdata/conquery/models/config/Dialect.java b/backend/src/main/java/com/bakdata/conquery/models/config/Dialect.java index c1effedb58..0bb1507f68 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/config/Dialect.java +++ b/backend/src/main/java/com/bakdata/conquery/models/config/Dialect.java @@ -1,8 +1,9 @@ package com.bakdata.conquery.models.config; import com.bakdata.conquery.sql.conversion.dialect.DialectBundle; -import com.bakdata.conquery.sql.conversion.dialect.HanaDialectBundle; -import com.bakdata.conquery.sql.conversion.dialect.PostgreDialectBundle; +import com.bakdata.conquery.sql.conversion.dialect.clickhouse.ClickhouseDialectBundle; +import com.bakdata.conquery.sql.conversion.dialect.hana.HanaDialectBundle; +import com.bakdata.conquery.sql.conversion.dialect.pg.PostgreDialectBundle; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -15,13 +16,8 @@ @Getter public enum Dialect { - /** - * Dialect for PostgreSQL database - */ POSTGRESQL(new PostgreDialectBundle()), - /** - * Dialect for SAP HANA database - */ + CLICKHOUSE(new ClickhouseDialectBundle()), HANA(new HanaDialectBundle()); private final DialectBundle dialectBundle; diff --git a/backend/src/main/java/com/bakdata/conquery/models/config/ExcelResultProvider.java b/backend/src/main/java/com/bakdata/conquery/models/config/ExcelResultProvider.java index 59cfaf3022..cf94d9953e 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/config/ExcelResultProvider.java +++ b/backend/src/main/java/com/bakdata/conquery/models/config/ExcelResultProvider.java @@ -78,6 +78,10 @@ public Collection generateResultURLs(ManagedExecution exec, UriBuil return Collections.emptyList(); } + if(singleExecution.getResultInfos() == null){ + return Collections.emptyList(); + } + // Save id column count to later check if xlsx dimensions are feasible idColumnsCount = exec.getConfig().getIdColumns().getIdResultInfos().size(); diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/MappableSingleColumnSelect.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/MappableSingleColumnSelect.java index 2617629536..8900fa8d2f 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/MappableSingleColumnSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/MappableSingleColumnSelect.java @@ -60,13 +60,10 @@ public MappableSingleColumnSelect(ColumnId column, @Nullable InternToExternMappe public static SingleColumnSqlSelect getSubstringSelect( Column column, Range.IntegerRange substringRange, SelectContext selectContext, String alias) { - Field field; - if (substringRange == null || substringRange.isAll()) { - field = field(name(selectContext.getTables().getRootTable(), column.getName()), String.class); - } - else { - field = field(name(selectContext.getTables().getRootTable(), column.getName()), String.class); + Field field = field(name(selectContext.getTables().getRootTable(), column.getName()), String.class); + + if (substringRange != null && !substringRange.isAll()) { if (substringRange.isAtLeast()) { field = substring(field, 1 + substringRange.getMin()); } @@ -79,7 +76,7 @@ else if (substringRange.isAtMost()) { } if (alias != null) { - field = field.as(alias); + field = field.as(name(alias)); } return new FieldWrapper<>(field, column.getName()); diff --git a/backend/src/main/java/com/bakdata/conquery/models/events/CBlock.java b/backend/src/main/java/com/bakdata/conquery/models/events/CBlock.java index 9e503b3b9d..981c48e622 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/events/CBlock.java +++ b/backend/src/main/java/com/bakdata/conquery/models/events/CBlock.java @@ -14,6 +14,7 @@ import com.bakdata.conquery.models.datasets.Table; import com.bakdata.conquery.models.datasets.concepts.Concept; import com.bakdata.conquery.models.datasets.concepts.Connector; +import com.bakdata.conquery.models.datasets.concepts.ValidityDate; import com.bakdata.conquery.models.datasets.concepts.tree.ConceptTreeCache; import com.bakdata.conquery.models.datasets.concepts.tree.ConceptTreeChild; import com.bakdata.conquery.models.datasets.concepts.tree.ConceptTreeConnector; @@ -95,7 +96,7 @@ public static CBlock createCBlock(ConceptTreeConnector connector, BucketId bucke final int[][] mostSpecificChildren = calculateSpecificChildrenPaths(bucket, connector, bucketManager); //TODO Object2LongMap final Map includedConcepts = calculateConceptElementPathBloomFilter(bucket, mostSpecificChildren); - final Map entitySpans = calculateEntityDateIndices(bucket); + final Map entitySpans = calculateEntityDateIndices(bucket, connector); final CBlock cBlock = new CBlock(bucketId, connector.getId(), includedConcepts, entitySpans, mostSpecificChildren); return cBlock; @@ -147,17 +148,10 @@ private static Map calculateConceptElementPathBloomFilter(Bucket b * * @implNote This is an unrolled implementation of {@link CDateRange#span(CDateRange)}. */ - private static Map calculateEntityDateIndices(Bucket bucket) { + private static Map calculateEntityDateIndices(Bucket bucket, ConceptTreeConnector connector) { final Map spans = new HashMap<>(); - final Table table = bucket.getTable().resolve(); - - - for (Column column : table.getColumns()) { - if (!column.getType().isDateCompatible()) { - continue; - } - + for (ValidityDate validityDate : connector.getValidityDates()) { for (String entity : bucket.entities()) { final int end = bucket.getEntityEnd(entity); @@ -166,14 +160,14 @@ private static Map calculateEntityDateIndices(Bucket bucket) int max = Integer.MIN_VALUE; int min = Integer.MAX_VALUE; - for (int event = bucket.getEntityStart(entity); event < end; event++) { - if (!bucket.has(event, column)) { + + final CDateRange range = validityDate.getValidityDate(event, bucket); + + if(range == null) { continue; } - final CDateRange range = bucket.getAsDateRange(event, column); - final int minValue = range.getMinValue(); min = Math.min(min, minValue); @@ -192,7 +186,6 @@ private static Map calculateEntityDateIndices(Bucket bucket) final CDateRange span = CDateRange.of(min, max); spans.compute(entity, (ignored, current) -> current == null ? span : current.span(span)); - } } diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/ListStringPrinter.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/ListStringPrinter.java index 218a37d71f..0e62677566 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/ListStringPrinter.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/ListStringPrinter.java @@ -1,6 +1,7 @@ package com.bakdata.conquery.models.query.resultinfo.printers.common; import java.util.Collection; +import java.util.Objects; import java.util.StringJoiner; import com.bakdata.conquery.models.config.LocaleConfig; @@ -24,7 +25,7 @@ public String apply(@NotNull Collection f) { continue; } - joiner.add(listFormat.escapeListElement(elementPrinter.apply(obj).toString())); + joiner.add(listFormat.escapeListElement(Objects.toString(elementPrinter.apply(obj)))); } return joiner.toString(); } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/CQExternalConverter.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/CQExternalConverter.java index ea148c4583..147fae21da 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/CQExternalConverter.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/CQExternalConverter.java @@ -1,6 +1,5 @@ package com.bakdata.conquery.sql.conversion.cqelement; -import static com.bakdata.conquery.sql.conversion.dialect.SqlFunctionProvider.SQL_UNIT_SEPARATOR; import static org.jooq.impl.DSL.*; import java.util.ArrayList; @@ -24,9 +23,11 @@ import com.google.common.base.Preconditions; import org.jooq.Field; import org.jooq.Name; +import org.jooq.Nullability; import org.jooq.Record; import org.jooq.Table; import org.jooq.impl.DSL; +import org.jooq.impl.SQLDataType; public class CQExternalConverter implements NodeConverter { @@ -41,8 +42,8 @@ private static QueryStep createExternalIdsCte(CQExternal external, SqlFunctionPr List rowSelects = createRowSelects(entry, functionProvider); unions.addAll(rowSelects); } - Preconditions.checkArgument(!unions.isEmpty(), "Expecting at least 1 converted resolved row when converting a CQExternal"); - QueryStep allStep = QueryStep.createUnionAllStep(unions, CQ_EXTERNAL_IDS_CTE_NAME, Collections.emptyList()); + Preconditions.checkArgument(!unions.isEmpty(), "Expecting at least 1 resolved row when converting a CQExternal"); + QueryStep allStep = QueryStep.createUnionAllStep(unions, CQ_EXTERNAL_IDS_CTE_NAME, Collections.emptyList(), context.isNegation()); Optional maybeValidityDate = allStep.getSelects().getValidityDate(); @@ -65,25 +66,22 @@ private static QueryStep createExternalIdsCte(CQExternal external, SqlFunctionPr * 1 row per ID is sufficient. For other dialects there can be multiple rows with the same pid -> date range from the date set. */ private static List createRowSelects(Map.Entry entry, SqlFunctionProvider functionProvider) { - SqlIdColumns ids = createIdSelect(entry); + SqlIdColumns ids = createIdSelect(entry, functionProvider); List validityDateEntries = functionProvider.forCDateSet(entry.getValue(), SharedAliases.DATES_COLUMN); return validityDateEntries.stream() .map(validityDateEntry -> createIdRowSelect(ids, validityDateEntry, functionProvider)) .toList(); } - private static SqlIdColumns createIdSelect(Map.Entry entry) { - Field primaryColumn = DSL.inline(entry.getKey()).coerce(Object.class).as(SharedAliases.PRIMARY_COLUMN.getAlias()); + private static SqlIdColumns createIdSelect(Map.Entry entry, SqlFunctionProvider functionProvider) { + Field primaryColumn = functionProvider.externalId(entry.getKey()).as(SharedAliases.PRIMARY_COLUMN.getAlias()); return new SqlIdColumns(primaryColumn); } - private static FieldWrapper createExtraColumnValue(Map.Entry> extraEntry) { - String extraValues = extraEntry.getValue().stream() - .map(DSL::val) - .map(Field::toString) - .collect(Collectors.joining(SQL_UNIT_SEPARATOR)); + private static FieldWrapper createExtraColumnValue(Map.Entry> extraEntry, SqlFunctionProvider functionProvider) { + Field extraValues = functionProvider.asArrayRepr(extraEntry.getValue()); final Name alias = name(extraEntry.getKey().replace(WHITESPACE, UNDERSCORE)); - final Field withAlias = field(extraValues).as(alias); + final Field withAlias = extraValues.as(alias); return new FieldWrapper<>(withAlias); } @@ -143,16 +141,15 @@ public ConversionContext convert(CQExternal external, ConversionContext context) QueryStep externalIdsCte = createExternalIdsCte(external, functionProvider, context); ConversionContext withExternalIdCte = context.withQueryStep(externalIdsCte); - if (!external.isWithExtras()) { return withExternalIdCte; } - QueryStep externalExtrasCte = createExternalExtrasCte(external, functionProvider); + QueryStep externalExtrasCte = createExternalExtrasCte(external, functionProvider, context); return withExternalIdCte.withExternalExtras(externalExtrasCte); } - private QueryStep createExternalExtrasCte(CQExternal external, SqlFunctionProvider functionProvider) { + private QueryStep createExternalExtrasCte(CQExternal external, SqlFunctionProvider functionProvider, ConversionContext context) { List unions = new ArrayList<>(); for (Map.Entry entry : external.getValuesResolved().entrySet()) { List>> extrasForId = external.getExtrasForId(entry.getKey()); @@ -160,7 +157,7 @@ private QueryStep createExternalExtrasCte(CQExternal external, SqlFunctionProvid unions.add(rowSelects); } Preconditions.checkArgument(!unions.isEmpty(), "Expecting at least 1 converted resolved row when converting a CQExternal"); - return QueryStep.createUnionAllStep(unions, CQ_EXTERNAL_EXTRAS_CTE_NAME, Collections.emptyList()); + return QueryStep.createUnionAllStep(unions, CQ_EXTERNAL_EXTRAS_CTE_NAME, Collections.emptyList(), context.isNegation()); } /** @@ -171,8 +168,8 @@ private QueryStep createRowSelects( List>> extra, SqlFunctionProvider functionProvider ) { - SqlIdColumns ids = createIdSelect(entry); - List extraSelects = extra.stream().map(CQExternalConverter::createExtraColumnValue).collect(Collectors.toList()); + SqlIdColumns ids = createIdSelect(entry, functionProvider); + List extraSelects = extra.stream().map((Map.Entry> extraEntry) -> createExtraColumnValue(extraEntry, functionProvider)).collect(Collectors.toList()); return createExtraRowSelect(ids, extraSelects, functionProvider); } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/CQYesConverter.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/CQYesConverter.java index eb6c8a234f..f45cba7d1b 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/CQYesConverter.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/CQYesConverter.java @@ -27,7 +27,7 @@ public Class getConversionClass() { public ConversionContext convert(CQYes cqYes, ConversionContext context) { ColumnConfig primaryColumnConfig = context.getIdColumns().findPrimaryIdColumn(); - Field primaryColumn = field(name(primaryColumnConfig.getField())); + Field primaryColumn = field(name(primaryColumnConfig.getField()), String.class); SqlIdColumns ids = new SqlIdColumns(primaryColumn); Selects selects = Selects.builder().ids(ids) diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/InvertCte.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/InvertCte.java index 30ef3a59b3..abd998364e 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/InvertCte.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/InvertCte.java @@ -1,5 +1,8 @@ package com.bakdata.conquery.sql.conversion.cqelement.aggregation; +import static org.jooq.impl.DSL.*; +import static org.jooq.impl.DSL.field; + import java.sql.Date; import java.util.List; import java.util.Optional; @@ -57,14 +60,14 @@ private Selects getInvertSelects(QueryStep rowNumberStep, SqlIdColumns coalesced SqlFunctionProvider functionProvider = context.getFunctionProvider(); ColumnDateRange validityDate = rowNumberStep.getSelects().getValidityDate().get(); - Field rangeStart = DSL.coalesce( + Field rangeStart = coalesce( QualifyingUtil.qualify(validityDate.getEnd(), ROWS_LEFT_TABLE_NAME), - functionProvider.toDateField(functionProvider.getMinDateExpression()) + functionProvider.getMinDateExpression() ).as(DateAggregationCte.RANGE_START); - Field rangeEnd = DSL.coalesce( + Field rangeEnd = coalesce( QualifyingUtil.qualify(validityDate.getStart(), ROWS_RIGHT_TABLE_NAME), - functionProvider.toDateField(functionProvider.getMaxDateExpression()) + functionProvider.getMaxDateExpression() ).as(DateAggregationCte.RANGE_END); return Selects.builder() @@ -76,9 +79,9 @@ private Selects getInvertSelects(QueryStep rowNumberStep, SqlIdColumns coalesced private TableOnConditionStep selfJoinWithShiftedRows(SqlIdColumns leftIds, SqlIdColumns rightIds, QueryStep rowNumberStep) { - Field leftRowNumber = DSL.field(DSL.name(ROWS_LEFT_TABLE_NAME, RowNumberCte.ROW_NUMBER_FIELD_NAME), Integer.class) - .plus(1); - Field rightRowNumber = DSL.field(DSL.name(ROWS_RIGHT_TABLE_NAME, RowNumberCte.ROW_NUMBER_FIELD_NAME), Integer.class); + Field leftRowNumber = field(name(ROWS_LEFT_TABLE_NAME, RowNumberCte.ROW_NUMBER_FIELD_NAME), Integer.class) + .plus(1); + Field rightRowNumber = field(name(ROWS_RIGHT_TABLE_NAME, RowNumberCte.ROW_NUMBER_FIELD_NAME), Integer.class); Condition[] joinConditions = Stream.concat( Stream.of(leftRowNumber.eq(rightRowNumber)), diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/PostgreSqlDateAggregator.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/PostgreSqlDateAggregator.java index 08e74dfcf8..43bb14e36a 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/PostgreSqlDateAggregator.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/aggregation/PostgreSqlDateAggregator.java @@ -1,5 +1,6 @@ package com.bakdata.conquery.sql.conversion.cqelement.aggregation; +import static org.jooq.impl.DSL.*; import static org.jooq.impl.DSL.field; import static org.jooq.impl.DSL.keyword; @@ -81,12 +82,12 @@ public QueryStep invertAggregatedIntervals(QueryStep baseStep, ConversionContext return baseStep; } - Field maxDateRange = DSL.function( + Field maxDateRange = function( "daterange", Object.class, - this.functionProvider.toDateField(this.functionProvider.getMinDateExpression()), - this.functionProvider.toDateField(this.functionProvider.getMaxDateExpression()), - DSL.inline("[]") + this.functionProvider.getMinDateExpression(), + this.functionProvider.getMaxDateExpression(), + inline("[]") ); // see https://www.postgresql.org/docs/current/functions-range.html @@ -126,7 +127,7 @@ public ColumnDateRange getAggregatedValidityDate(DateAggregationDates dateAggreg private static String createEmptyRangeForNullValues(Field field) { Keyword datemultirange = keyword("datemultirange"); - return DSL.coalesce(field("{0}::{1}", field, datemultirange), field("'{}'::{0}", datemultirange)) + return coalesce(field("{0}::{1}", field, datemultirange), field("'{}'::{0}", datemultirange)) .toString(); } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/CQConceptConverter.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/CQConceptConverter.java index 17bc77eefe..efad103752 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/CQConceptConverter.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/CQConceptConverter.java @@ -1,5 +1,7 @@ package com.bakdata.conquery.sql.conversion.cqelement.concept; +import static org.jooq.impl.DSL.*; + import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -40,10 +42,10 @@ import com.bakdata.conquery.sql.conversion.model.select.SqlSelect; import com.bakdata.conquery.util.TablePrimaryColumnUtil; import com.google.common.base.Preconditions; +import org.jooq.Condition; import org.jooq.Field; import org.jooq.Record; import org.jooq.TableLike; -import org.jooq.impl.DSL; public class CQConceptConverter implements NodeConverter { @@ -69,11 +71,11 @@ private static QueryStep finishConceptConversion(QueryStep predecessor, CQConcep SelectContext selectContext = SelectContext.create(ids, validityDate, universalTables, context); List converted = cqConcept.getSelects().stream() - .map(selectId -> { + .map(selectId -> { Select select = selectId.resolve(); - return select.createConverter().conceptSelect(select, selectContext); + return context.getDialectBundle().getSelectConverter(select).conceptSelect(select, selectContext); }) - .toList(); + .toList(); List queriesToJoin = new ArrayList<>(); queriesToJoin.add(predecessor); @@ -88,16 +90,16 @@ private static QueryStep finishConceptConversion(QueryStep predecessor, CQConcep List allConceptSelects = Stream.concat( converted.stream().flatMap(sqlSelects -> sqlSelects.getFinalSelects().stream()), // aggregate special selects (e.g. Exists) - predecessor.getQualifiedSelects().getSqlSelects().stream().map(SqlSelect::connectorAggregate) + predecessor.getQualifiedSelects().getSqlSelects().stream().map(SqlSelect::connectorAggregate) ) - .toList(); + .toList(); Selects finalSelects = Selects.builder() - .ids(ids) - .stratificationDate(predecessorSelects.getStratificationDate()) - .validityDate(validityDate) - .sqlSelects(allConceptSelects) - .build(); + .ids(ids) + .stratificationDate(predecessorSelects.getStratificationDate()) + .validityDate(validityDate) + .sqlSelects(allConceptSelects) + .build(); TableLike joinedTable = QueryStepJoiner.constructJoinedTable(queriesToJoin, ConqueryJoinType.INNER_JOIN, context); @@ -106,28 +108,28 @@ private static QueryStep finishConceptConversion(QueryStep predecessor, CQConcep Stream.concat( finalSelects.nonExplicitSelects().stream(), finalSelects.getSqlSelects().stream() - .filter(Predicate.not(SqlSelect::isUniversal)) - .flatMap(sqlSelect -> sqlSelect.toFields().stream()) + .filter(Predicate.not(SqlSelect::isUniversal)) + .flatMap(sqlSelect -> sqlSelect.toFields().stream()) ).toList(); return QueryStep.builder() - .cteName(universalTables.cteName(ConceptCteStep.UNIVERSAL_SELECTS)) - .selects(finalSelects) - .fromTable(joinedTable) - .groupBy(groupByFields) - .predecessors(queriesToJoin) - .negate(context.isNegation()) - .build(); + .cteName(universalTables.cteName(ConceptCteStep.UNIVERSAL_SELECTS)) + .selects(finalSelects) + .fromTable(joinedTable) + .groupBy(groupByFields) + .predecessors(queriesToJoin) + .negate(context.isNegation()) + .build(); } public static SqlIdColumns convertIds(CQConcept cqConcept, CQTable cqTable, ConversionContext conversionContext) { Table table = cqTable.getConnector().resolve().getResolvedTable(); - Field primaryColumn = TablePrimaryColumnUtil.findPrimaryColumn(table, conversionContext.getDefaultPrimaryColumn()); + Field primaryColumn = TablePrimaryColumnUtil.findPrimaryColumn(table, conversionContext.getDefaultPrimaryColumn()); if (cqConcept.isExcludeFromSecondaryId() - || conversionContext.getSecondaryIdDescription() == null - || !cqTable.hasSelectedSecondaryId(conversionContext.getSecondaryIdDescription().getId()) + || conversionContext.getSecondaryIdDescription() == null + || !cqTable.hasSelectedSecondaryId(conversionContext.getSecondaryIdDescription().getId()) ) { return new SqlIdColumns(primaryColumn).withAlias(); } @@ -142,13 +144,12 @@ public static SqlIdColumns convertIds(CQConcept cqConcept, CQTable cqTable, Conv ) ); - Field secondaryId = DSL.field(DSL.name(table.getName(), secondaryIdColumn.getName())); + Field secondaryId = field(name(table.getName(), secondaryIdColumn.getName()), String.class); return new SqlIdColumns(primaryColumn, secondaryId).withAlias(); } - private static Optional convertValidityDate(CQTable cqTable, String connectorLabel, ConversionContext context) { + private static ColumnDateRange convertValidityDate(String connectorLabel, ConversionContext context, ValidityDate validityDate) { SqlFunctionProvider functionProvider = context.getFunctionProvider(); - ValidityDate validityDate = cqTable.findValidityDate(); ColumnDateRange sqlValidityDate; boolean hasValidityDate = validityDate != null; @@ -167,28 +168,39 @@ private static Optional convertValidityDate(CQTable cqTable, St sqlValidityDate = functionProvider.forCDateRange(context.getDateRestrictionRange()); } else { - return Optional.empty(); + sqlValidityDate = functionProvider.allRange(); } } - return Optional.of(sqlValidityDate.asValidityDateRange(connectorLabel)); + return sqlValidityDate.asValidityDateRange(connectorLabel); } - private static Optional collectConditionFilters(List> conceptElements, CQTable cqTable, SqlFunctionProvider functionProvider) { - return collectConditions(conceptElements, cqTable, functionProvider) - .stream() - .reduce(WhereCondition::and) - .map(whereCondition -> new SqlFilters( - ConnectorSqlSelects.none(), - WhereClauses.builder().preprocessingCondition(whereCondition).build() - )); + private static SqlFilters collectConditionFilters( + List> conceptElements, CQTable cqTable, SqlFunctionProvider functionProvider) { + List conditions = new ArrayList<>(); + conditions.addAll(collectConditions(conceptElements, cqTable, functionProvider)); + + ValidityDate validityDate = cqTable.findValidityDate(); + Condition validityDateFilter = noCondition(); + if (validityDate != null) { + validityDateFilter = functionProvider.isNotEmptyValidityDate(validityDate); + } + + return new SqlFilters(ConnectorSqlSelects.none(), + WhereClauses.builder() + .preprocessingConditions(conditions) + .preprocessingCondition(ConditionUtil.wrap(validityDateFilter)) + .build() + ); } private static List collectConditions(List> conceptElements, CQTable cqTable, SqlFunctionProvider functionProvider) { List conditions = new ArrayList<>(); + convertConnectorCondition(cqTable, functionProvider).ifPresent(conditions::add); + for (ConceptElement conceptElement : conceptElements) { collectConditions(cqTable, conceptElement, functionProvider) .reduce(WhereCondition::and) @@ -216,41 +228,41 @@ private static Optional convertConnectorCondition(CQTable cqTabl final Connector connector = cqTable.getConnector().resolve(); return Optional.ofNullable(connector.getCondition()) - .map(condition -> condition.convertToSqlCondition(CTConditionContext.create(connector, functionProvider))); + .map(condition -> condition.convertToSqlCondition(CTConditionContext.create(connector, functionProvider))); } private static SqlFilters dateRestrictionFilter(ConversionContext context, ColumnDateRange validityDate) { List dateRestrictionSelects = new ArrayList<>(); List conditions = new ArrayList<>(); - - conditions.add(ConditionUtil.wrap(validityDate.isNotEmpty())); + SqlFunctionProvider functionProvider = context.getFunctionProvider(); if (context.getDateRestrictionRange() != null) { - SqlFunctionProvider functionProvider = context.getFunctionProvider(); ColumnDateRange dateRestriction = functionProvider.forCDateRange(context.getDateRestrictionRange()).as(SharedAliases.DATE_RESTRICTION.getAlias()); conditions.add(ConditionUtil.wrap(functionProvider.dateRestriction(dateRestriction, validityDate))); dateRestrictionSelects.addAll(dateRestriction.toFields().stream() - .map(FieldWrapper::new) - .toList()); + .map(FieldWrapper::new) + .toList()); } return new SqlFilters( ConnectorSqlSelects.builder().preprocessingSelects(dateRestrictionSelects).build(), WhereClauses.builder() - .eventFilters(conditions) - .build() + .eventFilters(conditions) + .build() ); } private static ConnectorSqlSelects createConceptColumnConnectorSqlSelects(CQConcept cqConcept, SelectContext selectContext) { + + return cqConcept.getSelects().stream() - .map(SelectId::resolve) - .filter(select -> select instanceof ConceptColumnSelect) - .findFirst() - .map(select -> select.createConverter().connectorSelect(select, selectContext)) - .orElse(ConnectorSqlSelects.none()); + .map(SelectId::resolve) + .filter(select -> select instanceof ConceptColumnSelect) + .findFirst() + .map(select -> selectContext.getDialectBundle().getSelectConverter(select).connectorSelect(select, selectContext)) + .orElse(ConnectorSqlSelects.none()); } @Override @@ -263,8 +275,8 @@ public ConversionContext convert(CQConcept cqConcept, ConversionContext context) TablePath tablePath = new TablePath(cqConcept, context); List convertedCQTables = cqConcept.getTables().stream() - .flatMap(cqTable -> convertCqTable(tablePath, cqConcept, cqTable, context).stream()) - .toList(); + .flatMap(cqTable -> convertCqTable(tablePath, cqConcept, cqTable, context).stream()) + .toList(); QueryStep joinedStep = QueryStepJoiner.joinSteps(convertedCQTables, ConqueryJoinType.OUTER_JOIN, DateAggregationAction.MERGE, context); QueryStep lastConceptStep = finishConceptConversion(joinedStep, cqConcept, tablePath, context); @@ -289,39 +301,40 @@ private CQTableContext createTableContext(TablePath tablePath, CQConcept cqConce SqlIdColumns ids = convertIds(cqConcept, cqTable, conversionContext); ConnectorSqlTables connectorTables = tablePath.getConnectorTables(cqTable); - Optional tablesValidityDate = convertValidityDate(cqTable, connectorTables.getLabel(), conversionContext); + ColumnDateRange tablesValidityDate = convertValidityDate(connectorTables.getLabel(), conversionContext, cqTable.findValidityDate()); // convert filters SqlFunctionProvider functionProvider = conversionContext.getFunctionProvider(); List allSqlFiltersForTable = new ArrayList<>(); + cqTable.getFilters().stream() - .map(filterValue -> filterValue.convertToSqlFilter(ids, conversionContext, connectorTables)) - .forEach(allSqlFiltersForTable::add); - collectConditionFilters(cqConcept.getElements().stream().>map(ConceptElementId::resolve).toList(), cqTable, functionProvider).ifPresent( - allSqlFiltersForTable::add); - if (tablesValidityDate.isPresent()) { - allSqlFiltersForTable.add(dateRestrictionFilter(conversionContext, tablesValidityDate.get())); - } + .map(filterValue -> filterValue.convertToSqlFilter(ids, conversionContext, connectorTables)) + .forEach(allSqlFiltersForTable::add); + + List> conceptElements = cqConcept.getElements().stream().>map(ConceptElementId::resolve).toList(); + allSqlFiltersForTable.add(collectConditionFilters(conceptElements, cqTable, functionProvider)); + + allSqlFiltersForTable.add(dateRestrictionFilter(conversionContext, tablesValidityDate)); // convert selects - SelectContext selectContext = SelectContext.create(ids, tablesValidityDate, connectorTables, conversionContext); + SelectContext selectContext = SelectContext.create(ids, Optional.of(tablesValidityDate), connectorTables, conversionContext); List allSelectsForTable = new ArrayList<>(); ConnectorSqlSelects conceptColumnSelect = createConceptColumnConnectorSqlSelects(cqConcept, selectContext); allSelectsForTable.add(conceptColumnSelect); cqTable.getSelects() - .stream() - .map(SelectId::resolve) - .map(select -> select.createConverter().connectorSelect(select, selectContext)) - .forEach(allSelectsForTable::add); + .stream() + .map(SelectId::resolve) + .map(select -> selectContext.getDialectBundle().getSelectConverter(select).connectorSelect(select, selectContext)) + .forEach(allSelectsForTable::add); return CQTableContext.builder() - .ids(ids) - .validityDate(tablesValidityDate) - .sqlSelects(allSelectsForTable) - .sqlFilters(allSqlFiltersForTable) - .connectorTables(connectorTables) - .conversionContext(conversionContext) - .build(); + .ids(ids) + .validityDate(tablesValidityDate) + .sqlSelects(allSelectsForTable) + .sqlFilters(allSqlFiltersForTable) + .connectorTables(connectorTables) + .conversionContext(conversionContext) + .build(); } } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/CQTableContext.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/CQTableContext.java index 7c83306b23..de565ccb5f 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/CQTableContext.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/CQTableContext.java @@ -24,7 +24,7 @@ class CQTableContext implements Context { SqlIdColumns ids; - Optional validityDate; + ColumnDateRange validityDate; List sqlSelects; List sqlFilters; ConnectorSqlTables connectorTables; diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/JoinBranchesCte.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/JoinBranchesCte.java index da826be3a0..b2f6718dfd 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/JoinBranchesCte.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/JoinBranchesCte.java @@ -58,7 +58,7 @@ protected QueryStep.QueryStepBuilder convertStep(CQTableContext tableContext) { // validity date aggregation Optional validityDate; - if (tableContext.getValidityDate().isEmpty() || !tableContext.getConnectorTables().isWithIntervalPacking()) { + if (!tableContext.getConnectorTables().isWithIntervalPacking()) { validityDate = Optional.empty(); } else { @@ -97,7 +97,7 @@ private static IntervalPackingContext createIntervalPackingContext(CQTableContex Selects predcessorSelects = tableContext.getPrevious().getQualifiedSelects(); return IntervalPackingContext.builder() .ids(predcessorSelects.getIds()) - .daterange(tableContext.getValidityDate().get()) + .daterange(tableContext.getValidityDate()) .tables(tableContext.getConnectorTables()) .build(); } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/PreprocessingCte.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/PreprocessingCte.java index 80f377a025..3ced541d97 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/PreprocessingCte.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/cqelement/concept/PreprocessingCte.java @@ -2,6 +2,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Optional; import com.bakdata.conquery.sql.conversion.dialect.SqlFunctionProvider; import com.bakdata.conquery.sql.conversion.model.QueryStep; @@ -32,7 +33,7 @@ public QueryStep.QueryStepBuilder convertStep(CQTableContext tableContext) { Selects preprocessingSelects = Selects.builder() .ids(tableContext.getIds()) - .validityDate(tableContext.getValidityDate()) + .validityDate(Optional.of(tableContext.getValidityDate())) .sqlSelects(forPreprocessing) .build(); // all where clauses that don't require any preprocessing (connector/child conditions) @@ -81,7 +82,7 @@ private static QueryStep.QueryStepBuilder joinWithStratificationTable( Selects selects = Selects.builder() .ids(stratificationSelects.getIds()) - .validityDate(tableContext.getValidityDate()) + .validityDate(Optional.of(tableContext.getValidityDate())) .stratificationDate(stratificationSelects.getStratificationDate()) .sqlSelects(preprocessingSelects) .build(); diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/DialectBundle.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/DialectBundle.java index e66402d491..d0596962c3 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/DialectBundle.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/dialect/DialectBundle.java @@ -1,5 +1,6 @@ package com.bakdata.conquery.sql.conversion.dialect; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.function.Function; @@ -7,6 +8,7 @@ import com.bakdata.conquery.models.config.ConqueryConfig; import com.bakdata.conquery.models.config.Dialect; +import com.bakdata.conquery.models.datasets.concepts.select.Select; import com.bakdata.conquery.models.events.MajorTypeId; import com.bakdata.conquery.models.query.Visitable; import com.bakdata.conquery.sql.conversion.Converter; @@ -20,6 +22,7 @@ import com.bakdata.conquery.sql.conversion.cqelement.concept.CQConceptConverter; import com.bakdata.conquery.sql.conversion.forms.StratificationFunctions; import com.bakdata.conquery.sql.conversion.model.QueryStepTransformer; +import com.bakdata.conquery.sql.conversion.model.select.SelectConverter; import com.bakdata.conquery.sql.conversion.query.AbsoluteFormQueryConverter; import com.bakdata.conquery.sql.conversion.query.CQReusedQueryConverter; import com.bakdata.conquery.sql.conversion.query.ConceptQueryConverter; @@ -34,7 +37,6 @@ import org.jooq.Field; import org.jooq.SQLDialect; -//TODO unify with com.bakdata.conquery.models.config.Dialect public interface DialectBundle { private static > List customize(List defaults, List substitutes) { @@ -75,8 +77,6 @@ public interface DialectBundle { List> getNodeConverters(DSLContext context); - SqlCDateSetParser getCDateSetParser(); - default boolean supportsSingleColumnRanges() { return false; } @@ -104,4 +104,17 @@ default List> getDefaultNodeConverters(DSLCon ); } + default Map, ? extends SelectConverter> getSelectConverterOverrides(){ + return Collections.emptyMap(); + } + + default SelectConverter maybeOverride = (SelectConverter