# 機能設計書 26-PRAGMA

## 概要

本ドキュメントは、SQLiteのPRAGMA機能の設計を記述する。PRAGMAはSQLite固有の特殊コマンドで、データベースエンジンの動作設定、状態照会、メンテナンス操作を行う。

### 本機能の処理概要

PRAGMAコマンドはSQLiteの内部動作パラメータの取得・設定、データベースの整合性チェック、スキーマ情報の照会など、多岐にわたる機能を提供する。

**業務上の目的・背景**：データベース管理者や開発者が、SQLiteエンジンの動作を細かく制御・監視するための統一インターフェースを提供する。標準SQLでは定義されていない、データベースエンジン固有の設定や操作を行える。

**機能の利用シーン**：
- パフォーマンスチューニング（cache_size, synchronous等）
- 整合性検証（integrity_check, quick_check）
- スキーマ情報取得（table_info, index_list等）
- セキュリティ設定（foreign_keys等）
- デバッグ・診断（compile_options等）

**主要な処理内容**：
1. 設定値の取得・変更（get/set型PRAGMA）
2. テーブル形式での情報返却（query型PRAGMA）
3. アクション実行（action型PRAGMA）
4. データベースメンテナンス

**関連システム・外部連携**：VDBEを通じてPRAGMA処理を実行。ページャー、B-Tree、キャッシュ等の各サブシステムに対する設定を変更する。

**権限による制御**：authorizerコールバックでPRAGMA単位で許可/拒否が可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | CLIメイン | 主機能 | PRAGMA入力・結果表示 |
| 9 | Speedtest1（メインスレッド版） | 補助機能 | ベンチマーク設定 |
| 10 | Speedtest1（Worker版） | 補助機能 | ベンチマーク設定 |

## 機能種別

設定管理 / データベースユーティリティ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| pragma_name | TEXT | Yes | PRAGMA名 | 有効なPRAGMA名 |
| schema | TEXT | No | データベース名（schema.pragma形式） | 存在するスキーマ |
| value | varies | No | 設定値 | PRAGMAごとに異なる |

### 入力データソース

- SQL文によるPRAGMAコマンド

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 結果行 | varies | PRAGMA種別による |

### 出力先

- クエリ結果として返却
- または副作用として設定変更

## 処理フロー

### 処理シーケンス

```
1. SQL解析
   └─ PRAGMA [schema.]pragma_name [(value)] をパース

2. PRAGMA名検索
   └─ aPragmaName[]配列からバイナリサーチ

3. authorizer呼び出し
   └─ SQLITE_PRAGMAアクションで認可チェック

4. PRAGMA種別に応じた処理
   └─ get/set型: 値の取得または設定
   └─ query型: 結果セット生成
   └─ action型: 操作実行
```

### フローチャート

```mermaid
flowchart TD
    A[PRAGMA command] --> B{PRAGMA名検索}
    B -->|見つからない| C[無視またはエラー]
    B -->|見つかった| D{authorizer許可?}
    D -->|拒否| E[エラー返却]
    D -->|許可| F{値指定有り?}
    F -->|No| G[現在値を返却]
    F -->|Yes| H[値を設定]
    H --> I[新しい値を返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-26-01 | 未知PRAGMA無視 | 未知のPRAGMA名はエラーでなく無視 | 常時 |
| BR-26-02 | スキーマ指定 | schema.pragma形式で特定DBへ適用 | スキーマ指定時 |
| BR-26-03 | 読み取り専用PRAGMA | compile_options等は値設定不可 | 常時 |
| BR-26-04 | トランザクション制限 | 一部PRAGMAはトランザクション外でのみ有効 | PRAGMA依存 |

### 主要PRAGMAカテゴリ

| カテゴリ | 例 | 説明 |
|---------|-----|------|
| キャッシュ制御 | cache_size, cache_spill | ページキャッシュ設定 |
| ジャーナル制御 | journal_mode, synchronous | トランザクションログ設定 |
| 整合性検査 | integrity_check, quick_check | データ整合性検証 |
| スキーマ情報 | table_info, index_list | メタデータ取得 |
| コンパイル設定 | compile_options | ビルド時オプション照会 |
| 外部キー | foreign_keys, foreign_key_check | 参照整合性 |
| 自動処理 | auto_vacuum, incremental_vacuum | 領域管理 |

## データベース操作仕様

### 操作別データベース影響一覧

| PRAGMA | 対象 | 操作種別 | 概要 |
|-----|-------------|---------|------|
| journal_mode | DBファイル | WRITE | ジャーナルモード変更 |
| wal_checkpoint | WALファイル | WRITE | チェックポイント実行 |
| integrity_check | 全ページ | READ | 整合性検査 |
| optimize | sqlite_stat | WRITE | 統計情報更新 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| SQLITE_ERROR | 値エラー | 無効な設定値 | 有効な値を指定 |
| SQLITE_AUTH | 認可拒否 | authorizerで拒否 | 権限を確認 |
| SQLITE_BUSY | ロック競合 | journal_mode変更中 | リトライ |
| SQLITE_READONLY | 読み取り専用 | 設定変更不可 | 書き込み可能DBを使用 |

### リトライ仕様

SQLITE_BUSY時、busy_handlerが設定されていればコールバックを呼び出す。

## トランザクション仕様

- ほとんどのPRAGMAはトランザクション外で実行推奨
- journal_modeはトランザクション中に変更不可（WAL↔非WAL）
- read_uncommittedはトランザクション動作に影響

## パフォーマンス要件

- PRAGMA検索: バイナリサーチによるO(log n)
- integrity_check: 全ページスキャンのためO(n)

## セキュリティ考慮事項

- authorizerでPRAGMA実行を制限可能
- writable_schemaは危険なため注意が必要
- trusted_schemaでSQL関数の信頼性を制御

## 備考

- SQLITE_OMIT_PRAGMAで一部PRAGMA無効化可能
- PRAGMA function_listでSQL関数一覧取得可能

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: PRAGMA定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | pragma.h | `src/pragma.h` | PragmaName構造体、aPragmaName[]配列 |
| 1-2 | pragma.c | `src/pragma.c` | pragmaLocate()関数（311-326行目） |

**読解のコツ**:
- pragma.hは自動生成ファイル（tool/mkpragmatab.tclで生成）
- aPragmaName[]は辞書順ソート済みでバイナリサーチ可能
- PragType_XXXマクロがPRAGMA種別を示す

#### Step 2: PRAGMA処理のエントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | pragma.c | `src/pragma.c` | sqlite3Pragma()関数（メイン処理） |

**主要処理フロー**:
1. PRAGMA名のバイナリサーチ
2. authorizerコールバック呼び出し
3. PragTypeに応じた分岐処理

#### Step 3: ヘルパー関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | pragma.c | `src/pragma.c` | getSafetyLevel()（72-92行目） |
| 3-2 | pragma.c | `src/pragma.c` | sqlite3GetBoolean()（97-99行目） |
| 3-3 | pragma.c | `src/pragma.c` | getLockingMode()（110-116行目） |
| 3-4 | pragma.c | `src/pragma.c` | getAutoVacuum()（125-132行目） |
| 3-5 | pragma.c | `src/pragma.c` | returnSingleInt()（217-220行目） |
| 3-6 | pragma.c | `src/pragma.c` | returnSingleText()（225-232行目） |

**主要処理フロー**:
- **72-92行目**: 安全レベル文字列→数値変換（on/off/false/yes/true/extra/full）
- **110-116行目**: ロッキングモード解析（exclusive/normal）
- **125-132行目**: auto_vacuumモード解析（none/full/incremental）
- **217-220行目**: 単一整数値の結果行返却
- **225-232行目**: 単一テキスト値の結果行返却

#### Step 4: 個別PRAGMAを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | pragma.c | `src/pragma.c` | integrity_check処理（integrityCheckResultRow等） |
| 4-2 | pragma.c | `src/pragma.c` | journal_mode処理 |
| 4-3 | pragma.c | `src/pragma.c` | table_info処理 |

### プログラム呼び出し階層図

```
sqlite3Pragma() [pragma.c]
    │
    ├─ pragmaLocate()
    │      └─ バイナリサーチでPRAGMA検索
    │
    ├─ sqlite3AuthCheck()
    │      └─ authorizerコールバック
    │
    └─ switch(pPragma->mPragFlg)
           │
           ├─ PragTyp_FLAG (get/setフラグ)
           │      └─ returnSingleInt()
           │
           ├─ PragTyp_CACHE_SIZE
           │      ├─ sqlite3BtreeSetCacheSize()
           │      └─ returnSingleInt()
           │
           ├─ PragTyp_JOURNAL_MODE
           │      ├─ sqlite3PagerJournalMode()
           │      └─ returnSingleText()
           │
           ├─ PragTyp_INTEGRITY_CHECK
           │      ├─ sqlite3BtreeIntegrityCheck()
           │      └─ 結果行生成
           │
           └─ PragTyp_TABLE_INFO
                  └─ テーブル情報クエリ生成
```

### データフロー図

```
[入力]                    [処理]                      [出力]

PRAGMA name ────────▶ pragmaLocate()
                            │
                    バイナリサーチ
                            │
                    PragmaName構造体
                            │
                    authorizer確認
                            │
                    ┌───────┴───────┐
                    │               │
               値なし           値あり
                    │               │
              現在値取得        値設定
                    │               │
                    └───────┬───────┘
                            │
                            ▼
                    結果行返却 ────────────▶ クライアント

PRAGMA integrity_check ▶ sqlite3BtreeIntegrityCheck()
                            │
                    全ページスキャン
                            │
                    エラー検出
                            │
                            ▼
                    エラー行返却 ──────────▶ クライアント
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| pragma.c | `src/pragma.c` | ソース | PRAGMA処理主実装 |
| pragma.h | `src/pragma.h` | ヘッダ | PRAGMA定義（自動生成） |
| pager.c | `src/pager.c` | ソース | ジャーナル関連PRAGMA |
| btree.c | `src/btree.c` | ソース | キャッシュ関連PRAGMA |
| build.c | `src/build.c` | ソース | スキーマ関連PRAGMA |
