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
page 37
ANTLRInputStream input = new ANTLRInputStream(is);
as of ANTLR 4 .8 should be:
CharStream stream = CharStreams.fromStream(i...
New
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
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’m not quite sure what’s going on here, but I’m unable to have to containers successfully complete the Readiness/Liveness checks. I’m im...
New
Title: Build a Weather Station with Elixir and Nerves: Problem connecting to Postgres with Grafana on (page 64)
If you follow the defau...
New
When I run the coverage example to report on missing lines, I get:
pytest --cov=cards --report=term-missing ch7
ERROR: usage: pytest [op...
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
Hi, I’ve got a question about the implementation of PubSub when using a Phoenix.Socket.Transport behaviour rather than channels.
Before ...
New
I just bought this book to learn about Android development, and I’m already running into a major issue in Ch. 1, p. 20: “Update activity...
New
@mfazio23
Android Studio will not accept anything I do when trying to use the Transformations class, as described on pp. 140-141. Googl...
New
Other popular topics
Take your Go skills to the next level by learning how to design, develop, and deploy a distributed service. Start from the bare essential...
New
Design and develop sophisticated 2D games that are as much fun to make as they are to play. From particle effects and pathfinding to soci...
New
You might be thinking we should just ask who’s not using VSCode :joy: however there are some new additions in the space that might give V...
New
New
I ended up cancelling my Moonlander order as I think it’s just going to be a bit too bulky for me.
I think the Planck and the Preonic (o...
New
Learn different ways of writing concurrent code in Elixir and increase your application's performance, without sacrificing scalability or...
New
We’ve talked about his book briefly here but it is quickly becoming obsolete - so he’s decided to create a series of 7 podcasts, the firs...
New
Rails 7 completely redefines what it means to produce fantastic user experiences and provides a way to achieve all the benefits of single...
New
Author Spotlight:
Peter Ullrich
@PJUllrich
Data is at the core of every business, but it is useless if nobody can access and analyze ...
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
Categories:
Sub Categories:
Popular Portals
- /elixir
- /rust
- /wasm
- /ruby
- /erlang
- /phoenix
- /keyboards
- /python
- /js
- /rails
- /security
- /go
- /swift
- /vim
- /java
- /clojure
- /emacs
- /haskell
- /typescript
- /svelte
- /onivim
- /kotlin
- /c-plus-plus
- /crystal
- /tailwind
- /react
- /gleam
- /ocaml
- /elm
- /vscode
- /flutter
- /html
- /ash
- /deepseek
- /zig
- /opensuse
- /centos
- /php
- /scala
- /react-native
- /lisp
- /sublime-text
- /textmate
- /nixos
- /debian
- /agda
- /deno
- /django
- /kubuntu
- /nodejs
- /arch-linux
- /spring
- /ubuntu
- /revery
- /manjaro
- /julia
- /diversity
- /lua
- /quarkus
- /markdown









