Skip to content

Commit

Permalink
Fix ConceptColumnSelect conversion if there is only 1 connector (#3495)
Browse files Browse the repository at this point in the history
  • Loading branch information
jnsrnhld authored Jul 29, 2024
1 parent c8f3dc3 commit 3667d79
Show file tree
Hide file tree
Showing 28 changed files with 210 additions and 110 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,9 @@
import com.bakdata.conquery.apiv1.query.concept.specific.CQConcept;
import com.bakdata.conquery.models.datasets.Column;
import com.bakdata.conquery.models.datasets.concepts.ConceptElement;
import com.bakdata.conquery.models.datasets.concepts.Connector;
import com.bakdata.conquery.models.datasets.concepts.select.concept.ConceptColumnSelect;
import com.bakdata.conquery.models.datasets.concepts.tree.ConceptTreeChild;
import com.bakdata.conquery.models.datasets.concepts.tree.ConceptTreeNode;
import com.bakdata.conquery.models.datasets.concepts.tree.TreeConcept;
import com.bakdata.conquery.models.query.queryplan.DateAggregationAction;
import com.bakdata.conquery.sql.conversion.NodeConverter;
import com.bakdata.conquery.sql.conversion.SharedAliases;
Expand Down Expand Up @@ -99,7 +97,7 @@ private static QueryStep finishConceptConversion(QueryStep predecessor, CQConcep
Optional<ColumnDateRange> validityDate = predecessorSelects.getValidityDate();
SqlIdColumns ids = predecessorSelects.getIds();

SelectContext<TreeConcept, ConceptSqlTables> selectContext = SelectContext.create(cqConcept, ids, validityDate, universalTables, context);
SelectContext<ConceptSqlTables> selectContext = SelectContext.create(cqConcept, ids, validityDate, universalTables, context);
List<ConceptSqlSelects> converted = cqConcept.getSelects().stream()
.map(select -> select.createConverter().conceptSelect(select, selectContext))
.toList();
Expand Down Expand Up @@ -153,7 +151,7 @@ private CQTableContext createTableContext(TablePath tablePath, CQConcept cqConce
getDateRestriction(conversionContext, tablesValidityDate).ifPresent(allSqlFiltersForTable::add);

// convert selects
SelectContext<Connector, ConnectorSqlTables> selectContext = SelectContext.create(cqTable, ids, tablesValidityDate, connectorTables, conversionContext);
SelectContext<ConnectorSqlTables> selectContext = SelectContext.create(cqTable, ids, tablesValidityDate, connectorTables, conversionContext);
List<ConnectorSqlSelects> allSelectsForTable = new ArrayList<>();
ConnectorSqlSelects conceptColumnSelect = createConceptColumnConnectorSqlSelects(cqConcept, selectContext);
allSelectsForTable.add(conceptColumnSelect);
Expand Down Expand Up @@ -277,7 +275,7 @@ private static Optional<SqlFilters> getDateRestriction(ConversionContext context
));
}

private static ConnectorSqlSelects createConceptColumnConnectorSqlSelects(CQConcept cqConcept, SelectContext<Connector, ConnectorSqlTables> selectContext) {
private static ConnectorSqlSelects createConceptColumnConnectorSqlSelects(CQConcept cqConcept, SelectContext<ConnectorSqlTables> selectContext) {
return cqConcept.getSelects().stream()
.filter(select -> select instanceof ConceptColumnSelect)
.findFirst()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,21 @@
import java.util.Map;

import com.bakdata.conquery.sql.conversion.model.CteStep;
import com.bakdata.conquery.sql.conversion.model.SqlTables;
import lombok.Getter;

@Getter
public class ConceptSqlTables extends ConnectorSqlTables {
public class ConceptSqlTables extends SqlTables {

private final List<ConnectorSqlTables> connectorTables;

public ConceptSqlTables(
String conceptConnectorLabel,
String rootTable,
Map<CteStep, String> cteNameMap,
Map<CteStep, CteStep> predecessorMap,
boolean containsIntervalPacking,
List<ConnectorSqlTables> connectorTables
) {
super(conceptConnectorLabel, rootTable, cteNameMap, predecessorMap, containsIntervalPacking);
super(rootTable, cteNameMap, predecessorMap);
this.connectorTables = connectorTables;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.Map;

import com.bakdata.conquery.models.datasets.concepts.Connector;
import com.bakdata.conquery.sql.conversion.cqelement.intervalpacking.IntervalPackingCteStep;
import com.bakdata.conquery.sql.conversion.model.CteStep;
import com.bakdata.conquery.sql.conversion.model.SqlTables;
Expand All @@ -20,14 +21,21 @@ public class ConnectorSqlTables extends SqlTables {
*/
private final boolean withIntervalPacking;

/**
* Corresponding {@link Connector} of these {@link SqlTables}.
*/
private final Connector connector;

public ConnectorSqlTables(
Connector connector,
String conceptConnectorLabel,
String rootTable,
Map<CteStep, String> cteNameMap,
Map<CteStep, CteStep> predecessorMap,
boolean containsIntervalPacking
) {
super(rootTable, cteNameMap, predecessorMap);
this.connector = connector;
this.label = conceptConnectorLabel;
this.withIntervalPacking = containsIntervalPacking;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ private static ConnectorSqlTables createConnectorTables(CQConcept cqConcept, CQT
Map<CteStep, String> cteNameMap = CteStep.createCteNameMap(tableInfo.getMappings().keySet(), conceptConnectorLabel, context.getNameGenerator());

return new ConnectorSqlTables(
cqTable.getConnector(),
conceptConnectorLabel,
tableInfo.getRootTable(),
cteNameMap,
Expand All @@ -70,11 +71,9 @@ public ConceptSqlTables createConceptTables(QueryStep predecessor) {
List<ConnectorSqlTables> connectorSqlTables = this.connectorTableMap.values().stream().toList();

return new ConceptSqlTables(
conceptName,
tableInfo.getRootTable(),
cteNameMap,
tableInfo.getMappings(),
tableInfo.isContainsIntervalPacking(),
connectorSqlTables
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import com.bakdata.conquery.models.common.Range;
import com.bakdata.conquery.models.datasets.Column;
import com.bakdata.conquery.models.datasets.concepts.Connector;
import com.bakdata.conquery.models.datasets.concepts.filters.specific.CountQuartersFilter;
import com.bakdata.conquery.models.datasets.concepts.select.connector.specific.CountQuartersSelect;
import com.bakdata.conquery.models.events.MajorTypeId;
Expand Down Expand Up @@ -34,7 +33,7 @@
public class CountQuartersSqlAggregator implements SelectConverter<CountQuartersSelect>, FilterConverter<CountQuartersFilter, Range.LongRange>, SqlAggregator {

@Override
public ConnectorSqlSelects connectorSelect(CountQuartersSelect countQuartersSelect, SelectContext<Connector, ConnectorSqlTables> selectContext) {
public ConnectorSqlSelects connectorSelect(CountQuartersSelect countQuartersSelect, SelectContext<ConnectorSqlTables> selectContext) {

String alias = selectContext.getNameGenerator().selectName(countQuartersSelect);
ConnectorSqlTables tables = selectContext.getTables();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.bakdata.conquery.models.common.Range;
import com.bakdata.conquery.models.datasets.Column;
import com.bakdata.conquery.models.datasets.concepts.Connector;
import com.bakdata.conquery.models.datasets.concepts.filters.specific.CountFilter;
import com.bakdata.conquery.models.datasets.concepts.select.connector.specific.CountSelect;
import com.bakdata.conquery.sql.conversion.cqelement.concept.ConceptCteStep;
Expand Down Expand Up @@ -36,7 +35,7 @@ public static CountType fromBoolean(boolean value) {
}

@Override
public ConnectorSqlSelects connectorSelect(CountSelect countSelect, SelectContext<Connector, ConnectorSqlTables> selectContext) {
public ConnectorSqlSelects connectorSelect(CountSelect countSelect, SelectContext<ConnectorSqlTables> selectContext) {

ConnectorSqlTables tables = selectContext.getTables();
CountType countType = CountType.fromBoolean(countSelect.isDistinct());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import com.bakdata.conquery.models.common.Range;
import com.bakdata.conquery.models.common.daterange.CDateRange;
import com.bakdata.conquery.models.datasets.Column;
import com.bakdata.conquery.models.datasets.concepts.Connector;
import com.bakdata.conquery.models.datasets.concepts.filters.specific.DateDistanceFilter;
import com.bakdata.conquery.models.datasets.concepts.select.connector.specific.DateDistanceSelect;
import com.bakdata.conquery.models.events.MajorTypeId;
Expand Down Expand Up @@ -36,7 +35,7 @@
public class DateDistanceSqlAggregator implements SelectConverter<DateDistanceSelect>, FilterConverter<DateDistanceFilter, Range.LongRange> {

@Override
public ConnectorSqlSelects connectorSelect(DateDistanceSelect select, SelectContext<Connector, ConnectorSqlTables> selectContext) {
public ConnectorSqlSelects connectorSelect(DateDistanceSelect select, SelectContext<ConnectorSqlTables> selectContext) {

Column column = select.getColumn();
String alias = selectContext.getNameGenerator().selectName(select);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import java.util.stream.Collectors;

import com.bakdata.conquery.models.datasets.Column;
import com.bakdata.conquery.models.datasets.concepts.Connector;
import com.bakdata.conquery.models.datasets.concepts.filters.specific.FlagFilter;
import com.bakdata.conquery.models.datasets.concepts.select.connector.specific.FlagSelect;
import com.bakdata.conquery.sql.conversion.cqelement.concept.ConceptCteStep;
Expand Down Expand Up @@ -73,7 +72,7 @@ public class FlagSqlAggregator implements SelectConverter<FlagSelect>, FilterCon
private static final Param<Integer> NUMERIC_TRUE_VAL = DSL.val(1);

@Override
public ConnectorSqlSelects connectorSelect(FlagSelect flagSelect, SelectContext<Connector, ConnectorSqlTables> selectContext) {
public ConnectorSqlSelects connectorSelect(FlagSelect flagSelect, SelectContext<ConnectorSqlTables> selectContext) {

SqlFunctionProvider functionProvider = selectContext.getConversionContext().getSqlDialect().getFunctionProvider();
SqlTables connectorTables = selectContext.getTables();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

import com.bakdata.conquery.models.common.IRange;
import com.bakdata.conquery.models.datasets.Column;
import com.bakdata.conquery.models.datasets.concepts.Connector;
import com.bakdata.conquery.models.datasets.concepts.filters.specific.SumFilter;
import com.bakdata.conquery.models.datasets.concepts.select.connector.specific.SumSelect;
import com.bakdata.conquery.sql.conversion.cqelement.concept.ConceptCteStep;
Expand Down Expand Up @@ -96,7 +95,7 @@ private enum SumDistinctCteStep implements CteStep {
private static final String SUM_DISTINCT_SUFFIX = "sum_distinct";

@Override
public ConnectorSqlSelects connectorSelect(SumSelect sumSelect, SelectContext<Connector, ConnectorSqlTables> selectContext) {
public ConnectorSqlSelects connectorSelect(SumSelect sumSelect, SelectContext<ConnectorSqlTables> selectContext) {

Column sumColumn = sumSelect.getColumn();
Column subtractColumn = sumSelect.getSubtractColumn();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import com.bakdata.conquery.models.datasets.concepts.Connector;
import com.bakdata.conquery.models.datasets.concepts.select.concept.ConceptColumnSelect;
import com.bakdata.conquery.models.datasets.concepts.tree.TreeConcept;
import com.bakdata.conquery.sql.conversion.SharedAliases;
import com.bakdata.conquery.sql.conversion.cqelement.concept.ConceptCteStep;
import com.bakdata.conquery.sql.conversion.cqelement.concept.ConceptSqlTables;
Expand Down Expand Up @@ -42,8 +41,8 @@ private enum CONCEPT_COLUMN_STEPS implements CteStep {
}

@Override
public ConnectorSqlSelects connectorSelect(ConceptColumnSelect select, SelectContext<Connector, ConnectorSqlTables> selectContext) {
Connector connector = selectContext.getSelectHolder();
public ConnectorSqlSelects connectorSelect(ConceptColumnSelect select, SelectContext<ConnectorSqlTables> selectContext) {
Connector connector = selectContext.getTables().getConnector();
if (connector.getColumn() == null) {
return ConnectorSqlSelects.none();
}
Expand All @@ -56,17 +55,17 @@ public ConnectorSqlSelects connectorSelect(ConceptColumnSelect select, SelectCon
}

@Override
public ConceptSqlSelects conceptSelect(ConceptColumnSelect select, SelectContext<TreeConcept, ConceptSqlTables> selectContext) {
public ConceptSqlSelects conceptSelect(ConceptColumnSelect select, SelectContext<ConceptSqlTables> selectContext) {

// we will do a union distinct on all Connector tables
List<? extends Connector> connectors;
if (isSingleConnectorConcept(selectContext.getSelectHolder())) {
if (isSingleConnector(selectContext.getTables())) {
// we union the Connector table with itself if there is only 1 Connector
Connector connector = selectContext.getSelectHolder().getConcept().getConnectors().get(0);
Connector connector = selectContext.getTables().getConnectorTables().get(0).getConnector();
connectors = List.of(connector, connector);
}
else {
connectors = selectContext.getSelectHolder().getConnectors();
connectors = selectContext.getTables().getConnectorTables().stream().map(ConnectorSqlTables::getConnector).toList();
}

NameGenerator nameGenerator = selectContext.getNameGenerator();
Expand Down Expand Up @@ -97,44 +96,42 @@ public ConceptSqlSelects conceptSelect(ConceptColumnSelect select, SelectContext
.build();
}

private static boolean isSingleConnectorConcept(TreeConcept treeConcept) {
return treeConcept.getConcept().getConnectors().size() == 1;
private static boolean isSingleConnector(ConceptSqlTables tables) {
return tables.getConnectorTables().size() == 1;
}

private static QueryStep createUnionConnectorConnectorsStep(
List<? extends Connector> connectors,
String alias,
SelectContext<TreeConcept, ConceptSqlTables> selectContext
SelectContext<ConceptSqlTables> selectContext
) {
List<QueryStep> unionSteps = selectContext.getTables()
.getConnectorTables()
.stream()
.map(tables -> createConnectorColumnSelectQuery(tables, connectors, alias, selectContext))
.toList();

List<QueryStep> unionSteps = connectors.stream().map(connector -> createConnectorColumnSelectQuery(connector, alias, selectContext)).toList();
String unionedColumnsCteName = selectContext.getNameGenerator().cteStepName(CONCEPT_COLUMN_STEPS.UNIONED_COLUMNS, alias);
return QueryStep.createUnionStep(unionSteps, unionedColumnsCteName, Collections.emptyList());
}

private static QueryStep createConnectorColumnSelectQuery(
ConnectorSqlTables tables,
List<? extends Connector> connectors,
Connector connector,
String alias,
SelectContext<TreeConcept, ConceptSqlTables> selectContext
SelectContext<ConceptSqlTables> selectContext
) {
Connector matchingConnector =
connectors.stream()
.filter(connector -> isMatchingConnector(tables, connector))
.findFirst()
.orElseThrow(() -> new IllegalStateException("Could not find matching connector for ConnectorSqlTables %s".formatted(tables)));

Table<Record> connectorTable = DSL.table(DSL.name(tables.cteName(ConceptCteStep.EVENT_FILTER)));

Field<Object> primaryColumn = TablePrimaryColumnUtil.findPrimaryColumn(matchingConnector.getTable(), selectContext.getConversionContext().getConfig());
// a ConceptColumn select uses all connectors a Concept has, even if they are not part of the CQConcept
// but if they are, we need to make sure we use the event-filtered table instead of the root table
String tableName = selectContext.getTables()
.getConnectorTables()
.stream()
.filter(tables -> Objects.equals(tables.getRootTable(), connector.getTable().getName()))
.findFirst()
.map(tables -> tables.cteName(ConceptCteStep.EVENT_FILTER))
.orElse(connector.getTable().getName());

Table<Record> connectorTable = DSL.table(DSL.name(tableName));

Field<Object> primaryColumn = TablePrimaryColumnUtil.findPrimaryColumn(connector.getTable(), selectContext.getConversionContext().getConfig());
Field<Object> qualifiedPrimaryColumn = QualifyingUtil.qualify(primaryColumn, connectorTable.getName()).as(SharedAliases.PRIMARY_COLUMN.getAlias());
SqlIdColumns ids = new SqlIdColumns(qualifiedPrimaryColumn);

Field<Object> connectorColumn = DSL.field(DSL.name(connectorTable.getName(), matchingConnector.getColumn().getName()));
Field<Object> connectorColumn = DSL.field(DSL.name(connectorTable.getName(), connector.getColumn().getName()));
Field<String> casted = selectContext.getFunctionProvider().cast(connectorColumn, SQLDataType.VARCHAR).as(alias);
FieldWrapper<String> connectorSelect = new FieldWrapper<>(casted);

Expand All @@ -149,11 +146,7 @@ private static QueryStep createConnectorColumnSelectQuery(
.build();
}

private static boolean isMatchingConnector(final ConnectorSqlTables tables, final Connector connector) {
return connector.getColumn() != null && (Objects.equals(tables.getRootTable(), connector.getTable().getName()));
}

private static FieldWrapper<String> createConnectorColumnStringAgg(SelectContext<TreeConcept, ConceptSqlTables> selectContext, QueryStep unionStep, String alias) {
private static FieldWrapper<String> createConnectorColumnStringAgg(SelectContext<ConceptSqlTables> selectContext, QueryStep unionStep, String alias) {
SqlFunctionProvider functionProvider = selectContext.getFunctionProvider();
Field<String> unionedColumn = DSL.field(DSL.name(unionStep.getCteName(), alias), String.class);
return new FieldWrapper<>(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package com.bakdata.conquery.sql.conversion.model.select;

import com.bakdata.conquery.models.datasets.concepts.Connector;
import com.bakdata.conquery.models.datasets.concepts.select.connector.specific.DateUnionSelect;
import com.bakdata.conquery.sql.conversion.cqelement.concept.ConnectorSqlTables;

public class DateUnionSelectConverter implements SelectConverter<DateUnionSelect> {

@Override
public ConnectorSqlSelects connectorSelect(DateUnionSelect select, SelectContext<Connector, ConnectorSqlTables> selectContext) {
public ConnectorSqlSelects connectorSelect(DateUnionSelect select, SelectContext<ConnectorSqlTables> selectContext) {
return DaterangeSelectUtil.createConnectorSqlSelects(
select,
(daterange, alias, functionProvider) -> new FieldWrapper<>(functionProvider.daterangeStringAggregation(daterange).as(alias)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import java.util.Optional;
import java.util.stream.Collectors;

import com.bakdata.conquery.models.datasets.concepts.Connector;
import com.bakdata.conquery.models.datasets.concepts.DaterangeSelectOrFilter;
import com.bakdata.conquery.models.identifiable.Named;
import com.bakdata.conquery.sql.conversion.cqelement.concept.ConceptCteStep;
Expand Down Expand Up @@ -45,7 +44,7 @@ public interface AggregationFunction {
public static <S extends DaterangeSelectOrFilter & Named<?>> ConnectorSqlSelects createConnectorSqlSelects(
S select,
AggregationFunction aggregationFunction,
SelectContext<Connector, ConnectorSqlTables> context
SelectContext<ConnectorSqlTables> context
) {
String alias = context.getNameGenerator().selectName(select);
ConnectorSqlTables tables = context.getTables();
Expand Down Expand Up @@ -95,7 +94,7 @@ private static Condition containsInfinityDate(ColumnDateRange validityDate, SqlF
return validityDate.getStart().eq(negativeInfinity).or(validityDate.getEnd().eq(positiveInfinity));
}

private static SqlTables createTables(String alias, SelectContext<Connector, ConnectorSqlTables> context) {
private static SqlTables createTables(String alias, SelectContext<ConnectorSqlTables> context) {
Map<CteStep, CteStep> predecessorMapping = new HashMap<>();
String eventFilterCteName = context.getTables().cteName(EVENT_FILTER);
predecessorMapping.putAll(IntervalPackingCteStep.getMappings(context.getSqlDialect()));
Expand All @@ -110,7 +109,7 @@ private static SqlTables createTables(String alias, SelectContext<Connector, Con
return new SqlTables(eventFilterCteName, cteNameMap, predecessorMapping);
}

private static QueryStep applyIntervalPacking(ColumnDateRange daterange, SqlTables dateUnionTables, SelectContext<?, ?> context) {
private static QueryStep applyIntervalPacking(ColumnDateRange daterange, SqlTables dateUnionTables, SelectContext<?> context) {

String eventFilterCteName = context.getTables().cteName(EVENT_FILTER);
IntervalPackingContext intervalPackingContext = IntervalPackingContext.builder()
Expand Down
Loading

0 comments on commit 3667d79

Please sign in to comment.