aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandrewproni <andrewproni@yandex-team.com>2023-07-06 02:15:56 +0300
committerandrewproni <andrewproni@yandex-team.com>2023-07-06 02:15:56 +0300
commit5cc334cba05a34b5895d365f7e5d2d6b08e2cec0 (patch)
tree2cc3518a82e575cc289831a7782ef0508066ac33
parent66f12c712380b84651e2e59039fbac3ed8f5cd7a (diff)
downloadydb-5cc334cba05a34b5895d365f7e5d2d6b08e2cec0.tar.gz
Syntax and StatsMode params
-rw-r--r--ydb/core/grpc_services/query/rpc_execute_query.cpp15
-rw-r--r--ydb/core/grpc_services/query/rpc_execute_script.cpp4
-rw-r--r--ydb/core/grpc_services/rpc_kqp_base.cpp22
-rw-r--r--ydb/core/grpc_services/rpc_kqp_base.h3
-rw-r--r--ydb/core/kqp/proxy_service/kqp_script_executions.cpp68
-rw-r--r--ydb/core/kqp/proxy_service/kqp_script_executions.h4
-rw-r--r--ydb/core/kqp/run_script_actor/kqp_run_script_actor.cpp15
-rw-r--r--ydb/core/kqp/ut/service/kqp_query_service_ut.cpp106
-rw-r--r--ydb/public/sdk/cpp/client/draft/ydb_query/client.cpp2
-rw-r--r--ydb/public/sdk/cpp/client/draft/ydb_query/query.h2
10 files changed, 201 insertions, 40 deletions
diff --git a/ydb/core/grpc_services/query/rpc_execute_query.cpp b/ydb/core/grpc_services/query/rpc_execute_query.cpp
index fbc118017c..08b7f86f49 100644
--- a/ydb/core/grpc_services/query/rpc_execute_query.cpp
+++ b/ydb/core/grpc_services/query/rpc_execute_query.cpp
@@ -113,21 +113,6 @@ bool FillTxControl(const Ydb::Query::TransactionControl& from, Ydb::Table::Trans
return true;
}
-Ydb::Table::QueryStatsCollection::Mode GetCollectStatsMode(Ydb::Query::StatsMode mode) {
- switch (mode) {
- case Ydb::Query::StatsMode::STATS_MODE_NONE:
- return Ydb::Table::QueryStatsCollection::STATS_COLLECTION_NONE;
- case Ydb::Query::StatsMode::STATS_MODE_BASIC:
- return Ydb::Table::QueryStatsCollection::STATS_COLLECTION_BASIC;
- case Ydb::Query::StatsMode::STATS_MODE_FULL:
- return Ydb::Table::QueryStatsCollection::STATS_COLLECTION_FULL;
- case Ydb::Query::StatsMode::STATS_MODE_PROFILE:
- return Ydb::Table::QueryStatsCollection::STATS_COLLECTION_PROFILE;
- default:
- return Ydb::Table::QueryStatsCollection::STATS_COLLECTION_UNSPECIFIED;
- }
-}
-
bool ParseQueryAction(const Ydb::Query::ExecuteQueryRequest& req, NKikimrKqp::EQueryAction& queryAction,
NYql::TIssues& issues)
{
diff --git a/ydb/core/grpc_services/query/rpc_execute_script.cpp b/ydb/core/grpc_services/query/rpc_execute_script.cpp
index 0a3c34db61..a4919ad913 100644
--- a/ydb/core/grpc_services/query/rpc_execute_script.cpp
+++ b/ydb/core/grpc_services/query/rpc_execute_script.cpp
@@ -44,7 +44,6 @@ bool FillQueryContent(const Ydb::Query::ExecuteScriptRequest& req, NKikimrKqp::T
}
}
-
std::tuple<Ydb::StatusIds::StatusCode, NYql::TIssues> FillKqpRequest(
const Ydb::Query::ExecuteScriptRequest& req, NKikimrKqp::TEvQueryRequest& kqpRequest)
{
@@ -66,7 +65,8 @@ std::tuple<Ydb::StatusIds::StatusCode, NYql::TIssues> FillKqpRequest(
}
}
-
+ kqpRequest.MutableRequest()->SetCollectStats(GetCollectStatsMode(req.stats_mode()));
+ kqpRequest.MutableRequest()->SetSyntax(req.script_content().syntax());
kqpRequest.MutableRequest()->SetType(NKikimrKqp::QUERY_TYPE_SQL_GENERIC_SCRIPT);
kqpRequest.MutableRequest()->SetKeepSession(false);
diff --git a/ydb/core/grpc_services/rpc_kqp_base.cpp b/ydb/core/grpc_services/rpc_kqp_base.cpp
index 350832e351..35d06393af 100644
--- a/ydb/core/grpc_services/rpc_kqp_base.cpp
+++ b/ydb/core/grpc_services/rpc_kqp_base.cpp
@@ -3,9 +3,9 @@
namespace NKikimr {
namespace NGRpcService {
-void FillQueryStats(Ydb::TableStats::QueryStats& queryStats, const NKikimrKqp::TQueryResponse& kqpResponse) {
- const auto& kqpStats = kqpResponse.GetQueryStats();
+
+void FillQueryStats(Ydb::TableStats::QueryStats& queryStats, const NKqpProto::TKqpStatsQuery& kqpStats) {
uint64_t totalCpuTimeUs = 0;
for (auto& exec : kqpStats.GetExecutions()) {
@@ -65,9 +65,27 @@ void FillQueryStats(Ydb::TableStats::QueryStats& queryStats, const NKikimrKqp::T
queryStats.set_process_cpu_time_us(kqpStats.GetWorkerCpuTimeUs());
queryStats.set_total_cpu_time_us(totalCpuTimeUs);
queryStats.set_total_duration_us(kqpStats.GetDurationUs());
+}
+void FillQueryStats(Ydb::TableStats::QueryStats& queryStats, const NKikimrKqp::TQueryResponse& kqpResponse) {
+ FillQueryStats(queryStats, kqpResponse.GetQueryStats());
queryStats.set_query_plan(kqpResponse.GetQueryPlan());
}
+Ydb::Table::QueryStatsCollection::Mode GetCollectStatsMode(Ydb::Query::StatsMode mode) {
+ switch (mode) {
+ case Ydb::Query::StatsMode::STATS_MODE_NONE:
+ return Ydb::Table::QueryStatsCollection::STATS_COLLECTION_NONE;
+ case Ydb::Query::StatsMode::STATS_MODE_BASIC:
+ return Ydb::Table::QueryStatsCollection::STATS_COLLECTION_BASIC;
+ case Ydb::Query::StatsMode::STATS_MODE_FULL:
+ return Ydb::Table::QueryStatsCollection::STATS_COLLECTION_FULL;
+ case Ydb::Query::StatsMode::STATS_MODE_PROFILE:
+ return Ydb::Table::QueryStatsCollection::STATS_COLLECTION_PROFILE;
+ default:
+ return Ydb::Table::QueryStatsCollection::STATS_COLLECTION_UNSPECIFIED;
+ }
+}
+
} // namespace NGRpcService
} // namespace NKikimr
diff --git a/ydb/core/grpc_services/rpc_kqp_base.h b/ydb/core/grpc_services/rpc_kqp_base.h
index 43c66ec464..c1451f4af5 100644
--- a/ydb/core/grpc_services/rpc_kqp_base.h
+++ b/ydb/core/grpc_services/rpc_kqp_base.h
@@ -74,8 +74,11 @@ inline bool CheckQuery(const TString& query, NYql::TIssues& issues) {
return true;
}
+void FillQueryStats(Ydb::TableStats::QueryStats& queryStats, const NKqpProto::TKqpStatsQuery& kqpStats);
void FillQueryStats(Ydb::TableStats::QueryStats& queryStats, const NKikimrKqp::TQueryResponse& kqpResponse);
+Ydb::Table::QueryStatsCollection::Mode GetCollectStatsMode(Ydb::Query::StatsMode mode);
+
template <typename TDerived, typename TRequest>
class TRpcKqpRequestActor : public TRpcOperationRequestActor<TDerived, TRequest> {
using TBase = TRpcOperationRequestActor<TDerived, TRequest>;
diff --git a/ydb/core/kqp/proxy_service/kqp_script_executions.cpp b/ydb/core/kqp/proxy_service/kqp_script_executions.cpp
index 34e0dc069a..8f256f91b1 100644
--- a/ydb/core/kqp/proxy_service/kqp_script_executions.cpp
+++ b/ydb/core/kqp/proxy_service/kqp_script_executions.cpp
@@ -3,6 +3,7 @@
#include <ydb/core/base/path.h>
#include <ydb/core/base/tablet_pipe.h>
+#include <ydb/core/grpc_services/rpc_kqp_base.h>
#include <ydb/core/kqp/common/events/events.h>
#include <ydb/core/kqp/common/kqp_script_executions.h>
#include <ydb/core/kqp/run_script_actor/kqp_run_script_actor.h>
@@ -356,6 +357,7 @@ private:
Col("meta", NScheme::NTypeIds::JsonDocument),
Col("parameters", NScheme::NTypeIds::String), // TODO: store aparameters separately to support bigger storage.
Col("result_set_metas", NScheme::NTypeIds::JsonDocument),
+ Col("stats", NScheme::NTypeIds::JsonDocument),
},
{ "database", "execution_id" }
)
@@ -490,7 +492,7 @@ public:
.Utf8(Request.GetRequest().GetQuery())
.Build()
.AddParam("$syntax")
- .Int32(Ydb::Query::SYNTAX_YQL_V1)
+ .Int32(Request.GetRequest().GetSyntax())
.Build()
.AddParam("$lease_duration")
.Interval(static_cast<i64>(LeaseDuration.MicroSeconds()))
@@ -727,12 +729,14 @@ private:
IRetryPolicy::IRetryState::TPtr RetryState = nullptr;
};
+
class TScriptExecutionFinisherBase : public TQueryBase {
public:
using TQueryBase::TQueryBase;
void FinishScriptExecution(const TString& database, const TString& executionId, Ydb::StatusIds::StatusCode operationStatus, Ydb::Query::ExecStatus execStatus,
- const NYql::TIssues& issues = LeaseExpiredIssues(), TTxControl txControl = TTxControl::ContinueAndCommitTx(), TString queryPlan = "{}") {
+ const NYql::TIssues& issues = LeaseExpiredIssues(), TTxControl txControl = TTxControl::ContinueAndCommitTx(),
+ TMaybe<NKqpProto::TKqpStatsQuery> kqpStats = Nothing(), TMaybe<TString> queryPlan = Nothing(), TMaybe<TString> queryAst = Nothing()) {
TString sql = R"(
DECLARE $database AS Text;
DECLARE $execution_id AS Text;
@@ -740,6 +744,8 @@ public:
DECLARE $execution_status AS Int32;
DECLARE $issues AS JsonDocument;
DECLARE $plan AS JsonDocument;
+ DECLARE $stats AS JsonDocument;
+ DECLARE $ast AS Text;
UPDATE `.metadata/script_executions`
SET
@@ -747,13 +753,24 @@ public:
execution_status = $execution_status,
issues = $issues,
plan = $plan,
- end_ts = CurrentUtcTimestamp()
+ end_ts = CurrentUtcTimestamp(),
+ stats = $stats,
+ ast = $ast
WHERE database = $database AND execution_id = $execution_id;
DELETE FROM `.metadata/script_execution_leases`
WHERE database = $database AND execution_id = $execution_id;
)";
+ TString serializedStats = "{}";
+ if (kqpStats) {
+ NJson::TJsonValue statsJson;
+ Ydb::TableStats::QueryStats queryStats;
+ NGRpcService::FillQueryStats(queryStats, *kqpStats);
+ NProtobufJson::Proto2Json(queryStats, statsJson, NProtobufJson::TProto2JsonConfig());
+ serializedStats = NJson::WriteJson(statsJson);
+ }
+
NYdb::TParamsBuilder params;
params
.AddParam("$database")
@@ -772,9 +789,15 @@ public:
.JsonDocument(SerializeIssues(issues))
.Build()
.AddParam("$plan")
- .JsonDocument(queryPlan)
+ .JsonDocument(queryPlan.GetOrElse("{}"))
+ .Build()
+ .AddParam("$stats")
+ .JsonDocument(serializedStats)
+ .Build()
+ .AddParam("$ast")
+ .Utf8(queryAst.GetOrElse(""))
.Build();
-
+
RunDataQuery(sql, &params, txControl);
}
@@ -802,7 +825,9 @@ public:
Ydb::StatusIds::StatusCode operationStatus,
Ydb::Query::ExecStatus execStatus,
NYql::TIssues issues,
- TString queryPlan = "{}"
+ TMaybe<NKqpProto::TKqpStatsQuery> queryStats = Nothing(),
+ TMaybe<TString> queryPlan = Nothing(),
+ TMaybe<TString> queryAst = Nothing()
)
: Database(database)
, ExecutionId(executionId)
@@ -810,7 +835,9 @@ public:
, OperationStatus(operationStatus)
, ExecStatus(execStatus)
, Issues(std::move(issues))
+ , QueryStats(std::move(queryStats))
, QueryPlan(std::move(queryPlan))
+ , QueryAst(std::move(queryAst))
{
}
@@ -860,7 +887,7 @@ public:
return;
}
- FinishScriptExecution(Database, ExecutionId, OperationStatus, ExecStatus, Issues, TTxControl::ContinueAndCommitTx(), QueryPlan);
+ FinishScriptExecution(Database, ExecutionId, OperationStatus, ExecStatus, Issues, TTxControl::ContinueAndCommitTx(), std::move(QueryStats), std::move(QueryPlan), std::move(QueryAst));
FinishWasRun = true;
} else {
Finish();
@@ -880,7 +907,9 @@ private:
const Ydb::StatusIds::StatusCode OperationStatus;
const Ydb::Query::ExecStatus ExecStatus;
const NYql::TIssues Issues;
- const TString QueryPlan;
+ const TMaybe<NKqpProto::TKqpStatsQuery> QueryStats;
+ const TMaybe<TString> QueryPlan;
+ const TMaybe<TString> QueryAst;
bool FinishWasRun = false;
};
@@ -1140,7 +1169,9 @@ public:
execution_mode,
result_set_metas,
plan,
- issues
+ issues,
+ stats,
+ ast
FROM `.metadata/script_executions`
WHERE database = $database AND execution_id = $execution_id;
@@ -1209,11 +1240,23 @@ public:
metadata.set_exec_mode(static_cast<Ydb::Query::ExecMode>(*executionMode));
}
+ const TMaybe<TString> serializedStats = result.ColumnParser("stats").GetOptionalJsonDocument();
+ if (serializedStats) {
+ NJson::TJsonValue statsJson;
+ NJson::ReadJsonTree(*serializedStats, &statsJson);
+ NProtobufJson::Json2Proto(statsJson, *metadata.mutable_exec_stats(), NProtobufJson::TJson2ProtoConfig());
+ }
+
const TMaybe<TString> plan = result.ColumnParser("plan").GetOptionalJsonDocument();
if (plan) {
metadata.mutable_exec_stats()->set_query_plan(*plan);
}
+ const TMaybe<TString> ast = result.ColumnParser("ast").GetOptionalUtf8();
+ if (ast) {
+ metadata.mutable_exec_stats()->set_query_ast(*ast);
+ }
+
const TMaybe<TString> issuesSerialized = result.ColumnParser("issues").GetOptionalJsonDocument();
if (issuesSerialized) {
Issues = DeserializeIssues(*issuesSerialized);
@@ -2021,9 +2064,12 @@ NActors::IActor* CreateScriptExecutionFinisher(
Ydb::StatusIds::StatusCode operationStatus,
Ydb::Query::ExecStatus execStatus,
NYql::TIssues issues,
- TString queryPlan)
+ TMaybe<NKqpProto::TKqpStatsQuery> queryStats,
+ TMaybe<TString> queryPlan,
+ TMaybe<TString> queryAst
+ )
{
- return new TScriptExecutionFinisher(executionId, database, leaseGeneration, operationStatus, execStatus, std::move(issues), std::move(queryPlan));
+ return new TScriptExecutionFinisher(executionId, database, leaseGeneration, operationStatus, execStatus, std::move(issues), std::move(queryStats), std::move(queryPlan), std::move(queryAst));
}
NActors::IActor* CreateForgetScriptExecutionOperationActor(TEvForgetScriptExecutionOperation::TPtr ev) {
diff --git a/ydb/core/kqp/proxy_service/kqp_script_executions.h b/ydb/core/kqp/proxy_service/kqp_script_executions.h
index 39fecad109..2aaaa65f9c 100644
--- a/ydb/core/kqp/proxy_service/kqp_script_executions.h
+++ b/ydb/core/kqp/proxy_service/kqp_script_executions.h
@@ -30,7 +30,9 @@ NActors::IActor* CreateScriptExecutionFinisher(
Ydb::StatusIds::StatusCode operationStatus,
Ydb::Query::ExecStatus execStatus,
NYql::TIssues issues,
- TString queryPlan = "{}"
+ TMaybe<NKqpProto::TKqpStatsQuery> queryStats = Nothing(),
+ TMaybe<TString> queryPlan = Nothing(),
+ TMaybe<TString> queryAst = Nothing()
);
// Updates lease deadline in database.
diff --git a/ydb/core/kqp/run_script_actor/kqp_run_script_actor.cpp b/ydb/core/kqp/run_script_actor/kqp_run_script_actor.cpp
index 95bca8895a..507e7771b7 100644
--- a/ydb/core/kqp/run_script_actor/kqp_run_script_actor.cpp
+++ b/ydb/core/kqp/run_script_actor/kqp_run_script_actor.cpp
@@ -166,8 +166,7 @@ private:
if (!FinalStatusIsSaved) {
FinalStatusIsSaved = true;
Register(CreateScriptExecutionFinisher(ExecutionId, Database, LeaseGeneration, Status, GetExecStatusFromStatusCode(Status),
- Issues, std::move(QueryPlan)));
- return;
+ Issues, std::move(QueryStats), std::move(QueryPlan), std::move(QueryAst)));
}
if (RunState != ERunState::Cancelled && RunState != ERunState::Finished) {
@@ -308,6 +307,14 @@ private:
QueryPlan = record.GetResponse().GetQueryPlan();
}
+ if (record.GetResponse().HasQueryStats()) {
+ QueryStats = record.GetResponse().GetQueryStats();
+ }
+
+ if (record.GetResponse().HasQueryAst()) {
+ QueryAst = record.GetResponse().GetQueryAst();
+ }
+
Finish(record.GetYdbStatus());
}
@@ -476,7 +483,9 @@ private:
ui32 SaveResultInflight = 0;
ui32 SaveResultMetaInflight = 0;
bool PendingResultMeta = false;
- TString QueryPlan = "{}";
+ TMaybe<TString> QueryPlan;
+ TMaybe<TString> QueryAst;
+ TMaybe<NKqpProto::TKqpStatsQuery> QueryStats;
};
} // namespace
diff --git a/ydb/core/kqp/ut/service/kqp_query_service_ut.cpp b/ydb/core/kqp/ut/service/kqp_query_service_ut.cpp
index 64b8b4f227..95bb3d9de1 100644
--- a/ydb/core/kqp/ut/service/kqp_query_service_ut.cpp
+++ b/ydb/core/kqp/ut/service/kqp_query_service_ut.cpp
@@ -329,16 +329,19 @@ Y_UNIT_TEST_SUITE(KqpQueryService) {
UNIT_ASSERT_VALUES_EQUAL(totalTasks, 2);
}
- NYdb::NQuery::TScriptExecutionOperation WaitScriptExecutionOperation(const NYdb::TOperation::TOperationId& operationId, const NYdb::TDriver& ydbDriver) {
+ NYdb::NQuery::TScriptExecutionOperation WaitScriptExecutionOperation(const NYdb::TOperation::TOperationId& operationId, const NYdb::TDriver& ydbDriver, i32 tries = -1) {
NYdb::NOperation::TOperationClient client(ydbDriver);
NThreading::TFuture<NYdb::NQuery::TScriptExecutionOperation> op;
do {
if (!op.Initialized()) {
Sleep(TDuration::MilliSeconds(10));
}
+ if (tries > 0) {
+ --tries;
+ }
op = client.Get<NYdb::NQuery::TScriptExecutionOperation>(operationId);
UNIT_ASSERT_C(op.GetValueSync().Status().IsSuccess(), op.GetValueSync().Status().GetStatus() << ":" << op.GetValueSync().Status().GetIssues().ToString());
- } while (!op.GetValueSync().Ready());
+ } while (!op.GetValueSync().Ready() && tries != 0);
return op.GetValueSync();
}
@@ -408,6 +411,14 @@ Y_UNIT_TEST_SUITE(KqpQueryService) {
}
}
+ void ValidatePlan(const TString& plan) {
+ UNIT_ASSERT(!plan.empty());
+ UNIT_ASSERT(plan != "{}");
+ NJson::TJsonValue jsonPlan;
+ NJson::ReadJsonTree(plan, &jsonPlan, true);
+ UNIT_ASSERT(ValidatePlanNodeIds(jsonPlan));
+ }
+
Y_UNIT_TEST(ExplainScript) {
auto kikimr = DefaultKikimrRunner();
auto db = kikimr.GetQueryClient();
@@ -424,11 +435,8 @@ Y_UNIT_TEST_SUITE(KqpQueryService) {
UNIT_ASSERT_EQUAL(readyOp.Metadata().ExecMode, EExecMode::Explain);
UNIT_ASSERT_EQUAL(readyOp.Metadata().ExecutionId, scriptExecutionOperation.Metadata().ExecutionId);
UNIT_ASSERT_STRING_CONTAINS(readyOp.Metadata().ScriptContent.Text, "SELECT 42");
- UNIT_ASSERT(!readyOp.Metadata().ExecStats.query_plan().empty());
- NJson::TJsonValue plan;
- NJson::ReadJsonTree(readyOp.Metadata().ExecStats.query_plan(), &plan, true);
- UNIT_ASSERT(ValidatePlanNodeIds(plan));
+ ValidatePlan(readyOp.Metadata().ExecStats.query_plan());
}
Y_UNIT_TEST(ParseScript) {
@@ -476,6 +484,92 @@ Y_UNIT_TEST_SUITE(KqpQueryService) {
UNIT_ASSERT_EQUAL_C(scriptExecutionOperation.Status().GetIssues().back().GetMessage(), "Query mode is not specified", scriptExecutionOperation.Status().GetIssues().ToString());
}
+ Y_UNIT_TEST(ExecuteScriptPg) {
+ auto kikimr = DefaultKikimrRunner();
+ auto db = kikimr.GetQueryClient();
+
+ auto settings = TExecuteScriptSettings()
+ .Syntax(Ydb::Query::SYNTAX_PG);
+
+ auto scriptExecutionOperation = db.ExecuteScript(R"(
+ SELECT * FROM (VALUES
+ (1::int8, 'one'),
+ (2::int8, 'two'),
+ (3::int8, 'three')
+ ) AS t;
+ )", settings).ExtractValueSync();
+
+ UNIT_ASSERT_VALUES_EQUAL_C(scriptExecutionOperation.Status().GetStatus(), EStatus::SUCCESS, scriptExecutionOperation.Status().GetIssues().ToString());
+ UNIT_ASSERT(scriptExecutionOperation.Metadata().ExecutionId);
+
+ NYdb::NQuery::TScriptExecutionOperation readyOp = WaitScriptExecutionOperation(scriptExecutionOperation.Id(), kikimr.GetDriver());
+ UNIT_ASSERT_EQUAL_C(readyOp.Metadata().ExecStatus, EExecStatus::Completed, readyOp.Status().GetIssues().ToString());
+ UNIT_ASSERT_EQUAL(readyOp.Metadata().ExecMode, EExecMode::Execute);
+ UNIT_ASSERT_EQUAL(readyOp.Metadata().ExecutionId, scriptExecutionOperation.Metadata().ExecutionId);
+ UNIT_ASSERT_EQUAL(readyOp.Metadata().ScriptContent.Syntax, ESyntax::Pg);
+
+ TFetchScriptResultsResult results = db.FetchScriptResults(scriptExecutionOperation, 0).ExtractValueSync();
+ UNIT_ASSERT_C(results.IsSuccess(), results.GetIssues().ToString());
+
+ CompareYson(R"([
+ ["1";"one"];
+ ["2";"two"];
+ ["3";"three"]
+ ])", FormatResultSetYson(results.GetResultSet()));
+ }
+
+
+ void ExecuteScriptWithStatsMode (Ydb::Query::StatsMode statsMode) {
+ auto kikimr = DefaultKikimrRunner();
+ auto db = kikimr.GetQueryClient();
+
+ auto settings = TExecuteScriptSettings()
+ .StatsMode(statsMode);
+
+ auto scriptExecutionOperation = db.ExecuteScript(R"(
+ SELECT 42
+ )", settings).ExtractValueSync();
+ UNIT_ASSERT_VALUES_EQUAL_C(scriptExecutionOperation.Status().GetStatus(), EStatus::SUCCESS, scriptExecutionOperation.Status().GetIssues().ToString());
+ UNIT_ASSERT(scriptExecutionOperation.Metadata().ExecutionId);
+
+ auto readyOp = WaitScriptExecutionOperation(scriptExecutionOperation.Id(), kikimr.GetDriver());
+ UNIT_ASSERT_EQUAL_C(readyOp.Metadata().ExecStatus, EExecStatus::Completed, readyOp.Status().GetIssues().ToString());
+ UNIT_ASSERT_EQUAL(readyOp.Metadata().ExecMode, EExecMode::Execute);
+ UNIT_ASSERT_EQUAL(readyOp.Metadata().ExecutionId, scriptExecutionOperation.Metadata().ExecutionId);
+ UNIT_ASSERT_STRING_CONTAINS(readyOp.Metadata().ScriptContent.Text, "SELECT 42");
+
+ if (statsMode == Ydb::Query::STATS_MODE_NONE) {
+ return;
+ }
+
+ // TODO: more checks?
+ UNIT_ASSERT_C(readyOp.Metadata().ExecStats.query_phases_size() == 1, readyOp.Metadata().ExecStats);
+ UNIT_ASSERT_C(readyOp.Metadata().ExecStats.total_duration_us() > 0, readyOp.Metadata().ExecStats);
+
+ if (statsMode == Ydb::Query::STATS_MODE_BASIC) {
+ return;
+ }
+
+ ValidatePlan(readyOp.Metadata().ExecStats.query_plan());
+ }
+
+
+ Y_UNIT_TEST(ExecuteScriptStatsBasic) {
+ ExecuteScriptWithStatsMode(Ydb::Query::STATS_MODE_BASIC);
+ }
+
+ Y_UNIT_TEST(ExecuteScriptStatsFull) {
+ ExecuteScriptWithStatsMode(Ydb::Query::STATS_MODE_FULL);
+ }
+
+ Y_UNIT_TEST(ExecuteScriptStatsProfile) {
+ ExecuteScriptWithStatsMode(Ydb::Query::STATS_MODE_PROFILE);
+ }
+
+ Y_UNIT_TEST(ExecuteScriptStatsNone) {
+ ExecuteScriptWithStatsMode(Ydb::Query::STATS_MODE_NONE);
+ }
+
Y_UNIT_TEST(ListScriptExecutions) {
auto kikimr = DefaultKikimrRunner();
auto db = kikimr.GetQueryClient();
diff --git a/ydb/public/sdk/cpp/client/draft/ydb_query/client.cpp b/ydb/public/sdk/cpp/client/draft/ydb_query/client.cpp
index 571ada740a..1c66094594 100644
--- a/ydb/public/sdk/cpp/client/draft/ydb_query/client.cpp
+++ b/ydb/public/sdk/cpp/client/draft/ydb_query/client.cpp
@@ -38,6 +38,8 @@ public:
using namespace Ydb::Query;
auto request = MakeOperationRequest<ExecuteScriptRequest>(settings);
request.set_exec_mode(settings.ExecMode_);
+ request.set_stats_mode(settings.StatsMode_);
+ request.mutable_script_content()->set_syntax(settings.Syntax_);
request.mutable_script_content()->set_text(script);
auto promise = NThreading::NewPromise<TScriptExecutionOperation>();
diff --git a/ydb/public/sdk/cpp/client/draft/ydb_query/query.h b/ydb/public/sdk/cpp/client/draft/ydb_query/query.h
index d07a96a94b..8fd44070ff 100644
--- a/ydb/public/sdk/cpp/client/draft/ydb_query/query.h
+++ b/ydb/public/sdk/cpp/client/draft/ydb_query/query.h
@@ -127,7 +127,9 @@ private:
using TAsyncExecuteQueryResult = NThreading::TFuture<TExecuteQueryResult>;
struct TExecuteScriptSettings : public TOperationRequestSettings<TExecuteScriptSettings> {
+ FLUENT_SETTING_DEFAULT(Ydb::Query::Syntax, Syntax, Ydb::Query::SYNTAX_YQL_V1);
FLUENT_SETTING_DEFAULT(Ydb::Query::ExecMode, ExecMode, Ydb::Query::EXEC_MODE_EXECUTE);
+ FLUENT_SETTING_DEFAULT(Ydb::Query::StatsMode, StatsMode, Ydb::Query::STATS_MODE_NONE);
};
class TVersionedScriptId {