Class QueryStack

java.lang.Object
ca.uhn.fhir.jpa.dao.predicate.querystack.QueryStack

public class QueryStack extends Object
This class represents a SQL SELECT statement that is selecting for resource PIDs, ie. the RES_ID column on the HFJ_RESOURCE (ResourceTable) table.

We add predicates (WHERE A=B) to it, and can join other tables to it as well. At the root of the query we are typically doing a select RES_ID from HFJ_RESOURCE where (....) and this class is used to build the where clause. In the case of subqueries though, we may be performing a select on a different table since many tables have a column with a FK dependency on RES_ID.

  • Constructor Details

    • QueryStack

      public QueryStack(javax.persistence.criteria.CriteriaBuilder theCriteriaBuilder, String theResourceType, SearchParameterMap theSearchParameterMap, ca.uhn.fhir.interceptor.model.RequestPartitionId theRequestPartitionId)
      Constructor
  • Method Details

    • pushResourceTableQuery

      public void pushResourceTableQuery()
      Add a new select RES_ID from HFJ_RESOURCE to the stack. All predicates added to the QueryRootStack will be added to this select clause until pop() is called.

      This method must only be called when the stack is empty.

    • pushResourceTableDistinctQuery

      Add a new select DISTINCT RES_ID from HFJ_RESOURCE to the stack. All predicates added to the QueryRootStack will be added to this select clause until pop() is called.

      This method must only be called when the stack is empty.

    • pushResourceTableCountQuery

      Add a new select count(RES_ID) from HFJ_RESOURCE to the stack. All predicates added to the QueryRootStack will be added to this select clause until pop() is called.

      This method must only be called when the stack is empty.

    • pushResourceTableSubQuery

      public void pushResourceTableSubQuery(String theResourceType)
      Add a new select RES_ID from HFJ_RESOURCE to the stack. All predicates added to the QueryRootStack will be added to this select clause until pop() is called.

      This method must only be called when the stack is NOT empty.

    • pushIndexTableSubQuery

      public void pushIndexTableSubQuery()
      Add a new select RES_ID from (....) to the stack, where the specific table being selected on will be determined based on the first call to createJoin(SearchBuilderJoinEnum, String). All predicates added to the QueryRootStack will be added to this select clause until pop() is called.

      This method must only be called when the stack is NOT empty.

    • pop

      public javax.persistence.criteria.AbstractQuery<Long> pop()
      This method must be called once all predicates have been added
    • createJoin

      public <T> javax.persistence.criteria.From<?,T> createJoin(SearchBuilderJoinEnum theType, String theSearchParameterName)
      Creates a new SQL join from the current select statement to another table, using the resource PID as the joining key
    • getExistingJoin

      public Optional<javax.persistence.criteria.Join<?,?>> getExistingJoin(SearchBuilderJoinKey theKey)
      Returns a join that was previously created by a call to createJoin(SearchBuilderJoinEnum, String), if one exists for the given key.
    • get

      public <Y> javax.persistence.criteria.Path<Y> get(String theAttributeName)
      Gets an attribute (aka a column) from the current select statement.
      Parameters:
      theAttributeName - Must be the name of a java field for the entity/table being selected on
    • addPredicate

      public void addPredicate(javax.persistence.criteria.Predicate thePredicate)
      Adds a predicate to the current select statement
    • addPredicateWithImplicitTypeSelection

      public void addPredicateWithImplicitTypeSelection(javax.persistence.criteria.Predicate thePredicate)
      Adds a predicate and marks it as having implicit type selection in it. In other words, call this method if a this predicate will ensure:
      • Only Resource PIDs for the correct resource type will be selected
      • Only Resource PIDs for non-deleted resources will be selected
      Setting this flag is a performance optimization, since it avoids the need for us to explicitly add predicates for the two conditions above.
    • addPredicatesWithImplicitTypeSelection

      public void addPredicatesWithImplicitTypeSelection(List<javax.persistence.criteria.Predicate> thePredicates)
      Adds predicates and marks them as having implicit type selection in it. In other words, call this method if a this predicate will ensure:
      • Only Resource PIDs for the correct resource type will be selected
      • Only Resource PIDs for non-deleted resources will be selected
      Setting this flag is a performance optimization, since it avoids the need for us to explicitly add predicates for the two conditions above.
    • addPredicates

      public void addPredicates(List<javax.persistence.criteria.Predicate> thePredicates)
      Adds predicate(s) to the current select statement
    • clearPredicates

      public void clearPredicates()
      Clear all predicates from the current select statement
    • getPredicates

      public List<javax.persistence.criteria.Predicate> getPredicates()
      Fetch all the current predicates

      TODO This should really be package protected, but it is called externally in one spot - We need to clean that up at some point.

    • clearHasImplicitTypeSelection

      See Also:
      • setHasImplicitTypeSelection()
    • isEmpty

      public boolean isEmpty()
    • orderBy

      public void orderBy(List<javax.persistence.criteria.Order> theOrders)
      Add an SQL order by expression
    • getLastUpdatedColumn

      public javax.persistence.criteria.Expression<Date> getLastUpdatedColumn()
      Fetch the column for the current table root that corresponds to the resource's lastUpdated time
    • getResourcePidColumn

      public javax.persistence.criteria.Expression<Long> getResourcePidColumn()
      Fetch the column for the current table root that corresponds to the resource's PID
    • subqueryForTagNegation

      public javax.persistence.criteria.Subquery<Long> subqueryForTagNegation()
    • getRootForComposite

      public javax.persistence.criteria.Root<?> getRootForComposite()
      TODO This class should avoid leaking the internal query root, but we need to do so for how composite search params are currently implemented. These only half work in the first place so I'm not going to worry about the fact that they rely on a leaky abstraction right now.. But when we get around to implementing composites properly, let's not continue this. JA 2020-05-12
    • addNeverMatchingPredicate

      public javax.persistence.criteria.Predicate addNeverMatchingPredicate()
      Add a predicate that will never match any resources
    • getJoinMap

      public Map<String,javax.persistence.criteria.From<?,ResourceIndexedSearchParamDate>> getJoinMap()