use super::{JoinOrderEnumerator, JoinOrderEnumeratorContext};
use crate::planning::plan::logical::LogicalNodeEnum;
impl JoinOrderEnumerator {
pub(super) fn variable_is_flat(
schema: &crate::planning::plan::factorization::FactorizedSchema,
context: &mut JoinOrderEnumeratorContext,
variable: &str,
) -> bool {
let key = context.join_key(variable);
let id = key.id().clone();
if let Some(pos) = schema.get_group_pos(&id) {
if let Some(group) = schema.get_group(pos) {
return group.is_flat();
}
}
schema
.get_group_pos_by_name_opt(variable)
.and_then(|pos| schema.get_group(pos))
.is_some_and(|g| g.is_flat())
}
pub(super) fn mix_overflow(encoding: u64, salt: u64) -> u64 {
let mut z = encoding
.wrapping_add(0x9e3779b97f4a7c15)
.wrapping_add(salt.wrapping_mul(0xbf58476d1ce4e5b9));
z = (z ^ (z >> 30)).wrapping_mul(0xbf58476d1ce4e5b9);
z = (z ^ (z >> 27)).wrapping_mul(0x94d049bb133111eb);
encoding ^ (z ^ (z >> 31))
}
pub(super) fn compute_schema_for_plan(
plan: &mut LogicalNodeEnum,
) -> Result<
crate::planning::plan::factorization::FactorizedSchema,
crate::planning::plan::factorization::FactorizationError,
> {
use crate::planning::plan::factorization::FactorizedSchemaCompute;
match plan {
LogicalNodeEnum::InnerJoin(n) => {
let mut left = (*n.left).clone();
let mut right = (*n.right).clone();
let left_schema = Self::compute_schema_for_plan(&mut left)?;
let right_schema = Self::compute_schema_for_plan(&mut right)?;
plan.compute_factorized_schema(&[left_schema, right_schema])
}
LogicalNodeEnum::WcoIntersect(n) => {
let mut child_schemas = Vec::with_capacity(n.deps.len());
for dep in n.deps.iter().cloned() {
let mut owned = dep;
child_schemas.push(Self::compute_schema_for_plan(&mut owned)?);
}
plan.compute_factorized_schema(&child_schemas)
}
_ => plan.compute_factorized_schema(&[]),
}
}
}