Browse Source

HPCC-15682 Add auto project for unprojected indexes

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday 9 years ago
parent
commit
b3be2191ae
3 changed files with 25 additions and 7 deletions
  1. 22 2
      ecl/hql/hqlpmap.cpp
  2. 2 3
      ecl/hql/hqlpmap.hpp
  3. 1 2
      ecl/hqlcpp/hqliproj.cpp

+ 22 - 2
ecl/hql/hqlpmap.cpp

@@ -524,8 +524,15 @@ IHqlExpression * NewProjectMapper2::recursiveExpandSelect(IHqlExpression * expr,
         unsigned match = targets.find(*plain);
         unsigned match = targets.find(*plain);
         if (match == NotFound)
         if (match == NotFound)
         {
         {
-            if (ignoreMissingFields)
-                return LINK(expr);
+            /*
+             * Sometimes the implicit project code will remove fields that are used in WILD() expressions.  This creates an inconsistency
+             * in the graph - a reference to a field that doesn't exist in the output of the previous expression.  If we are expanding
+             * a selector reference, and it isn't found in the input's dataset, assume it has been projected out, and remap it to the
+             * parent dataset.  (If this is wrong it will trigger an internal error later on.)
+             */
+            if (insideSelectorReference)
+                return createSelectExpr(LINK(newDataset), LINK(expr->queryChild(1)));
+
 #if 0
 #if 0
             dbglogExpr(plain.get());
             dbglogExpr(plain.get());
             ForEachItemIn(i, targets)
             ForEachItemIn(i, targets)
@@ -589,6 +596,19 @@ IHqlExpression * NewProjectMapper2::doExpandFields(IHqlExpression * expr, IHqlEx
     case no_record:
     case no_record:
         ret = LINK(expr);
         ret = LINK(expr);
         break;
         break;
+    case no_attr_expr:
+        if (expr->queryName() == _selectors_Atom)
+        {
+            if (!insideSelectorReference)
+            {
+                //Process any child no_selects so that missing entries are not fatal.
+                insideSelectorReference = true;
+                ret = doExpandFields(expr, oldDataset, newDataset, oldParent);
+                insideSelectorReference = false;
+                return ret;
+            }
+        }
+        break;
     case no_activerow:
     case no_activerow:
         {
         {
             IHqlExpression * ds = expr->queryChild(0);
             IHqlExpression * ds = expr->queryChild(0);

+ 2 - 3
ecl/hql/hqlpmap.hpp

@@ -32,7 +32,7 @@ class TableProjectMapper;
 class HQL_API NewProjectMapper2 : public CInterface
 class HQL_API NewProjectMapper2 : public CInterface
 {
 {
 public:
 public:
-    NewProjectMapper2() { ignoreMissingFields = false; mapping = NULL; matchedAll = true; expandCallback = NULL; }
+    NewProjectMapper2() { mapping = NULL; matchedAll = true; expandCallback = NULL; }
 
 
     //if newDataset is NULL, the mapping stored in the transform is returned unchanged (useful for seeing if filters can move over joins)
     //if newDataset is NULL, the mapping stored in the transform is returned unchanged (useful for seeing if filters can move over joins)
     IHqlExpression * expandFields(IHqlExpression * expr, IHqlExpression * oldDataset, IHqlExpression * newDataset, IHqlExpression * mapperParent, IExpandCallback * _expandCallback = NULL);
     IHqlExpression * expandFields(IHqlExpression * expr, IHqlExpression * oldDataset, IHqlExpression * newDataset, IHqlExpression * mapperParent, IExpandCallback * _expandCallback = NULL);
@@ -44,7 +44,6 @@ public:
     void initSelf(IHqlExpression * dataset);
     void initSelf(IHqlExpression * dataset);
     bool isMappingKnown();
     bool isMappingKnown();
     inline IHqlExpression * querySelf() { return self; }
     inline IHqlExpression * querySelf() { return self; }
-    void setIgnoreMissing() { ignoreMissingFields = true; }
     void setMapping(IHqlExpression * mapping);
     void setMapping(IHqlExpression * mapping);
     void setUnknownMapping();
     void setUnknownMapping();
 
 
@@ -83,7 +82,7 @@ private:
     CIArrayOf<NewProjectMapper2> children;
     CIArrayOf<NewProjectMapper2> children;
     OwnedHqlExpr self;
     OwnedHqlExpr self;
     IHqlExpression * mapping;
     IHqlExpression * mapping;
-    bool ignoreMissingFields;
+    bool insideSelectorReference = false;
     //Following are only set when expanding/contracting
     //Following are only set when expanding/contracting
     bool matchedAll;
     bool matchedAll;
     IExpandCallback * expandCallback;
     IExpandCallback * expandCallback;

+ 1 - 2
ecl/hqlcpp/hqliproj.cpp

@@ -2066,8 +2066,7 @@ ProjectExprKind ImplicitProjectTransformer::getProjectExprKind(IHqlExpression *
             return SourceActivity;
             return SourceActivity;
         }
         }
     case no_newkeyindex:
     case no_newkeyindex:
-        //Not compoundable for the moment - because it causes problems with assertwild(all, <old-expression>)
-        return SourceActivity;//CompoundableActivity;
+        return CompoundableActivity;
     case no_compound_diskread:
     case no_compound_diskread:
     case no_compound_disknormalize:
     case no_compound_disknormalize:
     case no_compound_indexread:
     case no_compound_indexread: