use std::borrow::Cow;
use crate::schema::{ColumnTable, SchemaFacts};
use gnitz_expr::RowFilter;
use crate::repr::Batch;
use crate::schema::{DerivedSchema, SchemaColumn, SchemaDescriptor, TypeCode};
pub fn op_filter(batch: &Batch, pred: &mut RowFilter) -> Option<Batch> {
let mut ranges: Vec<(usize, usize)> = Vec::new();
pred.ranges(&batch.as_mem_batch(), &mut ranges);
if ranges == [(0, batch.count)] {
return None;
}
Some(Batch::from_ranges(batch, &ranges, 0))
}
pub fn union_nullability_merge(a: &SchemaDescriptor, b: &SchemaDescriptor) -> Result<SchemaDescriptor, String> {
if !a.same_layout(b) {
return Err("union: inputs do not share a physical layout".to_string());
}
let cols: Vec<SchemaColumn> = (0..a.num_columns())
.map(|c| {
let (ac, bc) = (a.columns[c], b.columns[c]);
SchemaColumn::new(ac.type_code, ac.nullable | bc.nullable)
})
.collect();
Ok(SchemaDescriptor::new(&cols, a.pk_cols()))
}
pub fn null_extend_output_schema(
in_schema: &SchemaDescriptor,
type_codes: &[TypeCode],
nulls_first: bool,
) -> Result<SchemaDescriptor, String> {
let mut b = DerivedSchema::new();
b.push_pk_of(in_schema);
let fill = |b: &mut DerivedSchema| type_codes.iter().for_each(|&tc| b.push(SchemaColumn::new(tc, true)));
if nulls_first {
fill(&mut b);
b.push_payload_of(in_schema);
} else {
b.push_payload_of(in_schema);
fill(&mut b);
}
b.finish().map_err(|e| format!("null-extend: merged schema {e}"))
}
pub fn op_union(batch_a: Cow<'_, Batch>, batch_b: Cow<'_, Batch>, out_schema: &SchemaDescriptor) -> Batch {
let (batch_a, batch_b) = match batch_a.is_empty() {
true => (batch_b, batch_a),
false => (batch_a, batch_b),
};
if batch_b.is_empty() {
let mut out = batch_a.into_owned();
out.set_schema(out_schema);
return out;
}
if batch_a.stands_consolidated() && batch_b.stands_consolidated() {
return batch_a.merged_consolidated(&batch_b, out_schema);
}
match batch_a {
Cow::Borrowed(a) => Batch::concat(out_schema, [a.as_mem_batch(), batch_b.as_mem_batch()].into_iter()),
Cow::Owned(mut a) => {
a.set_schema(out_schema);
a.append_batch(&batch_b);
a
}
}
}
#[cfg(test)]
#[path = "tests/linear.rs"]
mod tests;