diff options
author | Alexey Borzenkov <snaury@yandex-team.ru> | 2022-04-18 18:40:06 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-04-18 18:40:06 +0300 |
commit | 7911fa007f4542bb16fc4db6f9a59493be04c09a (patch) | |
tree | 5e687d3a206a3ea815edf6c51926aeac05290910 | |
parent | 318ac23b965f65fb76e332dcb51ca378b4b94a12 (diff) | |
download | ydb-7911fa007f4542bb16fc4db6f9a59493be04c09a.tar.gz |
22-2: Validate cell sizes for columns, KIKIMR-14609
Merge from trunk: r9292957
REVIEW: 2426555
x-ydb-stable-ref: 1530dbb0378fd6c1658a48938752f54ec4cd4e8a
-rw-r--r-- | ydb/core/scheme/scheme_types_defs.cpp | 36 | ||||
-rw-r--r-- | ydb/core/scheme/scheme_types_defs.h | 17 | ||||
-rw-r--r-- | ydb/core/tablet_flat/flat_database.cpp | 22 | ||||
-rw-r--r-- | ydb/core/tablet_flat/flat_mem_warm.h | 3 | ||||
-rw-r--r-- | ydb/core/tablet_flat/flat_row_nulls.h | 5 |
5 files changed, 81 insertions, 2 deletions
diff --git a/ydb/core/scheme/scheme_types_defs.cpp b/ydb/core/scheme/scheme_types_defs.cpp index d27dc6aa10..8507a7d7df 100644 --- a/ydb/core/scheme/scheme_types_defs.cpp +++ b/ydb/core/scheme/scheme_types_defs.cpp @@ -1,4 +1,5 @@ #include "scheme_types_defs.h" +#include "scheme_tablecell.h" namespace NKikimr { @@ -9,5 +10,38 @@ namespace NNames { DECLARE_TYPED_TYPE_NAME(StepOrderId); } // namespace NNames -} // namespace NKikimr + + ::TString HasUnexpectedValueSize(const ::NKikimr::TRawTypeValue& value) { + ::TString result; + + if (value) { + const ui32 fixedSize = GetFixedSize(value.Type()); + if (fixedSize > 0 && value.Size() != fixedSize) { + result = ::TStringBuilder() + << "Value with declared type " << ui16(value.Type()) + << " has unexpected size " << value.Size() + << " (expected " << fixedSize << ")"; + } + } + + return result; + } + + ::TString HasUnexpectedValueSize(const ::NKikimr::TCell& value, TTypeId typeId) { + ::TString result; + + if (value) { + const ui32 fixedSize = GetFixedSize(typeId); + if (fixedSize > 0 && value.Size() != fixedSize) { + result = ::TStringBuilder() + << "Cell with declared type " << ui16(typeId) + << " has unexpected size " << value.Size() + << " (expected " << fixedSize << ")"; + } + } + + return result; + } + } // namespace NScheme +} // namespace NKikimr diff --git a/ydb/core/scheme/scheme_types_defs.h b/ydb/core/scheme/scheme_types_defs.h index 32a3a2b872..a0fd0f0e01 100644 --- a/ydb/core/scheme/scheme_types_defs.h +++ b/ydb/core/scheme/scheme_types_defs.h @@ -15,6 +15,9 @@ /**/ namespace NKikimr { + + struct TCell; + namespace NScheme { //////////////////////////////////////////////////////// @@ -60,5 +63,19 @@ inline ui32 GetFixedSize(NKikimr::NScheme::TTypeId typeId) { } } +/** + * Checks if the given value matches the expected type size + * + * Returns empty string on success or an error description in case of failure + */ +::TString HasUnexpectedValueSize(const ::NKikimr::TRawTypeValue& value); + +/** + * Checks if the given cell/type combination matches the expected type size + * + * Returns empty string on success or an error description in case of failure + */ +::TString HasUnexpectedValueSize(const ::NKikimr::TCell& value, TTypeId typeId); + } // namespace NScheme } // namespace NKikimr diff --git a/ydb/core/tablet_flat/flat_database.cpp b/ydb/core/tablet_flat/flat_database.cpp index c459119515..647e79645f 100644 --- a/ydb/core/tablet_flat/flat_database.cpp +++ b/ydb/core/tablet_flat/flat_database.cpp @@ -196,11 +196,33 @@ void TDatabase::Update(ui32 table, ERowOp rop, TRawVals key, TArrayRef<const TUp { Y_VERIFY_DEBUG(rowVersion != TRowVersion::Max(), "Updates cannot have v{max} as row version"); + for (size_t index = 0; index < key.size(); ++index) { + if (auto error = NScheme::HasUnexpectedValueSize(key[index])) { + Y_FAIL("Key index %" PRISZT " validation failure: %s", index, error.c_str()); + } + } + for (size_t index = 0; index < ops.size(); ++index) { + if (auto error = NScheme::HasUnexpectedValueSize(ops[index].Value)) { + Y_FAIL("Op index %" PRISZT " tag %" PRIu32 " validation failure: %s", index, ops[index].Tag, error.c_str()); + } + } + Redo->EvUpdate(table, rop, key, ops, rowVersion); } void TDatabase::UpdateTx(ui32 table, ERowOp rop, TRawVals key, TArrayRef<const TUpdateOp> ops, ui64 txId) { + for (size_t index = 0; index < key.size(); ++index) { + if (auto error = NScheme::HasUnexpectedValueSize(key[index])) { + Y_FAIL("Key index %" PRISZT " validation failure: %s", index, error.c_str()); + } + } + for (size_t index = 0; index < ops.size(); ++index) { + if (auto error = NScheme::HasUnexpectedValueSize(ops[index].Value)) { + Y_FAIL("Op index %" PRISZT " tag %" PRIu32 " validation failure: %s", index, ops[index].Tag, error.c_str()); + } + } + Redo->EvUpdateTx(table, rop, key, ops, txId); } diff --git a/ydb/core/tablet_flat/flat_mem_warm.h b/ydb/core/tablet_flat/flat_mem_warm.h index 851700f980..83b744b113 100644 --- a/ydb/core/tablet_flat/flat_mem_warm.h +++ b/ydb/core/tablet_flat/flat_mem_warm.h @@ -292,7 +292,8 @@ namespace NMem { } else if (TCellOp::HaveNoPayload(ops[it].NormalizedCellOp())) { /* Payloadless ECellOp types may have zero type value */ } else if (info->TypeId != ops[it].Value.Type()) { - Y_FAIL("Got un unexpected column type in cell update ops"); + Y_FAIL("Got an unexpected column type %" PRIu16 " in cell update for tag %" PRIu32 " (expected %" PRIu16 ")", + ops[it].Value.Type(), ops[it].Tag, info->TypeId); } auto cell = ops[it].AsCell(); diff --git a/ydb/core/tablet_flat/flat_row_nulls.h b/ydb/core/tablet_flat/flat_row_nulls.h index 7b5cb0fe02..c53cf73aed 100644 --- a/ydb/core/tablet_flat/flat_row_nulls.h +++ b/ydb/core/tablet_flat/flat_row_nulls.h @@ -20,6 +20,11 @@ namespace NTable { , Defs(defs) { Y_VERIFY(Defs.size() > 0 && Defs.size() == Types.size()); + for (size_t index = 0; index < Types.size(); ++index) { + if (auto error = NScheme::HasUnexpectedValueSize(Defs[index], Types[index])) { + Y_FAIL("Column default at index %" PRISZT " validation failed: %s", index, error.c_str()); + } + } } public: |