#![cfg_attr(not(debug_assertions), deny(clippy::disallowed_methods))]
#![cfg_attr(debug_assertions, warn(clippy::disallowed_methods))]
#![cfg_attr(not(debug_assertions), deny(warnings))]
#![allow(clippy::tabs_in_doc_comments)]
use reifydb_core::internal_error;
use reifydb_value::{
Result,
value::{
constraint::{Constraint, TypeConstraint},
value_type::ValueType,
},
};
use crate::{
ast::ast::{AstLiteral, AstType},
bump::BumpFragment,
diagnostic::AstError,
};
pub mod ast;
pub mod bump;
pub mod compiler;
pub mod diagnostic;
pub mod error;
pub mod expression;
pub mod fingerprint;
#[allow(dead_code, unused_variables)]
pub mod flow;
pub mod instruction;
pub mod nodes;
pub mod optimize;
pub mod plan;
pub mod query;
pub mod token;
pub(crate) fn convert_data_type(ast: &BumpFragment<'_>) -> Result<ValueType> {
Ok(match ast.text().to_ascii_lowercase().as_str() {
"bool" => ValueType::Boolean,
"boolean" => ValueType::Boolean,
"float4" => ValueType::Float4,
"float8" => ValueType::Float8,
"int1" => ValueType::Int1,
"int2" => ValueType::Int2,
"int4" => ValueType::Int4,
"int8" => ValueType::Int8,
"int16" => ValueType::Int16,
"uint1" => ValueType::Uint1,
"uint2" => ValueType::Uint2,
"uint4" => ValueType::Uint4,
"uint8" => ValueType::Uint8,
"uint16" => ValueType::Uint16,
"utf8" => ValueType::Utf8,
"text" => ValueType::Utf8,
"date" => ValueType::Date,
"datetime" => ValueType::DateTime,
"time" => ValueType::Time,
"duration" => ValueType::Duration,
"uuid4" => ValueType::Uuid4,
"uuid7" => ValueType::Uuid7,
"identityid" | "identity_id" => ValueType::IdentityId,
"blob" => ValueType::Blob,
"int" => ValueType::Int,
"uint" => ValueType::Uint,
"decimal" => ValueType::Decimal,
_ => {
return Err(AstError::UnrecognizedType {
fragment: ast.to_owned(),
}
.into());
}
})
}
pub(crate) fn convert_data_type_with_constraints(ast: &AstType) -> Result<TypeConstraint> {
match ast {
AstType::Unconstrained(name) => {
let base_type = convert_data_type(name)?;
Ok(TypeConstraint::unconstrained(base_type))
}
AstType::Constrained {
name,
params,
} => {
let base_type = convert_data_type(name)?;
let constraint = match (base_type.clone(), params.as_slice()) {
(ValueType::Utf8, [AstLiteral::Number(n)]) => {
let max_bytes = parse_number_literal(n.value())? as u32;
Some(Constraint::MaxBytes(max_bytes.into()))
}
(ValueType::Blob, [AstLiteral::Number(n)]) => {
let max_bytes = parse_number_literal(n.value())? as u32;
Some(Constraint::MaxBytes(max_bytes.into()))
}
(ValueType::Int, [AstLiteral::Number(n)]) => {
let max_bytes = parse_number_literal(n.value())? as u32;
Some(Constraint::MaxBytes(max_bytes.into()))
}
(ValueType::Uint, [AstLiteral::Number(n)]) => {
let max_bytes = parse_number_literal(n.value())? as u32;
Some(Constraint::MaxBytes(max_bytes.into()))
}
(ValueType::Decimal, [AstLiteral::Number(p), AstLiteral::Number(s)]) => {
let precision = parse_number_literal(p.value())? as u8;
let scale = parse_number_literal(s.value())? as u8;
Some(Constraint::PrecisionScale(precision.into(), scale.into()))
}
_ => None,
};
match constraint {
Some(c) => Ok(TypeConstraint::with_constraint(base_type, c)),
None => Ok(TypeConstraint::unconstrained(base_type)),
}
}
AstType::Optional(inner) => {
let inner_tc = convert_data_type_with_constraints(inner)?;
Ok(TypeConstraint::unconstrained(ValueType::Option(Box::new(inner_tc.get_type()))))
}
AstType::Qualified {
name,
..
} => Err(AstError::UnrecognizedType {
fragment: name.to_owned(),
}
.into()),
}
}
fn parse_number_literal(s: &str) -> Result<usize> {
s.parse::<usize>().map_err(|_| internal_error!("Invalid number literal: {}", s))
}
use reifydb_core::interface::version::{ComponentType, HasVersion, SystemVersion};
pub struct RqlVersion;
impl HasVersion for RqlVersion {
fn version(&self) -> SystemVersion {
SystemVersion {
name: env!("CARGO_PKG_NAME")
.strip_prefix("reifydb-")
.unwrap_or(env!("CARGO_PKG_NAME"))
.to_string(),
version: env!("CARGO_PKG_VERSION").to_string(),
description: "ReifyDB Query Language parser and planner module".to_string(),
r#type: ComponentType::Module,
}
}
}