diff --git a/csup/metadata.go b/csup/metadata.go index 0f1adfcdf..872b8a8db 100644 --- a/csup/metadata.go +++ b/csup/metadata.go @@ -342,26 +342,29 @@ func metadataValue(cctx *Context, sctx *super.Context, b *scode.Builder, id ID, return sctx.MustLookupTypeRecord(fields) case *Union: cmp := expr.NewValueCompareFn(order.Asc, order.NullsLast) + max, min := super.Null, super.Null var bb scode.Builder - var min, max *super.Value for _, id := range m.Values { val := newMetadataValue(cctx, sctx, &bb, id, projection) if val.IsNull() { continue } min2, max2 := val.Deref("min"), val.Deref("max") - if min == nil || (min2 != nil && cmp(*min, *min2) > 0) { - min = new(min2.Copy()) + if min2 == nil { + continue + } + if min.IsNull() || cmp(min, *min2) > 0 { + min = min2.Copy() } - if max == nil || (max2 != nil && cmp(*max, *max2) < 0) { - max = new(max2.Copy()) + if max.IsNull() || cmp(max, *max2) < 0 { + max = max2.Copy() } } - if min == nil { + if min.IsNull() { b.Append(nil) return super.TypeNull } - return metadataLeaf(sctx, b, *min, *max) + return metadataLeaf(sctx, b, min, max) case *Int: return metadataLeaf(sctx, b, super.NewInt(m.Typ, m.Min), super.NewInt(m.Typ, m.Max)) case *Uint: diff --git a/csup/object_test.go b/csup/object_test.go index 5fbbfc8e1..8768d1585 100644 --- a/csup/object_test.go +++ b/csup/object_test.go @@ -41,8 +41,8 @@ func TestObjectProjectMetadata(t *testing.T) { func TestObjectProjectMetadataForUnion(t *testing.T) { sctx := super.NewContext() supValues := []string{ - "{a:1::(int64|string),b?:2,c:3::(int64|null)}", - `{a:"s"::(int64|string),b?:_::int64,c:null::(int64|null)}`, + "{a:1::(int64|string),b?:2,c:3::(int64|null),d?:{e:4}}", + `{a:"s"::(int64|string),b?:_::int64,c:null::(int64|null),d?:_::{e:int64}}`, } builder := vector.NewDynamicValueBuilder() for _, s := range supValues { @@ -56,8 +56,8 @@ func TestObjectProjectMetadataForUnion(t *testing.T) { o, err := csup.NewObject(bytes.NewReader(csupBytes)) require.NoError(t, err) - p := field.NewProjection(field.DottedList("a,b,c")) + p := field.NewProjection(field.DottedList("a,b,c,d")) values := o.ProjectMetadata(super.NewContext(), p) require.Len(t, values, 1) - require.Equal(t, `{a:{min:1,max:"s"},b:{min:2,max:2},c:{min:3,max:3}}`, sup.FormatValue(values[0])) + require.Equal(t, `{a:{min:1,max:"s"},b:{min:2,max:2},c:{min:3,max:3},d:null}`, sup.FormatValue(values[0])) }