Sfoglia il codice sorgente

Merge pull request #9060 from ghalliday/issue8603

HPCC-8603 When assign to SELF.x.y also check if SELF.x assigned

Reviewed-By: Shamser Ahmed <shamser.ahmed@lexisnexis.co.uk>
Reviewed-By: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 8 anni fa
parent
commit
8b7b3b5b79
3 ha cambiato i file con 50 aggiunte e 12 eliminazioni
  1. 2 0
      ecl/hql/hqlgram.hpp
  2. 41 12
      ecl/hql/hqlgram2.cpp
  3. 7 0
      ecl/regress/issue8603.ecl

+ 2 - 0
ecl/hql/hqlgram.hpp

@@ -612,6 +612,8 @@ public:
     virtual size32_t errCount();
     virtual size32_t warnCount();
     
+    IHqlExpression * queryAlreadyAssigned(IHqlExpression * select);
+    bool checkAlreadyAssigned(const attribute & errpos, IHqlExpression * select);
     IHqlExpression * findAssignment(IHqlExpression *field);
     void addAssignment(attribute &field, attribute &source);
     void addAssignment(const attribute & errpos, IHqlExpression * targetExpr, IHqlExpression * srcExpr);

+ 41 - 12
ecl/hql/hqlgram2.cpp

@@ -1350,6 +1350,42 @@ IHqlExpression * HqlGram::leaveService(const attribute & errpos)
 
 /* this func does not affect linkage */
 /* Assume: field is of the form: (((self.r1).r2...).rn). */
+IHqlExpression * HqlGram::queryAlreadyAssigned(IHqlExpression * select)
+{
+    IHqlExpression * match = (IHqlExpression *)select->queryTransformExtra();
+    if (match && !match->isAttribute())
+        return select;
+    if (select->getOperator() == no_select)
+    {
+        IHqlExpression * lhs = select->queryChild(0);
+        if (lhs->getOperator() == no_select)
+            return queryAlreadyAssigned(lhs);
+    }
+    return nullptr;
+}
+
+bool HqlGram::checkAlreadyAssigned(const attribute & errpos, IHqlExpression * select)
+{
+    IHqlExpression * assigned = queryAlreadyAssigned(select);
+    if (!assigned)
+        return false;
+
+    StringBuffer s;
+    getFldName(assigned,s);
+    if (assigned == select)
+    {
+        reportError(ERR_VALUEDEFINED, errpos, "A value for \"%s\" has already been specified", s.str());
+    }
+    else
+    {
+        reportWarning(CategorySyntax, ERR_VALUEDEFINED, errpos.pos, "A value for \"%s\" has already been specified", s.str());
+        // MORE: Report this as an error in 7.0
+        //reportWarning(CategorySyntax, SeverityError, ERR_VALUEDEFINED, errpos.pos, "A value for \"%s\" has already been specified", s.str());
+    }
+
+    return true;
+}
+
 IHqlExpression * HqlGram::findAssignment(IHqlExpression *field)
 {
 //  assertex(field->getOperator() == no_select);
@@ -1434,11 +1470,9 @@ void HqlGram::addAssignment(attribute & target, attribute &source)
     }
     else if (targetOp == no_select)
     {
-        // self.* := expr;      assertex(targetExpr->getOperator()==no_select);
-        if (findAssignment(targetExpr))
+        // self.* := expr;
+        if (checkAlreadyAssigned(target, targetExpr))
         {
-            StringBuffer s;
-            reportError(ERR_VALUEDEFINED, target, "A value for \"%s\" has already been specified", getFldName(targetExpr,s).str());
         }
         else if (targetExpr->queryType()->getTypeCode() == type_row)
         {
@@ -1481,10 +1515,8 @@ void HqlGram::addAssignment(const attribute & errpos, IHqlExpression * targetExp
     else if (targetOp == no_select)
     {
         // self.* := expr;      assertex(targetExpr->getOperator()==no_select);
-        if (findAssignment(targetExpr))
+        if (checkAlreadyAssigned(errpos, targetExpr))
         {
-            StringBuffer s;
-            reportError(ERR_VALUEDEFINED, errpos, "A value for \"%s\" has already been specified", getFldName(targetExpr,s).str());
         }
         else if (targetExpr->queryType()->getTypeCode() == type_row)
         {
@@ -1805,11 +1837,8 @@ void HqlGram::addAssignall(IHqlExpression *tgt, IHqlExpression *src, const attri
     assertex(src);
 
     node_operator tgtOp = tgt->getOperator();
-    if ((tgtOp == no_select) && findAssignment(tgt))
-    {
-        StringBuffer s;
-        reportError(ERR_VALUEDEFINED, errpos, "A value for \"%s\" has already been specified", getFldName(tgt,s).str());
-    }
+    if (tgtOp == no_select)
+        checkAlreadyAssigned(errpos, tgt);
 
     IHqlExpression * srcRecord = src->queryRecord();
     IHqlExpression * tgtRecord = tgt->queryRecord();

+ 7 - 0
ecl/regress/issue8603.ecl

@@ -0,0 +1,7 @@
+r  := { INTEGER y };
+
+d := DATASET(1, TRANSFORM({ r x },   SELF.x.y := COUNTER));
+
+d2 := DATASET(1, TRANSFORM({ r x }, SELF.x := d[1].x, SELF.x.y := COUNTER));
+
+OUTPUT(d2);