@@ -690,12 +690,27 @@ Y_UNIT_TEST_SUITE(KqpOlap) {
690
690
};
691
691
}
692
692
693
- void CheckPlanForAggregatePushdown (const TString& query, NYdb::NTable::TTableClient& tableClient, const std::vector<std::string>& planNodes,
693
+ template <typename TClient>
694
+ auto StreamExplainQuery (const TString& query, TClient& client) {
695
+ if constexpr (std::is_same_v<NYdb::NTable::TTableClient, TClient>) {
696
+ TStreamExecScanQuerySettings scanSettings;
697
+ scanSettings.Explain (true );
698
+ return client.StreamExecuteScanQuery (query, scanSettings).GetValueSync ();
699
+ } else {
700
+ NYdb::NQuery::TExecuteQuerySettings scanSettings;
701
+ scanSettings.ExecMode (NYdb::NQuery::EExecMode::Explain);
702
+ return client.StreamExecuteQuery (query, NYdb::NQuery::TTxControl::BeginTx ().CommitTx (), scanSettings).GetValueSync ();
703
+ }
704
+ }
705
+
706
+ template <typename TClient>
707
+ void CheckPlanForAggregatePushdown (
708
+ const TString& query,
709
+ TClient& client,
710
+ const std::vector<std::string>& expectedPlanNodes,
694
711
const std::string& readNodeType)
695
712
{
696
- TStreamExecScanQuerySettings scanSettings;
697
- scanSettings.Explain (true );
698
- auto res = tableClient.StreamExecuteScanQuery (query, scanSettings).GetValueSync ();
713
+ auto res = StreamExplainQuery (query, client);
699
714
UNIT_ASSERT_C (res.IsSuccess (), res.GetIssues ().ToString ());
700
715
701
716
auto planRes = CollectStreamResult (res);
@@ -704,7 +719,7 @@ Y_UNIT_TEST_SUITE(KqpOlap) {
704
719
Cerr << planRes.PlanJson .GetOrElse (" NO_PLAN" ) << Endl;
705
720
Cerr << " AST:" << Endl;
706
721
Cerr << ast << Endl;
707
- for (auto planNode : planNodes ) {
722
+ for (auto planNode : expectedPlanNodes ) {
708
723
UNIT_ASSERT_C (ast.find (planNode) != std::string::npos,
709
724
TStringBuilder () << planNode << " was not found. Query: " << query);
710
725
}
@@ -2437,10 +2452,12 @@ Y_UNIT_TEST_SUITE(KqpOlap) {
2437
2452
ExpectedReply = value;
2438
2453
return *this ;
2439
2454
}
2455
+
2440
2456
TAggregationTestCase& AddExpectedPlanOptions (const std::string& value) {
2441
2457
ExpectedPlanOptions.emplace_back (value);
2442
2458
return *this ;
2443
2459
}
2460
+
2444
2461
const std::vector<std::string>& GetExpectedPlanOptions () const {
2445
2462
return ExpectedPlanOptions;
2446
2463
}
@@ -2548,7 +2565,28 @@ Y_UNIT_TEST_SUITE(KqpOlap) {
2548
2565
TestAggregationsInternal (cases);
2549
2566
}
2550
2567
2551
- void TestClickBenchBase (const std::vector<TAggregationTestCase>& cases) {
2568
+ template <typename TClient>
2569
+ auto StreamExecuteQuery (const TAggregationTestCase& testCase, TClient& client) {
2570
+ if constexpr (std::is_same_v<NYdb::NTable::TTableClient, TClient>) {
2571
+ return client.StreamExecuteScanQuery (testCase.GetFixedQuery ()).GetValueSync ();
2572
+ } else {
2573
+ return client.StreamExecuteQuery (
2574
+ testCase.GetFixedQuery (),
2575
+ NYdb::NQuery::TTxControl::BeginTx ().CommitTx ()).GetValueSync ();
2576
+ }
2577
+ }
2578
+
2579
+ template <typename TClient>
2580
+ void RunTestCaseWithClient (const TAggregationTestCase& testCase, TClient& client) {
2581
+ auto it = StreamExecuteQuery (testCase, client);
2582
+ UNIT_ASSERT_C (it.IsSuccess (), it.GetIssues ().ToString ());
2583
+ TString result = StreamResultToYson (it);
2584
+ if (!testCase.GetExpectedReply ().empty ()) {
2585
+ CompareYson (result, testCase.GetExpectedReply ());
2586
+ }
2587
+ }
2588
+
2589
+ void TestClickBenchBase (const std::vector<TAggregationTestCase>& cases, const bool genericQuery) {
2552
2590
auto settings = TKikimrSettings ()
2553
2591
.SetWithSampleTables (false )
2554
2592
.SetForceColumnTablesCompositeMarks (true );
@@ -2564,17 +2602,20 @@ Y_UNIT_TEST_SUITE(KqpOlap) {
2564
2602
WriteTestDataForClickBench (kikimr, " /Root/benchTable" , 0 , 1000000 + i * 1000000 , iterationPackSize);
2565
2603
}
2566
2604
2567
- for (auto && i : cases) {
2568
- const TString queryFixed = i.GetFixedQuery ();
2569
- {
2570
- auto it = tableClient.StreamExecuteScanQuery (queryFixed).GetValueSync ();
2571
- UNIT_ASSERT_C (it.IsSuccess (), it.GetIssues ().ToString ());
2572
- TString result = StreamResultToYson (it);
2573
- if (!i.GetExpectedReply ().empty ()) {
2574
- CompareYson (result, i.GetExpectedReply ());
2575
- }
2605
+ if (!genericQuery) {
2606
+ auto tableClient = kikimr.GetTableClient ();
2607
+ for (auto && i : cases) {
2608
+ const TString queryFixed = i.GetFixedQuery ();
2609
+ RunTestCaseWithClient (i, tableClient);
2610
+ CheckPlanForAggregatePushdown (queryFixed, tableClient, i.GetExpectedPlanOptions (), i.GetExpectedReadNodeType ());
2611
+ }
2612
+ } else {
2613
+ auto queryClient = kikimr.GetQueryClient ();
2614
+ for (auto && i : cases) {
2615
+ const TString queryFixed = i.GetFixedQuery ();
2616
+ RunTestCaseWithClient (i, queryClient);
2617
+ CheckPlanForAggregatePushdown (queryFixed, queryClient, i.GetExpectedPlanOptions (), i.GetExpectedReadNodeType ());
2576
2618
}
2577
- CheckPlanForAggregatePushdown (queryFixed, tableClient, i.GetExpectedPlanOptions (), i.GetExpectedReadNodeType ());
2578
2619
}
2579
2620
}
2580
2621
@@ -2637,12 +2678,14 @@ Y_UNIT_TEST_SUITE(KqpOlap) {
2637
2678
}
2638
2679
}
2639
2680
2640
- void TestClickBench (const std::vector<TAggregationTestCase>& cases) {
2641
- TestClickBenchBase (cases);
2642
- TestClickBenchInternal (cases);
2681
+ void TestClickBench (const std::vector<TAggregationTestCase>& cases, const bool genericQuery = false ) {
2682
+ TestClickBenchBase (cases, genericQuery);
2683
+ if (!genericQuery) {
2684
+ TestClickBenchInternal (cases);
2685
+ }
2643
2686
}
2644
2687
2645
- void TestTableWithNulls (const std::vector<TAggregationTestCase>& cases) {
2688
+ void TestTableWithNulls (const std::vector<TAggregationTestCase>& cases, const bool genericQuery = false ) {
2646
2689
auto settings = TKikimrSettings ()
2647
2690
.SetWithSampleTables (false )
2648
2691
.SetForceColumnTablesCompositeMarks (true );
@@ -2656,17 +2699,20 @@ Y_UNIT_TEST_SUITE(KqpOlap) {
2656
2699
WriteTestDataForTableWithNulls (kikimr, " /Root/tableWithNulls" );
2657
2700
}
2658
2701
2659
- for (auto && i : cases) {
2660
- const TString queryFixed = i.GetFixedQuery ();
2661
- {
2662
- auto it = tableClient.StreamExecuteScanQuery (queryFixed).GetValueSync ();
2663
- UNIT_ASSERT_C (it.IsSuccess (), it.GetIssues ().ToString ());
2664
- TString result = StreamResultToYson (it);
2665
- if (!i.GetExpectedReply ().empty ()) {
2666
- CompareYson (result, i.GetExpectedReply ());
2667
- }
2702
+ if (!genericQuery) {
2703
+ auto tableClient = kikimr.GetTableClient ();
2704
+ for (auto && i : cases) {
2705
+ RunTestCaseWithClient (i, tableClient);
2706
+ CheckPlanForAggregatePushdown (i.GetFixedQuery (), tableClient,
2707
+ i.GetExpectedPlanOptions (), i.GetExpectedReadNodeType ());
2708
+ }
2709
+ } else {
2710
+ auto queryClient = kikimr.GetQueryClient ();
2711
+ for (auto && i : cases) {
2712
+ RunTestCaseWithClient (i, queryClient);
2713
+ CheckPlanForAggregatePushdown (i.GetFixedQuery (), queryClient,
2714
+ i.GetExpectedPlanOptions (), i.GetExpectedReadNodeType ());
2668
2715
}
2669
- CheckPlanForAggregatePushdown (queryFixed, tableClient, i.GetExpectedPlanOptions (), i.GetExpectedReadNodeType ());
2670
2716
}
2671
2717
}
2672
2718
@@ -5883,6 +5929,53 @@ Y_UNIT_TEST_SUITE(KqpOlap) {
5883
5929
CompareYson (output, R"( [])" );
5884
5930
}
5885
5931
}
5932
+
5933
+ Y_UNIT_TEST (BlockGenericWithDistinct) {
5934
+ TAggregationTestCase testCase;
5935
+ testCase.SetQuery (R"(
5936
+ SELECT
5937
+ COUNT(DISTINCT id)
5938
+ FROM `/Root/tableWithNulls`
5939
+ WHERE level = 5 AND Cast(id AS String) = "5";
5940
+ )" )
5941
+ .AddExpectedPlanOptions (" KqpBlockReadOlapTableRanges" )
5942
+ .AddExpectedPlanOptions (" WideFromBlocks" )
5943
+ .SetExpectedReply (" [[1u]]" );
5944
+ TestTableWithNulls ({ testCase }, /* generic */ true );
5945
+ }
5946
+
5947
+ Y_UNIT_TEST (BlockGenericSimpleAggregation) {
5948
+ TAggregationTestCase testCase;
5949
+ testCase.SetQuery (R"(
5950
+ SELECT
5951
+ level, COUNT(*), SUM(id)
5952
+ FROM `/Root/tableWithNulls`
5953
+ WHERE level = 5
5954
+ GROUP BY level
5955
+ ORDER BY level;
5956
+ )" )
5957
+ .AddExpectedPlanOptions (" KqpBlockReadOlapTableRanges" )
5958
+ .AddExpectedPlanOptions (" WideFromBlocks" )
5959
+ .SetExpectedReply (R"( [[[5];1u;5]])" );
5960
+
5961
+ TestTableWithNulls ({ testCase }, /* generic */ true );
5962
+ }
5963
+
5964
+ Y_UNIT_TEST (BlockGenericSelectAll) {
5965
+ TAggregationTestCase testCase;
5966
+ testCase.SetQuery (R"(
5967
+ SELECT
5968
+ id, resource_id, level
5969
+ FROM `/Root/tableWithNulls`
5970
+ WHERE level != 5 OR level IS NULL
5971
+ ORDER BY id, resource_id, level;
5972
+ )" )
5973
+ .AddExpectedPlanOptions (" KqpBlockReadOlapTableRanges" )
5974
+ .AddExpectedPlanOptions (" WideFromBlocks" )
5975
+ .SetExpectedReply (R"( [[1;#;[1]];[2;#;[2]];[3;#;[3]];[4;#;[4]];[6;["6"];#];[7;["7"];#];[8;["8"];#];[9;["9"];#];[10;["10"];#]])" );
5976
+
5977
+ TestTableWithNulls ({ testCase }, /* generic */ true );
5978
+ }
5886
5979
}
5887
5980
5888
5981
} // namespace NKqp
0 commit comments