the new parser works

main
Ziyang Hu 2 years ago
parent 23d7c2d966
commit cd1d1f63cd

@ -10,7 +10,7 @@ use crate::data::expr::{get_op, Expr};
use crate::data::functions::{OP_LIST, OP_MINUS, OP_NEGATE}; use crate::data::functions::{OP_LIST, OP_MINUS, OP_NEGATE};
use crate::data::symb::Symbol; use crate::data::symb::Symbol;
use crate::data::value::DataValue; use crate::data::value::DataValue;
use crate::parse::script::{Pair, Pairs, Rule}; use crate::parse::script::{Pair, Rule};
lazy_static! { lazy_static! {
static ref PREC_CLIMBER: PrecClimber<Rule> = { static ref PREC_CLIMBER: PrecClimber<Rule> = {

@ -9,6 +9,7 @@ use crate::parse::script::query::parse_query;
pub(crate) mod query; pub(crate) mod query;
pub(crate) mod expr; pub(crate) mod expr;
pub(crate) mod pull;
#[derive(pest_derive::Parser)] #[derive(pest_derive::Parser)]
#[grammar = "cozoscript.pest"] #[grammar = "cozoscript.pest"]

@ -0,0 +1,11 @@
// fn parse_pull_spec(src: Pair<'_>) -> Result<JsonValue> {
// let mut src = src.into_inner();
// let name = src.next().unwrap().as_str();
// let args: Vec<_> = src
// .next()
// .unwrap()
// .into_inner()
// .map(parse_pull_arg)
// .try_collect()?;
// Ok(json!({"pull": name, "spec": args}))
// }

@ -20,8 +20,8 @@ use crate::data::symb::{Symbol, PROG_ENTRY};
use crate::data::tuple::Tuple; use crate::data::tuple::Tuple;
use crate::data::value::DataValue; use crate::data::value::DataValue;
use crate::parse::query::{ConstRules, OutSpec, QueryOutOptions, SortDir, ViewOp}; use crate::parse::query::{ConstRules, OutSpec, QueryOutOptions, SortDir, ViewOp};
use crate::parse::script::{Pair, Pairs, Rule};
use crate::parse::script::expr::build_expr; use crate::parse::script::expr::build_expr;
use crate::parse::script::{Pair, Pairs, Rule};
use crate::runtime::view::{ViewRelId, ViewRelKind, ViewRelMetadata}; use crate::runtime::view::{ViewRelId, ViewRelKind, ViewRelMetadata};
pub(crate) fn parse_query( pub(crate) fn parse_query(
@ -407,7 +407,10 @@ fn parse_algo_rule(
let mut els = inner.into_inner(); let mut els = inner.into_inner();
let name = els.next().unwrap().as_str(); let name = els.next().unwrap().as_str();
let args = els.map(|v| Symbol::from(v.as_str())).collect_vec(); let args = els.map(|v| Symbol::from(v.as_str())).collect_vec();
rule_args.push(AlgoRuleArg::Stored(Symbol::from(name), args)) rule_args.push(AlgoRuleArg::Stored(
Symbol::from(name.strip_prefix(':').unwrap()),
args,
))
} }
Rule::algo_triple_rel => { Rule::algo_triple_rel => {
let mut els = inner.into_inner(); let mut els = inner.into_inner();
@ -449,13 +452,12 @@ fn parse_algo_rule(
algo: AlgoHandle { algo: AlgoHandle {
name: Symbol::from(*algo_name), name: Symbol::from(*algo_name),
}, },
rule_args: vec![], rule_args,
options: Default::default(), options,
}, },
)) ))
} }
fn parse_limit_or_offset(src: Pair<'_>) -> Result<usize> { fn parse_limit_or_offset(src: Pair<'_>) -> Result<usize> {
let src = src.into_inner().next().unwrap().as_str(); let src = src.into_inner().next().unwrap().as_str();
str2usize(src) str2usize(src)

@ -6,10 +6,10 @@ use std::sync::{Arc, Mutex};
use std::time::Duration; use std::time::Duration;
use std::{fs, thread}; use std::{fs, thread};
use miette::{miette, bail, ensure, Result, IntoDiagnostic};
use either::{Left, Right}; use either::{Left, Right};
use itertools::Itertools; use itertools::Itertools;
use log::debug; use log::debug;
use miette::{bail, ensure, miette, IntoDiagnostic, Result};
use serde_json::json; use serde_json::json;
use smartstring::SmartString; use smartstring::SmartString;
@ -30,6 +30,7 @@ use crate::parse::cozoscript::query::{parse_query_to_json, ScriptType};
use crate::parse::cozoscript::sys::{CompactTarget, SysOp}; use crate::parse::cozoscript::sys::{CompactTarget, SysOp};
use crate::parse::query::ViewOp; use crate::parse::query::ViewOp;
use crate::parse::schema::AttrTxItem; use crate::parse::schema::AttrTxItem;
use crate::parse::script::{parse_script, CozoScript};
use crate::query::pull::CurrentPath; use crate::query::pull::CurrentPath;
use crate::runtime::transact::SessionTx; use crate::runtime::transact::SessionTx;
use crate::runtime::view::{ViewRelId, ViewRelMetadata}; use crate::runtime::view::{ViewRelId, ViewRelMetadata};
@ -361,12 +362,12 @@ impl Db {
Ok(json!(collected)) Ok(json!(collected))
} }
pub fn run_script(&self, payload: &str) -> Result<JsonValue> { pub fn run_script(&self, payload: &str) -> Result<JsonValue> {
let (script_type, payload) = parse_query_to_json(payload)?; let (script_type, json) = parse_query_to_json(payload)?;
match script_type { match script_type {
ScriptType::Query => self.run_query(&payload), ScriptType::Query => self.run_query(&payload),
ScriptType::Schema => self.transact_attributes(&payload), ScriptType::Schema => self.transact_attributes(&json),
ScriptType::Tx => self.transact_triples(&payload), ScriptType::Tx => self.transact_triples(&json),
ScriptType::Sys => self.run_sys_op(payload), ScriptType::Sys => self.run_sys_op(json),
} }
} }
pub fn convert_to_json_query(&self, payload: &str) -> Result<JsonValue> { pub fn convert_to_json_query(&self, payload: &str) -> Result<JsonValue> {
@ -380,19 +381,20 @@ impl Db {
Ok(json!({ key: payload })) Ok(json!({ key: payload }))
} }
pub fn run_json_query(&self, payload: &JsonValue) -> Result<JsonValue> { pub fn run_json_query(&self, payload: &JsonValue) -> Result<JsonValue> {
let (k, v) = payload todo!()
.as_object() // let (k, v) = payload
.ok_or_else(|| miette!("json query must be an object"))? // .as_object()
.iter() // .ok_or_else(|| miette!("json query must be an object"))?
.next() // .iter()
.ok_or_else(|| miette!("json query must be an object with keys"))?; // .next()
match k as &str { // .ok_or_else(|| miette!("json query must be an object with keys"))?;
"query" => self.run_query(v), // match k as &str {
"schema" => self.transact_attributes(v), // "query" => self.run_query(v),
"tx" => self.transact_triples(v), // "schema" => self.transact_attributes(v),
"sys" => self.run_sys_op(v.clone()), // "tx" => self.transact_triples(v),
v => bail!("unexpected key in json query: {}", v), // "sys" => self.run_sys_op(v.clone()),
} // v => bail!("unexpected key in json query: {}", v),
// }
} }
pub fn run_sys_op(&self, payload: JsonValue) -> Result<JsonValue> { pub fn run_sys_op(&self, payload: JsonValue) -> Result<JsonValue> {
let op: SysOp = serde_json::from_value(payload).into_diagnostic()?; let op: SysOp = serde_json::from_value(payload).into_diagnostic()?;
@ -433,9 +435,12 @@ impl Db {
} }
} }
} }
pub fn run_query(&self, payload: &JsonValue) -> Result<JsonValue> { pub fn run_query(&self, payload: &str) -> Result<JsonValue> {
let mut tx = self.transact()?; let mut tx = self.transact()?;
let input_program = tx.parse_query(payload, &Default::default())?; let input_program = match parse_script(payload, &Default::default())? {
CozoScript::Query(p) => p,
};
// let input_program = tx.parse_query(payload, &Default::default())?;
if let Some((meta, op)) = &input_program.out_opts.as_view { if let Some((meta, op)) = &input_program.out_opts.as_view {
if *op == ViewOp::Create { if *op == ViewOp::Create {
ensure!( ensure!(
@ -490,7 +495,8 @@ impl Db {
}; };
if !input_program.out_opts.sorters.is_empty() { if !input_program.out_opts.sorters.is_empty() {
let entry_head = input_program.get_entry_head()?.to_vec(); let entry_head = input_program.get_entry_head()?.to_vec();
let sorted_result = tx.sort_and_collect(result, &input_program.out_opts.sorters, &entry_head)?; let sorted_result =
tx.sort_and_collect(result, &input_program.out_opts.sorters, &entry_head)?;
let sorted_iter = if let Some(offset) = input_program.out_opts.offset { let sorted_iter = if let Some(offset) = input_program.out_opts.offset {
Left(sorted_result.scan_sorted().skip(offset)) Left(sorted_result.scan_sorted().skip(offset))
} else { } else {

@ -25,86 +25,86 @@ fn init_logger() {
fn air_routes() -> Result<()> { fn air_routes() -> Result<()> {
init_logger(); init_logger();
let db = create_db("_test_air_routes", false); let db = create_db("_test_air_routes", false);
let attr_res = db.run_script( // let attr_res = db.run_script(
r#" // r#"
:schema // :schema
//
put country { // put country {
code: string identity, // code: string identity,
desc: string // desc: string
} // }
put continent { // put continent {
code: string identity, // code: string identity,
desc: string // desc: string
} // }
put airport { // put airport {
iata: string identity, // iata: string identity,
icao: string index, // icao: string index,
city: string index, // city: string index,
desc: string, // desc: string,
region: string index, // region: string index,
country: ref, // country: ref,
runways: int, // runways: int,
longest: int, // longest: int,
altitude: int, // altitude: int,
lat: float, // lat: float,
lon: float // lon: float
} // }
put route { // put route {
src: ref, // src: ref,
dst: ref, // dst: ref,
distance: int // distance: int
} // }
put geo { // put geo {
contains: ref many, // contains: ref many,
} // }
"#, // "#,
); // );
//
if attr_res.is_ok() { // if attr_res.is_ok() {
let insertions = read_to_string("tests/air-routes-data.json").into_diagnostic()?; // let insertions = read_to_string("tests/air-routes-data.json").into_diagnostic()?;
let triple_insertion_time = Instant::now(); // let triple_insertion_time = Instant::now();
db.run_script(&insertions)?; // db.run_script(&insertions)?;
dbg!(triple_insertion_time.elapsed()); // dbg!(triple_insertion_time.elapsed());
} // }
//
let view_time = Instant::now(); // let view_time = Instant::now();
db.run_script(r#" // db.run_script(r#"
?[?src, ?dst, ?distance] := [?r route.src ?src], [?r route.dst ?dst], [?r route.distance ?distance]; // ?[?src, ?dst, ?distance] := [?r route.src ?src], [?r route.dst ?dst], [?r route.distance ?distance];
:view rederive flies_to; // :view rederive flies_to;
"#)?; // "#)?;
//
dbg!(view_time.elapsed()); // dbg!(view_time.elapsed());
//
let view_time2 = Instant::now(); // let view_time2 = Instant::now();
db.run_script( // db.run_script(
r#" // r#"
?[?src_c, ?dst_c, ?distance] := [?r route.src ?src], [?r route.dst ?dst], // ?[?src_c, ?dst_c, ?distance] := [?r route.src ?src], [?r route.dst ?dst],
[?r route.distance ?distance], // [?r route.distance ?distance],
[?src airport.iata ?src_c], [?dst airport.iata ?dst_c]; // [?src airport.iata ?src_c], [?dst airport.iata ?dst_c];
:view rederive flies_to_code; // :view rederive flies_to_code;
"#, // "#,
)?; // )?;
dbg!(view_time2.elapsed()); // dbg!(view_time2.elapsed());
//
let view_time3 = Instant::now(); // let view_time3 = Instant::now();
db.run_script( // db.run_script(
r#" // r#"
?[?code, ?lat, ?lon] := [?n airport.iata ?code], [?n airport.lat ?lat], [?n airport.lon ?lon]; // ?[?code, ?lat, ?lon] := [?n airport.iata ?code], [?n airport.lat ?lat], [?n airport.lon ?lon];
:view rederive code_lat_lon; // :view rederive code_lat_lon;
"# // "#
)?; // )?;
dbg!(view_time3.elapsed()); // dbg!(view_time3.elapsed());
//
println!("views: {}", db.list_relations()?); // println!("views: {}", db.list_relations()?);
//
let compact_main_time = Instant::now(); // let compact_main_time = Instant::now();
db.compact_main()?; // db.compact_main()?;
dbg!(compact_main_time.elapsed()); // dbg!(compact_main_time.elapsed());
//
let compact_view_time = Instant::now(); // let compact_view_time = Instant::now();
db.compact_view()?; // db.compact_view()?;
dbg!(compact_view_time.elapsed()); // dbg!(compact_view_time.elapsed());
let dfs_time = Instant::now(); let dfs_time = Instant::now();
let res = db.run_script(r#" let res = db.run_script(r#"

Loading…
Cancel
Save