Fix timeout in large $everything operation (#5298)

* Fixes

* Changelog

* Spotless

* Compress data file

* Remove fixme

* Fix imports

* Test fix

* Compile fix

* Apply spotless

* Address review comments
This commit is contained in:
James Agnew 2023-09-13 17:08:00 -04:00 committed by GitHub
parent 564beb7211
commit 7ecc0e66c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 1787 additions and 1717 deletions

View File

@ -0,0 +1,4 @@
---
type: fix
issue: 5298
title: "Under some circumstances, a large `$everything` operation could enter an infinite loop and eventually timeout with a failure. This has been corrected."

View File

@ -2679,6 +2679,7 @@ public class QueryStack {
Condition predicate =
table.createEverythingPredicate(theResourceName, theTypeSourceResourceNames, theTargetPids);
mySqlBuilder.addPredicate(predicate);
mySqlBuilder.getSelect().setIsDistinct(true);
}
public IQueryParameterType newParameterInstance(

View File

@ -2051,7 +2051,7 @@ public class SearchBuilder implements ISearchBuilder<JpaPid> {
}
if (myNext == null) {
// if we got here, it means the current PjaPid has already been processed
// if we got here, it means the current JpaPid has already been processed,
// and we will decide (here) if we need to fetch related resources recursively
if (myFetchIncludesForEverythingOperation) {
myIncludesIterator = new IncludesIterator(myPidSet, myRequest);

View File

@ -32,8 +32,6 @@ import org.hibernate.ScrollableResults;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Arrays;
import javax.persistence.EntityManager;
import javax.persistence.FlushModeType;
@ -48,14 +46,11 @@ public class SearchQueryExecutor implements ISearchQueryExecutor {
private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
private static final Logger ourLog = LoggerFactory.getLogger(SearchQueryExecutor.class);
private final GeneratedSql myGeneratedSql;
private final Integer myMaxResultsToFetch;
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
private EntityManager myEntityManager;
private boolean myQueryInitialized;
private Connection myConnection;
private PreparedStatement myStatement;
private ScrollableResultsIterator<Number> myResultSet;
private Long myNext;
@ -66,7 +61,6 @@ public class SearchQueryExecutor implements ISearchQueryExecutor {
Validate.notNull(theGeneratedSql, "theGeneratedSql must not be null");
myGeneratedSql = theGeneratedSql;
myQueryInitialized = false;
myMaxResultsToFetch = theMaxResultsToFetch;
}
/**
@ -76,7 +70,6 @@ public class SearchQueryExecutor implements ISearchQueryExecutor {
assert NO_MORE != null;
myGeneratedSql = null;
myMaxResultsToFetch = null;
myNext = NO_MORE;
}