Bruce Momjianのブログ投稿「SQLを介したランダムデータの生成」で、彼は次のコードを使用して5つのランダム文字列を生成しました。
SELECT
(
SELECT string_agg(x, '')
FROM (
SELECT chr(ascii('a') + floor(random() * 26)::integer)
FROM generate_series(1, 40 + b * 0) as f(g)
) AS y(x)
) AS result
FROM generate_series(1,5) as a(b);
result
------------------------------------------
plwfwcgajxdygfissmxqsywcwiqptytjjppgrvgb
sjaypirhuoynnvqjdgywfsfphuvzqbbilbhakyhf
ngtabkjfqibwahlicgisijatliuwgbcuiwujgeox
mqtnyewalettounachwjjzdrvxbbbpzogscexyfi
dzcstpsvwpefohwkfxmhnlwteyybxejbdltwamsx
(5 rows)
なぜ6行目の「b*0」が必要なのか疑問に思いました。それを削除すると、結果は5つのまったく同じ文字列に変更されました。これは、Postgresが外部の選択式(結果)をキャッシュしたことを意味します。
Postgresで式のキャッシュがどのように機能しているかがわかりませんでした。ドキュメントによると、 random()関数はVOLATILEとマークされているので、それに依存する式も揮発性であると思います。
Postgresで式キャッシングはどのように機能しますか?それはどこかに文書化されていますか?「b*0」がrandom()が無効にしたキャッシュを無効にしたのはなぜですか?
アップデート:
この問題を調査するために、「b * 0」をfloor()呼び出しの内側に移動して、random()と同じ位置/レベルにしました。
...
SELECT chr(ascii('a') + floor(random() * 26 + b * 0)::integer)
FROM generate_series(1, 40) as s(f)
...
結果はまだキャッシュされません。異なる文字列。
更新:問題を示す別の例
create sequence seq_test;
SELECT (SELECT nextval('seq_test')) FROM generate_series(1,5);
?column?
----------
1
1
1
1
1
(5 rows)