mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-09-30 19:01:19 +02:00
Teach PL/pgSQL about partitioned tables.
Table partitioning, introduced in commit f0e44751d7
, added a new
relkind - RELKIND_PARTITIONED_TABLE. Update a couple of places in
PL/pgSQL to handle it. Specifically plpgsql_parse_cwordtype() and
build_row_from_class() needed updating in order to make table%ROWTYPE
and table.col%TYPE work for partitioned tables.
Dean Rasheed, reviewed by Amit Langote.
Discussion: https://postgr.es/m/CAEZATCUnNOKN8sLML9jUzxecALWpEXK3a3W7y0PgFR4%2Buhgc%3Dg%40mail.gmail.com
This commit is contained in:
parent
f356ec5744
commit
d3c3f2b1e2
@ -1761,7 +1761,8 @@ plpgsql_parse_cwordtype(List *idents)
|
|||||||
classStruct->relkind != RELKIND_VIEW &&
|
classStruct->relkind != RELKIND_VIEW &&
|
||||||
classStruct->relkind != RELKIND_MATVIEW &&
|
classStruct->relkind != RELKIND_MATVIEW &&
|
||||||
classStruct->relkind != RELKIND_COMPOSITE_TYPE &&
|
classStruct->relkind != RELKIND_COMPOSITE_TYPE &&
|
||||||
classStruct->relkind != RELKIND_FOREIGN_TABLE)
|
classStruct->relkind != RELKIND_FOREIGN_TABLE &&
|
||||||
|
classStruct->relkind != RELKIND_PARTITIONED_TABLE)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1987,7 +1988,8 @@ build_row_from_class(Oid classOid)
|
|||||||
classStruct->relkind != RELKIND_VIEW &&
|
classStruct->relkind != RELKIND_VIEW &&
|
||||||
classStruct->relkind != RELKIND_MATVIEW &&
|
classStruct->relkind != RELKIND_MATVIEW &&
|
||||||
classStruct->relkind != RELKIND_COMPOSITE_TYPE &&
|
classStruct->relkind != RELKIND_COMPOSITE_TYPE &&
|
||||||
classStruct->relkind != RELKIND_FOREIGN_TABLE)
|
classStruct->relkind != RELKIND_FOREIGN_TABLE &&
|
||||||
|
classStruct->relkind != RELKIND_PARTITIONED_TABLE)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
||||||
errmsg("relation \"%s\" is not a table", relname)));
|
errmsg("relation \"%s\" is not a table", relname)));
|
||||||
|
@ -5979,3 +5979,48 @@ LINE 1: SELECT (SELECT string_agg(id || '=' || name, ',') FROM d)
|
|||||||
^
|
^
|
||||||
QUERY: SELECT (SELECT string_agg(id || '=' || name, ',') FROM d)
|
QUERY: SELECT (SELECT string_agg(id || '=' || name, ',') FROM d)
|
||||||
CONTEXT: PL/pgSQL function alter_table_under_transition_tables_upd_func() line 3 at RAISE
|
CONTEXT: PL/pgSQL function alter_table_under_transition_tables_upd_func() line 3 at RAISE
|
||||||
|
--
|
||||||
|
-- Check type parsing and record fetching from partitioned tables
|
||||||
|
--
|
||||||
|
CREATE TABLE partitioned_table (a int, b text) PARTITION BY LIST (a);
|
||||||
|
CREATE TABLE pt_part1 PARTITION OF partitioned_table FOR VALUES IN (1);
|
||||||
|
CREATE TABLE pt_part2 PARTITION OF partitioned_table FOR VALUES IN (2);
|
||||||
|
INSERT INTO partitioned_table VALUES (1, 'Row 1');
|
||||||
|
INSERT INTO partitioned_table VALUES (2, 'Row 2');
|
||||||
|
CREATE OR REPLACE FUNCTION get_from_partitioned_table(partitioned_table.a%type)
|
||||||
|
RETURNS partitioned_table AS $$
|
||||||
|
DECLARE
|
||||||
|
a_val partitioned_table.a%TYPE;
|
||||||
|
result partitioned_table%ROWTYPE;
|
||||||
|
BEGIN
|
||||||
|
a_val := $1;
|
||||||
|
SELECT * INTO result FROM partitioned_table WHERE a = a_val;
|
||||||
|
RETURN result;
|
||||||
|
END; $$ LANGUAGE plpgsql;
|
||||||
|
NOTICE: type reference partitioned_table.a%TYPE converted to integer
|
||||||
|
SELECT * FROM get_from_partitioned_table(1) AS t;
|
||||||
|
a | b
|
||||||
|
---+-------
|
||||||
|
1 | Row 1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION list_partitioned_table()
|
||||||
|
RETURNS SETOF partitioned_table.a%TYPE AS $$
|
||||||
|
DECLARE
|
||||||
|
row partitioned_table%ROWTYPE;
|
||||||
|
a_val partitioned_table.a%TYPE;
|
||||||
|
BEGIN
|
||||||
|
FOR row IN SELECT * FROM partitioned_table ORDER BY a LOOP
|
||||||
|
a_val := row.a;
|
||||||
|
RETURN NEXT a_val;
|
||||||
|
END LOOP;
|
||||||
|
RETURN;
|
||||||
|
END; $$ LANGUAGE plpgsql;
|
||||||
|
NOTICE: type reference partitioned_table.a%TYPE converted to integer
|
||||||
|
SELECT * FROM list_partitioned_table() AS t;
|
||||||
|
t
|
||||||
|
---
|
||||||
|
1
|
||||||
|
2
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
@ -4766,3 +4766,42 @@ ALTER TABLE alter_table_under_transition_tables
|
|||||||
DROP column name;
|
DROP column name;
|
||||||
UPDATE alter_table_under_transition_tables
|
UPDATE alter_table_under_transition_tables
|
||||||
SET id = id;
|
SET id = id;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Check type parsing and record fetching from partitioned tables
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE partitioned_table (a int, b text) PARTITION BY LIST (a);
|
||||||
|
CREATE TABLE pt_part1 PARTITION OF partitioned_table FOR VALUES IN (1);
|
||||||
|
CREATE TABLE pt_part2 PARTITION OF partitioned_table FOR VALUES IN (2);
|
||||||
|
|
||||||
|
INSERT INTO partitioned_table VALUES (1, 'Row 1');
|
||||||
|
INSERT INTO partitioned_table VALUES (2, 'Row 2');
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION get_from_partitioned_table(partitioned_table.a%type)
|
||||||
|
RETURNS partitioned_table AS $$
|
||||||
|
DECLARE
|
||||||
|
a_val partitioned_table.a%TYPE;
|
||||||
|
result partitioned_table%ROWTYPE;
|
||||||
|
BEGIN
|
||||||
|
a_val := $1;
|
||||||
|
SELECT * INTO result FROM partitioned_table WHERE a = a_val;
|
||||||
|
RETURN result;
|
||||||
|
END; $$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
SELECT * FROM get_from_partitioned_table(1) AS t;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION list_partitioned_table()
|
||||||
|
RETURNS SETOF partitioned_table.a%TYPE AS $$
|
||||||
|
DECLARE
|
||||||
|
row partitioned_table%ROWTYPE;
|
||||||
|
a_val partitioned_table.a%TYPE;
|
||||||
|
BEGIN
|
||||||
|
FOR row IN SELECT * FROM partitioned_table ORDER BY a LOOP
|
||||||
|
a_val := row.a;
|
||||||
|
RETURN NEXT a_val;
|
||||||
|
END LOOP;
|
||||||
|
RETURN;
|
||||||
|
END; $$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
SELECT * FROM list_partitioned_table() AS t;
|
||||||
|
Loading…
Reference in New Issue
Block a user