feat(BREAKING!): support incell list/map aggregation across duplicate rows with consistency checks#395
feat(BREAKING!): support incell list/map aggregation across duplicate rows with consistency checks#395
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #395 +/- ##
==========================================
- Coverage 73.35% 73.23% -0.12%
==========================================
Files 88 88
Lines 11284 11386 +102
==========================================
+ Hits 8277 8339 +62
- Misses 2440 2477 +37
- Partials 567 570 +3 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
| if field.opts.GetProp().GetAggregate() { | ||
| presentList := msg.Mutable(field.fd).List() | ||
| for i := range listValue.List().Len() { | ||
| newValue := listValue.List().Get(i) | ||
| if field.opts.GetKey() != "" && field.fd.Kind() != protoreflect.MessageKind { | ||
| // check duplicate elems for scalar/enum keyed-list | ||
| for j := range presentList.Len() { | ||
| elemVal := presentList.Get(j) | ||
| if elemVal.Equal(newValue) { | ||
| return false, xerrors.WrapKV(xerrors.E2028(newValue), r.CellDebugKV(colName)...) | ||
| } | ||
| } | ||
| } | ||
| presentList.Append(newValue) | ||
| } |
There was a problem hiding this comment.
- list aggregating, just append elems, no need to check uniqueness (if it is not keyed-list)
- wellknown messages should also be considered
| // | ||
| // See https://github.com/bufbuild/protovalidate. | ||
| string validate_message = 20; | ||
| // Whether this incell list/map field's value is aggregated vertically. |
There was a problem hiding this comment.
Same as horizontally, should also be supported.
There was a problem hiding this comment.
I don't think it's a good idea to support aggregating a horizontal list vertically. This may look weird:
| WeaponID | Attr1Name | Attr1Value | Attr2Name | Attr2Value | Level | UpgradeCost |
|---|---|---|---|---|---|---|
| map<uint32, Weapon> | [Attr]string | int32 | string | int32 | map<int32, Level> | int32 |
| Weapon's ID | Attr1's name | Attr1's value | Attr2's name | Attr2's value | Weapon's Level | Cost to upgrade weapon to next level |
| 1 | Attack | 100 | Defence | 200 | 1 | 10 |
| 1 | Crit | 30 | CritDamage | 50 | 2 | 20 |
There was a problem hiding this comment.
The design should be concistent and symmetry, Not only by visual.
b3ed9b7 to
e786604
Compare
| @@ -1,5 +1,5 @@ | |||
| ID,#IGNORE | |||
| "[]int32|{refer:""EquipConf.ID""}", | |||
| "[]int32|{refer:""EquipConf.ID"" aggregate:true}", | |||
There was a problem hiding this comment.
This is a serious Breaking Change!
There was a problem hiding this comment.
updated to title & description.
| @@ -1,5 +1,5 @@ | |||
| Target | |||
| []{union.Target}|{form:FORM_TEXT} | |||
| []{union.Target}|{form:FORM_TEXT aggregate:true} | |||
There was a problem hiding this comment.
The list's layout is incell but is used vertically, so need aggregate:true.
| 1,,11,110 | ||
| 2,Orange,20,200 |
There was a problem hiding this comment.
The default behaviour should be: fill the same value as before (just like the same key filled). Please also fix the other cases.
aggregate to enable aggregating incell lists/maps vertically
| // See https://github.com/bufbuild/protovalidate. | ||
| string validate_message = 20; | ||
| // Whether this incell list/map field's value is aggregated vertically. | ||
| bool aggregate = 21; |
aggregate to enable aggregating incell lists/maps vertically

Summary
This PR introduces a new field property
aggregateon incelllist/mapfields, enabling them to collect elements across vertically (or horizontally) duplicated rows sharing the same primary key into a single aggregated collection. Previously such duplicated rows were required to carry the identical incell value; now users can spread the contents of one logical list/map over multiple rows.Alongside the new capability, this PR adds strict consistency / uniqueness diagnostics and performs a large refactor of
internal/confgen/table_parser.goto unify the aggregation and duplicate-detection code paths.What's New
1. New field property:
FieldProp.aggregateAdded a new option in
proto/tableau/protobuf/tableau.proto:ExtractMapFieldProp/ExtractListFieldPropnow take the fieldlayoutand only propagateaggregatewhen the layout isLAYOUT_INCELL.2. New error codes
inconsistent value in aggregated cells— a non-aggregated incell list/map that appears on duplicated primary-key rows carries a value different from its first presence.duplicate elements in incell keyed-list— elements inside a single incell keyed-list are not unique.Both
en.yaml/zh.yamlare updated, andecode_generated.gois regenerated accordingly.3. Simplified E2005
E2005is narrowed from "map or keyed-list key not unique" to "map key not unique". Keyed-list duplicate detection now flows through the dedicated E2028 path, making error classification cleaner.4. Refactor of
table_parser.goLarge restructuring (~1.5k lines touched) to:
aggregatesemantics for incell list/map fields.E2023whenever a non-aggregated incell collection is observed to change across duplicated rows, using the first occurrence as the source of truth.E2028when the parsed incell keyed-list contains duplicate elements.document_parser.go/parser.go.Two small helpers (
listValues,mapValues) were added ininternal/confgen/util.goto extract values fromprotoreflect.List/protoreflect.Mapfor diagnostics.5. Test coverage
vertical_list.proto,horizontal_map.proto, etc.) to annotate incell list/map fields withprop:{aggregate:true}where cross-row aggregation is intended.internal/confgen/table_parser_test.gofor the new aggregation & consistency paths.Name/Desccolumns in several test CSVs, and added theAttrmap column toHorizontalStructMapto exercise an incellmapaggregation case.Migration Guide
Add
aggregate:trueto incell list/map fields to enable vertical aggregation. Scalars, enums, structs and horizontal lists or maps are not allowed to aggregate.Before
After