#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Strategy {
Atomic,
Online,
}
#[allow(clippy::struct_excessive_bools)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct OnlineRewrites {
pub create_index_concurrent: bool,
pub fk_not_valid_then_validate: bool,
pub check_not_valid_then_validate: bool,
pub not_null_via_check_pattern: bool,
pub refresh_mv_concurrently: bool,
pub view_drop_create_dependents: bool,
}
impl OnlineRewrites {
pub const fn all_enabled() -> Self {
Self {
create_index_concurrent: true,
fk_not_valid_then_validate: true,
check_not_valid_then_validate: true,
not_null_via_check_pattern: true,
refresh_mv_concurrently: true,
view_drop_create_dependents: true,
}
}
pub const fn all_disabled() -> Self {
Self {
create_index_concurrent: false,
fk_not_valid_then_validate: false,
check_not_valid_then_validate: false,
not_null_via_check_pattern: false,
refresh_mv_concurrently: false,
view_drop_create_dependents: false,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct PlannerPolicy {
pub strategy: Strategy,
pub online: OnlineRewrites,
pub planner_ruleset_version: u32,
}
impl PlannerPolicy {
pub const fn create_index_concurrent(&self) -> bool {
matches!(self.strategy, Strategy::Online) && self.online.create_index_concurrent
}
pub const fn fk_not_valid_then_validate(&self) -> bool {
matches!(self.strategy, Strategy::Online) && self.online.fk_not_valid_then_validate
}
pub const fn check_not_valid_then_validate(&self) -> bool {
matches!(self.strategy, Strategy::Online) && self.online.check_not_valid_then_validate
}
pub const fn not_null_via_check_pattern(&self) -> bool {
matches!(self.strategy, Strategy::Online) && self.online.not_null_via_check_pattern
}
pub const fn refresh_mv_concurrently(&self) -> bool {
matches!(self.strategy, Strategy::Online) && self.online.refresh_mv_concurrently
}
pub const fn view_drop_create_dependents(&self) -> bool {
self.online.view_drop_create_dependents
}
pub const fn is_online(&self) -> bool {
matches!(self.strategy, Strategy::Online)
}
}
impl Default for PlannerPolicy {
fn default() -> Self {
Self {
strategy: Strategy::Online,
online: OnlineRewrites::all_enabled(),
planner_ruleset_version: 1,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_is_online_with_every_rewrite_enabled() {
let p = PlannerPolicy::default();
assert!(p.is_online());
assert!(p.create_index_concurrent());
assert!(p.fk_not_valid_then_validate());
assert!(p.check_not_valid_then_validate());
assert!(p.not_null_via_check_pattern());
assert!(p.refresh_mv_concurrently());
assert!(p.view_drop_create_dependents());
assert_eq!(p.planner_ruleset_version, 1);
}
#[test]
fn atomic_strategy_disables_every_rewrite_regardless_of_switches() {
let p = PlannerPolicy {
strategy: Strategy::Atomic,
online: OnlineRewrites::all_enabled(),
planner_ruleset_version: 1,
};
assert!(!p.is_online());
assert!(!p.create_index_concurrent());
assert!(!p.fk_not_valid_then_validate());
assert!(!p.check_not_valid_then_validate());
assert!(!p.not_null_via_check_pattern());
assert!(!p.refresh_mv_concurrently());
assert!(p.view_drop_create_dependents());
}
#[test]
fn online_strategy_respects_individual_switches() {
let p = PlannerPolicy {
strategy: Strategy::Online,
online: OnlineRewrites {
create_index_concurrent: false,
fk_not_valid_then_validate: true,
check_not_valid_then_validate: false,
not_null_via_check_pattern: true,
refresh_mv_concurrently: false,
view_drop_create_dependents: true,
},
planner_ruleset_version: 1,
};
assert!(!p.create_index_concurrent());
assert!(p.fk_not_valid_then_validate());
assert!(!p.check_not_valid_then_validate());
assert!(p.not_null_via_check_pattern());
assert!(!p.refresh_mv_concurrently());
assert!(p.view_drop_create_dependents());
}
#[test]
fn online_with_all_disabled_disables_every_rewrite() {
let p = PlannerPolicy {
strategy: Strategy::Online,
online: OnlineRewrites::all_disabled(),
planner_ruleset_version: 1,
};
assert!(p.is_online());
assert!(!p.create_index_concurrent());
assert!(!p.fk_not_valid_then_validate());
assert!(!p.check_not_valid_then_validate());
assert!(!p.not_null_via_check_pattern());
assert!(!p.refresh_mv_concurrently());
assert!(!p.view_drop_create_dependents());
}
}