Class MatchingClauseNode
- java.lang.Object
-
- org.apache.derby.impl.sql.compile.QueryTreeNode
-
- org.apache.derby.impl.sql.compile.MatchingClauseNode
-
- All Implemented Interfaces:
Visitable
public class MatchingClauseNode extends QueryTreeNode
Node representing a WHEN MATCHED or WHEN NOT MATCHED clause in a MERGE statement.
-
-
Field Summary
Fields Modifier and Type Field Description private java.lang.String
_actionMethodName
private int
_clauseNumber
private DMLModStatementNode
_dml
private ResultColumnList
_insertColumns
private ResultColumnList
_insertValues
private ValueNode
_matchingRefinement
private java.lang.String
_resultSetFieldName
private java.lang.String
_rowMakingMethodName
private ResultColumnList
_thenColumns
private ResultColumnList
_updateColumns
private static java.lang.String
CURRENT_OF_NODE_NAME
-
Fields inherited from class org.apache.derby.impl.sql.compile.QueryTreeNode
AUTOINCREMENT_CREATE_MODIFY, AUTOINCREMENT_CYCLE, AUTOINCREMENT_INC_INDEX, AUTOINCREMENT_IS_AUTOINCREMENT_INDEX, AUTOINCREMENT_START_INDEX
-
-
Constructor Summary
Constructors Modifier Constructor Description private
MatchingClauseNode(ValueNode matchingRefinement, ResultColumnList updateColumns, ResultColumnList insertColumns, ResultColumnList insertValues, ContextManager cm)
Constructor called by factory methods.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description (package private) void
acceptChildren(Visitor v)
Accept the visitor for all visitable children of this node.private void
adjustMatchingRefinement(ResultColumnList selectList, ResultSetNode generatedScan)
Point the column references in the matching refinement at the corresponding columns returned by the driving left join.private void
adjustThenColumns(ResultColumnList selectList, ResultSetNode generatedScan, HalfOuterJoinNode hojn)
Point the column references in the temporary row at the corresponding columns returned by the driving left join.(package private) void
bind(DataDictionary dd, MergeNode mergeNode, FromList fullFromList, FromBaseTable targetTable)
Bind this WHEN [ NOT ] MATCHED clause against the parent MergeNodeprivate void
bindDelete(DataDictionary dd, FromList fullFromList, FromBaseTable targetTable)
Bind a WHEN MATCHED ...private void
bindExpressions(ResultColumnList rcl, FromList fromList)
Boilerplate for binding a list of ResultColumns against a FromListprivate void
bindInsert(DataDictionary dd, MergeNode mergeNode, FromList fullFromList, FromBaseTable targetTable)
Bind a WHEN NOT MATCHED ...private void
bindInsertValues(FromList fullFromList, FromTable targetTable)
Bind the values in the INSERT list(package private) void
bindRefinement(MergeNode mergeNode, FromList fullFromList)
Bind the optional refinement condition in the MATCHED clauseprivate void
bindSetClauses(MergeNode mergeNode, FromList fullFromList, FromTable targetTable, ResultColumnList setClauses)
Bind the SET clauses of an UPDATE actionprivate void
bindUpdate(DataDictionary dd, MergeNode mergeNode, FromList fullFromList, FromBaseTable targetTable)
Bind a WHEN MATCHED ...private ResultColumnList
buildFullColumnList(TableDescriptor td)
Build the full column list for a table.private void
buildThenColumnsForDelete()
Construct the signature of the temporary table which drives the INSERT/UPDATE/DELETE action.private void
buildThenColumnsForInsert(FromList fullFromList, FromTable targetTable, ResultColumnList fullRow, ResultColumnList insertColumns, ResultColumnList insertValues)
Construct the row in the temporary table which drives an INSERT action.private void
buildThenColumnsForUpdate(FromList fullFromList, FromTable targetTable, ResultColumnList fullRow, ResultColumnList beforeRow, ResultColumnList afterValues)
Construct the row in the temporary table which drives an UPDATE action.private ResultDescription
buildThenColumnSignature()
Build the signature of the row which will go into the temporary table.private void
forbidSubqueries()
Forbid subqueries in WHEN [ NOT ] MATCHED clauses.private void
forbidSubqueries(ResultColumnList rcl)
private void
forbidSubqueries(ValueNode expr)
(package private) void
generate(ActivationClassBuilder acb, ResultColumnList selectList, ResultSetNode generatedScan, HalfOuterJoinNode hojn, int clauseNumber)
Generate a method to invoke the INSERT/UPDATE/DELETE action.private void
generateInsertUpdateRow(ActivationClassBuilder acb, ResultColumnList selectList, ResultSetNode generatedScan, HalfOuterJoinNode hojn)
Generate a method to build a row for the temporary table for INSERT/UPDATE actions.(package private) void
generateResultSetField(ActivationClassBuilder acb, MethodBuilder mb)
Adds a field to the generated class to hold the ResultSet of "then" rows which drive the INSERT/UPDATE/DELETE action.private ResultSetNode
getBoundSelectUnderUpdate()
Get the bound SELECT node under the dummy UPDATE node.private java.util.HashSet<java.lang.String>
getChangedColumnNames()
Get the names of the columns explicitly changed by SET clausesprivate java.util.HashSet<java.lang.String>
getChangedGeneratedColumnNames(TableDescriptor targetTableDescriptor, java.util.HashSet<java.lang.String> changedColumnNames)
Get the names of the generated columns which are changed by the UPDATE statement.private int
getClauseType()
private java.util.List<ColumnReference>
getColumnReferences(QueryTreeNode expression)
Get a list of column references in an expression(package private) void
getColumnsInExpressions(MergeNode mergeNode, java.util.HashMap<java.lang.String,ColumnReference> drivingColumnMap)
Collect the columns mentioned by expressions in this MATCHED clauseprivate int
getMergeTableID(ColumnReference cr)
Find the MERGE table id of the indicated columnprivate int
getSelectListOffset(ResultColumnList selectList, ValueNode thenExpression)
Find a column reference in the SELECT list of the driving left join and return its 1-based offset into that list.(package private) ResultColumnList
getThenColumns()
Return the list of columns which form the rows of the ResultSet which drive the INSERT/UPDATE/DELETE actions.(package private) boolean
isDeleteClause()
Return true if this is a WHEN MATCHED ...(package private) boolean
isInsertClause()
Return true if this is a WHEN NOT MATCHED ...private boolean
isRowLocation(ResultColumn rc)
Return true if the ResultColumn represents a RowLocation(package private) boolean
isUpdateClause()
Return true if this is a WHEN MATCHED ...private ResultColumn
makeAutoGenRC(FromTable targetTable, ResultColumn origRC, int virtualColumnID)
Make a ResultColumn for an identity column which is being set to the DEFAULT value.(package private) ConstantAction
makeConstantAction(ActivationClassBuilder acb)
(package private) static MatchingClauseNode
makeDeleteClause(ValueNode matchingRefinement, ContextManager cm)
Make a WHEN MATCHED ...(package private) static MatchingClauseNode
makeInsertClause(ValueNode matchingRefinement, ResultColumnList insertColumns, ResultColumnList insertValues, ContextManager cm)
Make a WHEN NOT MATCHED ...(package private) static MatchingClauseNode
makeUpdateClause(ValueNode matchingRefinement, ResultColumnList updateColumns, ContextManager cm)
Make a WHEN MATCHED ...(package private) void
optimize()
Optimize the INSERT/UPDATE/DELETE action.(package private) void
printSubNodes(int depth)
Prints the sub-nodes of this object.private ResultColumnList
realiasSetClauses(FromBaseTable targetTable)
Due to discrepancies in how names are resolved by SELECT and UPDATE, we have to force the left side of SET clauses to use the same table identifiers as the right sides of the SET clauses.boolean
referencesSessionSchema()
Return true if the node references SESSION schema tables (temporary or permanent)private static boolean
referencesSessionSchema(QueryTreeNode node)
private void
remapConstraints()
Re-map ColumnReferences in constraints to point into the row from the temporary table.java.lang.String
toString()
Convert this object to a String.private void
useGeneratedScan(ResultColumnList selectList, ResultSetNode generatedScan, QueryTreeNode node)
Point a node's ColumnReferences into the row returned by the driving left join.-
Methods inherited from class org.apache.derby.impl.sql.compile.QueryTreeNode
accept, addTag, addUDTUsagePriv, addUDTUsagePriv, bindOffsetFetch, bindRowMultiSet, bindUserCatalogType, bindUserType, checkReliability, checkReliability, convertDefaultNode, copyTagsFrom, createTypeDependency, debugFlush, debugPrint, disablePrivilegeCollection, formatNodeString, generate, generateAuthorizeCheck, getBeginOffset, getClassFactory, getCompilerContext, getContext, getContextManager, getDataDictionary, getDependencyManager, getEndOffset, getExecutionFactory, getGenericConstantActionFactory, getIntProperty, getLanguageConnectionContext, getLongProperty, getNullNode, getOffsetOrderedNodes, getOptimizerFactory, getOptimizerTracer, getParameterTypes, getSchemaDescriptor, getSchemaDescriptor, getStatementType, getTableDescriptor, getTypeCompiler, getUDTDesc, isAtomic, isPrivilegeCollectionRequired, isSessionSchema, isSessionSchema, makeConstantAction, makeTableName, makeTableName, nodeHeader, optimizerTracingIsOn, orReliability, parseSearchCondition, parseStatement, printLabel, resolveTableToSynonym, setBeginOffset, setEndOffset, setRefActionInfo, stackPrint, taggedWith, treePrint, treePrint, verifyClassExist
-
-
-
-
Field Detail
-
CURRENT_OF_NODE_NAME
private static final java.lang.String CURRENT_OF_NODE_NAME
- See Also:
- Constant Field Values
-
_matchingRefinement
private ValueNode _matchingRefinement
-
_updateColumns
private ResultColumnList _updateColumns
-
_insertColumns
private ResultColumnList _insertColumns
-
_insertValues
private ResultColumnList _insertValues
-
_dml
private DMLModStatementNode _dml
-
_thenColumns
private ResultColumnList _thenColumns
-
_clauseNumber
private int _clauseNumber
-
_actionMethodName
private java.lang.String _actionMethodName
-
_resultSetFieldName
private java.lang.String _resultSetFieldName
-
_rowMakingMethodName
private java.lang.String _rowMakingMethodName
-
-
Constructor Detail
-
MatchingClauseNode
private MatchingClauseNode(ValueNode matchingRefinement, ResultColumnList updateColumns, ResultColumnList insertColumns, ResultColumnList insertValues, ContextManager cm) throws StandardException
Constructor called by factory methods.- Throws:
StandardException
-
-
Method Detail
-
makeUpdateClause
static MatchingClauseNode makeUpdateClause(ValueNode matchingRefinement, ResultColumnList updateColumns, ContextManager cm) throws StandardException
Make a WHEN MATCHED ... THEN UPDATE clause- Throws:
StandardException
-
makeDeleteClause
static MatchingClauseNode makeDeleteClause(ValueNode matchingRefinement, ContextManager cm) throws StandardException
Make a WHEN MATCHED ... THEN DELETE clause- Throws:
StandardException
-
makeInsertClause
static MatchingClauseNode makeInsertClause(ValueNode matchingRefinement, ResultColumnList insertColumns, ResultColumnList insertValues, ContextManager cm) throws StandardException
Make a WHEN NOT MATCHED ... THEN INSERT clause- Throws:
StandardException
-
isUpdateClause
boolean isUpdateClause()
Return true if this is a WHEN MATCHED ... UPDATE clause
-
isInsertClause
boolean isInsertClause()
Return true if this is a WHEN NOT MATCHED ... INSERT clause
-
isDeleteClause
boolean isDeleteClause()
Return true if this is a WHEN MATCHED ... DELETE clause
-
getThenColumns
ResultColumnList getThenColumns()
Return the list of columns which form the rows of the ResultSet which drive the INSERT/UPDATE/DELETE actions.
-
bind
void bind(DataDictionary dd, MergeNode mergeNode, FromList fullFromList, FromBaseTable targetTable) throws StandardException
Bind this WHEN [ NOT ] MATCHED clause against the parent MergeNode- Throws:
StandardException
-
bindRefinement
void bindRefinement(MergeNode mergeNode, FromList fullFromList) throws StandardException
Bind the optional refinement condition in the MATCHED clause- Throws:
StandardException
-
getColumnsInExpressions
void getColumnsInExpressions(MergeNode mergeNode, java.util.HashMap<java.lang.String,ColumnReference> drivingColumnMap) throws StandardException
Collect the columns mentioned by expressions in this MATCHED clause- Throws:
StandardException
-
bindUpdate
private void bindUpdate(DataDictionary dd, MergeNode mergeNode, FromList fullFromList, FromBaseTable targetTable) throws StandardException
Bind a WHEN MATCHED ... THEN UPDATE clause- Throws:
StandardException
-
realiasSetClauses
private ResultColumnList realiasSetClauses(FromBaseTable targetTable) throws StandardException
Due to discrepancies in how names are resolved by SELECT and UPDATE, we have to force the left side of SET clauses to use the same table identifiers as the right sides of the SET clauses.
- Throws:
StandardException
-
getBoundSelectUnderUpdate
private ResultSetNode getBoundSelectUnderUpdate() throws StandardException
Get the bound SELECT node under the dummy UPDATE node. This may not be the source result set of the UPDATE node. That is because a ProjectRestrictNode may have been inserted on top of it by DEFAULT handling. This method exists to make the UPDATE actions of MERGE statements behave like ordinary UPDATE statements in this situation. The behavior is actually wrong. See DERBY-6414. Depending on how that bug is addressed, we may be able to remove this method eventually.
- Throws:
StandardException
-
bindSetClauses
private void bindSetClauses(MergeNode mergeNode, FromList fullFromList, FromTable targetTable, ResultColumnList setClauses) throws StandardException
Bind the SET clauses of an UPDATE action- Throws:
StandardException
-
buildThenColumnsForUpdate
private void buildThenColumnsForUpdate(FromList fullFromList, FromTable targetTable, ResultColumnList fullRow, ResultColumnList beforeRow, ResultColumnList afterValues) throws StandardException
Construct the row in the temporary table which drives an UPDATE action. Unlike a DELETE, whose temporary row is just a list of copied columns, the temporary row for UPDATE may contain complex expressions which must be code-generated later on.
- Throws:
StandardException
-
getChangedColumnNames
private java.util.HashSet<java.lang.String> getChangedColumnNames() throws StandardException
Get the names of the columns explicitly changed by SET clauses- Throws:
StandardException
-
getChangedGeneratedColumnNames
private java.util.HashSet<java.lang.String> getChangedGeneratedColumnNames(TableDescriptor targetTableDescriptor, java.util.HashSet<java.lang.String> changedColumnNames) throws StandardException
Get the names of the generated columns which are changed by the UPDATE statement. These are the generated columns which match one of the following conditions:
- Are explicitly mentioned on the left side of a SET clause.
- Are built from other columns which are explicitly mentioned on the left side of a SET clause.
- Throws:
StandardException
-
bindDelete
private void bindDelete(DataDictionary dd, FromList fullFromList, FromBaseTable targetTable) throws StandardException
Bind a WHEN MATCHED ... THEN DELETE clause- Throws:
StandardException
-
buildThenColumnsForDelete
private void buildThenColumnsForDelete() throws StandardException
Construct the signature of the temporary table which drives the INSERT/UPDATE/DELETE action.
- Throws:
StandardException
-
bindInsert
private void bindInsert(DataDictionary dd, MergeNode mergeNode, FromList fullFromList, FromBaseTable targetTable) throws StandardException
Bind a WHEN NOT MATCHED ... THEN INSERT clause- Throws:
StandardException
-
bindInsertValues
private void bindInsertValues(FromList fullFromList, FromTable targetTable) throws StandardException
Bind the values in the INSERT list- Throws:
StandardException
-
buildFullColumnList
private ResultColumnList buildFullColumnList(TableDescriptor td) throws StandardException
Build the full column list for a table.
- Throws:
StandardException
-
buildThenColumnsForInsert
private void buildThenColumnsForInsert(FromList fullFromList, FromTable targetTable, ResultColumnList fullRow, ResultColumnList insertColumns, ResultColumnList insertValues) throws StandardException
Construct the row in the temporary table which drives an INSERT action. Unlike a DELETE, whose temporary row is just a list of copied columns, the temporary row for INSERT may contain complex expressions which must be code-generated later on.
- Throws:
StandardException
-
makeAutoGenRC
private ResultColumn makeAutoGenRC(FromTable targetTable, ResultColumn origRC, int virtualColumnID) throws StandardException
Make a ResultColumn for an identity column which is being set to the DEFAULT value. This special ResultColumn will make it through code generation so that it will be calculated when the INSERT/UPDATE action is run.
- Throws:
StandardException
-
bindExpressions
private void bindExpressions(ResultColumnList rcl, FromList fromList) throws StandardException
Boilerplate for binding a list of ResultColumns against a FromList- Throws:
StandardException
-
forbidSubqueries
private void forbidSubqueries() throws StandardException
Forbid subqueries in WHEN [ NOT ] MATCHED clauses.
- Throws:
StandardException
-
forbidSubqueries
private void forbidSubqueries(ResultColumnList rcl) throws StandardException
- Throws:
StandardException
-
forbidSubqueries
private void forbidSubqueries(ValueNode expr) throws StandardException
- Throws:
StandardException
-
optimize
void optimize() throws StandardException
Optimize the INSERT/UPDATE/DELETE action.
- Throws:
StandardException
-
makeConstantAction
ConstantAction makeConstantAction(ActivationClassBuilder acb) throws StandardException
- Throws:
StandardException
-
getClauseType
private int getClauseType()
-
buildThenColumnSignature
private ResultDescription buildThenColumnSignature() throws StandardException
Build the signature of the row which will go into the temporary table.
- Throws:
StandardException
-
generate
void generate(ActivationClassBuilder acb, ResultColumnList selectList, ResultSetNode generatedScan, HalfOuterJoinNode hojn, int clauseNumber) throws StandardException
Generate a method to invoke the INSERT/UPDATE/DELETE action. This method will be called at runtime by MatchingClauseConstantAction.executeConstantAction().
- Throws:
StandardException
-
remapConstraints
private void remapConstraints() throws StandardException
Re-map ColumnReferences in constraints to point into the row from the temporary table. This is where the row will be stored when constraints are being evaluated.
- Throws:
StandardException
-
generateResultSetField
void generateResultSetField(ActivationClassBuilder acb, MethodBuilder mb) throws StandardException
Adds a field to the generated class to hold the ResultSet of "then" rows which drive the INSERT/UPDATE/DELETE action. Generates code to push the contents of that field onto the stack.
- Throws:
StandardException
-
generateInsertUpdateRow
private void generateInsertUpdateRow(ActivationClassBuilder acb, ResultColumnList selectList, ResultSetNode generatedScan, HalfOuterJoinNode hojn) throws StandardException
Generate a method to build a row for the temporary table for INSERT/UPDATE actions. The method stuffs each column in the row with the result of the corresponding expression built out of columns in the current row of the driving left join. The method returns the stuffed row.
- Throws:
StandardException
-
adjustMatchingRefinement
private void adjustMatchingRefinement(ResultColumnList selectList, ResultSetNode generatedScan) throws StandardException
Point the column references in the matching refinement at the corresponding columns returned by the driving left join.
- Throws:
StandardException
-
adjustThenColumns
private void adjustThenColumns(ResultColumnList selectList, ResultSetNode generatedScan, HalfOuterJoinNode hojn) throws StandardException
Point the column references in the temporary row at the corresponding columns returned by the driving left join.
- Throws:
StandardException
-
useGeneratedScan
private void useGeneratedScan(ResultColumnList selectList, ResultSetNode generatedScan, QueryTreeNode node) throws StandardException
Point a node's ColumnReferences into the row returned by the driving left join.
- Throws:
StandardException
-
getSelectListOffset
private int getSelectListOffset(ResultColumnList selectList, ValueNode thenExpression) throws StandardException
Find a column reference in the SELECT list of the driving left join and return its 1-based offset into that list. Returns -1 if the column can't be found.
- Throws:
StandardException
-
getMergeTableID
private int getMergeTableID(ColumnReference cr)
Find the MERGE table id of the indicated column
-
acceptChildren
void acceptChildren(Visitor v) throws StandardException
Accept the visitor for all visitable children of this node.- Overrides:
acceptChildren
in classQueryTreeNode
- Parameters:
v
- the visitor- Throws:
StandardException
- on error
-
printSubNodes
void printSubNodes(int depth)
Prints the sub-nodes of this object. See QueryTreeNode.java for how tree printing is supposed to work.- Overrides:
printSubNodes
in classQueryTreeNode
- Parameters:
depth
- The depth of this node in the tree
-
toString
public java.lang.String toString()
Convert this object to a String. See comments in QueryTreeNode.java for how this should be done for tree printing.- Overrides:
toString
in classQueryTreeNode
- Returns:
- This object as a String
-
getColumnReferences
private java.util.List<ColumnReference> getColumnReferences(QueryTreeNode expression) throws StandardException
Get a list of column references in an expression- Throws:
StandardException
-
isRowLocation
private boolean isRowLocation(ResultColumn rc) throws StandardException
Return true if the ResultColumn represents a RowLocation- Throws:
StandardException
-
referencesSessionSchema
public boolean referencesSessionSchema() throws StandardException
Description copied from class:QueryTreeNode
Return true if the node references SESSION schema tables (temporary or permanent)- Overrides:
referencesSessionSchema
in classQueryTreeNode
- Returns:
- true if references SESSION schema tables, else false
- Throws:
StandardException
- Thrown on error
-
referencesSessionSchema
private static boolean referencesSessionSchema(QueryTreeNode node) throws StandardException
- Throws:
StandardException
-
-