Skip to content

Commit

Permalink
slightly reworked LoD hierarchy query to improve performance
Browse files Browse the repository at this point in the history
  • Loading branch information
clausnagel committed Jul 13, 2024
1 parent c25bd89 commit 897097a
Showing 1 changed file with 22 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,11 @@
import org.citydb.model.common.RelationType;
import org.citydb.sqlbuilder.common.SqlObject;
import org.citydb.sqlbuilder.function.Function;
import org.citydb.sqlbuilder.join.Joins;
import org.citydb.sqlbuilder.literal.BooleanLiteral;
import org.citydb.sqlbuilder.literal.IntegerLiteral;
import org.citydb.sqlbuilder.literal.StringLiteral;
import org.citydb.sqlbuilder.operation.Case;
import org.citydb.sqlbuilder.operation.Not;
import org.citydb.sqlbuilder.operation.Operators;
import org.citydb.sqlbuilder.query.CommonTableExpression;
import org.citydb.sqlbuilder.query.Select;
import org.citydb.sqlbuilder.schema.Table;
Expand Down Expand Up @@ -123,20 +121,21 @@ public Select getRecursiveLodQuery(Set<String> lods, boolean requireAll, int sea
adapter.getConnectionDetails().getSchema(), generator);

Select featureQuery = Select.newInstance()
.select(PlainText.of("null::bigint").as("id"),
table.column("id").as("feature_id"),
.select(table.column("id").as("feature_id"),
table.column("id").as("val_feature_id"),
IntegerLiteral.of(RelationType.CONTAINS.getDatabaseValue()).as("val_relation_type"),
PlainText.of("null::text").as("val_lod"));
IntegerLiteral.of(0).as("val_relation_type"));
Select propertyQuery = Select.newInstance()
.select(property.column("id"),
property.column("feature_id"),
.select(property.column("feature_id"),
property.column("val_feature_id"),
property.column("val_relation_type"),
property.column("val_lod"))
property.column("val_relation_type"))
.from(property)
.join(Joins.inner(hierarchy, "val_feature_id", Operators.EQUAL_TO, property.column("feature_id"))
.condition(hierarchy.column("val_relation_type").eq(RelationType.CONTAINS.getDatabaseValue())));
.join(hierarchy).on(hierarchy.column("val_feature_id").eq(property.column("feature_id")))
.where(property.column("val_feature_id").isNotNull(),
property.column("val_relation_type").eq(RelationType.CONTAINS.getDatabaseValue()));
Select hierarchyQuery = Select.newInstance()
.withRecursive(CommonTableExpression.of(hierarchy.getName(), featureQuery.unionAll(propertyQuery)))
.select(hierarchy.column("val_feature_id"))
.from(hierarchy);

if (searchDepth >= 0 && searchDepth != Integer.MAX_VALUE) {
featureQuery.select(IntegerLiteral.of(0).as("depth"));
Expand All @@ -145,6 +144,7 @@ public Select getRecursiveLodQuery(Set<String> lods, boolean requireAll, int sea
.then(PlainText.of("depth"))
.orElse(PlainText.of("depth").plus(1)))
.where(PlainText.of("depth").lt(IntegerLiteral.of(searchDepth + 1)));
hierarchyQuery.where(PlainText.of("depth").lt(IntegerLiteral.of(searchDepth + 1)));
} else {
featureQuery.select(BooleanLiteral.FALSE.as("is_cycle"),
PlainText.of("array[]::bigint[]").as("path"));
Expand All @@ -153,20 +153,25 @@ public Select getRecursiveLodQuery(Set<String> lods, boolean requireAll, int sea
.where(Not.of(PlainText.of("is_cycle")));
}

hierarchy = Table.of(hierarchyQuery, generator);
property = Table.of(org.citydb.database.schema.Table.PROPERTY.getName(),
adapter.getConnectionDetails().getSchema(), generator);

Select select = Select.newInstance()
.withRecursive(CommonTableExpression.of(hierarchy.getName(), featureQuery.unionAll(propertyQuery)))
.select(IntegerLiteral.of(1))
.from(hierarchy);
.from(property)
.join(hierarchy).on(hierarchy.column("val_feature_id").eq(property.column("feature_id")))
.fetch(1);

if (!lods.isEmpty()) {
select.where(adapter.getSchemaAdapter().getOperationHelper()
.in(hierarchy.column("val_lod"), lods.stream().map(StringLiteral::of).toList()));
.in(property.column("val_lod"), lods.stream().map(StringLiteral::of).toList()));
if (requireAll && lods.size() > 1) {
select.having(Function.of("count", hierarchy.column("val_lod")).qualifier("distinct")
select.having(Function.of("count", property.column("val_lod")).qualifier("distinct")
.eq(lods.size()));
}
} else {
select.where(hierarchy.column("val_lod").isNotNull());
select.where(property.column("val_lod").isNotNull());
}

return select;
Expand Down

0 comments on commit 897097a

Please sign in to comment.