public void QMWithDifferentSourcesAndSelectMany()
        {
            var q1 = new QMExtractorQueriable <TTreeQueryExecutorTest.TestNtupe>();
            var q2 = new QMExtractorQueriable <TTreeQueryExecutorTest.TestNtupeArrD>();

            var dude = q2.SelectMany(e => e.myvectorofdouble).Select(i => (int)1).Concat(q1.Select(i => (int)1)).Count();

            var qm     = QMExtractorExecutor.LastQM;
            var qmList = ConcatSplitterQueryVisitor.Split(qm)
                         .DumpToConsole();

            Assert.AreEqual(2, qmList.Length);

            CheckForQuery(() => q1.Select(i => (int)1).Count(), qmList);
            CheckForQuery(() => q2.SelectMany(e => e.myvectorofdouble).Select(i => (int)1).Count(), qmList);

            // Make sure the query providers are correct! Since we don't care about the order.
            var providersUsed1 = ExtractProviders <TTreeQueryExecutorTest.TestNtupe>(qmList);
            var providersUsed2 = ExtractProviders <TTreeQueryExecutorTest.TestNtupeArrD>(qmList);

            foreach (var item in providersUsed2)
            {
                providersUsed1.Add(item);
            }
            Assert.AreEqual(2, providersUsed1.Count);
            Assert.IsTrue(providersUsed1.Contains(q1.Provider));
            Assert.IsTrue(providersUsed1.Contains(q2.Provider));
        }
        public void QMWithConcatAndEarlyTake()
        {
            var q1 = new QMExtractorQueriable <ntup>();
            var r1 = q1.Take(10).Count();

            var qm     = QMExtractorExecutor.LastQM;
            var qmList = ConcatSplitterQueryVisitor.Split(qm)
                         .DumpToConsole();

            Assert.AreEqual(1, qmList.Length);
            CheckForQuery(() => q1.Take(10).Count(), qmList);
        }
        public void QMWith2ConcatsAndOneBurriedLateTake()
        {
            var q1 = new QMExtractorQueriable <ntup>();
            var q2 = new QMExtractorQueriable <ntup>();
            // THis is not allowed as the current infrastructure doesn't know how to do the Take properly (yet).
            // So this should cause an exception. It will print out, however, a way around this.
            var r1 = q1.Concat(q2).Where(x => x.run > 10).Take(300).Count();

            var qm     = QMExtractorExecutor.LastQM;
            var qmList = ConcatSplitterQueryVisitor.Split(qm)
                         .DumpToConsole();
        }
        public void WithConcatInSelectMany()
        {
            var q1 = new QMExtractorQueriable <TTreeQueryExecutorTest.TestNtupe>();
            var q2 = new QMExtractorQueriable <TTreeQueryExecutorTest.TestNtupeArrD>();

            var dude = q2.SelectMany(e => e.myvectorofdouble.Select(i => (int)1).Concat(q1.Select(eb => (int)1))).Count();
            var qm   = QMExtractorExecutor.LastQM;

            var QMList = ConcatSplitterQueryVisitor.Split(qm)
                         .DumpToConsole();

            Assert.AreEqual(2, QMList.Length);
        }
        public void TwoConcatsWithComplexObjectsAndGlobalTakes()
        {
            var q1 = new QueriableDummy <dummyntup>();
            var q2 = new QueriableDummy <dummyntup>();

            var s1 = q1.SelectMany(r => r.valC1D).Select(r => new ComplexObjectForTest1()
            {
                i = r
            }).Where(r => r.i > 10).Select(r => new ComplexObjectForTest2()
            {
                j = r.i
            }).Where(r => Math.Abs(r.j) < 200).Take(500);
            var s2 = q2.SelectMany(r => r.valC1D).Select(r => new ComplexObjectForTest1()
            {
                i = r
            }).Where(r => r.i > 20).Select(r => new ComplexObjectForTest2()
            {
                j = r.i
            }).Where(r => Math.Abs(r.j) < 200).Take(300);

            try
            {
                var r1 = s1.Concat(s2).Count();
            }
            catch (InvalidOperationException e) when(e.Message.Contains("can't translate"))
            {
            }

            var qm     = DummyQueryExectuor.LastQueryModel;
            var qmList = ConcatSplitterQueryVisitor.Split(qm)
                         .DumpToConsole();

            Assert.AreEqual(2, qmList.Length);
            //CheckForQuery(() => q1.SelectMany(r => r.valC1D).Select(r => new ComplexObjectForTest1() { i = r }).Where(r => r.i > 10).Where(r => Math.Abs(r.i) < 200).Take(500).Count(), qmList, 1, useDummy: true);
            //CheckForQuery(() => q2.SelectMany(r => r.valC1D).Select(r => new ComplexObjectForTest1() { i = r }).Where(r => r.i > 20).Where(r => Math.Abs(r.i) < 200).Take(300).Count(), qmList, 1, useDummy: true);

            // Dump the code
            var code1 = qmList[0].GenerateCode <int>();
            var code2 = qmList[1].GenerateCode <int>();

            Console.WriteLine();
            Console.WriteLine();
            code1.DumpCodeToConsole();
            Console.WriteLine();
            Console.WriteLine();
            code2.DumpCodeToConsole();

            // Next, produce code to make sure that we have a static definition.
            Assert.IsTrue(code1.DumpCode().Where(l => l.Contains("static int")).Any());
            Assert.IsTrue(code1.DumpCode().Where(l => l.Contains("static int")).Any());
        }
        public void QMWithSelectConcats()
        {
            var q1 = new QMExtractorQueriable <ntup>();
            var q2 = new QMExtractorQueriable <ntup>();
            var r1 = q1.Select(r => r.run).Concat(q2.Select(r => r.run + 1)).Count();

            var qm     = QMExtractorExecutor.LastQM;
            var qmList = ConcatSplitterQueryVisitor.Split(qm)
                         .DumpToConsole();

            Assert.AreEqual(2, qmList.Length);
            CheckForQuery(() => q1.Select(r => r.run).Count(), qmList);
            CheckForQuery(() => q2.Select(r => r.run + 1).Count(), qmList);
        }
        public void ConcatOfArrays()
        {
            // We need to fail badly when we have the Concat operator in a select clause.
            // We don't support this sort of thing, and none of the code that enables splitting
            // of queries should affect that.

            var q1 = new QMExtractorQueriable <TTreeQueryExecutorTest.TestNtupeArrD>();
            var r  = q1.Select(e => e.myvectorofdouble.Concat(e.myvectorofdouble).Count()).Sum();

            var qm     = QMExtractorExecutor.LastQM;
            var qmList = ConcatSplitterQueryVisitor.Split(qm)
                         .DumpToConsole();

            Assert.AreEqual(1, qmList.Length);
        }
        public void QMWith2ConcatsAndOneLateSkipPerSource()
        {
            var q1 = new QMExtractorQueriable <ntup>();
            var q2 = new QMExtractorQueriable <ntup>();
            // THis is not allowed as the current infrastructure doesn't know how to do the Take properly (yet).
            // So this should cause an exception.
            var r1 = q1.Concat(q2).SkipPerSource(300).Count();

            var qm     = QMExtractorExecutor.LastQM;
            var qmList = ConcatSplitterQueryVisitor.Split(qm)
                         .DumpToConsole();

            Assert.AreEqual(2, qmList.Length);
            CheckForQuery(() => q1.Skip(300).Count(), qmList, 2); // Can't really tell the difference between q1 and q2.
        }
        public void QMWith3Aggregate()
        {
            var q1  = new QMExtractorQueriable <TTreeQueryExecutorTest.TestNtupeArrD>();
            var q2  = new QMExtractorQueriable <TTreeQueryExecutorTest.TestNtupeArrD>();
            var q3  = new QMExtractorQueriable <TTreeQueryExecutorTest.TestNtupeArrD>();
            var seq = new IQueryable <TTreeQueryExecutorTest.TestNtupeArrD>[] { q1, q2, q3 };

            var all = seq.Skip(1).Aggregate(seq[0], (allc, next) => allc.Concat(next));
            var r   = all.Count();

            var qm     = QMExtractorExecutor.LastQM;
            var qmList = ConcatSplitterQueryVisitor.Split(qm)
                         .DumpToConsole();

            Assert.AreEqual(3, qmList.Length);
            CheckForQuery(() => q1.Count(), qmList, 3);
        }
        public void QMWith2SimpleConcats()
        {
            var q1 = new QMExtractorQueriable <ntup>();
            var q2 = new QMExtractorQueriable <ntup>();
            var r1 = q1.Concat(q2).Count();

            var qm     = QMExtractorExecutor.LastQM;
            var qmList = ConcatSplitterQueryVisitor.Split(qm)
                         .DumpToConsole();

            Assert.AreEqual(2, qmList.Length);
            CheckForQuery(() => q1.Count(), qmList, 2); // Can't really tell the difference between q1 and q2.

            // Make sure the query providers are correct! Since we don't care about the order.
            var providersUsed = ExtractProviders <ntup>(qmList);

            Assert.IsTrue(providersUsed.Contains(q1.Provider));
            Assert.IsTrue(providersUsed.Contains(q2.Provider));
            Assert.AreEqual(2, providersUsed.Count);
        }
        public void QMWithThreeAndSearchOperator()
        {
            var q1  = new QMExtractorQueriable <TTreeQueryExecutorTest.TestNtupeArrD>();
            var q2  = new QMExtractorQueriable <TTreeQueryExecutorTest.TestNtupeArrD>();
            var q3  = new QMExtractorQueriable <TTreeQueryExecutorTest.TestNtupeArrD>();
            var seq = new IQueryable <TTreeQueryExecutorTest.TestNtupeArrD>[] { q1, q2, q3 };

            var all = seq.Skip(1).Aggregate(seq[0], (allc, next) => allc.Concat(next));

            all
            .Select(e => e.myvectorofdouble.OrderByDescending(j => j).First())
            .Where(x => x > 5)
            .Count();

            var qm     = QMExtractorExecutor.LastQM;
            var qmList = ConcatSplitterQueryVisitor.Split(qm)
                         .DumpToConsole();

            Assert.AreEqual(3, qmList.Length);
            CheckForQuery(() => q1.Select(e => e.myvectorofdouble.OrderByDescending(j => j).First()).Where(x => x > 5).Count(), qmList, 3, "e");
        }
        public void QMWith3EmbededConcat()
        {
            var q1 = new QMExtractorQueriable <ntup>();
            var q2 = new QMExtractorQueriable <ntup>();
            var q3 = new QMExtractorQueriable <ntup>();
            var r1 = q1.Concat(q2.Concat(q3)).Count();

            var qm     = QMExtractorExecutor.LastQM;
            var qmList = ConcatSplitterQueryVisitor.Split(qm)
                         .DumpToConsole();

            Assert.AreEqual(3, qmList.Length);
            CheckForQuery(() => q1.Count(), qmList, 3);

            // Make sure the query providers are correct! Since we don't care about the order.
            var providersUsed = ExtractProviders <ntup>(qmList);

            Assert.IsTrue(providersUsed.Contains(q1.Provider));
            Assert.IsTrue(providersUsed.Contains(q2.Provider));
            Assert.IsTrue(providersUsed.Contains(q3.Provider));
            Assert.AreEqual(3, providersUsed.Count);
        }
        public void QMWith2ConcatsAndTwoEarlyTakesAndTests()
        {
            var q1 = new QueriableDummy <ntup>();
            var q2 = new QueriableDummy <ntup>();

            var s1 = q1.Where(x => x.run > 10).Take(500);
            var s2 = q2.Where(x => x.run > 20).Take(100);

            try
            {
                var r1 = s1.Concat(s2).Count();
            } catch (InvalidOperationException e) when(e.Message.Contains("can't translate"))
            {
            }

            var qm     = DummyQueryExectuor.LastQueryModel;
            var qmList = ConcatSplitterQueryVisitor.Split(qm)
                         .DumpToConsole();

            Assert.AreEqual(2, qmList.Length);
            CheckForQuery(() => q1.Where(x => x.run > 10).Take(500).Count(), qmList, 1, useDummy: true);
            CheckForQuery(() => q1.Where(x => x.run > 20).Take(100).Count(), qmList, 1, useDummy: true);

            // Dump the code
            var code1 = qmList[0].GenerateCode <int>();
            var code2 = qmList[1].GenerateCode <int>();

            Console.WriteLine();
            Console.WriteLine();
            code1.DumpCodeToConsole();
            Console.WriteLine();
            Console.WriteLine();
            code2.DumpCodeToConsole();

            // Next, produce code to make sure that we have a static definition.
            Assert.IsTrue(code1.DumpCode().Where(l => l.Contains("static int")).Any());
            Assert.IsTrue(code1.DumpCode().Where(l => l.Contains("static int")).Any());
        }
        public void QMWithMixedSelecAndConcats()
        {
            // This produces a rather nasty combination: one of the Concat operators ends
            // up in the main from clause, and the other one ends up in one of the result operators
            // of the main query model.
            var q1 = new QMExtractorQueriable <ntup>();
            var q2 = new QMExtractorQueriable <ntup>();
            var q3 = new QMExtractorQueriable <ntup>();

            var r1 = q1
                     .Select(r => r.run)
                     .Concat(q2.Select(r => r.run))
                     .Select(r => r * 2)
                     .Concat(q3.Select(r => r.run))
                     .Count();

            var qm     = QMExtractorExecutor.LastQM;
            var qmList = ConcatSplitterQueryVisitor.Split(qm)
                         .DumpToConsole();

            Assert.AreEqual(3, qmList.Length);
            CheckForQuery(() => q3.Select(r => r.run).Count(), qmList);
            CheckForQuery(() => q1.Select(r => r.run).Select(r => r * 2).Count(), qmList, 2);
        }