|
|||||||||
| Home >> All >> org >> apache >> derby >> impl >> sql >> [ compile overview ] | PREV CLASS NEXT CLASS | ||||||||
SUMMARY: JAVADOC | SOURCE | DOWNLOAD | NESTED | FIELD | CONSTR | METHOD |
DETAIL: FIELD | CONSTR | METHOD | ||||||||
org.apache.derby.impl.sql.compile
Class SubqueryNode

java.lang.Objectorg.apache.derby.impl.sql.compile.QueryTreeNode
org.apache.derby.impl.sql.compile.ValueNode
org.apache.derby.impl.sql.compile.SubqueryNode
- All Implemented Interfaces:
- org.apache.derby.iapi.sql.compile.Visitable
- public class SubqueryNode
- extends ValueNode
A SubqueryNode represents a subquery. Subqueries return values to their outer queries. An quantified subquery is one that appears under a quantified operator (like IN or EXISTS) - quantified subqueries can return more than one value per invocation. An expression subquery is one that is not directly under a quantified operator - expression subqueries are allowed to return at most one value per invocation (returning no value is considered to be equivalent to returning NULL). There are a large number of subquery types. Because of the large number of types, and the large amount of shared code, we have decided to have 1 SubqueryNode without any subclasses. The subquery type (and operator) is encoded in the subqueryType field. The query optimizer is responsible for optimizing subqueries, and also for transforming them so that code can be generated for them. The optimizer may eliminate some subqueries by transforming them into joins, or it may change the internal form of a subquery (for example, transforming 'where x in (select y from z where ...)' into 'where (select true from z where x = y and ...)'). Note that aggregates present some additional issues. A transformation such as:
- where x in (SELECT expression FROM z)
- where x = (SELECT true FROM (SELECT MAX(x) FROM z) WHERE SQLCOL1 = y)
| Fields inherited from class org.apache.derby.impl.sql.compile.ValueNode |
clause, dataTypeServices, IN_HAVING_CLAUSE, IN_SELECT_LIST, IN_UNKNOWN_CLAUSE, IN_WHERE_CLAUSE, transformed |
| Fields inherited from class org.apache.derby.impl.sql.compile.QueryTreeNode |
AUTOINCREMENT_INC_INDEX, AUTOINCREMENT_IS_AUTOINCREMENT_INDEX, AUTOINCREMENT_START_INDEX, beginOffset, endOffset |
| Constructor Summary | |
SubqueryNode()
|
|
| Method Summary | |
org.apache.derby.iapi.sql.compile.Visitable |
accept(org.apache.derby.iapi.sql.compile.Visitor v)
Accept a visitor, and call v.visit() on child nodes as necessary. |
ValueNode |
bindExpression(FromList fromList,
SubqueryList subqueryList,
java.util.Vector aggregateVector)
Bind this expression. |
private boolean |
canAllBeFlattened()
Can NOT IN, ALL be falttened to NOT EXISTS join? We can't or the flattening doesn't easily make sense if either side of the comparison is nullable. |
boolean |
categorize(org.apache.derby.iapi.util.JBitSet referencedTabs,
boolean simplePredsOnly)
Categorize this predicate. |
ValueNode |
changeToCNF(boolean underTopAndNode)
Finish putting an expression into conjunctive normal form. |
private void |
changeToCorrespondingExpressionType()
Convert this IN/ANY subquery, which is known to return at most 1 row, to an equivalent expression subquery. |
(package private) ValueNode |
eliminateNots(boolean underNotNode)
Eliminate NotNodes in the current query block. |
private ValueNode |
flattenToExistsJoin(int numTables,
FromList outerFromList,
SubqueryList outerSubqueryList,
PredicateList outerPredicateList,
boolean flattenableNotExists)
Flatten this subquery into the outer query block as an exists join. |
private ValueNode |
flattenToNormalJoin(int numTables,
FromList outerFromList,
SubqueryList outerSubqueryList,
PredicateList outerPredicateList)
Flatten this subquery into the outer query block. |
void |
generateExpression(ExpressionClassBuilder expressionBuilder,
org.apache.derby.iapi.services.compiler.MethodBuilder mbex)
Do code generation for this subquery. |
private org.apache.derby.iapi.services.compiler.LocalField |
generateMaterialization(ActivationClassBuilder acb,
org.apache.derby.iapi.services.compiler.MethodBuilder mbsq,
java.lang.String type)
|
private BinaryComparisonOperatorNode |
getNewJoinCondition(ValueNode leftOperand,
ValueNode rightOperand)
Build a new join condition between the leftOperand and the rightOperand. |
protected int |
getOrderableVariantType()
Return the variant type for the underlying expression. |
int |
getPointOfAttachment()
Get the ResultSet # for the point of attachment for this SubqueryNode. |
(package private) boolean |
getPreprocessed()
Get whether or not this SubqueryNode has already been preprocessed. |
ResultSetNode |
getResultSet()
Return the resultSet for this SubqueryNode. |
int |
getSubqueryType()
Return the type of this subquery. |
private BooleanConstantNode |
getTrueNode()
|
boolean |
getUnderTopAndNode()
Return whether or not this subquery is immediately under a top level AndNode. |
boolean |
hasCorrelatedCRs()
Check to see if this subquery has correlated column references. |
void |
init(java.lang.Object resultSet,
java.lang.Object subqueryType,
java.lang.Object leftOperand)
Initializer. |
private boolean |
isALL()
|
private boolean |
isANY()
|
private boolean |
isEXISTS()
|
private boolean |
isIN()
|
private boolean |
isInvariant()
Check to see if we have a Variant value below us. |
(package private) boolean |
isMaterializable()
|
private boolean |
isNOT_EXISTS()
|
private boolean |
isNOT_IN()
|
void |
modifyAccessPaths()
Make any changes to the access paths, as decided by the optimizer. |
void |
optimize(org.apache.derby.iapi.sql.dictionary.DataDictionary dataDictionary,
double outerRows)
Optimize this SubqueryNode. |
ValueNode |
preprocess(int numTables,
FromList outerFromList,
SubqueryList outerSubqueryList,
PredicateList outerPredicateList)
Preprocess an expression tree. |
void |
printSubNodes(int depth)
Prints the sub-nodes of this object. |
private UnaryComparisonOperatorNode |
pushNewPredicate(int numTables)
Transform: expresion QuantifiedOperator (select x from ...) into (select true from .. |
ValueNode |
remapColumnReferencesToExpressions()
Remap all ColumnReferences in this tree to be clones of the underlying expression. |
private void |
setDataTypeServices(ResultColumnList resultColumns)
|
(package private) void |
setParentComparisonOperator(BinaryComparisonOperatorNode parent)
Set the parent BCON. |
void |
setPointOfAttachment(int pointOfAttachment)
Set the point of attachment of this subquery. |
void |
setSubqueryType(int subqueryType)
Set the type of this subquery. |
private boolean |
singleFromBaseTable(FromList fromList)
Does the from list from the subquery contain a single entry which is a FBT or a PRN/FBT. |
java.lang.String |
toString()
Convert this object to a String. |
| Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
| Field Detail |
resultSet
ResultSetNode resultSet
subqueryType
int subqueryType
underTopAndNode
boolean underTopAndNode
preprocessed
boolean preprocessed
distinctExpression
boolean distinctExpression
leftOperand
ValueNode leftOperand
pushedNewPredicate
boolean pushedNewPredicate
parentComparisonOperator
BinaryComparisonOperatorNode parentComparisonOperator
trueNode
private BooleanConstantNode trueNode
subqueryNumber
private int subqueryNumber
pointOfAttachment
private int pointOfAttachment
foundCorrelation
private boolean foundCorrelation
doneCorrelationCheck
private boolean doneCorrelationCheck
foundVariant
private boolean foundVariant
doneInvariantCheck
private boolean doneInvariantCheck
NOTIMPLEMENTED_SUBQUERY
public static final int NOTIMPLEMENTED_SUBQUERY
- See Also:
- Constant Field Values
FROM_SUBQUERY
public static final int FROM_SUBQUERY
- See Also:
- Constant Field Values
IN_SUBQUERY
public static final int IN_SUBQUERY
- See Also:
- Constant Field Values
NOT_IN_SUBQUERY
public static final int NOT_IN_SUBQUERY
- See Also:
- Constant Field Values
EQ_ANY_SUBQUERY
public static final int EQ_ANY_SUBQUERY
- See Also:
- Constant Field Values
EQ_ALL_SUBQUERY
public static final int EQ_ALL_SUBQUERY
- See Also:
- Constant Field Values
NE_ANY_SUBQUERY
public static final int NE_ANY_SUBQUERY
- See Also:
- Constant Field Values
NE_ALL_SUBQUERY
public static final int NE_ALL_SUBQUERY
- See Also:
- Constant Field Values
GT_ANY_SUBQUERY
public static final int GT_ANY_SUBQUERY
- See Also:
- Constant Field Values
GT_ALL_SUBQUERY
public static final int GT_ALL_SUBQUERY
- See Also:
- Constant Field Values
GE_ANY_SUBQUERY
public static final int GE_ANY_SUBQUERY
- See Also:
- Constant Field Values
GE_ALL_SUBQUERY
public static final int GE_ALL_SUBQUERY
- See Also:
- Constant Field Values
LT_ANY_SUBQUERY
public static final int LT_ANY_SUBQUERY
- See Also:
- Constant Field Values
LT_ALL_SUBQUERY
public static final int LT_ALL_SUBQUERY
- See Also:
- Constant Field Values
LE_ANY_SUBQUERY
public static final int LE_ANY_SUBQUERY
- See Also:
- Constant Field Values
LE_ALL_SUBQUERY
public static final int LE_ALL_SUBQUERY
- See Also:
- Constant Field Values
EXISTS_SUBQUERY
public static final int EXISTS_SUBQUERY
- See Also:
- Constant Field Values
NOT_EXISTS_SUBQUERY
public static final int NOT_EXISTS_SUBQUERY
- See Also:
- Constant Field Values
EXPRESSION_SUBQUERY
public static final int EXPRESSION_SUBQUERY
- See Also:
- Constant Field Values
| Constructor Detail |
SubqueryNode
public SubqueryNode()
| Method Detail |
init
public void init(java.lang.Object resultSet, java.lang.Object subqueryType, java.lang.Object leftOperand)
- Initializer.
- Overrides:
initin classQueryTreeNode
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.
printSubNodes
public void printSubNodes(int depth)
- Prints the sub-nodes of this object. See QueryTreeNode.java for
how tree printing is supposed to work.
- Overrides:
printSubNodesin classQueryTreeNode
getResultSet
public ResultSetNode getResultSet()
- Return the resultSet for this SubqueryNode.
getSubqueryType
public int getSubqueryType()
- Return the type of this subquery.
setSubqueryType
public void setSubqueryType(int subqueryType)
- Set the type of this subquery.
setPointOfAttachment
public void setPointOfAttachment(int pointOfAttachment)
throws org.apache.derby.iapi.error.StandardException
- Set the point of attachment of this subquery.
getUnderTopAndNode
public boolean getUnderTopAndNode()
- Return whether or not this subquery is immediately under a top level
AndNode.
getPointOfAttachment
public int getPointOfAttachment()
- Get the ResultSet # for the point of attachment for this SubqueryNode.
getPreprocessed
boolean getPreprocessed()
- Get whether or not this SubqueryNode has already been
preprocessed.
setParentComparisonOperator
void setParentComparisonOperator(BinaryComparisonOperatorNode parent)
- Set the parent BCON. Useful when considering flattening
expression subqueries.
remapColumnReferencesToExpressions
public ValueNode remapColumnReferencesToExpressions() throws org.apache.derby.iapi.error.StandardException
- Remap all ColumnReferences in this tree to be clones of the
underlying expression.
- Overrides:
remapColumnReferencesToExpressionsin classValueNode
bindExpression
public ValueNode bindExpression(FromList fromList, SubqueryList subqueryList, java.util.Vector aggregateVector) throws org.apache.derby.iapi.error.StandardException
- Bind this expression. This means binding the sub-expressions,
as well as figuring out what the return type is for this expression.
- Overrides:
bindExpressionin classValueNode
preprocess
public ValueNode preprocess(int numTables, FromList outerFromList, SubqueryList outerSubqueryList, PredicateList outerPredicateList) throws org.apache.derby.iapi.error.StandardException
- Preprocess an expression tree. We do a number of transformations
here (including subqueries, IN lists, LIKE and BETWEEN) plus
subquery flattening.
NOTE: This is done before the outer ResultSetNode is preprocessed.
- Overrides:
preprocessin classValueNode
singleFromBaseTable
private boolean singleFromBaseTable(FromList fromList)
- Does the from list from the subquery contain a
single entry which is a FBT or a PRN/FBT.
canAllBeFlattened
private boolean canAllBeFlattened()
- Can NOT IN, ALL be falttened to NOT EXISTS join? We can't or the flattening doesn't
easily make sense if either side of the comparison is nullable. (beetle 5173)
flattenToNormalJoin
private ValueNode flattenToNormalJoin(int numTables, FromList outerFromList, SubqueryList outerSubqueryList, PredicateList outerPredicateList) throws org.apache.derby.iapi.error.StandardException
- Flatten this subquery into the outer query block.
At this point we are only flattening based on a uniqueness
condition and only flattening non-aggregate subqueries.
So, we promote the subquery's from list, as is, into
the outer from list. For EXISTS subquerys, we return a
TRUE. Otherwise we return a new comparison between
the leftOperand and the expression in the subquery's
SELECT list.
RESOLVE - we will need to modify this logic to account
for exists joins and aggregates as we support flattening
for them.
Anyway, here's what we do:
o We remove ourself from the outer subquery list.
o We decrement the nesting level for all tables
in the subquery tree.
o We append the subquery's from list to the outer
from list.
o We add the subquery's predicate list to the outer
predicate list. (The subquery has already been
preprocessed.)
o We add the subquery's subquery list to the outer
subquery list.
o For EXISTS, we return a true.
o Otherwise, we return a new comparison between the
leftOperand and the expression in the inner select's
RCL.
flattenToExistsJoin
private ValueNode flattenToExistsJoin(int numTables, FromList outerFromList, SubqueryList outerSubqueryList, PredicateList outerPredicateList, boolean flattenableNotExists) throws org.apache.derby.iapi.error.StandardException
- Flatten this subquery into the outer query block
as an exists join.
At this point we are only flattening non-aggregate subqueries
with a single FBT in the from list.
So, we transform all FBTs in the from list into ExistBaseTables,
update the dependency lists for each of the tables and then
flatten the subquery.
RESOLVE - we will need to modify this logic to account
for aggregates as we support flattening
for them.
isInvariant
private boolean isInvariant()
throws org.apache.derby.iapi.error.StandardException
- Check to see if we have a Variant value below us.
If so, return true. Caches the result so multiple
calls are ok.
hasCorrelatedCRs
public boolean hasCorrelatedCRs()
throws org.apache.derby.iapi.error.StandardException
- Check to see if this subquery has correlated
column references. Only useful results if
called AFTER binding (after CRs have been bound).
pushNewPredicate
private UnaryComparisonOperatorNode pushNewPredicate(int numTables) throws org.apache.derby.iapi.error.StandardException
- Transform:
expresion QuantifiedOperator (select x from ...)
into
(select true from .. where expression
x ...) IS [NOT] NULL or, if we have an aggregate: (select true from (select AGG(x) from ...) where expression x ...) IS [NOT] NULL For ANY and IN subqueries: o We generate an IS NULL above the SubqueryNode and return the top of the new tree to the caller. o The operator in the new predicate that is added to the subquery will correspond to the operator that modifies the ANY. (eg, = for = ANY, with = for IN.) For ALL and NOT IN subqueries: o We generate an IS NOT NULL above the SubqueryNode and return the top of the new tree to the caller. o The operator in the new predicate that is added to the subquery will be a BinaryAllOperatorNode whose bcoNodeType corresponds to the negation of the operator that modifies the ALL. (eg, <> for = ALL, with <> for NOT IN.) NOTE: This method is called after the underlying subquery has been preprocessed, so we build a new Predicate, not just a new expression.
getNewJoinCondition
private BinaryComparisonOperatorNode getNewJoinCondition(ValueNode leftOperand, ValueNode rightOperand) throws org.apache.derby.iapi.error.StandardException
- Build a new join condition between the leftOperand
and the rightOperand. The comparison operator
is dependent on the subquery type.
eliminateNots
ValueNode eliminateNots(boolean underNotNode) throws org.apache.derby.iapi.error.StandardException
- Eliminate NotNodes in the current query block. We traverse the tree,
inverting ANDs and ORs and eliminating NOTs as we go. We stop at
ComparisonOperators and boolean expressions. We invert
ComparisonOperators and replace boolean expressions with
boolean expression = false.
NOTE: Since we do not recurse under ComparisonOperators, there
still could be NotNodes left in the tree.
- Overrides:
eliminateNotsin classValueNode
changeToCNF
public ValueNode changeToCNF(boolean underTopAndNode) throws org.apache.derby.iapi.error.StandardException
- Finish putting an expression into conjunctive normal
form. An expression tree in conjunctive normal form meets
the following criteria:
o If the expression tree is not null,
the top level will be a chain of AndNodes terminating
in a true BooleanConstantNode.
o The left child of an AndNode will never be an AndNode.
o Any right-linked chain that includes an AndNode will
be entirely composed of AndNodes terminated by a true BooleanConstantNode.
o The left child of an OrNode will never be an OrNode.
o Any right-linked chain that includes an OrNode will
be entirely composed of OrNodes terminated by a false BooleanConstantNode.
o ValueNodes other than AndNodes and OrNodes are considered
leaf nodes for purposes of expression normalization.
In other words, we won't do any normalization under
those nodes.
In addition, we track whether or not we are under a top level AndNode.
SubqueryNodes need to know this for subquery flattening.
- Overrides:
changeToCNFin classValueNode
categorize
public boolean categorize(org.apache.derby.iapi.util.JBitSet referencedTabs, boolean simplePredsOnly) throws org.apache.derby.iapi.error.StandardException
- Categorize this predicate. Initially, this means
building a bit map of the referenced tables for each predicate.
If the source of this ColumnReference (at the next underlying level)
is not a ColumnReference or a VirtualColumnNode then this predicate
will not be pushed down.
For example, in:
select * from (select 1 from s) a (x) where x = 1
we will not push down x = 1.
NOTE: It would be easy to handle the case of a constant, but if the
inner SELECT returns an arbitrary expression, then we would have to copy
that tree into the pushed predicate, and that tree could contain
subqueries and method calls.
RESOLVE - revisit this issue once we have views.
- Overrides:
categorizein classValueNode
isMaterializable
boolean isMaterializable()
throws org.apache.derby.iapi.error.StandardException
optimize
public void optimize(org.apache.derby.iapi.sql.dictionary.DataDictionary dataDictionary, double outerRows) throws org.apache.derby.iapi.error.StandardException
- Optimize this SubqueryNode.
modifyAccessPaths
public void modifyAccessPaths()
throws org.apache.derby.iapi.error.StandardException
- Make any changes to the access paths, as decided by the optimizer.
getOrderableVariantType
protected int getOrderableVariantType()
throws org.apache.derby.iapi.error.StandardException
- Return the variant type for the underlying expression.
The variant type can be:
VARIANT - variant within a scan
(method calls and non-static field access)
SCAN_INVARIANT - invariant within a scan
(column references from outer tables)
QUERY_INVARIANT - invariant within the life of a query
(constant expressions)
- Overrides:
getOrderableVariantTypein classValueNode
generateExpression
public void generateExpression(ExpressionClassBuilder expressionBuilder, org.apache.derby.iapi.services.compiler.MethodBuilder mbex) throws org.apache.derby.iapi.error.StandardException
- Do code generation for this subquery.
- Overrides:
generateExpressionin classValueNode
generateMaterialization
private org.apache.derby.iapi.services.compiler.LocalField generateMaterialization(ActivationClassBuilder acb, org.apache.derby.iapi.services.compiler.MethodBuilder mbsq, java.lang.String type)
getTrueNode
private BooleanConstantNode getTrueNode() throws org.apache.derby.iapi.error.StandardException
accept
public org.apache.derby.iapi.sql.compile.Visitable accept(org.apache.derby.iapi.sql.compile.Visitor v) throws org.apache.derby.iapi.error.StandardException
- Accept a visitor, and call v.visit()
on child nodes as necessary.
- Specified by:
acceptin interfaceorg.apache.derby.iapi.sql.compile.Visitable- Overrides:
acceptin classQueryTreeNode
isIN
private boolean isIN()
isNOT_IN
private boolean isNOT_IN()
isANY
private boolean isANY()
isALL
private boolean isALL()
isEXISTS
private boolean isEXISTS()
isNOT_EXISTS
private boolean isNOT_EXISTS()
changeToCorrespondingExpressionType
private void changeToCorrespondingExpressionType()
throws org.apache.derby.iapi.error.StandardException
- Convert this IN/ANY subquery, which is known to return at most 1 row,
to an equivalent expression subquery.
setDataTypeServices
private void setDataTypeServices(ResultColumnList resultColumns) throws org.apache.derby.iapi.error.StandardException
|
|||||||||
| Home >> All >> org >> apache >> derby >> impl >> sql >> [ compile overview ] | PREV CLASS NEXT CLASS | ||||||||
SUMMARY: JAVADOC | SOURCE | DOWNLOAD | NESTED | FIELD | CONSTR | METHOD |
DETAIL: FIELD | CONSTR | METHOD | ||||||||
JAVADOC