feat: Add VEC_PRODUCT, VEC_ELEM_PRODUCT, VEC_NORM. (#5303)

* feat: Add `vec_product(col)` function.

* feat: Add `vec_elem_product` function

* feat: Add `vec_norm` function.
This commit is contained in:
Lin Yihai
2025-01-09 06:26:51 +00:00
committed by GitHub
parent 812a775b3d
commit fdbfebf4be
9 changed files with 686 additions and 0 deletions
+1
View File
@@ -33,6 +33,7 @@ mod time_range_filter_test;
mod function;
mod pow;
mod vec_product_test;
mod vec_sum_test;
async fn exec_selection(engine: QueryEngineRef, sql: &str) -> Vec<RecordBatch> {
+67
View File
@@ -0,0 +1,67 @@
// Copyright 2023 Greptime Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::borrow::Cow;
use common_function::scalars::vector::impl_conv::{
as_veclit, as_veclit_if_const, veclit_to_binlit,
};
use datatypes::prelude::Value;
use nalgebra::{Const, DVectorView, Dyn, OVector};
use crate::tests::{exec_selection, function};
#[tokio::test]
async fn test_vec_product_aggregator() -> Result<(), common_query::error::Error> {
common_telemetry::init_default_ut_logging();
let engine = function::create_query_engine_for_vector10x3();
let sql = "select VEC_PRODUCT(vector) as vec_product from vectors";
let result = exec_selection(engine.clone(), sql).await;
let value = function::get_value_from_batches("vec_product", result);
let mut expected_value = None;
let sql = "SELECT vector FROM vectors";
let vectors = exec_selection(engine, sql).await;
let column = vectors[0].column(0);
let vector_const = as_veclit_if_const(column)?;
for i in 0..column.len() {
let vector = match vector_const.as_ref() {
Some(vector) => Some(Cow::Borrowed(vector.as_ref())),
None => as_veclit(column.get_ref(i))?,
};
let Some(vector) = vector else {
expected_value = None;
break;
};
expected_value
.get_or_insert_with(|| {
OVector::from_iterator_generic(
Dyn(vector.len()),
Const::<1>,
(0..vector.len()).map(|_| 1.0),
)
})
.component_mul_assign(&DVectorView::from_slice(&vector, vector.len()));
}
let expected_value = match expected_value.map(|v| veclit_to_binlit(v.as_slice())) {
None => Value::Null,
Some(bytes) => Value::from(bytes),
};
assert_eq!(value, expected_value);
Ok(())
}