Repository: influxdata/influxdb
File: cmd/influxd/inspect/delete_tsm/delete_tsm.go (Go)

Code before:
			}

			// Skip block if this is the measurement and time range we are deleting.
			series, _ := tsm1.SeriesAndFieldFromCompositeKey(key)
			measurement, tags := models.ParseKey(series)
			if measurement == a.measurement || (a.sanitize && !models.ValidKeyTokens(measurement, tags)) {
				if a.verbose {
					cmd.Printf("deleting block: %s (%s-%s) sz=%d",
						key,
						time.Unix(0, minTime).UTC().Format(time.RFC3339Nano),
						time.Unix(0, maxTime).UTC().Format(time.RFC3339Nano),
						len(block),
					)
				}
				continue
			}

			if err := w.WriteBlock(key, minTime, maxTime, block); err != nil {
				return 0, fmt.Errorf("failed to write block: %w", err)
			}
			hasData = true
		}

		// Write index & close.
		// It is okay to have no index values if no block was written
		if err := w.WriteIndex(); err != nil && !(hasData || errors.Is(err, tsm1.ErrNoValues)) {
			return 0, fmt.Errorf("failed to write index to TSM file: %w", err)
		}
		return w.Size(), nil
	}()
	if err != nil {
		return err
	}

	if size > 0 {
		// Replace original file with new file.
		if err := file.RenameFile(outputPath, path); err != nil {
			return fmt.Errorf("failed to update TSM file %q: %w", path, err)
		}
	} else {
		// Empty TSM file, remove both original and temp
		if err = os.RemoveAll(path); err != nil {
			err = fmt.Errorf("failed to remove empty TSM file %q: %w", path, err)
		}
		if err2 := os.RemoveAll(outputPath); err2 != nil && err == nil {
			return fmt.Errorf("failed to remove temporary file %q: %w", outputPath, err2)
		}
		return err
	}
	return nil
}

Review comment (bug):
It seems like this will discard errors as long as `hasData = true`. For instance, if `hasData = true` and `w.WriteIndex` returns an out of space error (`syscall.ENOSPC`):
```
err != nil && !(hasData || errors.Is(err, tsm1.ErrNoValues))
syscall.ENOSPC != nil && !(true || errors.Is(syscall.ENOSPC, tsm1.ErrNoValues))
true && !(true || false)
true && !true
true && false
false
```

So the conditional will evaluate to false and we will ignore the `syscall.ENOSPC` returned by `w.WriteIndex`.

Am I missing something, or did I get my logic incorrect?

Code after:
			}

			// Skip block if this is the measurement and time range we are deleting.
			series, _ := tsm1.SeriesAndFieldFromCompositeKey(key)
			measurement, tags := models.ParseKey(series)
			if measurement == a.measurement || (a.sanitize && !models.ValidKeyTokens(measurement, tags)) {
				if a.verbose {
					cmd.Printf("deleting block: %s (%s-%s) sz=%d",
						key,
						time.Unix(0, minTime).UTC().Format(time.RFC3339Nano),
						time.Unix(0, maxTime).UTC().Format(time.RFC3339Nano),
						len(block),
					)
				}
				continue
			}

			if err := w.WriteBlock(key, minTime, maxTime, block); err != nil {
				return 0, fmt.Errorf("failed to write block: %w", err)
			}
			hasData = true
		}

		// Write index & close.
		// It is okay to have no index values if no block was written

		if err := w.WriteIndex(); err != nil && !(errors.Is(err, tsm1.ErrNoValues) && !hasData) {
			return 0, fmt.Errorf("failed to write index to TSM file: %w", err)
		}
		return w.Size(), nil
	}()
	if err != nil {
		return err
	}

	if size > 0 {
		// Replace original file with new file.
		if err := file.RenameFile(outputPath, path); err != nil {
			return fmt.Errorf("failed to update TSM file %q: %w", path, err)
		}
	} else {
		// Empty TSM file, remove both original and temp
		if err = os.RemoveAll(path); err != nil {
			err = fmt.Errorf("failed to remove empty TSM file %q: %w", path, err)
		}
		if err2 := os.RemoveAll(outputPath); err2 != nil && err == nil {
			return fmt.Errorf("failed to remove temporary file %q: %w", outputPath, err2)
		}
		return err
	}
	return nil