GitHub Copilot CLI と20世紀へタイムトラベル——1999年の PostgreSQL は、今のLinuxでビルドできるのか
はじめに
1999年の PostgreSQL は、今のUbuntuでビルドできるのか。
ある雑誌が最新の PostgreSQL 18 を特集しているのを見て、最初に PostgreSQL を触った頃のことを思い出しました。確か 1999 年、バージョン 6の時代です。そこから気になって調べているうちに、当時のソースコードが残っていることを発見し、ビルドして再現することを思い立ちました。古いディストリビューションも探しましたが、結局は最新の Ubuntu に持ち込み、ビルドは GitHub Copilot CLI に任せることにしました。
結果として、ビルドは成功し、SQLも実行できました。デフォルトの GPT-5.4 は短時間でかなりのところまで進めましたが、最後に残った psqlのメタコマンドまわりは、より多くのPremium Requestを使う Claude Opus 4.7 で復活させました。
これは、その記録です。

(検証環境: macOS Sequoia / Ubuntu 24.04 LTS / GitHub Copilot CLI v1.0.40・gpt-5.4・claude-opus-4.7)
Dockerイメージの作成と起動
初回 #01で作成したサンドボックス環境をベースにして、今回のPostgreSQLビルド環境を作成していますので、Dockerfileやcompose.ymlの詳細は初回 #01を参考にしてください。
macOS:~/docker$ docker compose build --no-cache
macOS:~/docker$ docker compose up -d
macOS:~/docker$ docker compose exec postgres6 bash
postgres:~$ uname -a
Linux 0713719379b9 6.8.0-100-generic #100-Ubuntu SMP PREEMPT_DYNAMIC Tue Jan 13 16:39:21 UTC 2026 aarch64 aarch64 aarch64 GNU/Linux
postgres:~$
この環境では約200秒(3分20秒)でイメージのビルドが完了したので、イメージを起動します。docker compose exec postgres6 bashでUbuntuにログインできれば成功です。
今回用意した Dockerfile と compose.yml はこちらですので、再現する際の参考にしてください。
Dockerfile
# syntax=docker/dockerfile:1
FROM ubuntu:24.04
ARG DEBIAN_FRONTEND=noninteractive
ARG POSTGRES_USER=postgres
ARG POSTGRES_GROUP=postgres
ARG POSTGRES_UID=999
ARG POSTGRES_GID=999
# 基本ツール + ロケール + タイムゾーンDB + PostgreSQL 6.5 ビルド用ツール
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates sudo curl wget git gh openssh-client bash zsh tmux procps \
vim nano less locales tzdata tree rsync cloc file patch \
build-essential make gcc g++ libc6-dev bison flex perl \
libreadline-dev zlib1g-dev libncurses-dev \
python3 python3-pip python3-venv \
&& locale-gen ja_JP.UTF-8 \
&& rm -rf /var/lib/apt/lists/*
# Node.js 24 LTS(NodeSource 公式手順ベース)
RUN apt-get update \
&& curl -fsSL https://deb.nodesource.com/setup_24.x | bash - \
&& apt-get install -y --no-install-recommends nodejs \
&& node -v \
&& rm -rf /var/lib/apt/lists/*
# pnpm は Corepack で有効化(メジャー 10 に固定)
RUN corepack enable \
&& corepack prepare pnpm@10 --activate
# 日本語ロケール + JST
ENV TZ=Asia/Tokyo
ENV LANG=ja_JP.UTF-8
ENV LC_ALL=ja_JP.UTF-8
RUN ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime \
&& echo "${TZ}" > /etc/timezone
ENV PG_HOME=/usr/local/pgsql
ENV PG_SRC=/usr/src/pgsql
ENV PGDATA=/usr/local/pgsql/data
# PostgreSQL 6.5 時代の標準ユーザー・グループ・ディレクトリを作成
RUN set -eux; \
if getent passwd "${POSTGRES_USER}" > /dev/null; then \
echo "User ${POSTGRES_USER} already exists:"; \
getent passwd "${POSTGRES_USER}"; \
exit 1; \
fi; \
if getent passwd "${POSTGRES_UID}" > /dev/null; then \
echo "UID ${POSTGRES_UID} already exists:"; \
getent passwd "${POSTGRES_UID}"; \
exit 1; \
fi; \
if getent group "${POSTGRES_GROUP}" > /dev/null; then \
echo "Group ${POSTGRES_GROUP} already exists. Reusing it."; \
else \
groupadd --system -g "${POSTGRES_GID}" "${POSTGRES_GROUP}"; \
fi; \
useradd --system \
--uid "${POSTGRES_UID}" \
--gid "${POSTGRES_GROUP}" \
--home-dir "${PG_HOME}" \
--create-home \
--shell /bin/bash \
"${POSTGRES_USER}"; \
install -d -m 0755 -o "${POSTGRES_USER}" -g "${POSTGRES_GROUP}" \
"${PG_SRC}" \
"${PG_HOME}" \
"${PG_HOME}/bin" \
"${PG_HOME}/.local/bin" \
"${PGDATA}" \
"${PG_HOME}/tmp"; \
chown -R "${POSTGRES_USER}:${POSTGRES_GROUP}" "${PG_SRC}" "${PG_HOME}"
# 実験用: パスワードなし sudo を許可(本番・共有環境では要見直し)
RUN set -eux; \
echo "${POSTGRES_USER} ALL=(ALL) NOPASSWD:ALL" > "/etc/sudoers.d/${POSTGRES_USER}"; \
chmod 0440 "/etc/sudoers.d/${POSTGRES_USER}"
USER ${POSTGRES_USER}
WORKDIR ${PG_HOME}
SHELL ["/bin/bash", "-lc"]
# ユーザーのローカルインストール先を PATH に追加
ENV PATH=${PG_HOME}/bin:${PG_HOME}/.local/bin:${PATH}
# 標準的な対話環境
RUN set -eux; \
shell_env="$(mktemp)"; \
{ \
echo 'case ":$PATH:" in *":/usr/local/pgsql/bin:"*) ;; *) export PATH="/usr/local/pgsql/bin:$PATH" ;; esac'; \
echo 'case ":$PATH:" in *":$HOME/.local/bin:"*) ;; *) export PATH="$HOME/.local/bin:$PATH" ;; esac'; \
echo 'export PGDATA="${PGDATA:-/usr/local/pgsql/data}"'; \
echo 'export PAGER=less'; \
echo 'alias ll="ls -alF"'; \
echo 'alias la="ls -A"'; \
echo 'alias l="ls -CF"'; \
echo 'dedup_path() { old_path="$PATH:"; PATH=""; while [ -n "$old_path" ]; do path_entry="${old_path%%:*}"; old_path="${old_path#*:}"; [ -z "$path_entry" ] && continue; case ":$PATH:" in *":$path_entry:"*) ;; *) PATH="${PATH:+$PATH:}$path_entry" ;; esac; done; export PATH; }'; \
echo 'dedup_path; unset -f dedup_path; unset old_path path_entry'; \
} > "${shell_env}"; \
tee -a ~/.bashrc ~/.profile ~/.zshrc < "${shell_env}" > /dev/null; \
rm -f "${shell_env}"; \
git config --global init.defaultBranch main; \
git config --global --add safe.directory "${PG_SRC}"
# uv / uvx(公式インストーラー)
RUN curl -LsSf https://astral.sh/uv/install.sh | sh \
&& "${PG_HOME}/.local/bin/uv" --version
# 起動時は bash
CMD ["bash"]
compose.yml
services:
postgres6:
# ローカルの Dockerfile からビルド
build:
context: .
dockerfile: Dockerfile
args:
POSTGRES_USER: ${POSTGRES_USER-postgres}
POSTGRES_GROUP: ${POSTGRES_GROUP-postgres}
POSTGRES_UID: ${POSTGRES_UID-999}
POSTGRES_GID: ${POSTGRES_GID-999}
# PostgreSQL 6.5 時代の標準インストール先をホームとして使う
working_dir: /usr/local/pgsql
volumes:
# postgres ホーム兼インストール先を named volume で永続化
- postgres6-pgsql:/usr/local/pgsql
# PostgreSQL 6.5 時代の標準ソース配置
- postgres6-src:/usr/src/pgsql
ports:
- "5432:5432" # PostgreSQL(注: macOS ホスト localhost のみで使う前提。LAN 公開する場合は要見直し)
tty: true
stdin_open: true
init: true
# 常駐用のダミープロセス(作業時は exec で入る)
command: ["sleep", "infinity"]
restart: unless-stopped
volumes:
postgres6-pgsql:
postgres6-src:
GitHub Copilot CLI のインストール
公式ドキュメントのscript でインストールにあるように、curl -fsSL https://gh.io/copilot-install | bashだけであっさりとインストールできてしまいます。
$ curl -fsSL https://gh.io/copilot-install | bash
Installing GitHub Copilot CLI...
Downloading from: https://github.com/github/copilot-cli/releases/latest/download/copilot-linux-arm64.tar.gz
✓ Checksum validated
✓ GitHub Copilot CLI installed to /usr/local/pgsql/.local/bin/copilot
Installation complete! Run 'copilot help' to get started.
インストール先の
/usr/local/pgsql/.local/bin/copilotは、このDockerイメージでpostgresユーザーのホームディレクトリが/usr/local/pgsqlに設定されているためです。
copilot で起動するので、/login でログインします。コンテナ中で実行しているので、ブラウザが起動しないため、手動でURLhttps://github.com/login/deviceをコピーしてデバイス認証を行い、無事にログインすることができました。ここで一旦/exitコマンドで終了しておきます。
GitHub Copilot CLIも他のAIコーディングエージェント同様、頻繁にアップデートが行われているので、アップデートの方法を確認します。CLIの中から /versionで最新版の有無を確認できるので、必要に応じて/update コマンドでアップデートします。いつでも最新の機能を利用したいので、随時アップデートは実行していきたいと思います。(2026年5月5日時点のバージョンはv1.0.40でした)
第1ラウンド——GPT-5.4で挑戦
PostgreSQL 6.5のビルド
それではGitHub Copilot CLIの力を借りて、1999年当時の最新である6.5.3をソースからビルドしてみたいと思います。
compose.ymlで用意したソース用のディレクトリ/usr/src/pgsqlに移動し、copilotを起動します。極力自走してもらいたいので、Shift+Tabを2回押してオートパイロット モードにします。
❯ PostgreSQL 6.5.3 をソースコードからビルドして。

さすがオートパイロット モードです。途中いろいろとエラーに遭遇しましたが、そのたびに自己解決して、最後はビルドを完了させました。
Task complete: ビルド完了の詳細ログ(GPT-5.4)
● Task complete
└ ビルド完了。 PostgreSQL 6.5.3 のソースを /usr/src/pgsql/postgresql-6.5.3 に展開し、現代の aarch64/Linux + GCC 13 + glibc
で通るよう最小限の互換修正を入れたうえでビルドしました。
主要成果物は以下です。
- src/backend/postgres
- src/bin/psql/psql
- src/interfaces/libpq/libpq.a
- src/interfaces/libpq/libpq.so.2.0
今回は make -f GNUmakefile COPT='-fcommon' CFLAGS_SL='-fPIC' all で通しています。修正内容は主に configure の GCC
バージョン取得、errno 周りの現代 glibc
対応、aarch64 用スピンロック実装、共有ライブラリ向け PIC 対応です。
補足: pl/plpgsql は古い lexer/parser 由来のエラーが出ますが、6.5.3 のトップレベル make はここを無視して進み、PostgreSQL
本体と主要クライアント/ライブラリは生成済みです.
インストール
❯次はテスト? それとも make install ?
Task complete: install 完了と配置先の詳細(GPT-5.4)
● Task complete
└ 完了。 PostgreSQL 6.5.3 をソースからビルドし、/usr/src/pgsql/pgsql-6.5.3-install に install まで行いました。aarch64/Linux
向けに必要だった互換修正も反映済みです。
確認できたこと:
- src/backend/postgres など主要成果物をビルド
- make -f GNUmakefile POSTGRESDIR=/usr/src/pgsql/pgsql-6.5.3-install COPT='-fcommon' CFLAGS_SL='-fPIC' install で配置
- install 済み postmaster を起動
- install 済み psql で SELECT 1; 実行成功
- createdb / destroydb 実行成功
主な配置先:
- bin: /usr/src/pgsql/pgsql-6.5.3-install/bin
- lib: /usr/src/pgsql/pgsql-6.5.3-install/lib
- テスト用データディレクトリ: /usr/src/pgsql/pgsql-6.5.3-data
注意点: 1999 年当時のコードを現代の aarch64 + GCC 13 + glibc で動かすため、configure・errno・スピンロック・BKI
生成物に互換修正を入れています。pl/plpgsql
は依然としてこの環境ではビルド失敗のままですが、PostgreSQL 本体、libpq、psql、createdb、destroydb は動作確認済みです.
psql起動
❯ 別のシェルから psql で確認したいので、PostgreSQL を起動して。
確認用のサンプルデータベースも作成して。
Task complete: PostgreSQL 起動・サンプル DB 作成の詳細(GPT-5.4)
● Task complete
└ 起動しました。 PostgreSQL 6.5.3 はバックグラウンドで動作中で、確認用の sampledb も作成済みです。接続先は localhost:55432
です。
別シェルからの確認例:
export PATH=/usr/src/pgsql/pgsql-6.5.3-install/bin:$PATH
export LD_LIBRARY_PATH=/usr/src/pgsql/pgsql-6.5.3-install/lib:$LD_LIBRARY_PATH
psql -p 55432 sampledb
サンプルテーブル:
SELECT * FROM greetings;
期待される結果:
id|message
--+---------------------------
1|hello from PostgreSQL 6.5.3
補足:
- install 先: /usr/src/pgsql/pgsql-6.5.3-install
- データディレクトリ: /usr/src/pgsql/pgsql-6.5.3-data
- サーバログ: /usr/src/pgsql/pgsql-6.5.3-postmaster.log
- 停止する場合: kill $(ps -u postgres -o pid=,args= | grep 'postmaster -D /usr/src/pgsql/pgsql-6.5.3-data -p 55432 -i' |
grep -v grep | awk '{print $1}')
順調にビルドからSQLの実行まで進みました。問題は、ここからでした。他にもいろいろ試そうと、psql のメタコマンド(バックスラッシュ付きの \dt など)を実行してみると、エラーになってしまいました。
この解決もGitHub Copilot CLIに依頼します。
❯postgres@0713719379b9:~$ psql -p 55432 sampledb
Welcome to the POSTGRESQL interactive sql monitor:
Please read the file COPYRIGHT for copyright terms of POSTGRESQL
[PostgreSQL 6.5.3 on arm-unknown-linux-gnu, compiled by gcc gcc (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0]
type \? for help on slash commands
type \q to quit
type \g or terminate with semicolon to execute query
You are currently connected to the database: sampledb
sampledb=> \dt
pqReadData() -- backend closed the channel unexpectedly.
This probably means the backend terminated abnormally
before or while processing the request.
エラーを解決して。
どうやら今回の特殊な環境6.5.3/aarch64では、挙動が不安定になるケースがあり解決が難しいので、別のアプローチで回避する結果となりました。
● Task complete
└ 修正しました。 psql の \dt が backend を落としていた原因を回避し、今は正常に一覧が返ります。
今回の 6.5.3/aarch64 環境では、`
- pg_class.relacl 読み取り
- relname !~ '^pg_' の正規表現フィルタ
- 従来の \dt 実装経路
のどれかを踏むと不安定になるため、psql の \dt を安全な直接 SQLへ差し替えました。現在の \dt は次のように動きます。
sampledb=> \dt
relation |type|relhasrules
--------------+----+-----------
greetings |r |f
...
注意: この回避版 \dt はシステムテーブルも含めて表示します。greetings は一覧に出ます。いったん psql
を起動し直せば新しいバイナリが使われます。
起動コマンドはそのままで大丈夫です。
export PATH=/usr/src/pgsql/pgsql-6.5.3-install/bin:$PATH
export LD_LIBRARY_PATH=/usr/src/pgsql/pgsql-6.5.3-install/lib:$LD_LIBRARY_PATH
psql -p 55432 sampledb
数分で原因を特定して解決してくれました。他にもありそうなので、チェックするように依頼しました。
❯ 他にも psql 内で不安定になるコマンドや処理があるかどうかチェックして。
● 一覧系でまだ落ちているものは、ほぼ全部「古い psql が危険な SQL を組み立てている」パターンでした。安全な直接 SQL に置き換えられるものはまとめて直します。
❯ なぜ危険なのか解説して。
● Task complete
└ 危険なのは、SQL が悪いというより「6.5.3 の backend 実装が現代環境で壊れる経路を踏む」からです。
今回の環境は PostgreSQL 6.5.3 + aarch64 + GCC 13 + 現代 glibc で、当時想定されていた i386/Linux
などと前提がかなり違います。そのため、psql
が作る一見まっとうな問い合わせでも、backend の古い実装バグや未互換部分を刺激すると backend process が segmentation fault
して接続断になります。
今回実際に危険だったのは主に 2 系統です。
1. relacl のような古いカタログ列アクセス
\z が使う SELECT relname, relacl FROM pg_class ... で落ちました。これは ACL 配列/可変長データの取り扱いが、現代 ABI
やメモリ配置では安全に動いていない可能性が高いです。
2. !~ '^pg_' のような正規表現フィルタ
\dt 系の元クエリは relname !~ '^pg_' を含んでいて、これだけで backend
が落ちる再現が取れました。つまり正規表現演算子の実装か、その評価中に呼ばれる古い文字列処理が現代環境で壊れています。
ポイントは、psql はメタコマンドのために内部で特殊な SQL を自動生成することです。ユーザーは \dt
としか打っていなくても、backend 側ではその危険な SQL
が実行されます。だから「単なる一覧コマンドなのに落ちる」ように見えます。
逆に言うと、危険なのは psql そのものではなく、psql が backend の壊れやすいコードパスを踏む SQL
を生成していたことです。なので今回は psql 側で、問題のある列や演算子を使わない安全な SQL
に差し替えて回避しました。
ここで驚いたのが、古いがゆえのバグを顕在化してくれました。Copilot CLI(GPT-5.4)の調査により、psql が backend の壊れやすいコードパスを踏む SQL を生成していたことがわかったので、Copilot CLI(GPT-5.4)はそこを修正し、安全なアプローチに書き換えています。
Task complete: メタコマンド安定性の一覧表(GPT-5.4)
● Task complete
└ チェックしました。 現状の PostgreSQL 6.5.3 / psql では、主要メタコマンドの安定性は次のとおりです。
┌──────────┬───────────────────┐
│ コマンド │ 状態 │
├──────────┼───────────────────┤
│ \l │ OK │
├──────────┼───────────────────┤
│ \dt │ OK │
├──────────┼───────────────────┤
│ \di │ OK │
├──────────┼───────────────────┤
│ \ds │ OK │
├──────────┼───────────────────┤
│ \da │ OK │
├──────────┼───────────────────┤
│ \df │ OK │
├──────────┼───────────────────┤
│ \do │ OK │
├──────────┼───────────────────┤
│ \dT │ OK │
├──────────┼───────────────────┤
│ \d │ backend crash │
├──────────┼───────────────────┤
│ \dS │ backend crash │
├──────────┼───────────────────┤
│ \z │ backend crash │
└──────────┴───────────────────┘
今回直したもの: \dt, \di, \ds, \da, \df, \do, \dT は、安全な直接 SQL を使うように psql
を差し替えて、落ちないことを確認しました。
まだ不安定なもの:
- \z は relacl 系のアクセスで backend が落ちます。
- \d と \dS は、まだ旧来の describe/listing 経路のどこかで backend を落とします。
通常の SQL 実行 (SELECT 1;, SELECT * FROM greetings; など) と、上の OK コマンド群は使えます。
しかしまだ完璧ではありません。3つのメタコマンドが不安定で psql が落ちたりします。しかし、これ以上深追いしても四半世紀以上の環境差を完璧に埋めることは不可能だと判断し、ひとまずGitHub Copilot CLI x GPT-5.4での検証を終えたいと思います。
Task complete: パッチファイル作成の詳細(GPT-5.4)
❯ 次回以降はパッチを当てられるようにパッチファイルを作成して。
● Task complete
└ パッチファイルを作成しました。 次回はこれを素の PostgreSQL 6.5.3
ソースに当てれば、今回の互換修正をまとめて再適用できます。
- パッチファイル: /usr/src/pgsql/postgresql-6.5.3-aarch64-compat.patch
適用方法:
cd /path/to/postgresql-6.5.3
patch -p1 < /usr/src/pgsql/postgresql-6.5.3-aarch64-compat.patch
このパッチには、少なくとも次が入っています。
- GCC 13/現代 configure 向け修正
- aarch64 用スピンロック対応
- errno 周りの現代 glibc 対応
- genbki.sh.in の修正(name が ame に壊れる生成不具合の根因修正)
- psql メタコマンドの安全側修正
補足: このパッチは生成物ではなく、元のソースに直接当てるための source-only patch です。素の postgresql-6.5.3.tar.gz へ
patch --dry-run -p1 で適用確認済みです。
今回行った修正をパッチファイル(490行)としてまとめてもらい、第1ラウンドは終了とします。完璧な勝利とは言えませんが、大きな勝ち(価値)をつかみ取ってくれました。参考までにトークンとPremium Requestの使用状況は以下のようになりました。
Changes +138 -173
Requests 10 Premium (1h 38m 11s)
Tokens ↑ 19.1m • ↓ 55.0k • 18.5m (cached) • 17.5k (reasoning)
今後のために2つのボリュームのバックアップを取っておきます。
mkdir -p backups
docker compose stop postgres6
docker run --rm --user 0 \
-v postgres6_postgres6-pgsql:/volume:ro \
-v "$PWD/backups:/backup" \
postgres6-postgres6:latest \
tar -C /volume -czf /backup/postgres6-pgsql-$(date +%Y%m%d-%H%M%S).tar.gz .
docker run --rm --user 0 \
-v postgres6_postgres6-src:/volume:ro \
-v "$PWD/backups:/backup" \
postgres6-postgres6:latest \
tar -C /volume -czf /backup/postgres6-src-$(date +%Y%m%d-%H%M%S).tar.gz .
第2ラウンド——Claude Opus 4.7で深掘り
第1ラウンドで使った環境を全てリセットして、Dockerイメージを再作成し、GitHub Copilot CLIをもう一度インストールします。そしてモデルにclaude-opus-4.7を指定します。
- 揃えたもの: Dockerイメージ、PostgreSQL 6.5.3のソース、最初のプロンプト(「PostgreSQL 6.5.3 をソースコードからビルドして。」)
- 変えたもの: モデル指定(GPT-5.4 → Claude Opus 4.7)
● Model changed from gpt-5.4 (medium) to claude-opus-4.7 (medium)
第1ラウンドと同じように、まずはビルドしてという依頼をしました。今回もオートパイロット モードがとても自律的にエラーを修正しながらビルドし、さらにはインストールまで行っています。しかも、第1ラウンドではsrcディレクトリ以下に独自のディレクトリを作ってインストールしていたのに対し、今回はデフォルトの/usr/local/pgsqlにインストールしています。このあたりがモデルの違いなのでしょうか。
Task complete: ビルド・インストール完了の詳細(Claude Opus 4.7)
❯ PostgreSQL 6.5.3 をソースコードからビルドして。
● Task complete
└ PostgreSQL 6.5.3 を /usr/local/pgsql にビルド・インストールしました。
実施内容
1. ソース取得: https://ftp.postgresql.org/pub/source/v6.5/postgresql-6.5.3.tar.gz を /usr/src/pgsql に展開。
2. aarch64 サポート追加:
- src/config.sub に aarch64 / aarch64-* を追加
- src/template/linux_aarch64 を作成 (CFLAGS: -O2 -fcommon)
- src/template/.similar に aarch64-unknown-linux-gnu=linux_aarch64 登録
- src/include/storage/s_lock.h に __aarch64__ 用の tas() を __sync_lock_test_and_set で実装
3. モダン環境向けの修正:
- configure(.in) の CC_VERSION を gcc --version | head -1 に修正 (sed multi-line 問題)
- backend/utils/error/{exc.c,elog.c} の extern int sys_nerr; を撤去 (glibc
2.32+ で削除)
- 6 ファイルに #include <errno.h> を追加 (TLS errno リンクエラー解消)
- backend/catalog/genbki.sh の gcc -E に -P 追加、s/^NameData/\name/g の \n 解釈バグ修正
- interfaces/libpq++ に using namespace std; と <cstring> を追加 (modern C++ 対応)
動作確認
PostgreSQL 6.5.3 on aarch64-unknown-linux-gnu,
compiled by gcc (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0
initdb → postmaster 起動 → CREATE TABLE / INSERT / SELECT まで成功確認。
使い方
export LD_LIBRARY_PATH=/usr/local/pgsql/lib
export PGLIB=/usr/local/pgsql/lib PGDATA=/path/to/data USER=postgres
export PATH=/usr/local/pgsql/bin:$PATH
initdb && postmaster -D $PGDATA
注: pl/plpgsql は古い flex/yacc との互換性のため省略 (Makefile 側で ignored)。コア機能には影響なし。
Task complete: PostgreSQL 起動と sampledb 作成(Claude Opus 4.7)
❯ 別のシェルから psql で確認したいので、PostgreSQL を起動して。
確認用のサンプルデータベースも作成して。
● Task complete
└ PostgreSQL 6.5.3 を起動し、サンプルデータベースを作成しました。
起動状態
- postmaster PID: 10877 (init の子プロセスとして常駐)
- ポート: 5432 (TCP/IP -i 有効)
- データディレクトリ: /usr/local/pgsql/data
- ログ: /usr/local/pgsql/postmaster.log
別シェルからの接続
export LD_LIBRARY_PATH=/usr/local/pgsql/lib
export PATH=/usr/local/pgsql/bin:$PATH
psql -d sampledb
# または
psql -h localhost -p 5432 -U postgres sampledb
サンプルデータベース sampledb
┌────────────┬──────┬──────────────────────────────────────────┐
│ テーブル │ 行数 │ カラム │
├────────────┼──────┼──────────────────────────────────────────┤
│ users │ 3 │ id, name, email │
├────────────┼──────┼──────────────────────────────────────────┤
│ products │ 3 │ id, name, price │
├────────────┼──────┼──────────────────────────────────────────┤
│ orders │ 4 │ id, user_id, product_id, qty, ordered_at │
└────────────┴──────┴──────────────────────────────────────────┘
SELECT, 2 テーブル JOIN, count などの動作を確認済みです。
停止: kill 10877
psql: SELECT 動作確認のログ(Claude Opus 4.7)
postgres@ba7ca84bc6c2:~$ export LD_LIBRARY_PATH=/usr/local/pgsql/lib
postgres@ba7ca84bc6c2:~$ export PATH=/usr/local/pgsql/bin:$PATH
postgres@ba7ca84bc6c2:~$ psql -d sampledb
Welcome to the POSTGRESQL interactive sql monitor:
Please read the file COPYRIGHT for copyright terms of POSTGRESQL
[PostgreSQL 6.5.3 on aarch64-unknown-linux-gnu, compiled by gcc gcc (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0]
type \? for help on slash commands
type \q to quit
type \g or terminate with semicolon to execute query
You are currently connected to the database: sampledb
sampledb=> SELECT * FROM products;
id|name | price
--+------+------
1|Coffee|450.00
2|Tea |350.00
3|Cake |600.00
(3 rows)
sampledb=>
指示に従ってコマンドを打つと、問題なくSELECTクエリが実行できました。問題は次です。
sampledb=> \dt
pqReadData() -- backend closed the channel unexpectedly.
This probably means the backend terminated abnormally
before or while processing the request.
sampledb=> \d
PQsendQuery() -- There is no connection to the backend.
sampledb=> \dS
PQsendQuery() -- There is no connection to the backend.
sampledb=> \z
PQsendQuery() -- There is no connection to the backend.

残念ながら、第1ラウンドと同じ現象が再現されましたので、解決を依頼します。
❯ エラーを解決して。
● Task complete
└ 解決完了 ✅
根本原因
PG 6.5.3 の makeList(elem, ..., -1) は可変引数の終端センチネルとして int -1 を渡していましたが、makeList 側は
va_arg(args, void *) で 8
バイトとして読み出します。aarch64 (LP64) では int=4B / pointer=8B のため、
- センチネル -1 がポインタ (void
*)-1 (= 0xFFFFFFFFFFFFFFFF) と等しくならず、ループが終端を見逃す
- 0xFFFFFFFF (int -1 の下位 32bit) などのゴミポインタがリストに混入
これが parse_expr.c:212 の makeList(lexpr, rexpr, -1) で発生し、AND ノードの args に不正ポインタが入り、リライタの
fireRIRonSubselect で SIGSEGV
を引き起こしていました。
なお ^ 開始の正規表現で発症したのは、parser/gram.y の makeIndexable() が「^pattern」を インデックス利用最適化 のため AND
ノードに分解する→case AND: が makeList(...,
-1) を呼ぶ、というパスを通るためです。
修正内容
makeList() の全呼び出し(5 ファイル:parser/parse_expr.c, parser/analyze.c, parser/gram.y, parser/gram.c,
rewrite/rewriteManip.c,
nodes/list.c)で、終端 -1 を (void *)-1 にキャスト。これでポインタサイズで渡され、va_arg(args, void *)
の比較が正しく終端を検出します。
動作確認
$ psql -d sampledb
sampledb=> \dt -- ✅ users / products / orders 表示
sampledb=> \d users -- ✅ カラム情報表示
sampledb=> \dS -- ✅ システムカタログ一覧
sampledb=> \z -- ✅ 権限一覧
sampledb=> SELECT 'pg_x'::text !~ '^pg_'::text; -- ✅ f
postmaster (PID 17574) が引き続きポート 5432 で稼働中。postgres ユーザの別シェルから psql -d sampledb
でそのまま接続して全スラッシュコマンドが使えます。
※AIコーディングエージェントの出力では「5ファイル」と要約されていますが、列挙されているのは6ファイルです。出力の忠実な再現として原文のまま掲載しています。

30分以上時間を使ってじっくり問題解決に取り組んだ結果、第1ラウンドでは解決できなかった問題を解決してくれました。
Task complete: 網羅安定性チェックとパッチ集約(Claude Opus 4.7)
❯ 他にも psql 内で不安定になるコマンドや処理があるかどうかチェックして。
● Task complete
└ psql 内の網羅的安定性チェックを実施。新規クラッシュは検出されず、makeList aarch64
センチネル修正は広範な不安定処理(3テーブル
JOIN、VIEW、サブクエリ、集約、トランザクション、各種スラッシュコマンド等)に有効と確認。
検出された他の事象は全て PG 6.5 時代の SQL 機能ギャップ(多行 VALUES 未サポート、SIMILAR TO 未実装、untyped NULL の
COALESCE/IS NULL、numeric × float の
operator 欠落 等)であり、移植バグではない。
潜在リスクとしてビルド時の cast to pointer from integer 警告 91 件は同種の int↔ptr ABI
❯ 次回以降はパッチを当てられるようにパッチファイルを作成して。
● Task complete
└ PostgreSQL 6.5.3 の aarch64 + modern gcc/glibc 対応パッチを単一ファイル化:
~/.copilot/session-state/<session-id>/files/patches/postgresql-6.5.3-aarch64-modern-gcc.patch (15
KB)
22 ファイルの差分を集約、ヘッダにバグの背景・適用手順を記載。pristine tarball 対する dry-run
と実適用で検証済み。生成物(gram.c, configure 出力, .sh ファイル等)は除外し、
./configure && make で再生成される設計。
今回の修正で作成されたパッチファイルは423行でした。また、トークンとPremium Requestの使用状況は以下のようになりました。レートも15倍なので仕方ないですが、GPT-5.4と比べると12倍の 120 Premium でした。
Requests 120 Premium (1h 29m 42s)
Tokens ↑ 20.9m • ↓ 92.8k • 20.4m (cached)

これで第2ラウンドも完了です。
第1ラウンドと第2ラウンドの比較
Premium Request はGitHub Copilotの利用枠の単位で、モデルごとに消費量が異なります。この記事では、各ラウンドで表示された利用量として比較しています。モデル名と倍率は公式の対応モデル一覧も参照してください。
| モデル | Premium Request | 到達点 |
|---|---|---|
| GPT-5.4 | 10 | ビルドとSQLの実行まで到達。psql の主要メタコマンドは復活したが、\d \dS \z は残課題 |
| Claude Opus 4.7 | 120(12倍) |
makeList() のABI不整合まで掘り下げ、\d \dS \z を含むメタコマンドを復活 |
GPT-5.4 は少ない Premium Request で、短時間に進めるには十分でした。一方で、最後に残ったaarch64特有のABI不整合、つまり関数の呼び出し規約やデータ型のサイズ差に起因する問題まで掘り下げるには Claude Opus 4.7 が必要でした。速さの GPT-5.4、深さの Claude Opus 4.7。その両方を --model で切り替えられること自体が、今回 GitHub Copilot CLI を選んだ一番大きな収穫でした。
まとめ
今回の実験では、1999年のPostgreSQL 6.5.3を、今のUbuntu(aarch64)上でビルドし、SQLを実行できるところまで再現できました。
20年以上前の古いソースコードを現代の環境で動かすと、単なるビルドエラーだけでなく、アーキテクチャやABIの違いまで表に出てきます。そこにAIコーディングエージェントがどこまで踏み込めるのかを、実例として確認できたのが今回の収穫でした。
機会があれば、また別の古いソフトウェアでも試してみたいと思います。次回もお楽しみに。
もし今回のような検証が面白く読めたなら、『オトナの自由研究』は他にもいろいろな記事を公開しています。連載全体の地図と、自分に合う「最初の一本」の選び方は以下の記事にまとめてあるので、気になる切り口から覗いてみてください。
この記事は「オトナの自由研究」シリーズの番外編です。消費財メーカーでデジタル戦略を推進する筆者が、最新テクノロジーを自分の手で試し、何ができるのか・どんな価値を生むのかを検証する過程を記録しています。
※本連載は個人の実験と学びの共有であり、所属組織の公式見解ではありません。
※記事内の評価結果は、2026年4月時点の検証環境(ハードウェア/ソフトウェア/モデルバージョン)とプロンプト条件に依存する単発の観測であり、再現性や恒常的な品質を保証するものではありません。
Discussion