Avoid using the all_datoms table when a type requirement prevents strings
This commit is contained in:
parent
c9e2ff8146
commit
89d3114bd1
2 changed files with 35 additions and 4 deletions
|
@ -406,6 +406,14 @@ impl ConjoiningClauses {
|
||||||
self.known_types.get(var).cloned().unwrap_or(ValueTypeSet::any())
|
self.known_types.get(var).cloned().unwrap_or(ValueTypeSet::any())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn required_type_set(&self, var: &Variable) -> ValueTypeSet {
|
||||||
|
self.required_types.get(var).cloned().unwrap_or(ValueTypeSet::any())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn possible_type_set(&self, var: &Variable) -> ValueTypeSet {
|
||||||
|
self.known_type_set(var).intersection(&self.required_type_set(var))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn bind_column_to_var<C: Into<Column>>(&mut self, schema: &Schema, table: TableAlias, column: C, var: Variable) {
|
pub fn bind_column_to_var<C: Into<Column>>(&mut self, schema: &Schema, table: TableAlias, column: C, var: Variable) {
|
||||||
let column = column.into();
|
let column = column.into();
|
||||||
// Do we have an external binding for this?
|
// Do we have an external binding for this?
|
||||||
|
@ -726,10 +734,11 @@ impl ConjoiningClauses {
|
||||||
// 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.
|
||||||
&PatternValuePlace::Variable(ref v) => {
|
&PatternValuePlace::Variable(ref v) => {
|
||||||
// Do we know that this variable can't be a string? If so, we don't need
|
// Do we know that this variable can't be a string? If so, we don't need
|
||||||
// AllDatoms. None or String means it could be or definitely is.
|
// AllDatoms.
|
||||||
match self.known_types.get(v).map(|types| types.contains(ValueType::String)) {
|
if !self.possible_type_set(v).contains(ValueType::String) {
|
||||||
Some(false) => DatomsTable::Datoms,
|
DatomsTable::Datoms
|
||||||
_ => DatomsTable::AllDatoms,
|
} else {
|
||||||
|
DatomsTable::AllDatoms
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&PatternValuePlace::Constant(NonIntegerConstant::Text(_)) =>
|
&PatternValuePlace::Constant(NonIntegerConstant::Text(_)) =>
|
||||||
|
|
|
@ -330,6 +330,28 @@ fn test_type_required_boolean() {
|
||||||
assert_eq!(args, vec![]);
|
assert_eq!(args, vec![]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_type_require_avoids_all_datoms() {
|
||||||
|
let schema = Schema::default();
|
||||||
|
// Since the constraint is first, we know we don't need to use all_datoms.
|
||||||
|
let query = r#"[:find ?x :where [(keyword ?e)] [?x _ ?e]]"#;
|
||||||
|
let SQLQuery { sql, args } = translate(&schema, query);
|
||||||
|
|
||||||
|
assert_eq!(sql, "SELECT DISTINCT `datoms00`.e AS `?x` \
|
||||||
|
FROM `datoms` AS `datoms00` \
|
||||||
|
WHERE (`datoms00`.value_type_tag = 13)");
|
||||||
|
assert_eq!(args, vec![]);
|
||||||
|
|
||||||
|
// Strings always need to use all_datoms.
|
||||||
|
let query = r#"[:find ?x :where [(string ?e)] [?x _ ?e]]"#;
|
||||||
|
let SQLQuery { sql, args } = translate(&schema, query);
|
||||||
|
|
||||||
|
assert_eq!(sql, "SELECT DISTINCT `all_datoms00`.e AS `?x` \
|
||||||
|
FROM `all_datoms` AS `all_datoms00` \
|
||||||
|
WHERE (`all_datoms00`.value_type_tag = 10)");
|
||||||
|
assert_eq!(args, vec![]);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_numeric_less_than_unknown_attribute() {
|
fn test_numeric_less_than_unknown_attribute() {
|
||||||
let schema = Schema::default();
|
let schema = Schema::default();
|
||||||
|
|
Loading…
Reference in a new issue