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

📄 groupbynode.java

📁 derby database source code.good for you.
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
						predicates,						dataDictionary,						(RequiredRowOrdering) null);		// RESOLVE: NEED TO FACTOR IN COST OF SORTING AND FIGURE OUT HOW		// MANY ROWS HAVE BEEN ELIMINATED.		costEstimate = optimizer.newCostEstimate();		costEstimate.setCost(childResult.getCostEstimate().getEstimatedCost(),							childResult.getCostEstimate().rowCount(),							childResult.getCostEstimate().singleScanRowCount());		return this;	}	ResultColumnDescriptor[] makeResultDescriptors(ExecutionContext ec)	{	    return childResult.makeResultDescriptors(ec);	}	/**	 * Return whether or not the underlying ResultSet tree will return	 * a single row, at most.	 * This is important for join nodes where we can save the extra next	 * on the right side if we know that it will return at most 1 row.	 *	 * @return Whether or not the underlying ResultSet tree will return a single row.	 * @exception StandardException		Thrown on error	 */	public boolean isOneRowResultSet()	throws StandardException	{		// Only consider scalar aggregates for now		return ((groupingList == null) ||  (groupingList.size() == 0));	}    /**     * generate the sort result set operating over the source	 * resultset.  Adds distinct aggregates to the sort if	 * necessary.     *	 * @exception StandardException		Thrown on error     */	public void generate(ActivationClassBuilder acb,								MethodBuilder mb)							throws StandardException	{		int					orderingItem = 0;		int					aggInfoItem = 0;		FormatableArrayHolder	orderingHolder;		/* Get the next ResultSet#, so we can number this ResultSetNode, its		 * ResultColumnList and ResultSet.		 */		assignResultSetNumber();		// Get the final cost estimate from the child.		costEstimate = childResult.getFinalCostEstimate();		/*		** Get the column ordering for the sort.  Note that		** for a scalar aggegate we may not have any ordering		** columns (if there are no distinct aggregates).		** WARNING: if a distinct aggregate is passed to		** SortResultSet it assumes that the last column		** is the distinct one.  If this assumption changes		** then SortResultSet will have to change.		*/		orderingHolder = acb.getColumnOrdering(groupingList);		if (addDistinctAggregate)		{			orderingHolder = acb.addColumnToOrdering(									orderingHolder,									addDistinctAggregateColumnNum);		}		if (SanityManager.DEBUG)		{			if (SanityManager.DEBUG_ON("AggregateTrace"))			{				StringBuffer s = new StringBuffer();									s.append("Group by column ordering is (");				ColumnOrdering[] ordering = 						(ColumnOrdering[])orderingHolder.getArray(ColumnOrdering.class);				for (int i = 0; i < ordering.length; i++)					{					s.append(ordering[i].getColumnId());					s.append(" ");				}				s.append(")");				SanityManager.DEBUG("AggregateTrace", s.toString());			}		}		orderingItem = acb.addItem(orderingHolder);		/*		** We have aggregates, so save the aggInfo		** struct in the activation and store the number		*/		if (SanityManager.DEBUG)		{			SanityManager.ASSERT(aggInfo != null,					"aggInfo not set up as expected");		}		aggInfoItem = acb.addItem(aggInfo);		acb.pushGetResultSetFactoryExpression(mb);		// Generate the child ResultSet		childResult.generate(acb, mb);		mb.push(isInSortedOrder);		mb.push(aggInfoItem);		mb.push(orderingItem);		acb.pushThisAsActivation(mb);		resultColumns.generateHolder(acb, mb);		mb.push(resultColumns.getTotalColumnSize());		mb.push(resultSetNumber);		/* Generate a (Distinct)ScalarAggregateResultSet if scalar aggregates */		if ((groupingList == null) ||  (groupingList.size() == 0))		{			genScalarAggregateResultSet(acb, mb);		}		/* Generate a (Distinct)GroupedAggregateResultSet if grouped aggregates */		else		{			genGroupedAggregateResultSet(acb, mb);		}	}	/**	 * Generate the code to evaluate scalar aggregates.	 *	 */	private	void genScalarAggregateResultSet(ActivationClassBuilder acb,												   MethodBuilder mb)	{		/* Generate the (Distinct)ScalarAggregateResultSet:		 *	arg1: childExpress - Expression for childResult		 *  arg2: isInSortedOrder - true if source result set in sorted order		 *  arg3: aggregateItem - entry in saved objects for the aggregates,		 *  arg4: orderItem - entry in saved objects for the ordering		 *  arg5: Activation		 *  arg6: rowAllocator - method to construct rows for fetching		 *			from the sort		 *  arg7: row size		 *  arg8: resultSetNumber		 *  arg9: Whether or not to perform min optimization.		 *  arg12: closeCleanup		 */		String resultSet = (addDistinctAggregate) ? "getDistinctScalarAggregateResultSet" : "getScalarAggregateResultSet";		mb.push(singleInputRowOptimization);		mb.push(costEstimate.rowCount());		mb.push(costEstimate.getEstimatedCost());		closeMethodArgument(acb, mb);		mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, resultSet, ClassName.NoPutResultSet, 12);	}	/**	 * Generate the code to evaluate grouped aggregates.	 *	 */	private	void genGroupedAggregateResultSet(ActivationClassBuilder acb,												   MethodBuilder mb)				throws StandardException	{		/* Generate the (Distinct)GroupedAggregateResultSet:		 *	arg1: childExpress - Expression for childResult		 *  arg2: isInSortedOrder - true if source result set in sorted order		 *  arg3: aggregateItem - entry in saved objects for the aggregates,		 *  arg4: orderItem - entry in saved objects for the ordering		 *  arg5: Activation		 *  arg6: rowAllocator - method to construct rows for fetching		 *			from the sort		 *  arg7: row size		 *  arg8: resultSetNumber		 *  arg11: closeCleanup		 */		String resultSet = (addDistinctAggregate) ? "getDistinctGroupedAggregateResultSet" : "getGroupedAggregateResultSet";    		mb.push(costEstimate.rowCount());		mb.push(costEstimate.getEstimatedCost());		closeMethodArgument(acb, mb);		mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, resultSet, ClassName.NoPutResultSet, 11);	}	///////////////////////////////////////////////////////////////	//	// UTILITIES	//	///////////////////////////////////////////////////////////////	/**	 * Method for creating a new result column referencing	 * the one passed in.	 *	 * @param	targetRC	the source	 * @param	dd	 *	 * @return the new result column	 *	 * @exception StandardException	on error	 */	private ResultColumn getColumnReference(ResultColumn targetRC, 								DataDictionary		dd)		throws StandardException	{		ColumnReference	tmpColumnRef;		ResultColumn	newRC;			tmpColumnRef = (ColumnReference) getNodeFactory().getNode(											C_NodeTypes.COLUMN_REFERENCE,											targetRC.getName(),											null,											getContextManager());		tmpColumnRef.setSource(targetRC);		tmpColumnRef.setType(targetRC.getExpressionType());		tmpColumnRef.setNestingLevel(this.getLevel());		tmpColumnRef.setSourceLevel(this.getLevel());		newRC = (ResultColumn) getNodeFactory().getNode(									C_NodeTypes.RESULT_COLUMN,									targetRC.getColumnName(),									tmpColumnRef,									getContextManager());		newRC.markGenerated();		newRC.bindResultColumnToExpression();		return newRC;	}	/**	 * Consider any optimizations after the optimizer has chosen a plan.	 * Optimizations include:	 *	o  min optimization for scalar aggregates	 *	o  max optimization for scalar aggregates	 *	 * @param selectHasPredicates true if SELECT containing this	 *		vector/scalar aggregate has a restriction	 *	 * @return Nothing.	 *	 * @exception StandardException	on error	 */	void considerPostOptimizeOptimizations(boolean selectHasPredicates)		throws StandardException	{		/* Consider the optimization for min with asc index on that column or		 * max with desc index on that column:		 *	o  No group by		 *  o  One of:		 *		o  min/max(ColumnReference) is only aggregate && source is 		 *		   ordered on the ColumnReference		 *		o  min/max(ConstantNode)		 * The optimization of the other way around (min with desc index or		 * max with asc index) has the same restrictions with the additional		 * temporary restriction of no qualifications at all (because		 * we don't have true backward scans).		 */		if (groupingList == null)		{			if (aggregateVector.size() == 1)			{				AggregateNode an = (AggregateNode) aggregateVector.elementAt(0);				AggregateDefinition ad = an.getAggregateDefinition();				if (ad instanceof MaxMinAggregateDefinition)				{					if (an.getOperand() instanceof ColumnReference)					{						/* See if the underlying ResultSet tree						 * is ordered on the ColumnReference.						 */						ColumnReference[] crs = new ColumnReference[1];						crs[0] = (ColumnReference) an.getOperand();												Vector tableVector = new Vector();						boolean minMaxOptimizationPossible = isOrderedOn(crs, false, tableVector);						if (SanityManager.DEBUG)						{							SanityManager.ASSERT(tableVector.size() <= 1, "bad number of FromBaseTables returned by isOrderedOn() -- "+tableVector.size());						}						if (minMaxOptimizationPossible)						{							boolean ascIndex = true;							int colNum = crs[0].getColumnNumber();														/* Check if we have an access path, this will be							 * null in a join case (See Beetle 4423)							 */							AccessPath accessPath= getTrulyTheBestAccessPath();							if (accessPath == null)								return;							IndexDescriptor id = accessPath.												getConglomerateDescriptor().												getIndexDescriptor();							int[] keyColumns = id.baseColumnPositions();							boolean[] isAscending = id.isAscending();							for (int i = 0; i < keyColumns.length; i++)							{								/* in such a query: select min(c3) from								 * tab1 where c1 = 2 and c2 = 5, if prefix keys								 * have equality operator, then we can still use								 * the index.  The checking of equality operator								 * has been done in isStrictlyOrderedOn.								 */								if (colNum == keyColumns[i])								{									if (! isAscending[i])										ascIndex = false;									break;								}							}							FromBaseTable fbt = (FromBaseTable)tableVector.firstElement();							MaxMinAggregateDefinition temp = (MaxMinAggregateDefinition)ad;							/*  MAX   ASC      NULLABLE                              *  ----  ----------							 *  TRUE  TRUE      TRUE/FALSE  =  Special Last Key Scan (ASC Index Last key with null skips)							 *  TRUE  FALSE     TRUE/FALSE  =  JustDisableBulk(DESC index 1st key with null skips)							 *  FALSE TRUE      TRUE/FALSE  = JustDisableBulk(ASC index 1st key)							 *  FALSE FALSE     TRUE/FALSE  = Special Last Key Scan(Desc Index Last Key)							 */							if (((!temp.isMax()) && ascIndex) || 								((temp.isMax()) && !ascIndex))							{								fbt.disableBulkFetch();								singleInputRowOptimization = true;							}							/*							** Max optimization with asc index or min with							** desc index is currently more							** restrictive than otherwise.							** We are getting the store to return the last							** row from an index (for the time being, the							** store cannot do real backward scans).  SO							** we cannot do this optimization if we have							** any predicates at all.							*/							else if (!selectHasPredicates && 									 ((temp.isMax() && ascIndex) || 									  (!temp.isMax() && !ascIndex )))							{								fbt.disableBulkFetch();								fbt.doSpecialMaxScan();								singleInputRowOptimization = true;							}						}					}					else if (an.getOperand() instanceof ConstantNode)					{						singleInputRowOptimization = true;					}				}			}		}	}}

⌨️ 快捷键说明

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