Skip to content

Commit ba75090

Browse files
dimitriHaoyu Huang
andauthored
pg hooks for online table (#693)
* pg hooks for online table (#24) Adding hooks for PG online table. - PreOnlineTableOp_hook - PostOnlineTableOp_hook - OnlineTableSecurityLabel_hook The 3 hooks are all used to bypass the ownership check on an online table. The Pre/Post hooks are used to allow non-online table owner to perform a few DDLs on the table, e.g., CREATE INDEX. - Pre hook will check the DDL type and whether the referenced relation is an online table. If the conditions are met, it will set the session user as the table owner. The rest of the PG code will work since the session is acting as the table owner now. - Post hook will restore the current user to the session user. OnlineTableSecurityLabel_hook is used to allow customers to add who can perform DDL on an online table. By default, the databricks_superuser can. OnlineTableSecurityLabel_hook will check if the session user is one of the roles attached to the online table. If it is, it will allow updating the label to add / remove roles. Otherwise, it will throw the permission error. Why we add them? 1. These 3 hooks are very specific for online table. We don't intend to use them for other purposes. 2. This is also the reason we are not overloading the public hook also. I need to be very specific on the code point where we want to set as table owner. standard_ProcessUtility contains too many stuff. I don't want to make our change generalize to all PG utilities. The extension change is inside https://github.com/databricks-eng/hadron/pull/492 * First pass of review. --------- Co-authored-by: Haoyu Huang <[email protected]>
1 parent a50d80c commit ba75090

File tree

4 files changed

+74
-3
lines changed

4 files changed

+74
-3
lines changed

src/backend/commands/seclabel.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ typedef struct
3333

3434
static List *label_provider_list = NIL;
3535

36+
/* BEGIN_PG_NEON */
37+
OnlineTableSecurityLabel_hook_type OnlineTableSecurityLabel_hook = NULL;
38+
/* END_PG_NEON */
39+
3640
static bool
3741
SecLabelSupportsObjectType(ObjectType objtype)
3842
{
@@ -168,9 +172,18 @@ ExecSecLabelStmt(SecLabelStmt *stmt)
168172
address = get_object_address(stmt->objtype, stmt->object,
169173
&relation, ShareUpdateExclusiveLock, false);
170174

171-
/* Require ownership of the target object. */
172-
check_object_ownership(GetUserId(), stmt->objtype, address,
173-
stmt->object, relation);
175+
/* BEGIN_PG_NEON */
176+
if (OnlineTableSecurityLabel_hook != NULL)
177+
{
178+
OnlineTableSecurityLabel_hook(stmt, &address, relation);
179+
}
180+
else
181+
{
182+
/* Require ownership of the target object. */
183+
check_object_ownership(GetUserId(), stmt->objtype, address,
184+
stmt->object, relation);
185+
}
186+
/* END_PG_NEON */
174187

175188
/* Perform other integrity checks as needed. */
176189
switch (stmt->objtype)

src/backend/tcop/utility.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@
6969
/* Hook for plugins to get control in ProcessUtility() */
7070
ProcessUtility_hook_type ProcessUtility_hook = NULL;
7171

72+
/* BEGIN_PG_NEON */
73+
PreOnlineTableOp_hook_type PreOnlineTableOp_hook = NULL;
74+
PostOnlineTableOp_hook_type PostOnlineTableOp_hook = NULL;
75+
/* END_PG_NEON */
76+
7277
/* local function declarations */
7378
static int ClassifyUtilityCommandAsReadOnly(Node *parsetree);
7479
static void ProcessUtilitySlow(ParseState *pstate,
@@ -1112,6 +1117,13 @@ ProcessUtilitySlow(ParseState *pstate,
11121117
if (isCompleteQuery)
11131118
EventTriggerDDLCommandStart(parsetree);
11141119

1120+
/* BEGIN_PG_NEON */
1121+
if (PreOnlineTableOp_hook != NULL)
1122+
{
1123+
PreOnlineTableOp_hook(parsetree);
1124+
}
1125+
/* END_PG_NEON */
1126+
11151127
switch (nodeTag(parsetree))
11161128
{
11171129
/*
@@ -1932,6 +1944,13 @@ ProcessUtilitySlow(ParseState *pstate,
19321944
}
19331945
PG_FINALLY();
19341946
{
1947+
/* BEGIN_PG_NEON */
1948+
if (PostOnlineTableOp_hook != NULL)
1949+
{
1950+
PostOnlineTableOp_hook(parsetree);
1951+
}
1952+
/* END_PG_NEON */
1953+
19351954
if (needCleanup)
19361955
EventTriggerEndCompleteQuery();
19371956
}

src/include/commands/seclabel.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,20 @@ typedef void (*check_object_relabel_type) (const ObjectAddress *object,
3131
extern void register_label_provider(const char *provider_name,
3232
check_object_relabel_type hook);
3333

34+
/* BEGIN_PG_NEON */
35+
36+
/*
37+
* OnlineTableSecurityLabel_hook is used to allow customers to perform DDL on
38+
* an online table. By default, only databricks_superuser can.
39+
* OnlineTableSecurityLabel_hook checks if the session user is one of the
40+
* roles attached to the online table. If it is, it allows updating the label
41+
* to add/remove roles. Otherwise, a permission error is thrown.
42+
*/
43+
typedef void (*OnlineTableSecurityLabel_hook_type) (SecLabelStmt *stmt,
44+
const ObjectAddress *object,
45+
Relation relation);
46+
47+
extern PGDLLIMPORT OnlineTableSecurityLabel_hook_type OnlineTableSecurityLabel_hook;
48+
/* END_PG_NEON */
49+
3450
#endif /* SECLABEL_H */

src/include/tcop/utility.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,29 @@ typedef void (*ProcessUtility_hook_type) (PlannedStmt *pstmt,
7777
DestReceiver *dest, QueryCompletion *qc);
7878
extern PGDLLIMPORT ProcessUtility_hook_type ProcessUtility_hook;
7979

80+
/* BEGIN_PG_NEON */
81+
82+
/*
83+
* The Pre/Post hooks are used to allow roles that do not own an online table
84+
* to still perform a few DDLs on the table, e.g., CREATE INDEX.
85+
*
86+
* - Pre hook will check the DDL type and whether the referenced relation is
87+
* an online table. If the conditions are met, it will set the session user
88+
* as the table owner.
89+
*
90+
* Postgres code then (typically) executes as the session user, which is now
91+
* SET to the table owner.
92+
*
93+
* - Post hook will restore the current user to the session user.
94+
*/
95+
typedef void (*PreOnlineTableOp_hook_type) (Node *parsetree);
96+
extern PGDLLIMPORT PreOnlineTableOp_hook_type PreOnlineTableOp_hook;
97+
98+
typedef void (*PostOnlineTableOp_hook_type) (Node *parsetree);
99+
extern PGDLLIMPORT PostOnlineTableOp_hook_type PostOnlineTableOp_hook;
100+
101+
/* END_PG_NEON */
102+
80103
extern void ProcessUtility(PlannedStmt *pstmt, const char *queryString,
81104
bool readOnlyTree,
82105
ProcessUtilityContext context, ParamListInfo params,

0 commit comments

Comments
 (0)