18#include "gandiva/tree_expr_builder.h"
19#include "arrow/status.h"
20#include "gandiva/filter.h"
21#include <catch_amalgamated.hpp>
22#include <arrow/util/key_value_metadata.h>
64DECLARE_SOA_TABLE(Segments,
"TEST",
"SEGMENTS", test::N, test::PointAId, test::PointBId, test::InfoId);
79 auto pwriter = b1.
cursor<o2::aod::Points3Ds>();
80 for (
auto i = 0;
i < 20; ++
i) {
81 pwriter(0, -1 *
i, (
int)(
i / 2), 2 *
i);
85 auto pt = o2::aod::Points3Ds{
t1};
86 auto pt1 = o2::aod::Points3DMk1s{
t1};
87 auto pt2 = o2::aod::Points3DMk2s{
t1};
88 auto pt3 = o2::aod::Points3DMk3s{
t1};
89 REQUIRE(pt1.begin().mark() == (
size_t)1);
90 REQUIRE(pt2.begin().mark() == (
size_t)2);
91 REQUIRE(pt3.begin().mark() == (
size_t)3);
97 auto rowWriter = builder.
persist<int32_t, int32_t>({
"fX",
"fY"});
111 i.mCurrentPos = &
pos;
129 arrow::ChunkedArray* chunks[2] = {
130 table->column(0).get(),
131 table->column(1).get()};
132 o2::aod::Points::iterator tests(chunks, {table->num_rows(), 0});
133 REQUIRE(tests.x() == 0);
134 REQUIRE(tests.y() == 0);
136 REQUIRE(tests.x() == 0);
137 REQUIRE(tests.y() == 1);
142 auto e = tests2.end();
156 REQUIRE(((
b + 1) == (
b + 1)));
157 REQUIRE(((
b + 7) !=
b));
158 REQUIRE(((
b + 7) != e));
159 REQUIRE(((
b + 8) == e));
161 for (
auto& t : tests2) {
162 REQUIRE(t.x() ==
value / 4);
163 REQUIRE((
size_t)t.y() ==
value);
168 for (
auto t1 = tests2.begin();
t1 != tests2.end(); ++
t1) {
169 for (
auto t2 =
t1 + 1; t2 != tests2.end(); ++t2) {
177 auto rowWriter = builder.
persist<int32_t, int32_t>({
"fX",
"fY"});
188 using Test1 =
InPlaceTable<
"A"_h, o2::aod::test::X, o2::aod::test::Y, o2::aod::test::Sum<o2::aod::test::X, o2::aod::test::Y>>;
191 for (
auto&
test : tests1) {
195 using Test2 =
InPlaceTable<
"B"_h, o2::aod::test::X, o2::aod::test::Y, o2::aod::test::Sum<o2::aod::test::Y, o2::aod::test::Y>>;
198 for (
auto&
test : tests2) {
206 auto rowWriter = builder.
persist<int32_t, int32_t>({
"fX",
"fY"});
220 foo.mCurrentPos = &index1;
222 bar.mCurrentPos = &index2;
223 REQUIRE(
foo.mCurrent == bar.mCurrent);
224 REQUIRE(
foo.mLast == bar.mLast);
225 REQUIRE(
foo.mColumn == bar.mColumn);
226 REQUIRE(
foo.mFirstIndex == bar.mFirstIndex);
227 REQUIRE(
foo.mCurrentChunk == bar.mCurrentChunk);
229 auto foobar = std::move(
foo);
230 REQUIRE(foobar.mCurrent == bar.mCurrent);
231 REQUIRE(foobar.mLast == bar.mLast);
232 REQUIRE(foobar.mColumn == bar.mColumn);
233 REQUIRE(foobar.mFirstIndex == bar.mFirstIndex);
234 REQUIRE(foobar.mCurrentChunk == bar.mCurrentChunk);
240 auto rowWriterX = builderX.
persist<int32_t>({
"fX"});
252 auto rowWriterY = builderY.
persist<int32_t>({
"fY"});
264 auto rowWriterZ = builderZ.
persist<int32_t>({
"fZ"});
276 auto rowWriterW = builderW.
persist<int32_t>({
"fW"});
288 REQUIRE(Test::contains<TestX>());
289 REQUIRE(Test::contains<TestY>());
290 REQUIRE(!Test::contains<TestZ>());
292 Test tests{{tableX, tableY}};
294 REQUIRE(tests.contains<TestX>());
295 REQUIRE(tests.contains<TestY>());
296 REQUIRE(!tests.contains<TestZ>());
298 for (
auto&
test : tests) {
302 auto tests2 =
join(TestX{tableX}, TestY{tableY});
303 static_assert(std::same_as<Test::self_t,
decltype(tests2)>,
"Joined tables should have the same type, regardless how we construct them");
304 for (
auto&
test : tests2) {
308 auto tests3 =
join(TestX{tableX}, TestY{tableY}, TestZ{tableZ});
310 for (
auto&
test : tests3) {
314 TestMoreThanTwo tests4{{tableX, tableY, tableZ}};
315 for (
auto&
test : tests4) {
320 auto joinError = [](
auto&& makeJoin) -> std::string {
328 REQUIRE(joinError([&] {
join(TestZ{tableZ}, TestW{tableW}); }) ==
"Tables TEST and TEST have different sizes (8 vs 3) and cannot be joined!");
329 REQUIRE(joinError([&] {
join(TestW{tableW}, TestY{tableY}, TestZ{tableZ}); }) ==
"Tables TEST and TEST have different sizes (3 vs 8) and cannot be joined!");
330 REQUIRE(joinError([&] {
join(TestX{tableX}, TestW{tableW}, TestZ{tableZ}); }) ==
"Tables TEST and TEST have different sizes (8 vs 3) and cannot be joined!");
331 REQUIRE(joinError([&] {
join(TestX{tableX}, TestY{tableY}, TestW{tableW}); }) ==
"Tables TEST and TEST have different sizes (8 vs 3) and cannot be joined!");
332 REQUIRE(joinError([&] {
Join<TestX, TestY, TestW>{{tableX, tableY, tableW}}; }) ==
"Tables at positions 1 and 2 have different sizes (8 vs 3) and cannot be joined!");
338 auto rowWriterA = builderA.
persist<int32_t, int32_t>({
"fX",
"fY"});
348 REQUIRE(tableA->num_rows() == 8);
351 auto rowWriterB = builderB.
persist<int32_t>({
"fX"});
363 auto rowWriterC = builderC.
persist<int32_t>({
"fZ"});
375 auto rowWriterD = builderD.
persist<int32_t, int32_t>({
"fX",
"fZ"});
376 rowWriterD(0, 16, 8);
377 rowWriterD(0, 17, 9);
378 rowWriterD(0, 18, 10);
379 rowWriterD(0, 19, 11);
380 rowWriterD(0, 20, 12);
381 rowWriterD(0, 21, 13);
382 rowWriterD(0, 22, 14);
383 rowWriterD(0, 23, 15);
395 static_assert(std::same_as<NestedJoinTest::columns_t, o2::framework::pack<o2::soa::Index<>, o2::aod::test::Y, o2::aod::test::X, o2::aod::test::Z>>,
"Bad nested join");
397 static_assert(std::same_as<ConcatTest::columns_t, o2::framework::pack<o2::soa::Index<>, o2::aod::test::X>>,
"Bad intersection of columns");
398 ConcatTest tests{{tableA, tableB}};
399 REQUIRE(16 == tests.size());
400 for (
auto&
test : tests) {
404 static_assert(std::same_as<NestedConcatTest::columns_t, o2::framework::pack<o2::aod::test::X>>,
"Bad nested concat");
411 auto status = gandiva::SelectionVector::MakeInt64(tests.size(), arrow::default_memory_pool(), &selection);
412 REQUIRE(status.ok());
414 auto fptr = tableA->schema()->GetFieldByName(
"fX");
415 REQUIRE(fptr !=
nullptr);
416 REQUIRE(fptr->name() ==
"fX");
417 REQUIRE(fptr->type()->id() == arrow::Type::INT32);
419 auto node_x = gandiva::TreeExprBuilder::MakeField(fptr);
420 auto literal_1 = gandiva::TreeExprBuilder::MakeLiteral(
static_cast<int32_t
>(1));
421 auto literal_3 = gandiva::TreeExprBuilder::MakeLiteral(
static_cast<int32_t
>(3));
422 auto equals_to_1 = gandiva::TreeExprBuilder::MakeFunction(
"equal", {node_x, literal_1}, arrow::boolean());
423 auto equals_to_3 = gandiva::TreeExprBuilder::MakeFunction(
"equal", {node_x, literal_3}, arrow::boolean());
424 auto node_or = gandiva::TreeExprBuilder::MakeOr({equals_to_1, equals_to_3});
425 auto condition = gandiva::TreeExprBuilder::MakeCondition(node_or);
426 REQUIRE(condition->ToString() ==
"bool equal((int32) fX, (const int32) 1) || bool equal((int32) fX, (const int32) 3)");
427 std::shared_ptr<gandiva::Filter>
filter;
428 status = gandiva::Filter::Make(tableA->schema(), condition, &
filter);
429 REQUIRE(status.ToString() ==
"OK");
431 arrow::TableBatchReader reader(*tableA);
432 std::shared_ptr<RecordBatch> batch;
433 auto s = reader.ReadNext(&batch);
435 REQUIRE(batch !=
nullptr);
436 REQUIRE(batch->num_rows() == 8);
437 auto st =
filter->Evaluate(*batch, selection);
438 REQUIRE(
st.ToString() ==
"OK");
443 FilteredTest filtered{{testA.asArrowTableRef()}, selection_f};
444 REQUIRE(2 == filtered.size());
447 REQUIRE(filtered.begin() != filtered.end());
448 for (
auto&
f : filtered) {
449 REQUIRE(
i * 2 + 1 ==
f.x());
450 REQUIRE(
i * 2 + 1 ==
f.index());
459 status = gandiva::SelectionVector::MakeInt64(tests.size(), arrow::default_memory_pool(), &selectionConcat);
460 REQUIRE(status.ok() ==
true);
461 selectionConcat->SetIndex(0, 0);
462 selectionConcat->SetIndex(1, 5);
463 selectionConcat->SetIndex(2, 10);
464 selectionConcat->SetNumSlots(3);
465 ConcatTest concatTest{tableA, tableB};
466 FilteredConcatTest concatTestTable{{concatTest.asArrowTableRef()}, selectionConcat};
467 REQUIRE(3 == concatTestTable.size());
470 auto b = concatTestTable.begin();
471 auto e = concatTestTable.end();
473 REQUIRE(
b.mRowIndex == 0);
474 REQUIRE(
b.getSelectionRow() == 0);
475 REQUIRE(e.index == 3);
477 REQUIRE(concatTestTable.begin() != concatTestTable.end());
478 for (
auto&
f : concatTestTable) {
479 REQUIRE(
i * 5 ==
f.x());
480 REQUIRE(
i * 5 ==
f.index());
481 REQUIRE(
i ==
f.filteredIndex());
489 status = gandiva::SelectionVector::MakeInt64(tests.size(), arrow::default_memory_pool(), &selectionJoin);
490 REQUIRE(status.ok() ==
true);
491 selectionJoin->SetIndex(0, 0);
492 selectionJoin->SetIndex(1, 2);
493 selectionJoin->SetIndex(2, 4);
494 selectionJoin->SetNumSlots(3);
495 JoinedTest testJoin{{tableA, tableC}};
496 FilteredJoinTest filteredJoin{{testJoin.asArrowTableRef()}, selectionJoin};
499 REQUIRE(filteredJoin.begin() != filteredJoin.end());
500 for (
auto&
f : filteredJoin) {
501 REQUIRE(
i * 2 ==
f.x());
502 REQUIRE(
i * 2 ==
f.index());
511 auto pointsWriter = builderA.
cursor<o2::aod::Points>();
512 pointsWriter(0, 0, 0);
513 pointsWriter(0, 3, 4);
515 o2::aod::Points points{pointsT};
516 REQUIRE(pointsT->num_rows() == 2);
519 auto infoWriter = builderA2.
cursor<o2::aod::Infos>();
520 infoWriter(0, 0,
true);
521 infoWriter(0, 1,
false);
522 infoWriter(0, 4,
true);
524 o2::aod::Infos infos{infosT};
525 REQUIRE(infos.begin().someBool() ==
true);
526 REQUIRE((infos.begin() + 1).someBool() ==
false);
527 REQUIRE((infos.begin() + 2).someBool() ==
true);
528 REQUIRE((infos.begin() + 2).color() == 4);
529 REQUIRE(infosT->num_rows() == 3);
532 auto segmentsWriter = builderB.
cursor<o2::aod::Segments>();
533 segmentsWriter(0, 10, 0, 1, 2);
534 auto segmentsT = builderB.
finalize();
535 o2::aod::Segments
segments{segmentsT};
536 REQUIRE(segmentsT->num_rows() == 1);
539 auto segmentsExtraWriter = builderC.
cursor<o2::aod::SegmentsExtras>();
540 segmentsExtraWriter(0, 1);
541 auto segmentsExtraT = builderC.
finalize();
542 o2::aod::SegmentsExtras segmentsExtras{segmentsExtraT};
543 REQUIRE(segmentsExtraT->num_rows() == 1);
545 REQUIRE(
segments.begin().pointAId() == 0);
546 REQUIRE(
segments.begin().pointBId() == 1);
547 static_assert(std::same_as<
decltype(
segments.begin().pointA()), o2::aod::Points::iterator>);
550 i.bindExternalIndices(&points, &infos);
551 REQUIRE(
i.n() == 10);
552 REQUIRE(
i.info().color() == 4);
553 REQUIRE(
i.info().someBool() ==
true);
554 REQUIRE(
i.pointA().x() == 0);
555 REQUIRE(
i.pointA().y() == 0);
556 REQUIRE(
i.pointB().x() == 3);
557 REQUIRE(
i.pointB().y() == 4);
559 segments.bindExternalIndices(&points, &infos);
561 REQUIRE(
j.n() == 10);
562 REQUIRE(
j.info().color() == 4);
563 REQUIRE(
j.info().someBool() ==
true);
564 REQUIRE(
j.pointA().x() == 0);
565 REQUIRE(
j.pointA().y() == 0);
566 REQUIRE(
j.pointB().x() == 3);
567 REQUIRE(
j.pointB().y() == 4);
570 joined.bindExternalIndices(&points, &infos);
571 auto se = joined.begin();
572 REQUIRE(se.n() == 10);
573 REQUIRE(se.info().color() == 4);
574 REQUIRE(se.pointA().x() == 0);
575 REQUIRE(se.pointA().y() == 0);
576 REQUIRE(se.pointB().x() == 3);
577 REQUIRE(se.pointB().y() == 4);
578 REQUIRE(se.thickness() == 1);
584 REQUIRE(
schema->num_fields() == 2);
585 REQUIRE(
schema->field(0)->name() ==
"fX");
586 REQUIRE(
schema->field(1)->name() ==
"fY");
592 auto rowWriterA = builderA.
persist<int32_t, int32_t>({
"fX",
"fY"});
595 rowWriterA(0, 2, 10);
596 rowWriterA(0, 3, 11);
597 rowWriterA(0, 4, 12);
598 rowWriterA(0, 5, 13);
599 rowWriterA(0, 6, 14);
600 rowWriterA(0, 7, 15);
602 REQUIRE(tableA->num_rows() == 8);
612 auto s1 = expressions::createSelection(testA.asArrowTable(), f1);
613 FilteredTest filtered1{{testA.asArrowTableRef()},
s1};
614 REQUIRE(4 == filtered1.size());
615 REQUIRE(filtered1.begin() != filtered1.end());
617 auto s2 = expressions::createSelection(testA.asArrowTable(), f2);
618 FilteredTest filtered2{{testA.asArrowTableRef()}, s2};
619 REQUIRE(2 == filtered2.size());
620 REQUIRE(filtered2.begin() != filtered2.end());
622 FilteredTest filteredUnion = filtered1 + filtered2;
623 REQUIRE(6 == filteredUnion.size());
625 std::vector<std::tuple<int32_t, int32_t>> expectedUnion{{0, 8}, {1, 9}, {2, 10}, {3, 11}, {6, 14}, {7, 15}};
627 for (
auto&
f : filteredUnion) {
628 REQUIRE(std::get<0>(expectedUnion[
i]) ==
f.x());
629 REQUIRE(std::get<1>(expectedUnion[
i]) ==
f.y());
630 REQUIRE(std::get<0>(expectedUnion[
i]) ==
f.index());
635 FilteredTest filteredIntersection = filtered1 * filtered2;
636 REQUIRE(0 == filteredIntersection.size());
638 REQUIRE(filteredIntersection.size() == 0);
641 auto s3 = expressions::createSelection(testA.asArrowTable(), f3);
642 FilteredTest filtered3{{testA.asArrowTableRef()}, s3};
643 REQUIRE(3 == filtered3.size());
644 REQUIRE(filtered3.begin() != filtered3.end());
646 FilteredTest unionIntersection = (filtered1 + filtered2) * filtered3;
647 REQUIRE(3 == unionIntersection.size());
650 for (
auto&
f : unionIntersection) {
652 REQUIRE(
i + 8 ==
f.y());
653 REQUIRE(
i ==
f.index());
662 auto rowWriterA = builderA.
persist<int32_t, int32_t>({
"fX",
"fY"});
665 rowWriterA(0, 2, 10);
666 rowWriterA(0, 3, 11);
667 rowWriterA(0, 4, 12);
668 rowWriterA(0, 5, 13);
669 rowWriterA(0, 6, 14);
670 rowWriterA(0, 7, 15);
672 REQUIRE(tableA->num_rows() == 8);
685 auto s1 = expressions::createSelection(testA.asArrowTable(), f1);
686 FilteredTest filtered{{testA.asArrowTableRef()},
s1};
687 REQUIRE(4 == filtered.size());
688 REQUIRE(filtered.begin() != filtered.end());
690 auto s2 = expressions::createSelection(filtered.asArrowTable(), f2);
691 NestedFilteredTest nestedFiltered{{filtered}, s2};
692 REQUIRE(2 == nestedFiltered.size());
694 for (
auto&
f : nestedFiltered) {
695 REQUIRE(
i + 2 ==
f.x());
696 REQUIRE(
i + 10 ==
f.y());
697 REQUIRE(
i + 2 ==
f.index());
702 auto s3 = expressions::createSelection(nestedFiltered.asArrowTable(), f3);
703 TripleNestedFilteredTest tripleFiltered{{nestedFiltered}, s3};
704 REQUIRE(1 == tripleFiltered.size());
706 for (
auto&
f : tripleFiltered) {
707 REQUIRE(
i + 2 ==
f.x());
708 REQUIRE(
i + 10 ==
f.y());
709 REQUIRE(
i + 2 ==
f.index());
718 [[maybe_unused]]
auto pwriter = bPoints.
cursor<o2::aod::Points>();
722 [[maybe_unused]]
auto iwriter = bInfos.
cursor<o2::aod::Infos>();
725 o2::aod::Points p{pempty};
726 o2::aod::Infos
i{iempty};
729 PI pi{{pempty, iempty}};
730 REQUIRE(pi.size() == 0);
731 auto spawned = Extend<o2::aod::Points, o2::aod::test::ESum>(p);
732 REQUIRE(spawned.size() == 0);
753 auto writer =
b.
cursor<o2::aod::Origints>();
754 for (
auto i = 0;
i < 20; ++
i) {
755 writer(0,
i,
i % 3 == 0);
757 auto origins =
b.finalize();
758 o2::aod::Origints o{origins};
761 auto writer_z =
z.
cursor<o2::aod::ManyReferences>();
762 std::vector<int>
ids;
763 for (
auto i = 0;
i < 5; ++
i) {
765 for (
auto j = 0;
j < 20; ++
j) {
770 auto mrefs =
z.finalize();
771 o2::aod::ManyReferences
m{mrefs};
774 auto writer_w =
w.
cursor<o2::aod::References>();
775 for (
auto i = 0;
i < 5 * 20; ++
i) {
778 auto refs =
w.finalize();
779 o2::aod::References
r{refs};
782 auto selection = expressions::createSelection(o.asArrowTable(), flt);
783 Flt
f{{o.asArrowTableRef()}, selection};
784 r.bindExternalIndices(&
f);
787 REQUIRE(it.origint_as<Flt>().globalIndex() == 3);
789 REQUIRE(it.origint_as<Flt>().globalIndex() == 4);
791 REQUIRE(it.origint_as<Flt>().globalIndex() == 5);
793 m.bindExternalIndices(&
f);
794 for (
auto const&
row :
m) {
795 auto os =
row.origints_as<Flt>();
796 auto fos =
row.filtered_origints_as<Flt>();
797 REQUIRE(os.size() == 20);
798 REQUIRE(fos.size() == 6);
814DECLARE_SOA_TABLE(PointsRefF,
"TEST",
"PTSREFF", test::SinglePointId, test::Points3DIdSlice, test::Points3DIds);
816 test::PointSeqIdSlice, test::PointSetIds);
822 auto pwriter = b1.
persist<int, int,
int>({
"fX",
"fY",
"fZ"});
823 for (
auto i = 0;
i < 20; ++
i) {
824 pwriter(0, -1 *
i, (
int)(
i / 2), 2 *
i);
829 auto prwriter = b2.
cursor<o2::aod::PointsRef>();
830 auto a = std::array{0, 1};
831 auto aa = std::vector{2, 3, 4};
832 prwriter(0, &
a[0], aa);
835 prwriter(0, &
a[0], aa);
838 auto pt = o2::aod::Points3Ds{tpts1};
839 auto prt = o2::aod::PointsRef{t2};
840 prt.bindExternalIndices(&pt);
842 auto it = prt.begin();
843 auto s1 = it.pointSlice();
844 auto g1 = it.pointGroup();
845 auto bb = std::same_as<
decltype(
s1), o2::aod::Points3Ds>;
847 REQUIRE(
s1.size() == 2);
849 for (
int i = 0;
i < 3; ++
i) {
850 REQUIRE(g1[
i].globalIndex() == aa[
i]);
855 for (
auto& p : it.pointGroup_as<o2::aod::Points3Ds>()) {
856 REQUIRE(p.x() == -1 * p.globalIndex());
860 auto s2 = it.pointSlice();
861 auto g2 = it.pointGroup();
862 REQUIRE(s2.size() == 7);
864 for (
int i = 0;
i < 3; ++
i) {
865 REQUIRE(g2[
i].globalIndex() == aa[
i]);
870 Flt
f{{tpts1}, expressions::createSelection(tpts1, fltx)};
871 prt.bindExternalIndices(&
f);
873 auto it2 = prt.begin();
874 auto s1f = it2.pointSlice_as<Flt>();
875 auto g1f = it2.pointGroup_as<Flt>();
876 REQUIRE(s1f.size() == 2);
878 for (
int i = 0;
i < 3; ++
i) {
879 REQUIRE(g1f[
i].globalIndex() == aa[
i]);
883 auto s2f = it2.pointSlice_as<Flt>();
884 auto g2f = it2.pointGroup_as<Flt>();
885 REQUIRE(s2f.size() == 7);
887 for (
int i = 0;
i < 3; ++
i) {
888 REQUIRE(g2f[
i].globalIndex() == aa[
i]);
892 auto pswriter = b3.
cursor<o2::aod::PointsSelfIndex>();
893 int references[] = {19, 2, 0, 13, 4, 6, 5, 5, 11, 9, 3, 8, 16, 14, 1, 18, 12, 18, 2, 7};
894 int slice[2] = {-1, -1};
895 std::vector<int> pset;
896 std::array<int, 4> withSlices = {3, 6, 13, 19};
897 std::array<std::pair<int, int>, 4> bounds = {std::pair{1, 5}, std::pair{3, 3}, std::pair{11, 11}, std::pair{10, 18}};
898 std::array<int, 4> withSets = {0, 1, 13, 14};
899 unsigned const int sizes[] = {3, 1, 5, 4};
902 for (
auto i = 0;
i < 20; ++
i) {
906 if (c1 < withSlices.size() &&
i == withSlices[c1]) {
907 slice[0] = bounds[c1].first;
908 slice[1] = bounds[c1].second;
911 if (c2 < withSets.size() &&
i == withSets[c2]) {
912 for (
auto z = 0U;
z <
sizes[c2]; ++
z) {
913 pset.push_back(
i + 1 +
z);
917 pswriter(0, -1 *
i, 0.5 *
i, 2 *
i, references[
i], slice, pset);
920 auto pst = o2::aod::PointsSelfIndex{t3};
921 pst.bindInternalIndicesTo(&pst);
925 for (
auto& p : pst) {
926 auto op = p.otherPoint_as<o2::aod::PointsSelfIndex>();
927 auto bbb = std::same_as<
decltype(
op), o2::aod::PointsSelfIndex::iterator>;
929 REQUIRE(
op.globalIndex() == references[
i]);
931 auto ops = p.pointSeq_as<o2::aod::PointsSelfIndex>();
932 auto bbbs = std::same_as<
decltype(ops), o2::aod::PointsSelfIndex>;
935 if (
i == withSlices[c1]) {
936 auto lit = ops.begin();
937 REQUIRE(ops.size() == bounds[c1].second - bounds[c1].first + 1);
938 REQUIRE(lit.globalIndex() == bounds[c1].first);
939 lit.moveByIndex(ops.size() - 1);
940 REQUIRE(lit.globalIndex() == bounds[c1].second);
943 REQUIRE(ops.size() == 0);
946 auto opss = p.pointSet_as<o2::aod::PointsSelfIndex>();
947 auto bbba = std::same_as<
decltype(opss), std::vector<o2::aod::PointsSelfIndex::iterator>>;
950 auto opss_ids = p.pointSetIds();
951 if (c2 < withSets.size() &&
i == withSets[c2]) {
952 REQUIRE(opss.size() ==
sizes[c2]);
953 REQUIRE(opss.begin()->globalIndex() ==
i + 1);
954 REQUIRE(opss.back().globalIndex() ==
i +
sizes[c2]);
956 for (
auto const&
id : opss_ids) {
957 REQUIRE(
id ==
i + 1 + c3);
962 REQUIRE(opss.size() == 0);
970DECLARE_SOA_TABLE(PointsSelfRef,
"TEST",
"PTSSR", test::OtherPointId, test::PointSeqIdSlice, test::PointSetIds);
976 auto pswriter = b3.
cursor<o2::aod::PointsSelfIndex>();
977 int references[] = {19, 2, 0, 13, 4, 6, 5, 5, 11, 9, 3, 8, 16, 14, 1, 18, 12, 18, 2, 7};
978 int slice[2] = {-1, -1};
979 std::vector<int> pset;
980 std::array<int, 4> withSlices = {3, 6, 13, 19};
981 std::array<std::pair<int, int>, 4> bounds = {std::pair{1, 5}, std::pair{3, 3}, std::pair{11, 11}, std::pair{10, 18}};
982 std::array<int, 4> withSets = {0, 1, 13, 14};
983 unsigned const int sizes[] = {3, 1, 5, 4};
986 for (
auto i = 0;
i < 20; ++
i) {
990 if (c1 < withSlices.size() &&
i == withSlices[c1]) {
991 slice[0] = bounds[c1].first;
992 slice[1] = bounds[c1].second;
995 if (c2 < withSets.size() &&
i == withSets[c2]) {
996 for (
auto z = 0U;
z <
sizes[c2]; ++
z) {
997 pset.push_back(
i + 1 +
z);
1001 pswriter(0, -1 *
i, 0.5 *
i, 2 *
i, references[
i], slice, pset);
1004 auto pst = o2::aod::PointsSelfIndex{t3};
1005 pst.bindInternalIndicesTo(&pst);
1008 for (
auto& p : pst) {
1009 auto ops = p.pointSeq_as<o2::aod::PointsSelfIndex>();
1010 for (
auto& pp : ops) {
1011 auto bpp = std::same_as<std::decay_t<
decltype(pp)>, o2::aod::PointsSelfIndex::iterator>;
1013 auto opps = pp.pointSeq_as<o2::aod::PointsSelfIndex>();
1014 for (
auto& ppp : opps) {
1015 auto bppp = std::same_as<std::decay_t<
decltype(ppp)>, o2::aod::PointsSelfIndex::iterator>;
1017 auto oppps = ppp.pointSeq_as<o2::aod::PointsSelfIndex>();
1018 for (
auto& pppp : oppps) {
1019 auto bpppp = std::same_as<std::decay_t<
decltype(pppp)>, o2::aod::PointsSelfIndex::iterator>;
1021 auto opppps = pppp.pointSeq_as<o2::aod::PointsSelfIndex>();
1029 auto corewriter =
b.
cursor<o2::aod::Points3Ds>();
1030 for (
auto i = 0;
i < 20; ++
i) {
1031 corewriter(0, -1 *
i, 0.5 *
i, 2 *
i);
1033 auto t1 =
b.finalize();
1038 auto extwriter = be.
cursor<o2::aod::PointsSelfRef>();
1039 for (
auto i = 0;
i < 20; ++
i) {
1043 if (c1 < withSlices.size() &&
i == withSlices[c1]) {
1044 slice[0] = bounds[c1].first;
1045 slice[1] = bounds[c1].second;
1048 if (c2 < withSets.size() &&
i == withSets[c2]) {
1049 for (
auto z = 0U;
z <
sizes[c2]; ++
z) {
1050 pset.push_back(
i + 1 +
z);
1054 extwriter(0, references[
i], slice, pset);
1058 FullPoints fp({
t1, t2});
1059 fp.bindInternalIndicesTo(&fp);
1063 for (
auto& p : fp) {
1064 REQUIRE(std::same_as<std::decay_t<
decltype(p)>, FullPoints::iterator>);
1065 auto ops = p.pointSeq_as<FullPoints>();
1066 for (
auto& pp : ops) {
1067 REQUIRE(std::same_as<std::decay_t<
decltype(pp)>, FullPoints::iterator>);
1068 auto opps = pp.pointSeq_as<FullPoints>();
1069 for (
auto& ppp : opps) {
1070 REQUIRE(std::same_as<std::decay_t<
decltype(ppp)>, FullPoints::iterator>);
1071 auto oppps = ppp.pointSeq_as<FullPoints>();
1072 for (
auto& pppp : oppps) {
1073 REQUIRE(std::same_as<std::decay_t<
decltype(pppp)>, FullPoints::iterator>);
1074 auto opppps = pppp.pointSeq_as<FullPoints>();
1080 auto const& fpa = fp;
1083 for (
auto const& it1 : fpa) {
1084 [[maybe_unused]]
auto it2 = fpa.rawIteratorAt(0);
1085 [[maybe_unused]]
auto it3 = fpa.iteratorAt(0);
1086 auto bit1 = std::same_as<std::decay_t<
decltype(it1)>, std::decay_t<
decltype(it2)>>;
1088 auto bit2 = std::same_as<std::decay_t<
decltype(it1)>, std::decay_t<
decltype(it3)>>;
1097 for (
auto& p : ffp) {
1098 REQUIRE(std::same_as<std::decay_t<
decltype(p)>, FilteredPoints::iterator>);
1099 REQUIRE(std::same_as<std::decay_t<
decltype(p)>::parent_t, FilteredPoints>);
1100 auto ops = p.pointSeq_as<
typename std::decay_t<
decltype(p)>::parent_t>();
1101 for (
auto& pp : ops) {
1102 REQUIRE(std::same_as<std::decay_t<
decltype(pp)>::parent_t, FilteredPoints>);
1103 auto opps = pp.pointSeq_as<FilteredPoints>();
1104 for (
auto& ppp : opps) {
1105 REQUIRE(std::same_as<std::decay_t<
decltype(ppp)>, FilteredPoints::iterator>);
1106 auto oppps = ppp.pointSeq_as<FilteredPoints>();
1107 for (
auto& pppp : oppps) {
1108 REQUIRE(std::same_as<std::decay_t<
decltype(pppp)>, FilteredPoints::iterator>);
1109 auto opppps = pppp.pointSeq_as<FilteredPoints>();
1115 auto const& ffpa = ffp;
1118 for (
auto const& it1 : ffpa) {
1119 [[maybe_unused]]
auto it2 = ffpa.rawIteratorAt(0);
1120 [[maybe_unused]]
auto it3 = ffpa.iteratorAt(0);
1121 using T1 = std::decay_t<
decltype(it1)>;
1122 using T2 = std::decay_t<
decltype(it2)>;
1123 using T3 = std::decay_t<
decltype(it3)>;
1124 auto bit1 = !std::same_as<T1, T2>;
1126 auto bit2 = !std::same_as<T1, T3>;
1128 auto bit3 = std::same_as<typename T1::policy_t, typename T3::policy_t>;
1130 auto bit4 = std::same_as<typename T1::policy_t, o2::soa::FilteredIndexPolicy>;
1132 auto bit5 = std::same_as<typename T2::policy_t, o2::soa::DefaultIndexPolicy>;
1140 auto writer =
b.
cursor<o2::aod::Lists>();
1141 std::vector<float> floats;
1142 std::vector<int> ints;
1143 for (
auto i = 1;
i < 11; ++
i) {
1146 for (
auto j = 0;
j <
i; ++
j) {
1147 floats.push_back(0.1231233f * (
float)
j + 0.1982798f);
1148 ints.push_back(
j + 10);
1151 writer(0, floats, ints);
1153 auto lt =
b.finalize();
1154 o2::aod::Lists tbl{lt};
1156 for (
auto&
row : tbl) {
1159 auto constexpr bf = std::same_as<
decltype(
f), gsl::span<
const float, (
size_t)-1>>;
1160 auto constexpr bi = std::same_as<
decltype(
i), gsl::span<
const int, (
size_t)-1>>;
1163 REQUIRE(
f.size() == s);
1164 REQUIRE(
i.size() == s);
1166 for (
auto j = 0u;
j <
f.size(); ++
j) {
1167 REQUIRE(
f[
j] == 0.1231233f * (
float)
j + 0.1982798f);
1168 REQUIRE(
i[
j] == (
int)
j + 10);
1177 auto writer =
b.
cursor<o2::aod::Origints>();
1178 for (
auto i = 0;
i < 20; ++
i) {
1179 writer(0,
i,
i % 3 == 0);
1181 auto origins =
b.finalize();
1182 o2::aod::Origints o{origins};
1185 auto writer_w =
w.
cursor<o2::aod::References>();
1187 for (
auto i = 0;
i < 5 * 20; ++
i) {
1193 auto refs =
w.finalize();
1194 o2::aod::References
r{refs};
1197 ArrowTableSlicingCache atscache({{o2::soa::getLabelFromType<o2::aod::References>(), o2::soa::getMatcherFromTypeForKey<o2::aod::References>(
key),
key}});
1198 auto s = atscache.updateCacheEntry(0, refs);
1201 for (
auto& oi : o) {
1202 auto cachedSlice =
r.sliceByCached(o2::aod::test::origintId, oi.globalIndex(), cache);
1203 REQUIRE(cachedSlice.size() == 5);
1204 for (
auto& ri : cachedSlice) {
1205 REQUIRE(ri.origintId() == oi.globalIndex());
1213 auto writer =
b.
cursor<o2::aod::Origints>();
1214 for (
auto i = 0;
i < 20; ++
i) {
1215 writer(0,
i,
i % 3 == 0);
1217 auto origins =
b.finalize();
1218 o2::aod::Origints o{origins};
1221 auto writer_w =
w.
cursor<o2::aod::References>();
1223 for (
auto i = 0;
i < 5 * 20; ++
i) {
1229 auto refs =
w.finalize();
1230 o2::aod::References
r{refs};
1233 auto writer_w2 = w2.
cursor<o2::aod::OtherReferences>();
1235 for (
auto i = 0;
i < 5 * 20; ++
i) {
1242 o2::aod::OtherReferences r2{refs2};
1245 J rr{{refs, refs2}};
1249 auto s = atscache.updateCacheEntry(0, refs2);
1252 for (
auto& oi : o) {
1253 auto cachedSlice = rr.sliceByCached(o2::aod::test::altOrigintId, oi.globalIndex(), cache);
1254 REQUIRE(cachedSlice.size() == 3);
1255 for (
auto& ri : cachedSlice) {
1256 REQUIRE(ri.altOrigintId() == oi.globalIndex());
1264 auto writer =
b.
cursor<o2::aod::Origints>();
1265 for (
auto i = 0;
i < 20; ++
i) {
1266 writer(0,
i,
i % 3 == 0);
1268 auto origins =
b.finalize();
1269 o2::aod::Origints o{origins};
1272 auto writer_w =
w.
cursor<o2::aod::References>();
1274 for (
auto i = 0;
i < 5 * 20; ++
i) {
1280 auto refs =
w.finalize();
1281 o2::aod::References
r{refs};
1284 auto writer_w2 = w2.
cursor<o2::aod::OtherReferences>();
1286 for (
auto i = 0;
i < 5 * 20; ++
i) {
1293 o2::aod::OtherReferences r2{refs2};
1296 J rr{{refs, refs2}};
1298 auto rrf = rr.
select(o2::aod::test::altOrigintId > 2 && o2::aod::test::altOrigintId < 15);
1302 auto s = atscache.updateCacheEntry(0, refs2);
1305 for (
auto& oi : o) {
1306 auto cachedSlice = rrf.sliceByCached(o2::aod::test::altOrigintId, oi.globalIndex(), cache);
1307 if (oi.globalIndex() <= 2 || oi.globalIndex() >= 15) {
1308 CHECK(cachedSlice.size() == 0);
1310 CHECK(cachedSlice.size() == 3);
1312 for (
auto& ri : cachedSlice) {
1313 REQUIRE(ri.altOrigintId() == oi.globalIndex());
1321 auto prwriter =
b.
cursor<o2::aod::PointsRefF>();
1322 auto a = std::array{0, 1};
1323 auto aa = std::vector{2, 3, 4};
1324 prwriter(0, 0, &
a[0], aa);
1327 prwriter(0, 1, &
a[0], aa);
1328 auto t =
b.finalize();
1329 auto prt = o2::aod::PointsRefF{t};
1331 for (
auto&
row : prt) {
1333 [[maybe_unused]]
auto sp =
row.singlePoint();
1335 REQUIRE(std::string{
error_from_ref(
ref).
what} ==
"Index pointing to Points3Ds is not bound! Did you subscribe to the table?");
1338 auto ps =
row.pointSlice();
1340 REQUIRE(std::string{
error_from_ref(
ref).
what} ==
"Index pointing to Points3Ds is not bound! Did you subscribe to the table?");
1343 auto pg =
row.pointGroup();
1345 REQUIRE(std::string{
error_from_ref(
ref).
what} ==
"Index pointing to Points3Ds is not bound! Did you subscribe to the table?");
1364 auto writer =
b.
cursor<o2::aod::BILists>();
1366 for (
auto i = 0;
i < 20; ++
i) {
1368 for (
auto j = 0;
j < 32; ++
j) {
1376 auto t =
b.finalize();
1378 o2::aod::BILists li{t};
1379 for (
auto const&
row : li) {
1380 auto iir =
row.smallIntArray();
1381 [[maybe_unused]]
auto bbrr =
row.boolArray_raw();
1382 REQUIRE(std::same_as<std::decay_t<
decltype(iir)>, int8_t
const*>);
1383 for (
auto i = 0;
i < 32; ++
i) {
1384 REQUIRE(iir[
i] ==
i);
1385 REQUIRE(
row.boolArray_bit(
i) == (
i % 2 == 0));
1402 table::One, table::Two, table::Three, table::Four,
1403 table::Five<table::Four>);
1409 auto writer =
b.
cursor<o2::aod::MixTest>();
1411 for (
auto i = 0;
i < 20; ++
i) {
1414 writer(0,
i, o2::constants::math::PI *
i, o2::constants::math::Almost0 *
i,
f);
1416 auto t =
b.finalize();
1417 o2::aod::MixTest mt{t};
1419 for (
auto const&
row : mt) {
1420 auto features1 =
row.getValues<float, o2::aod::table::One, o2::aod::table::Three>();
1421 auto features2 =
row.getValues<double, o2::aod::table::One, o2::aod::table::Two, o2::aod::table::Three>();
1422 auto features3 =
row.getValues<float, o2::aod::table::Two, o2::aod::table::Five<o2::aod::table::Four>>();
1423 auto b1 = std::same_as<std::array<float, 2>,
decltype(features1)>;
1425 auto b2 = std::same_as<std::array<double, 3>,
decltype(features2)>;
1427 auto b3 = std::same_as<std::array<float, 2>,
decltype(features3)>;
1429 REQUIRE(features1[0] == (
float)
count);
1430 REQUIRE(features1[1] == (
float)(o2::constants::math::Almost0 *
count));
1432 REQUIRE(features2[0] == (
double)
count);
1433 REQUIRE(features2[1] == (
double)(o2::constants::math::PI *
count));
1434 REQUIRE(features2[2] == (
double)(o2::constants::math::Almost0 *
count));
1436 REQUIRE(features3[0] == (
float)(o2::constants::math::PI *
count));
1437 REQUIRE(features3[1] == (
float)((
float)
count / (
float)(
count + 1)));
1480 REQUIRE(cursor.
lastIndex() + 1 <= reserved);
1482 auto table = builder->finalize();
1483 REQUIRE(table->num_rows() == 5);
1484 REQUIRE(table->num_columns() == 2);
1506 auto max8 = std::numeric_limits<uint8_t>::max();
1507 auto max16 = std::numeric_limits<uint8_t>::max();
1508 auto max32 = std::numeric_limits<uint8_t>::max();
1509 auto max64 = std::numeric_limits<uint8_t>::max();
1512 auto writer8 = b8.
cursor<o2::aod::UnsignedIntTest8>();
1513 for (uint64_t
i = 0;
i < max8;
i += (max8 / 100)) {
1517 o2::aod::UnsignedIntTest8 at8{{t8}};
1519 uint8_t limit8 = max8 / 2 + 1;
1525 REQUIRE(at8.size() == 128);
1526 REQUIRE(fat8.size() == 64);
1529 auto writer16 = b16.
cursor<o2::aod::UnsignedIntTest16>();
1530 for (uint64_t
i = 0;
i < max16;
i += (max16 / 100)) {
1534 o2::aod::UnsignedIntTest16 at16{{t16}};
1536 uint16_t limit16 = max16 / 2 + 1;
1542 REQUIRE(at16.size() == 128);
1543 REQUIRE(fat16.size() == 64);
1546 auto writer32 = b32.
cursor<o2::aod::UnsignedIntTest32>();
1547 for (uint64_t
i = 0;
i < max32;
i += (max32 / 100)) {
1551 o2::aod::UnsignedIntTest32 at32{{t32}};
1553 uint32_t limit32 = max32 / 2 + 1;
1559 REQUIRE(at32.size() == 128);
1560 REQUIRE(fat32.size() == 64);
1563 auto writer64 = b64.
cursor<o2::aod::UnsignedIntTest64>();
1564 for (uint64_t
i = 0;
i < max64;
i += (max64 / 100)) {
1568 o2::aod::UnsignedIntTest64 at64{{t64}};
1570 uint64_t limit64 = max64 / 2 + 1;
1576 REQUIRE(at64.size() == 128);
1577 REQUIRE(fat64.size() == 64);
#define DECLARE_SOA_ARRAY_INDEX_COLUMN(_Name_, _Getter_)
#define DECLARE_SOA_SLICE_INDEX_COLUMN(_Name_, _Getter_)
#define DECLARE_SOA_DYNAMIC_COLUMN(_Name_, _Getter_,...)
#define DECLARE_SOA_SELF_INDEX_COLUMN(_Name_, _Getter_)
#define DECLARE_SOA_TABLE(_Name_, _Origin_, _Desc_,...)
#define DECLARE_SOA_EXPRESSION_COLUMN(_Name_, _Getter_, _Type_, _Expression_)
#define DECLARE_SOA_COLUMN(_Name_, _Getter_, _Type_)
#define DECLARE_SOA_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Table_, _Suffix_)
#define DECLARE_SOA_SELF_SLICE_INDEX_COLUMN(_Name_, _Getter_)
#define DECLARE_SOA_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_)
#define DECLARE_SOA_TABLE_VERSIONED(_Name_, _Origin_, _Desc_, _Version_,...)
#define DECLARE_SOA_INDEX_COLUMN(_Name_, _Getter_)
#define DECLARE_SOA_BITMAP_COLUMN(_Name_, _Getter_, _Size_)
#define DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN(_Name_, _Getter_)
std::shared_ptr< arrow::Schema > schema
std::vector< double > sum
std::shared_ptr< T > get(const HistName &histName)
auto persist(std::array< char const *, sizeof...(ARGS)+1 > const &columnNames)
std::shared_ptr< arrow::Table > finalize()
void bindInternalIndicesTo(I const *ptr)
unfiltered_iterator begin()
auto select(framework::expressions::Filter const &f) const
GLuint GLsizei const GLuint const GLintptr const GLsizeiptr * sizes
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * value
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLboolean GLboolean GLboolean GLboolean a
GLubyte GLubyte GLubyte GLubyte w
GLdouble GLdouble GLdouble z
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
std::shared_ptr< gandiva::SelectionVector > Selection
gandiva::Selection createSelection(std::shared_ptr< arrow::Table > const &table, Filter const &expression)
Function for creating gandiva selection from our internal filter tree.
Defining ITS Vertex explicitly as messageable.
RuntimeError & error_from_ref(RuntimeErrorRef)
std::string cutString(std::string &&str)
auto createFieldsFromColumns(framework::pack< C... >)
constexpr auto join(Ts const &... t)
std::vector< int64_t > SelectionVector
FIXME: do not use data model tables.
char what[MAX_RUNTIME_ERROR_SIZE]
int64_t lastIndex()
Last index inserted in the table.
bool resetCursor(LifetimeHolder< TableBuilder > builder)
void reserve(int64_t size)
A struct, containing the root of the expression tree.