Search in sources :

Example 16 with JBitSet

use of org.apache.derby.iapi.util.JBitSet in project derby by apache.

the class FromSubquery method extractSubquery.

/**
 * Extract out and return the subquery, with a PRN on top.
 * (See FromSubquery.preprocess() for more details.)
 *
 * @param numTables			The number of tables in the DML Statement
 *
 * @return ResultSetNode at top of extracted tree.
 *
 * @exception StandardException		Thrown on error
 */
ResultSetNode extractSubquery(int numTables) throws StandardException {
    JBitSet newJBS;
    ResultSetNode newPRN;
    newPRN = new ProjectRestrictNode(subquery, /* Child ResultSet */
    getResultColumns(), /* Projection */
    null, /* Restriction */
    null, /* Restriction as PredicateList */
    null, /* Subquerys in Projection */
    null, /* Subquerys in Restriction */
    tableProperties, getContextManager());
    /* Set up the PRN's referencedTableMap */
    newJBS = new JBitSet(numTables);
    newJBS.set(tableNumber);
    newPRN.setReferencedTableMap(newJBS);
    ((FromTable) newPRN).setTableNumber(tableNumber);
    return newPRN;
}
Also used : JBitSet(org.apache.derby.iapi.util.JBitSet)

Example 17 with JBitSet

use of org.apache.derby.iapi.util.JBitSet in project derby by apache.

the class FromVTI method legalJoinOrder.

/**
 * @see Optimizable#legalJoinOrder
 */
@Override
public boolean legalJoinOrder(JBitSet assignedTableMap) {
    /* In order to tell if this is a legal join order, we
		 * need to see if the assignedTableMap, ORed with the
		 * outer tables that we are correlated with, contains
		 * our dependency map.
		 */
    JBitSet tempBitSet = assignedTableMap;
    tempBitSet.or(correlationMap);
    /* Have all of our dependencies been satisified? */
    return tempBitSet.contains(dependencyMap);
}
Also used : JBitSet(org.apache.derby.iapi.util.JBitSet)

Example 18 with JBitSet

use of org.apache.derby.iapi.util.JBitSet in project derby by apache.

the class FromVTI method preprocess.

/**
 * Preprocess a ResultSetNode - this currently means:
 *	o  Generating a referenced table map for each ResultSetNode.
 *  o  Putting the WHERE and HAVING clauses in conjunctive normal form (CNF).
 *  o  Converting the WHERE and HAVING clauses into PredicateLists and
 *	   classifying them.
 *  o  Ensuring that a ProjectRestrictNode is generated on top of every
 *     FromBaseTable and generated in place of every FromSubquery.
 *  o  Pushing single table predicates down to the new ProjectRestrictNodes.
 *
 * @param numTables			The number of tables in the DML Statement
 * @param gbl				The group by list, if any
 * @param fromList			The from list, if any
 *
 * @return ResultSetNode at top of preprocessed tree.
 *
 * @exception StandardException		Thrown on error
 */
@Override
ResultSetNode preprocess(int numTables, GroupByList gbl, FromList fromList) throws StandardException {
    methodCall.preprocess(numTables, new FromList(getOptimizerFactory().doJoinOrderOptimization(), getContextManager()), new SubqueryList(getContextManager()), new PredicateList(getContextManager()));
    /* Generate the referenced table map */
    setReferencedTableMap(new JBitSet(numTables));
    getReferencedTableMap().set(tableNumber);
    /* Create the dependency map.  This FromVTI depends on any
		 * tables which are referenced by the method call.  Note,
		 * though, that such tables should NOT appear in this node's
		 * referencedTableMap, since that field is really meant to
		 * hold the table numbers for any FromTables which appear
		 * AT OR UNDER the subtree whose root is this FromVTI.  That
		 * said, the tables referenced by methodCall do not appear
		 * "under" this FromVTI--on the contrary, they must appear
		 * "above" this FromVTI within the query tree in order to
		 * be referenced by the methodCall.  So methodCall table
		 * references do _not_ belong in this.referencedTableMap.
		 * (DERBY-3288)
		 */
    dependencyMap = new JBitSet(numTables);
    methodCall.categorize(dependencyMap, false);
    // Make sure this FromVTI does not "depend" on itself.
    dependencyMap.clear(tableNumber);
    // Get a JBitSet of the outer tables represented in the parameter list
    correlationMap = new JBitSet(numTables);
    methodCall.getCorrelationTables(correlationMap);
    return genProjectRestrict(numTables);
}
Also used : OptimizablePredicateList(org.apache.derby.iapi.sql.compile.OptimizablePredicateList) JBitSet(org.apache.derby.iapi.util.JBitSet)

Example 19 with JBitSet

use of org.apache.derby.iapi.util.JBitSet in project derby by apache.

the class HalfOuterJoinNode method transformOuterJoins.

/**
 * Transform any Outer Join into an Inner Join where applicable.
 * (Based on the existence of a null intolerant
 * predicate on the inner table.)
 *
 * @param predicateTree	The predicate tree for the query block
 *
 * @return The new tree top (OuterJoin or InnerJoin).
 *
 * @exception StandardException		Thrown on error
 */
@Override
FromTable transformOuterJoins(ValueNode predicateTree, int numTables) throws StandardException {
    ResultSetNode innerRS;
    if (predicateTree == null) {
        /* We can't transform this node, so tell both sides of the 
			 * outer join that they can't get flattened into outer query block.
			 */
        leftResultSet.notFlattenableJoin();
        rightResultSet.notFlattenableJoin();
        return this;
    }
    super.transformOuterJoins(predicateTree, numTables);
    if (rightOuterJoin) {
        if (SanityManager.DEBUG) {
            SanityManager.ASSERT(!transformed, "right OJ not expected to be transformed into left OJ yet");
        }
        innerRS = leftResultSet;
    } else {
        innerRS = rightResultSet;
    }
    // We a relooking for a null intolerant predicate on an inner table.
    // Collect base table numbers, also if they are located inside a join
    // (inner or outer), that is, the inner operand is itself a join,
    // recursively.
    JBitSet innerMap = innerRS.LOJgetReferencedTables(numTables);
    /* Walk predicates looking for 
		 * a null intolerant predicate on the inner table.
		 */
    ValueNode vn = predicateTree;
    while (vn instanceof AndNode) {
        AndNode and = (AndNode) vn;
        ValueNode left = and.getLeftOperand();
        /* Skip IS NULL predicates as they are not null intolerant */
        if (left.getClass().equals(IsNullNode.class) && ((IsNullNode) left).isNullNode()) {
            vn = and.getRightOperand();
            continue;
        }
        /* Only consider predicates that are relops */
        if (left instanceof RelationalOperator) {
            JBitSet refMap = new JBitSet(numTables);
            /* Do not consider method calls, 
				 * conditionals, field references, etc. */
            if (!(left.categorize(refMap, true))) {
                vn = and.getRightOperand();
                continue;
            }
            /* If the predicate is a null intolerant predicate
				 * on the right side then we can flatten to an
				 * inner join.  We do the xform here, flattening
				 * will happen later.
				 */
            for (int bit = 0; bit < numTables; bit++) {
                if (refMap.get(bit) && innerMap.get(bit)) {
                    // OJ -> IJ
                    JoinNode ij = new JoinNode(leftResultSet, rightResultSet, joinClause, null, getResultColumns(), null, null, getContextManager());
                    ij.setTableNumber(tableNumber);
                    ij.setSubqueryList(subqueryList);
                    ij.setAggregates(aggregates);
                    return ij;
                }
            }
        }
        vn = and.getRightOperand();
    }
    /* We can't transform this node, so tell both sides of the 
		 * outer join that they can't get flattened into outer query block.
		 */
    leftResultSet.notFlattenableJoin();
    rightResultSet.notFlattenableJoin();
    return this;
}
Also used : JBitSet(org.apache.derby.iapi.util.JBitSet)

Example 20 with JBitSet

use of org.apache.derby.iapi.util.JBitSet in project derby by apache.

the class HalfOuterJoinNode method LOJ_reorderable.

/**
 * This method recursively:
 * <ul>
 *    <li>determines if this part of the query tree is a compound OJ of
 *            the shape required for reordering and if so,</li>
 *    <li>does a reordering.</li>
 * </ul>
 * <pre>
 *
 *    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.
 * <p/>
 * OJ1 represents <em>this</em> before and after the reordering.
 * </pre>
 * <p/>
 * The join predicates are assumed to be in CNF form.
 * <p/>
 * <em>Note:</em> Present implementation limitations
 * <ul>
 *   <li>Only left outer joins are considered, i.e. both OJs in diagram
 *       above must be LOJ.</li>
 *   <li>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.</li>
 * </ul>
 *
 * @param numTables number of tables involved (needed to right size the
 *                  bitmaps)
 * @return 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
 */
@Override
boolean LOJ_reorderable(int numTables) throws StandardException {
    boolean anyChange = false;
    // row-preserving side
    ResultSetNode logicalLeftResultSet;
    // null-producing side
    ResultSetNode logicalRightResultSet;
    // null-producing side.
    if (rightOuterJoin) {
        // right outer join
        logicalLeftResultSet = rightResultSet;
        logicalRightResultSet = leftResultSet;
    } else {
        logicalLeftResultSet = leftResultSet;
        logicalRightResultSet = rightResultSet;
    }
    // Redundantly normalize the ON predicate (it will also be called in preprocess()).
    super.normExpressions();
    // This is a very simple OJ of base tables. Do nothing.
    if (logicalLeftResultSet instanceof FromBaseTable && logicalRightResultSet instanceof FromBaseTable)
        return anyChange;
    // table references need to be recomputed.
    if (logicalLeftResultSet instanceof HalfOuterJoinNode) {
        anyChange = ((HalfOuterJoinNode) logicalLeftResultSet).LOJ_reorderable(numTables) || anyChange;
    } else if (!(logicalLeftResultSet instanceof FromBaseTable)) {
        // select * from v8 left outer join (s left outer join r on (f = i)) on (e=v8.bv);
        return anyChange;
    }
    if (logicalRightResultSet instanceof HalfOuterJoinNode) {
        anyChange = ((HalfOuterJoinNode) logicalRightResultSet).LOJ_reorderable(numTables) || anyChange;
    } else if (!(logicalRightResultSet instanceof FromBaseTable)) {
        // right operand must be either a base table or another OJ
        return anyChange;
    }
    // into LOJ alread.  So, we skip optimizing ROJ at the moment.
    if (rightOuterJoin || (logicalRightResultSet instanceof HalfOuterJoinNode && ((HalfOuterJoinNode) logicalRightResultSet).rightOuterJoin)) {
        return LOJ_bindResultColumns(anyChange);
    }
    // Build the data structure for testing/doing OJ reordering.  Fill in
    // the table references on row-preserving and null-producing sides.  It
    // may be possible that either operand is a complex view.
    // Row-preserving
    JBitSet RPReferencedTableMap;
    // Null-producing
    JBitSet NPReferencedTableMap;
    RPReferencedTableMap = logicalLeftResultSet.LOJgetReferencedTables(numTables);
    NPReferencedTableMap = logicalRightResultSet.LOJgetReferencedTables(numTables);
    if ((RPReferencedTableMap == null || NPReferencedTableMap == null) && anyChange) {
        return LOJ_bindResultColumns(anyChange);
    }
    // to push the join.
    if (logicalRightResultSet instanceof HalfOuterJoinNode) {
        // Get the row-preserving map of the  child OJ
        JBitSet nestedChildOJRPRefTableMap = ((HalfOuterJoinNode) logicalRightResultSet).LOJgetRPReferencedTables(numTables);
        // Checks that top has p(t1,t2)
        if (!isNullRejecting(joinClause, RPReferencedTableMap, nestedChildOJRPRefTableMap)) {
            // No, give up.
            return LOJ_bindResultColumns(anyChange);
        }
        // Get the null-producing map of the child OJ
        JBitSet nestedChildOJNPRefTableMap = ((HalfOuterJoinNode) logicalRightResultSet).LOJgetNPReferencedTables(numTables);
        // Checks that right child has p(t2,t3)
        if (isNullRejecting(((HalfOuterJoinNode) logicalRightResultSet).joinClause, nestedChildOJRPRefTableMap, nestedChildOJNPRefTableMap)) {
            // before we proceed.
            if (super.subqueryList.size() != 0 || ((JoinNode) logicalRightResultSet).subqueryList.size() != 0 || super.joinPredicates.size() != 0 || ((JoinNode) logicalRightResultSet).joinPredicates.size() != 0 || super.usingClause != null || ((JoinNode) logicalRightResultSet).usingClause != null) {
                // get out of here
                return LOJ_bindResultColumns(anyChange);
            }
            // we are reordering the OJs.
            anyChange = true;
            ResultSetNode tmp = logicalLeftResultSet;
            ResultSetNode LChild, RChild;
            // this OJ
            // /      \
            // logicalLeftRS   LogicalRightRS
            // /     \
            // LChild  RChild
            // becomes
            // 
            // this OJ
            // /      \
            // LogicalRightRS   RChild
            // /     \
            // logicalLeftRS LChild <<< we need to be careful about this
            // order as the "LogicalRightRS
            // may be a ROJ
            // 
            // handle the lower level OJ node
            LChild = ((HalfOuterJoinNode) logicalRightResultSet).leftResultSet;
            RChild = ((HalfOuterJoinNode) logicalRightResultSet).rightResultSet;
            ((HalfOuterJoinNode) logicalRightResultSet).rightResultSet = LChild;
            ((HalfOuterJoinNode) logicalRightResultSet).leftResultSet = tmp;
            // switch the ON clause
            {
                ValueNode vn = joinClause;
                joinClause = ((HalfOuterJoinNode) logicalRightResultSet).joinClause;
                ((HalfOuterJoinNode) logicalRightResultSet).joinClause = vn;
            }
            // No need to switch HalfOuterJoinNode data members for now
            // because we are handling only OJ.
            // boolean local_rightOuterJoin = rightOuterJoin;
            // boolean local_transformed    = transformed;
            // rightOuterJoin = ((HalfOuterJoinNode)logicalRightResultSet).
            // rightOuterJoin;
            // transformed = ((HalfOuterJoinNode)logicalRightResultSet).
            // transformed;
            // ((HalfOuterJoinNode)logicalRightResultSet).rightOuterJoin =
            // local_rightOuterJoin;
            // ((HalfOuterJoinNode)logicalRightResultSet).transformed =
            // local_transformed;
            FromList localFromList = new FromList(getOptimizerFactory().doJoinOrderOptimization(), getContextManager());
            // switch OJ nodes: by handling the current OJ node
            leftResultSet = logicalRightResultSet;
            rightResultSet = RChild;
            // rebuild the result columns and re-bind column references
            ((HalfOuterJoinNode) leftResultSet).setResultColumns(null);
            // localFromList is empty:
            ((JoinNode) leftResultSet).bindResultColumns(localFromList);
            // left operand must be another OJ, so recurse.
            boolean localChange = ((HalfOuterJoinNode) leftResultSet).LOJ_reorderable(numTables);
        }
    }
    return LOJ_bindResultColumns(anyChange);
}
Also used : JBitSet(org.apache.derby.iapi.util.JBitSet)

Aggregations

JBitSet (org.apache.derby.iapi.util.JBitSet)39 OptimizablePredicate (org.apache.derby.iapi.sql.compile.OptimizablePredicate)12 OptimizablePredicateList (org.apache.derby.iapi.sql.compile.OptimizablePredicateList)7 Optimizable (org.apache.derby.iapi.sql.compile.Optimizable)2 ConglomerateDescriptor (org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor)2 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 IndexDescriptor (org.apache.derby.catalog.IndexDescriptor)1 ContextManager (org.apache.derby.iapi.services.context.ContextManager)1 FormatableBitSet (org.apache.derby.iapi.services.io.FormatableBitSet)1 CostEstimate (org.apache.derby.iapi.sql.compile.CostEstimate)1 DataValueDescriptor (org.apache.derby.iapi.types.DataValueDescriptor)1 StandardException (org.apache.derby.shared.common.error.StandardException)1