Skip to content

Commit

Permalink
feat: add list_len function (#609)
Browse files Browse the repository at this point in the history
This is the same implementation for all types, so we can move to a
generic `length` evaluator when we move to `sparrow-expressions`
package.
  • Loading branch information
jordanrfrazier authored Aug 7, 2023
1 parent 6db60f0 commit 8e2b748
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 0 deletions.
5 changes: 5 additions & 0 deletions crates/sparrow-compiler/src/functions/collection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,9 @@ pub(super) fn register(registry: &mut Registry) {
)
.with_implementation(Implementation::Instruction(InstOp::Collect))
.set_internal();

registry
.register("list_len<T: any>(input: list<T>) -> i32")
.with_implementation(Implementation::Instruction(InstOp::ListLen))
.set_internal();
}
1 change: 1 addition & 0 deletions crates/sparrow-instructions/src/evaluators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ fn create_simple_evaluator(
)
}
InstOp::Len => LenEvaluator::try_new(info),
InstOp::ListLen => ListLenEvaluator::try_new(info),
InstOp::LogicalAnd => LogicalAndKleeneEvaluator::try_new(info),
InstOp::LogicalOr => LogicalOrKleeneEvaluator::try_new(info),
InstOp::Lower => LowerEvaluator::try_new(info),
Expand Down
2 changes: 2 additions & 0 deletions crates/sparrow-instructions/src/evaluators/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod collect_primitive;
mod collect_string;
mod collect_struct;
mod index;
mod list_len;

pub(super) use collect_boolean::*;
pub(super) use collect_list::*;
Expand All @@ -13,3 +14,4 @@ pub(super) use collect_primitive::*;
pub(super) use collect_string::*;
pub(super) use collect_struct::*;
pub(super) use index::*;
pub(super) use list_len::*;
36 changes: 36 additions & 0 deletions crates/sparrow-instructions/src/evaluators/list/list_len.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use arrow::array::ArrayRef;

use arrow_schema::DataType;
use sparrow_plan::ValueRef;
use std::sync::Arc;

use crate::{Evaluator, EvaluatorFactory, StaticInfo};

/// Evaluator for `len` on lists.
///
/// Produces the length of the list.
#[derive(Debug)]
pub(in crate::evaluators) struct ListLenEvaluator {
list: ValueRef,
}

impl EvaluatorFactory for ListLenEvaluator {
fn try_new(info: StaticInfo<'_>) -> anyhow::Result<Box<dyn Evaluator>> {
let input_type = info.args[0].data_type.clone();
match input_type {
DataType::List(_) => (),
other => anyhow::bail!("expected list type, saw {:?}", other),
};

let list = info.unpack_argument()?;
Ok(Box::new(Self { list }))
}
}

impl Evaluator for ListLenEvaluator {
fn evaluate(&mut self, info: &dyn crate::RuntimeInfo) -> anyhow::Result<ArrayRef> {
let input = info.value(&self.list)?.array_ref()?;
let result = arrow::compute::kernels::length::length(input.as_ref())?;
Ok(Arc::new(result))
}
}
18 changes: 18 additions & 0 deletions crates/sparrow-main/tests/e2e/list_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,24 @@ async fn test_last_list() {
"###);
}

#[tokio::test]
async fn test_list_len() {
insta::assert_snapshot!(QueryFixture::new("{
len_struct: { s: Input.string_list } | collect(max=null) | list_len(),
len_num: Input.i64_list | list_len(),
len_str: Input.string_list | list_len(),
len_bool: Input.bool_list | list_len(),
}
").run_to_csv(&list_data_fixture().await).await.unwrap(), @r###"
_time,_subsort,_key_hash,_key,len_struct,len_num,len_str,len_bool
1996-12-19T16:39:57.000000000,0,18433805721903975440,1,1,3,2,2
1996-12-19T16:40:57.000000000,0,18433805721903975440,1,2,3,3,2
1996-12-19T16:40:59.000000000,0,18433805721903975440,1,3,3,0,3
1996-12-19T16:41:57.000000000,0,18433805721903975440,1,4,3,2,3
1996-12-19T16:42:57.000000000,0,18433805721903975440,1,5,3,1,1
"###);
}

#[tokio::test]
async fn test_list_schemas_are_compatible() {
// This query puts a collect() into a record, which
Expand Down
2 changes: 2 additions & 0 deletions crates/sparrow-plan/src/inst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ pub enum InstOp {
Last,
#[strum(props(signature = "len(s: string) -> i32"))]
Len,
#[strum(props(signature = "list_len<T: any>(input: list<T>) -> i32"))]
ListLen,
#[strum(props(signature = "logical_and(a: bool, b: bool) -> bool"))]
LogicalAnd,
#[strum(props(signature = "logical_or(a: bool, b: bool) -> bool"))]
Expand Down

0 comments on commit 8e2b748

Please sign in to comment.