@@ -13,17 +13,19 @@ const MaxFieldValueLength = 1048576
1313// ValidateFields will return a PartialWriteError if:
1414// - the point has inconsistent fields, or
1515// - the point has fields that are too long
16- func ValidateFields (mf * MeasurementFields , point models.Point , skipSizeValidation bool ) error {
16+ func ValidateFields (mf * MeasurementFields , point models.Point , skipSizeValidation bool ) ([] * FieldCreate , error ) {
1717 pointSize := point .StringSize ()
1818 iter := point .FieldIterator ()
19+ var fieldsToCreate []* FieldCreate
20+
1921 for iter .Next () {
2022 if ! skipSizeValidation {
2123 // Check for size of field too large. Note it is much cheaper to check the whole point size
2224 // than checking the StringValue size (StringValue potentially takes an allocation if it must
2325 // unescape the string, and must at least parse the string)
2426 if pointSize > MaxFieldValueLength && iter .Type () == models .String {
2527 if sz := len (iter .StringValue ()); sz > MaxFieldValueLength {
26- return PartialWriteError {
28+ return nil , PartialWriteError {
2729 Reason : fmt .Sprintf (
2830 "input field \" %s\" on measurement \" %s\" is too long, %d > %d" ,
2931 iter .FieldKey (), point .Name (), sz , MaxFieldValueLength ),
@@ -33,14 +35,9 @@ func ValidateFields(mf *MeasurementFields, point models.Point, skipSizeValidatio
3335 }
3436 }
3537
38+ fieldKey := iter .FieldKey ()
3639 // Skip fields name "time", they are illegal.
37- if bytes .Equal (iter .FieldKey (), timeBytes ) {
38- continue
39- }
40-
41- // If the fields is not present, there cannot be a conflict.
42- f := mf .FieldBytes (iter .FieldKey ())
43- if f == nil {
40+ if bytes .Equal (fieldKey , timeBytes ) {
4441 continue
4542 }
4643
@@ -49,18 +46,26 @@ func ValidateFields(mf *MeasurementFields, point models.Point, skipSizeValidatio
4946 continue
5047 }
5148
52- // If the types are not the same, there is a conflict.
53- if f .Type != dataType {
54- return PartialWriteError {
49+ // If the field is not present, remember to create it.
50+ f := mf .FieldBytes (fieldKey )
51+ if f == nil {
52+ fieldsToCreate = append (fieldsToCreate , & FieldCreate {
53+ Measurement : point .Name (),
54+ Field : & Field {
55+ Name : string (fieldKey ),
56+ Type : dataType ,
57+ }})
58+ } else if f .Type != dataType {
59+ // If the types are not the same, there is a conflict.
60+ return nil , PartialWriteError {
5561 Reason : fmt .Sprintf (
5662 "%s: input field \" %s\" on measurement \" %s\" is type %s, already exists as type %s" ,
57- ErrFieldTypeConflict , iter . FieldKey () , point .Name (), dataType , f .Type ),
63+ ErrFieldTypeConflict , fieldKey , point .Name (), dataType , f .Type ),
5864 Dropped : 1 ,
5965 }
6066 }
6167 }
62-
63- return nil
68+ return fieldsToCreate , nil
6469}
6570
6671// dataTypeFromModelsFieldType returns the influxql.DataType that corresponds to the
0 commit comments