TODO: refactor the code to move the engine-specific computation to the corresponding ddf-on-x
552848
@Override public FiveNumSummary[] getFiveNumSummary(List<String> columnNames) throws DDFException {
    FiveNumSummary[] fivenums = new FiveNumSummary[columnNames.size()];

    List<String> numericColumns = new ArrayList<String>();

    // Filter non-numeric columns
    for (String columnName : columnNames) {
      if (ColumnType.isNumeric(this.getDDF().getColumn(columnName).getType())) {
        numericColumns.add(columnName);
      }
    }

    String[] rs = null;

    if (numericColumns.size() > 0) {

      if (this.getDDF().getEngineType().equals(DDFManager.EngineType.SPARK)) {
        List<String> specs = Lists.newArrayList();
        for (String columnName : columnNames) {
          String query = fiveNumHiveFunction(columnName);
          if (query != null && query.length() > 0) {
            specs.add(query);
          }
        }

        String command = String.format("SELECT %s FROM %%s", StringUtils.join(specs.toArray(new String[0]), ','));

        mLog.info(">>>> command = " + command);
        // a fivenumsummary of an Int/Long column is in the format "[min, max, 1st_quantile, median, 3rd_quantile]"
        // each value can be a NULL
        // a fivenumsummary of an Double/Float column is in the format "min \t max \t[1st_quantile, median, 3rd_quantile]"
        // or "min \t max \t null"s

        rs = this.getDDF()
            .sql(command, String.format("Unable to get fivenum summary of the given columns from table %%s")).getRows()
            .get(0).replaceAll("\\[|\\]| ", "").replaceAll(",", "\t").split("\t| ");
      } else if (this.getDDF().getEngineType().equals(DDFManager.EngineType.POSTGRES)
              || this.getDDF().getEngineType().equals(DDFManager.EngineType.REDSHIFT)) {

        rs = new String[numericColumns.size()*5];

        int k = 0;
        // Need to separately compute each column's five-num values
        // Otherwise, combining all into a query will produce incorrect result in Redshift case
        // May be due to the nature of its window functions
        for(String column: numericColumns) {
          String sql = buildPostgresFiveNumSql(column, this.getDDF().getTableName());

          String[] ret = this.getDDF().getManager().sql(sql, false).getRows().get(0).split("\t");
          System.arraycopy(ret, 0, rs, k, 5);
          k += 5;
        }

      } else {
        throw new DDFException("Unsupported engine");
      }

    }


    int k = 0;
    for (int i = 0; i < columnNames.size(); i++) {
      if (!numericColumns.contains(columnNames.get(i))) {
        fivenums[i] = new FiveNumSummary(Double.NaN, Double.NaN, Double.NaN, Double.NaN, Double.NaN);
      } else {
        fivenums[i] = new FiveNumSummary(parseDouble(rs[5 * k]), parseDouble(rs[5 * k + 1]),
            parseDouble(rs[5 * k + 2]),
            parseDouble(rs[5 * k + 3]), parseDouble(rs[5 * k + 4]));
        k++;
      }
    }

    return fivenums;
  }
61212
public void accumulate(Object workingMemoryContext,
                           Object context,
                           Tuple tuple,
                           InternalFactHandle handle,
                           Declaration[] declarations,
                           Declaration[] innerDeclarations,
                           WorkingMemory workingMemory) throws Exception {
        Object[]  localVars = ((MVELAccumulatorContext) context).getVariables();
        MVELAccumulatorFactoryContext factoryContext = (MVELAccumulatorFactoryContext)workingMemoryContext;
        VariableResolverFactory factory = factoryContext.getActionFactory();
        actionUnit.updateFactory( handle, tuple, localVars, (InternalWorkingMemory) workingMemory, workingMemory.getGlobalResolver(), factory );

        DroolsVarFactory df = ( DroolsVarFactory ) factory.getNextFactory();
        
        if ( reverse != null ) {
            Object[] shadow = new Object [df.getOtherVarsPos()];
            for ( int i = 0; i < df.getOtherVarsPos(); i++ ) {
                shadow[i] = factory.getIndexedVariableResolver( i ).getValue();
                
                
            }
            // SNAPSHOT variable values
            ((MVELAccumulatorContext) context).getShadow().put( handle.getId(), shadow);
        }
        MVELSafeHelper.getEvaluator().executeExpression( this.action,
                                null,
                                factory );
        
        
        if ( localVars.length > 0 ) {
            for ( int i = 0; i < df.getOtherVarsLength(); i++ ) {
                localVars[i] = factory.getIndexedVariableResolver( df.getOtherVarsPos() + i ).getValue();
            }
        }
        
        ((MVELAccumulatorContext) context).setVariables( localVars );        
    }
1353247
function starx(obj) {
    if (!isGenerator(obj) && !isIterator(obj)) throw new TypeError('obj must be a generator or iterator')

    return function executor(done) {
      var self = this,
          done = once(done || noop),
          iterator = isGenerator(obj) ? obj.call(self) : obj

      process.nextTick(next)
      function next(err, value) {    
        var res, _next = once(next)

        domain.create()
          // iterator throws, we're done
          .on('error', done)
          .run(function() {
            res = err ? iterator.throw(err) : iterator.next(value)
          })
      
        domain.create()
          // yieldable throws, iterator is certainly not yet exhausted, so run next
          .on('error', _next)
          .run(function() {
            wrap.call(self, res.value).call(self, function cb() {
              (res.done ? done : _next).apply(null, arguments)
            })
          })
      }
    }
  }
954656
def _commonPrefetchDeclarativeIds(engine, mutex,
                                  Declarative, count) -> Optional[Iterable[int]]:
    
    if not count:
        logger.debug("Count was zero, no range returned")
        return

    conn = engine.connect()
    transaction = conn.begin()
    mutex.acquire()
    try:
        sequence = Sequence('%s_id_seq' % Declarative.__tablename__,
                            schema=Declarative.metadata.schema)

        if isPostGreSQLDialect(engine):
            sql = "SELECT setval('%(seq)s', (select nextval('%(seq)s') + %(add)s), true)"
            sql %= {
                'seq': '"%s"."%s"' % (sequence.schema, sequence.name),
                'add': count
            }
            nextStartId = conn.execute(sql).fetchone()[0]
            startId = nextStartId - count

        elif isMssqlDialect(engine):
            startId = conn.execute(
                'SELECT NEXT VALUE FOR "%s"."%s"'
                % (sequence.schema, sequence.name)
            ).fetchone()[0] + 1

            nextStartId = startId + count

            conn.execute('alter sequence "%s"."%s" restart with %s'
                         % (sequence.schema, sequence.name, nextStartId))

        else:
            raise NotImplementedError()

        transaction.commit()

        return iter(range(startId, nextStartId))

    finally:
        mutex.release()
        conn.close()
473196
public IModel KMeans(int numCentroids, int maxIters, int runs, String initMode)
      throws DDFException {
    return this.train("kmeans", numCentroids, maxIters, runs, initMode);
  }
1253787
public static <T> FlowableTransformer<T,T> doOnCancelFx(Action onDipsose) {
        return obs -> obs.doOnCancel(() -> runOnFx(onDipsose));
    }
432935
def _compile_pfgen(self):
        """"""
        string = '"""\n'
        string += 'system.dae.init_g()\n'
        for gcall, pflow, shunt, series, stagen, call in zip(
                self.gcall, self.pflow, self.shunt, self.series, self.stagen,
                self.gcalls):
            if gcall and pflow and (shunt or series) and not stagen:
                string += call
        string += '\n'
        string += 'system.dae.reset_small_g()\n'
        string += '"""'
        self.pfgen = compile(eval(string), '', 'exec')
54404
function() {

      // all cursor has results, than sent to join algorithm callback.

      var out;
      if (solver instanceof ydn.db.algo.AbstractSolver) {
        out = solver.solver(keys, values);
      } else {
        out = solver(keys, values);
      }
      if (ydn.db.core.DbOperator.DEBUG) {
        goog.global.console.log(me + ' received result from solver ' +
            out + ' for keys ' + ydn.json.stringify(keys));
      }
      var next_primary_keys = [];
      var next_effective_keys = [];
      var advance = [];
      var restart = [];
      if (goog.isArray(out)) {
        // adv vector is given
        for (var i = 0; i < out.length; i++) {
          if (out[i] === true) {
            advance[i] = 1;
          } else if (out[i] === false) {
            restart[i] = true;
          } else {
            next_effective_keys[i] = out[i];
          }
        }
      } else if (goog.isNull(out)) {
        // all stop
        next_primary_keys = [];
      } else if (!goog.isDef(out)) {
        // all continue;
        next_primary_keys = [];
        for (var i = 0; i < iterators.length; i++) {
          if (goog.isDef(idx2iterator[i])) {
            advance[i] = 1;
          }
        }
      } else if (goog.isObject(out)) {
        if (goog.DEBUG) {
          var valid_att = ['advance', 'continue', 'continuePrimary', 'restart'];
          for (var key in out) {
            if (!goog.array.contains(valid_att, key)) {
              throw new ydn.debug.error.InvalidOperationException(
                  'Unknown attribute "' + key +
                  '" in cursor advancement object');
            }
          }
        }
        next_primary_keys = out['continuePrimary'] || [];
        next_effective_keys = out['continue'] || [];
        advance = out['advance'] || [];
        restart = out['restart'] || [];
      } else {
        throw new ydn.debug.error.InvalidOperationException(
            'scan callback output');
      }
      var move_count = 0;
      result_count = 0;
      for (var i = 0; i < iterators.length; i++) {
        if (goog.isDefAndNotNull(next_primary_keys[i]) ||
            goog.isDef(next_effective_keys[i]) ||
            goog.isDefAndNotNull(restart[i]) ||
            goog.isDefAndNotNull(advance[i])) {
          // by marking non moving iterator first, both async and sync callback
          // work.
        } else {
          // take non advancing iterator as already moved.
          result_count++;
        }
      }
      for (var i = 0; i < iterators.length; i++) {
        if (goog.isDefAndNotNull(next_primary_keys[i]) ||
            goog.isDef(next_effective_keys[i]) ||
            goog.isDefAndNotNull(restart[i]) ||
            goog.isDefAndNotNull(advance[i])) {
          var idx = idx2iterator[i];
          if (!goog.isDef(idx)) {
            throw new ydn.error.InvalidOperationException(i +
                ' is not an iterator.');
          }
          var iterator = iterators[idx];
          var cursor = cursors[i];
          if (goog.DEBUG && !goog.isDefAndNotNull(keys[i])) {
            var at = i + '/' + iterators.length;
            if (goog.isDefAndNotNull(advance[i])) {
              throw new ydn.error.InvalidOperationError(cursor + ' ' + at +
                  ' must not advance ' + advance[i] + ' steps');
            } else if (goog.isDef(next_effective_keys[i])) {
              throw new ydn.error.InvalidOperationError(cursor + ' ' + at +
                  ' must not continue to key ' + next_effective_keys[i]);
            } else if (goog.isDefAndNotNull(next_primary_keys[i])) {
              throw new ydn.error.InvalidOperationError(cursor + ' ' + at +
                  ' must not continue to primary key ' + next_primary_keys[i]);
            }
          }

          keys[i] = undefined;
          values[i] = undefined;

          if (goog.isDefAndNotNull(restart[i])) {
            if (ydn.db.core.DbOperator.DEBUG) {
              goog.global.console.log('cursor ' + cursor + ' of iterator ' +
                  iterator + ': restarting.');
            }
            goog.asserts.assert(restart[i] === true, i +
                ' restart must be true');
            cursor.restart();
          } else if (goog.isDef(next_effective_keys[i])) {
            if (ydn.db.core.DbOperator.DEBUG) {
              goog.global.console.log(iterator + ': continuing to ' +
                  next_effective_keys[i]);
            }
            cursor.continueEffectiveKey(next_effective_keys[i]);
          } else if (goog.isDefAndNotNull(next_primary_keys[i])) {
            if (ydn.db.core.DbOperator.DEBUG) {
              goog.global.console.log(cursor + ': continuing to primary key ' +
                  next_primary_keys[i]);
            }
            cursor.continuePrimaryKey(next_primary_keys[i]);
          } else if (goog.isDefAndNotNull(advance[i])) {
            if (ydn.db.core.DbOperator.DEBUG) {
              goog.global.console.log(iterator + ': advancing ' + advance[i] +
                  ' steps.');
            }
            goog.asserts.assert(advance[i] === 1, i +
                ' advance value must be 1');

            cursor.advance(1);
          } else {
            throw new ydn.error.InternalError(iterator + ': has no action');
          }
          move_count++;
        }
      }
      // console.log(['on_result_ready', move_count, keys, adv]);
      if (move_count == 0) {
        do_exit();
      }

    }
150519
public void accumulate(Object workingMemoryContext,
                           Object context,
                           Tuple tuple,
                           InternalFactHandle handle,
                           Declaration[] declarations,
                           Declaration[] innerDeclarations,
                           WorkingMemory workingMemory) throws Exception {
        
        VariableResolverFactory factory = unit.getFactory( null, null, null, handle, tuple, null, (InternalWorkingMemory) workingMemory, workingMemory.getGlobalResolver()  );
        
        final Object value = MVEL.executeExpression( this.expression,
                                                     handle.getObject(),
                                                     factory );
        if ( this.function.supportsReverse() ) {
            ((MVELAccumulatorFunctionContext) context).reverseSupport.put( handle.getId(), value );
        }
        this.function.accumulate( ((MVELAccumulatorFunctionContext) context).context,
                                  value );
    }
628553
def _dK_ode_dtheta(self, target):
        """"""
        t_ode = self._t[self._index>0]
        dL_dK_ode = self._dL_dK[self._index>0, :]
        index_ode = self._index[self._index>0]-1
        if self._t2 is None:
            if t_ode.size==0:
                return        
            t2_ode = t_ode
            dL_dK_ode = dL_dK_ode[:, self._index>0]
            index2_ode = index_ode
        else:
            t2_ode = self._t2[self._index2>0]
            dL_dK_ode = dL_dK_ode[:, self._index2>0]
            if t_ode.size==0 or t2_ode.size==0:
                return
            index2_ode = self._index2[self._index2>0]-1

        h1 = self._compute_H(t_ode, index_ode, t2_ode, index2_ode, stationary=self.is_stationary, update_derivatives=True)
        #self._dK_ddelay = self._dh_ddelay
        self._dK_dsigma = self._dh_dsigma

        if self._t2 is None:
            h2 = h1
        else:
            h2 = self._compute_H(t2_ode, index2_ode, t_ode, index_ode, stationary=self.is_stationary, update_derivatives=True)

        #self._dK_ddelay += self._dh_ddelay.T
        self._dK_dsigma += self._dh_dsigma.T
        # C1 = self.sensitivity
        # C2 = self.sensitivity

        # K = 0.5 * (h1 + h2.T)
        # var2 = C1*C2
        # if self.is_normalized:
        #     dk_dD1 = (sum(sum(dL_dK.*dh1_dD1)) + sum(sum(dL_dK.*dh2_dD1.T)))*0.5*var2
        #     dk_dD2 = (sum(sum(dL_dK.*dh1_dD2)) + sum(sum(dL_dK.*dh2_dD2.T)))*0.5*var2
        #     dk_dsigma = 0.5 * var2 * sum(sum(dL_dK.*dK_dsigma))
        #     dk_dC1 = C2 * sum(sum(dL_dK.*K))
        #     dk_dC2 = C1 * sum(sum(dL_dK.*K))
        # else:
        #     K = np.sqrt(np.pi) * K
        #     dk_dD1 = (sum(sum(dL_dK.*dh1_dD1)) + * sum(sum(dL_dK.*K))
        #     dk_dC2 = self.sigma * C1 * sum(sum(dL_dK.*K))


        # dk_dSim1Variance = dk_dC1
        # Last element is the length scale.
        (dL_dK_ode[:, :, None]*self._dh_ddelay[:, None, :]).sum(2)

        target[-1] += (dL_dK_ode*self._dK_dsigma/np.sqrt(2)).sum()
56400
def _compute_dlt(self):
        """"""
        res = super()._compute_dlt()
        for rec in self:
            ltaf_to_apply = self.env['ddmrp.adjustment'].search(
                rec._ltaf_to_apply_domain())
            if ltaf_to_apply:
                ltaf = 1
                values = ltaf_to_apply.mapped('value')
                for val in values:
                    ltaf *= val
                prev = rec.dlt
                rec.dlt *= ltaf
                _logger.debug(
                    "LTAF=%s applied to %s. DLT: %s -> %s" %
                    (ltaf, rec.name, prev, rec.dlt))
        return res
854238
@Override
  public IModel train(String trainMethodName, Object... paramArgs) throws DDFException {
    /**
     * Example signatures we must support:
     * <p/>
     * Unsupervised Training
     * <p/>
     * <code>
     * Kmeans.train(data: RDD[Array[Double]], k: Int, maxIterations: Int, runs: Int, initializationMode: String)
     * </code>
     * <p/>
     * Supervised Training
     * <p/>
     * <code>
     * LogisticRegressionWithSGD.train(input: RDD[LabeledPoint], numIterations: Int, stepSize: Double, miniBatchFraction:
     * Double, initialWeights: Array[Double])
     *
     * SVM.train(input: RDD[LabeledPoint], numIterations: Int, stepSize: Double, regParam: Double, miniBatchFraction:
     * Double)
     * </code>
     */

    // Build the argument type array
    if (paramArgs == null) paramArgs = new Object[0];

    // Locate the training method
    String mappedName = Config.getValueWithGlobalDefault(this.getEngine(), trainMethodName);
    if (!Strings.isNullOrEmpty(mappedName)) trainMethodName = mappedName;

    TrainMethod trainMethod = new TrainMethod(trainMethodName, MLClassMethods.DEFAULT_TRAIN_METHOD_NAME, paramArgs);
    if (trainMethod.getMethod() == null) {
      throw new DDFException(String.format("Cannot locate method specified by %s", trainMethodName));
    }

    // Now we need to map the DDF and its column specs to the input format expected by the method we're invoking
    Object[] allArgs = this.buildArgsForMethod(trainMethod.getMethod(), paramArgs);

    // Invoke the training method
    Object rawModel = trainMethod.classInvoke(allArgs);


    List<Schema.Column> columns = this.getDDF().getSchemaHandler().getColumns();
    String[] trainedColumns = new String[columns.size()];

    for (int i = 0; i < columns.size(); i++) {
      trainedColumns[i] = columns.get(i).getName();
    }

    for (String col : trainedColumns) {
      mLog.info(">>>>>> trainedCol = " + col);
    }

    IModel model = this.newModel(rawModel);
    model.setTrainedColumns(trainedColumns);
    mLog.info(">>>> modelID = " + model.getName());
    this.getManager().addModel(model);
    return model;
  }
891587
def __computeDecomp(self):
        
        primeNumbers = [getPrimeFactors(d) for d in self.globalDims]

        ns = [len(pns) for pns in primeNumbers]
        validDecomps = []
        self.validProcs = []
        for it in MultiArrayIter(ns):
            inds = it.getIndices()
            decomp = [primeNumbers[d][inds[d]] for d in range(self.ndims)]
            self.validProcs.append(reduce(operator.mul, decomp, 1))
            if reduce(operator.mul, decomp, 1) == self.nprocs:
                validDecomps.append(decomp)

        # sort and remove duplicates
        self.validProcs.sort()
        vprocs = []
        for vp in self.validProcs:
            if len(vprocs) == 0 or (len(vprocs) >= 1 and vp != vprocs[-1]):
                vprocs.append(vp)
        self.validProcs = vprocs

        if len(validDecomps) == 0:
            # no solution
            return

        # find the optimal decomp among all valid decomps
        minCost = float('inf')
        bestDecomp = validDecomps[0]
        for decomp in validDecomps:
            sizes = [self.globalDims[d]//decomp[d] for d in range(self.ndims)]
            volume = reduce(operator.mul, sizes, 1)
            surface = 0
            for d in range(self.ndims):
                surface += 2*reduce(operator.mul, sizes[:d], 1) * \
                    reduce(operator.mul, sizes[d+1:], 1)
            cost = surface / float(volume)
            if cost < minCost:
                bestDecomp = decomp
                minCost = cost
        self.decomp = bestDecomp

        # ok, we have a valid decomp, now build the sub-domain iterator
        self.mit = MultiArrayIter(self.decomp, rowMajor=self.rowMajor)

        # fill in the proc to index set map
        procId = 0
        self.proc2IndexSet = {}
        numCellsPerProc = [self.globalDims[d]//self.decomp[d]
                           for d in range(self.ndims)]
        for it in self.mit:
            nps = it.getIndices()
            self.proc2IndexSet[procId] = []
            for d in range(self.ndims):
                sbeg = nps[d]*numCellsPerProc[d]
                send = (nps[d] + 1)*numCellsPerProc[d]
                self.proc2IndexSet[procId].append(slice(sbeg, send))
            procId += 1
16271
static Map<String, Object> sumOfDelta(Map<String, Object> state, Map<String, Object> delta) {
        InstanceKey instanceId = (InstanceKey) delta.get("InstanceKey");
        if (instanceId == null) {
            throw new RuntimeException("InstanceKey can not be null");
        }
        for (String key : delta.keySet()) {
            Object existing = state.get(key);
            Object current = delta.get(key);
            if (current instanceof Number) {
                if (existing == null) {
                    existing = 0;
                }
                Number v = (Number) existing;
                Number d = (Number) delta.get(key);
                state.put(key, v.longValue() + d.longValue());
            } else if (current instanceof NumberList) {
                if (existing == null) {
                    state.put(key, current);
                } else {
                    state.put(key, ((NumberList) existing).sum((NumberList) current));
                }
            } else {
                Object o = delta.get(key);
                if (o instanceof String[]) {
                    String[] vs = (String[]) o;
                    if (vs.length == 1) {
                        Object previousAggregateString = state.get(key);
                        if (previousAggregateString instanceof AggregateString) {
                            state.put(key, ((AggregateString) previousAggregateString).update(null, vs[0], instanceId));
                        } else {
                            state.put(key, AggregateString.create(vs[0], instanceId));
                        }
                    } else {
                        // it should always be AggregateString here since that's all we add above
                        AggregateString pas = (AggregateString) state.get(key);
                        state.put(key, pas.update(vs[0], vs[1], instanceId));
                    }
                } else {
                    state.put(key, String.valueOf(o));
                }

            }
        }
        return state;
    }
523362
def _dask_or_eager_func(name, eager_module=np, dask_module=dask_array,
                        list_of_args=False, array_args=slice(1),
                        requires_dask=None):
    """"""
    if dask_module is not None:
        def f(*args, **kwargs):
            if list_of_args:
                dispatch_args = args[0]
            else:
                dispatch_args = args[array_args]
            if any(isinstance(a, dask_array.Array) for a in dispatch_args):
                try:
                    wrapped = getattr(dask_module, name)
                except AttributeError as e:
                    raise AttributeError("%s: requires dask >=%s" %
                                         (e, requires_dask))
            else:
                wrapped = getattr(eager_module, name)
            return wrapped(*args, **kwargs)
    else:
        def f(*args, **kwargs):
            return getattr(eager_module, name)(*args, **kwargs)
    return f
816858
def getDelta(original, update):
    
    # Compute both keys
    k = genKw(*original)
    kPrime = genKw(*update)

    # Compute delta,p'
    delta = (kPrime * inverse(k, orderGt())) % orderGt()
    pPrime = generatorGt()**kPrime
    return delta,pPrime
1089902
function preprocessRawResults(rawResults, resolvedConfig) {
    rawResults.forEach((rawResult, resultId) => {
        if (!rawResult.attributePath) return; // e.g. sub-filter results don't need indexing

        // link resultIds into attribute tree (per DataSource):
        const attrNode = getAttribute(rawResult.attributePath, resolvedConfig);
        attrNode.dataSources[rawResult.dataSourceName].resultId = resultId;

        // index rows by childKey if available
        // (top-level result has no childKey and does not need to be indexed):
        if (rawResult.childKey) {
            const keyAttr = rawResult.childKey.length === 1 ? rawResult.childKey[0] : null;
            rawResult.indexedData = {};
            rawResult.data.forEach((row, i) => {
                function dereferenceKeyAttr(keyAttrib) {
                    const keyVal = row[keyAttrib];
                    if (keyVal === undefined) {
                        const attrPath =
                            rawResult.attributePath.length > 0 ? rawResult.attributePath.join('.') : '{root}';
                        throw new DataError(
                            `Result-row ${i} of "${attrPath}" (DataSource "${
                                rawResult.dataSourceName
                            }") misses child key attribute "${keyAttr}"`
                        );
                    }
                    return keyVal;
                }

                const key = keyAttr
                    ? '' + dereferenceKeyAttr(keyAttr) // speed up non-composite keys
                    : rawResult.childKey.map(dereferenceKeyAttr).join(keySeparator);

                if (!rawResult.uniqueChildKey) {
                    if (!rawResult.indexedData[key]) rawResult.indexedData[key] = [];
                    rawResult.indexedData[key].push(row);
                } else {
                    if (rawResult.indexedData[key]) {
                        const attrPath =
                            rawResult.attributePath.length > 0 ? rawResult.attributePath.join('.') : '{root}';
                        throw new DataError(
                            `Result-row ${i} of "${attrPath}" (DataSource "${
                                rawResult.dataSourceName
                            }") has duplicate child key "${key}"`
                        );
                    }
                    rawResult.indexedData[key] = row;
                }
            });
        }
    });
}