@@ -74,8 +74,8 @@ class SBEBlockExpressionTest : public EExpressionTestFixture {
74
74
extracted.tags [i], extracted.vals [i], expected[i].first , expected[i].second );
75
75
ASSERT_EQ (t, value::TypeTags::NumberInt32) << extracted;
76
76
ASSERT_EQ (value::bitcastTo<int32_t >(v), 0 )
77
- << " Got " << extracted[i] << " expected " << expected[i] << " full extracted output "
78
- << extracted;
77
+ << " Got " << extracted[i] << " expected " << expected[i]
78
+ << " full extracted output " << extracted;
79
79
}
80
80
}
81
81
@@ -86,6 +86,28 @@ class SBEBlockExpressionTest : public EExpressionTestFixture {
86
86
void testCmpScalar (const std::vector<std::pair<value::TypeTags, value::Value>>& testValues,
87
87
EPrimBinary::Op,
88
88
StringData cmpFunctionName);
89
+
90
+ std::pair<std::vector<bool >, std::vector<bool >> naiveLogicalAndOr (
91
+ std::unique_ptr<value::ValueBlock> leftBlock,
92
+ std::unique_ptr<value::ValueBlock> rightBlock) {
93
+ auto left = leftBlock->extract ();
94
+ auto right = rightBlock->extract ();
95
+ ASSERT_EQ (left.count , right.count );
96
+
97
+ std::vector<bool > andRes;
98
+ std::vector<bool > orRes;
99
+
100
+ for (size_t i = 0 ; i < left.count ; ++i) {
101
+ ASSERT_EQ (left.tags [i], value::TypeTags::Boolean);
102
+ ASSERT_EQ (right.tags [i], value::TypeTags::Boolean);
103
+ auto leftBool = value::bitcastTo<bool >(left.vals [i]);
104
+ auto rightBool = value::bitcastTo<bool >(right.vals [i]);
105
+ andRes.push_back (leftBool && rightBool);
106
+ orRes.push_back (leftBool || rightBool);
107
+ }
108
+
109
+ return std::pair{andRes, orRes};
110
+ }
89
111
};
90
112
91
113
TEST_F (SBEBlockExpressionTest, BlockExistsTest) {
@@ -550,8 +572,12 @@ TEST_F(SBEBlockExpressionTest, BlockApplyMaskedLambdaTest) {
550
572
TEST_F (SBEBlockExpressionTest, BlockLogicAndOrTest) {
551
573
value::ViewOfValueAccessor blockAccessorLeft;
552
574
value::ViewOfValueAccessor blockAccessorRight;
575
+ value::ViewOfValueAccessor falseMonoBlockAccessor;
576
+ value::ViewOfValueAccessor trueMonoBlockAccessor;
553
577
auto blockLeftSlot = bindAccessor (&blockAccessorLeft);
554
578
auto blockRightSlot = bindAccessor (&blockAccessorRight);
579
+ auto falseMonoBlockSlot = bindAccessor (&falseMonoBlockAccessor);
580
+ auto trueMonoBlockSlot = bindAccessor (&trueMonoBlockAccessor);
555
581
556
582
auto leftBlock = makeBoolBlock ({true , false , true , false });
557
583
blockAccessorLeft.reset (sbe::value::TypeTags::valueBlock,
@@ -561,6 +587,18 @@ TEST_F(SBEBlockExpressionTest, BlockLogicAndOrTest) {
561
587
blockAccessorRight.reset (sbe::value::TypeTags::valueBlock,
562
588
value::bitcastFrom<value::ValueBlock*>(rightBlock.get ()));
563
589
590
+ auto [fTag , fVal ] = makeBool (false );
591
+ std::unique_ptr<value::ValueBlock> falseMonoBlock =
592
+ std::make_unique<value::MonoBlock>(*leftBlock->tryCount (), fTag , fVal );
593
+ falseMonoBlockAccessor.reset (sbe::value::TypeTags::valueBlock,
594
+ value::bitcastFrom<value::ValueBlock*>(falseMonoBlock.get ()));
595
+
596
+ auto [tTag, tVal] = makeBool (true );
597
+ std::unique_ptr<value::ValueBlock> trueMonoBlock =
598
+ std::make_unique<value::MonoBlock>(*leftBlock->tryCount (), tTag, tVal);
599
+ trueMonoBlockAccessor.reset (sbe::value::TypeTags::valueBlock,
600
+ value::bitcastFrom<value::ValueBlock*>(trueMonoBlock.get ()));
601
+
564
602
{
565
603
auto expr = makeE<sbe::EFunction>(
566
604
" valueBlockLogicalAnd" ,
@@ -584,6 +622,40 @@ TEST_F(SBEBlockExpressionTest, BlockLogicAndOrTest) {
584
622
585
623
assertBlockOfBool (runTag, runVal, {true , true , true , false });
586
624
}
625
+
626
+ {
627
+ std::vector<value::SlotId> blockSlots{blockLeftSlot, falseMonoBlockSlot, trueMonoBlockSlot};
628
+ std::vector<std::unique_ptr<value::ValueBlock>> kBlocks ;
629
+ kBlocks .push_back (leftBlock->clone ());
630
+ kBlocks .push_back (falseMonoBlock->clone ());
631
+ kBlocks .push_back (trueMonoBlock->clone ());
632
+
633
+ for (size_t i = 0 ; i < blockSlots.size (); ++i) {
634
+ for (size_t j = 0 ; j < blockSlots.size (); ++j) {
635
+ auto andExpr = makeE<sbe::EFunction>(
636
+ " valueBlockLogicalAnd" ,
637
+ sbe::makeEs (makeE<EVariable>(blockSlots[i]), makeE<EVariable>(blockSlots[j])));
638
+ auto compiledAndExpr = compileExpression (*andExpr);
639
+
640
+ auto [andTag, andVal] = runCompiledExpression (compiledAndExpr.get ());
641
+ value::ValueGuard andGuard (andTag, andVal);
642
+
643
+ auto orExpr = makeE<sbe::EFunction>(
644
+ " valueBlockLogicalOr" ,
645
+ sbe::makeEs (makeE<EVariable>(blockSlots[i]), makeE<EVariable>(blockSlots[j])));
646
+ auto compiledOrExpr = compileExpression (*orExpr);
647
+
648
+ auto [orTag, orVal] = runCompiledExpression (compiledOrExpr.get ());
649
+ value::ValueGuard orGuard (orTag, orVal);
650
+
651
+ auto [andNaive, orNaive] =
652
+ naiveLogicalAndOr (kBlocks [i]->clone (), kBlocks [j]->clone ());
653
+
654
+ assertBlockOfBool (andTag, andVal, andNaive);
655
+ assertBlockOfBool (orTag, orVal, orNaive);
656
+ }
657
+ }
658
+ }
587
659
}
588
660
589
661
void SBEBlockExpressionTest::testFoldF (std::vector<bool > vals,
0 commit comments