Repository: influxdata/influxdb
File: tsdb/shard.go (Go)

Code before:
			}
			validField = true
			break
		}
		if !validField {
			if reason == "" {
				reason = fmt.Sprintf(
					"invalid field name: input field \"%s\" on measurement \"%s\" is invalid",
					"time", string(p.Name()))
			}
			dropped++
			continue
		}

		// Skip any points whose keys have been dropped. Dropped has already been incremented for them.
		if len(droppedKeys) > 0 && bytesutil.Contains(droppedKeys, keys[i]) {
			continue
		}

		err := func(p models.Point, iter models.FieldIterator) error {
			var newFields []*FieldCreate
			var validateErr error
			name := p.Name()
			mf := engine.MeasurementFields(name)
			// Check with the field validator.
			if newFields, validateErr = ValidateFields(mf, p, s.options.Config.SkipFieldSizeValidation); validateErr != nil {
				var err PartialWriteError
				switch {
				case errors.As(validateErr, &err):
					// This will turn into an error later, outside this lambda
					if reason == "" {
						reason = err.Reason
					}
					dropped += err.Dropped
					atomic.AddInt64(&s.stats.WritePointsDropped, int64(err.Dropped))
				default:
					return err
				}
				return nil
			}

			points[j] = points[i]
			j++
			fieldsToCreate = append(fieldsToCreate, newFields...)
			return nil
		}(p, iter)
		if err != nil {
			return nil, nil, err
		}
	}
	if dropped > 0 {

Review comment (bug):
I also now notice (and should have noticed in #25998 instead that the point's field names ("key") is checked against `timeBytes` twice. 

First here in `validateSeriesAndFields`: 
https://github.com/influxdata/influxdb/blob/cda0ef4445a7f23eaeba1d959a4dab1bbb354821/tsdb/shard.go#L684-L690

~Actually - I think this first check against timeBytes is totally broken. The check is inverted - it's missing an `!` meaning the second check is actually doing the work and this first check is a just a waste.~ EDIT: see next comment: this is doing some work but its nearly redundant with ValidateFields and a minor update there could delete one of the two checks for illegal `time` fields. 

and then later in `ValidateFields`:

https://github.com/influxdata/influxdb/blob/89b4b9720d66b8c1a95dfa209c8663dea80a84d1/tsdb/field_validator.go#L38-L42

My recommendation is to clean this up to but in a separate pr: It'll be one of the 5 of us who will next be reading this code so perhaps think kindly on our future selves!

Code after:
			}
			validField = true
			break
		}
		if !validField {
			if reason == "" {
				reason = fmt.Sprintf(
					"invalid field name: input field \"%s\" on measurement \"%s\" is invalid",
					"time", string(p.Name()))
			}
			dropped++
			continue
		}

		// Skip any points whose keys have been dropped. Dropped has already been incremented for them.
		if len(droppedKeys) > 0 && bytesutil.Contains(droppedKeys, keys[i]) {
			continue
		}

		var newFields []*FieldCreate
		var validateErr error
		name := p.Name()
		mf := engine.MeasurementFields(name)
		// Check with the field validator.
		if newFields, validateErr = ValidateFields(mf, p, s.options.Config.SkipFieldSizeValidation); validateErr != nil {
			var err PartialWriteError
			switch {
			case errors.As(validateErr, &err):
				// This will turn into an error later, outside this lambda
				if reason == "" {
					reason = err.Reason
				}
				dropped += err.Dropped
				atomic.AddInt64(&s.stats.WritePointsDropped, int64(err.Dropped))
				continue
			default:
				// Return validateErr, because err will be nil here
				return nil, nil, validateErr
			}
		}

		points[j] = points[i]
		j++
		fieldsToCreate = append(fieldsToCreate, newFields...)
	}
	if dropped > 0 {
		err = PartialWriteError{Reason: reason, Dropped: dropped, Database: s.database, RetentionPolicy: s.retentionPolicy}
	}

	return points[:j], fieldsToCreate, err
}