BUG #14205: Weird cast long int values to numeric leading to seq scan

From: maxim(dot)boguk(at)gmail(dot)com
To: pgsql-bugs(at)postgresql(dot)org
Subject: BUG #14205: Weird cast long int values to numeric leading to seq scan
Date: 2016-06-21 14:42:00
Message-ID: 20160621144200.5792.49545@wrigleys.postgresql.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

The following bug has been logged on the website:

Bug reference: 14205
Logged by: Maksym Boguk
Email address: maxim(dot)boguk(at)gmail(dot)com
PostgreSQL version: 9.5.3
Operating system: Linux
Description:

If an input value of the field=value goes over bigint range, the database
switches to the field::numeric=value::numeric plan, which leads to the seq
scan as result.

There is two query where problem visible (id any of int/bigint):
Good one (index scan):
explain select * from jobs where id=1000000000000000000;
QUERY PLAN
------------------------------------------------------------------------
Index Scan using jobs_pkey on jobs (cost=0.57..0.79 rows=1 width=527)
Index Cond: (id = '1000000000000000000'::bigint)

Bad one (please note the seq scan and rows estimation):
explain select * from jobs where id=10000000000000000000;
QUERY PLAN
-----------------------------------------------------------------
Seq Scan on jobs (cost=0.00..2722925.20 rows=645700 width=527)
Filter: ((id)::numeric = '10000000000000000000'::numeric)

This problem behavior stays the same over all range 9.2 - 9.5 versions.
It provides an easy way to DoS the database/project (5-10-20 seq scan over
large table usually mean to unresponsive database because IO or CPU
overload).

This problem doesn't affect server side prepared queries with placeholders,
but given almost ubiquitous usage of the pgbouncer in majority of the web
projects the server side prepared disabled almost everywhere.

I don't know is it 'work as designed' or result of some oversight, but IMHO
current behavior broken from common sense point of view (even if provides
correct empty result, after sequentially scanning whole 100Gb table).

PS: I know that it good practice to validate input before send it to the
database in any case, but from my experience the best what I ever seen in
real projects it verification input value via /^\d+$/ which provide no real
protection again this issue.

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Tom Lane 2016-06-21 14:49:40 Re: BUG #14205: Weird cast long int values to numeric leading to seq scan
Previous Message Michael Paquier 2016-06-21 06:20:21 Re: BUG #14204: COMPATIBILITY