-
Notifications
You must be signed in to change notification settings - Fork 1k
Add VisibilityBitmap to TableMapEvent in replication #813
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
Changes from 1 commit
ccabd26
6260982
cac73e6
b55ff1d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -81,6 +81,9 @@ type TableMapEvent struct { | |
// EnumSetDefaultCharset/EnumSetColumnCharset is similar to DefaultCharset/ColumnCharset but for enum/set columns. | ||
EnumSetDefaultCharset []uint64 | ||
EnumSetColumnCharset []uint64 | ||
|
||
// VisibilityBitmap stores bits that are set if corresponding column is not invisible (MySQL 8.0.23+) | ||
VisibilityBitmap []byte | ||
} | ||
|
||
func (e *TableMapEvent) Decode(data []byte) error { | ||
|
@@ -312,6 +315,9 @@ func (e *TableMapEvent) decodeOptionalMeta(data []byte) (err error) { | |
return err | ||
} | ||
|
||
case TABLE_MAP_OPT_META_COLUMN_VISIBILITY: | ||
e.VisibilityBitmap = v | ||
|
||
default: | ||
// Ignore for future extension | ||
} | ||
|
@@ -421,6 +427,7 @@ func (e *TableMapEvent) Dump(w io.Writer) { | |
fmt.Fprintf(w, "Primary key prefix: %v\n", e.PrimaryKeyPrefix) | ||
fmt.Fprintf(w, "Enum/set default charset: %v\n", e.EnumSetDefaultCharset) | ||
fmt.Fprintf(w, "Enum/set column charset: %v\n", e.EnumSetColumnCharset) | ||
fmt.Fprintf(w, "Invisible Column bitmap: \n%s", hex.Dump(e.VisibilityBitmap)) | ||
|
||
unsignedMap := e.UnsignedMap() | ||
fmt.Fprintf(w, "UnsignedMap: %#v\n", unsignedMap) | ||
|
@@ -440,6 +447,9 @@ func (e *TableMapEvent) Dump(w io.Writer) { | |
geometryTypeMap := e.GeometryTypeMap() | ||
fmt.Fprintf(w, "GeometryTypeMap: %#v\n", geometryTypeMap) | ||
|
||
visibilityMap := e.VisibilityMap() | ||
fmt.Fprintf(w, "VisibilityMap: %#v\n", visibilityMap) | ||
|
||
nameMaxLen := 0 | ||
for _, name := range e.ColumnName { | ||
if len(name) > nameMaxLen { | ||
|
@@ -730,6 +740,22 @@ func (e *TableMapEvent) GeometryTypeMap() map[int]uint64 { | |
return ret | ||
} | ||
|
||
// 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 { | ||
if len(e.VisibilityBitmap) == 0 { | ||
return nil | ||
} | ||
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 commentThe 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 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. @atercattus 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. 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 commentThe 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 commentThe 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
Welcome to find different code 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. My bad. |
||
p++ | ||
} | ||
return ret | ||
} | ||
|
||
// Below realType and IsXXXColumn are base from: | ||
// table_def::type in sql/rpl_utility.h | ||
// Table_map_log_event::print_columns in mysql-8.0/sql/log_event.cc and mariadb-10.5/sql/log_event_client.cc | ||
|
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 intoTestTableMapOptMetaNames
orTestTableMapHelperMaps
, but it's too packed and I saw no room for any addition. Your advice would be help me a lot. 😀