mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-20 15:35:29 +01:00
rename check_constant() to less confusing name
This commit is contained in:
@@ -479,7 +479,7 @@ fn rewrite_exprs_update(plan: &mut UpdatePlan) -> Result<()> {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ConstantPredicate {
|
||||
pub enum AlwaysTrueOrFalse {
|
||||
AlwaysTrue,
|
||||
AlwaysFalse,
|
||||
}
|
||||
@@ -489,17 +489,18 @@ pub enum ConstantPredicate {
|
||||
Implemented for ast::Expr
|
||||
*/
|
||||
pub trait Optimizable {
|
||||
// if the expression is a constant expression e.g. '1', returns the constant condition
|
||||
fn check_constant(&self) -> Result<Option<ConstantPredicate>>;
|
||||
// if the expression is a constant expression that, when evaluated as a condition, is always true or false
|
||||
// return a [ConstantPredicate].
|
||||
fn check_always_true_or_false(&self) -> Result<Option<AlwaysTrueOrFalse>>;
|
||||
fn is_always_true(&self) -> Result<bool> {
|
||||
Ok(self
|
||||
.check_constant()?
|
||||
.map_or(false, |c| c == ConstantPredicate::AlwaysTrue))
|
||||
.check_always_true_or_false()?
|
||||
.map_or(false, |c| c == AlwaysTrueOrFalse::AlwaysTrue))
|
||||
}
|
||||
fn is_always_false(&self) -> Result<bool> {
|
||||
Ok(self
|
||||
.check_constant()?
|
||||
.map_or(false, |c| c == ConstantPredicate::AlwaysFalse))
|
||||
.check_always_true_or_false()?
|
||||
.map_or(false, |c| c == AlwaysTrueOrFalse::AlwaysFalse))
|
||||
}
|
||||
fn is_rowid_alias_of(&self, table_index: usize) -> bool;
|
||||
fn is_nonnull(&self, tables: &[TableReference]) -> bool;
|
||||
@@ -599,22 +600,23 @@ impl Optimizable for ast::Expr {
|
||||
Expr::Variable(..) => false,
|
||||
}
|
||||
}
|
||||
fn check_constant(&self) -> Result<Option<ConstantPredicate>> {
|
||||
/// Returns true if the expression is a constant expression that, when evaluated as a condition, is always true or false
|
||||
fn check_always_true_or_false(&self) -> Result<Option<AlwaysTrueOrFalse>> {
|
||||
match self {
|
||||
Self::Literal(lit) => match lit {
|
||||
ast::Literal::Numeric(b) => {
|
||||
if let Ok(int_value) = b.parse::<i64>() {
|
||||
return Ok(Some(if int_value == 0 {
|
||||
ConstantPredicate::AlwaysFalse
|
||||
AlwaysTrueOrFalse::AlwaysFalse
|
||||
} else {
|
||||
ConstantPredicate::AlwaysTrue
|
||||
AlwaysTrueOrFalse::AlwaysTrue
|
||||
}));
|
||||
}
|
||||
if let Ok(float_value) = b.parse::<f64>() {
|
||||
return Ok(Some(if float_value == 0.0 {
|
||||
ConstantPredicate::AlwaysFalse
|
||||
AlwaysTrueOrFalse::AlwaysFalse
|
||||
} else {
|
||||
ConstantPredicate::AlwaysTrue
|
||||
AlwaysTrueOrFalse::AlwaysTrue
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -624,35 +626,35 @@ impl Optimizable for ast::Expr {
|
||||
let without_quotes = s.trim_matches('\'');
|
||||
if let Ok(int_value) = without_quotes.parse::<i64>() {
|
||||
return Ok(Some(if int_value == 0 {
|
||||
ConstantPredicate::AlwaysFalse
|
||||
AlwaysTrueOrFalse::AlwaysFalse
|
||||
} else {
|
||||
ConstantPredicate::AlwaysTrue
|
||||
AlwaysTrueOrFalse::AlwaysTrue
|
||||
}));
|
||||
}
|
||||
|
||||
if let Ok(float_value) = without_quotes.parse::<f64>() {
|
||||
return Ok(Some(if float_value == 0.0 {
|
||||
ConstantPredicate::AlwaysFalse
|
||||
AlwaysTrueOrFalse::AlwaysFalse
|
||||
} else {
|
||||
ConstantPredicate::AlwaysTrue
|
||||
AlwaysTrueOrFalse::AlwaysTrue
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(Some(ConstantPredicate::AlwaysFalse))
|
||||
Ok(Some(AlwaysTrueOrFalse::AlwaysFalse))
|
||||
}
|
||||
_ => Ok(None),
|
||||
},
|
||||
Self::Unary(op, expr) => {
|
||||
if *op == ast::UnaryOperator::Not {
|
||||
let trivial = expr.check_constant()?;
|
||||
let trivial = expr.check_always_true_or_false()?;
|
||||
return Ok(trivial.map(|t| match t {
|
||||
ConstantPredicate::AlwaysTrue => ConstantPredicate::AlwaysFalse,
|
||||
ConstantPredicate::AlwaysFalse => ConstantPredicate::AlwaysTrue,
|
||||
AlwaysTrueOrFalse::AlwaysTrue => AlwaysTrueOrFalse::AlwaysFalse,
|
||||
AlwaysTrueOrFalse::AlwaysFalse => AlwaysTrueOrFalse::AlwaysTrue,
|
||||
}));
|
||||
}
|
||||
|
||||
if *op == ast::UnaryOperator::Negative {
|
||||
let trivial = expr.check_constant()?;
|
||||
let trivial = expr.check_always_true_or_false()?;
|
||||
return Ok(trivial);
|
||||
}
|
||||
|
||||
@@ -661,50 +663,50 @@ impl Optimizable for ast::Expr {
|
||||
Self::InList { lhs: _, not, rhs } => {
|
||||
if rhs.is_none() {
|
||||
return Ok(Some(if *not {
|
||||
ConstantPredicate::AlwaysTrue
|
||||
AlwaysTrueOrFalse::AlwaysTrue
|
||||
} else {
|
||||
ConstantPredicate::AlwaysFalse
|
||||
AlwaysTrueOrFalse::AlwaysFalse
|
||||
}));
|
||||
}
|
||||
let rhs = rhs.as_ref().unwrap();
|
||||
if rhs.is_empty() {
|
||||
return Ok(Some(if *not {
|
||||
ConstantPredicate::AlwaysTrue
|
||||
AlwaysTrueOrFalse::AlwaysTrue
|
||||
} else {
|
||||
ConstantPredicate::AlwaysFalse
|
||||
AlwaysTrueOrFalse::AlwaysFalse
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
Self::Binary(lhs, op, rhs) => {
|
||||
let lhs_trivial = lhs.check_constant()?;
|
||||
let rhs_trivial = rhs.check_constant()?;
|
||||
let lhs_trivial = lhs.check_always_true_or_false()?;
|
||||
let rhs_trivial = rhs.check_always_true_or_false()?;
|
||||
match op {
|
||||
ast::Operator::And => {
|
||||
if lhs_trivial == Some(ConstantPredicate::AlwaysFalse)
|
||||
|| rhs_trivial == Some(ConstantPredicate::AlwaysFalse)
|
||||
if lhs_trivial == Some(AlwaysTrueOrFalse::AlwaysFalse)
|
||||
|| rhs_trivial == Some(AlwaysTrueOrFalse::AlwaysFalse)
|
||||
{
|
||||
return Ok(Some(ConstantPredicate::AlwaysFalse));
|
||||
return Ok(Some(AlwaysTrueOrFalse::AlwaysFalse));
|
||||
}
|
||||
if lhs_trivial == Some(ConstantPredicate::AlwaysTrue)
|
||||
&& rhs_trivial == Some(ConstantPredicate::AlwaysTrue)
|
||||
if lhs_trivial == Some(AlwaysTrueOrFalse::AlwaysTrue)
|
||||
&& rhs_trivial == Some(AlwaysTrueOrFalse::AlwaysTrue)
|
||||
{
|
||||
return Ok(Some(ConstantPredicate::AlwaysTrue));
|
||||
return Ok(Some(AlwaysTrueOrFalse::AlwaysTrue));
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
ast::Operator::Or => {
|
||||
if lhs_trivial == Some(ConstantPredicate::AlwaysTrue)
|
||||
|| rhs_trivial == Some(ConstantPredicate::AlwaysTrue)
|
||||
if lhs_trivial == Some(AlwaysTrueOrFalse::AlwaysTrue)
|
||||
|| rhs_trivial == Some(AlwaysTrueOrFalse::AlwaysTrue)
|
||||
{
|
||||
return Ok(Some(ConstantPredicate::AlwaysTrue));
|
||||
return Ok(Some(AlwaysTrueOrFalse::AlwaysTrue));
|
||||
}
|
||||
if lhs_trivial == Some(ConstantPredicate::AlwaysFalse)
|
||||
&& rhs_trivial == Some(ConstantPredicate::AlwaysFalse)
|
||||
if lhs_trivial == Some(AlwaysTrueOrFalse::AlwaysFalse)
|
||||
&& rhs_trivial == Some(AlwaysTrueOrFalse::AlwaysFalse)
|
||||
{
|
||||
return Ok(Some(ConstantPredicate::AlwaysFalse));
|
||||
return Ok(Some(AlwaysTrueOrFalse::AlwaysFalse));
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
|
||||
Reference in New Issue
Block a user