blob: dad45bcfd065a68b61291eb1a942971617058952 [file] [log] [blame]
/**********************************************************************
// @@@ 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: BinderUtils.cpp
* Description: all kind of general functionalities.
*
* Created: 09/22/2000
* Language: C++
* Status: $State: Exp $
*
*
******************************************************************************
*/
#include "BinderUtils.h"
#include "AllItemExpr.h"
#include "ItemOther.h"
#include "ItemColRef.h"
#include "NATable.h"
#include "ComMvDefs.h"
#include "BindWA.h"
//----------------------------------------------------------------------------
// extract the name from a reference or a rename
ColRefName BinderUtils::getColRefName(ItemExpr* pItemExpr)
{
if(ITM_REFERENCE == pItemExpr->getOperatorType())
{
return ((ColReference*)pItemExpr)->getColRefNameObj();
}
if(ITM_RENAME_COL == pItemExpr->getOperatorType())
{
return *(ColRefName*)(((RenameCol*)pItemExpr)->getNewColRefName());
}
CMPASSERT(FALSE);
return ColRefName();
}
//----------------------------------------------------------------------------
// set the LIST to an ItemExpr or ItemList tree
ItemExpr * BinderUtils::setItemExprFromList(const LIST(ItemExpr* ) & list,
CollHeap *heap,
ItemExprShapeEnum treeShape)
{
if( ! (list.entries() > 0 ) )
{
return NULL;
}
ItemExpr * result = list[0];
for (CollIndex i(1) ; i < list.entries() ; i++)
{
ItemExpr * pLeftSun = NULL;
ItemExpr * pRightSun = NULL;
switch(treeShape)
{
case LEFT_LINEAR_TREE:
{
pLeftSun = result;
pRightSun = list[i];
}
break;
case RIGHT_LINEAR_TREE:
{
pLeftSun = list[i];
pRightSun = result;
}
break;
case BUSHY_TREE:
default:
CMPASSERT(FALSE);
break;
};
result = new(heap)ItemList(pLeftSun, pRightSun);
} // for
return result;
}
//----------------------------------------------------------------------------
// Build a direction vector for the columns of the clustering index of the
// base table. The direction vector is a list of integers: 1 for ascending
// columns, and -1 for descending columns.
IntegerList *
BinderUtils::buildClusteringIndexDirectionVector(const NATable *naTable,
CollHeap *heap)
{
ExtendedQualName::SpecialTableType tableType =
naTable->getExtendedQualName().getSpecialType();
CMPASSERT(tableType != ExtendedQualName::RANGE_LOG_TABLE);
IntegerList *result = new(heap) IntegerList(heap);
const NAColumnArray &indexColumns =
naTable->getClusteringIndex()->getIndexKeyColumns();
CollIndex firstCol = 0;
CollIndex lastCol = indexColumns.entries()-1;
// If the NATable is of the IUD log, skip the first and last columns.
if (tableType == ExtendedQualName::IUD_LOG_TABLE ||
tableType == ExtendedQualName::GHOST_IUD_LOG_TABLE)
{
// Skip the first CI column: @EPOCH.
CMPASSERT(indexColumns[0]->getColName() == COMMV_EPOCH_COL);
firstCol++;
// Skip the last column of the IUD log: the log SYSKEY.
CMPASSERT(indexColumns[lastCol]->getColName() == "SYSKEY");
lastCol--;
}
for (CollIndex i=firstCol; i<=lastCol; i++)
{
if (indexColumns[i]->getClusteringKeyOrdering() == DESCENDING)
result->insert(-1);
else
result->insert(1);
}
return result;
} // BinderUtils::buildClusteringIndexDirectionVector
//----------------------------------------------------------------------------
// if we have renames on top of renames - this will return the ItemExpr below
// them. Example :in case we have a MAX(A_NAME) as max_a and the A_NAME is
// actually lets say a heading in the base table - we need to peel of all the
// Renames
const ItemExpr *BinderUtils::peelOffAllRenames(const ItemExpr *pColExpr)
{
const ItemExpr *pResult = pColExpr;
while (ITM_RENAME_COL == pResult->getOperatorType())
{
pResult = pResult->child(0);
}
return pResult;
} // MavBuilder::peelOfAllRenames
//----------------------------------------------------------------------------
// make the names into column Items.
void BinderUtils::appendToExprList(ItemExprList& toAddto,
const ConstStringList& columnNames,
CollHeap *heap,
OperatorTypeEnum itemType,
const CorrName& tableName)
{
for (CollIndex i(0) ; i < columnNames.entries() ; i++)
{
ColRefName *pColRefName = new(heap)
ColRefName(*(columnNames[i]), tableName, heap);
ItemExpr *pInsertValue = NULL;
switch(itemType)
{
case ITM_REFERENCE:
{
ColReference * pColRef = new(heap) ColReference(pColRefName);
pInsertValue = pColRef;
}
break;
case ITM_RENAME_COL:
{
RenameCol * pRenameCol = new(heap) RenameCol(NULL, pColRefName);
pInsertValue = pRenameCol;
}
break;
default:
CMPASSERT(FALSE);
}
toAddto.insert(pInsertValue);
}
} // BinderUtils::addToListAllColNamesAsItemExpr
//----------------------------------------------------------------------------
ItemExpr * BinderUtils::getNamesListAsItemExpr(
const ConstStringList & nameList,
CollHeap * heap,
OperatorTypeEnum itemType,
const CorrName& tableName)
{
ItemExprList resultList(heap);
BinderUtils::appendToExprList(resultList,
nameList,
heap,
itemType,
tableName);
return BinderUtils::setItemExprFromList(resultList, heap);
} // BinderUtils::getNamesListAsItemExpr
//----------------------------------------------------------------------------
ItemExpr *BinderUtils::buildPredOnCol(OperatorTypeEnum opType,
const NAString& colName,
Int32 constVal,
CollHeap *heap)
{
return new(heap)
BiRelat(opType,
new(heap) ColReference(new(heap)
ColRefName(colName, heap)),
new(heap) ConstValue(constVal));
}
//----------------------------------------------------------------------------
ColReference *BinderUtils::buildExpressionForSyskey(const CorrName *tableNameCorr,
CollHeap *heap,
Lng32 specialFlags,
const NAString *prefixColName)
{
NABoolean forceSystemColumn =
( (specialFlags & SP_ALL_COLUMNS) &&
!(specialFlags & SP_SYSKEY_AS_USER));
char syskeyName[] = "SYSKEY";
NAString colName;
if (prefixColName)
{
colName = *prefixColName + syskeyName;
}
else
{
colName = (specialFlags & SP_USE_AT_SYSKEY) ?
COMMV_BASE_SYSKEY_COL :
syskeyName;
}
ColReference *colRef = new(heap)
ColReference(new(heap)
ColRefName(colName,
*tableNameCorr,
heap));
if (forceSystemColumn)
colRef->setTargetColumnClass(SYSTEM_COLUMN);
return colRef;
} // buildExpressionForSyskey()
//----------------------------------------------------------------------------
// Build a list of ColReferences to the columns of the base table's
// clustering index columns.
ItemExpr *BinderUtils::buildClusteringIndexVector(const NATable *naTable,
CollHeap *heap,
const CorrName *nameOverride,
Lng32 specialFlags,
IntegerList *directionVector,
const NAString *prefixColName,
const NAString *prefixRenameColName)
{
ItemExpr *result = NULL;
ColRefName *colNameRef=NULL;
const NAColumnArray &indexColumns =
(specialFlags & SP_ALL_COLUMNS) ?
naTable->getNAColumnArray() :
naTable->getClusteringIndex()->getIndexKeyColumns();
const CorrName *tableNameCorr = NULL;
if (nameOverride != NULL)
{
tableNameCorr = nameOverride;
}
else
{
const QualifiedName& qualName = naTable->getTableName();
NAString schemaName(qualName.getSchemaName());
NAString catalogName(qualName.getCatalogName());
NAString tableName(naTable->getTableName().getObjectName());
tableNameCorr = new(heap) CorrName(tableName, heap, schemaName, catalogName);
}
for (CollIndex i=0; i<indexColumns.entries(); i++)
{
NAString colName = indexColumns[i]->getColName();
if (prefixColName != NULL)
colName = *prefixColName + colName;
ItemExpr *colExpr = NULL;
// If this is the SYSKEY or @SYSKEY column and appropriate flags are set
if ((colName == "SYSKEY"
||
(COMMV_SYSKEY_COL == colName && (specialFlags & SP_USE_AT_SYSKEY)))
&&
!(specialFlags & SP_USE_NULL))
{
ColReference *colRef = NULL;
colExpr = colRef = buildExpressionForSyskey(tableNameCorr, heap, specialFlags, prefixColName);
if (specialFlags & SP_RENAME_AT_SYSKEY)
{
// Rename @SYSKEY to SYSKEY
colNameRef = new(heap) ColRefName("SYSKEY", *tableNameCorr, heap);
}
else
{
colNameRef = &(colRef->getColRefNameObj());
}
}
else
{
if ( (specialFlags & SP_SKIP_EPOCH) && (COMMV_EPOCH_COL == colName))
{
continue;
}
if( (specialFlags & SP_SKIP_IUD_CONTROL_COLS)
&&
( COMMV_EPOCH_COL == colName
||
COMMV_OPTYPE_COL == colName
||
COMMV_IGNORE_COL == colName
||
COMMV_BITMAP_COL == colName
||
COMMV_RANGE_SIZE_COL == colName
||
COMMV_TS_COL == colName )
)
{
continue;
}
colNameRef = new(heap) ColRefName(colName, *tableNameCorr, heap);
if (specialFlags & SP_USE_NULL)
{
colExpr = new(heap) RenameCol(new(heap) ConstValue(), colNameRef);
}
else
{
colExpr = new(heap) ColReference(colNameRef);
}
}
if (specialFlags & SP_USE_OFFSET)
colExpr = new(heap) ItmSeqOffset( colExpr, 1);
if (specialFlags & SP_USE_LAST_NOT_NULL)
colExpr = new(heap) ItmSeqRunningFunction (ITM_LAST_NOT_NULL, colExpr);
if (directionVector!=NULL && (*directionVector)[i]==-1 && (!(specialFlags & SP_USE_NULL)) )
colExpr = new(heap) InverseOrder(colExpr);
if (prefixRenameColName != NULL)
{
colName = *prefixRenameColName + colName;
colNameRef = new(heap) ColRefName(colName, *tableNameCorr, heap);
}
colExpr = new(heap) RenameCol(colExpr, colNameRef);
if (result == NULL)
result = colExpr;
else
result = new(heap) ItemList(result, colExpr);
}
if (nameOverride == NULL)
delete tableNameCorr;
return result;
} // buildClusteringIndexVector()
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// QualNamePtrList
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Does this list of names contain 'name'?
NABoolean QualNamePtrList::containsName(const QualifiedName& name) const
{
for (CollIndex i=0; i<entries(); i++)
{
if (*at(i) == name)
return TRUE;
}
return FALSE;
}