MySQL 8.0.34 /MySQL 8.1.0 から文字列型カラムのデフォルト値に、CURRENT_USER関数やUSER関数が利用可能になりました。
CURRENT_USER() can now be used as a default value for VARCHAR and TEXT columns in CREATE TABLE and ALTER TABLE … ADD COLUMN statements.
The functions SESSION_USER(), USER(), and SYSTEM_USER() are also supported in all of the cases just mentioned. By way of example, the following sequence of statements now works similarly to what is shown here, with the precise output dependent on your environment:
引用: Changes in MySQL 8.0.34 (2023-07-18, General Availability)
使い方
CURRENT_USER関数が返す文字列は、最大32文字のユーザー名と最大255文字のホスト名の間に区切り文字として挟まる@の1文字を足した288文字が最大長になるので、設定するカラムの文字列長は288文字以上を設定してください。
1 2 3 4 |
CREATE TABLE sample ( insert_user VARCHAR(288) NOT NULL DEFAULT (USER()), insert_current_user VARCHAR(288) NOT NULL DEFAULT (CURRENT_USER()) ); |
想定される利用パターンとしては、ログや監査情報としてDB接続アカウント名を残す場面でしょうか?
1 2 3 4 5 6 7 8 9 |
CREATE TABLE logging ( log_id INT NOT NULL AUTO_INCREMENT, log_date DATETIME NOT NULL, message VARCHAR(255) NOT NULL, inv_insert_user VARCHAR(288) NOT NULL DEFAULT (USER()) INVISIBLE, inv_upd_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP INVISIBLE , PRIMARY KEY id (log_id), INDEX (log_date) ); |
上記のようなテーブルを作成すると、カラム名を指定しないと見えないカラムに挿入したDBユーザーを記録できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
mysql> INSERT logging -> (log_date, message) -> VALUE -> (now(), "Log message"); Query OK, 1 row affected (0.01 sec) mysql> SELECT * FROM logging; +--------+---------------------+-------------+ | log_id | log_date | message | +--------+---------------------+-------------+ | 1 | 2023-07-31 05:16:36 | Log message | +--------+---------------------+-------------+ 1 row in set (0.00 sec) mysql> SELECT log_id, log_date, message, inv_insert_user, inv_upd_date FROM logging; +--------+---------------------+-------------+-----------------+---------------------+ | log_id | log_date | message | inv_insert_user | inv_upd_date | +--------+---------------------+-------------+-----------------+---------------------+ | 1 | 2023-07-31 05:16:36 | Log message | root@localhost | 2023-07-31 05:16:36 | +--------+---------------------+-------------+-----------------+---------------------+ 1 row in set (0.00 sec) |
サポートされるストレージエンジン
リリースノートには使えるストレージエンジンについての記述は無く、英語のドキュメントのデフォルト値についてにも記述はありませんが、MySQL 8.0.34 /MySQL 8.1.0 ではサポートされているストレージエンジンは InnoDBとMyISAMだけです。
ソースコードを見ると、利用可能なストレージエンジンかどうかの判定をHA_SUPPORTS_DEFAULT_EXPRESSION
フラグで行っています。
1 2 3 4 5 6 7 8 |
// Check default value expressions against table's storage engine if (share->gen_def_field_count && outparam->file && (!(outparam->file->ha_table_flags() & HA_SUPPORTS_DEFAULT_EXPRESSION))) { my_error(ER_UNSUPPORTED_ACTION_ON_DEFAULT_VAL_GENERATED, MYF(0), "Specified storage engine"); error_reported = true; goto err; } |
引用: MySQL 8.0.34 sql/table.cc 3091行目から
下記はInnoDBの変更差分ですが、このフラグが追加されているストレージエンジンはInnoDBとMyISAMだけです。
1 2 3 4 5 6 7 8 9 10 |
@@ -2617,7 +2617,8 @@ ha_innobase::ha_innobase(handlerton *hton, TABLE_SHARE *table_arg) /* This won't be true until WL#8960 is completed. Still, claim support for partial update so that the optimizer parts get tested. */ - | HA_BLOB_PARTIAL_UPDATE | HA_SUPPORTS_GEOGRAPHIC_GEOMETRY_COLUMN), + | HA_BLOB_PARTIAL_UPDATE | HA_SUPPORTS_GEOGRAPHIC_GEOMETRY_COLUMN | + HA_SUPPORTS_DEFAULT_EXPRESSION), m_start_of_scan(), m_stored_select_lock_type(LOCK_NONE_UNSET), m_mysql_has_locked() {} |
引用: storage/innobase/handler/ha_innodb.cc
対応していないストレージエンジン(MEMORYやARCHIVE)でテーブルを作成しようとすると、エラーメッセージが表示されます。
1 2 3 4 |
mysql> CREATE TABLE unsupported_storage_engine ( -> create_user VARCHAR(288) DEFAULT (USER()) -> )ENGINE=ARCHIVE; ERROR 3774 (HY000): 'Specified storage engine' is not supported for default value expressions. |
まとめ
Innovation Release のMySQL 8.1がリリースされて、MySQL 8.0系には機能追加はなくなりバグ修正を中心になると思われます。
今後は様々な機能が積極的にInnovation Releaseの8.x系に追加されると思われるので、今後もこのBlogで新機能の紹介をしていけたらと思います。