use pgwire::error::PgWireResult;
use crate::control::security::deny::{self, DenyMode};
use crate::control::security::predicate::RlsPredicate;
use crate::control::security::predicate_parser::{parse_predicate, validate_auth_refs};
use super::super::super::types::sqlstate_error;
pub struct CompiledPredicate {
pub compiled_predicate: Option<RlsPredicate>,
pub on_deny: DenyMode,
}
pub fn compile_rls_predicate(
predicate_str: &str,
on_deny_raw: Option<&str>,
) -> PgWireResult<CompiledPredicate> {
let compiled = parse_predicate(predicate_str)
.map_err(|e| sqlstate_error("42601", &format!("predicate parse error: {e}")))?;
validate_auth_refs(&compiled).map_err(|e| sqlstate_error("42601", &e.to_string()))?;
let on_deny = if let Some(deny_text) = on_deny_raw {
let deny_parts: Vec<&str> = deny_text.split_whitespace().collect();
let slice = if deny_parts
.first()
.map(|s| s.eq_ignore_ascii_case("DENY"))
.unwrap_or(false)
{
&deny_parts[1..]
} else {
&deny_parts[..]
};
deny::parse_on_deny(slice).map_err(|e| sqlstate_error("42601", &e.to_string()))?
} else {
DenyMode::default()
};
Ok(CompiledPredicate {
compiled_predicate: Some(compiled),
on_deny,
})
}