Beispiel #1
0
// replace constant with new or existing SelParameter
void CacheWA::replaceWithNewOrOldSelParam
(ConstValue *val, const NAType *typ, const Selectivity sel, ExprValueId& tgt,
 BindWA &bindWA)
{
  // match SelParameters only in complex queries
  Lng32 complexity = (Lng32)CmpCommon::getDefaultNumeric
    (MATCH_CONSTANTS_OF_EQUALITY_PREDICATES);
  if (complexity >= 0 && numberOfScans_ >= complexity) {
    SelParameter *sParm;
    if (actuals_.find(val, (ConstantParameter**)&sParm)) {
      sParm->addPosition(++posCounter_);
      tgt = sParm; // replace with existing SelParameter
      return;
    }
    if (sels_.find(val, &sParm)) {
      sParm->addPosition(++posCounter_);
      tgt = sParm; // replace with existing SelParameter
      return;
    }
  }
  // query is simple or there is no matching constant.
  // introduce new SelParameter.
  SelParameter *nParam = new (wHeap()) SelParameter
    (val, wHeap(), typ, sel, ++posCounter_);
  addSelParam(nParam, bindWA);
  tgt = nParam;
}
Beispiel #2
0
// return current query's formal SelParamTypes
const SelParamTypeList *CacheWA::getFormalSelParamTypes() 
{ 
  // selTypes_ is always derived from sels_; so, free any previous
  // selTypes_ before deriving it again from sels_
  if (selTypes_) { NADELETE(selTypes_,SelParamTypeList,wHeap()); }
  // save pointer in selTypes_ so ~CacheWA() can free it
  selTypes_ = new (wHeap()) SelParamTypeList(&sels_, wHeap());
  return selTypes_;
}
Beispiel #3
0
// return current query's formal parameter types
const ParameterTypeList *CacheWA::getFormalParamTypes() 
{ 
  // parmTypes_ is always derived from actuals_; so, free any previous
  // parmTypes_ before deriving it again from actuals_
  if (parmTypes_) { NADELETE(parmTypes_,ParameterTypeList,wHeap()); }
  // save pointer in parmTypes_ so ~CacheWA() can free it
  parmTypes_ = new (wHeap()) ParameterTypeList(&actuals_, wHeap());
  return parmTypes_;
}
Beispiel #4
0
// compose and return TextKey of current query
TextKey* CacheWA::getTextKey(const char *sText, Lng32 charset,
                             const QryStmtAttributeSet& attrs)
{ 
  if (!tkey_) {
    // capture compiler environment for this query
    CompilerEnv *env = new (wHeap()) CompilerEnv
      (wHeap(), CmpMain::PREPARSE, attrs);

    // use query's formal parameter types, etc in creating its candidate Key
    // because the Key must hash to the same address as its cache entry.
    tkey_ = new (wHeap()) TextKey(sText, env, wHeap(), charset);
  }
  return tkey_; 
}
Beispiel #5
0
// compose and return cache key of current query
CacheKey* CacheWA::getCacheKey(const QryStmtAttributeSet& attrs)
{ 
  if (!ckey_) {
    // capture compiler environment for this query
    CompilerEnv *env = new (wHeap()) CompilerEnv(wHeap(), phase_, attrs);

    // use query's formal parameter types, etc in creating its candidate Key
    // because the Key must hash to the same address as its cache entry.
    ckey_ = new (wHeap()) CacheKey
      (qryText_, phase_, env, *getFormalParamTypes(), 
       *getFormalSelParamTypes(), wHeap(), reqdShape_, 
       isoLvl_, accMode_, isoLvlIDU_, autoCmt_, flags_, rbackMode_,
       tables_, useView_);
  }
  return ckey_; 
}
Beispiel #6
0
// -----------------------------------------------------------------------
// make an IndexDesc from an existing TableDesc and an NAFileSet
// -----------------------------------------------------------------------
IndexDesc::IndexDesc(TableDesc *tdesc, 
                     NAFileSet *fileSet, 
                     CmpContext* cmpContext)
     : tableDesc_(tdesc), clusteringIndexFlag_(FALSE), 
       identityColumnUniqueIndexFlag_(FALSE), partFunc_(NULL),
       fileSet_(fileSet), cmpContext_(cmpContext), scanBasicCosts_(NULL)
{
  DCMPASSERT( tdesc != NULL AND fileSet != NULL );

  Lng32 ixColNumber;
  ValueId keyValueId;
  ValueId baseValueId;

  const NATable *naTable = tdesc->getNATable();

  indexLevels_ = fileSet_->getIndexLevels();

  // ---------------------------------------------------------------------
  // Make the column list for the index or vertical partition.
  // Any reference to index also holds for vertical partitions.
  // ---------------------------------------------------------------------
  const NAColumnArray & allColumns = fileSet_->getAllColumns();

  // any index gets a new set of IndexColumn
  // item expressions and new value ids
  CollIndex i = 0;
  for (i = 0; i < allColumns.entries(); i++)
    {
      ItemExpr *baseItemExpr = NULL;

      // make a new IndexColumn item expression, indicate how it is
      // defined (in terms of base table columns) and give a value
      // id to the new IndexColumn expression
      if (allColumns[i]->getPosition() >= 0)
	{
	  baseValueId =
	    tdesc->getColumnList()[allColumns[i]->getPosition()];
	  baseItemExpr = baseValueId.getItemExpr();
	}
      else
	{
	  // this column doesn't exist in the base table.
	  // This is the KEYTAG column of sql/mp indices.
	  ItemExpr * keytag = new(wHeap())
            NATypeToItem((NAType *)(allColumns[i]->getType()));
	  keytag->synthTypeAndValueId();
	  baseValueId = keytag->getValueId();

	  baseItemExpr = NULL;
	}

#pragma nowarn(1506)   // warning elimination 
      IndexColumn *ixcol = new(wHeap()) IndexColumn(fileSet_,i,baseValueId);
#pragma warn(1506)  // warning elimination 
      ixcol->synthTypeAndValueId();

      // add the newly obtained value id to the index column list
      indexColumns_.insert(ixcol->getValueId());

      // if the index column is defined as a 1:1 copy of a base
      // column, add it as an equivalent index column (EIC) to the
      // base column item expression
      if ((baseItemExpr) &&
	  (baseItemExpr->getOperatorType() == ITM_BASECOLUMN))
	((BaseColumn *) baseItemExpr)->addEIC(ixcol->getValueId());
    }

  // ---------------------------------------------------------------------
  // make the list of access key columns in the index and make a list
  // of the order that the index provides
  // ---------------------------------------------------------------------
  const NAColumnArray & indexKeyColumns = fileSet_->getIndexKeyColumns();
  for (i = 0; i < indexKeyColumns.entries(); i++)
    {
      // which column of the index is this (usually this will be == i)
#pragma nowarn(1506)   // warning elimination 

      if ( !naTable->isHbaseTable() )
         ixColNumber = allColumns.index(indexKeyColumns[i]);
      else {
         // For Hbase tables, a new NAColumn is created for every column
         // in an index. The above pointer-based lookup for the key column
         // in base table will only find the index column itself. The
         // fix is to lookup by the column name and type as is 
         // implemented by the getColumnPosition() method.
         ixColNumber = allColumns.getColumnPosition(*indexKeyColumns[i]);
         CMPASSERT(ixColNumber >= 0);
      }

#pragma warn(1506)  // warning elimination 

      // insert the value id of the index column into the key column
      // value id list
      keyValueId = indexColumns_[ixColNumber];
      indexKey_.insert(keyValueId);

      // insert the same value id into the order list, if the column
      // is in ascending order, otherwise insert the inverse of the
      // column
      if (indexKeyColumns.isAscending(i))
	{
	  orderOfKeyValues_.insert(keyValueId);
	}
      else
	{
	  InverseOrder *invExpr = new(wHeap())
	    InverseOrder(keyValueId.getItemExpr());
	  invExpr->synthTypeAndValueId();
	  orderOfKeyValues_.insert(invExpr->getValueId());
	}
    }

  markIdentityColumnUniqueIndex(tdesc);

  // ---------------------------------------------------------------------
  // Find the clustering key columns in the index and store their value
  // ids in clusteringKey_
  // ---------------------------------------------------------------------
  NABoolean found = TRUE;
  const NAColumnArray & clustKeyColumns =
                      naTable->getClusteringIndex()->getIndexKeyColumns();

  for (i = 0; i < clustKeyColumns.entries() AND found; i++)
    {
      // which column of the index is this?
#pragma nowarn(1506)   // warning elimination 
      ixColNumber = allColumns.index(clustKeyColumns[i]);
#pragma warn(1506)  // warning elimination 

      found = (ixColNumber != NULL_COLL_INDEX);

      if (found)
	{
	  // insert the value id of the index column into the clustering key
	  // value id list
	  keyValueId = indexColumns_[ixColNumber];
	  clusteringKey_.insert(keyValueId);
	}
      else
	{
	  // clustering key isn't contained in this index, clear the
	  // list that is supposed to indicate the clustering key
	  clusteringKey_.clear();
	}
    }

  // ---------------------------------------------------------------------
  // make the list of partitioning key columns in the index and make a list
  // of the order that the partitioning provides
  // ---------------------------------------------------------------------
  const NAColumnArray & partitioningKeyColumns 
                                    = fileSet_->getPartitioningKeyColumns();
  for (i = 0; i < partitioningKeyColumns.entries(); i++)
    {
      // which column of the index is this 
#pragma nowarn(1506)   // warning elimination 
      ixColNumber = allColumns.index(partitioningKeyColumns[i]);
#pragma warn(1506)  // warning elimination 

      // insert the value id of the index column into the partitioningkey column
      // value id list
      keyValueId = indexColumns_[ixColNumber];
      partitioningKey_.insert(keyValueId);

      // insert the same value id into the order list, if the column
      // is in ascending order, otherwise insert the inverse of the
      // column
      if (partitioningKeyColumns.isAscending(i))
	{
	  orderOfPartitioningKeyValues_.insert(keyValueId);
	}
      else
	{
	  InverseOrder *invExpr = new(wHeap())
	    InverseOrder(keyValueId.getItemExpr());
	  invExpr->synthTypeAndValueId();
	  orderOfPartitioningKeyValues_.insert(invExpr->getValueId());
	}
    }

  // ---------------------------------------------------------------------
  // If this index is partitioned, find the partitioning key columns
  // and build a partitioning function.
  // ---------------------------------------------------------------------
  if ((fileSet_->getCountOfFiles() > 1) ||
      (fileSet_->getPartitioningFunction() &&
       fileSet_->getPartitioningFunction()->
       isARoundRobinPartitioningFunction()))
    partFunc_ = fileSet_->getPartitioningFunction()->
      createPartitioningFunctionForIndexDesc(this);
  
} // IndexDesc::IndexDesc()