From 6887712ec32d01984135056ec5828ef0a442e552 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Mon, 28 Oct 2019 17:01:42 -0700
Subject: [PATCH v2 8/8] jit: Add tests.

Author:
Reviewed-By:
Discussion: https://postgr.es/m/
Backpatch:
---
 src/test/regress/expected/jit.out   | 491 ++++++++++++++++++++++++++++
 src/test/regress/expected/jit_0.out |   5 +
 src/test/regress/parallel_schedule  |   2 +-
 src/test/regress/sql/jit.sql        | 166 ++++++++++
 4 files changed, 663 insertions(+), 1 deletion(-)
 create mode 100644 src/test/regress/expected/jit.out
 create mode 100644 src/test/regress/expected/jit_0.out
 create mode 100644 src/test/regress/sql/jit.sql

diff --git a/src/test/regress/expected/jit.out b/src/test/regress/expected/jit.out
new file mode 100644
index 00000000000..b1981df9fed
--- /dev/null
+++ b/src/test/regress/expected/jit.out
@@ -0,0 +1,491 @@
+/* skip test if JIT is not available */
+SELECT NOT (pg_jit_available() AND current_setting('jit')::bool)
+       AS skip_test \gset
+\if :skip_test
+\quit
+\endif
+-- start with a known baseline
+set jit_expressions = true;
+set jit_tuple_deforming = true;
+-- to reliably test, despite costs varying between platforms
+set jit_above_cost = 0;
+-- to make the bulk of the test cheaper
+set jit_optimize_above_cost = -1;
+set jit_inline_above_cost = -1;
+CREATE TABLE jittest_simple(id serial primary key, data text);
+INSERT INTO jittest_simple(data) VALUES('row1');
+INSERT INTO jittest_simple(data) VALUES('row2');
+-- verify that a simple relation-less query can be JITed
+BEGIN;
+SET LOCAL jit = false;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT txid_current() = txid_current();
+                          QUERY PLAN                           
+---------------------------------------------------------------
+ Result
+   Project: (txid_current() = txid_current()); JIT-Expr: false
+(2 rows)
+
+SELECT txid_current() = txid_current();
+ ?column? 
+----------
+ t
+(1 row)
+
+COMMIT;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT txid_current() = txid_current();
+                                   QUERY PLAN                                    
+---------------------------------------------------------------------------------
+ Result
+   Project: (txid_current() = txid_current()); JIT-Expr: evalexpr_0_0
+ JIT:
+   Functions: 1 (1 for expression evaluation)
+   Options: Inlining false, Optimization false, Expressions true, Deforming true
+(5 rows)
+
+SELECT txid_current() = txid_current();
+ ?column? 
+----------
+ t
+(1 row)
+
+-- that tuple deforming for a plain seqscan is JITed when projecting
+BEGIN;
+SET LOCAL jit = false;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT data FROM jittest_simple;
+            QUERY PLAN             
+-----------------------------------
+ Seq Scan on public.jittest_simple
+   Project: data; JIT-Expr: false
+(2 rows)
+
+SELECT data FROM jittest_simple;
+ data 
+------
+ row1
+ row2
+(2 rows)
+
+COMMIT;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT data FROM jittest_simple;
+                                   QUERY PLAN                                    
+---------------------------------------------------------------------------------
+ Seq Scan on public.jittest_simple
+   Project: data; JIT-Expr: evalexpr_0_0, JIT-Deform-Scan: deform_0_1
+ JIT:
+   Functions: 2 (1 for expression evaluation, 1 for tuple deforming)
+   Options: Inlining false, Optimization false, Expressions true, Deforming true
+(5 rows)
+
+SELECT data FROM jittest_simple;
+ data 
+------
+ row1
+ row2
+(2 rows)
+
+-- unfortunately currently the physical tlist optimization may prevent
+-- JITed tuple deforming from taking effect
+BEGIN;
+SET LOCAL jit = false;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT * FROM jittest_simple;
+            QUERY PLAN             
+-----------------------------------
+ Seq Scan on public.jittest_simple
+   Output: id, data
+(2 rows)
+
+SELECT * FROM jittest_simple;
+ id | data 
+----+------
+  1 | row1
+  2 | row2
+(2 rows)
+
+COMMIT;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT * FROM jittest_simple;
+            QUERY PLAN             
+-----------------------------------
+ Seq Scan on public.jittest_simple
+   Output: id, data
+(2 rows)
+
+SELECT * FROM jittest_simple;
+ id | data 
+----+------
+  1 | row1
+  2 | row2
+(2 rows)
+
+-- check that tuple deforming on wide tables works
+BEGIN;
+SET LOCAL jit_tuple_deforming = false;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT firstc, lastc FROM extra_wide_table;
+                                    QUERY PLAN                                    
+----------------------------------------------------------------------------------
+ Seq Scan on public.extra_wide_table
+   Project: firstc, lastc; JIT-Expr: evalexpr_0_0, JIT-Deform-Scan: false
+ JIT:
+   Functions: 1 (1 for expression evaluation)
+   Options: Inlining false, Optimization false, Expressions true, Deforming false
+(5 rows)
+
+SELECT firstc, lastc FROM extra_wide_table;
+  firstc   |  lastc   
+-----------+----------
+ first col | last col
+(1 row)
+
+COMMIT;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT firstc, lastc FROM extra_wide_table;
+                                   QUERY PLAN                                    
+---------------------------------------------------------------------------------
+ Seq Scan on public.extra_wide_table
+   Project: firstc, lastc; JIT-Expr: evalexpr_0_0, JIT-Deform-Scan: deform_0_1
+ JIT:
+   Functions: 2 (1 for expression evaluation, 1 for tuple deforming)
+   Options: Inlining false, Optimization false, Expressions true, Deforming true
+(5 rows)
+
+SELECT firstc, lastc FROM extra_wide_table;
+  firstc   |  lastc   
+-----------+----------
+ first col | last col
+(1 row)
+
+-----
+-- test costing
+-----
+-- don't perform JIT compilation unless worthwhile
+BEGIN;
+SET LOCAL jit_above_cost = 8000000000;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT tableoid FROM jittest_simple;
+              QUERY PLAN              
+--------------------------------------
+ Seq Scan on public.jittest_simple
+   Project: tableoid; JIT-Expr: false
+(2 rows)
+
+SET LOCAL enable_seqscan = false;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT tableoid FROM jittest_simple;
+                                   QUERY PLAN                                    
+---------------------------------------------------------------------------------
+ Seq Scan on public.jittest_simple
+   Project: tableoid; JIT-Expr: evalexpr_0_0
+ JIT:
+   Functions: 1 (1 for expression evaluation)
+   Options: Inlining false, Optimization false, Expressions true, Deforming true
+(5 rows)
+
+COMMIT;
+-- optimize once expensive enough
+BEGIN;
+SET LOCAL jit_above_cost = 0;
+SET LOCAL jit_optimize_above_cost = 8000000000;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT tableoid FROM jittest_simple;
+                                   QUERY PLAN                                    
+---------------------------------------------------------------------------------
+ Seq Scan on public.jittest_simple
+   Project: tableoid; JIT-Expr: evalexpr_0_0
+ JIT:
+   Functions: 1 (1 for expression evaluation)
+   Options: Inlining false, Optimization false, Expressions true, Deforming true
+(5 rows)
+
+SET LOCAL enable_seqscan = false;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT tableoid FROM jittest_simple;
+                                   QUERY PLAN                                   
+--------------------------------------------------------------------------------
+ Seq Scan on public.jittest_simple
+   Project: tableoid; JIT-Expr: evalexpr_0_0
+ JIT:
+   Functions: 1 (1 for expression evaluation)
+   Options: Inlining false, Optimization true, Expressions true, Deforming true
+(5 rows)
+
+COMMIT;
+-- behave sanely if optimization cost is below general JIT costs
+BEGIN;
+SET LOCAL jit_above_cost = 8000000000;
+SET LOCAL jit_optimize_above_cost = 0;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT tableoid FROM jittest_simple;
+              QUERY PLAN              
+--------------------------------------
+ Seq Scan on public.jittest_simple
+   Project: tableoid; JIT-Expr: false
+(2 rows)
+
+SET LOCAL enable_seqscan = false;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT tableoid FROM jittest_simple;
+                                   QUERY PLAN                                   
+--------------------------------------------------------------------------------
+ Seq Scan on public.jittest_simple
+   Project: tableoid; JIT-Expr: evalexpr_0_0
+ JIT:
+   Functions: 1 (1 for expression evaluation)
+   Options: Inlining false, Optimization true, Expressions true, Deforming true
+(5 rows)
+
+COMMIT;
+-- perform inlining once expensive enough
+BEGIN;
+SET LOCAL jit_above_cost = 0;
+SET LOCAL jit_inline_above_cost = 8000000000;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT tableoid FROM jittest_simple;
+                                   QUERY PLAN                                    
+---------------------------------------------------------------------------------
+ Seq Scan on public.jittest_simple
+   Project: tableoid; JIT-Expr: evalexpr_0_0
+ JIT:
+   Functions: 1 (1 for expression evaluation)
+   Options: Inlining false, Optimization false, Expressions true, Deforming true
+(5 rows)
+
+SET LOCAL enable_seqscan = false;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT tableoid FROM jittest_simple;
+                                   QUERY PLAN                                   
+--------------------------------------------------------------------------------
+ Seq Scan on public.jittest_simple
+   Project: tableoid; JIT-Expr: evalexpr_0_0
+ JIT:
+   Functions: 1 (1 for expression evaluation)
+   Options: Inlining true, Optimization false, Expressions true, Deforming true
+(5 rows)
+
+COMMIT;
+-- perform inlining once expensive enough
+BEGIN;
+SET LOCAL jit_above_cost = 0;
+SET LOCAL jit_inline_above_cost = 8000000000;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT tableoid FROM jittest_simple;
+                                   QUERY PLAN                                    
+---------------------------------------------------------------------------------
+ Seq Scan on public.jittest_simple
+   Project: tableoid; JIT-Expr: evalexpr_0_0
+ JIT:
+   Functions: 1 (1 for expression evaluation)
+   Options: Inlining false, Optimization false, Expressions true, Deforming true
+(5 rows)
+
+SET LOCAL enable_seqscan = false;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT tableoid FROM jittest_simple;
+                                   QUERY PLAN                                   
+--------------------------------------------------------------------------------
+ Seq Scan on public.jittest_simple
+   Project: tableoid; JIT-Expr: evalexpr_0_0
+ JIT:
+   Functions: 1 (1 for expression evaluation)
+   Options: Inlining true, Optimization false, Expressions true, Deforming true
+(5 rows)
+
+COMMIT;
+-- perform inlining and optimization once expensive enough
+BEGIN;
+SET LOCAL jit_above_cost = 0;
+SET LOCAL jit_inline_above_cost = 8000000000;
+SET LOCAL jit_optimize_above_cost = 8000000000;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT tableoid FROM jittest_simple;
+                                   QUERY PLAN                                    
+---------------------------------------------------------------------------------
+ Seq Scan on public.jittest_simple
+   Project: tableoid; JIT-Expr: evalexpr_0_0
+ JIT:
+   Functions: 1 (1 for expression evaluation)
+   Options: Inlining false, Optimization false, Expressions true, Deforming true
+(5 rows)
+
+SET LOCAL enable_seqscan = false;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT tableoid FROM jittest_simple;
+                                  QUERY PLAN                                   
+-------------------------------------------------------------------------------
+ Seq Scan on public.jittest_simple
+   Project: tableoid; JIT-Expr: evalexpr_0_0
+ JIT:
+   Functions: 1 (1 for expression evaluation)
+   Options: Inlining true, Optimization true, Expressions true, Deforming true
+(5 rows)
+
+COMMIT;
+-- check that inner/outer tuple deforming can be inferred for upper nodes, join case
+BEGIN;
+SET LOCAL enable_hashjoin = true;
+SET LOCAL enable_mergejoin = false;
+SET LOCAL enable_nestloop = false;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT a.data || b.data FROM jittest_simple a JOIN jittest_simple b USING(id);
+                                                    QUERY PLAN                                                     
+-------------------------------------------------------------------------------------------------------------------
+ Hash Join
+   Project: (a.data || b.data); JIT-Expr: evalexpr_0_3, JIT-Deform-Outer: deform_0_5, JIT-Deform-Inner: deform_0_4
+   Inner Unique: true
+   Hash Cond: (a.id = b.id); JIT-Expr: evalexpr_0_6, JIT-Deform-Outer: deform_0_8, JIT-Deform-Inner: deform_0_7
+   Outer Hash Key: a.id; JIT-Expr: evalexpr_0_9, JIT-Deform-Outer: deform_0_10
+   ->  Seq Scan on public.jittest_simple a
+         Output: a.id, a.data
+   ->  Hash
+         Output: b.data, b.id
+         Hash Key: b.id; JIT-Expr: evalexpr_0_2
+         ->  Seq Scan on public.jittest_simple b
+               Project: b.data, b.id; JIT-Expr: evalexpr_0_0, JIT-Deform-Scan: deform_0_1
+ JIT:
+   Functions: 11 (5 for expression evaluation, 6 for tuple deforming)
+   Options: Inlining false, Optimization false, Expressions true, Deforming true
+(15 rows)
+
+SELECT a.data || b.data FROM jittest_simple a JOIN jittest_simple b USING(id);
+ ?column? 
+----------
+ row1row1
+ row2row2
+(2 rows)
+
+COMMIT;
+BEGIN;
+SET LOCAL enable_hashjoin = false;
+SET LOCAL enable_mergejoin = true;
+SET LOCAL enable_nestloop = false;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT a.data || b.data FROM jittest_simple a JOIN jittest_simple b USING(id);
+                                                    QUERY PLAN                                                     
+-------------------------------------------------------------------------------------------------------------------
+ Merge Join
+   Project: (a.data || b.data); JIT-Expr: evalexpr_0_0, JIT-Deform-Outer: deform_0_2, JIT-Deform-Inner: deform_0_1
+   Inner Unique: true
+   Merge Cond: (a.id = b.id)
+   ->  Index Scan using jittest_simple_pkey on public.jittest_simple a
+         Output: a.id, a.data
+   ->  Index Scan using jittest_simple_pkey on public.jittest_simple b
+         Output: b.id, b.data
+ JIT:
+   Functions: 7 (3 for expression evaluation, 4 for tuple deforming)
+   Options: Inlining false, Optimization false, Expressions true, Deforming true
+(11 rows)
+
+SELECT a.data || b.data FROM jittest_simple a JOIN jittest_simple b USING(id);
+ ?column? 
+----------
+ row1row1
+ row2row2
+(2 rows)
+
+COMMIT;
+BEGIN;
+SET LOCAL enable_hashjoin = false;
+SET LOCAL enable_mergejoin = false;
+SET LOCAL enable_nestloop = true;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT a.data || b.data FROM jittest_simple a JOIN jittest_simple b USING(id);
+                                                    QUERY PLAN                                                     
+-------------------------------------------------------------------------------------------------------------------
+ Nested Loop
+   Project: (a.data || b.data); JIT-Expr: evalexpr_0_2, JIT-Deform-Outer: deform_0_4, JIT-Deform-Inner: deform_0_3
+   Inner Unique: true
+   ->  Seq Scan on public.jittest_simple a
+         Output: a.id, a.data
+   ->  Index Scan using jittest_simple_pkey on public.jittest_simple b
+         Output: b.id, b.data
+         Index Cond: (b.id = a.id); JIT-Expr: evalexpr_0_0, JIT-Deform-Scan: deform_0_1
+ JIT:
+   Functions: 5 (2 for expression evaluation, 3 for tuple deforming)
+   Options: Inlining false, Optimization false, Expressions true, Deforming true
+(11 rows)
+
+SELECT a.data || b.data FROM jittest_simple a JOIN jittest_simple b USING(id);
+ ?column? 
+----------
+ row1row1
+ row2row2
+(2 rows)
+
+COMMIT;
+-- check that inner/outer tuple deforming can be inferred for upper nodes, agg case
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT count(*), count(data), string_agg(data, ':') FROM jittest_simple;
+                                                                             QUERY PLAN                                                                              
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ Aggregate
+   Project: count(*), count(data), string_agg(data, ':'::text); JIT-Expr: evalexpr_0_0
+   Phase 1 using strategy "All":
+     Transition Function: int8inc(TRANS), int8inc_any(TRANS, data), string_agg_transfn(TRANS, data, ':'::text); JIT-Expr: evalexpr_0_1, JIT-Deform-Outer: deform_0_2
+     All Group
+   ->  Seq Scan on public.jittest_simple
+         Output: id, data
+ JIT:
+   Functions: 3 (2 for expression evaluation, 1 for tuple deforming)
+   Options: Inlining false, Optimization false, Expressions true, Deforming true
+(10 rows)
+
+SELECT count(*), count(data), string_agg(data, ':') FROM jittest_simple;
+ count | count | string_agg 
+-------+-------+------------
+     2 |     2 | row1:row2
+(1 row)
+
+-- Check that the equality hash-table function in a hash-aggregate can
+-- be accelerated.
+--
+-- XXX: Unfortunately this is currently broken
+BEGIN;
+SET LOCAL enable_hashagg = true;
+SET LOCAL enable_sort = false;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT data, string_agg(id::text, ', ') FROM jittest_simple GROUP BY data;
+                                                            QUERY PLAN                                                            
+----------------------------------------------------------------------------------------------------------------------------------
+ HashAggregate
+   Project: data, string_agg((id)::text, ', '::text); JIT-Expr: evalexpr_0_0, JIT-Deform-Outer: deform_0_1
+   Phase 0 using strategy "Hash":
+     Transition Function: string_agg_transfn(TRANS, (id)::text, ', '::text); JIT-Expr: evalexpr_0_5, JIT-Deform-Outer: deform_0_6
+     Hash Group: jittest_simple.data; JIT-Expr: evalexpr_0_2, JIT-Deform-Outer: deform_0_4, JIT-Deform-Inner: deform_0_3
+   ->  Seq Scan on public.jittest_simple
+         Output: id, data
+ JIT:
+   Functions: 7 (3 for expression evaluation, 4 for tuple deforming)
+   Options: Inlining false, Optimization false, Expressions true, Deforming true
+(10 rows)
+
+SELECT data, string_agg(id::text, ', ') FROM jittest_simple GROUP BY data;
+ data | string_agg 
+------+------------
+ row1 | 1
+ row2 | 2
+(2 rows)
+
+END;
+-- Unfortunately for sort based aggregates, the group comparison
+-- function can current not be JITed
+BEGIN;
+SET LOCAL enable_hashagg = false;
+SET LOCAL enable_sort = true;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT data, string_agg(id::text, ', ') FROM jittest_simple GROUP BY data;
+                                                            QUERY PLAN                                                            
+----------------------------------------------------------------------------------------------------------------------------------
+ GroupAggregate
+   Project: data, string_agg((id)::text, ', '::text); JIT-Expr: evalexpr_0_2, JIT-Deform-Outer: deform_0_3
+   Phase 1 using strategy "Sorted Input":
+     Transition Function: string_agg_transfn(TRANS, (id)::text, ', '::text); JIT-Expr: evalexpr_0_5, JIT-Deform-Outer: deform_0_6
+     Sorted Input Group: jittest_simple.data; JIT-Expr: evalexpr_0_4, JIT-Deform-Outer: false, JIT-Deform-Inner: false
+   ->  Sort
+         Output: data, id
+         Sort Key: jittest_simple.data
+         ->  Seq Scan on public.jittest_simple
+               Project: data, id; JIT-Expr: evalexpr_0_0, JIT-Deform-Scan: deform_0_1
+ JIT:
+   Functions: 7 (4 for expression evaluation, 3 for tuple deforming)
+   Options: Inlining false, Optimization false, Expressions true, Deforming true
+(13 rows)
+
+SELECT data, string_agg(id::text, ', ') FROM jittest_simple GROUP BY data;
+ data | string_agg 
+------+------------
+ row1 | 1
+ row2 | 2
+(2 rows)
+
+END;
+-- check that EXPLAIN ANALYZE output is reproducible with the right options
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS, ANALYZE, TIMING OFF, SUMMARY OFF) SELECT tableoid FROM jittest_simple;
+                                   QUERY PLAN                                    
+---------------------------------------------------------------------------------
+ Seq Scan on public.jittest_simple (actual rows=2 loops=1)
+   Project: tableoid; JIT-Expr: evalexpr_0_0
+ JIT:
+   Functions: 1 (1 for expression evaluation)
+   Options: Inlining false, Optimization false, Expressions true, Deforming true
+(5 rows)
+
+DROP TABLE jittest_simple;
diff --git a/src/test/regress/expected/jit_0.out b/src/test/regress/expected/jit_0.out
new file mode 100644
index 00000000000..9812cb33752
--- /dev/null
+++ b/src/test/regress/expected/jit_0.out
@@ -0,0 +1,5 @@
+/* skip test if JIT is not available */
+SELECT NOT (pg_jit_available() AND current_setting('jit')::bool)
+       AS skip_test \gset
+\if :skip_test
+\quit
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index fc0f14122bb..c1c3dd3af8b 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -78,7 +78,7 @@ test: brin gin gist spgist privileges init_privs security_label collate matview
 # ----------
 # Another group of parallel tests
 # ----------
-test: create_table_like alter_generic alter_operator misc async dbsize misc_functions sysviews tsrf tidscan collate.icu.utf8
+test: create_table_like alter_generic alter_operator misc async dbsize misc_functions sysviews tsrf tidscan collate.icu.utf8 jit
 
 # rules cannot run concurrently with any test that creates
 # a view or rule in the public schema
diff --git a/src/test/regress/sql/jit.sql b/src/test/regress/sql/jit.sql
new file mode 100644
index 00000000000..eb617c0ca58
--- /dev/null
+++ b/src/test/regress/sql/jit.sql
@@ -0,0 +1,166 @@
+/* skip test if JIT is not available */
+SELECT NOT (pg_jit_available() AND current_setting('jit')::bool)
+       AS skip_test \gset
+\if :skip_test
+\quit
+\endif
+
+-- start with a known baseline
+set jit_expressions = true;
+set jit_tuple_deforming = true;
+-- to reliably test, despite costs varying between platforms
+set jit_above_cost = 0;
+-- to make the bulk of the test cheaper
+set jit_optimize_above_cost = -1;
+set jit_inline_above_cost = -1;
+
+CREATE TABLE jittest_simple(id serial primary key, data text);
+INSERT INTO jittest_simple(data) VALUES('row1');
+INSERT INTO jittest_simple(data) VALUES('row2');
+
+-- verify that a simple relation-less query can be JITed
+BEGIN;
+SET LOCAL jit = false;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT txid_current() = txid_current();
+SELECT txid_current() = txid_current();
+COMMIT;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT txid_current() = txid_current();
+SELECT txid_current() = txid_current();
+
+
+-- that tuple deforming for a plain seqscan is JITed when projecting
+BEGIN;
+SET LOCAL jit = false;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT data FROM jittest_simple;
+SELECT data FROM jittest_simple;
+COMMIT;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT data FROM jittest_simple;
+SELECT data FROM jittest_simple;
+
+-- unfortunately currently the physical tlist optimization may prevent
+-- JITed tuple deforming from taking effect
+BEGIN;
+SET LOCAL jit = false;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT * FROM jittest_simple;
+SELECT * FROM jittest_simple;
+COMMIT;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT * FROM jittest_simple;
+SELECT * FROM jittest_simple;
+
+-- check that tuple deforming on wide tables works
+BEGIN;
+SET LOCAL jit_tuple_deforming = false;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT firstc, lastc FROM extra_wide_table;
+SELECT firstc, lastc FROM extra_wide_table;
+COMMIT;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT firstc, lastc FROM extra_wide_table;
+SELECT firstc, lastc FROM extra_wide_table;
+
+-----
+-- test costing
+-----
+
+-- don't perform JIT compilation unless worthwhile
+BEGIN;
+SET LOCAL jit_above_cost = 8000000000;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT tableoid FROM jittest_simple;
+SET LOCAL enable_seqscan = false;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT tableoid FROM jittest_simple;
+COMMIT;
+
+-- optimize once expensive enough
+BEGIN;
+SET LOCAL jit_above_cost = 0;
+SET LOCAL jit_optimize_above_cost = 8000000000;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT tableoid FROM jittest_simple;
+SET LOCAL enable_seqscan = false;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT tableoid FROM jittest_simple;
+COMMIT;
+
+-- behave sanely if optimization cost is below general JIT costs
+BEGIN;
+SET LOCAL jit_above_cost = 8000000000;
+SET LOCAL jit_optimize_above_cost = 0;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT tableoid FROM jittest_simple;
+SET LOCAL enable_seqscan = false;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT tableoid FROM jittest_simple;
+COMMIT;
+
+-- perform inlining once expensive enough
+BEGIN;
+SET LOCAL jit_above_cost = 0;
+SET LOCAL jit_inline_above_cost = 8000000000;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT tableoid FROM jittest_simple;
+SET LOCAL enable_seqscan = false;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT tableoid FROM jittest_simple;
+COMMIT;
+
+-- perform inlining once expensive enough
+BEGIN;
+SET LOCAL jit_above_cost = 0;
+SET LOCAL jit_inline_above_cost = 8000000000;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT tableoid FROM jittest_simple;
+SET LOCAL enable_seqscan = false;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT tableoid FROM jittest_simple;
+COMMIT;
+
+
+-- perform inlining and optimization once expensive enough
+BEGIN;
+SET LOCAL jit_above_cost = 0;
+SET LOCAL jit_inline_above_cost = 8000000000;
+SET LOCAL jit_optimize_above_cost = 8000000000;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT tableoid FROM jittest_simple;
+SET LOCAL enable_seqscan = false;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT tableoid FROM jittest_simple;
+COMMIT;
+
+-- check that inner/outer tuple deforming can be inferred for upper nodes, join case
+BEGIN;
+SET LOCAL enable_hashjoin = true;
+SET LOCAL enable_mergejoin = false;
+SET LOCAL enable_nestloop = false;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT a.data || b.data FROM jittest_simple a JOIN jittest_simple b USING(id);
+SELECT a.data || b.data FROM jittest_simple a JOIN jittest_simple b USING(id);
+COMMIT;
+BEGIN;
+SET LOCAL enable_hashjoin = false;
+SET LOCAL enable_mergejoin = true;
+SET LOCAL enable_nestloop = false;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT a.data || b.data FROM jittest_simple a JOIN jittest_simple b USING(id);
+SELECT a.data || b.data FROM jittest_simple a JOIN jittest_simple b USING(id);
+COMMIT;
+BEGIN;
+SET LOCAL enable_hashjoin = false;
+SET LOCAL enable_mergejoin = false;
+SET LOCAL enable_nestloop = true;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT a.data || b.data FROM jittest_simple a JOIN jittest_simple b USING(id);
+SELECT a.data || b.data FROM jittest_simple a JOIN jittest_simple b USING(id);
+COMMIT;
+
+-- check that inner/outer tuple deforming can be inferred for upper nodes, agg case
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT count(*), count(data), string_agg(data, ':') FROM jittest_simple;
+SELECT count(*), count(data), string_agg(data, ':') FROM jittest_simple;
+
+-- Check that the equality hash-table function in a hash-aggregate can
+-- be accelerated.
+BEGIN;
+SET LOCAL enable_hashagg = true;
+SET LOCAL enable_sort = false;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT data, string_agg(id::text, ', ') FROM jittest_simple GROUP BY data;
+SELECT data, string_agg(id::text, ', ') FROM jittest_simple GROUP BY data;
+END;
+
+-- Unfortunately for sort based aggregates, the group comparison
+-- function can current not be JITed
+BEGIN;
+SET LOCAL enable_hashagg = false;
+SET LOCAL enable_sort = true;
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS) SELECT data, string_agg(id::text, ', ') FROM jittest_simple GROUP BY data;
+SELECT data, string_agg(id::text, ', ') FROM jittest_simple GROUP BY data;
+END;
+
+-- check that EXPLAIN ANALYZE output is reproducible with the right options
+EXPLAIN (VERBOSE, COSTS OFF, JIT_DETAILS, ANALYZE, TIMING OFF, SUMMARY OFF) SELECT tableoid FROM jittest_simple;
+
+DROP TABLE jittest_simple;
-- 
2.23.0.385.gbc12974a89

