Class SetOperatorNode
- java.lang.Object
-
- org.apache.derby.impl.sql.compile.QueryTreeNode
-
- org.apache.derby.impl.sql.compile.ResultSetNode
-
- org.apache.derby.impl.sql.compile.FromTable
-
- org.apache.derby.impl.sql.compile.TableOperatorNode
-
- org.apache.derby.impl.sql.compile.SetOperatorNode
-
- All Implemented Interfaces:
Optimizable
,Visitable
- Direct Known Subclasses:
IntersectOrExceptNode
,UnionNode
abstract class SetOperatorNode extends TableOperatorNode
A SetOperatorNode represents a UNION, INTERSECT, or EXCEPT in a DML statement. Binding and optimization preprocessing is the same for all of these operations, so they share bind methods in this abstract class. The class contains a boolean telling whether the operation should eliminate duplicate rows.
-
-
Nested Class Summary
-
Nested classes/interfaces inherited from class org.apache.derby.impl.sql.compile.ResultSetNode
ResultSetNode.QueryExpressionClauses
-
-
Field Summary
Fields Modifier and Type Field Description (package private) boolean
all
Tells whether to eliminate duplicate rows.private PredicateList
leftOptPredicates
private java.util.HashMap<Predicate,Predicate>
leftScopedPreds
private PredicateList
pushedPredicates
(package private) ResultSetNode.QueryExpressionClauses
qec
private PredicateList
rightOptPredicates
private java.util.HashMap<Predicate,Predicate>
rightScopedPreds
-
Fields inherited from class org.apache.derby.impl.sql.compile.TableOperatorNode
leftOptimizer, leftResultSet, rightOptimizer, rightResultSet
-
Fields inherited from class org.apache.derby.impl.sql.compile.FromTable
ADD_PLAN, bestAccessPath, bestCostEstimate, bestSortAvoidancePath, correlationName, corrTableName, currentAccessPath, hashKeyColumns, initialCapacity, level, LOAD_PLAN, loadFactor, maxCapacity, origTableName, REMOVE_PLAN, tableNumber, tableProperties, trulyTheBestAccessPath, userSpecifiedJoinStrategy
-
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 Constructor Description SetOperatorNode(ResultSetNode leftResult, ResultSetNode rightResult, boolean all, java.util.Properties tableProperties, ContextManager cm)
Constructor for a SetOperatorNode.
-
Method Summary
All Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description void
bindExpressions(FromList fromList)
Bind the expressions under this TableOperatorNode.(package private) void
bindResultColumns(TableDescriptor targetTableDescriptor, FromVTI targetVTI, ResultColumnList targetColumnList, DMLStatementNode statement, FromList fromListParam)
Bind the result columns for this ResultSetNode to a base table.(package private) void
bindResultColumns(FromList fromListParam)
Bind the result columns of this ResultSetNode when there is no base table to bind them to.(package private) void
bindTargetExpressions(FromList fromListParam)
Bind the expressions in the target list.(package private) void
bindUntypedNullsToResultColumns(ResultColumnList rcl)
Bind the result columns of a table constructor to the types in the given ResultColumnList.private void
buildRCL()
Build the RCL for this node.(package private) ResultSetNode
ensurePredicateList(int numTables)
Ensure that the top of the RSN tree has a PredicateList.(package private) boolean
flattenableInFromSubquery(FromList fromList)
Evaluate whether or not the subquery in a FromSubquery is flattenable.(package private) FromTable
getFromTableByName(java.lang.String name, java.lang.String schemaName, boolean exactMatch)
Determine whether or not the specified name is an exposed name in the current query block.(package private) PredicateList
getLeftOptPredicateList()
Retrieve the list of optimizable predicates that are targeted for the left child.(package private) abstract java.lang.String
getOperatorName()
(package private) int
getParamColumnTypes(DataTypeDescriptor[] types, RowResultSetNode rrsn)
Get the parameter types from the given RowResultSetNode into the given array of types.(package private) PredicateList
getRightOptPredicateList()
Retrieve the list of optimizable predicates that are targeted for the right child.protected boolean
hasUnPushedPredicates()
It's possible that we tried to push predicates to this node's children but failed to do so.Optimizable
modifyAccessPath(JBitSet outerTables, PredicateList predList)
(package private) boolean
performMaterialization(JBitSet outerTables)
Return whether or not to materialize this ResultSet tree.(package private) ResultSetNode
preprocess(int numTables, GroupByList gbl, FromList fromList)
Put a ProjectRestrictNode on top of each FromTable in the FromList.(package private) void
printSubNodes(int depth)
Prints the sub-nodes of this object.void
pullOptPredicates(OptimizablePredicateList optimizablePredicates)
Pull all the OptimizablePredicates from this Optimizable and put them in the given OptimizablePredicateList.(package private) void
pushOffsetFetchFirst(ValueNode offset, ValueNode fetchFirst, boolean hasJDBClimitClause)
Push down the offset and fetch first parameters, if any, to this node.boolean
pushOptPredicate(OptimizablePredicate optimizablePredicate)
Push an OptimizablePredicate down, if this node accepts it.(package private) void
pushOrderByList(OrderByList orderByList)
Push the order by list down from the cursor node into its child result set so that the optimizer has all of the information that it needs to consider sort avoidance.void
pushQueryExpressionSuffix()
Set up a new level for order by and fetch/offset clauses.(package private) void
replaceOrForbidDefaults(TableDescriptor ttd, ResultColumnList tcl, boolean allowDefaults)
Replace any DEFAULTs with the associated tree for the default if allowed, or flag (when inside top level set operator nodes).(package private) void
setParamColumnTypes(DataTypeDescriptor[] types, RowResultSetNode rrsn)
Set the type of each ?(package private) ResultSetNode
setResultToBooleanTrueNode(boolean onlyConvertAlls)
Set the result column for the subquery to a boolean true, Useful for transformations such as changing: where exists (select ... from ...)java.lang.String
toString()
Convert this object to a String.(package private) void
verifySelectStarSubquery(FromList outerFromList, int subqueryType)
Verify that a SELECT * is valid for this type of subquery.-
Methods inherited from class org.apache.derby.impl.sql.compile.TableOperatorNode
acceptChildren, adjustForSortElimination, adjustForSortElimination, bindExpressionsWithTables, bindNonVTITables, bindVTITables, decrementLevel, getExposedName, getLeftmostResultSet, getLeftResultSet, getRightResultSet, modifyAccessPath, modifyAccessPaths, needsSpecialRCLBinding, optimize, optimizeSource, projectResultColumns, referencesSessionSchema, referencesTarget, rejectParameters, setLeftmostResultSet, setLevel, setNestedInParens, setReferencedColumns, updateBestPlanMap, verifyProperties
-
Methods inherited from class org.apache.derby.impl.sql.compile.FromTable
assignCostEstimate, canBeOrdered, columnsAreUpdatable, considerSortAvoidancePath, convertAbsoluteToRelativeColumnPosition, cursorTargetTable, estimateCost, feasibleJoinStrategy, fillInReferencedTableMap, flatten, forUpdate, getBaseTableName, getBestAccessPath, getBestSortAvoidancePath, getCorrelationName, getCostEstimate, getCurrentAccessPath, getFinalCostEstimate, getLevel, getMergeTableID, getName, getNumColumnsReturned, getOrigTableName, getProperties, getResultColumnsForList, getSchemaDescriptor, getSchemaDescriptor, getScratchCostEstimate, getTableDescriptor, getTableName, getTableNumber, getTrulyTheBestAccessPath, getUserSpecifiedJoinStrategy, hashKeyColumns, hasLargeObjectColumns, hasTableNumber, initAccessPaths, initialCapacity, isBaseTable, isCoveringIndex, isFlattenableJoinNode, isJoinColumnForRightOuterJoin, isMaterializable, isOneRowScan, isTargetTable, legalJoinOrder, loadFactor, LOJ_reorderable, markUpdatableByCursor, maxCapacity, memoryUsageOK, nextAccessPath, optimizeIt, optimizeSubqueries, pushExpressions, rememberAsBest, rememberJoinStrategyAsBest, rememberSortAvoidancePath, resetJoinStrategies, setCostEstimateCost, setHashKeyColumns, setMergeTableID, setOrigTableName, setProperties, setTableNumber, startOptimizing, supportsMultipleInstantiations, tellRowOrderingAboutConstantColumns, transformOuterJoins, uniqueJoin
-
Methods inherited from class org.apache.derby.impl.sql.compile.ResultSetNode
addNewPredicate, assignResultSetNumber, changeAccessPath, columnTypesAndLengthsMatch, considerMaterialization, enhanceRCLForInsert, generateNormalizationResultSet, generateResultSet, genProjectRestrict, genProjectRestrict, genProjectRestrictForReordering, getAllResultColumns, getCandidateFinalCostEstimate, getCostEstimate, getCursorTargetTable, getFromList, getMatchingColumn, getNewCostEstimate, getOptimizer, getOptimizerImpl, getRCLForInsert, getReferencedTableMap, getResultColumns, getResultSetNumber, getScratchCostEstimate, isCursorTargetTable, isInsertSource, isNotExists, isOneRowResultSet, isOrderedOn, isPossibleDistinctScan, isStatementResultSet, isUpdatableCursor, LOJgetReferencedTables, makeResultDescription, makeResultDescriptors, markAsCursorTargetTable, markForDistinctScan, markStatementResultSet, modifyAccessPaths, notCursorTargetTable, notFlattenableJoin, numDistinctAggregates, parseDefault, printQueryExpressionSuffixClauses, rejectXMLValues, renameGeneratedResultNames, returnsAtMostOneRow, setCandidateFinalCostEstimate, setCostEstimate, setCursorTargetTable, setInsertSource, setOptimizer, setReferencedTableMap, setResultColumns, setResultSetNumber, setScratchCostEstimate, setTableConstructorTypes, subqueryReferencesTarget, updateTargetLockMode
-
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
-
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
-
Methods inherited from interface org.apache.derby.iapi.sql.compile.Optimizable
getDataDictionary, getOptimizerTracer, getReferencedTableMap, getResultSetNumber, optimizerTracingIsOn
-
Methods inherited from interface org.apache.derby.iapi.sql.compile.Visitable
accept, addTag, taggedWith
-
-
-
-
Field Detail
-
all
boolean all
Tells whether to eliminate duplicate rows. all == TRUE means do not eliminate duplicates, all == FALSE means eliminate duplicates.
-
leftOptPredicates
private PredicateList leftOptPredicates
-
rightOptPredicates
private PredicateList rightOptPredicates
-
pushedPredicates
private PredicateList pushedPredicates
-
-
Constructor Detail
-
SetOperatorNode
SetOperatorNode(ResultSetNode leftResult, ResultSetNode rightResult, boolean all, java.util.Properties tableProperties, ContextManager cm) throws StandardException
Constructor for a SetOperatorNode.- Parameters:
leftResult
- The ResultSetNode on the left side of this unionrightResult
- The ResultSetNode on the right side of this unionall
- Whether or not this is an ALL.tableProperties
- Properties list associated with the tablecm
- The context manager- Throws:
StandardException
- Thrown on error
-
-
Method Detail
-
modifyAccessPath
public Optimizable modifyAccessPath(JBitSet outerTables, PredicateList predList) throws StandardException
- Throws:
StandardException
- Thrown on error- See Also:
Optimizable.modifyAccessPath(org.apache.derby.iapi.util.JBitSet)
-
pushOptPredicate
public boolean pushOptPredicate(OptimizablePredicate optimizablePredicate) throws StandardException
Description copied from interface:Optimizable
Push an OptimizablePredicate down, if this node accepts it.- Specified by:
pushOptPredicate
in interfaceOptimizable
- Overrides:
pushOptPredicate
in classFromTable
- Parameters:
optimizablePredicate
- OptimizablePredicate to push down.- Returns:
- Whether or not the predicate was pushed down.
- Throws:
StandardException
- Thrown on error- See Also:
Take a predicate and push it down to both the left AND right result sets. Return "true" if we successfully pushed it to both sides, and "false" otherwise. The assumption is that if we return "true", the caller will take the predicate and remove it from its own list of predicates to evaluate; if we return false, then the predicate will be evaluated at the level of the caller. So returning "false" means that the left and right result sets for this node will be fully returned, and then the predicate will be evaluated against the set-operator of those result sets (as of DERBY-805, the only set operator calling this method is UnionNode). If we can push the predicate down to both children, though, we can evaluate it closer to store, which means that each child result set returns only the correctly qualified rows, and thus the calling set operator will have a smaller result set on which to operate, which can boost performance. That said, if we can't push the predicate to _both_ sides, we don't push it at all. The reason is that if we push to one side but not to the other, we would have to ask the question of whether we should return "true" (meaning that the predicate would be removed from the caller's list and thus would _not_ be evaluated at the set-operator level) or "false" (meaning that the caller would keep the predicate and evaluate it at the set-operator level). Depending on the query in question, both answers could end up returning incorrect results. For example, if we push it to the right but not to the left, then leave it in the caller's list, the optimizer for the caller might decide to use the predicate to do a hash join with some outer result set (if the predicate is an equijoin predicate). That would result in materialization of the calling node and of its children--but since we pushed a predicate that depends on the outer table down into the right child, materialization of the right child will only return the rows that join with the _first_ row of the outer result set, which is wrong. If, on the other hand, we push the predicate to one side and then tell the caller to remove it from its list, the side to which we did _not_ push the predicate could return rows that aren't qualified. Then, since the caller removed the predicate from its list, it (the caller) will not evaluate the predicate on its own result set--and thus we can end up returning rows that we weren't supposed to return. So all of that said, only push (and return "true") if we think we can push the predicate to both sides.
-
pullOptPredicates
public void pullOptPredicates(OptimizablePredicateList optimizablePredicates) throws StandardException
Description copied from interface:Optimizable
Pull all the OptimizablePredicates from this Optimizable and put them in the given OptimizablePredicateList.- Specified by:
pullOptPredicates
in interfaceOptimizable
- Overrides:
pullOptPredicates
in classFromTable
- Parameters:
optimizablePredicates
- The list to put the pulled predicates in.- Throws:
StandardException
- Thrown on error- See Also:
Optimizable.pullOptPredicates(org.apache.derby.iapi.sql.compile.OptimizablePredicateList)
-
hasUnPushedPredicates
protected boolean hasUnPushedPredicates()
It's possible that we tried to push predicates to this node's children but failed to do so. This can happen if this node's children both satisfy the criteria for pushing a predicate (namely, they reference base tables) but the children's children do not (see modifyAccessPaths() above for an example of how that can happen). So this method determines whether or not this particular SetOperatorNode has predicates which were *not* successfully pushed to both of its children (note: this currently only applies to UnionNodes).- Returns:
- True if this SetOperatorNode has unpushed predicates; false otherwise.
-
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 classTableOperatorNode
- Returns:
- This object as a String
-
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 classTableOperatorNode
- Parameters:
depth
- The depth of this node in the tree
-
bindResultColumns
void bindResultColumns(FromList fromListParam) throws StandardException
Bind the result columns of this ResultSetNode when there is no base table to bind them to. This is useful for SELECT statements, where the result columns get their types from the expressions that live under them.- Overrides:
bindResultColumns
in classTableOperatorNode
- Parameters:
fromListParam
- FromList to use/append to.- Throws:
StandardException
- Thrown on error
-
bindResultColumns
void bindResultColumns(TableDescriptor targetTableDescriptor, FromVTI targetVTI, ResultColumnList targetColumnList, DMLStatementNode statement, FromList fromListParam) throws StandardException
Bind the result columns for this ResultSetNode to a base table. This is useful for INSERT and UPDATE statements, where the result columns get their types from the table being updated or inserted into. If a result column list is specified, then the verification that the result column list does not contain any duplicates will be done when binding them by name.- Overrides:
bindResultColumns
in classTableOperatorNode
- Parameters:
targetTableDescriptor
- The TableDescriptor for the table being updated or inserted intotargetColumnList
- For INSERT statements, the user does not have to supply column names (for example, "insert into t values (1,2,3)". When this parameter is null, it means that the user did not supply column names, and so the binding should be done based on order. When it is not null, it means do the binding by name, not position.statement
- Calling DMLStatementNode (Insert or Update)fromListParam
- FromList to use/append to.- Throws:
StandardException
- Thrown on error
-
buildRCL
private void buildRCL() throws StandardException
Build the RCL for this node. We propagate the RCL up from the left child to form this node's RCL.- Throws:
StandardException
- Thrown on error
-
bindUntypedNullsToResultColumns
void bindUntypedNullsToResultColumns(ResultColumnList rcl) throws StandardException
Bind the result columns of a table constructor to the types in the given ResultColumnList. Use when inserting from a table constructor, and there are nulls in the values clauses.- Overrides:
bindUntypedNullsToResultColumns
in classTableOperatorNode
- Parameters:
rcl
- The ResultColumnList with the types to bind to- Throws:
StandardException
- Thrown on error.
-
replaceOrForbidDefaults
void replaceOrForbidDefaults(TableDescriptor ttd, ResultColumnList tcl, boolean allowDefaults) throws StandardException
Replace any DEFAULTs with the associated tree for the default if allowed, or flag (when inside top level set operator nodes). Subqueries are checked for illegal DEFAULTs elsewhere.- Overrides:
replaceOrForbidDefaults
in classResultSetNode
- Parameters:
ttd
- The TableDescriptor for the target table.tcl
- The RCL for the target table.allowDefaults
- true if allowed- Throws:
StandardException
- Thrown on error
-
getParamColumnTypes
int getParamColumnTypes(DataTypeDescriptor[] types, RowResultSetNode rrsn) throws StandardException
Get the parameter types from the given RowResultSetNode into the given array of types. If an array position is already filled in, don't clobber it.- Parameters:
types
- The array of types to fill inrrsn
- The RowResultSetNode from which to take the param types- Returns:
- The number of new types found in the RowResultSetNode
- Throws:
StandardException
-
setParamColumnTypes
void setParamColumnTypes(DataTypeDescriptor[] types, RowResultSetNode rrsn) throws StandardException
Set the type of each ? parameter in the given RowResultSetNode according to its ordinal position in the given array of types.- Parameters:
types
- An array of types containing the proper type for each ? parameter, by ordinal position.rrsn
- A RowResultSetNode that could contain ? parameters whose types need to be set.- Throws:
StandardException
- Thrown on error
-
bindExpressions
public void bindExpressions(FromList fromList) throws StandardException
Description copied from class:TableOperatorNode
Bind the expressions under this TableOperatorNode. This means binding the sub-expressions, as well as figuring out what the return type is for each expression.- Overrides:
bindExpressions
in classTableOperatorNode
- Parameters:
fromList
- FromList to use/append to.- Throws:
StandardException
- Thrown on error
-
bindTargetExpressions
void bindTargetExpressions(FromList fromListParam) throws StandardException
Bind the expressions in the target list. This means binding the sub-expressions, as well as figuring out what the return type is for each expression. This is useful for EXISTS subqueries, where we need to validate the target list before blowing it away and replacing it with a SELECT true.- Overrides:
bindTargetExpressions
in classResultSetNode
- Throws:
StandardException
- Thrown on error
-
pushQueryExpressionSuffix
public void pushQueryExpressionSuffix()
Description copied from class:ResultSetNode
Set up a new level for order by and fetch/offset clauses. See Javadoc forResultSetNode.QueryExpressionClauses
. Overridden by implementors of pushOrderByNode, pushOffsetFetchFirst.- Overrides:
pushQueryExpressionSuffix
in classResultSetNode
-
pushOrderByList
void pushOrderByList(OrderByList orderByList)
Push the order by list down from the cursor node into its child result set so that the optimizer has all of the information that it needs to consider sort avoidance.- Overrides:
pushOrderByList
in classResultSetNode
- Parameters:
orderByList
- The order by list
-
pushOffsetFetchFirst
void pushOffsetFetchFirst(ValueNode offset, ValueNode fetchFirst, boolean hasJDBClimitClause)
Push down the offset and fetch first parameters, if any, to this node.- Overrides:
pushOffsetFetchFirst
in classResultSetNode
- Parameters:
offset
- the OFFSET, if anyfetchFirst
- the OFFSET FIRST, if anyhasJDBClimitClause
- true if the clauses were added by (and have the semantics of) a JDBC limit clause
-
preprocess
ResultSetNode preprocess(int numTables, GroupByList gbl, FromList fromList) throws StandardException
Put a ProjectRestrictNode on top of each FromTable in the FromList. ColumnReferences must continue to point to the same ResultColumn, so that ResultColumn must percolate up to the new PRN. However, that ResultColumn will point to a new expression, a VirtualColumnNode, which points to the FromTable and the ResultColumn that is the source for the ColumnReference. (The new PRN will have the original of the ResultColumnList and the ResultColumns from that list. The FromTable will get shallow copies of the ResultColumnList and its ResultColumns. ResultColumn.expression will remain at the FromTable, with the PRN getting a new VirtualColumnNode for each ResultColumn.expression.) We then project out the non-referenced columns. If there are no referenced columns, then the PRN's ResultColumnList will consist of a single ResultColumn whose expression is 1.- Overrides:
preprocess
in classTableOperatorNode
- Parameters:
numTables
- Number of tables in the DML Statementgbl
- The group by list, if anyfromList
- The from list, if any- Returns:
- The preprocessed ResultSetNode that can be optimized
- Throws:
StandardException
- Thrown on error
-
ensurePredicateList
ResultSetNode ensurePredicateList(int numTables) throws StandardException
Ensure that the top of the RSN tree has a PredicateList.- Overrides:
ensurePredicateList
in classResultSetNode
- Parameters:
numTables
- The number of tables in the query.- Returns:
- ResultSetNode A RSN tree with a node which has a PredicateList on top.
- Throws:
StandardException
- Thrown on error
-
verifySelectStarSubquery
void verifySelectStarSubquery(FromList outerFromList, int subqueryType) throws StandardException
Verify that a SELECT * is valid for this type of subquery.- Overrides:
verifySelectStarSubquery
in classResultSetNode
- Parameters:
outerFromList
- The FromList from the outer query block(s)subqueryType
- The subquery type- Throws:
StandardException
- Thrown on error
-
getFromTableByName
FromTable getFromTableByName(java.lang.String name, java.lang.String schemaName, boolean exactMatch) throws StandardException
Determine whether or not the specified name is an exposed name in the current query block.- Overrides:
getFromTableByName
in classTableOperatorNode
- Parameters:
name
- The specified name to search for as an exposed name.schemaName
- Schema name, if non-null.exactMatch
- Whether or not we need an exact match on specified schema and table names or match on table id.- Returns:
- The FromTable, if any, with the exposed name.
- Throws:
StandardException
- Thrown on error
-
setResultToBooleanTrueNode
ResultSetNode setResultToBooleanTrueNode(boolean onlyConvertAlls) throws StandardException
Set the result column for the subquery to a boolean true, Useful for transformations such as changing: where exists (select ... from ...) to: where (select true from ...) NOTE: No transformation is performed if the ResultColumn.expression is already the correct boolean constant. This method is used during binding of EXISTS predicates to map a subquery's result column list into a single TRUE node. For SELECT and VALUES subqueries this transformation is pretty straightforward. But for set operators (ex. INTERSECT) we have to do some extra work. To see why, assume we have the following query: select * from ( values 'BAD' ) as T where exists ((values 1) intersect (values 2)) If we treated the INTERSECT in this query the same way that we treat SELECT/VALUES subqueries then the above query would get transformed into: select * from ( values 'BAD' ) as T where ((values TRUE) intersect (values TRUE)) Since both children of the INTERSECT would then have the same value, the result of set operation would be a single value (TRUE), which means the WHERE clause would evaluate to TRUE and thus the query would return one row with value 'BAD'. That would be wrong. To avoid this problem, we internally wrap this SetOperatorNode inside a "SELECT *" subquery and then we change the new SelectNode's result column list (as opposed to *this* nodes' result column list) to a singe boolean true node: select * from ( values 'BAD' ) as T where SELECT TRUE FROM ((values 1) intersect (values 2)) In this case the left and right children of the INTERSECT retain their values, which ensures that the result of the intersect operation will be correct. Since (1 intersect 2) is an empty result set, the internally generated SELECT node will return zero rows, which in turn means the WHERE predicate will return NULL (an empty result set from a SubqueryNode is treated as NULL at execution time; see impl/sql/execute/AnyResultSet). Since NULL is not the same as TRUE the query will correctly return zero rows. DERBY-2370.- Overrides:
setResultToBooleanTrueNode
in classResultSetNode
- Parameters:
onlyConvertAlls
- Boolean, whether or not to just convert *'s- Returns:
- ResultSetNode whose resultColumn was transformed; defaults to "this" here, but can be overridden by subclasses.
- Throws:
StandardException
- Thrown on error
-
flattenableInFromSubquery
boolean flattenableInFromSubquery(FromList fromList)
Evaluate whether or not the subquery in a FromSubquery is flattenable. Currently, a FSqry is flattenable if all of the following are true: o Subquery is a SelectNode. (ie, not a RowResultSetNode or a UnionNode) o It contains no top level subqueries. (RESOLVE - we can relax this) o It does not contain a group by or having clause o It does not contain aggregates.- Overrides:
flattenableInFromSubquery
in classResultSetNode
- Parameters:
fromList
- The outer from list- Returns:
- boolean Whether or not the FromSubquery is flattenable.
-
performMaterialization
boolean performMaterialization(JBitSet outerTables) throws StandardException
Return whether or not to materialize this ResultSet tree.- Overrides:
performMaterialization
in classResultSetNode
- Returns:
- Whether or not to materialize this ResultSet tree. would return valid results.
- Throws:
StandardException
- Thrown on error
-
getOperatorName
abstract java.lang.String getOperatorName()
- Returns:
- the operator name: "UNION", "INTERSECT", or "EXCEPT"
-
getLeftOptPredicateList
PredicateList getLeftOptPredicateList() throws StandardException
Retrieve the list of optimizable predicates that are targeted for the left child. Create a new (empty) list if the list is null.- Throws:
StandardException
-
getRightOptPredicateList
PredicateList getRightOptPredicateList() throws StandardException
Retrieve the list of optimizable predicates that are targeted for the right child. Create a new (empty) list if the list is null.- Throws:
StandardException
-
-