Просмотр исходного кода

HPCC-18799 Improve default support for child dataset fields

Signed-off-by: Shamser Ahmed <shamser.ahmed@lexisnexis.co.uk>
Shamser Ahmed 7 лет назад
Родитель
Сommit
ed0300b73d

+ 1 - 1
ecl/hql/hqlexpr.cpp

@@ -13712,7 +13712,7 @@ extern HQL_API IHqlExpression * createNullExpr(IHqlExpression * expr)
     if (expr->getOperator()==no_select)
         return createNullExpr(expr->queryChild(1));
     IHqlExpression * defaultValue = queryAttributeChild(expr, defaultAtom, 0);
-    if (defaultValue)
+    if (defaultValue && defaultValue->getOperator()!=no_null)
         return LINK(defaultValue);
     return createNullExpr(expr->queryType());
 }

+ 2 - 1
ecl/hql/hqlgram.y

@@ -4778,8 +4778,9 @@ fieldAttr
                         {
                             $$.setExpr(createExprAttribute(xmlDefaultAtom, $3.getExpr()), $1);
                         }
-    | DEFAULT '(' constExpression ')'
+    | DEFAULT '(' goodObject ')'
                         {
+                            IHqlExpression * arg = $3.queryExpr();
                             $$.setExpr(createExprAttribute(defaultAtom, $3.getExpr()), $1);
                         }
     | STRING_CONST

+ 10 - 0
ecl/hql/hqlgram2.cpp

@@ -2718,6 +2718,16 @@ void HqlGram::addDatasetField(const attribute &errpos, IIdAtom * name, ITypeInfo
 
     if (queryAttributeInList(virtualAtom, attrs))
         reportError(ERR_BAD_FIELD_ATTR, errpos, "Virtual can only be specified on a scalar field");
+
+    IHqlExpression * defaultAttribute = queryAttributeInList(defaultAtom, attrs);
+    if (defaultAttribute)
+    {
+        IHqlExpression * defaultValue = defaultAttribute->queryChild(0);
+        if (isNullList(defaultValue) || (defaultValue->getOperator()==no_temptable && isNullList(defaultValue->queryChild(0))))
+        {
+            attrs = replaceExpression(attrs, defaultAttribute, createAttribute(defaultAtom,createNullExpr(dsType)));
+        }
+    }
     if (!attrs)
         attrs = extractAttrsFromExpr(value);
 

+ 5 - 1
ecl/hql/hqlutil.cpp

@@ -6303,6 +6303,10 @@ void TempTableTransformer::createTempTableAssign(HqlExprArray & assigns, IHqlExp
                                 castValue.set(src);
 
                         }
+                        else if (src->getOperator() == no_null)
+                        {
+                            castValue.setown(createDataset(no_null, LINK(record)));
+                        }
                         else
                         {
                             ERRORAT1(curRow->queryAttribute(_location_Atom), HQLERR_IncompatibleTypesForField, str(expr->queryName()));
@@ -8855,7 +8859,7 @@ bool ConstantRowCreator::processFieldValue(IHqlExpression * optLhs, ITypeInfo *
     case type_groupedtable:
         {
             assertex(optLhs);
-            IHqlExpression * field = optLhs->queryChild(1);
+            IHqlExpression * field = optLhs->getOperator() == no_select ? optLhs->queryChild(1) : optLhs;
             if (!field->hasAttribute(countAtom) && !field->hasAttribute(sizeofAtom))
             {
                 if (field->hasAttribute(_linkCounted_Atom))

+ 2 - 0
ecl/hqlcpp/hqlcerrors.hpp

@@ -220,6 +220,7 @@
 #define HQLERR_DatafileRequiresSigned           4208
 #define HQLERR_ExpectedFileLhsFetch             4209
 #define HQLERR_IncompatibleKeyedSubString       4210
+#define HQLERR_NonNullChildDSDefault            4211
 
 //Warnings....
 #define HQLWRN_PersistDataNotLikely             4500
@@ -521,6 +522,7 @@
 #define HQLERR_DatafileRequiresSigned_Text      "Insufficient access rights to use datafiles"
 #define HQLERR_ExpectedFileLhsFetch_Text        "The first argument of FETCH must be a disk file (had %s)"
 #define HQLERR_IncompatibleKeyedSubString_Text  "Cannot use two different KEYED substring filters for field %s in key %s"
+#define HQLERR_NonNullChildDSDefault_Text       "Non-null child dataset may not be used as default value (target field '%s')"
 
 //Warnings.
 #define HQLWRN_CannotRecreateDistribution_Text  "Cannot recreate the distribution for a persistent dataset"

+ 6 - 1
ecl/hqlcpp/hqlhtcpp.cpp

@@ -3748,7 +3748,12 @@ unsigned HqlCppTranslator::buildRtlField(StringBuffer & instanceName, IHqlExpres
             if (createConstantField(target, targetField, defaultValue))
                 appendStringAsQuotedCPP(defaultInitializer, target.length(), target.toByteArray(), false);
             else
-                throwError1(HQLERR_CouldNotGenerateDefault, str(field->queryName()));
+            {
+                if (targetField->isDataset() && !isNullList(defaultValue))
+                    throwError1(HQLERR_NonNullChildDSDefault, str(field->queryName()));
+                else
+                    throwError1(HQLERR_CouldNotGenerateDefault, str(field->queryName()));
+            }
         }
 
         StringBuffer definition;

+ 40 - 0
ecl/regress/issue18799.ecl

@@ -0,0 +1,40 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2018 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+crec := RECORD
+  string str1;
+  string str2;
+END;
+
+ds1 := RECORD
+  string str {DEFAULT('default1')};
+  DATASET(crec) kids := DATASET([],crec);
+END;
+
+ds2 := RECORD
+  string str {DEFAULT('default2')};
+  DATASET(crec) kids {DEFAULT(DATASET([],crec))};
+END;
+
+ds3 := RECORD
+  string str {DEFAULT('default3')};
+  DATASET(crec) kids {DEFAULT([])};
+END;
+
+OUTPUT(DATASET([{'test1'}], ds1));
+OUTPUT(DATASET([{'test2'}], ds2));
+OUTPUT(DATASET([{'test3'}], ds3));

+ 28 - 0
ecl/regress/issue18799bad.ecl

@@ -0,0 +1,28 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2018 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+crec := RECORD
+  string str1;
+  string str2;
+END;
+
+ds1 := RECORD
+  string str {DEFAULT('default1')};
+  DATASET(crec) kids {DEFAULT(DATASET([{'str1','str2'}], crec))};
+END;
+
+OUTPUT (DATASET([{'test1'}], ds1));