---
generated_at: 2026-02-04 10:30:00
metrics:
  claims_total: 70
  claims_with_evidence: 66
  claims_without_evidence: 4
confidence_derived: 0.94
---

# 根拠レポート：connector-avro 単体テストケース一覧

## 本レポートについて

### 目的
本レポートは、生成された単体テストケース一覧の信頼性を検証し、人間レビュアーが効率的にレビューできるようにすることを目的としています。

### チェック方法
以下の観点でドキュメントの内容（Claim：主張）を検証しています：

1. **根拠の有無確認**：各主張に対して、ソースコード・既存設計書・要件定義書などの根拠（Evidence）が存在するか
2. **根拠との整合性**：主張の内容が根拠と矛盾していないか
3. **網羅性**：参照すべき情報源を適切にカバーしているか

### 信頼度スコアの算出
- **confidence_derived** = 根拠あり件数 / 総主張件数
- 状態「○」：根拠あり、「△」：根拠不足または要確認

### 本レポートの使い方
1. まず「サマリー」で全体の信頼度と優先レビュー項目を確認
2. 「Claims と根拠の対応」で △ の項目を重点的にレビュー
3. 「不足情報」で補完が必要な情報源を確認

---

## 1) サマリー（まず見るところ）
- 総合信頼度（derived）：**0.94**
  - 根拠あり：66 / 70、根拠なし：4
- 優先レビュー（高）
  1. **UT-AVR-046（buildReaderの例外時リソースクローズ）**：FsInputのclose()呼び出し確認はコードの制御フローから推定しているが、実際のリソースリーク防止の完全性は実行時確認が必要
  2. **UT-AVR-063/064（supportsDataType）**：AvroUtils.supportsDataTypeの内部実装がconnector-avroモジュール外にあり、サポート/非サポートの境界が不明確
  3. **UT-AVR-067（圧縮オプション処理）**：AvroUtils.prepareWriteの内部実装がconnector-avroモジュール外にあり、圧縮オプションの具体的処理が未確認
  4. **UT-AVR-061（空ファイルリストのinferSchema）**：AvroUtils.inferSchemaの空リスト時の動作がモジュール外で定義されている

## 2) 参照した情報（Evidence一覧）
> ここに「実在するもの」だけ列挙。抽出フェーズで付けたIDをそのまま出す。

- E-01: `connector/avro/src/main/scala/org/apache/spark/sql/avro/AvroExpressionEvalUtils.scala` - schemaOfAvroメソッド定義（L27-44）
- E-02: `connector/avro/src/main/scala/org/apache/spark/sql/avro/AvroDataToCatalyst.scala` - AvroDataToCatalystクラス全体（L33-150）
- E-03: `connector/avro/src/main/scala/org/apache/spark/sql/avro/CatalystDataToAvro.scala` - CatalystDataToAvroクラス全体（L30-70）
- E-04: `connector/avro/src/main/scala/org/apache/spark/sql/avro/SchemaOfAvro.scala` - SchemaOfAvroクラス全体（L28-70）
- E-05: `connector/avro/src/main/scala/org/apache/spark/sql/avro/package.scala` - package object avro（L20-47）
- E-06: `connector/avro/src/main/scala/org/apache/spark/sql/v2/avro/AvroDataSourceV2.scala` - AvroDataSourceV2クラス全体（L26-45）
- E-07: `connector/avro/src/main/scala/org/apache/spark/sql/v2/avro/AvroPartitionReaderFactory.scala` - AvroPartitionReaderFactoryクラス全体（L48-122）
- E-08: `connector/avro/src/main/scala/org/apache/spark/sql/v2/avro/AvroScan.scala` - AvroScanクラス全体（L35-76）
- E-09: `connector/avro/src/main/scala/org/apache/spark/sql/v2/avro/AvroScanBuilder.scala` - AvroScanBuilderクラス全体（L27-55）
- E-10: `connector/avro/src/main/scala/org/apache/spark/sql/v2/avro/AvroTable.scala` - AvroTableクラス全体（L31-55）
- E-11: `connector/avro/src/main/scala/org/apache/spark/sql/v2/avro/AvroWrite.scala` - AvroWriteクラス全体（L28-40）

## 3) Claims と根拠の対応（レビューの主戦場）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-01 (UT-AVR-001) | PermissiveModeでasNullableが適用されたSQL型文字列が返る | E-01 (L36-43: parseModeのmatch式でPermissiveMode時にdt.asNullableを適用) | ○ |
| C-02 (UT-AVR-002) | FailFastModeではasNullableが適用されない | E-01 (L41-42: case _ => dt でそのまま返却) | ○ |
| C-03 (UT-AVR-003) | ネストされたスキーマが正しく変換される | E-01 (L31-35: SchemaConverters.toSqlTypeの呼び出し) | ○ |
| C-04 (UT-AVR-004) | useStableIdForUnionTypeが適用される | E-01 (L33: avroOptions.useStableIdForUnionTypeをtoSqlTypeに渡している) | ○ |
| C-05 (UT-AVR-005) | recursiveFieldMaxDepthが適用される | E-01 (L35: avroOptions.recursiveFieldMaxDepthをtoSqlTypeに渡している) | ○ |
| C-06 (UT-AVR-006) | inputTypesがSeq(BinaryType)を返す | E-02 (L39: override def inputTypes = Seq(BinaryType)) | ○ |
| C-07 (UT-AVR-007) | PermissiveModeでdataTypeがnullable型を返す | E-02 (L47-53: parseMode matchでPermissiveMode時にdt.asNullable) | ○ |
| C-08 (UT-AVR-008) | FailFastModeでdataTypeが元の型を返す | E-02 (L52: case _ => dt) | ○ |
| C-09 (UT-AVR-009) | 不正parseModeで例外スロー | E-02 (L82-86: mode != PermissiveMode && mode != FailFastModeで例外) | ○ |
| C-10 (UT-AVR-010) | nullableがtrue | E-02 (L56: override def nullable = true) | ○ |
| C-11 (UT-AVR-011) | 有効データのデシリアライズ | E-02 (L103-111: nullSafeEvalの正常系フロー) | ○ |
| C-12 (UT-AVR-012) | PermissiveModeで不正データにnull行返却 | E-02 (L116-117: NonFatalキャッチでPermissiveMode => nullResultRow) | ○ |
| C-13 (UT-AVR-013) | FailFastModeで不正データにSparkException | E-02 (L118-121: FailFastMode => throw new SparkException) | ○ |
| C-14 (UT-AVR-014) | 空バイト配列の挙動 | E-02 (L104-106: binary.lengthが0の場合のDecoderFactory動作) | ○ |
| C-15 (UT-AVR-015) | prettyNameがfrom_avro | E-02 (L130: override def prettyName = "from_avro") | ○ |
| C-16 (UT-AVR-016) | doGenCodeが正しいExprCode生成 | E-02 (L132-146: doGenCodeの実装) | ○ |
| C-17 (UT-AVR-017) | withNewChildInternalでコピー生成 | E-02 (L148-149: copy(child = newChild)) | ○ |
| C-18 (UT-AVR-018) | userProvidedSchemaの優先使用 | E-02 (L63: avroOptions.schema.getOrElse(actualSchema)) | ○ |
| C-19 (UT-AVR-019) | dataTypeがBinaryType | E-03 (L34: override def dataType = BinaryType) | ○ |
| C-20 (UT-AVR-020) | Catalyst値のAvroシリアライズ | E-03 (L51-58: nullSafeEvalの正常系フロー) | ○ |
| C-21 (UT-AVR-021) | jsonFormatSchema指定時のシリアライズ | E-03 (L37-38: jsonFormatSchema.map(_.parse)) | ○ |
| C-22 (UT-AVR-022) | スキーマ自動推論 | E-03 (L39: .getOrElse(SchemaConverters.toAvroType(...))) | ○ |
| C-23 (UT-AVR-023) | prettyNameがto_avro | E-03 (L60: override def prettyName = "to_avro") | ○ |
| C-24 (UT-AVR-024) | doGenCodeの実装 | E-03 (L62-65: doGenCodeの実装) | ○ |
| C-25 (UT-AVR-025) | withNewChildInternalでコピー | E-03 (L68-69: copy(child = newChild)) | ○ |
| C-26 (UT-AVR-026) | プリミティブ型のシリアライズ | E-03 (L54: serializer.serialize(input)) | ○ |
| C-27 (UT-AVR-027) | StructTypeのシリアライズ | E-03 (L51-58: nullSafeEval全体) | ○ |
| C-28 (UT-AVR-028) | dataTypeがStringType | E-04 (L33: override def dataType = StringType) | ○ |
| C-29 (UT-AVR-029) | nullableがfalse | E-04 (L35: override def nullable = false) | ○ |
| C-30 (UT-AVR-030) | prettyNameがschema_of_avro | E-04 (L54: override def prettyName = "schema_of_avro") | ○ |
| C-31 (UT-AVR-031) | replacementがStaticInvoke | E-04 (L60-69: override def replacement = StaticInvoke(...)) | ○ |
| C-32 (UT-AVR-032) | 不正parseModeで例外スロー | E-04 (L45-51: mode != PermissiveMode && mode != FailFastModeで例外) | ○ |
| C-33 (UT-AVR-033) | optionsのavroSchema優先 | E-04 (L42: avroOptions.schema.getOrElse(actualSchema)) | ○ |
| C-34 (UT-AVR-034) | from_avroの委譲 | E-05 (L33-36: functions.from_avroを呼び出し) | ○ |
| C-35 (UT-AVR-035) | to_avroの委譲 | E-05 (L46: functions.to_avroを呼び出し) | ○ |
| C-36 (UT-AVR-036) | fallbackFileFormatがAvroFileFormat | E-06 (L28: classOf[AvroFileFormat]) | ○ |
| C-37 (UT-AVR-037) | shortNameがavro | E-06 (L30: "avro") | ○ |
| C-38 (UT-AVR-038) | getTable(options)でAvroTable生成 | E-06 (L32-37: AvroTable(..., None, ...)) | ○ |
| C-39 (UT-AVR-039) | getTable(options, schema)でAvroTable生成 | E-06 (L39-44: AvroTable(..., Some(schema), ...)) | ○ |
| C-40 (UT-AVR-040) | .avroファイルのPartitionReader生成 | E-07 (L62: ignoreExtension || urlEncodedPath.endsWith(".avro")) | ○ |
| C-41 (UT-AVR-041) | ignoreExtension=trueで拡張子無視 | E-07 (L62: options.ignoreExtension条件) | ○ |
| C-42 (UT-AVR-042) | 非.avroファイルでEmptyPartitionReader | E-07 (L118-119: else EmptyPartitionReader) | ○ |
| C-43 (UT-AVR-043) | userProvidedSchemaの適用 | E-07 (L66-69: userProvidedSchema match) | ○ |
| C-44 (UT-AVR-044) | avroFilterPushDown=trueでOrderedFilters | E-07 (L93-94: SQLConf.get.avroFilterPushDown条件) | ○ |
| C-45 (UT-AVR-045) | avroFilterPushDown=falseでNoopFilters | E-07 (L95-96: else new NoopFilters) | ○ |
| C-46 (UT-AVR-046) | 例外時のFsInputクローズ | E-07 (L72-75: catch NonFatal -> in.close(); throw e) | ○ |
| C-47 (UT-AVR-047) | isSplitableがtrue | E-08 (L45: override def isSplitable = true) | ○ |
| C-48 (UT-AVR-048) | createReaderFactoryの生成 | E-08 (L47-63: createReaderFactoryの実装) | ○ |
| C-49 (UT-AVR-049) | 同一パラメータでequals=true | E-08 (L65-67: equals実装) | ○ |
| C-50 (UT-AVR-050) | 異なるdataSchemaでequals=false | E-08 (L66: dataSchema == a.dataSchema条件) | ○ |
| C-51 (UT-AVR-051) | 型不一致でfalse | E-08 (L68: case _ => false) | ○ |
| C-52 (UT-AVR-052) | 異なるpushedFiltersでfalse | E-08 (L67: equivalentFilters(pushedFilters, a.pushedFilters)) | ○ |
| C-53 (UT-AVR-053) | PushedFiltersメタデータ | E-08 (L73-74: getMetaData実装) | ○ |
| C-54 (UT-AVR-054) | 空フィルタのメタデータ | E-08 (L74: seqToString(pushedFilters.toImmutableArraySeq)) | ○ |
| C-55 (UT-AVR-055) | AvroScan生成 | E-09 (L35-46: build実装) | ○ |
| C-56 (UT-AVR-056) | フィルタプッシュダウン有効 | E-09 (L48-50: avroFilterPushDown条件でStructFilters.pushedFilters) | ○ |
| C-57 (UT-AVR-057) | フィルタプッシュダウン無効 | E-09 (L51-53: else Array.empty[Filter]) | ○ |
| C-58 (UT-AVR-058) | 空フィルタ配列 | E-09 (L48-53: pushDataFilters実装) | ○ |
| C-59 (UT-AVR-059) | ScanBuilder生成 | E-10 (L39-40: newScanBuilder実装) | ○ |
| C-60 (UT-AVR-060) | スキーマ推論 | E-10 (L42-43: inferSchema -> AvroUtils.inferSchema) | ○ |
| C-61 (UT-AVR-061) | 空ファイルリストのinferSchema | E-10 (L43: AvroUtils.inferSchema呼び出し) | △ |
| C-62 (UT-AVR-062) | WriteBuilder生成 | E-10 (L45-49: newWriteBuilder実装) | ○ |
| C-63 (UT-AVR-063) | supportsDataType=true | E-10 (L52: AvroUtils.supportsDataType(dataType)) | △ |
| C-64 (UT-AVR-064) | supportsDataType=false | E-10 (L52: AvroUtils.supportsDataType(dataType)) | △ |
| C-65 (UT-AVR-065) | formatNameがAVRO | E-10 (L54: "AVRO") | ○ |
| C-66 (UT-AVR-066) | prepareWrite委譲 | E-11 (L33-38: AvroUtils.prepareWrite呼び出し) | ○ |
| C-67 (UT-AVR-067) | 圧縮オプション処理 | E-11 (L38: AvroUtils.prepareWrite呼び出し) | △ |
| C-68 (UT-AVR-068) | BinaryDecoder再利用 | E-02 (L76: var decoder, L106: binaryDecoder(..., decoder)) | ○ |
| C-69 (UT-AVR-069) | OutputStream リセット | E-03 (L52: out.reset()) | ○ |
| C-70 (UT-AVR-070) | パーティション値の伝搬 | E-07 (L116-117: PartitionReaderWithPartitionValues) | ○ |

## 4) 不足情報（Unknown / Missing）
- **AvroUtils内部実装（モジュール外）**: `AvroUtils.supportsDataType`、`AvroUtils.inferSchema`、`AvroUtils.prepareWrite`の詳細実装はconnector-avroモジュール外（sql-coreまたはsql-avroパッケージ内）に定義されており、直接確認していない
  - 候補：sql-core内のAvroUtils.scala / sql-avroパッケージのAvroUtils実装
- **圧縮オプション**: `AvroUtils.prepareWrite`が圧縮オプションをどう処理するかはモジュール外の実装に依存
  - 候補：AvroUtils.prepareWrite内の圧縮コーデック設定処理

## 5) リスクフラグ（レビュー観点）
- 0（低リスク）：大半のテストケースはソースコード上のメソッドシグネチャ・制御フローと直接対応しており、高い信頼性がある
- 1（中リスク）：AvroUtils系の委譲先実装（supportsDataType、inferSchema、prepareWrite）に依存するテストケース（UT-AVR-061, 063, 064, 067）は、委譲先の具体的挙動に基づく期待結果の精度が検証不足

## 6) レビュアーチェックリスト（最小）
- [ ] AvroUtils.supportsDataTypeがサポートする/しないデータ型の具体例を確認し、UT-AVR-063/064の入力値を具体化する
- [ ] AvroUtils.inferSchemaの空ファイルリスト時の戻り値を確認し、UT-AVR-061の期待結果を確定する
- [ ] AvroUtils.prepareWriteの圧縮オプション処理を確認し、UT-AVR-067の期待結果を具体化する
- [ ] AvroDataToCatalystのnullSafeEvalで非StructType（例：ArrayType）のdataType時のnullResultRow=nullの挙動がUT-AVR-012で正しくカバーされているか確認する
- [ ] 各テストケースの優先度が組織のテスト方針と整合しているか確認する
