(query) Pre: Model columns that don't have type tags closer to Column.

This commit is contained in:
Nick Alexander 2018-04-18 08:38:46 -07:00
parent 36eca0bfb0
commit e532614908
3 changed files with 21 additions and 8 deletions

View file

@ -512,9 +512,6 @@ impl ConjoiningClauses {
// to get its type, record that we can get it from this table. // to get its type, record that we can get it from this table.
let needs_type_extraction = let needs_type_extraction =
!late_binding && // Never need to extract for bound vars. !late_binding && // Never need to extract for bound vars.
// Never need to extract types for refs, and var columns are handled elsewhere:
// a subquery will be projecting a type tag.
column == Column::Fixed(DatomsColumn::Value) &&
self.known_type(&var).is_none() && // Don't need to extract if we know a single type. self.known_type(&var).is_none() && // Don't need to extract if we know a single type.
!self.extracted_types.contains_key(&var); // We're already extracting the type. !self.extracted_types.contains_key(&var); // We're already extracting the type.
@ -523,8 +520,11 @@ impl ConjoiningClauses {
// If we subsequently find out its type, we'll remove this later -- see // If we subsequently find out its type, we'll remove this later -- see
// the removal in `constrain_var_to_type`. // the removal in `constrain_var_to_type`.
if needs_type_extraction { if needs_type_extraction {
self.extracted_types.insert(var.clone(), alias.for_type_tag()); if let Some(tag_alias) = alias.for_associated_type_tag() {
self.extracted_types.insert(var.clone(), tag_alias);
} }
}
self.column_bindings.entry(var).or_insert(vec![]).push(alias); self.column_bindings.entry(var).or_insert(vec![]).push(alias);
} }

View file

@ -127,6 +127,16 @@ impl DatomsColumn {
ValueTypeTag => "value_type_tag", ValueTypeTag => "value_type_tag",
} }
} }
/// The type of the `v` column is determined by the `value_type_tag` column. Return the
/// associated column determining the type of this column, if there is one.
pub fn associated_type_tag_column(&self) -> Option<DatomsColumn> {
use self::DatomsColumn::*;
match *self {
Value => Some(ValueTypeTag),
_ => None,
}
}
} }
impl ColumnName for DatomsColumn { impl ColumnName for DatomsColumn {
@ -220,9 +230,12 @@ impl QualifiedAlias {
QualifiedAlias(table, column.into()) QualifiedAlias(table, column.into())
} }
pub fn for_type_tag(&self) -> QualifiedAlias { pub fn for_associated_type_tag(&self) -> Option<QualifiedAlias> {
// TODO: this only makes sense for `DatomsColumn` tables. match self.1 {
QualifiedAlias(self.0.clone(), Column::Fixed(DatomsColumn::ValueTypeTag)) Column::Fixed(ref c) => c.associated_type_tag_column().map(Column::Fixed),
Column::Fulltext(_) => None,
Column::Variable(_) => None,
}.map(|d| QualifiedAlias(self.0.clone(), d))
} }
} }

View file

@ -170,7 +170,7 @@ impl ToConstraint for ColumnConstraint {
Constraint::equal(left.to_column(), right.to_column()), Constraint::equal(left.to_column(), right.to_column()),
Equals(qa, QueryValue::PrimitiveLong(value)) => { Equals(qa, QueryValue::PrimitiveLong(value)) => {
let tag_column = qa.for_type_tag().to_column(); let tag_column = qa.for_associated_type_tag().expect("an associated type tag alias").to_column();
let value_column = qa.to_column(); let value_column = qa.to_column();
// A bare long in a query might match a ref, an instant, a long (obviously), or a // A bare long in a query might match a ref, an instant, a long (obviously), or a