mirror of https://github.com/citusdata/citus.git
Merge pull request #1281 from citusdata/fix_permission_check
Fix access permission checks for distributed relations cr: @jasonmp85pull/1175/merge
commit
823cd0dc98
|
@ -454,6 +454,9 @@ FinalizeNonRouterPlan(PlannedStmt *localPlan, MultiPlan *multiPlan,
|
||||||
finalPlan->queryId = localPlan->queryId;
|
finalPlan->queryId = localPlan->queryId;
|
||||||
finalPlan->utilityStmt = localPlan->utilityStmt;
|
finalPlan->utilityStmt = localPlan->utilityStmt;
|
||||||
|
|
||||||
|
/* add original range table list for access permission checks */
|
||||||
|
finalPlan->rtable = list_concat(finalPlan->rtable, localPlan->rtable);
|
||||||
|
|
||||||
return finalPlan;
|
return finalPlan;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,7 +476,7 @@ FinalizeRouterPlan(PlannedStmt *localPlan, CustomScan *customScan)
|
||||||
List *targetList = NIL;
|
List *targetList = NIL;
|
||||||
List *columnNameList = 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;
|
int customScanRangeTableIndex = 1;
|
||||||
|
|
||||||
/* build a targetlist to read from the custom scan output */
|
/* build a targetlist to read from the custom scan output */
|
||||||
|
@ -514,6 +517,9 @@ FinalizeRouterPlan(PlannedStmt *localPlan, CustomScan *customScan)
|
||||||
remoteScanRangeTableEntry = RemoteScanRangeTableEntry(columnNameList);
|
remoteScanRangeTableEntry = RemoteScanRangeTableEntry(columnNameList);
|
||||||
routerPlan->rtable = list_make1(remoteScanRangeTableEntry);
|
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->canSetTag = true;
|
||||||
routerPlan->relationOids = NIL;
|
routerPlan->relationOids = NIL;
|
||||||
|
|
||||||
|
|
|
@ -40,9 +40,9 @@ EXPLAIN (COSTS FALSE, FORMAT TEXT)
|
||||||
SELECT l_quantity, count(*) count_quantity FROM lineitem
|
SELECT l_quantity, count(*) count_quantity FROM lineitem
|
||||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
||||||
Sort
|
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
|
-> HashAggregate
|
||||||
Group Key: l_quantity
|
Group Key: remote_scan.l_quantity
|
||||||
-> Custom Scan (Citus Real-Time)
|
-> Custom Scan (Citus Real-Time)
|
||||||
Task Count: 8
|
Task Count: 8
|
||||||
Tasks Shown: One of 8
|
Tasks Shown: One of 8
|
||||||
|
@ -60,7 +60,7 @@ EXPLAIN (COSTS FALSE, FORMAT JSON)
|
||||||
"Plan": {
|
"Plan": {
|
||||||
"Node Type": "Sort",
|
"Node Type": "Sort",
|
||||||
"Parallel Aware": false,
|
"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": [
|
"Plans": [
|
||||||
{
|
{
|
||||||
"Node Type": "Aggregate",
|
"Node Type": "Aggregate",
|
||||||
|
@ -68,7 +68,7 @@ EXPLAIN (COSTS FALSE, FORMAT JSON)
|
||||||
"Partial Mode": "Simple",
|
"Partial Mode": "Simple",
|
||||||
"Parent Relationship": "Outer",
|
"Parent Relationship": "Outer",
|
||||||
"Parallel Aware": false,
|
"Parallel Aware": false,
|
||||||
"Group Key": ["l_quantity"],
|
"Group Key": ["remote_scan.l_quantity"],
|
||||||
"Plans": [
|
"Plans": [
|
||||||
{
|
{
|
||||||
"Node Type": "Custom Scan",
|
"Node Type": "Custom Scan",
|
||||||
|
@ -131,8 +131,8 @@ EXPLAIN (COSTS FALSE, FORMAT XML)
|
||||||
<Node-Type>Sort</Node-Type>
|
<Node-Type>Sort</Node-Type>
|
||||||
<Parallel-Aware>false</Parallel-Aware>
|
<Parallel-Aware>false</Parallel-Aware>
|
||||||
<Sort-Key>
|
<Sort-Key>
|
||||||
<Item>COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)</Item>
|
<Item>COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)</Item>
|
||||||
<Item>l_quantity</Item>
|
<Item>remote_scan.l_quantity</Item>
|
||||||
</Sort-Key>
|
</Sort-Key>
|
||||||
<Plans>
|
<Plans>
|
||||||
<Plan>
|
<Plan>
|
||||||
|
@ -142,7 +142,7 @@ EXPLAIN (COSTS FALSE, FORMAT XML)
|
||||||
<Parent-Relationship>Outer</Parent-Relationship>
|
<Parent-Relationship>Outer</Parent-Relationship>
|
||||||
<Parallel-Aware>false</Parallel-Aware>
|
<Parallel-Aware>false</Parallel-Aware>
|
||||||
<Group-Key>
|
<Group-Key>
|
||||||
<Item>l_quantity</Item>
|
<Item>remote_scan.l_quantity</Item>
|
||||||
</Group-Key>
|
</Group-Key>
|
||||||
<Plans>
|
<Plans>
|
||||||
<Plan>
|
<Plan>
|
||||||
|
@ -205,8 +205,8 @@ EXPLAIN (COSTS FALSE, FORMAT YAML)
|
||||||
Node Type: "Sort"
|
Node Type: "Sort"
|
||||||
Parallel Aware: false
|
Parallel Aware: false
|
||||||
Sort Key:
|
Sort Key:
|
||||||
- "COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)"
|
- "COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)"
|
||||||
- "l_quantity"
|
- "remote_scan.l_quantity"
|
||||||
Plans:
|
Plans:
|
||||||
- Node Type: "Aggregate"
|
- Node Type: "Aggregate"
|
||||||
Strategy: "Hashed"
|
Strategy: "Hashed"
|
||||||
|
@ -214,7 +214,7 @@ EXPLAIN (COSTS FALSE, FORMAT YAML)
|
||||||
Parent Relationship: "Outer"
|
Parent Relationship: "Outer"
|
||||||
Parallel Aware: false
|
Parallel Aware: false
|
||||||
Group Key:
|
Group Key:
|
||||||
- "l_quantity"
|
- "remote_scan.l_quantity"
|
||||||
Plans:
|
Plans:
|
||||||
- Node Type: "Custom Scan"
|
- Node Type: "Custom Scan"
|
||||||
Parent Relationship: "Outer"
|
Parent Relationship: "Outer"
|
||||||
|
@ -246,9 +246,9 @@ EXPLAIN (COSTS FALSE, FORMAT TEXT)
|
||||||
SELECT l_quantity, count(*) count_quantity FROM lineitem
|
SELECT l_quantity, count(*) count_quantity FROM lineitem
|
||||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
||||||
Sort
|
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
|
-> HashAggregate
|
||||||
Group Key: l_quantity
|
Group Key: remote_scan.l_quantity
|
||||||
-> Custom Scan (Citus Real-Time)
|
-> Custom Scan (Citus Real-Time)
|
||||||
Task Count: 8
|
Task Count: 8
|
||||||
Tasks Shown: One of 8
|
Tasks Shown: One of 8
|
||||||
|
@ -261,9 +261,9 @@ Sort
|
||||||
EXPLAIN (COSTS FALSE, VERBOSE TRUE)
|
EXPLAIN (COSTS FALSE, VERBOSE TRUE)
|
||||||
SELECT sum(l_quantity) / avg(l_quantity) FROM lineitem;
|
SELECT sum(l_quantity) / avg(l_quantity) FROM lineitem;
|
||||||
Aggregate
|
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)
|
-> 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
|
Task Count: 8
|
||||||
Tasks Shown: One of 8
|
Tasks Shown: One of 8
|
||||||
-> Task
|
-> Task
|
||||||
|
@ -279,7 +279,7 @@ EXPLAIN (COSTS FALSE)
|
||||||
ORDER BY l_quantity LIMIT 10;
|
ORDER BY l_quantity LIMIT 10;
|
||||||
Limit
|
Limit
|
||||||
-> Sort
|
-> Sort
|
||||||
Sort Key: l_quantity
|
Sort Key: remote_scan.l_quantity
|
||||||
-> Custom Scan (Citus Real-Time)
|
-> Custom Scan (Citus Real-Time)
|
||||||
Task Count: 8
|
Task Count: 8
|
||||||
Tasks Shown: One of 8
|
Tasks Shown: One of 8
|
||||||
|
@ -368,10 +368,10 @@ EXPLAIN (COSTS FALSE, VERBOSE TRUE)
|
||||||
SELECT sum(l_quantity) / avg(l_quantity) FROM lineitem
|
SELECT sum(l_quantity) / avg(l_quantity) FROM lineitem
|
||||||
HAVING sum(l_quantity) > 100;
|
HAVING sum(l_quantity) > 100;
|
||||||
Aggregate
|
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)
|
Filter: (sum(remote_scan.worker_column_4) > '100'::numeric)
|
||||||
-> Custom Scan (Citus Real-Time)
|
-> 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
|
Task Count: 8
|
||||||
Tasks Shown: One of 8
|
Tasks Shown: One of 8
|
||||||
-> Task
|
-> Task
|
||||||
|
@ -386,11 +386,11 @@ EXPLAIN (COSTS FALSE, VERBOSE TRUE)
|
||||||
GROUP BY l_quantity
|
GROUP BY l_quantity
|
||||||
HAVING l_quantity > (100 * random());
|
HAVING l_quantity > (100 * random());
|
||||||
HashAggregate
|
HashAggregate
|
||||||
Output: l_quantity
|
Output: remote_scan.l_quantity
|
||||||
Group Key: remote_scan.l_quantity
|
Group Key: remote_scan.l_quantity
|
||||||
Filter: ((remote_scan.worker_column_2)::double precision > ('100'::double precision * random()))
|
Filter: ((remote_scan.worker_column_2)::double precision > ('100'::double precision * random()))
|
||||||
-> Custom Scan (Citus Real-Time)
|
-> Custom Scan (Citus Real-Time)
|
||||||
Output: l_quantity, worker_column_2
|
Output: remote_scan.l_quantity, remote_scan.worker_column_2
|
||||||
Task Count: 8
|
Task Count: 8
|
||||||
Tasks Shown: One of 8
|
Tasks Shown: One of 8
|
||||||
-> Task
|
-> Task
|
||||||
|
|
|
@ -40,9 +40,9 @@ EXPLAIN (COSTS FALSE, FORMAT TEXT)
|
||||||
SELECT l_quantity, count(*) count_quantity FROM lineitem
|
SELECT l_quantity, count(*) count_quantity FROM lineitem
|
||||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
||||||
Sort
|
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
|
-> HashAggregate
|
||||||
Group Key: l_quantity
|
Group Key: remote_scan.l_quantity
|
||||||
-> Custom Scan (Citus Real-Time)
|
-> Custom Scan (Citus Real-Time)
|
||||||
Task Count: 8
|
Task Count: 8
|
||||||
Tasks Shown: One of 8
|
Tasks Shown: One of 8
|
||||||
|
@ -59,13 +59,13 @@ EXPLAIN (COSTS FALSE, FORMAT JSON)
|
||||||
{
|
{
|
||||||
"Plan": {
|
"Plan": {
|
||||||
"Node Type": "Sort",
|
"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": [
|
"Plans": [
|
||||||
{
|
{
|
||||||
"Node Type": "Aggregate",
|
"Node Type": "Aggregate",
|
||||||
"Strategy": "Hashed",
|
"Strategy": "Hashed",
|
||||||
"Parent Relationship": "Outer",
|
"Parent Relationship": "Outer",
|
||||||
"Group Key": ["l_quantity"],
|
"Group Key": ["remote_scan.l_quantity"],
|
||||||
"Plans": [
|
"Plans": [
|
||||||
{
|
{
|
||||||
"Node Type": "Custom Scan",
|
"Node Type": "Custom Scan",
|
||||||
|
@ -123,8 +123,8 @@ EXPLAIN (COSTS FALSE, FORMAT XML)
|
||||||
<Plan>
|
<Plan>
|
||||||
<Node-Type>Sort</Node-Type>
|
<Node-Type>Sort</Node-Type>
|
||||||
<Sort-Key>
|
<Sort-Key>
|
||||||
<Item>COALESCE((sum((COALESCE((sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)</Item>
|
<Item>COALESCE((sum((COALESCE((sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)</Item>
|
||||||
<Item>l_quantity</Item>
|
<Item>remote_scan.l_quantity</Item>
|
||||||
</Sort-Key>
|
</Sort-Key>
|
||||||
<Plans>
|
<Plans>
|
||||||
<Plan>
|
<Plan>
|
||||||
|
@ -132,7 +132,7 @@ EXPLAIN (COSTS FALSE, FORMAT XML)
|
||||||
<Strategy>Hashed</Strategy>
|
<Strategy>Hashed</Strategy>
|
||||||
<Parent-Relationship>Outer</Parent-Relationship>
|
<Parent-Relationship>Outer</Parent-Relationship>
|
||||||
<Group-Key>
|
<Group-Key>
|
||||||
<Item>l_quantity</Item>
|
<Item>remote_scan.l_quantity</Item>
|
||||||
</Group-Key>
|
</Group-Key>
|
||||||
<Plans>
|
<Plans>
|
||||||
<Plan>
|
<Plan>
|
||||||
|
@ -190,14 +190,14 @@ EXPLAIN (COSTS FALSE, FORMAT YAML)
|
||||||
- Plan:
|
- Plan:
|
||||||
Node Type: "Sort"
|
Node Type: "Sort"
|
||||||
Sort Key:
|
Sort Key:
|
||||||
- "COALESCE((sum((COALESCE((sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)"
|
- "COALESCE((sum((COALESCE((sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)"
|
||||||
- "l_quantity"
|
- "remote_scan.l_quantity"
|
||||||
Plans:
|
Plans:
|
||||||
- Node Type: "Aggregate"
|
- Node Type: "Aggregate"
|
||||||
Strategy: "Hashed"
|
Strategy: "Hashed"
|
||||||
Parent Relationship: "Outer"
|
Parent Relationship: "Outer"
|
||||||
Group Key:
|
Group Key:
|
||||||
- "l_quantity"
|
- "remote_scan.l_quantity"
|
||||||
Plans:
|
Plans:
|
||||||
- Node Type: "Custom Scan"
|
- Node Type: "Custom Scan"
|
||||||
Parent Relationship: "Outer"
|
Parent Relationship: "Outer"
|
||||||
|
@ -225,9 +225,9 @@ EXPLAIN (COSTS FALSE, FORMAT TEXT)
|
||||||
SELECT l_quantity, count(*) count_quantity FROM lineitem
|
SELECT l_quantity, count(*) count_quantity FROM lineitem
|
||||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
||||||
Sort
|
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
|
-> HashAggregate
|
||||||
Group Key: l_quantity
|
Group Key: remote_scan.l_quantity
|
||||||
-> Custom Scan (Citus Real-Time)
|
-> Custom Scan (Citus Real-Time)
|
||||||
Task Count: 8
|
Task Count: 8
|
||||||
Tasks Shown: One of 8
|
Tasks Shown: One of 8
|
||||||
|
@ -240,9 +240,9 @@ Sort
|
||||||
EXPLAIN (COSTS FALSE, VERBOSE TRUE)
|
EXPLAIN (COSTS FALSE, VERBOSE TRUE)
|
||||||
SELECT sum(l_quantity) / avg(l_quantity) FROM lineitem;
|
SELECT sum(l_quantity) / avg(l_quantity) FROM lineitem;
|
||||||
Aggregate
|
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)
|
-> 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
|
Task Count: 8
|
||||||
Tasks Shown: One of 8
|
Tasks Shown: One of 8
|
||||||
-> Task
|
-> Task
|
||||||
|
@ -258,7 +258,7 @@ EXPLAIN (COSTS FALSE)
|
||||||
ORDER BY l_quantity LIMIT 10;
|
ORDER BY l_quantity LIMIT 10;
|
||||||
Limit
|
Limit
|
||||||
-> Sort
|
-> Sort
|
||||||
Sort Key: l_quantity
|
Sort Key: remote_scan.l_quantity
|
||||||
-> Custom Scan (Citus Real-Time)
|
-> Custom Scan (Citus Real-Time)
|
||||||
Task Count: 8
|
Task Count: 8
|
||||||
Tasks Shown: One of 8
|
Tasks Shown: One of 8
|
||||||
|
@ -347,10 +347,10 @@ EXPLAIN (COSTS FALSE, VERBOSE TRUE)
|
||||||
SELECT sum(l_quantity) / avg(l_quantity) FROM lineitem
|
SELECT sum(l_quantity) / avg(l_quantity) FROM lineitem
|
||||||
HAVING sum(l_quantity) > 100;
|
HAVING sum(l_quantity) > 100;
|
||||||
Aggregate
|
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)
|
Filter: (sum(remote_scan.worker_column_4) > '100'::numeric)
|
||||||
-> Custom Scan (Citus Real-Time)
|
-> 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
|
Task Count: 8
|
||||||
Tasks Shown: One of 8
|
Tasks Shown: One of 8
|
||||||
-> Task
|
-> Task
|
||||||
|
@ -365,11 +365,11 @@ EXPLAIN (COSTS FALSE, VERBOSE TRUE)
|
||||||
GROUP BY l_quantity
|
GROUP BY l_quantity
|
||||||
HAVING l_quantity > (100 * random());
|
HAVING l_quantity > (100 * random());
|
||||||
HashAggregate
|
HashAggregate
|
||||||
Output: l_quantity
|
Output: remote_scan.l_quantity
|
||||||
Group Key: remote_scan.l_quantity
|
Group Key: remote_scan.l_quantity
|
||||||
Filter: ((remote_scan.worker_column_2)::double precision > ('100'::double precision * random()))
|
Filter: ((remote_scan.worker_column_2)::double precision > ('100'::double precision * random()))
|
||||||
-> Custom Scan (Citus Real-Time)
|
-> Custom Scan (Citus Real-Time)
|
||||||
Output: l_quantity, worker_column_2
|
Output: remote_scan.l_quantity, remote_scan.worker_column_2
|
||||||
Task Count: 8
|
Task Count: 8
|
||||||
Tasks Shown: One of 8
|
Tasks Shown: One of 8
|
||||||
-> Task
|
-> Task
|
||||||
|
|
|
@ -56,11 +56,11 @@ ORDER BY
|
||||||
o_orderdate;
|
o_orderdate;
|
||||||
LOG: join order: [ "orders" ][ local partition join "lineitem" ][ single partition join "customer" ]
|
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 (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)
|
-> 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)
|
-> Custom Scan (Citus Task-Tracker) (cost=0.00..0.00 rows=0 width=0)
|
||||||
explain statements for distributed queries are not enabled
|
explain statements for distributed queries are not enabled
|
||||||
(6 rows)
|
(6 rows)
|
||||||
|
@ -99,11 +99,11 @@ ORDER BY
|
||||||
revenue DESC;
|
revenue DESC;
|
||||||
LOG: join order: [ "orders" ][ local partition join "lineitem" ][ single partition join "customer" ][ broadcast join "nation" ]
|
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 (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)
|
-> 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)
|
-> Custom Scan (Citus Task-Tracker) (cost=0.00..0.00 rows=0 width=0)
|
||||||
explain statements for distributed queries are not enabled
|
explain statements for distributed queries are not enabled
|
||||||
(6 rows)
|
(6 rows)
|
||||||
|
@ -161,7 +161,7 @@ LOG: join order: [ "lineitem" ][ local partition join "orders" ][ single partit
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
HashAggregate (cost=0.00..0.00 rows=0 width=0)
|
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)
|
-> Custom Scan (Citus Task-Tracker) (cost=0.00..0.00 rows=0 width=0)
|
||||||
explain statements for distributed queries are not enabled
|
explain statements for distributed queries are not enabled
|
||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
|
@ -50,11 +50,11 @@ ORDER BY
|
||||||
o_orderdate;
|
o_orderdate;
|
||||||
LOG: join order: [ "orders" ][ broadcast join "customer" ][ local partition join "lineitem" ]
|
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 (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)
|
-> 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)
|
-> Custom Scan (Citus Real-Time) (cost=0.00..0.00 rows=0 width=0)
|
||||||
explain statements for distributed queries are not enabled
|
explain statements for distributed queries are not enabled
|
||||||
(6 rows)
|
(6 rows)
|
||||||
|
@ -93,11 +93,11 @@ ORDER BY
|
||||||
revenue DESC;
|
revenue DESC;
|
||||||
LOG: join order: [ "orders" ][ broadcast join "customer" ][ broadcast join "nation" ][ local partition join "lineitem" ]
|
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 (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)
|
-> 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)
|
-> Custom Scan (Citus Real-Time) (cost=0.00..0.00 rows=0 width=0)
|
||||||
explain statements for distributed queries are not enabled
|
explain statements for distributed queries are not enabled
|
||||||
(6 rows)
|
(6 rows)
|
||||||
|
|
|
@ -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;
|
|
@ -62,9 +62,9 @@ EXPLAIN (COSTS FALSE, FORMAT TEXT)
|
||||||
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
||||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
||||||
Sort
|
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
|
-> HashAggregate
|
||||||
Group Key: l_quantity
|
Group Key: remote_scan.l_quantity
|
||||||
-> Custom Scan (Citus Real-Time)
|
-> Custom Scan (Citus Real-Time)
|
||||||
Task Count: 16
|
Task Count: 16
|
||||||
Tasks Shown: One of 16
|
Tasks Shown: One of 16
|
||||||
|
@ -82,7 +82,7 @@ EXPLAIN (COSTS FALSE, FORMAT JSON)
|
||||||
"Plan": {
|
"Plan": {
|
||||||
"Node Type": "Sort",
|
"Node Type": "Sort",
|
||||||
"Parallel Aware": false,
|
"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": [
|
"Plans": [
|
||||||
{
|
{
|
||||||
"Node Type": "Aggregate",
|
"Node Type": "Aggregate",
|
||||||
|
@ -90,7 +90,7 @@ EXPLAIN (COSTS FALSE, FORMAT JSON)
|
||||||
"Partial Mode": "Simple",
|
"Partial Mode": "Simple",
|
||||||
"Parent Relationship": "Outer",
|
"Parent Relationship": "Outer",
|
||||||
"Parallel Aware": false,
|
"Parallel Aware": false,
|
||||||
"Group Key": ["l_quantity"],
|
"Group Key": ["remote_scan.l_quantity"],
|
||||||
"Plans": [
|
"Plans": [
|
||||||
{
|
{
|
||||||
"Node Type": "Custom Scan",
|
"Node Type": "Custom Scan",
|
||||||
|
@ -154,8 +154,8 @@ EXPLAIN (COSTS FALSE, FORMAT XML)
|
||||||
<Node-Type>Sort</Node-Type>
|
<Node-Type>Sort</Node-Type>
|
||||||
<Parallel-Aware>false</Parallel-Aware>
|
<Parallel-Aware>false</Parallel-Aware>
|
||||||
<Sort-Key>
|
<Sort-Key>
|
||||||
<Item>COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)</Item>
|
<Item>COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)</Item>
|
||||||
<Item>l_quantity</Item>
|
<Item>remote_scan.l_quantity</Item>
|
||||||
</Sort-Key>
|
</Sort-Key>
|
||||||
<Plans>
|
<Plans>
|
||||||
<Plan>
|
<Plan>
|
||||||
|
@ -165,7 +165,7 @@ EXPLAIN (COSTS FALSE, FORMAT XML)
|
||||||
<Parent-Relationship>Outer</Parent-Relationship>
|
<Parent-Relationship>Outer</Parent-Relationship>
|
||||||
<Parallel-Aware>false</Parallel-Aware>
|
<Parallel-Aware>false</Parallel-Aware>
|
||||||
<Group-Key>
|
<Group-Key>
|
||||||
<Item>l_quantity</Item>
|
<Item>remote_scan.l_quantity</Item>
|
||||||
</Group-Key>
|
</Group-Key>
|
||||||
<Plans>
|
<Plans>
|
||||||
<Plan>
|
<Plan>
|
||||||
|
@ -228,8 +228,8 @@ EXPLAIN (COSTS FALSE, FORMAT YAML)
|
||||||
Node Type: "Sort"
|
Node Type: "Sort"
|
||||||
Parallel Aware: false
|
Parallel Aware: false
|
||||||
Sort Key:
|
Sort Key:
|
||||||
- "COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)"
|
- "COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)"
|
||||||
- "l_quantity"
|
- "remote_scan.l_quantity"
|
||||||
Plans:
|
Plans:
|
||||||
- Node Type: "Aggregate"
|
- Node Type: "Aggregate"
|
||||||
Strategy: "Hashed"
|
Strategy: "Hashed"
|
||||||
|
@ -237,7 +237,7 @@ EXPLAIN (COSTS FALSE, FORMAT YAML)
|
||||||
Parent Relationship: "Outer"
|
Parent Relationship: "Outer"
|
||||||
Parallel Aware: false
|
Parallel Aware: false
|
||||||
Group Key:
|
Group Key:
|
||||||
- "l_quantity"
|
- "remote_scan.l_quantity"
|
||||||
Plans:
|
Plans:
|
||||||
- Node Type: "Custom Scan"
|
- Node Type: "Custom Scan"
|
||||||
Parent Relationship: "Outer"
|
Parent Relationship: "Outer"
|
||||||
|
@ -269,9 +269,9 @@ EXPLAIN (COSTS FALSE, FORMAT TEXT)
|
||||||
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
||||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
||||||
Sort
|
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
|
-> HashAggregate
|
||||||
Group Key: l_quantity
|
Group Key: remote_scan.l_quantity
|
||||||
-> Custom Scan (Citus Real-Time)
|
-> Custom Scan (Citus Real-Time)
|
||||||
Task Count: 16
|
Task Count: 16
|
||||||
Tasks Shown: One of 16
|
Tasks Shown: One of 16
|
||||||
|
@ -285,9 +285,9 @@ Sort
|
||||||
EXPLAIN (COSTS FALSE, VERBOSE TRUE)
|
EXPLAIN (COSTS FALSE, VERBOSE TRUE)
|
||||||
SELECT sum(l_quantity) / avg(l_quantity) FROM lineitem_mx;
|
SELECT sum(l_quantity) / avg(l_quantity) FROM lineitem_mx;
|
||||||
Aggregate
|
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)
|
-> 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
|
Task Count: 16
|
||||||
Tasks Shown: One of 16
|
Tasks Shown: One of 16
|
||||||
-> Task
|
-> Task
|
||||||
|
@ -303,7 +303,7 @@ EXPLAIN (COSTS FALSE)
|
||||||
ORDER BY l_quantity LIMIT 10;
|
ORDER BY l_quantity LIMIT 10;
|
||||||
Limit
|
Limit
|
||||||
-> Sort
|
-> Sort
|
||||||
Sort Key: l_quantity
|
Sort Key: remote_scan.l_quantity
|
||||||
-> Custom Scan (Citus Real-Time)
|
-> Custom Scan (Citus Real-Time)
|
||||||
Task Count: 16
|
Task Count: 16
|
||||||
Tasks Shown: One of 16
|
Tasks Shown: One of 16
|
||||||
|
|
|
@ -62,9 +62,9 @@ EXPLAIN (COSTS FALSE, FORMAT TEXT)
|
||||||
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
||||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
||||||
Sort
|
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
|
-> HashAggregate
|
||||||
Group Key: l_quantity
|
Group Key: remote_scan.l_quantity
|
||||||
-> Custom Scan (Citus Real-Time)
|
-> Custom Scan (Citus Real-Time)
|
||||||
Task Count: 16
|
Task Count: 16
|
||||||
Tasks Shown: One of 16
|
Tasks Shown: One of 16
|
||||||
|
@ -81,13 +81,13 @@ EXPLAIN (COSTS FALSE, FORMAT JSON)
|
||||||
{
|
{
|
||||||
"Plan": {
|
"Plan": {
|
||||||
"Node Type": "Sort",
|
"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": [
|
"Plans": [
|
||||||
{
|
{
|
||||||
"Node Type": "Aggregate",
|
"Node Type": "Aggregate",
|
||||||
"Strategy": "Hashed",
|
"Strategy": "Hashed",
|
||||||
"Parent Relationship": "Outer",
|
"Parent Relationship": "Outer",
|
||||||
"Group Key": ["l_quantity"],
|
"Group Key": ["remote_scan.l_quantity"],
|
||||||
"Plans": [
|
"Plans": [
|
||||||
{
|
{
|
||||||
"Node Type": "Custom Scan",
|
"Node Type": "Custom Scan",
|
||||||
|
@ -146,8 +146,8 @@ EXPLAIN (COSTS FALSE, FORMAT XML)
|
||||||
<Plan>
|
<Plan>
|
||||||
<Node-Type>Sort</Node-Type>
|
<Node-Type>Sort</Node-Type>
|
||||||
<Sort-Key>
|
<Sort-Key>
|
||||||
<Item>COALESCE((sum((COALESCE((sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)</Item>
|
<Item>COALESCE((sum((COALESCE((sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)</Item>
|
||||||
<Item>l_quantity</Item>
|
<Item>remote_scan.l_quantity</Item>
|
||||||
</Sort-Key>
|
</Sort-Key>
|
||||||
<Plans>
|
<Plans>
|
||||||
<Plan>
|
<Plan>
|
||||||
|
@ -155,7 +155,7 @@ EXPLAIN (COSTS FALSE, FORMAT XML)
|
||||||
<Strategy>Hashed</Strategy>
|
<Strategy>Hashed</Strategy>
|
||||||
<Parent-Relationship>Outer</Parent-Relationship>
|
<Parent-Relationship>Outer</Parent-Relationship>
|
||||||
<Group-Key>
|
<Group-Key>
|
||||||
<Item>l_quantity</Item>
|
<Item>remote_scan.l_quantity</Item>
|
||||||
</Group-Key>
|
</Group-Key>
|
||||||
<Plans>
|
<Plans>
|
||||||
<Plan>
|
<Plan>
|
||||||
|
@ -213,14 +213,14 @@ EXPLAIN (COSTS FALSE, FORMAT YAML)
|
||||||
- Plan:
|
- Plan:
|
||||||
Node Type: "Sort"
|
Node Type: "Sort"
|
||||||
Sort Key:
|
Sort Key:
|
||||||
- "COALESCE((sum((COALESCE((sum(count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)"
|
- "COALESCE((sum((COALESCE((sum(remote_scan.count_quantity))::bigint, '0'::bigint))))::bigint, '0'::bigint)"
|
||||||
- "l_quantity"
|
- "remote_scan.l_quantity"
|
||||||
Plans:
|
Plans:
|
||||||
- Node Type: "Aggregate"
|
- Node Type: "Aggregate"
|
||||||
Strategy: "Hashed"
|
Strategy: "Hashed"
|
||||||
Parent Relationship: "Outer"
|
Parent Relationship: "Outer"
|
||||||
Group Key:
|
Group Key:
|
||||||
- "l_quantity"
|
- "remote_scan.l_quantity"
|
||||||
Plans:
|
Plans:
|
||||||
- Node Type: "Custom Scan"
|
- Node Type: "Custom Scan"
|
||||||
Parent Relationship: "Outer"
|
Parent Relationship: "Outer"
|
||||||
|
@ -248,9 +248,9 @@ EXPLAIN (COSTS FALSE, FORMAT TEXT)
|
||||||
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
||||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
||||||
Sort
|
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
|
-> HashAggregate
|
||||||
Group Key: l_quantity
|
Group Key: remote_scan.l_quantity
|
||||||
-> Custom Scan (Citus Real-Time)
|
-> Custom Scan (Citus Real-Time)
|
||||||
Task Count: 16
|
Task Count: 16
|
||||||
Tasks Shown: One of 16
|
Tasks Shown: One of 16
|
||||||
|
@ -264,9 +264,9 @@ Sort
|
||||||
EXPLAIN (COSTS FALSE, VERBOSE TRUE)
|
EXPLAIN (COSTS FALSE, VERBOSE TRUE)
|
||||||
SELECT sum(l_quantity) / avg(l_quantity) FROM lineitem_mx;
|
SELECT sum(l_quantity) / avg(l_quantity) FROM lineitem_mx;
|
||||||
Aggregate
|
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)
|
-> 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
|
Task Count: 16
|
||||||
Tasks Shown: One of 16
|
Tasks Shown: One of 16
|
||||||
-> Task
|
-> Task
|
||||||
|
@ -282,7 +282,7 @@ EXPLAIN (COSTS FALSE)
|
||||||
ORDER BY l_quantity LIMIT 10;
|
ORDER BY l_quantity LIMIT 10;
|
||||||
Limit
|
Limit
|
||||||
-> Sort
|
-> Sort
|
||||||
Sort Key: l_quantity
|
Sort Key: remote_scan.l_quantity
|
||||||
-> Custom Scan (Citus Real-Time)
|
-> Custom Scan (Citus Real-Time)
|
||||||
Task Count: 16
|
Task Count: 16
|
||||||
Tasks Shown: One of 16
|
Tasks Shown: One of 16
|
||||||
|
|
|
@ -225,3 +225,8 @@ test: multi_remove_node_reference_table
|
||||||
# multi_transactional_drop_shards tests for dropping shards using connection API
|
# multi_transactional_drop_shards tests for dropping shards using connection API
|
||||||
# ----------
|
# ----------
|
||||||
test: multi_transactional_drop_shards
|
test: multi_transactional_drop_shards
|
||||||
|
|
||||||
|
# ----------
|
||||||
|
# multi_multiuser tests simple combinations of permission access and queries
|
||||||
|
# ----------
|
||||||
|
test: multi_multiuser
|
||||||
|
|
|
@ -853,7 +853,7 @@ GROUP BY
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
HashAggregate (cost=0.00..0.00 rows=0 width=0)
|
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)
|
-> Custom Scan (Citus Real-Time) (cost=0.00..0.00 rows=0 width=0)
|
||||||
Task Count: 2
|
Task Count: 2
|
||||||
Tasks Shown: One of 2
|
Tasks Shown: One of 2
|
||||||
|
@ -1020,7 +1020,7 @@ LIMIT
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
Limit (cost=0.00..0.00 rows=0 width=0)
|
Limit (cost=0.00..0.00 rows=0 width=0)
|
||||||
-> Sort (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)
|
-> Custom Scan (Citus Real-Time) (cost=0.00..0.00 rows=0 width=0)
|
||||||
Task Count: 2
|
Task Count: 2
|
||||||
Tasks Shown: One of 2
|
Tasks Shown: One of 2
|
||||||
|
|
|
@ -853,7 +853,7 @@ GROUP BY
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
HashAggregate (cost=0.00..0.00 rows=0 width=0)
|
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)
|
-> Custom Scan (Citus Real-Time) (cost=0.00..0.00 rows=0 width=0)
|
||||||
Task Count: 2
|
Task Count: 2
|
||||||
Tasks Shown: One of 2
|
Tasks Shown: One of 2
|
||||||
|
@ -1017,7 +1017,7 @@ LIMIT
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
Limit (cost=0.00..0.00 rows=0 width=0)
|
Limit (cost=0.00..0.00 rows=0 width=0)
|
||||||
-> Sort (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)
|
-> Custom Scan (Citus Real-Time) (cost=0.00..0.00 rows=0 width=0)
|
||||||
Task Count: 2
|
Task Count: 2
|
||||||
Tasks Shown: One of 2
|
Tasks Shown: One of 2
|
||||||
|
|
|
@ -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;
|
Loading…
Reference in New Issue