aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Borzenkov <snaury@yandex-team.ru>2022-04-18 18:40:06 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-04-18 18:40:06 +0300
commit7911fa007f4542bb16fc4db6f9a59493be04c09a (patch)
tree5e687d3a206a3ea815edf6c51926aeac05290910
parent318ac23b965f65fb76e332dcb51ca378b4b94a12 (diff)
downloadydb-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.cpp36
-rw-r--r--ydb/core/scheme/scheme_types_defs.h17
-rw-r--r--ydb/core/tablet_flat/flat_database.cpp22
-rw-r--r--ydb/core/tablet_flat/flat_mem_warm.h3
-rw-r--r--ydb/core/tablet_flat/flat_row_nulls.h5
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: