Skip to content

Commit 1c5b4a3

Browse files
authored
Merge b486489 into 1c39afc
2 parents 1c39afc + b486489 commit 1c5b4a3

File tree

6 files changed

+75
-9
lines changed

6 files changed

+75
-9
lines changed

ydb/core/grpc_services/query/rpc_execute_script.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,6 @@ std::tuple<Ydb::StatusIds::StatusCode, NYql::TIssues> FillKqpRequest(
5959
kqpRequest.MutableRequest()->SetType(NKikimrKqp::QUERY_TYPE_SQL_GENERIC_SCRIPT);
6060
kqpRequest.MutableRequest()->SetKeepSession(false);
6161

62-
// TODO: Avoid explicit tx_control for script queries.
63-
kqpRequest.MutableRequest()->MutableTxControl()->mutable_begin_tx()->mutable_serializable_read_write();
64-
kqpRequest.MutableRequest()->MutableTxControl()->set_commit_tx(true);
65-
6662
kqpRequest.MutableRequest()->SetCancelAfterMs(GetDuration(req.operation_params().cancel_after()).MilliSeconds());
6763
kqpRequest.MutableRequest()->SetTimeoutMs(GetDuration(req.operation_params().operation_timeout()).MilliSeconds());
6864

ydb/core/kqp/session_actor/kqp_query_state.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,4 +306,21 @@ bool TKqpQueryState::HasErrors(const NSchemeCache::TSchemeCacheNavigate& respons
306306
return true;
307307
}
308308

309+
bool TKqpQueryState::HasImpliedAutostartTransactions() const {
310+
if (!HasTxControl()
311+
&& (RequestEv->GetAction() == NKikimrKqp::QUERY_ACTION_EXECUTE
312+
|| RequestEv->GetAction() == NKikimrKqp::QUERY_ACTION_EXECUTE_PREPARED)
313+
&& (RequestEv->GetType() == NKikimrKqp::QUERY_TYPE_SQL_GENERIC_QUERY
314+
|| RequestEv->GetType() == NKikimrKqp::QUERY_TYPE_SQL_GENERIC_SCRIPT
315+
|| RequestEv->GetType() == NKikimrKqp::QUERY_TYPE_SQL_GENERIC_CONCURRENT_QUERY))
316+
{
317+
for (const auto& transactionPtr : PreparedQuery->GetTransactions()) {
318+
if (transactionPtr->GetType() == NKqpProto::TKqpPhyTx::TYPE_GENERIC) { // data transaction
319+
return true;
320+
}
321+
}
322+
}
323+
return false;
324+
}
325+
309326
}

ydb/core/kqp/session_actor/kqp_query_state.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,8 @@ class TKqpQueryState : public TNonCopyable {
362362
return RequestEv->HasTxControl();
363363
}
364364

365+
bool HasImpliedAutostartTransactions() const;
366+
365367
const ::Ydb::Table::TransactionControl& GetTxControl() const {
366368
return RequestEv->GetTxControl();
367369
}

ydb/core/kqp/session_actor/kqp_session_actor.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -636,9 +636,21 @@ class TKqpSessionActor : public TActorBootstrapped<TKqpSessionActor> {
636636
Counters->ReportBeginTransaction(Settings.DbCounters, Transactions.EvictedTx, Transactions.Size(), Transactions.ToBeAbortedSize());
637637
}
638638

639+
static const Ydb::Table::TransactionControl& GetAutoTransactionControl() {
640+
auto create = []() -> Ydb::Table::TransactionControl {
641+
Ydb::Table::TransactionControl control;
642+
control.mutable_begin_tx()->mutable_serializable_read_write();
643+
control.set_commit_tx(true);
644+
return control;
645+
};
646+
static const Ydb::Table::TransactionControl control = create();
647+
return control;
648+
}
649+
639650
bool PrepareQueryTransaction() {
640-
if (QueryState->HasTxControl()) {
641-
const auto& txControl = QueryState->GetTxControl();
651+
bool autoTransaction = false;
652+
if (QueryState->HasTxControl() || (autoTransaction = QueryState->HasImpliedAutostartTransactions())) {
653+
const auto& txControl = autoTransaction ? GetAutoTransactionControl() : QueryState->GetTxControl();
642654

643655
QueryState->Commit = txControl.commit_tx();
644656
switch (txControl.tx_selector_case()) {
@@ -941,7 +953,7 @@ class TKqpSessionActor : public TActorBootstrapped<TKqpSessionActor> {
941953
case NKqpProto::TKqpPhyTx::TYPE_SCHEME:
942954
YQL_ENSURE(tx->StagesSize() == 0);
943955

944-
if (QueryState->TxCtx->EffectiveIsolationLevel != NKikimrKqp::ISOLATION_LEVEL_UNDEFINED) {
956+
if (QueryState->HasTxControl() && QueryState->TxCtx->EffectiveIsolationLevel != NKikimrKqp::ISOLATION_LEVEL_UNDEFINED) {
945957
ReplyQueryError(Ydb::StatusIds::PRECONDITION_FAILED,
946958
"Scheme operations cannot be executed inside transaction");
947959
return true;

ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1463,6 +1463,45 @@ Y_UNIT_TEST_SUITE(KqpQueryService) {
14631463
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::PRECONDITION_FAILED, result.GetIssues().ToString());
14641464
}
14651465

1466+
Y_UNIT_TEST(DdlExecuteScript) {
1467+
NKikimrConfig::TAppConfig appConfig;
1468+
appConfig.MutableTableServiceConfig()->SetEnablePreparedDdl(true);
1469+
auto setting = NKikimrKqp::TKqpSetting();
1470+
auto serverSettings = TKikimrSettings()
1471+
.SetAppConfig(appConfig)
1472+
.SetKqpSettings({setting})
1473+
.SetEnableScriptExecutionOperations(true);
1474+
1475+
TKikimrRunner kikimr(serverSettings);
1476+
auto db = kikimr.GetQueryClient();
1477+
1478+
const TString sql = R"sql(
1479+
CREATE TABLE TestDdlExecuteScript (
1480+
Key Uint64,
1481+
Value String,
1482+
PRIMARY KEY (Key)
1483+
);
1484+
)sql";
1485+
1486+
auto scriptExecutionOperation = db.ExecuteScript(sql).ExtractValueSync();
1487+
UNIT_ASSERT_VALUES_EQUAL_C(scriptExecutionOperation.Status().GetStatus(), EStatus::SUCCESS, scriptExecutionOperation.Status().GetIssues().ToString());
1488+
UNIT_ASSERT(scriptExecutionOperation.Metadata().ExecutionId);
1489+
1490+
NYdb::NOperation::TOperationClient client(kikimr.GetDriver());
1491+
TMaybe<NYdb::NQuery::TScriptExecutionOperation> readyOp;
1492+
while (true) {
1493+
auto op = client.Get<NYdb::NQuery::TScriptExecutionOperation>(scriptExecutionOperation.Id()).GetValueSync();
1494+
if (op.Ready()) {
1495+
readyOp = std::move(op);
1496+
break;
1497+
}
1498+
UNIT_ASSERT_C(op.Status().IsSuccess(), TStringBuilder() << op.Status().GetStatus() << ":" << op.Status().GetIssues().ToString());
1499+
Sleep(TDuration::MilliSeconds(10));
1500+
}
1501+
UNIT_ASSERT_C(readyOp->Status().IsSuccess(), readyOp->Status().GetIssues().ToString());
1502+
UNIT_ASSERT_EQUAL_C(readyOp->Metadata().ExecStatus, EExecStatus::Completed, readyOp->Status().GetIssues().ToString());
1503+
}
1504+
14661505
Y_UNIT_TEST(DdlMixedDml) {
14671506
NKikimrConfig::TAppConfig appConfig;
14681507
appConfig.MutableTableServiceConfig()->SetEnablePreparedDdl(true);
@@ -1495,7 +1534,7 @@ Y_UNIT_TEST_SUITE(KqpQueryService) {
14951534
UPSERT INTO KeyValue (Key, Value) VALUES (3, "Three");
14961535
SELECT * FROM KeyValue;
14971536
)", TTxControl::NoTx()).ExtractValueSync();
1498-
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::PRECONDITION_FAILED, result.GetIssues().ToString());
1537+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
14991538
}
15001539

15011540
Y_UNIT_TEST(Tcl) {

ydb/core/kqp/ut/service/kqp_qs_scripts_ut.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ Y_UNIT_TEST_SUITE(KqpQueryServiceScripts) {
203203
}
204204

205205

206-
void ExecuteScriptWithStatsMode (Ydb::Query::StatsMode statsMode) {
206+
void ExecuteScriptWithStatsMode(Ydb::Query::StatsMode statsMode) {
207207
auto kikimr = DefaultKikimrRunner();
208208
auto db = kikimr.GetQueryClient();
209209

0 commit comments

Comments
 (0)