feat: CompressionHint に値域 (rangeMin / rangeMax) を足し、aliases を schema:alternateName の下位プロパティとして宣言 - #26
Conversation
…alternateName の下位プロパティとして宣言 exdata-inc/dbp-data-catalogue#16 のカタログ整備で 2 点、この語彙の側が足りないことが分かったため。 ## 1. dbp:CompressionHint の値域 (rangeMin / rangeMax) dbp:precisionBytes は「値域と粒度からその値を表現するのに必要なバイト数」として決めている (dbp-data-catalogue 側は CI でその導出値と一致することを検証している)。ところが値域は dbp:DataFieldType にしか書けないので、**同じ項目型でもユースケースによって覆う値域が違う** 場合に、狭い側の hint まで「項目型が許容すべき最も広い値域」から導出した幅を持つことになる。 例(dbp-data-catalogue の acceleration): 人・自転車の加速度計の列は数 g で収まるが、 強震計(地盤・構造物)の列は桁違いに広い。項目型の値域は後者を覆う必要があるため、 前者の hint の precisionBytes も後者から導出されてしまい、実際より広い幅=圧縮後サイズの 過大申告になる。いま dbp-data-catalogue はこの差を dbp:accuracyNote の日本語散文で書いており、 機械可読になっていない(値域が割れるエントリが 9 件あり、いずれも値域を宣言できずにいる)。 そこで rangeMin / rangeMax の domainIncludes に dbp:CompressionHint を足し、 **省略時は所属する DataFieldType の値域を継承/記述時はそのユースケースが覆う範囲まで狭める** という読み方にした。既存データへの影響は無い(省略が従来どおりの意味)。 ## 2. dbp:aliases → schema:alternateName dbp:aliases は「項目名の別表記(検索キー)」で、schema.org の alternateName と同じものを 指している。schema.org しか知らない利用者からも別名が引けるよう、 rdfs:subPropertyOf schema:alternateName を宣言した。 .proto のフィールドは型とコメントしか持てず、「これは schema.org の X を狭めたもの」に あたる情報を書く場所が無い。一方 dbp-schema.jsonld は ProtoToJsonld.py の生成物なので、 .jsonld を直接手で書くと次の生成で消える。そのため CONTAINS_NODE_RELATIONS と同じく 生成器側の定数表(SUB_PROPERTY_OF_RELATIONS)として宣言し、rdf:Property の出力に rdfs:subPropertyOf を挿すようにした。 ## 生成物について dbp-schema.jsonld / dbp-schema.ja.jsonld は ProtoToJsonld.py の再実行で更新した (差分は上記 2 点のみ = 生成は再現している)。dbp_schema.pb.go と src/dbp_schema.rs は、 この環境に protoc / Go / protobuf のチェックアウトが無いため**再生成していない**。 従来どおり別途「update Rust / proto」の手順でお願いします。
|
Claude finished @nagata-yoshiteru's task —— View job レビュー結果
方向性は妥当だと思います(値域を 🔴 1.
|
There was a problem hiding this comment.
Pull request overview
本PRは、データフィールド型カタログで必要になった語彙拡張として、dbp:CompressionHint にユースケース別の値域(dbp:rangeMin / dbp:rangeMax)を持てるようにし、あわせて dbp:aliases を schema:alternateName の下位プロパティとして宣言できるよう JSON-LD 生成器を拡張するものです。
Changes:
CompressionHintにrangeMin/rangeMax(tag18/19)を追加し、JSON-LD 側でもdbp:rangeMin/dbp:rangeMaxのdomainIncludesにdbp:CompressionHintを反映dbp:aliasesをrdfs:subPropertyOf schema:alternateNameとして出力するため、ProtoToJsonld.pyに関係定義テーブルを追加- 生成物(
dbp-schema.jsonld/dbp-schema.ja.jsonld)とdbp_schema.sqlを更新
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| ProtoToJsonld.py | rdfs:subPropertyOf を生成するための定数表(SUB_PROPERTY_OF_RELATIONS)と出力分岐を追加 |
| dbp-schema.jsonld | aliases の rdfs:subPropertyOf と、rangeMin/rangeMax の domainIncludes に CompressionHint を反映 |
| dbp-schema.ja.jsonld | 日本語版 JSON-LD に同内容を反映 |
| dbp_schema.sql | CompressionHint テーブルに rangeMin / rangeMax 列を追加 |
| dbp_schema.proto | CompressionHint に rangeMin / rangeMax フィールドを追加 |
| dbp_schema.ja.proto | 日本語コメント版 .proto に同フィールドを追加 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Value range this use case covers. Omitted, the hint inherits the range of the DataFieldType it belongs to; declared, it narrows that range to the subset the use case actually spans, so precisionBytes follows from that subset rather than from the widest range the field type has to allow | ||
| optional string rangeMin = 18; | ||
| optional string rangeMax = 19; |
#26 に頂いたレビューへの対応。指摘の番号は元コメントに対応。 ## 1 (🔴) dbdiagram-oss_exported_data.json が dbp_schema.sql と乖離していた このファイルは DBML ソースを丸ごと埋め込んでおり、履歴上も dbp_schema.sql と常に 同じ commit で動いている(31b8baa ほか)のに、前 commit で更新し漏れていた。 埋め込み DBML の CompressionHint に rangeMin / rangeMax を追記(このファイルの 既存の書式どおり Text 型・CRLF)。あわせて chart.tables の CompressionHint ("28")の height を 455 → 515 に更新した — 既存 28 テーブルすべてで height = 30 * 列数 + 35 が成り立つので、2 列増で +60。 両方の DBML ソース(dbp_schema.sql と埋め込みテキスト)を @dbml/core で パースし、28 テーブルすべてで列名・列順が一致することを確認済み。 JSON はテキスト blob と height の 2 行だけの差分で、他は再整形されていない。 ## 2 (🟠) 新しく書いた読み方が JSON-LD に一切出ていなかった ParseProto() は既出の property についてはコメントを捨てるため、rangeMin / rangeMax の rdfs:comment は初出(RealWorldDataStructureProperty・ dbp_schema.proto:264)のものが代表になる。CompressionHint 側にどれだけ書いても 語彙には出ない状態だったので、推奨されていた案 a のとおり初出側のコメントを 両ドメインを覆う表現に書き換えた(.ja.proto も対称に更新)。 再生成した .jsonld の差分はこの 2 つの rdfs:comment のみ。 ## 3 (🟡) 片方だけ書いたときの解釈を決めた **フィールド単位で継承する**(rangeMin だけ書けば rangeMax は DataFieldType から 継承したままで、それは不完全な hint ではなく妥当な hint)。ペア単位の必須化はしない。 初出コメント・CompressionHint 側コメント・README に明記。 ## 4 (🟡) 「hint の値域 ⊆ 項目型の値域」の前提を明記した 記述した側は狭めることはあっても広げない、という前提であること、この語彙には 制約記述(SHACL 等)の仕組みが無いので検証は利用者側(precisionBytes を導出する consumer)の責務であること、を同じ 3 箇所に書いた。README には CompressionHint 自体の記述が無かったので「Data Field Catalogue」の節を新設している。 ## 5 (🔵) getJsonld() の dict 重複を解消 rdf:Property 分岐を、分岐ごとの dict リテラル 2 本からキー単位の組み立てに変更。 挿入順は従来どおり(rdfs:subPropertyOf は rdfs:label と schema:domainIncludes の 間)なので出力はバイト単位で不変 — 再生成した .jsonld の差分が指摘 2 の rdfs:comment 2 本だけであることがその確認になっている。 rdfs:Class 側は既存コードなのでレビューどおり手を付けていない。 ## 6 (🔵) SUB_PROPERTY_OF_RELATIONS のキー誤りを検出するようにした 表のキーが 1 つも一致しないまま黙って rdfs:subPropertyOf が消えるのを防ぐため、 WriteJsonld() で「graph に出した @id」と突き合わせ、未一致キーがあれば ValueError で落とす。**検査はファイルを開く前**に行うので、表を書き間違えても commit 済みの .jsonld が 0 バイトに切り詰められることはない(従来は with open が 関数全体を包んでいたため、この種の例外は必ず空ファイルを残していた)。 キーが満たすべき条件(WriteJsonld の item.key == -1 フィルタを通る id である こと)も定数表のコメントに残した。 負のプローブ: 表に "dbp:alias"(s 抜け)を足すと exit 1 で `SUB_PROPERTY_OF_RELATIONS keys not emitted into dbp-schema.jsonld: ['dbp:alias']` と名指しし、両 .jsonld の md5 が変わらないことを確認。 ## 生成物について dbp-schema.jsonld / .ja.jsonld は ProtoToJsonld.py の再実行で更新(HEAD の状態で 一度回して差分ゼロ = 生成が再現することを先に確認したうえで実施)。 dbp_schema.pb.go / src/dbp_schema.rs は前 commit と同じく再生成していない (この環境に protoc / Go が無い)。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
レビューありがとうございます。6 件すべて対応しました( 🔴 1.
|
|
Claude finished @nagata-yoshiteru's task —— View job 追加レビュー(
|
| key | テーブル | 列数 | height | 30×列数+35 |
|---|---|---|---|---|
"27" |
DataFieldType |
27 | 845 | 845 ✓ |
"28" |
CompressionHint |
16 | 515 | 515 ✓ |
"28" が CompressionHint であることも、dbp_schema.sql の Table 宣言順(28 個、最後が CompressionHint)と一致します。
2. コメントが語彙に出るようになった — dbp-schema.jsonld:1728 / :1748 と .ja.jsonld の同位置で、dbp:rangeMin / dbp:rangeMax の rdfs:comment に継承・絞り込み・包含前提の 3 点が載りました。.jsonld の差分がこの 4 行(英日 2 本ずつ)だけである点も確認済みです。
5. 出力バイト不変 — ProtoToJsonld.py:154-165 の挿入順は @id → @type → rdfs:comment → rdfs:label → (rdfs:subPropertyOf)→ schema:domainIncludes → schema:rangeIncludes で、変更前の 2 本のリテラルと同一です。.jsonld の差分が 2 の rdfs:comment だけであることが実測の裏付けになっています。
6. 検査の実装 — ProtoToJsonld.py:318-323。graph 構築後・open() 前で、指摘どおり commit 済みファイルを壊しません。
その他 — .proto の解析には影響なし(ParseProto() は line[0].startswith('//') の行を捨てるので、dbp_schema.proto:586-588 の 3 行コメントは無視され、末尾コメントを持つ初出行だけが rdfs:comment になります)。README の主張(dbp:compressionHints が DataFieldType に付く、DataFieldType は schema:Intangible の下位)も .proto と一致しています。
🟠 Go / Rust の再生成 — 想定より差分が増えています
未実施であること自体は PR 本文と Copilot のコメントで既知ですが、f9d1c3f で PR 本文の見積もりが古くなっています。 本文は
CompressionHintにrange_min/range_maxの 2 つのOption<String>が増えるだけのはずです
と書いていますが、2 の対応で初出コメントを書き換えたので、RealWorldDataStructureProperty 側の既存フィールドの doc comment も動きます:
src/dbp_schema.rs:534—/// Minimum value of numeric range→ 新しい長文(range_maxの分も同様)dbp_schema.pb.goの対応するコメントも同じく
再生成する人が「無関係な差分が出た」と誤解しないよう、本文の「range_min が無いことは確認済みです(src/dbp_schema.rs:1115-1146 の CompressionHint は tag 17 まで)。
🟡 dbp:decimalPlaces の継承だけ未定義のまま残っています
3 で rangeMin / rangeMax の継承を決めましたが、decimalPlaces は同じ形をしていて、同じ導出式の 3 つ目の入力なのに、何も決まっていません。
dbp_schema.proto:543—DataFieldType.decimalPlaces = 34dbp_schema.proto:577—CompressionHint.decimalPlaces = 10
つまり precisionBytes の 3 入力(rangeMin / rangeMax / decimalPlaces)のうち 2 つは「省略時は項目型から継承・片方ずつ」と明記され、3 つ目は無言です。CompressionHint 側の decimalPlaces が省略されたとき項目型の値を使うのか、それとも「未指定=丸めない」なのかで、導出バイト数が変わります。README の 1 文(「片方ずつ継承」の隣)に decimalPlaces も同じ扱いだと書けば済むと思います。既存フィールドなので本 PR の範囲外と判断されるなら、それでも構いません。
🔵 dbp:precisionBytes 側から導出規則に辿れません
dbp-schema.jsonld:1766-1781 の通り、dbp:precisionBytes の domainIncludes には dbp:CompressionHint が入っているのに、rdfs:comment は変更前のまま「Number of bytes used for numeric representation during compression」です。導出規則は rangeMin / rangeMax の側にしか書かれていないので、precisionBytes(=実際に導出される値そのもの)を引いた利用者は規則に辿り着けません。 dbp_schema.proto:266 の末尾コメントに「follows from rangeMin / rangeMax / decimalPlaces(on a CompressionHint, from the narrowed range)」程度を足すと、2 と同じ経路で語彙に出ます。
🔵 検査が「property として出したか」まで見ていません
ProtoToJsonld.py:318 の emitted は graph の全ノードの @id なので、クラスの id も含みます。sub_property_of は getJsonld() の rdf:Property 分岐でしか読まれない(rdfs:Class 分岐は無視する)ため、表に
"dbp:DataFieldType": "schema:Intangible", # クラスを書いてしまったを書くと検査は通り、rdfs:subPropertyOf は黙って消えます — 6 で塞ぎたかった穴がそのまま残る形です。1 語で締まります:
emitted = {node['@id'] for node in graph if node['@type'] == 'rdf:Property'}🔵 値側の typo は依然として通ります
キーは検査されるようになりましたが、値("schema:alternateName")は無検査なので、schema:alternatName と書くとどこにも存在しない @id を指す rdfs:subPropertyOf が出力されます。キーの typo(=関係が消える)より、こちらの方が下流には厄介です。このスクリプトは起動時に schema.org のグラフを schemaids(schema:alternateName 形式の id リスト)として読み込んでいるので、検査はほぼ無料です:
for key, value in SUB_PROPERTY_OF_RELATIONS.items():
if value.startswith('schema:') and value not in schemaids:
raise ValueError(f'SUB_PROPERTY_OF_RELATIONS[{key!r}] is not a schema.org term: {value}')🔵 README の見出しと項目 1 が噛み合っていません
README.md:41 の「Two things this vocabulary states but does not enforce」の下で、項目 2(広げない)は確かに「述べるが強制しない」ですが、項目 1(片方ずつ継承)は強制の話ではなく読み方の定義です。「Two things to know」程度にするか、項目 1 を上の Omitted / Declared のリストに寄せる方が読みやすいと思います。
今回も確認できなかったこと
この実行環境では python3 / node の実行が許可されておらず(Bash は git / grep / sed 相当の読み取りのみ)、ProtoToJsonld.py の再実行による生成再現性と、負のプローブの再現は私の側では検証できていません。 そちらで実行された旨と、.jsonld の差分が申告どおり 4 行だけであること(これは確認済み)を根拠に、報告を妥当と判断しています。
.pb.go / .rs / dbdiagram JSON の置いていかれを機械的に検出する手段が無い件は、おっしゃるとおり別 PR が適切だと思います。
結論: 取り込んで良いと思います。 上記のうち残る要対応は 🟠(PR 本文の「
@nagata-yoshiteru ご確認ください。
· branch claude/compression-hint-value-range-and-alias-alignment · View job
追加レビュー(`f9d1c3f` に対するもの)の 🟡 1 件・🔵 3 件と、 それに対する追加レビューで出た指摘を消化した。🟠(PR 本文の 「⚠️ 未実施」欄の見積もり修正)は PR 本文側で対応。 1. 🟡 `decimalPlaces` の継承が未定義だった `precisionBytes` の 3 入力のうち `rangeMin` / `rangeMax` は 「省略時は DataFieldType から継承・片方ずつ」と決めたのに、 3 つ目の `decimalPlaces` は無言のままで、hint が省略したときに 導出が定義されない状態だった。値域の両端と同じ読み方 (省略時は DataFieldType の値・記述すればその hint に適用)に 決めて、初出(tag 83)の末尾コメントと README に書いた。 あわせて「記述する場合は DataFieldType より多くの桁を保持しない」 (値域が狭まる側にしか動かないのと同じく、桁は粗くなる側にしか 動かない)も、値域の包含と同じ「述べるが強制しない」項目として明記。 2. 🔵 `precisionBytes` 側から導出規則に辿れなかった 規則は値域の側にしか書かれておらず、導出される値そのものを引いた 利用者は規則に辿り着けなかった。初出(tag 82)の末尾コメントに 導出式と、CompressionHint に付いたときの入力(記述されていれば 狭めた値域・無ければ項目型の値域)を書いた。`CompressionHint` ブロック側の tag 10 / 12 にも同じ内容を短く置いた(こちらは JSON-LD には出ないが、Go / Rust の doc comment には出る)。 3. 🔵 `SUB_PROPERTY_OF_RELATIONS` のキー検査がクラスを通していた `emitted` が graph の全ノードの `@id` だったため、クラスの id を キーに書くと検査を通り、`rdfs:subPropertyOf` は黙って消えていた (`getJsonld()` は `rdf:Property` の分岐でしか `sub_property_of` を 読まない)。`rdf:Property` のノードだけに絞った。 4. 🔵 値側の typo が無検査だった キーの typo(関係が消える)より、存在しない `@id` を指す `rdfs:subPropertyOf` が出る方が下流には厄介。schema.org の **プロパティ**の id 集合を新たに作り、値が必ずそこに含まれることを 要求する。プレフィックスで分岐すると `shema:` のような プレフィックス自体の typo が素通りするため、分岐せず一律に検査する。 クラス・データ型を指す値も同じく落ちる。報告はキー検査と同じく 全件まとめて。 5. README の見出しと項目の噛み合わせ 「Two things this vocabulary states but does not enforce」の項目 1 (片方ずつ継承)は強制の話ではなく読み方の定義だったので、 Omitted / Declared のリストへ移した。残る「述べるが強制しない」は 値域の包含と、上の桁の包含の 2 点。 検証: - `ProtoToJsonld.py` を再実行。`.jsonld` の差分は初出コメントを 書き換えた `dbp:precisionBytes` / `dbp:decimalPlaces` の `rdfs:comment` **4 行のみ**(英日 2 本ずつ)。他 141 ノードは不変。 再実行前に HEAD の状態でも 1 回回して差分ゼロを確認済み。 - 負のプローブ 7 通り(値のプレフィックス typo / 語の typo / クラス / データ型、キーのクラス id / typo、旧 `emitted` での クラス id)すべてで exit 1・原因を名指し・commit 済み `.jsonld` の md5 不変。旧 `emitted` ではクラス id が exit 0 で通り関係が消える ことも実測(この commit で塞いだ穴の再現)。
|
追加レビューありがとうございます。残っていた 🟠 / 🟡 / 🔵 の 5 点すべてに対応しました( 🟠 PR 本文の「
|
|
Claude finished @nagata-yoshiteru's task —— View job Claude finished @nagata-yoshiteru's task —— View job 追加レビュー(
|
レビューの 🔴 指摘。`5235829` で `__pycache__/ProtoToJsonld.cpython-314.pyc` (15,413 バイト)が混入していた。`ProtoToJsonld.py` をローカルで実行した副産物で、 意図的なものではない。 .gitignore には Rust / Cargo / RustRover の節しか無く Python の節が丸ごと無かったので、 放置すると生成器を回すたびに再発する。追跡中の Python は `ProtoToJsonld.py` と `convert-jsonld-graph-to-ntriple.ipynb` の 2 つなので、`.ipynb_checkpoints/` も併せて 無視する。 バイトコードはインタプリタのバージョン(cpython-314)に紐づく生成物で、他の版で回す人には 無効なファイルが残るだけ。この PR がまさに「生成物と生成器の一致」を扱っている最中でもある。
レビューの 🔵 指摘。キー側の検査は「キーが rdf:Property として出た」ことだけを見て、 そこから「getJsonld() の rdf:Property 分岐が sub_property_of を出したはず」を推論していた。 今のコードでは実際に成り立つが、代理指標なので分岐の構造が変われば黙って外れる。 `'rdfs:subPropertyOf' in node`(dict のキーの有無)で出力そのものを読む形に変えた。 本来検証したい性質——表に書いた関係が JSON-LD に載っている——を直接見るので、 getJsonld() が次にどう変わっても成り立つ。@type の絞り込みも兼ねる (rdfs:Class 分岐は rdfs:subPropertyOf を出さない)。エラー文言も 「プロパティとして出ていない」から「rdfs:subPropertyOf が届いていない」に合わせた。 検証: 再生成後の dbp-schema.jsonld / .ja.jsonld は md5 不変。負のプローブ 5 通り (キーの綴り間違い / キーがクラスの id / 出力側が関係を落とす / 値のプレフィックス typo / 値がクラス)すべて exit 1・commit 済み .jsonld は不変。3 つ目は旧実装では exit 0 で通り、出力に rdfs:subPropertyOf のキーが 1 つも無いまま生成が完了していた (=この commit が塞いだ穴)。rdfs:comment の文字列としての "rdfs:subPropertyOf" (dbp-schema.jsonld:1317)は値なので偽陽性にならない。
|
追加レビューありがとうございます。🔴 の 1 件を取り除きました( 🔴
|
| # | 壊し方 | 結果 |
|---|---|---|
| 1 | キーの綴り間違い(dbp:aliasses) |
exit 1 keys whose rdfs:subPropertyOf did not reach …: ['dbp:aliasses'] |
| 2 | キーがクラスの id(dbp:CompressionHint) |
exit 1 同上 |
| 3 | 出力側が関係を落とす(if self.sub_property_of is not None: → if False:) |
exit 1 … ['dbp:aliases'] |
| 4 | 値のプレフィックス typo(shema:alternateName) |
exit 1 values that are not schema.org properties |
| 5 | 値がクラス(schema:Thing) |
exit 1 同上 |
3 は旧実装では exit 0 で通ります(実測)。しかもそのとき生成された .jsonld には rdfs:subPropertyOf のキーが 1 つも無く、残っているのは :1317 の説明文の文字列だけでした。これが今回塞いだ穴そのものです。
🔵 残り 2 件について
- dbp → dbp の
rdfs:subPropertyOf— 「今やる必要は無く、その用途が出てきたときの選択肢として」とのことでしたので、今回は入れていません。表が 1 件しか無いうちに使われない分岐を足すと、次に広げる人が「なぜこの形なのか」を読み解く材料が無い状態になるためです。ご提案のコードは、上のwith_sub_property_ofを値検査より前に持ち上げれば 1 行で足りるので、その用途が出た時点で表と一緒に広げます。 dbp_schema.sqlのCompressionHintのコメント粒度 — ご自身で書かれていた「dbdiagram は ER 図の描画用で意味論の一次ソースではない」という割り切りを採り、現状のままにしています。dbdiagram-oss_exported_data.jsonの埋め込み DBML を再度同期させるコストに対して、.proto/ JSON-LD / README という一次ソース 3 つが既に揃って同じことを言っている状態なので、得るものが小さいと判断しました。異論があればお知らせください。
今回も確認できていないこと
.pb.go / src/dbp_schema.rs は引き続き未再生成です(merge 後にお願いします)。PR 本文の「
ECC レビュー
code-reviewer / python-reviewer の 2 本とも CRITICAL / HIGH / MEDIUM 0 件で APPROVE でした。出た LOW 2 件はどちらも push 前に取り込んでいます:
emittedという変数名が新しい意味を表していない →with_sub_property_ofに改名(上記)。- merge をふさいでいる 🔴 の修正と、後回しでよいと言われた 🔵 を同じ commit にまとめると、merge 直前に差分を広げることになる → 2 commit に分けました(
1e21a7eが 🔴 だけ、5bb6540が 🔵 だけ)。🔵 のほうを落として取り込みたい場合は、1e21a7eだけで 🔴 の対応は完結します。
@nagata-yoshiteru ご確認をお願いします。
|
Claude finished @nagata-yoshiteru's task —— View job Claude finished @nagata-yoshiteru's task —— View job 追加レビュー(
|
|
Claude finished @nagata-yoshiteru's task —— View job 追加レビュー(
|
| エンコード | 値 | |
|---|---|---|
| 変更前 | \xc6\x06 |
838 |
| 変更後 | \xa2\a |
930 |
と +92 バイトになっています。追加された中身を数えると:
FieldDescriptorProto× 2 —\x12\x1f(2) + 本体 31 バイト = 33 × 2 = 66- 合成 oneof (
_rangeMin/_rangeMax) × 2 —B\v(2) +\n\t_rangeMin(11) = 13 × 2 = 26
66 + 26 = 92 で、長さ varint の増分とぴたり一致します。切り詰めや余りが無いことの機械的な裏付けになっています。
本体 31 バイトの中身も展開して確認しました:
\n\brangeMin name = "rangeMin"
\x18\x12 number = 18 ← rangeMax は \x18\x13 = 19 ✓
\x01 label = LABEL_OPTIONAL ✓
(\t type = TYPE_STRING ✓ (.proto の optional string と一致)
H\x0e oneof_index = 14 ← rangeMax は \x0f = 15 ✓
R\brangeMin json_name = "rangeMin" ✓
\x88\x01\x01 proto3_optional = true ✓
oneof_index の 14 / 15 は、既存の最後(_isMostlyIncremental = 13)の次で連番です。合成 oneof の宣言も B\x14\n\x14_isMostlyIncremental の直後に同じ順で追加されており、proto3 optional の要求(合成 oneof は実 oneof の後ろ・フィールド宣言順)を満たしています。
2. .proto のコメントが両生成物に逐語で入っています
6 本すべて、末尾まで含めて文字列一致を確認しました(各コメントの末尾の一句が 3 ファイルで同数出現):
| tag | 末尾の一句 | 出現数(proto / pb.go / rs) |
|---|---|---|
| 80 / 81 / 83 | so consumers are the ones that have to check it |
3 / 3 / 3 |
| 82 | the range of the DataFieldType where it does not |
1 / 1 / 1 |
| 83 | it coarsens, never refines |
1 / 1 / 1 |
CompressionHint 10 / 83 |
keep no more places than the DataFieldType does |
2 / 2 / 2 |
CompressionHint 12 |
inherited from the DataFieldType otherwise |
1 / 1 / 1 |
CompressionHint 18/19 |
consumers that derive precisionBytes are the ones that have to check it |
1 / 1 / 1 |
これで PR 本文の「CompressionHint の tag 10・12 への doc comment 追加)。
コメントの配置も生成器の規約どおりです。RealWorldDataStructureProperty の range_min は /// Numeric range etc → 空行 → 本文(detached + trailing)、CompressionHint の range_min は 3 行の leading comment がそのまま連続する /// になっていて、decimal_places(tag 10)は detached + trailing。既存の他フィールドと同じ形です。
3. 生成器バージョンが動いていません
dbp_schema.pb.go:1-5 のヘッダ(protoc-gen-go v1.36.11 / protoc v7.35.1)は 1 文字も変わっていません。前回の b93d81e と同じツールチェーンで回っているので、当初懸念されていた「中途半端なバージョンで再生成して無関係な差分が大量に出る」状態にはなっていません。差分 45 行 / 18 行という規模も、.proto の変更量そのものです。
4. Go のアクセサ
GetRangeMin() / GetRangeMax() が GetIsMostlyIncremental() の直後に、既存と同じ if x != nil && x.RangeMin != nil の形で追加されています。unknownFields / sizeCache の空白が動いているのは、新フィールド追加による gofmt の再整列で、意味の変更はありません。depIdxs / NumMessages は、追加がスカラー 2 本のみなので変わらないのが正しい挙動です。
5. 他の成果物への影響
この commit が触ったのは .pb.go と .rs の 2 ファイルだけで、.jsonld / .sql / dbdiagram-oss_exported_data.json / README.md は 1 行も動いていません。今回は語彙の変更ではないので、これが正しい状態です(.jsonld は 5235829 時点で .proto のコメントを取り込み済み)。
6. 日英の .proto
dbp_schema.ja.proto の CompressionHint も rangeMin = 18 / rangeMax = 19 で番号が一致しています。こちらから生成される Go / Rust は無いので、追加の再生成は不要です。
🟠 PR 本文の「⚠️ 未実施」欄が古くなりました
内容の指摘ではなく、本文の記述だけの話です。冒頭の
⚠️ 未実施 —dbp_schema.pb.goとsrc/dbp_schema.rsこの PR では Go / Rust の生成物を更新していません。
は 1ea3cd2 で解消されました。merge 時のコミットメッセージにこの本文が入るので、「未実施」のまま残ると履歴を後から読む人が「Go / Rust はまだ古いはず」と誤解します。「1ea3cd2 で再生成済み」に書き換えて頂くか、節ごと「実施済み」に差し替えるのが良いと思います(列挙されている 3 種類の差分の内訳自体は、実際に入ったものと一致しているので、そのまま残して見出しだけ変えるので足ります)。
🔵 継承元の DataFieldType 側には doc comment がありません(次の機会で)
今回で CompressionHint.rangeMin(src/dbp_schema.rs:1150-1152)には「DataFieldType から継承する」と 3 行書かれましたが、その継承元である DataFieldType.rangeMin / rangeMax / decimalPlaces(dbp_schema.proto:541-543、tag 32〜34)は無印のままです(src/dbp_schema.rs:1073-1075)。
JSON-LD では dbp:rangeMin が 1 ノードで、初出(tag 80)の rdfs:comment が代表になるので語彙としては問題ありません。困るのは .pb.go / .rs だけを読む人で、CompressionHint 側から「DataFieldType の値が適用される」と言われて DataFieldType を見に行くと何も書かれていない、という往復になります。この PR で入った状態ではなく元からの形なので、直すとしても別途で構わないと思います(1 行の逆向きの導線で足ります)。
今回確認できなかったこと
この実行環境には go / protoc / cargo がなく、.pb.go のコンパイルと cargo build は実行できていません。 ただし今回は生成物の検証なので、上記 1(descriptor のバイト列が独立に計算した値と一致)と 2(コメントの逐語一致)で、生成が実際に走った結果であることは十分に裏が取れていると考えています。
前回まで指摘していた「生成物と生成器の一致を機械的に確かめる手段が無い」件は変わらず残っていますが、この PR で置いていかれていたものは全部追いつきました。CI 化は別 PR という整理に引き続き同意します。
結論: merge して良い状態です。 残っているのは 🟠(PR 本文の「
@nagata-yoshiteru ご確認ください。
· branch claude/compression-hint-value-range-and-alias-alignment · View job
exdata-inc/dbp-data-catalogueの Issue #16(データ項目型カタログの整備)を進める中で、この語彙の側が足りていない点が 2 つ見つかったので提案します。カタログ側 curator の合意はこちらのコメント(「よい! あと、その PR で出す新 schema に従って今のコードも書いちゃって ok」)で取れています。
1.
dbp:CompressionHintに値域(dbp:rangeMin/dbp:rangeMax)を追加原因 / 背景
dbp:precisionBytesは「値域と粒度(rangeMin/rangeMax/decimalPlaces)から、その float / int を表現するのに必要なバイト数」として決めています(カタログ側はこの導出値と一致することを CI で検証しています)。ところが値域は
dbp:DataFieldTypeにしか書けません。そのため 同じ項目型でも、ユースケースによって覆う値域が違う ケースで、狭い側の hint まで「項目型が許容すべき最も広い値域」から導出した幅を持つことになります。例(カタログの
acceleration):幅が実際より広いのは無駄なだけでなく、圧縮後サイズの過大申告(
dbp:lossyCompressionRateの既定値がprecisionBytes / 8なので、そのまま比にも波及する)になります。いまカタログ側はこの差をdbp:accuracyNoteの日本語散文で書いていて機械可読になっておらず、値域が割れる 9 エントリが値域を宣言できずに止まっています。修正内容
dbp:rangeMin/dbp:rangeMaxのschema:domainIncludesにdbp:CompressionHintを追加しました(.protoのmessage CompressionHintにフィールド 18 / 19 を足した結果として生成されます)。読み方は:dbp:DataFieldTypeの値域を継承する(=従来どおりの意味)なので 既存データの意味は変わりません(省略が従来の挙動)。
2.
dbp:aliasesをschema:alternateNameの下位プロパティとして宣言dbp:aliasesは「項目名の別表記(検索キー)」で、schema.org のalternateNameと同じものを指しています。schema.org しか知らない利用者からも別名が引けるよう、rdfs:subPropertyOf schema:alternateNameを宣言しました。.protoのフィールドは型とコメントしか持てず、「これは schema.org の X を狭めたもの」にあたる情報を書く場所がありません。一方dbp-schema.jsonldはProtoToJsonld.pyの生成物なので、.jsonldを手で直すと次の生成で消えます。そこで既存のCONTAINS_NODE_RELATIONSと同じく 生成器側の定数表(SUB_PROPERTY_OF_RELATIONS)として宣言し、rdf:Propertyの出力にrdfs:subPropertyOfを挿すようにしました。今後 schema.org と対応する dbp プロパティが増えたら、この表に 1 行足すだけで済みます。確認方法
dbp-schema.jsonld/dbp-schema.ja.jsonldはProtoToJsonld.pyを再実行して生成しました。差分が上記 2 点の 15 行のみであることが、生成が再現していることの確認になっています(既存の 143 ノードは 1 バイトも動いていません)。dbp:aliasesにrdfs:subPropertyOf、dbp:CompressionHintのschema:rangeIncludesにdbp:rangeMin/dbp:rangeMaxが入っていることを確認済み。dbp_schema.sql(dbdiagram のソース)のCompressionHintテーブルにも 2 列を追記しました。dbdiagram-oss_exported_data.json(同じ DBML を埋め込んでいる方)にも同じ 2 列と、CompressionHintのレイアウト高さを反映しました。両方の DBML ソースを@dbml/coreでパースし、28 テーブルすべてで列名・列順が一致することを確認済みです。dbp_schema.pb.goとsrc/dbp_schema.rsこの PR では Go / Rust の生成物を更新していません。実行環境に
protoc・Go ツールチェーン・build.rsが要求する protobuf のチェックアウトが無く、中途半端なバージョンで再生成すると無関係な差分が大量に出るためです。このリポジトリの従来どおり、別途「update Rust / proto」の手順での再生成をお願いします。再生成で出る差分は「新フィールド 2 つ」だけではありません(当初の見積もりを訂正します)。レビュー対応で
.protoのコメントを書き換えたため、既存フィールドの doc comment も動きます:CompressionHintにrange_min/range_max(tag 18 / 19)の 2 つのOption<String>が増えるRealWorldDataStructurePropertyのrange_min/range_max/precision_bytes/decimal_places(tag 80〜83)の doc comment が、継承・絞り込み・導出規則を書いた新しい文面に変わる(例:src/dbp_schema.rs:534の/// Minimum value of numeric range)CompressionHintのdecimal_places/precision_bytes(tag 10 / 12)に doc comment が付く無関係な差分ではないので、そのまま取り込んでいただいて問題ありません。
@nagata-yoshiteru レビューをお願いします。