Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit b238527

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/20181115223959.GB10913@telsasoft.com Backpatch: 11, just as jit compilation was
1 parent f17889b commit b238527

File tree

4 files changed

+30
-3
lines changed

4 files changed

+30
-3
lines changed

src/backend/jit/llvm/llvmjit_deform.c

+9-3
Original file line numberDiff line numberDiff line change
@@ -248,10 +248,16 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
248248
v_infomask2,
249249
"maxatt");
250250

251+
/*
252+
* Need to zext, as getelementptr otherwise treats hoff as a signed 8bit
253+
* integer, which'd yield a negative offset for t_hoff > 127.
254+
*/
251255
v_hoff =
252-
l_load_struct_gep(b, v_tuplep,
253-
FIELDNO_HEAPTUPLEHEADERDATA_HOFF,
254-
"t_hoff");
256+
LLVMBuildZExt(b,
257+
l_load_struct_gep(b, v_tuplep,
258+
FIELDNO_HEAPTUPLEHEADERDATA_HOFF,
259+
""),
260+
LLVMInt32Type(), "t_hoff");
255261

256262
v_tupdata_base =
257263
LLVMBuildGEP(b,

src/test/regress/expected/create_table.out

+10
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,16 @@ ERROR: relation "as_select1" already exists
261261
CREATE TABLE IF NOT EXISTS as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r';
262262
NOTICE: relation "as_select1" already exists, skipping
263263
DROP TABLE as_select1;
264+
-- create an extra wide table to test for issues related to that
265+
-- (temporarily hide query, to avoid the long CREATE TABLE stmt)
266+
\set ECHO none
267+
INSERT INTO extra_wide_table(firstc, lastc) VALUES('first col', 'last col');
268+
SELECT firstc, lastc FROM extra_wide_table;
269+
firstc | lastc
270+
-----------+----------
271+
first col | last col
272+
(1 row)
273+
264274
-- check that tables with oids cannot be created anymore
265275
CREATE TABLE withoid() WITH OIDS;
266276
ERROR: syntax error at or near "OIDS"

src/test/regress/expected/sanity_check.out

+1
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

+10
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,16 @@ CREATE TABLE as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r';
277277
CREATE TABLE IF NOT EXISTS as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r';
278278
DROP TABLE as_select1;
279279

280+
-- create an extra wide table to test for issues related to that
281+
-- (temporarily hide query, to avoid the long CREATE TABLE stmt)
282+
\set ECHO none
283+
SELECT 'CREATE TABLE extra_wide_table(firstc text, '|| array_to_string(array_agg('c'||i||' bool'),',')||', lastc text);'
284+
FROM generate_series(1, 1100) g(i)
285+
\gexec
286+
\set ECHO all
287+
INSERT INTO extra_wide_table(firstc, lastc) VALUES('first col', 'last col');
288+
SELECT firstc, lastc FROM extra_wide_table;
289+
280290
-- check that tables with oids cannot be created anymore
281291
CREATE TABLE withoid() WITH OIDS;
282292
CREATE TABLE withoid() WITH (oids);

0 commit comments

Comments
 (0)