No need to specify column dependencies unless it is :create or :replace

main
Ziyang Hu 1 year ago
parent e974be9a46
commit af46e62a86

@ -123,9 +123,8 @@ pub(crate) struct StoredRelationMetadata {
}
impl StoredRelationMetadata {
pub(crate) fn satisfied_by_required_col(&self, col: &ColumnDef, is_key: bool) -> Result<()> {
let targets = if is_key { &self.keys } else { &self.non_keys };
for target in targets {
pub(crate) fn satisfied_by_required_col(&self, col: &ColumnDef) -> Result<()> {
for target in self.keys.iter().chain(self.non_keys.iter()) {
if target.name == col.name {
return Ok(());
}
@ -140,9 +139,8 @@ impl StoredRelationMetadata {
}
Ok(())
}
pub(crate) fn compatible_with_col(&self, col: &ColumnDef, is_key: bool) -> Result<()> {
let targets = if is_key { &self.keys } else { &self.non_keys };
for target in targets {
pub(crate) fn compatible_with_col(&self, col: &ColumnDef) -> Result<()> {
for target in self.keys.iter().chain(self.non_keys.iter()) {
if target.name == col.name {
#[derive(Debug, Error, Diagnostic)]
#[error("requested column {0} has typing {1}, but the requested typing is {2}")]

@ -22,7 +22,11 @@ use thiserror::Error;
use crate::data::aggr::{parse_aggr, Aggregation};
use crate::data::expr::Expr;
use crate::data::functions::{str2vld, MAX_VALIDITY_TS};
use crate::data::program::{FixedRuleApply, FixedRuleArg, InputAtom, InputInlineRule, InputInlineRulesOrFixed, InputNamedFieldRelationApplyAtom, InputProgram, InputRelationApplyAtom, InputRuleApplyAtom, QueryAssertion, QueryOutOptions, RelationOp, SearchInput, SortDir, Unification};
use crate::data::program::{
FixedRuleApply, FixedRuleArg, InputAtom, InputInlineRule, InputInlineRulesOrFixed,
InputNamedFieldRelationApplyAtom, InputProgram, InputRelationApplyAtom, InputRuleApplyAtom,
QueryAssertion, QueryOutOptions, RelationOp, SearchInput, SortDir, Unification,
};
use crate::data::relation::{ColType, ColumnDef, NullableColType, StoredRelationMetadata};
use crate::data::symb::{Symbol, PROG_ENTRY};
use crate::data::value::{DataValue, ValidityTs};
@ -319,7 +323,14 @@ pub(crate) fn parse_query(
match args.next() {
None => stored_relation = Some(Left((name, span, op))),
Some(schema_p) => {
let (metadata, key_bindings, dep_bindings) = parse_schema(schema_p)?;
let (mut metadata, mut key_bindings, mut dep_bindings) =
parse_schema(schema_p)?;
if !matches!(op, RelationOp::Create | RelationOp::Replace) {
key_bindings.extend(dep_bindings);
dep_bindings = vec![];
metadata.keys.extend(metadata.non_keys);
metadata.non_keys = vec![];
}
stored_relation = Some(Right((
InputRelationHandle {
name,

@ -7,13 +7,14 @@
*/
use std::collections::{BTreeMap, BTreeSet};
use std::fmt::{Debug, Formatter};
use std::fmt::{Debug, Formatter, Write};
use std::iter;
use either::{Left, Right};
use itertools::Itertools;
use log::{debug, error};
use miette::{bail, Diagnostic, Result};
use smartstring::SmartString;
use thiserror::Error;
use crate::data::expr::{compute_bounds, eval_bytecode, eval_bytecode_pred, Bytecode, Expr};
@ -1027,14 +1028,14 @@ impl FtsSearchRA {
let q = match tuple[bind_idx].clone() {
DataValue::Str(s) => s,
DataValue::List(l) => {
let mut coll = String::new();
let mut coll = SmartString::new();
for d in l {
match d {
DataValue::Str(s) => {
if !coll.is_empty() {
coll += " OR ";
coll.write_str(" OR ").unwrap();
}
coll += &s
coll.write_str(&s).unwrap();
},
d => bail!("Expected string for FTS search, got {:?}", d),
}

@ -153,7 +153,6 @@ impl<'a> SessionTx<'a> {
&mut relation_store,
metadata,
key_bindings,
dep_bindings,
*span,
)?,
RelationOp::EnsureNot => self.ensure_not_in_relation(
@ -177,7 +176,6 @@ impl<'a> SessionTx<'a> {
&mut relation_store,
metadata,
key_bindings,
dep_bindings,
*span,
)?,
RelationOp::Create | RelationOp::Replace | RelationOp::Put => self.put_into_relation(
@ -243,12 +241,21 @@ impl<'a> SessionTx<'a> {
let mut new_tuples: Vec<DataValue> = vec![];
let mut old_tuples: Vec<DataValue> = vec![];
let val_extractors = make_extractors(
let val_extractors = if metadata.non_keys.is_empty() {
make_extractors(
&relation_store.metadata.non_keys,
&metadata.keys,
key_bindings,
headers,
)?
} else {
make_extractors(
&relation_store.metadata.non_keys,
&metadata.non_keys,
dep_bindings,
headers,
)?;
)?
};
key_extractors.extend(val_extractors);
let mut stack = vec![];
let hnsw_filters = Self::make_hnsw_filters(relation_store)?;
@ -499,7 +506,6 @@ impl<'a> SessionTx<'a> {
relation_store: &mut RelationHandle,
metadata: &StoredRelationMetadata,
key_bindings: &[Symbol],
dep_bindings: &[Symbol],
span: SourceSpan,
) -> Result<()> {
let is_callback_target = callback_targets.contains(&relation_store.name);
@ -531,8 +537,8 @@ impl<'a> SessionTx<'a> {
let val_extractors = make_update_extractors(
&relation_store.metadata.non_keys,
&metadata.non_keys,
dep_bindings,
&metadata.keys,
key_bindings,
headers,
);
@ -817,7 +823,6 @@ impl<'a> SessionTx<'a> {
relation_store: &mut RelationHandle,
metadata: &StoredRelationMetadata,
key_bindings: &[Symbol],
dep_bindings: &[Symbol],
span: SourceSpan,
) -> Result<()> {
if relation_store.access_level < AccessLevel::ReadOnly {
@ -837,8 +842,8 @@ impl<'a> SessionTx<'a> {
let val_extractors = make_extractors(
&relation_store.metadata.non_keys,
&metadata.non_keys,
dep_bindings,
&metadata.keys,
key_bindings,
headers,
)?;
key_extractors.extend(val_extractors);

@ -301,19 +301,16 @@ impl RelationHandle {
) -> Result<()> {
let InputRelationHandle { metadata, .. } = inp;
// check that every given key is found and compatible
for col in &metadata.keys {
self.metadata.compatible_with_col(col, true)?
}
for col in &metadata.non_keys {
self.metadata.compatible_with_col(col, false)?
for col in metadata.keys.iter().chain(self.metadata.non_keys.iter()) {
self.metadata.compatible_with_col(col)?
}
// check that every key is provided or has default
for col in &self.metadata.keys {
metadata.satisfied_by_required_col(col, true)?;
metadata.satisfied_by_required_col(col)?;
}
if !is_remove_or_update {
for col in &self.metadata.non_keys {
metadata.satisfied_by_required_col(col, false)?;
metadata.satisfied_by_required_col(col)?;
}
}
Ok(())

@ -536,7 +536,7 @@ fn test_index() {
.unwrap();
db.run_script(
r"?[fr, to, data] <- [[1,2,3],[4,5,6]] :put friends {fr, to => data}",
r"?[fr, to, data] <- [[1,2,3],[4,5,6]] :put friends {fr, to, data}",
Default::default(),
)
.unwrap();

Loading…
Cancel
Save