浏览代码

Merge pull request #14127 from ghalliday/issue24685

HPCC-24685 Disable remote index reads for signed integer key fields

Reviewed-By: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 4 年之前
父节点
当前提交
3acd0129e7
共有 4 个文件被更改,包括 64 次插入1 次删除
  1. 39 0
      rtl/eclrtl/rtlfield.cpp
  2. 2 0
      rtl/eclrtl/rtlfield.hpp
  3. 21 0
      rtl/eclrtl/rtlnktest.cpp
  4. 2 1
      thorlcr/activities/indexread/thindexreadslave.cpp

+ 39 - 0
rtl/eclrtl/rtlfield.cpp

@@ -3192,6 +3192,45 @@ extern bool ECLRTL_API hasTrailingFileposition(const RtlTypeInfo * type)
     return false;
 }
 
+//Does the field list contain a keyed int?  We are not interested in fields inside child datasets.
+//And keyed fields cannot exist within ifblocks.
+static bool containsKeyedSignedInt(const RtlFieldInfo * const * fields)
+{
+    if (!*fields)
+        return false;
+    while (*fields)
+    {
+        const RtlTypeInfo * type = (*fields)->type;
+        if (type->getType() == type_keyedint)
+        {
+            const RtlTypeInfo * baseType = type->queryChildType();
+            if (baseType->isSigned() && (baseType->getType() == type_int))
+                return true;
+        }
+        else if (type->getType() == type_record)
+        {
+            const RtlRecordTypeInfo * record = static_cast<const RtlRecordTypeInfo *>(type);
+            if (containsKeyedSignedInt(record->fields))
+                return true;
+        }
+        fields++;
+    }
+    return false;
+}
+
+extern bool ECLRTL_API containsKeyedSignedInt(const RtlTypeInfo * type)
+{
+    switch (type->getType())
+    {
+    case type_record:
+    {
+        const RtlRecordTypeInfo * record = static_cast<const RtlRecordTypeInfo *>(type);
+        return containsKeyedSignedInt(record->fields);
+    }
+    }
+    return false;
+}
+
 //-------------------------------------------------------------------------------------------------------------------
 
 size32_t RtlRecordTypeInfo::getMinSize() const

+ 2 - 0
rtl/eclrtl/rtlfield.hpp

@@ -752,6 +752,8 @@ extern int ECLRTL_API compareFields(const RtlFieldInfo * const * cur, const byte
 extern unsigned ECLRTL_API hashFields(const RtlFieldInfo * const * cur, const byte *self, unsigned inhash, bool excludePayload = false);
 extern bool ECLRTL_API hasTrailingFileposition(const RtlFieldInfo * const * fields);
 extern bool ECLRTL_API hasTrailingFileposition(const RtlTypeInfo * type);
+extern bool ECLRTL_API containsKeyedSignedInt(const RtlTypeInfo * type);
+
 extern size32_t translateScalar(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, const RtlTypeInfo &destType, const RtlTypeInfo &sourceType, const byte *source);
 
 #endif

+ 21 - 0
rtl/eclrtl/rtlnktest.cpp

@@ -311,6 +311,10 @@ protected:
     {
         RtlStringTypeInfo str1(type_string, 1);
         RtlIntTypeInfo int2(type_int, 2);
+        RtlIntTypeInfo int8(type_int, 8);
+        RtlSwapIntTypeInfo swapint2(type_int, 2);
+        RtlSwapIntTypeInfo swapint8(type_int, 8);
+        RtlKeyedIntTypeInfo keyedint8(type_keyedint, 8, &swapint8);
         RtlStringTypeInfo strx(type_string|RFTMunknownsize, 0);
         RtlUtf8TypeInfo utf8(type_utf8|RFTMunknownsize, 0, nullptr);
         testSerialize(int2, "[123]");
@@ -323,6 +327,23 @@ protected:
         testSerialize(int2, "(123,234),(456,567)");
         testSerialize(int2, "(456,567),(123,234)", "(123,234),(456,567)");
 
+        testSerialize(swapint2, "[123]");
+        testSerialize(swapint2, "(123,234]");
+        testSerialize(swapint2, "[123,234)");
+        testSerialize(swapint2, "(123,234)");
+        testSerialize(swapint2, "(,234)");
+        testSerialize(swapint2, "(128,)");
+        testSerialize(swapint2, "(,)");
+        testSerialize(swapint2, "(123,234),(456,567)");
+        testSerialize(swapint2, "(456,567),(123,234)", "(123,234),(456,567)");
+
+        testSerialize(int8, "[9223372036854775807]");
+        testSerialize(int8, "[-9223372036854775808]");
+        testSerialize(swapint8, "[9223372036854775807]");
+        testSerialize(swapint8, "[-9223372036854775808]");
+        testSerialize(keyedint8, "[10]");
+        testSerialize(keyedint8, "[-10]");
+
         testSerialize(str1, "['A']");
         testSerialize(str1, "[',']");
         testSerialize(str1, "['\\'']");

+ 2 - 1
thorlcr/activities/indexread/thindexreadslave.cpp

@@ -173,7 +173,8 @@ public:
                     Owned<ITranslator> translator = getTranslators(part);
                     IOutputMetaData *actualFormat = translator ? &translator->queryActualFormat() : expectedFormat;
                     bool tryRemoteStream = actualFormat->queryTypeInfo()->canInterpret() && actualFormat->queryTypeInfo()->canSerialize() &&
-                                           projectedFormat->queryTypeInfo()->canInterpret() && projectedFormat->queryTypeInfo()->canSerialize();
+                                           projectedFormat->queryTypeInfo()->canInterpret() && projectedFormat->queryTypeInfo()->canSerialize() &&
+                                           !containsKeyedSignedInt(actualFormat->queryTypeInfo());
 
                     /* If part can potentially be remotely streamed, 1st check if any part is local,
                      * then try to remote stream, and otherwise failover to legacy remote access