diff options
author | dcherednik <dcherednik@ydb.tech> | 2023-10-26 17:10:40 +0300 |
---|---|---|
committer | dcherednik <dcherednik@ydb.tech> | 2023-10-26 17:56:21 +0300 |
commit | 288878adf685a868ab3c47275063898b21bf06b4 (patch) | |
tree | 397cf2e27983927870555c03dbb16d81ef5aff7f | |
parent | 4f440816e221a84402c1a4bc06c2fb9e3bb168e8 (diff) | |
download | ydb-288878adf685a868ab3c47275063898b21bf06b4.tar.gz |
Additional check for PG compatibility. We should not have any indexes with same name. KIKIMR-18527
-rw-r--r-- | ydb/core/kqp/ut/pg/kqp_pg_ut.cpp | 14 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/schemeshard_path.cpp | 27 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/schemeshard_path.h | 1 |
3 files changed, 40 insertions, 2 deletions
diff --git a/ydb/core/kqp/ut/pg/kqp_pg_ut.cpp b/ydb/core/kqp/ut/pg/kqp_pg_ut.cpp index 76065d87b8..47db962035 100644 --- a/ydb/core/kqp/ut/pg/kqp_pg_ut.cpp +++ b/ydb/core/kqp/ut/pg/kqp_pg_ut.cpp @@ -1521,6 +1521,20 @@ Y_UNIT_TEST_SUITE(KqpPg) { { const auto query = Q_(R"( --!syntax_pg + CREATE TABLE test2( + id int8, + fk int8, + primary key(id) + ); + CREATE INDEX "test_fk_idx" ON test2 (fk); + )"); + + auto result = session.ExecuteQuery(query, txCtrl).ExtractValueSync(); + UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::BAD_REQUEST, result.GetIssues().ToString()); + } + { + const auto query = Q_(R"( + --!syntax_pg CREATE INDEX "test_fk_idx" ON test (fk); )"); diff --git a/ydb/core/tx/schemeshard/schemeshard_path.cpp b/ydb/core/tx/schemeshard/schemeshard_path.cpp index b686f33ce7..1914f885fd 100644 --- a/ydb/core/tx/schemeshard/schemeshard_path.cpp +++ b/ydb/core/tx/schemeshard/schemeshard_path.cpp @@ -917,11 +917,14 @@ const TPath::TChecker& TPath::TChecker::IsNameUniqGrandParentLevel(EStatus statu return *this; } + // must be a copy here auto path = Path.Parent(); if (!path.IsResolved()) { return *this; } + auto parentPathId = path->PathId; + path.Rise(); if (!path.IsResolved()) { return *this; @@ -929,9 +932,29 @@ const TPath::TChecker& TPath::TChecker::IsNameUniqGrandParentLevel(EStatus statu const auto& myName = Path.NameParts.back(); + auto raiseErr = [this](EStatus st, const TString& myName, const TString& conflict) -> const TPath::TChecker& { + return Fail(st, TStringBuilder() << "name " << myName + << " is not uniq. Found in: " << conflict); + }; + if (path.Elements.back()->FindChild(myName)) { - return Fail(status, TStringBuilder() << "name " << myName - << " is not uniq. Found in: " << path.PathString()); + return raiseErr(status, myName, path.PathString()); + } + + TVector<TPathId> uncles; + uncles.reserve(path.Elements.back()->GetChildren().size()); + for (const auto& [x, unclePathId] : path.Elements.back()->GetChildren()) { + if (unclePathId != parentPathId) { + uncles.emplace_back(unclePathId); + } + } + + for (const auto& pathid : uncles) { + auto& uncle = path.DiveByPathId(pathid); + if (uncle->FindChild(myName)) { + return raiseErr(status, myName, uncle.PathString()); + } + uncle.Rise(); } return *this; diff --git a/ydb/core/tx/schemeshard/schemeshard_path.h b/ydb/core/tx/schemeshard/schemeshard_path.h index 6022e0fa6f..bb34b06363 100644 --- a/ydb/core/tx/schemeshard/schemeshard_path.h +++ b/ydb/core/tx/schemeshard/schemeshard_path.h @@ -90,6 +90,7 @@ public: const TChecker& ImportsLimit(ui64 delta = 1, EStatus status = EStatus::StatusResourceExhausted) const; const TChecker& IsExternalTable(EStatus status = EStatus::StatusNameConflict) const; const TChecker& IsExternalDataSource(EStatus status = EStatus::StatusNameConflict) const; + // Check there are no uncles or cousins with same name const TChecker& IsNameUniqGrandParentLevel(EStatus status = EStatus::StatusNameConflict) const; }; |