diff --git a/ydb/core/kqp/opt/kqp_query_plan.cpp b/ydb/core/kqp/opt/kqp_query_plan.cpp index 86152bcdf838..9b47a4ae6484 100644 --- a/ydb/core/kqp/opt/kqp_query_plan.cpp +++ b/ydb/core/kqp/opt/kqp_query_plan.cpp @@ -244,8 +244,8 @@ class TxPlanSerializer { planNode.TypeName = "Effect"; Visit(TExprBase(stage), planNode); } else if (stageBase.Outputs()) { // Sink + AFL_ENSURE(stageBase.Outputs().Cast().Size() == 1); auto& planNode = AddPlanNode(phaseNode); - planNode.TypeName = "Sink"; Visit(TExprBase(stage), planNode); } } @@ -960,7 +960,8 @@ class TxPlanSerializer { if (auto outputs = expr.Cast().Outputs()) { for (auto output : outputs.Cast()) { if (auto sink = output.Maybe()) { - Visit(sink.Cast(), expr.Cast(), stagePlanNode); + AFL_ENSURE(outputs.Cast().Size() == 1); + Visit(sink.Cast(), expr.Cast(), planNode); } } } diff --git a/ydb/core/kqp/ut/federated_query/s3/kqp_s3_plan_ut.cpp b/ydb/core/kqp/ut/federated_query/s3/kqp_s3_plan_ut.cpp index c839b0f63b88..2ec1aae6f9af 100644 --- a/ydb/core/kqp/ut/federated_query/s3/kqp_s3_plan_ut.cpp +++ b/ydb/core/kqp/ut/federated_query/s3/kqp_s3_plan_ut.cpp @@ -143,9 +143,12 @@ Y_UNIT_TEST_SUITE(KqpS3PlanTest) { UNIT_ASSERT(NJson::ReadJsonTree(*queryResult.GetStats()->GetPlan(), &plan)); const auto& writeStagePlan = plan["Plan"]["Plans"][0]["Plans"][0]; - UNIT_ASSERT_VALUES_EQUAL(writeStagePlan["Node Type"].GetStringSafe(), "Stage-Sink"); - UNIT_ASSERT(writeStagePlan["Operators"].GetArraySafe().size() >= 1); - const auto& sinkOp = writeStagePlan["Operators"].GetArraySafe()[0]; + UNIT_ASSERT_VALUES_EQUAL(writeStagePlan["Node Type"].GetStringSafe(), "Stage"); + + const auto& sinkPlan = plan["Plan"]["Plans"][0]; + UNIT_ASSERT_VALUES_EQUAL(sinkPlan["Node Type"].GetStringSafe(), "Sink"); + UNIT_ASSERT(sinkPlan["Operators"].GetArraySafe().size() >= 1); + const auto& sinkOp = sinkPlan["Operators"].GetArraySafe()[0]; UNIT_ASSERT_VALUES_EQUAL(sinkOp["ExternalDataSource"].GetStringSafe(), "write_data_source"); UNIT_ASSERT_VALUES_EQUAL(sinkOp["Compression"].GetStringSafe(), "gzip"); @@ -218,9 +221,16 @@ Y_UNIT_TEST_SUITE(KqpS3PlanTest) { UNIT_ASSERT(NJson::ReadJsonTree(*queryResult.GetStats()->GetPlan(), &plan)); const auto& writeStagePlan = plan["Plan"]["Plans"][0]["Plans"][0]; - UNIT_ASSERT_VALUES_EQUAL(writeStagePlan["Node Type"].GetStringSafe(), "Stage-Sink"); + UNIT_ASSERT_VALUES_EQUAL(writeStagePlan["Node Type"].GetStringSafe(), "Stage"); UNIT_ASSERT_VALUES_EQUAL(writeStagePlan["Stats"]["Tasks"], 1); + const auto& sinkPlan = plan["Plan"]["Plans"][0]; + UNIT_ASSERT_VALUES_EQUAL(sinkPlan["Node Type"].GetStringSafe(), "Sink"); + UNIT_ASSERT(sinkPlan["Operators"].GetArraySafe().size() >= 1); + const auto& sinkOp = sinkPlan["Operators"].GetArraySafe()[0]; + UNIT_ASSERT_VALUES_EQUAL(sinkOp["Name"].GetStringSafe(), "FillTable"); + UNIT_ASSERT_VALUES_EQUAL(sinkOp["Table"].GetStringSafe(), "result_table"); + const auto& readStagePlan = plan["Plan"]["Plans"][0]["Plans"][0]["Plans"][0]["Plans"][0]; UNIT_ASSERT_VALUES_EQUAL(readStagePlan["Node Type"].GetStringSafe(), "Stage"); UNIT_ASSERT_VALUES_EQUAL(readStagePlan["Stats"]["Tasks"], 1); @@ -290,9 +300,16 @@ Y_UNIT_TEST_SUITE(KqpS3PlanTest) { UNIT_ASSERT(NJson::ReadJsonTree(*queryResult.GetStats()->GetPlan(), &plan)); const auto& writeStagePlan = plan["Plan"]["Plans"][0]["Plans"][0]; - UNIT_ASSERT_VALUES_EQUAL(writeStagePlan["Node Type"].GetStringSafe(), "Stage-Sink"); + UNIT_ASSERT_VALUES_EQUAL(writeStagePlan["Node Type"].GetStringSafe(), "Stage"); UNIT_ASSERT_VALUES_EQUAL(writeStagePlan["Stats"]["Tasks"], 42); + const auto& sinkPlan = plan["Plan"]["Plans"][0]; + UNIT_ASSERT_VALUES_EQUAL(sinkPlan["Node Type"].GetStringSafe(), "Sink"); + UNIT_ASSERT(sinkPlan["Operators"].GetArraySafe().size() >= 1); + const auto& sinkOp = sinkPlan["Operators"].GetArraySafe()[0]; + UNIT_ASSERT_VALUES_EQUAL(sinkOp["ExternalDataSource"].GetStringSafe(), "insert_data_sink"); + UNIT_ASSERT_VALUES_EQUAL(sinkOp["Extension"].GetStringSafe(), ".parquet"); + const auto& readStagePlan = plan["Plan"]["Plans"][0]["Plans"][0]["Plans"][0]["Plans"][0]; UNIT_ASSERT_VALUES_EQUAL(readStagePlan["Node Type"].GetStringSafe(), "TableFullScan"); UNIT_ASSERT_VALUES_EQUAL(readStagePlan["Stats"]["Tasks"], 42); diff --git a/ydb/core/kqp/ut/query/kqp_stats_ut.cpp b/ydb/core/kqp/ut/query/kqp_stats_ut.cpp index a610a1005b33..ee19d2046fcd 100644 --- a/ydb/core/kqp/ut/query/kqp_stats_ut.cpp +++ b/ydb/core/kqp/ut/query/kqp_stats_ut.cpp @@ -279,7 +279,7 @@ Y_UNIT_TEST_TWIN(DataQueryWithEffects, UseSink) { NJson::ReadJsonTree(result.GetQueryPlan(), &plan, true); if (UseSink) { - auto node = FindPlanNodeByKv(plan, "Node Type", "Stage-Sink"); + auto node = FindPlanNodeByKv(plan, "Node Type", "Stage"); UNIT_ASSERT_EQUAL(node.GetMap().at("Stats").GetMapSafe().at("Tasks").GetIntegerSafe(), 1); } else { auto node = FindPlanNodeByKv(plan, "Node Type", "Upsert-ConstantExpr"); diff --git a/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_explain.script-script_/explain.script.plan b/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_explain.script-script_/explain.script.plan index 0faa53fd98e5..581652f1a138 100644 --- a/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_explain.script-script_/explain.script.plan +++ b/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_explain.script-script_/explain.script.plan @@ -520,29 +520,31 @@ "Plans": [ { "Node Type": "Sink", + "Operators": [ + { + "Inputs": [], + "Name": "Replace", + "Path": "/local/base_explain_script_script/ScriptingTest", + "SinkType": "KqpTableSink", + "Table": "base_explain_script_script/ScriptingTest" + } + ], "PlanNodeId": 2, "Plans": [ { - "Node Type": "ConstantExpr-Sink", + "Node Type": "ConstantExpr", "Operators": [ { "Inputs": [], "Iterator": "[{Key: 3,Value: \"Three\"},{Key: 4,Value: \"Four\"}]", "Name": "Iterator" - }, - { - "Inputs": [], - "Name": "Replace", - "Path": "/local/base_explain_script_script/ScriptingTest", - "SinkType": "KqpTableSink", - "Table": "base_explain_script_script/ScriptingTest" } ], - "PlanNodeId": 1, - "Tables": [ - "base_explain_script_script/ScriptingTest" - ] + "PlanNodeId": 1 } + ], + "Tables": [ + "base_explain_script_script/ScriptingTest" ] } ], @@ -572,29 +574,31 @@ "Plans": [ { "Node Type": "Sink", + "Operators": [ + { + "Inputs": [], + "Name": "Replace", + "Path": "/local/base_explain_script_script/ScriptingTest", + "SinkType": "KqpTableSink", + "Table": "base_explain_script_script/ScriptingTest" + } + ], "PlanNodeId": 2, "Plans": [ { - "Node Type": "ConstantExpr-Sink", + "Node Type": "ConstantExpr", "Operators": [ { "Inputs": [], "Iterator": "[{Key: 1,Value: \"One\"},{Key: 2,Value: \"Two\"}]", "Name": "Iterator" - }, - { - "Inputs": [], - "Name": "Replace", - "Path": "/local/base_explain_script_script/ScriptingTest", - "SinkType": "KqpTableSink", - "Table": "base_explain_script_script/ScriptingTest" } ], - "PlanNodeId": 1, - "Tables": [ - "base_explain_script_script/ScriptingTest" - ] + "PlanNodeId": 1 } + ], + "Tables": [ + "base_explain_script_script/ScriptingTest" ] } ], diff --git a/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_join_group_by_lookup.script-script_/join_group_by_lookup.script.plan b/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_join_group_by_lookup.script-script_/join_group_by_lookup.script.plan index 67e5fb9fa820..d24bb2c08af4 100644 --- a/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_join_group_by_lookup.script-script_/join_group_by_lookup.script.plan +++ b/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_join_group_by_lookup.script-script_/join_group_by_lookup.script.plan @@ -282,29 +282,31 @@ "Plans": [ { "Node Type": "Sink", + "Operators": [ + { + "Inputs": [], + "Name": "Replace", + "Path": "/local/base_join_group_by_lookup_script_script/Temp", + "SinkType": "KqpTableSink", + "Table": "base_join_group_by_lookup_script_script/Temp" + } + ], "PlanNodeId": 2, "Plans": [ { - "Node Type": "ConstantExpr-Sink", + "Node Type": "ConstantExpr", "Operators": [ { "Inputs": [], "Iterator": "[{Group: 1,Value: \"One\"},{Group: 3,Value: \"Three\"}]", "Name": "Iterator" - }, - { - "Inputs": [], - "Name": "Replace", - "Path": "/local/base_join_group_by_lookup_script_script/Temp", - "SinkType": "KqpTableSink", - "Table": "base_join_group_by_lookup_script_script/Temp" } ], - "PlanNodeId": 1, - "Tables": [ - "base_join_group_by_lookup_script_script/Temp" - ] + "PlanNodeId": 1 } + ], + "Tables": [ + "base_join_group_by_lookup_script_script/Temp" ] } ], diff --git a/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_simple_ct.script-script_/simple_ct.script.plan b/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_simple_ct.script-script_/simple_ct.script.plan index 10512bcaaa79..a767440d0255 100644 --- a/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_simple_ct.script-script_/simple_ct.script.plan +++ b/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_simple_ct.script-script_/simple_ct.script.plan @@ -11,29 +11,31 @@ "Plans": [ { "Node Type": "Sink", + "Operators": [ + { + "Inputs": [], + "Name": "Upsert", + "Path": "/local/base_simple_ct_script_script/Questions", + "SinkType": "KqpTableSink", + "Table": "base_simple_ct_script_script/Questions" + } + ], "PlanNodeId": 2, "Plans": [ { - "Node Type": "ConstantExpr-Sink", + "Node Type": "ConstantExpr", "Operators": [ { "Inputs": [], "Iterator": "[{idx: 1,text: \"to do or not to do\"}]", "Name": "Iterator" - }, - { - "Inputs": [], - "Name": "Upsert", - "Path": "/local/base_simple_ct_script_script/Questions", - "SinkType": "KqpTableSink", - "Table": "base_simple_ct_script_script/Questions" } ], - "PlanNodeId": 1, - "Tables": [ - "base_simple_ct_script_script/Questions" - ] + "PlanNodeId": 1 } + ], + "Tables": [ + "base_simple_ct_script_script/Questions" ] } ], diff --git a/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_table_types.script-script_/table_types.script.plan b/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_table_types.script-script_/table_types.script.plan index 4f05136f0ad5..56d733d6119f 100644 --- a/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_table_types.script-script_/table_types.script.plan +++ b/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_table_types.script-script_/table_types.script.plan @@ -136,29 +136,31 @@ "Plans": [ { "Node Type": "Sink", + "Operators": [ + { + "Inputs": [], + "Name": "Replace", + "Path": "/local/base_table_types_script_script/TableTypes", + "SinkType": "KqpTableSink", + "Table": "base_table_types_script_script/TableTypes" + } + ], "PlanNodeId": 2, "Plans": [ { - "Node Type": "ConstantExpr-Sink", + "Node Type": "ConstantExpr", "Operators": [ { "Inputs": [], "Iterator": "[{Key: \"Key\",Value01: \"true\",Value02: 1,Value03: -1,Value04: 2,Value05: -2,Value06: 3,Value07: \"4.5\",Value08: Minus,Value09: \"3.14\",Value10: DyNumber,Value21: \"\\u041F\\u0440\\u0438\\u0432\\u0435\\u0442\",Value22: \"{\\\"name\\\": \\\"George\\\", \\\"age\\\": 23}\",Value23: JsonDocument,Value24: \"{a=1; b=2}\",Value31: Apply,Value32: Apply,Value33: Apply,Value34: Apply}]", "Name": "Iterator" - }, - { - "Inputs": [], - "Name": "Replace", - "Path": "/local/base_table_types_script_script/TableTypes", - "SinkType": "KqpTableSink", - "Table": "base_table_types_script_script/TableTypes" } ], - "PlanNodeId": 1, - "Tables": [ - "base_table_types_script_script/TableTypes" - ] + "PlanNodeId": 1 } + ], + "Tables": [ + "base_table_types_script_script/TableTypes" ] } ], diff --git a/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_write_multi_usage.script-script_/write_multi_usage.script.plan b/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_write_multi_usage.script-script_/write_multi_usage.script.plan index d47da6224a7e..9fa06e2b486e 100644 --- a/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_write_multi_usage.script-script_/write_multi_usage.script.plan +++ b/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_write_multi_usage.script-script_/write_multi_usage.script.plan @@ -217,19 +217,19 @@ "Plans": [ { "Node Type": "Sink", + "Operators": [ + { + "Inputs": [], + "Name": "Upsert", + "Path": "/local/base_write_multi_usage_script_script/Temp", + "SinkType": "KqpTableSink", + "Table": "base_write_multi_usage_script_script/Temp" + } + ], "PlanNodeId": 7, "Plans": [ { - "Node Type": "Stage-Sink", - "Operators": [ - { - "Inputs": [], - "Name": "Upsert", - "Path": "/local/base_write_multi_usage_script_script/Temp", - "SinkType": "KqpTableSink", - "Table": "base_write_multi_usage_script_script/Temp" - } - ], + "Node Type": "Stage", "PlanNodeId": 6, "Plans": [ { @@ -268,38 +268,40 @@ } ] } - ], - "Tables": [ - "base_write_multi_usage_script_script/Temp" ] } + ], + "Tables": [ + "base_write_multi_usage_script_script/Temp" ] }, { "Node Type": "Sink", + "Operators": [ + { + "Inputs": [], + "Name": "Delete", + "Path": "/local/base_write_multi_usage_script_script/Input1", + "SinkType": "KqpTableSink", + "Table": "base_write_multi_usage_script_script/Input1" + } + ], "PlanNodeId": 2, "Plans": [ { - "Node Type": "ConstantExpr-Sink", + "Node Type": "ConstantExpr", "Operators": [ { "Inputs": [], "Iterator": "[{Group: 1,Name: ToString}]", "Name": "Iterator" - }, - { - "Inputs": [], - "Name": "Delete", - "Path": "/local/base_write_multi_usage_script_script/Input1", - "SinkType": "KqpTableSink", - "Table": "base_write_multi_usage_script_script/Input1" } ], - "PlanNodeId": 1, - "Tables": [ - "base_write_multi_usage_script_script/Input1" - ] + "PlanNodeId": 1 } + ], + "Tables": [ + "base_write_multi_usage_script_script/Input1" ] } ], diff --git a/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_write_multi_usage_key.script-script_/write_multi_usage_key.script.plan b/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_write_multi_usage_key.script-script_/write_multi_usage_key.script.plan index 073b8bb49d0b..2a522bf93955 100644 --- a/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_write_multi_usage_key.script-script_/write_multi_usage_key.script.plan +++ b/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_write_multi_usage_key.script-script_/write_multi_usage_key.script.plan @@ -105,19 +105,19 @@ "Plans": [ { "Node Type": "Sink", + "Operators": [ + { + "Inputs": [], + "Name": "Upsert", + "Path": "/local/base_write_multi_usage_key_script_script/Temp", + "SinkType": "KqpTableSink", + "Table": "base_write_multi_usage_key_script_script/Temp" + } + ], "PlanNodeId": 5, "Plans": [ { - "Node Type": "Stage-Sink", - "Operators": [ - { - "Inputs": [], - "Name": "Upsert", - "Path": "/local/base_write_multi_usage_key_script_script/Temp", - "SinkType": "KqpTableSink", - "Table": "base_write_multi_usage_key_script_script/Temp" - } - ], + "Node Type": "Stage", "PlanNodeId": 4, "Plans": [ { @@ -169,11 +169,11 @@ } ] } - ], - "Tables": [ - "base_write_multi_usage_key_script_script/Temp" ] } + ], + "Tables": [ + "base_write_multi_usage_key_script_script/Temp" ] } ], diff --git a/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_write_write_group_by.script-script_/write_write_group_by.script.plan b/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_write_write_group_by.script-script_/write_write_group_by.script.plan index 64e854f08dad..c0f56a9055ec 100644 --- a/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_write_write_group_by.script-script_/write_write_group_by.script.plan +++ b/ydb/tests/functional/canonical/canondata/test_sql.TestCanonicalFolder1.test_case_write_write_group_by.script-script_/write_write_group_by.script.plan @@ -107,19 +107,19 @@ "Plans": [ { "Node Type": "Sink", + "Operators": [ + { + "Inputs": [], + "Name": "Upsert", + "Path": "/local/base_write_write_group_by_script_script/Temp", + "SinkType": "KqpTableSink", + "Table": "base_write_write_group_by_script_script/Temp" + } + ], "PlanNodeId": 7, "Plans": [ { - "Node Type": "Stage-Sink", - "Operators": [ - { - "Inputs": [], - "Name": "Upsert", - "Path": "/local/base_write_write_group_by_script_script/Temp", - "SinkType": "KqpTableSink", - "Table": "base_write_write_group_by_script_script/Temp" - } - ], + "Node Type": "Stage", "PlanNodeId": 6, "Plans": [ { @@ -200,11 +200,11 @@ } ] } - ], - "Tables": [ - "base_write_write_group_by_script_script/Temp" ] } + ], + "Tables": [ + "base_write_write_group_by_script_script/Temp" ] } ],