Class HalfOuterJoinNode

  • All Implemented Interfaces:
    Optimizable, Visitable

    class HalfOuterJoinNode
    extends JoinNode
    An HalfOuterJoinNode represents a left or a right outer join result set. Right outer joins are always transformed into left outer joins during preprocessing for simplicity.
    • Field Detail

      • rightOuterJoin

        private boolean rightOuterJoin
      • transformed

        private boolean transformed
    • Constructor Detail

      • HalfOuterJoinNode

        HalfOuterJoinNode​(ResultSetNode leftResult,
                          ResultSetNode rightResult,
                          ValueNode onClause,
                          ResultColumnList usingClause,
                          boolean rightOuterJoin,
                          java.util.Properties tableProperties,
                          ContextManager cm)
                   throws StandardException
        Constructor for a HalfOuterJoinNode.
        Parameters:
        leftResult - The ResultSetNode on the left side of this join
        rightResult - The ResultSetNode on the right side of this join
        onClause - The ON clause
        usingClause - The USING clause
        rightOuterJoin - Whether or not this node represents a user specified right outer join
        tableProperties - Properties list associated with the table
        cm - The context manager
        Throws:
        StandardException - Thrown on error
    • Method Detail

      • 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 class TableOperatorNode
        Returns:
        This object as a String
      • 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 class JoinNode
        Parameters:
        numTables - Number of tables in the DML Statement
        gbl - The group by list, if any
        fromList - The from list, if any
        Returns:
        The generated ProjectRestrictNode atop the original FromTable.
        Throws:
        StandardException - Thrown on error
      • pushExpressions

        void pushExpressions​(PredicateList outerPredicateList)
                      throws StandardException
        Push expressions down to the first ResultSetNode which can do expression evaluation and has the same referenced table map. RESOLVE - This means only pushing down single table expressions to DistinctNodes today. Once we have a better understanding of how the optimizer will work, we can push down join clauses.
        Overrides:
        pushExpressions in class JoinNode
        Parameters:
        outerPredicateList - The PredicateList from the outer RS.
        Throws:
        StandardException - Thrown on error
      • LOJ_reorderable

        boolean LOJ_reorderable​(int numTables)
                         throws StandardException
        This method recursively:
        • determines if this part of the query tree is a compound OJ of the shape required for reordering and if so,
        • does a reordering.
        
            OJ1  pT1T2                      OJ1  pT2T3
           /  \                             / \
          /    \                 can       /   t3
         t1    OJ2 pT2T3       reorder    /
               /  \              to      OJ2  pT1T2
              /    \                    /   \
             t2    t3                  /     \
                                     t1     t2
        
         where pR1R2 is a null-rejecting predicate which references the schema
         of joinee R1 and R2, cf. terminology explanation in #isNullRejecting.
         

        OJ1 represents this before and after the reordering.

        The join predicates are assumed to be in CNF form.

        Note: Present implementation limitations

        • Only left outer joins are considered, i.e. both OJs in diagram above must be LOJ.
        • Top left side must be a base table (t1 above). The bottow right side (t3 above) may be another OJ, so reordering can happen recursively.
        Overrides:
        LOJ_reorderable in class JoinNode
        Parameters:
        numTables - number of tables involved (needed to right size the bitmaps)
        Returns:
        boolean true if any reordering took place at this level or deeper so caller can know whether rebinding may be necessary
        Throws:
        StandardException - standard error policy
      • isNullRejecting

        private boolean isNullRejecting​(ValueNode joinClause,
                                        JBitSet leftTableMap,
                                        JBitSet rightTableMap)
                                 throws StandardException
        Tests pRiRj in the sense of Galindo-Legaria et al: Outerjoin Simplification and Reordering for Query Optimization, ACM Transactions on Database Systems, Vol. 22, No. 1, March 1997, Pages 43-74: "The set of attributes referenced by a predicate p is called the schema of p, and denoted sch(p). As a notational convention, we annotate predicates to reflect their schema. If sch(p) includes attributes of both Ri, Rj and only those relations, we can write the predicate as pRiRj. If a null-valued column is compared in a predicate that contains no OR connectives, the predicate evaluates to undefined, and the tuple is rejected. The relops satisfy this criterion.

        To simplify analysis, we only accept predicates of the form:

         X relop Y [and .. and X-n relop Y-n]
         
        At least one of the relops should reference both leftTableMap and rightTableMap, so that we know that sch(p) includes attributes of both Ri, Rj. I.e.

        X should be a table in leftTableMap, and Y should be a table in rightTableMap.

        or X should be a table in rightTableMap, and Y should be a table in leftTableMap.

        Parameters:
        joinClause - The join clause (i.e. predicate) we want to check
        leftTableMap - a bit map representing the tables expected for the predicate (logical left)
        rightTableMap - a bit map representing the tables expected for the predicate (logical right)
        Returns:
        true if the joinClause has at least one relop that references both leftTableMap and rightTableMap
        Throws:
        StandardException - standard exception policy
      • transformOuterJoins

        FromTable transformOuterJoins​(ValueNode predicateTree,
                                      int numTables)
                               throws StandardException
        Transform any Outer Join into an Inner Join where applicable. (Based on the existence of a null intolerant predicate on the inner table.)
        Overrides:
        transformOuterJoins in class JoinNode
        Parameters:
        predicateTree - The predicate tree for the query block
        Returns:
        The new tree top (OuterJoin or InnerJoin).
        Throws:
        StandardException - Thrown on error
      • addOuterJoinArguments

        int addOuterJoinArguments​(ActivationClassBuilder acb,
                                  MethodBuilder mb)
                           throws StandardException
        Generate and add any arguments specifict to outer joins. Generate the methods (and add them as parameters) for returning an empty row from 1 or more sides of an outer join, if required. Pass whether or not this was originally a right outer join.
        Overrides:
        addOuterJoinArguments in class JoinNode
        Parameters:
        acb - The ActivationClassBuilder
        mb - the method the generate code is to go into return The args that have been added
        Throws:
        StandardException - Thrown on error
      • getNumJoinArguments

        protected int getNumJoinArguments()
        Return the number of arguments to the join result set.
        Overrides:
        getNumJoinArguments in class JoinNode
      • getLogicalLeftResultSet

        ResultSetNode getLogicalLeftResultSet()
        Return the logical left result set for this qualified join node. (For RIGHT OUTER JOIN, the left is the right and the right is the left and the JOIN is the NIOJ).
        Overrides:
        getLogicalLeftResultSet in class JoinNode
      • getLogicalRightResultSet

        ResultSetNode getLogicalRightResultSet()
        Return the logical right result set for this qualified join node. (For RIGHT OUTER JOIN, the left is the right and the right is the left and the JOIN is the NIOJ).
        Overrides:
        getLogicalRightResultSet in class JoinNode
      • isRightOuterJoin

        boolean isRightOuterJoin()
        Return true if right outer join or false if left outer join Used to set Nullability correctly in JoinNode