Part 1: define ComputedTable.

Complex `or`s are translated to SQL as a subquery -- in particular, a
subquery that's a UNION. Conceptually, that subquery is a computed
table: `all_datoms` and `datoms` yield rows of e/a/v/tx, and each
computed table yields rows of variable bindings.

The table itself is a type, `ComputedTable`. Its `Union` case contains
everything a subquery needs: a `ConjoiningClauses` and a projection
list, which together allow us to build a SQL subquery, and a list of
variables that need type code extraction. (This is discussed further in
a later commit.)

Naturally we also need a way to refer to columns in a computed table.
We model this by a new enum case in `DatomsTable`, `Computed`, which
maintains an integer value that uniquely identifies a computed table.
This commit is contained in:
Richard Newman 2017-04-07 16:24:57 -07:00
parent 79ccd818f3
commit 7948788936
3 changed files with 27 additions and 2 deletions

View file

@ -48,6 +48,7 @@ use errors::{
use types::{
ColumnConstraint,
ColumnIntersection,
ComputedTable,
DatomsColumn,
DatomsTable,
EmptyBecause,
@ -141,6 +142,10 @@ pub struct ConjoiningClauses {
/// A vector of source/alias pairs used to construct a SQL `FROM` list.
pub from: Vec<SourceAlias>,
/// A vector of computed tables (typically subqueries). The index into this vector is used as
/// an identifier in a `DatomsTable::Computed(c)` table reference.
pub computed_tables: Vec<ComputedTable>,
/// A list of fragments that can be joined by `AND`.
pub wheres: ColumnIntersection,
@ -196,6 +201,7 @@ impl Default for ConjoiningClauses {
empty_because: None,
alias_counter: RcCounter::new(),
from: vec![],
computed_tables: vec![],
wheres: ColumnIntersection::default(),
input_variables: BTreeSet::new(),
column_bindings: BTreeMap::new(),
@ -588,7 +594,12 @@ impl ConjoiningClauses {
}
pub fn next_alias_for_table(&mut self, table: DatomsTable) -> TableAlias {
format!("{}{:02}", table.name(), self.alias_counter.next())
match table {
DatomsTable::Computed(u) =>
format!("{}{:02}", table.name(), u),
_ =>
format!("{}{:02}", table.name(), self.alias_counter.next()),
}
}
/// Produce a (table, alias) pair to handle the provided pattern.

View file

@ -110,6 +110,7 @@ pub use types::{
ColumnConstraint,
ColumnConstraintOrAlternation,
ColumnIntersection,
ComputedTable,
DatomsColumn,
DatomsTable,
QualifiedAlias,

View file

@ -8,6 +8,7 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use std::collections::BTreeSet;
use std::collections::HashSet;
use std::fmt::{
@ -28,13 +29,24 @@ use mentat_query::{
};
/// This enum models the fixed set of default tables we have -- two
/// tables and two views.
/// tables and two views -- and computed tables defined in the enclosing CC.
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum DatomsTable {
Datoms, // The non-fulltext datoms table.
FulltextValues, // The virtual table mapping IDs to strings.
FulltextDatoms, // The fulltext-datoms view.
AllDatoms, // Fulltext and non-fulltext datoms.
Computed(usize), // A computed table, tracked elsewhere in the query.
}
/// A source of rows that isn't a named table -- typically a subquery or union.
pub enum ComputedTable {
// Subquery(BTreeSet<Variable>, ::clauses::ConjoiningClauses),
Union {
projection: BTreeSet<Variable>,
type_extraction: BTreeSet<Variable>,
arms: Vec<::clauses::ConjoiningClauses>,
},
}
impl DatomsTable {
@ -44,6 +56,7 @@ impl DatomsTable {
DatomsTable::FulltextValues => "fulltext_values",
DatomsTable::FulltextDatoms => "fulltext_datoms",
DatomsTable::AllDatoms => "all_datoms",
DatomsTable::Computed(_) => "c",
}
}
}