
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

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

your book suggests to use Image.toByteData() to convert image to bytes, however I get the following error: "the getter ‘toByteData’ isn’t...
New

Hi,
build fails on:
bracket-lib = “~0.8.1”
when running on Mac Mini M1 Rust version 1.5.0:
Compiling winit v0.22.2
error[E0308]: mi...
New

This isn’t directly about the book contents so maybe not the right forum…but in some of the code apps (e.g. turbo/06) it sends a TURBO_ST...
New

Running mix deps.get in the sensor_hub directory fails with the following error:
** (Mix) No SSH public keys found in ~/.ssh. An ssh aut...
New

I’m under the impression that when the reader gets to page 136 (“View Data with the Database Inspector”), the code SHOULD be able to buil...
New

Is there any place where we can discuss the solutions to some of the exercises? I can figure most of them out, but am having trouble with...
New

Hi all,
currently I wonder how the Tailwind colours work (or don’t work).
For example, in app/views/layouts/application.html.erb I have...
New

AWDWR 7, page 152, page 153:
Hello everyone,
I’m a little bit lost on the hotwire part. I didn’t fully understand it.
On page 152 @rub...
New

Docker-Machine became part of the Docker Toolbox, which was deprecated in 2020, long after Docker Desktop supported Docker Engine nativel...
New
Other popular topics

I know that -t flag is used along with -i flag for getting an interactive shell. But I cannot digest what the man page for docker run com...
New
New

Just done a fresh install of macOS Big Sur and on installing Erlang I am getting:
asdf install erlang 23.1.2
Configure failed.
checking ...
New

Not sure if following fits exactly this thread, or if we should have a hobby thread…
For many years I’m designing and building model air...
New

Build highly interactive applications without ever leaving Elixir, the way the experts do. Let LiveView take care of performance, scalabi...
New

Crystal recently reached version 1. I had been following it for awhile but never got to really learn it. Most languages I picked up out o...
New

Think Again 50% Off Sale »
The theme of this sale is new perspectives on familiar topics.
Enter coupon code ThinkAgain2021 at checkout t...
New

Hello everyone! This thread is to tell you about what authors from The Pragmatic Bookshelf are writing on Medium.
New

Biggest jackpot ever apparently! :upside_down_face:
I don’t (usually) gamble/play the lottery, but working on a program to predict the...
New

If you get Can't find emacs in your PATH when trying to install Doom Emacs on your Mac you… just… need to install Emacs first! :lol:
bre...
New
Categories:
Sub Categories:
Popular Portals
- /elixir
- /rust
- /ruby
- /wasm
- /erlang
- /phoenix
- /keyboards
- /rails
- /js
- /python
- /security
- /go
- /swift
- /vim
- /clojure
- /emacs
- /haskell
- /java
- /onivim
- /svelte
- /typescript
- /crystal
- /c-plus-plus
- /kotlin
- /tailwind
- /gleam
- /ocaml
- /react
- /elm
- /flutter
- /vscode
- /ash
- /opensuse
- /centos
- /php
- /deepseek
- /html
- /zig
- /scala
- /textmate
- /sublime-text
- /nixos
- /debian
- /lisp
- /agda
- /react-native
- /kubuntu
- /arch-linux
- /revery
- /django
- /ubuntu
- /spring
- /manjaro
- /diversity
- /nodejs
- /lua
- /c
- /slackware
- /julia
- /neovim