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
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,
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"
e_star|f
emp|f
equipment_r|f
+extra_wide_table|f
f_star|f
fast_emp4000|t
float4_tbl|f
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);