@@ -2401,6 +2401,7 @@ apply_handle_insert(StringInfo s)
24012401EState * estate ;
24022402TupleTableSlot * remoteslot ;
24032403MemoryContext oldctx ;
2404+ bool run_as_owner ;
24042405
24052406/*
24062407 * Quick return if we are skipping data modification changes or handling
@@ -2425,8 +2426,13 @@ apply_handle_insert(StringInfo s)
24252426return ;
24262427}
24272428
2428- /* Make sure that any user-supplied code runs as the table owner. */
2429- SwitchToUntrustedUser (rel -> localrel -> rd_rel -> relowner ,& ucxt );
2429+ /*
2430+ * Make sure that any user-supplied code runs as the table owner, unless
2431+ * the user has opted out of that behavior.
2432+ */
2433+ run_as_owner = MySubscription -> runasowner ;
2434+ if (!run_as_owner )
2435+ SwitchToUntrustedUser (rel -> localrel -> rd_rel -> relowner ,& ucxt );
24302436
24312437/* Set relation for error callback */
24322438apply_error_callback_arg .rel = rel ;
@@ -2457,7 +2463,8 @@ apply_handle_insert(StringInfo s)
24572463/* Reset relation for error callback */
24582464apply_error_callback_arg .rel = NULL ;
24592465
2460- RestoreUserContext (& ucxt );
2466+ if (!run_as_owner )
2467+ RestoreUserContext (& ucxt );
24612468
24622469logicalrep_rel_close (rel ,NoLock );
24632470
@@ -2546,6 +2553,7 @@ apply_handle_update(StringInfo s)
25462553TupleTableSlot * remoteslot ;
25472554RTEPermissionInfo * target_perminfo ;
25482555MemoryContext oldctx ;
2556+ bool run_as_owner ;
25492557
25502558/*
25512559 * Quick return if we are skipping data modification changes or handling
@@ -2577,8 +2585,13 @@ apply_handle_update(StringInfo s)
25772585/* Check if we can do the update. */
25782586check_relation_updatable (rel );
25792587
2580- /* Make sure that any user-supplied code runs as the table owner. */
2581- SwitchToUntrustedUser (rel -> localrel -> rd_rel -> relowner ,& ucxt );
2588+ /*
2589+ * Make sure that any user-supplied code runs as the table owner, unless
2590+ * the user has opted out of that behavior.
2591+ */
2592+ run_as_owner = MySubscription -> runasowner ;
2593+ if (!run_as_owner )
2594+ SwitchToUntrustedUser (rel -> localrel -> rd_rel -> relowner ,& ucxt );
25822595
25832596/* Initialize the executor state. */
25842597edata = create_edata_for_relation (rel );
@@ -2630,7 +2643,8 @@ apply_handle_update(StringInfo s)
26302643/* Reset relation for error callback */
26312644apply_error_callback_arg .rel = NULL ;
26322645
2633- RestoreUserContext (& ucxt );
2646+ if (!run_as_owner )
2647+ RestoreUserContext (& ucxt );
26342648
26352649logicalrep_rel_close (rel ,NoLock );
26362650
@@ -2720,6 +2734,7 @@ apply_handle_delete(StringInfo s)
27202734EState * estate ;
27212735TupleTableSlot * remoteslot ;
27222736MemoryContext oldctx ;
2737+ bool run_as_owner ;
27232738
27242739/*
27252740 * Quick return if we are skipping data modification changes or handling
@@ -2750,8 +2765,13 @@ apply_handle_delete(StringInfo s)
27502765/* Check if we can do the delete. */
27512766check_relation_updatable (rel );
27522767
2753- /* Make sure that any user-supplied code runs as the table owner. */
2754- SwitchToUntrustedUser (rel -> localrel -> rd_rel -> relowner ,& ucxt );
2768+ /*
2769+ * Make sure that any user-supplied code runs as the table owner, unless
2770+ * the user has opted out of that behavior.
2771+ */
2772+ run_as_owner = MySubscription -> runasowner ;
2773+ if (!run_as_owner )
2774+ SwitchToUntrustedUser (rel -> localrel -> rd_rel -> relowner ,& ucxt );
27552775
27562776/* Initialize the executor state. */
27572777edata = create_edata_for_relation (rel );
@@ -2778,7 +2798,8 @@ apply_handle_delete(StringInfo s)
27782798/* Reset relation for error callback */
27792799apply_error_callback_arg .rel = NULL ;
27802800
2781- RestoreUserContext (& ucxt );
2801+ if (!run_as_owner )
2802+ RestoreUserContext (& ucxt );
27822803
27832804logicalrep_rel_close (rel ,NoLock );
27842805
@@ -3225,13 +3246,18 @@ apply_handle_truncate(StringInfo s)
32253246 * Even if we used CASCADE on the upstream primary we explicitly default
32263247 * to replaying changes without further cascading. This might be later
32273248 * changeable with a user specified option.
3249+ *
3250+ * MySubscription->runasowner tells us whether we want to execute
3251+ * replication actions as the subscription owner; the last argument to
3252+ * TruncateGuts tells it whether we want to switch to the table owner.
3253+ * Those are exactly opposite conditions.
32283254 */
32293255ExecuteTruncateGuts (rels ,
32303256relids ,
32313257relids_logged ,
32323258DROP_RESTRICT ,
32333259restart_seqs ,
3234- true );
3260+ ! MySubscription -> runasowner );
32353261foreach (lc ,remote_rels )
32363262{
32373263LogicalRepRelMapEntry * rel = lfirst (lc );