PostgreSQLをWindows上でソースコードからビルドしてplpythonを使う方法

VisualStudioのCコンパイラを使ってPostgreSQLをソースコードからビルドする方法をまとめました。
PL/Pythonを使えるようにするには設定が必要なため、本記事で説明します。

* デフォルト設定での手順はこちら：[関連記事1](https://qiita.com/t-kataym/items/e13c268f371fb87cb118)
* Linux上での手順はこちら：[関連記事2](https://qiita.com/t-kataym/items/61e93e0608cceb6b982d)

今回使用したバージョンはPostgreSQL14.2ですが、他のバージョンでも同様にできると思います。
# 事前準備
今回使用したツールとバージョンは以下のとおりです。
* Windows 10
* Visual Studio 2019
* Active Perl 5.28
* Active Tcl 8.6.9
* flex 2.6.4
* biosn 2.7
* Python 3.7.8

Active Perl/Tclおよびflex/bisonのインストールについては、[関連記事1](https://qiita.com/t-kataym/items/e13c268f371fb87cb118)の"事前準備"の章をご覧ください。
PythonはVisual Studioに付属のものを使用しました。

# Pythonの実行ファイルのパスの確認
[こちら](https://gammasoft.jp/blog/python-install-location/)のサイトを参考に、Pythonの実行ファイル（python.exe）のパスを確認します。
まずコマンドプロンプトを起動し、pyコマンドを実行します。
```shell
>py
Python 3.7.8 (tags/v3.7.8:4b47a5b6ba, Jun 28 2020, 08:53:46) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
```
Pythonスクリプトを入力できるようになるので、下記2行を入力します。
```python
import sys
sys.exec_prefix
```

以下のようにインストールフォルダが出力されるので覚えておきます。
```shell
>>> import sys
>>> sys.exec_prefix
'C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\Python37_64'
```

# ソースコードのダウンロード
PostgreSQLのソースコードはPostgreSQL公式サイトからダウンロードしました。  

https://www.postgresql.org/ftp/source/v14.2/

圧縮ファイルを解凍し、C:\Projects\postgresql-14.2 に置くこととします。
# Visual Studioビルド用設定ファイルの準備
PL/Pythonを使うには設定が必要ですので、本章で説明します。
デフォルト設定の場合、本章の操作は不要です。

src\tools\msvcフォルダに設定ファイルのサンプルconfig_default.plがあるので、そのファイルをconfig.plというファイル名でコピーします。

次にそのconfig.plをテキストエディタで編集します。
以下の行を変更します。
```perl
	python    => undef,    # --with-python=<path>
```
undefのところを、Pythonの実行ファイルのフォルダを設定します。
```perl
	python    => "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\Python37_64",    # --with-python=<path>
```
# ビルド
以降は[関連記事1](https://qiita.com/t-kataym/items/e13c268f371fb87cb118)の操作と同じです。
Visual Studioのコマンドプロンプトを開き、src\tools\msvcフォルダでmkvcbuildを実行します。
bisonやflex関連のエラーが発生した場合は、[関連記事1](https://qiita.com/t-kataym/items/e13c268f371fb87cb118)の"ソースコードのダウンロードと設定変更"の章をご覧ください。
![mkvcbuild](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581362/46b76155-eca0-4d50-2b4a-3bc06e745f5c.png)

Visual Studioのプロジェクトファイルが作成されるので、トップフォルダ（今回はC:\Projects\postgresql-14.2）にあるpgsql.slnというソリューションファイルを開きます。  
PLs/plpython3というプロジェクトがあるはずです。

あとは、「ソリューションのビルド(B)」を実行すればOKです。
![sln.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581362/554add6d-ea7b-7545-066c-dad740ad9330.png)

トップフォルダ下に、デバッグビルドの場合はDebug、リリースビルドの場合はReleaseフォルダが作成されているはずです。
# インストール
Visual Studioのコマンドプロンプト上で、src\tools\msvcフォルダでinstallを実行します。引数には、インストール先を指定します。
今回は、トップフォルダの下のpostgres1（C:\\Projects\postgresql-14.2\postgres1）を指定しました。
![install](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581362/cc83b623-606a-a1de-3982-607dcc163a08.png)
# サーバの起動とデータベースの作成
インストール先のbinフォルダには実行プログラムが入っているのでこれらを使用します。
例えば、インストールフォルダの下にdatabasesをデータベースクラスタとする場合、以下の手順でサーバを起動します。
1. コマンドプロンプトを起動し、binフォルダに移動します。
1. `.\initdb -D ..\databases` でデータベースクラスタを作成します。
1. `.\pg_ctl -D ..\databases start` でPostgreSQLサーバを起動します。
1. `.\createdb test` でtestというデータベースを作成します。

# PL/Pythonの使用準備
まず `.\psql test` でpsqlにてtestデータベースに接続します。

PL/Python extensionが使用可能かを確認します。
pg_available_extensionsをSELECTして、plpython3uが存在すればOKです。
```
test=# SELECT * FROM pg_available_extensions WHERE name = 'plpython3u';
    name    | default_version | installed_version |                  comment
------------+-----------------+-------------------+-------------------------------------------
 plpython3u | 1.0             |                   | PL/Python3U untrusted procedural language
(1 row)
```

次にplpython3uを有効化し、Pythonの実行ファイルのパスを返すストアドファンクションをPL/Pythonで作成してみます。
SELECTして結果が返ればOKです。
```
test=# CREATE EXTENSION plpython3u;
CREATE EXTENSION
test=# CREATE FUNCTION func1 (OUT path text) AS $$
test$# import sys
test$# return sys.exec_prefix
test$# $$ LANGUAGE 'plpython3u';
CREATE FUNCTION
test=# SELECT func1();
                               func1
-------------------------------------------------------------------
 C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64
(1 row)

```
# おわりに
PL/Pythonを使うためのVisualStudioでのPostgreSQLビルド方法を説明しました。
今回はPL/Pythonを使いたかったのでconfig.plファイルの変更は1行のみでしたが、config.plを見ると、[linuxでconfigureで指定するオプション](https://www.postgresql.org/docs/14/install-procedure.htm)の一部がWindowsでも指定できるようです。
ご参考までに設定項目を掲載しておきます。
```perl
	asserts => 0,    # --enable-cassert
	# blocksize => 8,         # --with-blocksize, 8kB by default
	# wal_blocksize => 8,     # --with-wal-blocksize, 8kB by default
	ldap      => 1,        # --with-ldap
	extraver  => undef,    # --with-extra-version=<string>
	gss       => undef,    # --with-gssapi=<path>
	icu       => undef,    # --with-icu=<path>
	lz4       => undef,    # --with-lz4=<path>
	nls       => undef,    # --enable-nls=<path>
	tap_tests => undef,    # --enable-tap-tests
	tcl       => undef,    # --with-tcl=<path>
	perl      => undef,    # --with-perl=<path>
	python    => undef,    # --with-python=<path>
	openssl   => undef,    # --with-ssl=openssl with <path>
	uuid      => undef,    # --with-uuid=<path>
	xml       => undef,    # --with-libxml=<path>
	xslt      => undef,    # --with-libxslt=<path>
	iconv     => undef,    # (not in configure, path to iconv)
	zlib      => undef     # --with-zlib=<path>
```


# 参考文献
* PostgreSQL 13.1文書 第17章 Windowsにおけるソースコードからのインストール  
https://www.postgresql.jp/document/13/html/install-windows-full.html
* Pythonのインストール場所について（Windows）  
https://gammasoft.jp/blog/python-install-location/
* （関連記事1）PostgreSQLをWindows上でソースコードからビルド  
https://qiita.com/t-kataym/items/e13c268f371fb87cb118
* （関連記事2）Linux上でPostgreSQLをソースコードからビルドしてplpythonを使う手順  
https://qiita.com/t-kataym/items/61e93e0608cceb6b982d