Skip to content

Commit 3dd0c50

Browse files
author
Shlomi Noach
authored
Merge pull request #473 from github/json-57-test
Supporting JSON columns
2 parents 7fa16df + c9f2da8 commit 3dd0c50

6 files changed

Lines changed: 61 additions & 1 deletion

File tree

doc/requirements-and-limitations.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ The `SUPER` privilege is required for `STOP SLAVE`, `START SLAVE` operations. Th
2828

2929
- MySQL 5.7 generated columns are not supported. They may be supported in the future.
3030

31-
- MySQL 5.7 `JSON` columns are not supported. They are likely to be supported shortly.
31+
- MySQL 5.7 `POINT` column type is not supported.
32+
33+
- MySQL 5.7 `JSON` columns are supported but not as part of `PRIMARY KEY`
3234

3335
- The two _before_ & _after_ tables must share a `PRIMARY KEY` or other `UNIQUE KEY`. This key will be used by `gh-ost` to iterate through the table rows when copying. [Read more](shared-key.md)
3436
- The migration key must not include columns with NULL values. This means either:

go/logic/inspect.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,11 @@ func (this *Inspector) applyColumnTypes(databaseName, tableName string, columnsL
545545
columnsList.GetColumn(columnName).Type = sql.DateTimeColumnType
546546
}
547547
}
548+
if strings.Contains(columnType, "json") {
549+
for _, columnsList := range columnsLists {
550+
columnsList.GetColumn(columnName).Type = sql.JSONColumnType
551+
}
552+
}
548553
if strings.HasPrefix(columnType, "enum") {
549554
for _, columnsList := range columnsLists {
550555
columnsList.GetColumn(columnName).Type = sql.EnumColumnType

go/sql/builder.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ func buildColumnsPreparedValues(columns *ColumnList) []string {
3838
var token string
3939
if column.timezoneConversion != nil {
4040
token = fmt.Sprintf("convert_tz(?, '%s', '%s')", column.timezoneConversion.ToTimezone, "+00:00")
41+
} else if column.Type == JSONColumnType {
42+
token = "convert(? using utf8mb4)"
4143
} else {
4244
token = "?"
4345
}
@@ -106,6 +108,8 @@ func BuildSetPreparedClause(columns *ColumnList) (result string, err error) {
106108
var setToken string
107109
if column.timezoneConversion != nil {
108110
setToken = fmt.Sprintf("%s=convert_tz(?, '%s', '%s')", EscapeName(column.Name), column.timezoneConversion.ToTimezone, "+00:00")
111+
} else if column.Type == JSONColumnType {
112+
setToken = fmt.Sprintf("%s=convert(? using utf8mb4)", EscapeName(column.Name))
109113
} else {
110114
setToken = fmt.Sprintf("%s=?", EscapeName(column.Name))
111115
}

go/sql/types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const (
2020
DateTimeColumnType = iota
2121
EnumColumnType = iota
2222
MediumIntColumnType = iota
23+
JSONColumnType = iota
2324
)
2425

2526
const maxMediumintUnsigned int32 = 16777215

localtests/json57/create.sql

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
drop table if exists gh_ost_test;
2+
create table gh_ost_test (
3+
id int auto_increment,
4+
j json,
5+
primary key(id)
6+
) auto_increment=1;
7+
8+
drop event if exists gh_ost_test;
9+
delimiter ;;
10+
create event gh_ost_test
11+
on schedule every 1 second
12+
starts current_timestamp
13+
ends current_timestamp + interval 60 second
14+
on completion not preserve
15+
enable
16+
do
17+
begin
18+
insert into gh_ost_test values (null, '"sometext"');
19+
insert into gh_ost_test values (null, '{"key":"val"}');
20+
insert into gh_ost_test values (null, '{"is-it": true, "count": 3, "elements": []}');
21+
end ;;

localtests/json57dml/create.sql

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
drop table if exists gh_ost_test;
2+
create table gh_ost_test (
3+
id int auto_increment,
4+
i int not null,
5+
updated tinyint not null default 0,
6+
j json,
7+
primary key(id)
8+
) auto_increment=1;
9+
10+
drop event if exists gh_ost_test;
11+
delimiter ;;
12+
create event gh_ost_test
13+
on schedule every 1 second
14+
starts current_timestamp
15+
ends current_timestamp + interval 60 second
16+
on completion not preserve
17+
enable
18+
do
19+
begin
20+
insert into gh_ost_test (id, i, j) values (null, 11, '"sometext"');
21+
insert into gh_ost_test (id, i, j) values (null, 13, '{"key":"val"}');
22+
insert into gh_ost_test (id, i, j) values (null, 17, '{"is-it": true, "count": 3, "elements": []}');
23+
24+
update gh_ost_test set j = '{"updated": 11}', updated = 1 where i = 11 and updated = 0;
25+
update gh_ost_test set j = json_set(j, '$.count', 13, '$.id', id), updated = 1 where i = 13 and updated = 0;
26+
delete from gh_ost_test where i = 17;
27+
end ;;

0 commit comments

Comments
 (0)