From b1ee7ec93e44266fc02a2e56965ec68c6ede19f4 Mon Sep 17 00:00:00 2001 From: Metin Doslu Date: Wed, 15 Mar 2017 11:47:55 +0200 Subject: [PATCH 1/3] Fix access permission checks for distributed relations With this commit, we add the range table list of the original query to our custom plan. Therefore, PostgreSQL can check relations in the original query for access permissions and error out if the proper access is not granted. --- src/backend/distributed/planner/multi_planner.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/backend/distributed/planner/multi_planner.c b/src/backend/distributed/planner/multi_planner.c index 7839c7cfc..d81776541 100644 --- a/src/backend/distributed/planner/multi_planner.c +++ b/src/backend/distributed/planner/multi_planner.c @@ -454,6 +454,9 @@ FinalizeNonRouterPlan(PlannedStmt *localPlan, MultiPlan *multiPlan, finalPlan->queryId = localPlan->queryId; finalPlan->utilityStmt = localPlan->utilityStmt; + /* add original range table list for access permission checks */ + finalPlan->rtable = list_concat(finalPlan->rtable, localPlan->rtable); + return finalPlan; } @@ -473,7 +476,7 @@ FinalizeRouterPlan(PlannedStmt *localPlan, CustomScan *customScan) List *targetList = NIL; List *columnNameList = NIL; - /* we will have only one range table entry */ + /* we will have custom scan range table entry as the first one in the list */ int customScanRangeTableIndex = 1; /* build a targetlist to read from the custom scan output */ @@ -514,6 +517,9 @@ FinalizeRouterPlan(PlannedStmt *localPlan, CustomScan *customScan) remoteScanRangeTableEntry = RemoteScanRangeTableEntry(columnNameList); routerPlan->rtable = list_make1(remoteScanRangeTableEntry); + /* add original range table list for access permission checks */ + routerPlan->rtable = list_concat(routerPlan->rtable, localPlan->rtable); + routerPlan->canSetTag = true; routerPlan->relationOids = NIL; From bcff6aa96cd3a8e765d375877b80b2f09bd8d898 Mon Sep 17 00:00:00 2001 From: Metin Doslu Date: Tue, 21 Mar 2017 17:14:52 +0200 Subject: [PATCH 2/3] Update regression tests for changing explain output --- src/test/regress/expected/multi_explain.out | 38 +++++++++---------- src/test/regress/expected/multi_explain_0.out | 38 +++++++++---------- .../expected/multi_join_order_tpch_large.out | 18 ++++----- .../expected/multi_join_order_tpch_small.out | 16 ++++---- .../regress/expected/multi_mx_explain.out | 30 +++++++-------- .../regress/expected/multi_mx_explain_0.out | 30 +++++++-------- src/test/regress/output/multi_subquery.source | 4 +- .../regress/output/multi_subquery_0.source | 4 +- 8 files changed, 89 insertions(+), 89 deletions(-) diff --git a/src/test/regress/expected/multi_explain.out b/src/test/regress/expected/multi_explain.out index e2ef27342..b5871d084 100644 --- a/src/test/regress/expected/multi_explain.out +++ b/src/test/regress/expected/multi_explain.out @@ -40,9 +40,9 @@ EXPLAIN (COSTS FALSE, FORMAT TEXT) SELECT l_quantity, count(*) count_quantity FROM lineitem GROUP BY l_quantity ORDER BY count_quantity, l_quantity; Sort - Sort Key: COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint), l_quantity + Sort Key: COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint), remote_scan.l_quantity -> HashAggregate - Group Key: l_quantity + Group Key: remote_scan.l_quantity -> Custom Scan (Citus Real-Time) Task Count: 8 Tasks Shown: One of 8 @@ -60,7 +60,7 @@ EXPLAIN (COSTS FALSE, FORMAT JSON) "Plan": { "Node Type": "Sort", "Parallel Aware": false, - "Sort Key": ["COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)", "l_quantity"], + "Sort Key": ["COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)", "remote_scan.l_quantity"], "Plans": [ { "Node Type": "Aggregate", @@ -68,7 +68,7 @@ EXPLAIN (COSTS FALSE, FORMAT JSON) "Partial Mode": "Simple", "Parent Relationship": "Outer", "Parallel Aware": false, - "Group Key": ["l_quantity"], + "Group Key": ["remote_scan.l_quantity"], "Plans": [ { "Node Type": "Custom Scan", @@ -131,8 +131,8 @@ EXPLAIN (COSTS FALSE, FORMAT XML) Sort false - COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint) - l_quantity + COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint) + remote_scan.l_quantity @@ -142,7 +142,7 @@ EXPLAIN (COSTS FALSE, FORMAT XML) Outer false - l_quantity + remote_scan.l_quantity @@ -205,8 +205,8 @@ EXPLAIN (COSTS FALSE, FORMAT YAML) Node Type: "Sort" Parallel Aware: false Sort Key: - - "COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)" - - "l_quantity" + - "COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)" + - "remote_scan.l_quantity" Plans: - Node Type: "Aggregate" Strategy: "Hashed" @@ -214,7 +214,7 @@ EXPLAIN (COSTS FALSE, FORMAT YAML) Parent Relationship: "Outer" Parallel Aware: false Group Key: - - "l_quantity" + - "remote_scan.l_quantity" Plans: - Node Type: "Custom Scan" Parent Relationship: "Outer" @@ -246,9 +246,9 @@ EXPLAIN (COSTS FALSE, FORMAT TEXT) SELECT l_quantity, count(*) count_quantity FROM lineitem GROUP BY l_quantity ORDER BY count_quantity, l_quantity; Sort - Sort Key: COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint), l_quantity + Sort Key: COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint), remote_scan.l_quantity -> HashAggregate - Group Key: l_quantity + Group Key: remote_scan.l_quantity -> Custom Scan (Citus Real-Time) Task Count: 8 Tasks Shown: One of 8 @@ -261,9 +261,9 @@ Sort EXPLAIN (COSTS FALSE, VERBOSE TRUE) SELECT sum(l_quantity) / avg(l_quantity) FROM lineitem; Aggregate - Output: (sum("?column?") / (sum("?column?_1") / pg_catalog.sum("?column?_2"))) + Output: (sum(remote_scan."?column?") / (sum(remote_scan."?column?_1") / pg_catalog.sum(remote_scan."?column?_2"))) -> Custom Scan (Citus Real-Time) - Output: "?column?", "?column?_1", "?column?_2" + Output: remote_scan."?column?", remote_scan."?column?_1", remote_scan."?column?_2" Task Count: 8 Tasks Shown: One of 8 -> Task @@ -279,7 +279,7 @@ EXPLAIN (COSTS FALSE) ORDER BY l_quantity LIMIT 10; Limit -> Sort - Sort Key: l_quantity + Sort Key: remote_scan.l_quantity -> Custom Scan (Citus Real-Time) Task Count: 8 Tasks Shown: One of 8 @@ -368,10 +368,10 @@ EXPLAIN (COSTS FALSE, VERBOSE TRUE) SELECT sum(l_quantity) / avg(l_quantity) FROM lineitem HAVING sum(l_quantity) > 100; Aggregate - Output: (sum("?column?") / (sum("?column?_1") / pg_catalog.sum("?column?_2"))) + Output: (sum(remote_scan."?column?") / (sum(remote_scan."?column?_1") / pg_catalog.sum(remote_scan."?column?_2"))) Filter: (sum(remote_scan.worker_column_4) > '100'::numeric) -> Custom Scan (Citus Real-Time) - Output: "?column?", "?column?_1", "?column?_2", worker_column_4 + Output: remote_scan."?column?", remote_scan."?column?_1", remote_scan."?column?_2", remote_scan.worker_column_4 Task Count: 8 Tasks Shown: One of 8 -> Task @@ -386,11 +386,11 @@ EXPLAIN (COSTS FALSE, VERBOSE TRUE) GROUP BY l_quantity HAVING l_quantity > (100 * random()); HashAggregate - Output: l_quantity + Output: remote_scan.l_quantity Group Key: remote_scan.l_quantity Filter: ((remote_scan.worker_column_2)::double precision > ('100'::double precision * random())) -> Custom Scan (Citus Real-Time) - Output: l_quantity, worker_column_2 + Output: remote_scan.l_quantity, remote_scan.worker_column_2 Task Count: 8 Tasks Shown: One of 8 -> Task diff --git a/src/test/regress/expected/multi_explain_0.out b/src/test/regress/expected/multi_explain_0.out index af839b514..c7f97c695 100644 --- a/src/test/regress/expected/multi_explain_0.out +++ b/src/test/regress/expected/multi_explain_0.out @@ -40,9 +40,9 @@ EXPLAIN (COSTS FALSE, FORMAT TEXT) SELECT l_quantity, count(*) count_quantity FROM lineitem GROUP BY l_quantity ORDER BY count_quantity, l_quantity; Sort - Sort Key: COALESCE((sum((COALESCE((sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint), l_quantity + Sort Key: COALESCE((sum((COALESCE((sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint), remote_scan.l_quantity -> HashAggregate - Group Key: l_quantity + Group Key: remote_scan.l_quantity -> Custom Scan (Citus Real-Time) Task Count: 8 Tasks Shown: One of 8 @@ -59,13 +59,13 @@ EXPLAIN (COSTS FALSE, FORMAT JSON) { "Plan": { "Node Type": "Sort", - "Sort Key": ["COALESCE((sum((COALESCE((sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)", "l_quantity"], + "Sort Key": ["COALESCE((sum((COALESCE((sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)", "remote_scan.l_quantity"], "Plans": [ { "Node Type": "Aggregate", "Strategy": "Hashed", "Parent Relationship": "Outer", - "Group Key": ["l_quantity"], + "Group Key": ["remote_scan.l_quantity"], "Plans": [ { "Node Type": "Custom Scan", @@ -123,8 +123,8 @@ EXPLAIN (COSTS FALSE, FORMAT XML) Sort - COALESCE((sum((COALESCE((sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint) - l_quantity + COALESCE((sum((COALESCE((sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint) + remote_scan.l_quantity @@ -132,7 +132,7 @@ EXPLAIN (COSTS FALSE, FORMAT XML) Hashed Outer - l_quantity + remote_scan.l_quantity @@ -190,14 +190,14 @@ EXPLAIN (COSTS FALSE, FORMAT YAML) - Plan: Node Type: "Sort" Sort Key: - - "COALESCE((sum((COALESCE((sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)" - - "l_quantity" + - "COALESCE((sum((COALESCE((sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)" + - "remote_scan.l_quantity" Plans: - Node Type: "Aggregate" Strategy: "Hashed" Parent Relationship: "Outer" Group Key: - - "l_quantity" + - "remote_scan.l_quantity" Plans: - Node Type: "Custom Scan" Parent Relationship: "Outer" @@ -225,9 +225,9 @@ EXPLAIN (COSTS FALSE, FORMAT TEXT) SELECT l_quantity, count(*) count_quantity FROM lineitem GROUP BY l_quantity ORDER BY count_quantity, l_quantity; Sort - Sort Key: COALESCE((sum((COALESCE((sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint), l_quantity + Sort Key: COALESCE((sum((COALESCE((sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint), remote_scan.l_quantity -> HashAggregate - Group Key: l_quantity + Group Key: remote_scan.l_quantity -> Custom Scan (Citus Real-Time) Task Count: 8 Tasks Shown: One of 8 @@ -240,9 +240,9 @@ Sort EXPLAIN (COSTS FALSE, VERBOSE TRUE) SELECT sum(l_quantity) / avg(l_quantity) FROM lineitem; Aggregate - Output: (sum("?column?") / (sum("?column?_1") / sum("?column?_2"))) + Output: (sum(remote_scan."?column?") / (sum(remote_scan."?column?_1") / sum(remote_scan."?column?_2"))) -> Custom Scan (Citus Real-Time) - Output: "?column?", "?column?_1", "?column?_2" + Output: remote_scan."?column?", remote_scan."?column?_1", remote_scan."?column?_2" Task Count: 8 Tasks Shown: One of 8 -> Task @@ -258,7 +258,7 @@ EXPLAIN (COSTS FALSE) ORDER BY l_quantity LIMIT 10; Limit -> Sort - Sort Key: l_quantity + Sort Key: remote_scan.l_quantity -> Custom Scan (Citus Real-Time) Task Count: 8 Tasks Shown: One of 8 @@ -347,10 +347,10 @@ EXPLAIN (COSTS FALSE, VERBOSE TRUE) SELECT sum(l_quantity) / avg(l_quantity) FROM lineitem HAVING sum(l_quantity) > 100; Aggregate - Output: (sum("?column?") / (sum("?column?_1") / sum("?column?_2"))) + Output: (sum(remote_scan."?column?") / (sum(remote_scan."?column?_1") / sum(remote_scan."?column?_2"))) Filter: (sum(remote_scan.worker_column_4) > '100'::numeric) -> Custom Scan (Citus Real-Time) - Output: "?column?", "?column?_1", "?column?_2", worker_column_4 + Output: remote_scan."?column?", remote_scan."?column?_1", remote_scan."?column?_2", remote_scan.worker_column_4 Task Count: 8 Tasks Shown: One of 8 -> Task @@ -365,11 +365,11 @@ EXPLAIN (COSTS FALSE, VERBOSE TRUE) GROUP BY l_quantity HAVING l_quantity > (100 * random()); HashAggregate - Output: l_quantity + Output: remote_scan.l_quantity Group Key: remote_scan.l_quantity Filter: ((remote_scan.worker_column_2)::double precision > ('100'::double precision * random())) -> Custom Scan (Citus Real-Time) - Output: l_quantity, worker_column_2 + Output: remote_scan.l_quantity, remote_scan.worker_column_2 Task Count: 8 Tasks Shown: One of 8 -> Task diff --git a/src/test/regress/expected/multi_join_order_tpch_large.out b/src/test/regress/expected/multi_join_order_tpch_large.out index 9489b567e..8f4655b46 100644 --- a/src/test/regress/expected/multi_join_order_tpch_large.out +++ b/src/test/regress/expected/multi_join_order_tpch_large.out @@ -55,12 +55,12 @@ ORDER BY revenue DESC, o_orderdate; LOG: join order: [ "orders" ][ local partition join "lineitem" ][ single partition join "customer" ] - QUERY PLAN --------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------ Sort (cost=0.00..0.00 rows=0 width=0) - Sort Key: sum((sum(revenue))) DESC, o_orderdate + Sort Key: sum((sum(remote_scan.revenue))) DESC, remote_scan.o_orderdate -> HashAggregate (cost=0.00..0.00 rows=0 width=0) - Group Key: l_orderkey, o_orderdate, o_shippriority + Group Key: remote_scan.l_orderkey, remote_scan.o_orderdate, remote_scan.o_shippriority -> Custom Scan (Citus Task-Tracker) (cost=0.00..0.00 rows=0 width=0) explain statements for distributed queries are not enabled (6 rows) @@ -98,12 +98,12 @@ GROUP BY ORDER BY revenue DESC; LOG: join order: [ "orders" ][ local partition join "lineitem" ][ single partition join "customer" ][ broadcast join "nation" ] - QUERY PLAN ----------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Sort (cost=0.00..0.00 rows=0 width=0) - Sort Key: sum((sum(revenue))) DESC + Sort Key: sum((sum(remote_scan.revenue))) DESC -> HashAggregate (cost=0.00..0.00 rows=0 width=0) - Group Key: c_custkey, c_name, c_acctbal, c_phone, n_name, c_address, c_comment + Group Key: remote_scan.c_custkey, remote_scan.c_name, remote_scan.c_acctbal, remote_scan.c_phone, remote_scan.n_name, remote_scan.c_address, remote_scan.c_comment -> Custom Scan (Citus Task-Tracker) (cost=0.00..0.00 rows=0 width=0) explain statements for distributed queries are not enabled (6 rows) @@ -161,7 +161,7 @@ LOG: join order: [ "lineitem" ][ local partition join "orders" ][ single partit QUERY PLAN -------------------------------------------------------------------------- HashAggregate (cost=0.00..0.00 rows=0 width=0) - Group Key: l_partkey + Group Key: remote_scan.l_partkey -> Custom Scan (Citus Task-Tracker) (cost=0.00..0.00 rows=0 width=0) explain statements for distributed queries are not enabled (4 rows) diff --git a/src/test/regress/expected/multi_join_order_tpch_small.out b/src/test/regress/expected/multi_join_order_tpch_small.out index c0466b1e3..b6f8cbf78 100644 --- a/src/test/regress/expected/multi_join_order_tpch_small.out +++ b/src/test/regress/expected/multi_join_order_tpch_small.out @@ -49,12 +49,12 @@ ORDER BY revenue DESC, o_orderdate; LOG: join order: [ "orders" ][ broadcast join "customer" ][ local partition join "lineitem" ] - QUERY PLAN ------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------------------ Sort (cost=0.00..0.00 rows=0 width=0) - Sort Key: sum((sum(revenue))) DESC, o_orderdate + Sort Key: sum((sum(remote_scan.revenue))) DESC, remote_scan.o_orderdate -> HashAggregate (cost=0.00..0.00 rows=0 width=0) - Group Key: l_orderkey, o_orderdate, o_shippriority + Group Key: remote_scan.l_orderkey, remote_scan.o_orderdate, remote_scan.o_shippriority -> Custom Scan (Citus Real-Time) (cost=0.00..0.00 rows=0 width=0) explain statements for distributed queries are not enabled (6 rows) @@ -92,12 +92,12 @@ GROUP BY ORDER BY revenue DESC; LOG: join order: [ "orders" ][ broadcast join "customer" ][ broadcast join "nation" ][ local partition join "lineitem" ] - QUERY PLAN ----------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Sort (cost=0.00..0.00 rows=0 width=0) - Sort Key: sum((sum(revenue))) DESC + Sort Key: sum((sum(remote_scan.revenue))) DESC -> HashAggregate (cost=0.00..0.00 rows=0 width=0) - Group Key: c_custkey, c_name, c_acctbal, c_phone, n_name, c_address, c_comment + Group Key: remote_scan.c_custkey, remote_scan.c_name, remote_scan.c_acctbal, remote_scan.c_phone, remote_scan.n_name, remote_scan.c_address, remote_scan.c_comment -> Custom Scan (Citus Real-Time) (cost=0.00..0.00 rows=0 width=0) explain statements for distributed queries are not enabled (6 rows) diff --git a/src/test/regress/expected/multi_mx_explain.out b/src/test/regress/expected/multi_mx_explain.out index 02dfbee99..8faca4b77 100644 --- a/src/test/regress/expected/multi_mx_explain.out +++ b/src/test/regress/expected/multi_mx_explain.out @@ -62,9 +62,9 @@ EXPLAIN (COSTS FALSE, FORMAT TEXT) SELECT l_quantity, count(*) count_quantity FROM lineitem_mx GROUP BY l_quantity ORDER BY count_quantity, l_quantity; Sort - Sort Key: COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint), l_quantity + Sort Key: COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint), remote_scan.l_quantity -> HashAggregate - Group Key: l_quantity + Group Key: remote_scan.l_quantity -> Custom Scan (Citus Real-Time) Task Count: 16 Tasks Shown: One of 16 @@ -82,7 +82,7 @@ EXPLAIN (COSTS FALSE, FORMAT JSON) "Plan": { "Node Type": "Sort", "Parallel Aware": false, - "Sort Key": ["COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)", "l_quantity"], + "Sort Key": ["COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)", "remote_scan.l_quantity"], "Plans": [ { "Node Type": "Aggregate", @@ -90,7 +90,7 @@ EXPLAIN (COSTS FALSE, FORMAT JSON) "Partial Mode": "Simple", "Parent Relationship": "Outer", "Parallel Aware": false, - "Group Key": ["l_quantity"], + "Group Key": ["remote_scan.l_quantity"], "Plans": [ { "Node Type": "Custom Scan", @@ -154,8 +154,8 @@ EXPLAIN (COSTS FALSE, FORMAT XML) Sort false - COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint) - l_quantity + COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint) + remote_scan.l_quantity @@ -165,7 +165,7 @@ EXPLAIN (COSTS FALSE, FORMAT XML) Outer false - l_quantity + remote_scan.l_quantity @@ -228,8 +228,8 @@ EXPLAIN (COSTS FALSE, FORMAT YAML) Node Type: "Sort" Parallel Aware: false Sort Key: - - "COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)" - - "l_quantity" + - "COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)" + - "remote_scan.l_quantity" Plans: - Node Type: "Aggregate" Strategy: "Hashed" @@ -237,7 +237,7 @@ EXPLAIN (COSTS FALSE, FORMAT YAML) Parent Relationship: "Outer" Parallel Aware: false Group Key: - - "l_quantity" + - "remote_scan.l_quantity" Plans: - Node Type: "Custom Scan" Parent Relationship: "Outer" @@ -269,9 +269,9 @@ EXPLAIN (COSTS FALSE, FORMAT TEXT) SELECT l_quantity, count(*) count_quantity FROM lineitem_mx GROUP BY l_quantity ORDER BY count_quantity, l_quantity; Sort - Sort Key: COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint), l_quantity + Sort Key: COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint), remote_scan.l_quantity -> HashAggregate - Group Key: l_quantity + Group Key: remote_scan.l_quantity -> Custom Scan (Citus Real-Time) Task Count: 16 Tasks Shown: One of 16 @@ -285,9 +285,9 @@ Sort EXPLAIN (COSTS FALSE, VERBOSE TRUE) SELECT sum(l_quantity) / avg(l_quantity) FROM lineitem_mx; Aggregate - Output: (sum("?column?") / (sum("?column?_1") / pg_catalog.sum("?column?_2"))) + Output: (sum(remote_scan."?column?") / (sum(remote_scan."?column?_1") / pg_catalog.sum(remote_scan."?column?_2"))) -> Custom Scan (Citus Real-Time) - Output: "?column?", "?column?_1", "?column?_2" + Output: remote_scan."?column?", remote_scan."?column?_1", remote_scan."?column?_2" Task Count: 16 Tasks Shown: One of 16 -> Task @@ -303,7 +303,7 @@ EXPLAIN (COSTS FALSE) ORDER BY l_quantity LIMIT 10; Limit -> Sort - Sort Key: l_quantity + Sort Key: remote_scan.l_quantity -> Custom Scan (Citus Real-Time) Task Count: 16 Tasks Shown: One of 16 diff --git a/src/test/regress/expected/multi_mx_explain_0.out b/src/test/regress/expected/multi_mx_explain_0.out index 0a74d3001..3c425c949 100644 --- a/src/test/regress/expected/multi_mx_explain_0.out +++ b/src/test/regress/expected/multi_mx_explain_0.out @@ -62,9 +62,9 @@ EXPLAIN (COSTS FALSE, FORMAT TEXT) SELECT l_quantity, count(*) count_quantity FROM lineitem_mx GROUP BY l_quantity ORDER BY count_quantity, l_quantity; Sort - Sort Key: COALESCE((sum((COALESCE((sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint), l_quantity + Sort Key: COALESCE((sum((COALESCE((sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint), remote_scan.l_quantity -> HashAggregate - Group Key: l_quantity + Group Key: remote_scan.l_quantity -> Custom Scan (Citus Real-Time) Task Count: 16 Tasks Shown: One of 16 @@ -81,13 +81,13 @@ EXPLAIN (COSTS FALSE, FORMAT JSON) { "Plan": { "Node Type": "Sort", - "Sort Key": ["COALESCE((sum((COALESCE((sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)", "l_quantity"], + "Sort Key": ["COALESCE((sum((COALESCE((sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)", "remote_scan.l_quantity"], "Plans": [ { "Node Type": "Aggregate", "Strategy": "Hashed", "Parent Relationship": "Outer", - "Group Key": ["l_quantity"], + "Group Key": ["remote_scan.l_quantity"], "Plans": [ { "Node Type": "Custom Scan", @@ -146,8 +146,8 @@ EXPLAIN (COSTS FALSE, FORMAT XML) Sort - COALESCE((sum((COALESCE((sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint) - l_quantity + COALESCE((sum((COALESCE((sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint) + remote_scan.l_quantity @@ -155,7 +155,7 @@ EXPLAIN (COSTS FALSE, FORMAT XML) Hashed Outer - l_quantity + remote_scan.l_quantity @@ -213,14 +213,14 @@ EXPLAIN (COSTS FALSE, FORMAT YAML) - Plan: Node Type: "Sort" Sort Key: - - "COALESCE((sum((COALESCE((sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)" - - "l_quantity" + - "COALESCE((sum((COALESCE((sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)" + - "remote_scan.l_quantity" Plans: - Node Type: "Aggregate" Strategy: "Hashed" Parent Relationship: "Outer" Group Key: - - "l_quantity" + - "remote_scan.l_quantity" Plans: - Node Type: "Custom Scan" Parent Relationship: "Outer" @@ -248,9 +248,9 @@ EXPLAIN (COSTS FALSE, FORMAT TEXT) SELECT l_quantity, count(*) count_quantity FROM lineitem_mx GROUP BY l_quantity ORDER BY count_quantity, l_quantity; Sort - Sort Key: COALESCE((sum((COALESCE((sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint), l_quantity + Sort Key: COALESCE((sum((COALESCE((sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint), remote_scan.l_quantity -> HashAggregate - Group Key: l_quantity + Group Key: remote_scan.l_quantity -> Custom Scan (Citus Real-Time) Task Count: 16 Tasks Shown: One of 16 @@ -264,9 +264,9 @@ Sort EXPLAIN (COSTS FALSE, VERBOSE TRUE) SELECT sum(l_quantity) / avg(l_quantity) FROM lineitem_mx; Aggregate - Output: (sum("?column?") / (sum("?column?_1") / sum("?column?_2"))) + Output: (sum(remote_scan."?column?") / (sum(remote_scan."?column?_1") / sum(remote_scan."?column?_2"))) -> Custom Scan (Citus Real-Time) - Output: "?column?", "?column?_1", "?column?_2" + Output: remote_scan."?column?", remote_scan."?column?_1", remote_scan."?column?_2" Task Count: 16 Tasks Shown: One of 16 -> Task @@ -282,7 +282,7 @@ EXPLAIN (COSTS FALSE) ORDER BY l_quantity LIMIT 10; Limit -> Sort - Sort Key: l_quantity + Sort Key: remote_scan.l_quantity -> Custom Scan (Citus Real-Time) Task Count: 16 Tasks Shown: One of 16 diff --git a/src/test/regress/output/multi_subquery.source b/src/test/regress/output/multi_subquery.source index 4c5931f17..3f892b2fa 100644 --- a/src/test/regress/output/multi_subquery.source +++ b/src/test/regress/output/multi_subquery.source @@ -853,7 +853,7 @@ GROUP BY QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- HashAggregate (cost=0.00..0.00 rows=0 width=0) - Group Key: hasdone + Group Key: remote_scan.hasdone -> Custom Scan (Citus Real-Time) (cost=0.00..0.00 rows=0 width=0) Task Count: 2 Tasks Shown: One of 2 @@ -1020,7 +1020,7 @@ LIMIT ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Limit (cost=0.00..0.00 rows=0 width=0) -> Sort (cost=0.00..0.00 rows=0 width=0) - Sort Key: user_lastseen DESC + Sort Key: remote_scan.user_lastseen DESC -> Custom Scan (Citus Real-Time) (cost=0.00..0.00 rows=0 width=0) Task Count: 2 Tasks Shown: One of 2 diff --git a/src/test/regress/output/multi_subquery_0.source b/src/test/regress/output/multi_subquery_0.source index 096c204e4..5d5eb53e9 100644 --- a/src/test/regress/output/multi_subquery_0.source +++ b/src/test/regress/output/multi_subquery_0.source @@ -853,7 +853,7 @@ GROUP BY QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- HashAggregate (cost=0.00..0.00 rows=0 width=0) - Group Key: hasdone + Group Key: remote_scan.hasdone -> Custom Scan (Citus Real-Time) (cost=0.00..0.00 rows=0 width=0) Task Count: 2 Tasks Shown: One of 2 @@ -1017,7 +1017,7 @@ LIMIT ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Limit (cost=0.00..0.00 rows=0 width=0) -> Sort (cost=0.00..0.00 rows=0 width=0) - Sort Key: user_lastseen DESC + Sort Key: remote_scan.user_lastseen DESC -> Custom Scan (Citus Real-Time) (cost=0.00..0.00 rows=0 width=0) Task Count: 2 Tasks Shown: One of 2 From 404e32cdb41656d38a1f48b8c4476f0d33d23a9e Mon Sep 17 00:00:00 2001 From: Metin Doslu Date: Wed, 22 Mar 2017 16:18:13 +0200 Subject: [PATCH 3/3] Add basic permission checking tests --- src/test/regress/expected/multi_multiuser.out | 138 ++++++++++++++++++ src/test/regress/multi_schedule | 5 + src/test/regress/sql/multi_multiuser.sql | 92 ++++++++++++ 3 files changed, 235 insertions(+) create mode 100644 src/test/regress/expected/multi_multiuser.out create mode 100644 src/test/regress/sql/multi_multiuser.sql diff --git a/src/test/regress/expected/multi_multiuser.out b/src/test/regress/expected/multi_multiuser.out new file mode 100644 index 000000000..3a4c9c0a5 --- /dev/null +++ b/src/test/regress/expected/multi_multiuser.out @@ -0,0 +1,138 @@ +-- +-- MULTI_MULTIUSERS +-- +-- Test user permissions. +-- +ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1420000; +ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1420000; +SET citus.shard_replication_factor TO 1; +SET citus.shard_count TO 2; +CREATE TABLE test (id integer); +SELECT create_distributed_table('test', 'id'); + create_distributed_table +-------------------------- + +(1 row) + +CREATE USER full_access; +NOTICE: not propagating CREATE ROLE/USER commands to worker nodes +HINT: Connect to worker nodes directly to manually create all necessary users and roles. +CREATE USER read_access; +NOTICE: not propagating CREATE ROLE/USER commands to worker nodes +HINT: Connect to worker nodes directly to manually create all necessary users and roles. +CREATE USER no_access; +NOTICE: not propagating CREATE ROLE/USER commands to worker nodes +HINT: Connect to worker nodes directly to manually create all necessary users and roles. +GRANT ALL ON TABLE test TO full_access; +GRANT SELECT ON TABLE test TO read_access; +\c - - - :worker_1_port +CREATE USER full_access; +NOTICE: not propagating CREATE ROLE/USER commands to worker nodes +HINT: Connect to worker nodes directly to manually create all necessary users and roles. +CREATE USER read_access; +NOTICE: not propagating CREATE ROLE/USER commands to worker nodes +HINT: Connect to worker nodes directly to manually create all necessary users and roles. +CREATE USER no_access; +NOTICE: not propagating CREATE ROLE/USER commands to worker nodes +HINT: Connect to worker nodes directly to manually create all necessary users and roles. +GRANT ALL ON TABLE test_1420000 TO full_access; +GRANT SELECT ON TABLE test_1420000 TO read_access; +\c - - - :worker_2_port +CREATE USER full_access; +NOTICE: not propagating CREATE ROLE/USER commands to worker nodes +HINT: Connect to worker nodes directly to manually create all necessary users and roles. +CREATE USER read_access; +NOTICE: not propagating CREATE ROLE/USER commands to worker nodes +HINT: Connect to worker nodes directly to manually create all necessary users and roles. +CREATE USER no_access; +NOTICE: not propagating CREATE ROLE/USER commands to worker nodes +HINT: Connect to worker nodes directly to manually create all necessary users and roles. +GRANT ALL ON TABLE test_1420001 TO full_access; +GRANT SELECT ON TABLE test_1420001 TO read_access; +\c - - - :master_port +-- create prepare tests +PREPARE prepare_insert AS INSERT INTO test VALUES ($1); +PREPARE prepare_select AS SELECT count(*) FROM test; +-- check full permission +SET ROLE full_access; +EXECUTE prepare_insert(1); +EXECUTE prepare_select; + count +------- + 1 +(1 row) + +INSERT INTO test VALUES (2); +SELECT count(*) FROM test; + count +------- + 2 +(1 row) + +SELECT count(*) FROM test WHERE id = 1; + count +------- + 1 +(1 row) + +SET citus.task_executor_type TO 'task-tracker'; +SELECT count(*) FROM test; + count +------- + 2 +(1 row) + +SET citus.task_executor_type TO 'real-time'; +-- check read permission +SET ROLE read_access; +EXECUTE prepare_insert(1); +ERROR: permission denied for relation test +EXECUTE prepare_select; + count +------- + 2 +(1 row) + +INSERT INTO test VALUES (2); +ERROR: permission denied for relation test +SELECT count(*) FROM test; + count +------- + 2 +(1 row) + +SELECT count(*) FROM test WHERE id = 1; + count +------- + 1 +(1 row) + +SET citus.task_executor_type TO 'task-tracker'; +SELECT count(*) FROM test; + count +------- + 2 +(1 row) + +SET citus.task_executor_type TO 'real-time'; +-- check no permission +SET ROLE no_access; +EXECUTE prepare_insert(1); +ERROR: permission denied for relation test +EXECUTE prepare_select; +ERROR: permission denied for relation test +INSERT INTO test VALUES (2); +ERROR: permission denied for relation test +SELECT count(*) FROM test; +ERROR: permission denied for relation test +SELECT count(*) FROM test WHERE id = 1; +ERROR: permission denied for relation test +SET citus.task_executor_type TO 'task-tracker'; +SELECT count(*) FROM test; +ERROR: permission denied for relation test +SET citus.task_executor_type TO 'real-time'; +RESET ROLE; +DROP TABLE test; +DROP USER full_access; +DROP USER read_access; +DROP USER no_access; diff --git a/src/test/regress/multi_schedule b/src/test/regress/multi_schedule index 87cc32444..986ccce31 100644 --- a/src/test/regress/multi_schedule +++ b/src/test/regress/multi_schedule @@ -225,3 +225,8 @@ test: multi_remove_node_reference_table # multi_transactional_drop_shards tests for dropping shards using connection API # ---------- test: multi_transactional_drop_shards + +# ---------- +# multi_multiuser tests simple combinations of permission access and queries +# ---------- +test: multi_multiuser diff --git a/src/test/regress/sql/multi_multiuser.sql b/src/test/regress/sql/multi_multiuser.sql new file mode 100644 index 000000000..486b827b3 --- /dev/null +++ b/src/test/regress/sql/multi_multiuser.sql @@ -0,0 +1,92 @@ +-- +-- MULTI_MULTIUSERS +-- +-- Test user permissions. +-- + +ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1420000; +ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1420000; + +SET citus.shard_replication_factor TO 1; +SET citus.shard_count TO 2; + +CREATE TABLE test (id integer); +SELECT create_distributed_table('test', 'id'); + +CREATE USER full_access; +CREATE USER read_access; +CREATE USER no_access; + +GRANT ALL ON TABLE test TO full_access; +GRANT SELECT ON TABLE test TO read_access; + +\c - - - :worker_1_port +CREATE USER full_access; +CREATE USER read_access; +CREATE USER no_access; + +GRANT ALL ON TABLE test_1420000 TO full_access; +GRANT SELECT ON TABLE test_1420000 TO read_access; + +\c - - - :worker_2_port +CREATE USER full_access; +CREATE USER read_access; +CREATE USER no_access; + +GRANT ALL ON TABLE test_1420001 TO full_access; +GRANT SELECT ON TABLE test_1420001 TO read_access; + +\c - - - :master_port + +-- create prepare tests +PREPARE prepare_insert AS INSERT INTO test VALUES ($1); +PREPARE prepare_select AS SELECT count(*) FROM test; + +-- check full permission +SET ROLE full_access; + +EXECUTE prepare_insert(1); +EXECUTE prepare_select; + +INSERT INTO test VALUES (2); +SELECT count(*) FROM test; +SELECT count(*) FROM test WHERE id = 1; + +SET citus.task_executor_type TO 'task-tracker'; +SELECT count(*) FROM test; +SET citus.task_executor_type TO 'real-time'; + +-- check read permission +SET ROLE read_access; + +EXECUTE prepare_insert(1); +EXECUTE prepare_select; + +INSERT INTO test VALUES (2); +SELECT count(*) FROM test; +SELECT count(*) FROM test WHERE id = 1; + +SET citus.task_executor_type TO 'task-tracker'; +SELECT count(*) FROM test; +SET citus.task_executor_type TO 'real-time'; + +-- check no permission +SET ROLE no_access; + +EXECUTE prepare_insert(1); +EXECUTE prepare_select; + +INSERT INTO test VALUES (2); +SELECT count(*) FROM test; +SELECT count(*) FROM test WHERE id = 1; + +SET citus.task_executor_type TO 'task-tracker'; +SELECT count(*) FROM test; +SET citus.task_executor_type TO 'real-time'; + +RESET ROLE; + +DROP TABLE test; +DROP USER full_access; +DROP USER read_access; +DROP USER no_access;