aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikolay Perfilov <pnv902@gmail.com>2022-04-27 20:47:47 +0300
committerNikolay Perfilov <pnv902@gmail.com>2022-04-27 20:47:47 +0300
commiteaf3ffde35539ef62187d854d9541bd84fcbd277 (patch)
tree6b7072b314e96c29010775c8e1db4e55b31686c4
parentd24943f728c369b6a1feb806c103b25cb5f945bd (diff)
downloadydb-eaf3ffde35539ef62187d854d9541bd84fcbd277.tar.gz
Add test with secondary index building for PK starting with Null, KIKIMR-14517
ref:1cd46448376c02e637bc5c9d2cc56a6091c0348a
-rw-r--r--ydb/core/kqp/ut/kqp_indexes_ut.cpp138
1 files changed, 138 insertions, 0 deletions
diff --git a/ydb/core/kqp/ut/kqp_indexes_ut.cpp b/ydb/core/kqp/ut/kqp_indexes_ut.cpp
index f928dc73d4..51d9197d1e 100644
--- a/ydb/core/kqp/ut/kqp_indexes_ut.cpp
+++ b/ydb/core/kqp/ut/kqp_indexes_ut.cpp
@@ -1463,6 +1463,144 @@ Y_UNIT_TEST_SUITE(KqpIndexes) {
}
+ Y_UNIT_TEST_QUAD(UpsertWithNullKeys, WithMvcc, UseNewEngine) {
+ auto setting = NKikimrKqp::TKqpSetting();
+ auto serverSettings = TKikimrSettings()
+ .SetEnableMvcc(WithMvcc)
+ .SetEnableMvccSnapshotReads(WithMvcc)
+ .SetKqpSettings({setting});
+ TKikimrRunner kikimr(serverSettings);
+ auto db = kikimr.GetTableClient();
+ auto session = db.CreateSession().GetValueSync().GetSession();
+
+ {
+ // Create table with 1 index
+ auto tableBuilder = db.GetTableBuilder();
+ tableBuilder
+ .AddNullableColumn("Key", EPrimitiveType::String)
+ .AddNullableColumn("IndexColumn1", EPrimitiveType::String)
+ .AddNullableColumn("IndexColumn2", EPrimitiveType::String)
+ .AddNullableColumn("Value", EPrimitiveType::String);
+ tableBuilder.SetPrimaryKeyColumns(TVector<TString>{"Key", "IndexColumn1", "IndexColumn2"});
+ tableBuilder.AddSecondaryIndex("IndexName1", TVector<TString>{"IndexColumn1"});
+ auto result = session.CreateTable("/Root/TestTable", tableBuilder.Build()).ExtractValueSync();
+ UNIT_ASSERT_VALUES_EQUAL(result.IsTransportError(), false);
+ UNIT_ASSERT_VALUES_EQUAL(result.GetStatus(), EStatus::SUCCESS);
+ }
+ {
+ // Upsert rows including one with PK starting with Null
+ const TString query1(Q_(R"(
+ UPSERT INTO `/Root/TestTable` (Key, IndexColumn1, IndexColumn2, Value) VALUES
+ ("Primary 1", "Secondary1 1", "Secondary2 1", "Value 1"),
+ (Null, "Secondary1 2", "Secondary2 2", "Value 2");
+ )"));
+
+ auto result = session.ExecuteDataQuery(
+ query1,
+ TTxControl::BeginTx(TTxSettings::SerializableRW()).CommitTx())
+ .ExtractValueSync();
+ UNIT_ASSERT(result.IsSuccess());
+ }
+ {
+ // Read row with PK starting with Null by index1
+ const TString query(Q1_(R"(
+ SELECT Value FROM `/Root/TestTable` VIEW IndexName1 WHERE IndexColumn1 = 'Secondary1 2';
+ )"));
+
+ auto result = session.ExecuteDataQuery(
+ query,
+ TTxControl::BeginTx(TTxSettings::SerializableRW()).CommitTx())
+ .ExtractValueSync();
+ UNIT_ASSERT(result.IsSuccess());
+ UNIT_ASSERT_VALUES_EQUAL(NYdb::FormatResultSetYson(result.GetResultSet(0)), "[[[\"Value 2\"]]]");
+ }
+ {
+ // Both rows should be in index1 table
+ const auto& yson = ReadTablePartToYson(session, "/Root/TestTable/IndexName1/indexImplTable");
+ const TString expected =
+ R"([[["Secondary1 1"];["Primary 1"];["Secondary2 1"]];)"
+ R"([["Secondary1 2"];#;["Secondary2 2"]]])";
+ UNIT_ASSERT_VALUES_EQUAL(yson, expected);
+ }
+ {
+ // Add second index with alter
+ TAlterTableSettings alterSettings;
+ alterSettings.AppendAddIndexes({ TIndexDescription("IndexName2", {"IndexColumn2"}) });
+ auto result = session.AlterTable("/Root/TestTable", alterSettings).ExtractValueSync();
+ UNIT_ASSERT_VALUES_EQUAL(result.IsTransportError(), false);
+ UNIT_ASSERT_VALUES_EQUAL(result.GetStatus(), EStatus::SUCCESS);
+ }
+ {
+ // Read row with PK starting with Null by index2
+ const TString query(Q1_(R"(
+ SELECT Value FROM `/Root/TestTable` VIEW IndexName2 WHERE IndexColumn2 = 'Secondary2 2';
+ )"));
+
+ auto result = session.ExecuteDataQuery(
+ query,
+ TTxControl::BeginTx(TTxSettings::SerializableRW()).CommitTx())
+ .ExtractValueSync();
+ UNIT_ASSERT(result.IsSuccess());
+ UNIT_ASSERT_VALUES_EQUAL(NYdb::FormatResultSetYson(result.GetResultSet(0)), "[[[\"Value 2\"]]]");
+ }
+ {
+ // Both rows should also be in index2 table
+ const auto& yson = ReadTablePartToYson(session, "/Root/TestTable/IndexName2/indexImplTable");
+ const TString expected =
+ R"([[["Secondary2 1"];["Primary 1"];["Secondary1 1"]];)"
+ R"([["Secondary2 2"];#;["Secondary1 2"]]])";
+ UNIT_ASSERT_VALUES_EQUAL(yson, expected);
+ }
+ {
+ // Upsert more rows including one with PK starting with Null
+ const TString query1(Q_(R"(
+ UPSERT INTO `/Root/TestTable` (Key, IndexColumn1, IndexColumn2, Value) VALUES
+ ("Primary 3", "Secondary1 3", "Secondary2 3", "Value 3"),
+ (Null, "Secondary1 4", "Secondary2 4", "Value 4");
+ )"));
+
+ auto result = session.ExecuteDataQuery(
+ query1,
+ TTxControl::BeginTx(TTxSettings::SerializableRW()).CommitTx())
+ .ExtractValueSync();
+ UNIT_ASSERT(result.IsSuccess());
+ }
+ {
+ // Read recently added row with PK starting with Null by index2
+ const TString query(Q1_(R"(
+ SELECT Value FROM `/Root/TestTable` VIEW IndexName2 WHERE IndexColumn2 = 'Secondary2 4';
+ )"));
+
+ auto result = session.ExecuteDataQuery(
+ query,
+ TTxControl::BeginTx(TTxSettings::SerializableRW()).CommitTx())
+ .ExtractValueSync();
+ UNIT_ASSERT(result.IsSuccess());
+ UNIT_ASSERT_VALUES_EQUAL(NYdb::FormatResultSetYson(result.GetResultSet(0)), "[[[\"Value 4\"]]]");
+ }
+ {
+ // All 4 rows should be in index1 table
+ const auto& yson = ReadTablePartToYson(session, "/Root/TestTable/IndexName1/indexImplTable");
+ const TString expected =
+ R"([[["Secondary1 1"];["Primary 1"];["Secondary2 1"]];)"
+ R"([["Secondary1 2"];#;["Secondary2 2"]];)"
+ R"([["Secondary1 3"];["Primary 3"];["Secondary2 3"]];)"
+ R"([["Secondary1 4"];#;["Secondary2 4"]]])";
+ UNIT_ASSERT_VALUES_EQUAL(yson, expected);
+ }
+ {
+ // All 4 rows should also be in index2 table
+ const auto& yson = ReadTablePartToYson(session, "/Root/TestTable/IndexName2/indexImplTable");
+ const TString expected =
+ R"([[["Secondary2 1"];["Primary 1"];["Secondary1 1"]];)"
+ R"([["Secondary2 2"];#;["Secondary1 2"]];)"
+ R"([["Secondary2 3"];["Primary 3"];["Secondary1 3"]];)"
+ R"([["Secondary2 4"];#;["Secondary1 4"]]])";
+ UNIT_ASSERT_VALUES_EQUAL(yson, expected);
+ }
+
+ }
+
Y_UNIT_TEST_TWIN(KeyIndex, WithMvcc) {
auto setting = NKikimrKqp::TKqpSetting();
auto serverSettings = TKikimrSettings()