Skip to content

Commit e34e30d

Browse files
authored
Avoid checking permission of Babelfish temp tables on parallel worker (#560) (#566)
Consider following facts, 1. Babelfish temp tables are implemented using ENR which is not shared between different backends. So if Parallel worker tries to check permissions on Babelfish then it will fail. 2. Any user should be able to access Babelfish temp tables under given session. 3. Postgres by default does not allow parallel operations on temp tables. Attempt to do so will result in run time error. Due to above facts, we should avoid permission check on temp tables within parallel workers while ensuring that leader does required permission check on other tables. This commits achieves this behaviour by introducing following three hooks, ParallelQueryMain_hook -- Hook that allows other extensions to pass on additional details from Leader node to parallel worker. For example, Babelfish extension can pass details of Babelfish temp table defined under current session with Parallel workers. ExecInitParallelPlan_hook -- Hook that allows Parallel worker to gather additional details passed by Leader node. For example, Babelfish extension can collect the details of Babelfish temp table shared by Leader node so that it can avoid permission checks. ExecCheckOneRelPerms_hook -- Hook that allows extension control permission checking on given relation/table. For example, Babelfish can use it to avoid permission check on temp tables under parallel worker. Task: BABEL-5703 Signed-off-by: Dipesh Dhameliya <[email protected]> (cherry picked from commit 5e62ffa)
1 parent b059d91 commit e34e30d

File tree

5 files changed

+61
-7
lines changed

5 files changed

+61
-7
lines changed

src/backend/executor/execMain.c

+26-3
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ ExecutorEnd_hook_type ExecutorEnd_hook = NULL;
7070

7171
TriggerRecuresiveCheck_hook_type TriggerRecuresiveCheck_hook = NULL;
7272
check_rowcount_hook_type check_rowcount_hook = NULL;
73+
ExecCheckOneRelPerms_hook_type ExecCheckOneRelPerms_hook = NULL;
74+
7375
/* Hook for plugin to get control in ExecCheckPermissions() */
7476
ExecutorCheckPerms_hook_type ExecutorCheckPerms_hook = NULL;
7577

@@ -648,6 +650,19 @@ ExecCheckOneRelPerms(RTEPermissionInfo *perminfo)
648650
requiredPerms = perminfo->requiredPerms;
649651
Assert(requiredPerms != 0);
650652

653+
/*
654+
* Babelfish specific logic - Babelfish temp table is implemented
655+
* using ENR which is not shared with parallel worker and parallel
656+
* operations are not allowed for temp table in Postgres. Babelfish
657+
* can skip permission check for such use cases under parallel worker
658+
* using this hook.
659+
* Note - This hook must not be used outside of Babelfish parallel worker
660+
*/
661+
if (ExecCheckOneRelPerms_hook &&
662+
IsBabelfishParallelWorker() &&
663+
(*ExecCheckOneRelPerms_hook)(perminfo))
664+
return true;
665+
651666
/*
652667
* userid to check as: current user unless we have a setuid indication.
653668
*
@@ -840,10 +855,9 @@ InitPlan(QueryDesc *queryDesc, int eflags)
840855
int i;
841856

842857
/*
843-
* Do permissions checks if not Babelfish parallel worker
858+
* Do permissions checks
844859
*/
845-
if (!IsBabelfishParallelWorker())
846-
ExecCheckPermissions(rangeTable, plannedstmt->permInfos, true);
860+
ExecCheckPermissions(rangeTable, plannedstmt->permInfos, true);
847861

848862
/*
849863
* initialize the node's execution state
@@ -3046,3 +3060,12 @@ EvalPlanQualEnd(EPQState *epqstate)
30463060
epqstate->relsubs_done = NULL;
30473061
epqstate->relsubs_blocked = NULL;
30483062
}
3063+
3064+
/*
3065+
* ExecCheckOneRelPerms_wrapper - wrapper around ExecCheckOneRelPerms
3066+
*/
3067+
bool
3068+
ExecCheckOneRelPerms_wrapper(RTEPermissionInfo *perminfo)
3069+
{
3070+
return ExecCheckOneRelPerms(perminfo);
3071+
}

src/backend/executor/execParallel.c

+19
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ typedef struct ExecParallelInitializeDSMContext
122122
int nnodes;
123123
} ExecParallelInitializeDSMContext;
124124

125+
ExecInitParallelPlan_hook_type ExecInitParallelPlan_hook = NULL;
126+
ParallelQueryMain_hook_type ParallelQueryMain_hook = NULL;
127+
125128
/* Helper functions that run in the parallel leader. */
126129
static char *ExecSerializePlan(Plan *plan, EState *estate);
127130
static bool ExecParallelEstimate(PlanState *planstate,
@@ -683,6 +686,10 @@ ExecInitParallelPlan(PlanState *planstate, EState *estate,
683686
mul_size(PARALLEL_TUPLE_QUEUE_SIZE, pcxt->nworkers));
684687
shm_toc_estimate_keys(&pcxt->estimator, 1);
685688

689+
/* Let extension estimate a dynamic shared memory needed to communicate additional context */
690+
if (ExecInitParallelPlan_hook)
691+
(*ExecInitParallelPlan_hook)(estate, pcxt, true);
692+
686693
/*
687694
* Give parallel-aware nodes a chance to add to the estimates, and get a
688695
* count of how many PlanState nodes there are.
@@ -773,6 +780,12 @@ ExecInitParallelPlan(PlanState *planstate, EState *estate,
773780
shm_toc_insert(pcxt->toc, PARALLEL_KEY_WAL_USAGE, walusage_space);
774781
pei->wal_usage = walusage_space;
775782

783+
/* Give extension a chance to share additional context */
784+
if (ExecInitParallelPlan_hook)
785+
{
786+
(*ExecInitParallelPlan_hook)(estate, pcxt,false);
787+
}
788+
776789
/* Set up the tuple queues that the workers will write into. */
777790
pei->tqueue = ExecParallelSetupTupleQueues(pcxt, false);
778791

@@ -1433,6 +1446,12 @@ ParallelQueryMain(dsm_segment *seg, shm_toc *toc)
14331446
area_space = shm_toc_lookup(toc, PARALLEL_KEY_DSA, false);
14341447
area = dsa_attach_in_place(area_space, seg);
14351448

1449+
/* Give extension chance to retrieve additional context shared by leader node */
1450+
if (ParallelQueryMain_hook)
1451+
{
1452+
(*ParallelQueryMain_hook)(toc);
1453+
}
1454+
14361455
/* Start up the executor */
14371456
queryDesc->plannedstmt->jitFlags = fpes->jit_flags;
14381457
ExecutorStart(queryDesc, fpes->eflags);

src/include/access/parallel.h

-4
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,11 @@ extern void ParallelWorkerMain(Datum main_arg);
8181
/* Below helpers are added to support parallel workers in Babelfish context */
8282
extern bool IsBabelfishParallelWorker(void);
8383

84-
/* Key for BabelfishFixedParallelState */
85-
#define BABELFISH_PARALLEL_KEY_FIXED UINT64CONST(0xBBF0000000000001)
86-
8784
/* Hooks for communicating babelfish related information to parallel worker */
8885
typedef void (*bbf_InitializeParallelDSM_hook_type)(ParallelContext *pcxt, bool estimate);
8986
extern PGDLLIMPORT bbf_InitializeParallelDSM_hook_type bbf_InitializeParallelDSM_hook;
9087

9188
typedef void (*bbf_ParallelWorkerMain_hook_type)(shm_toc *toc);
9289
extern PGDLLIMPORT bbf_ParallelWorkerMain_hook_type bbf_ParallelWorkerMain_hook;
9390

94-
9591
#endif /* PARALLEL_H */

src/include/executor/execParallel.h

+11
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,15 @@ extern void ExecParallelReinitialize(PlanState *planstate,
4848

4949
extern void ParallelQueryMain(dsm_segment *seg, shm_toc *toc);
5050

51+
typedef void (*ParallelQueryMain_hook_type)(shm_toc *toc);
52+
extern PGDLLIMPORT ParallelQueryMain_hook_type ParallelQueryMain_hook;
53+
54+
/*
55+
* When estimate = true passed then caller wants extension to estimate a dynamic shared memory (DSM)
56+
* needed by that extension to communicate additional context with Parallel worker.
57+
* When estimate = false then caller wants to insert additional context to DSM.
58+
*/
59+
typedef void (*ExecInitParallelPlan_hook_type)(EState *estate, ParallelContext *pcxt, bool estimate);
60+
extern PGDLLIMPORT ExecInitParallelPlan_hook_type ExecInitParallelPlan_hook;
61+
5162
#endif /* EXECPARALLEL_H */

src/include/executor/executor.h

+5
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ extern PGDLLIMPORT ExecUpdateResultTypeTL_hook_type ExecUpdateResultTypeTL_hook;
111111
typedef bool (*check_rowcount_hook_type) (int es_processed);
112112
extern PGDLLEXPORT check_rowcount_hook_type check_rowcount_hook;
113113

114+
typedef bool (*ExecCheckOneRelPerms_hook_type) (RTEPermissionInfo *perminfo);
115+
extern PGDLLEXPORT ExecCheckOneRelPerms_hook_type ExecCheckOneRelPerms_hook;
116+
114117
/*
115118
* prototypes from functions in execAmi.c
116119
*/
@@ -224,6 +227,8 @@ extern void standard_ExecutorEnd(QueryDesc *queryDesc);
224227
extern void ExecutorRewind(QueryDesc *queryDesc);
225228
extern bool ExecCheckPermissions(List *rangeTable,
226229
List *rteperminfos, bool ereport_on_violation);
230+
/* Wrapper around ExecCheckOneRelPerms */
231+
extern bool ExecCheckOneRelPerms_wrapper(RTEPermissionInfo *perminfo);
227232
extern void CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation,
228233
List *mergeActions);
229234
extern void InitResultRelInfo(ResultRelInfo *resultRelInfo,

0 commit comments

Comments
 (0)