Repository: milvus-io/milvus-sdk-go
Pull request #819 (2024-09-12 04:01:30)

enhance: support null and default value in go sdk
https://github.com/milvus-io/milvus/issues/31728

sre-ci-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by: *<a href="https://github.com/milvus-io/milvus-sdk-go/pull/819#" title="Author self-approved">smellthemoon</a>*
To complete the [pull request process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process), please assign **yah01** after the PR has been reviewed.
You can assign the PR to them by writing `/assign @yah01` in a comment when ready.

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=milvus-io%2Fmilvus-sdk-go).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/milvus-io/milvus-sdk-go/blob/master/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["yah01"]} -->

Patch:
diff --git a/client/data.go b/client/data.go
index 0e61a71..79e5a43 100644
--- a/client/data.go
+++ b/client/data.go
@@ -134,6 +134,7 @@ func (c *GrpcClient) handleSearchResult(schema *entity.Schema, outputFields []st
 	for i := 0; i < int(results.GetNumQueries()); i++ {
 		rc := int(results.GetTopks()[i]) // result entry count for current query
 		entry := SearchResult{
+			sch:         schema,
 			ResultCount: rc,
 			Scores:      results.GetScores()[offset : offset+rc],
 		}
diff --git a/client/insert.go b/client/insert.go
index 205b99a..689cd54 100644
--- a/client/insert.go
+++ b/client/insert.go
@@ -148,6 +148,16 @@ func (c *GrpcClient) processInsertColumns(colSchema *entity.Schema, columns ...e
 		_, has := mNameColumn[field.Name]
 		if !has &&
 			!field.AutoID && !field.IsDynamic {
+			// add a column which set nullable == true and fill it with all null value
+			if field.DefaultValue != nil || field.Nullable {
+				emptyColumn, err := entity.NewAllNullValueColumn(field.Name, field.DataType, rowSize)
+				// no err will be throw
+				if err != nil {
+					return nil, 0, fmt.Errorf("empty column fail to create, field name:%s ", field.Name)
+				}
+				mNameColumn[field.Name] = emptyColumn
+				continue
+			}
 			return nil, 0, fmt.Errorf("field %s not passed", field.Name)
 		}
 	}
diff --git a/client/results.go b/client/results.go
index 418abb5..8aba95a 100644
--- a/client/results.go
+++ b/client/results.go
@@ -1,6 +1,10 @@
 package client
 
 import (
+	"go/ast"
+	"reflect"
+
+	"github.com/cockroachdb/errors"
 	"github.com/milvus-io/milvus-sdk-go/v2/entity"
 )
 
@@ -9,6 +13,9 @@ import (
 // Fields contains the data of `outputFieleds` specified or all columns if non
 // Scores is actually the distance between the vector current record contains and the search target vector
 type SearchResult struct {
+	// internal schema for unmarshaling
+	sch *entity.Schema
+
 	ResultCount  int // the returning entry count
 	GroupByValue entity.Column
 	IDs          entity.Column // auto generated id, can be mapped to the columns from `Insert` API
@@ -44,6 +51,66 @@ func (sr *SearchResult) Slice(start, end int) *SearchResult {
 	return result
 }
 
+func (sr *SearchResult) Unmarshal(receiver interface{}) (err error) {
+	err = sr.Fields.Unmarshal(receiver)
+	if err != nil {
+		return err
+	}
+	return sr.fillPKEntry(receiver)
+}
+
+func (sr *SearchResult) fillPKEntry(receiver interface{}) (err error) {
+	defer func() {
+		if x := recover(); x != nil {
+			err = errors.Newf("failed to unmarshal result set: %v", x)
+		}
+	}()
+	rr := reflect.ValueOf(receiver)
+
+	if rr.Kind() == reflect.Ptr {
+		if rr.IsNil() && rr.CanAddr() {
+			rr.Set(reflect.New(rr.Type().Elem()))
+		}
+		rr = rr.Elem()
+	}
+
+	rt := rr.Type()
+	rv := rr
+
+	switch rt.Kind() {
+	case reflect.Slice:
+		pkField := sr.sch.PKField()
+
+		et := rt.Elem()
+		for et.Kind() == reflect.Ptr {
+			et = et.Elem()
+		}
+
+		candidates := parseCandidates(et)
+		candi, ok := candidates[pkField.Name]
+		if !ok {
+			// pk field not found in struct, skip
+			return nil
+		}
+		for i := 0; i < sr.IDs.Len(); i++ {
+			row := rv.Index(i)
+			for row.Kind() == reflect.Ptr {
+				row = row.Elem()
+			}
+
+			val, err := sr.IDs.Get(i)
+			if err != nil {
+				return err
+			}
+			row.Field(candi).Set(reflect.ValueOf(val))
+		}
+		rr.Set(rv)
+	default:
+		return errors.Newf("receiver need to be slice or array but get %v", rt.Kind())
+	}
+	return nil
+}
+
 // ResultSet is an alias type for column slice.
 type ResultSet []entity.Column
 
@@ -71,3 +138,87 @@ func (rs ResultSet) GetColumn(fieldName string) entity.Column {
 	}
 	return nil
 }
+
+func (rs ResultSet) Unmarshal(receiver interface{}) (err error) {
+	defer func() {
+		if x := recover(); x != nil {
+			err = errors.Newf("failed to unmarshal result set: %v", x)
+		}
+	}()
+	rr := reflect.ValueOf(receiver)
+
+	if rr.Kind() == reflect.Ptr {
+		if rr.IsNil() && rr.CanAddr() {
+			rr.Set(reflect.New(rr.Type().Elem()))
+		}
+		rr = rr.Elem()
+	}
+
+	rt := rr.Type()
+	rv := rr
+
+	switch rt.Kind() {
+	// TODO maybe support Array and just fill data
+	// case reflect.Array:
+	case reflect.Slice:
+		et := rt.Elem()
+		if et.Kind() != reflect.Ptr {
+			return errors.Newf("receiver must be slice of pointers but get: %v", et.Kind())
+		}
+		for et.Kind() == reflect.Ptr {
+			et = et.Elem()
+		}
+		for i := 0; i < rs.Len(); i++ {
+			data := reflect.New(et)
+			err := rs.fillData(data.Elem(), et, i)
+			if err != nil {
+				return err
+			}
+			rv = reflect.Append(rv, data)
+		}
+		rr.Set(rv)
+	default:
+		return errors.Newf("receiver need to be slice or array but get %v", rt.Kind())
+	}
+	return nil
+}
+
+func parseCandidates(dataType reflect.Type) map[string]int {
+	result := make(map[string]int)
+	for i := 0; i < dataType.NumField(); i++ {
+		f := dataType.Field(i)
+		// ignore anonymous field for now
+		if f.Anonymous || !ast.IsExported(f.Name) {
+			continue
+		}
+
+		name := f.Name
+		tag := f.Tag.Get(entity.MilvusTag)
+		tagSettings := entity.ParseTagSetting(tag, entity.MilvusTagSep)
+		if tagName, has := tagSettings[entity.MilvusTagName]; has {
+			name = tagName
+		}
+
+		result[name] = i
+	}
+	return result
+}
+
+func (rs ResultSet) fillData(data reflect.Value, dataType reflect.Type, idx int) error {
+	m := parseCandidates(dataType)
+	for i := 0; i < len(rs); i++ {
+		name := rs[i].Name()
+		fidx, ok := m[name]
+		if !ok {
+			// maybe return error
+			continue
+		}
+		val, err := rs[i].Get(idx)
+		if err != nil {
+			return err
+		}
+		// TODO check datatype
+		data.Field(fidx).Set(reflect.ValueOf(val))
+	}
+	return nil
+}
diff --git a/entity/columns.go b/entity/columns.go
index cf6e3a9..b23b43d 100644
--- a/entity/columns.go
+++ b/entity/columns.go
@@ -28,6 +28,7 @@ type Column interface {
 	Name() string
 	Type() FieldType
 	Len() int
+	Nullable() bool
 	Slice(int, int) Column
 	FieldData() *schemapb.FieldData
 	AppendValue(interface{}) error
@@ -191,6 +192,13 @@ func FieldDataColumn(fd *schemapb.FieldData, begin, end int) (Column, error) {
 		if !ok {
 			return nil, errFieldDataTypeNotMatch
 		}
+		if len(fd.GetValidData()) != 0 {
+			if end < 0 {
+				return NewNullableColumnBool(fd.GetFieldName(), data.BoolData.GetData()[begin:], fd.GetValidData()[begin:]), nil
+			}
+			return NewNullableColumnBool(fd.GetFieldName(), data.BoolData.GetData()[begin:end], fd.GetValidData()[begin:end]), nil
+		}
+
 		if end < 0 {
 			return NewColumnBool(fd.GetFieldName(), data.BoolData.GetData()[begin:]), nil
 		}
@@ -206,6 +214,13 @@ func FieldDataColumn(fd *schemapb.FieldData, begin, end int) (Column, error) {
 			values = append(values, int8(v))
 		}
 
+		if len(fd.GetValidData()) != 0 {
+			if end < 0 {
+				return NewNullableColumnInt8(fd.GetFieldName(), values[begin:], fd.GetValidData()[begin:]), nil
+			}
+			return NewNullableColumnInt8(fd.GetFieldName(), values[begin:end], fd.GetValidData()[begin:end]), nil
+		}
+
 		if end < 0 {
 			return NewColumnInt8(fd.GetFieldName(), values[begin:]), nil
 		}
@@ -221,10 +236,16 @@ func FieldDataColumn(fd *schemapb.FieldData, begin, end int) (Column, error) {
 		for _, v := range data.IntData.GetData() {
 			values = append(values, int16(v))
 		}
+		if len(fd.GetValidData()) != 0 {
+			if end < 0 {
+				return NewNullableColumnInt16(fd.GetFieldName(), values[begin:], fd.GetValidData()[begin:]), nil
+			}
+			return NewNullableColumnInt16(fd.GetFieldName(), values[begin:end], fd.GetValidData()[begin:end]), nil
+		}
+
 		if end < 0 {
 			return NewColumnInt16(fd.GetFieldName(), values[begin:]), nil
 		}
-
 		return NewColumnInt16(fd.GetFieldName(), values[begin:end]), nil
 
 	case schemapb.DataType_Int32:
@@ -232,6 +253,12 @@ func FieldDataColumn(fd *schemapb.FieldData, begin, end int) (Column, error) {
 		if !ok {
 			return nil, errFieldDataTypeNotMatch
 		}
+		if len(fd.GetValidData()) != 0 {
+			if end < 0 {
+				return NewNullableColumnInt32(fd.GetFieldName(), data.IntData.GetData()[begin:], fd.GetValidData()[begin:]), nil
+			}
+			return NewNullableColumnInt32(fd.GetFieldName(), data.IntData.GetData()[begin:end], fd.GetValidData()[begin:end]), nil
+		}
 		if end < 0 {
 			return NewColumnInt32(fd.GetFieldName(), data.IntData.GetData()[begin:]), nil
 		}
@@ -242,6 +269,12 @@ func FieldDataColumn(fd *schemapb.FieldData, begin, end int) (Column, error) {
 		if !ok {
 			return nil, errFieldDataTypeNotMatch
 		}
+		if len(fd.GetValidData()) != 0 {
+			if end < 0 {
+				return NewNullableColumnInt64(fd.GetFieldName(), data.LongData.GetData()[begin:], fd.GetValidData()[begin:]), nil
+			}
+			return NewNullableColumnInt64(fd.GetFieldName(), data.LongData.GetData()[begin:end], fd.GetValidData()[begin:end]), nil
+		}
 		if end < 0 {
 			return NewColumnInt64(fd.GetFieldName(), data.LongData.GetData()[begin:]), nil
 		}
@@ -252,6 +285,12 @@ func FieldDataColumn(fd *schemapb.FieldData, begin, end int) (Column, error) {
 		if !ok {
 			return nil, errFieldDataTypeNotMatch
 		}
+		if len(fd.GetValidData()) != 0 {
+			if end < 0 {
+				return NewNullableColumnFloat(fd.GetFieldName(), data.FloatData.GetData()[begin:], fd.GetValidData()[begin:]), nil
+			}
+			return NewNullableColumnFloat(fd.GetFieldName(), data.FloatData.GetData()[begin:end], fd.GetValidData()[begin:end]), nil
+		}
 		if end < 0 {
 			return NewColumnFloat(fd.GetFieldName(), data.FloatData.GetData()[begin:]), nil
 		}
@@ -262,6 +301,12 @@ func FieldDataColumn(fd *schemapb.FieldData, begin, end int) (Column, error) {
 		if !ok {
 			return nil, errFieldDataTypeNotMatch
 		}
+		if len(fd.GetValidData()) != 0 {
+			if end < 0 {
+				return NewNullableColumnDouble(fd.GetFieldName(), data.DoubleData.GetData()[begin:], fd.GetValidData()[begin:]), nil
+			}
+			return NewNullableColumnDouble(fd.GetFieldName(), data.DoubleData.GetData()[begin:end], fd.GetValidData()[begin:end]), nil
+		}
 		if end < 0 {
 			return NewColumnDouble(fd.GetFieldName(), data.DoubleData.GetData()[begin:]), nil
 		}
@@ -272,6 +317,12 @@ func FieldDataColumn(fd *schemapb.FieldData, begin, end int) (Column, error) {
 		if !ok {
 			return nil, errFieldDataTypeNotMatch
 		}
+		if len(fd.GetValidData()) != 0 {
+			if end < 0 {
+				return NewNullableColumnString(fd.GetFieldName(), data.StringData.GetData()[begin:], fd.GetValidData()[begin:]), nil
+			}
+			return NewNullableColumnString(fd.GetFieldName(), data.StringData.GetData()[begin:end], fd.GetValidData()[begin:end]), nil
+		}
 		if end < 0 {
 			return NewColumnString(fd.GetFieldName(), data.StringData.GetData()[begin:]), nil
 		}
@@ -282,6 +333,12 @@ func FieldDataColumn(fd *schemapb.FieldData, begin, end int) (Column, error) {
 		if !ok {
 			return nil, errFieldDataTypeNotMatch
 		}
+		if len(fd.GetValidData()) != 0 {
+			if end < 0 {
+				return NewNullableColumnVarChar(fd.GetFieldName(), data.StringData.GetData()[begin:], fd.GetValidData()[begin:]), nil
+			}
+			return NewNullableColumnVarChar(fd.GetFieldName(), data.StringData.GetData()[begin:end], fd.GetValidData()[begin:end]), nil
+		}
 		if end < 0 {
 			return NewColumnVarChar(fd.GetFieldName(), data.StringData.GetData()[begin:]), nil
 		}
@@ -299,6 +356,13 @@ func FieldDataColumn(fd *schemapb.FieldData, begin, end int) (Column, error) {
 			arrayData = data.GetData()[begin:end]
 		}
 
+		if len(fd.GetValidData()) != 0 {
+			if end < 0 {
+				return parseNullableArrayData(fd.GetFieldName(), data.GetElementType(), arrayData, fd.GetValidData()[begin:])
+			}
+			return parseNullableArrayData(fd.GetFieldName(), data.GetElementType(), arrayData, fd.GetValidData()[begin:end])
+		}
+
 		return parseArrayData(fd.GetFieldName(), data.GetElementType(), arrayData)
 
 	case schemapb.DataType_JSON:
@@ -307,6 +371,12 @@ func FieldDataColumn(fd *schemapb.FieldData, begin, end int) (Column, error) {
 		if !ok {
 			return nil, errFieldDataTypeNotMatch
 		}
+		if len(fd.GetValidData()) != 0 {
+			if end < 0 {
+				return NewNullableColumnJSONBytes(fd.GetFieldName(), data.JsonData.GetData()[begin:], fd.GetValidData()[begin:]).WithIsDynamic(isDynamic), nil
+			}
+			return NewNullableColumnJSONBytes(fd.GetFieldName(), data.JsonData.GetData()[begin:end], fd.GetValidData()[begin:end]).WithIsDynamic(isDynamic), nil
+		}
 		if end < 0 {
 			return NewColumnJSONBytes(fd.GetFieldName(), data.JsonData.GetData()[begin:]).WithIsDynamic(isDynamic), nil
 		}
@@ -416,6 +486,85 @@ func FieldDataColumn(fd *schemapb.FieldData, begin, end int) (Column, error) {
 	}
 }
 
+func parseNullableArrayData(fieldName string, elementType schemapb.DataType, fieldDataList []*schemapb.ScalarField, validData []bool) (Column, error) {
+	switch elementType {
+	case schemapb.DataType_Bool:
+		var data [][]bool
+		for _, fd := range fieldDataList {
+			data = append(data, fd.GetBoolData().GetData())
+		}
+		return NewNullableColumnBoolArray(fieldName, data, validData), nil
+
+	case schemapb.DataType_Int8:
+		var data [][]int8
+		for _, fd := range fieldDataList {
+			raw := fd.GetIntData().GetData()
+			row := make([]int8, 0, len(raw))
+			for _, item := range raw {
+				row = append(row, int8(item))
+			}
+			data = append(data, row)
+		}
+		return NewNullableColumnInt8Array(fieldName, data, validData), nil
+
+	case schemapb.DataType_Int16:
+		var data [][]int16
+		for _, fd := range fieldDataList {
+			raw := fd.GetIntData().GetData()
+			row := make([]int16, 0, len(raw))
+			for _, item := range raw {
+				row = append(row, int16(item))
+			}
+			data = append(data, row)
+		}
+		return NewNullableColumnInt16Array(fieldName, data, validData), nil
+
+	case schemapb.DataType_Int32:
+		var data [][]int32
+		for _, fd := range fieldDataList {
+			data = append(data, fd.GetIntData().GetData())
+		}
+		return NewNullableColumnInt32Array(fieldName, data, validData), nil
+
+	case schemapb.DataType_Int64:
+		var data [][]int64
+		for _, fd := range fieldDataList {
+			data = append(data, fd.GetLongData().GetData())
+		}
+		return NewNullableColumnInt64Array(fieldName, data, validData), nil
+
+	case schemapb.DataType_Float:
+		var data [][]float32
+		for _, fd := range fieldDataList {
+			data = append(data, fd.GetFloatData().GetData())
+		}
+		return NewNullableColumnFloatArray(fieldName, data, validData), nil
+
+	case schemapb.DataType_Double:
+		var data [][]float64
+		for _, fd := range fieldDataList {
+			data = append(data, fd.GetDoubleData().GetData())
+		}
+		return NewNullableColumnDoubleArray(fieldName, data, validData), nil
+
+	case schemapb.DataType_VarChar, schemapb.DataType_String:
+		var data [][][]byte
+		for _, fd := range fieldDataList {
+			strs := fd.GetStringData().GetData()
+			bytesData := make([][]byte, 0, len(strs))
+			for _, str := range strs {
+				bytesData = append(bytesData, []byte(str))
+			}
+			data = append(data, bytesData)
+		}
+
+		return NewNullableColumnVarCharArray(fieldName, data, validData), nil
+
+	default:
+		return nil, fmt.Errorf("unsupported element type %s", elementType)
+	}
+}
+
 func parseArrayData(fieldName string, elementType schemapb.DataType, fieldDataList []*schemapb.ScalarField) (Column, error) {
 
 	switch elementType {
@@ -615,3 +764,32 @@ func DefaultValueColumn(name string, dataType FieldType) (Column, error) {
 		return nil, fmt.Errorf("default value unsupported data type %s", dataType)
 	}
 }
+
+// NewAllNullValueColumn will return the empty scalars with nullable==true, and fill it with null
+func NewAllNullValueColumn(name string, dataType FieldType, rowSize int) (Column, error) {
+	switch dataType {
+	case FieldTypeBool:
+		return NewAllNullColumnBool(name, rowSize), nil
+	case FieldTypeInt8:
+		return NewAllNullColumnInt8(name, rowSize), nil
+	case FieldTypeInt16:
+		return NewAllNullColumnInt16(name, rowSize), nil
+	case FieldTypeInt32:
+		return NewAllNullColumnInt32(name, rowSize), nil
+	case FieldTypeInt64:
+		return NewAllNullColumnInt64(name, rowSize), nil
+	case FieldTypeFloat:
+		return NewAllNullColumnFloat(name, rowSize), nil
+	case FieldTypeDouble:
+		return NewAllNullColumnDouble(name, rowSize), nil
+	case FieldTypeString:
+		return NewAllNullColumnString(name, rowSize), nil
+	case FieldTypeVarChar:
+		return NewAllNullColumnVarChar(name, rowSize), nil
+	case FieldTypeJSON:
+		return NewAllNullColumnJSONBytes(name, rowSize), nil
+
+	default:
+		return nil, fmt.Errorf("default value unsupported data type %s", dataType)
+	}
+}
diff --git a/entity/columns_array.go b/entity/columns_array.go
index 9de845a..8f24731 100644
--- a/entity/columns_array.go
+++ b/entity/columns_array.go
@@ -10,8 +10,10 @@ import (
 // ColumnVarCharArray generated columns type for VarChar
 type ColumnVarCharArray struct {
 	ColumnBase
-	name   string
-	values [][][]byte
+	name        string
+	values      [][][]byte
+	validValues []bool
+	nullable    bool
 }
 
 // Name returns column name
@@ -29,6 +31,11 @@ func (c *ColumnVarCharArray) Len() int {
 	return len(c.values)
 }
 
+// Nullable returns column nullable
+func (c *ColumnVarCharArray) Nullable() bool {
+	return c.nullable
+}
+
 func (c *ColumnVarCharArray) Slice(start, end int) Column {
 	l := c.Len()
 	if start > l {
@@ -37,10 +44,16 @@ func (c *ColumnVarCharArray) Slice(start, end int) Column {
 	if end == -1 || end > l {
 		end = l
 	}
+	sliceValidValues := make([]bool, 0)
+	if c.nullable {
+		sliceValidValues = c.validValues[start:end]
+	}
 	return &ColumnVarCharArray{
-		ColumnBase: c.ColumnBase,
-		name:       c.name,
-		values:     c.values[start:end],
+		ColumnBase:  c.ColumnBase,
+		name:        c.name,
+		values:      c.values[start:end],
+		validValues: sliceValidValues,
+		nullable:    c.nullable,
 	}
 }
 
@@ -50,6 +63,14 @@ func (c *ColumnVarCharArray) Get(idx int) (interface{}, error) {
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return nil, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
 	return c.values[idx], nil
 }
 
@@ -58,22 +79,35 @@ func (c *ColumnVarCharArray) FieldData() *schemapb.FieldData {
 	fd := &schemapb.FieldData{
 		Type:      schemapb.DataType_Array,
 		FieldName: c.name,
+		ValidData: c.validValues,
 	}
-
-	data := make([]*schemapb.ScalarField, 0, c.Len())
-	for _, arr := range c.values {
+	convertTo := func(arr [][]byte) *schemapb.ScalarField {
 		converted := make([]string, 0, c.Len())
 		for i := 0; i < len(arr); i++ {
 			converted = append(converted, string(arr[i]))
 		}
-		data = append(data, &schemapb.ScalarField{
+		return &schemapb.ScalarField{
 			Data: &schemapb.ScalarField_StringData{
 				StringData: &schemapb.StringArray{
 					Data: converted,
 				},
 			},
-		})
+		}
+	}
+
+	data := make([]*schemapb.ScalarField, 0, len(c.validValues))
+	if c.nullable {
+		for i, v := range c.validValues {
+			if v {
+				data = append(data, convertTo(c.values[i]))
+			}
+		}
+	} else {
+		for _, arr := range c.values {
+			data = append(data, convertTo(arr))
+		}
 	}
+
 	fd.Field = &schemapb.FieldData_Scalars{
 		Scalars: &schemapb.ScalarField{
 			Data: &schemapb.ScalarField_ArrayData{
@@ -94,16 +128,33 @@ func (c *ColumnVarCharArray) ValueByIdx(idx int) ([][]byte, error) {
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return r, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
 	return c.values[idx], nil
 }
 
 // AppendValue append value into column
 func (c *ColumnVarCharArray) AppendValue(i interface{}) error {
+	var v [][]byte
+	if i == nil && c.nullable {
+		c.values = append(c.values, v)
+		c.validValues = append(c.validValues, false)
+		return nil
+	}
 	v, ok := i.([][]byte)
 	if !ok {
 		return fmt.Errorf("invalid type, expected []string, got %T", i)
 	}
 	c.values = append(c.values, v)
+	if c.nullable {
+		c.validValues = append(c.validValues, true)
+	}
 
 	return nil
 }
@@ -113,6 +164,11 @@ func (c *ColumnVarCharArray) Data() [][][]byte {
 	return c.values
 }
 
+// ValidData returns column validValues
+func (c *ColumnVarCharArray) ValidData() []bool {
+	return c.validValues
+}
+
 // NewColumnVarChar auto generated constructor
 func NewColumnVarCharArray(name string, values [][][]byte) *ColumnVarCharArray {
 	return &ColumnVarCharArray{
@@ -120,3 +176,13 @@ func NewColumnVarCharArray(name string, values [][][]byte) *ColumnVarCharArray {
 		values: values,
 	}
 }
+
+// NewNullableColumnJSONBytes composes a nullable Column with json bytes.
+func NewNullableColumnVarCharArray(name string, values [][][]byte, validValues []bool) *ColumnVarCharArray {
+	return &ColumnVarCharArray{
+		name:        name,
+		values:      values,
+		nullable:    true,
+		validValues: validValues,
+	}
+}
diff --git a/entity/columns_array_gen.go b/entity/columns_array_gen.go
index 6b80da2..79a3e3b 100755
--- a/entity/columns_array_gen.go
+++ b/entity/columns_array_gen.go
@@ -16,6 +16,8 @@ type ColumnBoolArray struct {
 	ColumnBase
 	name   string
 	values [][]bool
+	validValues []bool
+	nullable    bool
 }
 
 // Name returns column name
@@ -33,6 +35,12 @@ func (c *ColumnBoolArray) Len() int {
 	return len(c.values)
 }
 
+// Nullable returns column values nullable
+func (c *ColumnBoolArray) Nullable() bool {
+	return c.nullable
+}
+
+// Slice returns column slice
 func (c *ColumnBoolArray) Slice(start, end int) Column {
 	l := c.Len()
 	if start > l {
@@ -41,13 +49,16 @@ func (c *ColumnBoolArray) Slice(start, end int) Column {
 	if end == -1 || end > l {
 		end = l
 	}
-	if end == -1 || end > l {
-		end = l
+	sliceValidValues := make([]bool, 0)
+	if c.nullable {
+		sliceValidValues = c.validValues[start:end]
 	}
 	return &ColumnBoolArray{
-		ColumnBase: c.ColumnBase,
-		name:       c.name,
-		values:     c.values[start:end],
+		ColumnBase:  c.ColumnBase,
+		name:        c.name,
+		values:      c.values[start:end],
+		validValues: sliceValidValues,
+		nullable:    c.nullable,
 	}
 }
 
@@ -57,6 +68,14 @@ func (c *ColumnBoolArray) Get(idx int) (interface{}, error) {
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return nil, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
 	return c.values[idx], nil
 }
 
@@ -65,22 +84,36 @@ func (c *ColumnBoolArray) FieldData() *schemapb.FieldData {
 	fd := &schemapb.FieldData{
 		Type:      schemapb.DataType_Array,
 		FieldName: c.name,
+		ValidData: c.validValues,
 	}
 
-	data := make([]*schemapb.ScalarField, 0, c.Len())
-	for _, arr := range c.values {
+	convertTo := func(arr []bool) *schemapb.ScalarField {
 		converted := make([]bool, 0, c.Len())
 		for i := 0; i < len(arr); i++ {
 			converted = append(converted, bool(arr[i]))
 		}
-		data = append(data, &schemapb.ScalarField{
+		return &schemapb.ScalarField{
 			Data: &schemapb.ScalarField_BoolData{
 				BoolData: &schemapb.BoolArray{
 					Data: converted,
 				},
 			},
-		})
+		}
 	}
+
+	data := make([]*schemapb.ScalarField, 0, c.Len())
+	if c.nullable {
+		for i, v := range c.validValues {
+			if v {
+				data = append(data, convertTo(c.values[i]))
+			}
+		}
+	} else {
+		for _, arr := range c.values {
+			data = append(data, convertTo(arr))
+		}
+	}
+
 	fd.Field = &schemapb.FieldData_Scalars{
 		Scalars: &schemapb.ScalarField{
 			Data: &schemapb.ScalarField_ArrayData{
@@ -101,16 +134,33 @@ func (c *ColumnBoolArray) ValueByIdx(idx int) ([]bool, error) {
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return r, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
 	return c.values[idx], nil
 }
 
 // AppendValue append value into column
 func(c *ColumnBoolArray) AppendValue(i interface{}) error {
+	var v []bool
+	if i == nil && c.nullable {
+		c.values = append(c.values, v)
+		c.validValues = append(c.validValues, false)
+		return nil
+	}
 	v, ok := i.([]bool)
 	if !ok {
 		return fmt.Errorf("invalid type, expected []bool, got %T", i)
 	}
 	c.values = append(c.values, v)
+	if c.nullable {
+		c.validValues = append(c.validValues, true)
+	}
 
 	return nil
 }
@@ -120,6 +170,11 @@ func (c *ColumnBoolArray) Data() [][]bool {
 	return c.values
 }
 
+// ValidData returns column ValidData
+func (c *ColumnBoolArray) ValidData() []bool {
+	return c.validValues
+}
+
 // NewColumnBool auto generated constructor
 func NewColumnBoolArray(name string, values [][]bool) *ColumnBoolArray {
 	return &ColumnBoolArray {
@@ -128,11 +183,33 @@ func NewColumnBoolArray(name string, values [][]bool) *ColumnBoolArray {
 	}
 }
 
+// NewColumnBool auto generated constructor
+func NewNullableColumnBoolArray(name string, values [][]bool, validValues []bool) *ColumnBoolArray {
+	return &ColumnBoolArray {
+		name: name,
+		values: values,
+		nullable:    true,
+		validValues: validValues,
+	}
+}
+
+// NewAllNullColumnBool auto generated constructor
+func NewAllNullColumnBoolArray(name string, rowSize int) *ColumnBoolArray {
+	return &ColumnBoolArray {
+		name: name,
+		values: make([][]bool,rowSize),
+		nullable:    true,
+		validValues: make([]bool,rowSize),
+	}
+}
+
 // ColumnInt8Array generated columns type for Int8
 type ColumnInt8Array struct {
 	ColumnBase
 	name   string
 	values [][]int8
+	validValues []bool
+	nullable    bool
 }
 
 // Name returns column name
@@ -150,6 +227,12 @@ func (c *ColumnInt8Array) Len() int {
 	return len(c.values)
 }
 
+// Nullable returns column values nullable
+func (c *ColumnInt8Array) Nullable() bool {
+	return c.nullable
+}
+
+// Slice returns column slice
 func (c *ColumnInt8Array) Slice(start, end int) Column {
 	l := c.Len()
 	if start > l {
@@ -158,10 +241,16 @@ func (c *ColumnInt8Array) Slice(start, end int) Column {
 	if end == -1 || end > l {
 		end = l
 	}
+	sliceValidValues := make([]bool, 0)
+	if c.nullable {
+		sliceValidValues = c.validValues[start:end]
+	}
 	return &ColumnInt8Array{
-		ColumnBase: c.ColumnBase,
-		name:       c.name,
-		values:     c.values[start:end],
+		ColumnBase:  c.ColumnBase,
+		name:        c.name,
+		values:      c.values[start:end],
+		validValues: sliceValidValues,
+		nullable:    c.nullable,
 	}
 }
 
@@ -171,6 +260,14 @@ func (c *ColumnInt8Array) Get(idx int) (interface{}, error) {
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return nil, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
 	return c.values[idx], nil
 }
 
@@ -179,22 +276,36 @@ func (c *ColumnInt8Array) FieldData() *schemapb.FieldData {
 	fd := &schemapb.FieldData{
 		Type:      schemapb.DataType_Array,
 		FieldName: c.name,
+		ValidData: c.validValues,
 	}
 
-	data := make([]*schemapb.ScalarField, 0, c.Len())
-	for _, arr := range c.values {
+	convertTo := func(arr []int8) *schemapb.ScalarField {
 		converted := make([]int32, 0, c.Len())
 		for i := 0; i < len(arr); i++ {
 			converted = append(converted, int32(arr[i]))
 		}
-		data = append(data, &schemapb.ScalarField{
+		return &schemapb.ScalarField{
 			Data: &schemapb.ScalarField_IntData{
 				IntData: &schemapb.IntArray{
 					Data: converted,
 				},
 			},
-		})
+		}
 	}
+
+	data := make([]*schemapb.ScalarField, 0, c.Len())
+	if c.nullable {
+		for i, v := range c.validValues {
+			if v {
+				data = append(data, convertTo(c.values[i]))
+			}
+		}
+	} else {
+		for _, arr := range c.values {
+			data = append(data, convertTo(arr))
+		}
+	}
+
 	fd.Field = &schemapb.FieldData_Scalars{
 		Scalars: &schemapb.ScalarField{
 			Data: &schemapb.ScalarField_ArrayData{
@@ -215,16 +326,33 @@ func (c *ColumnInt8Array) ValueByIdx(idx int) ([]int8, error) {
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return r, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
 	return c.values[idx], nil
 }
 
 // AppendValue append value into column
 func(c *ColumnInt8Array) AppendValue(i interface{}) error {
+	var v []int8
+	if i == nil && c.nullable {
+		c.values = append(c.values, v)
+		c.validValues = append(c.validValues, false)
+		return nil
+	}
 	v, ok := i.([]int8)
 	if !ok {
 		return fmt.Errorf("invalid type, expected []int8, got %T", i)
 	}
 	c.values = append(c.values, v)
+	if c.nullable {
+		c.validValues = append(c.validValues, true)
+	}
 
 	return nil
 }
@@ -234,6 +362,11 @@ func (c *ColumnInt8Array) Data() [][]int8 {
 	return c.values
 }
 
+// ValidData returns column ValidData
+func (c *ColumnInt8Array) ValidData() []bool {
+	return c.validValues
+}
+
 // NewColumnInt8 auto generated constructor
 func NewColumnInt8Array(name string, values [][]int8) *ColumnInt8Array {
 	return &ColumnInt8Array {
@@ -242,11 +375,33 @@ func NewColumnInt8Array(name string, values [][]int8) *ColumnInt8Array {
 	}
 }
 
+// NewColumnInt8 auto generated constructor
+func NewNullableColumnInt8Array(name string, values [][]int8, validValues []bool) *ColumnInt8Array {
+	return &ColumnInt8Array {
+		name: name,
+		values: values,
+		nullable:    true,
+		validValues: validValues,
+	}
+}
+
+// NewAllNullColumnInt8 auto generated constructor
+func NewAllNullColumnInt8Array(name string, rowSize int) *ColumnInt8Array {
+	return &ColumnInt8Array {
+		name: name,
+		values: make([][]int8,rowSize),
+		nullable:    true,
+		validValues: make([]bool,rowSize),
+	}
+}
+
 // ColumnInt16Array generated columns type for Int16
 type ColumnInt16Array struct {
 	ColumnBase
 	name   string
 	values [][]int16
+	validValues []bool
+	nullable    bool
 }
 
 // Name returns column name
@@ -264,6 +419,12 @@ func (c *ColumnInt16Array) Len() int {
 	return len(c.values)
 }
 
+// Nullable returns column values nullable
+func (c *ColumnInt16Array) Nullable() bool {
+	return c.nullable
+}
+
+// Slice returns column slice
 func (c *ColumnInt16Array) Slice(start, end int) Column {
 	l := c.Len()
 	if start > l {
@@ -272,10 +433,16 @@ func (c *ColumnInt16Array) Slice(start, end int) Column {
 	if end == -1 || end > l {
 		end = l
 	}
+	sliceValidValues := make([]bool, 0)
+	if c.nullable {
+		sliceValidValues = c.validValues[start:end]
+	}
 	return &ColumnInt16Array{
-		ColumnBase: c.ColumnBase,
-		name:       c.name,
-		values:     c.values[start:end],
+		ColumnBase:  c.ColumnBase,
+		name:        c.name,
+		values:      c.values[start:end],
+		validValues: sliceValidValues,
+		nullable:    c.nullable,
 	}
 }
 
@@ -285,6 +452,14 @@ func (c *ColumnInt16Array) Get(idx int) (interface{}, error) {
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return nil, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
 	return c.values[idx], nil
 }
 
@@ -293,22 +468,36 @@ func (c *ColumnInt16Array) FieldData() *schemapb.FieldData {
 	fd := &schemapb.FieldData{
 		Type:      schemapb.DataType_Array,
 		FieldName: c.name,
+		ValidData: c.validValues,
 	}
 
-	data := make([]*schemapb.ScalarField, 0, c.Len())
-	for _, arr := range c.values {
+	convertTo := func(arr []int16) *schemapb.ScalarField {
 		converted := make([]int32, 0, c.Len())
 		for i := 0; i < len(arr); i++ {
 			converted = append(converted, int32(arr[i]))
 		}
-		data = append(data, &schemapb.ScalarField{
+		return &schemapb.ScalarField{
 			Data: &schemapb.ScalarField_IntData{
 				IntData: &schemapb.IntArray{
 					Data: converted,
 				},
 			},
-		})
+		}
+	}
+
+	data := make([]*schemapb.ScalarField, 0, c.Len())
+	if c.nullable {
+		for i, v := range c.validValues {
+			if v {
+				data = append(data, convertTo(c.values[i]))
+			}
+		}
+	} else {
+		for _, arr := range c.values {
+			data = append(data, convertTo(arr))
+		}
 	}
+
 	fd.Field = &schemapb.FieldData_Scalars{
 		Scalars: &schemapb.ScalarField{
 			Data: &schemapb.ScalarField_ArrayData{
@@ -329,16 +518,33 @@ func (c *ColumnInt16Array) ValueByIdx(idx int) ([]int16, error) {
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return r, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
 	return c.values[idx], nil
 }
 
 // AppendValue append value into column
 func(c *ColumnInt16Array) AppendValue(i interface{}) error {
+	var v []int16
+	if i == nil && c.nullable {
+		c.values = append(c.values, v)
+		c.validValues = append(c.validValues, false)
+		return nil
+	}
 	v, ok := i.([]int16)
 	if !ok {
 		return fmt.Errorf("invalid type, expected []int16, got %T", i)
 	}
 	c.values = append(c.values, v)
+	if c.nullable {
+		c.validValues = append(c.validValues, true)
+	}
 
 	return nil
 }
@@ -348,6 +554,11 @@ func (c *ColumnInt16Array) Data() [][]int16 {
 	return c.values
 }
 
+// ValidData returns column ValidData
+func (c *ColumnInt16Array) ValidData() []bool {
+	return c.validValues
+}
+
 // NewColumnInt16 auto generated constructor
 func NewColumnInt16Array(name string, values [][]int16) *ColumnInt16Array {
 	return &ColumnInt16Array {
@@ -356,11 +567,33 @@ func NewColumnInt16Array(name string, values [][]int16) *ColumnInt16Array {
 	}
 }
 
+// NewColumnInt16 auto generated constructor
+func NewNullableColumnInt16Array(name string, values [][]int16, validValues []bool) *ColumnInt16Array {
+	return &ColumnInt16Array {
+		name: name,
+		values: values,
+		nullable:    true,
+		validValues: validValues,
+	}
+}
+
+// NewAllNullColumnInt16 auto generated constructor
+func NewAllNullColumnInt16Array(name string, rowSize int) *ColumnInt16Array {
+	return &ColumnInt16Array {
+		name: name,
+		values: make([][]int16,rowSize),
+		nullable:    true,
+		validValues: make([]bool,rowSize),
+	}
+}
+
 // ColumnInt32Array generated columns type for Int32
 type ColumnInt32Array struct {
 	ColumnBase
 	name   string
 	values [][]int32
+	validValues []bool
+	nullable    bool
 }
 
 // Name returns column name
@@ -378,6 +611,12 @@ func (c *ColumnInt32Array) Len() int {
 	return len(c.values)
 }
 
+// Nullable returns column values nullable
+func (c *ColumnInt32Array) Nullable() bool {
+	return c.nullable
+}
+
+// Slice returns column slice
 func (c *ColumnInt32Array) Slice(start, end int) Column {
 	l := c.Len()
 	if start > l {
@@ -386,10 +625,16 @@ func (c *ColumnInt32Array) Slice(start, end int) Column {
 	if end == -1 || end > l {
 		end = l
 	}
+	sliceValidValues := make([]bool, 0)
+	if c.nullable {
+		sliceValidValues = c.validValues[start:end]
+	}
 	return &ColumnInt32Array{
-		ColumnBase: c.ColumnBase,
-		name:       c.name,
-		values:     c.values[start:end],
+		ColumnBase:  c.ColumnBase,
+		name:        c.name,
+		values:      c.values[start:end],
+		validValues: sliceValidValues,
+		nullable:    c.nullable,
 	}
 }
 
@@ -399,6 +644,14 @@ func (c *ColumnInt32Array) Get(idx int) (interface{}, error) {
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return nil, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
 	return c.values[idx], nil
 }
 
@@ -407,22 +660,36 @@ func (c *ColumnInt32Array) FieldData() *schemapb.FieldData {
 	fd := &schemapb.FieldData{
 		Type:      schemapb.DataType_Array,
 		FieldName: c.name,
+		ValidData: c.validValues,
 	}
 
-	data := make([]*schemapb.ScalarField, 0, c.Len())
-	for _, arr := range c.values {
+	convertTo := func(arr []int32) *schemapb.ScalarField {
 		converted := make([]int32, 0, c.Len())
 		for i := 0; i < len(arr); i++ {
 			converted = append(converted, int32(arr[i]))
 		}
-		data = append(data, &schemapb.ScalarField{
+		return &schemapb.ScalarField{
 			Data: &schemapb.ScalarField_IntData{
 				IntData: &schemapb.IntArray{
 					Data: converted,
 				},
 			},
-		})
+		}
+	}
+
+	data := make([]*schemapb.ScalarField, 0, c.Len())
+	if c.nullable {
+		for i, v := range c.validValues {
+			if v {
+				data = append(data, convertTo(c.values[i]))
+			}
+		}
+	} else {
+		for _, arr := range c.values {
+			data = append(data, convertTo(arr))
+		}
 	}
+
 	fd.Field = &schemapb.FieldData_Scalars{
 		Scalars: &schemapb.ScalarField{
 			Data: &schemapb.ScalarField_ArrayData{
@@ -443,16 +710,33 @@ func (c *ColumnInt32Array) ValueByIdx(idx int) ([]int32, error) {
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return r, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
 	return c.values[idx], nil
 }
 
 // AppendValue append value into column
 func(c *ColumnInt32Array) AppendValue(i interface{}) error {
+	var v []int32
+	if i == nil && c.nullable {
+		c.values = append(c.values, v)
+		c.validValues = append(c.validValues, false)
+		return nil
+	}
 	v, ok := i.([]int32)
 	if !ok {
 		return fmt.Errorf("invalid type, expected []int32, got %T", i)
 	}
 	c.values = append(c.values, v)
+	if c.nullable {
+		c.validValues = append(c.validValues, true)
+	}
 
 	return nil
 }
@@ -462,6 +746,11 @@ func (c *ColumnInt32Array) Data() [][]int32 {
 	return c.values
 }
 
+// ValidData returns column ValidData
+func (c *ColumnInt32Array) ValidData() []bool {
+	return c.validValues
+}
+
 // NewColumnInt32 auto generated constructor
 func NewColumnInt32Array(name string, values [][]int32) *ColumnInt32Array {
 	return &ColumnInt32Array {
@@ -470,11 +759,33 @@ func NewColumnInt32Array(name string, values [][]int32) *ColumnInt32Array {
 	}
 }
 
+// NewColumnInt32 auto generated constructor
+func NewNullableColumnInt32Array(name string, values [][]int32, validValues []bool) *ColumnInt32Array {
+	return &ColumnInt32Array {
+		name: name,
+		values: values,
+		nullable:    true,
+		validValues: validValues,
+	}
+}
+
+// NewAllNullColumnInt32 auto generated constructor
+func NewAllNullColumnInt32Array(name string, rowSize int) *ColumnInt32Array {
+	return &ColumnInt32Array {
+		name: name,
+		values: make([][]int32,rowSize),
+		nullable:    true,
+		validValues: make([]bool,rowSize),
+	}
+}
+
 // ColumnInt64Array generated columns type for Int64
 type ColumnInt64Array struct {
 	ColumnBase
 	name   string
 	values [][]int64
+	validValues []bool
+	nullable    bool
 }
 
 // Name returns column name
@@ -492,6 +803,12 @@ func (c *ColumnInt64Array) Len() int {
 	return len(c.values)
 }
 
+// Nullable returns column values nullable
+func (c *ColumnInt64Array) Nullable() bool {
+	return c.nullable
+}
+
+// Slice returns column slice
 func (c *ColumnInt64Array) Slice(start, end int) Column {
 	l := c.Len()
 	if start > l {
@@ -500,10 +817,16 @@ func (c *ColumnInt64Array) Slice(start, end int) Column {
 	if end == -1 || end > l {
 		end = l
 	}
+	sliceValidValues := make([]bool, 0)
+	if c.nullable {
+		sliceValidValues = c.validValues[start:end]
+	}
 	return &ColumnInt64Array{
-		ColumnBase: c.ColumnBase,
-		name:       c.name,
-		values:     c.values[start:end],
+		ColumnBase:  c.ColumnBase,
+		name:        c.name,
+		values:      c.values[start:end],
+		validValues: sliceValidValues,
+		nullable:    c.nullable,
 	}
 }
 
@@ -513,6 +836,14 @@ func (c *ColumnInt64Array) Get(idx int) (interface{}, error) {
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return nil, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
 	return c.values[idx], nil
 }
 
@@ -521,22 +852,36 @@ func (c *ColumnInt64Array) FieldData() *schemapb.FieldData {
 	fd := &schemapb.FieldData{
 		Type:      schemapb.DataType_Array,
 		FieldName: c.name,
+		ValidData: c.validValues,
 	}
 
-	data := make([]*schemapb.ScalarField, 0, c.Len())
-	for _, arr := range c.values {
+	convertTo := func(arr []int64) *schemapb.ScalarField {
 		converted := make([]int64, 0, c.Len())
 		for i := 0; i < len(arr); i++ {
 			converted = append(converted, int64(arr[i]))
 		}
-		data = append(data, &schemapb.ScalarField{
+		return &schemapb.ScalarField{
 			Data: &schemapb.ScalarField_LongData{
 				LongData: &schemapb.LongArray{
 					Data: converted,
 				},
 			},
-		})
+		}
+	}
+
+	data := make([]*schemapb.ScalarField, 0, c.Len())
+	if c.nullable {
+		for i, v := range c.validValues {
+			if v {
+				data = append(data, convertTo(c.values[i]))
+			}
+		}
+	} else {
+		for _, arr := range c.values {
+			data = append(data, convertTo(arr))
+		}
 	}
+
 	fd.Field = &schemapb.FieldData_Scalars{
 		Scalars: &schemapb.ScalarField{
 			Data: &schemapb.ScalarField_ArrayData{
@@ -557,16 +902,33 @@ func (c *ColumnInt64Array) ValueByIdx(idx int) ([]int64, error) {
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return r, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
 	return c.values[idx], nil
 }
 
 // AppendValue append value into column
 func(c *ColumnInt64Array) AppendValue(i interface{}) error {
+	var v []int64
+	if i == nil && c.nullable {
+		c.values = append(c.values, v)
+		c.validValues = append(c.validValues, false)
+		return nil
+	}
 	v, ok := i.([]int64)
 	if !ok {
 		return fmt.Errorf("invalid type, expected []int64, got %T", i)
 	}
 	c.values = append(c.values, v)
+	if c.nullable {
+		c.validValues = append(c.validValues, true)
+	}
 
 	return nil
 }
@@ -576,6 +938,11 @@ func (c *ColumnInt64Array) Data() [][]int64 {
 	return c.values
 }
 
+// ValidData returns column ValidData
+func (c *ColumnInt64Array) ValidData() []bool {
+	return c.validValues
+}
+
 // NewColumnInt64 auto generated constructor
 func NewColumnInt64Array(name string, values [][]int64) *ColumnInt64Array {
 	return &ColumnInt64Array {
@@ -584,11 +951,33 @@ func NewColumnInt64Array(name string, values [][]int64) *ColumnInt64Array {
 	}
 }
 
+// NewColumnInt64 auto generated constructor
+func NewNullableColumnInt64Array(name string, values [][]int64, validValues []bool) *ColumnInt64Array {
+	return &ColumnInt64Array {
+		name: name,
+		values: values,
+		nullable:    true,
+		validValues: validValues,
+	}
+}
+
+// NewAllNullColumnInt64 auto generated constructor
+func NewAllNullColumnInt64Array(name string, rowSize int) *ColumnInt64Array {
+	return &ColumnInt64Array {
+		name: name,
+		values: make([][]int64,rowSize),
+		nullable:    true,
+		validValues: make([]bool,rowSize),
+	}
+}
+
 // ColumnFloatArray generated columns type for Float
 type ColumnFloatArray struct {
 	ColumnBase
 	name   string
 	values [][]float32
+	validValues []bool
+	nullable    bool
 }
 
 // Name returns column name
@@ -606,6 +995,12 @@ func (c *ColumnFloatArray) Len() int {
 	return len(c.values)
 }
 
+// Nullable returns column values nullable
+func (c *ColumnFloatArray) Nullable() bool {
+	return c.nullable
+}
+
+// Slice returns column slice
 func (c *ColumnFloatArray) Slice(start, end int) Column {
 	l := c.Len()
 	if start > l {
@@ -614,10 +1009,16 @@ func (c *ColumnFloatArray) Slice(start, end int) Column {
 	if end == -1 || end > l {
 		end = l
 	}
+	sliceValidValues := make([]bool, 0)
+	if c.nullable {
+		sliceValidValues = c.validValues[start:end]
+	}
 	return &ColumnFloatArray{
-		ColumnBase: c.ColumnBase,
-		name:       c.name,
-		values:     c.values[start:end],
+		ColumnBase:  c.ColumnBase,
+		name:        c.name,
+		values:      c.values[start:end],
+		validValues: sliceValidValues,
+		nullable:    c.nullable,
 	}
 }
 
@@ -627,6 +1028,14 @@ func (c *ColumnFloatArray) Get(idx int) (interface{}, error) {
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return nil, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
 	return c.values[idx], nil
 }
 
@@ -635,22 +1044,36 @@ func (c *ColumnFloatArray) FieldData() *schemapb.FieldData {
 	fd := &schemapb.FieldData{
 		Type:      schemapb.DataType_Array,
 		FieldName: c.name,
+		ValidData: c.validValues,
 	}
 
-	data := make([]*schemapb.ScalarField, 0, c.Len())
-	for _, arr := range c.values {
+	convertTo := func(arr []float32) *schemapb.ScalarField {
 		converted := make([]float32, 0, c.Len())
 		for i := 0; i < len(arr); i++ {
 			converted = append(converted, float32(arr[i]))
 		}
-		data = append(data, &schemapb.ScalarField{
+		return &schemapb.ScalarField{
 			Data: &schemapb.ScalarField_FloatData{
 				FloatData: &schemapb.FloatArray{
 					Data: converted,
 				},
 			},
-		})
+		}
 	}
+
+	data := make([]*schemapb.ScalarField, 0, c.Len())
+	if c.nullable {
+		for i, v := range c.validValues {
+			if v {
+				data = append(data, convertTo(c.values[i]))
+			}
+		}
+	} else {
+		for _, arr := range c.values {
+			data = append(data, convertTo(arr))
+		}
+	}
+
 	fd.Field = &schemapb.FieldData_Scalars{
 		Scalars: &schemapb.ScalarField{
 			Data: &schemapb.ScalarField_ArrayData{
@@ -671,16 +1094,33 @@ func (c *ColumnFloatArray) ValueByIdx(idx int) ([]float32, error) {
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return r, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
 	return c.values[idx], nil
 }
 
 // AppendValue append value into column
 func(c *ColumnFloatArray) AppendValue(i interface{}) error {
+	var v []float32
+	if i == nil && c.nullable {
+		c.values = append(c.values, v)
+		c.validValues = append(c.validValues, false)
+		return nil
+	}
 	v, ok := i.([]float32)
 	if !ok {
 		return fmt.Errorf("invalid type, expected []float32, got %T", i)
 	}
 	c.values = append(c.values, v)
+	if c.nullable {
+		c.validValues = append(c.validValues, true)
+	}
 
 	return nil
 }
@@ -690,6 +1130,11 @@ func (c *ColumnFloatArray) Data() [][]float32 {
 	return c.values
 }
 
+// ValidData returns column ValidData
+func (c *ColumnFloatArray) ValidData() []bool {
+	return c.validValues
+}
+
 // NewColumnFloat auto generated constructor
 func NewColumnFloatArray(name string, values [][]float32) *ColumnFloatArray {
 	return &ColumnFloatArray {
@@ -698,11 +1143,33 @@ func NewColumnFloatArray(name string, values [][]float32) *ColumnFloatArray {
 	}
 }
 
+// NewColumnFloat auto generated constructor
+func NewNullableColumnFloatArray(name string, values [][]float32, validValues []bool) *ColumnFloatArray {
+	return &ColumnFloatArray {
+		name: name,
+		values: values,
+		nullable:    true,
+		validValues: validValues,
+	}
+}
+
+// NewAllNullColumnFloat auto generated constructor
+func NewAllNullColumnFloatArray(name string, rowSize int) *ColumnFloatArray {
+	return &ColumnFloatArray {
+		name: name,
+		values: make([][]float32,rowSize),
+		nullable:    true,
+		validValues: make([]bool,rowSize),
+	}
+}
+
 // ColumnDoubleArray generated columns type for Double
 type ColumnDoubleArray struct {
 	ColumnBase
 	name   string
 	values [][]float64
+	validValues []bool
+	nullable    bool
 }
 
 // Name returns column name
@@ -720,6 +1187,12 @@ func (c *ColumnDoubleArray) Len() int {
 	return len(c.values)
 }
 
+// Nullable returns column values nullable
+func (c *ColumnDoubleArray) Nullable() bool {
+	return c.nullable
+}
+
+// Slice returns column slice
 func (c *ColumnDoubleArray) Slice(start, end int) Column {
 	l := c.Len()
 	if start > l {
@@ -728,10 +1201,16 @@ func (c *ColumnDoubleArray) Slice(start, end int) Column {
 	if end == -1 || end > l {
 		end = l
 	}
+	sliceValidValues := make([]bool, 0)
+	if c.nullable {
+		sliceValidValues = c.validValues[start:end]
+	}
 	return &ColumnDoubleArray{
-		ColumnBase: c.ColumnBase,
-		name:       c.name,
-		values:     c.values[start:end],
+		ColumnBase:  c.ColumnBase,
+		name:        c.name,
+		values:      c.values[start:end],
+		validValues: sliceValidValues,
+		nullable:    c.nullable,
 	}
 }
 
@@ -741,6 +1220,14 @@ func (c *ColumnDoubleArray) Get(idx int) (interface{}, error) {
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return nil, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
 	return c.values[idx], nil
 }
 
@@ -749,22 +1236,36 @@ func (c *ColumnDoubleArray) FieldData() *schemapb.FieldData {
 	fd := &schemapb.FieldData{
 		Type:      schemapb.DataType_Array,
 		FieldName: c.name,
+		ValidData: c.validValues,
 	}
 
-	data := make([]*schemapb.ScalarField, 0, c.Len())
-	for _, arr := range c.values {
+	convertTo := func(arr []float64) *schemapb.ScalarField {
 		converted := make([]float64, 0, c.Len())
 		for i := 0; i < len(arr); i++ {
 			converted = append(converted, float64(arr[i]))
 		}
-		data = append(data, &schemapb.ScalarField{
+		return &schemapb.ScalarField{
 			Data: &schemapb.ScalarField_DoubleData{
 				DoubleData: &schemapb.DoubleArray{
 					Data: converted,
 				},
 			},
-		})
+		}
+	}
+
+	data := make([]*schemapb.ScalarField, 0, c.Len())
+	if c.nullable {
+		for i, v := range c.validValues {
+			if v {
+				data = append(data, convertTo(c.values[i]))
+			}
+		}
+	} else {
+		for _, arr := range c.values {
+			data = append(data, convertTo(arr))
+		}
 	}
+
 	fd.Field = &schemapb.FieldData_Scalars{
 		Scalars: &schemapb.ScalarField{
 			Data: &schemapb.ScalarField_ArrayData{
@@ -785,16 +1286,33 @@ func (c *ColumnDoubleArray) ValueByIdx(idx int) ([]float64, error) {
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return r, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
 	return c.values[idx], nil
 }
 
 // AppendValue append value into column
 func(c *ColumnDoubleArray) AppendValue(i interface{}) error {
+	var v []float64
+	if i == nil && c.nullable {
+		c.values = append(c.values, v)
+		c.validValues = append(c.validValues, false)
+		return nil
+	}
 	v, ok := i.([]float64)
 	if !ok {
 		return fmt.Errorf("invalid type, expected []float64, got %T", i)
 	}
 	c.values = append(c.values, v)
+	if c.nullable {
+		c.validValues = append(c.validValues, true)
+	}
 
 	return nil
 }
@@ -804,6 +1322,11 @@ func (c *ColumnDoubleArray) Data() [][]float64 {
 	return c.values
 }
 
+// ValidData returns column ValidData
+func (c *ColumnDoubleArray) ValidData() []bool {
+	return c.validValues
+}
+
 // NewColumnDouble auto generated constructor
 func NewColumnDoubleArray(name string, values [][]float64) *ColumnDoubleArray {
 	return &ColumnDoubleArray {
@@ -812,4 +1335,23 @@ func NewColumnDoubleArray(name string, values [][]float64) *ColumnDoubleArray {
 	}
 }
 
+// NewColumnDouble auto generated constructor
+func NewNullableColumnDoubleArray(name string, values [][]float64, validValues []bool) *ColumnDoubleArray {
+	return &ColumnDoubleArray {
+		name: name,
+		values: values,
+		nullable:    true,
+		validValues: validValues,
+	}
+}
+
+// NewAllNullColumnDouble auto generated constructor
+func NewAllNullColumnDoubleArray(name string, rowSize int) *ColumnDoubleArray {
+	return &ColumnDoubleArray {
+		name: name,
+		values: make([][]float64,rowSize),
+		nullable:    true,
+		validValues: make([]bool,rowSize),
+	}
+}
 
diff --git a/entity/columns_json.go b/entity/columns_json.go
index bdf1497..7118037 100644
--- a/entity/columns_json.go
+++ b/entity/columns_json.go
@@ -15,9 +15,11 @@ var _ (Column) = (*ColumnJSONBytes)(nil)
 // all items are marshaled json bytes.
 type ColumnJSONBytes struct {
 	ColumnBase
-	name      string
-	values    [][]byte
-	isDynamic bool
+	name        string
+	values      [][]byte
+	isDynamic   bool
+	validValues []bool
+	nullable    bool
 }
 
 // Name returns column name.
@@ -35,6 +37,11 @@ func (c *ColumnJSONBytes) Len() int {
 	return len(c.values)
 }
 
+// Nullable returns column nullable
+func (c *ColumnJSONBytes) Nullable() bool {
+	return c.nullable
+}
+
 func (c *ColumnJSONBytes) Slice(start, end int) Column {
 	l := c.Len()
 	if start > l {
@@ -43,10 +50,16 @@ func (c *ColumnJSONBytes) Slice(start, end int) Column {
 	if end == -1 || end > l {
 		end = l
 	}
+	sliceValidValues := make([]bool, 0)
+	if c.nullable {
+		sliceValidValues = c.validValues[start:end]
+	}
 	return &ColumnJSONBytes{
-		ColumnBase: c.ColumnBase,
-		name:       c.name,
-		values:     c.values[start:end],
+		ColumnBase:  c.ColumnBase,
+		name:        c.name,
+		values:      c.values[start:end],
+		validValues: sliceValidValues,
+		nullable:    c.nullable,
 	}
 }
 
@@ -55,6 +68,14 @@ func (c *ColumnJSONBytes) Get(idx int) (interface{}, error) {
 	if idx < 0 || idx > c.Len() {
 		return nil, errors.New("index out of range")
 	}
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return nil, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
 	return c.values[idx], nil
 }
 
@@ -72,13 +93,25 @@ func (c *ColumnJSONBytes) FieldData() *schema.FieldData {
 		Type:      schema.DataType_JSON,
 		FieldName: c.name,
 		IsDynamic: c.isDynamic,
+		ValidData: c.validValues,
+	}
+
+	data := make([][]byte, 0, c.Len())
+	if c.nullable {
+		for i, v := range c.validValues {
+			if v {
+				data = append(data, c.values[i])
+			}
+		}
+	} else {
+		data = c.values
 	}
 
 	fd.Field = &schema.FieldData_Scalars{
 		Scalars: &schema.ScalarField{
 			Data: &schema.ScalarField_JsonData{
 				JsonData: &schema.JSONArray{
-					Data: c.values,
+					Data: data,
 				},
 			},
 		},
@@ -92,12 +125,26 @@ func (c *ColumnJSONBytes) ValueByIdx(idx int) ([]byte, error) {
 	if idx < 0 || idx >= c.Len() {
 		return nil, errors.New("index out of range")
 	}
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return nil, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
 	return c.values[idx], nil
 }
 
 // AppendValue append value into column.
 func (c *ColumnJSONBytes) AppendValue(i interface{}) error {
 	var v []byte
+	if i == nil && c.nullable {
+		c.values = append(c.values, v)
+		c.validValues = append(c.validValues, false)
+		return nil
+	}
+
 	switch raw := i.(type) {
 	case []byte:
 		v = raw
@@ -120,6 +167,9 @@ func (c *ColumnJSONBytes) AppendValue(i interface{}) error {
 		}
 	}
 	c.values = append(c.values, v)
+	if c.nullable {
+		c.validValues = append(c.validValues, true)
+	}
 
 	return nil
 }
@@ -129,6 +179,11 @@ func (c *ColumnJSONBytes) Data() [][]byte {
 	return c.values
 }
 
+// ValidData returns column validValues
+func (c *ColumnJSONBytes) ValidData() []bool {
+	return c.validValues
+}
+
 func (c *ColumnJSONBytes) WithIsDynamic(isDynamic bool) *ColumnJSONBytes {
 	c.isDynamic = isDynamic
 	return c
@@ -145,3 +200,23 @@ func NewColumnJSONBytes(name string, values [][]byte) *ColumnJSONBytes {
 		values: values,
 	}
 }
+
+// NewNullableColumnJSONBytes composes a nullable Column with json bytes.
+func NewNullableColumnJSONBytes(name string, values [][]byte, validValues []bool) *ColumnJSONBytes {
+	return &ColumnJSONBytes{
+		name:        name,
+		values:      values,
+		nullable:    true,
+		validValues: validValues,
+	}
+}
+
+// NewAllNullColumnJSONBytes composes a nullable Column with json bytes.
+func NewAllNullColumnJSONBytes(name string, rowSize int) *ColumnJSONBytes {
+	return &ColumnJSONBytes{
+		name:        name,
+		values:      make([][]byte, rowSize),
+		nullable:    true,
+		validValues: make([]bool, rowSize),
+	}
+}
diff --git a/entity/columns_scalar_gen.go b/entity/columns_scalar_gen.go
index f97cbde..39e9be3 100755
--- a/entity/columns_scalar_gen.go
+++ b/entity/columns_scalar_gen.go
@@ -15,6 +15,8 @@ type ColumnBool struct {
 	ColumnBase
 	name   string
 	values []bool
+	validValues []bool
+	nullable    bool
 }
 
 // Name returns column name
@@ -32,6 +34,28 @@ func (c *ColumnBool) Len() int {
 	return len(c.values)
 }
 
+// Nullable returns column nullable
+func (c *ColumnBool) Nullable() bool {
+	return c.nullable
+}
+
+// Get returns value at index as interface{}.
+func (c *ColumnBool) Get(idx int) (interface{}, error) {
+	var r bool // use default value
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return nil, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
+	if idx < 0 || idx >= c.Len() {
+		return r, errors.New("index out of range")
+	}
+	return c.values[idx], nil
+}
+
 func (c *ColumnBool) Slice(start, end int) Column {
 	l := c.Len()
 	if start > l {
@@ -40,32 +64,39 @@ func (c *ColumnBool) Slice(start, end int) Column {
 	if end == -1 || end > l {
 		end = l
 	}
+	sliceValidValues := make([]bool, 0)
+	if c.nullable {
+		sliceValidValues = c.validValues[start:end]
+	}
 	return &ColumnBool{
 		ColumnBase: c.ColumnBase,
 		name:       c.name,
 		values:     c.values[start:end],
+		validValues: sliceValidValues,
+		nullable:    c.nullable,
 	}
 }
 
-// Get returns value at index as interface{}.
-func (c *ColumnBool) Get(idx int) (interface{}, error) {
-	var r bool // use default value
-	if idx < 0 || idx >= c.Len() {
-		return r, errors.New("index out of range")
-	}
-	return c.values[idx], nil
-}
-
 // FieldData return column data mapped to schema.FieldData
 func (c *ColumnBool) FieldData() *schema.FieldData {
 	fd := &schema.FieldData{
 		Type: schema.DataType_Bool,
 		FieldName: c.name,
+		ValidData: c.validValues,
 	}
 	data := make([]bool, 0, c.Len())
-	for i := 0; i < c.Len(); i++ {
-		data = append(data, bool(c.values[i]))
-	}
+	if c.nullable {
+		for i, v := range c.validValues {
+			if v {
+				data = append(data, c.values[i])
+			}
+		}
+	} else {
+		for i := 0; i < c.Len(); i++ {
+			data = append(data, c.values[i])
+		}
+	}
+	
 	fd.Field = &schema.FieldData_Scalars{
 		Scalars: &schema.ScalarField{
 			Data: &schema.ScalarField_BoolData{
@@ -82,6 +113,14 @@ func (c *ColumnBool) FieldData() *schema.FieldData {
 // error occurs when index out of range
 func (c *ColumnBool) ValueByIdx(idx int) (bool, error) {
 	var r bool // use default value
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return r, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return r, nil
+		}
+	}
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
@@ -90,11 +129,21 @@ func (c *ColumnBool) ValueByIdx(idx int) (bool, error) {
 
 // AppendValue append value into column
 func(c *ColumnBool) AppendValue(i interface{}) error {
+	var v bool
+	if i == nil && c.nullable {
+		c.values = append(c.values, v)
+		c.validValues = append(c.validValues, false)
+		return nil
+	}
+
 	v, ok := i.(bool)
 	if !ok {
 		return fmt.Errorf("invalid type, expected bool, got %T", i)
 	}
 	c.values = append(c.values, v)
+	if c.nullable {
+		c.validValues = append(c.validValues, true)
+	}
 
 	return nil
 }
@@ -104,6 +153,11 @@ func (c *ColumnBool) Data() []bool {
 	return c.values
 }
 
+// ValidData returns column validValues
+func (c *ColumnBool) ValidData() []bool {
+	return c.validValues
+}
+
 // NewColumnBool auto generated constructor
 func NewColumnBool(name string, values []bool) *ColumnBool {
 	return &ColumnBool {
@@ -112,11 +166,34 @@ func NewColumnBool(name string, values []bool) *ColumnBool {
 	}
 }
 
+// NewNullableColumnBool auto generated constructor
+func NewNullableColumnBool(name string, values []bool, validValues []bool) *ColumnBool {
+	return &ColumnBool {
+		name: name,
+		values: values,
+		nullable:    true,
+		validValues: validValues,
+	}
+}
+
+// NewAllNullColumnBool auto generated constructor
+func NewAllNullColumnBool(name string, rowSize int) *ColumnBool {
+	return &ColumnBool {
+		name: name,
+		values: make([]bool,rowSize),
+		nullable:    true,
+		validValues: make([]bool,rowSize),
+	}
+}
+
+
 // ColumnInt8 generated columns type for Int8
 type ColumnInt8 struct {
 	ColumnBase
 	name   string
 	values []int8
+	validValues []bool
+	nullable    bool
 }
 
 // Name returns column name
@@ -134,6 +211,28 @@ func (c *ColumnInt8) Len() int {
 	return len(c.values)
 }
 
+// Nullable returns column nullable
+func (c *ColumnInt8) Nullable() bool {
+	return c.nullable
+}
+
+// Get returns value at index as interface{}.
+func (c *ColumnInt8) Get(idx int) (interface{}, error) {
+	var r int8 // use default value
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return nil, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
+	if idx < 0 || idx >= c.Len() {
+		return r, errors.New("index out of range")
+	}
+	return c.values[idx], nil
+}
+
 func (c *ColumnInt8) Slice(start, end int) Column {
 	l := c.Len()
 	if start > l {
@@ -142,32 +241,39 @@ func (c *ColumnInt8) Slice(start, end int) Column {
 	if end == -1 || end > l {
 		end = l
 	}
+	sliceValidValues := make([]bool, 0)
+	if c.nullable {
+		sliceValidValues = c.validValues[start:end]
+	}
 	return &ColumnInt8{
 		ColumnBase: c.ColumnBase,
 		name:       c.name,
 		values:     c.values[start:end],
+		validValues: sliceValidValues,
+		nullable:    c.nullable,
 	}
 }
 
-// Get returns value at index as interface{}.
-func (c *ColumnInt8) Get(idx int) (interface{}, error) {
-	var r int8 // use default value
-	if idx < 0 || idx >= c.Len() {
-		return r, errors.New("index out of range")
-	}
-	return c.values[idx], nil
-}
-
 // FieldData return column data mapped to schema.FieldData
 func (c *ColumnInt8) FieldData() *schema.FieldData {
 	fd := &schema.FieldData{
 		Type: schema.DataType_Int8,
 		FieldName: c.name,
+		ValidData: c.validValues,
 	}
 	data := make([]int32, 0, c.Len())
-	for i := 0; i < c.Len(); i++ {
-		data = append(data, int32(c.values[i]))
-	}
+	if c.nullable {
+		for i, v := range c.validValues {
+			if v {
+				data = append(data, int32(c.values[i]))
+			}
+		}
+	} else {
+		for i := 0; i < c.Len(); i++ {
+			data = append(data, int32(c.values[i]))
+		}
+	}
+	
 	fd.Field = &schema.FieldData_Scalars{
 		Scalars: &schema.ScalarField{
 			Data: &schema.ScalarField_IntData{
@@ -184,6 +290,14 @@ func (c *ColumnInt8) FieldData() *schema.FieldData {
 // error occurs when index out of range
 func (c *ColumnInt8) ValueByIdx(idx int) (int8, error) {
 	var r int8 // use default value
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return r, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return r, nil
+		}
+	}
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
@@ -192,11 +306,21 @@ func (c *ColumnInt8) ValueByIdx(idx int) (int8, error) {
 
 // AppendValue append value into column
 func(c *ColumnInt8) AppendValue(i interface{}) error {
+	var v int8
+	if i == nil && c.nullable {
+		c.values = append(c.values, v)
+		c.validValues = append(c.validValues, false)
+		return nil
+	}
+
 	v, ok := i.(int8)
 	if !ok {
 		return fmt.Errorf("invalid type, expected int8, got %T", i)
 	}
 	c.values = append(c.values, v)
+	if c.nullable {
+		c.validValues = append(c.validValues, true)
+	}
 
 	return nil
 }
@@ -206,6 +330,11 @@ func (c *ColumnInt8) Data() []int8 {
 	return c.values
 }
 
+// ValidData returns column validValues
+func (c *ColumnInt8) ValidData() []bool {
+	return c.validValues
+}
+
 // NewColumnInt8 auto generated constructor
 func NewColumnInt8(name string, values []int8) *ColumnInt8 {
 	return &ColumnInt8 {
@@ -214,11 +343,34 @@ func NewColumnInt8(name string, values []int8) *ColumnInt8 {
 	}
 }
 
+// NewNullableColumnInt8 auto generated constructor
+func NewNullableColumnInt8(name string, values []int8, validValues []bool) *ColumnInt8 {
+	return &ColumnInt8 {
+		name: name,
+		values: values,
+		nullable:    true,
+		validValues: validValues,
+	}
+}
+
+// NewAllNullColumnInt8 auto generated constructor
+func NewAllNullColumnInt8(name string, rowSize int) *ColumnInt8 {
+	return &ColumnInt8 {
+		name: name,
+		values: make([]int8,rowSize),
+		nullable:    true,
+		validValues: make([]bool,rowSize),
+	}
+}
+
+
 // ColumnInt16 generated columns type for Int16
 type ColumnInt16 struct {
 	ColumnBase
 	name   string
 	values []int16
+	validValues []bool
+	nullable    bool
 }
 
 // Name returns column name
@@ -236,6 +388,28 @@ func (c *ColumnInt16) Len() int {
 	return len(c.values)
 }
 
+// Nullable returns column nullable
+func (c *ColumnInt16) Nullable() bool {
+	return c.nullable
+}
+
+// Get returns value at index as interface{}.
+func (c *ColumnInt16) Get(idx int) (interface{}, error) {
+	var r int16 // use default value
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return nil, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
+	if idx < 0 || idx >= c.Len() {
+		return r, errors.New("index out of range")
+	}
+	return c.values[idx], nil
+}
+
 func (c *ColumnInt16) Slice(start, end int) Column {
 	l := c.Len()
 	if start > l {
@@ -244,32 +418,39 @@ func (c *ColumnInt16) Slice(start, end int) Column {
 	if end == -1 || end > l {
 		end = l
 	}
+	sliceValidValues := make([]bool, 0)
+	if c.nullable {
+		sliceValidValues = c.validValues[start:end]
+	}
 	return &ColumnInt16{
 		ColumnBase: c.ColumnBase,
 		name:       c.name,
 		values:     c.values[start:end],
+		validValues: sliceValidValues,
+		nullable:    c.nullable,
 	}
 }
 
-// Get returns value at index as interface{}.
-func (c *ColumnInt16) Get(idx int) (interface{}, error) {
-	var r int16 // use default value
-	if idx < 0 || idx >= c.Len() {
-		return r, errors.New("index out of range")
-	}
-	return c.values[idx], nil
-}
-
 // FieldData return column data mapped to schema.FieldData
 func (c *ColumnInt16) FieldData() *schema.FieldData {
 	fd := &schema.FieldData{
 		Type: schema.DataType_Int16,
 		FieldName: c.name,
+		ValidData: c.validValues,
 	}
 	data := make([]int32, 0, c.Len())
-	for i := 0; i < c.Len(); i++ {
-		data = append(data, int32(c.values[i]))
-	}
+	if c.nullable {
+		for i, v := range c.validValues {
+			if v {
+				data = append(data, int32(c.values[i]))
+			}
+		}
+	} else {
+		for i := 0; i < c.Len(); i++ {
+			data = append(data, int32(c.values[i]))
+		}
+	}
+	
 	fd.Field = &schema.FieldData_Scalars{
 		Scalars: &schema.ScalarField{
 			Data: &schema.ScalarField_IntData{
@@ -286,6 +467,14 @@ func (c *ColumnInt16) FieldData() *schema.FieldData {
 // error occurs when index out of range
 func (c *ColumnInt16) ValueByIdx(idx int) (int16, error) {
 	var r int16 // use default value
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return r, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return r, nil
+		}
+	}
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
@@ -294,11 +483,21 @@ func (c *ColumnInt16) ValueByIdx(idx int) (int16, error) {
 
 // AppendValue append value into column
 func(c *ColumnInt16) AppendValue(i interface{}) error {
+	var v int16
+	if i == nil && c.nullable {
+		c.values = append(c.values, v)
+		c.validValues = append(c.validValues, false)
+		return nil
+	}
+
 	v, ok := i.(int16)
 	if !ok {
 		return fmt.Errorf("invalid type, expected int16, got %T", i)
 	}
 	c.values = append(c.values, v)
+	if c.nullable {
+		c.validValues = append(c.validValues, true)
+	}
 
 	return nil
 }
@@ -308,6 +507,11 @@ func (c *ColumnInt16) Data() []int16 {
 	return c.values
 }
 
+// ValidData returns column validValues
+func (c *ColumnInt16) ValidData() []bool {
+	return c.validValues
+}
+
 // NewColumnInt16 auto generated constructor
 func NewColumnInt16(name string, values []int16) *ColumnInt16 {
 	return &ColumnInt16 {
@@ -316,11 +520,34 @@ func NewColumnInt16(name string, values []int16) *ColumnInt16 {
 	}
 }
 
+// NewNullableColumnInt16 auto generated constructor
+func NewNullableColumnInt16(name string, values []int16, validValues []bool) *ColumnInt16 {
+	return &ColumnInt16 {
+		name: name,
+		values: values,
+		nullable:    true,
+		validValues: validValues,
+	}
+}
+
+// NewAllNullColumnInt16 auto generated constructor
+func NewAllNullColumnInt16(name string, rowSize int) *ColumnInt16 {
+	return &ColumnInt16 {
+		name: name,
+		values: make([]int16,rowSize),
+		nullable:    true,
+		validValues: make([]bool,rowSize),
+	}
+}
+
+
 // ColumnInt32 generated columns type for Int32
 type ColumnInt32 struct {
 	ColumnBase
 	name   string
 	values []int32
+	validValues []bool
+	nullable    bool
 }
 
 // Name returns column name
@@ -338,6 +565,28 @@ func (c *ColumnInt32) Len() int {
 	return len(c.values)
 }
 
+// Nullable returns column nullable
+func (c *ColumnInt32) Nullable() bool {
+	return c.nullable
+}
+
+// Get returns value at index as interface{}.
+func (c *ColumnInt32) Get(idx int) (interface{}, error) {
+	var r int32 // use default value
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return nil, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
+	if idx < 0 || idx >= c.Len() {
+		return r, errors.New("index out of range")
+	}
+	return c.values[idx], nil
+}
+
 func (c *ColumnInt32) Slice(start, end int) Column {
 	l := c.Len()
 	if start > l {
@@ -346,32 +595,39 @@ func (c *ColumnInt32) Slice(start, end int) Column {
 	if end == -1 || end > l {
 		end = l
 	}
+	sliceValidValues := make([]bool, 0)
+	if c.nullable {
+		sliceValidValues = c.validValues[start:end]
+	}
 	return &ColumnInt32{
 		ColumnBase: c.ColumnBase,
 		name:       c.name,
 		values:     c.values[start:end],
+		validValues: sliceValidValues,
+		nullable:    c.nullable,
 	}
 }
 
-// Get returns value at index as interface{}.
-func (c *ColumnInt32) Get(idx int) (interface{}, error) {
-	var r int32 // use default value
-	if idx < 0 || idx >= c.Len() {
-		return r, errors.New("index out of range")
-	}
-	return c.values[idx], nil
-}
-
 // FieldData return column data mapped to schema.FieldData
 func (c *ColumnInt32) FieldData() *schema.FieldData {
 	fd := &schema.FieldData{
 		Type: schema.DataType_Int32,
 		FieldName: c.name,
+		ValidData: c.validValues,
 	}
 	data := make([]int32, 0, c.Len())
-	for i := 0; i < c.Len(); i++ {
-		data = append(data, int32(c.values[i]))
-	}
+	if c.nullable {
+		for i, v := range c.validValues {
+			if v {
+				data = append(data, c.values[i])
+			}
+		}
+	} else {
+		for i := 0; i < c.Len(); i++ {
+			data = append(data, c.values[i])
+		}
+	}
+	
 	fd.Field = &schema.FieldData_Scalars{
 		Scalars: &schema.ScalarField{
 			Data: &schema.ScalarField_IntData{
@@ -388,6 +644,14 @@ func (c *ColumnInt32) FieldData() *schema.FieldData {
 // error occurs when index out of range
 func (c *ColumnInt32) ValueByIdx(idx int) (int32, error) {
 	var r int32 // use default value
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return r, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return r, nil
+		}
+	}
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
@@ -396,11 +660,21 @@ func (c *ColumnInt32) ValueByIdx(idx int) (int32, error) {
 
 // AppendValue append value into column
 func(c *ColumnInt32) AppendValue(i interface{}) error {
+	var v int32
+	if i == nil && c.nullable {
+		c.values = append(c.values, v)
+		c.validValues = append(c.validValues, false)
+		return nil
+	}
+
 	v, ok := i.(int32)
 	if !ok {
 		return fmt.Errorf("invalid type, expected int32, got %T", i)
 	}
 	c.values = append(c.values, v)
+	if c.nullable {
+		c.validValues = append(c.validValues, true)
+	}
 
 	return nil
 }
@@ -410,6 +684,11 @@ func (c *ColumnInt32) Data() []int32 {
 	return c.values
 }
 
+// ValidData returns column validValues
+func (c *ColumnInt32) ValidData() []bool {
+	return c.validValues
+}
+
 // NewColumnInt32 auto generated constructor
 func NewColumnInt32(name string, values []int32) *ColumnInt32 {
 	return &ColumnInt32 {
@@ -418,11 +697,34 @@ func NewColumnInt32(name string, values []int32) *ColumnInt32 {
 	}
 }
 
+// NewNullableColumnInt32 auto generated constructor
+func NewNullableColumnInt32(name string, values []int32, validValues []bool) *ColumnInt32 {
+	return &ColumnInt32 {
+		name: name,
+		values: values,
+		nullable:    true,
+		validValues: validValues,
+	}
+}
+
+// NewAllNullColumnInt32 auto generated constructor
+func NewAllNullColumnInt32(name string, rowSize int) *ColumnInt32 {
+	return &ColumnInt32 {
+		name: name,
+		values: make([]int32,rowSize),
+		nullable:    true,
+		validValues: make([]bool,rowSize),
+	}
+}
+
+
 // ColumnInt64 generated columns type for Int64
 type ColumnInt64 struct {
 	ColumnBase
 	name   string
 	values []int64
+	validValues []bool
+	nullable    bool
 }
 
 // Name returns column name
@@ -440,6 +742,28 @@ func (c *ColumnInt64) Len() int {
 	return len(c.values)
 }
 
+// Nullable returns column nullable
+func (c *ColumnInt64) Nullable() bool {
+	return c.nullable
+}
+
+// Get returns value at index as interface{}.
+func (c *ColumnInt64) Get(idx int) (interface{}, error) {
+	var r int64 // use default value
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return nil, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
+	if idx < 0 || idx >= c.Len() {
+		return r, errors.New("index out of range")
+	}
+	return c.values[idx], nil
+}
+
 func (c *ColumnInt64) Slice(start, end int) Column {
 	l := c.Len()
 	if start > l {
@@ -448,20 +772,17 @@ func (c *ColumnInt64) Slice(start, end int) Column {
 	if end == -1 || end > l {
 		end = l
 	}
+	sliceValidValues := make([]bool, 0)
+	if c.nullable {
+		sliceValidValues = c.validValues[start:end]
+	}
 	return &ColumnInt64{
 		ColumnBase: c.ColumnBase,
-		name: c.name,
-		values: c.values[start: end],
-	}
-}
-
-// Get returns value at index as interface{}.
-func (c *ColumnInt64) Get(idx int) (interface{}, error) {
-	var r int64 // use default value
-	if idx < 0 || idx >= c.Len() {
-		return r, errors.New("index out of range")
+		name:       c.name,
+		values:     c.values[start:end],
+		validValues: sliceValidValues,
+		nullable:    c.nullable,
 	}
-	return c.values[idx], nil
 }
 
 // FieldData return column data mapped to schema.FieldData
@@ -469,11 +790,21 @@ func (c *ColumnInt64) FieldData() *schema.FieldData {
 	fd := &schema.FieldData{
 		Type: schema.DataType_Int64,
 		FieldName: c.name,
+		ValidData: c.validValues,
 	}
 	data := make([]int64, 0, c.Len())
-	for i := 0; i < c.Len(); i++ {
-		data = append(data, int64(c.values[i]))
-	}
+	if c.nullable {
+		for i, v := range c.validValues {
+			if v {
+				data = append(data, c.values[i])
+			}
+		}
+	} else {
+		for i := 0; i < c.Len(); i++ {
+			data = append(data, c.values[i])
+		}
+	}
+	
 	fd.Field = &schema.FieldData_Scalars{
 		Scalars: &schema.ScalarField{
 			Data: &schema.ScalarField_LongData{
@@ -490,6 +821,14 @@ func (c *ColumnInt64) FieldData() *schema.FieldData {
 // error occurs when index out of range
 func (c *ColumnInt64) ValueByIdx(idx int) (int64, error) {
 	var r int64 // use default value
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return r, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return r, nil
+		}
+	}
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
@@ -498,11 +837,21 @@ func (c *ColumnInt64) ValueByIdx(idx int) (int64, error) {
 
 // AppendValue append value into column
 func(c *ColumnInt64) AppendValue(i interface{}) error {
+	var v int64
+	if i == nil && c.nullable {
+		c.values = append(c.values, v)
+		c.validValues = append(c.validValues, false)
+		return nil
+	}
+
 	v, ok := i.(int64)
 	if !ok {
 		return fmt.Errorf("invalid type, expected int64, got %T", i)
 	}
 	c.values = append(c.values, v)
+	if c.nullable {
+		c.validValues = append(c.validValues, true)
+	}
 
 	return nil
 }
@@ -512,6 +861,11 @@ func (c *ColumnInt64) Data() []int64 {
 	return c.values
 }
 
+// ValidData returns column validValues
+func (c *ColumnInt64) ValidData() []bool {
+	return c.validValues
+}
+
 // NewColumnInt64 auto generated constructor
 func NewColumnInt64(name string, values []int64) *ColumnInt64 {
 	return &ColumnInt64 {
@@ -520,11 +874,34 @@ func NewColumnInt64(name string, values []int64) *ColumnInt64 {
 	}
 }
 
+// NewNullableColumnInt64 auto generated constructor
+func NewNullableColumnInt64(name string, values []int64, validValues []bool) *ColumnInt64 {
+	return &ColumnInt64 {
+		name: name,
+		values: values,
+		nullable:    true,
+		validValues: validValues,
+	}
+}
+
+// NewAllNullColumnInt64 auto generated constructor
+func NewAllNullColumnInt64(name string, rowSize int) *ColumnInt64 {
+	return &ColumnInt64 {
+		name: name,
+		values: make([]int64,rowSize),
+		nullable:    true,
+		validValues: make([]bool,rowSize),
+	}
+}
+
+
 // ColumnFloat generated columns type for Float
 type ColumnFloat struct {
 	ColumnBase
 	name   string
 	values []float32
+	validValues []bool
+	nullable    bool
 }
 
 // Name returns column name
@@ -542,6 +919,28 @@ func (c *ColumnFloat) Len() int {
 	return len(c.values)
 }
 
+// Nullable returns column nullable
+func (c *ColumnFloat) Nullable() bool {
+	return c.nullable
+}
+
+// Get returns value at index as interface{}.
+func (c *ColumnFloat) Get(idx int) (interface{}, error) {
+	var r float32 // use default value
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return nil, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
+	if idx < 0 || idx >= c.Len() {
+		return r, errors.New("index out of range")
+	}
+	return c.values[idx], nil
+}
+
 func (c *ColumnFloat) Slice(start, end int) Column {
 	l := c.Len()
 	if start > l {
@@ -550,32 +949,39 @@ func (c *ColumnFloat) Slice(start, end int) Column {
 	if end == -1 || end > l {
 		end = l
 	}
+	sliceValidValues := make([]bool, 0)
+	if c.nullable {
+		sliceValidValues = c.validValues[start:end]
+	}
 	return &ColumnFloat{
 		ColumnBase: c.ColumnBase,
 		name:       c.name,
 		values:     c.values[start:end],
+		validValues: sliceValidValues,
+		nullable:    c.nullable,
 	}
 }
 
-// Get returns value at index as interface{}.
-func (c *ColumnFloat) Get(idx int) (interface{}, error) {
-	var r float32 // use default value
-	if idx < 0 || idx >= c.Len() {
-		return r, errors.New("index out of range")
-	}
-	return c.values[idx], nil
-}
-
 // FieldData return column data mapped to schema.FieldData
 func (c *ColumnFloat) FieldData() *schema.FieldData {
 	fd := &schema.FieldData{
 		Type: schema.DataType_Float,
 		FieldName: c.name,
+		ValidData: c.validValues,
 	}
 	data := make([]float32, 0, c.Len())
-	for i := 0; i < c.Len(); i++ {
-		data = append(data, float32(c.values[i]))
-	}
+	if c.nullable {
+		for i, v := range c.validValues {
+			if v {
+				data = append(data, c.values[i])
+			}
+		}
+	} else {
+		for i := 0; i < c.Len(); i++ {
+			data = append(data, c.values[i])
+		}
+	}
+	
 	fd.Field = &schema.FieldData_Scalars{
 		Scalars: &schema.ScalarField{
 			Data: &schema.ScalarField_FloatData{
@@ -592,6 +998,14 @@ func (c *ColumnFloat) FieldData() *schema.FieldData {
 // error occurs when index out of range
 func (c *ColumnFloat) ValueByIdx(idx int) (float32, error) {
 	var r float32 // use default value
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return r, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return r, nil
+		}
+	}
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
@@ -600,11 +1014,21 @@ func (c *ColumnFloat) ValueByIdx(idx int) (float32, error) {
 
 // AppendValue append value into column
 func(c *ColumnFloat) AppendValue(i interface{}) error {
+	var v float32
+	if i == nil && c.nullable {
+		c.values = append(c.values, v)
+		c.validValues = append(c.validValues, false)
+		return nil
+	}
+
 	v, ok := i.(float32)
 	if !ok {
 		return fmt.Errorf("invalid type, expected float32, got %T", i)
 	}
 	c.values = append(c.values, v)
+	if c.nullable {
+		c.validValues = append(c.validValues, true)
+	}
 
 	return nil
 }
@@ -614,6 +1038,11 @@ func (c *ColumnFloat) Data() []float32 {
 	return c.values
 }
 
+// ValidData returns column validValues
+func (c *ColumnFloat) ValidData() []bool {
+	return c.validValues
+}
+
 // NewColumnFloat auto generated constructor
 func NewColumnFloat(name string, values []float32) *ColumnFloat {
 	return &ColumnFloat {
@@ -622,11 +1051,34 @@ func NewColumnFloat(name string, values []float32) *ColumnFloat {
 	}
 }
 
+// NewNullableColumnFloat auto generated constructor
+func NewNullableColumnFloat(name string, values []float32, validValues []bool) *ColumnFloat {
+	return &ColumnFloat {
+		name: name,
+		values: values,
+		nullable:    true,
+		validValues: validValues,
+	}
+}
+
+// NewAllNullColumnFloat auto generated constructor
+func NewAllNullColumnFloat(name string, rowSize int) *ColumnFloat {
+	return &ColumnFloat {
+		name: name,
+		values: make([]float32,rowSize),
+		nullable:    true,
+		validValues: make([]bool,rowSize),
+	}
+}
+
+
 // ColumnDouble generated columns type for Double
 type ColumnDouble struct {
 	ColumnBase
 	name   string
 	values []float64
+	validValues []bool
+	nullable    bool
 }
 
 // Name returns column name
@@ -644,6 +1096,28 @@ func (c *ColumnDouble) Len() int {
 	return len(c.values)
 }
 
+// Nullable returns column nullable
+func (c *ColumnDouble) Nullable() bool {
+	return c.nullable
+}
+
+// Get returns value at index as interface{}.
+func (c *ColumnDouble) Get(idx int) (interface{}, error) {
+	var r float64 // use default value
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return nil, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
+	if idx < 0 || idx >= c.Len() {
+		return r, errors.New("index out of range")
+	}
+	return c.values[idx], nil
+}
+
 func (c *ColumnDouble) Slice(start, end int) Column {
 	l := c.Len()
 	if start > l {
@@ -652,32 +1126,39 @@ func (c *ColumnDouble) Slice(start, end int) Column {
 	if end == -1 || end > l {
 		end = l
 	}
+	sliceValidValues := make([]bool, 0)
+	if c.nullable {
+		sliceValidValues = c.validValues[start:end]
+	}
 	return &ColumnDouble{
 		ColumnBase: c.ColumnBase,
 		name:       c.name,
 		values:     c.values[start:end],
+		validValues: sliceValidValues,
+		nullable:    c.nullable,
 	}
 }
 
-// Get returns value at index as interface{}.
-func (c *ColumnDouble) Get(idx int) (interface{}, error) {
-	var r float64 // use default value
-	if idx < 0 || idx >= c.Len() {
-		return r, errors.New("index out of range")
-	}
-	return c.values[idx], nil
-}
-
 // FieldData return column data mapped to schema.FieldData
 func (c *ColumnDouble) FieldData() *schema.FieldData {
 	fd := &schema.FieldData{
 		Type: schema.DataType_Double,
 		FieldName: c.name,
+		ValidData: c.validValues,
 	}
 	data := make([]float64, 0, c.Len())
-	for i := 0; i < c.Len(); i++ {
-		data = append(data, float64(c.values[i]))
-	}
+	if c.nullable {
+		for i, v := range c.validValues {
+			if v {
+				data = append(data, c.values[i])
+			}
+		}
+	} else {
+		for i := 0; i < c.Len(); i++ {
+			data = append(data, c.values[i])
+		}
+	}
+	
 	fd.Field = &schema.FieldData_Scalars{
 		Scalars: &schema.ScalarField{
 			Data: &schema.ScalarField_DoubleData{
@@ -694,6 +1175,14 @@ func (c *ColumnDouble) FieldData() *schema.FieldData {
 // error occurs when index out of range
 func (c *ColumnDouble) ValueByIdx(idx int) (float64, error) {
 	var r float64 // use default value
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return r, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return r, nil
+		}
+	}
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
@@ -702,11 +1191,21 @@ func (c *ColumnDouble) ValueByIdx(idx int) (float64, error) {
 
 // AppendValue append value into column
 func(c *ColumnDouble) AppendValue(i interface{}) error {
+	var v float64
+	if i == nil && c.nullable {
+		c.values = append(c.values, v)
+		c.validValues = append(c.validValues, false)
+		return nil
+	}
+
 	v, ok := i.(float64)
 	if !ok {
 		return fmt.Errorf("invalid type, expected float64, got %T", i)
 	}
 	c.values = append(c.values, v)
+	if c.nullable {
+		c.validValues = append(c.validValues, true)
+	}
 
 	return nil
 }
@@ -716,6 +1215,11 @@ func (c *ColumnDouble) Data() []float64 {
 	return c.values
 }
 
+// ValidData returns column validValues
+func (c *ColumnDouble) ValidData() []bool {
+	return c.validValues
+}
+
 // NewColumnDouble auto generated constructor
 func NewColumnDouble(name string, values []float64) *ColumnDouble {
 	return &ColumnDouble {
@@ -724,11 +1228,34 @@ func NewColumnDouble(name string, values []float64) *ColumnDouble {
 	}
 }
 
+// NewNullableColumnDouble auto generated constructor
+func NewNullableColumnDouble(name string, values []float64, validValues []bool) *ColumnDouble {
+	return &ColumnDouble {
+		name: name,
+		values: values,
+		nullable:    true,
+		validValues: validValues,
+	}
+}
+
+// NewAllNullColumnDouble auto generated constructor
+func NewAllNullColumnDouble(name string, rowSize int) *ColumnDouble {
+	return &ColumnDouble {
+		name: name,
+		values: make([]float64,rowSize),
+		nullable:    true,
+		validValues: make([]bool,rowSize),
+	}
+}
+
+
 // ColumnString generated columns type for String
 type ColumnString struct {
 	ColumnBase
 	name   string
 	values []string
+	validValues []bool
+	nullable    bool
 }
 
 // Name returns column name
@@ -746,6 +1273,28 @@ func (c *ColumnString) Len() int {
 	return len(c.values)
 }
 
+// Nullable returns column nullable
+func (c *ColumnString) Nullable() bool {
+	return c.nullable
+}
+
+// Get returns value at index as interface{}.
+func (c *ColumnString) Get(idx int) (interface{}, error) {
+	var r string // use default value
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return nil, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
+	if idx < 0 || idx >= c.Len() {
+		return r, errors.New("index out of range")
+	}
+	return c.values[idx], nil
+}
+
 func (c *ColumnString) Slice(start, end int) Column {
 	l := c.Len()
 	if start > l {
@@ -754,32 +1303,39 @@ func (c *ColumnString) Slice(start, end int) Column {
 	if end == -1 || end > l {
 		end = l
 	}
+	sliceValidValues := make([]bool, 0)
+	if c.nullable {
+		sliceValidValues = c.validValues[start:end]
+	}
 	return &ColumnString{
 		ColumnBase: c.ColumnBase,
 		name:       c.name,
 		values:     c.values[start:end],
+		validValues: sliceValidValues,
+		nullable:    c.nullable,
 	}
 }
 
-// Get returns value at index as interface{}.
-func (c *ColumnString) Get(idx int) (interface{}, error) {
-	var r string // use default value
-	if idx < 0 || idx >= c.Len() {
-		return r, errors.New("index out of range")
-	}
-	return c.values[idx], nil
-}
-
 // FieldData return column data mapped to schema.FieldData
 func (c *ColumnString) FieldData() *schema.FieldData {
 	fd := &schema.FieldData{
 		Type: schema.DataType_String,
 		FieldName: c.name,
+		ValidData: c.validValues,
 	}
 	data := make([]string, 0, c.Len())
-	for i := 0; i < c.Len(); i++ {
-		data = append(data, string(c.values[i]))
-	}
+	if c.nullable {
+		for i, v := range c.validValues {
+			if v {
+				data = append(data, c.values[i])
+			}
+		}
+	} else {
+		for i := 0; i < c.Len(); i++ {
+			data = append(data, c.values[i])
+		}
+	}
+	
 	fd.Field = &schema.FieldData_Scalars{
 		Scalars: &schema.ScalarField{
 			Data: &schema.ScalarField_StringData{
@@ -796,6 +1352,14 @@ func (c *ColumnString) FieldData() *schema.FieldData {
 // error occurs when index out of range
 func (c *ColumnString) ValueByIdx(idx int) (string, error) {
 	var r string // use default value
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return r, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return r, nil
+		}
+	}
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
@@ -804,11 +1368,21 @@ func (c *ColumnString) ValueByIdx(idx int) (string, error) {
 
 // AppendValue append value into column
 func(c *ColumnString) AppendValue(i interface{}) error {
+	var v string
+	if i == nil && c.nullable {
+		c.values = append(c.values, v)
+		c.validValues = append(c.validValues, false)
+		return nil
+	}
+
 	v, ok := i.(string)
 	if !ok {
 		return fmt.Errorf("invalid type, expected string, got %T", i)
 	}
 	c.values = append(c.values, v)
+	if c.nullable {
+		c.validValues = append(c.validValues, true)
+	}
 
 	return nil
 }
@@ -818,6 +1392,11 @@ func (c *ColumnString) Data() []string {
 	return c.values
 }
 
+// ValidData returns column validValues
+func (c *ColumnString) ValidData() []bool {
+	return c.validValues
+}
+
 // NewColumnString auto generated constructor
 func NewColumnString(name string, values []string) *ColumnString {
 	return &ColumnString {
@@ -826,3 +1405,24 @@ func NewColumnString(name string, values []string) *ColumnString {
 	}
 }
 
+// NewNullableColumnString auto generated constructor
+func NewNullableColumnString(name string, values []string, validValues []bool) *ColumnString {
+	return &ColumnString {
+		name: name,
+		values: values,
+		nullable:    true,
+		validValues: validValues,
+	}
+}
+
+// NewAllNullColumnString auto generated constructor
+func NewAllNullColumnString(name string, rowSize int) *ColumnString {
+	return &ColumnString {
+		name: name,
+		values: make([]string,rowSize),
+		nullable:    true,
+		validValues: make([]bool,rowSize),
+	}
+}
+
+
diff --git a/entity/columns_sparse.go b/entity/columns_sparse.go
index 86693f0..54bdb68 100644
--- a/entity/columns_sparse.go
+++ b/entity/columns_sparse.go
@@ -143,6 +143,10 @@ func (c *ColumnSparseFloatVector) Len() int {
 	return len(c.vectors)
 }
 
+func (c *ColumnSparseFloatVector) Nullable() bool {
+	return false
+}
+
 func (c *ColumnSparseFloatVector) Slice(start, end int) Column {
 	l := c.Len()
 	if start > l {
diff --git a/entity/columns_varchar.go b/entity/columns_varchar.go
index f86b5d6..3930b44 100644
--- a/entity/columns_varchar.go
+++ b/entity/columns_varchar.go
@@ -10,8 +10,10 @@ import (
 // ColumnVarChar generated columns type for VarChar
 type ColumnVarChar struct {
 	ColumnBase
-	name   string
-	values []string
+	name        string
+	values      []string
+	validValues []bool
+	nullable    bool
 }
 
 // Name returns column name
@@ -29,16 +31,37 @@ func (c *ColumnVarChar) Len() int {
 	return len(c.values)
 }
 
+// Nullable returns column nullable
+func (c *ColumnVarChar) Nullable() bool {
+	return c.nullable
+}
+
 // Get returns value at index as interface{}.
 func (c *ColumnVarChar) Get(idx int) (interface{}, error) {
 	if idx < 0 || idx > c.Len() {
 		return "", errors.New("index out of range")
 	}
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return nil, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
 	return c.values[idx], nil
 }
 
 // GetAsString returns value at idx.
 func (c *ColumnVarChar) GetAsString(idx int) (string, error) {
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return "", errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return "", nil
+		}
+	}
 	if idx < 0 || idx > c.Len() {
 		return "", errors.New("index out of range")
 	}
@@ -53,10 +76,16 @@ func (c *ColumnVarChar) Slice(start, end int) Column {
 	if end == -1 || end > l {
 		end = l
 	}
+	sliceValidValues := make([]bool, 0, end-start)
+	if c.nullable {
+		sliceValidValues = c.validValues[start:end]
+	}
 	return &ColumnVarChar{
-		ColumnBase: c.ColumnBase,
-		name:       c.name,
-		values:     c.values[start:end],
+		ColumnBase:  c.ColumnBase,
+		name:        c.name,
+		values:      c.values[start:end],
+		validValues: sliceValidValues,
+		nullable:    c.nullable,
 	}
 }
 
@@ -65,11 +94,21 @@ func (c *ColumnVarChar) FieldData() *schema.FieldData {
 	fd := &schema.FieldData{
 		Type:      schema.DataType_VarChar,
 		FieldName: c.name,
+		ValidData: c.validValues,
 	}
 	data := make([]string, 0, c.Len())
-	for i := 0; i < c.Len(); i++ {
-		data = append(data, string(c.values[i]))
+	if c.nullable {
+		for i, v := range c.validValues {
+			if v {
+				data = append(data, string(c.values[i]))
+			}
+		}
+	} else {
+		for i := 0; i < c.Len(); i++ {
+			data = append(data, string(c.values[i]))
+		}
 	}
+
 	fd.Field = &schema.FieldData_Scalars{
 		Scalars: &schema.ScalarField{
 			Data: &schema.ScalarField_StringData{
@@ -89,6 +128,14 @@ func (c *ColumnVarChar) ValueByIdx(idx int) (string, error) {
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return r, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return r, nil
+		}
+	}
 	return c.values[idx], nil
 }
 
@@ -115,3 +162,23 @@ func NewColumnVarChar(name string, values []string) *ColumnVarChar {
 		values: values,
 	}
 }
+
+// NewColumnVarChar auto generated constructor
+func NewNullableColumnVarChar(name string, values []string, validValues []bool) *ColumnVarChar {
+	return &ColumnVarChar{
+		name:        name,
+		values:      values,
+		validValues: validValues,
+		nullable:    true,
+	}
+}
+
+// NewAllNullColumnVarChar auto generated constructor
+func NewAllNullColumnVarChar(name string, rowSize int) *ColumnVarChar {
+	return &ColumnVarChar{
+		name:        name,
+		values:      make([]string, rowSize),
+		nullable:    true,
+		validValues: make([]bool, rowSize),
+	}
+}
diff --git a/entity/columns_vector_gen.go b/entity/columns_vector_gen.go
index f690d36..63ac32c 100755
--- a/entity/columns_vector_gen.go
+++ b/entity/columns_vector_gen.go
@@ -34,6 +34,10 @@ func (c * ColumnBinaryVector) Len() int {
 	return len(c.values)
 }
 
+func (c * ColumnBinaryVector) Nullable() bool {
+	return false
+}
+
 func (c *ColumnBinaryVector) Slice(start, end int) Column {
 	l := c.Len()
 	if start > l {
@@ -140,6 +144,10 @@ func (c * ColumnFloatVector) Len() int {
 	return len(c.values)
 }
 
+func (c * ColumnFloatVector) Nullable() bool {
+	return false
+}
+
 // Dim returns vector dimension
 func (c *ColumnFloatVector) Dim() int {
 	return c.dim
@@ -248,6 +256,10 @@ func (c * ColumnFloat16Vector) Len() int {
 	return len(c.values)
 }
 
+func (c * ColumnFloat16Vector) Nullable() bool {
+	return false
+}
+
 func (c *ColumnFloat16Vector) Slice(start, end int) Column {
 	l := c.Len()
 	if start > l {
@@ -354,6 +366,10 @@ func (c * ColumnBFloat16Vector) Len() int {
 	return len(c.values)
 }
 
+func (c * ColumnBFloat16Vector) Nullable() bool {
+	return false
+}
+
 func (c *ColumnBFloat16Vector) Slice(start, end int) Column {
 	l := c.Len()
 	if start > l {
diff --git a/entity/gen/gen.go b/entity/gen/gen.go
index b7af896..7ec1872 100644
--- a/entity/gen/gen.go
+++ b/entity/gen/gen.go
@@ -40,6 +40,8 @@ type Column{{.TypeName}} struct {
 	ColumnBase
 	name   string
 	values []{{.TypeDef}}
+	validValues []bool
+	nullable    bool
 }
 
 // Name returns column name
@@ -57,25 +59,69 @@ func (c *Column{{.TypeName}}) Len() int {
 	return len(c.values)
 }
 
+// Nullable returns column nullable
+func (c *Column{{.TypeName}}) Nullable() bool {
+	return c.nullable
+}
+
 // Get returns value at index as interface{}.
 func (c *Column{{.TypeName}}) Get(idx int) (interface{}, error) {
 	var r {{.TypeDef}} // use default value
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return nil, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
 	return c.values[idx], nil
 }
 
+func (c *Column{{.TypeName}}) Slice(start, end int) Column {
+	l := c.Len()
+	if start > l {
+		start = l
+	}
+	if end == -1 || end > l {
+		end = l
+	}
+	sliceValidValues := make([]bool, 0)
+	if c.nullable {
+		sliceValidValues = c.validValues[start:end]
+	}
+	return &Column{{.TypeName}}{
+		ColumnBase: c.ColumnBase,
+		name:       c.name,
+		values:     c.values[start:end],
+		validValues: sliceValidValues,
+		nullable:    c.nullable,
+	}
+}
+
 // FieldData return column data mapped to schema.FieldData
 func (c *Column{{.TypeName}}) FieldData() *schema.FieldData {
 	fd := &schema.FieldData{
 		Type: schema.DataType_{{.TypeName}},
 		FieldName: c.name,
+		ValidData: c.validValues,
 	}
 	data := make([]{{.PbType}}, 0, c.Len())
-	for i := 0; i < c.Len(); i++ {
-		data = append(data, {{.PbType}}(c.values[i]))
+	if c.nullable {
+		for i, v := range c.validValues {
+			if v {
+				data = append(data, c.values[i])
+			}
+		}
+	} else {
+		for i := 0; i < c.Len(); i++ {
+			data = append(data, c.values[i])
+		}
 	}
+	
 	fd.Field = &schema.FieldData_Scalars{
 		Scalars: &schema.ScalarField{
 			Data: &schema.ScalarField_{{.PbName}}Data{
@@ -92,6 +138,14 @@ func (c *Column{{.TypeName}}) FieldData() *schema.FieldData {
 // error occurs when index out of range
 func (c *Column{{.TypeName}}) ValueByIdx(idx int) ({{.TypeDef}}, error) {
 	var r {{.TypeDef}} // use default value
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return r, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return r, nil
+		}
+	}
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
@@ -100,11 +154,21 @@ func (c *Column{{.TypeName}}) ValueByIdx(idx int) ({{.TypeDef}}, error) {
 
 // AppendValue append value into column
 func(c *Column{{.TypeName}}) AppendValue(i interface{}) error {
+	var v {{.TypeDef}}
+	if i == nil && c.nullable {
+		c.values = append(c.values, v)
+		c.validValues = append(c.validValues, false)
+		return nil
+	}
+
 	v, ok := i.({{.TypeDef}})
 	if !ok {
 		return fmt.Errorf("invalid type, expected {{.TypeDef}}, got %T", i)
 	}
 	c.values = append(c.values, v)
+	if c.nullable {
+		c.validValues = append(c.validValues, true)
+	}
 
 	return nil
 }
@@ -114,6 +178,11 @@ func (c *Column{{.TypeName}}) Data() []{{.TypeDef}} {
 	return c.values
 }
 
+// ValidData returns column validValues
+func (c *Column{{.TypeName}}) ValidData() []bool {
+	return c.validValues
+}
+
 // NewColumn{{.TypeName}} auto generated constructor
 func NewColumn{{.TypeName}}(name string, values []{{.TypeDef}}) *Column{{.TypeName}} {
 	return &Column{{.TypeName}} {
@@ -121,6 +190,27 @@ func NewColumn{{.TypeName}}(name string, values []{{.TypeDef}}) *Column{{.TypeNa
 		values: values,
 	}
 }
+
+// NewNullableColumn{{.TypeName}} auto generated constructor
+func NewNullableColumn{{.TypeName}}(name string, values []{{.TypeDef}}, validValues []bool) *Column{{.TypeName}} {
+	return &Column{{.TypeName}} {
+		name: name,
+		values: values,
+		nullable:    true,
+		validValues: validValues,
+	}
+}
+
+// NewAllNullColumn{{.TypeName}} auto generated constructor
+func NewAllNullColumn{{.TypeName}}(name string, rowSize int) *Column{{.TypeName}} {
+	return &Column{{.TypeName}} {
+		name: name,
+		values: make([]{{.TypeDef}},rowSize),
+		nullable:    true,
+		validValues: make([]bool,rowSize),
+	}
+}
+
 {{end}}{{end}}
 `))
 var vectorColumnTemplate = template.Must(template.New("").Parse(`// Code generated by go generate; DO NOT EDIT
@@ -159,6 +249,10 @@ func (c * Column{{.TypeName}}) Len() int {
 	return len(c.values)
 }
 
+func (c * Column{{.TypeName}}) Nullable() bool {
+	return false
+}
+
 // Dim returns vector dimension
 func (c *Column{{.TypeName}}) Dim() int {
 	return c.dim
@@ -352,6 +446,26 @@ func TestFieldData{{.TypeName}}Column(t *testing.T) {
 		assert.Equal(t, len, column.Len())
 		assert.Equal(t, FieldType{{.TypeName}}, column.Type())
 	})
+
+	t.Run("get null data", func(t *testing.T) {
+		fd.Field = &schema.FieldData_Scalars{
+			Scalars: &schema.ScalarField{
+				Data: &schema.ScalarField_{{.PbName}}Data{
+					{{.PbName}}Data: &schema.{{.PbName}}Array{
+						Data: make([]{{.PbType}}, len),
+					},
+				},
+			},
+		}
+		fd.ValidData = make([]bool, len)
+		column, err := FieldDataColumn(fd, 0, -1)
+		assert.Nil(t, err)
+		assert.NotNil(t, column)
+		
+		assert.Equal(t, name, column.Name())
+		assert.Equal(t, len, column.Len())
+		assert.Equal(t, FieldType{{.TypeName}}, column.Type())
+	})
 }
 {{end}}{{end}}
 `))
diff --git a/entity/genarray/gen_array.go b/entity/genarray/gen_array.go
index 63c951b..6e36020 100644
--- a/entity/genarray/gen_array.go
+++ b/entity/genarray/gen_array.go
@@ -26,6 +26,8 @@ type Column{{.TypeName}}Array struct {
 	ColumnBase
 	name   string
 	values [][]{{.TypeDef}}
+	validValues []bool
+	nullable    bool
 }
 
 // Name returns column name
@@ -43,12 +45,47 @@ func (c *Column{{.TypeName}}Array) Len() int {
 	return len(c.values)
 }
 
+// Nullable returns column values nullable
+func (c *Column{{.TypeName}}Array) Nullable() bool {
+	return c.nullable
+}
+
+// Slice returns column slice
+func (c *Column{{.TypeName}}Array) Slice(start, end int) Column {
+	l := c.Len()
+	if start > l {
+		start = l
+	}
+	if end == -1 || end > l {
+		end = l
+	}
+	sliceValidValues := make([]bool, 0)
+	if c.nullable {
+		sliceValidValues = c.validValues[start:end]
+	}
+	return &Column{{.TypeName}}Array{
+		ColumnBase:  c.ColumnBase,
+		name:        c.name,
+		values:      c.values[start:end],
+		validValues: sliceValidValues,
+		nullable:    c.nullable,
+	}
+}
+
 // Get returns value at index as interface{}.
 func (c *Column{{.TypeName}}Array) Get(idx int) (interface{}, error) {
 	var r []{{.TypeDef}} // use default value
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return nil, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
 	return c.values[idx], nil
 }
 
@@ -57,22 +94,36 @@ func (c *Column{{.TypeName}}Array) FieldData() *schemapb.FieldData {
 	fd := &schemapb.FieldData{
 		Type:      schemapb.DataType_Array,
 		FieldName: c.name,
+		ValidData: c.validValues,
 	}
 
-	data := make([]*schemapb.ScalarField, 0, c.Len())
-	for _, arr := range c.values {
+	convertTo := func(arr []{{.PbType}}) *schemapb.ScalarField {
 		converted := make([]{{.PbType}}, 0, c.Len())
 		for i := 0; i < len(arr); i++ {
 			converted = append(converted, {{.PbType}}(arr[i]))
 		}
-		data = append(data, &schemapb.ScalarField{
+		return &schemapb.ScalarField{
 			Data: &schemapb.ScalarField_{{.PbName}}Data{
 				{{.PbName}}Data: &schemapb.{{.PbName}}Array{
 					Data: converted,
 				},
 			},
-		})
+		}
 	}
+
+	data := make([]*schemapb.ScalarField, 0, c.Len())
+	if c.nullable {
+		for i, v := range c.validValues {
+			if v {
+				data = append(data, convertTo(c.values[i]))
+			}
+		}
+	} else {
+		for _, arr := range c.values {
+			data = append(data, convertTo(arr))
+		}
+	}
+
 	fd.Field = &schemapb.FieldData_Scalars{
 		Scalars: &schemapb.ScalarField{
 			Data: &schemapb.ScalarField_ArrayData{
@@ -93,16 +144,33 @@ func (c *Column{{.TypeName}}Array) ValueByIdx(idx int) ([]{{.TypeDef}}, error) {
 	if idx < 0 || idx >= c.Len() {
 		return r, errors.New("index out of range")
 	}
+	if c.nullable {
+		if idx < 0 || idx >= len(c.validValues) {
+			return r, errors.New("index out of validValues range")
+		}
+		if !c.validValues[idx] {
+			return nil, nil
+		}
+	}
 	return c.values[idx], nil
 }
 
 // AppendValue append value into column
 func(c *Column{{.TypeName}}Array) AppendValue(i interface{}) error {
+	var v []{{.TypeDef}}
+	if i == nil && c.nullable {
+		c.values = append(c.values, v)
+		c.validValues = append(c.validValues, false)
+		return nil
+	}
 	v, ok := i.([]{{.TypeDef}})
 	if !ok {
 		return fmt.Errorf("invalid type, expected []{{.TypeDef}}, got %T", i)
 	}
 	c.values = append(c.values, v)
+	if c.nullable {
+		c.validValues = append(c.validValues, true)
+	}
 
 	return nil
 }
@@ -112,6 +180,11 @@ func (c *Column{{.TypeName}}Array) Data() [][]{{.TypeDef}} {
 	return c.values
 }
 
+// ValidData returns column ValidData
+func (c *Column{{.TypeName}}Array) ValidData() []bool {
+	return c.validValues
+}
+
 // NewColumn{{.TypeName}} auto generated constructor
 func NewColumn{{.TypeName}}Array(name string, values [][]{{.TypeDef}}) *Column{{.TypeName}}Array {
 	return &Column{{.TypeName}}Array {
@@ -119,6 +192,26 @@ func NewColumn{{.TypeName}}Array(name string, values [][]{{.TypeDef}}) *Column{{
 		values: values,
 	}
 }
+
+// NewColumn{{.TypeName}} auto generated constructor
+func NewNullableColumn{{.TypeName}}Array(name string, values [][]{{.TypeDef}}, validValues []bool) *Column{{.TypeName}}Array {
+	return &Column{{.TypeName}}Array {
+		name: name,
+		values: values,
+		nullable:    true,
+		validValues: validValues,
+	}
+}
+
+// NewAllNullColumn{{.TypeName}} auto generated constructor
+func NewAllNullColumn{{.TypeName}}Array(name string, rowSize int) *Column{{.TypeName}}Array {
+	return &Column{{.TypeName}}Array {
+		name: name,
+		values: make([][]{{.TypeDef}},rowSize),
+		nullable:    true,
+		validValues: make([]bool,rowSize),
+	}
+}
 {{end}}{{end}}
 `))
 
diff --git a/entity/index.go b/entity/index.go
index eafdade..bf5717b 100644
--- a/entity/index.go
+++ b/entity/index.go
@@ -89,6 +89,7 @@ type SearchParam interface {
 	Params() map[string]interface{}
 	AddRadius(radius float64)
 	AddRangeFilter(rangeFilter float64)
+	AddPageRetainOrder(pageRetainOrder bool)
 }
 
 type baseSearchParams struct {
@@ -111,6 +112,10 @@ func (sp *baseSearchParams) AddRangeFilter(rangeFilter float64) {
 	sp.params["range_filter"] = rangeFilter
 }
 
+func (sp *baseSearchParams) AddPageRetainOrder(pageRetainOrder bool) {
+	sp.params["page_retain_order"] = pageRetainOrder
+}
+
 func newBaseSearchParams() baseSearchParams {
 	return baseSearchParams{
 		params: make(map[string]interface{}),
diff --git a/entity/rows.go b/entity/rows.go
index dc30af7..8b90024 100644
--- a/entity/rows.go
+++ b/entity/rows.go
@@ -32,7 +32,7 @@ const (
 	// MilvusTagSep struct tag const for attribute separator
 	MilvusTagSep = `;`
 
-	//MilvusTagName struct tag const for field name
+	// MilvusTagName struct tag const for field name
 	MilvusTagName = `NAME`
 
 	// VectorDimTag struct tag const for vector dimension
@@ -171,7 +171,7 @@ func ParseSchemaAny(r interface{}) (*Schema, error) {
 			switch elemType.Kind() {
 			case reflect.Uint8:
 				field.DataType = FieldTypeBinaryVector
-				//TODO maybe override by tag settings, when dim is not multiplier of 8
+				// TODO maybe override by tag settings, when dim is not multiplier of 8
 				field.TypeParams = map[string]string{
 					TypeParamDim: strconv.FormatInt(int64(arrayLen*8), 10),
 				}
@@ -300,32 +300,74 @@ func AnyToColumns(rows []interface{}, schemas ...*Schema) ([]Column, error) {
 		}
 		switch field.DataType {
 		case FieldTypeBool:
+			var col *ColumnBool
 			data := make([]bool, 0, rowsLen)
-			col := NewColumnBool(field.Name, data)
+			if field.Nullable {
+				validData := make([]bool, 0, rowsLen)
+				col = NewNullableColumnBool(field.Name, data, validData)
+			} else {
+				col = NewColumnBool(field.Name, data)
+			}
 			nameColumns[field.Name] = col
 		case FieldTypeInt8:
+			var col *ColumnInt8
 			data := make([]int8, 0, rowsLen)
-			col := NewColumnInt8(field.Name, data)
+			if field.Nullable {
+				validData := make([]bool, 0, rowsLen)
+				col = NewNullableColumnInt8(field.Name, data, validData)
+			} else {
+				col = NewColumnInt8(field.Name, data)
+			}
 			nameColumns[field.Name] = col
 		case FieldTypeInt16:
+			var col *ColumnInt16
 			data := make([]int16, 0, rowsLen)
-			col := NewColumnInt16(field.Name, data)
+			if field.Nullable {
+				validData := make([]bool, 0, rowsLen)
+				col = NewNullableColumnInt16(field.Name, data, validData)
+			} else {
+				col = NewColumnInt16(field.Name, data)
+			}
 			nameColumns[field.Name] = col
 		case FieldTypeInt32:
+			var col *ColumnInt32
 			data := make([]int32, 0, rowsLen)
-			col := NewColumnInt32(field.Name, data)
+			if field.Nullable {
+				validData := make([]bool, 0, rowsLen)
+				col = NewNullableColumnInt32(field.Name, data, validData)
+			} else {
+				col = NewColumnInt32(field.Name, data)
+			}
 			nameColumns[field.Name] = col
 		case FieldTypeInt64:
+			var col *ColumnInt64
 			data := make([]int64, 0, rowsLen)
-			col := NewColumnInt64(field.Name, data)
+			if field.Nullable {
+				validData := make([]bool, 0, rowsLen)
+				col = NewNullableColumnInt64(field.Name, data, validData)
+			} else {
+				col = NewColumnInt64(field.Name, data)
+			}
 			nameColumns[field.Name] = col
 		case FieldTypeFloat:
+			var col *ColumnFloat
 			data := make([]float32, 0, rowsLen)
-			col := NewColumnFloat(field.Name, data)
+			if field.Nullable {
+				validData := make([]bool, 0, rowsLen)
+				col = NewNullableColumnFloat(field.Name, data, validData)
+			} else {
+				col = NewColumnFloat(field.Name, data)
+			}
 			nameColumns[field.Name] = col
 		case FieldTypeDouble:
+			var col *ColumnDouble
 			data := make([]float64, 0, rowsLen)
-			col := NewColumnDouble(field.Name, data)
+			if field.Nullable {
+				validData := make([]bool, 0, rowsLen)
+				col = NewNullableColumnDouble(field.Name, data, validData)
+			} else {
+				col = NewColumnDouble(field.Name, data)
+			}
 			nameColumns[field.Name] = col
 		case FieldTypeString, FieldTypeVarChar:
 			data := make([]string, 0, rowsLen)
@@ -463,27 +505,51 @@ func AnyToColumns(rows []interface{}, schemas ...*Schema) ([]Column, error) {
 func NewArrayColumn(f *Field) Column {
 	switch f.ElementType {
 	case FieldTypeBool:
+		if f.Nullable {
+			return NewNullableColumnBoolArray(f.Name, nil, nil)
+		}
 		return NewColumnBoolArray(f.Name, nil)
 
 	case FieldTypeInt8:
+		if f.Nullable {
+			return NewNullableColumnInt8Array(f.Name, nil, nil)
+		}
 		return NewColumnInt8Array(f.Name, nil)
 
 	case FieldTypeInt16:
+		if f.Nullable {
+			return NewNullableColumnInt16Array(f.Name, nil, nil)
+		}
 		return NewColumnInt16Array(f.Name, nil)
 
 	case FieldTypeInt32:
+		if f.Nullable {
+			return NewNullableColumnInt32Array(f.Name, nil, nil)
+		}
 		return NewColumnInt32Array(f.Name, nil)
 
 	case FieldTypeInt64:
+		if f.Nullable {
+			return NewNullableColumnInt64Array(f.Name, nil, nil)
+		}
 		return NewColumnInt64Array(f.Name, nil)
 
 	case FieldTypeFloat:
+		if f.Nullable {
+			return NewNullableColumnFloatArray(f.Name, nil, nil)
+		}
 		return NewColumnFloatArray(f.Name, nil)
 
 	case FieldTypeDouble:
+		if f.Nullable {
+			return NewNullableColumnDoubleArray(f.Name, nil, nil)
+		}
 		return NewColumnDoubleArray(f.Name, nil)
 
 	case FieldTypeVarChar:
+		if f.Nullable {
+			return NewNullableColumnVarCharArray(f.Name, nil, nil)
+		}
 		return NewColumnVarCharArray(f.Name, nil)
 
 	default:
@@ -526,6 +592,22 @@ func reflectValueCandi(v reflect.Value) (map[string]fieldCandi, error) {
 	case reflect.Struct:
 		for i := 0; i < v.NumField(); i++ {
 			ft := v.Type().Field(i)
+			// embedded struct
+			if ft.Anonymous && ft.Type.Kind() == reflect.Struct {
+				embedCandidate, err := reflectValueCandi(v.Field(i))
+				if err != nil {
+					return nil, err
+				}
+				for key, candi := range embedCandidate {
+					_, ok := result[key]
+					if ok {
+						return nil, fmt.Errorf("column has duplicated name: %s when parsing field: %s", key, ft.Name)
+					}
+					result[key] = candi
+				}
+				continue
+			}
+
 			name := ft.Name
 			tag, ok := ft.Tag.Lookup(MilvusTag)
 
diff --git a/entity/schema.go b/entity/schema.go
index 9bb4754..26dce15 100644
--- a/entity/schema.go
+++ b/entity/schema.go
@@ -153,6 +153,8 @@ type Field struct {
 	IsPartitionKey  bool
 	IsClusteringKey bool
 	ElementType     FieldType
+	DefaultValue    *schema.ValueField
+	Nullable        bool
 }
 
 // ProtoMessage generates corresponding FieldSchema
@@ -170,6 +172,8 @@ func (f *Field) ProtoMessage() *schema.FieldSchema {
 		IsPartitionKey:  f.IsPartitionKey,
 		IsClusteringKey: f.IsClusteringKey,
 		ElementType:     schema.DataType(f.ElementType),
+		DefaultValue:    f.DefaultValue,
+		Nullable:        f.Nullable,
 	}
 }
 
@@ -221,7 +225,11 @@ func (f *Field) WithIsClusteringKey(isClusteringKey bool) *Field {
 	return f
 }
 
-/*
+func (f *Field) WithNullable(nullable bool) *Field {
+	f.Nullable = nullable
+	return f
+}
+
 func (f *Field) WithDefaultValueBool(defaultValue bool) *Field {
 	f.DefaultValue = &schema.ValueField{
 		Data: &schema.ValueField_BoolData{
@@ -274,7 +282,7 @@ func (f *Field) WithDefaultValueString(defaultValue string) *Field {
 		},
 	}
 	return f
-}*/
+}
 
 func (f *Field) WithTypeParams(key string, value string) *Field {
 	if f.TypeParams == nil {
@@ -327,6 +335,8 @@ func (f *Field) ReadProto(p *schema.FieldSchema) *Field {
 	f.IsPartitionKey = p.GetIsPartitionKey()
 	f.IsClusteringKey = p.GetIsClusteringKey()
 	f.ElementType = FieldType(p.GetElementType())
+	f.DefaultValue = p.GetDefaultValue()
+	f.Nullable = p.GetNullable()
 
 	return f
 }
diff --git a/go.mod b/go.mod
index b739441..1536779 100644
--- a/go.mod
+++ b/go.mod
@@ -7,7 +7,7 @@ require (
 	github.com/go-faker/faker/v4 v4.1.0
 	github.com/golang/protobuf v1.5.2
 	github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
-	github.com/milvus-io/milvus-proto/go-api/v2 v2.4.10-0.20240819025435-512e3b98866a
+	github.com/milvus-io/milvus-proto/go-api/v2 v2.3.4-0.20240909041258-8f8ca67816cd
 	github.com/stretchr/testify v1.8.1
 	github.com/tidwall/gjson v1.14.4
 	github.com/x448/float16 v0.8.4
diff --git a/go.sum b/go.sum
index 575eb0f..260f795 100644
--- a/go.sum
+++ b/go.sum
@@ -157,6 +157,10 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k
 github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
 github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8=
 github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
+github.com/milvus-io/milvus-proto/go-api/v2 v2.3.4-0.20240407081710-6c95f3065923 h1:95AQHE3LbCrbegdFZ+lfVNuPYnRgQDVEXHJQkk+3jj8=
+github.com/milvus-io/milvus-proto/go-api/v2 v2.3.4-0.20240407081710-6c95f3065923/go.mod h1:1OIl0v5PQeNxIJhCvY+K55CBUOYDZevw9g9380u1Wek=
+github.com/milvus-io/milvus-proto/go-api/v2 v2.3.4-0.20240909041258-8f8ca67816cd h1:x0b0+foTe23sKcVFseR1DE8+BB08EH6ViiRHaz8PEik=
+github.com/milvus-io/milvus-proto/go-api/v2 v2.3.4-0.20240909041258-8f8ca67816cd/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs=
 github.com/milvus-io/milvus-proto/go-api/v2 v2.4.10-0.20240819025435-512e3b98866a h1:0B/8Fo66D8Aa23Il0yrQvg1KKz92tE/BJ5BvkUxxAAk=
 github.com/milvus-io/milvus-proto/go-api/v2 v2.4.10-0.20240819025435-512e3b98866a/go.mod h1:1OIl0v5PQeNxIJhCvY+K55CBUOYDZevw9g9380u1Wek=
 github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=


Test patch:
diff --git a/client/insert_test.go b/client/insert_test.go
index 693c7b0..c640514 100644
--- a/client/insert_test.go
+++ b/client/insert_test.go
@@ -260,19 +260,26 @@ func (s *InsertSuite) TestInsertSuccess() {
 	})
 
 	s.Run("missing_field_with_default_value", func() {
-		s.T().Skip("skip for default value test")
 		defer s.resetMock()
 		s.setupHasCollection(testCollectionName)
 		s.setupHasPartition(testCollectionName, "partition_1")
 
 		s.setupDescribeCollection(testCollectionName, entity.NewSchema().
 			WithField(entity.NewField().WithIsPrimaryKey(true).WithIsAutoID(true).WithName("ID").WithDataType(entity.FieldTypeInt64)).
-			WithField(entity.NewField().WithName("default_value").WithDataType(entity.FieldTypeInt64)).
+			WithField(entity.NewField().WithName("default_value").WithDataType(entity.FieldTypeInt64).WithDefaultValueLong(1)).
 			WithField(entity.NewField().WithName("vector").WithDataType(entity.FieldTypeFloatVector).WithTypeParams(entity.TypeParamDim, "128")),
 		)
 
 		s.mock.EXPECT().Insert(mock.Anything, mock.AnythingOfType("*milvuspb.InsertRequest")).
 			Run(func(ctx context.Context, req *milvuspb.InsertRequest) {
+				var data *schemapb.FieldData
+				for _, d := range req.GetFieldsData() {
+					if d.FieldName == "default_value" {
+						data = d
+					}
+				}
+				s.Equal([]bool{false}, data.ValidData)
+				s.Equal(0, len(data.GetScalars().GetLongData().Data))
 				s.Equal(2, len(req.GetFieldsData()))
 			}).Return(&milvuspb.MutationResult{
 			Status: &commonpb.Status{},
@@ -291,6 +298,118 @@ func (s *InsertSuite) TestInsertSuccess() {
 		s.NoError(err)
 		s.Equal(1, r.Len())
 	})
+
+	s.Run("missing_field_with_nullable", func() {
+		defer s.resetMock()
+		s.setupHasCollection(testCollectionName)
+		s.setupHasPartition(testCollectionName, "partition_1")
+
+		s.setupDescribeCollection(testCollectionName, entity.NewSchema().
+			WithField(entity.NewField().WithIsPrimaryKey(true).WithIsAutoID(true).WithName("ID").WithDataType(entity.FieldTypeInt64)).
+			WithField(entity.NewField().WithName("nullable_fid").WithDataType(entity.FieldTypeInt64).WithNullable(true)).
+			WithField(entity.NewField().WithName("vector").WithDataType(entity.FieldTypeFloatVector).WithTypeParams(entity.TypeParamDim, "128")),
+		)
+
+		s.mock.EXPECT().Insert(mock.Anything, mock.AnythingOfType("*milvuspb.InsertRequest")).
+			Run(func(ctx context.Context, req *milvuspb.InsertRequest) {
+				s.Equal(2, len(req.GetFieldsData()))
+			}).Return(&milvuspb.MutationResult{
+			Status: &commonpb.Status{},
+			IDs: &schemapb.IDs{
+				IdField: &schemapb.IDs_IntId{
+					IntId: &schemapb.LongArray{
+						Data: []int64{1},
+					},
+				},
+			},
+		}, nil)
+
+		r, err := c.Insert(ctx, testCollectionName, "partition_1",
+			entity.NewColumnFloatVector("vector", 128, generateFloatVector(1, 128)),
+		)
+		s.NoError(err)
+		s.Equal(1, r.Len())
+	})
+
+	s.Run("insert_with_nullable_column", func() {
+		defer s.resetMock()
+		s.setupHasCollection(testCollectionName)
+		s.setupHasPartition(testCollectionName, "partition_1")
+
+		s.setupDescribeCollection(testCollectionName, entity.NewSchema().
+			WithField(entity.NewField().WithIsPrimaryKey(true).WithIsAutoID(true).WithName("ID").WithDataType(entity.FieldTypeInt64)).
+			WithField(entity.NewField().WithName("nullable_fid").WithDataType(entity.FieldTypeInt64).WithNullable(true)).
+			WithField(entity.NewField().WithName("vector").WithDataType(entity.FieldTypeFloatVector).WithTypeParams(entity.TypeParamDim, "128")),
+		)
+
+		s.mock.EXPECT().Insert(mock.Anything, mock.AnythingOfType("*milvuspb.InsertRequest")).
+			Run(func(ctx context.Context, req *milvuspb.InsertRequest) {
+				var data *schemapb.FieldData
+				for _, d := range req.GetFieldsData() {
+					if d.FieldName == "nullable_fid" {
+						data = d
+					}
+				}
+				s.Equal([]bool{false, true}, data.ValidData)
+				s.Equal([]int64{1}, data.GetScalars().GetLongData().Data)
+				s.Equal(2, len(req.GetFieldsData()))
+			}).Return(&milvuspb.MutationResult{
+			Status: &commonpb.Status{},
+			IDs: &schemapb.IDs{
+				IdField: &schemapb.IDs_IntId{
+					IntId: &schemapb.LongArray{
+						Data: []int64{1, 2},
+					},
+				},
+			},
+		}, nil)
+		value := make([]int64, 2)
+		value[1] = 1
+		validValue := make([]bool, 2)
+		validValue[1] = true
+		r, err := c.Insert(ctx, testCollectionName, "partition_1",
+			entity.NewNullableColumnInt64("nullable_fid", value, validValue),
+			entity.NewColumnFloatVector("vector", 128, generateFloatVector(2, 128)),
+		)
+		s.NoError(err)
+		s.Equal(2, r.Len())
+	})
+
+	s.Run("insert_with_nullable_column_with_default_value", func() {
+		defer s.resetMock()
+		s.setupHasCollection(testCollectionName)
+		s.setupHasPartition(testCollectionName, "partition_1")
+
+		s.setupDescribeCollection(testCollectionName, entity.NewSchema().
+			WithField(entity.NewField().WithIsPrimaryKey(true).WithIsAutoID(true).WithName("ID").WithDataType(entity.FieldTypeInt64)).
+			WithField(entity.NewField().WithName("nullable_fid").WithDataType(entity.FieldTypeInt64).WithNullable(true).WithDefaultValueLong(10)).
+			WithField(entity.NewField().WithName("vector").WithDataType(entity.FieldTypeFloatVector).WithTypeParams(entity.TypeParamDim, "128")),
+		)
+
+		s.mock.EXPECT().Insert(mock.Anything, mock.AnythingOfType("*milvuspb.InsertRequest")).
+			Run(func(ctx context.Context, req *milvuspb.InsertRequest) {
+				s.Equal(2, len(req.GetFieldsData()))
+			}).Return(&milvuspb.MutationResult{
+			Status: &commonpb.Status{},
+			IDs: &schemapb.IDs{
+				IdField: &schemapb.IDs_IntId{
+					IntId: &schemapb.LongArray{
+						Data: []int64{1, 2},
+					},
+				},
+			},
+		}, nil)
+		value := make([]int64, 2)
+		value[1] = 1
+		validValue := make([]bool, 2)
+		validValue[1] = true
+		r, err := c.Insert(ctx, testCollectionName, "partition_1",
+			entity.NewNullableColumnInt64("nullable_fid", value, validValue),
+			entity.NewColumnFloatVector("vector", 128, generateFloatVector(2, 128)),
+		)
+		s.NoError(err)
+		s.Equal(2, r.Len())
+	})
 }
 
 type UpsertSuite struct {
@@ -529,19 +648,26 @@ func (s *UpsertSuite) TestUpsertSuccess() {
 	})
 
 	s.Run("missing_field_with_default_value", func() {
-		s.T().Skip("skip for default value test")
 		defer s.resetMock()
 		s.setupHasCollection(testCollectionName)
 		s.setupHasPartition(testCollectionName, "partition_1")
 
 		s.setupDescribeCollection(testCollectionName, entity.NewSchema().
 			WithField(entity.NewField().WithIsPrimaryKey(true).WithIsAutoID(true).WithName("ID").WithDataType(entity.FieldTypeInt64)).
-			WithField(entity.NewField().WithName("default_value").WithDataType(entity.FieldTypeInt64)).
+			WithField(entity.NewField().WithName("default_value").WithDataType(entity.FieldTypeInt64).WithDefaultValueLong(1)).
 			WithField(entity.NewField().WithName("vector").WithDataType(entity.FieldTypeFloatVector).WithTypeParams(entity.TypeParamDim, "128")),
 		)
 
 		s.mock.EXPECT().Upsert(mock.Anything, mock.AnythingOfType("*milvuspb.UpsertRequest")).
 			Run(func(ctx context.Context, req *milvuspb.UpsertRequest) {
+				var data *schemapb.FieldData
+				for _, d := range req.GetFieldsData() {
+					if d.FieldName == "default_value" {
+						data = d
+					}
+				}
+				s.Equal([]bool{false}, data.ValidData)
+				s.Equal(0, len(data.GetScalars().GetLongData().Data))
 				s.Equal(2, len(req.GetFieldsData()))
 			}).Return(&milvuspb.MutationResult{
 			Status: &commonpb.Status{},
@@ -560,6 +686,118 @@ func (s *UpsertSuite) TestUpsertSuccess() {
 		s.NoError(err)
 		s.Equal(1, r.Len())
 	})
+
+	s.Run("missing_field_with_nullable", func() {
+		defer s.resetMock()
+		s.setupHasCollection(testCollectionName)
+		s.setupHasPartition(testCollectionName, "partition_1")
+
+		s.setupDescribeCollection(testCollectionName, entity.NewSchema().
+			WithField(entity.NewField().WithIsPrimaryKey(true).WithIsAutoID(true).WithName("ID").WithDataType(entity.FieldTypeInt64)).
+			WithField(entity.NewField().WithName("nullable_fid").WithDataType(entity.FieldTypeInt64).WithNullable(true)).
+			WithField(entity.NewField().WithName("vector").WithDataType(entity.FieldTypeFloatVector).WithTypeParams(entity.TypeParamDim, "128")),
+		)
+
+		s.mock.EXPECT().Upsert(mock.Anything, mock.AnythingOfType("*milvuspb.UpsertRequest")).
+			Run(func(ctx context.Context, req *milvuspb.UpsertRequest) {
+				s.Equal(2, len(req.GetFieldsData()))
+			}).Return(&milvuspb.MutationResult{
+			Status: &commonpb.Status{},
+			IDs: &schemapb.IDs{
+				IdField: &schemapb.IDs_IntId{
+					IntId: &schemapb.LongArray{
+						Data: []int64{1},
+					},
+				},
+			},
+		}, nil)
+
+		r, err := c.Upsert(ctx, testCollectionName, "partition_1",
+			entity.NewColumnFloatVector("vector", 128, generateFloatVector(1, 128)),
+		)
+		s.NoError(err)
+		s.Equal(1, r.Len())
+	})
+
+	s.Run("insert_with_nullable_column", func() {
+		defer s.resetMock()
+		s.setupHasCollection(testCollectionName)
+		s.setupHasPartition(testCollectionName, "partition_1")
+
+		s.setupDescribeCollection(testCollectionName, entity.NewSchema().
+			WithField(entity.NewField().WithIsPrimaryKey(true).WithIsAutoID(true).WithName("ID").WithDataType(entity.FieldTypeInt64)).
+			WithField(entity.NewField().WithName("nullable_fid").WithDataType(entity.FieldTypeInt64).WithNullable(true)).
+			WithField(entity.NewField().WithName("vector").WithDataType(entity.FieldTypeFloatVector).WithTypeParams(entity.TypeParamDim, "128")),
+		)
+
+		s.mock.EXPECT().Upsert(mock.Anything, mock.AnythingOfType("*milvuspb.UpsertRequest")).
+			Run(func(ctx context.Context, req *milvuspb.UpsertRequest) {
+				var data *schemapb.FieldData
+				for _, d := range req.GetFieldsData() {
+					if d.FieldName == "nullable_fid" {
+						data = d
+					}
+				}
+				s.Equal([]bool{false, true}, data.ValidData)
+				s.Equal([]int64{1}, data.GetScalars().GetLongData().Data)
+				s.Equal(2, len(req.GetFieldsData()))
+			}).Return(&milvuspb.MutationResult{
+			Status: &commonpb.Status{},
+			IDs: &schemapb.IDs{
+				IdField: &schemapb.IDs_IntId{
+					IntId: &schemapb.LongArray{
+						Data: []int64{1, 2},
+					},
+				},
+			},
+		}, nil)
+		value := make([]int64, 2)
+		value[1] = 1
+		validValue := make([]bool, 2)
+		validValue[1] = true
+		r, err := c.Upsert(ctx, testCollectionName, "partition_1",
+			entity.NewNullableColumnInt64("nullable_fid", value, validValue),
+			entity.NewColumnFloatVector("vector", 128, generateFloatVector(2, 128)),
+		)
+		s.NoError(err)
+		s.Equal(2, r.Len())
+	})
+
+	s.Run("insert_with_nullable_column_with_default_value", func() {
+		defer s.resetMock()
+		s.setupHasCollection(testCollectionName)
+		s.setupHasPartition(testCollectionName, "partition_1")
+
+		s.setupDescribeCollection(testCollectionName, entity.NewSchema().
+			WithField(entity.NewField().WithIsPrimaryKey(true).WithIsAutoID(true).WithName("ID").WithDataType(entity.FieldTypeInt64)).
+			WithField(entity.NewField().WithName("nullable_fid").WithDataType(entity.FieldTypeInt64).WithNullable(true).WithDefaultValueLong(10)).
+			WithField(entity.NewField().WithName("vector").WithDataType(entity.FieldTypeFloatVector).WithTypeParams(entity.TypeParamDim, "128")),
+		)
+
+		s.mock.EXPECT().Upsert(mock.Anything, mock.AnythingOfType("*milvuspb.UpsertRequest")).
+			Run(func(ctx context.Context, req *milvuspb.UpsertRequest) {
+				s.Equal(2, len(req.GetFieldsData()))
+			}).Return(&milvuspb.MutationResult{
+			Status: &commonpb.Status{},
+			IDs: &schemapb.IDs{
+				IdField: &schemapb.IDs_IntId{
+					IntId: &schemapb.LongArray{
+						Data: []int64{1, 2},
+					},
+				},
+			},
+		}, nil)
+		value := make([]int64, 2)
+		value[1] = 1
+		validValue := make([]bool, 2)
+		validValue[1] = true
+		r, err := c.Upsert(ctx, testCollectionName, "partition_1",
+			entity.NewNullableColumnInt64("nullable_fid", value, validValue),
+			entity.NewColumnFloatVector("vector", 128, generateFloatVector(2, 128)),
+		)
+		s.NoError(err)
+		s.Equal(2, r.Len())
+	})
 }
 
 func TestWrite(t *testing.T) {
diff --git a/client/results_test.go b/client/results_test.go
new file mode 100644
index 0000000..9181b70
--- /dev/null
+++ b/client/results_test.go
@@ -0,0 +1,109 @@
+package client
+
+import (
+	"testing"
+
+	"github.com/milvus-io/milvus-sdk-go/v2/entity"
+	"github.com/stretchr/testify/suite"
+)
+
+type ResultSetSuite struct {
+	suite.Suite
+}
+
+func (s *ResultSetSuite) TestResultsetUnmarshal() {
+	type MyData struct {
+		A int64     `milvus:"name:id"`
+		V []float32 `milvus:"name:vector"`
+	}
+	type OtherData struct {
+		A string    `milvus:"name:id"`
+		V []float32 `milvus:"name:vector"`
+	}
+
+	var (
+		idData     = []int64{1, 2, 3}
+		vectorData = [][]float32{
+			{0.1, 0.2},
+			{0.1, 0.2},
+			{0.1, 0.2},
+		}
+	)
+
+	rs := ResultSet([]entity.Column{
+		entity.NewColumnInt64("id", idData),
+		entity.NewColumnFloatVector("vector", 2, vectorData),
+	})
+	err := rs.Unmarshal([]MyData{})
+	s.Error(err)
+
+	receiver := []MyData{}
+	err = rs.Unmarshal(&receiver)
+	s.Error(err)
+
+	var ptrReceiver []*MyData
+	err = rs.Unmarshal(&ptrReceiver)
+	s.NoError(err)
+
+	for idx, row := range ptrReceiver {
+		s.Equal(row.A, idData[idx])
+		s.Equal(row.V, vectorData[idx])
+	}
+
+	var otherReceiver []*OtherData
+	err = rs.Unmarshal(&otherReceiver)
+	s.Error(err)
+}
+
+func (s *ResultSetSuite) TestSearchResultUnmarshal() {
+	type MyData struct {
+		A int64     `milvus:"name:id"`
+		V []float32 `milvus:"name:vector"`
+	}
+	type OtherData struct {
+		A string    `milvus:"name:id"`
+		V []float32 `milvus:"name:vector"`
+	}
+
+	var (
+		idData     = []int64{1, 2, 3}
+		vectorData = [][]float32{
+			{0.1, 0.2},
+			{0.1, 0.2},
+			{0.1, 0.2},
+		}
+	)
+
+	sr := SearchResult{
+		sch: entity.NewSchema().
+			WithField(entity.NewField().WithName("id").WithIsPrimaryKey(true).WithDataType(entity.FieldTypeInt64)).
+			WithField(entity.NewField().WithName("vector").WithDim(2).WithDataType(entity.FieldTypeFloatVector)),
+		IDs: entity.NewColumnInt64("id", idData),
+		Fields: ResultSet([]entity.Column{
+			entity.NewColumnFloatVector("vector", 2, vectorData),
+		}),
+	}
+	err := sr.Unmarshal([]MyData{})
+	s.Error(err)
+
+	receiver := []MyData{}
+	err = sr.Unmarshal(&receiver)
+	s.Error(err)
+
+	var ptrReceiver []*MyData
+	err = sr.Unmarshal(&ptrReceiver)
+	s.NoError(err)
+
+	for idx, row := range ptrReceiver {
+		s.Equal(row.A, idData[idx])
+		s.Equal(row.V, vectorData[idx])
+	}
+
+	var otherReceiver []*OtherData
+	err = sr.Unmarshal(&otherReceiver)
+	s.Error(err)
+}
+
+func TestResults(t *testing.T) {
+	suite.Run(t, new(ResultSetSuite))
+}
diff --git a/client/row_test.go b/client/row_test.go
index e69479d..4708c82 100644
--- a/client/row_test.go
+++ b/client/row_test.go
@@ -248,6 +248,46 @@ func (s *InsertByRowsSuite) TestSuccess() {
 	ctx, cancel := context.WithCancel(context.Background())
 	defer cancel()
 
+	s.Run("null value", func() {
+		defer s.resetMock()
+		s.setupHasCollection(testCollectionName)
+		s.setupHasPartition(testCollectionName, partName)
+		s.setupDescribeCollection(testCollectionName, entity.NewSchema().WithName(testCollectionName).
+			WithField(entity.NewField().WithName("ID").WithDataType(entity.FieldTypeInt64).WithIsPrimaryKey(true)).
+			WithField(entity.NewField().WithName("NullableFid").WithDataType(entity.FieldTypeInt64).WithNullable(true)).
+			WithField(entity.NewField().WithName("Vector").WithDataType(entity.FieldTypeFloatVector).WithTypeParams(entity.TypeParamDim, "128")),
+		)
+
+		s.mock.EXPECT().Insert(mock.Anything, mock.AnythingOfType("*milvuspb.InsertRequest")).
+			Run(func(_ context.Context, req *milvuspb.InsertRequest) {
+				s.Equal(testCollectionName, req.GetCollectionName())
+				s.Equal(partName, req.GetPartitionName())
+				s.Equal(3, len(req.GetFieldsData()))
+				var data *schemapb.FieldData
+				for _, d := range req.GetFieldsData() {
+					if d.FieldName == "NullableFid" {
+						data = d
+					}
+				}
+				s.Equal(1, len(data.ValidData))
+				s.Equal(0, len(data.GetScalars().GetLongData().Data))
+			}).Return(&milvuspb.MutationResult{
+			Status: &commonpb.Status{ErrorCode: commonpb.ErrorCode_Success},
+			IDs:    &schemapb.IDs{IdField: &schemapb.IDs_IntId{IntId: &schemapb.LongArray{Data: []int64{100}}}},
+		}, nil)
+		type row struct {
+			entity.RowBase
+			ID          int64
+			NullableFid interface{}
+			Vector      []float32
+		}
+		columns, err := c.InsertByRows(ctx, testCollectionName, partName, []entity.Row{
+			row{ID: 100, NullableFid: nil, Vector: make([]float32, 128)},
+		})
+		s.NoError(err)
+		s.Equal(1, columns.Len())
+	})
+
 	s.Run("non_dynamic", func() {
 		defer s.resetMock()
 		s.setupHasCollection(testCollectionName)
diff --git a/entity/columns_scalar_gen_test.go b/entity/columns_scalar_gen_test.go
index 70e1408..73ade6f 100755
--- a/entity/columns_scalar_gen_test.go
+++ b/entity/columns_scalar_gen_test.go
@@ -117,6 +117,26 @@ func TestFieldDataBoolColumn(t *testing.T) {
 		assert.Equal(t, len, column.Len())
 		assert.Equal(t, FieldTypeBool, column.Type())
 	})
+
+	t.Run("get null data", func(t *testing.T) {
+		fd.Field = &schema.FieldData_Scalars{
+			Scalars: &schema.ScalarField{
+				Data: &schema.ScalarField_BoolData{
+					BoolData: &schema.BoolArray{
+						Data: make([]bool, len),
+					},
+				},
+			},
+		}
+		fd.ValidData = make([]bool, len)
+		column, err := FieldDataColumn(fd, 0, -1)
+		assert.Nil(t, err)
+		assert.NotNil(t, column)
+		
+		assert.Equal(t, name, column.Name())
+		assert.Equal(t, len, column.Len())
+		assert.Equal(t, FieldTypeBool, column.Type())
+	})
 }
 
 func TestColumnInt8(t *testing.T) {
@@ -223,6 +243,26 @@ func TestFieldDataInt8Column(t *testing.T) {
 		assert.Equal(t, len, column.Len())
 		assert.Equal(t, FieldTypeInt8, column.Type())
 	})
+
+	t.Run("get null data", func(t *testing.T) {
+		fd.Field = &schema.FieldData_Scalars{
+			Scalars: &schema.ScalarField{
+				Data: &schema.ScalarField_IntData{
+					IntData: &schema.IntArray{
+						Data: make([]int32, len),
+					},
+				},
+			},
+		}
+		fd.ValidData = make([]bool, len)
+		column, err := FieldDataColumn(fd, 0, -1)
+		assert.Nil(t, err)
+		assert.NotNil(t, column)
+		
+		assert.Equal(t, name, column.Name())
+		assert.Equal(t, len, column.Len())
+		assert.Equal(t, FieldTypeInt8, column.Type())
+	})
 }
 
 func TestColumnInt16(t *testing.T) {
@@ -329,6 +369,26 @@ func TestFieldDataInt16Column(t *testing.T) {
 		assert.Equal(t, len, column.Len())
 		assert.Equal(t, FieldTypeInt16, column.Type())
 	})
+
+	t.Run("get null data", func(t *testing.T) {
+		fd.Field = &schema.FieldData_Scalars{
+			Scalars: &schema.ScalarField{
+				Data: &schema.ScalarField_IntData{
+					IntData: &schema.IntArray{
+						Data: make([]int32, len),
+					},
+				},
+			},
+		}
+		fd.ValidData = make([]bool, len)
+		column, err := FieldDataColumn(fd, 0, -1)
+		assert.Nil(t, err)
+		assert.NotNil(t, column)
+		
+		assert.Equal(t, name, column.Name())
+		assert.Equal(t, len, column.Len())
+		assert.Equal(t, FieldTypeInt16, column.Type())
+	})
 }
 
 func TestColumnInt32(t *testing.T) {
@@ -435,6 +495,26 @@ func TestFieldDataInt32Column(t *testing.T) {
 		assert.Equal(t, len, column.Len())
 		assert.Equal(t, FieldTypeInt32, column.Type())
 	})
+
+	t.Run("get null data", func(t *testing.T) {
+		fd.Field = &schema.FieldData_Scalars{
+			Scalars: &schema.ScalarField{
+				Data: &schema.ScalarField_IntData{
+					IntData: &schema.IntArray{
+						Data: make([]int32, len),
+					},
+				},
+			},
+		}
+		fd.ValidData = make([]bool, len)
+		column, err := FieldDataColumn(fd, 0, -1)
+		assert.Nil(t, err)
+		assert.NotNil(t, column)
+		
+		assert.Equal(t, name, column.Name())
+		assert.Equal(t, len, column.Len())
+		assert.Equal(t, FieldTypeInt32, column.Type())
+	})
 }
 
 func TestColumnInt64(t *testing.T) {
@@ -541,6 +621,26 @@ func TestFieldDataInt64Column(t *testing.T) {
 		assert.Equal(t, len, column.Len())
 		assert.Equal(t, FieldTypeInt64, column.Type())
 	})
+
+	t.Run("get null data", func(t *testing.T) {
+		fd.Field = &schema.FieldData_Scalars{
+			Scalars: &schema.ScalarField{
+				Data: &schema.ScalarField_LongData{
+					LongData: &schema.LongArray{
+						Data: make([]int64, len),
+					},
+				},
+			},
+		}
+		fd.ValidData = make([]bool, len)
+		column, err := FieldDataColumn(fd, 0, -1)
+		assert.Nil(t, err)
+		assert.NotNil(t, column)
+		
+		assert.Equal(t, name, column.Name())
+		assert.Equal(t, len, column.Len())
+		assert.Equal(t, FieldTypeInt64, column.Type())
+	})
 }
 
 func TestColumnFloat(t *testing.T) {
@@ -647,6 +747,26 @@ func TestFieldDataFloatColumn(t *testing.T) {
 		assert.Equal(t, len, column.Len())
 		assert.Equal(t, FieldTypeFloat, column.Type())
 	})
+
+	t.Run("get null data", func(t *testing.T) {
+		fd.Field = &schema.FieldData_Scalars{
+			Scalars: &schema.ScalarField{
+				Data: &schema.ScalarField_FloatData{
+					FloatData: &schema.FloatArray{
+						Data: make([]float32, len),
+					},
+				},
+			},
+		}
+		fd.ValidData = make([]bool, len)
+		column, err := FieldDataColumn(fd, 0, -1)
+		assert.Nil(t, err)
+		assert.NotNil(t, column)
+		
+		assert.Equal(t, name, column.Name())
+		assert.Equal(t, len, column.Len())
+		assert.Equal(t, FieldTypeFloat, column.Type())
+	})
 }
 
 func TestColumnDouble(t *testing.T) {
@@ -753,6 +873,26 @@ func TestFieldDataDoubleColumn(t *testing.T) {
 		assert.Equal(t, len, column.Len())
 		assert.Equal(t, FieldTypeDouble, column.Type())
 	})
+
+	t.Run("get null data", func(t *testing.T) {
+		fd.Field = &schema.FieldData_Scalars{
+			Scalars: &schema.ScalarField{
+				Data: &schema.ScalarField_DoubleData{
+					DoubleData: &schema.DoubleArray{
+						Data: make([]float64, len),
+					},
+				},
+			},
+		}
+		fd.ValidData = make([]bool, len)
+		column, err := FieldDataColumn(fd, 0, -1)
+		assert.Nil(t, err)
+		assert.NotNil(t, column)
+		
+		assert.Equal(t, name, column.Name())
+		assert.Equal(t, len, column.Len())
+		assert.Equal(t, FieldTypeDouble, column.Type())
+	})
 }
 
 func TestColumnString(t *testing.T) {
@@ -859,5 +999,25 @@ func TestFieldDataStringColumn(t *testing.T) {
 		assert.Equal(t, len, column.Len())
 		assert.Equal(t, FieldTypeString, column.Type())
 	})
+
+	t.Run("get null data", func(t *testing.T) {
+		fd.Field = &schema.FieldData_Scalars{
+			Scalars: &schema.ScalarField{
+				Data: &schema.ScalarField_StringData{
+					StringData: &schema.StringArray{
+						Data: make([]string, len),
+					},
+				},
+			},
+		}
+		fd.ValidData = make([]bool, len)
+		column, err := FieldDataColumn(fd, 0, -1)
+		assert.Nil(t, err)
+		assert.NotNil(t, column)
+		
+		assert.Equal(t, name, column.Name())
+		assert.Equal(t, len, column.Len())
+		assert.Equal(t, FieldTypeString, column.Type())
+	})
 }
 
diff --git a/entity/columns_varchar_test.go b/entity/columns_varchar_test.go
index 46a8835..0630bba 100644
--- a/entity/columns_varchar_test.go
+++ b/entity/columns_varchar_test.go
@@ -113,4 +113,24 @@ func TestFieldDataVarCharColumn(t *testing.T) {
 		assert.Equal(t, colLen, column.Len())
 		assert.Equal(t, FieldTypeVarChar, column.Type())
 	})
+
+	t.Run("get null data", func(t *testing.T) {
+		fd.Field = &schema.FieldData_Scalars{
+			Scalars: &schema.ScalarField{
+				Data: &schema.ScalarField_StringData{
+					StringData: &schema.StringArray{
+						Data: make([]string, colLen),
+					},
+				},
+			},
+		}
+		fd.ValidData = make([]bool, colLen)
+		column, err := FieldDataColumn(fd, 0, -1)
+		assert.Nil(t, err)
+		assert.NotNil(t, column)
+
+		assert.Equal(t, name, column.Name())
+		assert.Equal(t, colLen, column.Len())
+		assert.Equal(t, FieldTypeVarChar, column.Type())
+	})
 }
diff --git a/entity/index_test.go b/entity/index_test.go
index 06188ed..5411e5a 100644
--- a/entity/index_test.go
+++ b/entity/index_test.go
@@ -41,6 +41,12 @@ func TestAddRangeFilter(t *testing.T) {
 	assert.Equal(t, params.Params()["range_filter"], float64(20))
 }
 
+func TestPageRetainOrder(t *testing.T) {
+	params := newBaseSearchParams()
+	params.AddPageRetainOrder(true)
+	assert.Equal(t, params.Params()["page_retain_order"], true)
+}
+
 func TestIndexGPUCagra(t *testing.T) {
 	t.Run("index", func(t *testing.T) {
 		index, err := NewIndexGPUCagra(L2, 64, 64)
diff --git a/entity/rows_test.go b/entity/rows_test.go
index 19d182d..81c633d 100644
--- a/entity/rows_test.go
+++ b/entity/rows_test.go
@@ -57,7 +57,6 @@ type SliceBadDimStruct2 struct {
 }
 
 func TestParseSchema(t *testing.T) {
-
 	t.Run("invalid cases", func(t *testing.T) {
 		// anonymous struct with default collection name ("") will cause error
 		anonymusStruct := struct {
@@ -108,11 +107,9 @@ func TestParseSchema(t *testing.T) {
 		sch, err = ParseSchema(&SliceBadDimStruct2{})
 		assert.Nil(t, sch)
 		assert.NotNil(t, err)
-
 	})
 
 	t.Run("valid cases", func(t *testing.T) {
-
 		sch, err := ParseSchema(RowBase{})
 		assert.Nil(t, err)
 		assert.Equal(t, "RowBase", sch.CollectionName)
@@ -268,7 +265,6 @@ type RowsSuite struct {
 
 func (s *RowsSuite) TestRowsToColumns() {
 	s.Run("valid_cases", func() {
-
 		columns, err := RowsToColumns([]Row{&ValidStruct{}})
 		s.Nil(err)
 		s.Equal(10, len(columns))
@@ -358,6 +354,10 @@ func (s *RowsSuite) TestDynamicSchema() {
 }
 
 func (s *RowsSuite) TestReflectValueCandi() {
+	type DynamicRows struct {
+		Float float32 `json:"float" milvus:"name:float"`
+	}
+
 	cases := []struct {
 		tag       string
 		v         reflect.Value
@@ -381,6 +381,42 @@ func (s *RowsSuite) TestReflectValueCandi() {
 			},
 			expectErr: false,
 		},
+		{
+			tag: "StructRow",
+			v: reflect.ValueOf(struct {
+				A string
+				B int64
+			}{A: "abc", B: 16}),
+			expect: map[string]fieldCandi{
+				"A": {
+					name: "A",
+					v:    reflect.ValueOf("abc"),
+				},
+				"B": {
+					name: "B",
+					v:    reflect.ValueOf(int64(16)),
+				},
+			},
+			expectErr: false,
+		},
+		{
+			tag: "StructRow_DuplicateName",
+			v: reflect.ValueOf(struct {
+				A string `milvus:"name:a"`
+				B int64  `milvus:"name:a"`
+			}{A: "abc", B: 16}),
+			expectErr: true,
+		},
+		{
+			tag: "StructRow_EmbedDuplicateName",
+			v: reflect.ValueOf(struct {
+				Int64    int64     `json:"int64" milvus:"name:int64"`
+				Float    float32   `json:"float" milvus:"name:float"`
+				FloatVec []float32 `json:"floatVec" milvus:"name:floatVec"`
+				DynamicRows
+			}{}),
+			expectErr: true,
+		},
 	}
 
 	for _, c := range cases {
diff --git a/entity/schema_test.go b/entity/schema_test.go
index 3a67643..d664f49 100644
--- a/entity/schema_test.go
+++ b/entity/schema_test.go
@@ -29,13 +29,14 @@ func TestFieldSchema(t *testing.T) {
 		NewField().WithName("fp16_field").WithDataType(FieldTypeFloat16Vector).WithDim(128),
 		NewField().WithName("bf16_field").WithDataType(FieldTypeBFloat16Vector).WithDim(128),
 		NewField().WithName("cluster_key").WithDataType(FieldTypeInt32).WithIsClusteringKey(true),
-		/*
-			NewField().WithName("default_value_bool").WithDataType(FieldTypeBool).WithDefaultValueBool(true),
-			NewField().WithName("default_value_int").WithDataType(FieldTypeInt32).WithDefaultValueInt(1),
-			NewField().WithName("default_value_long").WithDataType(FieldTypeInt64).WithDefaultValueLong(1),
-			NewField().WithName("default_value_float").WithDataType(FieldTypeFloat).WithDefaultValueFloat(1),
-			NewField().WithName("default_value_double").WithDataType(FieldTypeDouble).WithDefaultValueDouble(1),
-			NewField().WithName("default_value_string").WithDataType(FieldTypeString).WithDefaultValueString("a"),*/
+		NewField().WithName("nullable_field").WithDataType(FieldTypeString).WithNullable(true),
+
+		NewField().WithName("default_value_bool").WithDataType(FieldTypeBool).WithDefaultValueBool(true),
+		NewField().WithName("default_value_int").WithDataType(FieldTypeInt32).WithDefaultValueInt(1),
+		NewField().WithName("default_value_long").WithDataType(FieldTypeInt64).WithDefaultValueLong(1),
+		NewField().WithName("default_value_float").WithDataType(FieldTypeFloat).WithDefaultValueFloat(1),
+		NewField().WithName("default_value_double").WithDataType(FieldTypeDouble).WithDefaultValueDouble(1),
+		NewField().WithName("default_value_string").WithDataType(FieldTypeString).WithDefaultValueString("a"),
 	}
 
 	for _, field := range fields {
@@ -51,6 +52,8 @@ func TestFieldSchema(t *testing.T) {
 		assert.Equal(t, field.Description, fieldSchema.GetDescription())
 		assert.Equal(t, field.TypeParams, KvPairsMap(fieldSchema.GetTypeParams()))
 		assert.EqualValues(t, field.ElementType, fieldSchema.GetElementType())
+		assert.Equal(t, field.DefaultValue, fieldSchema.DefaultValue)
+		assert.Equal(t, field.Nullable, fieldSchema.Nullable)
 		// marshal & unmarshal, still equals
 		nf := &Field{}
 		nf = nf.ReadProto(fieldSchema)
@@ -65,6 +68,8 @@ func TestFieldSchema(t *testing.T) {
 		assert.Equal(t, field.IsClusteringKey, nf.IsClusteringKey)
 		assert.EqualValues(t, field.TypeParams, nf.TypeParams)
 		assert.EqualValues(t, field.ElementType, nf.ElementType)
+		assert.Equal(t, field.DefaultValue, nf.DefaultValue)
+		assert.Equal(t, field.Nullable, nf.Nullable)
 	}
 
 	assert.NotPanics(t, func() {
diff --git a/test/common/response_check.go b/test/common/response_check.go
index 1a5840d..2d0b853 100644
--- a/test/common/response_check.go
+++ b/test/common/response_check.go
@@ -5,6 +5,7 @@ import (
 	"fmt"
 	"io"
 	"log"
+	"reflect"
 	"strings"
 	"testing"
 
@@ -155,9 +156,15 @@ func EqualColumn(t *testing.T, columnA entity.Column, columnB entity.Column) {
 	case entity.FieldTypeVarChar:
 		require.ElementsMatch(t, columnA.(*entity.ColumnVarChar).Data(), columnB.(*entity.ColumnVarChar).Data())
 	case entity.FieldTypeJSON:
-		log.Printf("columnA: %s", columnA.(*entity.ColumnJSONBytes).Data())
-		log.Printf("columnB: %s", columnB.(*entity.ColumnJSONBytes).Data())
-		require.ElementsMatch(t, columnA.(*entity.ColumnJSONBytes).Data(), columnB.(*entity.ColumnJSONBytes).Data())
+		log.Printf("columnA: %s", columnA.FieldData())
+		log.Printf("columnB: %s", columnB.FieldData())
+		require.Equal(t, reflect.TypeOf(columnA), reflect.TypeOf(columnB))
+		switch columnA.(type) {
+		case *entity.ColumnDynamic:
+			require.ElementsMatch(t, columnA.(*entity.ColumnDynamic).Data(), columnB.(*entity.ColumnDynamic).Data())
+		case *entity.ColumnJSONBytes:
+			require.ElementsMatch(t, columnA.(*entity.ColumnJSONBytes).Data(), columnB.(*entity.ColumnJSONBytes).Data())
+		}
 	case entity.FieldTypeFloatVector:
 		require.ElementsMatch(t, columnA.(*entity.ColumnFloatVector).Data(), columnB.(*entity.ColumnFloatVector).Data())
 	case entity.FieldTypeBinaryVector:
diff --git a/test/testcases/groupby_search_test.go b/test/testcases/groupby_search_test.go
index 40fa924..ae79584 100644
--- a/test/testcases/groupby_search_test.go
+++ b/test/testcases/groupby_search_test.go
@@ -64,13 +64,17 @@ func prepareDataForGroupBySearch(t *testing.T, loopInsert int, insertNi int, idx
 	mc := createMilvusClient(ctx, t)
 
 	// create collection with all datatype
-	cp := CollectionParams{CollectionFieldsType: AllFields, AutoID: false, EnableDynamicField: true,
-		ShardsNum: common.DefaultShards, Dim: common.DefaultDim}
+	cp := CollectionParams{
+		CollectionFieldsType: AllFields, AutoID: false, EnableDynamicField: true,
+		ShardsNum: common.DefaultShards, Dim: common.DefaultDim,
+	}
 	collName := createCollection(ctx, t, mc, cp)
 
 	// insert
-	dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: AllFields,
-		start: 0, nb: insertNi, dim: common.DefaultDim, EnableDynamicField: true, WithRows: false}
+	dp := DataParams{
+		CollectionName: collName, PartitionName: "", CollectionFieldsType: AllFields,
+		start: 0, nb: insertNi, dim: common.DefaultDim, EnableDynamicField: true, WithRows: false,
+	}
 	for i := 0; i < loopInsert; i++ {
 		_, _ = insertData(ctx, t, mc, dp)
 	}
@@ -79,9 +83,11 @@ func prepareDataForGroupBySearch(t *testing.T, loopInsert int, insertNi int, idx
 		mc.Flush(ctx, collName, false)
 	}
 
-	//create scalar index
-	supportedGroupByFields := []string{common.DefaultIntFieldName, common.DefaultInt8FieldName, common.DefaultInt16FieldName,
-		common.DefaultInt32FieldName, common.DefaultVarcharFieldName, common.DefaultBoolFieldName}
+	// create scalar index
+	supportedGroupByFields := []string{
+		common.DefaultIntFieldName, common.DefaultInt8FieldName, common.DefaultInt16FieldName,
+		common.DefaultInt32FieldName, common.DefaultVarcharFieldName, common.DefaultBoolFieldName,
+	}
 	for _, groupByField := range supportedGroupByFields {
 		err := mc.CreateIndex(ctx, collName, groupByField, entity.NewScalarIndex(), false)
 		common.CheckErr(t, err, true)
@@ -148,10 +154,12 @@ func TestSearchGroupByFloatDefault(t *testing.T) {
 							expr = fmt.Sprintf("%s == %v", groupByField, groupByValue)
 						}
 						// 	search filter with groupByValue is the top1
-						resFilter, _ := mc.Search(ctx, collName, []string{}, expr, []string{common.DefaultIntFieldName,
-							groupByField}, []entity.Vector{queryVec[i]}, common.DefaultFloatVecFieldName, metricType, 1, sp)
+						resFilter, _ := mc.Search(ctx, collName, []string{}, expr, []string{
+							common.DefaultIntFieldName,
+							groupByField,
+						}, []entity.Vector{queryVec[i]}, common.DefaultFloatVecFieldName, metricType, 1, sp)
 						filterTop1Pk, _ := resFilter[0].IDs.GetAsInt64(0)
-						//log.Printf("Search top1 with %s: groupByValue: %v, pkValue: %d. The returned pk by filter search is: %d",
+						// log.Printf("Search top1 with %s: groupByValue: %v, pkValue: %d. The returned pk by filter search is: %d",
 						//	groupByField, groupByValue, pkValue, filterTop1Pk)
 						if filterTop1Pk == pkValue {
 							hitsNum += 1
@@ -185,13 +193,17 @@ func TestGroupBySearchSparseVector(t *testing.T) {
 		mc := createMilvusClient(ctx, t)
 
 		// create -> insert [0, 3000) -> flush -> index -> load
-		cp := CollectionParams{CollectionFieldsType: Int64VarcharSparseVec, AutoID: false, EnableDynamicField: true,
-			ShardsNum: common.DefaultShards, Dim: common.DefaultDim, MaxLength: common.TestMaxLen}
+		cp := CollectionParams{
+			CollectionFieldsType: Int64VarcharSparseVec, AutoID: false, EnableDynamicField: true,
+			ShardsNum: common.DefaultShards, Dim: common.DefaultDim, MaxLength: common.TestMaxLen,
+		}
 		collName := createCollection(ctx, t, mc, cp, client.WithConsistencyLevel(entity.ClStrong))
 
 		// insert data
-		dp := DataParams{DoInsert: true, CollectionName: collName, CollectionFieldsType: Int64VarcharSparseVec, start: 0,
-			nb: 200, dim: common.DefaultDim, EnableDynamicField: true}
+		dp := DataParams{
+			DoInsert: true, CollectionName: collName, CollectionFieldsType: Int64VarcharSparseVec, start: 0,
+			nb: 200, dim: common.DefaultDim, EnableDynamicField: true,
+		}
 		for i := 0; i < 100; i++ {
 			_, _ = insertData(ctx, t, mc, dp)
 		}
@@ -219,8 +231,10 @@ func TestGroupBySearchSparseVector(t *testing.T) {
 					pkValue, _ := resGroupBy[i].IDs.GetAsInt64(j)
 					expr := fmt.Sprintf("%s == '%v' ", common.DefaultVarcharFieldName, groupByValue)
 					// 	search filter with groupByValue is the top1
-					resFilter, _ := mc.Search(ctx, collName, []string{}, expr, []string{common.DefaultIntFieldName,
-						common.DefaultVarcharFieldName}, []entity.Vector{queryVec[i]}, common.DefaultSparseVecFieldName, entity.IP, 1, sp)
+					resFilter, _ := mc.Search(ctx, collName, []string{}, expr, []string{
+						common.DefaultIntFieldName,
+						common.DefaultVarcharFieldName,
+					}, []entity.Vector{queryVec[i]}, common.DefaultSparseVecFieldName, entity.IP, 1, sp)
 					filterTop1Pk, _ := resFilter[0].IDs.GetAsInt64(0)
 					log.Printf("Search top1 with %s: groupByValue: %v, pkValue: %d. The returned pk by filter search is: %d",
 						common.DefaultVarcharFieldName, groupByValue, pkValue, filterTop1Pk)
@@ -251,13 +265,17 @@ func TestSearchGroupByBinaryDefault(t *testing.T) {
 			mc := createMilvusClient(ctx, t)
 
 			// create collection with all datatype
-			cp := CollectionParams{CollectionFieldsType: VarcharBinaryVec, AutoID: false, EnableDynamicField: true,
-				ShardsNum: common.DefaultShards, Dim: common.DefaultDim}
+			cp := CollectionParams{
+				CollectionFieldsType: VarcharBinaryVec, AutoID: false, EnableDynamicField: true,
+				ShardsNum: common.DefaultShards, Dim: common.DefaultDim,
+			}
 			collName := createCollection(ctx, t, mc, cp)
 
 			// insert
-			dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: VarcharBinaryVec,
-				start: 0, nb: 1000, dim: common.DefaultDim, EnableDynamicField: true, WithRows: false}
+			dp := DataParams{
+				CollectionName: collName, PartitionName: "", CollectionFieldsType: VarcharBinaryVec,
+				start: 0, nb: 1000, dim: common.DefaultDim, EnableDynamicField: true, WithRows: false,
+			}
 			for i := 0; i < 2; i++ {
 				_, _ = insertData(ctx, t, mc, dp)
 			}
@@ -296,8 +314,10 @@ func TestSearchGroupByBinaryGrowing(t *testing.T) {
 		mc := createMilvusClient(ctx, t)
 
 		// create collection with all datatype
-		cp := CollectionParams{CollectionFieldsType: VarcharBinaryVec, AutoID: false, EnableDynamicField: true,
-			ShardsNum: common.DefaultShards, Dim: common.DefaultDim}
+		cp := CollectionParams{
+			CollectionFieldsType: VarcharBinaryVec, AutoID: false, EnableDynamicField: true,
+			ShardsNum: common.DefaultShards, Dim: common.DefaultDim,
+		}
 		collName := createCollection(ctx, t, mc, cp)
 
 		// create index and load
@@ -307,8 +327,10 @@ func TestSearchGroupByBinaryGrowing(t *testing.T) {
 		common.CheckErr(t, err, true)
 
 		// insert
-		dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: VarcharBinaryVec,
-			start: 0, nb: 1000, dim: common.DefaultDim, EnableDynamicField: true, WithRows: false}
+		dp := DataParams{
+			CollectionName: collName, PartitionName: "", CollectionFieldsType: VarcharBinaryVec,
+			start: 0, nb: 1000, dim: common.DefaultDim, EnableDynamicField: true, WithRows: false,
+		}
 		_, _ = insertData(ctx, t, mc, dp)
 
 		// search params
@@ -318,8 +340,10 @@ func TestSearchGroupByBinaryGrowing(t *testing.T) {
 
 		// search with groupBy field
 		for _, groupByField := range supportedGroupByFields {
-			_, err := mc.Search(ctx, collName, []string{}, "", []string{common.DefaultVarcharFieldName,
-				groupByField}, queryVec, common.DefaultBinaryVecFieldName, metricType, common.DefaultTopK, sp,
+			_, err := mc.Search(ctx, collName, []string{}, "", []string{
+				common.DefaultVarcharFieldName,
+				groupByField,
+			}, queryVec, common.DefaultBinaryVecFieldName, metricType, common.DefaultTopK, sp,
 				client.WithGroupByField(groupByField), client.WithSearchQueryConsistencyLevel(entity.ClStrong))
 			common.CheckErr(t, err, false, "not support search_group_by operation based on binary vector column")
 		}
@@ -356,12 +380,14 @@ func TestSearchGroupByFloatGrowing(t *testing.T) {
 					} else {
 						expr = fmt.Sprintf("%s == %v", groupByField, groupByValue)
 					}
-					resFilter, _ := mc.Search(ctx, collName, []string{}, expr, []string{common.DefaultIntFieldName,
-						groupByField}, []entity.Vector{queryVec[i]}, common.DefaultFloatVecFieldName, metricType, 1, sp, client.WithSearchQueryConsistencyLevel(entity.ClStrong))
+					resFilter, _ := mc.Search(ctx, collName, []string{}, expr, []string{
+						common.DefaultIntFieldName,
+						groupByField,
+					}, []entity.Vector{queryVec[i]}, common.DefaultFloatVecFieldName, metricType, 1, sp, client.WithSearchQueryConsistencyLevel(entity.ClStrong))
 
 					// search filter with groupByValue is the top1
 					filterTop1Pk, _ := resFilter[0].IDs.GetAsInt64(0)
-					//log.Printf("Search top1 with %s: groupByValue: %v, pkValue: %d. The returned pk by filter search is: %d",
+					// log.Printf("Search top1 with %s: groupByValue: %v, pkValue: %d. The returned pk by filter search is: %d",
 					//	groupByField, groupByValue, pkValue, filterTop1Pk)
 					if filterTop1Pk == pkValue {
 						hitsNum += 1
@@ -390,7 +416,7 @@ func TestSearchGroupByPagination(t *testing.T) {
 	// search params
 	queryVec := common.GenSearchVectors(common.DefaultNq, common.DefaultDim, entity.FieldTypeFloatVector)
 	sp, _ := entity.NewIndexIvfFlatSearchParam(32)
-	var offset = int64(10)
+	offset := int64(10)
 
 	// search pagination & groupBy
 	resGroupByPagination, _ := mc.Search(ctx, collName, []string{}, "", []string{common.DefaultIntFieldName, common.DefaultVarcharFieldName},
@@ -464,6 +490,7 @@ func TestSearchGroupByRangeSearch(t *testing.T) {
 }
 
 func TestSearchGroupByHybridSearch(t *testing.T) {
+	t.Skip("case panic")
 	indexHnsw, _ := entity.NewIndexHNSW(entity.COSINE, 8, 96)
 	mc, ctx, collName := prepareDataForGroupBySearch(t, 10, 1000, indexHnsw, false)
 
@@ -496,10 +523,12 @@ func TestSearchGroupByHybridSearch(t *testing.T) {
 			pkValue, _ := resGroupBy[i].IDs.GetAsInt64(j)
 			expr = fmt.Sprintf("%s == '%v' ", groupByField, groupByValue)
 			// 	search filter with groupByValue is the top1
-			resFilter, _ := mc.Search(ctx, collName, []string{}, expr, []string{common.DefaultIntFieldName,
-				groupByField}, []entity.Vector{queryVec[i]}, common.DefaultFloatVecFieldName, entity.COSINE, 1, sp)
+			resFilter, _ := mc.Search(ctx, collName, []string{}, expr, []string{
+				common.DefaultIntFieldName,
+				groupByField,
+			}, []entity.Vector{queryVec[i]}, common.DefaultFloatVecFieldName, entity.COSINE, 1, sp)
 			filterTop1Pk, _ := resFilter[0].IDs.GetAsInt64(0)
-			//log.Printf("Search top1 with %s: groupByValue: %v, pkValue: %d. The returned pk by filter search is: %d",
+			// log.Printf("Search top1 with %s: groupByValue: %v, pkValue: %d. The returned pk by filter search is: %d",
 			//	groupByField, groupByValue, pkValue, filterTop1Pk)
 			if filterTop1Pk == pkValue {
 				hitsNum += 1
@@ -539,6 +568,7 @@ func TestHybridSearchDifferentGroupByField(t *testing.T) {
 
 // groupBy field not existed
 func TestSearchNotExistedGroupByField(t *testing.T) {
+	t.Skip("https://github.com/milvus-io/milvus-sdk-go/issues/828")
 	// prepare data
 	indexHnsw, _ := entity.NewIndexHNSW(entity.L2, 8, 96)
 	mc, ctx, collName := prepareDataForGroupBySearch(t, 2, 1000, indexHnsw, false)
diff --git a/test/testcases/insert_test.go b/test/testcases/insert_test.go
index b35375a..00f44b0 100644
--- a/test/testcases/insert_test.go
+++ b/test/testcases/insert_test.go
@@ -415,6 +415,52 @@ func TestInsertDynamicFieldData(t *testing.T) {
 
 }
 
+// dynamic field name is same as other field name
+func TestInsertRepeatedDynamicField(t *testing.T) {
+	ctx := createContext(t, time.Second*common.DefaultTimeout)
+
+	// connect
+	mc := createMilvusClient(ctx, t)
+	nb := 1000
+
+	// create collection enable dynamic field
+	schema := common.GenSchema(common.GenRandomString(6), false, common.GenDefaultFields(false), common.WithEnableDynamicField(true))
+	createCustomerCollection(ctx, t, mc, schema, 1)
+
+	// insert column with repeated dynamic field name
+	intColumn, floatColumn, vecColumn := common.GenDefaultColumnData(0, nb, common.DefaultDim)
+	dynamicColumn := common.GenColumnData(nb, nb, entity.FieldTypeInt64, common.DefaultFloatFieldName)
+	_, errInsert := mc.Insert(ctx, schema.CollectionName, "", intColumn, floatColumn, vecColumn, dynamicColumn)
+	common.CheckErr(t, errInsert, false, "duplicated column float found")
+
+	// insert rows with repeated dynamic field name
+	type DynamicRows struct {
+		Float float32 `json:"float" milvus:"name:float"`
+	}
+
+	type dataRows struct {
+		Int64    int64       `json:"int64" milvus:"name:int64"`
+		Float    float32     `json:"float" milvus:"name:float"`
+		FloatVec []float32   `json:"floatVec" milvus:"name:floatVec"`
+		DynamicRows
+	}
+	rows := make([]interface{}, 0, 100)
+	for i := 0; i < 100; i++ {
+		row := dataRows{
+			Int64:    int64(i),
+			Float:    float32(i),
+			FloatVec: common.GenFloatVector(common.DefaultDim),
+			DynamicRows:  DynamicRows{
+				Float: 0.0,
+			},
+		}
+		rows = append(rows, row)
+	}
+
+	_, err := mc.InsertRows(context.Background(), schema.CollectionName, "", rows)
+	common.CheckErr(t, err, false, "column has duplicated name: float when parsing field: DynamicRows")
+}
+
 // test insert array column with empty data
 func TestInsertEmptyArray(t *testing.T) {
 	ctx := createContext(t, time.Second*common.DefaultTimeout)
diff --git a/test/testcases/query_test.go b/test/testcases/query_test.go
index 2833fad..59148e8 100644
--- a/test/testcases/query_test.go
+++ b/test/testcases/query_test.go
@@ -984,12 +984,16 @@ func TestQueryJsonDynamicExpr(t *testing.T) {
 	// verify output fields and count, dynamicNumber value
 	common.CheckOutputFields(t, queryRes, []string{common.DefaultIntFieldName, common.DefaultJSONFieldName, common.DefaultDynamicNumberField})
 	require.Equal(t, 10, queryRes.GetColumn(common.DefaultJSONFieldName).Len())
+
+	// verify only dynamic part key: common.DefaultDynamicNumberField
 	dynamicNumColumn := queryRes.GetColumn(common.DefaultDynamicNumberField)
-	var numberData []int64
-	for i := 0; i < dynamicNumColumn.Len(); i++ {
-		line, _ := dynamicNumColumn.GetAsInt64(i)
-		numberData = append(numberData, line)
+	numberValues := make([]int32, 0, 10)
+	for i := 0; i < 10; i++ {
+		numberValues = append(numberValues, int32(i))
 	}
+	_expColumn := common.MergeColumnsToDynamic(10, common.GenDynamicFieldData(0, 10)[:1], common.DefaultDynamicFieldName)
+	expColumn := entity.NewColumnDynamic(_expColumn, common.DefaultDynamicNumberField)
+	common.EqualColumn(t, dynamicNumColumn, expColumn)
 }
 
 // test query and output both json and dynamic field