Class UnionStatementGenerator

java.lang.Object
org.datanucleus.store.rdbms.sql.AbstractSelectStatementGenerator
org.datanucleus.store.rdbms.sql.UnionStatementGenerator
All Implemented Interfaces:
SelectStatementGenerator

public class UnionStatementGenerator extends AbstractSelectStatementGenerator
Class to generate a SelectStatement for iterating through instances of a particular type (and optionally subclasses). Based around the candidate type having subclasses and we use UNIONs to return all possible types of candidate. Also allows select of a dummy column to return the type for the part of the UNION that the object came from. Please refer to the specific constructors for the usages.

Supported options

This generator supports
  • selectDnType : adds a SELECT of a dummy column accessible as "DN_TYPE" storing the class name.
  • allowNulls : whether we allow for null objects (only happens when we have a join table collection.
  • Field Details

    • DN_TYPE_COLUMN

      public static final String DN_TYPE_COLUMN
      Name of column added when using "selectDnType"
      See Also:
    • maxClassNameLength

      private int maxClassNameLength
  • Constructor Details

    • UnionStatementGenerator

      public UnionStatementGenerator(RDBMSStoreManager storeMgr, org.datanucleus.ClassLoaderResolver clr, Class candidateType, boolean includeSubclasses, DatastoreIdentifier candidateTableAlias, String candidateTableGroupName)
      Constructor using the candidateTable as the primary table. If we are querying objects of type A with subclasses A1, A2 the query will be of the form :-
       SELECT ['mydomain.A' AS DN_TYPE]
       FROM A THIS
         LEFT OUTER JOIN A1 SUBELEMENT0 ON SUBELEMENT0.A1_ID = THIS.A_ID
         LEFT OUTER JOIN A1 SUBELEMENT1 ON SUBELEMENT0.A2_ID = THIS.A_ID
       WHERE SUBELEMENT0.A1_ID IS NULL
       AND SUBELEMENT0.A2_ID IS NULL
      
       UNION 
      
       SELECT ['mydomain.A1' AS DN_TYPE] 
       FROM A THIS
         INNER JOIN A1 'ELEMENT' ON 'ELEMENT'.A1_ID = THIS.A_ID
      
       UNION
      
       SELECT ['mydomain.A2' AS DN_TYPE] 
       FROM A THIS
         INNER JOIN A2 'ELEMENT' ON 'ELEMENT'.A2_ID = THIS.A_ID
       
      So the first part of the UNION returns the objects just present in the A table, whilst the second part returns those just in table A1, and the third part returns those just in table A2.
      Parameters:
      storeMgr - the store manager
      clr - ClassLoader resolver
      candidateType - the candidate that we are looking for
      includeSubclasses - if the subclasses of the candidate should be included in the result
      candidateTableAlias - Alias to use for the candidate table (optional)
      candidateTableGroupName - Name of the table group for the candidate(s) (optional)
    • UnionStatementGenerator

      public UnionStatementGenerator(RDBMSStoreManager storeMgr, org.datanucleus.ClassLoaderResolver clr, Class candidateType, boolean includeSubclasses, DatastoreIdentifier candidateTableAlias, String candidateTableGroupName, Table joinTable, DatastoreIdentifier joinTableAlias, JavaTypeMapping joinElementMapping)
      Constructor using a join table as the primary table. If we are querying elements (B) of a collection in class A and B has subclasses B1, B2 stored via a join table (A_B) the query will be of the form :-
       SELECT ['mydomain.B' AS DN_TYPE]
       FROM A_B T0
         INNER JOIN B T1 ON T0.B_ID_EID = T1.B_ID
         LEFT OUTER JOIN B1 T2 ON T2.B1_ID = T0.B_ID_EID
         LEFT OUTER JOIN B2 T3 ON T3.B2_ID = T0.B_ID_EID
       WHERE T2.B1_ID IS NULL
       AND T3.B2_ID IS NULL
      
       UNION 
      
       SELECT ['mydomain.B1' AS DN_TYPE] 
       FROM A_B THIS
         INNER JOIN B T1 ON T1.B_ID = T0.B_ID_EID
         INNER JOIN B1 T2 ON T2.B1_ID = T1.B_ID
      
       UNION
      
       SELECT ['mydomain.A2' AS DN_TYPE] 
       FROM A_B THIS
         INNER JOIN B T1 ON T1.B_ID = T0.B_ID_EID
         INNER JOIN B2 T2 ON T2.B2_ID = T1.B_ID
       
      So the first part of the UNION returns the objects just present in the B table, whilst the second part returns those just in table B1, and the third part returns those just in table B2. When we have a join table collection we MUST select the join table since this then caters for the situation of having null elements (if we had selected the root element table we wouldn't know if there was a null element in the collection).
      Parameters:
      storeMgr - the store manager
      clr - ClassLoader resolver
      candidateType - the candidate that we are looking for
      includeSubclasses - if the subclasses of the candidate should be included in the result
      candidateTableAlias - Alias to use for the candidate table (optional)
      candidateTableGroupName - Name of the table group for the candidate(s) (optional)
      joinTable - Join table linking owner to elements
      joinTableAlias - any alias to use for the join table in the SQL
      joinElementMapping - Mapping in the join table to link to the element
  • Method Details

    • setParentStatement

      public void setParentStatement(SQLStatement stmt)
      Description copied from interface: SelectStatementGenerator
      Method to set the parent statement. Must be set before calling getStatement().
      Parameters:
      stmt - The parent statement
    • getStatement

      public SelectStatement getStatement(org.datanucleus.ExecutionContext ec)
      Accessor for the SelectStatement for the candidate [+ subclasses].
      Parameters:
      ec - ExecutionContext
      Returns:
      The SelectStatement returning objects with a UNION statement.
    • getSelectStatementForCandidate

      protected SelectStatement getSelectStatementForCandidate(String className, org.datanucleus.ExecutionContext ec)
      Convenience method to return the SelectStatement for a particular class. Returns a SelectStatement with primaryTable of the "candidateTable", and which joins to the table of the class (if different).
      Parameters:
      className - The class name to generate the statement for
      ec - ExecutionContext
      Returns:
      The SelectStatement
    • getSQLStatementForCandidateViaJoin

      protected SelectStatement getSQLStatementForCandidateViaJoin(String className)
      Convenience method to return the SQLStatement for a particular class selecting a join table. Returns a SQLStatement with primaryTable of the "joinTable", and which joins to the table of the class.
      Parameters:
      className - The class name to generate the statement for
      Returns:
      The SQLStatement
    • addTypeSelectForClass

      private void addTypeSelectForClass(SelectStatement stmt, String className)
      Convenience method to add a SELECT of a dummy column accessible as "DN_TYPE" storing the class name.
      Parameters:
      stmt - SQLStatement
      className - Name of the class