MariaDB 10.2 と 10.3 で空文字列がNULLに変換されるか検証

先日 [MariaDB 10.3 が GA になった](https://mariadb.com/kb/en/library/mariadb-1037-release-notes/)ようです。10.3では[Oracleとの互換機能](https://mariadb.com/kb/en/library/sql_modeoracle-from-mariadb-103/)が実装されており、その一機能として空文字列を NULL として扱うことが可能なようです。

前のバージョンの 10.2 と挙動を Docker 上で比較してみました。

# 10.2.15 で検証

Docker で MariaDB 10.2.15 を起動します。

```
docker run --env 'MYSQL_ALLOW_EMPTY_PASSWORD=true' -d mariadb:10.2
```

コンテナ上で mysql(MariaDB monitor)を起動します。

```
$ docker exec -it contairner_id mysql
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 10
Server version: 10.2.15-MariaDB-10.2.15+maria~jessie mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> 
```

## テスト用 database/table作成

```
MariaDB [(none)]> create database test;
Query OK, 1 row affected (0.00 sec)

MariaDB [(none)]> use test;
Database changed

MariaDB [test]> create table t1 (str varchar(8), time timestamp);
Query OK, 0 rows affected (0.01 sec)
```

ここで sql_mode の値を確認してみます。

```
MariaDB [test]> show variables like 'sql_mode';
+---------------+-------------------------------------------------------------------------------------------+
| Variable_name | Value                                                                                     |
+---------------+-------------------------------------------------------------------------------------------+
| sql_mode      | STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+---------------+-------------------------------------------------------------------------------------------+
```

## 空文字列をINSERT

空文字列とNULLをそれぞれテーブルに入れてみます。

```
MariaDB [test]> insert into t1 (str) values ('');
Query OK, 1 row affected (0.00 sec)

MariaDB [test]> select * from t1;
+------+---------------------+
| str  | time                |
+------+---------------------+
|      | 2018-06-01 17:11:52 |
+------+---------------------+
```

NULLではなく、空文字列となっています。

## NULLをINSERT

```
MariaDB [test]> insert into t1 (str) values (NULL);
Query OK, 1 row affected (0.00 sec)

MariaDB [test]> select * from t1;
+------+---------------------+
| str  | time                |
+------+---------------------+
|      | 2018-06-01 17:11:52 |
| NULL | 2018-06-01 17:12:24 |
+------+---------------------+
```

NULL が挿入されています。

sql_mode='EMPTY_STRING_IS_NULL' をダメ元で試してみましたが、実装されていないのでエラーになりました。

```
MariaDB [test]> SET sql_mode='EMPTY_STRING_IS_NULL';
ERROR 1231 (42000): Variable 'sql_mode' can't be set to the value of 'EMPTY_STRING_IS_NULL'
MariaDB [test]> 
```

# 10.3.7 GA で検証

10.2 と同様に 10.3.7 GA でテストしてみます。

```
docker run --env 'MYSQL_ALLOW_EMPTY_PASSWORD=true' -d mariadb:10.3
```

```
$ docker exec -it 546c1d4e797e mysql
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 8
Server version: 10.3.7-MariaDB-1:10.3.7+maria~jessie mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> 
```

## sql_mode

```
MariaDB [test]> show variables like 'sql_mode';
+---------------+-------------------------------------------------------------------------------------------+
| Variable_name | Value                                                                                     |
+---------------+-------------------------------------------------------------------------------------------+
| sql_mode      | STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+---------------+-------------------------------------------------------------------------------------------+
```

EMPTY_STRING_IS_NULL は有効になっていないようです。
有効にしてみます。

```
MariaDB [test]> SET sql_mode='ORACLE,EMPTY_STRING_IS_NULL';
Query OK, 0 rows affected (0.000 sec)

MariaDB [test]> show variables like 'sql_mode';
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Variable_name | Value                                                                                                                                                             |
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| sql_mode      | PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,EMPTY_STRING_IS_NULL,SIMULTANEOUS_ASSIGNMENT |
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
```

## 空文字列をINSERT

```
MariaDB [test]> insert into t1 (str) values ('');
Query OK, 1 row affected (0.003 sec)

MariaDB [test]> select * from t1;
+------+---------------------+
| str  | time                |
+------+---------------------+
| NULL | 2018-06-01 17:19:08 |
+------+---------------------+
```

10.2.15 とは異なり、*NULL* が入っています。

## NULLをINSERT

```
MariaDB [test]> insert into t1 (str) values (NULL);
Query OK, 1 row affected (0.004 sec)

MariaDB [test]> select * from t1;
+------+---------------------+
| str  | time                |
+------+---------------------+
| NULL | 2018-06-01 17:19:08 |
| NULL | 2018-06-01 17:19:54 |
+------+---------------------+
```

当然ですが、こちらもNULLが入りました。

MariaDB 10.3.7 GA では ```SET sql_mode='EMPTY_STRING_IS_NULL';``` で空文字列が NULL として扱われることが確認できました。