-
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
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. 😀