On 13 June 2017 at 05:50, Ashutosh Bapat <ashutosh.ba...@enterprisedb.com> wrote: > On Tue, Jun 13, 2017 at 12:03 AM, Dean Rasheed <dean.a.rash...@gmail.com> > wrote: >> Barring objections, I'll push my original patch and work up patches >> for the other couple of issues I found. > > No objections, the patch is good to go as is. Sorry for high-jacking > this thread. >
Thanks for the review. Patch pushed. Here are patches for the other 2 issues, with test cases showing how they currently fail on HEAD. Regards, Dean
diff --git a/src/backend/commands/policy.c b/src/backend/commands/policy.c new file mode 100644 index 4a75842..dad31df --- a/src/backend/commands/policy.c +++ b/src/backend/commands/policy.c @@ -474,7 +474,8 @@ RemoveRoleFromObjectPolicy(Oid roleid, O rel = relation_open(relid, AccessExclusiveLock); - if (rel->rd_rel->relkind != RELKIND_RELATION) + if (rel->rd_rel->relkind != RELKIND_RELATION && + rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("\"%s\" is not a table", diff --git a/src/test/regress/expected/rowsecurity.out b/src/test/regress/expected/rowsecurity.out new file mode 100644 index e2ec961..26d28f2 --- a/src/test/regress/expected/rowsecurity.out +++ b/src/test/regress/expected/rowsecurity.out @@ -3885,6 +3885,7 @@ RESET SESSION AUTHORIZATION; CREATE ROLE regress_rls_dob_role1; CREATE ROLE regress_rls_dob_role2; CREATE TABLE dob_t1 (c1 int); +CREATE TABLE dob_t2 (c1 int) PARTITION BY RANGE (c1); CREATE POLICY p1 ON dob_t1 TO regress_rls_dob_role1 USING (true); DROP OWNED BY regress_rls_dob_role1; DROP POLICY p1 ON dob_t1; -- should fail, already gone @@ -3892,6 +3893,9 @@ ERROR: policy "p1" for table "dob_t1" d CREATE POLICY p1 ON dob_t1 TO regress_rls_dob_role1,regress_rls_dob_role2 USING (true); DROP OWNED BY regress_rls_dob_role1; DROP POLICY p1 ON dob_t1; -- should succeed +CREATE POLICY p1 ON dob_t2 TO regress_rls_dob_role1,regress_rls_dob_role2 USING (true); +DROP OWNED BY regress_rls_dob_role1; +DROP POLICY p1 ON dob_t2; -- should succeed DROP USER regress_rls_dob_role1; DROP USER regress_rls_dob_role2; -- diff --git a/src/test/regress/sql/rowsecurity.sql b/src/test/regress/sql/rowsecurity.sql new file mode 100644 index 3ce9293..ba8fed4 --- a/src/test/regress/sql/rowsecurity.sql +++ b/src/test/regress/sql/rowsecurity.sql @@ -1740,6 +1740,7 @@ CREATE ROLE regress_rls_dob_role1; CREATE ROLE regress_rls_dob_role2; CREATE TABLE dob_t1 (c1 int); +CREATE TABLE dob_t2 (c1 int) PARTITION BY RANGE (c1); CREATE POLICY p1 ON dob_t1 TO regress_rls_dob_role1 USING (true); DROP OWNED BY regress_rls_dob_role1; @@ -1749,6 +1750,10 @@ CREATE POLICY p1 ON dob_t1 TO regress_rl DROP OWNED BY regress_rls_dob_role1; DROP POLICY p1 ON dob_t1; -- should succeed +CREATE POLICY p1 ON dob_t2 TO regress_rls_dob_role1,regress_rls_dob_role2 USING (true); +DROP OWNED BY regress_rls_dob_role1; +DROP POLICY p1 ON dob_t2; -- should succeed + DROP USER regress_rls_dob_role1; DROP USER regress_rls_dob_role2;
diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c new file mode 100644 index a637551..cc09355 --- a/src/pl/plpgsql/src/pl_comp.c +++ b/src/pl/plpgsql/src/pl_comp.c @@ -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))); diff --git a/src/test/regress/expected/plpgsql.out b/src/test/regress/expected/plpgsql.out new file mode 100644 index 7ebbde6..35b83f7 --- a/src/test/regress/expected/plpgsql.out +++ b/src/test/regress/expected/plpgsql.out @@ -5979,3 +5979,48 @@ LINE 1: SELECT (SELECT string_agg(id || ^ 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) + diff --git a/src/test/regress/sql/plpgsql.sql b/src/test/regress/sql/plpgsql.sql new file mode 100644 index 60d1d38..f957d70 --- a/src/test/regress/sql/plpgsql.sql +++ b/src/test/regress/sql/plpgsql.sql @@ -4766,3 +4766,42 @@ ALTER TABLE alter_table_under_transition 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;
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers