⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 selectnode.java

📁 derby database source code.good for you.
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
			return false;		}		/* Don't flatten if selectNode contains a group by or having clause */		if ((groupByList != null) || generatedForHavingClause)		{			return false;		}		/* Don't flatten if select list contains something that isn't cloneable.		 */		if (! resultColumns.isCloneable())		{			return false;		}		/* Don't flatten if selectNode contains an aggregate */		if ((selectAggregates != null) && 			 (selectAggregates.size() > 0))		{			return false;		}		return true;	}	/**	 * Replace this SelectNode with a ProjectRestrictNode,	 * since it has served its purpose.	 *	 * @param origFromListSize	The size of the original FROM list, before	 *							generation of join tree.	 * @return ResultSetNode	new ResultSetNode atop the query tree.	 *	 * @exception StandardException		Thrown on error	 */	public ResultSetNode genProjectRestrict(int origFromListSize)				throws StandardException	{		boolean				orderingDependent = false;		PredicateList		restrictionList;		ResultColumnList	prRCList;		ResultSetNode		prnRSN;		prnRSN = (ResultSetNode) getNodeFactory().getNode(								C_NodeTypes.PROJECT_RESTRICT_NODE,								fromList.elementAt(0),	/* Child ResultSet */								resultColumns,		/* Projection */								whereClause,			/* Restriction */								wherePredicates,/* Restriction as PredicateList */								selectSubquerys,/* Subquerys in Projection */								whereSubquerys,	/* Subquerys in Restriction */								null,								getContextManager()	 );		/*		** If we have aggregates OR a select list we want		** to generate a GroupByNode.  In the case of a		** scalar aggregate we have no grouping columns.		**		** JRESOLVE: what about correlated aggregates from another		** block.		*/ 		if (((selectAggregates != null) && (selectAggregates.size() > 0)) 			|| (groupByList != null))		{			GroupByNode gbn = (GroupByNode) getNodeFactory().getNode(												C_NodeTypes.GROUP_BY_NODE,												prnRSN,												groupByList,												selectAggregates,												null,												getContextManager());			gbn.considerPostOptimizeOptimizations(originalWhereClause != null);			gbn.assignCostEstimate(optimizer.getOptimizedCost());			groupByList = null;			prnRSN  = gbn.getParent();			// Remember if the result is dependent on the ordering			orderingDependent = orderingDependent || gbn.getIsInSortedOrder();		}		// if it is distinct, that must also be taken care of.		if (isDistinct)		{			// We first verify that a distinct is valid on the			// RCL.			resultColumns.verifyAllOrderable();			/* See if we can push duplicate elimination into the store			 * via a hash scan.  This is possible iff:			 *	o  A single table query			 *	o  We haven't merged the order by and distinct sorts.			 *	   (Results do not have to be in a particular order.)			 *	o  All entries in the select's RCL are ColumnReferences.			 *	o  No predicates (This is because we currently do not			 *	   differentiate between columns referenced in the select			 *	   list and columns referenced in other clauses.  In other			 *	   words, the store will do duplicate elimination based on			 *	   all referenced columns.)			 *	   RESOLVE - We can change this to be all referenced columns			 *	   have to be in the select list.  In that case, we need to			 *	   refine which predicates are allowed.  Basically, all predicates			 *	   must have been pushed down to the index/table scan.(If we make			 *	   this change, then we need to verify that non of the columns in			 *	   the predicates are correlated columns.)			 *	o  NOTE: The implementation of isPossibleDistinctScan() will return			 *	   false if there is an IndexRowToBaseRow above the 			 *	   FromBaseTable.  This is because all of a table's columns must come			 *	   from the same conglomerate in order to get consistent data.			 */			boolean distinctScanPossible = false;			if (origFromListSize == 1 &&				(! orderByAndDistinctMerged) &&				resultColumns.countNumberOfSimpleColumnReferences() == resultColumns.size())			{				boolean simpleColumns = true;				HashSet distinctColumns = new HashSet();				int size = resultColumns.size();				for (int i = 1; i <= size; i++) {					BaseColumnNode bc = resultColumns.getResultColumn(i).getBaseColumnNode();					if (bc == null) {						simpleColumns = false;						break;					}					distinctColumns.add(bc);				}				if (simpleColumns && prnRSN.isPossibleDistinctScan(distinctColumns)) {					prnRSN.markForDistinctScan();					distinctScanPossible = true;				}			}			if (!distinctScanPossible)			{				/* We can't do a distinct scan. Determine if we can filter out 				 * duplicates without a sorter. 				 */				boolean inSortedOrder = isOrderedResult(resultColumns, prnRSN, !(orderByAndDistinctMerged));				prnRSN = (ResultSetNode) getNodeFactory().getNode(											C_NodeTypes.DISTINCT_NODE,											prnRSN,											new Boolean(inSortedOrder),											null,											getContextManager());				prnRSN.costEstimate = costEstimate.cloneMe();				// Remember if the result is dependent on the ordering				orderingDependent = orderingDependent || inSortedOrder;			}		}		/* Generate the OrderByNode if a sort is still required for		 * the order by.		 */		if (orderByList != null)		{			if (orderByList.getSortNeeded())			{				prnRSN = (ResultSetNode) getNodeFactory().getNode(												C_NodeTypes.ORDER_BY_NODE,												prnRSN,												orderByList,												null,												getContextManager());				prnRSN.costEstimate = costEstimate.cloneMe();			}			int orderBySelect = this.getResultColumns().getOrderBySelect();			if (orderBySelect > 0)			{				ResultColumnList selectRCs = prnRSN.getResultColumns().copyListAndObjects();				int wholeSize = selectRCs.size();				for (int i = wholeSize - 1; orderBySelect > 0; i--, orderBySelect--)					selectRCs.removeElementAt(i);				selectRCs.genVirtualColumnNodes(prnRSN, prnRSN.getResultColumns());				prnRSN = (ResultSetNode) getNodeFactory().getNode(								C_NodeTypes.PROJECT_RESTRICT_NODE,								prnRSN,								selectRCs,								null,								null,								null,								null,								null,								getContextManager());			}		}		if (!(orderByList != null && orderByList.getSortNeeded()) && orderByQuery)		{			// Remember if the result is dependent on the ordering			orderingDependent = true;		}		/* If the result is ordering dependent, then we must		 * tell the underlying tree.  At minimum, this means no		 * group fetch on an index under an IndexRowToBaseRow		 * since that could lead to incorrect results.  (Bug 2347.)		 */		if (orderingDependent)		{			prnRSN.markOrderingDependent();		}		/* Set the cost of this node in the generated node */		prnRSN.costEstimate = costEstimate.cloneMe();		return prnRSN;	}	/**	 * Is the result of this node an ordered result set.  An ordered result set	 * means that the results from this node will come in a known sorted order.	 * This means that the data is ordered according to the order of the elements in the RCL.	 * Today, the data is considered ordered if:	 *		o The RCL is composed entirely of CRs or ConstantNodes	 *		o The underlying tree is ordered on the CRs in the order in which	 *			they appear in the RCL, taking equality predicates into account.	 * Future Enhancements:	 *		o The prefix will not be required to be in order.  (We will need to 	 *		  reorder the RCL and generate a PRN with an RCL in the expected order.)	 *	 * @return boolean	Whether or not this node returns an ordered result set.	 *	 * @exception StandardException		Thrown on error	 */	private boolean isOrderedResult(ResultColumnList resultColumns,										  ResultSetNode newTopRSN,										  boolean permuteOrdering)		throws StandardException	{		int rclSize = resultColumns.size();		/* Not ordered if RCL contains anything other than a ColumnReference		 * or a ConstantNode.		 */		int numCRs = 0;		for (int index = 0; index < rclSize; index++)		{			ResultColumn rc = (ResultColumn) resultColumns.elementAt(index);			if (rc.getExpression() instanceof ColumnReference)			{				numCRs++;			}			else if (! (rc.getExpression() instanceof ConstantNode))			{				return false;			}		}		// Corner case, all constants		if (numCRs == 0)		{			return true;		}		ColumnReference[] crs = new ColumnReference[numCRs];		// Now populate the CR array and see if ordered		int crsIndex = 0;		for (int index = 0; index < rclSize; index++)		{			ResultColumn rc = (ResultColumn) resultColumns.elementAt(index);			if (rc.getExpression() instanceof ColumnReference)			{				crs[crsIndex++] = (ColumnReference) rc.getExpression();			}		}		return newTopRSN.isOrderedOn(crs, permuteOrdering, (Vector)null);	}	/**	 * Ensure that the top of the RSN tree has a PredicateList.	 *	 * @param numTables			The number of tables in the query.	 * @return ResultSetNode	A RSN tree with a node which has a PredicateList on top.	 *	 * @exception StandardException		Thrown on error	 */	public ResultSetNode ensurePredicateList(int numTables) 		throws StandardException	{		return this;	}	/**	 * Optimize this SelectNode.  This means choosing the best access path	 * for each table, among other things.	 *	 * @param dataDictionary	The DataDictionary to use for optimization	 * @param predicateList		The predicate list to optimize against	 * @param outerRows			The number of outer joining rows	 *	 * @return	ResultSetNode	The top of the optimized tree	 *	 * @exception StandardException		Thrown on error	 */	public ResultSetNode optimize(DataDictionary dataDictionary,								  PredicateList	predicateList,								  double outerRows) 				throws StandardException	{		Optimizer		 optimizer;		/* Optimize any subquerys before optimizing the underlying result set */		/* selectSubquerys is always allocated at bind() time */		if (SanityManager.DEBUG)		SanityManager.ASSERT(selectSubquerys != null,			"selectSubquerys is expected to be non-null");		/* If this select node is the child of an outer node that is		 * being optimized, we can get here multiple times (once for		 * every permutation that is done for the outer node).  With		 * DERBY-805, we can add optimizable predicates to the WHERE		 * list as part of this method; thus, before proceeding we		 * need go through and remove any opt predicates that we added		 * to our WHERE list the last time we were here; if we don't		 * do that, we'll end up with the same predicates in our		 * WHERE list multiple times, which can lead to incorrect		 * optimization.		 */		if (wherePredicates != null)		{			// Iterate backwards because we might be deleting entries.			for (int i = wherePredicates.size() - 1; i >= 0; i--)			{				if (((Predicate)wherePredicates.elementAt(i)).isScopedForPush())					wherePredicates.removeOptPredicate(i);			}		}		/* Get a new optimizer */		/* With DERBY-805 we take any optimizable predicates that		 * were pushed into this node and we add them to the list of		 * predicates that we pass to the optimizer, thus allowing		 * the optimizer to use them when choosing an access path		 * for this SELECT node.  We do that by adding the predicates		 * to our WHERE list, since the WHERE predicate list is what		 * we pass to the optimizer for this select node (see below).		 * We have to pass the WHERE list directly (as opposed to		 * passing a copy) because the optimizer is only created one		 * time; it then uses the list we pass it for the rest of the		 * optimization phase and finally for "modifyAccessPaths()".		 * Since the optimizer can update/modify the list based on the		 * WHERE predicates (such as by adding internal predicates or		 * by modifying the actual predicates themselves), we need		 * those changes to be applied to the WHERE list directly for		 * subsequent processing (esp. for modification of the access		 * path).  Note that by adding outer opt predicates directly		 * to the WHERE list, we're changing the semantics of this		 * SELECT node.  This is only temporary, though--once the		 * optimizer is done with all of its work, any predicates		 * that were pushed here will have been pushed even further		 * down and thus will have been removed from the WHERE list		 * (if it's not possible to push them further down, then they		 * shouldn't have made it this far to begin with).		 */		if (predicateList != null)		{			if (wherePredicates == null) {				wherePredicates = (PredicateList) getNodeFactory().getNode(						C_NodeTypes.PREDICATE_LIST,						getContextManager());			}			Predicate pred = null;			int sz = predicateList.size();			for (int i = sz - 1; i >= 0; i--)			{				// We can tell if a predicate was pushed into this select				// node because it will have been "scoped" for this node;				// see Predicate.getScopedPredForResultSet() for more on				// what scoping is and how it's done.				pred = (Predicate)predicateList.getOptPredicate(i);				if (pred.isScopedForPush())				{					// If we're pushing the predicate down here, we have to					// remove it from the predicate list of the node above					// this select, in order to keep in line with established					// push 'protocol'.					wherePredicates.addOptPredicate(pred);					predicateList.removeOptPredicate(pred);				}			}		}		optimizer = getOptimizer(fromList,								wherePredicates,								dataDictionary,								orderByList);		optimizer.setOuterRows(outerRows);		/* Optimize this SelectNode */		while (optimizer.getNextPermutation())		{			while (optimizer.getNextDecoratedPermutation())			{				optimizer.costPermutation();			}		}		/* Get the cost */		costEstimate = optimizer.getOptimizedCost();		/* Update row counts if this is a scalar aggregate */		if ((selectAggregates != null) && (selectAggregates.size() > 0)) 		{			costEstimate.setEstimatedRowCount((long) outerRows);			costEstimate.setSingleScanRowCount(1);		}		selectSubquerys.optimize(dataDictionary, costEstimate.rowCount());

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -