/**********************************************************************
// @@@ START COPYRIGHT @@@
//
// 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.
//
// @@@ END COPYRIGHT @@@
**********************************************************************/
/* -*-C++-*-
******************************************************************************
*
* File:         MavRelRootBuilder.cpp
* Description:  Class MavRelRootBuilder, used by MavBuilder
*               for MV INTERNAL REFRESH command.
*
* Created:      12/27/2000
* Language:     C++
* Status:       $State: Exp $
*
*
******************************************************************************
*/

#include "Sqlcomp.h"  // for SQLDoublePrecision
#include "AllItemExpr.h"
#include "AllRelExpr.h"
#include "MVInfo.h"
#include "MvRefreshBuilder.h"
#include "MavRelRootBuilder.h"

// ===========================================================================
// ===========================================================================
// ===================  class  MavRelRootBuilder    =========================
// ===========================================================================
// ===========================================================================

//----------------------------------------------------------------------------
// 
MavRelRootBuilder::MavRelRootBuilder(const MVInfoForDML *mvInfo, 
                                     CollHeap           *heap)
  : heap_           (heap),
    posOfCountStar_ (mvInfo->getPosOfCountStar()),
    mavCols_        (mvInfo->getMVColumns()),
    deltaCorrName_  (MavBuilder::getSysDeltaName(), heap_),
    mavCorrName_    (MavBuilder::getSysMavName(),   heap_),
    calcCorrName_   (MavBuilder::getSysCalcName(),  heap_),
    countCols_      (heap_),
    sumCols_        (heap_),
    otherCols_      (heap_),
    groupByCols_    (heap_),
    extraMinMaxColRefs_(heap_),
    minMaxRecomputeOnUpdateCondition_(NULL),
    minMaxRecomputeOnInsertCondition_(NULL),
    isMavWithoutGroupBy_(FALSE)
{
}

//----------------------------------------------------------------------------
// No need to directly delete any of the pointers, because they all point 
// to data belonging to MVInfo. The only thing we need to do is clear 
// extraMinMaxColRefs_, because the ItemExprList Dtor deletes contained
// pointers.
MavRelRootBuilder::~MavRelRootBuilder() 
{
  extraMinMaxColRefs_.clear();
}

//----------------------------------------------------------------------------
// Prepare for creating the SYS_CALC columns, by divide the list of MAV 
// columns to 4 groups:
// 1. GroupBy columns - inserted directly into the RETDesc without change.
// 2. COUNT columns               - collected in countCols_, done in phase1.
// 3. SUM, MIN and MAX columns    - collected in sumCols_, done in phase2.
// 4. AVG, STDDEV, VARIANCE cols  - collected in otherCols_, done in phase3.
void MavRelRootBuilder::init()
{
  // Divide the MAV columns to groups:
  for (CollIndex i=0; i<mavCols_.entries(); i++)
  {
    MVColumnInfo *currentCol = mavCols_[i];

    if (currentCol->getColType() != COM_MVCOL_AGGREGATE)
    {  
      // This is a group-by column, or a constant that does not change.
      groupByCols_.insert(currentCol);
    }
    else
    {
      // This is an aggregate column. insert into the correct list.
      switch (currentCol->getOperatorType())
      {
	case ITM_COUNT: 
	case ITM_COUNT_NONULL: 
	  // No dependent columns, done in phase1.
	  countCols_.insert(currentCol);
	  break;

	case ITM_SUM:
	case ITM_MIN:
	case ITM_MAX:
	  // Use the SYS_CALC COUNT columns, done in phase2.
	  sumCols_.insert(currentCol);
	  break;

	case ITM_AVG:
	case ITM_STDDEV:
	case ITM_VARIANCE:
	  // Use the SYS_CALC COUNT and SUM columns, done in phase3.
	  otherCols_.insert(currentCol);
	  break;

	default:
	  CMPASSERT(FALSE);
      }
    }
  }
}  // MavRelRootBuilder::init()

//////////////////////////////////////////////////////////////////////////////
// Build a stack of 5 RelRoot nodes to calculate the SYS_CALC columns:
//     RelRoot (*, <GOP column>)
//        |
//     RelRoot (*, <AVG, STDDEV & VARIANCE cols>)
//        |
//     RelRoot (*, <sum, min & max columns>)
//        |
//     RelRoot (*, <count columns>)
//        |
//     topNode
//
//////////////////////////////////////////////////////////////////////////////
RelExpr *MavRelRootBuilder::buildCalcCalculationRootNodes(RelExpr *dcbTree)
{
  RelRoot *topNode;
  topNode = buildRootForCount (dcbTree);
  topNode = buildRootForSum   (topNode);
  topNode = buildRootForOthers(topNode);
  topNode = buildRootForGop   (topNode);

  topNode->addSelPredTree(buildSelfCancelingDeltaPredicate());

  return topNode;
}  // MavRelRootBuilder::buildCalcCalculationRootNodes(

//////////////////////////////////////////////////////////////////////////////
// First work on the RelRoot of the MAV select tree to fix the aggregate
// expressions for COUNT, SUM, MIN and MAX, and remove expressions for
// AVG, STDDEV and VARIANCE.
// Then, add another root node to re-introduce expressions for AVG, STDDEV
// and VARIANCE. this time using the fixed expressions of the first root node.
// The result tree is:
//     RelRoot (*, <AVG, STDDEV and VARIANCE columns>)
//        |
//   RenameTable  (to SYS_DELTA)
//        |
//   mvSelectTree (with a fixed select list
//////////////////////////////////////////////////////////////////////////////
RelExpr *MavRelRootBuilder::buildDeltaCalculationRootNodes(RelExpr  *mvSelectTree,
							   NABoolean canSkipMinMax,
							   NABoolean wasFullDE)
{
  checkForMavWithoutGroupBy(mvSelectTree);
  fixDeltaColumns(mvSelectTree, canSkipMinMax, wasFullDE);

  RelExpr *topNode = new(heap_) 
    RenameTable(mvSelectTree, MavBuilder::getSysDeltaName());

  if (isMavWithoutGroupBy())
    topNode = buildRootForNoGroupBy(topNode);

  topNode = buildRootForDelta(topNode);

  return topNode;
}  // MavRelRootBuilder::buildDeltaCalculationRootNodes()

//----------------------------------------------------------------------------
// Check if the query for this MAV is without a GROUP BY clause.
// The RelExpr tree for a query with no GROUP BY clause, does not have
// a GroupBy node in it. 
void MavRelRootBuilder::checkForMavWithoutGroupBy(RelExpr *mvSelectTree) 
{
  // Start from the top of the RelExpe tree.
  RelExpr *node = mvSelectTree;
  // Look for a GroupBy node.
  while (node->child(0) != NULL &&
         node->getOperatorType() != REL_GROUPBY)
    node = node->child(0);

  if (node->getOperatorType() != REL_GROUPBY)
    isMavWithoutGroupBy_ = TRUE;
  else
  {
    // Check if the child of our child is another GroupBy node.
    // This can only be the result of multi-delta optimization on a 
    // no-groupby MAV.
    if ( (node->child(0)->getOperatorType() == REL_ROOT)            &&
         (node->child(0)->child(0)->getOperatorType() == REL_GROUPBY) )
    {
      // Found another GroupBy node below.
      // Now verify that the top one has no grouping columns.
      GroupByAgg *groupByNode = (GroupByAgg *)node;
      if (groupByNode->getGroupExprTree() == NULL)
	isMavWithoutGroupBy_ = TRUE;
    }
  }
}  // MavRelRootBuilder::checkForMavWithoutGroupBy()

//----------------------------------------------------------------------------
// Transform each aggregate in the MAV select list, to use the @OP column in
// order to calculate deleted rows correctly:
// COUNT(*) => SUM(@OP)
// COUNT(a) => SUM(IF (a IS NULL) THEN 0 ELSE @OP) 
// SUM(a)   => SUM(a * @OP)
// MIN(a) & MAX(a) => Special treatment (see handleDeltaMinMaxColumns()).
// AVG, STDDEV and VARIANCE are derived from other COUNT and SUM columns. 
// They are removed from this select list to avoid divide by zero problems
// in case COUNT=0.
void MavRelRootBuilder::fixDeltaColumns(RelExpr   *mvSelectTree, 
					NABoolean  canSkipMinMax,
				        NABoolean  wasFullDE)
{
  // Get the MAV select list from the mvSelectTree.
  CMPASSERT(mvSelectTree->getOperatorType() == REL_ROOT);
  RelRoot *mavSelectRoot = (RelRoot *)mvSelectTree;

  ItemExprList mavSelectList(mavSelectRoot->removeCompExprTree(), heap_);
  ItemExprList newSelectList(heap_);

  const NAString& opName = MavBuilder::getVirtualOpColumnName();

  for (CollIndex i=0; i<mavSelectList.entries(); i++)
  {
    ItemExpr *selectListExpr = mavSelectList[i];

    CMPASSERT(selectListExpr->getOperatorType() == ITM_RENAME_COL);
    const NAString& colName = 
      ((RenameCol*)selectListExpr)->getNewColRefName()->getColName();
    ItemExpr *aggregateExpr = selectListExpr;
    while ((aggregateExpr->getOperatorType() == ITM_RENAME_COL) ||
           (aggregateExpr->getOperatorType() == ITM_CAST))
      aggregateExpr = aggregateExpr->child(0);

    // Assuming all aggregates are top-most functions as explained in the 
    // MV external spec.
    ItemExpr *aggregateOperand = aggregateExpr->child(0);
    ItemExpr *newExpr   = NULL;

    if (!aggregateExpr->containsAnAggregate())
    {
      // Non-aggregate columns (group-by cols) are added unchanged.
    }
    else
      switch (aggregateExpr->getOperatorType())
      {
	case ITM_COUNT_NONULL:
	  // COUNT(a) => SUM(IF (a IS NULL) THEN 0 ELSE @OP) 
	  newExpr = new(heap_) 
	    Aggregate(ITM_SUM, new(heap_) 
	      Case(NULL, new(heap_)
		IfThenElse (new(heap_) UnLogic(ITM_IS_NULL, aggregateOperand),
    			    new(heap_) SystemLiteral(0),
			    new(heap_) ColReference(new(heap_) 
			      ColRefName(opName)))));
	  selectListExpr->child(0) = newExpr;
	  break;

	case ITM_COUNT:
	  // COUNT(*) => SUM(@OP)
	  newExpr = new(heap_) 
	    Aggregate(ITM_SUM, 
    		      new(heap_) ColReference(new(heap_) ColRefName(opName)));
	  selectListExpr->child(0) = newExpr;
	  break;

	case ITM_SUM:
	  // SUM(a) => SUM(a * @OP)
	  newExpr = new(heap_)
	    BiArith(ITM_TIMES,
		    aggregateOperand,
		    new(heap_) ColReference(new(heap_) ColRefName(opName)));
	  aggregateExpr->child(0) = newExpr;
	  break;

	case ITM_MIN:
	case ITM_MAX:
	  // Handle Min/Max if not all deltas are INSERT ONLY.
	  if (!canSkipMinMax)
	    handleDeltaMinMaxColumns(aggregateExpr, colName, newSelectList, wasFullDE);
	  // Add the SYS_DELTA Min/Max aggregate as is.
	  break;

	case ITM_AVG:
	case ITM_DIVIDE:
	case ITM_VARIANCE:
	case ITM_STDDEV:
	  // Remove these expressions from the select list.
	  selectListExpr = NULL;
	  break;

	default:
	  // A new type of aggregate?
	  CMPASSERT(FALSE);
	  break;
      }

    if (selectListExpr!=NULL)
      newSelectList.insert(selectListExpr);
  }

  ItemExpr *selList = newSelectList.convertToItemExpr();
  mavSelectRoot->addCompExprTree(selList);

  mavSelectList.clear(); // Don't delete all the entries from the Dtor.
}  // MavRelRootBuilder::fixDeltaColumns()

//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
void MavRelRootBuilder::handleDeltaMinMaxColumns(ItemExpr        *aggregateExpr,
						 const NAString&  colName,
						 ItemExprList&    newSelectList,
						 NABoolean        wasFullDE)
{
  // 1. Add the column expressions to the MAV select list
  ItemExpr *extraInsCol = 
    buildExtraMinMaxExpr(aggregateExpr, colName, AGG_FOR_INSERT);
  newSelectList.insert(extraInsCol);

  ItemExpr *extraDelCol = 
    buildExtraMinMaxExpr(aggregateExpr, colName, AGG_FOR_DELETE);
  newSelectList.insert(extraDelCol);

  // 2. Create column references to the new columns.
  ColReference *colInsRef = new(heap_) 
    ColReference(createExtraAggName(colName, AGG_FOR_INSERT));
  extraMinMaxColRefs_.insert(colInsRef->copyTree(heap_));
  ColReference *colDelRef = new(heap_) 
    ColReference(createExtraAggName(colName, AGG_FOR_DELETE));
  extraMinMaxColRefs_.insert(colDelRef->copyTree(heap_));

  // 3. Build the MinMax recompute conditional expression.
  // The last parameter should be TRUE only if a full DE was performed
  // by the refresh utility.
  addToMinMaxRecomputeCondition(colName, colInsRef, colDelRef, 
				aggregateExpr->getOperatorType(), 
				wasFullDE);
}  // MavRelRootBuilder::handleDeltaMinMaxColumns()

//----------------------------------------------------------------------------
// The select list here is: (<fixed-count-cols>, <sum-col-refs>)
// The count cols become:
// Case( If <count-col> IS NULL THEN 0 ELSE <count-col>)
// Since the count cols were transformed from COUNT to SUM(@OP), They will 
// now evaluate to NULL instead of 0 when no data is returned, for MAVs 
// without a GROUP BY clause. This is what is fixed here.
//----------------------------------------------------------------------------
RelRoot *MavRelRootBuilder::buildRootForNoGroupBy(RelExpr *topNode)
{
  ItemExprList selectList(heap_);

  for (CollIndex i=0; i<countCols_.entries(); i++)
  {
    const MVColumnInfo *currentMavColumn = countCols_[i];
    const NAString& colName = currentMavColumn->getColName();

    // Build a col reference to the SYS_DELTA column.
    ItemExpr *sysDeltaColExpr = new(heap_)
      ColReference(new(heap_) ColRefName(colName, deltaCorrName_));

    ItemExpr *condExpr = new(heap_)
      Case(NULL, new(heap_)
	IfThenElse(new(heap_) UnLogic(ITM_IS_NULL, sysDeltaColExpr),
		   new(heap_) SystemLiteral(0),
		   sysDeltaColExpr->copyTree(heap_)));

    ItemExpr *renamedColExpr = new(heap_) 
      RenameCol(condExpr, new(heap_) ColRefName(colName, deltaCorrName_));

    selectList.insert(renamedColExpr);
  }

  // Add the SUM cols.
  addColsToSelectList(sumCols_, selectList, deltaCorrName_);

  // Add the extra Min/Max columns.
  selectList.insert(extraMinMaxColRefs_);

  // The select list is ready. Create the root over topNode.
  RelRoot *newRoot = new(heap_) 
    RelRoot(topNode, REL_ROOT, selectList.convertToItemExpr());
  newRoot->setDontOpenNewScope();

  selectList.clear();
  return newRoot;
}  // MavRelRootBuilder::buildRootForNoGroupBy()

//----------------------------------------------------------------------------
// The select list is: (<fixed-count-cols>, <col-ref-to-sum-cols>, 
//----------------------------------------------------------------------------
RelRoot *MavRelRootBuilder::buildRootForDelta(RelExpr *topNode)
{
  // Start the select list with SYS_MAV.*
  ColRefName *star = new(heap_) ColRefName(TRUE, heap_);
  ItemExpr *starReference = new(heap_) ColReference(star);

  const CorrName emptyCorrName("", heap_);

  ItemExprList newColumns(heap_);
  newColumns.insert(starReference);

  for (CollIndex i=0; i<otherCols_.entries(); i++)
  {
    const MVColumnInfo *currentMavColumn = otherCols_[i];
    const NAString& colName = currentMavColumn->getColName();

    const NAType *desiredType = new(heap_) SQLDoublePrecision(heap_, TRUE);
    ItemExpr *countDepCol = buildDepColExpr(emptyCorrName, currentMavColumn->getDepCol1());
    ItemExpr *sumDepCol   = buildDepColExpr(emptyCorrName, currentMavColumn->getDepCol2());
    ItemExpr *sum2DepCol  = NULL;
    
    ItemExpr *newColExpr = NULL;
    switch(currentMavColumn->getOperatorType())
    {
      case ITM_AVG:
	newColExpr = new(heap_)
	  BiArith(ITM_DIVIDE, sumDepCol, countDepCol);
	break;

      case ITM_STDDEV:
      case ITM_VARIANCE:
	sum2DepCol = buildDepColExpr(emptyCorrName, currentMavColumn->getDepCol3());

	newColExpr = new(heap_)
	  ScalarVariance(currentMavColumn->getOperatorType(),
	                 new(heap_) Cast(sum2DepCol,  desiredType), 
			 new(heap_) Cast(sumDepCol,   desiredType), 
			 new(heap_) Cast(countDepCol, desiredType));
	break;

      default: CMPASSERT(FALSE);
    }

    ItemExpr *condExpr = new(heap_)
      Case(NULL, new(heap_)
	IfThenElse(new(heap_) BiRelat(ITM_EQUAL, 
				      countDepCol,
				      new(heap_) SystemLiteral(0)),
		   new(heap_) SystemLiteral(),
		   newColExpr));

    ColRefName *newColName = new(heap_) ColRefName(colName, deltaCorrName_);
    ItemExpr *renamedColExpr = new(heap_) RenameCol(condExpr, newColName);

    newColumns.insert(renamedColExpr);
  }

  // The select list is ready. Create the root over topNode.
  RelRoot *newRoot = new(heap_) 
    RelRoot(topNode, REL_ROOT, newColumns.convertToItemExpr());

  newColumns.clear();

  return newRoot;
}  // MavRelRootBuilder::buildRootForDelta()

//----------------------------------------------------------------------------
// First, do the COUNT columns.
// The select list of this root is (*, <count cols>).
// For COUNT, the SYS_CALC.col expr is:
//   SYS_MAV.col + SYS_DELTA.col
// For MAVs without a GROUP BY clause, this is later fixed by 
// buildRootForNoGroupBy().
//----------------------------------------------------------------------------
RelRoot *MavRelRootBuilder::buildRootForCount(RelExpr *topNode)
{
  // Start the select list with *
  ItemExprList selectList(heap_);
  addStarToSelectList(selectList);

  addColsToSelectList(groupByCols_, selectList, deltaCorrName_, &calcCorrName_);

  // For each column in the COUNT list
  for (CollIndex i=0; i<countCols_.entries(); i++)
  {
    MVColumnInfo *currentCol = countCols_[i];
    const NAString& colName = currentCol->getColName();

    // Find the column in the SYS_DELTA and SYS_MAV lists.
    ItemExpr *sysDeltaColExpr = new(heap_)
      ColReference(new(heap_) ColRefName(colName, deltaCorrName_));

    ItemExpr *sysMavColExpr = new(heap_)
      ColReference(new(heap_) ColRefName(colName, mavCorrName_));
      
    ItemExpr *newCalcExpr = new(heap_) 
      BiArith(ITM_PLUS, sysDeltaColExpr, sysMavColExpr);

    // Add the col expression as SYS_CALC.col
    ColRefName *calcColName = new(heap_) ColRefName(colName, calcCorrName_);
    ItemExpr *newCalcCol = new(heap_) RenameCol(newCalcExpr, calcColName);

    selectList.insert(newCalcCol);
  }

  // The select list is ready. Create the root over topNode.
  RelRoot *newRoot = new(heap_) 
    RelRoot(topNode, REL_ROOT, selectList.convertToItemExpr());
  newRoot->setDontOpenNewScope();

  selectList.clear();
  return newRoot;
}  // MavRelRootBuilder::buildRootForCount()

//----------------------------------------------------------------------------
// Next, do the SUM, MIN and MAX columns, using the already calculated 
// and bound COUNT columns (SYS_CALC.dep1).
// For col=SUM(a), the new expr is:
//   CASE
// 1)  	WHEN (SYS_CALC.dep1 = 0)     THEN NULL
// 2)  	WHEN (SYS_MAV.col IS NULL)   THEN SYS_DELTA.col
// 3)  	WHEN (SYS_DELTA.col IS NULL) THEN SYS_MAV.col
//   	ELSE SYS_MAV.col + SYS_DELTA.col
//   END
// For col=MIN(a), the else clause is replaced by (no MIN ItemExpr):
//      WHEN (SYS_MAV.col < SYS_DELTA.col) THEN SYS_MAV.col
//      ELSE SYS_DELTA.col
// For col=MAX(a), the else clause is:
//      WHEN (SYS_MAV.col > SYS_DELTA.col) THEN SYS_MAV.col
//      ELSE SYS_DELTA.col
//----------------------------------------------------------------------------
RelRoot *MavRelRootBuilder::buildRootForSum(RelExpr *topNode)
{
  // Start the select list with *
  ItemExprList selectList(heap_);
  addStarToSelectList(selectList);

  // For each column in the COUNT list
  for (CollIndex i=0; i<sumCols_.entries(); i++)
  {
    MVColumnInfo *currentCol = sumCols_[i];
    const NAString& colName = currentCol->getColName();

    // Find the column in the SYS_DELTA and SYS_MAV lists.
    ItemExpr *sysDeltaColExpr = new(heap_)
      ColReference(new(heap_) ColRefName(colName, deltaCorrName_));

    ItemExpr *sysMavColExpr = new(heap_)
      ColReference(new(heap_) ColRefName(colName, mavCorrName_));
      
    // Find the dependent SYS_CALC COUNT column.
    ItemExpr *calcDep1 = 
      buildDepColExpr(calcCorrName_, currentCol->getDepCol1());

    // Build the condition bottom-up - do the ELSE clause first.
    ItemExpr *elseClause = NULL;
    if (currentCol->getOperatorType() == ITM_SUM)
    {
      // The ELSE clause for SUM is (SYS_MAV.col + SYS_DELTA.col).
      elseClause = new(heap_) 
        BiArith(ITM_PLUS, sysDeltaColExpr, sysMavColExpr);
    }
    else
    {
      // The ELSE clause for MIN is:
      //    WHEN (SYS_MAV.col < SYS_DELTA.col) THEN SYS_MAV.col
      //    ELSE SYS_DELTA.col
      // For MAX the < operator is replaced by >.
      OperatorTypeEnum sign = 
        (currentCol->getOperatorType()==ITM_MIN ? ITM_LESS : ITM_GREATER);
      elseClause = new(heap_) 
        IfThenElse(new(heap_) BiRelat(sign, sysMavColExpr, sysDeltaColExpr),
  		   sysMavColExpr,
		   sysDeltaColExpr);
    }

    // The 3rd WHEN clause: WHEN (SYS_DELTA.col IS NULL) THEN SYS_MAV.col
    ItemExpr *when3Clause = new(heap_)
      IfThenElse(new(heap_) UnLogic(ITM_IS_NULL, sysDeltaColExpr),
		 sysMavColExpr,
		 elseClause);

    // The 2nd WHEN clause: WHEN (SYS_MAV.col IS NULL) THEN SYS_DELTA.col
    ItemExpr *when2Clause = new(heap_)
      IfThenElse(new(heap_) UnLogic(ITM_IS_NULL, sysMavColExpr),
		 sysDeltaColExpr,
		 when3Clause);

    // The 1st WHEN clause: WHEN (SYS_CALC.dep1 = 0) THEN NULL
    ItemExpr *when1Clause = new(heap_)
      IfThenElse(new(heap_) BiRelat(ITM_EQUAL, 
    				    calcDep1,
				    new(heap_) SystemLiteral(0)),
		 new(heap_) SystemLiteral(), // NULL constant
		 when2Clause);

    // Build the CASE on top.
    ItemExpr *newCalcExpr = new(heap_) Case(NULL, when1Clause);

    // Add the col expression as SYS_CALC.col
    ColRefName *calcColName = new(heap_) ColRefName(colName, calcCorrName_);
    ItemExpr *newCalcCol = new(heap_) RenameCol(newCalcExpr, calcColName);

    selectList.insert(newCalcCol);
  }

  // The select list is ready. Create the root over topNode.
  RelRoot *newRoot = new(heap_) 
    RelRoot(topNode, REL_ROOT, selectList.convertToItemExpr());
  newRoot->setDontOpenNewScope();

  selectList.clear();
  return newRoot;
}  // MavRelRootBuilder::buildRootForSum()

//----------------------------------------------------------------------------
// Next, do the other columns (AVG, STDDEV, VARIANCE), using the already
// calculated and bound COUNT and SUM columns.
// There are 3 dependent columns here (found using MVInfo):
//   dep1 is COUNT(a),
//   dep2 is SUM(a),
//   dep3 is SUM(a*a) (only for STDDEV and VARIANCE)
//   depCount is COUNT(a)
// In the case of STDDEV with a weight parameter - STDDEV(a,b), then
//   dep1 is SUM(b),
//   dep2 is SUM(a*b),
//   dep3 is SUM(a*a*b)
//   depCount is COUNT(a*b) and is the dependent column of dep2.
//
// For col=AVG(a), the new expr is:
//   CASE
//      WHEN (SYS_CALC.depCount = 0)  THEN NULL
//      ELSE SYS_CALC.dep2 / SYS_CALC.dep1
//   END
//
// For STDDEV and VARIANCE its:
//   CASE
//      WHEN (SYS_CALC.depCount = 0)  THEN NULL
//      ELSE ScalarVariance(SYS_CALC.dep3, SYS_CALC.dep2, SYS_CALC.dep1)
//   END
// depCount is the COUNT dependent column of dep2. This works also in the
// case of STDDEV with a weight parameter
//----------------------------------------------------------------------------
RelRoot *MavRelRootBuilder::buildRootForOthers(RelExpr *topNode)
{
  // Start the select list with *
  ItemExprList selectList(heap_);
  addStarToSelectList(selectList);

  // For each column in the COUNT list
  for (CollIndex i=0; i<otherCols_.entries(); i++)
  {
    MVColumnInfo *currentCol = otherCols_[i];
    const NAString& colName = currentCol->getColName();

    const NAType *desiredType = new(heap_) SQLDoublePrecision(heap_, TRUE);

    // Find the dependent SYS_CALC COUNT and SUM columns.
    ItemExpr *calcDep1 = 
      buildDepColExpr(calcCorrName_, currentCol->getDepCol1());
    ItemExpr *calcDep2 = 
      buildDepColExpr(calcCorrName_, currentCol->getDepCol2());
    ItemExpr *calcDep3 = NULL;
    ItemExpr *calcDepCount = NULL;
    if (currentCol->getOperatorType() == ITM_AVG)
    {
      calcDepCount = calcDep1;
    }
    else
    {
      // dep3 and depCount are needed only for STDDEV and VARIANCE.
      calcDep3 = buildDepColExpr(calcCorrName_, currentCol->getDepCol3());

      // depCount is the dereferenced dep1 column of dep2.
      MVColumnInfo *dep2ColInfo =
	mavCols_.getMvColInfoByIndex(currentCol->getDepCol2());
      calcDepCount = 
	buildDepColExpr(calcCorrName_, dep2ColInfo->getDepCol1());
    }

    // Build the condition bottom-up - do the ELSE clause first.
    ItemExpr *elseClause = NULL;
    if (currentCol->getOperatorType() == ITM_AVG)
    {
      // For AVG, the ELSE clause is (SYS_CALC.dep2 / SYS_CALC.dep1).
      elseClause = new(heap_)
        BiArith(ITM_DIVIDE, calcDep2, calcDep1);
    }
    else
    {
      // For STDDEV and VARIANCE, the ELSE clause is
      // ScalarVariance(SYS_CALC.dep3, SYS_CALC.dep2, SYS_CALC.dep1)
      elseClause = new(heap_)
        ScalarVariance(currentCol->getOperatorType(), 
		       new(heap_) Cast(calcDep3, desiredType), 
		       new(heap_) Cast(calcDep2, desiredType), 
		       new(heap_) Cast(calcDep1, desiredType));
    }

    // The WHEN clause is the same for AVG, STDDEV and VARIANCE:
    // WHEN (SYS_CALC.depCount = 0)  THEN NULL
    ItemExpr *whenClause = new(heap_)
      IfThenElse(new(heap_) BiRelat(ITM_EQUAL, 
				    calcDepCount,
				    new(heap_) SystemLiteral(0)),
		 new(heap_) SystemLiteral(), // NULL constant
		 elseClause);

    // Put the CASE on top.
    ItemExpr *newCalcExpr = new(heap_) Case(NULL, whenClause);

    // Add the col expression as SYS_CALC.col
    ColRefName *calcColName = new(heap_) ColRefName(colName, calcCorrName_);
    ItemExpr *newCalcCol = new(heap_) RenameCol(newCalcExpr, calcColName);

    selectList.insert(newCalcCol);
  }

  // The select list is ready. Create the root over topNode.
  RelRoot *newRoot = new(heap_) 
    RelRoot(topNode, REL_ROOT, selectList.convertToItemExpr());
  newRoot->setDontOpenNewScope();

  selectList.clear();
  return newRoot;
}  // MavRelRootBuilder::buildRootForOthers()

//----------------------------------------------------------------------------
// Finally, Add the @GOP (Group Op) column- The select list is (*, <GOP expr>)
// This column is either 1, 2, 3 or 4 (see enum GroupOpNumbers).
// This is later used as the condition that routes the request down to the
// MAV Insert, MAV Delete or MAV Update nodes.
// @GOP is defined as (cnts represents the column name for COUNT(*)):
// CASE 
//   WHEN (SYS_MAV.cnts IS NULL)	                THEN GOP_INSERT
//   WHEN (SYS_MAV.cnts = (0 - SYS_DELTA.cnts))         THEN GOP_DELETE
//   WHEN <minMaxRecomputeCondition_>                   THEN GOP_MINMAX_RECOMPUTE
//   ELSE                                                    GOP_UPDATE
// END
// The minMaxRecomputeCondition_ condition is built during the 
// buildRootForDelta() phase, and checks if any of the current Min/Max values
// were deleted, so that recalculation is needed.
//
// A predicate is added to the RelRoot node to filter self-cancelling delta
// rows. The condition for a self-cancelling row is:
//   (SYS_MAV.cnts IS NULL AND SYS_DELTA.cnts = 0)
//----------------------------------------------------------------------------
RelRoot *MavRelRootBuilder::buildRootForGop(RelExpr *topNode)
{
  // Find the MAV column name for COUNT(*).
  const NAString& countStarColName =
    mavCols_[posOfCountStar_]->getColName();

  // The condition for Insert to MAV
  ItemExpr *insCondition = new(heap_) // (MAV.cnts IS NULL)
    UnLogic(ITM_IS_NULL, 
	    new(heap_) ColReference(new(heap_) 
	      ColRefName(countStarColName, mavCorrName_)));

  // The condition for Delete from MAV
  // (MAV.cnts = (0 - SYS_DELTA.cnts))
  ItemExpr *delCondition = new(heap_)
    BiRelat(ITM_EQUAL, 
  	    new(heap_) ColReference(new(heap_) 
	      ColRefName(countStarColName, mavCorrName_)),
	    new(heap_) BiArith(ITM_MINUS, 
    			       new(heap_) SystemLiteral(0),
			       new(heap_) ColReference(new(heap_) 
			         ColRefName(countStarColName, deltaCorrName_))));

  // These are the constants for all possible GOP column values.
  ItemExpr *constInsert = new(heap_) SystemLiteral(MavBuilder::GOP_INSERT);
  ItemExpr *constDelete = new(heap_) SystemLiteral(MavBuilder::GOP_DELETE);
  ItemExpr *constUpdate = new(heap_) SystemLiteral(MavBuilder::GOP_UPDATE);
  ItemExpr *constRecompFromUpdate = new(heap_) SystemLiteral(MavBuilder::GOP_MINMAX_RECOMPUTE_FROM_UPDATE);
  ItemExpr *constRecompFromInsert = new(heap_) SystemLiteral(MavBuilder::GOP_MINMAX_RECOMPUTE_FROM_INSERT);

  // The condition for recompute when a min/max value was deleted was created
  // during the buildRootForDelta() phase. If there are no Min/Max columns,
  // it is NULL, and therefore redundant.
  ItemExpr *lastClause;
  if (minMaxRecomputeOnUpdateCondition_ == NULL)
    lastClause = constUpdate;
  else
    lastClause = new(heap_) 
      IfThenElse(minMaxRecomputeOnUpdateCondition_, 
                 constRecompFromUpdate, 
		 constUpdate);

  ItemExpr *insertClause;
  if (minMaxRecomputeOnInsertCondition_ == NULL)
    insertClause = constInsert;
  else
    insertClause = new(heap_) 
      Case(NULL, new(heap_) IfThenElse(minMaxRecomputeOnInsertCondition_, 
                 constRecompFromInsert, 
		 constInsert));

  // Build the CASE and IF operators
  ItemExpr *gopExpression = new(heap_) 
    Case(NULL, 
	 new(heap_) IfThenElse(insCondition, insertClause,
	 new(heap_) IfThenElse(delCondition, constDelete, lastClause)));

  // Add the GOP expression as SYS_CALC.@GOP.
  ColRefName *gopColName = new(heap_)
    ColRefName(MavBuilder::getVirtualGopColumnName(), calcCorrName_);
  ItemExpr *gopColumn = new(heap_) RenameCol(gopExpression, gopColName);

  // Start the select list with *
  ItemExprList selectList(heap_);
  addStarToSelectList(selectList);

  selectList.insert(gopColumn);

  // The select list is ready. Create the root over topNode.
  RelRoot *newRoot = new(heap_) 
    RelRoot(topNode, REL_ROOT, selectList.convertToItemExpr());
  newRoot->setDontOpenNewScope();

  selectList.clear();
  return newRoot;
}  // MavRelRootBuilder::buildRootForGop()

//----------------------------------------------------------------------------
// The condition for a self-cancelling delta
// (SYS_MAV.cnts IS NULL AND SYS_DELTA.cnts = 0)
// If the MAV has no GROUP BY clause, the condition is:
// (SYS_MAV.cnts = 0 AND SYS_DELTA.cnts = 0)
//----------------------------------------------------------------------------
ItemExpr *MavRelRootBuilder::buildSelfCancelingDeltaPredicate()
{
  // Find the MAV column name for COUNT(*).
  const NAString& countStarColName = mavCols_[posOfCountStar_]->getColName();

  ItemExpr *mavCountStarCondition = NULL;
  ItemExpr *mavCountStarName = new(heap_) 
    ColReference(new(heap_) ColRefName(countStarColName, mavCorrName_));
  if (isMavWithoutGroupBy())
  {
    // (SYS_MAV.cnts = 0)
    mavCountStarCondition = new(heap_) 
      BiRelat(ITM_EQUAL, mavCountStarName, new(heap_) SystemLiteral(0));
  }
  else
  {
    // (SYS_MAV.cnts IS NULL)
    mavCountStarCondition = new(heap_) 
      UnLogic(ITM_IS_NULL, mavCountStarName);
  }

  // (mavCountStarCondition AND SYS_DELTA.cnts = 0)
  ItemExpr *selfCancelCondition = new(heap_)  
    BiLogic(ITM_AND,
	    mavCountStarCondition,
	    new(heap_) BiRelat(ITM_EQUAL, 
  			       new(heap_) ColReference(new(heap_) 
				 ColRefName(countStarColName, deltaCorrName_)),
			       new(heap_) SystemLiteral(0)));

  ItemExpr *notSelfCancelingDeltaPredicate = 
    new(heap_) UnLogic(ITM_NOT, selfCancelCondition);

  notSelfCancelingDeltaPredicate->setSelectivityFactor(1.0);

  return notSelfCancelingDeltaPredicate;
}  // MavRelRootBuilder::buildSelfCancelingDeltaPredicate()

//----------------------------------------------------------------------------
// Find the bound expression for column number depIndex from colList.
// depIndex is an index into the MVInfo list of MVColumnInfo objects, so we 
// first find the column name from mavCols_ (the MVInfo column list), and 
// then find that column by name from the RETDesc list (colList).
//----------------------------------------------------------------------------
ItemExpr *MavRelRootBuilder::buildDepColExpr(const CorrName& corrName,
				             Int32             depIndex) const
{
  CMPASSERT(depIndex != -1);

  // Find the column name from the MVInfo list.
  const NAString& depColName = 
    mavCols_.getMvColInfoByIndex(depIndex)->getColName();

  ItemExpr *colRef = new(heap_) 
    ColReference(new(heap_) ColRefName(depColName, corrName));

  return colRef;
}  // MavRelRootBuilder::buildDepColExpr()

//----------------------------------------------------------------------------
// create a name for the new aggregate column - this can be either MIN or MAX
ColRefName *MavRelRootBuilder::createExtraAggName(const NAString& mavColName, 
					          extraColumnType columnType) const
{
  NAString newColName = "@";
  newColName += mavColName;
  newColName += columnType == AGG_FOR_DELETE          ?
		MavBuilder::getExtraColSuffixForDel() :
		MavBuilder::getExtraColSuffixForIns();
		
  return new (heap_) ColRefName(newColName, deltaCorrName_);

} // MavRelRootBuilder::createExtraAggName()

//----------------------------------------------------------------------------
// if the aggregation is MAX(A) then we can create two types of columns:
// INS_MAX_A = MAX(CASE @OP WHEN -1 THEN null ELSE SYS_DELTA.A).
// DEL_MAX_A = MAX(CASE @OP WHEN  1 THEN null ELSE SYS_DELTA.A).
// the 1 & -1 values will be refered to as constOpValue.
ItemExpr *MavRelRootBuilder::buildExtraMinMaxExpr(const ItemExpr  *pMinMaxExpr, 
						  const NAString&  colName,
						  extraColumnType  columnType) const
{
  // if the pMinMaxExpr is the MAX(A) then pAggregationSubject is A.
  ItemExpr *pAggregationSubject = pMinMaxExpr->child(0);
  ItemExpr *copyOfAggSubject = pAggregationSubject->copyTree(heap_);
  ColReference *opCol = new(heap_) 
    ColReference(new(heap_) ColRefName(MavBuilder::getVirtualOpColumnName()));
  ConstValue *pConstOpValue = new(heap_) 
    SystemLiteral( (columnType == AGG_FOR_DELETE) ? 1 : -1);
 
  Case *pCase = new(heap_) 
    Case(NULL, new(heap_)
	 IfThenElse(new(heap_) BiRelat(ITM_EQUAL, opCol, pConstOpValue), 
		    new(heap_) SystemLiteral(), // NULL
		    copyOfAggSubject));
  Aggregate *pNewAggregate = new(heap_)
    Aggregate(pMinMaxExpr->getOperatorType(), pCase);

  ColRefName *extraColName = 
    createExtraAggName(colName, columnType);

  ItemExpr *result = new(heap_) RenameCol(pNewAggregate, extraColName);
  return result;
} // buildExtraMinMaxExpr

//----------------------------------------------------------------------------
// Build the conditional expression for deciding if the min/max value of a
// group was deleted from the MAV. 
// This method builds the expression for a specific MAV min/max column. 
// For a MAV column named col, the expression is:
//     SYS_DELTA.@col_DEL IS NOT NULL
//     AND
//     SYS_DELTA.@col_DEL op1 SYS_MAV.col
//     AND
//   ( SYS_DELTA.@col_INS IS NOT NULL   
//     OR   
//     SYS_DELTA.@col_DEL op2 SYS_DELTA.@col_INS )
// op1 is called logVsMavRelation and is <= for MIN, and >= for MAX.
// If full Duplicate Elimination was not performed by the refresh utility, 
// than op2 (called delVsInsertRelation) is the same as op1. Otherwise it 
// does not cover the = case (which means it is < instead of <=, and > instead
// of >=).
ItemExpr *MavRelRootBuilder::buildMinMaxRecomputeOnUpdateCondition(const NAString&  mavColName,
								   ColReference    *deltaInsCol,
								   ColReference    *deltaDelCol,
								   OperatorTypeEnum operatorType,
								   NABoolean        wasFullDE)
{
  NABoolean        noDE = TRUE;
  OperatorTypeEnum logVsMavRelation;
  OperatorTypeEnum delVsInsertRelation;

  ColReference *mavColNameRef = new(heap_)
    ColReference(new(heap_) ColRefName(mavColName, mavCorrName_));
  
  if (operatorType == ITM_MIN)
  {
    logVsMavRelation    = ITM_LESS_EQ;
    delVsInsertRelation = wasFullDE  ? 
                          ITM_LESS   : 
                          ITM_LESS_EQ;
  }
  else
  {
    CMPASSERT(operatorType ==  ITM_MAX);
    logVsMavRelation    = ITM_GREATER_EQ;
    delVsInsertRelation = wasFullDE    ? 
                          ITM_GREATER  : 
                          ITM_GREATER_EQ;
  }  

  ItemExpr * delIsNull = new(heap_)
    UnLogic(ITM_IS_NOT_NULL, deltaDelCol->copyTree(heap_));
  ItemExpr * insIsNull = new(heap_)
    UnLogic(ITM_IS_NULL, deltaInsCol->copyTree(heap_));
    
  BiRelat *pLogVsMav = new(heap_)
    BiRelat(logVsMavRelation, 
            deltaDelCol->copyTree(heap_), 
	    mavColNameRef);
  BiRelat *pDelVsIns = new(heap_)
    BiRelat(delVsInsertRelation, 
            deltaDelCol->copyTree(heap_), 
	    deltaInsCol->copyTree(heap_));

  // look at the drawing on top
  BiLogic * finalCondition = new(heap_) 
    BiLogic(ITM_AND, 
            delIsNull, 
	    new(heap_) BiLogic(ITM_AND, 
	                       pLogVsMav, 
			       new(heap_) BiLogic(ITM_OR, 
			                          insIsNull, 
						  pDelVsIns)));

  return finalCondition;
}  // MavRelRootBuilder::buildMinMaxRecomputeOnUpdateCondition()

//----------------------------------------------------------------------------
// Build the conditional expression for deciding if the min/max value of a
// new group was deleted.
// This method builds the expression for a specific MAV min/max column. 
// For a MAV column named col, the expression is:
//   SYS_DELTA.@col_DEL IS NOT NULL
//   AND
//   SYS_DELTA.@col_DEL = SYS_DELTA.@col_INS
// This condition is TRUE when, for example, for a new group (that does not 
// yet appear in the MAV, the operations are: INSERT 10, INSERT 20, DELETE 20.
// In this case we cannot know the new MAX value without recomputing it, 
// unless DE LEVEL is 3. Then - all the Insert-Delete pairs are deleted, and
// the Min/Max computation is straight forward.
ItemExpr *MavRelRootBuilder::buildMinMaxRecomputeOnInsertCondition(ColReference *deltaInsCol,
								   ColReference *deltaDelCol)
{
  ItemExpr * delIsNotNull = new(heap_)
    UnLogic(ITM_IS_NOT_NULL, deltaDelCol->copyTree(heap_));
    
  BiRelat *pDelVsIns = new(heap_)
    BiRelat(ITM_EQUAL, 
            deltaDelCol->copyTree(heap_), 
	    deltaInsCol->copyTree(heap_));

  BiLogic *finalCondition = new(heap_) 
    BiLogic(ITM_AND, delIsNotNull, pDelVsIns);

  return finalCondition;
}  // MavRelRootBuilder::buildMinMaxRecomputeOnInsertCondition()

//----------------------------------------------------------------------------
// The complete condition for Update vs. Recompute is the logical OR of all
// the conditions for specific min/max columns.
void MavRelRootBuilder::addToMinMaxRecomputeCondition(const NAString&  mavColName,
						       ColReference    *deltaInsCol,
						       ColReference    *deltaDelCol,
						       OperatorTypeEnum operatorType,
						       NABoolean        wasFullDE)
{
  ItemExpr *newCondition = 
    buildMinMaxRecomputeOnUpdateCondition(mavColName,
					  deltaInsCol,
					  deltaDelCol,
					  operatorType,
					  wasFullDE);

  if (minMaxRecomputeOnUpdateCondition_ == NULL)
    minMaxRecomputeOnUpdateCondition_ = newCondition;
  else
    minMaxRecomputeOnUpdateCondition_ = new(heap_)
      BiLogic(ITM_OR, minMaxRecomputeOnUpdateCondition_, newCondition);

  // If DE LEVEL is 3 (ALL), the next condition will never happen.
  if (wasFullDE)
    return;

  newCondition = 
    buildMinMaxRecomputeOnInsertCondition(deltaInsCol,
					  deltaDelCol);

  if (minMaxRecomputeOnInsertCondition_ == NULL)
    minMaxRecomputeOnInsertCondition_ = newCondition;
  else
    minMaxRecomputeOnInsertCondition_ = new(heap_)
      BiLogic(ITM_OR, minMaxRecomputeOnInsertCondition_, newCondition);
}  // MavRelRootBuilder::addToMinMaxRecomputeCondition()

//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
void MavRelRootBuilder::addColsToSelectList(LIST(MVColumnInfo *) listOfCols, 
					    ItemExprList&        selectList,
					    const CorrName&      corrName,
					    const CorrName      *renameTo)
{
  for (CollIndex i=0; i<listOfCols.entries(); i++)
  {
    const NAString& colName = listOfCols[i]->getColName();

    ItemExpr *colRef = new(heap_) 
      ColReference(new(heap_) ColRefName(colName, corrName));

    if (renameTo != NULL)
    {
      ColRefName *targetName = new(heap_) ColRefName(colName, *renameTo);
      colRef = new(heap_) RenameCol(colRef, targetName);
    }

    selectList.insert(colRef);
  }
}  // MavRelRootBuilder::addColsToSelectList()

//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
void MavRelRootBuilder::addStarToSelectList(ItemExprList& selectList)
{
  ColRefName *star = new(heap_) ColRefName(TRUE, heap_);
  star->setStarWithSystemAddedCols();
  ItemExpr *starRef = new(heap_) ColReference(star);

  selectList.insert(starRef);
}  // MavRelRootBuilder::addStarToSelectList()

