実行環境
v8をHomebrewでインストール
作業前にちゃんと確認すべきでしたが、とりあえずv8は入ってないと思いそのインストールから着手しました。Homebrew自体の環境構築から始め、Xcodeインストール等のGUI操作は直接Macで。Homebrewの使い方は下記が分かりやすかったです。
Homebrewの環境構築後は普通にv8をインストールできました。ただ、infoを見るとreadlineがないと出たので、念のためそれも追加。あとv8を最新版4.5にupgradeしようとしたらSHA256 mismatchとエラーになったので、今回はインストールされた4.1.0.27のまま。
brew install v8
brew install readline
brew info v8
v8: stable 4.5.103.35
Google's JavaScript engine
https://code.google.com/p/v8/
/usr/local/Cellar/v8/4.1.0.27 (24 files, 29M) *
Poured from bottle
From: https://github.com/Homebrew/homebrew/blob/master/Library/Formula/v8.rb
==> Dependencies
Optional: readline ✔
==> Options
--with-readline
Use readline instead of libedit
PL/v8をビルド(Postgres.appに付いてて不要だった)
これは間抜けな話で、今回のPostgres.app(9.5 Alpha 1)には最初からPL/v8のライブラリ(plv8.so)や拡張用ファイルが入っていたのに気付かず、自分でビルドしてしまった…。ともかく一応できたので経過をメモ。手順は下記を参考にしました。
↓ 実行したコマンド。V8_OUTDIRは意味なかったかもしれません。
git clone https://github.com/plv8/plv8.git
export PATH=/Applications/Postgres.app/Contents/Versions/9.5/bin:$PATH
export V8_OUTDIR=/usr/local/Cellar/v8/4.1.0.27/out/native/
export V8_SRCDIR=/usr/local/Cellar/v8/4.1.0.27/
cd plv8
make
make install
上記実行後、ライブラリ(plv8.so)やExtensionフォルダ ↓ を見ると確かにファイルが新しくなって元のを上書きしてました。バージョンは同じ1.5.0-dev1。
ls -lt /Applications/Postgres.app/Contents/Versions/9.5/share/postgresql/extension
必須か分かりませんが念のためPostgreSQLを再起動。まだMacのサービス管理に疎いのでpg_ctlコマンドで直接、データディレクトリも実パスで指定。実際のコマンドは一行です。
/Applications/Postgres.app/Contents/Versions/9.5/bin/pg_ctl restart
-D ~/Library/Application\ Support/Postgres/var-9.5
# just one line actually
データベースへインストール、ウィンドウ関数作成テスト
ここからはOS間で特に差はなく、前回までと同じ手順。psqlで接続、テスト用データベース作成、そのDBに接続してCREATE EXTENSIONするだけ。
psql -U "user" -h xxx.xxx.xxx.xxx
SELECT version();
version
----------------------------------------------------------------
PostgreSQL 9.5alpha1 on x86_64-apple-darwin14.3.0, compiled by
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0sv
n), 64-bit
(1 行)
CREATE DATABASE plv8_test
TEMPLATE template0
ENCODING 'UTF-8'
LC_COLLATE 'C'
LC_CTYPE 'C';
\c plv8_test
CREATE EXTENSION plv8;
SELECT extname, extversion FROM pg_extension;
extname | extversion
---------+------------
plpgsql | 1.0
plv8 | 1.5.0-dev1
(2 行)
テストとして、昨日と同じウィンドウ関数を作成。第1引数がINT型の列、第2引数が任意の境界値で、境界値以上の行だけを配列に追加していき、境界値未満の行で配列を空にリセットします。
CREATE OR REPLACE FUNCTION partial_accum( v1 int, v2 int )
RETURNS int[] LANGUAGE plv8 IMMUTABLE WINDOW AS $$
var w = plv8.get_window_object(),
obj = w.get_partition_local();
if (v1 < v2) {
w.set_partition_local({ "val": [] });
return null;
} else {
if (w.get_current_position() === 0 || obj[ "val" ].length ===
obj = { "val": [ v1 ] };
} else {
obj[ "val" ].push( v1 );
}
w.set_partition_local( obj );
return obj[ "val" ];
}
$$;
テスト用ダミーテーブルを作り実行。結果には特に意味ありません。
CREATE TABLE dummy AS
SELECT round(random() * 30) AS num
FROM generate_series(1, 20);
SELECT num, partial_accum(num :: int, 10) over()
FROM dummy;
num | partial_accum
-----+------------------
18 | {18}
13 | {18,13}
17 | {18,13,17}
24 | {18,13,17,24}
2 |
26 | {26}
30 | {26,30}
23 | {26,30,23}
20 | {26,30,23,20}
6 |
25 | {25}
10 | {25,10}
17 | {25,10,17}
13 | {25,10,17,13}
13 | {25,10,17,13,13}
5 |
7 |
26 | {26}
3 |
12 | {12}
(20 行)
まとめのまとめ
- RedHat 7系(CentOSとSL7)は、アルファ版のPostgreSQL 9.5に対しても既にインストール用パッケージがあるほどで、最も手軽。
- Macでは、Postgres.appなら最初から付いているので、後はv8さえあればたぶん簡単。今回は無駄に自力でビルドしてしまい、とりあえず動いてよかった。
- Windowsでは、PostgreSQL 9.2~9.4ならZIPを解凍してコピーするだけ。ただしZIPへのリンクがまとまってなく、Postgres Online Journalの記事から探すのがネックかも。9.5は現時点ではポスグレ本体から自力でビルドする必要があり、別問題。
- OSまたはPostgreSQLによって今回入れたPL/v8のバージョンが違い(1.3.0、1.4.x、1.5.0-dev1)、機能に差があるかは未調査。少なくとも1.4.xで、PL/v8ならではのTyped Arrayとウィンドウ関数作成が使えることは分かりました。