trafodion-codereview mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From zellerh <...@git.apache.org>
Subject [GitHub] incubator-trafodion pull request #826: {TRAFODION-1562] Index maintenence pe...
Date Thu, 10 Nov 2016 02:19:28 GMT
Github user zellerh commented on a diff in the pull request:

    https://github.com/apache/incubator-trafodion/pull/826#discussion_r87317361
  
    --- Diff: core/sql/optimizer/BindRelExpr.cpp ---
    @@ -10383,6 +10423,310 @@ NABoolean Insert::isUpsertThatNeedsMerge(NABoolean isAlignedRowFormat,
NABoolean
          return FALSE;
     }
     
    +#ifdef __ignore
    +// take an insert(src) node and transform it into
    +// a tuple_flow with old/new rows flowing to the IM tree.
    +// with a newly created input_scan
    +RelExpr* Insert::xformUpsertToEfficientTreeNoDup(BindWA *bindWA) 
    +{
    +  NATable *naTable = bindWA->getNATable(getTableName());
    +  if (bindWA->errStatus())
    +    return NULL;
    +  if ((naTable->getViewText() != NULL) && (naTable->getViewCheck()))		
    +    {		
    +      *CmpCommon::diags() << DgSqlCode(-3241) 		
    +			  << DgString0(" View with check option not allowed.");	    		
    +      bindWA->setErrStatus();		
    +      return NULL;		
    +    }
    +
    +  RelExpr *topNode = this;
    +  // Create a new BindScope, to encompass the new nodes 
    +  // upsert(left_join(input_scan, tuple))
    +  // and any inlining nodes that will be created. Any values the upsert
    +  // and children will need from src will be marked as outer references in that
    +  // new BindScope. We assume that "src" is already bound.
    +  ValueIdSet currOuterRefs = bindWA->getCurrentScope()->getOuterRefs();
    +
    +  CMPASSERT(child(0)->nodeIsBound());
    +
    +  BindScope *upsertScope = bindWA->getCurrentScope();
    +
    +  // columns of the target table
    +  const ValueIdList &tableCols = updateToSelectMap().getTopValues();
    +  const ValueIdList &sourceVals = updateToSelectMap().getBottomValues();
    +
    +  // create a Join node - left join of the base table columns with the columns to be
upserted.
    +  // columns of the target table
    +  CMPASSERT(child(0)->nodeIsBound());
    +  
    +  Scan * targetTableScan =
    +    new (bindWA->wHeap())
    +    Scan(CorrName(getTableDesc()->getCorrNameObj(), bindWA->wHeap()));
    +
    + 
    +  //join predicate between source columns and target table.
    +  ItemExpr * keyPred = NULL;
    +  ItemExpr * keyPredPrev = NULL;
    +  BaseColumn* baseCol;
    +  ColReference * targetColRef;
    +  int predCount = 0;
    +  ValueIdSet newOuterRefs;
    +  ItemExpr * pkeyValPrev;
    +  ItemExpr * pkeyVals;
    +  for (CollIndex i = 0; i < tableCols.entries(); i++)
    +    {
    +      baseCol = (BaseColumn *)(tableCols[i].getItemExpr()) ;
    +      if (baseCol->getNAColumn()->isSystemColumn())
    +	continue;
    +
    +      targetColRef = new(bindWA->wHeap()) ColReference(
    +						       new(bindWA->wHeap()) ColRefName(
    +										       baseCol->getNAColumn()->getFullColRefName(), bindWA->wHeap()));
    +    
    +
    +      if (baseCol->getNAColumn()->isClusteringKey())
    +	{
    +	  // create a join/key predicate between source and target table,
    +	  // on the clustering key columns of the target table, making
    +	  // ColReference nodes for the target table, so that we can bind
    +	  // those to the new scan
    +	  keyPredPrev = keyPred;
    +	  keyPred = new (bindWA->wHeap())
    +	    BiRelat(ITM_EQUAL, targetColRef, 
    +		    sourceVals[i].getItemExpr(),
    +		    baseCol->getType().supportsSQLnull());
    +	  predCount++;
    +	  if (predCount > 1) 
    +	    {
    +	      keyPred = new(bindWA->wHeap()) BiLogic(ITM_AND,
    +						     keyPredPrev,
    +						     keyPred);  
    +	    }
    +	  pkeyValPrev = pkeyVals;
    +    
    +	  pkeyVals = tableCols[i].getItemExpr();
    +	  if (i > 0) 
    +	    {
    +	      pkeyVals = new(bindWA->wHeap()) ItemList(pkeyVals,pkeyValPrev);
    +      
    +	    }
    +	}
    +     
    +    }
    + 
    +  // Map the table's primary key values to the source lists key values
    +  ValueIdList tablePKeyVals = NULL;
    +  ValueIdList sourcePKeyVals = NULL;
    +  
    +  pkeyVals->convertToValueIdList(tablePKeyVals,bindWA,ITM_ITEM_LIST);
    +  updateToSelectMap().mapValueIdListDown(tablePKeyVals,sourcePKeyVals);
    +  
    +  Join *lj = new(bindWA->wHeap()) Join(child(0),targetTableScan,REL_LEFT_JOIN,keyPred);
    +  lj->doNotTransformToTSJ();	  
    +  lj->setTSJForWrite(TRUE);
    +   bindWA->getCurrentScope()->xtnmStack()->createXTNM();
    +  RelExpr *boundLJ = lj->bindNode(bindWA);
    +  if (bindWA->errStatus())
    +    return NULL;
    +  bindWA->getCurrentScope()->xtnmStack()->removeXTNM();
    +  setChild(0,boundLJ);
    +  topNode = handleInlining(bindWA,topNode);
    +
    +
    +  return topNode; 
    +}
    +#endif
    +// take an insert(src) node and transform it into
    +// a tuple_flow with old/new rows flowing to the IM tree.
    +// with a newly created sequence node used to eliminate duplicates.
    +/*
    +               NJ
    +            /      \
    +         Sequence   NJ
    +        /            \  
    +     Left Join        IM Tree 
    +     /        \
    +    /          \
    +Input Tuplelist  Target Table Scan
    +or select list
    +*/
    +         
    +RelExpr* Insert::xformUpsertToEfficientTree(BindWA *bindWA) 
    +{
    +  NATable *naTable = bindWA->getNATable(getTableName());
    +  if (bindWA->errStatus())
    +    return NULL;
    +  if ((naTable->getViewText() != NULL) && (naTable->getViewCheck()))		
    +    {		
    +      *CmpCommon::diags() << DgSqlCode(-3241) 		
    +			  << DgString0(" View with check option not allowed.");	    		
    +      bindWA->setErrStatus();		
    +      return NULL;		
    +    }
    +
    +  RelExpr *topNode = this;
    + 
    +  CMPASSERT(child(0)->nodeIsBound());
    +
    +  BindScope *upsertScope = bindWA->getCurrentScope();
    +  // Create a new BindScope, to encompass the new nodes 
    +  // upsert(left_join(input_scan, tuple))
    +  // and any inlining nodes that will be created. Any values the upsert
    +  // and children will need from src will be marked as outer references in that
    +  // new BindScope. We assume that "src" is already bound.
    +  ValueIdSet currOuterRefs = bindWA->getCurrentScope()->getOuterRefs();
    +  // Save the current RETDesc.
    +  RETDesc *prevRETDesc = bindWA->getCurrentScope()->getRETDesc();
    +
    +  // columns of the target table
    +  const ValueIdList &tableCols = updateToSelectMap().getTopValues();
    +  const ValueIdList &sourceVals = updateToSelectMap().getBottomValues();
    +
    +  // create a Join node - left join of the base table columns with the columns to be
upserted.
    +  // columns of the target table
    +  CMPASSERT(child(0)->nodeIsBound());
    +  
    +  Scan * targetTableScan =
    +    new (bindWA->wHeap())
    +    Scan(CorrName(getTableDesc()->getCorrNameObj(), bindWA->wHeap()));
    +
    + 
    +  //join predicate between source columns and target table.
    +  ItemExpr * keyPred = NULL;
    +  ItemExpr * keyPredPrev = NULL;
    +  BaseColumn* baseCol;
    +  ColReference * targetColRef;
    +  int predCount = 0;
    +  ValueIdSet newOuterRefs;
    +  ItemExpr * pkeyValPrev;
    +  ItemExpr * pkeyVals = NULL;
    +  for (CollIndex i = 0; i < tableCols.entries(); i++)
    +    {
    +      baseCol = (BaseColumn *)(tableCols[i].getItemExpr()) ;
    +      if (baseCol->getNAColumn()->isSystemColumn())
    +	continue;
    +
    +      targetColRef = new(bindWA->wHeap()) ColReference(
    +						       new(bindWA->wHeap()) ColRefName(
    +										       baseCol->getNAColumn()->getFullColRefName(), bindWA->wHeap()));
    +    
    +
    +      if (baseCol->getNAColumn()->isClusteringKey())
    +	{
    +	  // create a join/key predicate between source and target table,
    +	  // on the clustering key columns of the target table, making
    +	  // ColReference nodes for the target table, so that we can bind
    +	  // those to the new scan
    +	  keyPredPrev = keyPred;
    +	  keyPred = new (bindWA->wHeap())
    +	    BiRelat(ITM_EQUAL, targetColRef, 
    +		    sourceVals[i].getItemExpr(),
    +		    baseCol->getType().supportsSQLnull());
    +	  predCount++;
    +	  if (predCount > 1) 
    +	    {
    +	      keyPred = new(bindWA->wHeap()) BiLogic(ITM_AND,
    +						     keyPredPrev,
    +						     keyPred);  
    +	    }
    +	  pkeyValPrev = pkeyVals;
    +    
    +	  pkeyVals = tableCols[i].getItemExpr();
    +	  
    +	  if (i > 0) 
    +	    {
    +	      pkeyVals = new(bindWA->wHeap()) ItemList(pkeyVals,pkeyValPrev);
    +      
    +	    }
    +	}
    +     
    +    }
    + 
    +  // Map the table's primary key values to the source lists key values
    +  ValueIdList tablePKeyVals = NULL;
    +  ValueIdList sourcePKeyVals = NULL;
    +  
    +  pkeyVals->convertToValueIdList(tablePKeyVals,bindWA,ITM_ITEM_LIST);
    +  updateToSelectMap().mapValueIdListDown(tablePKeyVals,sourcePKeyVals);
    +  
    +
    +
    +  Join *lj = new(bindWA->wHeap()) Join(child(0),targetTableScan,REL_LEFT_JOIN,keyPred);
    +  lj->doNotTransformToTSJ();	  
    --- End diff --
    
    I assume this is because we want to use the old state of the target table, before we applied
any updates. But, what if I do an upsert of 1000 rows into a table with 10 billion rows? Do
we really want to read 10 billion rows with all their columns into a hash join or merge join?
The merge would be vastly more efficient for this case - or am I missing something?
    
    Another way to see the old state of the table would be to add a sort node above the join,
so in this case we would only need to sort 1000 rows and we may need to do a sort anyway for
the sequence. So, maybe just add code that forces a sort operator for the required order of
the sequence node (at least forces it if we use a nested join or a merge join w/o a sort).


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

Mime
View raw message