0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Windows版PostgreSQLの拡張機能を作ってみる

Posted at

はじめに

2018年に下記の記事を書きました。しかし、残念ながら Windows版のpg_repackを正しく構築することが出来ませんでした。

別件のトラブルでpg_statsinfoについて調べていると、Windows版のpg_repackバイナリ配布しているという記事を見つけました。

SRA OSSとしてPostgreSQL拡張のWindowsバイナリ提供を開始しているが、今のところはサポート加入者のみで、一般配布は計画中とのこと。
※2025年05月時点ではまだ一般配布は行われていません。

じゃー自力でなんとかしてみようと考えたところです。

環境

  • Windos 11 Home 64bit
  • Visual Studio 2022(C++ によるデスクトップ開発) インストール済み
  • PostgreSQL 14.7

仕事の関係上、現時点では少し古めの PosstgreSQL のバージョンを使用します。

開発準備

PostgreSQL拡張をC言語を使用して開発するのですが、Visual Studio で下準備が必要となります。

単純なHello Worldの文字列を返すだけではつまらないので、フィボナッチ数を返す拡張機能を作成することにします。

Visual Studio用の拡張機能のビルド方法はPostgreSQLのWikiにまとまっていますが、英語の上に古いのは否めません。
今回、分かりやすく書いてみました。

参照記事

プロジェクト作成

C++でダイナミックリンクライブラリ(DLL)を選択します。
image.png
pg_fibonacci でプロジェクトを作成します。
image.png

プロパティ設定

pg_fibonacci でプロジェクトのプロパティにて、構成を「すべての構成」にします。

プリプロセッサ定義

C/C++の「プリプロセッサ」を選択、「プリプロセッサの定義」に「WIN32」を追加します。
PostgreSQLは「WINDLL」を同等のものとして認識しないため、Win32プラットフォームの場合は明示的に指定する必要があります。
※2014年の記事を参考にしているため、もう改善されている可能性があります。
image.png

C/C++の例外を無効化

C/C++の「コード生成」を選択、「C/C++の例外を有効にする」で「いいえ」にします。
image.png

コンパイルをC言語へ

C/C++の「詳細設定」を選択、「コンパイル言語の選択」で「C コードとしてコンパイル(/TC)」にします。
image.png

プリコンパイル済みヘッダーを使用しない

C/C++の「プリコンパイル済みヘッダー」を選択、「プリコンパイル済みヘッダー」で「プリコンパイル済みヘッダーを使用しない」にします。
image.png

マニフェストを生成しない

リンカーの「マニフェスト ファイル」を選択、「マニフェストの生成」で「いいえ (/MANIFEST:NO)」にします。
image.png

追加の依存関係

リンカーの「入力」を選択、「追加の依存ファイル」に「postgres.lib」を追加します。
image.png
「親またはプロジェクトの既定値から継承」のチェックは外さないでください。
単純な拡張機能では必要ありませんが、サーバー関数にリンクする場合は必要になります。
image.png

インクルードディレクトリ

C/C++の「全般」を選択、「追加のインクルードディレクトリ」で、PostgreSQLインストール配下の4つのフォルダを追加します。

  • include\server\port\win32_msvc
  • include\server\port\win32
  • include\server
  • include

image.png

今回の筆者の場合、PostgreSQLインストールフォルダは「C:\Program Files\PostgreSQL\14」になります。
image.png

ライブラリディレクトリ

リンカーの「全般」を選択、「追加のライブラリ ディレクトリ」で、PostgreSQLインストール配下のlibフォルダを追加します。次に「ライブラリ依存関係のリンク」を「いいえ」にします。
image.png

プロジェクトの構築

プルダウンメニューから「Relese」を選択します。
image.png

既存ファイルの削除

既存ファイルの「dllmain.cpp」と「pch.cpp」は不要なので削除します。

プログラム

構成

pg_fibonacci/
├── pg_fibonacci.c
├── pg_fibonacci.control
├── pg_fibonacci--1.0.sql

image.png

C言語ソース pg_fibonacci.c

pg_fibonacci.cを追加します。

pg_fibonacci.c
#include "postgres.h"
#include "fmgr.h"

#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif

#ifdef _WIN32
PGDLLEXPORT Datum fibonacci(PG_FUNCTION_ARGS);
#endif

PG_FUNCTION_INFO_V1(fibonacci);

Datum
fibonacci(PG_FUNCTION_ARGS)
{
    int32 n = PG_GETARG_INT32(0);

    if (n < 0)
        ereport(ERROR, (errmsg("Negative argument not allowed")));

    int64 a = 0, b = 1, temp;
    for (int i = 0; i < n; i++) {
        temp = a + b;
        a = b;
        b = temp;
    }

    PG_RETURN_INT64(a);
}

コントロールファイル pg_fibonacci.control

pg_fibonacci.controlを追加、プロパティにて「ビルドから除外」で「はい」にします。

pg_fibonacci.control
comment = 'Fibonacci function extension'
default_version = '1.0'
module_pathname = '$libdir/pg_fibonacci'
relocatable = true

SQL定義ファイル pg_fibonacci--1.0.sql

pg_fibonacci--1.0.sqlを追加、プロパティにて「ビルドから除外」で「はい」にします。

pg_fibonacci--1.0.sql
CREATE FUNCTION fibonacci(integer) RETURNS bigint
AS 'MODULE_PATHNAME', 'fibonacci'
LANGUAGE C STRICT;

導入

配置

今回の筆者の場合、PostgreSQLインストールフォルダは「C:\Program Files\PostgreSQL\14」になりますので、下記に配置します。

ファイル 配置先
pg_fibonacci.dll C:\Program Files\PostgreSQL\14\lib\
pg_fibonacci.control C:\Program Files\PostgreSQL\14\share\extension\
pg_fibonacci--1.0.sql 同上

PostgreSQLに拡張機能の登録

CREATE EXTENSION pg_fibonacci;

嵌まったこと

WindowsではC言語ソース内で下記の定義をしないとCREATE EXTENSIONにてcould not find functionエラーになります。
Stuck getting sample C function working on Windows version - stackoverflow

#ifdef _WIN32
PGDLLEXPORT Datum fibonacci(PG_FUNCTION_ARGS);
#endif

SQL : could not find function "fibonacci" in file "C:/Program Files/PostgreSQL/14/lib/pg_fibonacci.dll"

検証

SELECT fibonacci(10); -- 55
SELECT fibonacci(50); -- 12586269025

image.png

最後に

今回のpg_fibonacci.cは、ChatGPTで生成してもらいました。
設定が面倒な方は、GitHubから取得して改良してもらえばいいでしょう。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?