Search in sources :

Example 11 with JBitSet

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

the class JoinNode method grabJoinPredicates.

private void grabJoinPredicates(PredicateList outerPredicateList) throws StandardException {
    FromTable leftFromTable = (FromTable) leftResultSet;
    FromTable rightFromTable = (FromTable) rightResultSet;
    JBitSet leftReferencedTableMap = leftFromTable.getReferencedTableMap();
    JBitSet rightReferencedTableMap = rightFromTable.getReferencedTableMap();
    // Walk outerPredicateList backwards due to possible deletes
    for (int index = outerPredicateList.size() - 1; index >= 0; index--) {
        Predicate predicate = outerPredicateList.elementAt(index);
        if (!predicate.getPushable()) {
            continue;
        }
        JBitSet curBitSet = predicate.getReferencedSet();
        /* Do we have a match? */
        JBitSet innerBitSet = (JBitSet) rightReferencedTableMap.clone();
        innerBitSet.or(leftReferencedTableMap);
        if (innerBitSet.contains(curBitSet)) {
            /* Add the matching predicate to the push list */
            joinPredicates.addPredicate(predicate);
            /* Remap all of the ColumnReferences to point to the
				 * source of the values.
				 * The tree is something like:
				 *			PRN1
				 *			  |
				 *			 JN (this)
				 *		   /    \
				 *		PRN2	PRN3
				 *        |       |
				 *		FBT1	FBT2
				 *
				 * The ColumnReferences start off pointing to the RCL off of
				 * PRN1.  For optimization, we want them to point to the
				 * RCL off of PRN2 or PRN3.  In order to do that, we remap them
				 * twice here.  If optimization pushes them down to the
				 * base table, it will remap them again.
				 */
            RemapCRsVisitor rcrv = new RemapCRsVisitor(true);
            predicate.getAndNode().accept(rcrv);
            predicate.getAndNode().accept(rcrv);
            /* Remove the matching predicate from the outer list */
            outerPredicateList.removeElementAt(index);
        }
    }
}
Also used : JBitSet(org.apache.derby.iapi.util.JBitSet) OptimizablePredicate(org.apache.derby.iapi.sql.compile.OptimizablePredicate)

Example 12 with JBitSet

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

the class JoinNode method pushExpressionsToLeft.

protected void pushExpressionsToLeft(PredicateList outerPredicateList) throws StandardException {
    FromTable leftFromTable = (FromTable) leftResultSet;
    JBitSet leftReferencedTableMap = leftFromTable.getReferencedTableMap();
    // Walk outerPredicateList backwards due to possible deletes
    for (int index = outerPredicateList.size() - 1; index >= 0; index--) {
        Predicate predicate = outerPredicateList.elementAt(index);
        if (!predicate.getPushable()) {
            continue;
        }
        JBitSet curBitSet = predicate.getReferencedSet();
        /* Do we have a match? */
        if (leftReferencedTableMap.contains(curBitSet)) {
            /* Add the matching predicate to the push list */
            getLeftPredicateList().addPredicate(predicate);
            /* Remap all of the ColumnReferences to point to the
				 * source of the values.
				 * The tree is something like:
				 *			PRN1
				 *			  |
				 *			 JN (this)
				 *		   /    \
				 *		PRN2	PRN3
				 *        |       |
				 *		FBT1	FBT2
				 *
				 * The ColumnReferences start off pointing to the RCL off of
				 * PRN1.  For optimization, we want them to point to the
				 * RCL off of PRN2.  In order to do that, we remap them
				 * twice here.  If optimization pushes them down to the
				 * base table, it will remap them again.
				 */
            RemapCRsVisitor rcrv = new RemapCRsVisitor(true);
            predicate.getAndNode().accept(rcrv);
            predicate.getAndNode().accept(rcrv);
            /* Remove the matching predicate from the outer list */
            outerPredicateList.removeElementAt(index);
        }
    }
}
Also used : JBitSet(org.apache.derby.iapi.util.JBitSet) OptimizablePredicate(org.apache.derby.iapi.sql.compile.OptimizablePredicate)

Example 13 with JBitSet

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

the class SelectNode method preprocess.

/**
 * 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.
 *
 * @param numTables			The number of tables in the DML Statement
 * @param gbl				The outer group by list, if any
 * @param fl			The from list, if any
 *
 * @return The generated ProjectRestrictNode atop the original FromTable.
 *
 * @exception StandardException		Thrown on error
 */
@Override
ResultSetNode preprocess(int numTables, GroupByList gbl, FromList fl) throws StandardException {
    ResultSetNode newTop = this;
    /* Put the expression trees in conjunctive normal form.
		 * NOTE - This needs to occur before we preprocess the subqueries
		 * because the subquery transformations assume that any subquery operator 
		 * negation has already occurred.
		 */
    whereClause = normExpressions(whereClause);
    // DERBY-3257. We need to normalize the having clause as well, because
    // preProcess expects CNF.
    havingClause = normExpressions(havingClause);
    /**
     * This method determines if (1) the query is a LOJ, and (2) if the LOJ is a candidate for
     * reordering (i.e., linearization).  The condition for LOJ linearization is:
     * 1. either LOJ or ROJ in the fromList, i.e., no INNER, NO FULL JOINs
     * 2. ON clause must be equality join between left and right operands and in CNF (i.e., AND is allowed)
     */
    boolean anyChange = fromList.LOJ_reorderable(numTables);
    if (anyChange) {
        FromList afromList = new FromList(getOptimizerFactory().doJoinOrderOptimization(), getContextManager());
        bindExpressions(afromList);
        fromList.bindResultColumns(afromList);
    }
    /* Preprocess the fromList.  For each FromTable, if it is a FromSubquery
		 * then we will preprocess it, replacing the FromSubquery with a
		 * ProjectRestrictNode. If it is a FromBaseTable, then we will generate
		 * the ProjectRestrictNode above it.
		 */
    fromList.preprocess(numTables, groupByList, whereClause);
    /* selectSubquerys is always allocated at bind() time */
    if (SanityManager.DEBUG) {
        SanityManager.ASSERT(selectSubquerys != null, "selectSubquerys is expected to be non-null");
    }
    /* Preprocess the RCL after the from list so that
		 * we can flatten/optimize any subqueries in the
		 * select list.
		 */
    getResultColumns().preprocess(numTables, fromList, whereSubquerys, wherePredicates);
    /* Preprocess the expressions.  (This is necessary for subqueries.
		 * This is also where we do tranformations such as for LIKE.)
		 *
		 * NOTE: We do this after preprocessing the fromList so that, for
		 * quantified subqueries, the join expression with the outer
		 * expression will be pushable (to be pushable, the ColumnReference
		 * has to point to a VirtualColumnNode, and not to a BaseColumnNode).
		 */
    if (whereClause != null) {
        // WHERE EXISTS subqueries.
        if (whereSubquerys != null) {
            whereSubquerys.markWhereSubqueries();
        }
        whereClause = whereClause.preprocess(numTables, fromList, whereSubquerys, wherePredicates);
    }
    /* Preprocess the group by list too. We need to compare 
		 * expressions in the group by list with the select list and we 
		 * can't rewrite one and not the other.
		 */
    if (groupByList != null) {
        groupByList.preprocess(numTables, fromList, whereSubquerys, wherePredicates);
    }
    if (havingClause != null) {
        // DERBY-3257
        // Mark  subqueries that are part of the having clause as
        // such so we can avoid flattenning later. Having subqueries
        // cannot be flattened because we cannot currently handle
        // column references at the same source level.
        // DERBY-3257 required we normalize the having clause which
        // triggered flattening because SubqueryNode.underTopAndNode
        // became true after normalization.  We needed another way to
        // turn flattening off. Perhaps the long term solution is
        // to avoid this restriction all together but that was beyond
        // the scope of this bugfix.
        havingSubquerys.markHavingSubqueries();
        havingClause = havingClause.preprocess(numTables, fromList, havingSubquerys, wherePredicates);
    }
    /* Pull apart the expression trees */
    if (whereClause != null) {
        wherePredicates.pullExpressions(numTables, whereClause);
        whereClause = null;
    }
    /* RESOLVE - Where should we worry about expression pull up for
		 * expensive predicates?
		 */
    // Flatten any flattenable FromSubquerys or JoinNodes
    fromList.flattenFromTables(getResultColumns(), wherePredicates, whereSubquerys, groupByList, havingClause);
    if (wherePredicates != null && wherePredicates.size() > 0 && fromList.size() > 0) {
        // Perform various forms of transitive closure on wherePredicates
        if (fromList.size() > 1) {
            performTransitiveClosure(numTables);
        }
        for (int i = 0; i < qec.size(); i++) {
            final OrderByList obl = qec.getOrderByList(i);
            if (obl != null) {
                // Remove constant columns from order by list.  Constant
                // columns are ones that have equality comparisons with
                // constant expressions (e.g. x = 3)
                obl.removeConstantColumns(wherePredicates);
                /*
                     ** It's possible for the order by list to shrink to
                     ** nothing as a result of removing constant columns.  If
                     ** this happens, get rid of the list entirely.
                     */
                if (obl.size() == 0) {
                    qec.setOrderByList(i, null);
                    getResultColumns().removeOrderByColumns();
                }
            }
        }
    }
    /* A valid group by without any aggregates or a having clause
		 * is equivalent to a distinct without the group by.  We do the transformation
		 * in order to simplify the group by code.
		 */
    if (groupByList != null && havingClause == null && selectAggregates.isEmpty() && whereAggregates.isEmpty()) {
        isDistinct = true;
        groupByList = null;
        wasGroupBy = true;
    }
    /* Consider distinct elimination based on a uniqueness condition.
		 * In order to do this:
		 *	o  All top level ColumnReferences in the select list are
		 *	   from the same base table.  (select t1.c1, t2.c2 + t3.c3 is 
		 *	   okay - t1 is the table of interest.)
		 *  o  If the from list is a single table then the columns in the
		 *	   select list plus the columns in the where clause that are
		 *	   in = comparisons with constants or parameters must be a
		 *	   superset of any unique index.
		 *  o  If the from list has multiple tables then at least 1 table
		 *	   meet the following - the set of columns in = comparisons
		 *	   with constants or parameters is a superset of any unique
		 *	   index on the table.  All of the other tables must meet
		 *	   the following - the set of columns in = comparisons with
		 *	   constants, parameters or join columns is a superset of
		 *	   any unique index on the table.  If the table from which
		 *	   the columns in the select list are coming from is in this
		 *     later group then the rule for it is to also include
		 *     the columns in the select list in the set of columns that
		 *     needs to be a superset of the unique index.  Whew!
		 */
    if (isDistinct && groupByList == null) {
        int distinctTable = getResultColumns().allTopCRsFromSameTable();
        if (distinctTable != -1) {
            if (fromList.returnsAtMostSingleRow(getResultColumns(), whereClause, wherePredicates, getDataDictionary())) {
                isDistinct = false;
            }
        }
        for (int i = 0; i < qec.size(); i++) {
            /* If we were unable to eliminate the distinct and we have
                 * an order by then we can consider eliminating the sort for
                 * the order by.  All of the columns in the order by list must
                 * be ascending in order to do this.  There are 2 cases:
                 *  o   The order by list is an in order prefix of the columns
                 *      in the select list.  In this case the output of the
                 *      sort from the distinct will be in the right order
                 *      so we simply eliminate the order by list.
                 *  o   The order by list is a subset of the columns in the
                 *      the select list.  In this case we need to reorder the
                 *      columns in the select list so that the ordering columns
                 *      are an in order prefix of the select list and put a PRN
                 *      above the select so that the shape of the result set
                 *      is as expected.
                 */
            final OrderByList obl = qec.getOrderByList(i);
            if (isDistinct && obl != null && obl.allAscending()) {
                /* Order by list currently restricted to columns in select
                     * list, so we will always eliminate the order by here.
                     */
                if (obl.isInOrderPrefix(getResultColumns())) {
                    qec.setOrderByList(i, null);
                } else {
                    /* Order by list is not an in order prefix of the
                         * select list so we must reorder the columns in the
                         * the select list to match the order by list and
                         * generate the PRN above us to preserve the expected
                         * order.
                         */
                    newTop = genProjectRestrictForReordering();
                    obl.resetToSourceRCs();
                    setResultColumns(obl.reorderRCL(getResultColumns()));
                    newTop.getResultColumns().removeOrderByColumns();
                    qec.setOrderByList(i, null);
                }
                orderByAndDistinctMerged = true;
            }
        }
    }
    /*
		 * Push predicates that are pushable.
		 *
		 * NOTE: We pass the wherePredicates down to the new PRNs here,
		 * so they can pull any clauses and possibily push them down further.
		 * NOTE: We wait until all of the FromTables have been preprocessed
		 * until we attempt to push down predicates, because we cannot push down
		 * a predicate if the immediate source of any of its column references
		 * is not a ColumnReference or a VirtualColumnNode.
		 */
    fromList.pushPredicates(wherePredicates);
    /* Set up the referenced table map */
    setReferencedTableMap(new JBitSet(numTables));
    int flSize = fromList.size();
    for (int index = 0; index < flSize; index++) {
        getReferencedTableMap().or(((FromTable) fromList.elementAt(index)).getReferencedTableMap());
    }
    /* Copy the referenced table map to the new tree top, if necessary */
    if (newTop != this) {
        newTop.setReferencedTableMap((JBitSet) getReferencedTableMap().clone());
    }
    if (qec.getOrderByList(0) != null) {
        // only relevant for first one
        // Collect window function calls and in-lined window definitions
        // contained in them from the orderByList.
        CollectNodesVisitor<WindowFunctionNode> cnvw = new CollectNodesVisitor<WindowFunctionNode>(WindowFunctionNode.class);
        qec.getOrderByList(0).accept(cnvw);
        for (WindowFunctionNode wfn : cnvw.getList()) {
            windowFuncCalls.add(wfn);
            if (wfn.getWindow() instanceof WindowDefinitionNode) {
                // Window function call contains an inline definition, add
                // it to our list of windows.
                windows = addInlinedWindowDefinition(windows, wfn);
            } else {
                if (SanityManager.DEBUG) {
                    SanityManager.ASSERT(false, "a window reference, should be bound already");
                }
            }
        }
    }
    return newTop;
}
Also used : JBitSet(org.apache.derby.iapi.util.JBitSet)

Example 14 with JBitSet

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

the class FromBaseTable method uniqueJoin.

/**
 * @see org.apache.derby.iapi.sql.compile.Optimizable#uniqueJoin
 */
@Override
public double uniqueJoin(OptimizablePredicateList predList) throws StandardException {
    double retval = -1.0;
    PredicateList pl = (PredicateList) predList;
    int numColumns = getTableDescriptor().getNumberOfColumns();
    int tableNo = getTableNumber();
    // This is supposed to be an array of table numbers for the current
    // query block. It is used to determine whether a join is with a
    // correlation column, to fill in eqOuterCols properly. We don't care
    // about eqOuterCols, so just create a zero-length array, pretending
    // that all columns are correlation columns.
    int[] tableNumbers = new int[0];
    JBitSet[] tableColMap = new JBitSet[1];
    tableColMap[0] = new JBitSet(numColumns + 1);
    pl.checkTopPredicatesForEqualsConditions(tableNo, null, tableNumbers, tableColMap, false);
    if (supersetOfUniqueIndex(tableColMap)) {
        retval = getBestAccessPath().getCostEstimate().singleScanRowCount();
    }
    return retval;
}
Also used : OptimizablePredicateList(org.apache.derby.iapi.sql.compile.OptimizablePredicateList) JBitSet(org.apache.derby.iapi.util.JBitSet)

Example 15 with JBitSet

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

the class FromList method returnsAtMostSingleRow.

/**
 * This method is used for both subquery flattening and distinct
 * elimination based on a uniqueness condition.  For subquery
 * flattening we want to make sure that the query block
 * will return at most 1 row.  For distinct elimination we
 * want to make sure that the query block will not return
 * any duplicates.
 * This is true if every table in the from list is
 * (a base table and the set of columns from the table that
 * are in equality comparisons with expressions that do not include columns
 * from the same table is a superset of any unique index
 * on the table) or an EXISTS FBT.  In addition, at least 1 of the tables
 * in the list has a set of columns in equality comparisons with expressions
 * that do not include column references from the same query block
 * is a superset of a unique index
 * on that table.  (This ensures that the query block will onlyr
 * return a single row.)
 * This method is expected to be called after normalization and
 * after the from list has been preprocessed.
 * It can be called both before and after the predicates have
 * been pulled from the where clause.
 * The algorithm for this is as follows
 *
 *	If any table in the query block is not a base table, give up.
 * 	For each table in the query
 *		Ignore exists table since they can only produce one row
 *
 *		create a matrix of tables and columns from the table (tableColMap)
 *		(this is used to keep track of the join columns and constants
 *		that can be used to figure out whether the rows from a join
 *		or in a select list are distinct based on unique indexes)
 *
 *		create an array of columns from the table(eqOuterCol)
 *		(this is used to determine that only one row will be returned
 *		from a join)
 *
 *		if the current table is the table for the result columns
 *			set the result columns in the eqOuterCol and tableColMap
 *			(if these columns are a superset of a unique index and
 *			all joining tables result in only one row, the
 *			results will be distinct)
 *		go through all the predicates and update tableColMap  and
 *		eqOuterCol with join columns and correlation variables,
 *		parameters and constants
 *		since setting constants, correlation variables and parameters,
 * 		reduces the number of columns required for uniqueness in a
 *		multi-column index, they are set for all the tables (if the
 *		table is not the result table, in this case only the column of the
 *		result table is set)
 *		join columns are just updated for the column in the row of the
 *		joining table.
 *
 *		check if the marked columns in tableColMap are a superset of a unique
 *			index
 *			(This means that the join will only produce 1 row when joined
 *			with 1 row of another table)
 *		check that there is a least one table for which the columns in
 *			eqOuterCol(i.e. constant values) are a superset of a unique index
 *			(This quarantees that there will be only one row selected
 *			from this table).
 *
 *	Once all tables have been evaluated, check that all the tables can be
 * 	joined by unique index or will have only one row
 *
 * @param rcl				If non-null, the RCL from the query block.
 *							If non-null for subqueries, then entry can
 *							be considered as part of an = comparison.
 * @param whereClause		The WHERE clause to consider.
 * @param wherePredicates	The predicates that have already been
 *							pulled from the WHERE clause.
 * @param dd				The DataDictionary to use.
 *
 * @return	Whether or not query block will return
 *			at most 1 row for a subquery, no duplicates
 *			for a distinct.
 *
 * @exception StandardException		Thrown on error
 */
boolean returnsAtMostSingleRow(ResultColumnList rcl, ValueNode whereClause, PredicateList wherePredicates, DataDictionary dd) throws StandardException {
    boolean satisfiesOuter = false;
    int[] tableNumbers;
    ColumnReference additionalCR = null;
    PredicateList predicatesTemp;
    predicatesTemp = new PredicateList(getContextManager());
    for (Predicate p : wherePredicates) {
        predicatesTemp.addPredicate(p);
    }
    /* When considering subquery flattening, we are interested
		 * in the 1st (and only) entry in the RCL.  (The RCL will be
		 * null if result column is not of interest for subquery flattening.)
		 * We are interested in all entries in the RCL for distinct
		 * elimination.
		 */
    if (rcl != null) {
        ResultColumn rc = rcl.elementAt(0);
        if (rc.getExpression() instanceof ColumnReference) {
            additionalCR = (ColumnReference) rc.getExpression();
        }
    }
    /* First see if all entries are FromBaseTables.  No point
		 * in continuing if not.
		 */
    int size = size();
    for (int index = 0; index < size; index++) {
        FromTable fromTable = (FromTable) elementAt(index);
        if (!(fromTable instanceof ProjectRestrictNode)) {
            return false;
        }
        ProjectRestrictNode prn = (ProjectRestrictNode) fromTable;
        if (!(prn.getChildResult() instanceof FromBaseTable)) {
            return false;
        }
        FromBaseTable fbt = (FromBaseTable) prn.getChildResult();
        // 
        if (fbt.getExistsBaseTable()) {
            int existsTableNumber = fbt.getTableNumber();
            for (int i = predicatesTemp.size() - 1; i >= 0; i--) {
                AndNode topAndNode = predicatesTemp.elementAt(i).getAndNode();
                for (ValueNode whereWalker = topAndNode; whereWalker instanceof AndNode; whereWalker = ((AndNode) whereWalker).getRightOperand()) {
                    // See if this is a candidate =
                    AndNode and = (AndNode) whereWalker;
                    // predicates are considered during DISTINCT elimination.
                    if (!and.getLeftOperand().isRelationalOperator() || !(((RelationalOperator) (and.getLeftOperand())).getOperator() == RelationalOperator.EQUALS_RELOP)) {
                        continue;
                    }
                    JBitSet referencedTables = and.getLeftOperand().getTablesReferenced();
                    if (referencedTables.get(existsTableNumber)) {
                        predicatesTemp.removeElementAt(i);
                        break;
                    }
                }
            }
        }
    }
    /* Build an array of tableNumbers from this query block.
		 * We will use that array to find out if we have at least
		 * one table with a uniqueness condition based only on
		 * constants, parameters and correlation columns.
		 */
    tableNumbers = getTableNumbers();
    JBitSet[][] tableColMap = new JBitSet[size][size];
    boolean[] oneRow = new boolean[size];
    boolean oneRowResult;
    /* See if each table has a uniqueness condition */
    for (int index = 0; index < size; index++) {
        ProjectRestrictNode prn = (ProjectRestrictNode) elementAt(index);
        FromBaseTable fbt = (FromBaseTable) prn.getChildResult();
        // Skip over EXISTS FBT since they cannot introduce duplicates
        if (fbt.getExistsBaseTable()) {
            oneRow[index] = true;
            continue;
        }
        int numColumns = fbt.getTableDescriptor().getNumberOfColumns();
        boolean[] eqOuterCols = new boolean[numColumns + 1];
        int tableNumber = fbt.getTableNumber();
        boolean resultColTable = false;
        for (int i = 0; i < size; i++) tableColMap[index][i] = new JBitSet(numColumns + 1);
        if (additionalCR != null && additionalCR.getTableNumber() == tableNumber) {
            rcl.recordColumnReferences(eqOuterCols, tableColMap[index], index);
            resultColTable = true;
        }
        /* Now see if there are any equality conditions
			 * of interest in the where clause.
			 */
        if (whereClause != null) {
            whereClause.checkTopPredicatesForEqualsConditions(tableNumber, eqOuterCols, tableNumbers, tableColMap[index], resultColTable);
        }
        /* Now see if there are any equality conditions
			 * of interest in the where predicates.
			 */
        predicatesTemp.checkTopPredicatesForEqualsConditions(tableNumber, eqOuterCols, tableNumbers, tableColMap[index], resultColTable);
        /* Now see if there are any equality conditions
			 * of interest that were already pushed down to the
			 * PRN above the FBT. (Single table predicates.)
			 */
        if (prn.getRestrictionList() != null) {
            prn.getRestrictionList().checkTopPredicatesForEqualsConditions(tableNumber, eqOuterCols, tableNumbers, tableColMap[index], resultColTable);
        }
        /* We can finally check to see if the marked columns
			 * are a superset of any unique index.
			 */
        if (!fbt.supersetOfUniqueIndex(tableColMap[index])) {
            return false;
        }
        /* Do we have at least 1 table whose equality condition
			 * is based solely on constants, parameters and correlation columns.
			 */
        oneRowResult = fbt.supersetOfUniqueIndex(eqOuterCols);
        if (oneRowResult) {
            oneRow[index] = true;
            satisfiesOuter = true;
        }
    }
    /* Have we met all of the criteria */
    if (satisfiesOuter) {
        /* check that all the tables are joined by unique indexes 
			 * or only produce 1 row
			 */
        boolean foundOneRow = true;
        while (foundOneRow) {
            foundOneRow = false;
            for (int index = 0; index < size; index++) {
                if (oneRow[index]) {
                    for (int i = 0; i < size; i++) {
                        /* unique key join - exists tables already marked as 
							 * 1 row - so don't need to look at them
							 */
                        if (!oneRow[i] && tableColMap[i][index].get(0)) {
                            oneRow[i] = true;
                            foundOneRow = true;
                        }
                    }
                }
            }
        }
        /* does any table produce more than one row */
        for (int index = 0; index < size; index++) {
            if (!oneRow[index]) {
                satisfiesOuter = false;
                break;
            }
        }
    }
    return satisfiesOuter;
}
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