Part 3: have table_for_places return a Result, not an Option.
This commit is contained in:
parent
01ca0ae5c1
commit
ce3c4f0dca
1 changed files with 21 additions and 21 deletions
|
@ -430,31 +430,31 @@ impl ConjoiningClauses {
|
||||||
schema.get_entid(&ident)
|
schema.get_entid(&ident)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn table_for_attribute_and_value<'s, 'a>(&self, attribute: &'s Attribute, value: &'a PatternValuePlace) -> Option<DatomsTable> {
|
fn table_for_attribute_and_value<'s, 'a>(&self, attribute: &'s Attribute, value: &'a PatternValuePlace) -> ::std::result::Result<DatomsTable, EmptyBecause> {
|
||||||
if attribute.fulltext {
|
if attribute.fulltext {
|
||||||
match value {
|
match value {
|
||||||
&PatternValuePlace::Placeholder =>
|
&PatternValuePlace::Placeholder =>
|
||||||
Some(DatomsTable::Datoms), // We don't need the value.
|
Ok(DatomsTable::Datoms), // We don't need the value.
|
||||||
|
|
||||||
// TODO: an existing non-string binding can cause this pattern to fail.
|
// TODO: an existing non-string binding can cause this pattern to fail.
|
||||||
&PatternValuePlace::Variable(_) =>
|
&PatternValuePlace::Variable(_) =>
|
||||||
Some(DatomsTable::AllDatoms),
|
Ok(DatomsTable::AllDatoms),
|
||||||
|
|
||||||
&PatternValuePlace::Constant(NonIntegerConstant::Text(_)) =>
|
&PatternValuePlace::Constant(NonIntegerConstant::Text(_)) =>
|
||||||
Some(DatomsTable::AllDatoms),
|
Ok(DatomsTable::AllDatoms),
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
// We can't succeed if there's a non-string constant value for a fulltext
|
// We can't succeed if there's a non-string constant value for a fulltext
|
||||||
// field.
|
// field.
|
||||||
None
|
Err(EmptyBecause::NonStringFulltextValue)
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Some(DatomsTable::Datoms)
|
Ok(DatomsTable::Datoms)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn table_for_unknown_attribute<'s, 'a>(&self, value: &'a PatternValuePlace) -> Option<DatomsTable> {
|
fn table_for_unknown_attribute<'s, 'a>(&self, value: &'a PatternValuePlace) -> ::std::result::Result<DatomsTable, EmptyBecause> {
|
||||||
// If the value is known to be non-textual, we can simply use the regular datoms
|
// If the value is known to be non-textual, we can simply use the regular datoms
|
||||||
// table (TODO: and exclude on `index_fulltext`!).
|
// table (TODO: and exclude on `index_fulltext`!).
|
||||||
//
|
//
|
||||||
|
@ -463,7 +463,7 @@ impl ConjoiningClauses {
|
||||||
//
|
//
|
||||||
// If the value is a variable or string, we must use `all_datoms`, or do the join
|
// If the value is a variable or string, we must use `all_datoms`, or do the join
|
||||||
// ourselves, because we'll need to either extract or compare on the string.
|
// ourselves, because we'll need to either extract or compare on the string.
|
||||||
Some(
|
Ok(
|
||||||
match value {
|
match value {
|
||||||
// TODO: see if the variable is projected, aggregated, or compared elsewhere in
|
// TODO: see if the variable is projected, aggregated, or compared elsewhere in
|
||||||
// the query. If it's not, we don't need to use all_datoms here.
|
// the query. If it's not, we don't need to use all_datoms here.
|
||||||
|
@ -484,17 +484,17 @@ impl ConjoiningClauses {
|
||||||
|
|
||||||
/// Decide which table to use for the provided attribute and value.
|
/// Decide which table to use for the provided attribute and value.
|
||||||
/// If the attribute input or value binding doesn't name an attribute, or doesn't name an
|
/// If the attribute input or value binding doesn't name an attribute, or doesn't name an
|
||||||
/// attribute that is congruent with the supplied value, we mark the CC as known-empty and
|
/// attribute that is congruent with the supplied value, we return an `EmptyBecause`.
|
||||||
/// return `None`.
|
/// The caller is responsible for marking the CC as known-empty if this is a fatal failure.
|
||||||
fn table_for_places<'s, 'a>(&mut self, schema: &'s Schema, attribute: &'a PatternNonValuePlace, value: &'a PatternValuePlace) -> Option<DatomsTable> {
|
fn table_for_places<'s, 'a>(&self, schema: &'s Schema, attribute: &'a PatternNonValuePlace, value: &'a PatternValuePlace) -> ::std::result::Result<DatomsTable, EmptyBecause> {
|
||||||
match attribute {
|
match attribute {
|
||||||
&PatternNonValuePlace::Ident(ref kw) =>
|
&PatternNonValuePlace::Ident(ref kw) =>
|
||||||
schema.attribute_for_ident(kw)
|
schema.attribute_for_ident(kw)
|
||||||
.when_not(|| self.mark_known_empty(EmptyBecause::InvalidAttributeIdent(kw.clone())))
|
.ok_or_else(|| EmptyBecause::InvalidAttributeIdent(kw.clone()))
|
||||||
.and_then(|attribute| self.table_for_attribute_and_value(attribute, value)),
|
.and_then(|attribute| self.table_for_attribute_and_value(attribute, value)),
|
||||||
&PatternNonValuePlace::Entid(id) =>
|
&PatternNonValuePlace::Entid(id) =>
|
||||||
schema.attribute_for_entid(id)
|
schema.attribute_for_entid(id)
|
||||||
.when_not(|| self.mark_known_empty(EmptyBecause::InvalidAttributeEntid(id)))
|
.ok_or_else(|| EmptyBecause::InvalidAttributeEntid(id))
|
||||||
.and_then(|attribute| self.table_for_attribute_and_value(attribute, value)),
|
.and_then(|attribute| self.table_for_attribute_and_value(attribute, value)),
|
||||||
// TODO: In a prepared context, defer this decision until a second algebrizing phase.
|
// TODO: In a prepared context, defer this decision until a second algebrizing phase.
|
||||||
// #278.
|
// #278.
|
||||||
|
@ -513,18 +513,15 @@ impl ConjoiningClauses {
|
||||||
Some(TypedValue::Keyword(ref kw)) =>
|
Some(TypedValue::Keyword(ref kw)) =>
|
||||||
// Don't recurse: avoid needing to clone the keyword.
|
// Don't recurse: avoid needing to clone the keyword.
|
||||||
schema.attribute_for_ident(kw)
|
schema.attribute_for_ident(kw)
|
||||||
.when_not(|| self.mark_known_empty(EmptyBecause::InvalidAttributeIdent(kw.clone())))
|
.ok_or_else(|| EmptyBecause::InvalidAttributeIdent(kw.clone()))
|
||||||
.and_then(|attribute| self.table_for_attribute_and_value(attribute, value)),
|
.and_then(|attribute| self.table_for_attribute_and_value(attribute, value)),
|
||||||
Some(v) => {
|
Some(v) => {
|
||||||
// This pattern cannot match: the caller has bound a non-entity value to an
|
// This pattern cannot match: the caller has bound a non-entity value to an
|
||||||
// attribute place. Return `None` and invalidate this CC.
|
// attribute place.
|
||||||
self.mark_known_empty(EmptyBecause::InvalidBinding(DatomsColumn::Attribute,
|
Err(EmptyBecause::InvalidBinding(DatomsColumn::Attribute, v.clone()))
|
||||||
v.clone()));
|
|
||||||
None
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -534,8 +531,11 @@ impl ConjoiningClauses {
|
||||||
/// `is_known_empty`.
|
/// `is_known_empty`.
|
||||||
fn alias_table<'s, 'a>(&mut self, schema: &'s Schema, pattern: &'a Pattern) -> Option<SourceAlias> {
|
fn alias_table<'s, 'a>(&mut self, schema: &'s Schema, pattern: &'a Pattern) -> Option<SourceAlias> {
|
||||||
self.table_for_places(schema, &pattern.attribute, &pattern.value)
|
self.table_for_places(schema, &pattern.attribute, &pattern.value)
|
||||||
.when_not(|| assert!(self.is_known_empty)) // table_for_places should have flipped this.
|
.map_err(|reason| {
|
||||||
|
self.mark_known_empty(reason);
|
||||||
|
})
|
||||||
.map(|table| SourceAlias(table, (self.aliaser)(table)))
|
.map(|table| SourceAlias(table, (self.aliaser)(table)))
|
||||||
|
.ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_attribute<'s, 'a>(&self, schema: &'s Schema, pattern: &'a Pattern) -> Option<&'s Attribute> {
|
fn get_attribute<'s, 'a>(&self, schema: &'s Schema, pattern: &'a Pattern) -> Option<&'s Attribute> {
|
||||||
|
|
Loading…
Reference in a new issue