mutation shorthands shouldn't break old assumptions

main
Ziyang Hu 1 year ago
parent b9b3475a14
commit 2f7bd95e9c

@ -22,7 +22,11 @@ use thiserror::Error;
use crate::data::aggr::{parse_aggr, Aggregation}; use crate::data::aggr::{parse_aggr, Aggregation};
use crate::data::expr::Expr; use crate::data::expr::Expr;
use crate::data::functions::{str2vld, MAX_VALIDITY_TS}; use crate::data::functions::{str2vld, MAX_VALIDITY_TS};
use crate::data::program::{FixedRuleApply, FixedRuleArg, InputAtom, InputInlineRule, InputInlineRulesOrFixed, InputNamedFieldRelationApplyAtom, InputProgram, InputRelationApplyAtom, InputRuleApplyAtom, QueryAssertion, QueryOutOptions, RelationOp, ReturnMutation, SearchInput, SortDir, Unification}; use crate::data::program::{
FixedRuleApply, FixedRuleArg, InputAtom, InputInlineRule, InputInlineRulesOrFixed,
InputNamedFieldRelationApplyAtom, InputProgram, InputRelationApplyAtom, InputRuleApplyAtom,
QueryAssertion, QueryOutOptions, RelationOp, ReturnMutation, SearchInput, SortDir, Unification,
};
use crate::data::relation::{ColType, ColumnDef, NullableColType, StoredRelationMetadata}; use crate::data::relation::{ColType, ColumnDef, NullableColType, StoredRelationMetadata};
use crate::data::symb::{Symbol, PROG_ENTRY}; use crate::data::symb::{Symbol, PROG_ENTRY};
use crate::data::value::{DataValue, ValidityTs}; use crate::data::value::{DataValue, ValidityTs};
@ -395,7 +399,7 @@ pub(crate) fn parse_query(
.. ..
}, },
RelationOp::Create, RelationOp::Create,
_ _,
)) = &prog.out_opts.store_relation )) = &prog.out_opts.store_relation
{ {
let mut bindings = key_bindings.clone(); let mut bindings = key_bindings.clone();
@ -449,15 +453,14 @@ pub(crate) fn parse_query(
} }
} }
let head_args = prog.get_entry_out_head()?;
if !prog.out_opts.sorters.is_empty() { if !prog.out_opts.sorters.is_empty() {
#[derive(Debug, Error, Diagnostic)] #[derive(Debug, Error, Diagnostic)]
#[error("Sort key '{0}' not found")] #[error("Sort key '{0}' not found")]
#[diagnostic(code(parser::sort_key_not_found))] #[diagnostic(code(parser::sort_key_not_found))]
struct SortKeyNotFound(String, #[label] SourceSpan); struct SortKeyNotFound(String, #[label] SourceSpan);
let head_args = prog.get_entry_out_head()?;
for (sorter, _) in &prog.out_opts.sorters { for (sorter, _) in &prog.out_opts.sorters {
ensure!( ensure!(
head_args.contains(sorter), head_args.contains(sorter),
@ -471,13 +474,27 @@ pub(crate) fn parse_query(
#[diagnostic(code(parser::relation_has_no_keys))] #[diagnostic(code(parser::relation_has_no_keys))]
struct RelationHasNoKeys(String, #[label] SourceSpan); struct RelationHasNoKeys(String, #[label] SourceSpan);
let empty_mutation_head = match &prog.out_opts.store_relation {
if let Some((handle, _, _)) = &mut prog.out_opts.store_relation { None => false,
Some((handle, _, _)) => {
if handle.key_bindings.is_empty() { if handle.key_bindings.is_empty() {
if handle.dep_bindings.is_empty() { if handle.dep_bindings.is_empty() {
if head_args.is_empty() { true
} else {
bail!(RelationHasNoKeys(handle.name.to_string(), handle.span)); bail!(RelationHasNoKeys(handle.name.to_string(), handle.span));
}
} else { } else {
false
}
}
};
if empty_mutation_head {
let head_args = prog.get_entry_out_head()?;
if let Some((handle, _, _)) = &mut prog.out_opts.store_relation {
if head_args.is_empty() {
bail!(RelationHasNoKeys(handle.name.to_string(), handle.span));
}
handle.key_bindings = head_args.clone(); handle.key_bindings = head_args.clone();
handle.metadata.keys = head_args handle.metadata.keys = head_args
.iter() .iter()
@ -490,10 +507,8 @@ pub(crate) fn parse_query(
default_gen: None, default_gen: None,
}) })
.collect(); .collect();
}
} else { } else {
bail!(RelationHasNoKeys(handle.name.to_string(), handle.span)); unreachable!()
}
} }
} }

@ -184,6 +184,7 @@ fn strict_checks_for_fixed_rules_args() {
?[] <~ PageRank(r[_, _]) ?[] <~ PageRank(r[_, _])
"#, "#,
); );
println!("{:?}", res);
assert!(res.is_ok()); assert!(res.is_ok());
let db = DbInstance::default(); let db = DbInstance::default();

Loading…
Cancel
Save