浏览代码

HPCC-18013 Add method to get RtlRecord from IOutputMetaData

Also fixes various internal errors encountered when using VIRTUAL RECORD to
signify passing just the row metadata to external functions.

Signed-off-by: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 8 年之前
父节点
当前提交
410cccd62a

+ 1 - 1
common/thorhelper/thorcommon.ipp

@@ -405,7 +405,6 @@ public:
     {
         return original->queryChildMeta(i);
     }
-
 protected:
     size32_t offset;
     IOutputMetaData *original;
@@ -540,6 +539,7 @@ public:
     {
         return original->queryChildMeta(i);
     }
+    virtual const RtlRecord *queryRecordAccessor(bool expand) const override { return original->queryRecordAccessor(expand); }
 
 protected:
     size32_t offset;

+ 2 - 1
common/thorhelper/thorfile.cpp

@@ -25,7 +25,8 @@
 #include "rtlfield.hpp"
 #include "rtlds_imp.hpp"
 
-namespace thorfile {
+namespace thorfile
+{  // Make sure we can't clash with generated versions or version check mechanism fails.
 #include "eclhelper_base.hpp"
 }
 #include "thorcommon.ipp"

+ 3 - 3
ecl/hql/hqlexpr.ipp

@@ -1715,10 +1715,10 @@ public:
     virtual type_t getTypeCode() const { return type_record; }
     virtual size32_t getSize();
     virtual unsigned getAlignment();
-    virtual unsigned getPrecision() { assertex(!"tbd"); return 0; }
+    virtual unsigned getPrecision() { return 0; }
     virtual unsigned getBitSize()  { return 0; }
-    virtual unsigned getStringLen() { assertex(!"tbd"); return 0; }
-    virtual unsigned getDigits() { assertex(!"tbd"); return 0; }
+    virtual unsigned getStringLen() { return 0; }
+    virtual unsigned getDigits() { return 0; }
     virtual bool assignableFrom(ITypeInfo * source);
     virtual IValue * castFrom(bool isSignedValue, __int64 value) { return NULL; }
     virtual IValue * castFrom(double value)  { return NULL; }

+ 20 - 12
ecl/hql/hqlstack.cpp

@@ -22,9 +22,6 @@
 #include "eclrtl_imp.hpp"
 #include "rtlfield.hpp"
 #include "rtlds_imp.hpp"
-namespace hqlstack {
-#include "eclhelper_base.hpp"
-}
 #include "rtlrecord.hpp"
 #include "rtldynfield.hpp"
 #include "hqlstack.hpp"
@@ -38,39 +35,37 @@ namespace hqlstack {
  *
  */
 
-class CDynamicOutputMetaData : public hqlstack::COutputMetaData
+class CDynamicOutputMetaData : public COutputMetaData
 {
 public:
-    CDynamicOutputMetaData(const RtlRecordTypeInfo & fields)
-    : offsetInformation(fields, true), typeInfo(fields)
+    CDynamicOutputMetaData(const RtlRecordTypeInfo & fields) : typeInfo(fields)
     {
-
     }
 
     virtual const RtlTypeInfo * queryTypeInfo() const { return &typeInfo; }
     virtual size32_t getRecordSize(const void * row)
     {
         //Allocate a temporary offset array on the stack to avoid runtime overhead.
-        unsigned numOffsets = offsetInformation.getNumVarFields() + 1;
+        const RtlRecord *offsetInformation = queryRecordAccessor(true);
+        unsigned numOffsets = offsetInformation->getNumVarFields() + 1;
         size_t * variableOffsets = (size_t *)alloca(numOffsets * sizeof(size_t));
-        RtlRow offsetCalculator(offsetInformation, row, numOffsets, variableOffsets);
+        RtlRow offsetCalculator(*offsetInformation, row, numOffsets, variableOffsets);
         return offsetCalculator.getRecordSize();
     }
 
     virtual size32_t getFixedSize() const
     {
-        return offsetInformation.getFixedSize();
+        return queryRecordAccessor(true)->getFixedSize();
     }
     // returns 0 for variable row size
     virtual size32_t getMinRecordSize() const
     {
-        return offsetInformation.getMinRecordSize();
+        return queryRecordAccessor(true)->getMinRecordSize();
     }
 
     virtual IOutputRowDeserializer * createDiskDeserializer(ICodeContext * ctx, unsigned activityId) { throwUnexpected(); }
 
 protected:
-    RtlRecord offsetInformation;
     const RtlTypeInfo &typeInfo;
 };
 
@@ -270,6 +265,19 @@ int FuncCallStack::push(ITypeInfo* argType, IHqlExpression* curParam)
             return -1;
         break;
     }
+    case type_record:
+    {
+        try
+        {
+            pushMeta(curParam->queryRecordType());
+        }
+        catch (IException *E)
+        {
+            ::Release(E);
+            return -1;
+        }
+        break;
+    }
     default:
         EclIR::dump_ir(curParam);
         //code isn't here to pass sets/datasets to external functions....

+ 3 - 0
ecl/hql/hqlutil.cpp

@@ -7805,6 +7805,9 @@ protected:
         case type_date:
             //may possibly have some support in the future, but not yet...
             return false;
+        case type_record:
+            result.append(lookupRepeat("R15IOutputMetaData"));
+            return true;
         }
         throwUnexpected();
     }

+ 8 - 0
ecl/hqlcpp/hqlcpp.cpp

@@ -6162,6 +6162,11 @@ void HqlCppTranslator::doBuildCall(BuildCtx & ctx, const CHqlBoundTarget * tgt,
                 normalizeBoundExpr(ctx, bound);
                 break;
             }
+        case type_record:
+            {
+                args.append(*buildMetaParameter(curParam));
+                break;
+            }
         default:
             {
                 buildExpr(ctx, castParam, bound);
@@ -6219,6 +6224,9 @@ void HqlCppTranslator::doBuildCall(BuildCtx & ctx, const CHqlBoundTarget * tgt,
                 bound.expr.setown(getPointer(bound.expr));
                 break;
             }
+        case type_record:
+            done = true;
+            break;
         case type_array:
             UNIMPLEMENTED;
         }

+ 3 - 0
ecl/hqlcpp/hqlhtcpp.cpp

@@ -63,7 +63,10 @@
 #include "eclrtl_imp.hpp"
 #include "rtlfield.hpp"
 #include "rtlds_imp.hpp"
+namespace hqlhtcpp
+{  // Make sure we can't clash with generated versions or version check mechanism fails (if this dll was ever in the future linked in runtime)
 #include "eclhelper_base.hpp"
+}
 
 #include "ctfile.hpp"   // for KEYBUILD_MAXLENGTH
 

+ 1 - 1
ecl/hqlcpp/hqlwcpp.cpp

@@ -887,7 +887,7 @@ void HqlCppWriter::generateParamCpp(IHqlExpression * param, IHqlExpression * att
     switch (paramType->getTypeCode())
     {
     case type_record:
-        out.append("IOutputMetaData * ");
+        out.append("IOutputMetaData &");
         break;
     case type_dictionary:
     case type_table:

+ 1 - 1
roxie/ccd/ccdserver.cpp

@@ -49,7 +49,7 @@
 #include "ftbase.ipp"
 
 namespace ccdserver_hqlhelper
-{
+{  // Make sure we can't clash with generated versions or version check mechanism fails.
 #include "eclhelper_base.hpp"
 }
 

+ 0 - 25
rtl/eclrtl/rtlds_imp.hpp

@@ -349,31 +349,6 @@ extern ECLRTL_API void rtlLinkChildren(void * self, IOutputMetaData & meta);
 
 //---------------------------------------------------------------------------
 
-class ECLRTL_API CSimpleSourceRowPrefetcher : public ISourceRowPrefetcher, public RtlCInterface
-{
-public:
-    CSimpleSourceRowPrefetcher(IOutputMetaData & _meta, ICodeContext * _ctx, unsigned _activityId)
-    {
-        deserializer.setown(_meta.querySerializedDiskMeta()->createDiskDeserializer(_ctx, _activityId));
-        rowAllocator.setown(_ctx->getRowAllocator(&_meta, _activityId));
-    }
-
-    RTLIMPLEMENT_IINTERFACE
-
-    virtual void readAhead(IRowDeserializerSource & in)
-    {
-        RtlDynamicRowBuilder rowBuilder(rowAllocator);
-        size32_t len = deserializer->deserialize(rowBuilder, in);
-        rtlReleaseRow(rowBuilder.finalizeRowClear(len));
-    }
-
-protected:
-    Owned<IOutputRowDeserializer> deserializer;
-    Owned<IEngineRowAllocator> rowAllocator;
-};
-
-//---------------------------------------------------------------------------
-
 class ECLRTL_API RtlLinkedDatasetBuilder
 {
 public:

+ 26 - 16
rtl/eclrtl/rtldynfield.cpp

@@ -23,6 +23,7 @@
 #include "eclhelper.hpp"
 #include "eclrtl_imp.hpp"
 #include "rtldynfield.hpp"
+#include "rtlrecord.hpp"
 
 //---------------------------------------------------------------------------------------------------------------------
 
@@ -463,8 +464,12 @@ extern ECLRTL_API IRtlFieldTypeDeserializer *createRtlFieldTypeDeserializer()
     return new CRtlFieldTypeDeserializer;
 }
 
+extern ECLRTL_API StringBuffer &dumpTypeInfo(StringBuffer &ret, const RtlTypeInfo *t)
+{
+    return CRtlFieldTypeSerializer::serialize(ret, t);
+}
 
-extern ECLRTL_API void dumpDatasetType(size32_t & __lenResult,char * & __result,IOutputMetaData &  metaVal,IRowStream * val)
+extern ECLRTL_API void dumpRecordType(size32_t & __lenResult,char * & __result,IOutputMetaData &metaVal)
 {
     StringBuffer ret;
     CRtlFieldTypeSerializer::serialize(ret, metaVal.queryTypeInfo());
@@ -480,23 +485,28 @@ extern ECLRTL_API void dumpDatasetType(size32_t & __lenResult,char * & __result,
     __result = ret.detach();
 }
 
-extern ECLRTL_API StringBuffer &dumpTypeInfo(StringBuffer &ret, const RtlTypeInfo *t)
+extern ECLRTL_API void getFieldVal(size32_t & __lenResult,char * & __result, int column, IOutputMetaData &  metaVal, const byte *row)
 {
-    return CRtlFieldTypeSerializer::serialize(ret, t);
+    __lenResult = 0;
+    __result = nullptr;
+    if (column >= 0)
+    {
+        const RtlRecord *r = metaVal.queryRecordAccessor(true);
+        if (r)
+        {
+            unsigned numOffsets = r->getNumVarFields() + 1;
+            size_t * variableOffsets = (size_t *)alloca(numOffsets * sizeof(size_t));
+            RtlRow offsetCalculator(*r, row, numOffsets, variableOffsets);
+            if (column != (unsigned) -1)
+                offsetCalculator.getUtf8(__lenResult, __result, column);
+        }
+    }
 }
 
-extern ECLRTL_API void dumpRecordType(size32_t & __lenResult,char * & __result,IOutputMetaData &  metaVal,const byte * val)
+extern ECLRTL_API int getFieldNum(const char *fieldName, IOutputMetaData &  metaVal)
 {
-    StringBuffer ret;
-    CRtlFieldTypeSerializer::serialize(ret, metaVal.queryTypeInfo());
-
-#ifdef _DEBUG
-    CRtlFieldTypeDeserializer deserializer;
-    StringBuffer ret2;
-    CRtlFieldTypeSerializer::serialize(ret2, deserializer.deserialize(ret));
-    assert(streq(ret, ret2));
-#endif
-
-    __lenResult = ret.length();
-    __result = ret.detach();
+    const RtlRecord *r = metaVal.queryRecordAccessor(true);
+    if (r)
+        return r->getFieldNum(fieldName);
+    return -1;
 }

+ 10 - 4
rtl/eclrtl/rtldynfield.hpp

@@ -90,16 +90,22 @@ extern ECLRTL_API IRtlFieldTypeDeserializer *createRtlFieldTypeDeserializer();
 extern ECLRTL_API StringBuffer &dumpTypeInfo(StringBuffer &ret, const RtlTypeInfo *t);
 
 /**
- * Serialize metadata of supplied stream to JSON, and return it to ECL caller as a string. Used for testing serializer.
+ * Serialize metadata of supplied record to JSON, and return it to ECL caller as a string. Used for testing serializer.
  *
  */
-extern ECLRTL_API void dumpDatasetType(size32_t & __lenResult,char * & __result,IOutputMetaData &  metaVal,IRowStream * val);
+extern ECLRTL_API void dumpRecordType(size32_t & __lenResult, char * & __result, IOutputMetaData &  metaVal);
 
 /**
- * Serialize metadata of supplied record to JSON, and return it to ECL caller as a string. Used for testing serializer.
+ * Extract a field from a record via dynamic column number
+ *
+ */
+extern ECLRTL_API void getFieldVal(size32_t & __lenResult, char * & __result, int column, IOutputMetaData &  metaVal, const byte *row);
+
+/**
+ * Extract a column number from a record via dynamic fieldname
  *
  */
-extern ECLRTL_API void dumpRecordType(size32_t & __lenResult,char * & __result,IOutputMetaData &  metaVal,const byte * val);
+extern ECLRTL_API int getFieldNum(const char *fieldName, IOutputMetaData &  metaVal);
 
 
 #endif

+ 232 - 1
rtl/eclrtl/rtlrecord.cpp

@@ -22,6 +22,7 @@
 #include "jlib.hpp"
 #include "eclhelper.hpp"
 #include "eclrtl_imp.hpp"
+#include "rtlds_imp.hpp"
 #include "rtlrecord.hpp"
 
 /*
@@ -128,8 +129,73 @@ static const RtlFieldInfo * * expandNestedRows(const RtlFieldInfo * * target, co
     return target;
 }
 
+class FieldNameToFieldNumMap
+{
+public:
+    FieldNameToFieldNumMap(const RtlFieldInfo * const * fields, bool expand)
+    {
+        unsigned idx = 0;
+        if (expand)
+            expandFields(nullptr, idx, fields);
+        else
+        {
+            for (;*fields;fields++)
+            {
+                const RtlFieldInfo * cur = *fields;
+                const RtlTypeInfo * type = cur->type;
+                map.setValue(cur->name, idx);
+                idx++;
+            }
+        }
+    }
+    unsigned lookup(const char *name) const
+    {
+        unsigned *result = map.getValue(name);
+        if (result)
+            return *result;
+        else
+            return (unsigned) -1;
+    }
+protected:
+    void expandFields(const char *prefix, unsigned &idx, const RtlFieldInfo * const * fields)
+    {
+        for (;*fields;fields++)
+        {
+            const RtlFieldInfo * cur = *fields;
+            const RtlTypeInfo * type = cur->type;
+            if (type->getType() == type_record)
+            {
+                const RtlFieldInfo * const * nested = type->queryFields();
+                if (nested)
+                {
+                    StringBuffer newPrefix(prefix);
+                    newPrefix.append(cur->name).append('.');
+                    expandFields(newPrefix, idx, nested);
+                }
+            }
+            else if (prefix)
+            {
+                StringBuffer name(prefix);
+                name.append(cur->name);
+                map.setValue(name, idx);
+                idx++;
+            }
+            else
+            {
+                map.setValue(cur->name, idx);
+                idx++;
+            }
+        }
+    }
+    MapStringTo<unsigned> map;
+};
+
+RtlRecord::RtlRecord(const RtlRecordTypeInfo & record, bool expandFields)
+: RtlRecord(record.fields, expandFields)  // delegated constructor
+{
+}
 
-RtlRecord::RtlRecord(const RtlRecordTypeInfo & record, bool expandFields) : fields(record.fields), originalFields(record.fields)
+RtlRecord::RtlRecord(const RtlFieldInfo * const *_fields, bool expandFields) : fields(_fields), originalFields(_fields), nameMap(nullptr)
 {
     //MORE: Does not cope with ifblocks.
     numVarFields = 0;
@@ -192,6 +258,7 @@ RtlRecord::~RtlRecord()
     delete [] fixedOffsets;
     delete [] whichVariableOffset;
     delete [] variableFieldIds;
+    delete nameMap;
 }
 
 
@@ -219,6 +286,31 @@ size32_t RtlRecord::getMinRecordSize() const
     return minSize;
 }
 
+static const FieldNameToFieldNumMap *setupNameMap(const RtlFieldInfo * const * fields, bool expand, std::atomic<const FieldNameToFieldNumMap *> &aNameMap)
+{
+    const FieldNameToFieldNumMap *lnameMap = new FieldNameToFieldNumMap(fields, expand);
+    const FieldNameToFieldNumMap *expected = nullptr;
+    if (aNameMap.compare_exchange_strong(expected, lnameMap))
+        return lnameMap;
+    else
+    {
+        // Other thread already set it while we were creating
+        delete lnameMap;
+        return expected;  // has been updated to the value set by other thread
+    }
+}
+
+unsigned RtlRecord::getFieldNum(const char *fieldName) const
+{
+    // NOTE: the nameMap field cannot be declared as atomic, since the class definition is included in generated
+    // code which is not (yet) compiled using C++11. If that changes then the reinterpret_cast can be removed.
+    std::atomic<const FieldNameToFieldNumMap *> &aNameMap = reinterpret_cast<std::atomic<const FieldNameToFieldNumMap *> &>(nameMap);
+    const FieldNameToFieldNumMap *useMap = aNameMap.load(std::memory_order_relaxed);
+    if (!useMap)
+        useMap = setupNameMap(originalFields, originalFields!=fields, aNameMap);
+    return useMap->lookup(fieldName);
+}
+
 //---------------------------------------------------------------------------------------------------------------------
 
 RtlRow::RtlRow(const RtlRecord & _info, const void * optRow, unsigned numOffsets, size_t * _variableOffsets) : info(_info), variableOffsets(_variableOffsets)
@@ -260,3 +352,142 @@ RtlDynRow::~RtlDynRow()
     delete [] variableOffsets;
 }
 
+//-----------------
+
+static const RtlRecord *setupRecordAccessor(const COutputMetaData &meta, bool expand, std::atomic<const RtlRecord *> &aRecordAccessor)
+{
+    const RtlRecord *lRecordAccessor = new RtlRecord(meta.queryTypeInfo()->queryFields(), expand);
+    const RtlRecord *expected = nullptr;
+    if (aRecordAccessor.compare_exchange_strong(expected, lRecordAccessor))
+        return lRecordAccessor;
+    else
+    {
+        // Other thread already set it while we were creating
+        delete lRecordAccessor;
+        return expected;  // has been updated to the value set by other thread
+    }
+}
+
+COutputMetaData::COutputMetaData()
+{
+    recordAccessor[0] = recordAccessor[1] = NULL;
+}
+
+COutputMetaData::~COutputMetaData()
+{
+    delete recordAccessor[0]; delete recordAccessor[1];
+}
+
+const RtlRecord *COutputMetaData::queryRecordAccessor(bool expand) const
+{
+    // NOTE: the recordAccessor field cannot be declared as atomic, since the class definition is included in generated
+    // code which is not (yet) compiled using C++11. If that changes then the reinterpret_cast can be removed.
+    std::atomic<const RtlRecord *> &aRecordAccessor = reinterpret_cast<std::atomic<const RtlRecord *> &>(recordAccessor[expand]);
+    const RtlRecord *useAccessor = aRecordAccessor.load(std::memory_order_relaxed);
+    if (!useAccessor)
+        useAccessor = setupRecordAccessor(*this, expand, aRecordAccessor);
+    return useAccessor;
+}
+
+class CVariableOutputRowSerializer : public COutputRowSerializer
+{
+public:
+    inline CVariableOutputRowSerializer(unsigned _activityId, IOutputMetaData * _meta) : COutputRowSerializer(_activityId) { meta = _meta; }
+
+    virtual void serialize(IRowSerializerTarget & out, const byte * self)
+    {
+        unsigned size = meta->getRecordSize(self);
+        out.put(size, self);
+    }
+
+protected:
+    IOutputMetaData * meta;
+};
+
+class ECLRTL_API CSimpleSourceRowPrefetcher : public ISourceRowPrefetcher, public RtlCInterface
+{
+public:
+    CSimpleSourceRowPrefetcher(IOutputMetaData & _meta, ICodeContext * _ctx, unsigned _activityId)
+    {
+        deserializer.setown(_meta.querySerializedDiskMeta()->createDiskDeserializer(_ctx, _activityId));
+        rowAllocator.setown(_ctx->getRowAllocator(&_meta, _activityId));
+    }
+
+    RTLIMPLEMENT_IINTERFACE
+
+    virtual void readAhead(IRowDeserializerSource & in)
+    {
+        RtlDynamicRowBuilder rowBuilder(rowAllocator);
+        size32_t len = deserializer->deserialize(rowBuilder, in);
+        rtlReleaseRow(rowBuilder.finalizeRowClear(len));
+    }
+
+protected:
+    Owned<IOutputRowDeserializer> deserializer;
+    Owned<IEngineRowAllocator> rowAllocator;
+};
+
+//---------------------------------------------------------------------------
+
+
+IOutputRowSerializer * COutputMetaData::createDiskSerializer(ICodeContext * ctx, unsigned activityId)
+{
+    return new CVariableOutputRowSerializer(activityId, this);
+}
+
+ISourceRowPrefetcher * COutputMetaData::createDiskPrefetcher(ICodeContext * ctx, unsigned activityId)
+{
+    ISourceRowPrefetcher * fetcher = defaultCreateDiskPrefetcher(ctx, activityId);
+    if (fetcher)
+        return fetcher;
+    //Worse case implementation using a deserialize
+    return new CSimpleSourceRowPrefetcher(*this, ctx, activityId);
+}
+
+ISourceRowPrefetcher *COutputMetaData::defaultCreateDiskPrefetcher(ICodeContext * ctx, unsigned activityId)
+{
+    if (getMetaFlags() & MDFneedserializedisk)
+        return querySerializedDiskMeta()->createDiskPrefetcher(ctx, activityId);
+    CSourceRowPrefetcher * fetcher = doCreateDiskPrefetcher(activityId);
+    if (fetcher)
+    {
+        fetcher->onCreate(ctx);
+        return fetcher;
+    }
+    return NULL;
+}
+
+IOutputRowSerializer *CFixedOutputMetaData::createDiskSerializer(ICodeContext * ctx, unsigned activityId)
+{
+    return new CFixedOutputRowSerializer(activityId, fixedSize);
+}
+
+IOutputRowDeserializer *CFixedOutputMetaData::createDiskDeserializer(ICodeContext * ctx, unsigned activityId)
+{
+    return new CFixedOutputRowDeserializer(activityId, fixedSize);
+}
+
+ISourceRowPrefetcher *CFixedOutputMetaData::createDiskPrefetcher(ICodeContext * ctx, unsigned activityId)
+{
+    ISourceRowPrefetcher * fetcher = defaultCreateDiskPrefetcher(ctx, activityId);
+    if (fetcher)
+        return fetcher;
+    return new CFixedSourceRowPrefetcher(activityId, fixedSize);
+}
+
+IOutputRowSerializer * CActionOutputMetaData::createDiskSerializer(ICodeContext * ctx, unsigned activityId)
+{
+    return new CFixedOutputRowSerializer(activityId, 0);
+}
+
+IOutputRowDeserializer * CActionOutputMetaData::createDiskDeserializer(ICodeContext * ctx, unsigned activityId)
+{
+    return new CFixedOutputRowDeserializer(activityId, 0);
+}
+
+ISourceRowPrefetcher * CActionOutputMetaData::createDiskPrefetcher(ICodeContext * ctx, unsigned activityId)
+{
+    return new CFixedSourceRowPrefetcher(activityId, 0);
+}
+
+

+ 250 - 2
rtl/eclrtl/rtlrecord.hpp

@@ -25,10 +25,164 @@
 #endif
 
 #include "eclrtl_imp.hpp"
+#include "rtlds_imp.hpp"
 #include "rtlfield.hpp"
 
+//---------------------------------------------------------------------------
+// Record size handling.
+
+class CGlobalHelperClass : public RtlCInterface
+{
+public:
+    inline CGlobalHelperClass(unsigned _activityId) { activityId = _activityId; ctx = NULL; }
+
+    inline void onCreate(ICodeContext * _ctx) { ctx = _ctx; }
+
+protected:
+    ICodeContext * ctx;
+    unsigned activityId;
+
+};
+
+class COutputRowSerializer : implements IOutputRowSerializer, public CGlobalHelperClass
+{
+public:
+    inline COutputRowSerializer(unsigned _activityId) : CGlobalHelperClass(_activityId) { }
+    RTLIMPLEMENT_IINTERFACE
+
+    virtual void serialize(IRowSerializerTarget & out, const byte * self) = 0;
+};
+
+
+class COutputRowDeserializer : implements IOutputRowDeserializer, public RtlCInterface
+{
+public:
+    inline COutputRowDeserializer(unsigned _activityId) { activityId = _activityId; ctx = NULL; }
+    RTLIMPLEMENT_IINTERFACE
+
+    inline void onCreate(ICodeContext * _ctx) { ctx = _ctx; }
+
+    virtual size32_t deserialize(ARowBuilder & rowBuilder, IRowDeserializerSource & in) = 0;
+
+protected:
+    ICodeContext * ctx;
+    unsigned activityId;
+};
+
+
+class CSourceRowPrefetcher : implements ISourceRowPrefetcher, public RtlCInterface
+{
+public:
+    inline CSourceRowPrefetcher(unsigned _activityId) { activityId = _activityId; ctx = NULL; }
+    RTLIMPLEMENT_IINTERFACE
+
+    inline void onCreate(ICodeContext * _ctx) { ctx = _ctx; }
+
+    virtual void readAhead(IRowDeserializerSource & in) = 0;
+
+protected:
+    ICodeContext * ctx;
+    unsigned activityId;
+};
+
+
+class CFixedOutputRowSerializer : public COutputRowSerializer
+{
+public:
+    inline CFixedOutputRowSerializer(unsigned _activityId, unsigned _fixedSize) : COutputRowSerializer(_activityId) { fixedSize = _fixedSize; }
+
+    virtual void serialize(IRowSerializerTarget & out, const byte * self) { out.put(fixedSize, self); }
+
+protected:
+    size32_t fixedSize;
+};
+
+class CFixedOutputRowDeserializer : public COutputRowDeserializer
+{
+public:
+    inline CFixedOutputRowDeserializer(unsigned _activityId, unsigned _fixedSize) : COutputRowDeserializer(_activityId) { fixedSize = _fixedSize; }
+
+    virtual size32_t deserialize(ARowBuilder & rowBuilder, IRowDeserializerSource & in) { in.read(fixedSize, rowBuilder.getSelf()); return fixedSize; }
+
+protected:
+    size32_t fixedSize;
+};
+
+class CFixedSourceRowPrefetcher : public CSourceRowPrefetcher
+{
+public:
+    inline CFixedSourceRowPrefetcher(unsigned _activityId, unsigned _fixedSize) : CSourceRowPrefetcher(_activityId) { fixedSize = _fixedSize; }
+
+    virtual void readAhead(IRowDeserializerSource & in) { in.skip(fixedSize); }
+
+protected:
+    size32_t fixedSize;
+};
+
+//---------------------------------------------------------------------------
+
+class CXmlToRowTransformer : implements IXmlToRowTransformer, public CGlobalHelperClass
+{
+public:
+    inline CXmlToRowTransformer(unsigned _activityId) : CGlobalHelperClass(_activityId) {}
+    RTLIMPLEMENT_IINTERFACE
+
+};
+
+//---------------------------------------------------------------------------
+// Record size handling.
+
+class CNormalizeChildIterator : implements INormalizeChildIterator, public RtlCInterface
+{
+public:
+    CNormalizeChildIterator(IOutputMetaData & _recordSize) : iter(0, NULL, _recordSize) {}
+    RTLIMPLEMENT_IINTERFACE
+
+    virtual byte * first(const void * parentRecord)         { init(parentRecord); return (byte *)iter.first(); }
+    virtual byte * next()                                   { return (byte *)iter.next(); }
+    virtual void init(const void * parentRecord) = 0;
+
+    inline void setDataset(size32_t len, const void * data) { iter.setDataset(len, data); }
+
+protected:
+    RtlVariableDatasetCursor    iter;
+};
+
+class CNormalizeLinkedChildIterator : implements INormalizeChildIterator, public RtlCInterface
+{
+public:
+    CNormalizeLinkedChildIterator() : iter(0, NULL) {}
+    RTLIMPLEMENT_IINTERFACE
+
+    virtual byte * first(const void * parentRecord)         { init(parentRecord); return (byte *)iter.first(); }
+    virtual byte * next()                                   { return (byte *)iter.next(); }
+    virtual void init(const void * parentRecord) = 0;
+
+    inline void setDataset(unsigned _numRows, byte * * _rows) { iter.setDataset(_numRows, _rows); }
+
+protected:
+    RtlSafeLinkedDatasetCursor  iter;
+};
+
+class CNormalizeStreamedChildIterator : implements INormalizeChildIterator, public RtlCInterface
+{
+public:
+    CNormalizeStreamedChildIterator() {}
+    RTLIMPLEMENT_IINTERFACE
+
+    virtual byte * first(const void * parentRecord)         { init(parentRecord); return (byte *)iter.first(); }
+    virtual byte * next()                                   { return (byte *)iter.next(); }
+    virtual void init(const void * parentRecord) = 0;
+
+    inline void setDataset(IRowStream * _streamed) { iter.init(_streamed); }
+
+protected:
+    RtlStreamedDatasetCursor  iter;
+};
+
+
 //These classes provides a relatively efficient way to access fields within a variable length record structure.
-// Probably convert to an interface with various concrete implementations for varing degrees of complexity
+// Probably convert to an interface with various concrete implementations for varying degrees of complexity
 //
 // Complications:
 // * ifblocks
@@ -36,11 +190,14 @@
 // * alien data types
 //
 
+class FieldNameToFieldNumMap;
+
 struct ECLRTL_API RtlRecord
 {
 public:
     friend class RtlRow;
     RtlRecord(const RtlRecordTypeInfo & fields, bool expandFields);
+    RtlRecord(const RtlFieldInfo * const * fields, bool expandFields);
     ~RtlRecord();
 
     void calcRowOffsets(size_t * variableOffsets, const void * _row) const;
@@ -63,9 +220,11 @@ public:
 
     virtual size32_t getMinRecordSize() const;
 
+    inline unsigned getNumFields() const { return numFields; }
     inline unsigned getNumVarFields() const { return numVarFields; }
     inline const RtlTypeInfo * queryType(unsigned field) const { return fields[field]->type; }
-
+    inline const char * queryName(unsigned field) const { return fields[field]->name; }
+    unsigned getFieldNum(const char *fieldName) const;
 protected:
     size_t * fixedOffsets;        // fixed portion of the field offsets + 1 extra
     unsigned * whichVariableOffset;// which variable offset should be added to the fixed
@@ -74,6 +233,7 @@ protected:
     unsigned numVarFields;
     const RtlFieldInfo * const * fields;
     const RtlFieldInfo * const * originalFields;
+    mutable const FieldNameToFieldNumMap *nameMap;
 };
 
 class ECLRTL_API RtlRow
@@ -148,4 +308,92 @@ protected:
     RtlRecord offsetInformation;
 };
 
+class CSourceRowPrefetcher;
+
+class ECLRTL_API COutputMetaData : implements IOutputMetaData, public RtlCInterface
+{
+public:
+    RTLIMPLEMENT_IINTERFACE
+    COutputMetaData();
+    ~COutputMetaData();
+
+    virtual void toXML(const byte * self, IXmlWriter & out) {
+                                                                const RtlTypeInfo * type = queryTypeInfo();
+                                                                if (type)
+                                                                {
+                                                                    RtlFieldStrInfo dummyField("",NULL,type);
+                                                                    type->toXML(self, self, &dummyField, out);
+                                                                }
+                                                            }
+    virtual unsigned getVersion() const                     { return OUTPUTMETADATA_VERSION; }
+    virtual unsigned getMetaFlags()                         { return MDFhasserialize|MDFhasxml; }
+
+    virtual void destruct(byte * self)                      {}
+    virtual IOutputMetaData * querySerializedDiskMeta()    { return this; }
+    virtual IOutputRowSerializer * createDiskSerializer(ICodeContext * ctx, unsigned activityId);
+    virtual ISourceRowPrefetcher * createDiskPrefetcher(ICodeContext * ctx, unsigned activityId);
+    //Default internal serializers are the same as the disk versions
+    virtual IOutputRowSerializer * createInternalSerializer(ICodeContext * ctx, unsigned activityId)
+    {
+        return createDiskSerializer(ctx, activityId);
+    }
+    virtual IOutputRowDeserializer * createInternalDeserializer(ICodeContext * ctx, unsigned activityId)
+    {
+        return createDiskDeserializer(ctx, activityId);
+    }
+    virtual void walkIndirectMembers(const byte * self, IIndirectMemberVisitor & visitor) { }
+    virtual IOutputMetaData * queryChildMeta(unsigned i) { return NULL; }
+
+    virtual const RtlRecord *queryRecordAccessor(bool expand) const;
+
+protected:
+    //This is the prefetch function that is actually generated by the code generator
+    virtual CSourceRowPrefetcher * doCreateDiskPrefetcher(unsigned activityId) { return NULL; }
+
+    ISourceRowPrefetcher * defaultCreateDiskPrefetcher(ICodeContext * ctx, unsigned activityId);
+    mutable RtlRecord *recordAccessor[2];
+};
+
+class ECLRTL_API CFixedOutputMetaData : public COutputMetaData
+{
+public:
+    CFixedOutputMetaData(size32_t _fixedSize)               { fixedSize = _fixedSize; }
+
+    virtual size32_t getRecordSize(const void *rec)         { return fixedSize; }
+    virtual size32_t getMinRecordSize() const               { return fixedSize; }
+    virtual size32_t getFixedSize() const                   { return fixedSize; }
+
+    virtual IOutputRowSerializer * createDiskSerializer(ICodeContext * ctx, unsigned activityId);
+    virtual IOutputRowDeserializer * createDiskDeserializer(ICodeContext * ctx, unsigned activityId);
+    virtual ISourceRowPrefetcher * createDiskPrefetcher(ICodeContext * ctx, unsigned activityId);
+
+protected:
+    size32_t fixedSize;
+};
+
+class ECLRTL_API CVariableOutputMetaData : public COutputMetaData
+{
+public:
+    CVariableOutputMetaData(size32_t _minSize) : minSize(_minSize) { }
+
+    virtual size32_t getMinRecordSize() const               { return minSize; }
+    virtual size32_t getFixedSize() const                   { return 0; }  // is variable
+
+protected:
+    size32_t minSize;
+};
+
+class ECLRTL_API CActionOutputMetaData : public COutputMetaData
+{
+public:
+    virtual size32_t getRecordSize(const void *)            { return 0; }
+    virtual size32_t getMinRecordSize() const               { return 0; }
+    virtual size32_t getFixedSize() const                   { return 0; }  // is pseudo-variable
+    virtual void toXML(const byte * self, IXmlWriter & out) { }
+    virtual IOutputRowSerializer * createDiskSerializer(ICodeContext * ctx, unsigned activityId);
+    virtual IOutputRowDeserializer * createDiskDeserializer(ICodeContext * ctx, unsigned activityId);
+    virtual ISourceRowPrefetcher * createDiskPrefetcher(ICodeContext * ctx, unsigned activityId);
+};
+
+
 #endif

+ 3 - 0
rtl/include/eclhelper.hpp

@@ -450,6 +450,8 @@ interface IIndirectMemberVisitor
     //MORE: add new functions if anything else is implemented out of line (e.g., strings)
 };
 
+class RtlRecord;
+
 interface IOutputMetaData : public IRecordSize
 {
     inline bool isGrouped()                 { return (getMetaFlags() & MDFgrouped) != 0; }
@@ -473,6 +475,7 @@ interface IOutputMetaData : public IRecordSize
     virtual void process(const byte * self, IFieldProcessor & target, unsigned from, unsigned to) {}            // from and to are *hints* for the range of fields to call through with
     virtual void walkIndirectMembers(const byte * self, IIndirectMemberVisitor & visitor) = 0;
     virtual IOutputMetaData * queryChildMeta(unsigned i) = 0;
+    virtual const RtlRecord *queryRecordAccessor(bool expand) const { return NULL; }
 };
 
 

+ 5 - 299
rtl/include/eclhelper_base.hpp

@@ -18,6 +18,11 @@
 #ifndef ECLHELPER_BASE_HPP
 #define ECLHELPER_BASE_HPP
 
+// NOTE: this file must not be included OTHER than from generated code, unless inside a namespace,
+// since it is important that the correct implementation of selectInterface (the one from the generated DLL) is used.
+// Only the base classes for Activity helpers - CHThorArg and derived classes - should be included in this file.
+// All code should be implemented inline.
+
 //Don't #include any files here - because sometimes included inside a namespace, and that generates confusion.
 
 /*
@@ -28,305 +33,6 @@ Doesn't include jlib.hpp yet, so different implementation of CInterface (RtlCInt
 */
 
 //---------------------------------------------------------------------------
-// Record size handling.
-
-class CGlobalHelperClass : public RtlCInterface
-{
-public:
-    inline CGlobalHelperClass(unsigned _activityId) { activityId = _activityId; ctx = NULL; }
-
-    inline void onCreate(ICodeContext * _ctx) { ctx = _ctx; }
-
-protected:
-    ICodeContext * ctx;
-    unsigned activityId;
-
-};
-
-class COutputRowSerializer : implements IOutputRowSerializer, public CGlobalHelperClass
-{
-public:
-    inline COutputRowSerializer(unsigned _activityId) : CGlobalHelperClass(_activityId) { }
-    RTLIMPLEMENT_IINTERFACE
-
-    virtual void serialize(IRowSerializerTarget & out, const byte * self) = 0;
-};
-
-
-class COutputRowDeserializer : implements IOutputRowDeserializer, public RtlCInterface
-{
-public:
-    inline COutputRowDeserializer(unsigned _activityId) { activityId = _activityId; ctx = NULL; }
-    RTLIMPLEMENT_IINTERFACE
-
-    inline void onCreate(ICodeContext * _ctx) { ctx = _ctx; }
-
-    virtual size32_t deserialize(ARowBuilder & rowBuilder, IRowDeserializerSource & in) = 0;
-
-protected:
-    ICodeContext * ctx;
-    unsigned activityId;
-};
-
-
-class CSourceRowPrefetcher : implements ISourceRowPrefetcher, public RtlCInterface
-{
-public:
-    inline CSourceRowPrefetcher(unsigned _activityId) { activityId = _activityId; ctx = NULL; }
-    RTLIMPLEMENT_IINTERFACE
-
-    inline void onCreate(ICodeContext * _ctx) { ctx = _ctx; }
-
-    virtual void readAhead(IRowDeserializerSource & in) = 0;
-
-protected:
-    ICodeContext * ctx;
-    unsigned activityId;
-};
-
-
-class CFixedOutputRowSerializer : public COutputRowSerializer
-{
-public:
-    inline CFixedOutputRowSerializer(unsigned _activityId, unsigned _fixedSize) : COutputRowSerializer(_activityId) { fixedSize = _fixedSize; }
-
-    virtual void serialize(IRowSerializerTarget & out, const byte * self) { out.put(fixedSize, self); }
-
-protected:
-    size32_t fixedSize;
-};
-
-class CFixedOutputRowDeserializer : public COutputRowDeserializer
-{
-public:
-    inline CFixedOutputRowDeserializer(unsigned _activityId, unsigned _fixedSize) : COutputRowDeserializer(_activityId) { fixedSize = _fixedSize; }
-
-    virtual size32_t deserialize(ARowBuilder & rowBuilder, IRowDeserializerSource & in) { in.read(fixedSize, rowBuilder.getSelf()); return fixedSize; }
-
-protected:
-    size32_t fixedSize;
-};
-
-class CFixedSourceRowPrefetcher : public CSourceRowPrefetcher
-{
-public:
-    inline CFixedSourceRowPrefetcher(unsigned _activityId, unsigned _fixedSize) : CSourceRowPrefetcher(_activityId) { fixedSize = _fixedSize; }
-
-    virtual void readAhead(IRowDeserializerSource & in) { in.skip(fixedSize); }
-
-protected:
-    size32_t fixedSize;
-};
-
-class CVariableOutputRowSerializer : public COutputRowSerializer
-{
-public:
-    inline CVariableOutputRowSerializer(unsigned _activityId, IOutputMetaData * _meta) : COutputRowSerializer(_activityId) { meta = _meta; }
-
-    virtual void serialize(IRowSerializerTarget & out, const byte * self)
-    {
-        unsigned size = meta->getRecordSize(self);
-        out.put(size, self); 
-    }
-
-protected:
-    IOutputMetaData * meta;
-};
-
-class COutputMetaData : implements IOutputMetaData, public RtlCInterface
-{
-public:
-    RTLIMPLEMENT_IINTERFACE
-
-    virtual void toXML(const byte * self, IXmlWriter & out) { 
-                                                                const RtlTypeInfo * type = queryTypeInfo();
-                                                                if (type)
-                                                                {
-                                                                    RtlFieldStrInfo dummyField("",NULL,type);
-                                                                    type->toXML(self, self, &dummyField, out);
-                                                                }
-                                                            }
-    virtual unsigned getVersion() const                     { return OUTPUTMETADATA_VERSION; }
-    virtual unsigned getMetaFlags()                         { return MDFhasserialize|MDFhasxml; }
-
-    virtual void destruct(byte * self)                      {}
-    virtual IOutputMetaData * querySerializedDiskMeta()    { return this; }
-    virtual IOutputRowSerializer * createDiskSerializer(ICodeContext * ctx, unsigned activityId)
-    {
-        return new CVariableOutputRowSerializer(activityId, this);
-    }
-    virtual ISourceRowPrefetcher * createDiskPrefetcher(ICodeContext * ctx, unsigned activityId)
-    {
-        ISourceRowPrefetcher * fetcher = defaultCreateDiskPrefetcher(ctx, activityId);
-        if (fetcher)
-            return fetcher;
-        //Worse case implementation using a deserialize
-        return new CSimpleSourceRowPrefetcher(*this, ctx, activityId);
-    }
-    //Default internal serializers are the same as the disk versions
-    virtual IOutputRowSerializer * createInternalSerializer(ICodeContext * ctx, unsigned activityId)
-    {
-        return createDiskSerializer(ctx, activityId);
-    }
-    virtual IOutputRowDeserializer * createInternalDeserializer(ICodeContext * ctx, unsigned activityId)
-    {
-        return createDiskDeserializer(ctx, activityId);
-    }
-    virtual void walkIndirectMembers(const byte * self, IIndirectMemberVisitor & visitor) { }
-    virtual IOutputMetaData * queryChildMeta(unsigned i) { return NULL; }
-
-protected:
-    //This is the prefetch function that is actually generated by the code generator
-    virtual CSourceRowPrefetcher * doCreateDiskPrefetcher(unsigned activityId) { return NULL; }
-
-    inline ISourceRowPrefetcher * defaultCreateDiskPrefetcher(ICodeContext * ctx, unsigned activityId)
-    {
-        if (getMetaFlags() & MDFneedserializedisk)
-            return querySerializedDiskMeta()->createDiskPrefetcher(ctx, activityId);
-        CSourceRowPrefetcher * fetcher = doCreateDiskPrefetcher(activityId);
-        if (fetcher)
-        {
-            fetcher->onCreate(ctx);
-            return fetcher;
-        }
-        return NULL;
-    }
-};
-
-class CFixedOutputMetaData : public COutputMetaData
-{
-public:
-    CFixedOutputMetaData(size32_t _fixedSize)               { fixedSize = _fixedSize; }
-
-    virtual size32_t getRecordSize(const void *rec)         { return fixedSize; }
-    virtual size32_t getMinRecordSize() const               { return fixedSize; }
-    virtual size32_t getFixedSize() const                   { return fixedSize; }
-
-    virtual IOutputRowSerializer * createDiskSerializer(ICodeContext * ctx, unsigned activityId)
-    {
-        return new CFixedOutputRowSerializer(activityId, fixedSize);
-    }
-    virtual IOutputRowDeserializer * createDiskDeserializer(ICodeContext * ctx, unsigned activityId)
-    {
-        return new CFixedOutputRowDeserializer(activityId, fixedSize);
-    }
-    virtual ISourceRowPrefetcher * createDiskPrefetcher(ICodeContext * ctx, unsigned activityId)
-    {
-        ISourceRowPrefetcher * fetcher = defaultCreateDiskPrefetcher(ctx, activityId);
-        if (fetcher)
-            return fetcher;
-        return new CFixedSourceRowPrefetcher(activityId, fixedSize);
-    }
-
-protected:
-    size32_t fixedSize;
-};
-
-class CVariableOutputMetaData : public COutputMetaData
-{
-public:
-    CVariableOutputMetaData(size32_t _minSize) : minSize(_minSize) { }
-
-    virtual size32_t getMinRecordSize() const               { return minSize; }
-    virtual size32_t getFixedSize() const                   { return 0; }  // is variable
-
-protected:
-    size32_t minSize;
-};
-
-class CActionOutputMetaData : public COutputMetaData
-{
-public:
-    virtual size32_t getRecordSize(const void *)            { return 0; }
-    virtual size32_t getMinRecordSize() const               { return 0; }
-    virtual size32_t getFixedSize() const                   { return 0; }  // is pseudo-variable
-    virtual void toXML(const byte * self, IXmlWriter & out) { }
-    virtual IOutputRowSerializer * createDiskSerializer(ICodeContext * ctx, unsigned activityId)
-    {
-        return new CFixedOutputRowSerializer(activityId, 0);
-    }
-    virtual IOutputRowDeserializer * createDiskDeserializer(ICodeContext * ctx, unsigned activityId)
-    {
-        return new CFixedOutputRowDeserializer(activityId, 0);
-    }
-    virtual ISourceRowPrefetcher * createDiskPrefetcher(ICodeContext * ctx, unsigned activityId)
-    {
-        return new CFixedSourceRowPrefetcher(activityId, 0);
-    }
-};
-
-//---------------------------------------------------------------------------
-
-class CXmlToRowTransformer : implements IXmlToRowTransformer, public CGlobalHelperClass
-{
-public:
-    inline CXmlToRowTransformer(unsigned _activityId) : CGlobalHelperClass(_activityId) {}
-    RTLIMPLEMENT_IINTERFACE
-
-};
-
-//---------------------------------------------------------------------------
-// Record size handling.
-
-class ThorHelper : public RtlCInterface
-{
-public:
-    ThorHelper()                                            { ctx = 0; }
-
-protected:
-    ICodeContext * ctx;
-};
-
-
-class CNormalizeChildIterator : implements INormalizeChildIterator, public RtlCInterface
-{
-public:
-    CNormalizeChildIterator(IOutputMetaData & _recordSize) : iter(0, NULL, _recordSize) {}
-    RTLIMPLEMENT_IINTERFACE
-
-    virtual byte * first(const void * parentRecord)         { init(parentRecord); return (byte *)iter.first(); }
-    virtual byte * next()                                   { return (byte *)iter.next(); }
-    virtual void init(const void * parentRecord) = 0;
-
-    inline void setDataset(size32_t len, const void * data) { iter.setDataset(len, data); }
-
-protected:
-    RtlVariableDatasetCursor    iter;
-};
-    
-class CNormalizeLinkedChildIterator : implements INormalizeChildIterator, public RtlCInterface
-{
-public:
-    CNormalizeLinkedChildIterator() : iter(0, NULL) {}
-    RTLIMPLEMENT_IINTERFACE
-
-    virtual byte * first(const void * parentRecord)         { init(parentRecord); return (byte *)iter.first(); }
-    virtual byte * next()                                   { return (byte *)iter.next(); }
-    virtual void init(const void * parentRecord) = 0;
-
-    inline void setDataset(unsigned _numRows, byte * * _rows) { iter.setDataset(_numRows, _rows); }
-
-protected:
-    RtlSafeLinkedDatasetCursor  iter;
-};
-    
-class CNormalizeStreamedChildIterator : implements INormalizeChildIterator, public RtlCInterface
-{
-public:
-    CNormalizeStreamedChildIterator() {}
-    RTLIMPLEMENT_IINTERFACE
-
-    virtual byte * first(const void * parentRecord)         { init(parentRecord); return (byte *)iter.first(); }
-    virtual byte * next()                                   { return (byte *)iter.next(); }
-    virtual void init(const void * parentRecord) = 0;
-
-    inline void setDataset(IRowStream * _streamed) { iter.init(_streamed); }
-
-protected:
-    RtlStreamedDatasetCursor  iter;
-};
-
-//---------------------------------------------------------------------------
 
 class CThorArg : public RtlCInterface
 {

+ 2 - 2
testing/regress/ecl/serializetypes.ecl

@@ -18,8 +18,8 @@
 //Test serialization of various record/dataset types, including default values
 
 s := service
-   string dumpRecordType(row val) : eclrtl,pure,library='eclrtl',entrypoint='dumpRecordType',passParameterMeta(true),fold;
-   string dumpRecordTypeNF(row val) : eclrtl,pure,library='eclrtl',entrypoint='dumpRecordType',passParameterMeta(true);
+   string dumpRecordType(virtual record val) : eclrtl,pure,library='eclrtl',entrypoint='dumpRecordType',fold;
+   string dumpRecordTypeNF(virtual record val) : eclrtl,pure,library='eclrtl',entrypoint='dumpRecordType';
 end;
 
 rr := record

+ 2 - 4
thorlcr/thorutil/thormisc.cpp

@@ -46,12 +46,10 @@
 #include "eclrtl_imp.hpp"
 #include "rtlread_imp.hpp"
 #include "rtlfield.hpp"
+#include "rtlrecord.hpp"
 #include "rtlds_imp.hpp"
 #include "rmtfile.hpp"
 
-namespace thormisc {  // Make sure we can't clash with generated versions or version check mechanism fails.
- #include "eclhelper_base.hpp" 
-}
 
 #define SDS_LOCK_TIMEOUT 30000
 
@@ -1133,7 +1131,7 @@ bool CFifoFileCache::isAvailable(const char *filename)
 IOutputMetaData *createFixedSizeMetaData(size32_t sz)
 {
     // sure if this allowed or is cheating!
-    return new thormisc::CFixedOutputMetaData(sz);
+    return new CFixedOutputMetaData(sz);
 }