use super::CompiledNode;
use super::prelit::PreLit;
use crate::arena::DataValue;
use crate::opcode::OpCode;
use datavalue::OwnedDataValue;
#[inline]
pub(super) fn precompute_lit(value: &OwnedDataValue) -> Option<PreLit> {
let dv = match value {
OwnedDataValue::Null => DataValue::Null,
OwnedDataValue::Bool(b) => DataValue::Bool(*b),
OwnedDataValue::Number(n) => DataValue::Number(*n),
OwnedDataValue::String(s) if s.is_empty() => DataValue::String(""),
OwnedDataValue::Array(a) if a.is_empty() => DataValue::Array(&[]),
OwnedDataValue::Object(o) if o.is_empty() => DataValue::Object(&[]),
#[cfg(feature = "datetime")]
OwnedDataValue::DateTime(d) => DataValue::DateTime(*d),
#[cfg(feature = "datetime")]
OwnedDataValue::Duration(d) => DataValue::Duration(*d),
_ => return None,
};
Some(PreLit::from_static(dv))
}
#[inline]
fn iterates_args0(opcode: OpCode) -> bool {
#[cfg(feature = "ext-array")]
if matches!(opcode, OpCode::Sort) {
return true;
}
matches!(
opcode,
OpCode::Filter
| OpCode::Map
| OpCode::All
| OpCode::Some
| OpCode::None
| OpCode::Reduce
| OpCode::Min
| OpCode::Max
)
}
pub(crate) fn populate_lits(node: &mut CompiledNode) {
node.visit_children_mut(&mut populate_lits);
if let CompiledNode::Value { value, lit, .. } = node {
if lit.is_none() {
*lit = PreLit::composite(value);
}
return;
}
if let CompiledNode::BuiltinOperator {
opcode,
args,
predicate_hint,
iter_arg_kind,
..
} = node
{
*predicate_hint =
crate::operators::array::FastPredicate::try_detect_owned(*opcode, args).map(Box::new);
*iter_arg_kind = if iterates_args0(*opcode) && !args.is_empty() {
crate::operators::array::IterArgKind::classify(&args[0])
} else {
crate::operators::array::IterArgKind::General
};
}
}