/*

   Derby - Class org.apache.derby.impl.sql.compile.AggregateNode

   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to you 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 java.util.List;
import org.apache.derby.catalog.AliasInfo;
import org.apache.derby.catalog.TypeDescriptor;
import org.apache.derby.catalog.types.AggregateAliasInfo;
import org.apache.derby.iapi.error.StandardException;
import org.apache.derby.iapi.reference.SQLState;
import org.apache.derby.iapi.services.compiler.MethodBuilder;
import org.apache.derby.iapi.services.context.ContextManager;
import org.apache.derby.iapi.services.loader.ClassFactory;
import org.apache.derby.iapi.services.loader.ClassInspector;
import org.apache.derby.shared.common.sanity.SanityManager;
import org.apache.derby.iapi.sql.compile.CompilerContext;
import org.apache.derby.iapi.sql.compile.Visitor;
import org.apache.derby.iapi.sql.dictionary.AliasDescriptor;
import org.apache.derby.iapi.sql.dictionary.DataDictionary;
import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
import org.apache.derby.iapi.types.DataTypeDescriptor;

/**
 * An Aggregate Node is a node that represents a set function/aggregate.
 * It used for all system aggregates as well as user defined aggregates.
 */

class AggregateNode extends UnaryOperatorNode
{
    static final class BuiltinAggDescriptor
    {
        public  final   String  aggName;
        public  final   String  aggClassName;
        public  final   TypeDescriptor  argType;
        public  final   TypeDescriptor  returnType;

        public BuiltinAggDescriptor
            (
             String aggName,
             String aggClassName,
             TypeDescriptor argType,
             TypeDescriptor returnType
             )
        {
            this.aggName = aggName;
            this.aggClassName = aggClassName;
            this.argType = argType;
            this.returnType = returnType;
        }
    }
    
    //
    // Builtin aggregates which implement org.apache.derby.agg.Aggregator.
    //
    private static  BuiltinAggDescriptor[]  BUILTIN_MODERN_AGGS =
    {
        new BuiltinAggDescriptor
        (
         "VAR_POP",
         "org.apache.derby.impl.sql.execute.VarPAggregator",
         TypeDescriptor.DOUBLE,
         TypeDescriptor.DOUBLE
         ),
        new BuiltinAggDescriptor
        (
         "VAR_SAMP",
         "org.apache.derby.impl.sql.execute.VarSAggregator",
         TypeDescriptor.DOUBLE,
         TypeDescriptor.DOUBLE
         ),
        new BuiltinAggDescriptor
        (
         "STDDEV_POP",
         "org.apache.derby.impl.sql.execute.StdDevPAggregator",
         TypeDescriptor.DOUBLE,
         TypeDescriptor.DOUBLE
         ),
        new BuiltinAggDescriptor
        (
         "STDDEV_SAMP",
         "org.apache.derby.impl.sql.execute.StdDevSAggregator",
         TypeDescriptor.DOUBLE,
         TypeDescriptor.DOUBLE
         ),
    };
    
	private boolean					distinct;

	private AggregateDefinition		uad;
    private TableName           userAggregateName;
	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;

    /**
     * Constructed when binding a StaticMethodNode that we realize is
     * an aggregate.
     *
     * @param operand the value expression for the aggregate
     * @param uadClass the class of the user aggregate definition
     * @param alias the name by which the aggregate was called
     * @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
     * @param cm context manager
     * @throws StandardException
     */
     AggregateNode(
            ValueNode operand,
            UserAggregateDefinition uadClass,
            TableName alias,
            boolean distinct,
            String aggregateName,
            ContextManager cm) throws StandardException {
        this(operand, alias, distinct, aggregateName, cm);
        setUserDefinedAggregate(uadClass);
    }

    /**
     * @param operand the value expression for the aggregate
     * @param uadClass the class name for user aggregate definition
     * for the aggregate
     * @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
     * @param cm context manager
     * @throws StandardException
     */
    AggregateNode(
            ValueNode operand,
            TableName uadClass,
            boolean distinct,
            String aggregateName,
            ContextManager cm) throws StandardException {
        super(operand, cm);
        this.aggregateName = aggregateName;
        this.userAggregateName = uadClass;
        this.distinct = distinct;
    }

    /**
     * @param operand the value expression for the aggregate
     * @param uadClass 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
     * @param cm context manager
     * @throws StandardException
     */
    AggregateNode(
            ValueNode operand,
            Class<?> uadClass,
            boolean distinct,
            String aggregateName,
            ContextManager cm) throws StandardException {
        super(operand, cm);
        this.aggregateName = aggregateName;
        this.aggregateDefinitionClass = uadClass;

        // Distinct is meaningless for min and max
        if (!aggregateDefinitionClass.equals(MaxMinAggregateDefinition.class)) {
            this.distinct = distinct;
        }

        this.aggregateDefinitionClassName = aggregateDefinitionClass.getName();
    }


    /** initialize fields for user defined aggregate */
    private void setUserDefinedAggregate( UserAggregateDefinition userAgg )
    {
        this.uad = userAgg;
        this.aggregateDefinitionClass = uad.getClass();
        this.aggregateDefinitionClassName = aggregateDefinitionClass.getName();
    }

	/**
	 * 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 rcl	The RCL to append to.
	 * @param tableNumber	The tableNumber for the new ColumnReference
	 *
	 * @return ValueNode	The (potentially) modified tree.
	 *
	 * @exception StandardException			Thrown on error
	 */
    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 =
                new ResultColumn(generatedColName, this, getContextManager());
			generatedRC.markGenerated();
	
			/*
			** Parse time.	
			*/
            generatedRef = new ColumnReference(generatedRC.getName(),
                                               null,
                                               getContextManager());

			// RESOLVE - unknown nesting level, but not correlated, so nesting levels must be 0
            generatedRef.setSource(generatedRC);
			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
	 */
    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
	 */
    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 aggregates        The aggregate list being built as we find AggregateNodes
	 *
	 * @return	The new top of the expression tree.
	 *
	 * @exception StandardException		Thrown on error
	 */
    @Override
    ValueNode bindExpression(
        FromList fromList, SubqueryList subqueryList, List<AggregateNode> aggregates)
			throws StandardException
	{
        DataDictionary  dd = getDataDictionary();
		DataTypeDescriptor 	dts = null;
		ClassFactory		cf;

		cf = getClassFactory();
		classInspector = cf.getClassInspector();

        boolean noSchema = true;
        if ( userAggregateName != null )
        {
            noSchema = (userAggregateName.getSchemaName() == null );
            userAggregateName.bind();
        }

        // If this is a user-defined aggregate that hasn't been bound yet,
        // bind it now.
        if (userAggregateName != null && uad == null)
        {
            String  schemaName = userAggregateName.getSchemaName();
            AliasDescriptor ad = resolveAggregate
                (
                 dd,
                 getSchemaDescriptor( schemaName, true ),
                 userAggregateName.getTableName(),
                 noSchema
                 );

            if ( ad == null )
            {
                throw StandardException.newException
                    (
                     SQLState.LANG_OBJECT_NOT_FOUND,
                     AliasDescriptor.getAliasType( AliasInfo.ALIAS_TYPE_AGGREGATE_AS_CHAR ),
                     userAggregateName.getTableName()
                     );
            }
            
            setUserDefinedAggregate( new UserAggregateDefinition( ad ) );
            aggregateName = ad.getJavaClassName();
         }

		instantiateAggDef();

        // if this is a user-defined aggregate
        if ( isUserDefinedAggregate() )
        {
            AliasDescriptor ad = ((UserAggregateDefinition) uad).getAliasDescriptor();
            boolean         isModernBuiltinAggregate =
                SchemaDescriptor.STD_SYSTEM_SCHEMA_NAME.equals( ad.getSchemaName() );

            if ( distinct && isModernBuiltinAggregate )
            {
                throw StandardException.newException( SQLState.LANG_BAD_DISTINCT_AGG );
            }

            // set up dependency on the user-defined aggregate and compile a check for USAGE
            // priv if needed
            getCompilerContext().createDependency( ad );

            if ( isPrivilegeCollectionRequired() )
            {
                //
                // Don't need a privilege check for modern, builtin (system)
                // aggregates. They are tricky. They masquerade as user-defined
                // aggregates because they implement org.apache.derby.agg.Aggregator
                //
                if ( !isModernBuiltinAggregate )
                {
                    getCompilerContext().addRequiredUsagePriv( ad );
                }
            }
        }

        // Add ourselves to the list of aggregates before we do anything else.
        aggregates.add(this);

        CompilerContext cc = getCompilerContext();
        
        // operand being null means a count(*)
		if (operand != null)
		{
            int previousReliability = orReliability( CompilerContext.AGGREGATE_RESTRICTION );
            bindOperand(fromList, subqueryList, aggregates);
            cc.setReliability( previousReliability );
            
			/*
			** 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, 
                     getSQLName()
                    );
			}

			// Also forbid any window function inside an aggregate unless in
			// subquery, cf. SQL 2003, section 10.9, SR 7 a).
			SelectNode.checkNoWindowFunctions(operand, 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.
			*/
			if (distinct)
			{
				/*
				** For now, we check to see if orderable() returns
				** true for this type.  In the future we may need
				** to check to see if the type implements Orderable
				**
				*/
				if (!operand.getTypeId().orderable(cf))
				{
					throw StandardException.newException(SQLState.LANG_COLUMN_NOT_ORDERABLE_DURING_EXECUTION, 
							dts.getTypeId().getSQLTypeName());
				}

			}

			/*
			** Don't allow an untyped null
			*/
			if (operand instanceof UntypedNullConstantNode)
			{
				throw StandardException.newException
                    (SQLState.LANG_USER_AGGREGATE_BAD_TYPE_NULL, getSQLName());
			}
		}

		/*
		** Ask the aggregate definition whether it can handle
	 	** the input datatype.
	 	*/
        aggregatorClassName = new StringBuffer();
        DataTypeDescriptor resultType = uad.getAggregator(dts, aggregatorClassName);

		if (resultType == null)
		{
			throw StandardException.newException
                (
                 SQLState.LANG_USER_AGGREGATE_BAD_TYPE, 
                 getSQLName(), 
                 operand.getTypeId().getSQLTypeName()
                 );
		}

        // For user-defined aggregates, the input operand may need to be
        // coerced to the expected input type of the aggregator.
        if ( isUserDefinedAggregate() )
        {
            ValueNode   castNode = ((UserAggregateDefinition) uad).castInputValue
                ( operand, getContextManager() );

            if ( castNode != null )
            {
                operand = castNode.bindExpression( fromList, subqueryList, aggregates );
            }
        }

		checkAggregatorClassName(aggregatorClassName.toString());

		setType(resultType);

		return this;
	}

	/**
	 * Resolve a user-defined aggregate.
	 */
    static AliasDescriptor resolveAggregate
        ( DataDictionary dd, SchemaDescriptor sd, String rawName, boolean noSchema )
        throws StandardException
    {
        // first see if this is one of the builtin aggregates which
        // implements the Aggregator interface
        AliasDescriptor ad = resolveBuiltinAggregate( dd, rawName, noSchema );
        if ( ad != null ) { return ad; }
        
        // if the schema has a null UUID, that means the schema has not
        // been created yet. in that case, it doesn't have any aggregates in it.
        if ( sd.getUUID() == null ) { return null; }
        
        java.util.List<AliasDescriptor> list = dd.getRoutineList
            ( sd.getUUID().toString(), rawName, AliasInfo.ALIAS_NAME_SPACE_AGGREGATE_AS_CHAR );

        if ( list.size() > 0 ) { return list.get( 0 ); }

        return null;
    }

    /**
     * Construct an AliasDescriptor for a modern builtin aggregate.
     */
    private static AliasDescriptor resolveBuiltinAggregate
        ( DataDictionary dd, String rawName, boolean noSchema )
        throws StandardException
    {
        // builtin aggregates may not be schema-qualified
        if ( !noSchema ) { return null; }

        BuiltinAggDescriptor    bad = null;

        for ( BuiltinAggDescriptor aggDescriptor : BUILTIN_MODERN_AGGS )
        {
            if ( aggDescriptor.aggName.equals( rawName ) )
            {
                bad = aggDescriptor;
                break;
            }
        }
        if ( bad == null ) { return null; }

        AliasInfo   aliasInfo = new AggregateAliasInfo( bad.argType, bad.returnType );
        
        return new AliasDescriptor
            (
             dd,
             null,
             rawName,
             dd.getSystemSchemaDescriptor().getUUID(),
             bad.aggClassName,
             AliasInfo.ALIAS_TYPE_AGGREGATE_AS_CHAR,
             AliasInfo.ALIAS_NAME_SPACE_AGGREGATE_AS_CHAR,
             false,
             aliasInfo,
             null
             );
    }
    
	/*
	** Make sure the aggregator class is ok
	*/
	private void checkAggregatorClassName(String className) throws StandardException
	{
		verifyClassExist(className);

		if (!classInspector.assignableTo(className, "org.apache.derby.iapi.sql.execute.ExecAggregator"))
		{
			throw StandardException.newException(SQLState.LANG_BAD_AGGREGATOR_CLASS2, 
													className, 
													getSQLName(),
													operand.getTypeId().getSQLTypeName());
		}
	}

		
	/*
	** Instantiate the aggregate definition.
	*/
	private void instantiateAggDef() throws StandardException
	{
        if ( uad == null )
        {
            Class<?> theClass = aggregateDefinitionClass;

            // get the class
            if (theClass == null)
            {
                String aggClassName = aggregateDefinitionClassName;
                verifyClassExist(aggClassName);

                try
                {
                    theClass = classInspector.getClass(aggClassName);
                }
                catch (Throwable t)
                {
                    throw StandardException.unexpectedUserException(t);
                }
            }

            // get an instance
            Object instance = null;
            try
            {
                instance = theClass.getConstructor().newInstance();
            }
            catch (Throwable t)
            {
                throw StandardException.unexpectedUserException(t);
            }

            if (!(instance instanceof AggregateDefinition))
            {
                throw StandardException.newException(SQLState.LANG_INVALID_USER_AGGREGATE_DEFINITION2, aggregateDefinitionClassName);
            }

            if (instance instanceof MaxMinAggregateDefinition)
            {
                MaxMinAggregateDefinition temp = (MaxMinAggregateDefinition)instance;
                if (aggregateName.equals("MAX"))
                    temp.setMaxOrMin(true);
                else
                    temp.setMaxOrMin(false);
            }

            if (instance instanceof SumAvgAggregateDefinition)
            {
                SumAvgAggregateDefinition temp1 = (SumAvgAggregateDefinition)instance;
                if (aggregateName.equals("SUM"))
                    temp1.setSumOrAvg(true);
                else
                    temp1.setSumOrAvg(false);
            }

            this.uad = (AggregateDefinition)instance;
        }
	
		setOperator(aggregateName);
		setMethodName(aggregateDefinitionClassName);
	}

	/**
	 * Indicate whether this aggregate is distinct or not.
	 *
	 * @return 	true/false
	 */
    boolean isDistinct()
	{
		return distinct;
	}

	/**
	 * Get the class that implements that aggregator for this
	 * node.
	 *
	 * @return the class name
	 */
    String  getAggregatorClassName()
	{
		return aggregatorClassName.toString();
	}

	/**
	 * Get the class that implements that aggregator for this
	 * node.
	 *
	 * @return the class name
	 */
    String  getAggregateName()
	{
		return aggregateName;
	}

	/**
	 * Get the result column that has a new aggregator.
	 * This aggregator will be fed into the sorter.
	 *
	 * @param dd	the data dictionary
	 *
	 * @return the result column.  WARNING: it still needs to be bound
	 *
	 * @exception StandardException on error
	 */
    ResultColumn    getNewAggregatorResultColumn(DataDictionary dd)
		throws StandardException
	{
		String	className = aggregatorClassName.toString();

		DataTypeDescriptor compType =
            DataTypeDescriptor.getSQLDataTypeDescriptor(className);

		/*
		** Create a null of the right type.  The proper aggregators
		** are created dynamically by the SortObservers
		*/
		ConstantNode nullNode = getNullNode(compType);

		nullNode.bindExpression(
						null,	// from
						null,	// subquery
						null);	// aggregate

		/*
		** Create a result column with this new node below
		** it.
		*/
        return new ResultColumn(aggregateName, nullNode, getContextManager());
	}


	/**
	 * Get the aggregate expression in a new result
	 * column.
	 *
	 * @param dd the data dictionary
	 *
	 * @return the result column.  WARNING: it still needs to be bound
	 *
	 * @exception StandardException on error
	 */
    ResultColumn    getNewExpressionResultColumn(DataDictionary dd)
		throws StandardException
	{
		ValueNode		node;
		/*
		** Create a result column with the aggrergate operand
		** it.  If there is no operand, then we have a COUNT(*),
		** so we'll have to create a new null node and put
		** that in place.
		*/
		node = (operand == null) ?
			this.getNewNullResultExpression() :
			operand;

        return new ResultColumn(
            "##aggregate expression", node, getContextManager());
	}

	/**
	 * Get the null aggregate result expression
	 * column.
	 *
	 * @return the value node
	 *
	 * @exception StandardException on error
	 */
    ValueNode   getNewNullResultExpression()
		throws StandardException
	{
		/*
		** Create a result column with the aggrergate operand
		** it.
		*/
		return getNullNode(getTypeServices());
	}

	/**
	 * Do code generation for this unary operator.  Should
	 * never be called for an aggregate -- it should be converted
	 * into something else by code generation time.
	 *
	 * @param acb	The ExpressionClassBuilder for the class we're generating
	 * @param mb	The method the code to place the code
	 *
	 * @exception StandardException		Thrown on error
	 */
    @Override
    void generateExpression(ExpressionClassBuilder acb, MethodBuilder mb)
		throws StandardException
	{
		if (SanityManager.DEBUG)
		{
			SanityManager.THROWASSERT("generateExpression() should never "+
					"be called on an AggregateNode.  "+
					"replaceAggregatesWithColumnReferences should have " +
					"been called prior to generateExpression");
		}
	}

	/**
	 * Print a string ref of this node.
	 *
	 * @return a string representation of this node 
	 */
    @Override
	public String toString()
	{
		if (SanityManager.DEBUG)
		{
			return "aggregateName: " + getSQLName() + "\n" +
				"distinct: " + distinct + "\n" +
				super.toString();
		}
		else
		{
			return "";
		}
	}

    boolean isConstant()
	{
		return false;
	}
	
    @Override
    boolean constantExpression(PredicateList where)
	{
		return false;
	}

    /** Get the SQL name of the aggregate */
    public  String  getSQLName()
    {
        if ( isUserDefinedAggregate() )
        {
            return ((UserAggregateDefinition) uad).
                    getAliasDescriptor().getQualifiedName();
        }
        else { return aggregateName; }
    }
    
    /** Return true if this is a user-defined aggregate */
    private boolean isUserDefinedAggregate()
    {
        return uad instanceof UserAggregateDefinition;
    }

    @Override
    void acceptChildren(Visitor v) throws StandardException {
        super.acceptChildren(v);

        if (userAggregateName != null) {
            userAggregateName = (TableName) userAggregateName.accept(v);
        }
    }
}
