@@ -2113,3 +2113,108 @@ def test_partition_evolution_pushdown(
21132113 assert src_data == tgt_data
21142114
21152115 _drop_tables (pg_conn , "evo_src" , "evo_tgt" )
2116+
2117+
2118+ def test_enable_partitioned_write_pushdown_guc (
2119+ extension ,
2120+ s3 ,
2121+ with_default_location ,
2122+ pg_conn ,
2123+ pgduck_conn ,
2124+ grant_access_to_data_file_partition ,
2125+ ):
2126+ """
2127+ When pg_lake_table.enable_partitioned_write_pushdown is off,
2128+ partitioned INSERT..SELECT falls back to row-by-row processing
2129+ but still produces correct results. Non-partitioned pushdown
2130+ remains unaffected.
2131+ """
2132+ _setup_schema (pg_conn )
2133+ _drop_tables (pg_conn , "guc_src" , "guc_tgt_part" , "guc_tgt_nopart" )
2134+ src = _table ("guc_src" )
2135+ tgt_part = _table ("guc_tgt_part" )
2136+ tgt_nopart = _table ("guc_tgt_nopart" )
2137+
2138+ # source table
2139+ run_command (
2140+ f"""
2141+ CREATE TABLE { src } (id INT, ts TIMESTAMP)
2142+ USING iceberg WITH (autovacuum_enabled = false);
2143+ INSERT INTO { src }
2144+ SELECT i, '2025-01-01'::timestamp + (i || ' days')::interval
2145+ FROM generate_series(1, 20) AS i;
2146+ """ ,
2147+ pg_conn ,
2148+ )
2149+ pg_conn .commit ()
2150+
2151+ # partitioned target
2152+ run_command (
2153+ f"""
2154+ CREATE TABLE { tgt_part } (id INT, ts TIMESTAMP)
2155+ USING iceberg
2156+ WITH (partition_by = 'month(ts)', autovacuum_enabled = false);
2157+ """ ,
2158+ pg_conn ,
2159+ )
2160+ pg_conn .commit ()
2161+
2162+ # non-partitioned target
2163+ run_command (
2164+ f"""
2165+ CREATE TABLE { tgt_nopart } (id INT, ts TIMESTAMP)
2166+ USING iceberg WITH (autovacuum_enabled = false);
2167+ """ ,
2168+ pg_conn ,
2169+ )
2170+ pg_conn .commit ()
2171+
2172+ # verify pushdown is on by default for partitioned tables
2173+ assert_query_pushdownable (
2174+ f"INSERT INTO { tgt_part } SELECT * FROM { src } " , pg_conn
2175+ )
2176+
2177+ # disable partitioned write pushdown
2178+ run_command (
2179+ "SET pg_lake_table.enable_partitioned_write_pushdown TO false;" , pg_conn
2180+ )
2181+
2182+ # partitioned INSERT..SELECT should no longer be pushdownable
2183+ assert_query_not_pushdownable (
2184+ f"INSERT INTO { tgt_part } SELECT * FROM { src } " , pg_conn
2185+ )
2186+
2187+ # non-partitioned INSERT..SELECT should still be pushdownable
2188+ assert_query_pushdownable (
2189+ f"INSERT INTO { tgt_nopart } SELECT * FROM { src } " , pg_conn
2190+ )
2191+
2192+ # insert via row-by-row fallback should still produce correct results
2193+ run_command (f"INSERT INTO { tgt_part } SELECT * FROM { src } ;" , pg_conn )
2194+ pg_conn .commit ()
2195+
2196+ res = run_query (
2197+ f"""
2198+ SELECT count(*), count(DISTINCT id)
2199+ FROM { tgt_part } ;
2200+ """ ,
2201+ pg_conn ,
2202+ )
2203+ assert res [0 ][0 ] == 20
2204+ assert res [0 ][1 ] == 20
2205+
2206+ # verify partition files are correct
2207+ file_cnt = run_query (
2208+ f"""
2209+ SELECT count(*)
2210+ FROM lake_table.files
2211+ WHERE table_name = '{ tgt_part } '::regclass;
2212+ """ ,
2213+ pg_conn ,
2214+ )[0 ][0 ]
2215+ assert file_cnt == 1 # all in January 2025
2216+
2217+ run_command (
2218+ "RESET pg_lake_table.enable_partitioned_write_pushdown;" , pg_conn
2219+ )
2220+ _drop_tables (pg_conn , "guc_src" , "guc_tgt_part" , "guc_tgt_nopart" )
0 commit comments