Переглянути джерело

Merge pull request #4032 from ghalliday/issue8810

HPCC-8810 Generate an RtlDictionaryTypeInfo for dictionary fields

Reviewed-By: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 12 роки тому
батько
коміт
1bd8c86747
3 змінених файлів з 87 додано та 1 видалено
  1. 9 1
      ecl/hqlcpp/hqlhtcpp.cpp
  2. 68 0
      rtl/eclrtl/rtlfield.cpp
  3. 10 0
      rtl/eclrtl/rtlfield_imp.hpp

+ 9 - 1
ecl/hqlcpp/hqlhtcpp.cpp

@@ -3928,7 +3928,6 @@ unsigned HqlCppTranslator::buildRtlType(StringBuffer & instanceName, ITypeInfo *
                 fieldType |= RFTMlinkcounted;
             break;
         }
-    case type_dictionary:
     case type_table:
     case type_groupedtable:
         {
@@ -3939,6 +3938,15 @@ unsigned HqlCppTranslator::buildRtlType(StringBuffer & instanceName, ITypeInfo *
                 fieldType |= RFTMlinkcounted;
             break;
         }
+    case type_dictionary:
+        {
+            className.clear().append("RtlDictionaryTypeInfo");
+            arguments.append(",&");
+            childType = buildRtlType(arguments, ::queryRecordType(type));
+            if (hasLinkCountedModifier(type))
+                fieldType |= RFTMlinkcounted;
+            break;
+        }
     case type_set:
         className.clear().append("RtlSetTypeInfo");
         arguments.append(",&");

+ 68 - 0
rtl/eclrtl/rtlfield.cpp

@@ -848,6 +848,74 @@ size32_t RtlDatasetTypeInfo::toXML(const byte * self, const byte * selfrow, cons
 
 //-------------------------------------------------------------------------------------------------------------------
 
+size32_t RtlDictionaryTypeInfo::size(const byte * self, const byte * selfrow) const
+{
+    if (isLinkCounted())
+        return sizeof(size32_t) + sizeof(void * *);
+    return sizeof(size32_t) + rtlReadUInt4(self);
+}
+
+size32_t RtlDictionaryTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
+{
+    if (isLinkCounted())
+    {
+        if (target.processBeginDataset(field))
+        {
+            size32_t thisCount = rtlReadUInt4(self);
+            const byte * * rows = *reinterpret_cast<const byte * * const *>(self + sizeof(size32_t));
+            for (unsigned i= 0; i < thisCount; i++)
+            {
+                const byte * row = rows[i];
+                if (row)
+                    child->process(row, row, field, target);
+            }
+            target.processEndDataset(field);
+        }
+        return sizeof(size32_t) + sizeof(void * *);
+    }
+    else
+    {
+        //MORE: We could interpret serialized dictionaries if there was ever a need
+        UNIMPLEMENTED;
+    }
+}
+
+size32_t RtlDictionaryTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
+{
+    StringAttr outerTag;
+    if (hasOuterXPath(field))
+    {
+        queryNestedOuterXPath(outerTag, field);
+        target.outputBeginNested(outerTag, false);
+    }
+
+    unsigned thisSize;
+    if (isLinkCounted())
+    {
+        size32_t thisCount = rtlReadUInt4(self);
+        const byte * * rows = *reinterpret_cast<const byte * * const *>(self + sizeof(size32_t));
+        for (unsigned i= 0; i < thisCount; i++)
+        {
+            const byte * row = rows[i];
+            if (row)
+                child->toXML(row, row, field, target);
+        }
+        thisSize = sizeof(size32_t) + sizeof(void * *);
+    }
+    else
+    {
+        //MORE: We could interpret serialized dictionaries if there was ever a need
+        UNIMPLEMENTED;
+    }
+
+    if (outerTag)
+        target.outputEndNested(outerTag);
+
+    return thisSize;
+}
+
+//-------------------------------------------------------------------------------------------------------------------
+
 size32_t RtlIfBlockTypeInfo::size(const byte * self, const byte * selfrow) const 
 {
     if (getCondition(selfrow))

+ 10 - 0
rtl/eclrtl/rtlfield_imp.hpp

@@ -233,6 +233,16 @@ struct ECLRTL_API RtlDatasetTypeInfo : public RtlCompoundTypeInfo
 };
 
 
+struct ECLRTL_API RtlDictionaryTypeInfo : public RtlCompoundTypeInfo
+{
+    inline RtlDictionaryTypeInfo(unsigned _fieldType, unsigned _length, const RtlTypeInfo * _child) : RtlCompoundTypeInfo(_fieldType, _length, _child) {}
+
+    virtual size32_t size(const byte * self, const byte * selfrow) const;
+    virtual size32_t process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const;
+    virtual size32_t toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const;
+};
+
+
 struct ECLRTL_API RtlIfBlockTypeInfo : public RtlTypeInfoBase
 {
     inline RtlIfBlockTypeInfo(unsigned _fieldType, unsigned _length, const RtlFieldInfo * const * _fields) : RtlTypeInfoBase(_fieldType, _length), fields(_fields) {}