# 機能設計書 28-組み込みSQL関数

## 概要

本ドキュメントは、SQLiteの組み込みSQL関数（func.c）の機能設計を記述する。これらの関数はSQL文内で使用できる標準的な文字列操作、数値演算、型変換などの機能を提供する。

### 本機能の処理概要

組み込みSQL関数は、SELECT文やWHERE句、その他のSQL式内で呼び出すことができるスカラー関数と集約関数を提供する。日付・時刻関数（date.c）とJSON関数（json.c）は別ファイルで実装される。

**業務上の目的・背景**：SQL内でデータ変換や計算を行うことで、アプリケーション層でのデータ処理を削減し、効率的なクエリ実行を可能にする。標準的なSQL関数に加え、SQLite独自の便利な関数も提供される。

**機能の利用シーン**：
- 文字列操作（連結、部分文字列、大文字/小文字変換）
- 数値計算（絶対値、四捨五入、乱数）
- NULL処理（coalesce, ifnull, nullif）
- 型情報取得（typeof）
- 集約処理（sum, avg, count, min, max）

**主要な処理内容**：
1. スカラー関数：1行ごとに値を計算
2. 集約関数：複数行から単一の値を計算
3. ウィンドウ関数：パーティション内での計算

**関連システム・外部連携**：VDBEが関数を呼び出し、結果をsqlite3_result_*で返却。

**権限による制御**：authorizer関数でユーザー定義関数を制限可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | CLIメイン | 主機能 | SQLクエリでの関数使用 |

## 機能種別

SQL関数 / データ変換

## 入力仕様

### 入力パラメータ

関数ごとに異なる。以下は代表的な関数の例。

| 関数名 | 引数 | 説明 |
|--------|-----|------|
| length(X) | TEXT/BLOB | 文字数またはバイト数 |
| substr(X,Y,Z) | TEXT/BLOB, INT, INT | 部分文字列 |
| instr(X,Y) | TEXT, TEXT | 検索位置 |
| abs(X) | NUMERIC | 絶対値 |
| round(X,Y) | NUMERIC, INT | 四捨五入 |

### 入力データソース

- SQL文の式として呼び出し

## 出力仕様

### 出力データ

関数の戻り値として返却。型は関数により異なる。

### 出力先

- クエリ結果の列として返却

## 処理フロー

### 処理シーケンス

```
1. SQL解析
   └─ 関数呼び出しを識別

2. 関数検索
   └─ 組み込み関数テーブルから検索

3. 引数評価
   └─ 各引数を評価

4. 関数実行
   └─ xSFunc（スカラー）またはxStep/xFinal（集約）を呼び出し

5. 結果返却
   └─ sqlite3_result_*で結果を設定
```

### フローチャート

```mermaid
flowchart TD
    A[関数呼び出し] --> B{組み込み?}
    B -->|Yes| C[引数型チェック]
    B -->|No| D[ユーザー定義関数検索]
    C --> E{スカラー or 集約?}
    E -->|スカラー| F[xSFunc呼び出し]
    E -->|集約| G[xStep/xFinal呼び出し]
    F --> H[sqlite3_result_*]
    G --> H
    H --> I[結果返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-28-01 | NULL伝播 | ほとんどの関数はNULL引数に対してNULLを返す | 例外: coalesce, ifnull |
| BR-28-02 | 型変換 | 必要に応じて自動的に型変換 | 関数依存 |
| BR-28-03 | オーバーフロー | 整数オーバーフロー時はエラーまたは浮動小数点へ | abs(-9223372036854775808) |
| BR-28-04 | 照合順序 | 文字列関数は照合順序に従う | min/max等 |

### 主要関数カテゴリ

| カテゴリ | 関数例 | 説明 |
|---------|-----|------|
| 文字列 | length, substr, instr, replace, trim | 文字列操作 |
| 数値 | abs, round, max, min, random | 数値計算 |
| NULL | coalesce, ifnull, nullif, iif | NULL処理 |
| 型 | typeof, cast | 型情報/変換 |
| 集約 | sum, avg, count, total, group_concat | 集約計算 |
| その他 | hex, zeroblob, quote, printf | ユーティリティ |

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

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

組み込みSQL関数はデータベースを直接変更しない（読み取り専用）。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| SQLITE_ERROR | オーバーフロー | abs(-9223372036854775808) | エラー返却 |
| SQLITE_NOMEM | メモリ不足 | 大きな文字列操作 | メモリ確保後再試行 |
| SQLITE_TOOBIG | サイズ超過 | SQLITE_LIMIT_LENGTH超過 | 制限内の操作 |

### リトライ仕様

特になし。

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

- 組み込み関数はトランザクション状態に依存しない
- random()は非決定的だが、トランザクションセーフ

## パフォーマンス要件

- 関数検索: ハッシュテーブルによるO(1)
- 文字列関数: 文字列長に比例O(n)
- 集約関数: 行数に比例O(n)

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

- load_extension()はデフォルトで無効
- zeroblob()で大量メモリ消費の可能性
- random()は暗号用途には不適

## 備考

- SQLITE_DETERMINISTICフラグで決定的関数を示す
- SQLITE_FUNC_INTERNALで内部関数を示す

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | func.c | `src/func.c` | sqlite3GetFuncCollSeq()（27-34行目） |
| 1-2 | func.c | `src/func.c` | sqlite3SkipAccumulatorLoad()（40-44行目） |

**読解のコツ**:
- sqlite3GetFuncCollSeq(): 関数に関連付けられた照合順序を取得
- sqlite3SkipAccumulatorLoad(): 集約関数のアキュムレータロードスキップ

#### Step 2: 代表的なスカラー関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | func.c | `src/func.c` | minmaxFunc()（49-74行目） |
| 2-2 | func.c | `src/func.c` | typeofFunc()（79-98行目） |
| 2-3 | func.c | `src/func.c` | lengthFunc()（116-150行目） |
| 2-4 | func.c | `src/func.c` | absFunc()（194-230行目） |
| 2-5 | func.c | `src/func.c` | instrFunc()（243-306行目） |
| 2-6 | func.c | `src/func.c` | substrFunc()（347-400行目以降） |

**主要処理フロー**:
- **79-98行目**: typeofFunc - sqlite3_value_type()で型を判定、"integer"/"real"/"text"/"blob"/"null"を返却
- **116-150行目**: lengthFunc - TEXT型はUTF-8文字数、BLOB/INTEGER/FLOATはバイト数
- **194-230行目**: absFunc - 整数オーバーフローチェック（SMALLEST_INT64）
- **243-306行目**: instrFunc - BLOBとTEXTの両方に対応、UTF-8マルチバイト考慮

#### Step 3: 文字列フォーマット関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | func.c | `src/func.c` | printfFunc()（311-333行目） |

**主要処理フロー**:
- **311-333行目**: printf/format関数 - PrintfArguments構造体で可変引数処理

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

```
SQL: SELECT length('hello')
    │
    ├─ sqlite3_prepare()
    │      └─ 関数検索
    │
    └─ sqlite3_step()
           │
           ├─ OP_Function
           │      │
           │      ├─ lengthFunc()
           │      │      ├─ sqlite3_value_type()
           │      │      └─ sqlite3_result_int()
           │      │
           │      └─ 結果をレジスタへ
           │
           └─ OP_ResultRow

SQL: SELECT sum(amount) FROM orders
    │
    ├─ sqlite3_prepare()
    │      └─ 集約関数検索
    │
    └─ sqlite3_step()
           │
           ├─ 行ループ
           │      └─ OP_AggStep
           │             └─ sumStep()
           │
           └─ OP_AggFinal
                  └─ sumFinalize()
```

### データフロー図

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

sqlite3_value[] ──────▶ xSFunc()
                            │
                    引数型チェック
                            │
                    計算実行
                            │
                    sqlite3_result_*()
                            │
                            ▼
                    結果値 ─────────────────▶ VDBEレジスタ

行データ ────────────▶ xStep()
                            │
                    アキュムレータ更新
                            │
               （複数行繰り返し）
                            │
                            ▼
                    xFinal()
                            │
                    最終結果計算
                            │
                            ▼
                    集約結果 ─────────────▶ VDBEレジスタ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| func.c | `src/func.c` | ソース | 組み込み関数主実装 |
| vdbe.c | `src/vdbe.c` | ソース | OP_Function実行 |
| sqlite3.h | `src/sqlite3.h` | ヘッダ | sqlite3_result_*定義 |
| sqliteInt.h | `src/sqliteInt.h` | ヘッダ | FuncDef構造体定義 |
