From be5610b5263a271766d7be9dc615749048a622c8 Mon Sep 17 00:00:00 2001 From: Nikita Vasilev Date: Fri, 28 Nov 2025 14:17:08 +0300 Subject: [PATCH 1/3] fix --- .../kqp/executer_actor/kqp_data_executer.cpp | 3 +- ydb/core/kqp/opt/kqp_opt_effects.cpp | 22 ++++++++++ .../kqp/session_actor/kqp_session_actor.cpp | 29 +++++++------ ydb/core/kqp/ut/olap/kqp_olap_ut.cpp | 42 ++++++++++++++----- ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp | 3 +- 5 files changed, 73 insertions(+), 26 deletions(-) diff --git a/ydb/core/kqp/executer_actor/kqp_data_executer.cpp b/ydb/core/kqp/executer_actor/kqp_data_executer.cpp index 6e7c17681ef0..9d7684330fa9 100644 --- a/ydb/core/kqp/executer_actor/kqp_data_executer.cpp +++ b/ydb/core/kqp/executer_actor/kqp_data_executer.cpp @@ -1882,7 +1882,8 @@ class TKqpDataExecuter : public TKqpExecuterBaseGetType(), stage))) { - auto error = TStringBuilder() << "Data manipulation queries do not support column shard tables."; + auto error = TStringBuilder() + << "Data manipulation queries with column-oriented tables are supported only by API QueryService."; LOG_E(error); ReplyErrorAndDie(Ydb::StatusIds::PRECONDITION_FAILED, YqlIssue({}, NYql::TIssuesIds::KIKIMR_PRECONDITION_FAILED, error)); diff --git a/ydb/core/kqp/opt/kqp_opt_effects.cpp b/ydb/core/kqp/opt/kqp_opt_effects.cpp index 9e2d5a103e01..a919e88515d2 100644 --- a/ydb/core/kqp/opt/kqp_opt_effects.cpp +++ b/ydb/core/kqp/opt/kqp_opt_effects.cpp @@ -207,6 +207,17 @@ bool BuildUpsertRowsEffect(const TKqlUpsertRows& node, TExprContext& ctx, const const bool isOlap = (table.Metadata->Kind == EKikimrTableKind::Olap); const i64 priority = isOlap ? 0 : order; + if (isOlap && !(kqpCtx.IsGenericQuery() || (kqpCtx.IsDataQuery() && kqpCtx.Config->AllowOlapDataQuery))) { + ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), + TStringBuilder() << "Data manipulation queries with column-oriented tables are supported only by API QueryService.")); + return false; + } + if (isOlap && !kqpCtx.Config->EnableOlapSink) { + ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), + TStringBuilder() << "Data manipulation queries with column-oriented are disabled.")); + return false; + } + if (IsDqPureExpr(node.Input())) { if (sinkEffect) { stageInput = RebuildPureStageWithSink( @@ -350,6 +361,17 @@ bool BuildDeleteRowsEffect(const TKqlDeleteRows& node, TExprContext& ctx, const const bool isOlap = (table.Metadata->Kind == EKikimrTableKind::Olap); const i64 priority = isOlap ? 0 : order; + if (isOlap && !(kqpCtx.IsGenericQuery() || (kqpCtx.IsDataQuery() && kqpCtx.Config->AllowOlapDataQuery))) { + ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), + TStringBuilder() << "Data manipulation queries with column-oriented tables are supported only by API QueryService.")); + return false; + } + if (isOlap && !kqpCtx.Config->EnableOlapSink) { + ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), + TStringBuilder() << "Data manipulation queries with column-oriented are disabled.")); + return false; + } + if (IsDqPureExpr(node.Input())) { if (sinkEffect) { stageInput = RebuildPureStageWithSink( diff --git a/ydb/core/kqp/session_actor/kqp_session_actor.cpp b/ydb/core/kqp/session_actor/kqp_session_actor.cpp index 866d106cb3e8..2676c5d299b8 100644 --- a/ydb/core/kqp/session_actor/kqp_session_actor.cpp +++ b/ydb/core/kqp/session_actor/kqp_session_actor.cpp @@ -1142,32 +1142,35 @@ class TKqpSessionActor : public TActorBootstrapped, IActorExce QueryState->TxCtx->HasOltpTable |= hasOltpWrite || hasOltpRead; QueryState->TxCtx->HasTableWrite |= hasOlapWrite || hasOltpWrite; QueryState->TxCtx->HasTableRead |= hasOlapRead || hasOltpRead; - if (QueryState->TxCtx->HasOlapTable && QueryState->TxCtx->HasOltpTable && QueryState->TxCtx->HasTableWrite - && !QueryState->TxCtx->EnableHtapTx.value_or(false) && !QueryState->IsSplitted()) { - ReplyQueryError(Ydb::StatusIds::PRECONDITION_FAILED, - "Write transactions that use both row-oriented and column-oriented tables are disabled at current time."); - return false; - } - if (QueryState->TxCtx->EffectiveIsolationLevel == NKikimrKqp::ISOLATION_LEVEL_SNAPSHOT_RW - && QueryState->TxCtx->HasOltpTable) { - ReplyQueryError(Ydb::StatusIds::PRECONDITION_FAILED, - "SnapshotRW can only be used with olap tables."); - return false; - } if (QueryState->TxCtx->EffectiveIsolationLevel != NKikimrKqp::ISOLATION_LEVEL_SERIALIZABLE && QueryState->TxCtx->EffectiveIsolationLevel != NKikimrKqp::ISOLATION_LEVEL_SNAPSHOT_RO + && QueryState->TxCtx->EffectiveIsolationLevel != NKikimrKqp::ISOLATION_LEVEL_SNAPSHOT_RW && QueryState->GetType() != NKikimrKqp::QUERY_TYPE_SQL_SCAN && QueryState->GetType() != NKikimrKqp::QUERY_TYPE_AST_SCAN && QueryState->GetType() != NKikimrKqp::QUERY_TYPE_SQL_GENERIC_SCRIPT && QueryState->TxCtx->HasOlapTable) { ReplyQueryError(Ydb::StatusIds::PRECONDITION_FAILED, TStringBuilder() - << "Read from column tables is not supported in Online Read-Only or Stale Read-Only transaction modes. " + << "Read from column-oriented tables is not supported in Online Read-Only or Stale Read-Only transaction modes. " << "Use Serializable or Snapshot Read-Only mode instead."); return false; } + if (QueryState->TxCtx->EffectiveIsolationLevel == NKikimrKqp::ISOLATION_LEVEL_SNAPSHOT_RW + && QueryState->TxCtx->HasOltpTable) { + ReplyQueryError(Ydb::StatusIds::PRECONDITION_FAILED, + "SnapshotRW can only be used with column-oriented tables."); + return false; + } + + if (QueryState->TxCtx->HasOlapTable && QueryState->TxCtx->HasOltpTable && QueryState->TxCtx->HasTableWrite + && !QueryState->TxCtx->EnableHtapTx.value_or(false) && !QueryState->IsSplitted()) { + ReplyQueryError(Ydb::StatusIds::PRECONDITION_FAILED, + "Write transactions that use both row-oriented and column-oriented tables are disabled at current time."); + return false; + } + QueryState->TxCtx->SetTempTables(QueryState->TempTablesState); if (phyQuery.GetForceImmediateEffectsExecution()) { Counters->ForcedImmediateEffectsExecution->Inc(); diff --git a/ydb/core/kqp/ut/olap/kqp_olap_ut.cpp b/ydb/core/kqp/ut/olap/kqp_olap_ut.cpp index 83c1582b3fcb..a112b2014416 100644 --- a/ydb/core/kqp/ut/olap/kqp_olap_ut.cpp +++ b/ydb/core/kqp/ut/olap/kqp_olap_ut.cpp @@ -2894,10 +2894,10 @@ Y_UNIT_TEST_SUITE(KqpOlap) { UNIT_ASSERT(TExtLocalHelper(kikimr).TryCreateTable("olapStore", "olapTable_9", 9)); } - void TestOlapUpsert(ui32 numShards) { + void TestOlapUpsert(ui32 numShards, bool allowOlapDataQuery) { auto settings = TKikimrSettings().SetWithSampleTables(false); settings.AppConfig.MutableTableServiceConfig()->SetEnableOlapSink(true); - settings.AppConfig.MutableTableServiceConfig()->SetAllowOlapDataQuery(true); + settings.AppConfig.MutableTableServiceConfig()->SetAllowOlapDataQuery(allowOlapDataQuery); TKikimrRunner kikimr(settings); auto tableClient = kikimr.GetTableClient(); @@ -2929,7 +2929,15 @@ Y_UNIT_TEST_SUITE(KqpOlap) { (1, 15, 'ccccccc', 23, 1); )", TTxControl::BeginTx(TTxSettings::SerializableRW()).CommitTx()).ExtractValueSync(); // TODO: snapshot isolation? - UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString()); + if (allowOlapDataQuery) { + UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString()); + } else { + UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::GENERIC_ERROR, result.GetIssues().ToString()); + UNIT_ASSERT_C( + result.GetIssues().ToString().contains( + "Data manipulation queries with column-oriented tables are supported only by API QueryService."), + result.GetIssues().ToString()); + } { TString query = R"( @@ -2941,19 +2949,31 @@ Y_UNIT_TEST_SUITE(KqpOlap) { auto it = session.ExecuteDataQuery(query, TTxControl::BeginTx(TTxSettings::SerializableRW()).CommitTx()).GetValueSync(); - UNIT_ASSERT_C(it.IsSuccess(), it.GetIssues().ToString()); - TString result = FormatResultSetYson(it.GetResultSet(0)); - Cout << result << Endl; - CompareYson(result, R"([[15;0];[15;1]])"); + if (allowOlapDataQuery) { + UNIT_ASSERT_C(it.IsSuccess(), it.GetIssues().ToString()); + TString result = FormatResultSetYson(it.GetResultSet(0)); + Cout << result << Endl; + CompareYson(result, R"([[15;0];[15;1]])"); + } else { + UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::GENERIC_ERROR, result.GetIssues().ToString()); + UNIT_ASSERT_C( + result.GetIssues().ToString().contains( + "Data manipulation queries with column-oriented tables are supported only by API QueryService."), + result.GetIssues().ToString()); + } } } - Y_UNIT_TEST(OlapUpsertImmediate) { - TestOlapUpsert(1); + Y_UNIT_TEST(OlapUpsertOneShard) { + TestOlapUpsert(1, true); + } + + Y_UNIT_TEST(OlapUpsertTwoShards) { + TestOlapUpsert(2, true); } - Y_UNIT_TEST(OlapUpsert) { - TestOlapUpsert(2); + Y_UNIT_TEST(OlapUpsertDisabled) { + TestOlapUpsert(2, false); } Y_UNIT_TEST(OlapDeleteImmediate) { diff --git a/ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp b/ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp index f1d89149889a..32404d373528 100644 --- a/ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp +++ b/ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp @@ -5059,7 +5059,8 @@ Y_UNIT_TEST_SUITE(KqpQueryService) { )", NYdb::NQuery::TTxControl::BeginTx().CommitTx()).ExtractValueSync(); UNIT_ASSERT(!prepareResult.IsSuccess()); UNIT_ASSERT_C( - prepareResult.GetIssues().ToString().contains("Data manipulation queries do not support column shard tables."), + prepareResult.GetIssues().ToString().contains( + "Data manipulation queries with column-oriented are disabled."), prepareResult.GetIssues().ToString()); } From 206a23a181500f7832f6b215be30a21f9e3d43e2 Mon Sep 17 00:00:00 2001 From: Nikita Vasilev Date: Fri, 28 Nov 2025 17:27:34 +0300 Subject: [PATCH 2/3] fix --- ydb/core/kqp/ut/olap/kqp_olap_ut.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ydb/core/kqp/ut/olap/kqp_olap_ut.cpp b/ydb/core/kqp/ut/olap/kqp_olap_ut.cpp index a112b2014416..7dae2345daad 100644 --- a/ydb/core/kqp/ut/olap/kqp_olap_ut.cpp +++ b/ydb/core/kqp/ut/olap/kqp_olap_ut.cpp @@ -4733,7 +4733,7 @@ Y_UNIT_TEST_SUITE(KqpOlap) { UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::PRECONDITION_FAILED, result.GetIssues().ToString()); UNIT_ASSERT_STRING_CONTAINS_C( result.GetIssues().ToString(), - "Read from column tables is not supported in Online Read-Only or Stale Read-Only transaction modes.", + "Read from column-oriented tables is not supported in Online Read-Only or Stale Read-Only transaction modes.", result.GetIssues().ToString()); } @@ -4744,7 +4744,7 @@ Y_UNIT_TEST_SUITE(KqpOlap) { UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::PRECONDITION_FAILED, result.GetIssues().ToString()); UNIT_ASSERT_STRING_CONTAINS_C( result.GetIssues().ToString(), - "Read from column tables is not supported in Online Read-Only or Stale Read-Only transaction modes.", + "Read from column-oriented tables is not supported in Online Read-Only or Stale Read-Only transaction modes.", result.GetIssues().ToString()); } } From 0d36b5b2af795b85c8411c8d85a10e013174f1ef Mon Sep 17 00:00:00 2001 From: Nikita Vasilev Date: Mon, 1 Dec 2025 11:21:50 +0300 Subject: [PATCH 3/3] fix --- ydb/core/kqp/opt/kqp_opt_effects.cpp | 4 ++-- ydb/core/kqp/ut/olap/kqp_olap_ut.cpp | 2 +- ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ydb/core/kqp/opt/kqp_opt_effects.cpp b/ydb/core/kqp/opt/kqp_opt_effects.cpp index a919e88515d2..05ca3990b218 100644 --- a/ydb/core/kqp/opt/kqp_opt_effects.cpp +++ b/ydb/core/kqp/opt/kqp_opt_effects.cpp @@ -214,7 +214,7 @@ bool BuildUpsertRowsEffect(const TKqlUpsertRows& node, TExprContext& ctx, const } if (isOlap && !kqpCtx.Config->EnableOlapSink) { ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), - TStringBuilder() << "Data manipulation queries with column-oriented are disabled.")); + TStringBuilder() << "Data manipulation queries with column-oriented tables are disabled.")); return false; } @@ -368,7 +368,7 @@ bool BuildDeleteRowsEffect(const TKqlDeleteRows& node, TExprContext& ctx, const } if (isOlap && !kqpCtx.Config->EnableOlapSink) { ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), - TStringBuilder() << "Data manipulation queries with column-oriented are disabled.")); + TStringBuilder() << "Data manipulation queries with column-oriented tables are disabled.")); return false; } diff --git a/ydb/core/kqp/ut/olap/kqp_olap_ut.cpp b/ydb/core/kqp/ut/olap/kqp_olap_ut.cpp index 7dae2345daad..6fde024f709b 100644 --- a/ydb/core/kqp/ut/olap/kqp_olap_ut.cpp +++ b/ydb/core/kqp/ut/olap/kqp_olap_ut.cpp @@ -2960,7 +2960,7 @@ Y_UNIT_TEST_SUITE(KqpOlap) { result.GetIssues().ToString().contains( "Data manipulation queries with column-oriented tables are supported only by API QueryService."), result.GetIssues().ToString()); - } + } } } diff --git a/ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp b/ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp index 32404d373528..a4f29e891b44 100644 --- a/ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp +++ b/ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp @@ -5060,7 +5060,7 @@ Y_UNIT_TEST_SUITE(KqpQueryService) { UNIT_ASSERT(!prepareResult.IsSuccess()); UNIT_ASSERT_C( prepareResult.GetIssues().ToString().contains( - "Data manipulation queries with column-oriented are disabled."), + "Data manipulation queries with column-oriented tables are disabled."), prepareResult.GetIssues().ToString()); }