-
Notifications
You must be signed in to change notification settings - Fork 412
ddl: Fix default value filling with finer granularity #10682
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 4 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
635a65e
Pick the test and default value filling behavior fix
JaySon-Huang c71f617
Refine the logic for filling in default values with finer granularity
JaySon-Huang c28401e
Format files
JaySon-Huang 6ce06c8
fix
JaySon-Huang 1c9a0eb
Add more test assert
JaySon-Huang d7c8130
Clearly comment
JaySon-Huang c8c3875
Add table info parsing ut
JaySon-Huang 817ce95
Add more case in ReadFromRegionDefaultValue
JaySon-Huang bc5ae87
Add fullstack test
JaySon-Huang d8448b5
Add debug log and test case
JaySon-Huang 02761a8
Add the case to handle column under non-public state with origin_default
JaySon-Huang a428cd6
Revert "Add debug log and test case"
JaySon-Huang 0499e1c
Add and fix unit tests
JaySon-Huang f264ae9
minor polish
JaySon-Huang File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | |||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -388,19 +388,19 @@ bool appendRowToBlock( | ||||||||||||||||||||||||||||
| } | |||||||||||||||||||||||||||||
| } | |||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||
| // When the `column_info` is missing in the encoded row, we try to add default value to the `block` at `block_column_pos`. | |||||||||||||||||||||||||||||
| // Return true if we could add default value to the column. Otherwise false and the caller should trigger schema sync. | |||||||||||||||||||||||||||||
| inline bool addDefaultValueToColumnIfPossible( | |||||||||||||||||||||||||||||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Summary the logical change under different aspect:
|
|||||||||||||||||||||||||||||
| const ColumnInfo & column_info, | |||||||||||||||||||||||||||||
| Block & block, | |||||||||||||||||||||||||||||
| size_t block_column_pos, | |||||||||||||||||||||||||||||
| bool ignore_pk_if_absent, | |||||||||||||||||||||||||||||
| bool force_decode) | |||||||||||||||||||||||||||||
| { | |||||||||||||||||||||||||||||
| // We consider a missing column could be safely filled with NULL, unless it has not default value and is NOT NULL. | |||||||||||||||||||||||||||||
| // This could saves lots of unnecessary schema syncs for old data with a newer schema that has newly added columns. | |||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||
| if (column_info.hasPriKeyFlag()) | |||||||||||||||||||||||||||||
| { | |||||||||||||||||||||||||||||
| // For clustered index or pk_is_handle, if the pk column does not exists, it can still be decoded from the key | |||||||||||||||||||||||||||||
| // For clustered index or pk_is_handle, if the pk column does not exists, it can still be decoded from the key. | |||||||||||||||||||||||||||||
| // just skip this column. | |||||||||||||||||||||||||||||
| if (ignore_pk_if_absent) | |||||||||||||||||||||||||||||
| return true; | |||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||
|
|
@@ -409,18 +409,44 @@ inline bool addDefaultValueToColumnIfPossible( | ||||||||||||||||||||||||||||
| return false; | |||||||||||||||||||||||||||||
| // Else non-clustered index, and not pk_is_handle, it could be a row encoded by older schema, | |||||||||||||||||||||||||||||
| // we need to fill the column which has primary key flag with default value. | |||||||||||||||||||||||||||||
| // fallthrough to fill default value when force_decode | |||||||||||||||||||||||||||||
| // fallthrough to fill default value when `force_decode==true` | |||||||||||||||||||||||||||||
| } | |||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||
| if (column_info.hasNoDefaultValueFlag() && column_info.hasNotNullFlag()) | |||||||||||||||||||||||||||||
| if (column_info.hasNotNullFlag()) | |||||||||||||||||||||||||||||
| { | |||||||||||||||||||||||||||||
| if (!force_decode) | |||||||||||||||||||||||||||||
| return false; | |||||||||||||||||||||||||||||
| // Else the row does not contain this "not null" / "no default value" column, | |||||||||||||||||||||||||||||
| // it could be a row encoded by older schema. | |||||||||||||||||||||||||||||
| // fallthrough to fill default value when force_decode | |||||||||||||||||||||||||||||
| { | |||||||||||||||||||||||||||||
| if (column_info.hasNoDefaultValueFlag()) | |||||||||||||||||||||||||||||
| { | |||||||||||||||||||||||||||||
| // This is a Column that defined as NOT NULL but no default value. In this case, user | |||||||||||||||||||||||||||||
| // should fill the column value when inserting data. But in the encoded value, the | |||||||||||||||||||||||||||||
| // datum of this Column is missing. | |||||||||||||||||||||||||||||
| // It could be a row encoded by newer schema after turning `NOT NULL` to `NULLABLE`. | |||||||||||||||||||||||||||||
| // Return false to trigger schema sync when `force_decode==false`. | |||||||||||||||||||||||||||||
| return false; | |||||||||||||||||||||||||||||
| } | |||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||
| assert(!column_info.hasNoDefaultValueFlag()); | |||||||||||||||||||||||||||||
| if (!column_info.hasOriDefaultValue()) | |||||||||||||||||||||||||||||
| { | |||||||||||||||||||||||||||||
| // This is a Column that defined as NOT NULL with default value. In this case, tidb-server | |||||||||||||||||||||||||||||
| // should fill the column value when inserting data unless the Column's default value is null, | |||||||||||||||||||||||||||||
| // and the value equals to that but has no origin default. | |||||||||||||||||||||||||||||
| // Reference: https://github.com/pingcap/tidb/blob/v8.5.5/pkg/table/tables/tables.go#L1463-L1489 | |||||||||||||||||||||||||||||
| // Now in the encoded value, the datum of this Column is missing. It could be a row encoded by | |||||||||||||||||||||||||||||
| // older schema after turning `NOT NULL` to `NULLABLE`. If the column_info has no origin default value, | |||||||||||||||||||||||||||||
| // Return false to trigger schema sync when `force_decode==false`. | |||||||||||||||||||||||||||||
| return false; | |||||||||||||||||||||||||||||
| } | |||||||||||||||||||||||||||||
| // Else the Column has a not null origin default value, the key-value should be encoded in a old schema that | |||||||||||||||||||||||||||||
| // this Column is not yet added. Fallthrough to fill the column with original default value. | |||||||||||||||||||||||||||||
| } | |||||||||||||||||||||||||||||
| // Else force_decode == true, the row does not contain this "not null" / "no default value" column. | |||||||||||||||||||||||||||||
| // It could be a row encoded by older schema, fallthrough to fill the column with original default value. | |||||||||||||||||||||||||||||
| } | |||||||||||||||||||||||||||||
| // not null or has no default value, tidb will fill with specific value. | |||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||
| // We consider a missing column could be safely filled with NULL or original default value. | |||||||||||||||||||||||||||||
| // This could saves lots of unnecessary schema syncs for old data with a newer schema that has newly added columns. | |||||||||||||||||||||||||||||
| auto * raw_column = const_cast<IColumn *>((block.getByPosition(block_column_pos)).column.get()); | |||||||||||||||||||||||||||||
| raw_column->insert(column_info.defaultValueToField()); | |||||||||||||||||||||||||||||
| return true; | |||||||||||||||||||||||||||||
|
|
@@ -460,7 +486,9 @@ bool appendRowV2ToBlockImpl( | ||||||||||||||||||||||||||||
| num_not_null_columns, | |||||||||||||||||||||||||||||
| value_offsets); | |||||||||||||||||||||||||||||
| size_t values_start_pos = cursor; | |||||||||||||||||||||||||||||
| // how many not null columns have been processed | |||||||||||||||||||||||||||||
| size_t idx_not_null = 0; | |||||||||||||||||||||||||||||
| // how many null columns have been processed | |||||||||||||||||||||||||||||
| size_t idx_null = 0; | |||||||||||||||||||||||||||||
| // Merge ordered not null/null columns to keep order. | |||||||||||||||||||||||||||||
| while (idx_not_null < not_null_column_ids.size() || idx_null < null_column_ids.size()) | |||||||||||||||||||||||||||||
|
|
@@ -481,20 +509,21 @@ bool appendRowV2ToBlockImpl( | ||||||||||||||||||||||||||||
| const auto next_column_id = column_ids_iter->first; | |||||||||||||||||||||||||||||
| if (next_column_id > next_datum_column_id) | |||||||||||||||||||||||||||||
| { | |||||||||||||||||||||||||||||
| // The next column id to read is bigger than the column id of next datum in encoded row. | |||||||||||||||||||||||||||||
| // The next_column_id to read is bigger than the next_datum_column_id in encoded row. | |||||||||||||||||||||||||||||
| // It means this is the datum of extra column. May happen when reading after dropping | |||||||||||||||||||||||||||||
| // a column. | |||||||||||||||||||||||||||||
| // For `force_decode == false`, we should return false to let upper layer trigger schema sync. | |||||||||||||||||||||||||||||
| if (!force_decode) | |||||||||||||||||||||||||||||
| return false; | |||||||||||||||||||||||||||||
| // Ignore the extra column and continue to parse other datum | |||||||||||||||||||||||||||||
| // For `force_decode == true`, we just skip this extra column and continue to parse other datum. | |||||||||||||||||||||||||||||
| if (is_null) | |||||||||||||||||||||||||||||
| idx_null++; | |||||||||||||||||||||||||||||
| else | |||||||||||||||||||||||||||||
| idx_not_null++; | |||||||||||||||||||||||||||||
| } | |||||||||||||||||||||||||||||
| else if (next_column_id < next_datum_column_id) | |||||||||||||||||||||||||||||
| { | |||||||||||||||||||||||||||||
| // The next column id to read is less than the column id of next datum in encoded row. | |||||||||||||||||||||||||||||
| // The next_column_id to read is less than the next_datum_column_id in encoded row. | |||||||||||||||||||||||||||||
| // It means this is the datum of missing column. May happen when reading after adding | |||||||||||||||||||||||||||||
| // a column. | |||||||||||||||||||||||||||||
| // Fill with default value and continue to read data for next column id. | |||||||||||||||||||||||||||||
|
|
@@ -505,7 +534,9 @@ bool appendRowV2ToBlockImpl( | ||||||||||||||||||||||||||||
| block_column_pos, | |||||||||||||||||||||||||||||
| ignore_pk_if_absent, | |||||||||||||||||||||||||||||
| force_decode)) | |||||||||||||||||||||||||||||
| { | |||||||||||||||||||||||||||||
| return false; | |||||||||||||||||||||||||||||
| } | |||||||||||||||||||||||||||||
| column_ids_iter++; | |||||||||||||||||||||||||||||
| block_column_pos++; | |||||||||||||||||||||||||||||
| } | |||||||||||||||||||||||||||||
|
|
@@ -570,8 +601,12 @@ bool appendRowV2ToBlockImpl( | ||||||||||||||||||||||||||||
| block_column_pos++; | |||||||||||||||||||||||||||||
| } | |||||||||||||||||||||||||||||
| } | |||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||
| // There are more columns to read other than the datum encoded in the row. | |||||||||||||||||||||||||||||
| while (column_ids_iter != column_ids_iter_end) | |||||||||||||||||||||||||||||
| { | |||||||||||||||||||||||||||||
| // Skip if the column_id is the same as `pk_handle_id`. The value of column | |||||||||||||||||||||||||||||
| // `pk_handle_id` will be filled in upper layer but not in this function. | |||||||||||||||||||||||||||||
| if (column_ids_iter->first != pk_handle_id) | |||||||||||||||||||||||||||||
| { | |||||||||||||||||||||||||||||
| const auto & column_info = column_infos[column_ids_iter->second]; | |||||||||||||||||||||||||||||
|
|
@@ -581,7 +616,9 @@ bool appendRowV2ToBlockImpl( | ||||||||||||||||||||||||||||
| block_column_pos, | |||||||||||||||||||||||||||||
| ignore_pk_if_absent, | |||||||||||||||||||||||||||||
| force_decode)) | |||||||||||||||||||||||||||||
| { | |||||||||||||||||||||||||||||
| return false; | |||||||||||||||||||||||||||||
| } | |||||||||||||||||||||||||||||
| } | |||||||||||||||||||||||||||||
| column_ids_iter++; | |||||||||||||||||||||||||||||
| block_column_pos++; | |||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.