Part 4: look up attributes for bound variables when making type determinations.

This commit is contained in:
Richard Newman 2017-04-05 12:49:50 -07:00
parent 72977f52e4
commit a07efc0a9e
2 changed files with 20 additions and 2 deletions

View file

@ -599,12 +599,26 @@ impl ConjoiningClauses {
.ok()
}
fn get_attribute_for_value<'s>(&self, schema: &'s Schema, value: &TypedValue) -> Option<&'s Attribute> {
match value {
&TypedValue::Ref(id) => schema.attribute_for_entid(id),
&TypedValue::Keyword(ref kw) => schema.attribute_for_ident(kw),
_ => None,
}
}
fn get_attribute<'s, 'a>(&self, schema: &'s Schema, pattern: &'a Pattern) -> Option<&'s Attribute> {
match pattern.attribute {
PatternNonValuePlace::Entid(id) =>
schema.attribute_for_entid(id),
PatternNonValuePlace::Ident(ref kw) =>
schema.attribute_for_ident(kw),
PatternNonValuePlace::Variable(ref var) =>
// If the pattern has a variable, we've already determined that the binding -- if
// any -- is acceptable and yields a table. Here, simply look to see if it names
// an attribute so we can find out the type.
self.value_bindings.get(var)
.and_then(|val| self.get_attribute_for_value(schema, val)),
_ =>
None,
}

View file

@ -460,8 +460,12 @@ mod testing {
assert!(!cc.is_known_empty);
assert_eq!(cc.from, vec![SourceAlias(DatomsTable::Datoms, "datoms00".to_string())]);
// ?x must be a ref.
assert_eq!(cc.known_type(&x).unwrap(), ValueType::Ref);
// ?x must be a ref, and ?v a boolean.
assert_eq!(cc.known_type(&x), Some(ValueType::Ref));
// We don't need to extract a type for ?v, because the attribute is known.
assert!(!cc.extracted_types.contains_key(&v));
assert_eq!(cc.known_type(&v), Some(ValueType::Boolean));
// ?x is bound to datoms0.e.
assert_eq!(cc.column_bindings.get(&x).unwrap(), &vec![d0_e.clone()]);