MariaDBの同一ホスト間のデータ同期システムとして作っていたmagentadeskなのですが、
0.7.0のリリースで、MySQL 8.0.31 と 8.0.32 の対応を入れました。
https://github.com/shigenobu/magentadesk
なんで今までやらなかったかというと、
- テーブルの解析でのinformation_schemaの格納のされ方が微妙にMariaDBとMySQLで異なる
- MySQLではEXCEPTが8.0.31までなかった
- MariaDBのdynamic columnに相当する機能がMySQLでは賄えるか不安だった
- シーケンスがないのをどうするか
といったところでしたが、MySQL 8.0.31でEXCEPTが入ったので、
本腰入れて対応してみました。
やってみて色々大変でした。
なかでもUNIONの動作がおかしくて、無理やりやる感じでした。
MariaDBとMySQLでのUNIONの動作を見てみます。
まず以下のデータを用意します。
> select * from base;
+------+
| c |
+------+
| 1 |
| 2 |
+------+
> select * from compare;
+------+
| c |
+------+
| 1 |
| 3 |
+------+
次にこんなSQLを投げます。
with
t1 as
(
select * from base
except
select * from compare
),
t2 as
(
select * from compare
except
select * from base
),
tt1 as
(
select
json_object('c', t1.c) as b,
json_object('c', t2.c) as c
from
t1
left outer join
t2
on t1.c = t2.c
),
tt2 as
(
select
json_object('c', t1.c) as b,
json_object('c', t2.c) as c
from
t1
right outer join
t2
on t1.c = t2.c
),
t as
(
select * from tt1
union
select * from tt2
)
select * from t;
ちょっとややこしいのですが、
MariaDBとMySQLの結果を見てみます。
(MariaDB)
+-------------+-------------+
| b | c |
+-------------+-------------+
| {"c": 2} | {"c": null} |
| {"c": null} | {"c": 3} |
+-------------+-------------+
(MySQL)
+-------------+-------------+
| b | c |
+-------------+-------------+
| {"c": 2} | {"c": null} |
| {"c": 1} | {"c": 1} |
| {"c": null} | {"c": 3} |
+-------------+-------------+
いやー、MySQLの結果がおかしいですよね。これ仕様なのか?
EXCEPTで除いている筈なのに。。
MySQLのUNIONは結構昔から不具合あるようで、
なんかこうなってくると複雑な集計クエリーを投げるのがちょっと怖い感じもしますね。
現状では、気をつけましょうとしかいいようがないですが。。
以上