Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Fix jit compilation bug on wide tables.
authorAndres Freund <andres@anarazel.de>
Tue, 27 Nov 2018 18:07:43 +0000 (10:07 -0800)
committerAndres Freund <andres@anarazel.de>
Tue, 27 Nov 2018 18:07:43 +0000 (10:07 -0800)
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

src/backend/jit/llvm/llvmjit_deform.c
src/test/regress/expected/create_table.out
src/test/regress/expected/sanity_check.out
src/test/regress/sql/create_table.sql

index 795f67114e65c784ba329ef757f4854a3ec59915..e406d392d4e16e325d647a877b63b8afb4bedc11 100644 (file)
@@ -208,10 +208,16 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts)
                            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,
index e156e800c2274b30d2b4ef580b0ba0b3a1b5ecea..8cd148601d29a096ccc51a8f284e492d7de6b049 100644 (file)
@@ -263,6 +263,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 the oid column is added before the primary key is checked
 CREATE TABLE oid_pk (f1 INT, PRIMARY KEY(oid)) WITH OIDS;
 DROP TABLE oid_pk;
index 9c7a60c092d0c85d7812de3fca812466752b1ea3..66957706a000058e9217cad7fb879ac6721e954c 100644 (file)
@@ -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
index 2af4455ecf8b3cc2f03304d8831cf0f54c892de0..df8b66fac4d54cc6f7257e130730c05ca058b7c0 100644 (file)
@@ -278,6 +278,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 the oid column is added before the primary key is checked
 CREATE TABLE oid_pk (f1 INT, PRIMARY KEY(oid)) WITH OIDS;
 DROP TABLE oid_pk;