Optimizer: Use "(a == b) || (a == c)" instead of "a IN (b, c)"

rules
Tpt 2 years ago
parent ee90363898
commit d2d98e09e8
  1. 28
      lib/sparopt/src/algebra.rs
  2. 5
      lib/sparopt/src/optimizer.rs
  3. 38
      lib/src/sparql/plan_builder.rs

@ -35,8 +35,6 @@ pub enum Expression {
/// [op:numeric-less-than](https://www.w3.org/TR/xpath-functions/#func-numeric-less-than) and other XSD greater than operators.
Less(Box<Self>, Box<Self>),
LessOrEqual(Box<Self>, Box<Self>),
/// [IN](https://www.w3.org/TR/sparql11-query/#func-in)
In(Box<Self>, Vec<Self>),
/// [op:numeric-add](https://www.w3.org/TR/xpath-functions/#func-numeric-add) and other XSD additions.
Add(Box<Self>, Box<Self>),
/// [op:numeric-subtract](https://www.w3.org/TR/xpath-functions/#func-numeric-subtract) and other XSD subtractions.
@ -122,13 +120,19 @@ impl Expression {
Box::new(Self::from_sparql_algebra(left, graph_name)),
Box::new(Self::from_sparql_algebra(right, graph_name)),
),
AlExpression::In(left, right) => Self::In(
Box::new(Self::from_sparql_algebra(left, graph_name)),
AlExpression::In(left, right) => {
let left = Self::from_sparql_algebra(left, graph_name);
right
.iter()
.map(|e| Self::from_sparql_algebra(e, graph_name))
.collect(),
),
.map(|e| {
Self::Equal(
Box::new(left.clone()),
Box::new(Self::from_sparql_algebra(e, graph_name)),
)
})
.reduce(|a, b| Self::Or(Box::new(a), Box::new(b)))
.unwrap_or_else(|| false.into())
}
AlExpression::Add(left, right) => Self::Add(
Box::new(Self::from_sparql_algebra(left, graph_name)),
Box::new(Self::from_sparql_algebra(right, graph_name)),
@ -311,10 +315,6 @@ impl From<&Expression> for AlExpression {
Box::new(left.as_ref().into()),
Box::new(right.as_ref().into()),
),
Expression::In(left, right) => Self::In(
Box::new(left.as_ref().into()),
right.iter().map(|e| e.into()).collect(),
),
Expression::Add(left, right) => Self::Add(
Box::new(left.as_ref().into()),
Box::new(right.as_ref().into()),
@ -1332,8 +1332,6 @@ pub enum FixedPointExpression {
And(Box<Self>, Box<Self>),
/// [sameTerm](https://www.w3.org/TR/sparql11-query/#func-sameTerm).
SameTerm(Box<Self>, Box<Self>),
/// [IN](https://www.w3.org/TR/sparql11-query/#func-in)
In(Box<Self>, Vec<Self>),
/// [fn:not](https://www.w3.org/TR/xpath-functions/#func-not).
Not(Box<Self>),
/// A regular function call.
@ -1449,10 +1447,6 @@ impl From<FixedPointExpression> for Expression {
FixedPointExpression::SameTerm(left, right) => {
Self::SameTerm(Box::new((*left).into()), Box::new((*right).into()))
}
FixedPointExpression::In(left, right) => Self::In(
Box::new((*left).into()),
right.into_iter().map(Into::into).collect(),
),
FixedPointExpression::Not(inner) => Self::Not(Box::new((*inner).into())),
FixedPointExpression::FunctionCall(name, args) => {
Self::FunctionCall(name, args.into_iter().map(Into::into).collect())

@ -175,11 +175,6 @@ impl Optimizer {
let right = Self::normalize_expression(*right);
Expression::LessOrEqual(Box::new(left), Box::new(right))
}
Expression::In(left, right) => {
let left = Self::normalize_expression(*left);
let right = right.into_iter().map(Self::normalize_expression).collect();
Expression::In(Box::new(left), right)
}
Expression::Add(left, right) => {
let left = Self::normalize_expression(*left);
let right = Self::normalize_expression(*right);

@ -657,25 +657,6 @@ impl<'a> PlanBuilder<'a> {
Box::new(self.build_for_expression(a, variables)?),
Box::new(self.build_for_expression(b, variables)?),
),
Expression::In(e, l) => {
let e = self.build_for_expression(e, variables)?;
l.iter()
.map(|v| {
Ok(PlanExpression::Equal(
Box::new(e.clone()),
Box::new(self.build_for_expression(v, variables)?),
))
})
.reduce(|a: Result<_, EvaluationError>, b| {
Ok(PlanExpression::Or(Box::new(a?), Box::new(b?)))
})
.unwrap_or_else(|| {
Ok(PlanExpression::Literal(PlanTerm {
encoded: false.into(),
plain: false.into(),
}))
})?
}
Expression::Add(a, b) => PlanExpression::Add(
Box::new(self.build_for_expression(a, variables)?),
Box::new(self.build_for_expression(b, variables)?),
@ -1035,25 +1016,6 @@ impl<'a> PlanBuilder<'a> {
Box::new(self.build_for_fixed_point_expression(a, variables)?),
Box::new(self.build_for_fixed_point_expression(b, variables)?),
),
FixedPointExpression::In(e, l) => {
let e = self.build_for_fixed_point_expression(e, variables)?;
l.iter()
.map(|v| {
Ok(PlanExpression::Equal(
Box::new(e.clone()),
Box::new(self.build_for_fixed_point_expression(v, variables)?),
))
})
.reduce(|a: Result<_, EvaluationError>, b| {
Ok(PlanExpression::Or(Box::new(a?), Box::new(b?)))
})
.unwrap_or_else(|| {
Ok(PlanExpression::Literal(PlanTerm {
encoded: false.into(),
plain: false.into(),
}))
})?
}
FixedPointExpression::Not(e) => PlanExpression::Not(Box::new(
self.build_for_fixed_point_expression(e, variables)?,
)),

Loading…
Cancel
Save