@@ -1019,13 +1019,26 @@ fn auto_migrate_constraints(plan: &mut AutoMigratePlan, new_tables: &HashSet<&Id
10191019// Because we can refer to many tables and fields on the row level-security query, we need to remove all of them,
10201020// then add the new ones, instead of trying to track the graph of dependencies.
10211021fn auto_migrate_row_level_security ( plan : & mut AutoMigratePlan ) -> Result < ( ) > {
1022+ // Track if any RLS rules were changed.
1023+ let mut old_rls = HashSet :: new ( ) ;
1024+ let mut new_rls = HashSet :: new ( ) ;
1025+
10221026 for rls in plan. old . row_level_security ( ) {
1027+ old_rls. insert ( rls. key ( ) ) ;
10231028 plan. steps . push ( AutoMigrateStep :: RemoveRowLevelSecurity ( rls. key ( ) ) ) ;
10241029 }
10251030 for rls in plan. new . row_level_security ( ) {
1031+ new_rls. insert ( rls. key ( ) ) ;
10261032 plan. steps . push ( AutoMigrateStep :: AddRowLevelSecurity ( rls. key ( ) ) ) ;
10271033 }
10281034
1035+ // After changing an RLS rule and updating the module, the updated rule does not take effect for clients until they reconnect.
1036+ // This is because subscriptions are cached and we don't flush the cache when RLS rules are updated.
1037+ // We can force flush the cache by force disconnecting all clients if an RLS rule has been added, removed, or updated.
1038+ if old_rls != new_rls {
1039+ plan. steps . push ( AutoMigrateStep :: DisconnectAllUsers ) ;
1040+ }
1041+
10291042 Ok ( ( ) )
10301043}
10311044
@@ -2245,4 +2258,52 @@ mod tests {
22452258 ) ;
22462259 }
22472260 }
2261+
2262+ #[ test]
2263+ fn change_rls_disconnect_clients ( ) {
2264+ let old_def = create_module_def ( |_builder| { } ) ;
2265+
2266+ let new_def = create_module_def ( |_builder| { } ) ;
2267+
2268+ let plan = ponder_auto_migrate ( & old_def, & new_def) . expect ( "auto migration should succeed" ) ;
2269+ assert ! ( !plan. disconnects_all_users( ) , "{plan:#?}" ) ;
2270+
2271+ let old_def = create_module_def ( |builder| {
2272+ builder. add_row_level_security ( "SELECT true;" ) ;
2273+ } ) ;
2274+ let new_def = create_module_def ( |builder| {
2275+ builder. add_row_level_security ( "SELECT false;" ) ;
2276+ } ) ;
2277+
2278+ let plan = ponder_auto_migrate ( & old_def, & new_def) . expect ( "auto migration should succeed" ) ;
2279+ assert ! ( plan. disconnects_all_users( ) , "{plan:#?}" ) ;
2280+
2281+ let old_def = create_module_def ( |builder| {
2282+ builder. add_row_level_security ( "SELECT true;" ) ;
2283+ } ) ;
2284+
2285+ let new_def = create_module_def ( |_builder| {
2286+ // Remove RLS
2287+ } ) ;
2288+ let plan = ponder_auto_migrate ( & old_def, & new_def) . expect ( "auto migration should succeed" ) ;
2289+ assert ! ( plan. disconnects_all_users( ) , "{plan:#?}" ) ;
2290+
2291+ let old_def = create_module_def ( |_builder| { } ) ;
2292+
2293+ let new_def = create_module_def ( |builder| {
2294+ builder. add_row_level_security ( "SELECT false;" ) ;
2295+ } ) ;
2296+ let plan = ponder_auto_migrate ( & old_def, & new_def) . expect ( "auto migration should succeed" ) ;
2297+ assert ! ( plan. disconnects_all_users( ) , "{plan:#?}" ) ;
2298+
2299+ let old_def = create_module_def ( |builder| {
2300+ builder. add_row_level_security ( "SELECT true;" ) ;
2301+ } ) ;
2302+
2303+ let new_def = create_module_def ( |builder| {
2304+ builder. add_row_level_security ( "SELECT true;" ) ;
2305+ } ) ;
2306+ let plan = ponder_auto_migrate ( & old_def, & new_def) . expect ( "auto migration should succeed" ) ;
2307+ assert ! ( !plan. disconnects_all_users( ) , "{plan:#?}" ) ;
2308+ }
22482309}
0 commit comments