use reifydb_core::error::diagnostic::query;
use reifydb_transaction::transaction::Transaction;
use reifydb_type::{err, error, error::Diagnostic, fragment::Fragment};
use crate::{
Result,
ast::ast::{Ast, AstFrom},
bump::BumpBox,
expression::{AliasExpression, ExpressionCompiler, IdentExpression},
plan::logical::{
Compiler, EnvironmentNode, GeneratorNode, InlineDataNode, LogicalPlan, RemoteScanNode, ShapeScanNode,
VariableSourceNode,
resolver::{self, ResolvedSource},
},
};
impl<'bump> Compiler<'bump> {
pub(crate) fn compile_from(&self, ast: AstFrom<'bump>, tx: &mut Transaction<'_>) -> Result<LogicalPlan<'bump>> {
match ast {
AstFrom::Source {
source,
..
} => {
let resolved_source = resolver::resolve_unresolved_source(&self.catalog, tx, &source)?;
match resolved_source {
ResolvedSource::Remote {
address,
token,
local_namespace,
remote_name,
} => Ok(LogicalPlan::RemoteScan(RemoteScanNode {
address,
token,
local_namespace,
remote_name,
})),
ResolvedSource::Shape(resolved) => {
Ok(LogicalPlan::PrimitiveScan(ShapeScanNode {
source: resolved,
columns: None,
index: None,
}))
}
}
}
AstFrom::Inline {
list,
..
} => {
let mut rows = Vec::new();
for row in list.nodes {
match row {
Ast::Inline(row) => {
let mut alias_fields = Vec::new();
for field in row.keyed_values {
if field.key.token.fragment.text().starts_with('#') {
return Err(error!(
query::system_column_read_only(
field.key
.token
.fragment
.to_owned()
)
));
}
let key_fragment = field.key.token.fragment.to_owned();
let alias = IdentExpression(key_fragment.clone());
let expr = ExpressionCompiler::compile(
BumpBox::into_inner(field.value),
)?;
let alias_expr = AliasExpression {
alias,
expression: Box::new(expr),
fragment: key_fragment,
};
alias_fields.push(alias_expr);
}
rows.push(alias_fields);
}
_ => {
return err!(Diagnostic {
code: "E0001".to_string(),
rql: None,
message: "Expected encoded in static data".to_string(),
column: None,
fragment: Fragment::None,
label: None,
help: None,
notes: vec![],
cause: None,
operator_chain: None,
});
}
}
}
Ok(LogicalPlan::InlineData(InlineDataNode {
rows,
}))
}
AstFrom::Generator(generator) => {
let expressions = generator
.nodes
.into_iter()
.map(ExpressionCompiler::compile)
.collect::<Result<Vec<_>>>()?;
Ok(LogicalPlan::Generator(GeneratorNode {
name: generator.name,
expressions,
}))
}
AstFrom::Variable {
variable,
..
} => {
let variable_name = variable.token.fragment;
Ok(LogicalPlan::VariableSource(VariableSourceNode {
name: variable_name,
}))
}
AstFrom::Environment {
..
} => Ok(LogicalPlan::Environment(EnvironmentNode {})),
}
}
}