serramatutu commented on code in PR #833:
URL: https://github.com/apache/arrow-go/pull/833#discussion_r3864238055


##########
arrow/array/struct.go:
##########
@@ -494,40 +525,59 @@ func (b *StructBuilder) UnmarshalOne(dec *json.Decoder) 
error {
                                return errors.New("missing key")
                        }
 
-                       if keylist[key] {
+                       if _, dup := keylist[key]; dup {
                                return fmt.Errorf("key %s is specified twice", 
key)
                        }
 
-                       keylist[key] = true
+                       var next json.RawMessage
+                       if err := dec.Decode(&next); err != nil {
+                               return err
+                       }
 
-                       idx, ok := b.dtype.(*arrow.StructType).FieldIdx(key)
+                       idx, ok := dtype.FieldIdx(key)
                        if !ok {
-                               var extra interface{}
-                               if err := dec.Decode(&extra); err != nil {
-                                       return err
-                               }
                                continue
                        }
 
-                       if err := b.fields[idx].UnmarshalOne(dec); err != nil {
-                               return err
+                       if bytes.Equal(next, []byte("null")) && 
!dtype.Field(idx).Nullable {
+                               return fmt.Errorf("field '%s' is non-nullable 
but got null", dtype.Field(idx).Name)
+                       }
+
+                       keylist[key] = next
+               }
+
+               // consume '}'
+               if _, err := dec.Token(); err != nil {
+                       return err
+               }
+
+               // check that all non-nullable fields were specified
+               for _, field := range dtype.Fields() {
+                       if _, ok := keylist[field.Name]; !ok && !field.Nullable 
{
+                               return fmt.Errorf("field '%s' is required but 
no value was given", field.Name)
                        }
                }
 
-               // Append null values to all optional fields that were not 
presented in the json input
-               for _, field := range b.dtype.(*arrow.StructType).Fields() {
-                       if !field.Nullable {
+               // All validation passed; append the struct entry and its child 
values.
+               b.Append(true)
+               for i, field := range dtype.Fields() {
+                       next, hasKey := keylist[field.Name]
+                       if !hasKey {
+                               // Optional fields that were not present get a 
null.
+                               if field.Nullable {
+                                       b.fields[i].AppendNull()
+                               }
                                continue
                        }
-                       idx, _ := 
b.dtype.(*arrow.StructType).FieldIdx(field.Name)
-                       if _, hasKey := keylist[field.Name]; !hasKey {
-                               b.fields[idx].AppendNull()
+
+                       valDec := json.NewDecoder(bytes.NewReader(next))
+                       valDec.UseNumber()
+                       if err := b.fields[i].UnmarshalOne(valDec); err != nil {
+                               b.Resize(-1)

Review Comment:
   Using the builder checkpoint for this now. I added `[2,"bad"]` as a test 
case.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to