The Upsert That Forgot to Add — Java Bug Hunt

Inspired by analytics counters everywhere: the "ON CONFLICT ADD" upsert that actually does "ON CONFLICT REPLACE".

  • Language: Java
  • Layer: Database
  • Difficulty: Easy
  • Concepts: Upserts, Counters
  • Modelled on: Analytics counters
  • Visible tests: deltas accumulate on existing keys; new keys initialise with the delta
  • Reward: 50 XP for a complete fix

Briefing

Inspired by analytics counters everywhere: the "ON CONFLICT ADD" upsert that actually does "ON CONFLICT REPLACE". Every flush OVERWRITES the day's count with the latest batch, and the dashboards saw only the last five minutes of every day.

CounterUpdater.java merges a delta into the store. The store (locked) is a plain map.

Bug report

BUG-UPSERT · Priority: High · Reported by: analytics

applyDelta(store, key, delta):

  • existing key -> ADD delta to the stored value
  • new key -> initialise with delta

Observed: page_views was 40,000 at 23:55 and 312 at midnight — each batch replaced the total.

Logs

[flush] page_views <- 312 (was 40188)

The code as shipped

CounterUpdater.java (editable)

class CounterUpdater {
    static void applyDelta(CounterStore store, String key, long delta) {
        store.put(key, delta);
    }
}

Read-only context: CounterStore.java.

Open the hunt to edit the files, run the visible tests and submit against the hidden ones. More Java bug hunts.