Skip to content

Commit eaac13e

Browse files
authored
Avoid checking permission of Babelfish temp tables on parallel worker (#572)
Consider following facts, 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. Any user should be able to access Babelfish temp tables under given session. 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. ExecCheckRTEPerms_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. Also, this changes introduces stringToBms(...) API using which we can directly build Bitmapset from given string. This is especially useful by Babelfish parallel worker to prepare Bitmapset of temp relids from string shared by Leader node. Task: BABEL-5703 Signed-off-by: Dipesh Dhameliya <[email protected]> (cherry picked from commit fa391af)
1 parent 22cca1e commit eaac13e

File tree

7 files changed

+80
-7
lines changed

7 files changed

+80
-7
lines changed

src/backend/executor/execMain.c

+27-3
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ TriggerRecuresiveCheck_hook_type TriggerRecuresiveCheck_hook = NULL;
7979
/* Hook for plugin to get control in ExecCheckRTPerms() */
8080
ExecutorCheckPerms_hook_type ExecutorCheckPerms_hook = NULL;
8181

82+
/* Hook for plugin to get control in ExecCheckRTEPerms() */
83+
ExecCheckRTEPerms_hook_type ExecCheckRTEPerms_hook = NULL;
84+
8285
/* decls for local routines only used within this module */
8386
static void InitPlan(QueryDesc *queryDesc, int eflags);
8487
static void CheckValidRowMarkRel(Relation rel, RowMarkType markType);
@@ -618,6 +621,19 @@ ExecCheckRTEPerms(RangeTblEntry *rte)
618621

619622
relOid = rte->relid;
620623

624+
/*
625+
* Babelfish specific logic - Babelfish temp table is implemented
626+
* using ENR which is not shared with parallel worker and parallel
627+
* operations are not allowed for temp table in Postgres. Babelfish
628+
* can skip permission check for such use cases under parallel worker
629+
* using this hook.
630+
* Note - This hook must not be used outside of Babelfish parallel worker
631+
*/
632+
if (ExecCheckRTEPerms_hook &&
633+
IsBabelfishParallelWorker() &&
634+
(*ExecCheckRTEPerms_hook)(rte))
635+
return true;
636+
621637
/*
622638
* userid to check as: current user unless we have a setuid indication.
623639
*
@@ -810,10 +826,9 @@ InitPlan(QueryDesc *queryDesc, int eflags)
810826
int i;
811827

812828
/*
813-
* Do permissions checks if not Babelfish parallel worker
829+
* Do permissions checks
814830
*/
815-
if (!IsBabelfishParallelWorker())
816-
ExecCheckRTPerms(rangeTable, true);
831+
ExecCheckRTPerms(rangeTable, true);
817832

818833
/*
819834
* initialize the node's execution state
@@ -2944,3 +2959,12 @@ EvalPlanQualEnd(EPQState *epqstate)
29442959
epqstate->relsubs_done = NULL;
29452960
epqstate->epqExtra->relsubs_blocked = NULL;
29462961
}
2962+
2963+
/*
2964+
* ExecCheckRTEPerms_wrapper - wrapper around ExecCheckRTEPerms
2965+
*/
2966+
bool
2967+
ExecCheckRTEPerms_wrapper(RangeTblEntry *rte)
2968+
{
2969+
return ExecCheckRTEPerms(rte);
2970+
}

src/backend/executor/execParallel.c

+19
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ typedef struct ExecParallelInitializeDSMContext
124124
int nnodes;
125125
} ExecParallelInitializeDSMContext;
126126

127+
ExecInitParallelPlan_hook_type ExecInitParallelPlan_hook = NULL;
128+
ParallelQueryMain_hook_type ParallelQueryMain_hook = NULL;
129+
127130
/* Helper functions that run in the parallel leader. */
128131
static char *ExecSerializePlan(Plan *plan, EState *estate);
129132
static bool ExecParallelEstimate(PlanState *node,
@@ -684,6 +687,10 @@ ExecInitParallelPlan(PlanState *planstate, EState *estate,
684687
mul_size(PARALLEL_TUPLE_QUEUE_SIZE, pcxt->nworkers));
685688
shm_toc_estimate_keys(&pcxt->estimator, 1);
686689

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

777+
/* Give extension a chance to share additional context */
778+
if (ExecInitParallelPlan_hook)
779+
{
780+
(*ExecInitParallelPlan_hook)(estate, pcxt,false);
781+
}
782+
770783
/* Set up the tuple queues that the workers will write into. */
771784
pei->tqueue = ExecParallelSetupTupleQueues(pcxt, false);
772785

@@ -1427,6 +1440,12 @@ ParallelQueryMain(dsm_segment *seg, shm_toc *toc)
14271440
area_space = shm_toc_lookup(toc, PARALLEL_KEY_DSA, false);
14281441
area = dsa_attach_in_place(area_space, seg);
14291442

1443+
/* Give extension chance to retrieve additional context shared by leader node */
1444+
if (ParallelQueryMain_hook)
1445+
{
1446+
(*ParallelQueryMain_hook)(toc);
1447+
}
1448+
14301449
/* Start up the executor */
14311450
queryDesc->plannedstmt->jitFlags = fpes->jit_flags;
14321451
ExecutorStart(queryDesc, fpes->eflags);

src/backend/nodes/read.c

+18
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <ctype.h>
2323

2424
#include "common/string.h"
25+
#include "nodes/bitmapset.h"
2526
#include "nodes/pg_list.h"
2627
#include "nodes/readfuncs.h"
2728
#include "nodes/value.h"
@@ -472,3 +473,20 @@ nodeRead(const char *token, int tok_len)
472473

473474
return (void *) result;
474475
}
476+
477+
/*
478+
* Helper function for Babelfish to build Bitmapset from string.
479+
*/
480+
Bitmapset *
481+
stringToBms(const char *str)
482+
{
483+
Bitmapset *ret;
484+
const char *save_strtok;
485+
486+
save_strtok = pg_strtok_ptr;
487+
pg_strtok_ptr = str; /* point pg_strtok at the string to read */
488+
489+
ret = readBitmapset();
490+
pg_strtok_ptr = save_strtok;
491+
return ret;
492+
}

src/include/access/parallel.h

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

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

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

95-
9692
#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

+4
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ extern PGDLLIMPORT ExecutorCheckPerms_hook_type ExecutorCheckPerms_hook;
8787
typedef bool (*TriggerRecuresiveCheck_hook_type) (ResultRelInfo *resultRelInfo);
8888
extern PGDLLIMPORT TriggerRecuresiveCheck_hook_type TriggerRecuresiveCheck_hook;
8989

90+
typedef bool (*ExecCheckRTEPerms_hook_type) (RangeTblEntry *rte);
91+
extern PGDLLEXPORT ExecCheckRTEPerms_hook_type ExecCheckRTEPerms_hook;
92+
9093
/*
9194
* prototypes from functions in execAmi.c
9295
*/
@@ -200,6 +203,7 @@ extern void standard_ExecutorEnd(QueryDesc *queryDesc);
200203
extern void ExecutorRewind(QueryDesc *queryDesc);
201204
extern bool ExecCheckRTPerms(List *rangeTable, bool ereport_on_violation);
202205
extern void CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation);
206+
extern bool ExecCheckRTEPerms_wrapper(RangeTblEntry *rte);
203207
extern void InitResultRelInfo(ResultRelInfo *resultRelInfo,
204208
Relation resultRelationDesc,
205209
Index resultRelationIndex,

src/include/nodes/nodes.h

+1
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,7 @@ extern bool *readBoolCols(int numCols);
648648
extern int *readIntCols(int numCols);
649649
extern Oid *readOidCols(int numCols);
650650
extern int16 *readAttrNumberCols(int numCols);
651+
extern struct Bitmapset *stringToBms(const char *str);
651652

652653
/*
653654
* nodes/copyfuncs.c

0 commit comments

Comments
 (0)