Class SQLStatement

  • Direct Known Subclasses:
    DeleteStatement, InsertStatement, SelectStatement, UpdateStatement

    public abstract class SQLStatement
    extends Object
    Class providing an API for generating SQL statements. Caller should create the SQLStatement object and (optionally) call setClassLoaderResolver() to set any class loading restriction. Then the caller builds up the statement using the various methods, and accesses the SQL statement using getSQLText().

    The generated SQL is cached. Any use of a mutating method, changing the composition of the statement will clear the cached SQL, and it will be regenerated when

    getSQLText
    is called next.

    Table Groups

    When tables are registered in the statement they are split into "table groups". A table group is, in simple terms, an object in the query. If a table has a super-table and a field of the object is selected that is in the super-table then the super-table is added to the table group. If there is a join to a related object then the table of this object will be put in a new table group. So the same datastore table can appear multiple times in the statement, each time for a different object.

    Table Aliases

    All methods that cause a new SQLTable to be created also allow specification of the table alias in the statement. Where the alias is not provided then we use a table "namer" (definable on the plugin-point "org.datanucleus.store.rdbms.sql_tablenamer"). The table namer can define names simply based on the table number, or based on table group and the number of tables in the group etc etc. To select a particular table "namer", set the extension "table-naming-strategy" to the key of the namer plugin. The default is "alpha-scheme" which bases table names on the group and number in that group. Note that this class is not intended to be thread-safe. It is used by a single ExecutionContext
    • Field Detail

      • tableNamerByName

        protected static final Map<String,​SQLTableNamer> tableNamerByName
        Map of SQLTable naming instance keyed by the name of the naming scheme, shared across threads.
      • sql

        protected SQLText sql
        Cached SQL statement, generated by getSQLText().
      • clr

        protected org.datanucleus.ClassLoaderResolver clr
        ClassLoader resolver to use. Used by sub-expressions. Defaults to the loader resolver for the store manager.
      • queryGenerator

        protected QueryGenerator queryGenerator
        Context of any query generation.
      • candidateClassName

        protected String candidateClassName
        Name of class that this statement selects (optional, only typically for unioned statements).
      • extensions

        protected Map<String,​Object> extensions
        Map of extensions for use in generating the SQL, keyed by the extension name.
      • parent

        protected SQLStatement parent
        Parent statement, if this is a subquery SELECT. Must be set at construction.
      • primaryTable

        protected SQLTable primaryTable
        Primary table for this statement.
      • joins

        protected List<SQLJoin> joins
        List of joins for this statement.
      • requiresJoinReorder

        protected boolean requiresJoinReorder
      • tables

        protected Map<String,​SQLTable> tables
        Map of tables referenced in this statement, keyed by their alias. Note that these aliases are in the input case.
      • tableGroups

        protected Map<String,​SQLTableGroup> tableGroups
        Map of table groups keyed by the group name.
    • Constructor Detail

      • SQLStatement

        public SQLStatement​(SQLStatement parentStmt,
                            RDBMSStoreManager rdbmsMgr,
                            Table table,
                            DatastoreIdentifier alias,
                            String tableGroupName,
                            Map<String,​Object> extensions)
        Constructor for an SQL statement that is a subquery of another statement.
        Parameters:
        parentStmt - Parent statement
        rdbmsMgr - The datastore manager
        table - The primary table
        alias - Alias for this table
        tableGroupName - Name of candidate table-group (if any). Uses "Group0" if not provided
        extensions - Any extensions (optional)
    • Method Detail

      • setClassLoaderResolver

        public void setClassLoaderResolver​(org.datanucleus.ClassLoaderResolver clr)
      • getClassLoaderResolver

        public org.datanucleus.ClassLoaderResolver getClassLoaderResolver()
      • setCandidateClassName

        public void setCandidateClassName​(String name)
      • getCandidateClassName

        public String getCandidateClassName()
      • setQueryGenerator

        public void setQueryGenerator​(QueryGenerator gen)
      • getParentStatement

        public SQLStatement getParentStatement()
      • isChildStatementOf

        public boolean isChildStatementOf​(SQLStatement stmt)
        Convenience method to return if this statement is a child (inner) statement of the supplied statement.
        Parameters:
        stmt - The statement that may be parent, grandparent etc of this statement
        Returns:
        Whether this is a child of the supplied statement
      • addExtension

        public void addExtension​(String key,
                                 Object value)
        Method to define an extension for this query statement allowing control over its behaviour in generating a query.
        Parameters:
        key - Extension key
        value - Value for the key
      • getValueForExtension

        public Object getValueForExtension​(String key)
        Accessor for the value for an extension.
        Parameters:
        key - Key for the extension
        Returns:
        Value for the extension (if any)
      • getPrimaryTable

        public SQLTable getPrimaryTable()
        Accessor for the primary table of the statement.
        Returns:
        The primary table
      • getTable

        public SQLTable getTable​(String alias)
        Accessor for the SQLTable object with the specified alias (if defined for this statement). Note that this alias should be in the same case as what they were defined to the statement as.
        Parameters:
        alias - Alias
        Returns:
        The SQLTable
      • getTableForDatastoreContainer

        public SQLTable getTableForDatastoreContainer​(Table table)
        Convenience method to find a registered SQLTable that is for the specified table
        Parameters:
        table - The table
        Returns:
        The SQLTable (or null if not referenced)
      • getTable

        public SQLTable getTable​(Table table,
                                 String groupName)
        Accessor for the SQLTable object for the specified table (if defined for this statement) in the specified table group.
        Parameters:
        table - The table
        groupName - Name of the table group where we should look for this table
        Returns:
        The SQLTable (if found)
      • getTableGroup

        public SQLTableGroup getTableGroup​(String groupName)
        Accessor for the table group with this name.
        Parameters:
        groupName - Name of the group
        Returns:
        The table group
      • getNumberOfTableGroups

        public int getNumberOfTableGroups()
        Accessor for the number of table groups.
        Returns:
        Number of table groups (including that of the candidate)
      • getNumberOfTables

        public int getNumberOfTables()
        Accessor for the number of tables defined for this statement.
        Returns:
        Number of tables (in addition to the primary table)
      • join

        public SQLTable join​(SQLJoin.JoinType joinType,
                             SQLTable sourceTable,
                             JavaTypeMapping sourceMapping,
                             Table target,
                             String targetAlias,
                             JavaTypeMapping targetMapping,
                             Object[] discrimValues,
                             String tableGrpName)
        Method to form a join to the specified table using the provided mappings, with the join also being applied to any UNIONed statements.
        Parameters:
        joinType - Type of join.
        sourceTable - SQLTable for the source (null implies primaryTable)
        sourceMapping - Mapping in this table to join from
        target - Table to join to
        targetAlias - Alias for the target table (if known)
        targetMapping - Mapping in the other table to join to (also defines the table to join to)
        discrimValues - Any discriminator values to apply for the joined table (null if not)
        tableGrpName - Name of the table group for the target (null implies a new group)
        Returns:
        SQLTable for the target
      • join

        public SQLTable join​(SQLJoin.JoinType joinType,
                             SQLTable sourceTable,
                             JavaTypeMapping sourceMapping,
                             Table target,
                             String targetAlias,
                             JavaTypeMapping targetMapping,
                             Object[] discrimValues,
                             String tableGrpName,
                             SQLJoin parentJoin)
        Method to form a join to the specified table using the provided mappings, with the join also being applied to any UNIONed statements.
        Parameters:
        joinType - Type of join.
        sourceTable - SQLTable for the source (null implies primaryTable)
        sourceMapping - Mapping in this table to join from
        target - Table to join to
        targetAlias - Alias for the target table (if known)
        targetMapping - Mapping in the other table to join to (also defines the table to join to)
        discrimValues - Any discriminator values to apply for the joined table (null if not)
        tableGrpName - Name of the table group for the target (null implies a new group)
        parentJoin - Parent join when this join will be a sub-join (part of "join grouping")
        Returns:
        SQLTable for the target
      • join

        public SQLTable join​(SQLJoin.JoinType joinType,
                             SQLTable sourceTable,
                             JavaTypeMapping sourceMapping,
                             Table target,
                             String targetAlias,
                             JavaTypeMapping targetMapping,
                             Object[] discrimValues,
                             String tableGrpName,
                             boolean applyToUnions)
        Method to form a join to the specified table using the provided mappings.
        Parameters:
        joinType - Type of join.
        sourceTable - SQLTable for the source (null implies primaryTable)
        sourceMapping - Mapping in this table to join from
        target - Table to join to
        targetAlias - Alias for the target table (if known)
        targetMapping - Mapping in the other table to join to (also defines the table to join to)
        discrimValues - Any discriminator values to apply for the joined table (null if not)
        tableGrpName - Name of the table group for the target (null implies a new group)
        applyToUnions - Whether to apply to any unioned statements (only applies to SELECT statements)
        Returns:
        SQLTable for the target
      • join

        public SQLTable join​(SQLJoin.JoinType joinType,
                             SQLTable sourceTable,
                             JavaTypeMapping sourceMapping,
                             Table target,
                             String targetAlias,
                             JavaTypeMapping targetMapping,
                             Object[] discrimValues,
                             String tableGrpName,
                             boolean applyToUnions,
                             SQLJoin parentJoin)
        Method to form a join to the specified table using the provided mappings.
        Parameters:
        joinType - Type of join.
        sourceTable - SQLTable for the source (null implies primaryTable)
        sourceMapping - Mapping in this table to join from
        target - Table to join to
        targetAlias - Alias for the target table (if known)
        targetMapping - Mapping in the other table to join to (also defines the table to join to)
        discrimValues - Any discriminator values to apply for the joined table (null if not)
        tableGrpName - Name of the table group for the target (null implies a new group)
        applyToUnions - Whether to apply to any unioned statements (only applies to SELECT statements)
        parentJoin - Parent join when this join will be a sub-join (part of "join grouping")
        Returns:
        SQLTable for the target
      • join

        public SQLTable join​(SQLJoin.JoinType joinType,
                             SQLTable sourceTable,
                             JavaTypeMapping sourceMapping,
                             JavaTypeMapping sourceParentMapping,
                             Table target,
                             String targetAlias,
                             JavaTypeMapping targetMapping,
                             JavaTypeMapping targetParentMapping,
                             Object[] discrimValues,
                             String tableGrpName,
                             boolean applyToUnions,
                             SQLJoin parentJoin)
        Method to form a join to the specified table using the provided mappings, with the join condition derived from the source-target mappings.
        Parameters:
        joinType - Type of join.
        sourceTable - SQLTable for the source (null implies primaryTable)
        sourceMapping - Mapping in this table to join from
        sourceParentMapping - Optional, if this source mapping is a sub mapping (e.g interface impl).
        target - Table to join to
        targetAlias - Alias for the target table (if known)
        targetMapping - Mapping in the other table to join to (also defines the table to join to)
        targetParentMapping - Optional, if this source mapping is a sub mapping (e.g interface impl).
        discrimValues - Any discriminator values to apply for the joined table (null if not)
        tableGrpName - Name of the table group for the target (null implies a new group)
        applyToUnions - Whether to apply to any unioned statements (only applies to SELECT statements)
        parentJoin - Parent join when this join will be a sub-join (part of "join grouping")
        Returns:
        SQLTable for the target
      • join

        public SQLTable join​(SQLJoin.JoinType joinType,
                             SQLTable sourceTable,
                             Table target,
                             String targetAlias,
                             String tableGrpName,
                             BooleanExpression joinCondition,
                             boolean applyToUnions)
        Method to form a join to the specified table using the provided mappings and applying the provided join condition (rather than generating one from the source/target mappings). This is used with JPQL where we allow two root entities to be joined using a provide "ON" condition.
        Parameters:
        joinType - Type of join.
        sourceTable - SQLTable for the source (null implies primaryTable)
        target - Table to join to
        targetAlias - Alias for the target table (if known)
        tableGrpName - Name of the table group for the target (null implies a new group)
        joinCondition - On clause for the join
        applyToUnions - Whether to apply to any unioned statements (only applies to SELECT statements)
        Returns:
        SQLTable for the target
      • getJoinTypeForTable

        public SQLJoin.JoinType getJoinTypeForTable​(SQLTable sqlTbl)
        Accessor for the type of join used for the specified table.
        Parameters:
        sqlTbl - The table to check
        Returns:
        The join type, or null if not joined in this statement
      • addAndConditionToJoinForTable

        public void addAndConditionToJoinForTable​(SQLTable sqlTbl,
                                                  BooleanExpression andCondition,
                                                  boolean applyToUnions)
        Method to find the JOIN for the specified table and add the specified 'and' condition to the JOIN as an 'ON' clause.
        Parameters:
        sqlTbl - The table
        andCondition - The 'ON' condition to add
        applyToUnions - Whether to apply to unions (see SelectStatement)
      • getJoinForTable

        public SQLJoin getJoinForTable​(SQLTable sqlTbl)
        Accessor for the type of join used for the specified table.
        Parameters:
        sqlTbl - The table to check
        Returns:
        The join type, or null if not joined in this statement
      • removeCrossJoin

        public String removeCrossJoin​(SQLTable targetSqlTbl)
        Method to remove a cross join for the specified table (if joined via cross join). Also removes the table from the list of tables. This is called where we have bound a variable via a CROSS JOIN (in the absence of better information) and found out later it could become an INNER JOIN. If the supplied table is not joined via a cross join then does nothing.
        Parameters:
        targetSqlTbl - The table to drop the cross join for
        Returns:
        The removed alias
      • putSQLTableInGroup

        protected void putSQLTableInGroup​(SQLTable sqlTbl,
                                          String groupName,
                                          SQLJoin.JoinType joinType)
        Convenience method to add the SQLTable to the specified group. If the group doesn't yet exist then it adds it.
        Parameters:
        sqlTbl - SQLTable to add
        groupName - The group
        joinType - type of join to start this table group
      • addJoin

        protected void addJoin​(SQLJoin.JoinType joinType,
                               SQLTable sourceTable,
                               SQLTable targetTable,
                               BooleanExpression joinCondition,
                               SQLJoin parentJoin)
        Internal method to form a join to the specified table using the provided mappings.
        Parameters:
        joinType - Type of join (INNER, LEFT OUTER, RIGHT OUTER, CROSS, NON-ANSI)
        sourceTable - SQLTable to join from
        targetTable - SQLTable to join to
        joinCondition - Condition for the join
        parentJoin - Optional parent join (which will mean this join becomes a sub-join)
      • getJoinConditionForJoin

        protected BooleanExpression getJoinConditionForJoin​(SQLTable sourceTable,
                                                            JavaTypeMapping sourceMapping,
                                                            JavaTypeMapping sourceParentMapping,
                                                            SQLTable targetTable,
                                                            JavaTypeMapping targetMapping,
                                                            JavaTypeMapping targetParentMapping,
                                                            Object[] discrimValues)
        Convenience method to generate the join condition between source and target tables for the supplied mappings.
        Parameters:
        sourceTable - Source table
        sourceMapping - Mapping in source table
        sourceParentMapping - Optional parent of this source mapping (if joining an impl of an interface)
        targetTable - Target table
        targetMapping - Mapping in target table
        targetParentMapping - Optional parent of this target mapping (if joining an impl of an interface)
        discrimValues - Optional discriminator values to further restrict
        Returns:
        The join condition
      • getTableNamer

        protected SQLTableNamer getTableNamer​(String namingSchema)
        Method to return the namer for a particular schema. If there is no instantiated namer for this schema then instantiates one.
        Parameters:
        namingSchema - Table naming schema to use
        Returns:
        The namer
      • whereAnd

        public void whereAnd​(BooleanExpression expr,
                             boolean applyToUnions)
        Method to add an AND condition to the WHERE clause.
        Parameters:
        expr - The condition
        applyToUnions - whether to apply this and to any UNIONs in the statement (only applies to SELECT statements)
      • whereOr

        public void whereOr​(BooleanExpression expr,
                            boolean applyToUnions)
        Method to add an OR condition to the WHERE clause.
        Parameters:
        expr - The condition
        applyToUnions - Whether to apply to unions (only applies to SELECT statements)
      • getSQLText

        public SQLText getSQLText()
      • invalidateStatement

        protected void invalidateStatement()
        Method to uncache the generated SQL (because some condition has changed).
      • log

        public void log​(org.datanucleus.util.NucleusLogger logger)
        Method to dump the statement to the supplied log (debug level). Logs the SQL that this statement equates to, and the TableGroup(s) and their associated tables.
        Parameters:
        logger - The logger