/// <summary> /// WrapParallel builds a parallel copy of the query stage for each source in ConcatenatingTable sources. /// It is used to allow running optimized query stages and running in parallel when multiple tables are involved. /// </summary> /// <remarks> /// WrapParallel can only be used by verbs where the output when run on the concatenated inputs rows from many sources /// produces the same output as running in parallel on each source and then concatenating the result rows. /// </remarks> /// <param name="source">IXTable to wrap</param> /// <param name="builder">Wrapping function</param> /// <returns>Wrapped IXTable</returns> public static IXTable WrapParallel(this IXTable source, XqlParser parser, Func <IXTable, IXTable> builder) { ConcatenatedTable cSource = source as ConcatenatedTable; if (cSource != null) { Position currentPosition = parser.CurrentPosition; return(ConcatenatedTable.Build(cSource.Sources.Select((s) => { parser.RewindTo(currentPosition); return builder(s); }))); } return(builder(source)); }