Skip to content

Commit 5bf3ee2

Browse files
committed
fix: fixed source table schema being different in partition_data_time
1 parent 41bc480 commit 5bf3ee2

10 files changed

+681
-11
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
5.2.4
2+
=====
3+
BUG FIXES
4+
---------
5+
- Allow partition_data functions and procedure to work when the source table is in a different schema than the partition table.
6+
- Removed SECURITY DEFINER from the last two functions that still had it lingering.
7+
8+
19
5.2.3
210
=====
311
BUG FIXES

META.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "pg_partman",
33
"abstract": "Extension to manage partitioned tables by time or ID",
4-
"version": "5.2.3",
4+
"version": "5.2.4",
55
"maintainer": [
66
"Keith Fiske <keith@keithf4.com>"
77
],
@@ -20,9 +20,9 @@
2020
},
2121
"provides": {
2222
"pg_partman": {
23-
"file": "sql/pg_partman--5.2.3.sql",
23+
"file": "sql/pg_partman--5.2.4.sql",
2424
"docfile": "doc/pg_partman.md",
25-
"version": "5.2.3",
25+
"version": "5.2.4",
2626
"abstract": "Extension to manage partitioned tables by time or ID"
2727
}
2828
},

doc/pg_partman.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ Privileges & ownership are NOT inherited by default. If enabled by pg_partman, n
8989
If you are using the IDENTITY feature for sequences, the automatic generation of new sequence values using this feature is only supported when data is inserted through the parent table, not directly into the children.
9090

9191
IMPORTANT NOTES:
92-
* The template table feature is only a temporary solution to help speed up declarative partitioning adoption. As things are handled better in core, the use of the template table will be phased out quickly from pg_partman. If a feature that was managed by the template is supported in core in the future, it will eventually be removed from template management in pg_partman, so please plan ahead for that during major version upgrading if it applies to you.
93-
92+
* The template table feature is only a temporary solution to help speed up declarative partitioning adoption. As things are handled better in core, the use of the template table will be phased out quickly from pg_partman. If a feature that was managed by the template is supported in core in the future, it will eventually be removed from template management in pg_partman, so please plan ahead for that during major version upgrading if it applies to you.
93+
* If you are needing to use the REPLICA IDENTITY property for logical replication with the USING INDEX clause, note that this is only supported if the index you need to use has been created on the actual parent table, NOT the template. Since there is no way to limit whether the REPLICA IDENTITY is made on both the parent table and the template, there's no way to tell which one is the "right" identity. Therefore only the parent table was chosen as the source to be consistent with the other identity inheritance methods (FULL & NONE).
9494
* The UNLOGGED status is managed via pg_partman's template due to an inconsistency in the way the property is handled when either enabling or disabling UNLOGGED on the parent table of a partition set. That property does not actually change on the parent table when the ALTER command is written so new child tables will continue to use the property that existed before. So if you wanted to change a partition set from UNLOGGED to LOGGED for all future children, it does not work. With the property now being managed on the template table, changing it there will allow the change to propagate to newly created children. Pre-existing child tables will have to be changed manually, but that has always been the case. See reported bug at https://www.postgresql.org/message-id/flat/15954-b61523bed4b110c4%40postgresql.org
9595

9696
### Time Zones

pg_partman.control

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
default_version = '5.2.3'
1+
default_version = '5.2.4'
22
comment = 'Extension to manage partitioned tables by time or ID'
33
relocatable = false
44
superuser = false

sql/functions/partition_data_time.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ FOR i IN 1..p_batch_count LOOP
162162
EXIT;
163163
END IF;
164164

165-
SELECT child_start_time INTO v_min_partition_timestamp FROM @extschema@.show_partition_info(v_source_schemaname||'.'||v_last_partition
165+
SELECT child_start_time INTO v_min_partition_timestamp FROM @extschema@.show_partition_info(v_parent_schema||'.'||v_last_partition
166166
, v_partition_interval::text
167167
, p_parent_table);
168168
v_max_partition_timestamp := v_min_partition_timestamp + v_partition_interval;

sql/tables/tables.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ CHECK (@extschema@.check_automatic_maintenance_value(sub_automatic_maintenance))
135135
* Check function for config table epoch types
136136
*/
137137
CREATE FUNCTION @extschema@.check_epoch_type (p_type text) RETURNS boolean
138-
LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER
138+
LANGUAGE plpgsql IMMUTABLE
139139
SET search_path TO pg_catalog, pg_temp
140140
AS $$
141141
DECLARE
@@ -161,7 +161,7 @@ CHECK (@extschema@.check_epoch_type(sub_epoch));
161161
*/
162162
-- Allow hash in future update
163163
CREATE FUNCTION @extschema@.check_partition_type (p_type text) RETURNS boolean
164-
LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER
164+
LANGUAGE plpgsql IMMUTABLE
165165
SET search_path TO pg_catalog, pg_temp
166166
AS $$
167167
DECLARE

test/test-id-10-source-generated.sql

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
-- ########## ID 10 TESTS ##########
2+
-- Additional tests:
3+
-- Partition col is primary key with generated identity
4+
-- Populate initial data from source table
5+
-- Since this is id partitioning, we can use the partition key for primary key, so that should work from parent
6+
7+
\set ON_ERROR_ROLLBACK 1
8+
\set ON_ERROR_STOP true
9+
10+
BEGIN;
11+
SELECT set_config('search_path','partman, public',false);
12+
13+
SELECT plan(51);
14+
CREATE SCHEMA partman_test;
15+
CREATE SCHEMA partman_source;
16+
17+
CREATE TABLE partman_test.id_taptest_table
18+
(col1 bigint PRIMARY KEY NOT NULL GENERATED ALWAYS AS IDENTITY
19+
, col2 text not null default 'stuff'
20+
, col3 timestamptz DEFAULT now()
21+
, col4 text)
22+
PARTITION BY RANGE (col1);
23+
CREATE TABLE partman_test.undo_taptest (LIKE partman_test.id_taptest_table INCLUDING ALL);
24+
25+
CREATE TABLE partman_source.id_taptest_table_source (LIKE partman_test.id_taptest_table INCLUDING ALL);
26+
27+
INSERT INTO partman_source.id_taptest_table_source (col4) VALUES ('stuff'||generate_series(3000000001,3000000009));
28+
29+
SELECT results_eq('SELECT count(*)::int FROM partman_source.id_taptest_table_source', ARRAY[9], 'Ensure source has expected row count');
30+
31+
SELECT create_parent('partman_test.id_taptest_table', 'col1', '10');
32+
33+
SELECT has_table('partman_test', 'id_taptest_table_p0', 'Check id_taptest_table_p0 exists');
34+
SELECT has_table('partman_test', 'id_taptest_table_p10', 'Check id_taptest_table_p10 exists');
35+
SELECT has_table('partman_test', 'id_taptest_table_p20', 'Check id_taptest_table_p20 exists');
36+
SELECT has_table('partman_test', 'id_taptest_table_p30', 'Check id_taptest_table_p30 exists');
37+
SELECT has_table('partman_test', 'id_taptest_table_p40', 'Check id_taptest_table_p40 exists');
38+
SELECT has_table('partman_test', 'id_taptest_table_default', 'Check id_taptest_table_default exists');
39+
SELECT hasnt_table('partman_test', 'id_taptest_table_p50', 'Check id_taptest_table_p50 doesn''t exists yet');
40+
SELECT col_is_pk('partman_test', 'id_taptest_table_p0', ARRAY['col1'], 'Check for primary key in id_taptest_table_p0');
41+
SELECT col_is_pk('partman_test', 'id_taptest_table_p10', ARRAY['col1'], 'Check for primary key in id_taptest_table_p10');
42+
SELECT col_is_pk('partman_test', 'id_taptest_table_p20', ARRAY['col1'], 'Check for primary key in id_taptest_table_p20');
43+
SELECT col_is_pk('partman_test', 'id_taptest_table_p30', ARRAY['col1'], 'Check for primary key in id_taptest_table_p30');
44+
SELECT col_is_pk('partman_test', 'id_taptest_table_p40', ARRAY['col1'], 'Check for primary key in id_taptest_table_p40');
45+
SELECT col_is_pk('partman_test', 'id_taptest_table_default', ARRAY['col1'], 'Check for primary key in id_taptest_table_default');
46+
47+
SELECT results_eq('SELECT partman.partition_data_id(''partman_test.id_taptest_table'', ''20'', p_source_table := ''partman_source.id_taptest_table_source'', p_ignored_columns := ARRAY[''col1''])::int', ARRAY[9], 'Move data out of source table into partitioned table');
48+
49+
SELECT is_empty('SELECT * FROM ONLY partman_test.id_taptest_table_default', 'Check that default table has no data');
50+
SELECT results_eq('SELECT count(*)::int FROM partman_test.id_taptest_table', ARRAY[9], 'Check count from parent table');
51+
SELECT results_eq('SELECT count(*)::int FROM partman_test.id_taptest_table_p0', ARRAY[9], 'Check count from id_taptest_table_p0');
52+
53+
INSERT INTO partman_test.id_taptest_table (col4) VALUES ('stuff'||generate_series(3000000010,3000000025));
54+
-- Run again to make new partition based on latest data
55+
SELECT run_maintenance();
56+
57+
SELECT is_empty('SELECT * FROM ONLY partman_test.id_taptest_table', 'Check that parent table has had no data inserted to it');
58+
SELECT results_eq('SELECT count(*)::int FROM partman_test.id_taptest_table_p10', ARRAY[10], 'Check count from id_taptest_table_p10');
59+
SELECT results_eq('SELECT count(*)::int FROM partman_test.id_taptest_table_p20', ARRAY[6], 'Check count from id_taptest_table_p20');
60+
61+
SELECT has_table('partman_test', 'id_taptest_table_p50', 'Check id_taptest_table_p50 exists');
62+
SELECT has_table('partman_test', 'id_taptest_table_p60', 'Check id_taptest_table_p60 exists yet');
63+
SELECT hasnt_table('partman_test', 'id_taptest_table_p70', 'Check id_taptest_table_p70 doesn''t exists yet');
64+
SELECT col_is_pk('partman_test', 'id_taptest_table_p50', ARRAY['col1'], 'Check for primary key in id_taptest_table_p50');
65+
66+
INSERT INTO partman_test.id_taptest_table (col4) VALUES ('stuff'||generate_series(3000000026,3000000038));
67+
68+
SELECT run_maintenance();
69+
70+
SELECT is_empty('SELECT * FROM ONLY partman_test.id_taptest_table', 'Check that parent table has had no data inserted to it');
71+
SELECT results_eq('SELECT count(*)::int FROM partman_test.id_taptest_table', ARRAY[38], 'Check count from id_taptest_table');
72+
SELECT results_eq('SELECT count(*)::int FROM partman_test.id_taptest_table_p20', ARRAY[10], 'Check count from id_taptest_table_p20');
73+
SELECT results_eq('SELECT count(*)::int FROM partman_test.id_taptest_table_p30', ARRAY[9], 'Check count from id_taptest_table_p30');
74+
75+
SELECT has_table('partman_test', 'id_taptest_table_p70', 'Check id_taptest_table_p70 exists');
76+
SELECT hasnt_table('partman_test', 'id_taptest_table_p80', 'Check id_taptest_table_p80 doesn''t exists yet');
77+
SELECT col_is_pk('partman_test', 'id_taptest_table_p60', ARRAY['col1'], 'Check for primary key in id_taptest_table_p60');
78+
SELECT col_is_pk('partman_test', 'id_taptest_table_p70', ARRAY['col1'], 'Check for primary key in id_taptest_table_p70');
79+
80+
-- Max value is 38 above
81+
SELECT drop_partition_id('partman_test.id_taptest_table', '20', p_keep_table := false);
82+
SELECT hasnt_table('partman_test', 'id_taptest_table_p0', 'Check id_taptest_table_p0 doesn''t exists anymore');
83+
SELECT has_table('partman_test', 'id_taptest_table_p10', 'Check id_taptest_table_p10 exists');
84+
85+
UPDATE part_config SET retention = '10' WHERE parent_table = 'partman_test.id_taptest_table';
86+
SELECT drop_partition_id('partman_test.id_taptest_table', p_keep_table := false);
87+
SELECT hasnt_table('partman_test', 'id_taptest_table_p10', 'Check id_taptest_table_p10 doesn''t exists anymore');
88+
SELECT has_table('partman_test', 'id_taptest_table_p20', 'Check id_taptest_table_p20 exists');
89+
90+
SELECT undo_partition('partman_test.id_taptest_table', 'partman_test.undo_taptest', p_keep_table := false, p_ignored_columns := ARRAY['col1']);
91+
SELECT hasnt_table('partman_test', 'id_taptest_table_p20', 'Check id_taptest_table_p20 does not exist');
92+
SELECT has_table('partman_test', 'id_taptest_table_p30', 'Check id_taptest_table_p30 exists');
93+
94+
-- Test keeping the rest of the tables
95+
SELECT undo_partition('partman_test.id_taptest_table', 'partman_test.undo_taptest', 10, p_ignored_columns := ARRAY['col1']);
96+
SELECT results_eq('SELECT count(*)::int FROM ONLY partman_test.undo_taptest', ARRAY[19], 'Check count from undo table after undo');
97+
SELECT has_table('partman_test', 'id_taptest_table_p30', 'Check id_taptest_table_p30 still exists');
98+
SELECT is_empty('SELECT * FROM partman_test.id_taptest_table_p30', 'Check child table had its data removed id_taptest_table_p30');
99+
SELECT has_table('partman_test', 'id_taptest_table_p40', 'Check id_taptest_table_p40 still exists');
100+
SELECT is_empty('SELECT * FROM partman_test.id_taptest_table_p40', 'Check child table had its data removed id_taptest_table_p40');
101+
SELECT has_table('partman_test', 'id_taptest_table_p50', 'Check id_taptest_table_p50 still exists');
102+
SELECT is_empty('SELECT * FROM partman_test.id_taptest_table_p50', 'Check child table had its data removed id_taptest_table_p50');
103+
SELECT has_table('partman_test', 'id_taptest_table_p60', 'Check id_taptest_table_p60 still exists');
104+
SELECT is_empty('SELECT * FROM partman_test.id_taptest_table_p60', 'Check child table had its data removed id_taptest_table_p60');
105+
SELECT has_table('partman_test', 'id_taptest_table_p70', 'Check id_taptest_table_p70 still exists');
106+
SELECT is_empty('SELECT * FROM partman_test.id_taptest_table_p70', 'Check child table had its data removed id_taptest_table_p70');
107+
108+
SELECT hasnt_table('partman_test', 'template_id_taptest_table', 'Check that template table was dropped');
109+
110+
SELECT * FROM finish();
111+
ROLLBACK;

0 commit comments

Comments
 (0)