Skip to content

Commit 0a09f29

Browse files
ExecuteData set transaction mode always (#7982)
Co-authored-by: Ivan Sukhov <[email protected]>
1 parent bdb5777 commit 0a09f29

File tree

2 files changed

+90
-1
lines changed

2 files changed

+90
-1
lines changed

ydb/core/viewer/json_query.h

+4
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,10 @@ class TJsonQuery : public TViewerPipeClient<TJsonQuery> {
210210
request.SetType(NKikimrKqp::QUERY_TYPE_SQL_DML);
211211
request.SetKeepSession(false);
212212
SetTransactionMode(request);
213+
if (!request.txcontrol().has_begin_tx()) {
214+
request.mutable_txcontrol()->mutable_begin_tx()->mutable_serializable_read_write();
215+
request.mutable_txcontrol()->set_commit_tx(true);
216+
}
213217
} else if (Action == "explain" || Action == "explain-ast" || Action == "explain-data") {
214218
request.SetAction(NKikimrKqp::QUERY_ACTION_EXPLAIN);
215219
request.SetType(NKikimrKqp::QUERY_TYPE_SQL_DML);

ydb/core/viewer/viewer_ut.cpp

+86-1
Original file line numberDiff line numberDiff line change
@@ -1115,6 +1115,91 @@ Y_UNIT_TEST_SUITE(Viewer) {
11151115
size_t AuthorizeTicketFails = 0;
11161116
};
11171117

1118+
TString PostQuery(TKeepAliveHttpClient& httpClient, TString query, TString action = "", TString transactionMode = "", HttpCodes expectedCode = HTTP_OK) {
1119+
TStringStream requestBody;
1120+
requestBody
1121+
<< "{ \"query\": \"" << query << "\","
1122+
<< " \"database\": \"/Root\","
1123+
<< " \"action\": \"" << action << "\","
1124+
<< " \"syntax\": \"yql_v1\","
1125+
<< " \"transaction_mode\": \"" << transactionMode << "\","
1126+
<< " \"stats\": \"none\" }";
1127+
TStringStream responseStream;
1128+
TKeepAliveHttpClient::THeaders headers;
1129+
headers["Content-Type"] = "application/json";
1130+
headers["Authorization"] = "test_ydb_token";
1131+
const TKeepAliveHttpClient::THttpCode statusCode = httpClient.DoPost("/viewer/json/query?timeout=600000&base64=false&schema=modern", requestBody.Str(), &responseStream, headers);
1132+
const TString response = responseStream.ReadAll();
1133+
UNIT_ASSERT_EQUAL_C(statusCode, expectedCode, statusCode << ": " << response);
1134+
return response;
1135+
}
1136+
1137+
Y_UNIT_TEST(ExecuteQueryDoesntExecuteSchemeOperationsInsideTransation) {
1138+
TPortManager tp;
1139+
ui16 port = tp.GetPort(2134);
1140+
ui16 grpcPort = tp.GetPort(2135);
1141+
ui16 monPort = tp.GetPort(8765);
1142+
auto settings = TServerSettings(port);
1143+
settings.InitKikimrRunConfig()
1144+
.SetNodeCount(1)
1145+
.SetUseRealThreads(true)
1146+
.SetDomainName("Root")
1147+
.SetMonitoringPortOffset(monPort, true);
1148+
1149+
TServer server(settings);
1150+
server.EnableGRpc(grpcPort);
1151+
TClient client(settings);
1152+
client.InitRootScheme();
1153+
1154+
TTestActorRuntime& runtime = *server.GetRuntime();
1155+
runtime.SetLogPriority(NKikimrServices::TICKET_PARSER, NLog::PRI_TRACE);
1156+
1157+
TKeepAliveHttpClient httpClient("localhost", monPort);
1158+
1159+
//Scheme operations cannot be executed inside transaction
1160+
TString response = PostQuery(httpClient, "CREATE TABLE `/Root/Test` (Key Uint64, Value String, PRIMARY KEY (Key));", "execute-query", "serializable-read-write", HTTP_BAD_REQUEST);
1161+
{
1162+
NJson::TJsonReaderConfig jsonCfg;
1163+
NJson::TJsonValue json;
1164+
NJson::ReadJsonTree(response, &jsonCfg, &json, /* throwOnError = */ true);
1165+
UNIT_ASSERT_EQUAL_C(json["error"].GetMap().at("message").GetString(), "Scheme operations cannot be executed inside transaction", response);
1166+
}
1167+
}
1168+
1169+
Y_UNIT_TEST(UseTransactionWhenExecuteDataActionQuery) {
1170+
TPortManager tp;
1171+
ui16 port = tp.GetPort(2134);
1172+
ui16 grpcPort = tp.GetPort(2135);
1173+
ui16 monPort = tp.GetPort(8765);
1174+
auto settings = TServerSettings(port);
1175+
settings.InitKikimrRunConfig()
1176+
.SetNodeCount(1)
1177+
.SetUseRealThreads(true)
1178+
.SetDomainName("Root")
1179+
.SetMonitoringPortOffset(monPort, true);
1180+
1181+
TServer server(settings);
1182+
server.EnableGRpc(grpcPort);
1183+
TClient client(settings);
1184+
client.InitRootScheme();
1185+
1186+
TTestActorRuntime& runtime = *server.GetRuntime();
1187+
runtime.SetLogPriority(NKikimrServices::TICKET_PARSER, NLog::PRI_TRACE);
1188+
1189+
TKeepAliveHttpClient httpClient("localhost", monPort);
1190+
1191+
PostQuery(httpClient, "CREATE TABLE `/Root/Test` (Key Uint64, Value String, PRIMARY KEY (Key));", "execute-query");
1192+
PostQuery(httpClient, "INSERT INTO `/Root/Test` (Key, Value) VALUES (1, 'testvalue');", "execute-query");
1193+
TString response = PostQuery(httpClient, "SELECT * FROM `/Root/Test`;", "execute-data");
1194+
{
1195+
NJson::TJsonReaderConfig jsonCfg;
1196+
NJson::TJsonValue json;
1197+
NJson::ReadJsonTree(response, &jsonCfg, &json, /* throwOnError = */ true);
1198+
auto resultSets = json["result"].GetArray();
1199+
UNIT_ASSERT_EQUAL_C(1, resultSets.size(), response);
1200+
}
1201+
}
1202+
11181203
Y_UNIT_TEST(FloatPointJsonQuery) {
11191204
TPortManager tp;
11201205
ui16 port = tp.GetPort(2134);
@@ -1210,7 +1295,7 @@ Y_UNIT_TEST_SUITE(Viewer) {
12101295
"database": "/Root",
12111296
"action": "execute-script",
12121297
"syntax": "yql_v1",
1213-
"stats": "profile"
1298+
"stats": "none"
12141299
})json";
12151300
const TKeepAliveHttpClient::THttpCode statusCode = httpClient.DoPost("/viewer/json/query?timeout=600000&base64=false&schema=modern", requestBody, &responseStream, headers);
12161301
const TString response = responseStream.ReadAll();

0 commit comments

Comments
 (0)