Simplify error propagation

next
Sayan Nandan 1 year ago
parent 1abe4a7217
commit 9ceaa54abd
No known key found for this signature in database
GPG Key ID: 42EEDF4AE9D96B54

@ -26,14 +26,14 @@
use crate::engine::{
core::{self, model::delta::DataDeltaKind},
error::{DatabaseError, DatabaseResult},
error::{Error, QueryResult},
fractal::GlobalInstanceLike,
idx::MTIndex,
ql::dml::del::DeleteStatement,
sync,
};
pub fn delete(global: &impl GlobalInstanceLike, mut delete: DeleteStatement) -> DatabaseResult<()> {
pub fn delete(global: &impl GlobalInstanceLike, mut delete: DeleteStatement) -> QueryResult<()> {
core::with_model_for_data_update(global, delete.entity(), |model| {
let g = sync::atm::cpin();
let schema_version = model.delta_state().schema_current_version();
@ -55,7 +55,7 @@ pub fn delete(global: &impl GlobalInstanceLike, mut delete: DeleteStatement) ->
);
Ok(())
}
None => Err(DatabaseError::DmlEntryNotFound),
None => Err(Error::QPDmlRowNotFound),
}
})
}

@ -30,14 +30,14 @@ use crate::engine::{
index::{DcFieldIndex, PrimaryIndexKey, Row},
model::{delta::DataDeltaKind, Fields, Model},
},
error::{DatabaseError, DatabaseResult},
error::{Error, QueryResult},
fractal::GlobalInstanceLike,
idx::{IndexBaseSpec, MTIndex, STIndex, STIndexSeq},
ql::dml::ins::{InsertData, InsertStatement},
sync::atm::cpin,
};
pub fn insert(global: &impl GlobalInstanceLike, insert: InsertStatement) -> DatabaseResult<()> {
pub fn insert(global: &impl GlobalInstanceLike, insert: InsertStatement) -> QueryResult<()> {
core::with_model_for_data_update(global, insert.entity(), |mdl| {
let irmwd = mdl.intent_write_new_data();
let (pk, data) = prepare_insert(mdl, irmwd.fields(), insert.data())?;
@ -57,7 +57,7 @@ pub fn insert(global: &impl GlobalInstanceLike, insert: InsertStatement) -> Data
);
Ok(())
} else {
Err(DatabaseError::DmlConstraintViolationDuplicate)
Err(Error::QPDmlDuplicate)
}
})
}
@ -67,7 +67,7 @@ fn prepare_insert(
model: &Model,
fields: &Fields,
insert: InsertData,
) -> DatabaseResult<(PrimaryIndexKey, DcFieldIndex)> {
) -> QueryResult<(PrimaryIndexKey, DcFieldIndex)> {
let mut okay = fields.len() == insert.column_count();
let mut prepared_data = DcFieldIndex::idx_init_cap(fields.len());
match insert {
@ -113,6 +113,6 @@ fn prepare_insert(
};
Ok((primary_key, prepared_data))
} else {
Err(DatabaseError::DmlDataValidationError)
Err(Error::QPDmlValidationError)
}
}

@ -33,7 +33,7 @@ use crate::{
engine::{
core::model::Model,
data::{lit::LitIR, spec::DataspecMeta1D, tag::DataTag},
error::{DatabaseError, DatabaseResult},
error::{Error, QueryResult},
ql::dml::WhereClause,
},
util::compiler,
@ -47,7 +47,7 @@ impl Model {
pub(self) fn resolve_where<'a>(
&self,
where_clause: &mut WhereClause<'a>,
) -> DatabaseResult<LitIR<'a>> {
) -> QueryResult<LitIR<'a>> {
match where_clause.clauses_mut().remove(self.p_key().as_bytes()) {
Some(clause)
if clause.filter_hint_none()
@ -55,7 +55,7 @@ impl Model {
{
Ok(clause.rhs())
}
_ => compiler::cold_rerr(DatabaseError::DmlWhereClauseUnindexedExpr),
_ => compiler::cold_rerr(Error::QPDmlWhereHasUnindexedColumn),
}
}
}

@ -27,7 +27,7 @@
use crate::engine::{
core::index::DcFieldIndex,
data::cell::{Datacell, VirtualDatacell},
error::{DatabaseError, DatabaseResult},
error::{Error, QueryResult},
fractal::GlobalInstanceLike,
idx::{STIndex, STIndexSeq},
ql::dml::sel::SelectStatement,
@ -38,7 +38,7 @@ pub fn select_custom<F>(
global: &impl GlobalInstanceLike,
mut select: SelectStatement,
mut cellfn: F,
) -> DatabaseResult<()>
) -> QueryResult<()>
where
F: FnMut(&Datacell),
{
@ -51,7 +51,7 @@ where
match fields.st_get(key) {
Some(dc) => cellfn(dc),
None if key == mdl.p_key() => cellfn(&pkdc),
None => return Err(DatabaseError::FieldNotFound),
None => return Err(Error::QPUnknownField),
}
Ok(())
};
@ -68,7 +68,7 @@ where
}
}
}
None => return Err(DatabaseError::DmlEntryNotFound),
None => return Err(Error::QPDmlRowNotFound),
}
Ok(())
})

@ -37,7 +37,7 @@ use {
spec::{Dataspec1D, DataspecMeta1D},
tag::{DataTag, TagClass},
},
error::{DatabaseError, DatabaseResult},
error::{Error, QueryResult},
fractal::GlobalInstanceLike,
idx::STIndex,
ql::dml::upd::{AssignmentExpression, UpdateStatement},
@ -233,7 +233,7 @@ pub fn collect_trace_path() -> Vec<&'static str> {
ROUTE_TRACE.with(|v| v.borrow().iter().cloned().collect())
}
pub fn update(global: &impl GlobalInstanceLike, mut update: UpdateStatement) -> DatabaseResult<()> {
pub fn update(global: &impl GlobalInstanceLike, mut update: UpdateStatement) -> QueryResult<()> {
core::with_model_for_data_update(global, update.entity(), |mdl| {
let mut ret = Ok(());
// prepare row fetch
@ -243,7 +243,7 @@ pub fn update(global: &impl GlobalInstanceLike, mut update: UpdateStatement) ->
// fetch row
let g = sync::atm::cpin();
let Some(row) = mdl.primary_index().select(key, &g) else {
return Err(DatabaseError::DmlEntryNotFound);
return Err(Error::QPDmlRowNotFound);
};
// lock row
let mut row_data_wl = row.d_data().write();
@ -280,7 +280,7 @@ pub fn update(global: &impl GlobalInstanceLike, mut update: UpdateStatement) ->
_ => {
input_trace("fieldnotfound");
rollback_now = true;
ret = Err(DatabaseError::FieldNotFound);
ret = Err(Error::QPUnknownField);
break;
}
}
@ -314,20 +314,20 @@ pub fn update(global: &impl GlobalInstanceLike, mut update: UpdateStatement) ->
list.push(rhs.into());
} else {
rollback_now = true;
ret = Err(DatabaseError::ServerError);
ret = Err(Error::SysOutOfMemory);
break;
}
}
} else {
input_trace("list;badtag");
rollback_now = true;
ret = Err(DatabaseError::DmlConstraintViolationFieldTypedef);
ret = Err(Error::QPDmlValidationError);
break;
}
}
_ => {
input_trace("unknown_reason;exitmainloop");
ret = Err(DatabaseError::DmlConstraintViolationFieldTypedef);
ret = Err(Error::QPDmlValidationError);
rollback_now = true;
break;
}

@ -38,7 +38,7 @@ use {
self::{model::Model, util::EntityLocator},
crate::engine::{
core::space::Space,
error::{DatabaseError, DatabaseResult},
error::{Error, QueryResult},
fractal::GlobalInstanceLike,
idx::{IndexST, STIndex},
},
@ -60,9 +60,9 @@ pub(self) fn with_model_for_data_update<'a, T, E, F>(
global: &impl GlobalInstanceLike,
entity: E,
f: F,
) -> DatabaseResult<T>
) -> QueryResult<T>
where
F: FnOnce(&Model) -> DatabaseResult<T>,
F: FnOnce(&Model) -> QueryResult<T>,
E: 'a + EntityLocator<'a>,
{
let (space_name, model_name) = entity.parse_entity()?;
@ -96,17 +96,17 @@ impl GlobalNS {
pub fn with_space<T>(
&self,
space: &str,
f: impl FnOnce(&Space) -> DatabaseResult<T>,
) -> DatabaseResult<T> {
f: impl FnOnce(&Space) -> QueryResult<T>,
) -> QueryResult<T> {
let sread = self.index_space.read();
let Some(space) = sread.st_get(space) else {
return Err(DatabaseError::DdlSpaceNotFound);
return Err(Error::QPObjectNotFound);
};
f(space)
}
pub fn with_model<'a, T, E, F>(&self, entity: E, f: F) -> DatabaseResult<T>
pub fn with_model<'a, T, E, F>(&self, entity: E, f: F) -> QueryResult<T>
where
F: FnOnce(&Model) -> DatabaseResult<T>,
F: FnOnce(&Model) -> QueryResult<T>,
E: 'a + EntityLocator<'a>,
{
entity

@ -33,7 +33,7 @@ use {
tag::{DataTag, TagClass},
DictEntryGeneric,
},
error::{DatabaseError, DatabaseResult},
error::{Error, QueryResult},
fractal::GlobalInstanceLike,
idx::{IndexST, IndexSTSeqCns, STIndex, STIndexSeq},
ql::{
@ -81,10 +81,10 @@ fn no_field(mr: &IWModel, new: &str) -> bool {
!mr.fields().st_contains(new)
}
fn check_nullable(props: &mut HashMap<Box<str>, DictEntryGeneric>) -> DatabaseResult<bool> {
fn check_nullable(props: &mut HashMap<Box<str>, DictEntryGeneric>) -> QueryResult<bool> {
match props.remove("nullable") {
Some(DictEntryGeneric::Data(b)) if b.kind() == TagClass::Bool => Ok(b.bool()),
Some(_) => Err(DatabaseError::DdlModelAlterBadProperty),
Some(_) => Err(Error::QPDdlInvalidProperties),
None => Ok(false),
}
}
@ -94,14 +94,14 @@ impl<'a> AlterPlan<'a> {
mv: &Model,
wm: &IWModel,
AlterModel { model, kind }: AlterModel<'a>,
) -> DatabaseResult<AlterPlan<'a>> {
) -> QueryResult<AlterPlan<'a>> {
let mut no_lock = true;
let mut okay = true;
let action = match kind {
AlterKind::Remove(r) => {
let mut x = HashSet::new();
if !r.iter().all(|id| x.insert(id.as_str())) {
return Err(DatabaseError::DdlModelAlterBad);
return Err(Error::QPDdlModelAlterIllegal);
}
let mut not_found = false;
if r.iter().all(|id| {
@ -112,9 +112,9 @@ impl<'a> AlterPlan<'a> {
}) {
can_ignore!(AlterAction::Remove(r))
} else if not_found {
return Err(DatabaseError::FieldNotFound);
return Err(Error::QPUnknownField);
} else {
return Err(DatabaseError::DdlModelAlterProtectedField);
return Err(Error::QPDdlModelAlterIllegal);
}
}
AlterKind::Add(new_fields) => {
@ -148,7 +148,7 @@ impl<'a> AlterPlan<'a> {
mv.guard_pk(&field_name)?;
// get the current field
let Some(current_field) = wm.fields().st_get(field_name.as_str()) else {
return Err(DatabaseError::FieldNotFound);
return Err(Error::QPUnknownField);
};
// check props
let is_nullable = check_nullable(&mut props)?;
@ -174,7 +174,7 @@ impl<'a> AlterPlan<'a> {
no_lock,
})
} else {
Err(DatabaseError::DdlModelAlterBad)
Err(Error::QPDdlModelAlterIllegal)
}
}
fn ldeltas(
@ -183,7 +183,7 @@ impl<'a> AlterPlan<'a> {
nullable: bool,
super_nlck: &mut bool,
super_okay: &mut bool,
) -> DatabaseResult<(bool, Field)> {
) -> QueryResult<(bool, Field)> {
#[inline(always)]
fn classeq(current: &Layer, new: &Layer, class: TagClass) -> bool {
// KIDDOS, LEARN SOME RELATIONS BEFORE WRITING CODE
@ -197,7 +197,7 @@ impl<'a> AlterPlan<'a> {
}
if layers.len() > current.layers().len() {
// simply a dumb tomato; ELIMINATE THESE DUMB TOMATOES
return Err(DatabaseError::DdlModelAlterBad);
return Err(Error::QPDdlModelAlterIllegal);
}
let mut no_lock = !(current.is_nullable() & !nullable);
let mut deltasize = (current.is_nullable() ^ nullable) as usize;
@ -216,7 +216,7 @@ impl<'a> AlterPlan<'a> {
// actually parse the new layer
okay &= props.is_empty();
let Some(new_parsed_layer) = Layer::get_layer(&ty) else {
return Err(DatabaseError::DdlModelAlterBadTypedef);
return Err(Error::QPDdlInvalidTypeDefinition);
};
match (
current_layer.tag.tag_selector(),
@ -233,7 +233,7 @@ impl<'a> AlterPlan<'a> {
}
_ => {
// can't cast this directly
return Err(DatabaseError::DdlModelAlterBadTypedef);
return Err(Error::QPDdlInvalidTypeDefinition);
}
}
*new_layer = new_parsed_layer;
@ -243,7 +243,7 @@ impl<'a> AlterPlan<'a> {
if okay {
Ok((deltasize != 0, new_field))
} else {
Err(DatabaseError::DdlModelAlterBad)
Err(Error::QPDdlModelAlterIllegal)
}
}
}
@ -252,7 +252,7 @@ impl Model {
pub fn transactional_exec_alter<G: GlobalInstanceLike>(
global: &G,
alter: AlterModel,
) -> DatabaseResult<()> {
) -> QueryResult<()> {
let (space_name, model_name) = EntityLocator::parse_entity(alter.model)?;
global.namespace().with_space(space_name, |space| {
space.with_model(model_name, |model| {
@ -263,7 +263,7 @@ impl Model {
// we have a legal plan; acquire exclusive if we need it
if !plan.no_lock {
// TODO(@ohsayan): allow this later on, once we define the syntax
return Err(DatabaseError::NeedLock);
return Err(Error::QPNeedLock);
}
// fine, we're good
let mut iwm = iwm;

@ -39,7 +39,7 @@ use {
tag::{DataTag, FullTag, TagClass, TagSelector},
uuid::Uuid,
},
error::{DatabaseError, DatabaseResult},
error::{Error, QueryResult},
fractal::GlobalInstanceLike,
idx::{IndexBaseSpec, IndexSTSeqCns, STIndex, STIndexSeq},
mem::VInline,
@ -132,9 +132,9 @@ impl Model {
fn not_pk(&self, new: &str) -> bool {
!self.is_pk(new)
}
fn guard_pk(&self, new: &str) -> DatabaseResult<()> {
fn guard_pk(&self, new: &str) -> QueryResult<()> {
if self.is_pk(new) {
Err(DatabaseError::DdlModelAlterProtectedField)
Err(Error::QPDdlModelAlterIllegal)
} else {
Ok(())
}
@ -169,7 +169,7 @@ impl Model {
fields,
props,
}: CreateModel,
) -> DatabaseResult<Self> {
) -> QueryResult<Self> {
let mut okay = props.is_empty() & !fields.is_empty();
// validate fields
let mut field_spec = fields.into_iter();
@ -199,7 +199,7 @@ impl Model {
return Ok(Self::new_restore(Uuid::new(), last_pk.into(), tag, fields));
}
}
Err(DatabaseError::DdlModelBadDefinition)
Err(Error::QPDdlModelBadDefinition)
}
}
@ -207,13 +207,13 @@ impl Model {
pub fn transactional_exec_create<G: GlobalInstanceLike>(
global: &G,
stmt: CreateModel,
) -> DatabaseResult<()> {
) -> QueryResult<()> {
let (space_name, model_name) = stmt.model_name.parse_entity()?;
let model = Self::process_create(stmt)?;
global.namespace().with_space(space_name, |space| {
let mut w_space = space.models().write();
if w_space.st_contains(model_name) {
return Err(DatabaseError::DdlModelAlreadyExists);
return Err(Error::QPDdlObjectAlreadyExists);
}
if G::FS_IS_NON_NULL {
// prepare txn
@ -236,12 +236,12 @@ impl Model {
pub fn transactional_exec_drop<G: GlobalInstanceLike>(
global: &G,
stmt: DropModel,
) -> DatabaseResult<()> {
) -> QueryResult<()> {
let (space_name, model_name) = stmt.entity.parse_entity()?;
global.namespace().with_space(space_name, |space| {
let mut w_space = space.models().write();
let Some(model) = w_space.get(model_name) else {
return Err(DatabaseError::DdlModelNotFound);
return Err(Error::QPObjectNotFound);
};
if G::FS_IS_NON_NULL {
// prepare txn
@ -310,7 +310,7 @@ impl Field {
pub fn layers(&self) -> &[Layer] {
&self.layers
}
pub fn parse_layers(spec: Vec<LayerSpec>, nullable: bool) -> DatabaseResult<Self> {
pub fn parse_layers(spec: Vec<LayerSpec>, nullable: bool) -> QueryResult<Self> {
let mut layers = spec.into_iter().rev();
let mut okay = true;
let mut fin = false;
@ -333,7 +333,7 @@ impl Field {
nullable,
})
} else {
Err(DatabaseError::DdlModelInvalidTypeDefinition)
Err(Error::QPDdlInvalidTypeDefinition)
}
}
#[inline(always)]

@ -28,7 +28,7 @@ use {
crate::engine::{
core::{model::Model, RWLIdx},
data::{dict, uuid::Uuid, DictEntryGeneric, DictGeneric},
error::{DatabaseError, DatabaseResult},
error::{Error, QueryResult},
fractal::GlobalInstanceLike,
idx::{IndexST, STIndex},
ql::ddl::{alt::AlterSpace, crt::CreateSpace, drop::DropSpace},
@ -99,7 +99,7 @@ impl ProcedureCreate {
}
impl Space {
pub fn _create_model(&self, name: &str, model: Model) -> DatabaseResult<()> {
pub fn _create_model(&self, name: &str, model: Model) -> QueryResult<()> {
if self
.mns
.write()
@ -107,7 +107,7 @@ impl Space {
{
Ok(())
} else {
Err(DatabaseError::DdlModelAlreadyExists)
Err(Error::QPDdlObjectAlreadyExists)
}
}
pub fn get_uuid(&self) -> Uuid {
@ -122,11 +122,11 @@ impl Space {
pub fn with_model<T>(
&self,
model: &str,
f: impl FnOnce(&Model) -> DatabaseResult<T>,
) -> DatabaseResult<T> {
f: impl FnOnce(&Model) -> QueryResult<T>,
) -> QueryResult<T> {
let mread = self.mns.read();
let Some(model) = mread.st_get(model) else {
return Err(DatabaseError::DdlModelNotFound);
return Err(Error::QPObjectNotFound);
};
f(model)
}
@ -164,7 +164,7 @@ impl Space {
space_name,
mut props,
}: CreateSpace,
) -> DatabaseResult<ProcedureCreate> {
) -> QueryResult<ProcedureCreate> {
let space_name = space_name.to_string().into_boxed_str();
// check env
let env = match props.remove(SpaceMeta::KEY_ENV) {
@ -172,7 +172,8 @@ impl Space {
Some(DictEntryGeneric::Data(l)) if l.is_null() => IndexST::default(),
None if props.is_empty() => IndexST::default(),
_ => {
return Err(DatabaseError::DdlSpaceBadProperty);
// unknown properties
return Err(Error::QPDdlInvalidProperties);
}
};
Ok(ProcedureCreate {
@ -192,13 +193,13 @@ impl Space {
pub fn transactional_exec_create<G: GlobalInstanceLike>(
global: &G,
space: CreateSpace,
) -> DatabaseResult<()> {
) -> QueryResult<()> {
// process create
let ProcedureCreate { space_name, space } = Self::process_create(space)?;
// acquire access
let mut wl = global.namespace().spaces().write();
if wl.st_contains(&space_name) {
return Err(DatabaseError::DdlSpaceAlreadyExists);
return Err(Error::QPDdlObjectAlreadyExists);
}
// commit txn
if G::FS_IS_NON_NULL {
@ -219,19 +220,19 @@ impl Space {
space_name,
updated_props,
}: AlterSpace,
) -> DatabaseResult<()> {
) -> QueryResult<()> {
global.namespace().with_space(&space_name, |space| {
match updated_props.get(SpaceMeta::KEY_ENV) {
Some(DictEntryGeneric::Map(_)) if updated_props.len() == 1 => {}
Some(DictEntryGeneric::Data(l)) if updated_props.len() == 1 && l.is_null() => {}
None if updated_props.is_empty() => return Ok(()),
_ => return Err(DatabaseError::DdlSpaceBadProperty),
_ => return Err(Error::QPDdlInvalidProperties),
}
let mut space_props = space.meta.dict().write();
// create patch
let patch = match dict::rprepare_metadata_patch(&space_props, updated_props) {
Some(patch) => patch,
None => return Err(DatabaseError::DdlSpaceBadProperty),
None => return Err(Error::QPDdlInvalidProperties),
};
if G::FS_IS_NON_NULL {
// prepare txn
@ -254,18 +255,18 @@ impl Space {
pub fn transactional_exec_drop<G: GlobalInstanceLike>(
global: &G,
DropSpace { space, force: _ }: DropSpace,
) -> DatabaseResult<()> {
) -> QueryResult<()> {
// TODO(@ohsayan): force remove option
// TODO(@ohsayan): should a drop space block the entire global table?
let space_name = space;
let mut wgns = global.namespace().spaces().write();
let space = match wgns.get(space_name.as_str()) {
Some(space) => space,
None => return Err(DatabaseError::DdlSpaceNotFound),
None => return Err(Error::QPObjectNotFound),
};
let space_w = space.mns.write();
if space_w.st_len() != 0 {
return Err(DatabaseError::DdlSpaceRemoveNonEmpty);
return Err(Error::QPDdlNotEmpty);
}
// we can remove this
if G::FS_IS_NON_NULL {

@ -29,13 +29,13 @@ use crate::engine::{
model::{alt::AlterPlan, Model},
tests::ddl_model::{create, exec_create},
},
error::DatabaseResult,
error::QueryResult,
fractal::GlobalInstanceLike,
idx::STIndex,
ql::{ast::parse_ast_node_full, ddl::alt::AlterModel, tests::lex_insecure},
};
fn with_plan(model: &str, plan: &str, f: impl Fn(AlterPlan)) -> DatabaseResult<()> {
fn with_plan(model: &str, plan: &str, f: impl Fn(AlterPlan)) -> QueryResult<()> {
let model = create(model)?;
let tok = lex_insecure(plan.as_bytes()).unwrap();
let alter = parse_ast_node_full(&tok[2..]).unwrap();
@ -52,7 +52,7 @@ fn exec_plan(
model: &str,
plan: &str,
f: impl Fn(&Model),
) -> DatabaseResult<()> {
) -> QueryResult<()> {
let mdl_name = exec_create(global, model, new_space)?;
let prev_uuid = {
let gns = global.namespace().spaces().read();
@ -77,7 +77,7 @@ mod plan {
use crate::{
engine::{
core::model::{self, alt::AlterAction, Field, Layer},
error::DatabaseError,
error::Error,
},
vecfuse,
};
@ -164,7 +164,7 @@ mod plan {
|_| {}
)
.unwrap_err(),
DatabaseError::FieldNotFound
Error::QPUnknownField
);
}
#[test]
@ -176,7 +176,7 @@ mod plan {
|_| {}
)
.unwrap_err(),
DatabaseError::DdlModelAlterProtectedField
Error::QPDdlModelAlterIllegal
);
}
#[test]
@ -188,7 +188,7 @@ mod plan {
|_| {}
)
.unwrap_err(),
DatabaseError::DdlModelAlterBad
Error::QPDdlModelAlterIllegal
);
}
#[test]
@ -200,7 +200,7 @@ mod plan {
|_| {}
)
.unwrap_err(),
DatabaseError::DdlModelAlterBad
Error::QPDdlModelAlterIllegal
);
}
#[test]
@ -212,7 +212,7 @@ mod plan {
|_| {}
)
.unwrap_err(),
DatabaseError::DdlModelAlterProtectedField
Error::QPDdlModelAlterIllegal
);
}
#[test]
@ -224,7 +224,7 @@ mod plan {
|_| {}
)
.unwrap_err(),
DatabaseError::FieldNotFound
Error::QPUnknownField
);
}
fn bad_type_cast(orig_ty: &str, new_ty: &str) {
@ -235,7 +235,7 @@ mod plan {
super::with_plan(&create, &alter, |_| {}).expect_err(&format!(
"found no error in transformation: {orig_ty} -> {new_ty}"
)),
DatabaseError::DdlModelAlterBadTypedef,
Error::QPDdlInvalidTypeDefinition,
"failed to match error in transformation: {orig_ty} -> {new_ty}",
)
}
@ -353,7 +353,7 @@ mod plan {
mod exec {
use crate::engine::{
core::model::{DeltaVersion, Field, Layer},
error::DatabaseError,
error::Error,
fractal::test_utils::TestGlobal,
idx::{STIndex, STIndexSeq},
};
@ -445,7 +445,7 @@ mod exec {
|_| {},
)
.unwrap_err(),
DatabaseError::NeedLock
Error::QPNeedLock
);
}
}

@ -30,7 +30,7 @@ mod validation {
crate::engine::{
core::model::{DeltaVersion, Field, Layer},
data::tag::{DataTag, FullTag},
error::DatabaseError,
error::Error,
idx::STIndexSeq,
},
};
@ -89,7 +89,7 @@ mod validation {
"create model mymodel(primary username: string, primary contract_location: binary)"
)
.unwrap_err(),
DatabaseError::DdlModelBadDefinition
Error::QPDdlModelBadDefinition
);
}
@ -97,7 +97,7 @@ mod validation {
fn duplicate_fields() {
assert_eq!(
create("create model mymodel(primary username: string, username: binary)").unwrap_err(),
DatabaseError::DdlModelBadDefinition
Error::QPDdlModelBadDefinition
);
}
@ -105,7 +105,7 @@ mod validation {
fn illegal_props() {
assert_eq!(
create("create model mymodel(primary username: string, password: binary) with { lol_prop: false }").unwrap_err(),
DatabaseError::DdlModelBadDefinition
Error::QPDdlModelBadDefinition
);
}
@ -116,12 +116,12 @@ mod validation {
"create model mymodel(primary username_bytes: list { type: uint8 }, password: binary)"
)
.unwrap_err(),
DatabaseError::DdlModelBadDefinition
Error::QPDdlModelBadDefinition
);
assert_eq!(
create("create model mymodel(primary username: float32, password: binary)")
.unwrap_err(),
DatabaseError::DdlModelBadDefinition
Error::QPDdlModelBadDefinition
);
}
}

@ -26,23 +26,23 @@
use crate::engine::{
core::model::Field,
error::DatabaseResult,
error::QueryResult,
ql::{ast::parse_ast_node_multiple_full, tests::lex_insecure},
};
fn layerview_nullable(layer_def: &str, nullable: bool) -> DatabaseResult<Field> {
fn layerview_nullable(layer_def: &str, nullable: bool) -> QueryResult<Field> {
let tok = lex_insecure(layer_def.as_bytes()).unwrap();
let spec = parse_ast_node_multiple_full(&tok).unwrap();
Field::parse_layers(spec, nullable)
}
fn layerview(layer_def: &str) -> DatabaseResult<Field> {
fn layerview(layer_def: &str) -> QueryResult<Field> {
layerview_nullable(layer_def, false)
}
mod layer_spec_validation {
use {
super::layerview,
crate::engine::{core::model::Layer, error::DatabaseError},
crate::engine::{core::model::Layer, error::Error},
};
#[test]
@ -64,7 +64,7 @@ mod layer_spec_validation {
fn invalid_list() {
assert_eq!(
layerview("list").unwrap_err(),
DatabaseError::DdlModelInvalidTypeDefinition
Error::QPDdlInvalidTypeDefinition
);
}
@ -72,7 +72,7 @@ mod layer_spec_validation {
fn invalid_flat() {
assert_eq!(
layerview("string { type: string }").unwrap_err(),
DatabaseError::DdlModelInvalidTypeDefinition
Error::QPDdlInvalidTypeDefinition
);
}
}

@ -30,7 +30,7 @@ mod layer;
use crate::engine::{
core::{model::Model, space::Space},
error::DatabaseResult,
error::QueryResult,
fractal::GlobalInstanceLike,
idx::STIndex,
ql::{
@ -40,7 +40,7 @@ use crate::engine::{
},
};
fn create(s: &str) -> DatabaseResult<Model> {
fn create(s: &str) -> QueryResult<Model> {
let tok = lex_insecure(s.as_bytes()).unwrap();
let create_model = parse_ast_node_full(&tok[2..]).unwrap();
Model::process_create(create_model)
@ -50,7 +50,7 @@ pub fn exec_create(
global: &impl GlobalInstanceLike,
create_stmt: &str,
create_new_space: bool,
) -> DatabaseResult<String> {
) -> QueryResult<String> {
let tok = lex_insecure(create_stmt.as_bytes()).unwrap();
let create_model = parse_ast_node_full::<CreateModel>(&tok[2..]).unwrap();
let name = match create_model.model_name {
@ -67,14 +67,14 @@ pub fn exec_create(
pub fn exec_create_new_space(
global: &impl GlobalInstanceLike,
create_stmt: &str,
) -> DatabaseResult<()> {
) -> QueryResult<()> {
exec_create(global, create_stmt, true).map(|_| ())
}
pub fn exec_create_no_create(
global: &impl GlobalInstanceLike,
create_stmt: &str,
) -> DatabaseResult<()> {
) -> QueryResult<()> {
exec_create(global, create_stmt, false).map(|_| ())
}

@ -27,7 +27,7 @@
use crate::engine::{
core::space::{Space, SpaceMeta},
data::cell::Datacell,
error::DatabaseError,
error::Error,
fractal::test_utils::TestGlobal,
};
@ -122,7 +122,7 @@ fn alter_nx() {
|_| {},
)
.unwrap_err(),
DatabaseError::DdlSpaceNotFound
Error::QPObjectNotFound
);
}

@ -27,7 +27,7 @@
use crate::engine::{
core::space::{Space, SpaceMeta},
data::cell::Datacell,
error::DatabaseError,
error::Error,
fractal::test_utils::TestGlobal,
};
@ -73,7 +73,7 @@ fn exec_create_space_with_bad_env_type() {
let global = TestGlobal::new_with_tmp_nullfs_driver();
assert_eq!(
super::exec_create(&global, "create space myspace with { env: 100 }", |_| {}).unwrap_err(),
DatabaseError::DdlSpaceBadProperty
Error::QPDdlInvalidProperties
);
}
@ -87,6 +87,6 @@ fn exec_create_space_with_random_property() {
|_| {}
)
.unwrap_err(),
DatabaseError::DdlSpaceBadProperty
Error::QPDdlInvalidProperties
);
}

@ -30,7 +30,7 @@ mod create;
use crate::engine::{
core::space::Space,
data::uuid::Uuid,
error::DatabaseResult,
error::QueryResult,
fractal::GlobalInstanceLike,
ql::{
ast::{self},
@ -42,7 +42,7 @@ fn exec_create(
gns: &impl GlobalInstanceLike,
create: &str,
verify: impl Fn(&Space),
) -> DatabaseResult<Uuid> {
) -> QueryResult<Uuid> {
let tok = lex(create.as_bytes()).unwrap();
let ast_node =
ast::parse_ast_node_full::<crate::engine::ql::ddl::crt::CreateSpace>(&tok[2..]).unwrap();
@ -58,7 +58,7 @@ fn exec_alter(
gns: &impl GlobalInstanceLike,
alter: &str,
verify: impl Fn(&Space),
) -> DatabaseResult<Uuid> {
) -> QueryResult<Uuid> {
let tok = lex(alter.as_bytes()).unwrap();
let ast_node =
ast::parse_ast_node_full::<crate::engine::ql::ddl::alt::AlterSpace>(&tok[2..]).unwrap();
@ -75,7 +75,7 @@ fn exec_create_alter(
crt: &str,
alt: &str,
verify_post_alt: impl Fn(&Space),
) -> DatabaseResult<Uuid> {
) -> QueryResult<Uuid> {
let uuid_crt = exec_create(gns, crt, |_| {})?;
let uuid_alt = exec_alter(gns, alt, verify_post_alt)?;
assert_eq!(uuid_crt, uuid_alt);

@ -24,7 +24,7 @@
*
*/
use crate::engine::{error::DatabaseError, fractal::test_utils::TestGlobal};
use crate::engine::{error::Error, fractal::test_utils::TestGlobal};
#[test]
fn simple_delete() {
@ -51,6 +51,6 @@ fn delete_nonexisting() {
"sayan",
)
.unwrap_err(),
DatabaseError::DmlEntryNotFound
Error::QPDmlRowNotFound
);
}

@ -24,7 +24,7 @@
*
*/
use crate::engine::{data::cell::Datacell, error::DatabaseError, fractal::test_utils::TestGlobal};
use crate::engine::{data::cell::Datacell, error::Error, fractal::test_utils::TestGlobal};
#[derive(sky_macros::Wrapper, Debug)]
struct Tuple(Vec<(Box<str>, Datacell)>);
@ -83,6 +83,6 @@ fn insert_duplicate() {
assert_eq!(
super::exec_insert_only(&global, "insert into myspace.mymodel('sayan', 'pass123')")
.unwrap_err(),
DatabaseError::DmlConstraintViolationDuplicate
Error::QPDmlDuplicate
);
}

@ -32,7 +32,7 @@ mod update;
use crate::engine::{
core::{dml, index::Row, model::Model},
data::{cell::Datacell, lit::LitIR},
error::DatabaseResult,
error::QueryResult,
fractal::GlobalInstanceLike,
ql::{
ast::{parse_ast_node_full, Entity},
@ -42,10 +42,7 @@ use crate::engine::{
sync,
};
fn _exec_only_create_space_model(
global: &impl GlobalInstanceLike,
model: &str,
) -> DatabaseResult<()> {
fn _exec_only_create_space_model(global: &impl GlobalInstanceLike, model: &str) -> QueryResult<()> {
if !global.namespace().spaces().read().contains_key("myspace") {
global.namespace().test_new_empty_space("myspace");
}
@ -58,7 +55,7 @@ fn _exec_only_insert<T>(
global: &impl GlobalInstanceLike,
insert: &str,
and_then: impl Fn(Entity) -> T,
) -> DatabaseResult<T> {
) -> QueryResult<T> {
let lex_insert = lex_insecure(insert.as_bytes()).unwrap();
let stmt_insert = parse_ast_node_full::<InsertStatement>(&lex_insert[1..]).unwrap();
let entity = stmt_insert.entity();
@ -72,7 +69,7 @@ fn _exec_only_read_key_and_then<T>(
entity: Entity,
key_name: &str,
and_then: impl Fn(Row) -> T,
) -> DatabaseResult<T> {
) -> QueryResult<T> {
let guard = sync::atm::cpin();
global.namespace().with_model(entity, |mdl| {
let _irm = mdl.intent_read_model();
@ -86,11 +83,7 @@ fn _exec_only_read_key_and_then<T>(
})
}
fn _exec_delete_only(
global: &impl GlobalInstanceLike,
delete: &str,
key: &str,
) -> DatabaseResult<()> {
fn _exec_delete_only(global: &impl GlobalInstanceLike, delete: &str, key: &str) -> QueryResult<()> {
let lex_del = lex_insecure(delete.as_bytes()).unwrap();
let delete = parse_ast_node_full::<DeleteStatement>(&lex_del[1..]).unwrap();
let entity = delete.entity();
@ -106,10 +99,7 @@ fn _exec_delete_only(
Ok(())
}
fn _exec_only_select(
global: &impl GlobalInstanceLike,
select: &str,
) -> DatabaseResult<Vec<Datacell>> {
fn _exec_only_select(global: &impl GlobalInstanceLike, select: &str) -> QueryResult<Vec<Datacell>> {
let lex_sel = lex_insecure(select.as_bytes()).unwrap();
let select = parse_ast_node_full(&lex_sel[1..]).unwrap();
let mut r = Vec::new();
@ -117,7 +107,7 @@ fn _exec_only_select(
Ok(r)
}
fn _exec_only_update(global: &impl GlobalInstanceLike, update: &str) -> DatabaseResult<()> {
fn _exec_only_update(global: &impl GlobalInstanceLike, update: &str) -> QueryResult<()> {
let lex_upd = lex_insecure(update.as_bytes()).unwrap();
let update = parse_ast_node_full(&lex_upd[1..]).unwrap();
dml::update(global, update)
@ -129,17 +119,14 @@ pub(self) fn exec_insert<T: Default>(
insert: &str,
key_name: &str,
f: impl Fn(Row) -> T,
) -> DatabaseResult<T> {
) -> QueryResult<T> {
_exec_only_create_space_model(global, model)?;
_exec_only_insert(global, insert, |entity| {
_exec_only_read_key_and_then(global, entity, key_name, |row| f(row))
})?
}
pub(self) fn exec_insert_only(
global: &impl GlobalInstanceLike,
insert: &str,
) -> DatabaseResult<()> {
pub(self) fn exec_insert_only(global: &impl GlobalInstanceLike, insert: &str) -> QueryResult<()> {
_exec_only_insert(global, insert, |_| {})
}
@ -149,7 +136,7 @@ pub(self) fn exec_delete(
insert: Option<&str>,
delete: &str,
key: &str,
) -> DatabaseResult<()> {
) -> QueryResult<()> {
_exec_only_create_space_model(global, model)?;
if let Some(insert) = insert {
_exec_only_insert(global, insert, |_| {})?;
@ -162,7 +149,7 @@ pub(self) fn exec_select(
model: &str,
insert: &str,
select: &str,
) -> DatabaseResult<Vec<Datacell>> {
) -> QueryResult<Vec<Datacell>> {
_exec_only_create_space_model(global, model)?;
_exec_only_insert(global, insert, |_| {})?;
_exec_only_select(global, select)
@ -171,7 +158,7 @@ pub(self) fn exec_select(
pub(self) fn exec_select_only(
global: &impl GlobalInstanceLike,
select: &str,
) -> DatabaseResult<Vec<Datacell>> {
) -> QueryResult<Vec<Datacell>> {
_exec_only_select(global, select)
}
@ -181,7 +168,7 @@ pub(self) fn exec_update(
insert: &str,
update: &str,
select: &str,
) -> DatabaseResult<Vec<Datacell>> {
) -> QueryResult<Vec<Datacell>> {
_exec_only_create_space_model(global, model)?;
_exec_only_insert(global, insert, |_| {})?;
_exec_only_update(global, update)?;

@ -24,7 +24,7 @@
*
*/
use crate::engine::{data::cell::Datacell, error::DatabaseError, fractal::test_utils::TestGlobal};
use crate::engine::{data::cell::Datacell, error::Error, fractal::test_utils::TestGlobal};
#[test]
fn simple_select_wildcard() {
@ -97,6 +97,6 @@ fn select_nonexisting() {
"select username, password from myspace.mymodel where username = 'notsayan'",
)
.unwrap_err(),
DatabaseError::DmlEntryNotFound
Error::QPDmlRowNotFound
);
}

@ -25,7 +25,7 @@
*/
use crate::engine::{
core::dml, data::cell::Datacell, error::DatabaseError, fractal::test_utils::TestGlobal,
core::dml, data::cell::Datacell, error::Error, fractal::test_utils::TestGlobal,
};
#[test]
@ -96,7 +96,7 @@ fn fail_operation_on_null() {
"select * from myspace.mymodel where username='sayan'"
)
.unwrap_err(),
DatabaseError::DmlConstraintViolationFieldTypedef
Error::QPDmlValidationError
);
assert_eq!(
dml::update_flow_trace(),
@ -116,7 +116,7 @@ fn fail_unknown_fields() {
"select * from myspace.mymodel where username='sayan'"
)
.unwrap_err(),
DatabaseError::FieldNotFound
Error::QPUnknownField
);
assert_eq!(dml::update_flow_trace(), ["fieldnotfound", "rollback"]);
// verify integrity
@ -142,7 +142,7 @@ fn fail_typedef_violation() {
"select * from myspace.mymodel where username = 'sayan'"
)
.unwrap_err(),
DatabaseError::DmlConstraintViolationFieldTypedef
Error::QPDmlValidationError
);
assert_eq!(
dml::update_flow_trace(),

@ -25,27 +25,27 @@
*/
use crate::engine::{
error::{DatabaseError, DatabaseResult},
error::{Error, QueryResult},
ql::ast::Entity,
};
pub trait EntityLocator<'a> {
fn parse_entity(self) -> DatabaseResult<(&'a str, &'a str)>
fn parse_entity(self) -> QueryResult<(&'a str, &'a str)>
where
Self: 'a;
}
impl<'a> EntityLocator<'a> for (&'a str, &'a str) {
fn parse_entity(self) -> DatabaseResult<(&'a str, &'a str)> {
fn parse_entity(self) -> QueryResult<(&'a str, &'a str)> {
Ok(self)
}
}
impl<'a> EntityLocator<'a> for Entity<'a> {
fn parse_entity(self) -> DatabaseResult<(&'a str, &'a str)>
fn parse_entity(self) -> QueryResult<(&'a str, &'a str)>
where
Self: 'a,
{
self.into_full_str().ok_or(DatabaseError::ExpectedEntity)
self.into_full_str().ok_or(Error::QPExpectedEntity)
}
}

@ -25,129 +25,79 @@
*/
use super::{storage::v1::SDSSError, txn::TransactionError};
pub type QueryResult<T> = Result<T, Error>;
pub type LangResult<T> = Result<T, LangError>;
pub type LexResult<T> = Result<T, LexError>;
pub type DatabaseResult<T> = Result<T, DatabaseError>;
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[repr(u8)]
/// Lex phase errors
pub enum LexError {
// insecure lex
/// Invalid signed numeric literal
InvalidSignedNumericLit,
/// Invalid unsigned literal
InvalidUnsignedLiteral,
/// Invaid binary literal
InvalidBinaryLiteral,
/// Invalid string literal
InvalidStringLiteral,
// secure lex
/// Dataframe params are invalid
BadPframe,
// generic
/// Unrecognized byte in stream
UnexpectedByte,
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[repr(u8)]
/// AST errors
pub enum LangError {
// generic
/// Unexpected end of syntax
UnexpectedEOS,
/// Last resort error kind when error specificity is hard to trace
BadSyntax,
/// Expected a token that defines a statement, found something else
ExpectedStatement,
// ast nodes: usually parents at heigher hights
/// Expected an entity, but found invalid tokens
ExpectedEntity,
// ast nodes: usually children wrt height
/// Bad syn tymeta element
SynBadTyMeta,
/// Bad syn map element
SynBadMap,
/// Bad expr: relational
ExprBadRel,
// ast nodes: usually the root
/// Unknown `create` statement
StmtUnknownCreate,
/// Unknown `alter` statement
StmtUnknownAlter,
/// unknown `drop` statement
StmtUnknownDrop,
}
#[derive(Debug)]
#[repr(u8)]
#[cfg_attr(test, derive(PartialEq))]
/// Executor errors
pub enum DatabaseError {
// sys
SysBadItemID,
// query generic
/// this needs an explicit lock
NeedLock,
/// expected a full entity, but found a single implicit entity
ExpectedEntity,
// ddl
/// unknown property or bad type for property
DdlSpaceBadProperty,
/// the space already exists
DdlSpaceAlreadyExists,
/// the space doesn't exist
DdlSpaceNotFound,
/// the space that we attempted to remove is non-empty
DdlSpaceRemoveNonEmpty,
/// bad definition for some typedef in a model
DdlModelInvalidTypeDefinition,
/// bad model definition; most likely an illegal primary key
DdlModelBadDefinition,
/// the model already exists
DdlModelAlreadyExists,
/// an alter attempted to remove a protected field (usually the primary key)
DdlModelAlterProtectedField,
/// an alter model attempted to modify an invalid property/a property with an illegal value
DdlModelAlterBadProperty,
/// the alter model statement is "wrong"
DdlModelAlterBad,
/// an alter attempted to update an nx field
FieldNotFound,
/// bad type definition to alter
DdlModelAlterBadTypedef,
/// didn't find the model
DdlModelNotFound,
/// attempted a remove, but the model view is nonempty
DdlModelViewNotEmpty,
// dml
/// Duplicate
DmlConstraintViolationDuplicate,
/// data validation error
DmlDataValidationError,
/// The expression in a where clause is not indexed (in the way the expression expects it to be)
DmlWhereClauseUnindexedExpr,
/// The entry was not found
DmlEntryNotFound,
/// illegal data
DmlIllegalData,
/// field definition violation
DmlConstraintViolationFieldTypedef,
ServerError,
/// an enumeration of 'flat' errors that the server actually responds to the client with, since we do not want to send specific information
/// about anything (as that will be a security hole). The variants correspond with their actual response codes
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Error {
/// I/O error
SysIOError,
/// out of memory
SysOutOfMemory,
/// unknown server error
SysUnknownError,
/// invalid protocol packet
NetProtocolIllegalPacket,
/// something like an integer that randomly has a character to attached to it like `1234q`
LexInvalidLiteral,
/// something like an invalid 'string" or a safe string with a bad length etc
LexInvalidEscapedLiteral,
/// unexpected byte
LexUnexpectedByte,
/// expected a longer statement
QLUnexpectedEndOfStatement,
/// incorrect syntax for "something"
QLInvalidSyntax,
/// expected a statement keyword found something else
QLExpectedStatement,
/// invalid collection definition definition
QLInvalidCollectionSyntax,
/// invalid type definition syntax
QLInvalidTypeDefinitionSyntax,
/// invalid relational expression
QLIllegalRelExp,
/// expected a full entity definition
QPExpectedEntity,
/// expected a statement, found something else
QPExpectedStatement,
/// unknown statement
QPUnknownStatement,
/// this query needs a lock for execution, but that wasn't explicitly allowed anywhere
QPNeedLock,
/// the object to be used as the "query container" is missing (for example, insert when the model was missing)
QPObjectNotFound,
/// an unknown field was attempted to be accessed/modified/...
QPUnknownField,
/// invalid property for an object
QPDdlInvalidProperties,
/// create space/model, but the object already exists
QPDdlObjectAlreadyExists,
/// an object that was attempted to be removed is non-empty, and for this object, removals require it to be empty
QPDdlNotEmpty,
/// invalid type definition
QPDdlInvalidTypeDefinition,
/// bad model definition
QPDdlModelBadDefinition,
/// illegal alter model query
QPDdlModelAlterIllegal,
/// violated the uniqueness property
QPDmlDuplicate,
/// the data could not be validated for being accepted into a field/function/etc.
QPDmlValidationError,
/// the where expression has an unindexed column essentially implying that we can't run this query because of perf concerns
QPDmlWhereHasUnindexedColumn,
/// the row matching the given match expression was not found
QPDmlRowNotFound,
/// transactional error
TransactionalError,
StorageSubsystemErr(SDSSError),
}
impl From<SDSSError> for DatabaseError {
fn from(e: SDSSError) -> Self {
Self::StorageSubsystemErr(e)
}
/// storage subsystem error
StorageSubsystemError,
}
impl From<TransactionError> for DatabaseError {
fn from(_: TransactionError) -> Self {
Self::TransactionalError
direct_from! {
Error[_] => {
SDSSError as StorageSubsystemError,
TransactionError as TransactionalError,
}
}

@ -290,7 +290,7 @@ impl FractalMgr {
model: &Model,
observed_size: usize,
mdl_driver: &super::FractalModelDriver,
) -> Result<(), crate::engine::error::DatabaseError> {
) -> crate::engine::error::QueryResult<()> {
if observed_size == 0 {
// no changes, all good
return Ok(());

@ -60,6 +60,9 @@ macro_rules! direct_from {
($for:ty => {$($other:ty as $me:ident),*$(,)?}) => {
$(impl ::core::convert::From<$other> for $for {fn from(v: $other) -> Self {Self::$me(v.into())}})*
};
($for:ty[_] => {$($other:ty as $me:ident),*$(,)?}) => {
$(impl ::core::convert::From<$other> for $for {fn from(_: $other) -> Self {Self::$me}})*
};
}
#[allow(unused_macros)]

@ -37,7 +37,7 @@ use {
crate::{
engine::{
data::{cell::Datacell, lit::LitIR},
error::{LangError, LangResult},
error::{Error, QueryResult},
},
util::{compiler, MaybeInit},
},
@ -443,7 +443,7 @@ impl<'a> Entity<'a> {
#[inline(always)]
/// Attempt to parse an entity using the given token stream. It also accepts a counter
/// argument to forward the cursor
pub fn parse_from_tokens_len_checked(tok: &'a [Token], c: &mut usize) -> LangResult<Self> {
pub fn parse_from_tokens_len_checked(tok: &'a [Token], c: &mut usize) -> QueryResult<Self> {
let is_current = Self::signature_matches_single_len_checked(tok);
let is_full = Self::signature_matches_full_len_checked(tok);
let r = match () {
@ -457,14 +457,14 @@ impl<'a> Entity<'a> {
*c += 1;
Self::parse_uck_tokens_single(tok)
},
_ => return Err(LangError::ExpectedEntity),
_ => return Err(Error::QPExpectedEntity),
};
Ok(r)
}
#[inline(always)]
pub fn parse_from_state_rounded_result<Qd: QueryData<'a>>(
state: &mut State<'a, Qd>,
) -> LangResult<Self> {
) -> QueryResult<Self> {
let mut e = MaybeInit::uninit();
Self::parse_from_state_rounded(state, &mut e);
if compiler::likely(state.okay()) {
@ -473,7 +473,7 @@ impl<'a> Entity<'a> {
Ok(e.assume_init())
}
} else {
Err(LangError::ExpectedEntity)
Err(Error::QPExpectedEntity)
}
}
#[inline(always)]
@ -560,14 +560,14 @@ pub enum Statement<'a> {
}
#[cfg(test)]
pub fn compile_test<'a>(tok: &'a [Token<'a>]) -> LangResult<Statement<'a>> {
pub fn compile_test<'a>(tok: &'a [Token<'a>]) -> QueryResult<Statement<'a>> {
self::compile(tok, InplaceData::new())
}
#[inline(always)]
pub fn compile<'a, Qd: QueryData<'a>>(tok: &'a [Token<'a>], d: Qd) -> LangResult<Statement<'a>> {
pub fn compile<'a, Qd: QueryData<'a>>(tok: &'a [Token<'a>], d: Qd) -> QueryResult<Statement<'a>> {
if compiler::unlikely(tok.len() < 2) {
return Err(LangError::UnexpectedEOS);
return Err(Error::QLUnexpectedEndOfStatement);
}
let mut state = State::new(tok, d);
match state.fw_read() {
@ -576,12 +576,12 @@ pub fn compile<'a, Qd: QueryData<'a>>(tok: &'a [Token<'a>], d: Qd) -> LangResult
Token![create] => match state.fw_read() {
Token![model] => ASTNode::from_state(&mut state).map(Statement::CreateModel),
Token![space] => ASTNode::from_state(&mut state).map(Statement::CreateSpace),
_ => compiler::cold_rerr(LangError::StmtUnknownCreate),
_ => compiler::cold_rerr(Error::QPUnknownStatement),
},
Token![alter] => match state.fw_read() {
Token![model] => ASTNode::from_state(&mut state).map(Statement::AlterModel),
Token![space] => ASTNode::from_state(&mut state).map(Statement::AlterSpace),
_ => compiler::cold_rerr(LangError::StmtUnknownAlter),
_ => compiler::cold_rerr(Error::QPUnknownStatement),
},
Token![drop] if state.remaining() >= 2 => ddl::drop::parse_drop(&mut state),
Token::Ident(id) if id.eq_ignore_ascii_case("inspect") => {
@ -592,6 +592,6 @@ pub fn compile<'a, Qd: QueryData<'a>>(tok: &'a [Token<'a>], d: Qd) -> LangResult
Token![select] => ASTNode::from_state(&mut state).map(Statement::Select),
Token![update] => ASTNode::from_state(&mut state).map(Statement::Update),
Token![delete] => ASTNode::from_state(&mut state).map(Statement::Delete),
_ => compiler::cold_rerr(LangError::ExpectedStatement),
_ => compiler::cold_rerr(Error::QPUnknownStatement),
}
}

@ -27,7 +27,7 @@
#[cfg(test)]
use crate::engine::ql::{ast::InplaceData, lex::Token};
use crate::engine::{
error::{LangError, LangResult},
error::{Error, QueryResult},
ql::ast::{QueryData, State},
};
@ -40,38 +40,38 @@ pub trait ASTNode<'a>: Sized {
/// - If the implementor uses a cow style parse, then set [`ASTNode::VERIFY`] to
/// true
/// - Try to propagate errors via [`State`] if possible
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self>;
fn from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self>;
fn from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
let r = <Self as ASTNode>::_from_state(state);
if Self::VERIFY {
return if state.okay() {
r
} else {
Err(LangError::BadSyntax)
Err(Error::QLInvalidSyntax)
};
}
r
}
#[cfg(test)]
/// Parse multiple nodes of this AST node type. Intended for the test suite.
fn _multiple_from_state<Qd: QueryData<'a>>(_: &mut State<'a, Qd>) -> LangResult<Vec<Self>> {
fn _multiple_from_state<Qd: QueryData<'a>>(_: &mut State<'a, Qd>) -> QueryResult<Vec<Self>> {
unimplemented!()
}
#[cfg(test)]
fn multiple_from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Vec<Self>> {
fn multiple_from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Vec<Self>> {
let r = <Self as ASTNode>::_multiple_from_state(state);
if Self::VERIFY {
return if state.okay() {
r
} else {
Err(LangError::BadSyntax)
Err(Error::QLInvalidSyntax)
};
}
r
}
#[cfg(test)]
/// Parse this AST node utilizing the full token-stream. Intended for the test suite.
fn from_insecure_tokens_full(tok: &'a [Token<'a>]) -> LangResult<Self> {
fn from_insecure_tokens_full(tok: &'a [Token<'a>]) -> QueryResult<Self> {
let mut state = State::new(tok, InplaceData::new());
let r = <Self as ASTNode>::from_state(&mut state)?;
assert!(state.exhausted());
@ -80,24 +80,24 @@ pub trait ASTNode<'a>: Sized {
#[cfg(test)]
/// Parse multiple nodes of this AST node type, utilizing the full token stream.
/// Intended for the test suite.
fn multiple_from_insecure_tokens_full(tok: &'a [Token<'a>]) -> LangResult<Vec<Self>> {
fn multiple_from_insecure_tokens_full(tok: &'a [Token<'a>]) -> QueryResult<Vec<Self>> {
let mut state = State::new(tok, InplaceData::new());
let r = Self::multiple_from_state(&mut state);
if state.exhausted() && state.okay() {
r
} else {
Err(LangError::BadSyntax)
Err(Error::QLInvalidSyntax)
}
}
}
#[cfg(test)]
pub fn parse_ast_node_full<'a, N: ASTNode<'a>>(tok: &'a [Token<'a>]) -> LangResult<N> {
pub fn parse_ast_node_full<'a, N: ASTNode<'a>>(tok: &'a [Token<'a>]) -> QueryResult<N> {
N::from_insecure_tokens_full(tok)
}
#[cfg(test)]
pub fn parse_ast_node_multiple_full<'a, N: ASTNode<'a>>(
tok: &'a [Token<'a>],
) -> LangResult<Vec<N>> {
) -> QueryResult<Vec<N>> {
N::multiple_from_insecure_tokens_full(tok)
}

@ -29,7 +29,7 @@ use {
crate::{
engine::{
data::DictGeneric,
error::{LangError, LangResult},
error::{Error, QueryResult},
ql::{
ast::{Entity, QueryData, State},
lex::{Ident, Token},
@ -55,9 +55,9 @@ impl<'a> AlterSpace<'a> {
}
#[inline(always)]
/// Parse alter space from tokens
fn parse<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn parse<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
if compiler::unlikely(state.remaining() <= 3) {
return compiler::cold_rerr(LangError::UnexpectedEOS);
return compiler::cold_rerr(Error::QLUnexpectedEndOfStatement);
}
let space_name = state.fw_read();
state.poison_if_not(space_name.is_ident());
@ -67,7 +67,7 @@ impl<'a> AlterSpace<'a> {
state.cursor_ahead(); // ignore errors
if compiler::unlikely(!state.okay()) {
return Err(LangError::BadSyntax);
return Err(Error::QLInvalidSyntax);
}
let space_name = unsafe {
@ -82,7 +82,7 @@ impl<'a> AlterSpace<'a> {
updated_props: d,
})
} else {
Err(LangError::SynBadMap)
Err(Error::QLInvalidCollectionSyntax)
}
}
}
@ -111,10 +111,10 @@ pub enum AlterKind<'a> {
impl<'a> AlterModel<'a> {
#[inline(always)]
/// Parse an [`AlterKind`] from the given token stream
fn parse<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn parse<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
// alter model mymodel remove x
if state.remaining() <= 2 || !state.cursor_has_ident_rounded() {
return compiler::cold_rerr(LangError::BadSyntax);
return compiler::cold_rerr(Error::QLInvalidSyntax);
// FIXME(@ohsayan): bad because no specificity
}
let model_name = Entity::parse_from_state_rounded_result(state)?;
@ -122,7 +122,7 @@ impl<'a> AlterModel<'a> {
Token![add] => AlterKind::alter_add(state),
Token![remove] => AlterKind::alter_remove(state),
Token![update] => AlterKind::alter_update(state),
_ => Err(LangError::ExpectedStatement),
_ => Err(Error::QPExpectedStatement),
};
kind.map(|kind| AlterModel::new(model_name, kind))
}
@ -131,24 +131,24 @@ impl<'a> AlterModel<'a> {
impl<'a> AlterKind<'a> {
#[inline(always)]
/// Parse the expression for `alter model <> add (..)`
fn alter_add<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn alter_add<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
ExpandedField::parse_multiple(state).map(Self::Add)
}
#[inline(always)]
/// Parse the expression for `alter model <> add (..)`
fn alter_update<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn alter_update<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
ExpandedField::parse_multiple(state).map(Self::Update)
}
#[inline(always)]
/// Parse the expression for `alter model <> remove (..)`
fn alter_remove<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn alter_remove<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
const DEFAULT_REMOVE_COL_CNT: usize = 4;
/*
WARNING: No trailing commas allowed
<remove> ::= <ident> | <openparen> (<ident> <comma>)*<closeparen>
*/
if compiler::unlikely(state.exhausted()) {
return compiler::cold_rerr(LangError::UnexpectedEOS);
return compiler::cold_rerr(Error::QLUnexpectedEndOfStatement);
}
let r = match state.fw_read() {
@ -177,10 +177,10 @@ impl<'a> AlterKind<'a> {
if state.okay() {
cols.into_boxed_slice()
} else {
return Err(LangError::BadSyntax);
return Err(Error::QLInvalidSyntax);
}
}
_ => return Err(LangError::BadSyntax),
_ => return Err(Error::QLInvalidSyntax),
};
Ok(Self::Remove(r))
}
@ -190,17 +190,17 @@ mod impls {
use {
super::{AlterModel, AlterSpace},
crate::engine::{
error::LangResult,
error::QueryResult,
ql::ast::{traits::ASTNode, QueryData, State},
},
};
impl<'a> ASTNode<'a> for AlterModel<'a> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
Self::parse(state)
}
}
impl<'a> ASTNode<'a> for AlterSpace<'a> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
Self::parse(state)
}
}

@ -29,7 +29,7 @@ use {
crate::{
engine::{
data::DictGeneric,
error::{LangError, LangResult},
error::{Error, QueryResult},
ql::{
ast::{Entity, QueryData, State},
lex::Ident,
@ -51,10 +51,10 @@ pub struct CreateSpace<'a> {
impl<'a> CreateSpace<'a> {
#[inline(always)]
/// Parse space data from the given tokens
fn parse<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn parse<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
// smallest declaration: `create space myspace` -> >= 1 token
if compiler::unlikely(state.remaining() < 1) {
return compiler::cold_rerr(LangError::UnexpectedEOS);
return compiler::cold_rerr(Error::QLUnexpectedEndOfStatement);
}
let space_name = state.fw_read();
state.poison_if_not(space_name.is_ident());
@ -76,7 +76,7 @@ impl<'a> CreateSpace<'a> {
props: d,
})
} else {
Err(LangError::BadSyntax)
Err(Error::QLInvalidSyntax)
}
}
}
@ -108,9 +108,9 @@ impl<'a> CreateModel<'a> {
}
}
fn parse<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn parse<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
if compiler::unlikely(state.remaining() < 10) {
return compiler::cold_rerr(LangError::UnexpectedEOS);
return compiler::cold_rerr(Error::QLUnexpectedEndOfStatement);
}
// model name; ignore errors
let mut model_uninit = MaybeInit::uninit();
@ -147,7 +147,7 @@ impl<'a> CreateModel<'a> {
props,
})
} else {
Err(LangError::BadSyntax)
Err(Error::QLInvalidSyntax)
}
}
}
@ -156,17 +156,17 @@ mod impls {
use {
super::{CreateModel, CreateSpace},
crate::engine::{
error::LangResult,
error::QueryResult,
ql::ast::{traits::ASTNode, QueryData, State},
},
};
impl<'a> ASTNode<'a> for CreateSpace<'a> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
Self::parse(state)
}
}
impl<'a> ASTNode<'a> for CreateModel<'a> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
Self::parse(state)
}
}

@ -25,7 +25,7 @@
*/
use crate::engine::{
error::{LangError, LangResult},
error::{Error, QueryResult},
ql::{
ast::{Entity, QueryData, State, Statement},
lex::{Ident, Token},
@ -45,7 +45,7 @@ impl<'a> DropSpace<'a> {
pub const fn new(space: Ident<'a>, force: bool) -> Self {
Self { space, force }
}
fn parse<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<DropSpace<'a>> {
fn parse<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<DropSpace<'a>> {
if state.cursor_is_ident() {
let ident = state.fw_read();
// should we force drop?
@ -62,7 +62,7 @@ impl<'a> DropSpace<'a> {
));
}
}
Err(LangError::BadSyntax)
Err(Error::QLInvalidSyntax)
}
}
@ -77,14 +77,14 @@ impl<'a> DropModel<'a> {
pub fn new(entity: Entity<'a>, force: bool) -> Self {
Self { entity, force }
}
fn parse<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn parse<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
let e = Entity::parse_from_state_rounded_result(state)?;
let force = state.cursor_rounded_eq(Token::Ident(Ident::from("force")));
state.cursor_ahead_if(force);
if state.exhausted() {
return Ok(DropModel::new(e, force));
} else {
Err(LangError::BadSyntax)
Err(Error::QLInvalidSyntax)
}
}
}
@ -93,11 +93,11 @@ impl<'a> DropModel<'a> {
/// ## Panic
///
/// If token stream length is < 2
pub fn parse_drop<'a, Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Statement<'a>> {
pub fn parse_drop<'a, Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Statement<'a>> {
match state.fw_read() {
Token![model] => DropModel::parse(state).map(Statement::DropModel),
Token![space] => return DropSpace::parse(state).map(Statement::DropSpace),
_ => Err(LangError::StmtUnknownDrop),
_ => Err(Error::QPUnknownStatement),
}
}
@ -106,24 +106,24 @@ mod impls {
use {
super::{DropModel, DropSpace},
crate::engine::{
error::LangResult,
error::QueryResult,
ql::ast::{traits::ASTNode, QueryData, State, Statement},
},
};
impl<'a> ASTNode<'a> for DropModel<'a> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
Self::parse(state)
}
}
impl<'a> ASTNode<'a> for DropSpace<'a> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
Self::parse(state)
}
}
#[derive(sky_macros::Wrapper, Debug)]
pub struct DropStatementAST<'a>(Statement<'a>);
impl<'a> ASTNode<'a> for DropStatementAST<'a> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
super::parse_drop(state).map(Self)
}
}

@ -26,7 +26,7 @@
use crate::{
engine::{
error::{LangError, LangResult},
error::{Error, QueryResult},
ql::{
ast::{Entity, QueryData, State, Statement},
lex::Token,
@ -37,7 +37,7 @@ use crate::{
pub fn parse_inspect<'a, Qd: QueryData<'a>>(
state: &mut State<'a, Qd>,
) -> LangResult<Statement<'a>> {
) -> QueryResult<Statement<'a>> {
/*
inpsect model <entity>
inspect space <entity>
@ -47,7 +47,7 @@ pub fn parse_inspect<'a, Qd: QueryData<'a>>(
*/
if compiler::unlikely(state.remaining() < 1) {
return compiler::cold_rerr(LangError::UnexpectedEOS);
return compiler::cold_rerr(Error::QLUnexpectedEndOfStatement);
}
match state.fw_read() {
@ -65,7 +65,7 @@ pub fn parse_inspect<'a, Qd: QueryData<'a>>(
}
_ => {
state.cursor_back();
Err(LangError::ExpectedStatement)
Err(Error::QPExpectedStatement)
}
}
}
@ -73,13 +73,13 @@ pub fn parse_inspect<'a, Qd: QueryData<'a>>(
pub use impls::InspectStatementAST;
mod impls {
use crate::engine::{
error::LangResult,
error::QueryResult,
ql::ast::{traits::ASTNode, QueryData, State, Statement},
};
#[derive(sky_macros::Wrapper, Debug)]
pub struct InspectStatementAST<'a>(Statement<'a>);
impl<'a> ASTNode<'a> for InspectStatementAST<'a> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
super::parse_inspect(state).map(Self)
}
}

@ -50,7 +50,7 @@ use crate::{
cell::Datacell,
dict::{DictEntryGeneric, DictGeneric},
},
error::{LangError, LangResult},
error::{Error, QueryResult},
ql::{
ast::{QueryData, State},
lex::{Ident, Token},
@ -356,10 +356,10 @@ impl<'a> FieldSpec<'a> {
primary,
}
}
pub fn parse<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
pub fn parse<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
if compiler::unlikely(state.remaining() < 2) {
// smallest field: `ident: type`
return Err(LangError::UnexpectedEOS);
return Err(Error::QLUnexpectedEndOfStatement);
}
// check if primary or null
let is_primary = state.cursor_eq(Token![primary]);
@ -371,7 +371,7 @@ impl<'a> FieldSpec<'a> {
// field name
let field_name = match (state.fw_read(), state.fw_read()) {
(Token::Ident(id), Token![:]) => id,
_ => return Err(LangError::BadSyntax),
_ => return Err(Error::QLInvalidSyntax),
};
// layers
let mut layers = Vec::new();
@ -384,7 +384,7 @@ impl<'a> FieldSpec<'a> {
primary: is_primary,
})
} else {
Err(LangError::SynBadTyMeta)
Err(Error::QLInvalidTypeDefinitionSyntax)
}
}
}
@ -407,10 +407,10 @@ impl<'a> ExpandedField<'a> {
}
#[inline(always)]
/// Parse a field declared using the field syntax
pub(super) fn parse<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
pub(super) fn parse<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
if compiler::unlikely(state.remaining() < 6) {
// smallest: fieldname { type: ident }
return Err(LangError::UnexpectedEOS);
return Err(Error::QLUnexpectedEndOfStatement);
}
let field_name = state.fw_read();
state.poison_if_not(field_name.is_ident());
@ -423,7 +423,7 @@ impl<'a> ExpandedField<'a> {
// this has layers. fold them; but don't forget the colon
if compiler::unlikely(state.exhausted()) {
// we need more tokens
return Err(LangError::UnexpectedEOS);
return Err(Error::QLUnexpectedEndOfStatement);
}
state.poison_if_not(state.cursor_eq(Token![:]));
state.cursor_ahead();
@ -450,12 +450,14 @@ impl<'a> ExpandedField<'a> {
layers,
})
} else {
Err(LangError::BadSyntax)
Err(Error::QLInvalidSyntax)
}
}
#[inline(always)]
/// Parse multiple fields declared using the field syntax. Flag setting allows or disallows reset syntax
pub fn parse_multiple<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Box<[Self]>> {
pub fn parse_multiple<Qd: QueryData<'a>>(
state: &mut State<'a, Qd>,
) -> QueryResult<Box<[Self]>> {
const DEFAULT_ADD_COL_CNT: usize = 4;
/*
WARNING: No trailing commas allowed
@ -466,7 +468,7 @@ impl<'a> ExpandedField<'a> {
alter model add myfield { type string }
*/
if compiler::unlikely(state.remaining() < 5) {
return compiler::cold_rerr(LangError::UnexpectedEOS);
return compiler::cold_rerr(Error::QLUnexpectedEndOfStatement);
}
match state.read() {
Token::Ident(_) => {
@ -498,10 +500,10 @@ impl<'a> ExpandedField<'a> {
if state.okay() {
Ok(cols.into_boxed_slice())
} else {
Err(LangError::BadSyntax)
Err(Error::QLInvalidSyntax)
}
}
_ => Err(LangError::ExpectedStatement),
_ => Err(Error::QPExpectedStatement),
}
}
}
@ -516,24 +518,24 @@ mod impls {
FieldSpec, LayerSpec,
},
crate::engine::{
error::LangResult,
error::QueryResult,
ql::ast::{traits::ASTNode, QueryData, State},
},
};
impl<'a> ASTNode<'a> for ExpandedField<'a> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
Self::parse(state)
}
fn _multiple_from_state<Qd: QueryData<'a>>(
state: &mut State<'a, Qd>,
) -> LangResult<Vec<Self>> {
) -> QueryResult<Vec<Self>> {
Self::parse_multiple(state).map(Vec::from)
}
}
impl<'a> ASTNode<'a> for LayerSpec<'a> {
// important: upstream must verify this
const VERIFY: bool = true;
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
let mut layers = Vec::new();
rfold_layers(state, &mut layers);
assert!(layers.len() == 1);
@ -541,7 +543,7 @@ mod impls {
}
fn _multiple_from_state<Qd: QueryData<'a>>(
state: &mut State<'a, Qd>,
) -> LangResult<Vec<Self>> {
) -> QueryResult<Vec<Self>> {
let mut l = Vec::new();
rfold_layers(state, &mut l);
Ok(l)
@ -552,7 +554,7 @@ mod impls {
impl<'a> ASTNode<'a> for DictBasic {
// important: upstream must verify this
const VERIFY: bool = true;
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
let mut dict = DictGeneric::new();
rfold_dict(DictFoldState::OB, state, &mut dict);
Ok(Self(dict))
@ -563,7 +565,7 @@ mod impls {
impl<'a> ASTNode<'a> for DictTypeMetaSplit {
// important: upstream must verify this
const VERIFY: bool = true;
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
let mut dict = DictGeneric::new();
rfold_tymeta(DictFoldState::CB_OR_IDENT, state, &mut dict);
Ok(Self(dict))
@ -574,14 +576,14 @@ mod impls {
impl<'a> ASTNode<'a> for DictTypeMeta {
// important: upstream must verify this
const VERIFY: bool = true;
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
let mut dict = DictGeneric::new();
rfold_tymeta(DictFoldState::OB, state, &mut dict);
Ok(Self(dict))
}
}
impl<'a> ASTNode<'a> for FieldSpec<'a> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
Self::parse(state)
}
}

@ -30,7 +30,7 @@ use {
super::WhereClause,
crate::{
engine::{
error::{LangError, LangResult},
error::{Error, QueryResult},
ql::ast::{Entity, QueryData, State},
},
util::{compiler, MaybeInit},
@ -73,7 +73,7 @@ impl<'a> DeleteStatement<'a> {
Self::new(entity, WhereClause::new(wc))
}
#[inline(always)]
pub fn parse_delete<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
pub fn parse_delete<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
/*
TODO(@ohsayan): Volcano
smallest tt:
@ -81,7 +81,7 @@ impl<'a> DeleteStatement<'a> {
^1 ^2 ^3 ^4 ^5
*/
if compiler::unlikely(state.remaining() < 5) {
return compiler::cold_rerr(LangError::UnexpectedEOS);
return compiler::cold_rerr(Error::QLUnexpectedEndOfStatement);
}
// from + entity
state.poison_if_not(state.cursor_eq(Token![from]));
@ -101,7 +101,7 @@ impl<'a> DeleteStatement<'a> {
wc,
})
} else {
compiler::cold_rerr(LangError::BadSyntax)
compiler::cold_rerr(Error::QLInvalidSyntax)
}
}
}
@ -110,12 +110,12 @@ mod impls {
use {
super::DeleteStatement,
crate::engine::{
error::LangResult,
error::QueryResult,
ql::ast::{traits::ASTNode, QueryData, State},
},
};
impl<'a> ASTNode<'a> for DeleteStatement<'a> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
Self::parse_delete(state)
}
}

@ -28,7 +28,7 @@ use {
crate::{
engine::{
data::cell::Datacell,
error::{LangError, LangResult},
error::{Error, QueryResult},
ql::{
ast::{Entity, QueryData, State},
lex::{Ident, Token},
@ -350,14 +350,14 @@ impl<'a> InsertStatement<'a> {
}
impl<'a> InsertStatement<'a> {
pub fn parse_insert<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
pub fn parse_insert<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
/*
smallest:
insert into model (primarykey)
^1 ^2 ^3 ^4 ^5
*/
if compiler::unlikely(state.remaining() < 5) {
return compiler::cold_rerr(LangError::UnexpectedEOS);
return compiler::cold_rerr(Error::QLUnexpectedEndOfStatement);
}
state.poison_if_not(state.cursor_eq(Token![into]));
state.cursor_ahead(); // ignore errors
@ -392,7 +392,7 @@ impl<'a> InsertStatement<'a> {
data,
})
} else {
compiler::cold_rerr(LangError::BadSyntax)
compiler::cold_rerr(Error::QLInvalidSyntax)
}
}
}
@ -405,12 +405,12 @@ mod impls {
use {
super::InsertStatement,
crate::engine::{
error::LangResult,
error::QueryResult,
ql::ast::{traits::ASTNode, QueryData, State},
},
};
impl<'a> ASTNode<'a> for InsertStatement<'a> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
Self::parse_insert(state)
}
}
@ -421,7 +421,7 @@ mod impls {
parse_data_map_syntax, parse_data_tuple_syntax, parse_list, Datacell, HashMap,
},
crate::engine::{
error::LangResult,
error::QueryResult,
ql::ast::{traits::ASTNode, QueryData, State},
},
};
@ -430,7 +430,7 @@ mod impls {
impl<'a> ASTNode<'a> for List {
// important: upstream must verify this
const VERIFY: bool = true;
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
let mut l = Vec::new();
parse_list(state, &mut l);
Ok(List(l))
@ -441,7 +441,7 @@ mod impls {
impl<'a> ASTNode<'a> for DataTuple {
// important: upstream must verify this
const VERIFY: bool = true;
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
let r = parse_data_tuple_syntax(state);
Ok(Self(r))
}
@ -451,7 +451,7 @@ mod impls {
impl<'a> ASTNode<'a> for DataMap {
// important: upstream must verify this
const VERIFY: bool = true;
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
let r = parse_data_map_syntax(state);
Ok(Self(
r.into_iter()

@ -168,21 +168,21 @@ mod impls {
use {
super::{RelationalExpr, WhereClause},
crate::engine::{
error::{LangError, LangResult},
error::{Error, QueryResult},
ql::ast::{traits::ASTNode, QueryData, State},
},
};
impl<'a> ASTNode<'a> for WhereClause<'a> {
// important: upstream must verify this
const VERIFY: bool = true;
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
let wh = Self::parse_where(state);
Ok(wh)
}
}
impl<'a> ASTNode<'a> for RelationalExpr<'a> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
Self::try_parse(state).ok_or(LangError::ExprBadRel)
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
Self::try_parse(state).ok_or(Error::QLIllegalRelExp)
}
}
}

@ -28,7 +28,7 @@ use {
super::{WhereClause, WhereClauseCollection},
crate::{
engine::{
error::{LangError, LangResult},
error::{Error, QueryResult},
ql::{
ast::{Entity, QueryData, State},
lex::{Ident, Token},
@ -96,7 +96,7 @@ impl<'a> SelectStatement<'a> {
}
impl<'a> SelectStatement<'a> {
pub fn parse_select<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
pub fn parse_select<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
/*
Smallest query:
select * from model
@ -104,7 +104,7 @@ impl<'a> SelectStatement<'a> {
1 2 3
*/
if compiler::unlikely(state.remaining() < 3) {
return compiler::cold_rerr(LangError::UnexpectedEOS);
return compiler::cold_rerr(Error::QLUnexpectedEndOfStatement);
}
let mut select_fields = Vec::new();
let is_wildcard = state.cursor_eq(Token![*]);
@ -123,7 +123,7 @@ impl<'a> SelectStatement<'a> {
state.poison_if_not(is_wildcard | !select_fields.is_empty());
// we should have from + model
if compiler::unlikely(state.remaining() < 2 || !state.okay()) {
return compiler::cold_rerr(LangError::BadSyntax);
return compiler::cold_rerr(Error::QLInvalidSyntax);
}
state.poison_if_not(state.cursor_eq(Token![from]));
state.cursor_ahead(); // ignore errors
@ -146,7 +146,7 @@ impl<'a> SelectStatement<'a> {
clause: WhereClause::new(clauses),
})
} else {
compiler::cold_rerr(LangError::BadSyntax)
compiler::cold_rerr(Error::QLInvalidSyntax)
}
}
}
@ -155,12 +155,12 @@ mod impls {
use {
super::SelectStatement,
crate::engine::{
error::LangResult,
error::QueryResult,
ql::ast::{traits::ASTNode, QueryData, State},
},
};
impl<'a> ASTNode<'a> for SelectStatement<'a> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
Self::parse_select(state)
}
}

@ -32,7 +32,7 @@ use {
engine::{
core::query_meta::AssignmentOperator,
data::lit::LitIR,
error::{LangError, LangResult},
error::{Error, QueryResult},
ql::{
ast::{Entity, QueryData, State},
lex::Ident,
@ -172,7 +172,7 @@ impl<'a> UpdateStatement<'a> {
}
}
#[inline(always)]
pub fn parse_update<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
pub fn parse_update<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
/*
TODO(@ohsayan): Allow volcanoes
smallest tt:
@ -180,7 +180,7 @@ impl<'a> UpdateStatement<'a> {
^1 ^2 ^3 ^4 ^5^6 ^7^8^9
*/
if compiler::unlikely(state.remaining() < 9) {
return compiler::cold_rerr(LangError::UnexpectedEOS);
return compiler::cold_rerr(Error::QLUnexpectedEndOfStatement);
}
// parse entity
let mut entity = MaybeInit::uninit();
@ -218,7 +218,7 @@ impl<'a> UpdateStatement<'a> {
wc: WhereClause::new(clauses),
})
} else {
compiler::cold_rerr(LangError::BadSyntax)
compiler::cold_rerr(Error::QLInvalidSyntax)
}
}
}
@ -227,22 +227,22 @@ mod impls {
use {
super::UpdateStatement,
crate::engine::{
error::LangResult,
error::QueryResult,
ql::ast::{traits::ASTNode, QueryData, State},
},
};
impl<'a> ASTNode<'a> for UpdateStatement<'a> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
Self::parse_update(state)
}
}
#[cfg(test)]
mod test {
use super::{super::AssignmentExpression, ASTNode, LangResult, QueryData, State};
use super::{super::AssignmentExpression, ASTNode, QueryResult, QueryData, State};
impl<'a> ASTNode<'a> for AssignmentExpression<'a> {
// important: upstream must verify this
const VERIFY: bool = true;
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
let mut expr = Vec::new();
AssignmentExpression::parse_and_append_expression(state, &mut expr);
state.poison_if_not(expr.len() == 1);
@ -250,7 +250,7 @@ mod impls {
}
fn _multiple_from_state<Qd: QueryData<'a>>(
state: &mut State<'a, Qd>,
) -> LangResult<Vec<Self>> {
) -> QueryResult<Vec<Self>> {
let mut expr = Vec::new();
AssignmentExpression::parse_and_append_expression(state, &mut expr);
Ok(expr)

@ -34,7 +34,7 @@ use {
lit::{Lit, LitIR},
spec::Dataspec1D,
},
error::{LexError, LexResult},
error::{Error, QueryResult},
},
util::compiler,
},
@ -62,7 +62,7 @@ impl<'a> InsecureLexer<'a> {
}
}
#[inline(always)]
pub fn lex(src: Slice<'a>) -> LexResult<Vec<Token<'a>>> {
pub fn lex(src: Slice<'a>) -> QueryResult<Vec<Token<'a>>> {
let mut slf = Self::new(src);
slf._lex();
let RawLexer {
@ -133,7 +133,7 @@ impl<'a> InsecureLexer<'a> {
slf.push_token(Lit::SignedInt(num));
}
_ => {
compiler::cold_call(|| slf.set_error(LexError::InvalidSignedNumericLit));
compiler::cold_call(|| slf.set_error(Error::LexInvalidLiteral));
}
}
} else {
@ -174,7 +174,7 @@ impl<'a> InsecureLexer<'a> {
Ok(num) if compiler::likely(wseof) => {
slf.tokens.push(Token::Lit(Lit::UnsignedInt(num)))
}
_ => slf.set_error(LexError::InvalidUnsignedLiteral),
_ => slf.set_error(Error::LexInvalidLiteral),
}
}
@ -224,7 +224,7 @@ impl<'a> InsecureLexer<'a> {
slf.incr_cursor_by(size);
}
} else {
slf.set_error(LexError::InvalidBinaryLiteral);
slf.set_error(Error::LexInvalidLiteral);
}
}
#[inline(always)]
@ -275,7 +275,7 @@ impl<'a> InsecureLexer<'a> {
let terminated = slf.peek_eq_and_forward(quote_style);
match String::from_utf8(buf) {
Ok(st) if terminated => slf.tokens.push(Token::Lit(st.into_boxed_str().into())),
_ => slf.set_error(LexError::InvalidStringLiteral),
_ => slf.set_error(Error::LexInvalidLiteral),
}
}
}
@ -295,11 +295,11 @@ impl<'a> SafeLexer<'a> {
}
}
#[inline(always)]
pub fn lex(src: Slice<'a>) -> LexResult<Vec<Token>> {
pub fn lex(src: Slice<'a>) -> QueryResult<Vec<Token>> {
Self::new(src)._lex()
}
#[inline(always)]
fn _lex(self) -> LexResult<Vec<Token<'a>>> {
fn _lex(self) -> QueryResult<Vec<Token<'a>>> {
let Self { base: mut l } = self;
while l.not_exhausted() && l.no_error() {
let b = unsafe {
@ -453,11 +453,11 @@ impl<'a> SafeQueryData<'a> {
Self { p, t }
}
#[inline(always)]
pub fn parse_data(pf: Slice<'a>, pf_sz: usize) -> LexResult<Box<[LitIR<'a>]>> {
pub fn parse_data(pf: Slice<'a>, pf_sz: usize) -> QueryResult<Box<[LitIR<'a>]>> {
Self::p_revloop(pf, pf_sz)
}
#[inline(always)]
pub fn parse(qf: Slice<'a>, pf: Slice<'a>, pf_sz: usize) -> LexResult<Self> {
pub fn parse(qf: Slice<'a>, pf: Slice<'a>, pf_sz: usize) -> QueryResult<Self> {
let q = SafeLexer::lex(qf);
let p = Self::p_revloop(pf, pf_sz);
match (q, p) {
@ -467,7 +467,7 @@ impl<'a> SafeQueryData<'a> {
}
}
#[inline]
pub(super) fn p_revloop(mut src: Slice<'a>, size: usize) -> LexResult<Box<[LitIR<'a>]>> {
pub(super) fn p_revloop(mut src: Slice<'a>, size: usize) -> QueryResult<Box<[LitIR<'a>]>> {
static LITIR_TF: [for<'a> fn(Slice<'a>, &mut usize, &mut Vec<LitIR<'a>>) -> bool; 7] = [
SafeQueryData::uint, // tc: 0
SafeQueryData::sint, // tc: 1
@ -493,7 +493,7 @@ impl<'a> SafeQueryData<'a> {
if compiler::likely(okay) {
Ok(data.into_boxed_slice())
} else {
Err(LexError::BadPframe)
Err(Error::LexInvalidEscapedLiteral)
}
}
}

@ -28,7 +28,7 @@ use {
super::Slice,
crate::engine::{
data::{lit::Lit, spec::Dataspec1D},
error::LexError,
error::Error,
},
core::{borrow::Borrow, fmt, ops::Deref, slice, str},
};
@ -373,7 +373,7 @@ pub struct RawLexer<'a> {
c: *const u8,
e: *const u8,
pub(super) tokens: Vec<Token<'a>>,
pub(super) last_error: Option<LexError>,
pub(super) last_error: Option<Error>,
}
// ctor
@ -491,7 +491,7 @@ impl<'a> RawLexer<'a> {
while self.peek_is_and_forward(|b| b == b' ' || b == b'\t' || b == b'\n') {}
}
#[inline(always)]
pub(super) fn set_error(&mut self, e: LexError) {
pub(super) fn set_error(&mut self, e: Error) {
self.last_error = Some(e);
}
#[inline(always)]
@ -532,7 +532,7 @@ impl<'a> RawLexer<'a> {
pub(super) fn scan_byte(&mut self, byte: u8) {
match symof(byte) {
Some(tok) => self.push_token(tok),
None => return self.set_error(LexError::UnexpectedByte),
None => return self.set_error(Error::LexUnexpectedByte),
}
unsafe {
// UNSAFE(@ohsayan): we are sent a byte, so fw cursor

@ -27,7 +27,7 @@
use {
super::lex::{InsecureLexer, SafeLexer, Symbol, Token},
crate::{
engine::{data::cell::Datacell, error::LexResult},
engine::{data::cell::Datacell, error::QueryResult},
util::test_utils,
},
rand::{self, Rng},
@ -41,12 +41,12 @@ mod structure_syn;
#[inline(always)]
/// Uses the [`InsecureLexer`] to lex the given input
pub fn lex_insecure(src: &[u8]) -> LexResult<Vec<Token<'_>>> {
pub fn lex_insecure(src: &[u8]) -> QueryResult<Vec<Token<'_>>> {
InsecureLexer::lex(src)
}
#[inline(always)]
/// Uses the [`SafeLexer`] to lex the given input
pub fn lex_secure(src: &[u8]) -> LexResult<Vec<Token>> {
pub fn lex_secure(src: &[u8]) -> QueryResult<Vec<Token>> {
SafeLexer::lex(src)
}

@ -31,7 +31,7 @@ use {
},
crate::engine::{
data::{lit::Lit, spec::Dataspec1D},
error::LexError,
error::Error,
},
};
@ -143,23 +143,14 @@ fn lex_string_escape_bs() {
#[test]
fn lex_string_bad_escape() {
let wth = br#" '\a should be an alert on windows apparently' "#;
assert_eq!(
lex_insecure(wth).unwrap_err(),
LexError::InvalidStringLiteral
);
assert_eq!(lex_insecure(wth).unwrap_err(), Error::LexInvalidLiteral);
}
#[test]
fn lex_string_unclosed() {
let wth = br#" 'omg where did the end go "#;
assert_eq!(
lex_insecure(wth).unwrap_err(),
LexError::InvalidStringLiteral
);
assert_eq!(lex_insecure(wth).unwrap_err(), Error::LexInvalidLiteral);
let wth = br#" 'see, we escaped the end\' "#;
assert_eq!(
lex_insecure(wth).unwrap_err(),
LexError::InvalidStringLiteral
);
assert_eq!(lex_insecure(wth).unwrap_err(), Error::LexInvalidLiteral);
}
#[test]
fn lex_unsafe_literal_mini() {

@ -30,7 +30,7 @@ use crate::engine::{
space::{Space, SpaceMeta},
},
data::{cell::Datacell, tag::TagSelector, uuid::Uuid, DictEntryGeneric},
error::DatabaseError,
error::Error,
fractal::{test_utils::TestGlobal, GlobalInstanceLike},
idx::STIndex,
ql::{
@ -318,7 +318,7 @@ fn drop_model() {
.namespace()
.with_model(("myspace", "mymodel"), |_| { Ok(()) })
.unwrap_err(),
DatabaseError::DdlModelNotFound
Error::QPObjectNotFound
);
})
})

Loading…
Cancel
Save