diff --git a/ydb/core/kqp/opt/kqp_query_plan.cpp b/ydb/core/kqp/opt/kqp_query_plan.cpp index 50d81bbca4d5..ea2a2bf32a7c 100644 --- a/ydb/core/kqp/opt/kqp_query_plan.cpp +++ b/ydb/core/kqp/opt/kqp_query_plan.cpp @@ -1721,12 +1721,13 @@ class TxPlanSerializer { AddReadTableSettings(op, read, readInfo); - if (read.Maybe()) { + if (auto maybeRead = read.Maybe()) { op.Properties["SsaProgram"] = GetSsaProgramInJsonByTable(table, planNode.StageProto); + AddOptimizerEstimates(op, maybeRead.Cast().Process()); + } else { + AddOptimizerEstimates(op, read); } - AddOptimizerEstimates(op, read); - auto readName = GetNameByReadType(readInfo.Type); op.Properties["Name"] = readName; ui32 operatorId = AddOperator(planNode, readName, std::move(op)); @@ -2386,7 +2387,7 @@ void RemoveStats(NJson::TJsonValue& plan) { NJson::TJsonValue SimplifyQueryPlan(NJson::TJsonValue& plan) { static const THashSet redundantNodes = { - "UnionAll", + "UnionAll", "Broadcast", "Map", "HashShuffle", diff --git a/ydb/core/kqp/ut/join/data/queries/test_join_hint.sql b/ydb/core/kqp/ut/join/data/queries/test_join_hint1.sql similarity index 100% rename from ydb/core/kqp/ut/join/data/queries/test_join_hint.sql rename to ydb/core/kqp/ut/join/data/queries/test_join_hint1.sql diff --git a/ydb/core/kqp/ut/join/kqp_join_order_ut.cpp b/ydb/core/kqp/ut/join/kqp_join_order_ut.cpp index 1027b08e013f..55e4f6f8fa56 100644 --- a/ydb/core/kqp/ut/join/kqp_join_order_ut.cpp +++ b/ydb/core/kqp/ut/join/kqp_join_order_ut.cpp @@ -5,6 +5,7 @@ #include +#include #include #include @@ -93,8 +94,17 @@ static TKikimrRunner GetKikimrWithJoinSettings(bool useStreamLookupJoin = false, void PrintPlan(const TString& plan) { Cout << plan << Endl; - NYdb::NConsoleClient::TQueryPlanPrinter queryPlanPrinter(NYdb::NConsoleClient::EDataFormat::PrettyTable, true, Cout, 150); + NYdb::NConsoleClient::TQueryPlanPrinter queryPlanPrinter(NYdb::NConsoleClient::EDataFormat::PrettyTable, true, Cout, 0); queryPlanPrinter.Print(plan); + + std::string joinOrder = GetJoinOrder(plan).GetStringRobust(); + + Cout << "JoinOrder: " << joinOrder << Endl; + std::replace(joinOrder.begin(), joinOrder.end(), '[', '('); + std::replace(joinOrder.begin(), joinOrder.end(), ']', ')'); + std::replace(joinOrder.begin(), joinOrder.end(), ',', ' '); + joinOrder.erase(std::remove(joinOrder.begin(), joinOrder.end(), '\"'), joinOrder.end()); + Cout << "JoinOrder" << joinOrder << Endl; } class TChainTester { @@ -355,13 +365,6 @@ Y_UNIT_TEST_SUITE(KqpJoinOrder) { } } - /* tpcds23 has > 1 result sets */ - Y_UNIT_TEST_XOR_OR_BOTH_FALSE(TPCDS23, StreamLookupJoin, ColumnStore) { - ExplainJoinOrderTestDataQueryWithStats( - "queries/tpcds23.sql", "stats/tpcds1000s.json", StreamLookupJoin, ColumnStore - ); - } - Y_UNIT_TEST_XOR_OR_BOTH_FALSE(FiveWayJoin, StreamLookupJoin, ColumnStore) { ExecuteJoinOrderTestDataQueryWithStats( "queries/five_way_join.sql", "stats/basic.json", StreamLookupJoin, ColumnStore @@ -410,14 +413,6 @@ Y_UNIT_TEST_SUITE(KqpJoinOrder) { ); } - Y_UNIT_TEST_XOR_OR_BOTH_FALSE(TestJoinHint, StreamLookupJoin, ColumnStore) { - CheckJoinCardinality("queries/test_join_hint.sql", "stats/basic.json", "InnerJoin (Grace)", 10e6, StreamLookupJoin, ColumnStore); - } - - Y_UNIT_TEST_XOR_OR_BOTH_FALSE(TestJoinHint2, StreamLookupJoin, ColumnStore) { - CheckJoinCardinality("queries/test_join_hint2.sql", "stats/basic.json", "InnerJoin (MapJoin)", 1, StreamLookupJoin, ColumnStore); - } - Y_UNIT_TEST_XOR_OR_BOTH_FALSE(FiveWayJoinWithConstantFold, StreamLookupJoin, ColumnStore) { ExecuteJoinOrderTestDataQueryWithStats("queries/five_way_join_with_constant_fold.sql", "stats/basic.json", StreamLookupJoin, ColumnStore); } @@ -458,6 +453,13 @@ Y_UNIT_TEST_SUITE(KqpJoinOrder) { ExecuteJoinOrderTestDataQueryWithStats("queries/tpcds16.sql", "stats/tpcds1000s.json", StreamLookupJoin, ColumnStore); } + /* tpcds23 has > 1 result sets */ + Y_UNIT_TEST_XOR_OR_BOTH_FALSE(TPCDS23, StreamLookupJoin, ColumnStore) { + ExplainJoinOrderTestDataQueryWithStats( + "queries/tpcds23.sql", "stats/tpcds1000s.json", StreamLookupJoin, ColumnStore + ); + } + Y_UNIT_TEST_XOR_OR_BOTH_FALSE(TPCDS34, StreamLookupJoin, ColumnStore) { ExecuteJoinOrderTestDataQueryWithStats("queries/tpcds34.sql", "stats/tpcds1000s.json", StreamLookupJoin, ColumnStore); } @@ -494,6 +496,14 @@ Y_UNIT_TEST_SUITE(KqpJoinOrder) { ExecuteJoinOrderTestDataQueryWithStats("queries/tpcds96.sql", "stats/tpcds1000s.json", StreamLookupJoin, ColumnStore); } + Y_UNIT_TEST_XOR_OR_BOTH_FALSE(TestJoinHint1, StreamLookupJoin, ColumnStore) { + CheckJoinCardinality("queries/test_join_hint1.sql", "stats/basic.json", "InnerJoin (Grace)", 10e6, StreamLookupJoin, ColumnStore); + } + + Y_UNIT_TEST_XOR_OR_BOTH_FALSE(TestJoinHint2, StreamLookupJoin, ColumnStore) { + CheckJoinCardinality("queries/test_join_hint2.sql", "stats/basic.json", "InnerJoin (MapJoin)", 1, StreamLookupJoin, ColumnStore); + } + Y_UNIT_TEST_XOR_OR_BOTH_FALSE(TestJoinOrderHintsSimple, StreamLookupJoin, ColumnStore) { auto plan = ExecuteJoinOrderTestDataQueryWithStats("queries/join_order_hints_simple.sql", "stats/basic.json", StreamLookupJoin, ColumnStore); UNIT_ASSERT_VALUES_EQUAL(GetJoinOrder(plan).GetStringRobust(), R"(["T",["R","S"]])") ; @@ -512,7 +522,7 @@ Y_UNIT_TEST_SUITE(KqpJoinOrder) { UNIT_ASSERT_C(joinOrder.find(R"(["T","U"])") != TString::npos, joinOrder); } - void JoinOrderTestWithOverridenStats(const TString& queryPath, const TString& statsPath, TString correctJoinOrderPath, bool useStreamLookupJoin, bool useColumnStore + void CanonizedJoinOrderTest(const TString& queryPath, const TString& statsPath, TString correctJoinOrderPath, bool useStreamLookupJoin, bool useColumnStore ) { auto kikimr = GetKikimrWithJoinSettings(useStreamLookupJoin, GetStatic(statsPath)); auto db = kikimr.GetTableClient(); @@ -557,44 +567,44 @@ Y_UNIT_TEST_SUITE(KqpJoinOrder) { } } - Y_UNIT_TEST_XOR_OR_BOTH_FALSE(OverrideStatsTPCH2, StreamLookupJoin, ColumnStore) { - JoinOrderTestWithOverridenStats( + Y_UNIT_TEST_XOR_OR_BOTH_FALSE(CanonizedJoinOrderTPCH2, StreamLookupJoin, ColumnStore) { + CanonizedJoinOrderTest( "queries/tpch2.sql", "stats/tpch1000s.json", "join_order/tpch2_1000s.json", StreamLookupJoin, ColumnStore ); } - Y_UNIT_TEST_XOR_OR_BOTH_FALSE(OverrideStatsTPCH9, StreamLookupJoin, ColumnStore) { - JoinOrderTestWithOverridenStats( + Y_UNIT_TEST_XOR_OR_BOTH_FALSE(CanonizedJoinOrderTPCH9, StreamLookupJoin, ColumnStore) { + CanonizedJoinOrderTest( "queries/tpch9.sql", "stats/tpch1000s.json", "join_order/tpch9_1000s.json", StreamLookupJoin, ColumnStore ); } - Y_UNIT_TEST_XOR_OR_BOTH_FALSE(OverrideStatsTPCDS64, StreamLookupJoin, ColumnStore) { - JoinOrderTestWithOverridenStats( + Y_UNIT_TEST_XOR_OR_BOTH_FALSE(CanonizedJoinOrderTPCDS64, StreamLookupJoin, ColumnStore) { + CanonizedJoinOrderTest( "queries/tpcds64.sql", "stats/tpcds1000s.json", "join_order/tpcds64_1000s.json", StreamLookupJoin, ColumnStore ); } - Y_UNIT_TEST_XOR_OR_BOTH_FALSE(OverrideStatsTPCDS64_small, StreamLookupJoin, ColumnStore) { - JoinOrderTestWithOverridenStats( + Y_UNIT_TEST_XOR_OR_BOTH_FALSE(CanonizedJoinOrderTPCDS64_small, StreamLookupJoin, ColumnStore) { + CanonizedJoinOrderTest( "queries/tpcds64_small.sql", "stats/tpcds1000s.json", "join_order/tpcds64_small_1000s.json", StreamLookupJoin, ColumnStore ); } - Y_UNIT_TEST_XOR_OR_BOTH_FALSE(OverrideStatsTPCDS78, StreamLookupJoin, ColumnStore) { - JoinOrderTestWithOverridenStats( + Y_UNIT_TEST_XOR_OR_BOTH_FALSE(CanonizedJoinOrderTPCDS78, StreamLookupJoin, ColumnStore) { + CanonizedJoinOrderTest( "queries/tpcds78.sql", "stats/tpcds1000s.json", "join_order/tpcds78_1000s.json", StreamLookupJoin, ColumnStore ); } - Y_UNIT_TEST(TPCC) { - JoinOrderTestWithOverridenStats( + Y_UNIT_TEST(CanonizedJoinOrderTPCC) { + CanonizedJoinOrderTest( "queries/tpcc.sql", "stats/tpcc.json", "join_order/tpcc.json", false, false ); } - Y_UNIT_TEST(LookupBug) { - JoinOrderTestWithOverridenStats( + Y_UNIT_TEST(CanonizedJoinOrderLookupBug) { + CanonizedJoinOrderTest( "queries/lookupbug.sql", "stats/lookupbug.json", "join_order/lookupbug.json", false, false ); }