Class 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 Detail

      • QueryStack

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

      • 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

        public void 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

        public void 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<Longpop()
        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
      • 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.

      • 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<DategetLastUpdatedColumn()
        Fetch the column for the current table root that corresponds to the resource's lastUpdated time
      • getResourcePidColumn

        public javax.persistence.criteria.Expression<LonggetResourcePidColumn()
        Fetch the column for the current table root that corresponds to the resource's PID
      • 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