# 機能設計書 25-ORCサポート

## 概要

本ドキュメントは、Apache SparkにおけるApache ORCカラムナフォーマットの読み書き機能の設計について記述する。述語プッシュダウンやカラムプルーニングに対応し、効率的なデータI/Oを提供する。

### 本機能の処理概要

SparkのORCサポートは、Apache ORC（Optimized Row Columnar）カラムナストレージフォーマットの読み書き機能を提供する。ORCはHiveエコシステムで広く使用されるカラム指向フォーマットであり、高い圧縮率、述語プッシュダウン、カラムプルーニング、ACIDトランザクション対応等の機能を持つ。

**業務上の目的・背景**：Hiveエコシステムとの互換性を保ちつつ、大規模データの効率的な分析処理を可能にする。ORCフォーマットはHiveテーブルの標準的なストレージフォーマットの一つであり、既存のHiveデータ資産をSparkで活用するために必要な機能である。

**機能の利用シーン**：Hiveテーブルのデータ読み書き、データレイク上のORC形式データの処理、ETLパイプラインでのORC形式出力、Parquetの代替フォーマットとしての利用。

**主要な処理内容**：
1. ORCファイルの読み込み（スキーマ推論、述語プッシュダウン、カラムプルーニング）
2. ORCファイルの書き出し（圧縮コーデック選択、パーティション書き込み）
3. OrcFiltersによるSpark述語からORCフィルタへの変換
4. OrcSerializer/OrcDeserializerによるデータ変換
5. ベクトル化読み取り（OrcColumnarBatchReader対応）

**関連システム・外部連携**：Apache ORCライブラリ、Hadoop FileSystem API、Hiveメタストア（Hiveテーブル連携時）

**権限による制御**：ファイルシステムのアクセス権限に依存。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 直接関連する画面なし |

## 機能種別

データ連携 / CRUD操作 / ファイルI/O

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| path | String | Yes | ORCファイルパス | 有効なファイルシステムパス |
| compression | String | No | 圧縮コーデック（snappy, zlib, lzo, zstd, none） | サポート対象コーデック |
| mergeSchema | Boolean | No | スキーママージの有効/無効 | true/false |
| spark.sql.orc.filterPushdown | Boolean | No | フィルタプッシュダウン（デフォルト: true） | true/false |

### 入力データソース

- Hadoop互換ファイルシステム上のORCファイル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| DataFrame | Dataset[Row] | 読み込まれたORCデータ |
| InternalRow | InternalRow | 行単位の内部データ表現 |

### 出力先

- DataFrame/Dataset（読み取り結果）
- Hadoop互換ファイルシステム上のORCファイル（書き出し結果）

## 処理フロー

### 処理シーケンス

```
1. OrcFileFormatによるデータソース登録（shortName "orc"）
   └─ FileFormat/DataSourceRegister/SessionStateHelperの実装
2. 読み込み時: スキーマ推論
   └─ OrcUtils.inferSchema()によるORCメタデータからのスキーマ取得
3. フィルタプッシュダウン
   └─ OrcFilters.createFilter()でSpark述語をORC SearchArgumentに変換
4. 書き出し時: OrcOutputWriterによる書き込み
   └─ 圧縮コーデック適用（COMPRESS属性で設定）
```

### フローチャート

```mermaid
flowchart TD
    A[spark.read.orc] --> B[OrcFileFormat]
    B --> C{スキーマ指定?}
    C -->|Yes| D[ユーザースキーマ適用]
    C -->|No| E[OrcUtils.inferSchema]
    D --> F[OrcFilters.createFilter]
    E --> F
    F --> G[カラムプルーニング]
    G --> H[OrcデータReader]
    H --> I[OrcDeserializer]
    I --> J[InternalRow]
    J --> K[DataFrame]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-25-01 | デフォルト圧縮 | OrcOptions.compressionCodecで圧縮コーデックを制御 | 書き出し時 |
| BR-25-02 | フィルタ変換 | OrcFiltersBaseとOrcFiltersがSpark述語をORC SearchArgumentに変換 | 読み込み時 |
| BR-25-03 | スキーマ推論 | OrcUtils.inferSchema()がORCファイルメタデータからスキーマを推論 | スキーマ未指定時 |

### 計算ロジック

ORC SearchArgumentを使用した述語プッシュダウンにより、ストライプ（ORC内のデータ単位）レベルでのフィルタリングを実現。各ストライプの統計情報（min/max/count）を利用して、条件に合致しないストライプをスキップする。

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

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

本機能はファイルシステム上のORCファイルを対象とし、直接的なデータベース操作は行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ORC_READ_ERROR | 読み取りエラー | ORCファイルの破損・不正フォーマット | ファイルの確認・再生成 |
| SCHEMA_MISMATCH | スキーマエラー | スキーマの互換性問題 | スキーマ確認 |
| CODEC_NOT_FOUND | コーデックエラー | 指定された圧縮コーデックが未サポート | サポート対象コーデックの確認 |

### リトライ仕様

ファイル読み取りの失敗はタスクレベルでリトライされる。

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

書き出し時はFileOutputCommitterによるコミットプロトコルが適用される。

## パフォーマンス要件

- カラムプルーニングによる不要データの読み飛ばし
- 述語プッシュダウンによるストライプスキップ
- 圧縮による転送データ量の削減

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

- ファイルシステムのアクセス権限に依存
- ORC暗号化機能（encryption zones対応）

## 備考

- SparkはApache ORC公式ライブラリを使用
- Hive互換のORC読み書きが可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | OrcOptions.scala | `sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/orc/OrcOptions.scala` | ORC固有オプション定義 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | OrcFileFormat.scala | `sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/orc/OrcFileFormat.scala` | FileFormatインターフェース実装 |

**主要処理フロー**:
1. **49-53行目**: OrcFileFormatクラス定義、FileFormat/DataSourceRegister/SessionStateHelperの実装
2. **55行目**: shortName() = "orc"
3. **63-68行目**: inferSchema() - OrcUtils.inferSchemaに委譲
4. **70-80行目**: prepareWrite() - OrcOptionsとCOMPRESS属性の設定

#### Step 3: フィルタ処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | OrcFilters.scala | `sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/orc/OrcFilters.scala` | Spark述語からORC SearchArgumentへの変換 |
| 3-2 | OrcFiltersBase.scala | `sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/orc/OrcFiltersBase.scala` | フィルタ変換基底クラス |

#### Step 4: シリアライゼーションを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | OrcSerializer.scala | `sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/orc/OrcSerializer.scala` | Spark InternalRowからORC型への変換 |
| 4-2 | OrcDeserializer.scala | `sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/orc/OrcDeserializer.scala` | ORC型からSpark InternalRowへの変換 |

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

```
DataFrameReader.orc() / spark.read.orc()
    │
    ├─ OrcFileFormat
    │      ├─ inferSchema() → OrcUtils.inferSchema()
    │      ├─ prepareWrite() → OrcOptions + COMPRESS設定
    │      └─ buildReaderWithPartitionValues()
    │             ├─ OrcFilters.createFilter() (述語プッシュダウン)
    │             ├─ OrcDeserializer (デシリアライゼーション)
    │             └─ OrcColumnarBatchReader (ベクトル化)
    │
    └─ OrcOutputWriter
           └─ OrcSerializer → ORC Writer (Apache ORCライブラリ)
```

### データフロー図

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

ORCファイル ──────────▶ OrcFileFormat ──────────▶ DataFrame
(HDFS/S3/GCS)            │
                         ├─ スキーマ推論 (OrcUtils)
                         ├─ フィルタプッシュダウン (OrcFilters)
                         ├─ カラムプルーニング
                         └─ デシリアライゼーション (OrcDeserializer)

DataFrame ───────────▶ OrcOutputWriter ─────────▶ ORCファイル
                         │
                         ├─ シリアライゼーション (OrcSerializer)
                         └─ 圧縮コーデック適用
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| OrcFileFormat.scala | `sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/orc/OrcFileFormat.scala` | ソース | V1 ORCデータソース実装 |
| OrcFilters.scala | `sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/orc/OrcFilters.scala` | ソース | フィルタプッシュダウン変換 |
| OrcFiltersBase.scala | `sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/orc/OrcFiltersBase.scala` | ソース | フィルタ変換基底クラス |
| OrcSerializer.scala | `sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/orc/OrcSerializer.scala` | ソース | Spark→ORC型変換 |
| OrcDeserializer.scala | `sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/orc/OrcDeserializer.scala` | ソース | ORC→Spark型変換 |
| OrcUtils.scala | `sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/orc/OrcUtils.scala` | ソース | ユーティリティ関数 |
| OrcOptions.scala | `sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/orc/OrcOptions.scala` | ソース | ORCオプション定義 |
| OrcOutputWriter.scala | `sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/orc/OrcOutputWriter.scala` | ソース | ORC書き込み |
| OrcShimUtils.scala | `sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/orc/OrcShimUtils.scala` | ソース | ORC互換ユーティリティ |
