Top Description Fields Constructors Methods
org.apache.derby.impl.sql.compile

public Class MatchingClauseNode

extends QueryTreeNode
Class Inheritance
Imports
java.lang.reflect.Modifier, java.util.ArrayList, .HashMap, .HashSet, .List, org.apache.derby.catalog.types.DefaultInfoImpl, org.apache.derby.shared.common.error.StandardException, org.apache.derby.shared.common.reference.ClassName, .SQLState, org.apache.derby.iapi.services.classfile.VMOpcode, org.apache.derby.iapi.services.compiler.LocalField, .MethodBuilder, org.apache.derby.iapi.services.context.ContextManager, org.apache.derby.iapi.services.io.FormatableBitSet, org.apache.derby.shared.common.sanity.SanityManager, org.apache.derby.iapi.sql.ResultColumnDescriptor, .ResultDescription, org.apache.derby.iapi.sql.compile.CompilerContext, .IgnoreFilter, .Visitor, org.apache.derby.iapi.sql.dictionary.ColumnDescriptor, .ColumnDescriptorList, .DataDictionary, .TableDescriptor, org.apache.derby.iapi.sql.execute.ConstantAction, .NoPutResultSet, org.apache.derby.iapi.types.DataTypeDescriptor, .DataValueDescriptor

Node representing a WHEN MATCHED or WHEN NOT MATCHED clause in a MERGE statement.

Field Summary

Modifier and TypeField and Description
private String
private int
private DMLModStatementNode
private ResultColumnList
private ResultColumnList
private ValueNode
private String
private String
private ResultColumnList
private ResultColumnList
private static final String
Inherited from org.apache.derby.impl.sql.compile.QueryTreeNode:
AUTOINCREMENT_CREATE_MODIFYAUTOINCREMENT_CYCLEAUTOINCREMENT_INC_INDEXAUTOINCREMENT_IS_AUTOINCREMENT_INDEXAUTOINCREMENT_START_INDEX

Constructor Summary

AccessConstructor and Description
private
MatchingClauseNode(ValueNode matchingRefinement, ResultColumnList updateColumns, ResultColumnList insertColumns, ResultColumnList insertValues, ContextManager cm)

Constructor called by factory methods.

Method Summary

Modifier and TypeMethod and Description
pack-priv void
acceptChildren(Visitor
the visitor
v
)

Overrides org.apache.derby.impl.sql.compile.QueryTreeNode.acceptChildren.

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.

private boolean
autoincrementColumnSetToDEFAULT(TableDescriptor
Target table catalog info
targetTableDescriptor
,
ResultColumnList
Columns explicitly mentioned in the VALUES clause
valuesList
)

Return true if the VALUES clause of the INSERT branch contains an autoincrement column which is set to DEFAULT or if the VALUES clause doesn't explicitly mention the autoincrement column.

pack-priv void
bind(DataDictionary dd, MergeNode mergeNode, FromList fullFromList, FromBaseTable targetTable)

Bind this WHEN [ NOT ] MATCHED clause against the parent MergeNode

private 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 FromList

private 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

pack-priv void
bindRefinement(MergeNode mergeNode, FromList fullFromList)

Bind the optional refinement condition in the MATCHED clause

private void
bindSetClauses(MergeNode mergeNode, FromList fullFromList, FromTable targetTable, ResultColumnList setClauses)

Bind the SET clauses of an UPDATE action

private 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
private void
pack-priv 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.

pack-priv 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 HashSet<String>
getChangedColumnNames()

Get the names of the columns explicitly changed by SET clauses

private HashSet<String>
getChangedGeneratedColumnNames(TableDescriptor targetTableDescriptor, HashSet<String> changedColumnNames)

Get the names of the generated columns which are changed by the UPDATE statement.

private int
private List<ColumnReference>
getColumnReferences(QueryTreeNode expression)

Get a list of column references in an expression

pack-priv void
getColumnsInExpressions(MergeNode mergeNode, HashMap<String, ColumnReference> drivingColumnMap)

Collect the columns mentioned by expressions in this MATCHED clause

private int
getMergeTableID(ColumnReference cr)

Find the MERGE table id of the indicated column

private 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.

pack-priv ResultColumnList
getThenColumns()

Return the list of columns which form the rows of the ResultSet which drive the INSERT/UPDATE/DELETE actions.

pack-priv boolean
isDeleteClause()

Return true if this is a WHEN MATCHED ...

pack-priv boolean
isInsertClause()

Return true if this is a WHEN NOT MATCHED ...

private boolean
isRowLocation(ResultColumn rc)

Return true if the ResultColumn represents a RowLocation

pack-priv 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.

pack-priv ConstantAction
pack-priv static MatchingClauseNode
makeDeleteClause(ValueNode matchingRefinement, ContextManager cm)

Make a WHEN MATCHED ...

pack-priv static MatchingClauseNode
makeInsertClause(ValueNode matchingRefinement, ResultColumnList insertColumns, ResultColumnList insertValues, ContextManager cm)

Make a WHEN NOT MATCHED ...

pack-priv static MatchingClauseNode
makeUpdateClause(ValueNode matchingRefinement, ResultColumnList updateColumns, ContextManager cm)

Make a WHEN MATCHED ...

pack-priv void
optimize()

Optimize the INSERT/UPDATE/DELETE action.

pack-priv void
printSubNodes(int
The depth of this node in the tree
depth
)

Overrides org.apache.derby.impl.sql.compile.QueryTreeNode.printSubNodes.

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.

public boolean
referencesSessionSchema()

Overrides org.apache.derby.impl.sql.compile.QueryTreeNode.referencesSessionSchema.

Return true if the node references SESSION schema tables (temporary or permanent)

private static boolean
private void
remapConstraints()

Re-map ColumnReferences in constraints to point into the row from the temporary table.

public String

Returns:

This object as a String
toString
()

Overrides org.apache.derby.impl.sql.compile.QueryTreeNode.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.

Inherited from org.apache.derby.impl.sql.compile.QueryTreeNode:
acceptaddTagaddUDTUsagePrivaddUDTUsagePrivbindOffsetFetchbindRowMultiSetbindUserCatalogTypebindUserTypecheckReliabilitycheckReliabilityconvertDefaultNodecopyTagsFromcreateTypeDependencydebugFlushdebugPrintdisablePrivilegeCollectionformatNodeStringgenerategenerateAuthorizeCheckgetBeginOffsetgetClassFactorygetCompilerContextgetContextgetContextManagergetDataDictionarygetDependencyManagergetEndOffsetgetExecutionFactorygetGenericConstantActionFactorygetIntPropertygetLanguageConnectionContextgetLongPropertygetNullNodegetOffsetOrderedNodesgetOptimizerFactorygetOptimizerTracergetParameterTypesgetSchemaDescriptorgetSchemaDescriptorgetStatementTypegetTableDescriptorgetTypeCompilergetUDTDescisAtomicisPrivilegeCollectionRequiredisSessionSchemaisSessionSchemamakeConstantActionmakeTableNamemakeTableNamenodeHeaderoptimizerTracingIsOnorReliabilityparseSearchConditionparseStatementprintLabelresolveTableToSynonymsetBeginOffsetsetEndOffsetsetRefActionInfostackPrinttaggedWithtreePrinttreePrintverifyClassExist

Field Detail

_actionMethodNameback to summary
private String _actionMethodName
_clauseNumberback to summary
private int _clauseNumber
_dmlback to summary
private DMLModStatementNode _dml
_insertColumnsback to summary
private ResultColumnList _insertColumns
_insertValuesback to summary
private ResultColumnList _insertValues
_matchingRefinementback to summary
private ValueNode _matchingRefinement
_resultSetFieldNameback to summary
private String _resultSetFieldName
_rowMakingMethodNameback to summary
private String _rowMakingMethodName
_thenColumnsback to summary
private ResultColumnList _thenColumns
_updateColumnsback to summary
private ResultColumnList _updateColumns
CURRENT_OF_NODE_NAMEback to summary
private static final String CURRENT_OF_NODE_NAME

Constructor Detail

MatchingClauseNodeback to summary
private MatchingClauseNode(ValueNode matchingRefinement, ResultColumnList updateColumns, ResultColumnList insertColumns, ResultColumnList insertValues, ContextManager cm) throws StandardException

Constructor called by factory methods.

Method Detail

acceptChildrenback to summary
pack-priv void acceptChildren(Visitor v) throws StandardException

Overrides org.apache.derby.impl.sql.compile.QueryTreeNode.acceptChildren.

Accept the visitor for all visitable children of this node.

Parameters
v:Visitor

the visitor

Annotations
@Override
Exceptions
StandardException:
on error
adjustMatchingRefinementback to summary
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.

adjustThenColumnsback to summary
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.

autoincrementColumnSetToDEFAULTback to summary
private boolean autoincrementColumnSetToDEFAULT(TableDescriptor targetTableDescriptor, ResultColumnList valuesList)

Return true if the VALUES clause of the INSERT branch contains an autoincrement column which is set to DEFAULT or if the VALUES clause doesn't explicitly mention the autoincrement column.

Parameters
targetTableDescriptor:TableDescriptor

Target table catalog info

valuesList:ResultColumnList

Columns explicitly mentioned in the VALUES clause

bindback to summary
pack-priv void bind(DataDictionary dd, MergeNode mergeNode, FromList fullFromList, FromBaseTable targetTable) throws StandardException

Bind this WHEN [ NOT ] MATCHED clause against the parent MergeNode

bindDeleteback to summary
private void bindDelete(DataDictionary dd, FromList fullFromList, FromBaseTable targetTable) throws StandardException

Bind a WHEN MATCHED ... THEN DELETE clause

bindExpressionsback to summary
private void bindExpressions(ResultColumnList rcl, FromList fromList) throws StandardException

Boilerplate for binding a list of ResultColumns against a FromList

bindInsertback to summary
private void bindInsert(DataDictionary dd, MergeNode mergeNode, FromList fullFromList, FromBaseTable targetTable) throws StandardException

Bind a WHEN NOT MATCHED ... THEN INSERT clause

bindInsertValuesback to summary
private void bindInsertValues(FromList fullFromList, FromTable targetTable) throws StandardException

Bind the values in the INSERT list

bindRefinementback to summary
pack-priv void bindRefinement(MergeNode mergeNode, FromList fullFromList) throws StandardException

Bind the optional refinement condition in the MATCHED clause

bindSetClausesback to summary
private void bindSetClauses(MergeNode mergeNode, FromList fullFromList, FromTable targetTable, ResultColumnList setClauses) throws StandardException

Bind the SET clauses of an UPDATE action

bindUpdateback to summary
private void bindUpdate(DataDictionary dd, MergeNode mergeNode, FromList fullFromList, FromBaseTable targetTable) throws StandardException

Bind a WHEN MATCHED ... THEN UPDATE clause

buildFullColumnListback to summary
private ResultColumnList buildFullColumnList(TableDescriptor td) throws StandardException

Build the full column list for a table.

buildThenColumnsForDeleteback to summary
private void buildThenColumnsForDelete() throws StandardException

Construct the signature of the temporary table which drives the INSERT/UPDATE/DELETE action.

buildThenColumnsForInsertback to summary
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.

buildThenColumnsForUpdateback to summary
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.

buildThenColumnSignatureback to summary
private ResultDescription buildThenColumnSignature() throws StandardException

Build the signature of the row which will go into the temporary table.

forbidSubqueriesback to summary
private void forbidSubqueries() throws StandardException

Forbid subqueries in WHEN [ NOT ] MATCHED clauses.

forbidSubqueriesback to summary
private void forbidSubqueries(ResultColumnList rcl) throws StandardException
forbidSubqueriesback to summary
private void forbidSubqueries(ValueNode expr) throws StandardException
generateback to summary
pack-priv 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().

generateInsertUpdateRowback to summary
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.

generateResultSetFieldback to summary
pack-priv 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.

getBoundSelectUnderUpdateback to summary
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.

getChangedColumnNamesback to summary
private HashSet<String> getChangedColumnNames() throws StandardException

Get the names of the columns explicitly changed by SET clauses

getChangedGeneratedColumnNamesback to summary
private HashSet<String> getChangedGeneratedColumnNames(TableDescriptor targetTableDescriptor, HashSet<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.
getClauseTypeback to summary
private int getClauseType()
getColumnReferencesback to summary
private List<ColumnReference> getColumnReferences(QueryTreeNode expression) throws StandardException

Get a list of column references in an expression

getColumnsInExpressionsback to summary
pack-priv void getColumnsInExpressions(MergeNode mergeNode, HashMap<String, ColumnReference> drivingColumnMap) throws StandardException

Collect the columns mentioned by expressions in this MATCHED clause

getMergeTableIDback to summary
private int getMergeTableID(ColumnReference cr)

Find the MERGE table id of the indicated column

getSelectListOffsetback to summary
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.

getThenColumnsback to summary
pack-priv ResultColumnList getThenColumns()

Return the list of columns which form the rows of the ResultSet which drive the INSERT/UPDATE/DELETE actions.

isDeleteClauseback to summary
pack-priv boolean isDeleteClause()

Return true if this is a WHEN MATCHED ... DELETE clause

isInsertClauseback to summary
pack-priv boolean isInsertClause()

Return true if this is a WHEN NOT MATCHED ... INSERT clause

isRowLocationback to summary
private boolean isRowLocation(ResultColumn rc) throws StandardException

Return true if the ResultColumn represents a RowLocation

isUpdateClauseback to summary
pack-priv boolean isUpdateClause()

Return true if this is a WHEN MATCHED ... UPDATE clause

makeAutoGenRCback to summary
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.

makeConstantActionback to summary
pack-priv ConstantAction makeConstantAction(ActivationClassBuilder acb) throws StandardException
makeDeleteClauseback to summary
pack-priv static MatchingClauseNode makeDeleteClause(ValueNode matchingRefinement, ContextManager cm) throws StandardException

Make a WHEN MATCHED ... THEN DELETE clause

makeInsertClauseback to summary
pack-priv static MatchingClauseNode makeInsertClause(ValueNode matchingRefinement, ResultColumnList insertColumns, ResultColumnList insertValues, ContextManager cm) throws StandardException

Make a WHEN NOT MATCHED ... THEN INSERT clause

makeUpdateClauseback to summary
pack-priv static MatchingClauseNode makeUpdateClause(ValueNode matchingRefinement, ResultColumnList updateColumns, ContextManager cm) throws StandardException

Make a WHEN MATCHED ... THEN UPDATE clause

optimizeback to summary
pack-priv void optimize() throws StandardException

Optimize the INSERT/UPDATE/DELETE action.

printSubNodesback to summary
pack-priv void printSubNodes(int depth)

Overrides org.apache.derby.impl.sql.compile.QueryTreeNode.printSubNodes.

Prints the sub-nodes of this object. See QueryTreeNode.java for how tree printing is supposed to work.

Parameters
depth:int

The depth of this node in the tree

Annotations
@Override
realiasSetClausesback to summary
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.

referencesSessionSchemaback to summary
public boolean referencesSessionSchema() throws StandardException

Overrides org.apache.derby.impl.sql.compile.QueryTreeNode.referencesSessionSchema.

Doc from org.apache.derby.impl.sql.compile.QueryTreeNode.referencesSessionSchema.

Return true if the node references SESSION schema tables (temporary or permanent)

Returns:boolean

true if references SESSION schema tables, else false

Annotations
@Override
Exceptions
StandardException:
Thrown on error
referencesSessionSchemaback to summary
private static boolean referencesSessionSchema(QueryTreeNode node) throws StandardException
remapConstraintsback to summary
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.

toStringback to summary
public String toString()

Overrides org.apache.derby.impl.sql.compile.QueryTreeNode.toString.

Convert this object to a String. See comments in QueryTreeNode.java for how this should be done for tree printing.

Returns:String

This object as a String

Annotations
@Override
useGeneratedScanback to summary
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.