@@ -2401,6 +2401,7 @@ apply_handle_insert(StringInfo s)
2401
2401
EState * estate ;
2402
2402
TupleTableSlot * remoteslot ;
2403
2403
MemoryContext oldctx ;
2404
+ bool run_as_owner ;
2404
2405
2405
2406
/*
2406
2407
* Quick return if we are skipping data modification changes or handling
@@ -2425,8 +2426,13 @@ apply_handle_insert(StringInfo s)
2425
2426
return ;
2426
2427
}
2427
2428
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 );
2430
2436
2431
2437
/* Set relation for error callback */
2432
2438
apply_error_callback_arg .rel = rel ;
@@ -2457,7 +2463,8 @@ apply_handle_insert(StringInfo s)
2457
2463
/* Reset relation for error callback */
2458
2464
apply_error_callback_arg .rel = NULL ;
2459
2465
2460
- RestoreUserContext (& ucxt );
2466
+ if (!run_as_owner )
2467
+ RestoreUserContext (& ucxt );
2461
2468
2462
2469
logicalrep_rel_close (rel , NoLock );
2463
2470
@@ -2546,6 +2553,7 @@ apply_handle_update(StringInfo s)
2546
2553
TupleTableSlot * remoteslot ;
2547
2554
RTEPermissionInfo * target_perminfo ;
2548
2555
MemoryContext oldctx ;
2556
+ bool run_as_owner ;
2549
2557
2550
2558
/*
2551
2559
* Quick return if we are skipping data modification changes or handling
@@ -2577,8 +2585,13 @@ apply_handle_update(StringInfo s)
2577
2585
/* Check if we can do the update. */
2578
2586
check_relation_updatable (rel );
2579
2587
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 );
2582
2595
2583
2596
/* Initialize the executor state. */
2584
2597
edata = create_edata_for_relation (rel );
@@ -2630,7 +2643,8 @@ apply_handle_update(StringInfo s)
2630
2643
/* Reset relation for error callback */
2631
2644
apply_error_callback_arg .rel = NULL ;
2632
2645
2633
- RestoreUserContext (& ucxt );
2646
+ if (!run_as_owner )
2647
+ RestoreUserContext (& ucxt );
2634
2648
2635
2649
logicalrep_rel_close (rel , NoLock );
2636
2650
@@ -2720,6 +2734,7 @@ apply_handle_delete(StringInfo s)
2720
2734
EState * estate ;
2721
2735
TupleTableSlot * remoteslot ;
2722
2736
MemoryContext oldctx ;
2737
+ bool run_as_owner ;
2723
2738
2724
2739
/*
2725
2740
* Quick return if we are skipping data modification changes or handling
@@ -2750,8 +2765,13 @@ apply_handle_delete(StringInfo s)
2750
2765
/* Check if we can do the delete. */
2751
2766
check_relation_updatable (rel );
2752
2767
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 );
2755
2775
2756
2776
/* Initialize the executor state. */
2757
2777
edata = create_edata_for_relation (rel );
@@ -2778,7 +2798,8 @@ apply_handle_delete(StringInfo s)
2778
2798
/* Reset relation for error callback */
2779
2799
apply_error_callback_arg .rel = NULL ;
2780
2800
2781
- RestoreUserContext (& ucxt );
2801
+ if (!run_as_owner )
2802
+ RestoreUserContext (& ucxt );
2782
2803
2783
2804
logicalrep_rel_close (rel , NoLock );
2784
2805
@@ -3225,13 +3246,18 @@ apply_handle_truncate(StringInfo s)
3225
3246
* Even if we used CASCADE on the upstream primary we explicitly default
3226
3247
* to replaying changes without further cascading. This might be later
3227
3248
* 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.
3228
3254
*/
3229
3255
ExecuteTruncateGuts (rels ,
3230
3256
relids ,
3231
3257
relids_logged ,
3232
3258
DROP_RESTRICT ,
3233
3259
restart_seqs ,
3234
- true );
3260
+ ! MySubscription -> runasowner );
3235
3261
foreach (lc , remote_rels )
3236
3262
{
3237
3263
LogicalRepRelMapEntry * rel = lfirst (lc );
0 commit comments