Simplifies SPARQL algebra functions representation

pull/10/head
Tpt 5 years ago
parent de8997c750
commit c5a03e5584
  1. 469
      lib/src/sparql/algebra.rs
  2. 151
      lib/src/sparql/plan.rs
  3. 116
      lib/src/sparql/sparql_grammar.rustpeg

@ -422,63 +422,9 @@ pub enum Expression {
UnaryPlus(Box<Expression>), UnaryPlus(Box<Expression>),
UnaryMinus(Box<Expression>), UnaryMinus(Box<Expression>),
UnaryNot(Box<Expression>), UnaryNot(Box<Expression>),
StrFunctionCall(Box<Expression>), FunctionCall(Function, Vec<Expression>),
LangFunctionCall(Box<Expression>), Exists(Box<GraphPattern>),
LangMatchesFunctionCall(Box<Expression>, Box<Expression>), Bound(Variable),
DatatypeFunctionCall(Box<Expression>),
BoundFunctionCall(Variable),
IRIFunctionCall(Box<Expression>),
BNodeFunctionCall(Option<Box<Expression>>),
RandFunctionCall(),
AbsFunctionCall(Box<Expression>),
CeilFunctionCall(Box<Expression>),
FloorFunctionCall(Box<Expression>),
RoundFunctionCall(Box<Expression>),
ConcatFunctionCall(Vec<Expression>),
SubStrFunctionCall(Box<Expression>, Box<Expression>, Option<Box<Expression>>),
StrLenFunctionCall(Box<Expression>),
ReplaceFunctionCall(
Box<Expression>,
Box<Expression>,
Box<Expression>,
Option<Box<Expression>>,
),
UCaseFunctionCall(Box<Expression>),
LCaseFunctionCall(Box<Expression>),
EncodeForURIFunctionCall(Box<Expression>),
ContainsFunctionCall(Box<Expression>, Box<Expression>),
StrStartsFunctionCall(Box<Expression>, Box<Expression>),
StrEndsFunctionCall(Box<Expression>, Box<Expression>),
StrBeforeFunctionCall(Box<Expression>, Box<Expression>),
StrAfterFunctionCall(Box<Expression>, Box<Expression>),
YearFunctionCall(Box<Expression>),
MonthFunctionCall(Box<Expression>),
DayFunctionCall(Box<Expression>),
HoursFunctionCall(Box<Expression>),
MinutesFunctionCall(Box<Expression>),
SecondsFunctionCall(Box<Expression>),
TimezoneFunctionCall(Box<Expression>),
TzFunctionCall(Box<Expression>),
NowFunctionCall(),
UUIDFunctionCall(),
StrUUIDFunctionCall(),
MD5FunctionCall(Box<Expression>),
SHA1FunctionCall(Box<Expression>),
SHA256FunctionCall(Box<Expression>),
SHA384FunctionCall(Box<Expression>),
SHA512FunctionCall(Box<Expression>),
CoalesceFunctionCall(Vec<Expression>),
IfFunctionCall(Box<Expression>, Box<Expression>, Box<Expression>),
StrLangFunctionCall(Box<Expression>, Box<Expression>),
StrDTFunctionCall(Box<Expression>, Box<Expression>),
SameTermFunctionCall(Box<Expression>, Box<Expression>),
IsIRIFunctionCall(Box<Expression>),
IsBlankFunctionCall(Box<Expression>),
IsLiteralFunctionCall(Box<Expression>),
IsNumericFunctionCall(Box<Expression>),
RegexFunctionCall(Box<Expression>, Box<Expression>, Option<Box<Expression>>),
CustomFunctionCall(NamedNode, Vec<Expression>),
ExistsFunctionCall(Box<GraphPattern>),
} }
impl fmt::Display for Expression { impl fmt::Display for Expression {
@ -518,96 +464,20 @@ impl fmt::Display for Expression {
Expression::UnaryPlus(e) => write!(f, "+{}", e), Expression::UnaryPlus(e) => write!(f, "+{}", e),
Expression::UnaryMinus(e) => write!(f, "-{}", e), Expression::UnaryMinus(e) => write!(f, "-{}", e),
Expression::UnaryNot(e) => write!(f, "!{}", e), Expression::UnaryNot(e) => write!(f, "!{}", e),
Expression::StrFunctionCall(e) => write!(f, "STR({})", e), Expression::FunctionCall(function, parameters) => {
Expression::LangFunctionCall(e) => write!(f, "LANG({})", e), write!(f, "{}(", function)?;
Expression::LangMatchesFunctionCall(a, b) => write!(f, "LANGMATCHES({}, {})", a, b), let mut cont = false;
Expression::DatatypeFunctionCall(e) => write!(f, "DATATYPE({})", e), for p in parameters {
Expression::BoundFunctionCall(v) => write!(f, "BOUND({})", v), if cont {
Expression::IRIFunctionCall(e) => write!(f, "IRI({})", e), write!(f, ", ")?;
Expression::BNodeFunctionCall(v) => v }
.as_ref() p.fmt(f)?;
.map(|id| write!(f, "BNODE({})", id)) cont = true;
.unwrap_or_else(|| write!(f, "BNODE()")), }
Expression::RandFunctionCall() => write!(f, "RAND()"), write!(f, ")")
Expression::AbsFunctionCall(e) => write!(f, "ABS({})", e), }
Expression::CeilFunctionCall(e) => write!(f, "CEIL({})", e), Expression::Exists(p) => write!(f, "EXISTS {{ {} }}", p),
Expression::FloorFunctionCall(e) => write!(f, "FLOOR({})", e), Expression::Bound(v) => write!(f, "BOUND({})", v),
Expression::RoundFunctionCall(e) => write!(f, "ROUND({})", e),
Expression::ConcatFunctionCall(e) => write!(
f,
"CONCAT({})",
e.iter()
.map(|v| v.to_string())
.collect::<Vec<String>>()
.join(", ")
),
Expression::SubStrFunctionCall(a, b, c) => c
.as_ref()
.map(|cv| write!(f, "SUBSTR({}, {}, {})", a, b, cv))
.unwrap_or_else(|| write!(f, "SUBSTR({}, {})", a, b)),
Expression::StrLenFunctionCall(e) => write!(f, "STRLEN({})", e),
Expression::ReplaceFunctionCall(arg, pattern, replacement, flags) => match flags {
Some(flags) => write!(
f,
"REPLACE({}, {}, {}, {})",
arg, pattern, replacement, flags
),
None => write!(f, "REPLACE({}, {}, {})", arg, pattern, replacement),
},
Expression::UCaseFunctionCall(e) => write!(f, "UCASE({})", e),
Expression::LCaseFunctionCall(e) => write!(f, "LCASE({})", e),
Expression::EncodeForURIFunctionCall(e) => write!(f, "ENCODE_FOR_URI({})", e),
Expression::ContainsFunctionCall(a, b) => write!(f, "CONTAINS({}, {})", a, b),
Expression::StrStartsFunctionCall(a, b) => write!(f, "STRSTATS({}, {})", a, b),
Expression::StrEndsFunctionCall(a, b) => write!(f, "STRENDS({}, {})", a, b),
Expression::StrBeforeFunctionCall(a, b) => write!(f, "STRBEFORE({}, {})", a, b),
Expression::StrAfterFunctionCall(a, b) => write!(f, "STRAFTER({}, {})", a, b),
Expression::YearFunctionCall(e) => write!(f, "YEAR({})", e),
Expression::MonthFunctionCall(e) => write!(f, "MONTH({})", e),
Expression::DayFunctionCall(e) => write!(f, "DAY({})", e),
Expression::HoursFunctionCall(e) => write!(f, "HOURS({})", e),
Expression::MinutesFunctionCall(e) => write!(f, "MINUTES({})", e),
Expression::SecondsFunctionCall(e) => write!(f, "SECONDS({})", e),
Expression::TimezoneFunctionCall(e) => write!(f, "TIMEZONE({})", e),
Expression::TzFunctionCall(e) => write!(f, "TZ({})", e),
Expression::NowFunctionCall() => write!(f, "NOW()"),
Expression::UUIDFunctionCall() => write!(f, "UUID()"),
Expression::StrUUIDFunctionCall() => write!(f, "STRUUID()"),
Expression::MD5FunctionCall(e) => write!(f, "MD5({})", e),
Expression::SHA1FunctionCall(e) => write!(f, "SHA1({})", e),
Expression::SHA256FunctionCall(e) => write!(f, "SHA256({})", e),
Expression::SHA384FunctionCall(e) => write!(f, "SHA384({})", e),
Expression::SHA512FunctionCall(e) => write!(f, "SHA512({})", e),
Expression::CoalesceFunctionCall(e) => write!(
f,
"COALESCE({})",
e.iter()
.map(|v| v.to_string())
.collect::<Vec<String>>()
.join(", ")
),
Expression::IfFunctionCall(a, b, c) => write!(f, "IF({}, {}, {})", a, b, c),
Expression::StrLangFunctionCall(a, b) => write!(f, "STRLANG({}, {})", a, b),
Expression::StrDTFunctionCall(a, b) => write!(f, "STRDT({}, {})", a, b),
Expression::SameTermFunctionCall(a, b) => write!(f, "sameTerm({}, {})", a, b),
Expression::IsIRIFunctionCall(e) => write!(f, "isIRI({})", e),
Expression::IsBlankFunctionCall(e) => write!(f, "isBLANK({})", e),
Expression::IsLiteralFunctionCall(e) => write!(f, "isLITERAL({})", e),
Expression::IsNumericFunctionCall(e) => write!(f, "isNUMERIC({})", e),
Expression::RegexFunctionCall(text, pattern, flags) => match flags {
Some(flags) => write!(f, "REGEX({}, {}, {})", text, pattern, flags),
None => write!(f, "REGEX({}, {})", text, pattern),
},
Expression::CustomFunctionCall(iri, args) => write!(
f,
"{}({})",
iri,
args.iter()
.map(|v| v.to_string())
.collect::<Vec<String>>()
.join(", ")
),
Expression::ExistsFunctionCall(p) => write!(f, "EXISTS {{ {} }}", p),
} }
} }
} }
@ -708,197 +578,136 @@ impl<'a> fmt::Display for SparqlExpression<'a> {
Expression::UnaryPlus(e) => write!(f, "+{}", SparqlExpression(&*e)), Expression::UnaryPlus(e) => write!(f, "+{}", SparqlExpression(&*e)),
Expression::UnaryMinus(e) => write!(f, "-{}", SparqlExpression(&*e)), Expression::UnaryMinus(e) => write!(f, "-{}", SparqlExpression(&*e)),
Expression::UnaryNot(e) => match e.as_ref() { Expression::UnaryNot(e) => match e.as_ref() {
Expression::ExistsFunctionCall(p) => { Expression::Exists(p) => write!(f, "NOT EXISTS {{ {} }}", SparqlGraphPattern(&*p)),
write!(f, "NOT EXISTS {{ {} }}", SparqlGraphPattern(&*p))
}
e => write!(f, "!{}", e), e => write!(f, "!{}", e),
}, },
Expression::StrFunctionCall(e) => write!(f, "STR({})", SparqlExpression(&*e)), Expression::FunctionCall(function, parameters) => {
Expression::LangFunctionCall(e) => write!(f, "LANG({})", SparqlExpression(&*e)), write!(f, "{}(", function)?;
Expression::LangMatchesFunctionCall(a, b) => write!( let mut cont = false;
f, for p in parameters {
"LANGMATCHES({}, {})", if cont {
SparqlExpression(&*a), write!(f, ", ")?;
SparqlExpression(&*b)
),
Expression::DatatypeFunctionCall(e) => write!(f, "DATATYPE({})", SparqlExpression(&*e)),
Expression::BoundFunctionCall(v) => write!(f, "BOUND({})", v),
Expression::IRIFunctionCall(e) => write!(f, "IRI({})", SparqlExpression(&*e)),
Expression::BNodeFunctionCall(v) => v
.as_ref()
.map(|id| write!(f, "BOUND({})", SparqlExpression(&*id)))
.unwrap_or_else(|| write!(f, "BOUND()")),
Expression::RandFunctionCall() => write!(f, "RAND()"),
Expression::AbsFunctionCall(e) => write!(f, "ABS({})", SparqlExpression(&*e)),
Expression::CeilFunctionCall(e) => write!(f, "CEIL({})", SparqlExpression(&*e)),
Expression::FloorFunctionCall(e) => write!(f, "FLOOR({})", SparqlExpression(&*e)),
Expression::RoundFunctionCall(e) => write!(f, "ROUND({})", SparqlExpression(&*e)),
Expression::ConcatFunctionCall(e) => write!(
f,
"CONCAT({})",
e.iter()
.map(|v| SparqlExpression(v).to_string())
.collect::<Vec<String>>()
.join(", ")
),
Expression::SubStrFunctionCall(a, b, c) => c
.as_ref()
.map(|cv| {
write!(
f,
"SUBSTR({}, {}, {})",
SparqlExpression(&*a),
SparqlExpression(&*b),
SparqlExpression(cv)
)
})
.unwrap_or_else(|| {
write!(
f,
"SUBSTR({}, {})",
SparqlExpression(&*a),
SparqlExpression(&*b)
)
}),
Expression::StrLenFunctionCall(e) => write!(f, "STRLEN({})", SparqlExpression(&*e)),
Expression::ReplaceFunctionCall(arg, pattern, replacement, flags) => match flags {
Some(flags) => write!(
f,
"REPLACE({}, {}, {}, {})",
SparqlExpression(&*arg),
SparqlExpression(&*pattern),
SparqlExpression(&*replacement),
flags
),
None => write!(
f,
"REPLACE({}, {}, {})",
SparqlExpression(&*arg),
SparqlExpression(&*pattern),
SparqlExpression(&*replacement)
),
},
Expression::UCaseFunctionCall(e) => write!(f, "UCASE({})", SparqlExpression(&*e)),
Expression::LCaseFunctionCall(e) => write!(f, "LCASE({})", SparqlExpression(&*e)),
Expression::EncodeForURIFunctionCall(e) => {
write!(f, "ENCODE_FOR_URI({})", SparqlExpression(&*e))
} }
Expression::ContainsFunctionCall(a, b) => write!( SparqlExpression(&*p).fmt(f)?;
f, cont = true;
"CONTAINS({}, {})",
SparqlExpression(&*a),
SparqlExpression(&*b)
),
Expression::StrStartsFunctionCall(a, b) => write!(
f,
"STRSTATS({}, {})",
SparqlExpression(&*a),
SparqlExpression(&*b)
),
Expression::StrEndsFunctionCall(a, b) => write!(
f,
"STRENDS({}, {})",
SparqlExpression(&*a),
SparqlExpression(&*b)
),
Expression::StrBeforeFunctionCall(a, b) => write!(
f,
"STRBEFORE({}, {})",
SparqlExpression(&*a),
SparqlExpression(&*b)
),
Expression::StrAfterFunctionCall(a, b) => write!(
f,
"STRAFTER({}, {})",
SparqlExpression(&*a),
SparqlExpression(&*b)
),
Expression::YearFunctionCall(e) => write!(f, "YEAR({})", SparqlExpression(&*e)),
Expression::MonthFunctionCall(e) => write!(f, "MONTH({})", SparqlExpression(&*e)),
Expression::DayFunctionCall(e) => write!(f, "DAY({})", SparqlExpression(&*e)),
Expression::HoursFunctionCall(e) => write!(f, "HOURS({})", SparqlExpression(&*e)),
Expression::MinutesFunctionCall(e) => write!(f, "MINUTES({})", SparqlExpression(&*e)),
Expression::SecondsFunctionCall(e) => write!(f, "SECONDS({})", SparqlExpression(&*e)),
Expression::TimezoneFunctionCall(e) => write!(f, "TIMEZONE({})", SparqlExpression(&*e)),
Expression::TzFunctionCall(e) => write!(f, "TZ({})", SparqlExpression(&*e)),
Expression::NowFunctionCall() => write!(f, "NOW()"),
Expression::UUIDFunctionCall() => write!(f, "UUID()"),
Expression::StrUUIDFunctionCall() => write!(f, "STRUUID()"),
Expression::MD5FunctionCall(e) => write!(f, "MD5({})", SparqlExpression(&*e)),
Expression::SHA1FunctionCall(e) => write!(f, "SHA1({})", SparqlExpression(&*e)),
Expression::SHA256FunctionCall(e) => write!(f, "SHA256({})", SparqlExpression(&*e)),
Expression::SHA384FunctionCall(e) => write!(f, "SHA384({})", SparqlExpression(&*e)),
Expression::SHA512FunctionCall(e) => write!(f, "SHA512({})", SparqlExpression(&*e)),
Expression::CoalesceFunctionCall(e) => write!(
f,
"COALESCE({})",
e.iter()
.map(|v| SparqlExpression(&*v).to_string())
.collect::<Vec<String>>()
.join(", ")
),
Expression::IfFunctionCall(a, b, c) => write!(
f,
"IF({}, {}, {})",
SparqlExpression(&*a),
SparqlExpression(&*b),
SparqlExpression(&*c)
),
Expression::StrLangFunctionCall(a, b) => write!(
f,
"STRLANG({}, {})",
SparqlExpression(&*a),
SparqlExpression(&*b)
),
Expression::StrDTFunctionCall(a, b) => write!(
f,
"STRDT({}, {})",
SparqlExpression(&*a),
SparqlExpression(&*b)
),
Expression::SameTermFunctionCall(a, b) => write!(
f,
"sameTerm({}, {})",
SparqlExpression(&*a),
SparqlExpression(&*b)
),
Expression::IsIRIFunctionCall(e) => write!(f, "isIRI({})", SparqlExpression(&*e)),
Expression::IsBlankFunctionCall(e) => write!(f, "isBLANK({})", SparqlExpression(&*e)),
Expression::IsLiteralFunctionCall(e) => {
write!(f, "isLITERAL({})", SparqlExpression(&*e))
} }
Expression::IsNumericFunctionCall(e) => { write!(f, ")")
write!(f, "isNUMERIC({})", SparqlExpression(&*e))
} }
Expression::RegexFunctionCall(text, pattern, flags) => match flags { Expression::Bound(v) => write!(f, "BOUND({})", v),
Some(flags) => write!( Expression::Exists(p) => write!(f, "EXISTS {{ {} }}", SparqlGraphPattern(&*p)),
f,
"REGEX({}, {}, {})",
SparqlExpression(&*text),
SparqlExpression(&*pattern),
flags
),
None => write!(
f,
"REGEX({}, {})",
SparqlExpression(&*text),
SparqlExpression(&*pattern)
),
},
Expression::CustomFunctionCall(iri, args) => write!(
f,
"{}({})",
iri,
args.iter()
.map(|v| SparqlExpression(v).to_string())
.collect::<Vec<String>>()
.join(", ")
),
Expression::ExistsFunctionCall(p) => {
write!(f, "EXISTS {{ {} }}", SparqlGraphPattern(&*p))
} }
} }
} }
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub enum Function {
Str,
Lang,
LangMatches,
Datatype,
IRI,
BNode,
Rand,
Abs,
Ceil,
Floor,
Round,
Concat,
SubStr,
StrLen,
Replace,
UCase,
LCase,
EncodeForURI,
Contains,
StrStarts,
StrEnds,
StrBefore,
StrAfter,
Year,
Month,
Day,
Hours,
Minutes,
Seconds,
Timezone,
Tz,
Now,
UUID,
StrUUID,
MD5,
SHA1,
SHA256,
SHA384,
SHA512,
Coalesce,
If,
StrLang,
StrDT,
SameTerm,
IsIRI,
IsBlank,
IsLiteral,
IsNumeric,
Regex,
Custom(NamedNode),
}
impl fmt::Display for Function {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Function::Str => write!(f, "STR"),
Function::Lang => write!(f, "LANG"),
Function::LangMatches => write!(f, "LANGMATCHES"),
Function::Datatype => write!(f, "DATATYPE"),
Function::IRI => write!(f, "IRI"),
Function::BNode => write!(f, "BNODE"),
Function::Rand => write!(f, "RAND"),
Function::Abs => write!(f, "ABS"),
Function::Ceil => write!(f, "CEIL"),
Function::Floor => write!(f, "FLOOR"),
Function::Round => write!(f, "ROUND"),
Function::Concat => write!(f, "CONCAT"),
Function::SubStr => write!(f, "SUBSTR"),
Function::StrLen => write!(f, "STRLEN"),
Function::Replace => write!(f, "REPLACE"),
Function::UCase => write!(f, "UCASE"),
Function::LCase => write!(f, "LCASE"),
Function::EncodeForURI => write!(f, "ENCODE_FOR_URI"),
Function::Contains => write!(f, "CONTAINS"),
Function::StrStarts => write!(f, "STRSTATS"),
Function::StrEnds => write!(f, "STRENDS"),
Function::StrBefore => write!(f, "STRBEFORE"),
Function::StrAfter => write!(f, "STRAFTER"),
Function::Year => write!(f, "YEAR"),
Function::Month => write!(f, "MONTH"),
Function::Day => write!(f, "DAY"),
Function::Hours => write!(f, "HOURS"),
Function::Minutes => write!(f, "MINUTES"),
Function::Seconds => write!(f, "SECONDS"),
Function::Timezone => write!(f, "TIMEZONE"),
Function::Tz => write!(f, "TZ"),
Function::Now => write!(f, "NOW"),
Function::UUID => write!(f, "UUID"),
Function::StrUUID => write!(f, "STRUUID"),
Function::MD5 => write!(f, "MD5"),
Function::SHA1 => write!(f, "SHA1"),
Function::SHA256 => write!(f, "SHA256"),
Function::SHA384 => write!(f, "SHA384"),
Function::SHA512 => write!(f, "SHA512"),
Function::Coalesce => write!(f, "COALESCE"),
Function::If => write!(f, "IF"),
Function::StrLang => write!(f, "STRLANG"),
Function::StrDT => write!(f, "STRDT"),
Function::SameTerm => write!(f, "sameTerm"),
Function::IsIRI => write!(f, "isIRI"),
Function::IsBlank => write!(f, "isBLANK"),
Function::IsLiteral => write!(f, "isLITERAL"),
Function::IsNumeric => write!(f, "isNUMERIC"),
Function::Regex => write!(f, "REGEX"),
Function::Custom(iri) => iri.fmt(f),
}
}
} }
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)] #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]

@ -616,84 +616,84 @@ impl<'a, S: EncodedQuadsStore> PlanBuilder<'a, S> {
Expression::UnaryNot(e) => { Expression::UnaryNot(e) => {
PlanExpression::UnaryNot(Box::new(self.build_for_expression(e, variables)?)) PlanExpression::UnaryNot(Box::new(self.build_for_expression(e, variables)?))
} }
Expression::StrFunctionCall(e) => { Expression::FunctionCall(function, parameters) => match function {
PlanExpression::Str(Box::new(self.build_for_expression(e, variables)?)) Function::Str => PlanExpression::Str(Box::new(
} self.build_for_expression(&parameters[0], variables)?,
Expression::LangFunctionCall(e) => { )),
PlanExpression::Lang(Box::new(self.build_for_expression(e, variables)?)) Function::Lang => PlanExpression::Lang(Box::new(
} self.build_for_expression(&parameters[0], variables)?,
Expression::LangMatchesFunctionCall(a, b) => PlanExpression::LangMatches( )),
Box::new(self.build_for_expression(a, variables)?), Function::LangMatches => PlanExpression::LangMatches(
Box::new(self.build_for_expression(b, variables)?), Box::new(self.build_for_expression(&parameters[0], variables)?),
Box::new(self.build_for_expression(&parameters[1], variables)?),
), ),
Expression::DatatypeFunctionCall(e) => { Function::Datatype => PlanExpression::Datatype(Box::new(
PlanExpression::Datatype(Box::new(self.build_for_expression(e, variables)?)) self.build_for_expression(&parameters[0], variables)?,
} )),
Expression::BoundFunctionCall(v) => PlanExpression::Bound(variable_key(variables, v)), Function::IRI => PlanExpression::IRI(Box::new(
Expression::IRIFunctionCall(e) => { self.build_for_expression(&parameters[0], variables)?,
PlanExpression::IRI(Box::new(self.build_for_expression(e, variables)?)) )),
} Function::BNode => PlanExpression::BNode(match parameters.get(0) {
Expression::BNodeFunctionCall(e) => PlanExpression::BNode(match e {
Some(e) => Some(Box::new(self.build_for_expression(e, variables)?)), Some(e) => Some(Box::new(self.build_for_expression(e, variables)?)),
None => None, None => None,
}), }),
Expression::YearFunctionCall(e) => { Function::Year => PlanExpression::Year(Box::new(
PlanExpression::Year(Box::new(self.build_for_expression(e, variables)?)) self.build_for_expression(&parameters[0], variables)?,
} )),
Expression::MonthFunctionCall(e) => { Function::Month => PlanExpression::Month(Box::new(
PlanExpression::Month(Box::new(self.build_for_expression(e, variables)?)) self.build_for_expression(&parameters[0], variables)?,
} )),
Expression::DayFunctionCall(e) => { Function::Day => PlanExpression::Day(Box::new(
PlanExpression::Day(Box::new(self.build_for_expression(e, variables)?)) self.build_for_expression(&parameters[0], variables)?,
} )),
Expression::HoursFunctionCall(e) => { Function::Hours => PlanExpression::Hours(Box::new(
PlanExpression::Hours(Box::new(self.build_for_expression(e, variables)?)) self.build_for_expression(&parameters[0], variables)?,
} )),
Expression::MinutesFunctionCall(e) => { Function::Minutes => PlanExpression::Minutes(Box::new(
PlanExpression::Minutes(Box::new(self.build_for_expression(e, variables)?)) self.build_for_expression(&parameters[0], variables)?,
} )),
Expression::SecondsFunctionCall(e) => { Function::Seconds => PlanExpression::Seconds(Box::new(
PlanExpression::Seconds(Box::new(self.build_for_expression(e, variables)?)) self.build_for_expression(&parameters[0], variables)?,
} )),
Expression::UUIDFunctionCall() => PlanExpression::UUID(), Function::UUID => PlanExpression::UUID(),
Expression::StrUUIDFunctionCall() => PlanExpression::StrUUID(), Function::StrUUID => PlanExpression::StrUUID(),
Expression::CoalesceFunctionCall(l) => { Function::Coalesce => {
PlanExpression::Coalesce(self.expression_list(l, variables)?) PlanExpression::Coalesce(self.expression_list(&parameters, variables)?)
} }
Expression::IfFunctionCall(a, b, c) => PlanExpression::If( Function::If => PlanExpression::If(
Box::new(self.build_for_expression(a, variables)?), Box::new(self.build_for_expression(&parameters[0], variables)?),
Box::new(self.build_for_expression(b, variables)?), Box::new(self.build_for_expression(&parameters[1], variables)?),
Box::new(self.build_for_expression(c, variables)?), Box::new(self.build_for_expression(&parameters[2], variables)?),
), ),
Expression::StrLangFunctionCall(a, b) => PlanExpression::StrLang( Function::StrLang => PlanExpression::StrLang(
Box::new(self.build_for_expression(a, variables)?), Box::new(self.build_for_expression(&parameters[0], variables)?),
Box::new(self.build_for_expression(b, variables)?), Box::new(self.build_for_expression(&parameters[1], variables)?),
), ),
Expression::SameTermFunctionCall(a, b) => PlanExpression::SameTerm( Function::SameTerm => PlanExpression::SameTerm(
Box::new(self.build_for_expression(a, variables)?), Box::new(self.build_for_expression(&parameters[0], variables)?),
Box::new(self.build_for_expression(b, variables)?), Box::new(self.build_for_expression(&parameters[1], variables)?),
), ),
Expression::IsIRIFunctionCall(e) => { Function::IsIRI => PlanExpression::IsIRI(Box::new(
PlanExpression::IsIRI(Box::new(self.build_for_expression(e, variables)?)) self.build_for_expression(&parameters[0], variables)?,
} )),
Expression::IsBlankFunctionCall(e) => { Function::IsBlank => PlanExpression::IsBlank(Box::new(
PlanExpression::IsBlank(Box::new(self.build_for_expression(e, variables)?)) self.build_for_expression(&parameters[0], variables)?,
} )),
Expression::IsLiteralFunctionCall(e) => { Function::IsLiteral => PlanExpression::IsLiteral(Box::new(
PlanExpression::IsLiteral(Box::new(self.build_for_expression(e, variables)?)) self.build_for_expression(&parameters[0], variables)?,
} )),
Expression::IsNumericFunctionCall(e) => { Function::IsNumeric => PlanExpression::IsNumeric(Box::new(
PlanExpression::IsNumeric(Box::new(self.build_for_expression(e, variables)?)) self.build_for_expression(&parameters[0], variables)?,
} )),
Expression::RegexFunctionCall(text, pattern, flags) => PlanExpression::Regex( Function::Regex => PlanExpression::Regex(
Box::new(self.build_for_expression(text, variables)?), Box::new(self.build_for_expression(&parameters[0], variables)?),
Box::new(self.build_for_expression(pattern, variables)?), Box::new(self.build_for_expression(&parameters[1], variables)?),
match flags { match parameters.get(2) {
Some(flags) => Some(Box::new(self.build_for_expression(flags, variables)?)), Some(flags) => Some(Box::new(self.build_for_expression(flags, variables)?)),
None => None, None => None,
}, },
), ),
Expression::CustomFunctionCall(name, parameters) => { Function::Custom(name) => {
if *name == *xsd::BOOLEAN { if *name == *xsd::BOOLEAN {
self.build_cast( self.build_cast(
parameters, parameters,
@ -702,7 +702,12 @@ impl<'a, S: EncodedQuadsStore> PlanBuilder<'a, S> {
"boolean", "boolean",
)? )?
} else if *name == *xsd::DOUBLE { } else if *name == *xsd::DOUBLE {
self.build_cast(parameters, PlanExpression::DoubleCast, variables, "double")? self.build_cast(
parameters,
PlanExpression::DoubleCast,
variables,
"double",
)?
} else if *name == *xsd::FLOAT { } else if *name == *xsd::FLOAT {
self.build_cast(parameters, PlanExpression::FloatCast, variables, "float")? self.build_cast(parameters, PlanExpression::FloatCast, variables, "float")?
} else if *name == *xsd::DECIMAL { } else if *name == *xsd::DECIMAL {
@ -731,12 +736,20 @@ impl<'a, S: EncodedQuadsStore> PlanBuilder<'a, S> {
"dateTime", "dateTime",
)? )?
} else if *name == *xsd::STRING { } else if *name == *xsd::STRING {
self.build_cast(parameters, PlanExpression::StringCast, variables, "string")? self.build_cast(
parameters,
PlanExpression::StringCast,
variables,
"string",
)?
} else { } else {
Err(format_err!("Not supported custom function {}", expression))? Err(format_err!("Not supported custom function {}", expression))?
} }
} }
_ => unimplemented!(), _ => unimplemented!(),
},
Expression::Bound(v) => PlanExpression::Bound(variable_key(variables, v)),
Expression::Exists(_) => unimplemented!(),
}) })
} }

@ -354,7 +354,7 @@ Constraint -> Expression = BrackettedExpression / BuiltInCall / FunctionCall
//[70] //[70]
FunctionCall -> Expression = f: iri _ a: ArgList { FunctionCall -> Expression = f: iri _ a: ArgList {
Expression::CustomFunctionCall(f, a) Expression::FunctionCall(Function::Custom(f), a)
} }
//[71] //[71]
@ -754,81 +754,81 @@ BrackettedExpression -> Expression = '(' _ e:Expression _ ')' { e }
//[121] //[121]
BuiltInCall -> Expression = BuiltInCall -> Expression =
a:Aggregate { state.new_aggregation(a).into() } / a:Aggregate { state.new_aggregation(a).into() } /
"STR"i _ '(' _ e:Expression _ ')' { Expression::StrFunctionCall(Box::new(e)) } / "STR"i _ '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::Str, vec![e]) } /
"LANG"i _ '(' _ e:Expression _ ')' { Expression::LangFunctionCall(Box::new(e)) } / "LANG"i _ '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::Lang, vec![e]) } /
"LANGMATCHES"i _ '(' _ a:Expression _ ',' _ b:Expression _ ')' { Expression::LangMatchesFunctionCall(Box::new(a), Box::new(b)) } / "LANGMATCHES"i _ '(' _ a:Expression _ ',' _ b:Expression _ ')' { Expression::FunctionCall(Function::LangMatches, vec![a, b]) } /
"DATATYPE"i _ '(' _ e:Expression _ ')' { Expression::DatatypeFunctionCall(Box::new(e)) } / "DATATYPE"i _ '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::Datatype, vec![e]) } /
"BOUND"i _ '(' _ v:Var _ ')' { Expression::BoundFunctionCall(v) } / "BOUND"i _ '(' _ v:Var _ ')' { Expression::Bound(v) } /
("IRI"i / "URI"i) _ '(' _ e:Expression _ ')' { Expression::IRIFunctionCall(Box::new(e)) } / ("IRI"i / "URI"i) _ '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::IRI, vec![e]) } /
"BNODE"i '(' _ e:Expression _ ')' { Expression::BNodeFunctionCall(Some(Box::new(e))) } / "BNODE"i '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::BNode, vec![e]) } /
"BNODE"i NIL { Expression::BNodeFunctionCall(None) } / "BNODE"i NIL { Expression::FunctionCall(Function::BNode, vec![]) } /
"RAND"i _ NIL { Expression::RandFunctionCall() } / "RAND"i _ NIL { Expression::FunctionCall(Function::Rand, vec![]) } /
"ABS"i _ '(' _ e:Expression _ ')' { Expression::AbsFunctionCall(Box::new(e)) } / "ABS"i _ '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::Abs, vec![e]) } /
"CEIL"i _ '(' _ e:Expression _ ')' { Expression::CeilFunctionCall(Box::new(e)) } / "CEIL"i _ '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::Ceil, vec![e]) } /
"FLOOR"i _ '(' _ e:Expression _ ')' { Expression::FloorFunctionCall(Box::new(e)) } / "FLOOR"i _ '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::Floor, vec![e]) } /
"ROUND"i _ '(' _ e:Expression _ ')' { Expression::RoundFunctionCall(Box::new(e)) } / "ROUND"i _ '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::Round, vec![e]) } /
"CONCAT"i e:ExpressionList { Expression::ConcatFunctionCall(e) } / "CONCAT"i e:ExpressionList { Expression::FunctionCall(Function::Concat, e) } /
SubstringExpression / SubstringExpression /
"STRLEN"i _ '(' _ e: Expression _ ')' { Expression::StrLenFunctionCall(Box::new(e)) } / "STRLEN"i _ '(' _ e: Expression _ ')' { Expression::FunctionCall(Function::StrLen, vec![e]) } /
StrReplaceExpression / StrReplaceExpression /
"UCASE"i _ '(' _ e:Expression _ ')' { Expression::UCaseFunctionCall(Box::new(e)) } / "UCASE"i _ '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::UCase, vec![e]) } /
"LCASE"i _ '(' _ e:Expression _ ')' { Expression::LCaseFunctionCall(Box::new(e)) } / "LCASE"i _ '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::LCase, vec![e]) } /
'ENCODE_FOR_URI' '(' _ e: Expression _ ')' { Expression::EncodeForURIFunctionCall(Box::new(e)) } / 'ENCODE_FOR_URI' '(' _ e: Expression _ ')' { Expression::FunctionCall(Function::EncodeForURI, vec![e]) } /
"CONTAINS"i _ '(' _ a:Expression _ ',' _ b:Expression _ ')' { Expression::ContainsFunctionCall(Box::new(a), Box::new(b)) } / "CONTAINS"i _ '(' _ a:Expression _ ',' _ b:Expression _ ')' { Expression::FunctionCall(Function::Contains, vec![a, b]) } /
"STRSTARTS"i _ '(' _ a:Expression _ ',' _ b:Expression _ ')' { Expression::StrStartsFunctionCall(Box::new(a), Box::new(b)) } / "STRSTARTS"i _ '(' _ a:Expression _ ',' _ b:Expression _ ')' { Expression::FunctionCall(Function::StrStarts, vec![a, b]) } /
"STRENDS"i _ '(' _ a:Expression _ ',' _ b:Expression _ ')' { Expression::StrEndsFunctionCall(Box::new(a), Box::new(b)) } / "STRENDS"i _ '(' _ a:Expression _ ',' _ b:Expression _ ')' { Expression::FunctionCall(Function::StrEnds, vec![a, b]) } /
"STRBEFORE"i _ '(' _ a:Expression _ ',' _ b:Expression _ ')' { Expression::StrBeforeFunctionCall(Box::new(a), Box::new(b)) } / "STRBEFORE"i _ '(' _ a:Expression _ ',' _ b:Expression _ ')' { Expression::FunctionCall(Function::StrBefore, vec![a, b]) } /
"STRAFTER"i _ '(' _ a:Expression _ ',' _ b:Expression _ ')' { Expression::StrAfterFunctionCall(Box::new(a), Box::new(b)) } / "STRAFTER"i _ '(' _ a:Expression _ ',' _ b:Expression _ ')' { Expression::FunctionCall(Function::StrAfter, vec![a, b]) } /
"YEAR"i _ '(' _ e:Expression _ ')' { Expression::YearFunctionCall(Box::new(e)) } / "YEAR"i _ '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::Year, vec![e]) } /
"MONTH"i _ '(' _ e:Expression _ ')' { Expression::MonthFunctionCall(Box::new(e)) } / "MONTH"i _ '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::Month, vec![e]) } /
"DAY"i _ '(' _ e:Expression _ ')' { Expression::DayFunctionCall(Box::new(e)) } / "DAY"i _ '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::Day, vec![e]) } /
"HOURS"i _ '(' _ e:Expression _ ')' { Expression::HoursFunctionCall(Box::new(e)) } / "HOURS"i _ '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::Hours, vec![e]) } /
"MINUTES"i _ '(' _ e:Expression _ ')' { Expression::MinutesFunctionCall(Box::new(e)) } / "MINUTES"i _ '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::Minutes, vec![e]) } /
"SECONDS"i _ '(' _ e:Expression _ ')' { Expression::SecondsFunctionCall(Box::new(e)) } / "SECONDS"i _ '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::Seconds, vec![e]) } /
"TIMEZONE"i _ '(' _ e:Expression _ ')' { Expression::TimezoneFunctionCall(Box::new(e)) } / "TIMEZONE"i _ '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::Timezone, vec![e]) } /
"TZ"i _ '(' _ e:Expression _ ')' { Expression::TzFunctionCall(Box::new(e)) } / "TZ"i _ '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::Tz, vec![e]) } /
"NOW"i _ NIL { Expression::NowFunctionCall() } / "NOW"i _ NIL { Expression::FunctionCall(Function::Now, vec![]) } /
"UUID"i _ NIL { Expression::UUIDFunctionCall() }/ "UUID"i _ NIL { Expression::FunctionCall(Function::UUID, vec![]) }/
"STRUUID"i _ NIL { Expression::StrUUIDFunctionCall() } / "STRUUID"i _ NIL { Expression::FunctionCall(Function::StrUUID, vec![]) } /
"MD5"i '(' _ e:Expression _ ')' { Expression::MD5FunctionCall(Box::new(e)) } / "MD5"i '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::MD5, vec![e]) } /
"SHA1"i '(' _ e:Expression _ ')' { Expression::SHA1FunctionCall(Box::new(e)) } / "SHA1"i '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::SHA1, vec![e]) } /
"SHA256"i '(' _ e:Expression _ ')' { Expression::SHA256FunctionCall(Box::new(e)) } / "SHA256"i '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::SHA256, vec![e]) } /
"SHA384"i '(' _ e:Expression _ ')' { Expression::SHA384FunctionCall(Box::new(e)) } / "SHA384"i '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::SHA384, vec![e]) } /
"SHA512"i '(' _ e:Expression _ ')' { Expression::SHA512FunctionCall(Box::new(e)) } / "SHA512"i '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::SHA512, vec![e]) } /
"COALESCE"i e:ExpressionList { Expression::CoalesceFunctionCall(e) } / "COALESCE"i e:ExpressionList { Expression::FunctionCall(Function::Coalesce, e) } /
"IF"i _ '(' _ a:Expression _ ',' _ b:Expression _ ',' _ c:Expression _ ')' { Expression::IfFunctionCall(Box::new(a), Box::new(b), Box::new(c)) } / "IF"i _ '(' _ a:Expression _ ',' _ b:Expression _ ',' _ c:Expression _ ')' { Expression::FunctionCall(Function::If, vec![a, b, c]) } /
"STRLANG"i _ '(' _ a:Expression _ ',' _ b:Expression _ ')' { Expression::StrLangFunctionCall(Box::new(a), Box::new(b)) } / "STRLANG"i _ '(' _ a:Expression _ ',' _ b:Expression _ ')' { Expression::FunctionCall(Function::StrLang, vec![a, b]) } /
"STRDT"i _ '(' _ a:Expression _ ',' _ b:Expression _ ')' { Expression::StrDTFunctionCall(Box::new(a), Box::new(b)) } / "STRDT"i _ '(' _ a:Expression _ ',' _ b:Expression _ ')' { Expression::FunctionCall(Function::StrDT, vec![a, b]) } /
"sameTerm"i '(' _ a:Expression _ ',' _ b:Expression _ ')' { Expression::SameTermFunctionCall(Box::new(a), Box::new(b)) } / "sameTerm"i '(' _ a:Expression _ ',' _ b:Expression _ ')' { Expression::FunctionCall(Function::SameTerm, vec![a, b]) } /
("isIRI"i / "isURI"i) _ '(' _ e:Expression _ ')' { Expression::IsIRIFunctionCall(Box::new(e)) } / ("isIRI"i / "isURI"i) _ '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::IsIRI, vec![e]) } /
"isBLANK"i '(' _ e:Expression _ ')' { Expression::IsBlankFunctionCall(Box::new(e)) } / "isBLANK"i '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::IsBlank, vec![e]) } /
"isLITERAL"i '(' _ e:Expression _ ')' { Expression::IsLiteralFunctionCall(Box::new(e)) } / "isLITERAL"i '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::IsLiteral, vec![e]) } /
"isNUMERIC"i '(' _ e:Expression _ ')' { Expression::IsNumericFunctionCall(Box::new(e)) } / "isNUMERIC"i '(' _ e:Expression _ ')' { Expression::FunctionCall(Function::IsNumeric, vec![e]) } /
RegexExpression / RegexExpression /
ExistsFunc / ExistsFunc /
NotExistsFunc NotExistsFunc
//[122] //[122]
RegexExpression -> Expression = RegexExpression -> Expression =
"REGEX"i _ '(' _ a:Expression _ ',' _ b:Expression _ ',' _ c:Expression _ ')' { Expression::RegexFunctionCall(Box::new(a), Box::new(b), Some(Box::new(c))) } / "REGEX"i _ '(' _ a:Expression _ ',' _ b:Expression _ ',' _ c:Expression _ ')' { Expression::FunctionCall(Function::Regex, vec![a, b, c]) } /
"REGEX"i _ '(' _ a:Expression _ ',' _ b:Expression _ ')' { Expression::RegexFunctionCall(Box::new(a), Box::new(b), None) } "REGEX"i _ '(' _ a:Expression _ ',' _ b:Expression _ ')' { Expression::FunctionCall(Function::Regex, vec![a, b]) }
SubstringExpression -> Expression = SubstringExpression -> Expression =
"SUBSTR"i _ '(' _ a:Expression _ ',' _ b:Expression _ ',' _ c:Expression _ ')' { Expression::SubStrFunctionCall(Box::new(a), Box::new(b), Some(Box::new(c))) } / "SUBSTR"i _ '(' _ a:Expression _ ',' _ b:Expression _ ',' _ c:Expression _ ')' { Expression::FunctionCall(Function::SubStr, vec![a, b, c]) } /
"SUBSTR"i _ '(' _ a:Expression _ ',' _ b:Expression _ ')' { Expression::SubStrFunctionCall(Box::new(a), Box::new(b), None) } "SUBSTR"i _ '(' _ a:Expression _ ',' _ b:Expression _ ')' { Expression::FunctionCall(Function::SubStr, vec![a, b]) }
//[124] //[124]
StrReplaceExpression -> Expression = StrReplaceExpression -> Expression =
"REPLACE"i _ '(' _ a:Expression _ ',' _ b:Expression _ ',' _ c:Expression _ ',' _ d:Expression _ ')' { Expression::ReplaceFunctionCall(Box::new(a), Box::new(b), Box::new(c), Some(Box::new(d))) } / "REPLACE"i _ '(' _ a:Expression _ ',' _ b:Expression _ ',' _ c:Expression _ ',' _ d:Expression _ ')' { Expression::FunctionCall(Function::Replace, vec![a, b, c, d]) } /
"REPLACE"i _ '(' _ a:Expression _ ',' _ b:Expression _ ',' _ c:Expression _ ')' { Expression::ReplaceFunctionCall(Box::new(a), Box::new(b), Box::new(c), None) } "REPLACE"i _ '(' _ a:Expression _ ',' _ b:Expression _ ',' _ c:Expression _ ')' { Expression::FunctionCall(Function::Replace, vec![a, b, c]) }
//[125] //[125]
ExistsFunc -> Expression = "EXISTS"i _ p:GroupGraphPattern { Expression::ExistsFunctionCall(Box::new(p)) } ExistsFunc -> Expression = "EXISTS"i _ p:GroupGraphPattern { Expression::Exists(Box::new(p)) }
//[126] //[126]
NotExistsFunc -> Expression = "NOT"i _ "EXISTS"i _ p:GroupGraphPattern { Expression::UnaryNot(Box::new(Expression::ExistsFunctionCall(Box::new(p)))) } NotExistsFunc -> Expression = "NOT"i _ "EXISTS"i _ p:GroupGraphPattern { Expression::UnaryNot(Box::new(Expression::Exists(Box::new(p)))) }
//[127] //[127]
Aggregate -> Aggregation = Aggregate -> Aggregation =
@ -854,7 +854,7 @@ Aggregate -> Aggregation =
//[128] //[128]
iriOrFunction -> Expression = i: iri _ a: ArgList? { iriOrFunction -> Expression = i: iri _ a: ArgList? {
match a { match a {
Some(a) => Expression::CustomFunctionCall(i, a), Some(a) => Expression::FunctionCall(Function::Custom(i), a),
None => Expression::Constant(i.into()) None => Expression::Constant(i.into())
} }
} }

Loading…
Cancel
Save