@@ -13,17 +13,19 @@ const MaxFieldValueLength = 1048576
13
13
// ValidateFields will return a PartialWriteError if:
14
14
// - the point has inconsistent fields, or
15
15
// - 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 ) {
17
17
pointSize := point .StringSize ()
18
18
iter := point .FieldIterator ()
19
+ var fieldsToCreate []* FieldCreate
20
+
19
21
for iter .Next () {
20
22
if ! skipSizeValidation {
21
23
// Check for size of field too large. Note it is much cheaper to check the whole point size
22
24
// than checking the StringValue size (StringValue potentially takes an allocation if it must
23
25
// unescape the string, and must at least parse the string)
24
26
if pointSize > MaxFieldValueLength && iter .Type () == models .String {
25
27
if sz := len (iter .StringValue ()); sz > MaxFieldValueLength {
26
- return PartialWriteError {
28
+ return nil , PartialWriteError {
27
29
Reason : fmt .Sprintf (
28
30
"input field \" %s\" on measurement \" %s\" is too long, %d > %d" ,
29
31
iter .FieldKey (), point .Name (), sz , MaxFieldValueLength ),
@@ -33,14 +35,9 @@ func ValidateFields(mf *MeasurementFields, point models.Point, skipSizeValidatio
33
35
}
34
36
}
35
37
38
+ fieldKey := iter .FieldKey ()
36
39
// 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 ) {
44
41
continue
45
42
}
46
43
@@ -49,18 +46,26 @@ func ValidateFields(mf *MeasurementFields, point models.Point, skipSizeValidatio
49
46
continue
50
47
}
51
48
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 {
55
61
Reason : fmt .Sprintf (
56
62
"%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 ),
58
64
Dropped : 1 ,
59
65
}
60
66
}
61
67
}
62
-
63
- return nil
68
+ return fieldsToCreate , nil
64
69
}
65
70
66
71
// dataTypeFromModelsFieldType returns the influxql.DataType that corresponds to the
0 commit comments