Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit aee085b

Browse files
committed
Fix jit compilation bug on wide tables.
The function generated to perform JIT compiled tuple deforming failed when HeapTupleHeader's t_hoff was bigger than a signed int8. I'd failed to realize that LLVM's getelementptr would treat an int8 index argument as signed, rather than unsigned. That means that a hoff larger than 127 would result in a negative offset being applied. Fix that by widening the index to 32bit. Add a testcase with a wide table. Don't drop it, as it seems useful to verify other tools deal properly with wide tables. Thanks to Justin Pryzby for both reporting a bug and then reducing it to a reproducible testcase! Reported-By: Justin Pryzby Author: Andres Freund Discussion: https://postgr.es/m/[email protected] Backpatch: 11, just as jit compilation was
1 parent 5ef8f08 commit aee085b

File tree

4 files changed

+30
-3
lines changed

4 files changed

+30
-3
lines changed

src/backend/jit/llvm/llvmjit_deform.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,10 +208,16 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts)
208208
v_infomask2,
209209
"maxatt");
210210

211+
/*
212+
* Need to zext, as getelementptr otherwise treats hoff as a signed 8bit
213+
* integer, which'd yield a negative offset for t_hoff > 127.
214+
*/
211215
v_hoff =
212-
l_load_struct_gep(b, v_tuplep,
213-
FIELDNO_HEAPTUPLEHEADERDATA_HOFF,
214-
"t_hoff");
216+
LLVMBuildZExt(b,
217+
l_load_struct_gep(b, v_tuplep,
218+
FIELDNO_HEAPTUPLEHEADERDATA_HOFF,
219+
""),
220+
LLVMInt32Type(), "t_hoff");
215221

216222
v_tupdata_base =
217223
LLVMBuildGEP(b,

src/test/regress/expected/create_table.out

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,16 @@ ERROR: relation "as_select1" already exists
263263
CREATE TABLE IF NOT EXISTS as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r';
264264
NOTICE: relation "as_select1" already exists, skipping
265265
DROP TABLE as_select1;
266+
-- create an extra wide table to test for issues related to that
267+
-- (temporarily hide query, to avoid the long CREATE TABLE stmt)
268+
\set ECHO none
269+
INSERT INTO extra_wide_table(firstc, lastc) VALUES('first col', 'last col');
270+
SELECT firstc, lastc FROM extra_wide_table;
271+
firstc | lastc
272+
-----------+----------
273+
first col | last col
274+
(1 row)
275+
266276
-- check that the oid column is added before the primary key is checked
267277
CREATE TABLE oid_pk (f1 INT, PRIMARY KEY(oid)) WITH OIDS;
268278
DROP TABLE oid_pk;

src/test/regress/expected/sanity_check.out

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ dupindexcols|t
4444
e_star|f
4545
emp|f
4646
equipment_r|f
47+
extra_wide_table|f
4748
f_star|f
4849
fast_emp4000|t
4950
float4_tbl|f

src/test/regress/sql/create_table.sql

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,16 @@ CREATE TABLE as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r';
278278
CREATE TABLE IF NOT EXISTS as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r';
279279
DROP TABLE as_select1;
280280

281+
-- create an extra wide table to test for issues related to that
282+
-- (temporarily hide query, to avoid the long CREATE TABLE stmt)
283+
\set ECHO none
284+
SELECT 'CREATE TABLE extra_wide_table(firstc text, '|| array_to_string(array_agg('c'||i||' bool'),',')||', lastc text);'
285+
FROM generate_series(1, 1100) g(i)
286+
\gexec
287+
\set ECHO all
288+
INSERT INTO extra_wide_table(firstc, lastc) VALUES('first col', 'last col');
289+
SELECT firstc, lastc FROM extra_wide_table;
290+
281291
-- check that the oid column is added before the primary key is checked
282292
CREATE TABLE oid_pk (f1 INT, PRIMARY KEY(oid)) WITH OIDS;
283293
DROP TABLE oid_pk;

0 commit comments

Comments
 (0)