/**********************************************************************
// @@@ 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:         RETDesc.C
* Description:  Descriptor for the table derived from a RelExpr
* Created:      6/1/95
* Language:     C++
*
*
**************************************************************************
*/


#include "Sqlcomp.h"
#include "AllItemExpr.h"
#include "BindWA.h"
#include "Refresh.h"
#include "MvRefreshBuilder.h"
#include "MVInfo.h"

// ***********************************************************************
// RETDesc::RETDesc()
// ***********************************************************************

RETDesc::RETDesc()
: groupedFlag_(FALSE),
  xtnm_(CmpCommon::statementHeap()),
  xcnm_(CmpCommon::statementHeap()),
  userColumnList_(CmpCommon::statementHeap()),
  naTypeForUserColumnList_(CmpCommon::statementHeap()),
  systemColumnList_(CmpCommon::statementHeap()),
  routineFlag_(FALSE),
  bindWA_(NULL)
{
  //cerr << "RETDesc()     \t" << this << " " << endl;	// ##
}

RETDesc::RETDesc(BindWA* bindWA)
: groupedFlag_(FALSE),
  userColumnList_(bindWA->wHeap()),
  naTypeForUserColumnList_(CmpCommon::statementHeap()),
  systemColumnList_(bindWA->wHeap()),
  xtnm_(bindWA->wHeap()),
  xcnm_(bindWA->wHeap()),
  routineFlag_(FALSE),
  bindWA_(bindWA)
{
  bindWA->getRETDescList().insert(this);
  //cerr << "RETDesc(bwa)  \t" << this << " " << endl;	// ##
}

RETDesc::RETDesc(BindWA *bindWA, const RETDesc& sourceTable)
: userColumnList_(bindWA->wHeap()),
  naTypeForUserColumnList_(CmpCommon::statementHeap()),
  systemColumnList_(bindWA->wHeap()),
  xtnm_(bindWA->wHeap()),
  xcnm_(bindWA->wHeap()),
  groupedFlag_(FALSE),
  routineFlag_(FALSE),
  bindWA_(bindWA)
{
  bindWA->getRETDescList().insert(this);
  //cerr << "RETDesc(bwa,RD&)\t" << this << " " << (void*)&sourceTable << " " << endl;  // ##
  addColumns(bindWA, sourceTable);
}

RETDesc::RETDesc(BindWA *bindWA, TableDesc *tdesc, CorrName *newCorrName)
: userColumnList_(bindWA->wHeap()),
  naTypeForUserColumnList_(CmpCommon::statementHeap()),
  systemColumnList_(bindWA->wHeap()),
  xtnm_(bindWA->wHeap()),
  xcnm_(bindWA->wHeap()),
  groupedFlag_(FALSE),
  routineFlag_(FALSE),
  bindWA_(bindWA)
{
  bindWA->getRETDescList().insert(this);
  //cerr << "RETDesc(bwa,TD*)\t" << this << " " << endl;	// ##

  // Get the corrName, and for performance, apply the defaults to it now,
  // before the loop where it is passed down and "defaulted" again and again.
  CorrName& corrName = newCorrName ? *newCorrName : tdesc->getCorrNameObj();
  NAString cat, sch, tbl;
  corrName.extractAndDefaultNameParts(bindWA,
                                      bindWA->getDefaultSchema(),
                                      cat, sch, tbl);

  const ValueIdList& vidList = tdesc->getColumnList();
  for (CollIndex i = 0; i < vidList.entries(); i++) {
    ValueId valId = vidList[i];
    CMPASSERT(valId.getItemExpr()->getOperatorType() == ITM_BASECOLUMN);
    BaseColumn *baseCol = (BaseColumn *) valId.getItemExpr();
    NAColumn *column = baseCol->getNAColumn();
    ColRefName colRefName(column->getColName(), corrName,
                          CmpCommon::statementHeap());
    addColumn(bindWA, colRefName, valId, 
	      column->getColumnClass(),
	      column->getHeading());

  }

} // RETDesc::RETDesc()

RETDesc::RETDesc(BindWA *bindWA, RoutineDesc *rdesc, QualifiedName *newQualName)
: userColumnList_(bindWA->wHeap()),
  naTypeForUserColumnList_(CmpCommon::statementHeap()),
  systemColumnList_(bindWA->wHeap()),
  xtnm_(bindWA->wHeap()),
  xcnm_(bindWA->wHeap()),
  groupedFlag_(FALSE),
  routineFlag_(TRUE),
  bindWA_(bindWA)
{
  bindWA->getRETDescList().insert(this);
  //cerr << "RETDesc(bwa,TD*)\t" << this << " " << endl;	// ##

  // Get the QualifiedName, and for performance, apply the defaults to it now,
  // before the loop where it is passed down and "defaulted" again and again.
  CMPASSERT(newQualName || (rdesc && rdesc->getNARoutine() &&
                      rdesc->getNARoutine()->getRoutineName()));
      
  const QualifiedName& qualName = newQualName ? *newQualName : 
                            rdesc->getNARoutine()->getRoutineName()->getQualifiedNameObj();
  NAString cat, sch, routine;
  qualName.extractAndDefaultNameParts( bindWA->getDefaultSchema(),
                                      cat, sch, routine);

  // Only the output parameters of the routine are part of the RETDesc..
  const ValueIdList& vidList = rdesc->getOutputColumnList();
  const NARoutine *naroutine = NULL;
  if (rdesc->isUUDFRoutine()) naroutine = rdesc->getActionNARoutine();
  else                        naroutine = rdesc->getNARoutine();

  // if (!naroutine) error.

  for (CollIndex i = 0; i < vidList.entries(); i++) {
    ValueId valId = vidList[i];
    CMPASSERT(valId.getItemExpr()->getOperatorType() == ITM_ROUTINE_PARAM);
    RoutineParam *routineOutParam = (RoutineParam *) valId.getItemExpr();
    NAColumn *column = naroutine->getParams()[routineOutParam->getOrdinalPos()];
    ColRefName colRefName(column->getColName(), qualName,
                          CmpCommon::statementHeap());
    addColumn(bindWA, colRefName, valId, 
	      column->getColumnClass(),
	      column->getHeading());
  }

} // RETDesc::RETDesc()

RETDesc::~RETDesc()
{
  systemColumnList_.clearAndDestroy();
  userColumnList_.clearAndDestroy();
  if (bindWA_)
    bindWA_->getRETDescList().remove(this);
  //cerr << "~RETDesc~     \t" << this << " bwa=" << bindWA_ << " " << endl;	// ##
}


// ***********************************************************************
// RETDesc::addColumn()
// ***********************************************************************
void RETDesc::addColumn(BindWA *bindWA,
			const ColRefName& colRefName,
                        const ValueId valId,
                        const ColumnClass colClass,
			const char *heading)
{
  //
  // Create a column descriptor, insert it into the column list, and add the
  // exposed column name(s) to the hash table.
  //
  if (colClass == SYSTEM_COLUMN)
    addColumnDesc(bindWA, colRefName, valId, heading, systemColumnList_);
  else
    addColumnDesc(bindWA, colRefName, valId, heading, userColumnList_);
  //
  // If the column has a qualifier, find the list of columns for that qualifier.
  //
  // Create that list the first time (even for a "system" column -- see how
  // OrderBy processing is done -- this lets errmsg 4001-04 tables-in-scope
  // info to be correct).
  //
  // If the column is a user column, insert it into the list. 
  //
  CorrName corrName(colRefName.getCorrNameObj(), CmpCommon::statementHeap());
  if (corrName != "") {
    ColumnDescList *columnList = getQualColumnList(corrName);
    if (!columnList) {
      columnList = new (bindWA->wHeap()) ColumnDescList(bindWA->wHeap());
      xtnm_.insertNames(bindWA, corrName, columnList);
    }
    if (colClass != SYSTEM_COLUMN) {
      ColumnDesc *column = userColumnList_[getDegree() - 1];
      columnList->insert(column);
    }
  }
} // RETDesc::addColumn

// ***********************************************************************
// RETDesc::delColumn()
// ***********************************************************************
void RETDesc::delColumn(BindWA *bindWA,
			const ColRefName& colRefName,
                        const ColumnClass colClass)
{
  //
  // Delete the column descriptor from the column list and the hash table.
  //
  if (colClass == SYSTEM_COLUMN) {
    delColumnDesc(bindWA, colRefName, systemColumnList_);
    return;
  }
  delColumnDesc(bindWA, colRefName, userColumnList_);
  //
  // If the user column has a qualifier, find the list of columns for that
  // qualifier; if such a list exists, delete the column descriptor from it.
  //
  CorrName corrName(colRefName.getCorrNameObj());
  if (corrName != "") {
    //
    // If a qualified column list has been created, delete column desc from it.
    //
    ColumnDescList *columnList = getQualColumnList(corrName);
    if (columnList) delColumnDesc(bindWA, colRefName, *columnList);
  }
} // RETDesc::delColumn

// ***********************************************************************
// RETDesc::addColumnDesc()
// ***********************************************************************
void RETDesc::addColumnDesc(BindWA *bindWA,
			    const ColRefName& colRefName,
                            const ValueId valId,
			    const char *heading,
                            ColumnDescList& columnList)
{
  // Create a column descriptor and insert it into the column list.
  //
  ColumnDesc *column = new (bindWA->wHeap()) ColumnDesc(colRefName, valId,
							heading, bindWA->wHeap());
  columnList.insert(column);

  // The newSimpleDup logic, in several places below, is to detect one type
  // of duplicate column that the XCNM hash table cannot:
  // that both "col" and "corr-or-qual.col" appear.
  // E.g, the following duplicates (ambiguities) are detected:
  //	select a,ta.a from ta order by a;	-- found by XCNM logic
  //	select ta.a,a from ta order by a;	-- found by XCNM logic
  //	select * from ta x, ta y order by a;	-- found by XCNM logic
  //	select a,ta.a from ta order by ta.a;	-- found by newSimpleDup logic
  //	select ta.a,a from ta order by ta.a;	-- found by newSimpleDup logic
  // while preserving the legality of the following:
  //	select * from ta x, ta y order by x.a,y.a;	-- legal!
  //	select a,ta.a from ta;				-- legal, of course
  //
  // To understand this newSimpleDup logic, first realize that if multiple
  // tables are in the FROM-list, then the XCNM logic will disallow references
  // to duplicate simple names ("col") in the select-list.
  // Thus newSimpleDup only has to deal with queries on one table.
  //
  ValueId newSimpleDup(NULL_VALUE_ID);

  CorrName corrName(colRefName.getCorrNameObj(), CmpCommon::statementHeap());
  ExtendedQualName::SpecialTableType specialType = corrName.getSpecialType();

  // Add the exposed column name(s) to the hash table.
  // First, the simple name "col" ...
  //
  NAString simpleColNameStr(colRefName.getColName(),
                            CmpCommon::statementHeap());
  ColRefName simpleColRefName(simpleColNameStr);
  simpleColRefName.setSpecialType(specialType);
  ColumnNameMap *xcnmEntry = findColumn(simpleColRefName);
  if (xcnmEntry) {
    if (NOT xcnmEntry->isDuplicate())
      newSimpleDup = xcnmEntry->getValueId();	// *not* "newSimpleDup = valId"!
    xcnmEntry->setDuplicateFlag();
  } else
    xcnm_.insert(new (bindWA->wHeap()) ColumnNameMap(simpleColRefName, column, bindWA->wHeap()));

  if (corrName == "") {
    if (newSimpleDup != NULL_VALUE_ID && simpleColNameStr != "") {
      // Find previously added xcnm's whose simple name is "col"
      // and whose valueId matches, and mark them as dups.
      LIST(ColumnNameMap*) xcnmList(CmpCommon::statementHeap());
      xcnm_.dump(xcnmList);
      for (CollIndex i = 0; i < xcnmList.entries(); i++) {
	if (xcnmList[i]->getValueId() == newSimpleDup &&
	    xcnmList[i]->getColRefNameObj().getColName() == simpleColNameStr)
	  xcnmList[i]->setDuplicateFlag();
      }
    }
    return;
  }

  // ... Second, the name "corr-or-qual.col", if "corr" or "qual" is present:
  // if "corr", insert "corr.col" into hash table;
  // if "qual", insert fully expanded "c.s.t.col" into hash table, plus
  //    if "c"==default-catalog, insert "s.t.col", plus
  //      if also "s"==default-schema, insert "t.col".
  //
  // The insertion and the duplicate flagging allow our later discovery
  // of ambiguous column references, e.g.,
  //   "select * from (select a,b as a from ta) as aa order by aa.a;"
  //
  // The logic here is similar to that in RETDesc::delColumnDesc and
  // XTNM::insertNames -- just a little more complicated (pointers, and
  // construction of objects only if needed) because it's a tiny bit more
  // efficient in runtime for this most common codepath.

  NAString cat, sch, tbl;
  Int32 defaultMatch = corrName.extractAndDefaultNameParts(
					bindWA,
                                        bindWA->getDefaultSchema(),
                                        cat, sch, tbl);

  ColRefName *cstColRefName = NULL, *stColRefName = NULL, *tColRefName = NULL;
  const ColRefName *canonicalColRefName;

  if (corrName.getCorrNameAsString() != "") {
    canonicalColRefName = &colRefName;		// "corr.col" just as passed in
    CMPASSERT(!defaultMatch);
  } else {

    cstColRefName = new(bindWA->wHeap())
                      ColRefName(simpleColNameStr, 
                                 CorrName(tbl,bindWA->wHeap(),sch,cat),
                                 bindWA->wHeap());
    cstColRefName->setSpecialType(specialType);
    canonicalColRefName = cstColRefName;	// "c.s.t.col"

    if (defaultMatch) {
      stColRefName = new(bindWA->wHeap())
	               ColRefName(simpleColNameStr, 
                                  CorrName(tbl,bindWA->wHeap(),sch),
                                  bindWA->wHeap());
      stColRefName->setSpecialType(specialType);

      if (defaultMatch > 1) {
	tColRefName = new(bindWA->wHeap())
	                ColRefName(simpleColNameStr, 
                                   CorrName(tbl),
                                   bindWA->wHeap());
	tColRefName->setSpecialType(specialType);
      }
    }
  }

  // This first if-test is just a performance hack:
  // If simple "col" wasn't a duplicate, "canon.col" can't be, so skip findCol
  if (xcnmEntry) {
    xcnmEntry = findColumn(*canonicalColRefName);
    if (xcnmEntry) {
      xcnmEntry->setDuplicateFlag();
      
      if(xcnmEntry->getValueId() != valId){
	xcnmEntry->setQualifiedColumnAmbiguousFlag();
      }

      if (defaultMatch) {
	xcnmEntry = findColumn(*stColRefName);
	CMPASSERT(xcnmEntry);
	xcnmEntry->setDuplicateFlag();

	if(xcnmEntry->getValueId() != valId){
	  xcnmEntry->setQualifiedColumnAmbiguousFlag();
	}

	if (defaultMatch > 1) {
	  xcnmEntry = findColumn(*tColRefName);
	  CMPASSERT(xcnmEntry);
	  xcnmEntry->setDuplicateFlag();

	  if(xcnmEntry->getValueId() != valId){
	    xcnmEntry->setQualifiedColumnAmbiguousFlag();
	  }

	} // "t.col" must be marked as a dup too
      } // "s.t.col" must be marked as a dup too
    } // "canon.col" was a dup
  } // simple "col" was a dup

  if (!xcnmEntry) {
    // If simple "col" was added on a previous call -- and thus was found
    // to be a dup in the logic above -- then mark these xcnm's we are
    // about to insert as dups, right off the bat.
    NABoolean isDup = newSimpleDup == valId;
    xcnm_.insert(new (bindWA->wHeap())
		 ColumnNameMap(*canonicalColRefName, column, bindWA->wHeap(), isDup));
    if (defaultMatch) {
      xcnm_.insert(new (bindWA->wHeap())
		   ColumnNameMap(*stColRefName, column, bindWA->wHeap(), isDup));
      if (defaultMatch > 1) {
	xcnm_.insert(new (bindWA->wHeap())
		     ColumnNameMap(*tColRefName, column, bindWA->wHeap(), isDup));
      } // "t.col" not dup, must be inserted
    } // "s.t.col" not dup, must be inserted
  } // "canon.col" not dup, insert

  delete cstColRefName;
  delete stColRefName;
  delete tColRefName;

} // RETDesc::addColumnDesc

// ***********************************************************************
// RETDesc::delColumnDesc()
// ***********************************************************************
void RETDesc::delColumnDesc(BindWA *bindWA,
			    const ColRefName& colRefName,
                            ColumnDescList& columnList)
{
  //
  // Delete all matching column descriptor(s) from the column list.
  //
  // "if (columnList.remove(&tmpColumn))"
  // does not work here, since columnList is a list of pointers,
  // i.e. remove does pointer comparisons only (and never finds a match).
  for (CollIndex i = 0; i < columnList.entries(); i++) {
    ColumnDesc *colDesc = columnList[i];
    if (colDesc->getColRefNameObj() == colRefName) {
      columnList.remove(colDesc);
      break;
    }
  }
  //
  // Delete the exposed column name(s) from the hash table.
  //
  CorrName corrName(colRefName.getCorrNameObj());
  ExtendedQualName::SpecialTableType specialType = corrName.getSpecialType();

  NAString simpleColNameStr(colRefName.getColName(),
                            CmpCommon::statementHeap());
  ColRefName simpleColRefName(simpleColNameStr);
  simpleColRefName.setSpecialType(specialType);
  xcnm_.remove(&simpleColRefName);
  if (corrName == "") return;

  NAString cat, sch, tbl;
  Int32 defaultMatch = corrName.extractAndDefaultNameParts(
					bindWA,
                                        bindWA->getDefaultSchema(),
                                        cat, sch, tbl);

  ColRefName cstColRefName(simpleColNameStr, CorrName(tbl,bindWA->wHeap(),sch,cat));
  ColRefName stColRefName(simpleColNameStr, CorrName(tbl,bindWA->wHeap(),sch));
  ColRefName tColRefName(simpleColNameStr, CorrName(tbl));
  cstColRefName.setSpecialType(specialType);
  stColRefName.setSpecialType(specialType);
  tColRefName.setSpecialType(specialType);

  const ColRefName *canonicalColRefName;
  if (corrName.getCorrNameAsString() != "")
    canonicalColRefName = &colRefName;		// "corr.col"
  else
    canonicalColRefName = &cstColRefName;	// "c.s.t.col"

  xcnm_.remove(canonicalColRefName);
  if (defaultMatch) {
    xcnm_.remove(&stColRefName);
    if (defaultMatch > 1)
      xcnm_.remove(&tColRefName);
  }

} // RETDesc::delColumnDesc

// ***********************************************************************
// RETDesc::nullInstantiateAndAddColumns()
// Operates on the "this" RETDesc, adding columns to it from columnList.
// ***********************************************************************
void RETDesc::nullInstantiateAndAddColumns(BindWA *bindWA,
					   NABoolean forceCast,
					   const ColumnDescList& columnList,
					   const ColumnClass colClass)
{
  for (CollIndex i = 0; i < columnList.entries(); i++) {
    ValueId nullId = columnList[i]->getValueId().nullInstantiate(bindWA,
								 forceCast);
    addColumn(bindWA, columnList[i]->getColRefNameObj(), nullId, colClass);
  }
} // RETDesc::nullInstantiateAndAddColumns

// ***********************************************************************
// RETDesc::nullInstantiate()
// Returns a new RETDesc, the null-instantiated copy of the const "this";
// and appends list of columns to nullOutputList.
// ***********************************************************************
RETDesc *RETDesc::nullInstantiate(BindWA *bindWA,
				  NABoolean forceCast,
				  ValueIdList& nullOutputList) const
{
  RETDesc *resultTable = new (bindWA->wHeap()) RETDesc();

  resultTable->nullInstantiateAndAddColumns(bindWA,
					    forceCast,
					    *getColumnList(),
					    USER_COLUMN);

  resultTable->nullInstantiateAndAddColumns(bindWA,
					    forceCast,
					    *getSystemColumnList(),
					    SYSTEM_COLUMN);

  resultTable->getValueIdList(nullOutputList, USER_AND_SYSTEM_COLUMNS);
  return resultTable;
} // RETDesc::nullInstantiate()

// ***********************************************************************
// RETDesc::findColumn()
// find an entry whose vid matches and is either
// 1. fully-qualified and whose vid matches ...or...
// 2. is a fabricated name
// ***********************************************************************
ColumnNameMap *RETDesc::findColumn(const ValueId vid) const
{
  LIST(ColumnNameMap *) colNameMapList(STMTHEAP);

  ColumnNameMap *currColNameMap = NULL;

  xcnm_.dump(colNameMapList);

  for (CollIndex i = 0; i < colNameMapList.entries(); i++)
  {
    ColumnNameMap *colNameMap = colNameMapList[i];
    if (colNameMap->getValueId() EQU vid)
    {
      const ColRefName &colRefName = colNameMap->getColumnDesc()->
                                     getColRefNameObj();
      if (colRefName.isFabricated())
      {
        return colNameMap;
      }
      else if (NOT colRefName.isEmpty() AND
               colRefName.getCorrNameObj().getQualifiedNameObj().
               fullyExpanded())
      {
        return colNameMap;
      }
      else if(!currColNameMap || 
              (colRefName.getCorrNameObj().getQualifiedNameObj().
               numberExpanded() >
               currColNameMap->getColumnDesc()->getColRefNameObj().
               getCorrNameObj().getQualifiedNameObj().numberExpanded())) {
        currColNameMap = colNameMap;
      }
    }
  } // for
  return currColNameMap;
} // RETDesc::findColumn()

// ***********************************************************************
// RETDesc::getTableList()
// Returns a list of the FROM-clause tables described by this RETDesc.
// Only one name (the canonical name) for each table ref appears in the list.
// ***********************************************************************
void RETDesc::getTableList(LIST(TableNameMap*) &xtnmList,
			   NAString *textList) const
{
  xtnmList.clear();
  xtnm_.dump(xtnmList);
  CollIndex i;

  // Get rid of dummy entries inserted by XTNM::insertNames().
  for (i = xtnmList.entries(); i-- > 0; )
    if (!xtnmList[i]->getColumnList()) 
      xtnmList.removeAt(i);

  // Separate names by number of parts (corr, tbl, sch.tbl, cat.sch.tbl)
  LIST(TableNameMap*) xtnmCORR(STMTHEAP), xtnmT(STMTHEAP); 
  LIST(TableNameMap*) xtnmST(STMTHEAP), xtnmCST(STMTHEAP);
  for (i = 0; i < xtnmList.entries(); i++) {
    const CorrName& corr = xtnmList[i]->getTableName();
    const QualifiedName& qual = corr.getQualifiedNameObj();
    if (!corr.isFabricated())
      if (!corr.getCorrNameAsString().isNull())
	xtnmCORR.insert(xtnmList[i]);
      else if (qual.getSchemaName().isNull())
	xtnmT.insert(xtnmList[i]);
      else if (qual.getCatalogName().isNull())
	xtnmST.insert(xtnmList[i]);
      else
	xtnmCST.insert(xtnmList[i]);
  }
  ComASSERT(xtnmCST.entries() >= xtnmST.entries());
  ComASSERT(xtnmCST.entries() >= xtnmT.entries());

  // Put into the list only the full 3-part names and the correlation names
  xtnmList = xtnmCST;
  for (i = 0; i < xtnmCORR.entries(); i++)
    xtnmList.insert(xtnmCORR[i]);

  formatTableList(xtnmList, textList);	// a no-op if textList passed as NULL

} // RETDesc::getTableList

/*static*/ void RETDesc::formatTableList(LIST(TableNameMap*) &xtnmList,
					 NAString *textList,
					 NABoolean includePartitionName) /*const*/
{
  if (!textList) return;		// do nothing if passed as NULL

  // Sort in ascending order by name, removing any duplicates.
  if (xtnmList.entries() > 1) {
    LIST(TableNameMap*) xtnmT(STMTHEAP);
    xtnmT = xtnmList;
    xtnmList.clear();

    while (xtnmT.entries()) {
      NAString minT(CmpCommon::statementHeap());
      if (includePartitionName)
	minT = xtnmT[0]->getTableName().getExposedNameAsStringWithPartitionNames();
      else
	minT = xtnmT[0]->getTableName().getExposedNameAsAnsiString();

      CollIndex minTi = 0;

      for (CollIndex i = xtnmT.entries() - 1; i > 0; i--) {

        NAString T(CmpCommon::statementHeap());
	if (includePartitionName)
	  T = xtnmT[i]->getTableName().getExposedNameAsStringWithPartitionNames(); 
	else
	  T = xtnmT[i]->getTableName().getExposedNameAsAnsiString();

	if (minT > T) {
	  minT = T; minTi = i; break;
	}
	else if (minT == T)		// remove dups
	  xtnmT.removeAt(i);		// this is why we loop backwards
      }		// for

      if (xtnmList.entries() == 0 ||	// don't insert dups
          xtnmList[xtnmList.entries()-1]->getTableName() != 
	  xtnmT[minTi]->getTableName())
	xtnmList.insert(xtnmT[minTi]);

      xtnmT.removeAt(minTi);		// been there, seen that minimum
    }		// while
  }		// if

  for (CollIndex i = 0; i < xtnmList.entries(); i++) {
    NAString T(CmpCommon::statementHeap());
	if (includePartitionName)
	  T = xtnmList[i]->getTableName().getExposedNameAsStringWithPartitionNames();
	else
	  T = xtnmList[i]->getTableName().getExposedNameAsAnsiString(FALSE, TRUE);
    if (!T.isNull()) { 			// if not fabricated
      if (!textList->isNull())
        *textList += ", ";
      *textList += T;
      if (xtnmList[i]->getTableName().isVolatile())
	{
	  *textList += "(volatile)";
	}
    }
  }

} // RETDesc::formatTableList

// ***********************************************************************
// MVs --
// These methods are only called from a RelRoot or RenameTable nodes when
// the BindWA flag isBindingMvRefresh is set: during CREATE MV, and during
// the binding of an INTERNAL REFRESH command.
// If the RETDesc of the current scope has column called colName - copy 
// it over. If the column is already in this RETDesc (by ValueId), 
// delete it and insert it again with the original name (NOT of the view).
// ***********************************************************************
void RETDesc::propagateColumn(BindWA	       *bindWA, 
			      const ColRefName& colName, 
			      NABoolean		isFromRoot,
			      ColumnClass       colClass)
{
  ColumnNameMap *colMap = NULL; 
  // Find the column in the RETDesc of the current scope.
  RETDesc *retDesc = bindWA->getCurrentScope()->getRETDesc();
  if (retDesc != NULL)
    colMap = retDesc->findColumn(colName);

  if (colMap != NULL)
  {
    // If it is not in 'this', copy it over.
    ColumnNameMap *viewCol = findColumn(colMap->getValueId());
    if (viewCol != NULL)
    {
      NABoolean isSyskeyOfLog = 
	colName.getCorrNameObj().getSpecialType() == ExtendedQualName::IUD_LOG_TABLE;
      if (isFromRoot || isSyskeyOfLog)
	return;
      else
      {
	// this RETDesc already has the ValueId - delete it before reinserting.
	const ColRefName& viewColRefName = 
	  viewCol->getColumnDesc()->getColRefNameObj();
	delColumn(bindWA, viewColRefName, colClass);
      }
    }

    addColumn(bindWA, colMap->getColumnDesc()->getColRefNameObj(), 
              colMap->getValueId(), colClass);
  } 
}

// Find the columns to propagate: the @OP column, and the SYSKEY columns 
// of the underlying tables.
void RETDesc::propagateOpAndSyskeyColumns(BindWA *bindWA, NABoolean isFromRoot)
{
  // Find the SYSKEY and @OP columns from the user column list.
  ValueIdList vidList;
  RETDesc *source = bindWA->getCurrentScope()->getRETDesc();
  if (source == NULL)
    return;

  source->getValueIdList(vidList, USER_COLUMN);
  for (CollIndex i=0; i<vidList.entries(); i++)
  {
    ColumnNameMap *colMap = source->findColumn(vidList[i]);
    if (colMap == NULL)
      continue;

    const ColRefName& colName = 
      colMap->getColumnDesc()->getColRefNameObj();
    if (colName.getColName() != "SYSKEY"       &&
        colName.getColName() != MavBuilder::getVirtualOpColumnName())
      continue;

    propagateColumn(bindWA, colName, isFromRoot, USER_COLUMN);
  }

  // Find the SYSKEY columns from the system column list.
  vidList.clear();
  source->getValueIdList(vidList, SYSTEM_COLUMN);
  for (CollIndex j=0; j<vidList.entries(); j++)
  {
    ColumnNameMap *colMap = source->findColumn(vidList[j]);
    if (colMap == NULL)
      continue;

    const ColRefName& colName = 
      colMap->getColumnDesc()->getColRefNameObj();
    if (colName.getColName() != "SYSKEY")
      continue;

    propagateColumn(bindWA, colName, isFromRoot, SYSTEM_COLUMN);
  }
}

// create a list of NATypes corresponding to each entry in the
// userColumnList_ in RETDesc. Used by generator to convert to
// this type during output expr code gen.
// Return: TRUE, if error. FALSE, if all ok.
NABoolean RETDesc::createNATypeForUserColumnList(CollHeap * heap)
{
  for (CollIndex i = 0; i < userColumnList_.entries(); i++) 
    {
      const NAType &userColType = userColumnList_[i]->getValueId().getType();
      NAType * newType = userColType.newCopy(heap);
      naTypeForUserColumnList_.insert(newType);
    }
  return FALSE;
}
	
void RETDesc::changeNATypeForUserColumnList(CollIndex index, const NAType * newType)
{
  naTypeForUserColumnList_.removeAt(index);
  naTypeForUserColumnList_.insertAt(index, (NAType*)newType);
}
				 
// ***********************************************************************
// Display/print, for debugging.
// ***********************************************************************
void RETDesc::display() const { print(); }

void RETDesc::print(FILE* ofd, const char* indent, const char* title) const
{
#ifndef NDEBUG
  CollIndex i;

  BUMP_INDENT(indent);
  fprintf(ofd,"\n NEW RetDesc START \n%s%s %p %s\n --------------------- \n",
    NEW_INDENT, title, this,
    groupedFlag_ ? "(grouped) " : "");

  LIST(TableNameMap*) xtnmList(STMTHEAP);
  xtnm_.dump(xtnmList);
  for (i = 0; i < xtnmList.entries(); i++)
    fprintf(ofd, "%s\n ",
		 xtnmList[i]->getTableName().getExposedNameAsString().data());
  fprintf(ofd,"\n\n\n");

  for (i = 0; i < userColumnList_.entries(); i++) {
    if (i > 0) fprintf(ofd,",\n ");
    userColumnList_[i]->print(ofd, NEW_INDENT, "");
  }
  if (systemColumnList_.entries()) fprintf(ofd,"\nSYSTEM COLUMNS:\n; ");
  for (i = 0; i < systemColumnList_.entries(); i++) {
    if (i > 0) fprintf(ofd,", ");
    systemColumnList_[i]->print(ofd, NEW_INDENT, "");
  }
  if (userColumnList_.entries() || systemColumnList_.entries())
    fprintf(ofd,"\n\nUSER COLUMNS:\n\n");

  LIST(ColumnNameMap*) xcnmList(CmpCommon::statementHeap());
  xcnm_.dump(xcnmList);
  for (i = 0; i < xcnmList.entries(); i++) {
    if (i > 0) fprintf(ofd,",\n");
    xcnmList[i]->print(ofd, NEW_INDENT, "");
  }
  if (i) fprintf(ofd,"\n");

#endif
} // RETDesc::print()

static void displayDownHelper(RelExpr *re, RETDesc *prevRD, int level)
{
  RETDesc *thisRD = re->getRETDesc();
  char indent[20];

  snprintf(indent, sizeof(indent), "Level %4d:  ", level);
  cout << endl
       << endl
       << indent
       << "====== Operator: " << re->getText().data()
       << endl
       << flush;
  if (thisRD != prevRD && thisRD)
    thisRD->print(stdout, indent);
  else if (thisRD == NULL)
    cout << indent << "++++++ RETDesc is NULL" << endl;
  else
    cout << indent << "++++++ RETDesc is the same as its parent" << endl;


  for (int c=0; c<re->getArity(); c++)
    {
      RelExpr *x = re->child(c);
      if (x)
        {
          cout << indent << "++++++ Child " << c << endl;
          displayDownHelper(x, thisRD, level+1);
        }
    }
} // RETDesc::displayDown

/*static*/ void RETDesc::displayDown(RelExpr *re)
{
  displayDownHelper(re, NULL, 1);
} // RETDesc::displayDown

