瀏覽代碼

Merge pull request #13065 from ghalliday/issue22939

HPCC-22939 Fix segment fault if library parameter is a row containing a child dataset

Reviewed-By: Shamser Ahmed <shamser.ahmed@lexisnexis.co.uk>
Reviewed-By: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 5 年之前
父節點
當前提交
4b02a93637

+ 3 - 1
ecl/hqlcpp/hqlhtcpp.cpp

@@ -15582,7 +15582,9 @@ ABoundActivity * HqlCppTranslator::doBuildActivityProject(BuildCtx & ctx, IHqlEx
 
 ABoundActivity * HqlCppTranslator::doBuildActivitySerialize(BuildCtx & ctx, IHqlExpression * expr)
 {
-    IHqlExpression * dataset = expr->queryChild(0);
+    LinkedHqlExpr dataset = expr->queryChild(0);
+    if (dataset->isDatarow())
+        dataset.setown(createDatasetFromRow(LINK(dataset)));
     bool serialize = (expr->getOperator() == no_serialize);
 
     Owned<ABoundActivity> boundDataset = buildCachedActivity(ctx, dataset);

+ 11 - 0
ecl/hqlcpp/hqlttcpp.cpp

@@ -9906,6 +9906,17 @@ IHqlExpression * HqlLinkedChildRowTransformer::createTransformedBody(IHqlExpress
             return QuickHqlTransformer::createTransformedBody(expr);
         }
         break;
+    case no_libraryinput:
+        {
+            //no_libraryinput are passed in in their serialized form.  But this transformation adds LCR to all records
+            //of the same type regardless of where they are used.
+            //Ideally it would be context depenedent, but I have no idea how to implement that currently, so for the
+            //moment ensure the no_libraryinput uses the serialized form, but then transform to in memory form.
+            OwnedHqlExpr transformed = QuickHqlTransformer::createTransformedBody(expr);
+            if (expr != transformed)
+                return ensureDeserialized(expr, transformed->queryType(), diskAtom);
+            return transformed.getClear();
+        }
     case no_output:
         //would this be a good idea for output to file?  output to pipe?
         if (false)

+ 60 - 0
testing/regress/ecl/aaalibrary7.ecl

@@ -0,0 +1,60 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2019 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.
+############################################################################## */
+
+//nohthor
+//nothor
+//publish
+
+#option ('targetService', 'aaaLibrary7');
+#option ('createServiceAlias', true);
+
+idRecord := RECORD
+    unsigned id;
+END;
+
+childRecord := RECORD
+    unsigned5 childId;
+    dataset(idRecord) ids;
+END;
+
+searchOptions := RECORD
+    unsigned3 mainId;
+    dataset(childRecord) children;
+END;
+
+
+namesRecord :=
+            RECORD
+string20        surname;
+string10        forename;
+integer2        age := 25;
+            END;
+
+FilterDatasetInterface(dataset(namesRecord) ds, searchOptions options) := interface
+    export dataset(namesRecord) matches;
+    export dataset(namesRecord) others;
+end;
+
+
+filterDatasetLibrary(dataset(namesRecord) ds, searchOptions options) := module,library(FilterDatasetInterface)
+    shared f := ds;
+    shared searchAge := options.children[1].ids[1].id;
+    export matches := f(age = searchAge);
+    export others := f(age != searchAge);
+end;
+
+build(filterDatasetLibrary);

+ 15 - 0
testing/regress/ecl/key/library7.xml

@@ -0,0 +1,15 @@
+<Dataset name='logging'>
+ <Row><txt>Logging</txt></Row>
+</Dataset>
+<Dataset name='Liz'>
+ <Row><surname>Halliday            </surname><forename>Liz       </forename><age>30</age></Row>
+</Dataset>
+<Dataset name='Gavin'>
+ <Row><surname>Smith               </surname><forename>George    </forename><age>75</age></Row>
+</Dataset>
+<Dataset name='NotGavin'>
+ <Row><surname>Halliday            </surname><forename>Gavin     </forename><age>31</age></Row>
+ <Row><surname>Halliday            </surname><forename>Liz       </forename><age>30</age></Row>
+ <Row><surname>Jones               </surname><forename>John      </forename><age>44</age></Row>
+ <Row><surname>Smith               </surname><forename>Baby      </forename><age>2</age></Row>
+</Dataset>

+ 71 - 0
testing/regress/ecl/library7.ecl

@@ -0,0 +1,71 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2019 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.
+############################################################################## */
+
+//nohthor
+//nothor
+//The library is defined and built in aaalibrary6.ecl
+
+idRecord := RECORD
+    unsigned id;
+END;
+
+childRecord := RECORD
+    unsigned5 childId;
+    dataset(idRecord) ids;
+END;
+
+searchOptions := RECORD
+    unsigned3 mainId;
+    dataset(childRecord) children;
+END;
+
+
+namesRecord :=
+            RECORD
+string20        surname;
+string10        forename;
+integer2        age := 25;
+            END;
+
+FilterDatasetInterface(dataset(namesRecord) ds, searchOptions options) := interface
+    export dataset(namesRecord) matches;
+    export dataset(namesRecord) others;
+end;
+
+
+filterDataset(dataset(namesRecord) ds, searchOptions options) := library('aaaLibrary7',FilterDatasetInterface(ds,options));
+
+
+mkOptions(unsigned age) := ROW({0, [{2, [{age}]}]}, searchOptions);
+
+namesTable := dataset([
+        {'Halliday','Gavin',31},
+        {'Halliday','Liz',30},
+        {'Jones','John', 44},
+        {'Smith','George',75},
+        {'Smith','Baby', 2}], namesRecord);
+
+filtered1 := filterDataset(namesTable, mkOptions(30));
+filtered2 := filterDataset(namesTable, mkOptions(75));
+
+logging := DATASET([{'Logging'}], {string txt});
+sequential(
+  output(logging,named('logging'));
+  output(filtered1.matches,,named('Liz'));
+  output(filtered2.matches,,named('Gavin'));
+  output(filtered2.others,,named('NotGavin'));
+)