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

📄 aggregatenode.java

📁 derby database source code.good for you.
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*   Derby - Class org.apache.derby.impl.sql.compile.AggregateNode   Copyright 1998, 2004 The Apache Software Foundation or its licensors, as applicable.   Licensed under the Apache License, Version 2.0 (the "License");   you may not use this file except in compliance with the License.   You may obtain a copy of the License at      http://www.apache.org/licenses/LICENSE-2.0   Unless required by applicable law or agreed to in writing, software   distributed under the License is distributed on an "AS IS" BASIS,   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   See the License for the specific language governing permissions and   limitations under the License. */package	org.apache.derby.impl.sql.compile;import org.apache.derby.iapi.services.compiler.MethodBuilder;import org.apache.derby.iapi.services.sanity.SanityManager;import org.apache.derby.iapi.services.loader.ClassInspector;import org.apache.derby.iapi.services.loader.ClassFactory;import org.apache.derby.iapi.error.StandardException;import org.apache.derby.iapi.sql.dictionary.DataDictionary;import org.apache.derby.iapi.sql.compile.CompilerContext;import org.apache.derby.iapi.sql.compile.C_NodeTypes;import org.apache.derby.iapi.types.DataTypeDescriptor;import org.apache.derby.iapi.types.TypeId;import org.apache.derby.iapi.reference.SQLState;import org.apache.derby.iapi.sql.dictionary.DataDictionary;import org.apache.derby.iapi.sql.execute.ExecAggregator;import org.apache.derby.iapi.error.StandardException;import org.apache.derby.iapi.reference.SQLState;import org.apache.derby.impl.sql.compile.ActivationClassBuilder;import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;import org.apache.derby.catalog.AliasInfo;import org.apache.derby.catalog.TypeDescriptor;import org.apache.derby.impl.sql.compile.CountAggregateDefinition;import org.apache.derby.impl.sql.compile.MaxMinAggregateDefinition;import org.apache.derby.impl.sql.compile.SumAvgAggregateDefinition;import java.util.Vector;/** * An Aggregate Node is a node that reprsents a set function/aggregate. * It used for all system aggregates as well as user defined aggregates. * * @author jamie */public class AggregateNode extends UnaryOperatorNode{	private boolean					distinct;	private AggregateDefinition		uad;	private StringBuffer			aggregatorClassName;	private String					aggregateDefinitionClassName;	private Class					aggregateDefinitionClass;	private ClassInspector			classInspector;	private String					aggregateName;	/*	** We wind up pushing all aggregates into a different	** resultColumnList.  When we do this (in 	** replaceAggregateWithColumnReference), we return a	** column reference and create a new result column.	** This is used to store that result column.	*/	private ResultColumn			generatedRC;	private ColumnReference			generatedRef;	/**	 * Intializer.  Used for user defined and internally defined aggregates.	 * Called when binding a StaticMethodNode that we realize is an aggregate.	 *	 * @param operand	the value expression for the aggregate	 * @param uadClass	the class name for user aggregate definition for the aggregate	 *					or the Class for the internal aggregate type.	 * @param distinct	boolean indicating whether this is distinct	 *					or not.	 * @param aggregateName	the name of the aggregate from the user's perspective,	 *					e.g. MAX	 *	 * @exception StandardException on error	 */	public void init	(		Object	operand,		Object		uadClass,		Object		distinct,		Object		aggregateName	) throws StandardException	{		super.init(operand);		this.aggregateName = (String) aggregateName;		if (uadClass instanceof String)		{			this.aggregateDefinitionClassName = (String) uadClass;			this.distinct = ((Boolean) distinct).booleanValue();		}		else		{			this.aggregateDefinitionClass = (Class) uadClass;			this.aggregateDefinitionClassName =										aggregateDefinitionClass.getName();			// Distinct is meaningless for min and max			if (!aggregateDefinitionClass.equals(MaxMinAggregateDefinition.class))			{				this.distinct = ((Boolean) distinct).booleanValue();			}		}	}	/**	 * Replace aggregates in the expression tree with a ColumnReference to	 * that aggregate, append the aggregate to the supplied RCL (assumed to	 * be from the child ResultSetNode) and return the ColumnReference.	 * This is useful for pushing aggregates in the Having clause down to	 * the user's select at parse time.  It is also used for moving around 	 * Aggregates in the select list when creating the Group By node.  In 	 * that case it is called <B> after </B> bind time, so we need to create	 * the column differently.	 *	 * @param childRCL	The RCL to append to.	 * @param tableNumber	The tableNumber for the new ColumnReference	 *	 * @return ValueNode	The (potentially) modified tree.	 *	 * @exception StandardException			Thrown on error	 */	public ValueNode replaceAggregatesWithColumnReferences(ResultColumnList rcl, int tableNumber)		throws StandardException	{		/*		** This call is idempotent.  Do		** the right thing if we have already		** replaced ourselves.		*/		if (generatedRef == null)		{			String					generatedColName;			CompilerContext 		cc = getCompilerContext();			generatedColName ="SQLCol" + cc.getNextColumnNumber();			generatedRC = (ResultColumn) getNodeFactory().getNode(											C_NodeTypes.RESULT_COLUMN,											generatedColName,											this,											getContextManager());			generatedRC.markGenerated();				/*			** Parse time.				*/			if (getTypeServices() == null)			{				generatedRef = (ColumnReference) getNodeFactory().getNode(												C_NodeTypes.COLUMN_REFERENCE,												generatedColName,												null,												getContextManager());			}			else			{				generatedRef = (ColumnReference) getNodeFactory().getNode(												C_NodeTypes.COLUMN_REFERENCE,												generatedRC.getName(),												null,												getContextManager());				generatedRef.setType(this.getTypeServices());			}			// RESOLVE - unknown nesting level, but not correlated, so nesting levels must be 0			generatedRef.setNestingLevel(0);			generatedRef.setSourceLevel(0);			if (tableNumber != -1)			{				generatedRef.setTableNumber(tableNumber);			}			rcl.addResultColumn(generatedRC);			/* 			** Mark the ColumnReference as being generated to replace			** an aggregate			*/			generatedRef.markGeneratedToReplaceAggregate();		}		else		{			rcl.addResultColumn(generatedRC);		}		return generatedRef;	}	/**	 * Get the AggregateDefinition.	 *	 * @return The AggregateDefinition	 */	AggregateDefinition getAggregateDefinition()	{		return uad;	}	/**	 * Get the generated ResultColumn where this	 * aggregate now resides after a call to 	 * replaceAggregatesWithColumnReference().	 *	 * @return the result column	 */	public ResultColumn getGeneratedRC()	{		if (SanityManager.DEBUG)		{			SanityManager.ASSERT(generatedRC != null, 				"generatedRC is null.  replaceAggregateWithColumnReference() "+				"has not been called on this AggergateNode.  Make sure "+				"the node is under a ResultColumn as expected.");		}							return generatedRC;	}	/**	 * Get the generated ColumnReference to this	 * aggregate after the parent called	 * replaceAggregatesWithColumnReference().	 *	 * @return the column reference	 */	public ColumnReference getGeneratedRef()	{		if (SanityManager.DEBUG)		{			SanityManager.ASSERT(generatedRef != null, 				"generatedRef is null.  replaceAggregateWithColumnReference() "+				"has not been called on this AggergateNode.  Make sure "+				"the node is under a ResultColumn as expected.");		}		return generatedRef;	}	/**	 * Bind this operator.  Determine the type of the subexpression,	 * and pass that into the UserAggregate.	 *	 * @param fromList			The query's FROM list	 * @param subqueryList		The subquery list being built as we find SubqueryNodes	 * @param aggregateVector	The aggregate list being built as we find AggregateNodes	 *	 * @return	The new top of the expression tree.	 *	 * @exception StandardException		Thrown on error	 */	public ValueNode bindExpression(					FromList			fromList,					SubqueryList		subqueryList,					Vector				aggregateVector)			throws StandardException	{		TypeId	outType;		TypeId	inputType = null;		Class				inputClass = null;		String				inputTypeName = null;		Class				inputInterfaceClass = null;		String				inputInterfaceName = null;		DataTypeDescriptor 	dts = null;		TypeDescriptor 		resultType = null;		ClassFactory		cf;		cf = getClassFactory();		classInspector = cf.getClassInspector();		instantiateAggDef();		/* Add ourselves to the aggregateVector before we do anything else */		aggregateVector.addElement(this);		super.bindExpression(				fromList, subqueryList,				aggregateVector);		if (operand != null)		{			/*			** Make sure that we don't have an aggregate 			** IMMEDIATELY below us.  Don't search below			** any ResultSetNodes.			*/			HasNodeVisitor visitor = new HasNodeVisitor(this.getClass(), ResultSetNode.class);			operand.accept(visitor);			if (visitor.hasNode())			{				throw StandardException.newException(SQLState.LANG_USER_AGGREGATE_CONTAINS_AGGREGATE, 						aggregateName);			}			/*			** Check the type of the operand.  Make sure that the user			** defined aggregate can handle the operand datatype.			*/			dts = operand.getTypeServices();			/* Convert count(nonNullableColumn) to count(*)	*/			if (uad instanceof CountAggregateDefinition &&				!dts.isNullable())			{				setOperator(aggregateName);				setMethodName(aggregateName);			}			/*			** If we have a distinct, then the value expression			** MUST implement Orderable because we are going			** to process it using it as part of a sort.			*/

⌨️ 快捷键说明

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