Package org.datanucleus.store.rdbms.sql
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 Summary
Fields Modifier and Type Field Description protected String
candidateClassName
Name of class that this statement selects (optional, only typically for unioned statements).protected org.datanucleus.ClassLoaderResolver
clr
ClassLoader resolver to use.static String
EXTENSION_LOCK_FOR_UPDATE
static String
EXTENSION_LOCK_FOR_UPDATE_NOWAIT
static String
EXTENSION_SQL_TABLE_NAMING_STRATEGY
protected Map<String,Object>
extensions
Map of extensions for use in generating the SQL, keyed by the extension name.protected List<SQLJoin>
joins
List of joins for this statement.protected SQLTableNamer
namer
protected SQLStatement
parent
Parent statement, if this is a subquery SELECT.protected SQLTable
primaryTable
Primary table for this statement.protected QueryGenerator
queryGenerator
Context of any query generation.protected RDBMSStoreManager
rdbmsMgr
Manager for the RDBMS datastore.protected boolean
requiresJoinReorder
protected SQLText
sql
Cached SQL statement, generated by getSQLText().protected Map<String,SQLTableGroup>
tableGroups
Map of table groups keyed by the group name.protected static Map<String,SQLTableNamer>
tableNamerByName
Map of SQLTable naming instance keyed by the name of the naming scheme, shared across threads.protected Map<String,SQLTable>
tables
Map of tables referenced in this statement, keyed by their alias.protected BooleanExpression
where
Where clause.
-
Constructor Summary
Constructors Constructor Description 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.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description 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.void
addExtension(String key, Object value)
Method to define an extension for this query statement allowing control over its behaviour in generating a query.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.String
getCandidateClassName()
org.datanucleus.ClassLoaderResolver
getClassLoaderResolver()
DatastoreAdapter
getDatastoreAdapter()
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.SQLJoin
getJoinForTable(SQLTable sqlTbl)
Accessor for the type of join used for the specified table.SQLJoin.JoinType
getJoinTypeForTable(SQLTable sqlTbl)
Accessor for the type of join used for the specified table.int
getNumberOfTableGroups()
Accessor for the number of table groups.int
getNumberOfTables()
Accessor for the number of tables defined for this statement.SQLStatement
getParentStatement()
SQLTable
getPrimaryTable()
Accessor for the primary table of the statement.QueryGenerator
getQueryGenerator()
RDBMSStoreManager
getRDBMSManager()
SQLExpressionFactory
getSQLExpressionFactory()
SQLText
getSQLText()
SQLTable
getTable(String alias)
Accessor for the SQLTable object with the specified alias (if defined for this statement).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.SQLTable
getTableForDatastoreContainer(Table table)
Convenience method to find a registered SQLTable that is for the specified tableSQLTableGroup
getTableGroup(String groupName)
Accessor for the table group with this name.protected SQLTableNamer
getTableNamer(String namingSchema)
Method to return the namer for a particular schema.Object
getValueForExtension(String key)
Accessor for the value for an extension.protected void
invalidateStatement()
Method to uncache the generated SQL (because some condition has changed).boolean
isChildStatementOf(SQLStatement stmt)
Convenience method to return if this statement is a child (inner) statement of the supplied statement.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.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.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.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.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.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).void
log(org.datanucleus.util.NucleusLogger logger)
Method to dump the statement to the supplied log (debug level).protected void
putSQLTableInGroup(SQLTable sqlTbl, String groupName, SQLJoin.JoinType joinType)
Convenience method to add the SQLTable to the specified group.String
removeCrossJoin(SQLTable targetSqlTbl)
Method to remove a cross join for the specified table (if joined via cross join).void
setCandidateClassName(String name)
void
setClassLoaderResolver(org.datanucleus.ClassLoaderResolver clr)
void
setQueryGenerator(QueryGenerator gen)
void
whereAnd(BooleanExpression expr, boolean applyToUnions)
Method to add an AND condition to the WHERE clause.void
whereOr(BooleanExpression expr, boolean applyToUnions)
Method to add an OR condition to the WHERE clause.
-
-
-
Field Detail
-
EXTENSION_SQL_TABLE_NAMING_STRATEGY
public static final String EXTENSION_SQL_TABLE_NAMING_STRATEGY
- See Also:
- Constant Field Values
-
EXTENSION_LOCK_FOR_UPDATE
public static final String EXTENSION_LOCK_FOR_UPDATE
- See Also:
- Constant Field Values
-
EXTENSION_LOCK_FOR_UPDATE_NOWAIT
public static final String EXTENSION_LOCK_FOR_UPDATE_NOWAIT
- See Also:
- Constant Field Values
-
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.
-
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 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 statementrdbmsMgr
- The datastore managertable
- The primary tablealias
- Alias for this tabletableGroupName
- Name of candidate table-group (if any). Uses "Group0" if not providedextensions
- Any extensions (optional)
-
-
Method Detail
-
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 keyvalue
- 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 tablegroupName
- 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 fromtarget
- Table to join totargetAlias
- 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 fromtarget
- Table to join totargetAlias
- 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 fromtarget
- Table to join totargetAlias
- 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 fromtarget
- Table to join totargetAlias
- 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 fromsourceParentMapping
- Optional, if this source mapping is a sub mapping (e.g interface impl).target
- Table to join totargetAlias
- 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 totargetAlias
- 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 joinapplyToUnions
- 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 tableandCondition
- The 'ON' condition to addapplyToUnions
- 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 addgroupName
- The groupjoinType
- 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 fromtargetTable
- SQLTable to join tojoinCondition
- Condition for the joinparentJoin
- 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 tablesourceMapping
- Mapping in source tablesourceParentMapping
- Optional parent of this source mapping (if joining an impl of an interface)targetTable
- Target tabletargetMapping
- Mapping in target tabletargetParentMapping
- 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 conditionapplyToUnions
- 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 conditionapplyToUnions
- 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
-
-