From 1f51886b3e44f0868f57f345c791b86015cf5cd6 Mon Sep 17 00:00:00 2001 From: Patrick Pichler Date: Wed, 31 Jul 2024 21:10:57 +0200 Subject: [PATCH] Use bytes interface value for zero native type struct fields instead of dynamic list (#981) * Use bytes interface value for zero native type struct fields instead of dynamic list If a struct has a byte array/slice field and it happens to be the zero value, a dynamic list object was returned. This caused issues with functions taking `Bytes` via arguments, as the type checker will accept such functions, but they might fail at runtime. To work around this, the raw bytes array/slice is returned in case of an zero value. * Remove unused special handling cases for retrieving field values For most types, it is good enough to use the raw interface values for null types. Hence the logic of getFieldValue has been adjusted to remove some special handling code. --- ext/native.go | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/ext/native.go b/ext/native.go index 75dff5a0..35b0f1e3 100644 --- a/ext/native.go +++ b/ext/native.go @@ -279,7 +279,7 @@ func (tp *nativeTypeProvider) FindStructFieldType(typeName, fieldName string) (* GetFrom: func(obj any) (any, error) { refVal := reflect.Indirect(reflect.ValueOf(obj)) refField := valueFieldByName(tp.options.parseStructTags, refVal, fieldName) - return getFieldValue(tp, refField), nil + return getFieldValue(refField), nil }, }, true } @@ -704,21 +704,16 @@ func (t *nativeType) hasField(fieldName string) (reflect.StructField, bool) { } func adaptFieldValue(adapter types.Adapter, refField reflect.Value) ref.Val { - return adapter.NativeToValue(getFieldValue(adapter, refField)) + return adapter.NativeToValue(getFieldValue(refField)) } -func getFieldValue(adapter types.Adapter, refField reflect.Value) any { +func getFieldValue(refField reflect.Value) any { if refField.IsZero() { switch refField.Kind() { - case reflect.Array, reflect.Slice: - return types.NewDynamicList(adapter, []ref.Val{}) - case reflect.Map: - return types.NewDynamicMap(adapter, map[ref.Val]ref.Val{}) case reflect.Struct: if refField.Type() == timestampType { - return types.Timestamp{Time: time.Unix(0, 0)} + return time.Unix(0, 0) } - return reflect.New(refField.Type()).Elem().Interface() case reflect.Pointer: return reflect.New(refField.Type().Elem()).Interface() }