瀏覽代碼

HPCC-13588 Fix bug in generated code for index containing datasets inside rows

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday 10 年之前
父節點
當前提交
bea4d0016f
共有 4 個文件被更改,包括 93 次插入4 次删除
  1. 39 0
      ecl/hql/hqlexpr.cpp
  2. 8 4
      ecl/hqlcpp/hqlsource.cpp
  3. 40 0
      testing/regress/ecl/issue13588.ecl
  4. 6 0
      testing/regress/ecl/key/issue13588.xml

+ 39 - 0
ecl/hql/hqlexpr.cpp

@@ -12342,6 +12342,34 @@ IHqlExpression * ensureActiveRow(IHqlExpression * expr)
     return createRow(no_activerow, LINK(expr->queryNormalizedSelector()));
 }
 
+static void ensureSerialized(HqlExprArray & assigns, IHqlExpression *transform, IHqlExpression * srcRecord, IHqlExpression * tgtRecord, IAtom * serialForm)
+{
+    OwnedHqlExpr childSelf = createSelector(no_self, tgtRecord, NULL);
+    ForEachChild(i, srcRecord)
+    {
+        IHqlExpression * src = srcRecord->queryChild(i);
+        IHqlExpression * tgt = tgtRecord->queryChild(i);
+        dbgassertex(src->getOperator() == tgt->getOperator());
+        switch (src->getOperator())
+        {
+        case no_field:
+            {
+                OwnedHqlExpr  match = getExtractSelect(transform, src, false);
+                assertex(match);
+                OwnedHqlExpr lhs = createSelectExpr(LINK(childSelf), LINK(tgt));
+                assigns.append(*createAssign(lhs.getClear(), ensureSerialized(match, serialForm)));
+                break;
+            }
+        case no_record:
+            ensureSerialized(assigns, transform, src, tgt, serialForm);
+            break;
+        case no_ifblock:
+            ensureSerialized(assigns, transform, src->queryChild(1), tgt->queryChild(1), serialForm);
+            break;
+        }
+    }
+}
+
 IHqlExpression * ensureSerialized(IHqlExpression * expr, IAtom * serialForm)
 {
     ITypeInfo * type = expr->queryType();
@@ -12349,6 +12377,17 @@ IHqlExpression * ensureSerialized(IHqlExpression * expr, IAtom * serialForm)
     if (type == serialType)
         return LINK(expr);
 
+    if (expr->getOperator() == no_createrow)
+    {
+        IHqlExpression * serialRecord = queryRecord(serialType);
+        IHqlExpression * exprRecord = expr->queryRecord();
+        IHqlExpression * transform = expr->queryChild(0);
+        HqlExprArray assigns;
+        ensureSerialized(assigns, transform, exprRecord, serialRecord, serialForm);
+        OwnedHqlExpr newTransform = createValue(no_transform, makeTransformType(serialRecord->getType()), assigns);
+        return createRow(no_createrow, newTransform.getClear());
+    }
+
     HqlExprArray args;
     args.append(*LINK(expr));
     args.append(*createAttribute(serialForm));

+ 8 - 4
ecl/hqlcpp/hqlsource.cpp

@@ -410,9 +410,13 @@ static void createPhysicalLogicalAssigns(HqlExprArray & assigns, IHqlExpression
                 {
                     IHqlExpression * curPhysical = nextDiskField(diskRecord, diskIndex);
                     OwnedHqlExpr physicalSelect = createSelectExpr(LINK(diskDataset), LINK(curPhysical));
-                    if (cur->isDatarow() && !cur->hasAttribute(blobAtom) && !isInPayload())
+                    if (cur->isDatarow() && !cur->hasAttribute(blobAtom) && (!isInPayload() || (physicalSelect->queryType() != target->queryType())))
                     {
-                        createPhysicalLogicalAssigns(assigns, target, curPhysical->queryRecord(), cur->queryRecord(), physicalSelect, allowTranslate, NotFound);
+                        HqlExprArray subassigns;
+                        OwnedHqlExpr childSelf = createSelector(no_self, cur, NULL);
+                        createPhysicalLogicalAssigns(subassigns, childSelf, curPhysical->queryRecord(), cur->queryRecord(), physicalSelect, false, NotFound);
+                        OwnedHqlExpr transform = createValue(no_transform, makeTransformType(cur->queryRecord()->getType()), subassigns);
+                        newValue.setown(createRow(no_createrow, transform.getClear()));
                     }
                     else
                         newValue.setown(convertIndexPhysical2LogicalValue(cur, physicalSelect, allowTranslate));
@@ -500,10 +504,10 @@ static IHqlExpression * createPhysicalIndexRecord(HqlMapTransformer & mapper, IH
             {
                 //This should support other non serialized formats.  E.g., link counted strings. 
                 //Simplest would be to move getSerializedForm code + call that first.
-                if (cur->hasAttribute(_linkCounted_Atom))
+                if (cur->hasAttribute(_linkCounted_Atom) || cur->isDatarow())
                 {
                     newField = getSerializedForm(cur, diskAtom);
-                    assertex(newField != cur);
+                    assertex(newField != cur || cur->isDatarow());
                 }
                 else
                 {

+ 40 - 0
testing/regress/ecl/issue13588.ecl

@@ -0,0 +1,40 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+
+xRec := RECORD
+    integer x;
+END;
+
+idRecord := RECORD
+    integer         id;
+    string          name;
+    DATASET(xRec)   x;
+END;
+
+rowRecord := RECORD
+    integer id;
+    idRecord r;
+END;
+
+ds := DATASET([
+        {1,{2,'gavin',[{1},{2}]}},
+        {2,{3,'john',[{-1},{-5}]}}], rowRecord);
+
+i := INDEX(ds, { id }, { ds }, 'REGRESS::TEMP::ISSUE13588');
+BUILD(i,OVERWRITE);
+OUTPUT(i,OVERWRITE);

+ 6 - 0
testing/regress/ecl/key/issue13588.xml

@@ -0,0 +1,6 @@
+<Dataset name='Result 1'>
+</Dataset>
+<Dataset name='Result 2'>
+ <Row><id>1</id><r><id>2</id><name>gavin</name><x><Row><x>1</x></Row><Row><x>2</x></Row></x></r><__internal_fpos__>0</__internal_fpos__></Row>
+ <Row><id>2</id><r><id>3</id><name>john</name><x><Row><x>-1</x></Row><Row><x>-5</x></Row></x></r><__internal_fpos__>0</__internal_fpos__></Row>
+</Dataset>