parse associate tables

main
Ziyang Hu 2 years ago
parent c8c8ac15e3
commit 9e06b23f35

@ -63,7 +63,7 @@ impl<'a> TableRowGetter<'a> {
.map(Tuple::new);
Ok(res)
}
pub fn get_with_iter<'b, T: Iterator<Item = Value<'b>>>(
pub fn get_with_iter<'b, T: Iterator<Item=Value<'b>>>(
&mut self,
vals: T,
) -> Result<Option<SliceTuple>> {
@ -258,7 +258,7 @@ impl<'a> OutputItPlan<'a> {
}
impl<'a> ExecPlan<'a> {
pub fn iter(&'a self) -> Result<Box<dyn Iterator<Item = Result<MegaTuple>> + 'a>> {
pub fn iter(&'a self) -> Result<Box<dyn Iterator<Item=Result<MegaTuple>> + 'a>> {
match self {
ExecPlan::NodeItPlan { it, info, .. } => {
let it = it.try_get()?;
@ -507,10 +507,10 @@ fn shift_accessor_map(amap: AccessorMap, (keyshift, valshift): (usize, usize)) -
tid.in_root,
tid.id
+ if cid.is_key {
keyshift as i64
} else {
valshift as i64
},
keyshift as i64
} else {
valshift as i64
},
),
cid,
),
@ -707,19 +707,22 @@ impl<'a> Session<'a> {
}
fn convert_from_data_to_plan(&self, from_data: Vec<FromEl>) -> Result<ExecPlan> {
let convert_el = |el| match el {
FromEl::Simple(el) => match el.info.kind {
DataKind::Node => Ok(ExecPlan::NodeItPlan {
it: IteratorSlot::Dummy,
info: el.info,
binding: Some(el.binding),
}),
DataKind::Edge => Ok(ExecPlan::EdgeItPlan {
it: IteratorSlot::Dummy,
info: el.info,
binding: Some(el.binding),
}),
_ => Err(LogicError("Wrong type for table binding".to_string())),
},
FromEl::Simple(el) => {
let core = match el.info.kind {
DataKind::Node => ExecPlan::NodeItPlan {
it: IteratorSlot::Dummy,
info: el.info,
binding: Some(el.binding),
},
DataKind::Edge => ExecPlan::EdgeItPlan {
it: IteratorSlot::Dummy,
info: el.info,
binding: Some(el.binding),
},
_ => return Err(LogicError("Wrong type for table binding".to_string())),
};
Ok(core)
}
FromEl::Chain(ch) => {
let mut it = ch.into_iter();
let nxt = it

@ -19,6 +19,7 @@ pub enum FromEl {
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct SimpleFromEl {
pub table: String,
pub associates: Vec<(String, TableInfo)>,
pub binding: String,
pub info: TableInfo,
}
@ -34,6 +35,7 @@ pub enum EdgeOrNodeKind {
pub struct EdgeOrNodeEl {
pub table: String,
pub binding: Option<String>,
pub associates: Vec<(String, TableInfo)>,
pub info: TableInfo,
pub kind: EdgeOrNodeKind,
pub left_outer_marker: bool,
@ -63,10 +65,16 @@ impl<'a> Session<'a> {
}
let table_name = build_name_in_def(pairs.next().unwrap(), true)?;
let table_info = self.get_table_info(&table_name)?;
let associates = pairs.map(|p| -> Result<(String, TableInfo)> {
let a_name = build_name_in_def(p, true)?;
let a_info = self.get_table_info(&a_name)?;
Ok((a_name, a_info))
}).collect::<Result<Vec<_>>>()?;
let ret = FromEl::Simple(Box::new(SimpleFromEl {
binding: name.to_string(),
table: table_name,
info: table_info,
associates,
}));
Ok(ret)
}
@ -131,7 +139,7 @@ impl<'a> Session<'a> {
}
fn parse_node_pattern(&self, pair: Pair<Rule>) -> Result<EdgeOrNodeEl> {
let (table, binding, info) = self.parse_node_or_edge(pair)?;
let (table, binding, info, associates) = self.parse_node_or_edge(pair)?;
if info.kind != DataKind::Node {
return Err(CozoError::LogicError(format!("{} is not a node", table)));
}
@ -142,11 +150,12 @@ impl<'a> Session<'a> {
kind: EdgeOrNodeKind::Node,
left_outer_marker: false,
right_outer_marker: false,
associates
})
}
fn parse_edge_pattern(&self, pair: Pair<Rule>, is_fwd: bool) -> Result<EdgeOrNodeEl> {
let (table, binding, info) = self.parse_node_or_edge(pair)?;
let (table, binding, info, associates) = self.parse_node_or_edge(pair)?;
if info.kind != DataKind::Edge {
return Err(CozoError::LogicError(format!("{} is not an edge", table)));
}
@ -161,10 +170,11 @@ impl<'a> Session<'a> {
},
left_outer_marker: false,
right_outer_marker: false,
associates
})
}
fn parse_node_or_edge(&self, pair: Pair<Rule>) -> Result<(String, Option<String>, TableInfo)> {
fn parse_node_or_edge(&self, pair: Pair<Rule>) -> Result<(String, Option<String>, TableInfo, Vec<(String, TableInfo)>)> {
let name;
let mut pairs = pair.into_inner();
@ -178,8 +188,13 @@ impl<'a> Session<'a> {
let table_name = build_name_in_def(cur_pair, true)?;
let table_info = self.get_table_info(&table_name)?;
// println!("{:?}, {}, {:?}", name, table_name, table_info);
let associates = pairs.map(|p| -> Result<(String, TableInfo)> {
let a_name = build_name_in_def(p, true)?;
let a_info = self.get_table_info(&a_name)?;
Ok((a_name, a_info))
}).collect::<Result<Vec<_>>>()?;
Ok((table_name, name.map(|v| v.to_string()), table_info))
Ok((table_name, name.map(|v| v.to_string()), table_info, associates))
}
pub fn parse_where_pattern(&self, pair: Pair<Rule>) -> Result<Value> {

@ -177,14 +177,14 @@ insert = {"insert"}
from_pattern = { "from" ~ (from_el ~ ",")* ~ from_el }
from_el = _{ simple_from_pattern | node_edge_pattern }
simple_from_pattern = { ident ~ ":" ~ name_in_def }
simple_from_pattern = { ident ~ ":" ~ name_in_def ~ ("+" ~ name_in_def)* }
node_edge_pattern = { node_pattern? ~ (edge_pattern ~ node_pattern)* ~ edge_pattern? }
node_pattern = {"(" ~ ident? ~ ":" ~ name_in_def ~ ")"}
node_pattern = {"(" ~ ident? ~ ":" ~ name_in_def ~ ("+" ~ name_in_def)* ~ ")"}
edge_pattern = { outer_join_marker? ~ (fwd_edge_pattern | bwd_edge_pattern) ~ outer_join_marker? }
fwd_edge_pattern = { "-" ~ edge_pattern_inner ~ "->" }
bwd_edge_pattern = { "<-" ~ edge_pattern_inner ~ "-" }
edge_pattern_inner = _{"[" ~ ident? ~ ":" ~ name_in_def ~ "]"}
edge_pattern_inner = _{"[" ~ ident? ~ ":" ~ name_in_def ~ ("+" ~ name_in_def)* ~ "]"}
outer_join_marker = { "?" }
where_pattern = { "where" ~ (expr ~ ",")* ~ expr }
@ -192,8 +192,8 @@ select_pattern = { "select" ~ (select_dict | scoped_dict) ~ ( (order_pattern ~ o
order_pattern = { "ordered" ~ "[" ~ order_el ~ ("," ~ order_el)* ~ "]" }
order_el = _{order_asc | order_dsc}
order_asc = {"+"? ~ ident}
order_dsc = {"-" ~ ident}
order_asc = {expr ~ (":" ~ "asc")?}
order_dsc = {expr ~ (":" ~ "desc")}
offset_pattern = { limit_clause? ~ offset_clause? }
limit_clause = { "limit" ~ pos_int }
offset_clause = { "offset" ~ pos_int }

@ -119,8 +119,9 @@ pub enum Value<'a> {
EndSentinel,
}
// #[derive(Clone, PartialEq, Ord, PartialOrd, Eq)]
// pub struct DescVal<'a>(pub Box<Value<'a>>);
// DescVal are kind of "write-only": you construct them, write them to keys to let the database do
// the sorting, and never read them back in program logic. In particular there is no need for them
// to support operators and methods.
pub type DescVal<'a> = Reverse<Box<Value<'a>>>;
pub type StaticValue = Value<'static>;

Loading…
Cancel
Save