|
10 | 10 | #include <ydb/core/tx/columnshard/splitter/batch_slice.h> |
11 | 11 |
|
12 | 12 | #include <ydb/library/formats/arrow/simple_arrays_cache.h> |
| 13 | +#include <ydb/core/base/appdata_fwd.h> |
| 14 | +#include <ydb/core/protos/config.pb.h> |
13 | 15 |
|
14 | 16 | #include <util/string/join.h> |
15 | 17 |
|
@@ -92,36 +94,31 @@ TConclusion<std::shared_ptr<arrow::RecordBatch>> ISnapshotSchema::PrepareForModi |
92 | 94 | if (targetIdx == -1) { |
93 | 95 | return TConclusionStatus::Success(); |
94 | 96 | } |
| 97 | + const auto hasNull = NArrow::HasNulls(incomingBatch->column(incomingIdx)); |
95 | 98 | const std::optional<i32> pkFieldIdx = GetIndexInfo().GetPKColumnIndexByIndexVerified(targetIdx); |
96 | | - if (!NArrow::HasNulls(incomingBatch->column(incomingIdx))) { |
97 | | - if (pkFieldIdx) { |
98 | | - AFL_VERIFY(*pkFieldIdx < (i32)pkColumns.size()); |
99 | | - AFL_VERIFY(!pkColumns[*pkFieldIdx]); |
100 | | - pkColumns[*pkFieldIdx] = incomingBatch->column(incomingIdx); |
101 | | - ++pkColumnsCount; |
102 | | - } |
103 | | - return TConclusionStatus::Success(); |
104 | | - } |
105 | | - if (pkFieldIdx) { |
| 99 | + if (pkFieldIdx && hasNull && !AppData()->ColumnShardConfig.GetAllowNullableColumnsInPK()) { |
106 | 100 | return TConclusionStatus::Fail("null data for pk column is impossible for '" + dstSchema.field(targetIdx)->name() + "'"); |
107 | 101 | } |
108 | | - switch (mType) { |
109 | | - case NEvWrite::EModificationType::Replace: |
110 | | - case NEvWrite::EModificationType::Insert: |
111 | | - case NEvWrite::EModificationType::Upsert: { |
112 | | - if (GetIndexInfo().IsNullableVerifiedByIndex(targetIdx)) { |
113 | | - return TConclusionStatus::Success(); |
114 | | - } |
115 | | - if (GetIndexInfo().GetColumnExternalDefaultValueByIndexVerified(targetIdx)) { |
116 | | - return TConclusionStatus::Success(); |
117 | | - } else { |
118 | | - return TConclusionStatus::Fail("empty field for non-default column: '" + dstSchema.field(targetIdx)->name() + "'"); |
119 | | - } |
| 102 | + if (hasNull) { |
| 103 | + switch (mType) { |
| 104 | + case NEvWrite::EModificationType::Replace: |
| 105 | + case NEvWrite::EModificationType::Insert: |
| 106 | + case NEvWrite::EModificationType::Upsert: { |
| 107 | + if (!GetIndexInfo().IsNullableVerifiedByIndex(targetIdx) && !GetIndexInfo().GetColumnExternalDefaultValueByIndexVerified(targetIdx)) |
| 108 | + return TConclusionStatus::Fail("empty field for non-default column: '" + dstSchema.field(targetIdx)->name() + "'"); |
| 109 | + } |
| 110 | + case NEvWrite::EModificationType::Delete: |
| 111 | + case NEvWrite::EModificationType::Update: |
| 112 | + break; |
120 | 113 | } |
121 | | - case NEvWrite::EModificationType::Delete: |
122 | | - case NEvWrite::EModificationType::Update: |
123 | | - return TConclusionStatus::Success(); |
124 | 114 | } |
| 115 | + if (pkFieldIdx) { |
| 116 | + AFL_VERIFY(*pkFieldIdx < (i32)pkColumns.size()); |
| 117 | + AFL_VERIFY(!pkColumns[*pkFieldIdx]); |
| 118 | + pkColumns[*pkFieldIdx] = incomingBatch->column(incomingIdx); |
| 119 | + ++pkColumnsCount; |
| 120 | + } |
| 121 | + return TConclusionStatus::Success(); |
125 | 122 | }; |
126 | 123 | const auto nameResolver = [&](const std::string& fieldName) -> i32 { |
127 | 124 | return GetIndexInfo().GetColumnIndexOptional(fieldName).value_or(-1); |
|
0 commit comments