MySQL HeatWave で動作の制限・制約がある SQL 文 (3) 関数・オペレータ

こちらの記事の続きです。

- **[MySQL HeatWave で動作の制限・制約がある SQL 文 (2) データ型 (2)](https://qiita.com/hmatsu47/items/bae9e9c406416069c65b)**

https://qiita.com/hmatsu47/items/bae9e9c406416069c65b

今回は関数とオペレータの制限です。

**HeatWave で使えない関数・オペレータが含まれる SQL 文は自動的に MySQL DB 側で実行される** だけの話であり、[こちら](https://qiita.com/hmatsu47/items/5bf7b37f694e56f3dc82#2-time_zone%E3%82%92system0000%E4%BB%A5%E5%A4%96%E3%81%AB%E8%A8%AD%E5%AE%9A%E3%81%97%E3%81%9F%E3%81%A8%E3%81%8D%E3%81%AEtimestamp%E5%88%97update)のようにデータ不整合が生じるおそれもないので、MySQL HeatWave User Guide に記載された内容を翻訳してそのまま列挙します。

- **[2.16.3 Functions and Operator Limitations](https://dev.mysql.com/doc/heatwave/en/mys-hw-limitations-functions.html)（MySQL HeatWave User Guide）**

https://dev.mysql.com/doc/heatwave/en/mys-hw-limitations-functions.html

:::note warn
2023/9/6 時点（MySQL バージョン 8.1.0-u1-cloud）の情報です。
今後、制限が変わる可能性があります。
:::

## HeatWave で実行できないもの（MySQL DB で実行され HeatWave にオフロードされないもの）

これらに当てはまる関数・オペレータを含む SQL 文を HeatWave で高速化したい場合は、HeatWave で実行できる内容・形式に書き換える、テーブルに含まれる列のデータ型の定義を変更するなどの対応が必要になります。

- ビット関数と演算子
- 日付（時刻・日時）値に対する`CAST() AS SIGNED`および`UNSIGNED`
  - `CAST()`については他にも制限あり
  - サポートされているものは MySQL HeatWave User Guide の **[Section 2.12.3 Cast Functions and Operators](https://dev.mysql.com/doc/heatwave/en/mys-hw-cast-functions-operators.html)** を参照
- `JOIN`述語としての`COALESCE()`
- `MET`や`Europe/Amsterdam`などの名前付きタイムゾーンでの`CONVERT_TZ()`。
  - `CONVERT_TZ(O_ORDERDATE, 'UTC','EST')`は`CONVERT_TZ(O_ORDERDATE, '+00:00','-05:00')`の形に書き換えると使用可
- 全文検索関数
- XML・JSON・空間（GIS）およびその他のドメイン固有の関数
- ユーザー定義関数（Loadable Functions）
- `GROUP_CONCAT()`と以下の組み合わせ
  - `ORDER BY`
  - 辞書エンコードされた文字列型の列（`RAPID_COLUMN=ENCODING=SORTED`）
    - 辞書エンコードについては MySQL HeatWave User Guide の **[2.7.1 Encoding String Columns](https://dev.mysql.com/doc/heatwave/en/mys-hw-encoding-string-columns.html)** および **[2.13.2 Dictionary Encoding](https://dev.mysql.com/doc/heatwave/en/mys-hw-dictionary-encoding.html)** を参照
  - `WITH ROLLUP`
  - 厳密モード以外（`GROUP_CONCAT()`は厳密モードでのみ使用可能）
- `YEAR`型に対する`GREATEST()`関数と`LEAST()`関数
  - `GREATEST()`関数および`LEAST()`関数は、日付（日時・時間）型とそれ以外の型との比較には非対応
- `CASE`制御フロー演算子または`IF()`関数で、集約関数内になく、`GROUP BY`キーの一部でもない列を含むもの
- `YEAR`型の日付関数
- `VARLEN`エンコードされていない列に対する文字列関数および演算子
  - MySQL HeatWave User Guide の **[2.7.1 Encoding String Columns](https://dev.mysql.com/doc/heatwave/en/mys-hw-encoding-string-columns.html)** を参照
- 文字列引数と非文字列引数が混在する比較関数で、HeatWave が不正な結果を返す場合がある
- 列挙（`ENUM`）データ型と日付（時刻・日時）データ型を持つ`AVG()`集約関数
- 列挙型・文字列型・日付（時刻・日時）データ型に対する以下の集約関数
  - `STD()`
  - `STDDEV()`
  - `STDDEV_POP()`
  - `STDDEV_SAMP()`
  - `SUM()`
  - `VAR_POP()`
  - `VAR_SAMP()`
  - `VARIANCE()`
    - これらのうち、`SUM()`以外については準結合（セミジョイン）内でも使用不可
      - 例：`SELECT FROM A WHERE a1 IN (SELECT VAR_POP(b1) FROM B);`
    - これらの集約関数は HeatWave 非対応のデータ型に対しては使用不可
      - HeatWave 対応のデータ型については MySQL HeatWave User Guide の **[2.10 Supported Data Types](https://dev.mysql.com/doc/heatwave/en/mys-hw-supported-data-types.html)** を参照
- `WEEK(date[,mode])`における`default_week_format`システム変数
  - `mode`引数を使用する場合は、`mode`値を明示的に定義する必要がある

正直なところ、これら全てを静的に解析して対処するのは難しいので、実際に SQL 文を流して判断するのが良さそうですね。

---

**2023/9/6 追記：**
続きの記事を書きました。

- **[MySQL HeatWave で動作の制限・制約がある SQL 文 (4) インデックスヒント・オプティマイザヒント・結合（JOIN）](https://qiita.com/hmatsu47/items/b7d43ff93567f4487ca3)**

https://qiita.com/hmatsu47/items/b7d43ff93567f4487ca3