Skip to content

Commit 76b54f2

Browse files
authored
[feat] history relationship dedup logic (#538)
* dedup logic * fix + unit test * fix * utilize validator
1 parent 9888ac1 commit 76b54f2

File tree

6 files changed

+288
-16
lines changed

6 files changed

+288
-16
lines changed

dao-impl/ebean-dao/src/main/java/com/linkedin/metadata/dao/EbeanLocalRelationshipQueryDAO.java

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -522,26 +522,54 @@ private <SNAPSHOT extends RecordTemplate> SNAPSHOT constructSnapshot(@Nonnull fi
522522
* INNER JOIN source_entity_table st ON st.urn = rt.sourceEntityUrn
523523
* WHERE destination entity filters AND source entity filters AND relationship filters</p>
524524
*
525+
* <p> or if relationshipLookUpContext.isIncludeNonCurrentRelationships is true </p>
526+
*
527+
* <p>SELECT * FROM (
528+
* SELECT rt.*, ROW_NUMBER() OVER (PARTITION BY rt.source, rt.metadata$type, rt.destination ORDER BY rt.lastmodifiedon DESC) AS row_num
529+
* FROM relationship_table rt
530+
* INNER JOIN destination_entity_table dt ON dt.urn = rt.destinationEntityUrn
531+
* INNER JOIN source_entity_table st ON st.urn = rt.sourceEntityUrn
532+
* WHERE destination entity filters AND source entity filters AND relationship filters)
533+
* ranked_rows WHERE row_num = 1</p>
534+
*
525535
* @param relationshipTableName relationship table name
526536
* @param relationshipFilter filter on relationship
527537
* @param sourceTableName source entity table name
528538
* @param sourceEntityFilter filter on source entity.
529539
* @param destTableName destination entity table name. Always null if building relationship with non-mg
530540
* entity.
531541
* @param destinationEntityFilter filter on destination entity.
532-
* @param limit max number of records to return. If < 0, will return all records.
533-
* @param offset offset to start from. If < 0, will start from 0.
542+
* @param limit max number of records to return. If less than 0, will return all records.
543+
* @param offset offset to start from. If less than 0, will start from 0.
534544
*/
535545
@Nonnull
536-
private String buildFindRelationshipSQL(
537-
@Nonnull final String relationshipTableName, @Nonnull final LocalRelationshipFilter relationshipFilter,
538-
@Nullable final String sourceTableName, @Nullable final LocalRelationshipFilter sourceEntityFilter,
539-
@Nullable final String destTableName, @Nullable final LocalRelationshipFilter destinationEntityFilter,
540-
int limit, int offset, RelationshipLookUpContext relationshipLookUpContext) {
546+
@VisibleForTesting
547+
public String buildFindRelationshipSQL(@Nonnull final String relationshipTableName,
548+
@Nonnull final LocalRelationshipFilter relationshipFilter, @Nullable final String sourceTableName,
549+
@Nullable final LocalRelationshipFilter sourceEntityFilter, @Nullable final String destTableName,
550+
@Nullable final LocalRelationshipFilter destinationEntityFilter, int limit, int offset,
551+
RelationshipLookUpContext relationshipLookUpContext) {
541552

542553
boolean includeNonCurrentRelationships = relationshipLookUpContext.isIncludeNonCurrentRelationships();
543554
StringBuilder sqlBuilder = new StringBuilder();
544-
sqlBuilder.append("SELECT rt.* FROM ").append(relationshipTableName).append(" rt ");
555+
556+
if (includeNonCurrentRelationships) {
557+
sqlBuilder.append("SELECT * FROM (");
558+
}
559+
560+
sqlBuilder.append("SELECT rt.*");
561+
562+
if (includeNonCurrentRelationships) {
563+
final boolean isNonDollarVirtualColumnsEnabled = _eBeanDAOConfig.isNonDollarVirtualColumnsEnabled();
564+
final String metadataTypeColName = isNonDollarVirtualColumnsEnabled ? "metadata0type" : "metadata$type";
565+
final boolean hasMetadataTypeCol = _schemaValidatorUtil.columnExists(relationshipTableName, metadataTypeColName);
566+
567+
sqlBuilder.append(", ROW_NUMBER() OVER (PARTITION BY rt.source")
568+
.append(hasMetadataTypeCol ? ", rt." + metadataTypeColName : "")
569+
.append(", rt.destination ORDER BY rt.lastmodifiedon DESC) AS row_num");
570+
}
571+
572+
sqlBuilder.append(" FROM ").append(relationshipTableName).append(" rt ");
545573

546574
List<Pair<LocalRelationshipFilter, String>> filters = new ArrayList<>();
547575

@@ -612,7 +640,8 @@ private String buildFindRelationshipSQL(
612640
}
613641
if (whereClauseBuilder.length() != 0) {
614642
if (includeNonCurrentRelationships) {
615-
sqlBuilder.append("WHERE ").append(whereClauseBuilder.toString().replaceFirst("^AND\\s+", ""));
643+
String where = whereClauseBuilder.toString().replaceFirst("\\s*AND\\s+", "");
644+
sqlBuilder.append("WHERE ").append(where);
616645
} else {
617646
sqlBuilder.append("WHERE ").append(whereClauseBuilder);
618647
}
@@ -628,6 +657,11 @@ private String buildFindRelationshipSQL(
628657
sqlBuilder.append(" OFFSET ").append(offset);
629658
}
630659
}
660+
661+
if (includeNonCurrentRelationships) {
662+
sqlBuilder.append(") ranked_rows WHERE row_num = 1");
663+
}
664+
631665
return sqlBuilder.toString();
632666
}
633667

0 commit comments

Comments
 (0)