mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-27 08:39:28 +08:00
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
This commit is contained in:
parent
f17889b221
commit
b238527664
@ -248,10 +248,16 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
|
||||
v_infomask2,
|
||||
"maxatt");
|
||||
|
||||
/*
|
||||
* Need to zext, as getelementptr otherwise treats hoff as a signed 8bit
|
||||
* integer, which'd yield a negative offset for t_hoff > 127.
|
||||
*/
|
||||
v_hoff =
|
||||
l_load_struct_gep(b, v_tuplep,
|
||||
FIELDNO_HEAPTUPLEHEADERDATA_HOFF,
|
||||
"t_hoff");
|
||||
LLVMBuildZExt(b,
|
||||
l_load_struct_gep(b, v_tuplep,
|
||||
FIELDNO_HEAPTUPLEHEADERDATA_HOFF,
|
||||
""),
|
||||
LLVMInt32Type(), "t_hoff");
|
||||
|
||||
v_tupdata_base =
|
||||
LLVMBuildGEP(b,
|
||||
|
@ -261,6 +261,16 @@ ERROR: relation "as_select1" already exists
|
||||
CREATE TABLE IF NOT EXISTS as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r';
|
||||
NOTICE: relation "as_select1" already exists, skipping
|
||||
DROP TABLE as_select1;
|
||||
-- create an extra wide table to test for issues related to that
|
||||
-- (temporarily hide query, to avoid the long CREATE TABLE stmt)
|
||||
\set ECHO none
|
||||
INSERT INTO extra_wide_table(firstc, lastc) VALUES('first col', 'last col');
|
||||
SELECT firstc, lastc FROM extra_wide_table;
|
||||
firstc | lastc
|
||||
-----------+----------
|
||||
first col | last col
|
||||
(1 row)
|
||||
|
||||
-- check that tables with oids cannot be created anymore
|
||||
CREATE TABLE withoid() WITH OIDS;
|
||||
ERROR: syntax error at or near "OIDS"
|
||||
|
@ -44,6 +44,7 @@ dupindexcols|t
|
||||
e_star|f
|
||||
emp|f
|
||||
equipment_r|f
|
||||
extra_wide_table|f
|
||||
f_star|f
|
||||
fast_emp4000|t
|
||||
float4_tbl|f
|
||||
|
@ -277,6 +277,16 @@ CREATE TABLE as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r';
|
||||
CREATE TABLE IF NOT EXISTS as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r';
|
||||
DROP TABLE as_select1;
|
||||
|
||||
-- create an extra wide table to test for issues related to that
|
||||
-- (temporarily hide query, to avoid the long CREATE TABLE stmt)
|
||||
\set ECHO none
|
||||
SELECT 'CREATE TABLE extra_wide_table(firstc text, '|| array_to_string(array_agg('c'||i||' bool'),',')||', lastc text);'
|
||||
FROM generate_series(1, 1100) g(i)
|
||||
\gexec
|
||||
\set ECHO all
|
||||
INSERT INTO extra_wide_table(firstc, lastc) VALUES('first col', 'last col');
|
||||
SELECT firstc, lastc FROM extra_wide_table;
|
||||
|
||||
-- check that tables with oids cannot be created anymore
|
||||
CREATE TABLE withoid() WITH OIDS;
|
||||
CREATE TABLE withoid() WITH (oids);
|
||||
|
Loading…
Reference in New Issue
Block a user