Skip to content

Conversation

@awildturtok
Copy link
Collaborator

@awildturtok awildturtok commented Jan 22, 2026

Eine Beispielhafte join-table könnte folgende Einträge enthalten:

                     resolved_id                      | col_val
------------------------------------------------------+----------
 database.icd.s00-t98.s00-s09.s00.s00_0.s00_00 | T612
 database.icd.s00-t98.s00-s09.s00.s00_0.s00_00 | T611
 database.icd.s00-t98.s00-s09.s00.s00_0.s00_00 | T610
 database.icd.j00-j99.j30-j39.j38.j38_0.j38_00 | J951
  select
    diag.id as "pid",
    least(
      'infinity'::date,
      lower("datum"),
      upper("datum")
    ) as "lower_bound",
    greatest(
      '-infinity'::date,
      lower("datum"),
      upper("datum")
    ) as "upper_bound",
    "resolved_id"
  from "diag"
    left outer join "icd_ids"
      on "diag"."icd_code" = "col_val"

im Falle von ColumnEquals wären dann noch weitere Spalten dabei. Bei PRESENT/EMPTY wären stattdessen true/false drin, die dann im join abgebildet werden.

awildturtok and others added 30 commits November 12, 2025 15:24
# Conflicts:
#	backend/src/main/java/com/bakdata/conquery/mode/local/LocalStorageListener.java
Also fixes a case, where missing entries were not registered to the root.
…tats-as-sql-function

# Conflicts:
#	backend/src/main/java/com/bakdata/conquery/models/messages/namespaces/specific/UpdateMatchingStatsMessage.java
Comment on lines +19 to +20
@Data
public abstract class StorageListener<T extends Namespace>{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ich hätte das Interface beibehalten und davon diese abstract Class abgeleitet.

Interfaces können auch praktisch sein, da man für diese Proxies implementieren kann

*/
//TODO better name
record Expression(ConceptElement<?> conceptElement, Map<Field<?>, Set<Param<?>>> conditions) {
public Expression and(Expression other) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Braust du hier nicht eine parallel Struktur zu dem eigentlich Klassen Konstruct auf (AndCondition)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nein, weil das nicht die Condition Logik abbildet. OR kann ich soweit ich das sehe nicht mit den join-tables abbilden und wird auch einfach nirgends verwendet.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ebenso hab ich NOT nicht implmenetiert. Also es wird bei and bleiben, weil es die Logik vom Baum abbildet

Comment on lines +42 to +44
public Expression buildExpression(CTConditionContext context, ConceptElement<?> id) {
throw new IllegalStateException("Not implemented");
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

buildExpression aufzurufen wirkt wie ein Minenfeld 👀
Ich bin aber auch verwirrt, weil ich nur einen Aufruf dafür finde, der wiederum in einem anderen buildExpression ist

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

na ich hab einfach noch nicht alles implementiert und wir werden auch nicht alles implementieren können. NOT wurde eh nur mit IS_EMPTY/_PRESENT in Verbindung verwendet. deswegen hab ich das unrolled. NotCondition kommt dann weg

@JsonIgnore
private long numberOfEntities = -1L;

public synchronized long countEvents() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

müssen die synchronized sein?

if (foundEntities.add(entityForEvent)) {
numberOfEntities++;
}
public void addEventFromBucket(String entityForEvent, Bucket bucket, int event, Iterable<Column> dateColumns) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bucket ist bei SQL aber kein Ding mehr oder? Kann die Logik an einen passenderen Ort gepackt werden?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Löschen?

Comment on lines +405 to +406
.buildExpression(context, current)
.and(parentExpression);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bei Equal wirst du hier aber viele Doppelungen haben, da die Parentnodes ein Superset der ChildNodes sind

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Die werden schon geschnitten in der Expression and Implementierung

out.add(forCurrent);

for (ConceptTreeChild child : current.getChildren()) {
out.addAll(collectAllExpressions(child, forCurrent, context));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Du kannst dir hier viele kurzlebige Allokationen sparen in dem du die Liste zum hinzufügen als Argument mitgibst und nicht in jeder Recursion eine weitere Liste erzeugst.

return """
CREATE OR REPLACE FUNCTION %s(%s) RETURNS output NVARCHAR(500) AS
BEGIN
output = %s;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Muss %s nicht sanitized werden?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

die methode wird eh nicht mehr gebraucht aber für das was ich gemacht hatte nein, weil ich da jooq SQL reingesteckt hatte und das auch ausgeführt haben wollte

case REAL -> field.getDataType().isNumeric();
case DECIMAL -> field.getDataType().isDecimal();
case MONEY -> field.getDataType().isDecimal();
case MONEY -> true; // TODO Need to find proper name
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ist das ein Workaround?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jooq hat kein money type und es gibt keine introspection, die mir money herausgibt

private CDateRange span;

@JsonIgnore
private long numberOfEvents = -1L;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vielleicht könnte man hier generell auf LongAdder umsteigen und auf die Map verzichten, aber ist nur so ein Gedanke. Würde glaube ich die Synchronisierungs- und Summen-Logik vereinfachen.

@Override
public WhereCondition convertToSqlCondition(CTConditionContext context) {
Field<String> field = DSL.field(DSL.name(context.getConnectorTable().getName(), column), String.class);
Field<String> field = (Field<String>) (Field<?>) field(DSL.name(column));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Field<String> field = (Field<String>) (Field<?>) field(DSL.name(column));
Field<String> field = field(DSL.name(column), String.class);


@Override
public Expression buildExpression(CTConditionContext context, ConceptElement<?> id) {
return new Expression(id, Map.of(field(DSL.name(getColumn()), VARCHAR).as("%s_equal".formatted(column)), values.stream().map(DSL::val).collect(Collectors.toSet())));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return new Expression(id, Map.of(field(DSL.name(getColumn()), VARCHAR).as("%s_equal".formatted(column)), values.stream().map(DSL::val).collect(Collectors.toSet())));
return new Expression(id, Map.of(field(name(getColumn()), VARCHAR).as("%s_equal".formatted(column)), values.stream().map(DSL::val).collect(Collectors.toSet())));


@Override
public WhereCondition convertToSqlCondition(CTConditionContext context) {
Condition condition = DSL.field(DSL.name(column)).isNull();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hier hast du überall noch nicht den static import für DSL. gemacht, an anderer Stelle schon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants