Prestoの新しい関数まとめ (v0.153 ~ v0.173)

Prestoの0.152.3がSep 28, 2016にリリースされてから半年ほどで0.173になりました。
（ちなみにTreasureDataのPrestoのバージョンは0.152.3 (2017年4月12日時点)なので、現時点では下記機能は使えません。バージョンは[こちら](https://docs.treasuredata.com/articles/presto#presto-query-language-reference)を参照）
さて、0.153~0.173までの間でリリースされた中の新しく追加された関数について見ていきたいと思います。
https://prestodb.io/docs/current/release.html


# 関数系

## Add levenshtein_distance() function

二つの文字列間のレーベンシュタイン距離を調べる。類似度検索みたいなことができるようにになる。

```
select levenshtein_distance('xxx','xyx')
-> 1
```

## Add shuffle() function for arrays

配列の要素をランダムに並び替えてくれる。（ユースケースがいまいちわからない・・・

https://prestodb.io/docs/current/functions/array.html#shuffle

```
SELECT 
  shuffle(x)
FROM (
  SELECT 
    ARRAY['xxx','xyx', 'xzy', 'aaa'] AS x
) t
```

## Add a variant of from_unixtime() function that takes a timezone argument.

from_unixtime(unixtime) -> timestamp
だけだったのが
from_unixtime(unixtime, xxxx) -> timestamp with timezoneがサポート。これはちょっと嬉しい。

```
-- 1491922800 = 2017/04/12 00:00:00 JST

SELECT from_unixtime(1491922800) => 2017-04-11 15:00:00.000
SELECT from_unixtime(1491922800, 'Asia/Tokyo') => 2017-04-12 00:00:00.000 Asia/Tokyo
SELECT from_unixtime(1491922800, 9, 0) => 2017-04-12 00:00:00.000 +09:00
```

## Add bitwise_and_agg() and bitwise_or_agg() aggregation functions.

そもそもbitwiseを使っているのを見たことがないので、略。
https://prestodb.io/docs/current/functions/bitwise.html

## Add from_big_endian_64() function

引数がbinaryなので、略

## Add xxhash64() and to_big_endian_64() functions.

同上だけれども動かそうと思うと、to_utf8を使ってhash化できたりする。

```
SELECT xxhash64(to_utf8('aiueo'))
=> 42 34 03 ba 0b 4e 2c c3
```

## Add codepoint(), skewness() and kurtosis() functions.

[codepoint()](https://prestodb.io/docs/current/functions/string.html#codepoint)は。。。略。

[skewness()](https://prestodb.io/docs/current/functions/aggregate.html#skewness)と[kurtosis()](https://prestodb.io/docs/current/functions/aggregate.html#kurtosis)は、歪度と尖度を算出する関数。
ここら辺がわかりやすいが、http://support.minitab.com/ja-jp/minitab/17/topic-library/basic-statistics-and-graphs/summary-statistics/how-skewness-and-kurtosis-affect-your-distribution/
まあ統計とかしてない人には関係ないので略。

## Add arrays_overlap() and array_except() functions.

[arrays_overlap](https://prestodb.io/docs/current/functions/array.html#arrays_overlap)は、二つの配列の要素のうち１つでも同じかどうかを判別（論理演算のANDが一つでもあるか）。一つでも同じならTrue, 違ければFalse。

[array_except](https://prestodb.io/docs/current/functions/array.html#array_except)は、二つの配列で、aの配列の要素のうちbの配列の要素を除外した配列を返してくれる。ただし、重複も除去されます。

```
SELECT array_except(a,b)
FROM (
  SELECT
    ARRAY['a','c','c'] as a,
    ARRAY['a','b'] as b
) t
=> ["c"]
```


## Add support for quantified comparison predicates: ALL, ANY, and SOME.

https://prestodb.io/docs/current/functions/comparison.html#quantified-comparison-predicates-all-any-and-some
こんな評価構文ってあるんだ、知らなかった・・・っていうのが本当のところですが、面白いですね。
当然のことながらWHERE句でも使えるので、条件指定がシンプルに表現できそうですね。

```
SELECT 42 >= ALL (SELECT 41 UNION ALL SELECT 42 UNION ALL SELECT 43)
=> false
SELECT 42 >= ANY (SELECT 41 UNION ALL SELECT 42 UNION ALL SELECT 43)
=> true
```

## Add Lambda Expressions and Functions
[ラムダ式](https://prestodb.io/docs/current/functions/lambda.html
)のサポート。。。ラムダ式はまじでみるのがつらい。これをゴリゴリ使われて、パフォーマンスチューニングとか依頼されたら涙目になりそうではある。

ただARRAYの操作なんかは便利そうで、例えば、下記のようなARRAYの内容をNULLを0埋めしてからSUMさせるような集計なんかは簡単にできてよさそう。

```
SELECT reduce(ARRAY [5, 20, NULL, 50], 0, (s, x) -> s + COALESCE(x, 0), s -> s);
=> 75
```


# まとめ

リリースノートを眺めていると、パフォーマンス改善系が多く、そろそろSQL構文レベルでの追加はだいぶ減っているように見受けられる（相関サブクエリとかがまだ完璧じゃないが徐々にサポートしているっぽい）。とはいえ関数は引き続き増えているのでやはり便利。（思ったよりは多くなかったが、半年で関数だけでこれだけ増えているですごい）

また、PrestoのRoadmapを眺めると、https://github.com/prestodb/presto/wiki/Roadmap
GROUPINGとGeoSpatial functionが関数としては今後嬉しいところですね。