Part 2: include necessary 'with' variables in SQL projection list.

The test produces projection elements for `:with`, even though there are
no aggregates in the query. This test will need to be adjusted when we
optimize this away!
This commit is contained in:
Richard Newman 2017-04-13 11:45:38 -07:00
parent 5db0870209
commit 5d2193bd63
2 changed files with 32 additions and 0 deletions

View file

@ -199,6 +199,7 @@ fn project_elements<'a, I: IntoIterator<Item = &'a Element>>(
let mut cols = Vec::with_capacity(count);
let mut i: i32 = 0;
let mut templates = vec![];
let mut with = query.with.clone();
for e in elements {
match e {
@ -206,6 +207,8 @@ fn project_elements<'a, I: IntoIterator<Item = &'a Element>>(
// into the SQL projection, aliased to the name of the variable,
// and we push an annotated index into the projector.
&Element::Variable(ref var) => {
// If we're projecting this, we don't need it in :with.
with.remove(var);
let (column, name) = candidate_column(query, var);
cols.push(ProjectedColumn(column, name));
@ -225,6 +228,18 @@ fn project_elements<'a, I: IntoIterator<Item = &'a Element>>(
}
}
for var in with {
// We need to collect these into the SQL column list, but they don't affect projection.
// If a variable is of a non-fixed type, also project the type tag column, so we don't
// accidentally unify across types when considering uniqueness!
let (column, name) = candidate_column(query, &var);
cols.push(ProjectedColumn(column, name));
if query.cc.known_type(&var).is_none() {
let (type_column, type_name) = candidate_type_column(query, &var);
cols.push(ProjectedColumn(type_column, type_name));
}
}
(Projection::Columns(cols), templates)
}

View file

@ -353,3 +353,20 @@ fn test_complex_or_join_type_projection() {
LIMIT 1");
assert_eq!(args, vec![]);
}
#[test]
fn test_with_without_aggregate() {
let schema = prepopulated_schema();
// Known type.
let input = r#"[:find ?x :with ?y :where [?x :foo/bar ?y]]"#;
let SQLQuery { sql, args } = translate(&schema, input, None);
assert_eq!(sql, "SELECT DISTINCT `datoms00`.e AS `?x`, `datoms00`.v AS `?y` FROM `datoms` AS `datoms00` WHERE `datoms00`.a = 99");
assert_eq!(args, vec![]);
// Unknown type.
let input = r#"[:find ?x :with ?y :where [?x _ ?y]]"#;
let SQLQuery { sql, args } = translate(&schema, input, None);
assert_eq!(sql, "SELECT DISTINCT `all_datoms00`.e AS `?x`, `all_datoms00`.v AS `?y`, `all_datoms00`.value_type_tag AS `?y_value_type_tag` FROM `all_datoms` AS `all_datoms00`");
assert_eq!(args, vec![]);
}