Github user zellerh commented on a diff in the pull request: https://github.com/apache/incubator-trafodion/pull/1253#discussion_r142531876 --- Diff: core/sql/generator/GenRelUpdate.cpp --- @@ -292,8 +292,85 @@ static short genUpdExpr( return 0; } -static short genUpdConstraintExpr(Generator *generator) +// Used to generate update or insert constraint expressions for update operators +static short genUpdConstraintExpr(Generator * generator, + ItemExpr * constrTree, + const ValueIdSet & constraintColumns, + ValueIdArray & targetRecExprArray, + ex_expr ** targetExpr /* out */) { + ExpGenerator * expGen = generator->getExpGenerator(); + + // The Attributes for the table columns refer to the old values of the column. + // The constraints must operate on the new values, though. So we must do a + // switcheroo on the Attributes for the update expression. The target value IDs + // come from targetRecExprArray. + + ValueIdList savedSourceVIDlist; + NAList<Attributes*> savedSourceAttrsList(generator->wHeap()); + + for (ValueId sourceValId = constraintColumns.init(); + constraintColumns.next(sourceValId); + constraintColumns.advance(sourceValId)) + { + NAColumn * sourceCol = ((IndexColumn*)sourceValId.getItemExpr())->getNAColumn(); + ValueId targetValId; + NABoolean found = FALSE; + for (CollIndex ni = 0; (!found) && (ni < targetRecExprArray.entries()); ni++) + { + const ItemExpr *assignExpr = targetRecExprArray[ni].getItemExpr(); + targetValId = assignExpr->child(0)->castToItemExpr()->getValueId(); + NAColumn *targetCol = NULL; + if (targetValId.getItemExpr()->getOperatorType() == ITM_BASECOLUMN) + targetCol = ((BaseColumn*)targetValId.getItemExpr())->getNAColumn(); + else if (targetValId.getItemExpr()->getOperatorType() == ITM_INDEXCOLUMN) + targetCol = ((IndexColumn*)targetValId.getItemExpr())->getNAColumn(); + + if ((targetCol) && + (targetCol->getColName() == sourceCol->getColName()) && + (targetCol->getHbaseColFam() == sourceCol->getHbaseColFam()) && + (targetCol->getHbaseColQual() == sourceCol->getHbaseColQual()) && + (targetCol->getNATable()->getTableName().getQualifiedNameAsAnsiString() == + sourceCol->getNATable()->getTableName().getQualifiedNameAsAnsiString())) + { + found = TRUE; + break; + } + } + + if (found) + { + Attributes * sourceValAttr = (generator->addMapInfo(sourceValId, 0))->getAttr(); + Attributes * targetValAttr = (generator->getMapInfo(targetValId, 0))->getAttr(); + + // Save original location attributes so we can change them back after + // generating the update constraint expression + + Attributes * savedValAttr = new(generator->wHeap()) Attributes(); + savedValAttr->copyLocationAttrs(sourceValAttr); + savedSourceAttrsList.insert(savedValAttr); + savedSourceVIDlist.insert(sourceValId); + + sourceValAttr->copyLocationAttrs(targetValAttr); + } + + } + + // Now that we have remapped the Attributes for the columns to their values + // in the new record, we can generate the update constraint expression. + + expGen->generateExpr(constrTree->getValueId(), ex_expr::exp_SCAN_PRED, + targetExpr); + + // Now put the Attributes back the way they were. + + for (Lng32 i = 0; i < savedSourceVIDlist.entries(); i++) + { + ValueId sourceValId = savedSourceVIDlist[i]; + Attributes * sourceValAttr = (generator->getMapInfo(sourceValId, 0))->getAttr(); + sourceValAttr->copyLocationAttrs(savedSourceAttrsList[i]); --- End diff -- If we created a new map table entry on line 343, this code won't delete that entry. As far as I can tell, it would put back the temporary location that was assigned for a new entry? See comment above, I would recommend not modifying map tables. If you want to stay with the MapTable method, though, it might be better to drop those entries that were created on line 343 here.
---