use std::net::SocketAddr;
use crate::control::planner::context::QueryContext;
use crate::control::planner::context::query::DEFAULT_SHUFFLE_AGG_THRESHOLD;
use crate::control::state::SharedState;
use crate::types::TenantId;
use super::session::SessionStore;
pub fn parse_bool_session_value(value: &str) -> Option<bool> {
match value.trim().to_ascii_lowercase().as_str() {
"on" | "true" | "t" | "yes" | "y" | "1" => Some(true),
"off" | "false" | "f" | "no" | "n" | "0" => Some(false),
_ => None,
}
}
#[derive(Debug, Clone, Copy)]
pub struct PlanningOverrideFlags {
pub force_shuffle_join: bool,
pub force_shuffle_agg: bool,
pub threshold_overridden: bool,
pub agg_threshold_overridden: bool,
}
impl PlanningOverrideFlags {
pub fn bypass_plan_cache(&self) -> bool {
self.force_shuffle_join
|| self.force_shuffle_agg
|| self.threshold_overridden
|| self.agg_threshold_overridden
}
}
pub fn apply_planning_session_overrides(
query_ctx: &QueryContext,
sessions: &SessionStore,
state: &SharedState,
addr: &SocketAddr,
tenant_id: TenantId,
) -> PlanningOverrideFlags {
{
let tenants = match state.tenants.lock() {
Ok(t) => t,
Err(p) => p.into_inner(),
};
query_ctx.set_max_vector_dim(tenants.quota(tenant_id).max_vector_dim);
}
let force_shuffle_join = sessions
.get_parameter(addr, "nodedb.force_shuffle_join")
.as_deref()
.and_then(parse_bool_session_value)
.unwrap_or(false);
let shuffle_num_parts = sessions
.get_parameter(addr, "nodedb.shuffle_num_parts")
.and_then(|v| v.parse::<u32>().ok())
.unwrap_or(0);
query_ctx.set_force_shuffle_join(force_shuffle_join, shuffle_num_parts);
let force_shuffle_agg = sessions
.get_parameter(addr, "nodedb.force_shuffle_agg")
.as_deref()
.and_then(parse_bool_session_value)
.unwrap_or(false);
let shuffle_agg_num_parts = sessions
.get_parameter(addr, "nodedb.shuffle_agg_num_parts")
.and_then(|v| v.parse::<u32>().ok())
.unwrap_or(0);
query_ctx.set_force_shuffle_agg(force_shuffle_agg, shuffle_agg_num_parts);
let tuning_threshold = state.tuning.cluster_transport.broadcast_threshold_bytes;
let session_threshold = sessions
.get_parameter(addr, "nodedb.broadcast_threshold_bytes")
.and_then(|v| v.parse::<usize>().ok());
let broadcast_threshold_bytes = session_threshold.unwrap_or(tuning_threshold);
query_ctx.set_broadcast_threshold_bytes(broadcast_threshold_bytes);
let session_agg_threshold = sessions
.get_parameter(addr, "nodedb.shuffle_agg_threshold")
.and_then(|v| v.parse::<usize>().ok());
let shuffle_agg_threshold = session_agg_threshold.unwrap_or(DEFAULT_SHUFFLE_AGG_THRESHOLD);
query_ctx.set_shuffle_agg_threshold(shuffle_agg_threshold);
PlanningOverrideFlags {
force_shuffle_join,
force_shuffle_agg,
threshold_overridden: session_threshold.is_some_and(|t| t != tuning_threshold),
agg_threshold_overridden: session_agg_threshold
.is_some_and(|t| t != DEFAULT_SHUFFLE_AGG_THRESHOLD),
}
}