mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 12:41:57 +03:00
Adjust INCLUDE index truncation comments and code.
Add several assertions that ensure that we're dealing with a pivot tuple without non-key attributes where that's expected. Also, remove the assertion within _bt_isequal(), restoring the v10 function signature. A similar check will be performed for the page highkey within _bt_moveright() in most cases. Also avoid dropping all objects within regression tests, to increase pg_dump test coverage for INCLUDE indexes. Rather than using infrastructure that's generally intended to be used with reference counted heap tuple descriptors during truncation, use the same function that was introduced to store flat TupleDescs in shared memory (we use a temp palloc'd buffer). This isn't strictly necessary, but seems more future-proof than the old approach. It also lets us avoid including rel.h within indextuple.c, which was arguably a modularity violation. Also, we now call index_deform_tuple() with the truncated TupleDesc, not the source TupleDesc, since that's more robust, and saves a few cycles. In passing, fix a memory leak by pfree'ing truncated pivot tuple memory during CREATE INDEX. Also pfree during a page split, just to be consistent. Refactor _bt_check_natts() to be more readable. Author: Peter Geoghegan with some editorization by me Reviewed by: Alexander Korotkov, Teodor Sigaev Discussion: https://www.postgresql.org/message-id/CAH2-Wz%3DkCWuXeMrBCopC-tFs3FbiVxQNjjgNKdG2sHxZ5k2y3w%40mail.gmail.com
This commit is contained in:
@ -1,81 +1,78 @@
|
||||
/*
|
||||
* 1.test CREATE INDEX
|
||||
*
|
||||
* Deliberately avoid dropping objects in this section, to get some pg_dump
|
||||
* coverage.
|
||||
*/
|
||||
-- Regular index with included columns
|
||||
CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box);
|
||||
INSERT INTO tbl SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
|
||||
CREATE INDEX tbl_idx ON tbl using btree (c1, c2) INCLUDE (c3,c4);
|
||||
CREATE TABLE tbl_include_reg (c1 int, c2 int, c3 int, c4 box);
|
||||
INSERT INTO tbl_include_reg SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
|
||||
CREATE INDEX tbl_include_reg_idx ON tbl_include_reg using btree (c1, c2) INCLUDE (c3,c4);
|
||||
-- must fail because of intersection of key and included columns
|
||||
CREATE INDEX tbl_idx ON tbl using btree (c1, c2) INCLUDE (c1,c3);
|
||||
CREATE INDEX tbl_include_reg_idx ON tbl_include_reg using btree (c1, c2) INCLUDE (c1,c3);
|
||||
ERROR: included columns must not intersect with key columns
|
||||
SELECT pg_get_indexdef(i.indexrelid)
|
||||
FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid
|
||||
WHERE i.indrelid = 'tbl'::regclass ORDER BY c.relname;
|
||||
pg_get_indexdef
|
||||
--------------------------------------------------------------------------
|
||||
CREATE INDEX tbl_idx ON public.tbl USING btree (c1, c2) INCLUDE (c3, c4)
|
||||
WHERE i.indrelid = 'tbl_include_reg'::regclass ORDER BY c.relname;
|
||||
pg_get_indexdef
|
||||
--------------------------------------------------------------------------------------------------
|
||||
CREATE INDEX tbl_include_reg_idx ON public.tbl_include_reg USING btree (c1, c2) INCLUDE (c3, c4)
|
||||
(1 row)
|
||||
|
||||
DROP TABLE tbl;
|
||||
-- Unique index and unique constraint
|
||||
CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box);
|
||||
INSERT INTO tbl SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
|
||||
CREATE UNIQUE INDEX tbl_idx_unique ON tbl using btree (c1, c2) INCLUDE (c3, c4);
|
||||
ALTER TABLE tbl add UNIQUE USING INDEX tbl_idx_unique;
|
||||
ALTER TABLE tbl add UNIQUE (c1, c2) INCLUDE (c3, c4);
|
||||
CREATE TABLE tbl_include_unique1 (c1 int, c2 int, c3 int, c4 box);
|
||||
INSERT INTO tbl_include_unique1 SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
|
||||
CREATE UNIQUE INDEX tbl_include_unique1_idx_unique ON tbl_include_unique1 using btree (c1, c2) INCLUDE (c3, c4);
|
||||
ALTER TABLE tbl_include_unique1 add UNIQUE USING INDEX tbl_include_unique1_idx_unique;
|
||||
ALTER TABLE tbl_include_unique1 add UNIQUE (c1, c2) INCLUDE (c3, c4);
|
||||
SELECT pg_get_indexdef(i.indexrelid)
|
||||
FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid
|
||||
WHERE i.indrelid = 'tbl'::regclass ORDER BY c.relname;
|
||||
pg_get_indexdef
|
||||
---------------------------------------------------------------------------------------------
|
||||
CREATE UNIQUE INDEX tbl_c1_c2_c3_c4_key ON public.tbl USING btree (c1, c2) INCLUDE (c3, c4)
|
||||
CREATE UNIQUE INDEX tbl_idx_unique ON public.tbl USING btree (c1, c2) INCLUDE (c3, c4)
|
||||
WHERE i.indrelid = 'tbl_include_unique1'::regclass ORDER BY c.relname;
|
||||
pg_get_indexdef
|
||||
-----------------------------------------------------------------------------------------------------------------------------
|
||||
CREATE UNIQUE INDEX tbl_include_unique1_c1_c2_c3_c4_key ON public.tbl_include_unique1 USING btree (c1, c2) INCLUDE (c3, c4)
|
||||
CREATE UNIQUE INDEX tbl_include_unique1_idx_unique ON public.tbl_include_unique1 USING btree (c1, c2) INCLUDE (c3, c4)
|
||||
(2 rows)
|
||||
|
||||
DROP TABLE tbl;
|
||||
-- Unique index and unique constraint. Both must fail.
|
||||
CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box);
|
||||
INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
|
||||
CREATE UNIQUE INDEX tbl_idx_unique ON tbl using btree (c1, c2) INCLUDE (c3, c4);
|
||||
ERROR: could not create unique index "tbl_idx_unique"
|
||||
CREATE TABLE tbl_include_unique2 (c1 int, c2 int, c3 int, c4 box);
|
||||
INSERT INTO tbl_include_unique2 SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
|
||||
CREATE UNIQUE INDEX tbl_include_unique2_idx_unique ON tbl_include_unique2 using btree (c1, c2) INCLUDE (c3, c4);
|
||||
ERROR: could not create unique index "tbl_include_unique2_idx_unique"
|
||||
DETAIL: Key (c1, c2)=(1, 2) is duplicated.
|
||||
ALTER TABLE tbl add UNIQUE (c1, c2) INCLUDE (c3, c4);
|
||||
ERROR: could not create unique index "tbl_c1_c2_c3_c4_key"
|
||||
ALTER TABLE tbl_include_unique2 add UNIQUE (c1, c2) INCLUDE (c3, c4);
|
||||
ERROR: could not create unique index "tbl_include_unique2_c1_c2_c3_c4_key"
|
||||
DETAIL: Key (c1, c2)=(1, 2) is duplicated.
|
||||
DROP TABLE tbl;
|
||||
-- PK constraint
|
||||
CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box);
|
||||
INSERT INTO tbl SELECT 1, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
|
||||
ALTER TABLE tbl add PRIMARY KEY (c1, c2) INCLUDE (c3, c4);
|
||||
CREATE TABLE tbl_include_pk (c1 int, c2 int, c3 int, c4 box);
|
||||
INSERT INTO tbl_include_pk SELECT 1, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
|
||||
ALTER TABLE tbl_include_pk add PRIMARY KEY (c1, c2) INCLUDE (c3, c4);
|
||||
SELECT pg_get_indexdef(i.indexrelid)
|
||||
FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid
|
||||
WHERE i.indrelid = 'tbl'::regclass ORDER BY c.relname;
|
||||
pg_get_indexdef
|
||||
----------------------------------------------------------------------------------
|
||||
CREATE UNIQUE INDEX tbl_pkey ON public.tbl USING btree (c1, c2) INCLUDE (c3, c4)
|
||||
WHERE i.indrelid = 'tbl_include_pk'::regclass ORDER BY c.relname;
|
||||
pg_get_indexdef
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
CREATE UNIQUE INDEX tbl_include_pk_pkey ON public.tbl_include_pk USING btree (c1, c2) INCLUDE (c3, c4)
|
||||
(1 row)
|
||||
|
||||
DROP TABLE tbl;
|
||||
CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box);
|
||||
INSERT INTO tbl SELECT 1, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
|
||||
CREATE UNIQUE INDEX tbl_idx_unique ON tbl using btree (c1, c2) INCLUDE (c3, c4);
|
||||
ALTER TABLE tbl add PRIMARY KEY USING INDEX tbl_idx_unique;
|
||||
CREATE TABLE tbl_include_box (c1 int, c2 int, c3 int, c4 box);
|
||||
INSERT INTO tbl_include_box SELECT 1, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
|
||||
CREATE UNIQUE INDEX tbl_include_box_idx_unique ON tbl_include_box using btree (c1, c2) INCLUDE (c3, c4);
|
||||
ALTER TABLE tbl_include_box add PRIMARY KEY USING INDEX tbl_include_box_idx_unique;
|
||||
SELECT pg_get_indexdef(i.indexrelid)
|
||||
FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid
|
||||
WHERE i.indrelid = 'tbl'::regclass ORDER BY c.relname;
|
||||
pg_get_indexdef
|
||||
----------------------------------------------------------------------------------------
|
||||
CREATE UNIQUE INDEX tbl_idx_unique ON public.tbl USING btree (c1, c2) INCLUDE (c3, c4)
|
||||
WHERE i.indrelid = 'tbl_include_box'::regclass ORDER BY c.relname;
|
||||
pg_get_indexdef
|
||||
----------------------------------------------------------------------------------------------------------------
|
||||
CREATE UNIQUE INDEX tbl_include_box_idx_unique ON public.tbl_include_box USING btree (c1, c2) INCLUDE (c3, c4)
|
||||
(1 row)
|
||||
|
||||
DROP TABLE tbl;
|
||||
-- PK constraint. Must fail.
|
||||
CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box);
|
||||
INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
|
||||
ALTER TABLE tbl add PRIMARY KEY (c1, c2) INCLUDE (c3, c4);
|
||||
ERROR: could not create unique index "tbl_pkey"
|
||||
CREATE TABLE tbl_include_box_pk (c1 int, c2 int, c3 int, c4 box);
|
||||
INSERT INTO tbl_include_box_pk SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
|
||||
ALTER TABLE tbl_include_box_pk add PRIMARY KEY (c1, c2) INCLUDE (c3, c4);
|
||||
ERROR: could not create unique index "tbl_include_box_pk_pkey"
|
||||
DETAIL: Key (c1, c2)=(1, 2) is duplicated.
|
||||
DROP TABLE tbl;
|
||||
/*
|
||||
* 2. Test CREATE TABLE with constraint
|
||||
*/
|
||||
|
@ -185,6 +185,12 @@ sql_sizing|f
|
||||
sql_sizing_profiles|f
|
||||
stud_emp|f
|
||||
student|f
|
||||
tbl_include_box|t
|
||||
tbl_include_box_pk|f
|
||||
tbl_include_pk|t
|
||||
tbl_include_reg|t
|
||||
tbl_include_unique1|t
|
||||
tbl_include_unique2|f
|
||||
tenk1|t
|
||||
tenk2|t
|
||||
test_range_excl|t
|
||||
|
@ -1,59 +1,56 @@
|
||||
/*
|
||||
* 1.test CREATE INDEX
|
||||
*
|
||||
* Deliberately avoid dropping objects in this section, to get some pg_dump
|
||||
* coverage.
|
||||
*/
|
||||
|
||||
-- Regular index with included columns
|
||||
CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box);
|
||||
INSERT INTO tbl SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
|
||||
CREATE INDEX tbl_idx ON tbl using btree (c1, c2) INCLUDE (c3,c4);
|
||||
CREATE TABLE tbl_include_reg (c1 int, c2 int, c3 int, c4 box);
|
||||
INSERT INTO tbl_include_reg SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
|
||||
CREATE INDEX tbl_include_reg_idx ON tbl_include_reg using btree (c1, c2) INCLUDE (c3,c4);
|
||||
-- must fail because of intersection of key and included columns
|
||||
CREATE INDEX tbl_idx ON tbl using btree (c1, c2) INCLUDE (c1,c3);
|
||||
CREATE INDEX tbl_include_reg_idx ON tbl_include_reg using btree (c1, c2) INCLUDE (c1,c3);
|
||||
SELECT pg_get_indexdef(i.indexrelid)
|
||||
FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid
|
||||
WHERE i.indrelid = 'tbl'::regclass ORDER BY c.relname;
|
||||
DROP TABLE tbl;
|
||||
WHERE i.indrelid = 'tbl_include_reg'::regclass ORDER BY c.relname;
|
||||
|
||||
-- Unique index and unique constraint
|
||||
CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box);
|
||||
INSERT INTO tbl SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
|
||||
CREATE UNIQUE INDEX tbl_idx_unique ON tbl using btree (c1, c2) INCLUDE (c3, c4);
|
||||
ALTER TABLE tbl add UNIQUE USING INDEX tbl_idx_unique;
|
||||
ALTER TABLE tbl add UNIQUE (c1, c2) INCLUDE (c3, c4);
|
||||
CREATE TABLE tbl_include_unique1 (c1 int, c2 int, c3 int, c4 box);
|
||||
INSERT INTO tbl_include_unique1 SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
|
||||
CREATE UNIQUE INDEX tbl_include_unique1_idx_unique ON tbl_include_unique1 using btree (c1, c2) INCLUDE (c3, c4);
|
||||
ALTER TABLE tbl_include_unique1 add UNIQUE USING INDEX tbl_include_unique1_idx_unique;
|
||||
ALTER TABLE tbl_include_unique1 add UNIQUE (c1, c2) INCLUDE (c3, c4);
|
||||
SELECT pg_get_indexdef(i.indexrelid)
|
||||
FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid
|
||||
WHERE i.indrelid = 'tbl'::regclass ORDER BY c.relname;
|
||||
DROP TABLE tbl;
|
||||
WHERE i.indrelid = 'tbl_include_unique1'::regclass ORDER BY c.relname;
|
||||
|
||||
-- Unique index and unique constraint. Both must fail.
|
||||
CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box);
|
||||
INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
|
||||
CREATE UNIQUE INDEX tbl_idx_unique ON tbl using btree (c1, c2) INCLUDE (c3, c4);
|
||||
ALTER TABLE tbl add UNIQUE (c1, c2) INCLUDE (c3, c4);
|
||||
DROP TABLE tbl;
|
||||
CREATE TABLE tbl_include_unique2 (c1 int, c2 int, c3 int, c4 box);
|
||||
INSERT INTO tbl_include_unique2 SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
|
||||
CREATE UNIQUE INDEX tbl_include_unique2_idx_unique ON tbl_include_unique2 using btree (c1, c2) INCLUDE (c3, c4);
|
||||
ALTER TABLE tbl_include_unique2 add UNIQUE (c1, c2) INCLUDE (c3, c4);
|
||||
|
||||
-- PK constraint
|
||||
CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box);
|
||||
INSERT INTO tbl SELECT 1, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
|
||||
ALTER TABLE tbl add PRIMARY KEY (c1, c2) INCLUDE (c3, c4);
|
||||
CREATE TABLE tbl_include_pk (c1 int, c2 int, c3 int, c4 box);
|
||||
INSERT INTO tbl_include_pk SELECT 1, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
|
||||
ALTER TABLE tbl_include_pk add PRIMARY KEY (c1, c2) INCLUDE (c3, c4);
|
||||
SELECT pg_get_indexdef(i.indexrelid)
|
||||
FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid
|
||||
WHERE i.indrelid = 'tbl'::regclass ORDER BY c.relname;
|
||||
DROP TABLE tbl;
|
||||
WHERE i.indrelid = 'tbl_include_pk'::regclass ORDER BY c.relname;
|
||||
|
||||
CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box);
|
||||
INSERT INTO tbl SELECT 1, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
|
||||
CREATE UNIQUE INDEX tbl_idx_unique ON tbl using btree (c1, c2) INCLUDE (c3, c4);
|
||||
ALTER TABLE tbl add PRIMARY KEY USING INDEX tbl_idx_unique;
|
||||
CREATE TABLE tbl_include_box (c1 int, c2 int, c3 int, c4 box);
|
||||
INSERT INTO tbl_include_box SELECT 1, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
|
||||
CREATE UNIQUE INDEX tbl_include_box_idx_unique ON tbl_include_box using btree (c1, c2) INCLUDE (c3, c4);
|
||||
ALTER TABLE tbl_include_box add PRIMARY KEY USING INDEX tbl_include_box_idx_unique;
|
||||
SELECT pg_get_indexdef(i.indexrelid)
|
||||
FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid
|
||||
WHERE i.indrelid = 'tbl'::regclass ORDER BY c.relname;
|
||||
DROP TABLE tbl;
|
||||
WHERE i.indrelid = 'tbl_include_box'::regclass ORDER BY c.relname;
|
||||
|
||||
-- PK constraint. Must fail.
|
||||
CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box);
|
||||
INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
|
||||
ALTER TABLE tbl add PRIMARY KEY (c1, c2) INCLUDE (c3, c4);
|
||||
DROP TABLE tbl;
|
||||
CREATE TABLE tbl_include_box_pk (c1 int, c2 int, c3 int, c4 box);
|
||||
INSERT INTO tbl_include_box_pk SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
|
||||
ALTER TABLE tbl_include_box_pk add PRIMARY KEY (c1, c2) INCLUDE (c3, c4);
|
||||
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user