Class SQLStatement

java.lang.Object
org.datanucleus.store.rdbms.sql.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 Details

    • EXTENSION_SQL_TABLE_NAMING_STRATEGY

      public static final String EXTENSION_SQL_TABLE_NAMING_STRATEGY
      See Also:
    • EXTENSION_LOCK_FOR_UPDATE

      public static final String EXTENSION_LOCK_FOR_UPDATE
      See Also:
    • EXTENSION_LOCK_FOR_UPDATE_NOWAIT

      public static final String EXTENSION_LOCK_FOR_UPDATE_NOWAIT
      See Also:
    • 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().
    • rdbmsMgr

      protected RDBMSStoreManager rdbmsMgr
      Manager for the RDBMS datastore.
    • 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.
    • namer

      protected SQLTableNamer namer
    • 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.
    • where

      protected BooleanExpression where
      Where clause.
  • Constructor Details

    • 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 Details

    • getRDBMSManager

      public RDBMSStoreManager getRDBMSManager()
    • setClassLoaderResolver

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

      public org.datanucleus.ClassLoaderResolver getClassLoaderResolver()
    • setCandidateClassName

      public void setCandidateClassName(String name)
    • getCandidateClassName

      public String getCandidateClassName()
    • getQueryGenerator

      public QueryGenerator getQueryGenerator()
    • setQueryGenerator

      public void setQueryGenerator(QueryGenerator gen)
    • getSQLExpressionFactory

      public SQLExpressionFactory getSQLExpressionFactory()
    • getDatastoreAdapter

      public DatastoreAdapter getDatastoreAdapter()
    • 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