Class JoinNode

All Implemented Interfaces:
Optimizable, Visitable
Direct Known Subclasses:
HalfOuterJoinNode

class JoinNode extends TableOperatorNode
A JoinNode represents a join result set for either of the basic DML operations: SELECT and INSERT. For INSERT - SELECT, any of the fields in a JoinNode can be used (the JoinNode represents the (join) SELECT statement in the INSERT - SELECT). For INSERT, the resultColumns in the selectList will contain the names of the columns being inserted into or updated.
  • Field Details

  • Constructor Details

    • JoinNode

      JoinNode(ResultSetNode leftResult, ResultSetNode rightResult, ValueNode onClause, ResultColumnList usingClause, ResultColumnList selectList, Properties tableProperties, Properties joinOrderStrategyProperties, ContextManager cm) throws StandardException
      Constructor for a JoinNode.
      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
      selectList - The result column list for the join
      tableProperties - Properties list associated with the table
      joinOrderStrategyProperties - User provided optimizer overrides
      cm - The context manager
      Throws:
      StandardException - Thrown on error
  • Method Details

    • optimizeIt

      public CostEstimate optimizeIt(Optimizer optimizer, OptimizablePredicateList predList, CostEstimate outerCost, RowOrdering rowOrdering) throws StandardException
      Description copied from interface: Optimizable
      Choose the best access path for this Optimizable.
      Specified by:
      optimizeIt in interface Optimizable
      Overrides:
      optimizeIt in class FromTable
      Parameters:
      optimizer - Optimizer to use.
      predList - The predicate list to optimize against
      outerCost - The CostEstimate for the outer tables in the join order, telling how many times this Optimizable will be scanned.
      rowOrdering - The row ordering for all the tables in the join order, including this one.
      Returns:
      The optimizer's estimated cost of the best access path.
      Throws:
      StandardException - Thrown on error
      See Also:
    • 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 interface Optimizable
      Overrides:
      pushOptPredicate in class FromTable
      Parameters:
      optimizablePredicate - OptimizablePredicate to push down.
      Returns:
      Whether or not the predicate was pushed down.
      Throws:
      StandardException - Thrown on error
      See Also:
    • modifyAccessPath

      public Optimizable modifyAccessPath(JBitSet outerTables) throws StandardException
      Description copied from interface: Optimizable
      Modify the access path for this Optimizable, as necessary. This includes things like adding a result set to translate from index rows to base rows
      Specified by:
      modifyAccessPath in interface Optimizable
      Overrides:
      modifyAccessPath in class TableOperatorNode
      Parameters:
      outerTables - Bit map of the tables that are outer to this one in the join order.
      Returns:
      The (potentially new) Optimizable at the top of the tree.
      Throws:
      StandardException - Thrown on error
      See Also:
    • adjustNumberOfRowsReturned

      protected void adjustNumberOfRowsReturned(CostEstimate costEstimate)
      Some types of joins (e.g. outer joins) will return a different number of rows than is predicted by optimizeIt() in JoinNode. So, adjust this value now. This method does nothing for most join types.
    • getAllResultColumns

      ResultColumnList getAllResultColumns(TableName allTableName) throws StandardException
      Return a ResultColumnList with all of the columns in this table. (Used in expanding '*'s.) NOTE: Since this method is for expanding a "*" in the SELECT list, ResultColumn.expression will be a ColumnReference.
      Overrides:
      getAllResultColumns in class ResultSetNode
      Parameters:
      allTableName - The qualifier on the "*"
      Returns:
      ResultColumnList List of result columns from this table.
      Throws:
      StandardException - Thrown on error
    • getAllResultColumnsNoUsing

      private ResultColumnList getAllResultColumnsNoUsing(TableName allTableName) throws StandardException
      Return a ResultColumnList with all of the columns in this table. (Used in expanding '*'s.) NOTE: Since this method is for expanding a "*" in the SELECT list, ResultColumn.expression will be a ColumnReference. NOTE: This method is handles the case when there is no USING clause. The caller handles the case when there is a USING clause.
      Parameters:
      allTableName - The qualifier on the "*"
      Returns:
      ResultColumnList List of result columns from this table.
      Throws:
      StandardException - Thrown on error
    • getMatchingColumn

      ResultColumn getMatchingColumn(ColumnReference columnReference) throws StandardException
      Try to find a ResultColumn in the table represented by this FromTable that matches the name in the given ColumnReference.
      Overrides:
      getMatchingColumn in class ResultSetNode
      Parameters:
      columnReference - The columnReference whose name we're looking for in the given table.
      Returns:
      A ResultColumn whose expression is the ColumnNode that matches the ColumnReference. Returns null if there is no match.
      Throws:
      StandardException - Thrown on error
    • bindExpressions

      public void bindExpressions(FromList fromListParam) throws StandardException
      Bind the expressions under this node.
      Overrides:
      bindExpressions in class TableOperatorNode
      Parameters:
      fromListParam - FromList to use/append to.
      Throws:
      StandardException - Thrown on error
    • 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 class TableOperatorNode
      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 class TableOperatorNode
      Parameters:
      targetTableDescriptor - The TableDescriptor for the table being updated or inserted into
      targetColumnList - 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 RCLs up from the children and splice them to form this node's RCL.
      Throws:
      StandardException - Thrown on error
    • deferredBindExpressions

      private void deferredBindExpressions(FromList fromListParam) throws StandardException
      Throws:
      StandardException
    • bindExpression

      public ValueNode bindExpression(ValueNode expression, boolean useLeftChild, boolean useRightChild, String expressionType) throws StandardException
      Bind an expression against the child tables of the JoinNode. May update the subquery and aggregate lists in the JoinNode. Assumes that the subquery and aggregate lists for the JoinNode have already been created.
      Returns:
      the bound expression
      Throws:
      StandardException
    • makeFromList

      public FromList makeFromList(boolean useLeftChild, boolean useRightChild) throws StandardException
      Make a FromList for binding
      Throws:
      StandardException
    • getCommonColumnsForNaturalJoin

      private ResultColumnList getCommonColumnsForNaturalJoin() throws StandardException
      Generate a result column list with all the column names that appear on both sides of the join operator. Those are the columns to use as join columns in a natural join.
      Returns:
      RCL with all the common columns
      Throws:
      StandardException - on error
    • extractColumnNames

      private static List<String> extractColumnNames(ResultColumnList rcl)
      Extract all the column names from a result column list.
      Parameters:
      rcl - the result column list to extract the names from
      Returns:
      a list of all the column names in the RCL
    • 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 TableOperatorNode
      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
    • projectResultColumns

      void projectResultColumns() throws StandardException
      Find the unreferenced result columns and project them out. This is used in pre-processing joins that are not flattened into the where clause.
      Overrides:
      projectResultColumns in class TableOperatorNode
      Throws:
      StandardException
    • normExpressions

      void normExpressions() throws StandardException
      Put the expression trees in conjunctive normal form
      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 FromTable
      Parameters:
      outerPredicateList - The PredicateList from the outer RS.
      Throws:
      StandardException - Thrown on error
    • pushExpressionsToLeft

      protected void pushExpressionsToLeft(PredicateList outerPredicateList) throws StandardException
      Throws:
      StandardException
    • pushExpressionsToRight

      private void pushExpressionsToRight(PredicateList outerPredicateList) throws StandardException
      Throws:
      StandardException
    • grabJoinPredicates

      private void grabJoinPredicates(PredicateList outerPredicateList) throws StandardException
      Throws:
      StandardException
    • flatten

      FromList flatten(ResultColumnList rcl, PredicateList outerPList, SubqueryList sql, GroupByList gbl, ValueNode havingClause) throws StandardException
      Flatten this JoinNode into the outer query block. The steps in flattening are: o Mark all ResultColumns as redundant, so that they are "skipped over" at generate(). o Append the joinPredicates to the outer list. o Create a FromList from the tables being joined and return that list so that the caller will merge the 2 lists
      Overrides:
      flatten in class FromTable
      Parameters:
      rcl - The RCL from the outer query
      outerPList - PredicateList to append wherePredicates to.
      sql - The SubqueryList from the outer query
      gbl - The group by list, if any
      havingClause - The HAVING clause, if any
      Returns:
      FromList The fromList from the underlying SelectNode.
      Throws:
      StandardException - Thrown on error
    • LOJ_reorderable

      boolean LOJ_reorderable(int numTables) throws StandardException
      Currently we don't reordering any outer join w/ inner joins.
      Overrides:
      LOJ_reorderable in class FromTable
      Throws:
      StandardException
    • 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 FromTable
      Parameters:
      predicateTree - The predicate tree for the query block
      Returns:
      The new tree top (OuterJoin or InnerJoin).
      Throws:
      StandardException - Thrown on error
    • generate

      void generate(ActivationClassBuilder acb, MethodBuilder mb) throws StandardException
      For joins, the tree will be (nodes are left out if the clauses are empty): ProjectRestrictResultSet -- for the having and the select list SortResultSet -- for the group by list ProjectRestrictResultSet -- for the where and the select list (if no group or having) the result set for the fromList
      Overrides:
      generate in class QueryTreeNode
      Parameters:
      acb - The ActivationClassBuilder for the class being built
      mb - The method for the generated code to go into
      Throws:
      StandardException - Thrown on error
    • generateCore

      void generateCore(ActivationClassBuilder acb, MethodBuilder mb, int joinType) throws StandardException
      Generate the code for a qualified join node.
      Throws:
      StandardException - Thrown on error
    • generateCore

      void generateCore(ActivationClassBuilder acb, MethodBuilder mb, int joinType, ValueNode joinClause, SubqueryList subquerys) throws StandardException
      Do the generation work for the join node hierarchy.
      Parameters:
      acb - The ActivationClassBuilder
      mb - the method the code is to go into
      joinType - The join type
      joinClause - The join clause, if any
      subquerys - The list of subqueries in the join clause, if any
      Throws:
      StandardException - Thrown on error
    • getJoinArguments

      private int getJoinArguments(ActivationClassBuilder acb, MethodBuilder mb, ValueNode joinClause) throws StandardException
      Get the arguments to the join result set.
      Parameters:
      acb - The ActivationClassBuilder for the class we're building.
      mb - the method the generated code is going into
      joinClause - The join clause, if any
      Returns:
      The array of arguments to the join result set
      Throws:
      StandardException - Thrown on error
    • getFinalCostEstimate

      CostEstimate getFinalCostEstimate() throws StandardException
      Description copied from class: FromTable
      Get the final CostEstimate for this FromTable.
      Overrides:
      getFinalCostEstimate in class FromTable
      Returns:
      The final CostEstimate for this JoinNode, which is sum the costs for the inner and outer table. The number of rows, though, is that for the inner table only.
      Throws:
      StandardException
      See Also:
    • oneRowRightSide

      void oneRowRightSide(ActivationClassBuilder acb, MethodBuilder mb) throws StandardException
      Throws:
      StandardException
    • getNumJoinArguments

      protected int getNumJoinArguments()
      Return the number of arguments to the join result set. This will be overridden for other types of joins (for example, outer joins).
    • addOuterJoinArguments

      int addOuterJoinArguments(ActivationClassBuilder acb, MethodBuilder mb) throws StandardException
      Generate and add any arguments specifict to outer joins. (Expected to be overriden, where appropriate, in subclasses.)
      Parameters:
      acb - The ActivationClassBuilder
      mb - the method the generated code is to go into return The number of args added
      Throws:
      StandardException - Thrown on error
    • joinTypeToString

      static String joinTypeToString(int joinType)
      Convert the joinType to a string.
      Parameters:
      joinType - The joinType as an int.
      Returns:
      String The joinType as a String.
    • getLeftPredicateList

      protected PredicateList getLeftPredicateList() throws StandardException
      Throws:
      StandardException
    • getRightPredicateList

      protected PredicateList getRightPredicateList() throws StandardException
      Throws:
      StandardException
    • updateTargetLockMode

      int updateTargetLockMode()
      Get the lock mode for the target of an update statement (a delete or update). The update mode will always be row for CurrentOfNodes. It will be table if there is no where clause.
      Overrides:
      updateTargetLockMode in class ResultSetNode
      Returns:
      The lock mode
      See Also:
    • notFlattenableJoin

      void notFlattenableJoin()
      Mark this node and its children as not being a flattenable join.
      Overrides:
      notFlattenableJoin in class ResultSetNode
    • isFlattenableJoinNode

      boolean isFlattenableJoinNode()
      Is this FromTable a JoinNode which can be flattened into the parents FromList.
      Overrides:
      isFlattenableJoinNode in class FromTable
      Returns:
      boolean Whether or not this FromTable can be flattened.
    • isOrderedOn

      boolean isOrderedOn(ColumnReference[] crs, boolean permuteOrdering, List<FromBaseTable> fbtHolder) throws StandardException
      Return whether or not the underlying ResultSet tree is ordered on the specified columns. RESOLVE - This method currently only considers the outermost table of the query block.
      Overrides:
      isOrderedOn in class ResultSetNode
      Parameters:
      crs - The specified ColumnReference[]
      permuteOrdering - Whether or not the order of the CRs in the array can be permuted
      fbtHolder - List that is to be filled with the FromBaseTable
      Returns:
      Whether the underlying ResultSet tree is ordered on the specified column.
      Throws:
      StandardException - Thrown 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 class TableOperatorNode
      Parameters:
      depth - The depth of this node in the tree
    • setSubqueryList

      void setSubqueryList(SubqueryList subqueryList)
    • setAggregates

      void setAggregates(List<AggregateNode> aggregates)
    • setNaturalJoin

      void setNaturalJoin()
      Flag this as a natural join so that an implicit USING clause will be generated in the bind phase.
    • 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).
    • 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).
    • acceptChildren

      void acceptChildren(Visitor v) throws StandardException
      Accept the visitor for all visitable children of this node.
      Overrides:
      acceptChildren in class TableOperatorNode
      Parameters:
      v - the visitor
      Throws:
      StandardException - on error
    • LOJgetReferencedTables

      JBitSet LOJgetReferencedTables(int numTables) throws StandardException
      Overrides:
      LOJgetReferencedTables in class ResultSetNode
      Throws:
      StandardException