


C++の分析データベースエンジンを直し、必要なテストまで通す
C++で作られた分析データベースエンジンのコードを直す時に使う。SQLの解析から実行までの流れで直す場所を探し、生成ファイルは生成元のソースから作り直し、C++の書き方とエラー処理の決まりを守り、SQLロジックテストと必要なビルドを全部通してから終わりにする。
このAIルールを使うには
## 作業の段階に合わせて、ビルドの種類と回すテストを選ぶ
日常的な反復を不必要に遅くせず、有効なアサーションと診断を提供できるビルド構成を選ぶ。
### ビルド戦略
- 必要な検査を維持できる場合、デバッグシンボル付きの最適化ビルドを通常の開発構成として使用する。
- メモリ安全性、アサーション失敗、最適化の影響を受ける可能性がある動作を調査するときは、完全に計測機能を有効化したデバッグビルドを使用する。
- コミット前にリポジトリのフォーマッターを実行する。
- 承認された生成ターゲットを通じてソース由来のファイルを再生成する。このターゲットは必要なフォーマット処理も適用する。
### テスト戦略
- 通常の反復では高速なユニットテストスイートを実行する。
- 限定的な変更を診断するときは、実行範囲を単一のテストファイルまたはテストケースに絞る。
- 変更が共有動作に影響し得る場合、広範な引き渡しの前に低速テストを含む完全なスイートを実行する。
- 継続的インテグレーションの失敗を修正するときは、文書化された順序で必要な各構成を再現する。
- 影響を受ける境界で必要な場合は、構成マトリクス、ベクトル化実行、サニタイザー、アサーションの各ビルドを含める。
- 差異が無関係である証拠がないまま、失敗している正式なゲートをより高速なローカル構成で代替してはならない。
## 直す前に、SQLの解析から結果を返すまでの流れを追う
症状が最初に現れたモジュールだけを修正せず、クエリのライフサイクル全体を通して動作を追跡する。
### パイプラインの段階
1. SQLテキストを文、式、テーブル参照の構文木へ解析する。
2. 論理計画を作成しながら、カタログに対して名前と型をバインドする。
3. 意味を保つ規則とコストベースの選択によって論理計画を最適化する。
4. 論理演算子を物理演算子へ変換する。
5. ベクトル化された並列パイプラインを通じて物理演算子を実行する。
6. 接続とクライアントコンテキストを通じて結果を返す。
### コンポーネントの所有範囲
- 文法とパーサー変換を同期させる。すべての文法規則に対応する変換が必要となる。
- バインド、型解決、サブクエリ、論理演算子はプランナーの所有範囲とする。
- オプティマイザーは観測可能な意味を変えずに計画を変換する。
- 物理計画、演算子、式の評価は実行層の所有範囲とする。
- 永続ストレージ、バッファリング、圧縮、チェックポイント、先行書き込みログはストレージ層に置く。
- スキーマ、テーブル、関数、型について、カタログを唯一の信頼できる情報源として扱う。
- トランザクション、取り消し状態、マルチバージョン同時実行制御を、タスクスケジューリングや並列パイプラインから分離する。
## データを列ごとのバッチで処理し、所有権の決まりを守る
分析エンジンには、解析済み構文、バインド済み式、列の識別情報、物理ベクトル、所有権を明確に区別することが欠かせない。
### データフロー
- データを行単位ではなく、列指向のバッチで処理する。
- 各バッチ列をエンジンのベクトル抽象化で表現する。
- 計画と実行を通じて、テーブルと列のインデックスから成る安定した組を引き継ぐ。
- 解析済み式は未バインドのままにし、型付けおよびバインド済みの式から分離する。
- ベクトル化式エグゼキューターを通じてバインド済み式を評価する。
### 所有権と型
- デフォルトでは排他的なスマート所有権を使用する。
- 複数のライフタイムが本当に必要な場合に限り、共有所有権を使用する。
- null許容の非所有参照と、nullではないことが保証された参照を区別する。
- 所有権を持つ生ポインターは決して使用しない。
- 型昇格とキャストを、単一の正式な規則セットに集約する。
- 型システムを迂回せず、拡張機構を通じてカスタム型を追加する。
- 木の走査にはVisitor、デシリアライズにはFactory、演算子・エントリ・式の階層には型付きサブクラスを使用する。
## 拡張機能と生成ファイルは、生成元のソースで直す
ツリー内の拡張機能、外部で保守される拡張機能、生成コード、リリース成果物を、それぞれ異なる所有区分として扱う。
### 拡張機能の境界
- ツリー内の拡張機能は、宣言されたソースディレクトリで直接編集する。
- 外部で保守される拡張機能は別のリポジトリに置き、リポジトリ側が所有する変更は指定されたパッチ機構で適用する。
- 拡張機能一式のビルドと、明示的に指定したサブセットのビルドの両方をサポートする。
- 拡張機能の変更は、組み込み機能と同じコアインターフェースおよび型規則に対してテストする。
### 生成成果物
- APIバインディング、登録、設定、シリアライズコード、ストレージメタデータ、メトリクス、列挙型ユーティリティを生成するソースファイルを特定する。
- 生成成果物そのものだけを編集せず、その生成元となるソースを編集する。
- ソースを変更した後、承認された生成ターゲットを実行する。
- 生成された差分に無関係な変更がないか確認し、標準フォーマッターで整形する。
## C++の書き方の決まりに従い、コメントを短く保つ
低レベルコードの一貫性は、所有権、インデックス、外部向けインターフェース、制御フローに関する曖昧さを減らす。
### コードスタイル
- リポジトリのインデント規則と配置規則を使用し、フォーマッターで行幅の上限を強制する。
- プラットフォーム依存の整数幅ではなく、固定幅整数型を優先する。
- オフセット、インデックス、個数には、プロジェクト指定のインデックス型を使用する。
- 単純でない読み取り専用オブジェクトはconst参照で渡す。
- 走査を明確に表せる場合は、範囲ベースのループを優先する。
- 条件分岐とループでは必ず波括弧を使用する。
- `const_cast`は決して使用しない。
- 確立されたファイル、型、変数、関数の命名規則に従う。
### コメント
- コメントは短く保ち、通常の説明は明確なコード自体に担わせる。
- 長期的に有効な意図、制約、明白でない不変条件をコメントに記す。
- 特定の課題に固有の修正履歴をコード内に残さない。
- オフバイワン修正など変更の経緯は、変更説明またはコミットメッセージに記載する。
- コード構造と命名では不変条件を明確にできない場合に限り、長いコメントを使用する。
## エラーの種類で例外とアサーションを使い分け、SQLロジックテストを書く
クエリを終了すべきか、回復できるか、プログラマーによる内部欠陥が発生したかに応じて、エラーの伝達経路を選ぶ。
### エラーポリシー
- 解析エラー、対象オブジェクトの不在、メモリ枯渇など、クエリを終了させる失敗には例外を使用する。
- 同じクエリ内で回復可能な条件には戻り値を使用する。
- ユーザー入力では決して発生してはならないプログラマーの誤りには、デバッグアサーションを使用する。
- 違反した不変条件が分かる程度にアサーションを具体化する。
- 想定される無効な入力を内部アサーション失敗に変えてはならない。
### SQLロジックテスト
- クエリ動作にはC++テストより宣言的なSQLロジックテストを優先する。
- 成功しなければならない文と、失敗しなければならない文を分けて指定する。
- クエリで期待する結果列の型を宣言する。
- フレームワークの正式な区切り記号で、クエリテキストと期待行を分離する。
- エラーテキストの正規表現による期待値は、正確な文言が意図的に不安定な場合に限り使用する。
- 必要な環境変数を明示的に宣言する。
- デフォルト実行を実用的に保つため、低速テストにはフレームワークの低速テスト指定を付ける。
- 正常系だけでなく、数値型、文字列型、ネスト型、および無効または予期しない使用方法も対象にする。
- 提出前に正式な完全スイートの合格を必須とする。
## テストから直す場所を探し、必要な確認を全部終えてから完了にする
編集前にテストとアーキテクチャ上の所有範囲を使って機能の所在を特定し、その変更の影響を受ける派生面をすべて検証する。
### 調査手順
1. 既存のテストを探し、サポートされる構文と期待される動作を把握する。
2. パーサーからバインダー、オプティマイザー、物理計画、実行まで機能を追跡する。
3. 対応する文、演算子、式、カタログ、関数の型を特定する。
4. 機能が登録されている場所と、その外部向け宣言が置かれている場所を確認する。
5. リポジトリ標準のコード検索ツールで、実装ファイルと外部向けヘッダーを検索する。
6. 変更したソースに依存する生成ファイルと拡張面を特定する。
### 完了時の確認
- 広範なテストの前に、限定的な回帰テストを追加または更新する。
- フォーマット処理とソース生成を実行する。
- 限定テストを実行し、その後に必要なユニット、低速、サニタイザー、アサーション、構成、ベクトルの各スイートを実行する。
- 影響を受ける実行ファイルと拡張機能をビルドする。
- 生成差分とドキュメントの所有範囲を確認する。
- 必要なすべてのゲートに実際の結果が出るまで、完了を宣言してはならない。
