2003-08-26 20:32:23 +02:00
|
|
|
--
|
2006-09-04 00:37:06 +02:00
|
|
|
-- UPDATE syntax tests
|
2003-08-26 20:32:23 +02:00
|
|
|
--
|
|
|
|
|
|
|
|
CREATE TABLE update_test (
|
|
|
|
a INT DEFAULT 10,
|
2006-09-04 00:37:06 +02:00
|
|
|
b INT,
|
|
|
|
c TEXT
|
2003-08-26 20:32:23 +02:00
|
|
|
);
|
|
|
|
|
Add support for INSERT ... ON CONFLICT DO NOTHING/UPDATE.
The newly added ON CONFLICT clause allows to specify an alternative to
raising a unique or exclusion constraint violation error when inserting.
ON CONFLICT refers to constraints that can either be specified using a
inference clause (by specifying the columns of a unique constraint) or
by naming a unique or exclusion constraint. DO NOTHING avoids the
constraint violation, without touching the pre-existing row. DO UPDATE
SET ... [WHERE ...] updates the pre-existing tuple, and has access to
both the tuple proposed for insertion and the existing tuple; the
optional WHERE clause can be used to prevent an update from being
executed. The UPDATE SET and WHERE clauses have access to the tuple
proposed for insertion using the "magic" EXCLUDED alias, and to the
pre-existing tuple using the table name or its alias.
This feature is often referred to as upsert.
This is implemented using a new infrastructure called "speculative
insertion". It is an optimistic variant of regular insertion that first
does a pre-check for existing tuples and then attempts an insert. If a
violating tuple was inserted concurrently, the speculatively inserted
tuple is deleted and a new attempt is made. If the pre-check finds a
matching tuple the alternative DO NOTHING or DO UPDATE action is taken.
If the insertion succeeds without detecting a conflict, the tuple is
deemed inserted.
To handle the possible ambiguity between the excluded alias and a table
named excluded, and for convenience with long relation names, INSERT
INTO now can alias its target table.
Bumps catversion as stored rules change.
Author: Peter Geoghegan, with significant contributions from Heikki
Linnakangas and Andres Freund. Testing infrastructure by Jeff Janes.
Reviewed-By: Heikki Linnakangas, Andres Freund, Robert Haas, Simon Riggs,
Dean Rasheed, Stephen Frost and many others.
2015-05-08 05:31:36 +02:00
|
|
|
CREATE TABLE upsert_test (
|
|
|
|
a INT PRIMARY KEY,
|
|
|
|
b TEXT
|
|
|
|
);
|
|
|
|
|
2006-09-04 00:37:06 +02:00
|
|
|
INSERT INTO update_test VALUES (5, 10, 'foo');
|
|
|
|
INSERT INTO update_test(b, a) VALUES (15, 10);
|
2003-08-26 20:32:23 +02:00
|
|
|
|
|
|
|
SELECT * FROM update_test;
|
|
|
|
|
|
|
|
UPDATE update_test SET a = DEFAULT, b = DEFAULT;
|
|
|
|
|
|
|
|
SELECT * FROM update_test;
|
|
|
|
|
2006-01-22 06:20:35 +01:00
|
|
|
-- aliases for the UPDATE target table
|
|
|
|
UPDATE update_test AS t SET b = 10 WHERE t.a = 10;
|
|
|
|
|
|
|
|
SELECT * FROM update_test;
|
|
|
|
|
|
|
|
UPDATE update_test t SET b = t.b + 10 WHERE t.a = 10;
|
|
|
|
|
|
|
|
SELECT * FROM update_test;
|
|
|
|
|
2006-08-03 16:54:44 +02:00
|
|
|
--
|
|
|
|
-- Test VALUES in FROM
|
|
|
|
--
|
|
|
|
|
|
|
|
UPDATE update_test SET a=v.i FROM (VALUES(100, 20)) AS v(i, j)
|
2006-09-04 00:37:06 +02:00
|
|
|
WHERE update_test.b = v.j;
|
2006-08-03 16:54:44 +02:00
|
|
|
|
|
|
|
SELECT * FROM update_test;
|
|
|
|
|
2016-11-20 20:26:19 +01:00
|
|
|
-- fail, wrong data type:
|
|
|
|
UPDATE update_test SET a = v.* FROM (VALUES(100, 20)) AS v(i, j)
|
|
|
|
WHERE update_test.b = v.j;
|
|
|
|
|
2006-09-04 00:37:06 +02:00
|
|
|
--
|
|
|
|
-- Test multiple-set-clause syntax
|
|
|
|
--
|
|
|
|
|
Implement UPDATE tab SET (col1,col2,...) = (SELECT ...), ...
This SQL-standard feature allows a sub-SELECT yielding multiple columns
(but only one row) to be used to compute the new values of several columns
to be updated. While the same results can be had with an independent
sub-SELECT per column, such a workaround can require a great deal of
duplicated computation.
The standard actually says that the source for a multi-column assignment
could be any row-valued expression. The implementation used here is
tightly tied to our existing sub-SELECT support and can't handle other
cases; the Bison grammar would have some issues with them too. However,
I don't feel too bad about this since other cases can be converted into
sub-SELECTs. For instance, "SET (a,b,c) = row_valued_function(x)" could
be written "SET (a,b,c) = (SELECT * FROM row_valued_function(x))".
2014-06-18 19:22:25 +02:00
|
|
|
INSERT INTO update_test SELECT a,b+1,c FROM update_test;
|
|
|
|
SELECT * FROM update_test;
|
|
|
|
|
2006-09-04 00:37:06 +02:00
|
|
|
UPDATE update_test SET (c,b,a) = ('bugle', b+11, DEFAULT) WHERE c = 'foo';
|
|
|
|
SELECT * FROM update_test;
|
|
|
|
UPDATE update_test SET (c,b) = ('car', a+b), a = a + 1 WHERE a = 10;
|
|
|
|
SELECT * FROM update_test;
|
|
|
|
-- fail, multi assignment to same column:
|
|
|
|
UPDATE update_test SET (c,b) = ('car', a+b), b = a + 1 WHERE a = 10;
|
|
|
|
|
Implement UPDATE tab SET (col1,col2,...) = (SELECT ...), ...
This SQL-standard feature allows a sub-SELECT yielding multiple columns
(but only one row) to be used to compute the new values of several columns
to be updated. While the same results can be had with an independent
sub-SELECT per column, such a workaround can require a great deal of
duplicated computation.
The standard actually says that the source for a multi-column assignment
could be any row-valued expression. The implementation used here is
tightly tied to our existing sub-SELECT support and can't handle other
cases; the Bison grammar would have some issues with them too. However,
I don't feel too bad about this since other cases can be converted into
sub-SELECTs. For instance, "SET (a,b,c) = row_valued_function(x)" could
be written "SET (a,b,c) = (SELECT * FROM row_valued_function(x))".
2014-06-18 19:22:25 +02:00
|
|
|
-- uncorrelated sub-select:
|
|
|
|
UPDATE update_test
|
|
|
|
SET (b,a) = (select a,b from update_test where b = 41 and c = 'car')
|
|
|
|
WHERE a = 100 AND b = 20;
|
|
|
|
SELECT * FROM update_test;
|
|
|
|
-- correlated sub-select:
|
|
|
|
UPDATE update_test o
|
|
|
|
SET (b,a) = (select a+1,b from update_test i
|
|
|
|
where i.a=o.a and i.b=o.b and i.c is not distinct from o.c);
|
|
|
|
SELECT * FROM update_test;
|
|
|
|
-- fail, multiple rows supplied:
|
|
|
|
UPDATE update_test SET (b,a) = (select a+1,b from update_test);
|
|
|
|
-- set to null if no rows supplied:
|
|
|
|
UPDATE update_test SET (b,a) = (select a+1,b from update_test where a = 1000)
|
|
|
|
WHERE a = 11;
|
|
|
|
SELECT * FROM update_test;
|
Improve handling of "UPDATE ... SET (column_list) = row_constructor".
Previously, the right-hand side of a multiple-column assignment, if it
wasn't a sub-SELECT, had to be a simple parenthesized expression list,
because gram.y was responsible for "bursting" the construct into
independent column assignments. This had the minor defect that you
couldn't write ROW (though you should be able to, since the standard says
this is a row constructor), and the rather larger defect that unlike other
uses of row constructors, we would not expand a "foo.*" item into multiple
columns.
Fix that by changing the RHS to be just "a_expr" in the grammar, leaving
it to transformMultiAssignRef to separate the elements of a RowExpr;
which it will do only after performing standard transformation of the
RowExpr, so that "foo.*" behaves as expected.
The key reason we didn't do that before was the hard-wired handling of
DEFAULT tokens (SetToDefault nodes). This patch deals with that issue by
allowing DEFAULT in any a_expr and having parse analysis throw an error
if SetToDefault is found in an unexpected place. That's an improvement
anyway since the error can be more specific than just "syntax error".
The SQL standard suggests that the RHS could be any a_expr yielding a
suitable row value. This patch doesn't really move the goal posts in that
respect --- you're still limited to RowExpr or a sub-SELECT --- but it does
fix the grammar restriction, so it provides some tangible progress towards
a full implementation. And the limitation is now documented by an explicit
error message rather than an unhelpful "syntax error".
Discussion: <8542.1479742008@sss.pgh.pa.us>
2016-11-22 21:19:57 +01:00
|
|
|
-- *-expansion should work in this context:
|
|
|
|
UPDATE update_test SET (a,b) = ROW(v.*) FROM (VALUES(21, 100)) AS v(i, j)
|
2016-11-20 20:26:19 +01:00
|
|
|
WHERE update_test.a = v.i;
|
Improve handling of "UPDATE ... SET (column_list) = row_constructor".
Previously, the right-hand side of a multiple-column assignment, if it
wasn't a sub-SELECT, had to be a simple parenthesized expression list,
because gram.y was responsible for "bursting" the construct into
independent column assignments. This had the minor defect that you
couldn't write ROW (though you should be able to, since the standard says
this is a row constructor), and the rather larger defect that unlike other
uses of row constructors, we would not expand a "foo.*" item into multiple
columns.
Fix that by changing the RHS to be just "a_expr" in the grammar, leaving
it to transformMultiAssignRef to separate the elements of a RowExpr;
which it will do only after performing standard transformation of the
RowExpr, so that "foo.*" behaves as expected.
The key reason we didn't do that before was the hard-wired handling of
DEFAULT tokens (SetToDefault nodes). This patch deals with that issue by
allowing DEFAULT in any a_expr and having parse analysis throw an error
if SetToDefault is found in an unexpected place. That's an improvement
anyway since the error can be more specific than just "syntax error".
The SQL standard suggests that the RHS could be any a_expr yielding a
suitable row value. This patch doesn't really move the goal posts in that
respect --- you're still limited to RowExpr or a sub-SELECT --- but it does
fix the grammar restriction, so it provides some tangible progress towards
a full implementation. And the limitation is now documented by an explicit
error message rather than an unhelpful "syntax error".
Discussion: <8542.1479742008@sss.pgh.pa.us>
2016-11-22 21:19:57 +01:00
|
|
|
-- you might expect this to work, but syntactically it's not a RowExpr:
|
|
|
|
UPDATE update_test SET (a,b) = (v.*) FROM (VALUES(21, 101)) AS v(i, j)
|
2016-11-20 20:26:19 +01:00
|
|
|
WHERE update_test.a = v.i;
|
2006-09-04 00:37:06 +02:00
|
|
|
|
2006-01-22 06:20:35 +01:00
|
|
|
-- if an alias for the target table is specified, don't allow references
|
|
|
|
-- to the original table name
|
|
|
|
UPDATE update_test AS t SET b = update_test.b + 10 WHERE t.a = 10;
|
|
|
|
|
2011-04-25 15:46:53 +02:00
|
|
|
-- Make sure that we can update to a TOASTed value.
|
|
|
|
UPDATE update_test SET c = repeat('x', 10000) WHERE c = 'car';
|
|
|
|
SELECT a, b, char_length(c) FROM update_test;
|
|
|
|
|
Add support for INSERT ... ON CONFLICT DO NOTHING/UPDATE.
The newly added ON CONFLICT clause allows to specify an alternative to
raising a unique or exclusion constraint violation error when inserting.
ON CONFLICT refers to constraints that can either be specified using a
inference clause (by specifying the columns of a unique constraint) or
by naming a unique or exclusion constraint. DO NOTHING avoids the
constraint violation, without touching the pre-existing row. DO UPDATE
SET ... [WHERE ...] updates the pre-existing tuple, and has access to
both the tuple proposed for insertion and the existing tuple; the
optional WHERE clause can be used to prevent an update from being
executed. The UPDATE SET and WHERE clauses have access to the tuple
proposed for insertion using the "magic" EXCLUDED alias, and to the
pre-existing tuple using the table name or its alias.
This feature is often referred to as upsert.
This is implemented using a new infrastructure called "speculative
insertion". It is an optimistic variant of regular insertion that first
does a pre-check for existing tuples and then attempts an insert. If a
violating tuple was inserted concurrently, the speculatively inserted
tuple is deleted and a new attempt is made. If the pre-check finds a
matching tuple the alternative DO NOTHING or DO UPDATE action is taken.
If the insertion succeeds without detecting a conflict, the tuple is
deemed inserted.
To handle the possible ambiguity between the excluded alias and a table
named excluded, and for convenience with long relation names, INSERT
INTO now can alias its target table.
Bumps catversion as stored rules change.
Author: Peter Geoghegan, with significant contributions from Heikki
Linnakangas and Andres Freund. Testing infrastructure by Jeff Janes.
Reviewed-By: Heikki Linnakangas, Andres Freund, Robert Haas, Simon Riggs,
Dean Rasheed, Stephen Frost and many others.
2015-05-08 05:31:36 +02:00
|
|
|
-- Test ON CONFLICT DO UPDATE
|
|
|
|
INSERT INTO upsert_test VALUES(1, 'Boo');
|
|
|
|
-- uncorrelated sub-select:
|
|
|
|
WITH aaa AS (SELECT 1 AS a, 'Foo' AS b) INSERT INTO upsert_test
|
|
|
|
VALUES (1, 'Bar') ON CONFLICT(a)
|
|
|
|
DO UPDATE SET (b, a) = (SELECT b, a FROM aaa) RETURNING *;
|
|
|
|
-- correlated sub-select:
|
|
|
|
INSERT INTO upsert_test VALUES (1, 'Baz') ON CONFLICT(a)
|
|
|
|
DO UPDATE SET (b, a) = (SELECT b || ', Correlated', a from upsert_test i WHERE i.a = upsert_test.a)
|
|
|
|
RETURNING *;
|
|
|
|
-- correlated sub-select (EXCLUDED.* alias):
|
|
|
|
INSERT INTO upsert_test VALUES (1, 'Bat') ON CONFLICT(a)
|
|
|
|
DO UPDATE SET (b, a) = (SELECT b || ', Excluded', a from upsert_test i WHERE i.a = excluded.a)
|
|
|
|
RETURNING *;
|
|
|
|
|
2005-04-07 17:23:06 +02:00
|
|
|
DROP TABLE update_test;
|
Add support for INSERT ... ON CONFLICT DO NOTHING/UPDATE.
The newly added ON CONFLICT clause allows to specify an alternative to
raising a unique or exclusion constraint violation error when inserting.
ON CONFLICT refers to constraints that can either be specified using a
inference clause (by specifying the columns of a unique constraint) or
by naming a unique or exclusion constraint. DO NOTHING avoids the
constraint violation, without touching the pre-existing row. DO UPDATE
SET ... [WHERE ...] updates the pre-existing tuple, and has access to
both the tuple proposed for insertion and the existing tuple; the
optional WHERE clause can be used to prevent an update from being
executed. The UPDATE SET and WHERE clauses have access to the tuple
proposed for insertion using the "magic" EXCLUDED alias, and to the
pre-existing tuple using the table name or its alias.
This feature is often referred to as upsert.
This is implemented using a new infrastructure called "speculative
insertion". It is an optimistic variant of regular insertion that first
does a pre-check for existing tuples and then attempts an insert. If a
violating tuple was inserted concurrently, the speculatively inserted
tuple is deleted and a new attempt is made. If the pre-check finds a
matching tuple the alternative DO NOTHING or DO UPDATE action is taken.
If the insertion succeeds without detecting a conflict, the tuple is
deemed inserted.
To handle the possible ambiguity between the excluded alias and a table
named excluded, and for convenience with long relation names, INSERT
INTO now can alias its target table.
Bumps catversion as stored rules change.
Author: Peter Geoghegan, with significant contributions from Heikki
Linnakangas and Andres Freund. Testing infrastructure by Jeff Janes.
Reviewed-By: Heikki Linnakangas, Andres Freund, Robert Haas, Simon Riggs,
Dean Rasheed, Stephen Frost and many others.
2015-05-08 05:31:36 +02:00
|
|
|
DROP TABLE upsert_test;
|
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
|
|
|
|
|
|
|
-- update to a partition should check partition bound constraint for the new tuple
|
|
|
|
create table range_parted (
|
|
|
|
a text,
|
|
|
|
b int
|
|
|
|
) partition by range (a, b);
|
|
|
|
create table part_a_1_a_10 partition of range_parted for values from ('a', 1) to ('a', 10);
|
|
|
|
create table part_a_10_a_20 partition of range_parted for values from ('a', 10) to ('a', 20);
|
|
|
|
create table part_b_1_b_10 partition of range_parted for values from ('b', 1) to ('b', 10);
|
|
|
|
create table part_b_10_b_20 partition of range_parted for values from ('b', 10) to ('b', 20);
|
|
|
|
insert into part_a_1_a_10 values ('a', 1);
|
|
|
|
insert into part_b_10_b_20 values ('b', 10);
|
|
|
|
|
|
|
|
-- fail
|
|
|
|
update part_a_1_a_10 set a = 'b' where a = 'a';
|
|
|
|
update range_parted set b = b - 1 where b = 10;
|
|
|
|
-- ok
|
|
|
|
update range_parted set b = b + 1 where b = 10;
|
|
|
|
|
Allow a partitioned table to have a default partition.
Any tuples that don't route to any other partition will route to the
default partition.
Jeevan Ladhe, Beena Emerson, Ashutosh Bapat, Rahila Syed, and Robert
Haas, with review and testing at various stages by (at least) Rushabh
Lathia, Keith Fiske, Amit Langote, Amul Sul, Rajkumar Raghuanshi, Sven
Kunze, Kyotaro Horiguchi, Thom Brown, Rafia Sabih, and Dilip Kumar.
Discussion: http://postgr.es/m/CAH2L28tbN4SYyhS7YV1YBWcitkqbhSWfQCy0G=apRcC_PEO-bg@mail.gmail.com
Discussion: http://postgr.es/m/CAOG9ApEYj34fWMcvBMBQ-YtqR9fTdXhdN82QEKG0SVZ6zeL1xg@mail.gmail.com
2017-09-08 23:28:04 +02:00
|
|
|
-- Creating default partition for range
|
|
|
|
create table part_def partition of range_parted default;
|
|
|
|
\d+ part_def
|
|
|
|
insert into range_parted values ('c', 9);
|
|
|
|
-- ok
|
|
|
|
update part_def set a = 'd' where a = 'c';
|
|
|
|
-- fail
|
|
|
|
update part_def set a = 'a' where a = 'd';
|
|
|
|
|
|
|
|
create table list_parted (
|
|
|
|
a text,
|
|
|
|
b int
|
|
|
|
) partition by list (a);
|
|
|
|
create table list_part1 partition of list_parted for values in ('a', 'b');
|
|
|
|
create table list_default partition of list_parted default;
|
|
|
|
insert into list_part1 values ('a', 1);
|
|
|
|
insert into list_default values ('d', 10);
|
|
|
|
|
|
|
|
-- fail
|
|
|
|
update list_default set a = 'a' where a = 'd';
|
|
|
|
-- ok
|
|
|
|
update list_default set a = 'x' where a = 'd';
|
|
|
|
|
Add hash partitioning.
Hash partitioning is useful when you want to partition a growing data
set evenly. This can be useful to keep table sizes reasonable, which
makes maintenance operations such as VACUUM faster, or to enable
partition-wise join.
At present, we still depend on constraint exclusion for partitioning
pruning, and the shape of the partition constraints for hash
partitioning is such that that doesn't work. Work is underway to fix
that, which should both improve performance and make partitioning
pruning work with hash partitioning.
Amul Sul, reviewed and tested by Dilip Kumar, Ashutosh Bapat, Yugo
Nagata, Rajkumar Raghuwanshi, Jesper Pedersen, and by me. A few
final tweaks also by me.
Discussion: http://postgr.es/m/CAAJ_b96fhpJAP=ALbETmeLk1Uni_GFZD938zgenhF49qgDTjaQ@mail.gmail.com
2017-11-10 00:07:25 +01:00
|
|
|
-- create custom operator class and hash function, for the same reason
|
|
|
|
-- explained in alter_table.sql
|
|
|
|
create or replace function dummy_hashint4(a int4, seed int8) returns int8 as
|
|
|
|
$$ begin return (a + seed); end; $$ language 'plpgsql' immutable;
|
|
|
|
create operator class custom_opclass for type int4 using hash as
|
|
|
|
operator 1 = , function 2 dummy_hashint4(int4, int8);
|
|
|
|
|
|
|
|
create table hash_parted (
|
|
|
|
a int,
|
|
|
|
b int
|
|
|
|
) partition by hash (a custom_opclass, b custom_opclass);
|
|
|
|
create table hpart1 partition of hash_parted for values with (modulus 2, remainder 1);
|
|
|
|
create table hpart2 partition of hash_parted for values with (modulus 4, remainder 2);
|
|
|
|
create table hpart3 partition of hash_parted for values with (modulus 8, remainder 0);
|
|
|
|
create table hpart4 partition of hash_parted for values with (modulus 8, remainder 4);
|
|
|
|
insert into hpart1 values (1, 1);
|
|
|
|
insert into hpart2 values (2, 5);
|
|
|
|
insert into hpart4 values (3, 4);
|
|
|
|
|
|
|
|
-- fail
|
|
|
|
update hpart1 set a = 3, b=4 where a = 1;
|
|
|
|
update hash_parted set b = b - 1 where b = 1;
|
|
|
|
-- ok
|
|
|
|
update hash_parted set b = b + 8 where b = 1;
|
|
|
|
|
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
|
|
|
-- cleanup
|
2017-03-06 11:20:53 +01:00
|
|
|
drop table range_parted;
|
Allow a partitioned table to have a default partition.
Any tuples that don't route to any other partition will route to the
default partition.
Jeevan Ladhe, Beena Emerson, Ashutosh Bapat, Rahila Syed, and Robert
Haas, with review and testing at various stages by (at least) Rushabh
Lathia, Keith Fiske, Amit Langote, Amul Sul, Rajkumar Raghuanshi, Sven
Kunze, Kyotaro Horiguchi, Thom Brown, Rafia Sabih, and Dilip Kumar.
Discussion: http://postgr.es/m/CAH2L28tbN4SYyhS7YV1YBWcitkqbhSWfQCy0G=apRcC_PEO-bg@mail.gmail.com
Discussion: http://postgr.es/m/CAOG9ApEYj34fWMcvBMBQ-YtqR9fTdXhdN82QEKG0SVZ6zeL1xg@mail.gmail.com
2017-09-08 23:28:04 +02:00
|
|
|
drop table list_parted;
|
Add hash partitioning.
Hash partitioning is useful when you want to partition a growing data
set evenly. This can be useful to keep table sizes reasonable, which
makes maintenance operations such as VACUUM faster, or to enable
partition-wise join.
At present, we still depend on constraint exclusion for partitioning
pruning, and the shape of the partition constraints for hash
partitioning is such that that doesn't work. Work is underway to fix
that, which should both improve performance and make partitioning
pruning work with hash partitioning.
Amul Sul, reviewed and tested by Dilip Kumar, Ashutosh Bapat, Yugo
Nagata, Rajkumar Raghuwanshi, Jesper Pedersen, and by me. A few
final tweaks also by me.
Discussion: http://postgr.es/m/CAAJ_b96fhpJAP=ALbETmeLk1Uni_GFZD938zgenhF49qgDTjaQ@mail.gmail.com
2017-11-10 00:07:25 +01:00
|
|
|
drop table hash_parted;
|
|
|
|
drop operator class custom_opclass using hash;
|
|
|
|
drop function dummy_hashint4(a int4, seed int8);
|