Apply newly bound values to existing columns.

This commit lifts some logic out of the scalar ground handler to apply
elsewhere.

When a new value binding is encountered for a variable to which column
bindings have already been established, we do two things:

- We apply a new constraint to the primary column. This ensures that the
  behavior for ground-first and ground-second is equivalent.
- We eliminate any existing column type extraction: it won't be
  necessary now that a constant value and constant type are known.
This commit is contained in:
Richard Newman 2017-06-12 17:33:40 -07:00
parent f7a3fd5b17
commit 17c59bbff6
2 changed files with 19 additions and 20 deletions

View file

@ -36,10 +36,8 @@ use errors::{
};
use types::{
ColumnConstraint,
ComputedTable,
EmptyBecause,
QualifiedAlias,
SourceAlias,
ValueTypeSet,
VariableColumn,
@ -112,23 +110,6 @@ impl ConjoiningClauses {
self.bind_value(&var, value.clone());
}
let vt = value.value_type();
// Check to see whether this variable is already associated to a column.
// If so, we want to add an equality filter (or, in the future, redo the existing patterns).
if let Some(QualifiedAlias(table, column)) = self.column_bindings
.get(&var)
.and_then(|vec| vec.get(0).cloned()) {
self.constrain_column_to_constant(table, column, value);
}
// Are we also trying to figure out the type of the value when the query runs?
// If so, constrain that!
if let Some(table) = self.extracted_types.get(&var)
.map(|qa| qa.0.clone()) {
self.wheres.add_intersection(ColumnConstraint::HasType(table, vt));
}
Ok(())
}

View file

@ -338,7 +338,25 @@ impl ConjoiningClauses {
impl ConjoiningClauses {
/// Be careful with this. It'll overwrite existing bindings.
pub fn bind_value(&mut self, var: &Variable, value: TypedValue) {
self.constrain_var_to_type(var.clone(), value.value_type());
let vt = value.value_type();
self.constrain_var_to_type(var.clone(), vt);
// Are there any existing column bindings for this variable?
// If so, generate a constraint against the primary column.
if let Some(vec) = self.column_bindings.get(var) {
if let Some(col) = vec.first() {
self.wheres.add_intersection(ColumnConstraint::Equals(col.clone(), QueryValue::TypedValue(value.clone())));
}
}
// Are we also trying to figure out the type of the value when the query runs?
// If so, constrain that!
if let Some(table) = self.extracted_types.get(&var)
.map(|qa| qa.0.clone()) {
self.wheres.add_intersection(ColumnConstraint::HasType(table, value.value_type()));
}
// Finally, store the binding for future use.
self.value_bindings.insert(var.clone(), value);
}