소스 검색

Merge pull request #13135 from ghalliday/issue23091

HPCC-23091 Fix problem with ABSTRACT MODULE caused by parameter replacement

Reviewed-By: Shamser Ahmed <shamser.ahmed@lexisnexis.co.uk>
Reviewed-By: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 5 년 전
부모
커밋
3bdda57bd9
3개의 변경된 파일32개의 추가작업 그리고 6개의 파일을 삭제
  1. 24 3
      ecl/hql/hqlexpr.cpp
  2. 1 0
      ecl/hql/hqltrans.ipp
  3. 7 3
      ecl/hql/hqlvalid.cpp

+ 24 - 3
ecl/hql/hqlexpr.cpp

@@ -4637,8 +4637,11 @@ switch (op)
         break;
     case no_funcdef:
         {
-            assertex(queryType()->getTypeCode() == type_function && queryChild(1) && queryChild(1)->getOperator() == no_sortlist);
+            IHqlExpression * formals = queryChild(1);
+            assertex(queryType()->getTypeCode() == type_function && queryChild(1) && formals->getOperator() == no_sortlist);
             assertex(queryType()->queryChildType() == queryChild(0)->queryType());
+            ForEachChild(i, formals)
+                assertex(formals->queryChild(i)->getOperator() == no_param);
             break;
         }
     case no_setresult:
@@ -9270,6 +9273,23 @@ void CHqlLibraryInstance::sethash()
 
 //==============================================================================================================
 
+//Replace expressions, but do not replace parameters
+static HqlTransformerInfo quickNoParamExpressionReplacerInfo("QuickNoParamExpressionReplacer");
+class HQL_API QuickNoParamExpressionReplacer : public QuickExpressionReplacer
+{
+public:
+    QuickNoParamExpressionReplacer() : QuickExpressionReplacer(quickNoParamExpressionReplacerInfo)
+    {
+    }
+    virtual IHqlExpression * createTransformedBody(IHqlExpression * expr)
+    {
+        if (expr->getOperator() == no_param)
+            return LINK(expr);
+        return QuickExpressionReplacer::createTransformedBody(expr);
+    }
+};
+
+
 //Each function instance needs to have a unique set of parameters
 static IHqlExpression * cloneFunction(IHqlExpression * expr)
 {
@@ -9280,7 +9300,7 @@ static IHqlExpression * cloneFunction(IHqlExpression * expr)
     if (formals->numChildren() == 0)
         return LINK(expr);
 
-    QuickExpressionReplacer replacer;
+    QuickNoParamExpressionReplacer replacer;
     ForEachChild(i, formals)
     {
         IHqlExpression * formal = formals->queryChild(i);
@@ -11913,7 +11933,8 @@ protected:
                 if (oldModule != newModule)
                 {
                     IIdAtom * selectedName = expr->queryChild(3)->queryId();
-                    newModule.setown(checkCreateConcreteModule(ctx.errors, newModule, newModule->queryAttribute(_location_Atom)));
+                    IHqlExpression * location = newModule->queryAttribute(_location_Atom);
+                    newModule.setown(checkCreateConcreteModule(ctx.errors, newModule, location));
 
                     HqlDummyLookupContext dummyctx(ctx.errors);
                     IHqlScope * newScope = newModule->queryScope();

+ 1 - 0
ecl/hql/hqltrans.ipp

@@ -264,6 +264,7 @@ class HQL_API QuickExpressionReplacer : public QuickHqlTransformer
 {
 public:
     QuickExpressionReplacer();
+    QuickExpressionReplacer(HqlTransformerInfo & _info) : QuickHqlTransformer(_info, NULL) {}
 
     void setMapping(IHqlExpression * oldValue, IHqlExpression * newValue);
 };

+ 7 - 3
ecl/hql/hqlvalid.cpp

@@ -153,12 +153,16 @@ void reportAbstractModule(IErrorReceiver & errors, IHqlExpression * expr, const
         }
     }
 
+    StringBuffer name;
+    if (expr->queryId())
+        name.append(" (").append(str(expr->queryId())).append(")");
+
     if (fieldText.length())
-        reportError(&errors, ERR_ABSTRACT_MODULE, errpos, "Cannot use an abstract MODULE in this context (%s undefined)", fieldText.str());
+        reportError(&errors, ERR_ABSTRACT_MODULE, errpos, "Cannot use an abstract MODULE%s in this context (%s undefined)", name.str(), fieldText.str());
     else if (expr->hasAttribute(interfaceAtom))
-        reportError(&errors, ERR_ABSTRACT_MODULE, errpos, "Cannot use an abstract MODULE in this context (INTERFACE must be instantiated)");
+        reportError(&errors, ERR_ABSTRACT_MODULE, errpos, "Cannot use an abstract MODULE%s in this context (INTERFACE must be instantiated)", name.str());
     else
-        reportError(&errors, ERR_ABSTRACT_MODULE, errpos, "Cannot use an abstract MODULE in this context");
+        reportError(&errors, ERR_ABSTRACT_MODULE, errpos, "Cannot use an abstract MODULE%s in this context", name.str());
 }
 
 IHqlExpression * checkCreateConcreteModule(IErrorReceiver * errors, IHqlExpression * expr, const IHqlExpression * locationExpr)