use std::{ptr, sync::Arc};
use crate::{
core::{
column::ColumnView,
error::{
self, Error, ErrorCode, FACT_ACTUAL_ROWS, FACT_EXPECTED_ROWS, FACT_LEFT_TYPE_ID, FACT_RIGHT_TYPE_ID, Result,
},
scalar::Scalar,
table::{Table, TableView},
types::TypeId,
},
runtime::{execution_context::Exec, execution_domain::ExecutionDomain, execution_resolver::ResolvedExecution},
};
pub(crate) fn validate_boolean_mask(
mask: &ColumnView<'_>,
expected_rows: usize,
expected_rows_label: &'static str,
operation: &'static str,
) -> Result<()> {
let mask_dtype = mask.data_type()?;
if mask_dtype.id() != TypeId::Bool8 {
return Err(Error::new_with(
ErrorCode::TypeMismatch,
operation,
format!("filter mask must be Bool8, got {:?}", mask_dtype.id()),
)
.with_fact(FACT_LEFT_TYPE_ID, mask_dtype.id())
.with_fact(FACT_RIGHT_TYPE_ID, TypeId::Bool8));
}
let mask_len = mask.len()?;
if mask_len != expected_rows {
return Err(Error::new_with(
ErrorCode::ColumnLengthMismatch,
operation,
format!("filter mask length ({mask_len}) does not match {expected_rows_label} ({expected_rows})"),
)
.with_fact(FACT_ACTUAL_ROWS, mask_len)
.with_fact(FACT_EXPECTED_ROWS, expected_rows));
}
Ok(())
}
pub(crate) fn apply_boolean_mask_impl(
input: &TableView<'_>,
mask: &ColumnView<'_>,
output_domain: &Arc<ExecutionDomain>,
exec_options: &cudf_sys::cudf_exec_options_t,
operation: &'static str,
) -> Result<Table> {
let mut out = ptr::null_mut();
let status =
unsafe { cudf_sys::cudf_apply_boolean_mask_ex(input.raw_handle(), mask.raw_handle(), &mut out, exec_options) };
error::check_status_in_with_details(status, operation, [("execution_authority", "retained_domain".to_string())])?;
unsafe { Table::from_raw_with_domain(out, Arc::clone(output_domain)) }
}
pub(crate) fn apply_boolean_mask(input: &TableView<'_>, mask: &ColumnView<'_>) -> Result<Table> {
let input_rows = input.num_rows()?;
validate_boolean_mask(mask, input_rows, "table row count", "filter::apply_boolean_mask")?;
let ctx = Exec::RETAINED;
let execution = ResolvedExecution::binary(
input.execution_domain(),
mask.execution_domain(),
ctx,
"filter::apply_boolean_mask",
)?;
apply_boolean_mask_impl(
input,
mask,
execution.output_domain(),
execution.exec_options(),
"filter::apply_boolean_mask",
)
}
pub(crate) fn apply_row_predicate_impl(
input: &TableView<'_>,
nodes: &[cudf_sys::cudf_row_predicate_node_t],
root_index: i32,
retained_scalars: &[Scalar],
output_domain: &Arc<ExecutionDomain>,
exec_options: &cudf_sys::cudf_exec_options_t,
operation: &'static str,
) -> Result<Table> {
let _retained_scalars = retained_scalars;
let mut out = ptr::null_mut();
let status = unsafe {
cudf_sys::cudf_filter_rows_by_predicate_ex(
input.raw_handle(),
nodes.as_ptr(),
error::usize_to_i32(nodes.len(), operation, "node_count")?,
root_index,
&mut out,
exec_options,
)
};
error::check_status_in_with_details(
status,
operation,
[
("node_count", nodes.len().to_string()),
("root_index", root_index.to_string()),
("execution_authority", "retained_domain".to_string()),
],
)?;
unsafe { Table::from_raw_with_domain(out, Arc::clone(output_domain)) }
}