Browse Source

HPCC-23230 Rationalize createValue() and createDataset()

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday 5 năm trước cách đây
mục cha
commit
31a7258ebf

+ 5 - 5
common/fileview2/fvwugen.cpp

@@ -54,12 +54,12 @@ MODULE_INIT(INIT_PRIORITY_STANDARD)
 IHqlExpression * addFilter(IHqlExpression * dataset, IHqlExpression * limitField)
 {
     IHqlExpression * lower = createConstant(limitField->queryType()->castFrom(true, (__int64)0));
-    lower = createValue(no_colon, lower, createValue(no_stored, createConstant(LOWER_LIMIT_ID)));
+    lower = createValue(no_colon, lower->getType(), lower, createValue(no_stored, makeVoidType(), createConstant(LOWER_LIMIT_ID)));
     lower = createSymbol(createIdAtom(LOWER_LIMIT_ID), lower, ob_private);
     dataset = createDataset(no_filter, LINK(dataset), createBoolExpr(no_ge, LINK(limitField), lower));
 
     IHqlExpression * upper = createConstant((int)DISKREAD_PAGE_SIZE);
-    upper = createValue(no_colon, upper, createValue(no_stored, createConstant(RECORD_LIMIT_ID)));
+    upper = createValue(no_colon, upper->getType(), upper, createValue(no_stored, makeVoidType(), createConstant(RECORD_LIMIT_ID)));
     upper = createSymbol(createIdAtom(RECORD_LIMIT_ID), upper, ob_private);
     dataset = createDataset(no_choosen, dataset, upper);
     dataset = createSymbol(createIdAtom("_Filtered_"), dataset, ob_private);
@@ -112,7 +112,7 @@ IHqlExpression * buildDiskFileViewerEcl(const char * logicalName, IHqlExpression
     OwnedHqlExpr newRecord = createRecord(fields);
     newRecord.setown(createSymbol(createIdAtom("_SourceRecord_"), newRecord.getLink(), ob_private));
 
-    OwnedHqlExpr dataset = createNewDataset(createConstant(logicalName), newRecord.getLink(), createValue(no_thor), NULL, NULL, NULL);
+    OwnedHqlExpr dataset = createNewDataset(createConstant(logicalName), newRecord.getLink(), createValue(no_thor, makeNullType()), NULL, NULL, NULL);
     OwnedHqlExpr filtered = addFilter(dataset, filepos);
     OwnedHqlExpr projected = addSimplifyProject(filtered);
     OwnedHqlExpr output = addOutput(projected);
@@ -123,7 +123,7 @@ IHqlExpression * buildDiskFileViewerEcl(const char * logicalName, IHqlExpression
 
 IHqlExpression * buildDiskOutputEcl(const char * logicalName, IHqlExpression * record)
 {
-    OwnedHqlExpr dataset = createNewDataset(createConstant(logicalName), LINK(record), createValue(no_thor), NULL, NULL, NULL);
+    OwnedHqlExpr dataset = createNewDataset(createConstant(logicalName), LINK(record), createValue(no_thor, makeNullType()), NULL, NULL, NULL);
     return addOutput(dataset);
 }
 
@@ -182,7 +182,7 @@ IHqlExpression * PositionTransformer::createTransformed(IHqlExpression * _expr)
                 {
                     IHqlExpression * newTarget = createField(child->queryId(), child->getType(), LINK(child), insertedAttr.getLink());
                     fields.append(*newTarget);
-                    assigns.append(*createValue(no_assign, makeVoidType(), newTarget, createSelectExpr(createValue(no_left), LINK(newTarget))));
+                    assigns.append(*createValue(no_assign, makeVoidType(), newTarget, createSelectExpr(createValue(no_left, makeNullType()), LINK(newTarget)))); // MORE: This probably doesn't work because left needs a selSeq and record as children.  All this code is deprecated so not a priority.
                 }
             }
             IHqlExpression * newRecord = createRecord(fields);

+ 76 - 52
ecl/hql/hqlexpr.cpp

@@ -439,8 +439,8 @@ MODULE_INIT(INIT_PRIORITY_HQLINTERNAL)
     nullType = makeNullType();
     sourcePaths = new KeptAtomTable;
     blank = createStringValue("",(unsigned)0);
-    cachedActiveTableExpr = createValue(no_activetable);
-    cachedSelfReferenceExpr = createValue(no_selfref);
+    cachedActiveTableExpr = createValue(no_activetable, LINK(nullType));
+    cachedSelfReferenceExpr = createValue(no_selfref, LINK(nullType));
     cachedNullRecord = createRecord()->closeExpr();
     cachedSelfExpr = createValue(no_self, makeRowType(cachedNullRecord->getType()));
     OwnedHqlExpr nonEmptyAttr = createAttribute(_nonEmpty_Atom);
@@ -5019,11 +5019,23 @@ unsigned CHqlRealExpression::getCachedEclCRC()
     if (cachedCRC)
         return cachedCRC;
 
+    ITypeInfo * thisType = queryType();
     unsigned crc = op;
     switch (op)
     {
     case no_record:
     case no_type:
+        thisType = nullptr;
+        break;
+    case no_thor:
+    case no_flat:
+    case no_sql:
+    case no_csv:
+    case no_xml:
+    case no_json:
+    case no_null:
+        if (thisType && (thisType->getTypeCode() == type_null))
+            thisType = nullptr;
         break;
     case no_self:
         //ignore new record argument
@@ -5031,12 +5043,13 @@ unsigned CHqlRealExpression::getCachedEclCRC()
         return crc;
     case no_selfref:
         crc = no_self;
+        thisType = nullptr;
         break;
     case no_assertconstant:
     case no_assertconcrete:
         return queryChild(0)->getCachedEclCRC();
     case no_sortlist:
-        //backward compatibility
+        thisType = nullptr;
         break;
     case no_attr_expr:
         {
@@ -5045,30 +5058,26 @@ unsigned CHqlRealExpression::getCachedEclCRC()
             //will be incompatible.
             if (name == maxLengthAtom || name == xpathAtom || name == cardinalityAtom || name == caseAtom || name == maxCountAtom || name == choosenAtom || name == maxSizeAtom || name == namedAtom || name == rangeAtom || name == xmlDefaultAtom || name == virtualAtom)
                 crc = no_attr;
-            //fallthrough
+            break;
         }
-    default:
+    }
+
+    if (thisType && this != queryExpression(thisType))
+    {
+        ITypeInfo * hashType = thisType;
+        switch (hashType->getTypeCode())
         {
-            ITypeInfo * thisType = queryType();
-            if (thisType && this != queryExpression(thisType))
-            {
-                ITypeInfo * hashType = thisType;
-                switch (hashType->getTypeCode())
-                {
-                case type_transform:
-                    hashType = hashType->queryChildType();
-                    break;
-                case type_row:
-                    //Backward compatibility
-                    if (op == no_field)
-                        hashType = hashType->queryChildType();
-                    break;
-                }
-                unsigned typeCRC = hashType->getCrc();
-                crc = hashc((const byte *)&typeCRC, sizeof(typeCRC), crc);
-            }
+        case type_transform:
+            hashType = hashType->queryChildType();
+            break;
+        case type_row:
+            //Backward compatibility
+            if (op == no_field)
+                hashType = hashType->queryChildType();
             break;
         }
+        unsigned typeCRC = hashType->getCrc();
+        crc = hashc((const byte *)&typeCRC, sizeof(typeCRC), crc);
     }
 
     unsigned numChildrenToHash = numChildren();
@@ -5188,6 +5197,22 @@ CHqlExpression *CHqlExpressionWithType::makeExpression(node_operator _op, ITypeI
     return (CHqlExpression *)e->closeExpr();
 }
 
+CHqlExpression* CHqlExpressionWithType::makeExpression(node_operator op, ITypeInfo *type, const std::initializer_list<IHqlExpression *> &operands)
+{
+    HqlExprArray args;
+    args.ensure(operands.size());
+    for (auto & cur : operands)
+    {
+        //Skip null entries
+        if (cur)
+        {
+            dbgassertex(QUERYINTERFACE(cur, IHqlExpression));
+            args.append(*cur);
+        }
+    }
+    return makeExpression(op, type, args);
+}
+
 CHqlExpression *CHqlExpressionWithType::makeExpression(node_operator _op, ITypeInfo *_type, ...)
 {
     unsigned numArgs = 0;
@@ -11182,10 +11207,6 @@ extern IHqlExpression *createParameter(IIdAtom * id, unsigned idx, ITypeInfo *ty
     return CHqlParameter::makeParameter(id, idx, type, attrs);
 }
 
-extern IHqlExpression *createValue(node_operator op)
-{
-    return CHqlExpressionWithType::makeExpression(op, NULL, NULL);
-}
 extern IHqlExpression *createValue(node_operator op, ITypeInfo *type)
 {
     return CHqlExpressionWithType::makeExpression(op, type, NULL);
@@ -11209,6 +11230,7 @@ extern IHqlExpression *createOpenValue(node_operator op, ITypeInfo *type)
             case type_table:
                 assertex(!"createDataset should be called instead");
             }
+            break;
         }
     }
 #endif
@@ -11240,11 +11262,6 @@ extern IHqlExpression *createOpenNamedValue(node_operator op, ITypeInfo *type, I
     return new CHqlNamedExpression(op, type, id, NULL);
 }
 
-extern IHqlExpression *createValue(node_operator op, IHqlExpression *p1, IHqlExpression *p2)
-{
-    return CHqlExpressionWithType::makeExpression(op, p1->getType(), p1, p2, NULL);
-}
-
 extern IHqlExpression *createValue(node_operator op, ITypeInfo *type, IHqlExpression *p1)
 {
     return CHqlExpressionWithType::makeExpression(op, type, p1, NULL);
@@ -11288,17 +11305,6 @@ extern IHqlExpression *createValueF(node_operator op, ITypeInfo *type, ...)
     return CHqlExpressionWithType::makeExpression(op, type, children);
 }
 
-extern HQL_API IHqlExpression * createValueFromCommaList(node_operator op, ITypeInfo * type, IHqlExpression * argsExpr)
-{
-    HqlExprArray args;
-    if (argsExpr)
-    {
-        argsExpr->unwindList(args, no_comma);
-        argsExpr->Release();
-    }
-    return createValue(op, type, args);
-}
-
 extern HQL_API IHqlExpression * createValueSafe(node_operator op, ITypeInfo * type, const HqlExprArray & args)
 {
     return createValueSafe(op, type, args, 0, args.ordinality());
@@ -11510,6 +11516,27 @@ extern IHqlExpression *createDatasetF(node_operator op, ...)
     return createDataset(op, children);
 }
 
+IHqlExpression *createDataset(node_operator op, const std::initializer_list<IHqlExpression *> &operands)
+{
+    HqlExprArray args;
+    for (auto & cur : operands)
+    {
+        //Skip null entries, and expand no_comma
+        if (cur)
+        {
+            dbgassertex(QUERYINTERFACE(cur, IHqlExpression));
+            if (cur->getOperator() == no_comma)
+            {
+                cur->unwindList(args, no_comma);
+                cur->Release();
+            }
+            else
+                args.append(*cur);
+        }
+    }
+    return createDataset(op, args);
+}
+
 IHqlExpression *createDictionary(node_operator op, HqlExprArray & parms)
 {
 #ifdef GATHER_LINK_STATS
@@ -13029,16 +13056,13 @@ IHqlExpression * createExternalFuncdefFromInternal(IHqlExpression * funcdef)
     return replaceChild(funcdef, 0, externalExpr);
 }
 
-extern IHqlExpression* createValue(node_operator op, HqlExprArray& operands) {
-    return CHqlExpressionWithType::makeExpression(op, NULL, operands);
+extern IHqlExpression* createValue(node_operator op, ITypeInfo *type, HqlExprArray& operands) {
+    return CHqlExpressionWithType::makeExpression(op, type, operands);
 }
 
-extern IHqlExpression* createValue(node_operator op, ITypeInfo *_type, HqlExprArray& operands) {
-    return CHqlExpressionWithType::makeExpression(op, _type, operands);
-}
-
-extern IHqlExpression *createValue(node_operator op, IHqlExpression *p1) {
-    return CHqlExpressionWithType::makeExpression(op, NULL, p1, NULL);
+extern IHqlExpression* createValue(node_operator op, ITypeInfo *type, const std::initializer_list<IHqlExpression *> &operands)
+{
+    return CHqlExpressionWithType::makeExpression(op, type, operands);
 }
 
 extern IHqlExpression* createConstant(int ival) {
@@ -16263,7 +16287,7 @@ IHqlExpression * createSelector(node_operator op, IHqlExpression * ds, IHqlExpre
     case no_activetable:
         return LINK(cachedActiveTableExpr);
     default:
-        return createValue(op);
+        return createValue(op, makeNullType());
     }
 }
 

+ 4 - 6
ecl/hql/hqlexpr.hpp

@@ -18,6 +18,8 @@
 #ifndef HQLEXPR_INCL
 #define HQLEXPR_INCL
 
+#include <initializer_list>
+
 #define USE_SELSEQ_UID
 //It is impossible to ensure that LEFT/RIGHT are unique, and cannot be nested.  For instance
 //x := PROJECT(ds, t(LEFT));
@@ -1276,8 +1278,6 @@ struct OwnedHqlExprItem : public CInterface
 };
 
 extern HQL_API const char *getOpString(node_operator op);
-extern HQL_API IHqlExpression *createValue(node_operator op);
-extern HQL_API IHqlExpression *createValue(node_operator op, IHqlExpression *p1, IHqlExpression *p2);
 extern HQL_API IHqlExpression *createOpenValue(node_operator op, ITypeInfo *type);
 extern HQL_API IHqlExpression *createOpenNamedValue(node_operator op, ITypeInfo *type, IIdAtom * id);
 extern HQL_API IHqlExpression *createNamedValue(node_operator op, ITypeInfo *type, IIdAtom * id, HqlExprArray & args);
@@ -1290,9 +1290,9 @@ extern HQL_API IHqlExpression *createValue(node_operator op, ITypeInfo * type, I
 extern HQL_API IHqlExpression *createValue(node_operator op, ITypeInfo * type, IHqlExpression *p1, IHqlExpression *p2, IHqlExpression *p3, IHqlExpression *p4);
 extern HQL_API IHqlExpression *createValueF(node_operator op, ITypeInfo * type, ...);
 extern HQL_API IHqlExpression *createValue(node_operator op, ITypeInfo * type, HqlExprArray & args);        //NB: This deletes the array that is passed
+extern HQL_API IHqlExpression* createValue(node_operator op, ITypeInfo *type, const std::initializer_list<IHqlExpression *> &operands);
 extern HQL_API IHqlExpression *createValueSafe(node_operator op, ITypeInfo * type, const HqlExprArray & args);
 extern HQL_API IHqlExpression *createValueSafe(node_operator op, ITypeInfo * type, const HqlExprArray & args, unsigned from, unsigned max);
-extern HQL_API IHqlExpression *createValueFromCommaList(node_operator op, ITypeInfo * type, IHqlExpression * argsExpr);
 
 //These all consume their arguments
 extern HQL_API IHqlExpression *createWrapper(node_operator op, IHqlExpression * expr);
@@ -1331,6 +1331,7 @@ extern HQL_API IHqlExpression *createDataset(node_operator op, IHqlExpression *d
 extern HQL_API IHqlExpression *createDataset(node_operator op, IHqlExpression *dataset, IHqlExpression *elist);
 extern HQL_API IHqlExpression *createDataset(node_operator op, HqlExprArray & parms);       // inScope should only be set internally.
 extern HQL_API IHqlExpression *createDatasetF(node_operator op, ...);
+extern HQL_API IHqlExpression *createDataset(node_operator op, const std::initializer_list<IHqlExpression *> &operands);
 extern HQL_API IHqlExpression *createDictionary(node_operator op, IHqlExpression *initializer, IHqlExpression *recordDef);
 extern HQL_API IHqlExpression *createDictionary(node_operator op, IHqlExpression *dictionary);
 extern HQL_API IHqlExpression *createDictionary(node_operator op, HqlExprArray & parms);
@@ -1422,9 +1423,6 @@ inline bool isFail(IHqlExpression * expr)       { return expr->getOperator() ==
 extern HQL_API IHqlExpression * createDelayedReference(node_operator op, IHqlExpression * moduleMarker, IHqlExpression * attr, unsigned lookupFlags, HqlLookupContext & ctx);
 extern HQL_API IHqlExpression * createLibraryInstance(IHqlExpression * scopeFunction, HqlExprArray &operands);
 
-extern HQL_API IHqlExpression* createValue(node_operator op, ITypeInfo *type, HqlExprArray& operands);
-extern HQL_API IHqlExpression* createValue(node_operator op, HqlExprArray& operands);
-extern HQL_API IHqlExpression *createValue(node_operator op, IHqlExpression *p1);
 extern HQL_API IHqlExpression* createConstant(int ival);
 extern HQL_API IHqlExpression *queryConstantLikelihoodUnknown();
 extern HQL_API IHqlExpression *queryConstantLikelihoodLikely();

+ 1 - 0
ecl/hql/hqlexpr.ipp

@@ -422,6 +422,7 @@ class HQL_API CHqlExpressionWithType : public CHqlExpressionWithTables
 public:
     static CHqlExpression *makeExpression(node_operator op, ITypeInfo *type, HqlExprArray &operands);
     static CHqlExpression *makeExpression(node_operator op, ITypeInfo *type, ...);
+    static CHqlExpression *makeExpression(node_operator op, ITypeInfo *type, const std::initializer_list<IHqlExpression *> &operands);
 
     virtual ITypeInfo *queryType() const override;
     virtual ITypeInfo *getType() override;

+ 6 - 6
ecl/hql/hqlfold.cpp

@@ -2447,7 +2447,7 @@ IHqlExpression * foldConstantOperator(IHqlExpression * expr, unsigned foldOption
                     return LINK(child);
                 IHqlExpression * opt = expr->queryAttribute(extendAtom);
                 IHqlExpression * selectors = expr->queryAttribute(_selectors_Atom);
-                return createValue(no_assertwild, makeBoolType(), createValue(no_all), LINK(selectors), LINK(opt));
+                return createValue(no_assertwild, makeBoolType(), createValue(no_all, makeNullType()), LINK(selectors), LINK(opt));
             }
             break;
         }
@@ -3330,7 +3330,7 @@ IHqlExpression * foldConstantOperator(IHqlExpression * expr, unsigned foldOption
                             {
                                 IHqlExpression * result = (IHqlExpression *)&caseResults.item(i);
                                 IValue * castRes = result->queryValue()->castTo(newType);
-                                IHqlExpression * newMapping = createValue(no_mapto, LINK(child->queryChild(i+1)->queryChild(0)), createConstant(castRes));
+                                IHqlExpression * newMapping = createValue(no_mapto, LINK(newType), LINK(child->queryChild(i+1)->queryChild(0)), createConstant(castRes));
                                 newCaseMaps.append(*newMapping);
                             }
                             newCaseMaps.append(*createConstant(defVal->castTo(newType)));
@@ -3504,7 +3504,7 @@ IHqlExpression * foldConstantOperator(IHqlExpression * expr, unsigned foldOption
                                 IHqlExpression * val2 = (IHqlExpression*)&caseInput2.item(k);
                                 if (val1->queryValue()->compare(val2->queryValue()) == 0)
                                 {
-                                    IHqlExpression * newMapping = createValue(no_mapto, LINK(leftExpr->queryChild(i+1)->queryChild(0)), LINK(expr->queryChild(k+1)->queryChild(1)));
+                                    IHqlExpression * newMapping = createValue(no_mapto, expr->getType(), LINK(leftExpr->queryChild(i+1)->queryChild(0)), LINK(expr->queryChild(k+1)->queryChild(1)));
                                     newCaseMaps.append(*newMapping);
                                     found = true;
                                     break;
@@ -3512,7 +3512,7 @@ IHqlExpression * foldConstantOperator(IHqlExpression * expr, unsigned foldOption
                             }
                             if (inRes && !found)
                             {
-                                IHqlExpression * newMapping = createValue(no_mapto, LINK(leftExpr->queryChild(i+1)->queryChild(0)), LINK(defCase1));
+                                IHqlExpression * newMapping = createValue(no_mapto, expr->getType(), LINK(leftExpr->queryChild(i+1)->queryChild(0)), LINK(defCase1));
                                 newCaseMaps.append(*newMapping);
                             }
                         }
@@ -3657,7 +3657,7 @@ IHqlExpression * foldConstantOperator(IHqlExpression * expr, unsigned foldOption
                             if (alreadyDone.find(*value) == NotFound)
                             {
                                 alreadyDone.append(*value);
-                                args2.append(*createValue(no_mapto, LINK(value), LINK(mapValue)));
+                                args2.append(*createValue(no_mapto, mapValue->getType(), LINK(value), LINK(mapValue)));
                             }
                         }
                     }
@@ -4952,7 +4952,7 @@ IHqlExpression * NullFolderMixin::queryOptimizeAggregateInline(IHqlExpression *
     HqlExprArray args;
     args.append(*createAssign(LINK(assign->queryChild(0)), LINK(value)));
     OwnedHqlExpr newTransform = createValue(no_transform, transform->getType(), args);
-    OwnedHqlExpr values = createValue(no_transformlist, newTransform.getClear());
+    OwnedHqlExpr values = createValue(no_transformlist, makeNullType(), newTransform.getClear());
     return createDataset(no_inlinetable, values.getClear(), LINK(expr->queryRecord()));
 }
 

+ 30 - 21
ecl/hql/hqlgram.y

@@ -2091,7 +2091,8 @@ conditionalAssignmentElseClause
                             parser->normalizeExpression($2);
                             parser->ensureBoolean($2);
                             //normalizeExpression($2, type_boolean, false);
-                            OwnedHqlExpr map = createValue(no_mapto, $2.getExpr(), $4.getExpr());
+                            OwnedHqlExpr other = $4.getExpr();
+                            OwnedHqlExpr map = createValue(no_mapto, other->getType(), $2.getExpr(), LINK(other));
                             $$.setExpr(createComma(map.getClear(), $5.getExpr()), $1);
                         }
     ;
@@ -2125,7 +2126,7 @@ transformation1
                                 IHqlExpression * arg = $3.queryExpr();
                                 if ((arg->getOperator() == no_list) && (arg->numChildren() == 0))
                                 {
-                                    $3.release().setExpr(createValue(no_null));
+                                    $3.release().setExpr(createValue(no_null, makeNullType()));
                                 }
                             }
                             parser->addAssignment($1, $3);
@@ -2503,7 +2504,7 @@ actionStmt
     | OUTPUT '(' startTopFilter optOutputWuFlags ')' endTopFilter
                         {
                             IHqlExpression *dataset = $3.getExpr();
-                            IHqlExpression *record = createValue(no_null);
+                            IHqlExpression *record = createValue(no_null, makeNullType());
                             OwnedHqlExpr select = createDatasetF(no_selectfields, dataset, record, NULL); //createUniqueId(), NULL);
                             OwnedHqlExpr flags = $4.getExpr();
 
@@ -2752,9 +2753,13 @@ actionStmt
                                 parser->reportError(ERR_TYPEMISMATCH_RECORD, $4, "Indexes must have the same structure");
                             parser->normalizeExpression($7, type_string, false);
 
-                            OwnedHqlExpr options = createComma($3.getExpr(), $5.getExpr(), $7.getExpr(), $8.getExpr());
-                            parser->saveDiskAccessInformation($1, options);
-                            $$.setExpr(createValueFromCommaList(no_keydiff, makeVoidType(), options.getClear()));
+                            HqlExprArray args;
+                            args.append(*$3.getExpr());
+                            args.append(*$5.getExpr());
+                            args.append(*$7.getExpr());
+                            $8.unwindCommaList(args);
+                            parser->saveDiskAccessInformation($1, args);
+                            $$.setExpr(createValue(no_keydiff, makeVoidType(), args));
                             $$.setPosition($1);
                         }
     | KEYPATCH '(' dataSet ',' expression ',' expression keyDiffFlags ')'
@@ -2763,10 +2768,14 @@ actionStmt
                                 parser->reportError(ERR_EXPECTED_INDEX,$3,"Expected an index");
                             parser->normalizeExpression($5, type_string, false);
                             parser->normalizeExpression($7, type_string, false);
-                            OwnedHqlExpr options = createComma($3.getExpr(), $5.getExpr(), $7.getExpr(), $8.getExpr());
 
-                            parser->saveDiskAccessInformation($1, options);
-                            $$.setExpr(createValueFromCommaList(no_keypatch, makeVoidType(), options.getClear()));
+                            HqlExprArray args;
+                            args.append(*$3.getExpr());
+                            args.append(*$5.getExpr());
+                            args.append(*$7.getExpr());
+                            $8.unwindCommaList(args);
+                            parser->saveDiskAccessInformation($1, args);
+                            $$.setExpr(createValue(no_keypatch, makeVoidType(), args));
                             $$.setPosition($1);
                         }
     | EVALUATE '(' expression ')'
@@ -3908,7 +3917,7 @@ keyDiffFlag
 optRecordDef
     : recordDef
     |                   {
-                            $$.setExpr(createValue(no_null));
+                            $$.setExpr(createValue(no_null, makeNullType()));
                             $$.clearPosition();
                         }
     ;
@@ -5317,7 +5326,7 @@ query
                             expr = parser->attachPendingWarnings(expr);
                             expr = parser->attachMetaAttributes(expr, meta);
 
-                            IHqlExpression *record = createValue(no_null);
+                            IHqlExpression *record = createValue(no_null, makeNullType());
                             OwnedHqlExpr select = createDatasetF(no_selectfields, expr, record, NULL);
                             HqlExprArray args;
                             args.append(*select.getClear());
@@ -7341,7 +7350,7 @@ scopeFunctionWithParameters
                             OwnedHqlExpr parms = $4.getExpr();
                             //NB: Do not call createComma() incase the first argument is a dataset
                             if (parms)
-                                $$.setExpr(createValue(no_comma, $1.getExpr(), parms.getClear()), $1);
+                                $$.setExpr(createValue(no_comma, nullptr, $1.getExpr(), parms.getClear()), $1);
                             else
                                 $$.setExpr($1.getExpr(), $1);
                         }
@@ -10263,23 +10272,23 @@ failDatasetParam
     ;
 
 mode
-    : FLAT              {   $$.setExpr(createValue(no_flat));   }
-    | CSV               {   $$.setExpr(createValue(no_csv));    }
+    : FLAT              {   $$.setExpr(createValue(no_flat, makeNullType()));   }
+    | CSV               {   $$.setExpr(createValue(no_csv, makeNullType()));    }
     | CSV '(' csvOptions ')'
                         {   
                             HqlExprArray args;
                             $3.unwindCommaList(args);
                             $$.setExpr(createValue(no_csv, makeNullType(), args));
                         }
-    | SQL               {   $$.setExpr(createValue(no_sql));    }
-    | THOR              {   $$.setExpr(createValue(no_thor));   }
+    | SQL               {   $$.setExpr(createValue(no_sql, makeNullType()));    }
+    | THOR              {   $$.setExpr(createValue(no_thor, makeNullType()));   }
     | THOR  '(' expression ')'
                         {
                             throwUnexpected();
                             parser->normalizeExpression($3);
-                            $$.setExpr(createValue(no_thor, $3.getExpr()));
+                            $$.setExpr(createValue(no_thor, makeNullType(),  $3.getExpr()));
                         }
-    | XML_TOKEN         {   $$.setExpr(createValue(no_xml));    }
+    | XML_TOKEN         {   $$.setExpr(createValue(no_xml, makeNullType()));    }
     | XML_TOKEN '(' xmlOptions ')'
                         {
                             HqlExprArray args;
@@ -10296,7 +10305,7 @@ mode
                                 args.add(*createConstant("xml"), 0);
                             $$.setExpr(createValue(no_xml, makeNullType(), args));
                         }
-    | JSON_TOKEN         {   $$.setExpr(createValue(no_json));    }
+    | JSON_TOKEN         {   $$.setExpr(createValue(no_json, makeNullType()));    }
     | JSON_TOKEN '(' xmlOptions ')'
                         {
                             HqlExprArray args;
@@ -10985,7 +10994,7 @@ skewAttribute
                                 parser->normalizeExpression($3, type_numeric, true);
                             }
                             else
-                                $3.setExpr(createValue(no_null));
+                                $3.setExpr(createValue(no_null, makeNullType()));
 
                             parser->normalizeExpression($5, type_any, true);
                             parser->normalizeExpression($5, type_numeric, false);
@@ -11141,7 +11150,7 @@ parseFlag
     | MIN               {   $$.setExpr(createAttribute(minAtom)); }
     | USE '(' globalPatternAttribute ')'
                         {
-                            $$.setExpr(createValue(no_pat_use, $3.getExpr()));
+                            $$.setExpr(createValue(no_pat_use, makeNullType(), $3.getExpr()));
                         }
     | BEST              {   $$.setExpr(createAttribute(bestAtom)); }
     | MANY BEST         {   $$.setExpr(createComma(createAttribute(bestAtom), createAttribute(manyAtom))); }

+ 17 - 13
ecl/hql/hqlgram2.cpp

@@ -296,7 +296,7 @@ IHqlExpression * HqlGram::createSetRange(attribute & array, attribute & range)
                     IHqlExpression * from = ensureExprType(rangeExpr->queryChild(0), indexType);
                     IHqlExpression * to = ensureExprType(rangeExpr->queryChild(1), indexType);
                     OwnedHqlExpr length = createValue(no_add, LINK(indexType), createValue(no_sub, LINK(indexType), to, from), createConstant(indexType->castFrom(true, (__int64)1)));
-                    dsChooseN.setown(createDataset(no_choosen, dsFromList.getClear(), createComma(length.getClear(), LINK(from))));
+                    dsChooseN.setown(createDataset(no_choosen, { dsFromList.getClear(), length.getClear(), LINK(from) }));
                     break;
                 }
             case no_rangeto :
@@ -1152,7 +1152,7 @@ IHqlExpression * HqlGram::processIndexBuild(const attribute &err, attribute & in
         bool hasFileposition = getBoolAttributeInList(flags, filepositionAtom, true);
         record.setown(checkBuildIndexRecord(record.getClear(), *recordAttr));
         record.setown(checkIndexRecord(record, *recordAttr, flags));
-        projectedDataset.setown(createDatasetF(no_selectfields, LINK(dataset), LINK(record), NULL));
+        projectedDataset.setown(createDataset(no_selectfields, { LINK(dataset), LINK(record) }));
         warnIfRecordPacked(projectedDataset, *recordAttr);
     }
     else
@@ -1688,6 +1688,7 @@ void HqlGram::addAssignment(attribute & target, attribute &source)
         {
             case type_record:
             case type_row:
+            case type_null: // Assign no_null
                 addAssignall(targetExpr.getClear(), srcExpr.getClear(), target);
                 break;
             default:
@@ -1695,6 +1696,7 @@ void HqlGram::addAssignment(attribute & target, attribute &source)
                     StringBuffer msg("Can not assign non-record type ");
                     getFriendlyTypeStr(type, msg).append(" to self");
                     reportError(ERR_TRANS_ILLASSIGN2SELF, target, "%s", msg.str());
+                    break;
                 }
         }
     }
@@ -1732,6 +1734,7 @@ void HqlGram::addAssignment(const attribute & errpos, IHqlExpression * targetExp
         {
             case type_record:
             case type_row:
+            case type_null: // no_null
                 addAssignall(LINK(targetExpr), LINK(srcExpr), errpos);
                 break;
             default:
@@ -1739,6 +1742,7 @@ void HqlGram::addAssignment(const attribute & errpos, IHqlExpression * targetExp
                     StringBuffer msg("Can not assign non-record type ");
                     getFriendlyTypeStr(type, msg).append(" to self");
                     reportError(ERR_TRANS_ILLASSIGN2SELF, errpos, "%s", msg.str());
+                    break;
                 }
         }
     }
@@ -1793,7 +1797,7 @@ void HqlGram::doAddAssignment(IHqlExpression * transform, IHqlExpression * _fiel
     // type checking
     ITypeInfo* fldType = field->queryType();
     Owned<ITypeInfo> rhsType = rhs->getType();
-    if (!rhsType)           // this happens when rhs is no_null.
+    if (!rhsType || (rhsType->getTypeCode() == type_null))           // this happens when rhs is no_null.
         rhsType.set(fldType);
 
     // handle alien type
@@ -2053,7 +2057,7 @@ IHqlExpression * HqlGram::createDefaultProjectDataset(IHqlExpression * record, I
     OwnedHqlExpr seq = createActiveSelectorSequence(src, NULL);
     OwnedHqlExpr left = createSelector(no_left, src, seq);
     OwnedHqlExpr transform = createDefaultAssignTransform(record, left, errpos);
-    return createDatasetF(no_hqlproject, ::ensureDataset(src), LINK(transform), LINK(seq), NULL);
+    return createDataset(no_hqlproject, { ::ensureDataset(src), LINK(transform), LINK(seq) });
 }
 
 
@@ -2192,7 +2196,7 @@ IHqlExpression * HqlGram::createRowAssignTransform(const attribute & srcAttr, co
 
 IHqlExpression * HqlGram::createClearTransform(IHqlExpression * record, const attribute & errpos)
 {
-    OwnedHqlExpr null = createValue(no_null);
+    OwnedHqlExpr null = createValue(no_null, makeNullType());
     return createDefaultAssignTransform(record, null, errpos);
 }
 
@@ -5829,8 +5833,8 @@ IHqlExpression * HqlGram::createDatasetFromList(attribute & listAttr, attribute
 
     if ((list->getOperator() == no_list) && (list->numChildren() == 0))
     {
-        OwnedHqlExpr list = createValue(no_null);
-        OwnedHqlExpr table = createDataset(no_temptable, LINK(list), createComma(record.getClear(), LINK(attrs)));
+        OwnedHqlExpr list = createValue(no_null, makeNullType());
+        OwnedHqlExpr table = createDataset(no_temptable, { LINK(list), record.getClear(), LINK(attrs) });
         return convertTempTableToInlineTable(*errorHandler, listAttr.pos, table);
     }
 
@@ -7204,13 +7208,13 @@ IHqlExpression * HqlGram::createBuildIndexFromIndex(attribute & indexAttr, attri
 
     IHqlExpression * select;
     if (sourceDataset)
-        select = createDatasetF(no_newusertable, LINK(sourceDataset), LINK(record), LINK(transform), NULL); //createUniqueId(), NULL);
+        select = createDataset(no_newusertable, { LINK(sourceDataset), LINK(record), LINK(transform) });
     else if (transform)
-        select = createDatasetF(no_newusertable, LINK(dataset), LINK(record), LINK(transform), NULL); //createUniqueId(), NULL);
+        select = createDataset(no_newusertable, { LINK(dataset), LINK(record), LINK(transform) });
     else
     {
         IHqlExpression * newRecord = checkBuildIndexRecord(LINK(record), errpos);
-        select = createDatasetF(no_selectfields, LINK(dataset), newRecord, NULL); //createUniqueId(), NULL);
+        select = createDataset(no_selectfields, { LINK(dataset), newRecord });
     }
 
     HqlExprArray args;
@@ -10101,7 +10105,7 @@ void HqlGram::defineSymbolProduction(attribute & nameattr, attribute & paramattr
         if (etype && etype->getTypeCode()==type_record)
         {
             IHqlExpression *recordDef = queryExpression(etype);
-            expr.setown(createDatasetF(no_table, createConstant(str(name)), LINK(recordDef), LINK(expr), NULL));
+            expr.setown(createDataset(no_table, { createConstant(str(name)), LINK(recordDef), LINK(expr) }));
         }
         break;
 
@@ -10752,7 +10756,7 @@ IHqlExpression * HqlGram::createIffDataset(IHqlExpression * record, IHqlExpressi
             OwnedHqlExpr left = createSelector(no_left, ds, seq);
             OwnedHqlExpr selectedValue = createSelectExpr(LINK(left), LINK(rhs));
             OwnedHqlExpr transform = createSingleValueTransform(record, selectedValue);
-            return createDatasetF(no_hqlproject, LINK(ds), LINK(transform), LINK(seq), NULL);
+            return createDataset(no_hqlproject, { LINK(ds), LINK(transform), LINK(seq) });
         }
 
     }
@@ -10770,7 +10774,7 @@ IHqlExpression * HqlGram::createIff(attribute & condAttr, attribute & leftAttr,
     OwnedHqlExpr record = createRecord(field);
     OwnedHqlExpr lhs = createIffDataset(record, left);
     OwnedHqlExpr rhs = createIffDataset(record, right);
-    OwnedHqlExpr ifDs = createDatasetF(no_if, condAttr.getExpr(), lhs.getClear(), rhs.getClear(), NULL);
+    OwnedHqlExpr ifDs = createDataset(no_if, { condAttr.getExpr(), lhs.getClear(), rhs.getClear() });
     OwnedHqlExpr row1 = createRow(no_selectnth, ifDs.getClear(), getSizetConstant(1));
     return createSelectExpr(LINK(row1), LINK(field));
 }

+ 1 - 1
ecl/hql/hqlir.cpp

@@ -2380,7 +2380,7 @@ static const char * const expectedIR1 [] = {
 "%e28 = inlinetable(%e26,%e3) : %t27;",
 "%e29 = %e28 {location '',9,7};",
 "%e30 = %e29 {symbol ds@9};",
-"%e31 = null : <null>;",
+"%e31 = null : %t25;",
 "%e32 = selectfields(%e30,%e31) : %t27;",
 "%t33 = type int4;",
 "%c34 = constant 706706620 : %t33;",

+ 2 - 2
ecl/hql/hqlpregex.cpp

@@ -282,7 +282,7 @@ IHqlExpression * HqlRegexParser::parse2()
             //MORE: This really needs to be utf-8 compliant...
             char next = (char)nextAdvance();
             //MORE: interpret special characters....
-            return createValue(no_pat_const, createConstant(createStringValue(&next, 1)));
+            return createValue(no_pat_const, makePatternType(), createConstant(createStringValue(&next, 1)));
         }
     default:
         if (nextIsSpecial())
@@ -330,7 +330,7 @@ IHqlExpression * HqlRegexParser::parse2()
                 break;
             }
         }
-        return createValue(no_pat_const, createConstant(value));
+        return createValue(no_pat_const, makePatternType(), createConstant(value));
     }
 }
 

+ 4 - 4
ecl/hql/hqltrans.cpp

@@ -3069,7 +3069,7 @@ void MergingHqlTransformer::pushChildContext(IHqlExpression * expr, IHqlExpressi
     IHqlExpression * scope = expr;
     //NB: Do no call createComma because that calls createDataset which unwinds a comma list!
     if (childScope)
-        childScope.setown(createValue(no_comma,LINK(scope), childScope.getClear()));
+        childScope.setown(createValue(no_comma, nullptr, LINK(scope), childScope.getClear()));
     else
         childScope.set(scope);
     initializeActiveSelector(expr, transformed);
@@ -4579,8 +4579,8 @@ void ScopedTransformer::throwScopeError()
 
 ScopedDependentTransformer::ScopedDependentTransformer(HqlTransformerInfo & _info) : ScopedTransformer(_info)
 {
-    cachedLeft.setown(createValue(no_left));
-    cachedRight.setown(createValue(no_right));
+    cachedLeft.setown(createValue(no_left, makeNullType()));
+    cachedRight.setown(createValue(no_right, makeNullType()));
 }
 
 bool ScopedDependentTransformer::setDataset(IHqlExpression * ds, IHqlExpression * transformedDs)
@@ -4677,7 +4677,7 @@ void ScopedDependentTransformer::pushChildContext(IHqlExpression * expr, IHqlExp
     {
         //NB: Do no call createComma because that calls createDataset which unwinds a comma list!
         if (childScope)
-            childScope.setown(createValue(no_comma,LINK(scope), childScope.getClear()));
+            childScope.setown(createValue(no_comma, nullptr, LINK(scope), childScope.getClear()));
         else
             childScope.set(scope);
 

+ 6 - 6
ecl/hql/hqlutil.cpp

@@ -1177,7 +1177,7 @@ IHqlExpression * JoinOrderSpotter::doFindJoinSortOrders(IHqlExpression * conditi
             if (lmatch)
             {
                 if (rmatch)
-                    return createValue(no_and, lmatch, rmatch);
+                    return createValue(no_and, makeBoolType(), lmatch, rmatch);
                 else
                     return lmatch;
             }
@@ -5165,12 +5165,12 @@ IHqlExpression * ModuleExpander::createExpanded(IHqlExpression * scopeExpr, IHql
                 if (value->isDictionary())
                 {
                     value.setown(createDataset(no_datasetfromdictionary, value.getClear()));
-                    value.setown(createDataset(no_selectfields, value.getClear(), createValue(no_null)));
+                    value.setown(createDataset(no_selectfields, value.getClear(), createValue(no_null, makeNullType())));
                     op = no_output;
                 }
                 else if (value->isDataset())
                 {
-                    value.setown(createDataset(no_selectfields, LINK(value), createValue(no_null)));
+                    value.setown(createDataset(no_selectfields, LINK(value), createValue(no_null, makeNullType())));
                     op = no_output;
                 }
                 else if (value->isDatarow())
@@ -6680,7 +6680,7 @@ void TempTableTransformer::createTempTableAssign(HqlExprArray & assigns, IHqlExp
                             HqlExprArray children;
                             children.append(*LINK(src));
                             children.append(*LINK(record));
-                            OwnedHqlExpr tempTable = createValue(no_temptable, children);
+                            OwnedHqlExpr tempTable = createDataset(no_temptable, children);
 //                          castValue.setown(transform(tempTable));
                             castValue.set(tempTable);
                         }
@@ -6691,7 +6691,7 @@ void TempTableTransformer::createTempTableAssign(HqlExprArray & assigns, IHqlExp
                                 transforms.append(*createTempTableTransform(src->queryChild(idx), record));
 
                             HqlExprArray children;
-                            children.append(*createValue(no_transformlist, transforms));
+                            children.append(*createValue(no_transformlist, makeNullType(), transforms));
                             children.append(*LINK(record));
                             castValue.setown(createDataset(no_inlinetable, children));
                         }
@@ -10310,7 +10310,7 @@ unsigned buildRtlRecordFields(IRtlFieldTypeDeserializer &deserializer, unsigned
         {
         case no_ifblock:
         {
-            OwnedHqlExpr key = createValue(no_comma, LINK(rowRecord), LINK(field));
+            OwnedHqlExpr key = createValue(no_comma, makeVoidType(), LINK(rowRecord), LINK(field));
             const RtlTypeInfo * type = deserializer.lookupType(key);
             if (!type)
             {

+ 3 - 3
ecl/hqlcpp/hqlcpp.cpp

@@ -2854,7 +2854,7 @@ void HqlCppTranslator::buildIncrementAssign(BuildCtx & ctx, IHqlExpression * tar
         }
     }
 
-    OwnedHqlExpr plus = createValue(no_add, LINK(target), castValue.getClear());
+    OwnedHqlExpr plus = createValue(no_add, LINK(type), LINK(target), castValue.getClear());
     buildAssign(condctx, target, plus);
 }
 
@@ -2886,7 +2886,7 @@ void HqlCppTranslator::buildIncrementAssign(BuildCtx & ctx, const CHqlBoundTarge
         }
     }
 
-    OwnedHqlExpr plus = createValue(no_add, target.getTranslatedExpr(), castValue.getClear());
+    OwnedHqlExpr plus = createValue(no_add, LINK(type), target.getTranslatedExpr(), castValue.getClear());
     buildExprAssign(ctx, target, plus);
 }
 
@@ -10056,7 +10056,7 @@ bool HqlCppTranslator::doBuildExprInfiniteSubString(BuildCtx & ctx, SubStringInf
 
     OwnedHqlExpr length;
     if (start && !isZero(start))
-        length.setown(createValue(no_sub, info.boundTo.expr.getLink(), LINK(start)));
+        length.setown(createValue(no_sub, info.boundTo.getType(), info.boundTo.expr.getLink(), LINK(start)));
     else
         length.setown(info.boundTo.expr.getLink());
     tgt.length.setown(ensureExprType(length, sizetType));

+ 1 - 0
ecl/hqlcpp/hqlcpp.ipp

@@ -280,6 +280,7 @@ public:
     IHqlExpression * getTranslatedExpr() const;
     inline bool isStreamed() const              { return hasStreamedModifier(queryType()); }
 
+    ITypeInfo * getType() const                 { return expr->getType(); }
     ITypeInfo * queryType() const               { return expr->queryType(); }
     void set(const CHqlBoundExpr & src)         { expr.set(src.expr); length.set(src.length); count.set(src.count); isAll.set(src.isAll); }
     void setFromTarget(const CHqlBoundTarget & target);

+ 4 - 4
ecl/hqlcpp/hqlcppcase.cpp

@@ -284,8 +284,8 @@ void HqlCppCaseInfo::buildChop3Map(BuildCtx & ctx, IExprProcessor & target, CHql
     {
         unsigned mid = start + (end - start) / 2;
         generateCompareVar(ctx, temp, test, queryCompare(mid));
-        OwnedHqlExpr test1 = createValue(no_eq, LINK(temp), getZero());
-        OwnedHqlExpr test2 = createValue(no_lt, LINK(temp), getZero());
+        OwnedHqlExpr test1 = createValue(no_eq, makeBoolType(), LINK(temp), getZero());
+        OwnedHqlExpr test2 = createValue(no_lt, makeBoolType(), LINK(temp), getZero());
 
         BuildCtx subctx(ctx);
         IHqlStmt * if1 = subctx.addFilter(test1);                   // if (test == 0)
@@ -615,7 +615,7 @@ void HqlCppCaseInfo::buildLoopChopMap(BuildCtx & ctx, IExprProcessor & target, C
         target.process(translator,ctx, defaultValue);
 
         OwnedHqlExpr loopc = createBoolExpr(no_lt, LINK(leftVar), LINK(rightVar));
-        OwnedHqlExpr mid = createValue(no_div, createValue(no_add, LINK(leftVar), LINK(rightVar)), createConstant(indexType->castFrom(false, 2)));
+        OwnedHqlExpr mid = createValue(no_div, LINK(indexType), createValue(no_add, LINK(indexType), LINK(leftVar), LINK(rightVar)), createConstant(indexType->castFrom(false, 2)));
         OwnedHqlExpr mid_p1 = createValue(no_add, LINK(indexType), LINK(midVar), createConstant(indexType->castFrom(false, 1)));
         OwnedHqlExpr curelem = createValue(no_index, LINK(compareType), boundTable.getTranslatedExpr(), createTranslated(mid_p1));
         OwnedHqlExpr test1 = createBoolExpr(no_lt, LINK(compareVar), getZero());
@@ -1047,7 +1047,7 @@ IHqlExpression * HqlCppCaseInfo::createResultsExpr(IHqlExpression * matchVar, bo
 
 void HqlCppCaseInfo::generateCompareVar(BuildCtx & ctx, IHqlExpression * target, CHqlBoundExpr & test, IHqlExpression * other)
 {
-    OwnedHqlExpr compare = createValue(no_order, test.getTranslatedExpr(), LINK(other));
+    OwnedHqlExpr compare = createValue(no_order, makeIntType(4, true), test.getTranslatedExpr(), LINK(other));
     translator.buildAssignToTemp(ctx, target, compare);
 }
     

+ 5 - 4
ecl/hqlcpp/hqlcset.cpp

@@ -338,7 +338,7 @@ BoundRow * InlineBlockDatasetCursor::buildIterateLoop(BuildCtx & ctx, bool needT
         OwnedHqlExpr counter = ctx.getTempDeclare(unsignedType, count);
 
         //while (count--)
-        test.setown(createValue(no_postdec, LINK(counter)));
+        test.setown(createValue(no_postdec, counter->getType(), LINK(counter)));
     }
 
     ctx.addLoop(test, NULL, false);
@@ -626,7 +626,7 @@ BoundRow * InlineLinkedDatasetCursor::doBuildIterateLoop(BuildCtx & ctx, bool ne
     OwnedHqlExpr counter = ctx.getTempDeclare(unsignedType, count);
 
     //while (count--)
-    test.setown(createValue(no_postdec, LINK(counter)));
+    test.setown(createValue(no_postdec, LINK(unsignedType), LINK(counter)));
 
     ctx.addLoop(test, NULL, false);
     ctx.addQuoted(s.clear().append(rowName).append(" = *").append(cursorName).append("++;"));
@@ -1064,7 +1064,7 @@ BoundRow * MultiLevelDatasetCursor::buildSelectNth(BuildCtx & ctx, IHqlExpressio
     buildIterateLoop(subctx, true);
     if (!selectFirst)
     {
-        OwnedHqlExpr test = createValue(no_eq, makeBoolType(), createValue(no_predec, LINK(boundCount.expr)), getZero());
+        OwnedHqlExpr test = createValue(no_eq, makeBoolType(), createValue(no_predec, boundCount.getType(), LINK(boundCount.expr)), getZero());
         subctx.addFilter(test);
     }
 
@@ -1832,7 +1832,8 @@ void InlineDatasetBuilder::finishRow(BuildCtx & ctx, BoundRow * selfCursor)
     }
     else
     {
-        OwnedHqlExpr inc = createValue(no_add, LINK(selfCursor->queryBound()), LINK(bound.expr));
+        IHqlExpression * boundCursor = selfCursor->queryBound();
+        OwnedHqlExpr inc = createValue(no_add, boundCursor->getType(), LINK(boundCursor), LINK(bound.expr));
         ctx.addAssign(selfCursor->queryBound(), inc);
     }
 }

+ 2 - 2
ecl/hqlcpp/hqlhtcpp.cpp

@@ -199,7 +199,7 @@ IHqlExpression * getMetaUniqueKey(IHqlExpression * record, bool grouped)
     if (grouped)
         search.setown(createAttribute(groupedAtom, search.getClear()));
     if (!search)
-        search.setown(createValue(no_null));
+        search.setown(createValue(no_null, makeNullType()));
     return search.getClear();
 }
 
@@ -15014,7 +15014,7 @@ ABoundActivity * HqlCppTranslator::doBuildActivityChooseSets(BuildCtx & ctx, IHq
             buildFilter(condctx, cond2);
         }
 
-        OwnedHqlExpr inc = createValue(no_postinc, bucketExpr.getLink());
+        OwnedHqlExpr inc = createValue(no_postinc, LINK(unsignedType), bucketExpr.getLink());
         condctx.addExpr(inc);
         BuildCtx doneCtx(condctx);
         buildFilter(doneCtx, condDone);

+ 2 - 2
ecl/hqlcpp/hqlresource.cpp

@@ -2759,7 +2759,7 @@ IHqlExpression * SpillerInfo::createSpilledRead(IHqlExpression * spillReason)
             args.append(*createSpillName());
             args.append(*LINK(record));
         }
-        args.append(*createValue(no_thor));
+        args.append(*createValue(no_thor, makeNullType()));
         addSpillFlags(args, true);
         args.append(*createUniqueId());
         args.append(*createExprAttribute(_signed_Atom, createConstant("hpcc")));
@@ -6246,7 +6246,7 @@ IHqlExpression * EclResourcer::doCreateResourced(IHqlExpression * expr, Resource
         if (!transformed->isAction())
             transformed.setown(info->createTransformedExpr(transformed));
         else if (defineSideEffect)
-            transformed.setown(createValue(no_definesideeffect, LINK(transformed), createUniqueId()));
+            transformed.setown(createValue(no_definesideeffect, makeVoidType(), LINK(transformed), createUniqueId()));
     }
 
     return transformed.getClear();

+ 1 - 1
ecl/hqlcpp/hqlsource.cpp

@@ -1106,7 +1106,7 @@ void SourceBuilder::appendFilter(SharedHqlExpr & unkeyedFilter, IHqlExpression *
         else
         {
             if (unkeyedFilter)
-                unkeyedFilter.setown(createValue(no_and, unkeyedFilter.getClear(), LINK(expr)));
+                unkeyedFilter.setown(createValue(no_and, makeBoolType(), unkeyedFilter.getClear(), LINK(expr)));
             else
                 unkeyedFilter.set(expr);
         }

+ 4 - 4
ecl/hqlcpp/hqltcppc.cpp

@@ -173,7 +173,7 @@ void SizeStruct::addVariableExpr(unsigned _varMinSize, IHqlExpression * expr)
 {
     varMinSize += _varMinSize;
     if (varSize)
-        varSize.setown(createValue(no_add, varSize.getClear(), LINK(expr)));
+        varSize.setown(createValue(no_add, makeIntType(4,false), varSize.getClear(), LINK(expr)));
     else
         varSize.set(expr);
 }
@@ -2523,11 +2523,11 @@ void CBitfieldInfo::buildColumnExpr(HqlCppTranslator & translator, BuildCtx & ct
     OwnedHqlExpr address = getColumnAddress(translator, ctx, selector, queryStorageType(), 0);
     OwnedHqlExpr value = convertAddressToValue(address, queryStorageType());
     if (bitOffset > 0)
-        value.setown(createValue(no_rshift, LINK(value), getSizetConstant((int)bitOffset)));
+        value.setown(createValue(no_rshift, value->getType(), LINK(value), getSizetConstant((int)bitOffset)));
 
     unsigned __int64 mask = ((unsigned __int64)1<<columnType->getBitSize())-1;
     IValue * maskValue = columnType->queryChildType()->castFrom(false, (__int64)mask);
-    bound.expr.setown(createValue(no_band, LINK(value), createConstant(maskValue)));
+    bound.expr.setown(createValue(no_band, value->getType(), LINK(value), createConstant(maskValue)));
 }
 
 IHqlExpression * CBitfieldInfo::buildSizeOfUnbound(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector)
@@ -2575,7 +2575,7 @@ void CBitfieldInfo::setColumn(HqlCppTranslator & translator, BuildCtx & ctx, IRe
     IValue * oldMaskValue = storageType->castFrom(false, (__int64)shiftMask);
     IHqlExpression * oldMask = createConstant(oldMaskValue);
     IHqlExpression * transColumn = createTranslatedOwned(columnRef);
-    IHqlExpression * oldValue = createValue(no_band, transColumn, createValue(no_bnot,oldMask));
+    IHqlExpression * oldValue = createValue(no_band, LINK(storageType), transColumn, createValue(no_bnot, LINK(storageType), oldMask));
 
     IValue * newMaskValue = storageType->castFrom(false, (__int64)mask);
     IHqlExpression * newMask = createConstant(newMaskValue);

+ 2 - 2
ecl/hqlcpp/hqltcppc2.cpp

@@ -470,7 +470,7 @@ void CChildLimitedDatasetColumnInfo::buildDeserializeChildLoop(HqlCppTranslator
     CHqlBoundExpr bound;
     translator.buildTempExpr(loopctx, mappedCount, bound);
 
-    OwnedHqlExpr test = createValue(no_postdec, LINK(bound.expr));
+    OwnedHqlExpr test = createValue(no_postdec, bound.getType(), LINK(bound.expr));
     loopctx.addLoop(test, NULL, false);
 }
 
@@ -522,7 +522,7 @@ bool CChildLimitedDatasetColumnInfo::buildReadAhead(HqlCppTranslator & translato
             CHqlBoundExpr bound;
             translator.buildTempExpr(loopctx, replacedCount, bound);
 
-            OwnedHqlExpr test = createValue(no_postdec, LINK(bound.expr));
+            OwnedHqlExpr test = createValue(no_postdec, bound.getType(), LINK(bound.expr));
             loopctx.addLoop(test, NULL, false);
 
             StringBuffer helperCpp;

+ 1 - 1
ecl/hqlcpp/hqltomita.cpp

@@ -1383,7 +1383,7 @@ void TomitaContext::compileSearchPattern()
 
     eofToken.setown(new TomToken(NULL, noGuards));
     tokens.append(*LINK(eofToken));
-    OwnedHqlExpr nullExpr = createValue(no_null);
+    OwnedHqlExpr nullExpr = createValue(no_null, makeNullType());
 
     //MORE, create rules for used list...
     expandRecursion();

+ 7 - 7
ecl/hqlcpp/hqlttcpp.cpp

@@ -5654,7 +5654,7 @@ void GlobalAttributeInfo::doSplitGlobalDefinition(ITypeInfo * type, IHqlExpressi
             args.kill();
             args.append(*LINK(filename));
             args.append(*LINK(record));
-            args.append(*createValue(no_thor));
+            args.append(*createValue(no_thor, makeNullType()));
             args.append(*createAttribute(_noVirtual_Atom));         // don't interpret virtual fields in spilled output
             args.append(*createExprAttribute(_signed_Atom, createConstant("hpcc")));
 
@@ -6927,7 +6927,7 @@ IHqlExpression * WorkflowTransformer::createSequentialWorkflow(IHqlExpression *
         else
         {
             if (nextBranch)
-                nextBranch.setown(createValue(expr->getOperator(), nextBranch.getClear(), LINK(transformed)));
+                nextBranch.setown(createValue(expr->getOperator(), makeVoidType(), nextBranch.getClear(), LINK(transformed)));
             else
                 nextBranch.set(transformed);
             inheritDependencies(nextBranch);
@@ -8716,7 +8716,7 @@ void AutoScopeMigrateTransformer::doAnalyseExpr(IHqlExpression * expr)
         break;
     case no_thor:
         //ignore thor attribute on a dataset..
-        if (expr->queryType())
+        if (expr->queryType() && (expr->queryType()->getTypeCode() != type_null))
         {
             curGraph++;
             graphDepth++;
@@ -8995,14 +8995,14 @@ IHqlExpression * FilterCloner::inheritFilters(IHqlExpression * expr)
             {
                 DBGLOG("Inheriting filter condition");
                 IHqlExpression * cond = replaceExpression(lhsExtra, lhs, rhs);
-                return createValue(no_and, LINK(expr), cond);
+                return createValue(no_and, makeBoolType(), LINK(expr), cond);
             }
             IHqlExpression * rhsExtra = (IHqlExpression *)rhs->queryTransformExtra();
             if (rhsExtra)
             {
                 DBGLOG("Inheriting filter condition");
                 IHqlExpression * cond = replaceExpression(rhsExtra, rhs, lhs);
-                return createValue(no_and, LINK(expr), cond);
+                return createValue(no_and, makeBoolType(), LINK(expr), cond);
             }
             break;
         }
@@ -9016,7 +9016,7 @@ IHqlExpression * FilterCloner::inheritFilters(IHqlExpression * expr)
             if (lhsExtra)
             {
                 DBGLOG("Inheriting filter condition");
-                return createValue(no_and, LINK(expr), LINK(lhsExtra));
+                return createValue(no_and, makeBoolType(), LINK(expr), LINK(lhsExtra));
             }
             break;
         }
@@ -12367,7 +12367,7 @@ IHqlExpression * HqlTreeNormalizer::transformTable(IHqlExpression * untransforme
     if (getStringValue(s, filename, NULL).length() == 0)
         return transformed.getClear();
 
-    OwnedHqlExpr modeThor = createValue(no_thor);
+    OwnedHqlExpr modeThor = createValue(no_thor, makeNullType());
     IHqlExpression * diskRead = replaceChild(transformed, 2, modeThor);
     HqlExprArray args;
     args.append(*diskRead);