douglasshuang
High Performance PostgreSQL for Rails: Off-by-one bug in `SCRUB_BATCHES` procedure (page 65)
The SCRUB_BATCHES procedure has an off-by-one bug that causes it to skip one row after each batch. Here is output showing the incorrect behavior:
owner@localhost:5432 rideshare_development# CALL SCRUB_BATCHES();
NOTICE: current_id: 1 - Number of rows updated: 1000
NOTICE: current_id: 1002 - Number of rows updated: 1000
NOTICE: current_id: 2003 - Number of rows updated: 1000
NOTICE: current_id: 3004 - Number of rows updated: 1000
NOTICE: current_id: 4005 - Number of rows updated: 1000
NOTICE: current_id: 5006 - Number of rows updated: 1000
NOTICE: current_id: 6007 - Number of rows updated: 1000
NOTICE: current_id: 7008 - Number of rows updated: 1000
NOTICE: current_id: 8009 - Number of rows updated: 1000
NOTICE: current_id: 9010 - Number of rows updated: 1000
NOTICE: current_id: 10011 - Number of rows updated: 1000
NOTICE: current_id: 11012 - Number of rows updated: 1000
NOTICE: current_id: 12013 - Number of rows updated: 1000
NOTICE: current_id: 13014 - Number of rows updated: 1000
NOTICE: current_id: 14015 - Number of rows updated: 1000
NOTICE: current_id: 15016 - Number of rows updated: 1000
NOTICE: current_id: 16017 - Number of rows updated: 1000
NOTICE: current_id: 17018 - Number of rows updated: 1000
NOTICE: current_id: 18019 - Number of rows updated: 1000
NOTICE: current_id: 19020 - Number of rows updated: 1000
NOTICE: current_id: 20021 - Number of rows updated: 190
CALL
owner@localhost:5432 rideshare_development# SELECT id, email FROM users WHERE id IN (1000, 1001, 1002);
id | email
------+-----------------------------------------
1000 | 6ddd3da1abbacd649a2853d9@email.com
1001 | Jenee-Robel-driver-1000@email.com
1002 | efa11a15129ea1bed93f96@email.com
(3 rows)
The bug is in this assignment statement at the end of the loop body:
current_id := current_id + batch_size + 1;
It should read as follows:
current_id := current_id + batch_size;
Here is the output after the correction:
owner@localhost:5432 rideshare_development# CALL SCRUB_BATCHES();
NOTICE: current_id: 1 - Number of rows updated: 1000
NOTICE: current_id: 1001 - Number of rows updated: 1000
NOTICE: current_id: 2001 - Number of rows updated: 1000
NOTICE: current_id: 3001 - Number of rows updated: 1000
NOTICE: current_id: 4001 - Number of rows updated: 1000
NOTICE: current_id: 5001 - Number of rows updated: 1000
NOTICE: current_id: 6001 - Number of rows updated: 1000
NOTICE: current_id: 7001 - Number of rows updated: 1000
NOTICE: current_id: 8001 - Number of rows updated: 1000
NOTICE: current_id: 9001 - Number of rows updated: 1000
NOTICE: current_id: 10001 - Number of rows updated: 1000
NOTICE: current_id: 11001 - Number of rows updated: 1000
NOTICE: current_id: 12001 - Number of rows updated: 1000
NOTICE: current_id: 13001 - Number of rows updated: 1000
NOTICE: current_id: 14001 - Number of rows updated: 1000
NOTICE: current_id: 15001 - Number of rows updated: 1000
NOTICE: current_id: 16001 - Number of rows updated: 1000
NOTICE: current_id: 17001 - Number of rows updated: 1000
NOTICE: current_id: 18001 - Number of rows updated: 1000
NOTICE: current_id: 19001 - Number of rows updated: 1000
NOTICE: current_id: 20001 - Number of rows updated: 210
CALL
owner@localhost:5432 rideshare_development# SELECT id, email FROM users WHERE id IN (1000, 1001, 1002);
id | email
------+-----------------------------------------
1000 | 4b44cfd50568b6a9c54@email.com
1001 | fc7266ea448226ed25ccdc7f1@email.com
1002 | 6fdbe4620e31b4464b1b5fd95c64c@email.com
(3 rows)
Marked As Solved
andatki
Author of High Performance PostgreSQL for Rails
Hi @douglasshuang. Thank you for the detailed bug report. I was able to verify what you’re saying and agree that the last assignment within the loop should not add 1. I took that off as you suggested and the print output matches what you have.
I’m submitting a fix and hopefully it makes it into a future edition of the book. Thanks again for taking the time to notice this and prepare a detailed write-up!
1
Also Liked
douglasshuang
My pleasure, Thank you!
1
Popular Pragmatic Bookshelf topics
Following the steps described in Chapter 6 of the book, I’m stuck with running the migration as described on page 84:
bundle exec sequel...
New
Title: Web Development with Clojure, Third Edition, pg 116
Hi - I just started chapter 5 and I am stuck on page 116 while trying to star...
New
Hello! On page xix of the preface, it says there is a community forum "… for help if your’re stuck on one of the exercises in this book… ...
New
A Common-Sense Guide to Data Structures and Algorithms, Second Edition by Jay Wengrow @jaywengrow
Hi,
I have the paperback version of t...
New
I think I might have found a problem involving SwitchCompat, thumbTint, and trackTint.
As entered, the SwitchCompat changes color to hol...
New
When trying to run tox in parallel as explained on page 151, I got the following error:
tox: error: argument -p/–parallel: expected one...
New
The allprojects block listed on page 245 produces the following error when syncing gradle:
“org.gradle.api.GradleScriptException: A prob...
New
Hi, I’ve got a question about the implementation of PubSub when using a Phoenix.Socket.Transport behaviour rather than channels.
Before ...
New
Book: Programming Phoenix LiveView, page 142 (157/378), file lib/pento_web/live/product_live/form_component.ex, in the function below:
d...
New
From page 13:
On Python 3.7, you can install the libraries with pip by running these commands inside a Python venv using Visual Studio ...
New
Other popular topics
Reading something? Working on something? Planning something? Changing jobs even!?
If you’re up for sharing, please let us know what you’...
New
My first contact with Erlang was about 2 years ago when I used RabbitMQ, which is written in Erlang, for my job. This made me curious and...
New
New
Small essay with thoughts on macOS vs. Linux:
I know @Exadra37 is just waiting around the corner to scream at me “I TOLD YOU SO!!!” but I...
New
Tailwind CSS is an exciting new CSS framework that allows you to design your site by composing simple utility classes to create complex e...
New
Build efficient applications that exploit the unique benefits of a pure functional language, learning from an engineer who uses Haskell t...
New
A Brief Review of the Minisforum V3 AMD Tablet.
Update: I have created an awesome-minisforum-v3 GitHub repository to list information fo...
New
I’m able to do the “artistic” part of game-development; character designing/modeling, music, environment modeling, etc.
However, I don’t...
New
Explore the power of Ash Framework by modeling and building the domain for a real-world web application.
Rebecca Le @sevenseacat and ...
New
This is cool!
DEEPSEEK-V3 ON M4 MAC: BLAZING FAST INFERENCE ON APPLE SILICON
We just witnessed something incredible: the largest open-s...
New
Categories:
Sub Categories:
Popular Portals
- /elixir
- /rust
- /wasm
- /ruby
- /erlang
- /phoenix
- /keyboards
- /python
- /js
- /rails
- /security
- /go
- /swift
- /vim
- /java
- /clojure
- /typescript
- /emacs
- /haskell
- /svelte
- /onivim
- /kotlin
- /react
- /c-plus-plus
- /crystal
- /tailwind
- /gleam
- /ocaml
- /elm
- /vscode
- /flutter
- /html
- /ash
- /deepseek
- /zig
- /opensuse
- /centos
- /php
- /react-native
- /scala
- /lisp
- /sublime-text
- /textmate
- /nixos
- /debian
- /agda
- /deno
- /django
- /kubuntu
- /arch-linux
- /nodejs
- /spring
- /ubuntu
- /revery
- /manjaro
- /julia
- /lua
- /diversity
- /quarkus
- /laravel









