void PhysSequence::computeHistoryParams(Lng32 histRecLength,
                                        Lng32 &maxRowsInOLAPBuffer,
                                        Lng32 &minNumberOfOLAPBuffers,
                                        Lng32 &numberOfWinOLAPBuffers,
                                        Lng32 &maxNumberOfOLAPBuffers,
                                        Lng32 &olapBufferSize)
{
  Lng32 maxFWAdditionalBuffers = getDefault(OLAP_MAX_FIXED_WINDOW_EXTRA_BUFFERS);
  maxNumberOfOLAPBuffers = getDefault(OLAP_MAX_NUMBER_OF_BUFFERS);
  // For testing we may force a smaller max # rows in a buffer
  Lng32 forceMaxRowsInOLAPBuffer =  getDefault(OLAP_MAX_ROWS_IN_OLAP_BUFFER);
  minNumberOfOLAPBuffers = 0;
  numberOfWinOLAPBuffers = 0;
  olapBufferSize = getDefault(OLAP_BUFFER_SIZE);
  Lng32 olapAvailableBufferSize = olapBufferSize
                                 - ROUND8(sizeof(HashBufferHeader)); // header
  // also consider the trailer reserved for DP2's checksum, for overflow only
  if ( getUnboundedFollowing() ) olapAvailableBufferSize -= 8 ; 

  if ( histRecLength > olapAvailableBufferSize)
  { // history row exceeds size limit fir the overflow
    if (getUnboundedFollowing())
    {
       *CmpCommon::diags() << DgSqlCode(-4390)
			    << DgInt0(olapAvailableBufferSize);
       GenExit();
       return ;
    }
    else
    {
      olapAvailableBufferSize = histRecLength;
      // Buffer needs to accomodate the header, but not the trailer (no O/F)
      olapBufferSize = histRecLength + ROUND8(sizeof(HashBufferHeader)) ;
    }
  }

  // Calculate the max # rows in a buffer
  maxRowsInOLAPBuffer = olapAvailableBufferSize / histRecLength ;

  // For testing - we may override the above max # rows
  if ( forceMaxRowsInOLAPBuffer > 0 && 
       forceMaxRowsInOLAPBuffer < maxRowsInOLAPBuffer )
    maxRowsInOLAPBuffer = forceMaxRowsInOLAPBuffer ;

  minNumberOfOLAPBuffers = numHistoryRows_ / maxRowsInOLAPBuffer;

  if ( numHistoryRows_ % maxRowsInOLAPBuffer >0)
  {
    minNumberOfOLAPBuffers++;
  }

  if (getUnboundedFollowing())
  {
    numberOfWinOLAPBuffers = minFollowingRows_/maxRowsInOLAPBuffer ;
    if (minFollowingRows_ % maxRowsInOLAPBuffer >0)
    {
      numberOfWinOLAPBuffers++;
    }

    if (numberOfWinOLAPBuffers +1 > minNumberOfOLAPBuffers)
    {
      minNumberOfOLAPBuffers = numberOfWinOLAPBuffers +1 ;
    }

    //produce an error here if maxNumberOfOLAPBuffers < minNumberOfOLAPBuffers 
  }
  else
  {
    maxNumberOfOLAPBuffers = minNumberOfOLAPBuffers + maxFWAdditionalBuffers;
  }
}
short
PhysSample::codeGen(Generator *generator) 
{  
  // Get a local handle on some of the generator objects.
  //
  CollHeap *wHeap = generator->wHeap();
  Space *space = generator->getSpace();
  MapTable *mapTable = generator->getMapTable();
  ExpGenerator *expGen = generator->getExpGenerator();

  // Allocate a new map table for this node. This must be done
  // before generating the code for my child so that this local
  // map table will be sandwiched between the map tables already
  // generated and the map tables generated by my offspring.
  //
  // Only the items available as output from this node will
  // be put in the local map table. Before exiting this function, all of
  // my offsprings map tables will be removed. Thus, none of the outputs 
  // from nodes below this node will be visible to nodes above it except 
  // those placed in the local map table and those that already exist in
  // my ancestors map tables. This is the standard mechanism used in the
  // generator for managing the access to item expressions.
  //
  MapTable *localMapTable = generator->appendAtEnd();

  // Since this operation doesn't modify the row on the way down the tree,
  // go ahead and generate the child subtree. Capture the given composite row
  // descriptor and the child's returned TDB and composite row descriptor.
  //
  ex_cri_desc * givenCriDesc = generator->getCriDesc(Generator::DOWN);
  child(0)->codeGen(generator);
  ComTdb *childTdb = (ComTdb*)generator->getGenObj();
  ex_cri_desc * childCriDesc = generator->getCriDesc(Generator::UP);
  ExplainTuple *childExplainTuple = generator->getExplainTuple();

  // Geneate the sampling expression.
  //
  ex_expr *balExpr = NULL;
  Int32 returnFactorOffset = 0;
  ValueId val;
  val = balanceExpr().init();
  if(balanceExpr().next(val))
    expGen->generateSamplingExpr(val, &balExpr, returnFactorOffset);

  // Alias the sampleColumns() so that they reference the underlying
  // expressions directly. This is done to avoid having to generate and
  // execute a project expression that simply moves the columns from
  // one tupp to another to reflect the application of the sampledCol
  // function.
  //
//   ValueId valId;
//   for(valId = sampledColumns().init();
//       sampledColumns().next(valId);
//       sampledColumns().advance(valId))
//     {
//       MapInfo *mapInfoChild = localMapTable->getMapInfoAsIs
// 	(valId.getItemExpr()->child(0)->castToItemExpr()->getValueId());
//       GenAssert(mapInfoChild, "Sample::codeGen -- no child map info.");
//       Attributes *attr = mapInfoChild->getAttr();
//       MapInfo *mapInfo = localMapTable->addMapInfoToThis(valId, attr);
//       mapInfo->codeGenerated();
//     }
// check if any of the columns inthe sampled columns are lob columns. If so, return an error.
  ValueId valId;
  for(valId = sampledColumns().init();
      sampledColumns().next(valId);
      sampledColumns().advance(valId))
    {
      const NAType &colType = valId.getType();
      if ((colType.getFSDatatype() == REC_BLOB) ||
	  (colType.getFSDatatype() == REC_CLOB))
	{
	   *CmpCommon::diags() << DgSqlCode(-4322);
	   GenExit();
	}
    }
  // Now, remove all attributes from the map table except the 
  // the stuff in the local map table -- the result of this node.
  //
//  localMapTable->removeAll();

  // Generate the expression to evaluate predicate on the sampled row.
  //
  ex_expr *postPred = 0;
  if (!selectionPred().isEmpty()) {
    ItemExpr * newPredTree 
      = selectionPred().rebuildExprTree(ITM_AND,TRUE,TRUE);

    expGen->generateExpr(newPredTree->getValueId(), ex_expr::exp_SCAN_PRED,
			 &postPred);
  }

  // Construct the Sample TDB.
  //
  ComTdbSample *sampleTdb
    = new(space) ComTdbSample(NULL,
			      balExpr,
			      returnFactorOffset,
			      postPred,
			      childTdb,
			      givenCriDesc,
			      childCriDesc,
			      (queue_index)getDefault(GEN_SAMPLE_SIZE_DOWN),
			      (queue_index)getDefault(GEN_SAMPLE_SIZE_UP));
  generator->initTdbFields(sampleTdb);

  if(!generator->explainDisabled()) {
    generator->
      setExplainTuple(addExplainInfo(sampleTdb,
                                     childExplainTuple,
                                     0,
                                     generator));
  }

  generator->setCriDesc(givenCriDesc, Generator::DOWN);
  generator->setCriDesc(childCriDesc, Generator::UP);
  generator->setGenObj(this, sampleTdb);

  return 0;
}