BUG #19887: cube expression index returns wrong rows after extra_float_digits change

From: PG Bug reporting form <noreply(at)postgresql(dot)org>
To: pgsql-bugs(at)lists(dot)postgresql(dot)org
Cc: idrissaajalloh(at)gmail(dot)com
Subject: BUG #19887: cube expression index returns wrong rows after extra_float_digits change
Date: 2026-11-11 15:07:37
Message-ID: 19887-b2be0d8951d8498b@postgresql.org
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

The following bug has been logged on the website:

Bug reference: 19887
Logged by: Wren
Email address: idrissaajalloh(at)gmail(dot)com
PostgreSQL version: 18.6
Operating system: Linux/amd64
Description:

A cube expression index built with extra_float_digits = 0 returns no rows
after the setting is changed to 3, while sequential evaluation of the same
predicate returns one row. cube_out(cube) is marked IMMUTABLE, but the same
cube value is rendered as (1.23456789012346) with the first setting and
(1.2345678901234567) with the second.

An IMMUTABLE output function must produce the same result for the same
input. Changing a session setting therefore should not make indexed and
sequential evaluation of the same expression disagree.

How to repeat:

\set ON_ERROR_STOP on
DROP TABLE IF EXISTS points;
DROP EXTENSION IF EXISTS cube;
CREATE EXTENSION cube;

SELECT p.provolatile AS cube_out_volatility
FROM pg_proc AS p
WHERE p.oid = 'cube_out(cube)'::regprocedure;

SET extra_float_digits = 0;
CREATE TABLE points(c cube);
INSERT INTO points VALUES ('(1.2345678901234567)'::cube);
SELECT c::text AS output_at_zero
FROM points;
CREATE INDEX points_text_idx ON points ((c::text));

SET extra_float_digits = 3;
SELECT c::text AS output_at_three
FROM points;

SET enable_seqscan = on;
SET enable_indexscan = off;
SET enable_bitmapscan = off;
SELECT count(*) AS seq_count
FROM points
WHERE c::text = '(1.2345678901234567)';

SET enable_indexscan = on;
SET enable_bitmapscan = on;
SET enable_seqscan = off;
SELECT count(*) AS index_count
FROM points
WHERE c::text = '(1.2345678901234567)';

EXPLAIN (COSTS OFF)
SELECT count(*)
FROM points
WHERE c::text = '(1.2345678901234567)';

RESET enable_seqscan;
RESET enable_indexscan;
RESET enable_bitmapscan;
RESET extra_float_digits;
DROP TABLE points;
DROP EXTENSION cube;

The relevant output was:

cube_out_volatility
---------------------
i
(1 row)

output_at_zero
--------------------
(1.23456789012346)
(1 row)

output_at_three
----------------------
(1.2345678901234567)
(1 row)

seq_count
-----------
1
(1 row)

index_count
-------------
0
(1 row)

QUERY PLAN
------------------------------------------------------------
Aggregate
-> Index Scan using points_text_idx on points
Index Cond: ((c)::text = '(1.2345678901234567)'::text)
(3 rows)

The issue was reproduced on PostgreSQL 18.6 on Linux/amd64 with the cube
extension and the session-local settings shown above. The IMMUTABLE
declaration permits c::text in the expression index even though its result
changes with extra_float_digits, leaving the index with text generated under
the earlier setting. This occurs when cube text output is stored in an
expression index and extra_float_digits changes before the indexed
expression is queried.

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Fujii Masao 2026-11-11 15:18:40 Re: BUG #19880: hstore(record) expression index returns wrong rows after TimeZone change
Previous Message PG Bug reporting form 2026-11-11 14:49:13 BUG #19886: pg_terminate_backend timeout expires early after latch wakeups