-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Add VisibilityBitmap to TableMapEvent in replication #813
Add VisibilityBitmap to TableMapEvent in replication #813
Conversation
VisibilityBitmap
to TableMapEvent
for MySQL 8.0.23+ Invisible…VisibilityBitmap
to TableMapEvent
in replication
VisibilityBitmap
to TableMapEvent
in replication
@lance6716 |
I will take a look some hours later. Thanks for your PR 😄 |
… Columns Changes: - `TableMapEvent.VisibilityBitmap` `VisibilityBitmap` is a bitmap where each bit represents the visibility of a corresponding column in a table. If a bit is set, it indicates that the corresponding column is NOT an invinsible column. Invisible column was introduced in MySQL version 8.0.23. - `TableMapEvent.VisibilityMap` `VisibilityMap` lists boolean values of which is true if column of the same index is NOT an invisible column. Co-authored-by: sean <sean.k1@kakaoent.com>
b2e8633
to
ccabd26
Compare
I added a co-author. |
replication/row_event.go
Outdated
p := 0 | ||
ret := make(map[int]bool) | ||
for i := 0; i < int(e.ColumnCount); i++ { | ||
ret[i] = e.VisibilityBitmap[p/8]&(1<<uint(7-p%8)) != 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Maybe it's a little easier to understand the original code with countdown instead of 1<<uint(7-p%8)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@atercattus
I appreciate your review. Also, I agree with you and I can get this fixed.
Actually VisibilityMap
is copy and paste of existing UnsignedMap
. Should I fix UnsignedMap
too?
I could create a separate PR it if it seems irrelevant to this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh. @lance6716 what do you think about this? Apply the Boy Scout Rule or not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we decide to improve, the code will look like below.
func (e *TableMapEvent) VisibilityMap() map[int]bool {
if len(e.VisibilityBitmap) == 0 {
return nil
}
ret := make(map[int]bool)
for _, field := range e.VisibilityBitmap {
for c, i := 0x80, 0; c != 0; c, i = c>>1, i+1 {
ret[i] = field&byte(c) != 0
}
}
return ret
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The old code is really not easy to understand 😢 I also hope we start to improve the readability. As for UnsignedMap, I'm OK that you also modify it in this PR or another PR. WDYT @atercattus
Your new code snippet seems not optimal. The status of i
should be kept when iterate bytes of VisibilityBitmap
. And we can early stop when the column count is not a multiple of 8 (though the original code seems not optimize about this). Maybe we can
...
i := 0
for e.VisibilityBitmap {
for c := 0x80; ... {
ret[i] = ...
i++
if i >= e.ColumnCount { return }
}
}
...
Welcome to find different code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My bad. i
should indeed be initialized outside of the inner loop.
replication/row_event.go
Outdated
p := 0 | ||
ret := make(map[int]bool) | ||
for i := 0; i < int(e.ColumnCount); i++ { | ||
ret[i] = e.VisibilityBitmap[p/8]&(1<<uint(7-p%8)) != 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The old code is really not easy to understand 😢 I also hope we start to improve the readability. As for UnsignedMap, I'm OK that you also modify it in this PR or another PR. WDYT @atercattus
Your new code snippet seems not optimal. The status of i
should be kept when iterate bytes of VisibilityBitmap
. And we can early stop when the column count is not a multiple of 8 (though the original code seems not optimize about this). Maybe we can
...
i := 0
for e.VisibilityBitmap {
for c := 0x80; ... {
ret[i] = ...
i++
if i >= e.ColumnCount { return }
}
}
...
Welcome to find different code
// VisibilityMap returns a map: column index -> visiblity. | ||
// Invisible column was introduced in MySQL 8.0.23 | ||
// nil is returned if not available. | ||
func (e *TableMapEvent) VisibilityMap() map[int]bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As for testing, I think maybe you can capture/construct some VisibilityBitmap
bytes and test the result of TableMapEvent.VisibilityMap is expected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lance6716
Sure. I think I should create a separate function. Just as TestTableMapOptMetaPrimaryKey
is defined solely for primary key type meta data. At first, I thought about squeezing into TestTableMapOptMetaNames
or TestTableMapHelperMaps
, but it's too packed and I saw no room for any addition. Your advice would be help me a lot. 😀
Changes: - Refactpred `UnsignedMap` - Refactored `VisibilityMap` Suggested by: go-mysql-org#813 (comment)
Changes: - Refactpred `UnsignedMap` - Refactored `VisibilityMap` Suggested by: go-mysql-org#813 (comment)
20bf956
to
6260982
Compare
Changes: - Added data for MySQL 8.0 only (Only MySQL 8.0.23+ supports invisible columns)
I added test case for 8.0 only, because the keyword |
ptal @atercattus |
But on a second thought, I would like to add case 2 where invisible columns do not exist at all! This case will be applicable to the rest of vendors and versions too; MySQL 5.7, MariaDB 10.4 and MairaDB 10.5. |
Changes: - Add test case 2 where invisible columns does not exists at all
lgtm now. let's wait @atercattus |
@dongwook-chan seems atercattus is a bit busy. Do you want me to merge it or you can wait a bit longer ? |
@lance6716 No need to wait any longer! |
I was implementing optional_metadata field in table_map_event for python-mysql-replication.
And came across this repo and found that metadata type COLUMN_VISIBILITY isn't implemented.
Changes
TableMapEvent.VisibilityBitmap
VisibilityBitmap
is a bitmap where each bit represents the visibility of a corresponding column in a table.TableMapEvent.VisibilityMap
VisibilityMap
lists boolean values of which is true if column of the same index is NOT an invisible column.Examples
You can check the visibility of a column by its table by executing
DESCRIBE
command.