# 機能設計書 19-VDBEトレース

## 概要

本ドキュメントは、SQLiteにおけるVDBEトレース機能について記述する。VDBEトレースは、sqlite3_trace()やEXPLAIN文で使用されるSQL文の展開とトレース出力を提供する機能である。

### 本機能の処理概要

**業務上の目的・背景**：データベースアプリケーションのデバッグやパフォーマンス分析において、実行されるSQL文の内容を確認することは重要である。特にプリペアドステートメントでは、バインドパラメータの実際の値を含む完全なSQL文を確認したいニーズがある。VDBEトレース機能は、ホストパラメータ（?、?N、:name等）を実際の値に展開したSQL文を生成する。

**機能の利用シーン**：
- sqlite3_trace_v2()コールバックでのSQL文ロギング
- デバッグ時のSQL確認
- パフォーマンス分析ツールとの連携
- EXPLAIN出力の生成

**主要な処理内容**：
1. SQL文字列のスキャンとトークン解析
2. ホストパラメータの検出
3. バインド変数の値取得
4. パラメータ値のリテラル形式への変換
5. 展開済みSQL文字列の構築

**関連システム・外部連携**：VDBEバイトコードエンジン、sqlite3_trace_v2()コールバック

**権限による制御**：特になし（デバッグ機能）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 直接的な画面関連なし（デバッグ機能） |

## 機能種別

デバッグ支援 / トレース出力

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| p | Vdbe* | Yes | プリペアドステートメント | 有効なVdbe |
| zRawSql | const char* | Yes | 元のSQL文（パラメータ付き） | - |

### 入力データソース

- プリペアドステートメントのSQL文
- バインドされたパラメータ値（p->aVar[]）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | char* | パラメータ展開済みSQL文字列（要sqlite3_free） |

### 出力先

- 呼び出し元（展開済みSQL文字列）
- トレースコールバック

## 処理フロー

### 処理シーケンス

```
1. 出力バッファ初期化
   └─ sqlite3StrAccumInit()

2. ネスト実行チェック
   └─ db->nVdbeExec > 1の場合はコメント形式で出力

3. パラメータなしチェック
   └─ p->nVar == 0の場合はそのまま出力

4. トークンスキャンループ
   └─ findNextHostParameter()で次のパラメータ位置検出
   └─ パラメータまでのテキストを出力

5. パラメータ種別判定
   └─ ?: 位置パラメータ
   └─ ?N: 番号付きパラメータ
   └─ :name, $name, @name, #name: 名前付きパラメータ

6. パラメータインデックス取得
   └─ sqlite3VdbeParameterIndex()で名前からインデックス取得

7. 値のリテラル変換
   └─ NULL: "NULL"
   └─ 整数: "%lld"
   └─ 実数: "%!.15g"
   └─ 文字列: "'%.*q'"（クォートエスケープ）
   └─ BLOB: "x'..'"（16進数）
   └─ zeroblob: "zeroblob(%d)"

8. 文字列完成
   └─ sqlite3StrAccumFinish()
```

### フローチャート

```mermaid
flowchart TD
    A[VDBEトレース開始] --> B[出力バッファ初期化]
    B --> C{ネスト実行?}
    C -->|Yes| D[コメント形式で全文出力]
    D --> Z[終了]
    C -->|No| E{パラメータあり?}
    E -->|No| F[SQL文そのまま出力]
    F --> Z
    E -->|Yes| G[トークンスキャン]
    G --> H{パラメータ検出?}
    H -->|No| I[残りテキスト出力]
    I --> Z
    H -->|Yes| J[パラメータまでのテキスト出力]
    J --> K[パラメータ種別判定]
    K --> L[インデックス取得]
    L --> M{値の型}
    M -->|NULL| N["NULL"出力]
    M -->|整数| O[整数リテラル出力]
    M -->|実数| P[実数リテラル出力]
    M -->|文字列| Q[クォート文字列出力]
    M -->|BLOB| R[16進BLOB出力]
    N --> G
    O --> G
    P --> G
    Q --> G
    R --> G
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-19-01 | ネスト実行 | nVdbeExec > 1の場合はコメント形式（-- ）で出力 | 常時 |
| BR-19-02 | 文字列エスケープ | シングルクォートは''にエスケープ | 文字列値 |
| BR-19-03 | サイズ制限 | SQLITE_TRACE_SIZE_LIMIT定義時は長いデータを切り詰め | 定義時 |
| BR-19-04 | UTF-16変換 | UTF-16データはUTF-8に変換して出力 | UTF-16時 |

### 計算ロジック

特になし

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

データベースへの直接操作なし（読み取りのみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| SQLITE_NOMEM | メモリ不足 | 出力バッファ割り当て失敗 | NULLを返却 |

### リトライ仕様

エラー時はNULL返却。リトライなし。

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

トランザクションとは無関係（読み取り専用処理）

## パフォーマンス要件

- SQL文長に比例した処理時間
- トレースは通常デバッグ時のみ有効化

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

- パラメータ値がログに出力されるため、機密データの漏洩に注意
- 本番環境でのトレース有効化は慎重に

## 備考

- SQLITE_OMIT_TRACE定義時はこの機能は無効
- sqlite3_trace_v2()のSQLITE_TRACE_STMTフラグで呼び出される

---

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

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

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | vdbeInt.h | `src/vdbeInt.h` | Vdbe構造体のaVar[]（バインド変数配列） |
| 1-2 | sqliteInt.h | `src/sqliteInt.h` | StrAccum構造体（文字列構築用） |

**読解のコツ**:
- p->aVar[]: バインドされた値の配列（Mem構造体）
- p->nVar: バインド変数の数
- StrAccum: 動的文字列構築用の構造体

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | vdbetrace.c | `src/vdbetrace.c` | sqlite3VdbeExpandSql()がメイン関数 |

**主要処理フロー**:
1. **72-89行目**: 関数シグネチャと変数宣言
2. **90-97行目**: ネスト実行時のコメント形式出力
3. **98-99行目**: パラメータなし時のそのまま出力
4. **101-102行目**: findNextHostParameter()でパラメータ検索
5. **108-124行目**: パラメータ種別に応じたインデックス取得
6. **129-185行目**: 値の型に応じたリテラル出力
7. **188-189行目**: 結果文字列の完成

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | vdbetrace.c | `src/vdbetrace.c` | findNextHostParameter()（29-46行目）- パラメータ位置検出 |

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

```
sqlite3VdbeExpandSql() [vdbetrace.c:72]
    │
    ├─ sqlite3StrAccumInit() [printf.c]
    │      └─ 出力バッファ初期化
    │
    ├─ (ネスト実行時)
    │      └─ sqlite3_str_append() で"-- "付き出力
    │
    ├─ findNextHostParameter() [vdbetrace.c:29]
    │      └─ sqlite3GetToken() でトークン解析
    │
    ├─ sqlite3VdbeParameterIndex() [vdbeapi.c]
    │      └─ 名前付きパラメータのインデックス取得
    │
    ├─ (値の型に応じた出力)
    │      ├─ MEM_Null: "NULL"
    │      ├─ MEM_Int/IntReal: sqlite3_str_appendf("%lld")
    │      ├─ MEM_Real: sqlite3_str_appendf("%!.15g")
    │      ├─ MEM_Str: sqlite3_str_appendf("'%.*q'")
    │      ├─ MEM_Zero: sqlite3_str_appendf("zeroblob(%d)")
    │      └─ MEM_Blob: sqlite3_str_appendf("x'%02x'...")
    │
    └─ sqlite3StrAccumFinish() [printf.c]
           └─ 結果文字列の確定
```

### データフロー図

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

zRawSql ─────────▶ sqlite3VdbeExpandSql()
(元SQL文)                     │
                              ▼
                    findNextHostParameter()
                              │
                              ▼
                    ┌─────────┴─────────┐
                    ▼                   ▼
            テキスト部分          パラメータ部分
                    │                   │
                    ▼                   ▼
            そのまま出力        p->aVar[idx]参照
                                        │
                                        ▼
                               値の型に応じた変換
                                        │
                    ┌───────────────────┼───────────────────┐
                    ▼                   ▼                   ▼
               "NULL"            整数/実数          'string'/x'blob'
                    │                   │                   │
                    └───────────────────┼───────────────────┘
                                        ▼
                                展開済みSQL ──────▶ 呼び出し元
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| vdbetrace.c | `src/vdbetrace.c` | ソース | VDBEトレースメイン処理 |
| vdbeapi.c | `src/vdbeapi.c` | ソース | sqlite3VdbeParameterIndex() |
| printf.c | `src/printf.c` | ソース | StrAccum関連関数 |
| tokenize.c | `src/tokenize.c` | ソース | sqlite3GetToken() |
| vdbeInt.h | `src/vdbeInt.h` | ヘッダー | Vdbe構造体定義 |
