/**********************************************************************
// @@@ 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:         ExCompoundStmt.cpp 
* Description:  3GL compound statement (CS) operator.
*	
* Created:      4/1/98 
* Language:     C++
*
*
*
******************************************************************************
*/

#include "ex_stdh.h"
#include "ComTdb.h"
#include "ex_tcb.h"
#include "ex_expr.h"
#include "ex_error.h"
#include "str.h"
#include "ExCompoundStmt.h"
#include "ExStats.h"


//////////////////////////////////////////////////////////////////////////////
// CatpoundStmt TDB methods.
//////////////////////////////////////////////////////////////////////////////
ex_tcb * ExCatpoundStmtTdb::build(ex_globals *glob)
{
  ex_tcb *left = tdbLeft_->build(glob);
  ex_tcb *right = tdbRight_->build(glob);

  ExCatpoundStmtTcb *cs = 
    new(glob->getSpace()) ExCatpoundStmtTcb(*this, *left, *right, glob);
  
  cs->registerSubtasks();
  
  return cs;
} // ExCatpoundStmtTdb::build


//////////////////////////////////////////////////////////////////////////////
// CatpoundStmt TCB methods.
//////////////////////////////////////////////////////////////////////////////
ExCatpoundStmtTcb::ExCatpoundStmtTcb(const ExCatpoundStmtTdb &tdb, 
                                     const ex_tcb &left,   
                                     const ex_tcb &right, 
                                     ex_globals *glob) : 
  ex_tcb(tdb, 1, glob)
{
  CollHeap *space = glob->getSpace();

  // Init children TCB handles.
  tcbLeft_ = &left;
  tcbRight_ = &right;

  // Init queue pairs used to communicate with children.
  qleft_ = left.getParentQueue();
  qright_ = right.getParentQueue();

  // flowParent2Right's rentry->copyAtp(lentry) requires right down-queue
  // allocate its ATPs. Otherwise, rentry->copyAtp() will crash because
  // of a null qright_.down->queue.atp_.
  qright_.down->allocateAtps(glob->getSpace());

  ex_cri_desc *criDown = tdb.criDescDown_;  
  ex_cri_desc *criUp = tdb.criDescUp_;

  // Allocate queue pair used to communicate with parent.
  qparent_.down = new(space) ex_queue(ex_queue::DOWN_QUEUE,
                                      tdb.queueSizeDown_,
                                      criDown,
                                      space);
  qparent_.up = new(space) ex_queue(ex_queue::UP_QUEUE,
                                    tdb.queueSizeUp_,
                                    criUp,
                                    space);

  // Allocate private state in each entry of the down queue.
  ExCatpoundStmtPrivateState *p = new(space) ExCatpoundStmtPrivateState(this);
  qparent_.down->allocatePstate(p, this);
  delete p;

  // remember parent's down-queue index
  parent2leftx_ = qparent_.down->getHeadIndex();

  // remember left child's up-queue index
  leftupx_ = qleft_.up->getHeadIndex();
} // ExCatpoundStmtTcb::ExCatpoundStmtTcb


ExCatpoundStmtTcb::~ExCatpoundStmtTcb()
{
  delete qparent_.up;
  delete qparent_.down;
  freeResources();
} // ExCatpoundStmtTcb::~ExCatpoundStmtTcb


void ExCatpoundStmtTcb::registerSubtasks()
{
  ExScheduler *sched = getGlobals()->getScheduler();

  // schedule sWorkDownLeft only if parent down-queue is non-empty
  // or if left child down-queue is non-full.
  sched->registerInsertSubtask(sWorkDownLeft, this, qparent_.down,"P1");
  sched->registerUnblockSubtask(sWorkDownLeft, this, qleft_.down);

  // schedule sWorkLeft2Right only if left child up-queue is non-empty
  // or if right child down-queue or parent up-queue is non-full
  sched->registerInsertSubtask(sWorkLeft2Right, this, qleft_.up,"P2");
  sched->registerUnblockSubtask(sWorkLeft2Right, this, qright_.down);
  sched->registerUnblockSubtask(sWorkLeft2Right, this, qparent_.up);
  
  // schedule sWorkUp only if right child up-queue is non-empty
  // or if parent up-queue is non-full.
  sched->registerInsertSubtask(sWorkUp, this, qright_.up,"P3");
  sched->registerUnblockSubtask(sWorkUp, this, qparent_.up);

  // schedule sWorkCancel if a cancel request is received 
  sched->registerCancelSubtask(sWorkCancel, this, qparent_.down,"CN");
} // ExCatpoundStmtTcb::registerSubtasks


inline const ex_tcb* ExCatpoundStmtTcb::getChild(Int32 pos) const
{
  ex_assert((pos >= 0), "ExCatpoundStmtTcb::getChild"); 
  if (pos == 0)
    return tcbLeft_;
  else if (pos == 1)
    return tcbRight_;
  else
    return NULL;
} // ExCatpoundStmtTcb::getChild


ExWorkProcRetcode ExCatpoundStmtTcb::work()
{
  // The work methods for the CS operator:
  // (1) workDownLeft() - Process new request, giving it to the left child.
  // (2) workLeft2Right() - Flow tuple value and control from left to right.
  // (3) workUp() - Flow result from right up-queue to parent up-queue.

  // This default work method is never called.
  ex_assert(0, "ExCatpoundStmtTcb::work: Invalid state");
  return WORK_OK;
} // ExCatpoundStmtTcb::work


// Work procedure to send requests down to left child
ExWorkProcRetcode ExCatpoundStmtTcb::workDownLeft()
{
  // while we have unprocessed down requests and while left
  // child's down queue has room, start more child requests
  while (qparent_.down->entryExists(parent2leftx_) && 
         !qleft_.down->isFull()) {
    startLeftChild();
    parent2leftx_++;
  }
  return WORK_OK;
} // ExCatpoundStmtTcb::workDownLeft


void ExCatpoundStmtTcb::startLeftChild()
{
  // Process the new parent request.
  ex_queue_entry *pentry = qparent_.down->getQueueEntry(parent2leftx_);
  ex_queue_entry *lentry = qleft_.down->getTailEntry();

  ExCatpoundStmtPrivateState &pstate = 
    *((ExCatpoundStmtPrivateState*)pentry->pstate);

  // Init private state.
  pstate.init();

  // pass same request to left child
  const ex_queue::down_request request = pentry->downState.request;
  lentry->downState.request = request;
  lentry->downState.requestValue = pentry->downState.requestValue;
  lentry->downState.parentIndex = parent2leftx_; 
  lentry->passAtp(pentry);

  qleft_.down->insert();
  pstate.leftstate_ = CS_STARTED;

  if (request == ex_queue::GET_NOMORE) {
    // immediately cancel the request (requests are already in
    // cancelled state but the cancel callback isn't activated yet)
    qleft_.down->cancelRequestWithParentIndex(parent2leftx_);
    pstate.leftstate_ = CS_CANCELLED;
  }
} // ExCatpoundStmtTcb::startLeftChild


// flow tuple values and control from left to right child
ExWorkProcRetcode ExCatpoundStmtTcb::workLeft2Right()
{
  // We want to remove left up-queue entries as soon as they're passed to
  // the right child. But, we can't. We must defer removing some (ie, the 
  // 1st and its Q_NO_DATA) left up-queue entries to workUp because 
  // catpoundstmts like
  //   begin; select count(*) from t; delete from t; end;
  // may have a right child that produce no data result, ie, its first
  // up-queue entry is a Q_NO_DATA. Q_NO_DATA does not carry any data. 
  // We must flow any left data up to the parent even if the right child
  // is a non-data-producing statement.

  // while left child's up-queue is non-empty do
  for (; qleft_.up->entryExists(leftupx_); leftupx_++) {
    // process reply from left child
    ex_queue_entry *lentry = qleft_.up->getQueueEntry(leftupx_);
    ex_queue_entry *rentry = qright_.down->getTailEntry();
    ex_queue_entry *pentry = qparent_.down->getQueueEntry
      (lentry->upState.parentIndex);

    ExCatpoundStmtPrivateState &pstate = 
      *((ExCatpoundStmtPrivateState*)pentry->pstate);

    switch(lentry->upState.status) {
    case ex_queue::Q_NO_DATA:
      // if we did not get atleast one row from the left child and we
      // are expecting rows (because of SELECT) from the left child
      // then raise a warning and stop further execution of CS statements
      if (pstate.leftstate_ == CS_STARTED &&
          expectingLeftRows() ) {
        if (qparent_.up->isFull()) return WORK_OK; // try again later
        pstate.leftstate_ = CS_ERROR;
        if (afterUpdate()) {
          processEODErrorOrWarning(FALSE);
        }
        else {
          processEODErrorOrWarning(TRUE);
        }
        if (qparent_.up->isFull()) return WORK_OK; 
      }

      if (pstate.leftstate_ == CS_ERROR || 
          pstate.leftstate_ == CS_CANCELLED) { 
        if (qparent_.up->isFull())return WORK_OK; // try again later
        passChildReplyUp(lentry); // pass EOD up
        if (pstate.leftrows_ > 0) { 
          // some data is parked in up-queue; flush it.
          qleft_.up->removeHead(); // the 1st row
        }
        // we must remove left up-queue's EOD. 
        qleft_.up->removeHead(); // the EOD
        qparent_.down->removeHead(); // done with this request
      }
      else { // it's not an error nor a cancel
        if (qright_.down->isFull()) return WORK_OK; // try again later
        // for safety and correctness, we wait until
        // left is done before passing control to right
        if (pstate.leftstate_ == CS_STARTED) { // left has no data result
          // flow parent's down-queue entry to the right
          flowParent2Right(lentry->upState.parentIndex);
          qleft_.up->removeHead(); // it's now useless
        }
        qright_.down->insert();
        pstate.leftstate_ = CS_DONE;
        pstate.rightstate_ = CS_STARTED;
        if (pentry->downState.request == ex_queue::GET_NOMORE) {
          // immediately cancel the request
          qright_.down->cancelRequestWithParentIndex
            (lentry->upState.parentIndex);
          pstate.rightstate_ = CS_CANCELLED;
        }
      }
      break;
    case ex_queue::Q_OK_MMORE:
      if (pstate.leftstate_ == CS_ERROR || 
          pstate.leftstate_ == CS_CANCELLED) {
        qleft_.up->removeHead(); // toss it out; it's useless
        continue;
      }
      if (pstate.leftrows_ == 0) {
        // make sure right child's down-queue is not full before
        // changing its tail entry.
        if (qright_.down->isFull()) return WORK_OK; // try again later
        // catpound statement flows only 1st row from left to right
        flowLeft2Right(lentry);
        pstate.leftstate_ = CS_NOT_EMPTY;
      }
      else { // pstate.leftrows_ > 0
        pentry->downState.request = ex_queue::GET_NOMORE;
        if (qparent_.up->isFull()) return WORK_OK; // try again later
        pstate.leftstate_ = CS_ERROR;
        processCardinalityError(lentry);
        qleft_.up->removeHead(); // toss it out; it's useless
      }
      pstate.leftrows_++;
      break;
    case ex_queue::Q_SQLERROR:
      if (pstate.leftstate_ == CS_ERROR || 
          pstate.leftstate_ == CS_CANCELLED) {
        qleft_.up->removeHead(); // toss it out; it's useless
        continue;
      }
      pentry->downState.request = ex_queue::GET_NOMORE;
      if (qparent_.up->isFull()) return WORK_OK; // try again later
      pstate.leftstate_ = CS_ERROR;
      processError(lentry->getAtp(), NULL);
      qleft_.up->removeHead(); // toss it out; it's useless
      // pstate.leftrows_++; don't do this here because the Q_NO_DATA
      // case above checks for a positive leftrows_ and will try to 
      // remove the entry we've just removed from the left up-queue.
      
      break;
    case ex_queue::Q_INVALID:
    default:
      ex_assert(0,"ExCatpoundStmtTcb:workLeft2Right: Invalid state");
      break;
    }
  }
  return WORK_OK;
} // ExCatpoundStmtTcb::workLeft2Right


// flow tuple value from left to right
void ExCatpoundStmtTcb::flowLeft2Right(ex_queue_entry *lentry)
{
  ex_queue_entry *rentry = qright_.down->getTailEntry();
  ex_queue_entry *pentry = qparent_.down->getQueueEntry
    (lentry->upState.parentIndex);

  // pass same request from left to right child
  rentry->downState.request = pentry->downState.request;
  rentry->downState.requestValue = pentry->downState.requestValue;

  // associate right-down request with left-up entry's parent index
  rentry->downState.parentIndex = lentry->upState.parentIndex;

  // catpound statement flows any input data from left to right
  rentry->copyAtp(lentry);
  // passAtp may be OK here. But, we use copyAtp to be consistent with
  // ExCatpoundStmtTcb::flowParent2Right
} // ExCatpoundStmtTcb::flowLeft2Right


// flow tuple value from parent to right
void ExCatpoundStmtTcb::flowParent2Right(queue_index pindex)
{
  // We're the 2nd catpoundstmt node in a 3-statement block like this
  //   begin; select a from t; delete from u; select b from v; end;
  // The queues look like this
  //                  +--+
  //                  |CS|
  //                  +--+
  //   | |    +-+             | |      +-+
  //   | |    | |             |g|      | |
  //   +-+    | |             +-+      | |
  //      +--+                    +--+
  //      |S |                    |CS|
  //      +--+                    +--+
  //                    | |    +-+    | |    +-+
  //                    | |    |e|    | |    | |
  //                    +-+    | |    +-+    | |
  //                       +--+          +--+
  //                       |D |          |S |
  //                       +--+          +--+
  // The 1st catpoundstmt flowed the 1st select's result to our parent's
  // down-queue(g). Our left child (the delete) has a Q_NO_DATA in its up-
  // queue(e). Now, we must flow our parent's down-queue data (g) to our
  // right child's down-queue. If we don't do this (and instead flow our
  // left up-queue to the right down-queue), we'll lose the 1st select's
  // result because our left up-queue has nothing but a Q_NO_DATA.

  ex_queue_entry *rentry = qright_.down->getTailEntry();
  ex_queue_entry *pentry = qparent_.down->getQueueEntry(pindex);

  // pass same request from parent to right child
  rentry->downState.request = pentry->downState.request;
  rentry->downState.requestValue = pentry->downState.requestValue;

  // associate right-down request with parent index
  rentry->downState.parentIndex = pindex;

  // pass data from parent-to-right
  rentry->copyAtp(pentry);
  // passAtp would be incorrect here because catpoundstmts like this
  //   begin; set :h = select c from t; insert into s(d) values(:h); end;
  // require that :h be set to null if "select c from t" has no data.
  // In this case, copyAtp sets :h to null whereas passAtp leaves :h
  // uninitialized.
} // ExCatpoundStmtTcb::flowParent2Right


ExWorkProcRetcode ExCatpoundStmtTcb::workUp()
{
  // while there is work that has been started do
  while (qparent_.down->getHeadIndex() != parent2leftx_) {
    // get head entry and pstate
    ex_queue_entry *pdentry = qparent_.down->getHeadEntry();
    ExCatpoundStmtPrivateState &pstate = 
      *((ExCatpoundStmtPrivateState*) pdentry->pstate);
    Int32 eod = 0;

    // while we have (up or cancel or error) work to do, ie,
    // while right child's up-queue is non-empty do
    for (; !qright_.up->isEmpty() && !eod; qright_.up->removeHead()) {
      // get right child's first up-queue entry
      ex_queue_entry *rentry = qright_.up->getHeadEntry();
      // get parent's last up-queue entry
      ex_queue_entry *puentry = qparent_.up->getTailEntry();
        
      switch (rentry->upState.status) {
      case ex_queue::Q_NO_DATA:
        // any room in the up-queue?
        if (qparent_.up->isFull()) return WORK_OK; // no, try again later

        // if we did not get atleast one row from the right child and we
        // are expecting rows (because of SELECT) from the right child
        // then raise a warning and stop further execution of CS statements
        if (pstate.rightstate_ == CS_STARTED &&
            expectingRightRows() ) {
          pstate.rightstate_ = CS_ERROR;
          if (afterUpdate()) {
            processEODErrorOrWarning(FALSE);
          }
          else {
            processEODErrorOrWarning(TRUE);
          }
          if (qparent_.up->isFull()) return WORK_OK;
        }

        if (pstate.rightstate_ == CS_ERROR || 
            pstate.rightstate_ == CS_CANCELLED) { 
          passChildReplyUp(rentry); // pass EOD up
        }
        else {
          if (pstate.rightstate_ == CS_STARTED && pstate.leftrows_ > 0) {
            // right has no data but left has some. pass left data up.
            passChildReplyUp(qleft_.up->getHeadEntry());
            pstate.rightrows_ = pstate.leftrows_;
            if (qparent_.up->isFull()) {
              pstate.rightstate_ = CS_DONE; // pass it up exactly once
              return WORK_OK; // retry passing EOD later
            }
          }
          pstate.rightstate_ = CS_DONE;
          passChildReplyUp(rentry); // pass EOD up
          if (getStatsEntry() != NULL) {
            getStatsEntry()->setActualRowsReturned(pstate.rightrows_);
          } 
        }
        eod = 1; // this parent request is done
        if (pstate.leftrows_ > 0) {
        // left had some data and that data has been catenated into right
        // child's atp, flush that left child data parked in it's up-queue.
          qleft_.up->removeHead(); // left data
          qleft_.up->removeHead(); // left EOD
        }
        break;
      case ex_queue::Q_OK_MMORE:
      case ex_queue::Q_SQLERROR:
        // if right is cancelled or an error, then throw it away
        if (pstate.rightstate_ == CS_ERROR ||
            pstate.rightstate_ == CS_CANCELLED) continue;

        if (qparent_.up->isFull()) return WORK_OK; // retry later

        if (rentry->upState.status == ex_queue::Q_SQLERROR) {
          pstate.rightstate_ = CS_ERROR;
          processError(rentry->getAtp(), NULL);
        }
        // catpound statement passes-up only 1st row from right
        else if (pstate.rightrows_ == 0) {
          passChildReplyUp(rentry);
          pstate.rightstate_ = CS_NOT_EMPTY;
        }
        else if (pstate.rightrows_ > 0) {
          pstate.rightstate_ = CS_ERROR;
          processCardinalityError(rentry);
        }
        pstate.rightrows_++;
        break;
      case ex_queue::Q_INVALID:
      default:
        ex_assert(0,"ExCatpoundStmtTcb::workUp: Invalid state");
        break;
      }
    }
    // right child's up-queue is empty or current request is done
    if (eod)
      qparent_.down->removeHead(); // this parent request is done
    else
      return WORK_OK;
  }
  return WORK_OK;
} // ExCatpoundStmtTcb::workUp


void ExCatpoundStmtTcb::passChildReplyUp(ex_queue_entry *centry)
{
  // get parent's down-queue head entry and its pstate
  ex_queue_entry *pdentry = qparent_.down->getHeadEntry();

  // get parent's last up-queue entry
  ex_queue_entry *puentry = qparent_.up->getTailEntry();

  // prepare to pass rentry up to parent's up-queue
  puentry->upState.status = centry->upState.status;
  puentry->upState.setMatchNo(centry->upState.getMatchNo());
  puentry->upState.parentIndex = pdentry->downState.parentIndex;
  puentry->upState.downIndex = qparent_.down->getHeadIndex();

  // pass the reply up to the parent's up-queue
  puentry->copyAtp(centry);
  qparent_.up->insert();
} // ExCatpoundStmtTcb::passChildReplyUp


ExWorkProcRetcode ExCatpoundStmtTcb::workCancel()
{
  // Check the down queue from the parent for cancellations. Propagate
  // cancel requests and remove all requests that are completely cancelled.
  // Loop over all requests that have been sent down.
  queue_index x;
  for (x = qparent_.down->getHeadIndex(); x != parent2leftx_; x++) {
    ex_queue_entry *pentry = qparent_.down->getQueueEntry(x);

    // check whether the current down request is cancelled
    if (pentry->downState.request == ex_queue::GET_NOMORE) {
      ExCatpoundStmtPrivateState &pstate = 
        *((ExCatpoundStmtPrivateState*)pentry->pstate);
	  if (pstate.leftstate_ == CS_STARTED ||
          pstate.leftstate_ == CS_NOT_EMPTY) {
        // cancel request to left child
        qleft_.down->cancelRequestWithParentIndex(x);
        pstate.leftstate_ = CS_CANCELLED;
      }
      if (pstate.rightstate_ == CS_STARTED ||
          pstate.rightstate_ == CS_NOT_EMPTY) {
        // cancel request to right child
        qright_.down->cancelRequestWithParentIndex(x);
        pstate.rightstate_ = CS_CANCELLED;
      }
    }
  }
  return WORK_OK;
} // ExCatpoundStmtTcb::workCancel


// Process and propagate error up to parent's up-queue
void ExCatpoundStmtTcb::processError(atp_struct *atp, ComDiagsArea *da)
{
  ex_queue_entry *pdentry = qparent_.down->getHeadEntry();
  ex_queue_entry *puentry = qparent_.up->getTailEntry();
  ExCatpoundStmtPrivateState &pstate = 
    *((ExCatpoundStmtPrivateState*)pdentry->pstate);

  // set up error entry for parent up-queue
  puentry->copyAtp(atp);
  puentry->upState.status = ex_queue::Q_SQLERROR;
  puentry->upState.parentIndex = pdentry->downState.parentIndex;
  puentry->upState.downIndex = qparent_.down->getHeadIndex();
  puentry->upState.setMatchNo(pstate.rightrows_);
  if (da) puentry->setDiagsArea(da);

  // insert entry into parent's up queue
  qparent_.up->insert();	  

  // cancel this request and all its children
  qparent_.down->cancelRequest(qparent_.down->getHeadIndex());
  workCancel();
} // ExCatpoundStmtTcb::processError


// Process CS error due to a child returning > 1 row.
void ExCatpoundStmtTcb::processCardinalityError(ex_queue_entry *centry)
{
  // create error for diags
  ComDiagsArea *da = ExRaiseSqlError
    (getGlobals()->getDefaultHeap(), centry,
     (ExeErrorCode)-EXE_BLOCK_CARDINALITY_VIOLATION); 
  processError(centry->getAtp(), da);
} // ExCatpoundStmtTcb::processCardinalityError


//This method is used to raise error -EXE_CS_EOD_ROLLBACK_ERROR or
// warning +EXE_CS_EOD. Raising this error or warning causes further processing of the 
// CS to be stopped and if any updates were seen previously in this CS then the 
// whole transaction is rolled back. Note that the warning EXE_CS_EOD is actually 
//raised as an error here and and attached to a Q_SQLERROR entry. It is converted into a 
//warning in the root::fetch or root::oltExecute method. This is done since it 
//is crucial that this warning be posted and further processing on the offending CS be stopped.
//There is a possibility that warnings are not propogated correctly and we continue processing
//on the CS once the warning has been raised as an actual warning. 
void ExCatpoundStmtTcb::processEODErrorOrWarning(NABoolean isWarning)
{

  ex_queue_entry *pdentry = qparent_.down->getHeadEntry();
  ex_queue_entry *puentry = qparent_.up->getTailEntry();

  ComDiagsArea * da ;

  if (isWarning)
     da = ExRaiseSqlError(getGlobals()->getDefaultHeap(), puentry,
                         (ExeErrorCode)-EXE_CS_EOD);
  else
     da = ExRaiseSqlError(getGlobals()->getDefaultHeap(), puentry,
                         (ExeErrorCode)-EXE_CS_EOD_ROLLBACK_ERROR);

  puentry->setDiagsArea(da);
  puentry->upState.status = ex_queue::Q_SQLERROR;
  puentry->upState.parentIndex = pdentry->downState.parentIndex;
  puentry->upState.downIndex = qparent_.down->getHeadIndex();
  puentry->upState.setMatchNo((Lng32)0);
  
  qparent_.up->insert();
}
  
//////////////////////////////////////////////////////////////////////////////
// CatpoundStmtPrivateState methods.
//////////////////////////////////////////////////////////////////////////////
void ExCatpoundStmtPrivateState::init() 
{
  leftstate_  = ExCatpoundStmtTcb::CS_EMPTY;
  rightstate_ = ExCatpoundStmtTcb::CS_EMPTY;
  leftrows_ = 0;
  rightrows_ = 0;
} // void ExCatpoundStmtPrivateState::init


ex_tcb_private_state*
ExCatpoundStmtPrivateState::allocate_new(const ex_tcb *tcb)
{
  return new(((ex_tcb *)tcb)->getSpace()) 
    ExCatpoundStmtPrivateState((ExCatpoundStmtTcb *) tcb);
} // ExCatpoundStmtPrivateState::allocate_new
