-- -- VALUES test -- insertinto inserttest values(10, 20, '40'), (-1, 2, DEFAULT),
((select2), (select i from (values(3)) as foo (i)), 'values are fun!');
select * from inserttest;
-- -- TOASTed value test -- insertinto inserttest values(30, 50, repeat('x', 10000));
select col1, col2, char_length(col3) from inserttest;
droptable inserttest;
-- -- tuple larger than fillfactor -- CREATETABLE large_tuple_test (a int, b text) WITH (fillfactor = 10); ALTERTABLE large_tuple_test ALTERCOLUMN b SET STORAGE plain;
-- create page w/ free space in range [nearlyEmptyFreeSpace, MaxHeapTupleSize) INSERTINTO large_tuple_test (select1, NULL);
-- should still fit on the page INSERTINTO large_tuple_test (select2, repeat('a', 1000)); SELECT pg_size_pretty(pg_relation_size('large_tuple_test'::regclass, 'main'));
-- add small record to the second page INSERTINTO large_tuple_test (select3, NULL);
-- now this tuple won't fit on the second page, but the insert should -- still succeed by extending the relation INSERTINTO large_tuple_test (select4, repeat('a', 8126));
DROPTABLE large_tuple_test;
-- -- check indirection (field/array assignment), cf bug #14265 -- -- these tests are aware that transformInsertStmt has 3 separate code paths --
create type insert_test_type as (if1 int, if2 text[]);
-- fail (partition key a has a NOT NULL constraint) insertinto part1 values (null); -- fail (expression key (b+0) cannot be null either) insertinto part1 values (1);
createtable list_parted (
a text,
b int
) partition by list (lower(a)); createtable part_aa_bb partition of list_parted FORVALUESIN ('aa', 'bb'); createtable part_cc_dd partition of list_parted FORVALUESIN ('cc', 'dd'); createtable part_null partition of list_parted FORVALUESIN (null);
-- check in case of multi-level partitioned table createtable part_ee_ff partition of list_parted forvaluesin ('ee', 'ff') partition by range (b); createtable part_ee_ff1 partition of part_ee_ff forvaluesfrom (1) to (10); createtable part_ee_ff2 partition of part_ee_ff forvaluesfrom (10) to (20);
-- test default partition createtable part_default partition of list_parted default; -- Negative test: a row, which would fit in other partition, does not fit -- default partition, even when inserted directly insertinto part_default values ('aa', 2); insertinto part_default values (null, 2); -- ok insertinto part_default values ('Zz', 2); -- test if default partition works as expected for multi-level partitioned -- table as well as when default partition itself is further partitioned droptable part_default; createtable part_xx_yy partition of list_parted forvaluesin ('xx', 'yy') partition by list (a); createtable part_xx_yy_p1 partition of part_xx_yy forvaluesin ('xx'); createtable part_xx_yy_defpart partition of part_xx_yy default; createtable part_default partition of list_parted default partition by range(b); createtable part_default_p1 partition of part_default forvaluesfrom (20) to (30); createtable part_default_p2 partition of part_default forvaluesfrom (30) to (40);
select tableoid::regclass, * from range_parted; -- ok insertinto list_parted values (null, 1); insertinto list_parted (a) values ('aA'); -- fail (partition of part_ee_ff not found in both cases) insertinto list_parted values ('EE', 0); insertinto part_ee_ff values ('EE', 0); -- ok insertinto list_parted values ('EE', 1); insertinto part_ee_ff values ('EE', 10); select tableoid::regclass, * from list_parted;
-- some more tests to exercise tuple-routing with multi-level partitioning createtable part_gg partition of list_parted forvaluesin ('gg') partition by range (b); createtable part_gg1 partition of part_gg forvaluesfrom (minvalue) to (1); createtable part_gg2 partition of part_gg forvaluesfrom (1) to (10) partition by range (b); createtable part_gg2_1 partition of part_gg2 forvaluesfrom (1) to (5); createtable part_gg2_2 partition of part_gg2 forvaluesfrom (5) to (10);
createtable part_ee_ff3 partition of part_ee_ff forvaluesfrom (20) to (30) partition by range (b); createtable part_ee_ff3_1 partition of part_ee_ff3 forvaluesfrom (20) to (25); createtable part_ee_ff3_2 partition of part_ee_ff3 forvaluesfrom (25) to (30);
truncate list_parted; insertinto list_parted values ('aa'), ('cc'); insertinto list_parted select'Ff', s.a from generate_series(1, 29) s(a); insertinto list_parted select'gg', s.a from generate_series(1, 9) s(a); insertinto list_parted (b) values (1); select tableoid::regclass::text, a, min(b) as min_b, max(b) as max_b from list_parted groupby1, 2orderby1;
-- direct partition inserts should check hash partition bound constraint
createtable hash_parted (
a int
) partition by hash (a part_test_int4_ops); createtable hpart0 partition of hash_parted forvalueswith (modulus 4, remainder 0); createtable hpart1 partition of hash_parted forvalueswith (modulus 4, remainder 1); createtable hpart2 partition of hash_parted forvalueswith (modulus 4, remainder 2); createtable hpart3 partition of hash_parted forvalueswith (modulus 4, remainder 3);
-- test that a default partition added as the first partition accepts any value -- including null createtable list_parted (a int) partition by list (a); createtable part_default partition of list_parted default;
\d+ part_default insertinto part_default values (null); insertinto part_default values (1); insertinto part_default values (-1); select tableoid::regclass, a from list_parted; -- cleanup droptable list_parted;
-- more tests for certain multi-level partitioning scenarios createtable mlparted (a int, b int) partition by range (a, b); createtable mlparted1 (b intnotnull, a intnotnull) partition by range ((b+0)); createtable mlparted11 (like mlparted1); altertable mlparted11 drop a; altertable mlparted11 add a int; altertable mlparted11 drop a; altertable mlparted11 add a intnotnull; -- attnum for key attribute 'a' is different in mlparted, mlparted1, and mlparted11 select attrelid::regclass, attname, attnum from pg_attribute where attname = 'a' and (attrelid = 'mlparted'::regclass or attrelid = 'mlparted1'::regclass or attrelid = 'mlparted11'::regclass) orderby attrelid::regclass::text;
altertable mlparted1 attach partition mlparted11 forvaluesfrom (2) to (5); altertable mlparted attach partition mlparted1 forvaluesfrom (1, 2) to (1, 10);
-- check that "(1, 2)" is correctly routed to mlparted11. insertinto mlparted values (1, 2); select tableoid::regclass, * from mlparted;
-- check that proper message is shown after failure to route through mlparted1 insertinto mlparted (a, b) values (1, 5);
-- have a BR trigger modify the row such that the check_b is violated create function mlparted11_trig_fn()
returns triggerAS
$$
begin
NEW.b := 4; return NEW;
end;
$$
language plpgsql; createtrigger mlparted11_trig beforeinsertON mlparted11 foreach row execute procedure mlparted11_trig_fn();
-- check that the correct row is shown when constraint check_b fails after -- "(1, 2)" is routed to mlparted11 (actually "(1, 4)" would be shown due -- to the BR trigger mlparted11_trig_fn) insertinto mlparted values (1, 2); droptrigger mlparted11_trig on mlparted11; drop function mlparted11_trig_fn();
-- check that inserting into an internal partition successfully results in -- checking its partition constraint before inserting into the leaf partition -- selected by tuple-routing insertinto mlparted1 (a, b) values (2, 3);
-- check routing error through a list partitioned table when the key is null createtable lparted_nonullpart (a int, b char) partition by list (b); createtable lparted_nonullpart_a partition of lparted_nonullpart forvaluesin ('a'); insertinto lparted_nonullpart values (1); droptable lparted_nonullpart;
-- check that RETURNING works correctly with tuple-routing altertable mlparted dropconstraint check_b; createtable mlparted12 partition of mlparted1 forvaluesfrom (5) to (10); createtable mlparted2 (b intnotnull, a intnotnull); altertable mlparted attach partition mlparted2 forvaluesfrom (1, 10) to (1, 20); createtable mlparted3 partition of mlparted forvaluesfrom (1, 20) to (1, 30); createtable mlparted4 (like mlparted); altertable mlparted4 drop a; altertable mlparted4 add a intnotnull; altertable mlparted attach partition mlparted4 forvaluesfrom (1, 30) to (1, 40); with ins (a, b, c) as
(insertinto mlparted (b, a) select s.a, 1from generate_series(2, 39) s(a) returning tableoid::regclass, *) select a, b, min(c), max(c) from ins groupby a, b orderby1;
altertable mlparted add c text; createtable mlparted5 (c text, a intnotnull, b intnotnull) partition by list (c); createtable mlparted5a (a intnotnull, c text, b intnotnull); altertable mlparted5 attach partition mlparted5a forvaluesin ('a'); altertable mlparted attach partition mlparted5 forvaluesfrom (1, 40) to (1, 50); altertable mlparted addconstraint check_b check (a = 1and b < 45); insertinto mlparted values (1, 45, 'a'); create function mlparted5abrtrig_func() returns triggeras $$ begin new.c = 'b'; return new; end; $$ language plpgsql; createtrigger mlparted5abrtrig beforeinserton mlparted5a foreach row execute procedure mlparted5abrtrig_func(); insertinto mlparted5 (a, b, c) values (1, 40, 'a'); droptable mlparted5; altertable mlparted dropconstraint check_b;
-- Check multi-level default partition createtable mlparted_def partition of mlparted default partition by range(a); createtable mlparted_def1 partition of mlparted_def forvaluesfrom (40) to (50); createtable mlparted_def2 partition of mlparted_def forvaluesfrom (50) to (60); insertinto mlparted values (40, 100); insertinto mlparted_def1 values (42, 100); insertinto mlparted_def2 values (54, 50); -- fail insertinto mlparted values (70, 100); insertinto mlparted_def1 values (52, 50); insertinto mlparted_def2 values (34, 50); -- ok createtable mlparted_defd partition of mlparted_def default; insertinto mlparted values (70, 100);
select tableoid::regclass, * from mlparted_def;
-- Check multi-level tuple routing with attributes dropped from the -- top-most parent. First remove the last attribute. altertable mlparted add d int, add e int; altertable mlparted drop e; createtable mlparted5 partition of mlparted forvaluesfrom (1, 40) to (1, 50) partition by range (c); createtable mlparted5_ab partition of mlparted5 forvaluesfrom ('a') to ('c') partition by list (c); -- This partitioned table should remain with no partitions. createtable mlparted5_cd partition of mlparted5 forvaluesfrom ('c') to ('e') partition by list (c); createtable mlparted5_a partition of mlparted5_ab forvaluesin ('a'); createtable mlparted5_b (d int, b int, c text, a int); altertable mlparted5_ab attach partition mlparted5_b forvaluesin ('b');
truncate mlparted; insertinto mlparted values (1, 2, 'a', 1); insertinto mlparted values (1, 40, 'a', 1); -- goes to mlparted5_a insertinto mlparted values (1, 45, 'b', 1); -- goes to mlparted5_b insertinto mlparted values (1, 45, 'c', 1); -- goes to mlparted5_cd, fails insertinto mlparted values (1, 45, 'f', 1); -- goes to mlparted5, fails select tableoid::regclass, * from mlparted orderby a, b, c, d; altertable mlparted drop d;
truncate mlparted; -- Remove the before last attribute. altertable mlparted add e int, add d int; altertable mlparted drop e; insertinto mlparted values (1, 2, 'a', 1); insertinto mlparted values (1, 40, 'a', 1); -- goes to mlparted5_a insertinto mlparted values (1, 45, 'b', 1); -- goes to mlparted5_b insertinto mlparted values (1, 45, 'c', 1); -- goes to mlparted5_cd, fails insertinto mlparted values (1, 45, 'f', 1); -- goes to mlparted5, fails select tableoid::regclass, * from mlparted orderby a, b, c, d; altertable mlparted drop d; droptable mlparted5;
-- check that message shown after failure to find a partition shows the -- appropriate key description (or none) in various situations createtable key_desc (a int, b int) partition by list ((a+0)); createtable key_desc_1 partition of key_desc forvaluesin (1) partition by range (b);
create user regress_insert_other_user; grantselect (a) on key_desc_1 to regress_insert_other_user; grantinserton key_desc to regress_insert_other_user;
set role regress_insert_other_user; -- no key description is shown insertinto key_desc values (1, 1);
reset role; grantselect (b) on key_desc_1 to regress_insert_other_user; set role regress_insert_other_user; -- key description (b)=(1) is now shown insertinto key_desc values (1, 1);
-- key description is not shown if key contains expression insertinto key_desc values (2, 1);
reset role; revokeallon key_desc from regress_insert_other_user; revokeallon key_desc_1 from regress_insert_other_user; drop role regress_insert_other_user; droptable key_desc, key_desc_1;
-- test minvalue/maxvalue restrictions createtable mcrparted (a int, b int, c int) partition by range (a, abs(b), c); createtable mcrparted0 partition of mcrparted forvaluesfrom (minvalue, 0, 0) to (1, maxvalue, maxvalue); createtable mcrparted2 partition of mcrparted forvaluesfrom (10, 6, minvalue) to (10, maxvalue, minvalue); createtable mcrparted4 partition of mcrparted forvaluesfrom (21, minvalue, 0) to (30, 20, minvalue);
-- check multi-column range partitioning expression enforces the same -- constraint as what tuple-routing would determine it to be createtable mcrparted0 partition of mcrparted forvaluesfrom (minvalue, minvalue, minvalue) to (1, maxvalue, maxvalue); createtable mcrparted1 partition of mcrparted forvaluesfrom (2, 1, minvalue) to (10, 5, 10); createtable mcrparted2 partition of mcrparted forvaluesfrom (10, 6, minvalue) to (10, maxvalue, maxvalue); createtable mcrparted3 partition of mcrparted forvaluesfrom (11, 1, 1) to (20, 10, 10); createtable mcrparted4 partition of mcrparted forvaluesfrom (21, minvalue, minvalue) to (30, 20, maxvalue); createtable mcrparted5 partition of mcrparted forvaluesfrom (30, 21, 20) to (maxvalue, maxvalue, maxvalue);
-- null not allowed in range partition insertinto mcrparted values (null, null, null);
-- check rows select tableoid::regclass::text, * from mcrparted orderby1;
-- cleanup droptable mcrparted;
-- check that a BR constraint can't make partition contain violating rows createtable brtrigpartcon (a int, b text) partition by list (a); createtable brtrigpartcon1 partition of brtrigpartcon forvaluesin (1); createorreplace function brtrigpartcon1trigf() returns triggeras $$begin new.a := 2; return new; end$$ language plpgsql; createtrigger brtrigpartcon1trig beforeinserton brtrigpartcon1 foreach row execute procedure brtrigpartcon1trigf(); insertinto brtrigpartcon values (1, 'hi there'); insertinto brtrigpartcon1 values (1, 'hi there');
-- check that the message shows the appropriate column description in a -- situation where the partitioned table is not the primary ModifyTable node createtable inserttest3 (f1 text default'foo', f2 text default'bar', f3 int); create role regress_coldesc_role; grantinserton inserttest3 to regress_coldesc_role; grantinserton brtrigpartcon to regress_coldesc_role; revokeselecton brtrigpartcon from regress_coldesc_role; set role regress_coldesc_role; with result as (insertinto brtrigpartcon values (1, 'hi there') returning 1) insertinto inserttest3 (f3) select * from result;
reset role;
-- cleanup revokeallon inserttest3 from regress_coldesc_role; revokeallon brtrigpartcon from regress_coldesc_role; drop role regress_coldesc_role; droptable inserttest3; droptable brtrigpartcon; drop function brtrigpartcon1trigf();
-- check that "do nothing" BR triggers work with tuple-routing createtable donothingbrtrig_test (a int, b text) partition by list (a); createtable donothingbrtrig_test1 (b text, a int); createtable donothingbrtrig_test2 (c text, b text, a int); altertable donothingbrtrig_test2 dropcolumn c; createorreplace function donothingbrtrig_func() returns triggeras $$begin raise notice 'b: %', new.b; returnNULL; end$$ language plpgsql; createtrigger donothingbrtrig1 beforeinserton donothingbrtrig_test1 foreach row execute procedure donothingbrtrig_func(); createtrigger donothingbrtrig2 beforeinserton donothingbrtrig_test2 foreach row execute procedure donothingbrtrig_func(); altertable donothingbrtrig_test attach partition donothingbrtrig_test1 forvaluesin (1); altertable donothingbrtrig_test attach partition donothingbrtrig_test2 forvaluesin (2); insertinto donothingbrtrig_test values (1, 'foo'), (2, 'bar');
copy donothingbrtrig_test from stdout; 1 baz 2 qux
\. select tableoid::regclass, * from donothingbrtrig_test;
-- cleanup droptable donothingbrtrig_test; drop function donothingbrtrig_func();
-- check multi-column range partitioning with minvalue/maxvalue constraints createtable mcrparted (a text, b int) partition by range(a, b); createtable mcrparted1_lt_b partition of mcrparted forvaluesfrom (minvalue, minvalue) to('b', minvalue); createtable mcrparted2_b partition of mcrparted forvaluesfrom ('b', minvalue) to ('c', minvalue); createtable mcrparted3_c_to_common partition of mcrparted forvaluesfrom ('c', minvalue) to ('common', minvalue); createtable mcrparted4_common_lt_0 partition of mcrparted forvaluesfrom ('common', minvalue) to ('common', 0); createtable mcrparted5_common_0_to_10 partition of mcrparted forvaluesfrom ('common', 0) to ('common', 10); createtable mcrparted6_common_ge_10 partition of mcrparted forvaluesfrom ('common', 10) to ('common', maxvalue); createtable mcrparted7_gt_common_lt_d partition of mcrparted forvaluesfrom ('common', maxvalue) to ('d', minvalue); createtable mcrparted8_ge_d partition of mcrparted forvaluesfrom ('d', minvalue) to (maxvalue, maxvalue);
-- check that wholerow vars in the RETURNING list work with partitioned tables createtable returningwrtest (a int) partition by list (a); createtable returningwrtest1 partition of returningwrtest forvaluesin (1); insertinto returningwrtest values (1) returning returningwrtest;
-- check also that the wholerow vars in RETURNING list are converted as needed altertable returningwrtest add b text; createtable returningwrtest2 (b text, c int, a int); altertable returningwrtest2 drop c; altertable returningwrtest attach partition returningwrtest2 forvaluesin (2); insertinto returningwrtest values (2, 'foo') returning returningwrtest; droptable returningwrtest;
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.37Bemerkung:
(vorverarbeitet am 2026-08-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.