# 機能設計書 11-DROP TABLE処理

## 概要

本ドキュメントは、SQLiteにおけるDROP TABLE文の処理機能について記述する。DROP TABLEはデータベーススキーマからテーブル定義を削除し、関連するすべてのデータ、インデックス、トリガーを破棄する機能である。

### 本機能の処理概要

**業務上の目的・背景**：データベース運用において、不要になったテーブルや誤って作成したテーブルを削除する必要がある。DROP TABLE機能は、テーブル定義とそのデータを完全に削除し、ストレージ領域を解放するために不可欠な機能である。また、アプリケーションのバージョンアップ時のスキーマ変更や、テスト環境のクリーンアップにも使用される。

**機能の利用シーン**：
- 不要になったテーブルの削除
- スキーマ変更時の古いテーブル構造の破棄
- テスト・開発環境でのデータベースリセット
- アプリケーションのアンインストール時のデータクリーンアップ

**主要な処理内容**：
1. テーブル名の解決とスキーマ検証
2. 認証コールバックによるアクセス権限チェック
3. システムテーブル・シャドウテーブルの保護チェック
4. 関連トリガーの削除
5. AUTOINCREMENTシーケンス情報の削除
6. sqlite_schemaテーブルからのメタデータ削除
7. B-Treeルートページの破棄
8. 統計テーブル（sqlite_stat1〜4）からの関連エントリ削除
9. 外部キー制約の処理
10. スキーマ変更の確定（スキーマクッキーの更新）

**関連システム・外部連携**：VDBEバイトコードエンジン、B-Treeストレージエンジン、ページャー

**権限による制御**：sqlite3_set_authorizer()で設定された認可コールバックにより、SQLITE_DROP_TABLE、SQLITE_DROP_TEMP_TABLE、SQLITE_DROP_VTABLE等のアクションコードでアクセス制御が可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 8 | SQLite3 Fiddle | 主機能 | テーブル削除DDLの実行 |

## 機能種別

DDL操作（データ定義言語） / スキーマ変更 / データ削除

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| pName | SrcList* | Yes | 削除対象テーブル名（データベース名を含む場合あり） | テーブルの存在確認、アクセス権限確認 |
| isView | int | Yes | ビュー削除フラグ（0=テーブル, LOCATE_VIEW=ビュー） | DROP VIEW/DROP TABLEの区別 |
| noErr | int | Yes | IF EXISTS指定フラグ | 1の場合、テーブル不存在時もエラーなし |

### 入力データソース

- SQL文解析結果（パーサーから渡されるトークン情報）
- データベーススキーマ（sqlite_schemaテーブル）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | void | 直接的な戻り値なし（エラーはParse構造体に設定） |
| pParse->nErr | int | エラー発生時にインクリメント |
| pParse->zErrMsg | char* | エラーメッセージ |

### 出力先

- sqlite_schemaテーブル（メタデータ削除）
- B-Treeストレージ（データページ解放）
- sqlite_statN テーブル（統計情報削除）
- sqlite_sequence テーブル（AUTOINCREMENT情報削除）

## 処理フロー

### 処理シーケンス

```
1. スキーマ読み込み
   └─ sqlite3ReadSchema()でデータベーススキーマを読み込み

2. テーブル検索
   └─ sqlite3LocateTableItem()でテーブルオブジェクトを取得

3. 仮想テーブルの場合
   └─ sqlite3ViewGetColumnNames()で列情報を初期化

4. 認証チェック
   └─ sqlite3AuthCheck()でSQLITE_DELETE、SQLITE_DROP_TABLE等を確認

5. ドロップ不可テーブルのチェック
   └─ tableMayNotBeDropped()でsqlite_*テーブル等を保護

6. VIEW/TABLE区別チェック
   └─ DROP TABLEでビューを削除しようとした場合エラー

7. VDBEコード生成開始
   └─ sqlite3GetVdbe()でVDBEプログラムを取得

8. 書き込みトランザクション開始
   └─ sqlite3BeginWriteOperation()

9. 統計テーブルのクリア
   └─ sqlite3ClearStatTables()でsqlite_stat1〜4から削除

10. 外部キー処理
    └─ sqlite3FkDropTable()で参照整合性チェック

11. テーブル削除コード生成
    └─ sqlite3CodeDropTable()でVDBE命令生成
```

### フローチャート

```mermaid
flowchart TD
    A[DROP TABLE開始] --> B{スキーマ読み込み成功?}
    B -->|No| Z[終了]
    B -->|Yes| C[テーブル検索]
    C --> D{テーブル存在?}
    D -->|No| E{IF EXISTS指定?}
    E -->|Yes| Z
    E -->|No| F[エラー: no such table]
    F --> Z
    D -->|Yes| G[認証チェック]
    G --> H{認証成功?}
    H -->|No| Z
    H -->|Yes| I{システムテーブル?}
    I -->|Yes| J[エラー: may not be dropped]
    J --> Z
    I -->|No| K{VIEW/TABLE一致?}
    K -->|No| L[エラー: use DROP VIEW/TABLE]
    L --> Z
    K -->|Yes| M[VDBE取得]
    M --> N[書き込みトランザクション開始]
    N --> O[統計テーブルクリア]
    O --> P[外部キー処理]
    P --> Q[関連トリガー削除]
    Q --> R[AUTOINCREMENT情報削除]
    R --> S[sqlite_schema更新]
    S --> T[B-Tree破棄]
    T --> U[スキーマクッキー更新]
    U --> Z
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-11-01 | システムテーブル保護 | sqlite_で始まるシステムテーブルは削除不可（sqlite_stat*とsqlite_parametersを除く） | 常時 |
| BR-11-02 | シャドウテーブル保護 | Defensiveモード有効時、仮想テーブルのシャドウテーブルは削除不可 | SQLITE_Defensive有効時 |
| BR-11-03 | VIEW/TABLE区別 | DROP TABLEではビューを削除不可、DROP VIEWではテーブルを削除不可 | 常時 |
| BR-11-04 | IF EXISTS | IF EXISTS指定時、テーブル不存在でもエラーにしない | IF EXISTS指定時 |
| BR-11-05 | エポニマステーブル保護 | エポニマス仮想テーブル（名前で参照される一時的仮想テーブル）は削除不可 | 常時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| トリガー削除 | sqlite_schema | DELETE | テーブルに関連するトリガー定義を削除 |
| AUTOINCREMENT削除 | sqlite_sequence | DELETE | AUTOINCREMENTカウンタを削除 |
| メタデータ削除 | sqlite_schema | DELETE | テーブル・インデックス定義を削除 |
| 統計情報削除 | sqlite_stat1〜4 | DELETE | テーブル統計情報を削除 |
| データ削除 | 対象テーブル | 全データ削除 | B-Treeルートページを破棄 |

### テーブル別操作詳細

#### sqlite_schema

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | - | tbl_name=%Q AND type!='trigger' | トリガーは別途削除 |

#### sqlite_sequence

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | - | name=%Q | AUTOINCREMENTテーブルのみ |

#### sqlite_stat1〜4

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | - | tbl=%Q | 統計テーブルが存在する場合のみ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | no such table | テーブルが存在しない（IF EXISTSなし） | 正しいテーブル名を指定 |
| - | table %s may not be dropped | システムテーブル等の削除試行 | 削除対象を確認 |
| - | use DROP VIEW to delete view %s | DROP TABLEでビューを削除しようとした | DROP VIEWを使用 |
| - | use DROP TABLE to delete table %s | DROP VIEWでテーブルを削除しようとした | DROP TABLEを使用 |
| SQLITE_AUTH | 認証エラー | authorizerコールバックが拒否 | 権限を確認 |

### リトライ仕様

DROP TABLEはアトミック操作であり、失敗時は自動ロールバックされる。明示的なリトライ機構は提供されない。

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

- 書き込みトランザクション内で実行される
- sqlite3BeginWriteOperation()により排他ロックを取得
- スキーマクッキーが更新され、他の接続のキャッシュが無効化される
- エラー発生時は全変更がロールバックされる

## パフォーマンス要件

- テーブルサイズに比例した処理時間（B-Tree破棄のため）
- 大規模テーブルの削除時はauto_vacuumモードでページ再編成が発生する可能性あり

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

- sqlite3_set_authorizer()コールバックによるアクセス制御
- システムテーブル（sqlite_*）の保護
- Defensiveモードでのシャドウテーブル保護
- 仮想テーブル削除時のxDestroy/VDestroyコールバック呼び出し

## 備考

- 仮想テーブルの場合、OP_VBeginでトランザクション開始、OP_VDestroyで破棄処理を実行
- DROP TABLEはDDL文であり、暗黙的にトランザクションをコミットする

---

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

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

### 推奨読解順序

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

まず、DROP TABLE処理で使用される主要なデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | sqliteInt.h | `src/sqliteInt.h` | Table構造体、SrcList構造体、Parse構造体の定義 |
| 1-2 | btreeInt.h | `src/btreeInt.h` | B-Tree関連の構造体定義 |

**読解のコツ**: Table構造体のtabFlagsフィールドには、TF_Autoincrement、TF_Shadow、TF_Eponymousなどの重要なフラグがビットマスクで格納されている。

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

処理の起点となる関数を特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | build.c | `src/build.c` | sqlite3DropTable()関数（3490行目〜）がエントリーポイント |

**主要処理フロー**:
1. **3496-3498行目**: メモリアロケーション失敗チェック
2. **3503行目**: sqlite3ReadSchema()でスキーマ読み込み
3. **3506行目**: sqlite3LocateTableItem()でテーブル検索
4. **3516行目**: sqlite3SchemaToIndex()でデータベースインデックス取得
5. **3560行目**: tableMayNotBeDropped()でシステムテーブルチェック
6. **3584行目**: sqlite3BeginWriteOperation()で書き込み開始
7. **3586行目**: sqlite3ClearStatTables()で統計テーブルクリア
8. **3587行目**: sqlite3FkDropTable()で外部キー処理
9. **3589行目**: sqlite3CodeDropTable()で削除コード生成

#### Step 3: テーブル削除コード生成を理解する

sqlite3CodeDropTable()関数の詳細。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | build.c | `src/build.c` | sqlite3CodeDropTable()関数（3382行目〜） |

**主要処理フロー**:
- **3388行目**: sqlite3GetVdbe()でVDBEプログラム取得
- **3390行目**: sqlite3BeginWriteOperation()でトランザクション開始
- **3402-3408行目**: 関連トリガーのループ削除
- **3416-3421行目**: AUTOINCREMENTのsqlite_sequence削除
- **3431-3434行目**: sqlite_schemaからメタデータ削除
- **3436行目**: destroyTable()でB-Treeルートページ破棄
- **3446行目**: OP_DropTable命令追加
- **3447行目**: sqlite3ChangeCookie()でスキーマクッキー更新

#### Step 4: 統計テーブルクリア処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | build.c | `src/build.c` | sqlite3ClearStatTables()関数（3359行目〜） |

**主要処理フロー**:
- **3367-3376行目**: sqlite_stat1〜4の各テーブルに対してDELETE文を生成

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

```
sqlite3DropTable() [build.c:3490]
    │
    ├─ sqlite3ReadSchema() [prepare.c]
    │      └─ スキーマ読み込み
    │
    ├─ sqlite3LocateTableItem() [build.c:481]
    │      └─ sqlite3LocateTable() [build.c:408]
    │             └─ sqlite3FindTable() [build.c:337]
    │
    ├─ sqlite3AuthCheck() [auth.c]
    │      └─ 認証コールバック呼び出し
    │
    ├─ tableMayNotBeDropped() [build.c:3471]
    │      └─ sqlite3ReadOnlyShadowTables() [build.c:3455]
    │
    ├─ sqlite3GetVdbe() [vdbeaux.c]
    │
    ├─ sqlite3BeginWriteOperation() [build.c]
    │
    ├─ sqlite3ClearStatTables() [build.c:3359]
    │      └─ sqlite3NestedParse() [build.c:293]
    │
    ├─ sqlite3FkDropTable() [fkey.c]
    │
    └─ sqlite3CodeDropTable() [build.c:3382]
           ├─ sqlite3TriggerList() [trigger.c]
           ├─ sqlite3DropTriggerPtr() [trigger.c]
           ├─ sqlite3NestedParse() [build.c:293]
           ├─ destroyTable() [build.c]
           ├─ OP_VDestroy (仮想テーブル時)
           ├─ OP_DropTable
           └─ sqlite3ChangeCookie() [build.c]
```

### データフロー図

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

DROP TABLE文 ──────▶ パーサー ──────────────▶ Parse構造体
                          │
                          ▼
               sqlite3DropTable()
                          │
           ┌──────────────┼──────────────┐
           ▼              ▼              ▼
    認証チェック    スキーマ検証    テーブル検索
           │              │              │
           └──────────────┼──────────────┘
                          ▼
              sqlite3CodeDropTable()
                          │
           ┌──────────────┼──────────────┐
           ▼              ▼              ▼
    トリガー削除    AUTOINCREMENT   B-Tree破棄
                      削除
           │              │              │
           └──────────────┼──────────────┘
                          ▼
               sqlite_schema ──────▶ メタデータ削除
               sqlite_stat* ───────▶ 統計情報削除
               sqlite_sequence ────▶ シーケンス削除
               B-Tree pages ───────▶ ページ解放
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| build.c | `src/build.c` | ソース | DROP TABLE主要処理、sqlite3DropTable()、sqlite3CodeDropTable() |
| trigger.c | `src/trigger.c` | ソース | トリガー削除処理 |
| fkey.c | `src/fkey.c` | ソース | 外部キー制約処理 |
| auth.c | `src/auth.c` | ソース | 認証処理 |
| vdbeaux.c | `src/vdbeaux.c` | ソース | VDBEヘルパー関数 |
| btree.c | `src/btree.c` | ソース | B-Tree操作（ページ破棄） |
| sqliteInt.h | `src/sqliteInt.h` | ヘッダー | 主要データ構造定義 |
| vdbe.h | `src/vdbe.h` | ヘッダー | VDBE命令定義 |
