extract table refs from cnf conditions

main
Ziyang Hu 2 years ago
parent 55c7bfc302
commit dff481130b

@ -1,6 +1,47 @@
use std::collections::HashSet;
use crate::db::table::TableId;
use crate::relation::value;
use crate::relation::value::Value;
pub fn extract_tables(val: &Value) -> HashSet<TableId> {
let mut coll = HashSet::new();
do_extract_tables(val, &mut coll);
coll
}
fn do_extract_tables(val: &Value, coll: &mut HashSet<TableId>) {
match val {
Value::Null |
Value::Bool(_) |
Value::Int(_) |
Value::Float(_) |
Value::Uuid(_) |
Value::Text(_) => {}
Value::List(l) => {
for v in l {
do_extract_tables(v, coll);
}
}
Value::Dict(d) => {
for v in d.values() {
do_extract_tables(v, coll);
}
}
Value::Variable(_) => {}
Value::TupleRef(tid, _cid) => {
coll.insert(*tid);
}
Value::Apply(_, args) => {
for v in args {
do_extract_tables(v, coll);
}
}
Value::FieldAccess(_, _) => {}
Value::IdxAccess(_, _) => {}
Value::EndSentinel => {}
}
}
pub fn cnf_transform(mut val: Value) -> Value {
loop {
let (changed, new_val) = do_cnf_transform(val);

@ -1,10 +1,11 @@
use std::borrow::Cow;
use std::cmp::{max, min};
use std::collections::{BTreeMap};
use std::collections::{BTreeMap, HashSet};
use cozorocks::SlicePtr;
use crate::db::cnf_transform::cnf_transform;
use crate::db::cnf_transform::{cnf_transform, extract_tables};
use crate::db::engine::{Session};
use crate::db::plan::AccessorMap;
use crate::db::table::TableId;
use crate::relation::value::{Value};
use crate::error::{CozoError, Result};
use crate::error::CozoError::{InvalidArgument, LogicError};
@ -108,12 +109,32 @@ impl<'s> Session<'s> {
let (ev, new_v) = self.partial_eval(value.clone(), params, table_bindings)?;
let new_v = cnf_transform(new_v.clone());
if new_v == value {
return Ok((ev, new_v))
return Ok((ev, new_v));
} else {
value = new_v
}
}
}
pub fn cnf_with_table_refs<'a>(&self, value: Value<'a>, params: &BTreeMap<String, Value<'a>>,
table_bindings: &AccessorMap) -> Result<Vec<(Value<'a>, HashSet<TableId>)>> {
let (_, value) = self.partial_cnf_eval(value, params, table_bindings)?;
let conjunctives;
if let Value::Apply(op, args) = value {
if op == value::OP_AND {
conjunctives = args;
} else {
conjunctives = vec![Value::Apply(op, args)];
}
} else {
conjunctives = vec![value]
}
Ok(conjunctives.into_iter().map(|v| {
let tids = extract_tables(&v);
(v, tids)
}).collect())
}
pub fn partial_eval<'a>(&self, value: Value<'a>, params: &BTreeMap<String, Value<'a>>,
table_bindings: &AccessorMap) -> Result<(bool, Value<'a>)> {
match value {

@ -5,7 +5,7 @@ use crate::error::CozoError::LogicError;
use crate::relation::data::DataKind;
use crate::relation::typing::Typing;
#[derive(Eq, PartialEq, Debug, Clone, Copy, Ord, PartialOrd)]
#[derive(Eq, PartialEq, Debug, Clone, Copy, Ord, PartialOrd, Hash)]
pub struct TableId {
pub in_root: bool,
pub id: i64,

Loading…
Cancel
Save