BUG #17884: gist_page_items() crashes for a non-leaf page of an index with non-key columns - Mailing list pgsql-bugs

From PG Bug reporting form
Subject BUG #17884: gist_page_items() crashes for a non-leaf page of an index with non-key columns
Date
Msg-id 17884-cb8c326522977acb@postgresql.org
Whole thread Raw
Responses Re: BUG #17884: gist_page_items() crashes for a non-leaf page of an index with non-key columns
List pgsql-bugs
The following bug has been logged on the website:

Bug reference:      17884
Logged by:          Alexander Lakhin
Email address:      exclusion@gmail.com
PostgreSQL version: 15.2
Operating system:   Ubuntu 22.04
Description:

The following script:
CREATE TABLE tbl(p point, t1 text, t2 text);
CREATE INDEX tbl_gist_idx ON tbl USING gist (p) INCLUDE (t1, t2);
INSERT INTO tbl SELECT point(x, x), repeat('x', 500), repeat('x', 500) FROM
generate_series(1, 100) AS x;

CREATE EXTENSION pageinspect;
SELECT * FROM gist_page_items(get_raw_page('tbl_gist_idx', 0),
'tbl_gist_idx');

causes a server crash with the following stack trace:
Core was generated by `postgres: law regression [local] SELECT
                        '.
Program terminated with signal SIGSEGV, Segmentation fault.

warning: Section `.reg-xstate/681022' in core file too small.
#0  0x000055c05775638c in index_deform_tuple_internal
(tupleDescriptor=0x7f3b2cb45558, values=0x7ffe813b5cf0, 
    isnull=0x7ffe813b5ca0, tp=0x55c058cb5630 "", bp=0x55c058cb5630 "",
hasnulls=0) at indextuple.c:520
520                                     off = att_align_pointer(off,
thisatt->attalign, -1,
(gdb) bt
#0  0x000055c05775638c in index_deform_tuple_internal
(tupleDescriptor=0x7f3b2cb45558, values=0x7ffe813b5cf0, 
    isnull=0x7ffe813b5ca0, tp=0x55c058cb5630 "", bp=0x55c058cb5630 "",
hasnulls=0) at indextuple.c:520
#1  0x000055c057756186 in index_deform_tuple (tup=0x55c058cb5628,
tupleDescriptor=0x7f3b2cb45558, 
    values=0x7ffe813b5cf0, isnull=0x7ffe813b5ca0) at indextuple.c:467
#2  0x00007f3b38c79abc in gist_page_items (fcinfo=0x55c058c77420) at
gistfuncs.c:258
#3  0x000055c057a5e447 in ExecMakeTableFunctionResult
(setexpr=0x55c058c81a28, econtext=0x55c058c818e0, 
    argContext=0x55c058c77300, expectedDesc=0x55c058c82ce8,
randomAccess=false) at execSRF.c:234
#4  0x000055c057a7be29 in FunctionNext (node=0x55c058c816c8) at
nodeFunctionscan.c:95
#5  0x000055c057a5ff3d in ExecScanFetch (node=0x55c058c816c8,
accessMtd=0x55c057a7bd74 <FunctionNext>, 
    recheckMtd=0x55c057a7c170 <FunctionRecheck>) at execScan.c:133
#6  0x000055c057a5ffb6 in ExecScan (node=0x55c058c816c8,
accessMtd=0x55c057a7bd74 <FunctionNext>, 
    recheckMtd=0x55c057a7c170 <FunctionRecheck>) at execScan.c:182
#7  0x000055c057a7c1c9 in ExecFunctionScan (pstate=0x55c058c816c8) at
nodeFunctionscan.c:270
#8  0x000055c057a5b9a4 in ExecProcNodeFirst (node=0x55c058c816c8) at
execProcnode.c:464
#9  0x000055c057a4ebd1 in ExecProcNode (node=0x55c058c816c8) at
../../../src/include/executor/executor.h:259
#10 0x000055c057a51ae4 in ExecutePlan (estate=0x55c058c81490,
planstate=0x55c058c816c8, use_parallel_mode=false, 
    operation=CMD_SELECT, sendTuples=true, numberTuples=0,
direction=ForwardScanDirection, dest=0x55c058cacc28, 
    execute_once=true) at execMain.c:1636
#11 0x000055c057a4f308 in standard_ExecutorRun (queryDesc=0x55c058bbe9b0,
direction=ForwardScanDirection, count=0, 
    execute_once=true) at execMain.c:363
#12 0x000055c057a4f0f3 in ExecutorRun (queryDesc=0x55c058bbe9b0,
direction=ForwardScanDirection, count=0, 
    execute_once=true) at execMain.c:307
#13 0x000055c057cc959e in PortalRunSelect (portal=0x55c058c08e80,
forward=true, count=0, dest=0x55c058cacc28)
    at pquery.c:924
#14 0x000055c057cc91bc in PortalRun (portal=0x55c058c08e80,
count=9223372036854775807, isTopLevel=true, run_once=true, 
    dest=0x55c058cacc28, altdest=0x55c058cacc28, qc=0x7ffe813b6430) at
pquery.c:768
#15 0x000055c057cc2050 in exec_simple_query (
    query_string=0x55c058b9c680 "SELECT * FROM
gist_page_items(get_raw_page('tbl_gist_idx', 0), 'tbl_gist_idx');")
    at postgres.c:1250
#16 0x000055c057cc6f74 in PostgresMain (dbname=0x55c058bc8d08 "regression",
username=0x55c058bc8ce8 "law")
    at postgres.c:4593
#17 0x000055c057bebe7c in BackendRun (port=0x55c058bc0420) at
postmaster.c:4511
#18 0x000055c057beb703 in BackendStartup (port=0x55c058bc0420) at
postmaster.c:4239
#19 0x000055c057be7678 in ServerLoop () at postmaster.c:1806
#20 0x000055c057be6dd8 in PostmasterMain (argc=3, argv=0x55c058b96630) at
postmaster.c:1478
#21 0x000055c057ada5f4 in main (argc=3, argv=0x55c058b96630) at main.c:202

Here gist_page_items() tries to decode a tuple using a descriptor of the
index (defining 3 columns), but in fact non-leaf page items contain no
non-key data as
SELECT * FROM gist_page_items_bytea(get_raw_page('tbl_gist_idx', 0));
shows:
 itemoffset |    ctid    | itemlen | dead |
    key_data                                      

------------+------------+---------+------+------------------------------------------------------------------------------------
          1 | (1,65535)  |      40 | f    | \x00000100ffff28...00f03f
          2 | (2,65535)  |      40 | f    | \x00000200ffff28...001440
...
         25 | (25,65535) |      40 | f    | \x00001900ffff28...405840
(25 rows)

Compare with a leaf page (notably different itemlen):
SELECT * FROM gist_page_items_bytea(get_raw_page('tbl_gist_idx', 1));
          1 | (0,1) |    1048 | f    | \x0000000001001844...787878
          2 | (0,2) |    1048 | f    | \x0000000002001844....787878
...

Other index types are not affected because:
btree outputs all data bytes, not keys only;
brin, gin, hash don't support included columns.

Observed on REL_14_STABLE (starting from 756ab2912) .. master.


pgsql-bugs by date:

Previous
From: Tom Lane
Date:
Subject: Re: BUG #17883: Segmentation fault when create brin index on user-defined type.
Next
From: PG Bug reporting form
Date:
Subject: BUG #17885: slow planning constraint_exclusion