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_MATVIEW &&
|
||||
classStruct->relkind != RELKIND_COMPOSITE_TYPE &&
|
||||
classStruct->relkind != RELKIND_FOREIGN_TABLE)
|
||||
classStruct->relkind != RELKIND_FOREIGN_TABLE &&
|
||||
classStruct->relkind != RELKIND_PARTITIONED_TABLE)
|
||||
goto done;
|
||||
|
||||
/*
|
||||
@ -1987,7 +1988,8 @@ build_row_from_class(Oid classOid)
|
||||
classStruct->relkind != RELKIND_VIEW &&
|
||||
classStruct->relkind != RELKIND_MATVIEW &&
|
||||
classStruct->relkind != RELKIND_COMPOSITE_TYPE &&
|
||||
classStruct->relkind != RELKIND_FOREIGN_TABLE)
|
||||
classStruct->relkind != RELKIND_FOREIGN_TABLE &&
|
||||
classStruct->relkind != RELKIND_PARTITIONED_TABLE)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
||||
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)
|
||||
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;
|
||||
UPDATE alter_table_under_transition_tables
|
||||
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…
x
Reference in New Issue
Block a user