LCOV - code coverage report
Current view: top level - backend/engine/semantic/functions - kll_funcs_test.cc (source / functions) Coverage Total Hit
Test: _coverage_report.dat Lines: 100.0 % 91 91
Test Date: 2026-07-02 21:01:18 Functions: 100.0 % 9 9

            Line data    Source code
       1              : #include "backend/engine/semantic/functions/kll_funcs.h"
       2              : 
       3              : #include <optional>
       4              : #include <vector>
       5              : 
       6              : #include "backend/engine/semantic/value.h"
       7              : #include "googlesql/public/types/array_type.h"
       8              : #include "gtest/gtest.h"
       9              : 
      10              : namespace bigquery_emulator {
      11              : namespace backend {
      12              : namespace engine {
      13              : namespace semantic {
      14              : namespace functions {
      15              : namespace {
      16              : 
      17            5 : const ::googlesql::ArrayType* Int64ArrayType() {
      18            5 :   return ::googlesql::types::Int64ArrayType();
      19            5 : }
      20              : 
      21              : absl::StatusOr<Value> InitInt64(const std::vector<int64_t>& values,
      22            7 :                                 int64_t precision = 1000) {
      23            7 :   std::vector<Value> inputs;
      24            7 :   inputs.reserve(values.size());
      25           25 :   for (int64_t v : values) {
      26           25 :     inputs.push_back(Value::Int64(v));
      27           25 :   }
      28            7 :   return KllQuantilesInitInt64Values(inputs, precision);
      29            7 : }
      30              : 
      31              : }  // namespace
      32              : 
      33            1 : TEST(KllFuncsTest, InitInt64ProducesNonEmptySketch) {
      34            1 :   auto sketch = InitInt64({1, 2, 3, 4, 5});
      35            2 :   ASSERT_TRUE(sketch.ok()) << sketch.status();
      36            1 :   EXPECT_FALSE(sketch->is_null());
      37            1 :   EXPECT_EQ(sketch->type_kind(), ::googlesql::TYPE_BYTES);
      38            1 :   EXPECT_GT(sketch->bytes_value().size(), 4u);
      39            1 : }
      40              : 
      41            1 : TEST(KllFuncsTest, ExtractInt64HalvesOnSmallSet) {
      42            1 :   auto sketch = InitInt64({1, 2, 3, 4, 5});
      43            2 :   ASSERT_TRUE(sketch.ok()) << sketch.status();
      44              : 
      45            1 :   auto halves = KllQuantilesExtractInt64Scalar({*sketch, Value::Int64(2)},
      46            1 :                                                Int64ArrayType());
      47            2 :   ASSERT_TRUE(halves.ok()) << halves.status();
      48            1 :   ASSERT_TRUE(halves->type()->IsArray());
      49            1 :   ASSERT_EQ(halves->elements().size(), 3u);
      50            1 :   EXPECT_EQ(halves->elements()[0].int64_value(), 1);
      51            1 :   EXPECT_EQ(halves->elements()[1].int64_value(), 3);
      52            1 :   EXPECT_EQ(halves->elements()[2].int64_value(), 5);
      53            1 : }
      54              : 
      55            1 : TEST(KllFuncsTest, ExtractPointInt64P80) {
      56            1 :   auto sketch = InitInt64({1, 2, 3, 4, 5});
      57            2 :   ASSERT_TRUE(sketch.ok()) << sketch.status();
      58              : 
      59            1 :   auto p80 = KllQuantilesExtractPointInt64Scalar({*sketch, Value::Double(0.8)});
      60            2 :   ASSERT_TRUE(p80.ok()) << p80.status();
      61            1 :   EXPECT_EQ(p80->int64_value(), 4);
      62            1 : }
      63              : 
      64            1 : TEST(KllFuncsTest, MergePartialRoundTrip) {
      65            1 :   auto sketch_a = InitInt64({1, 2, 3});
      66            1 :   auto sketch_b = InitInt64({4, 5});
      67            2 :   ASSERT_TRUE(sketch_a.ok()) << sketch_a.status();
      68            2 :   ASSERT_TRUE(sketch_b.ok()) << sketch_b.status();
      69              : 
      70            1 :   auto merged = KllQuantilesMergePartialAggregate({{*sketch_a, *sketch_b}});
      71            2 :   ASSERT_TRUE(merged.ok()) << merged.status();
      72            1 :   EXPECT_FALSE(merged->is_null());
      73              : 
      74            1 :   auto halves = KllQuantilesExtractInt64Scalar({*merged, Value::Int64(2)},
      75            1 :                                                Int64ArrayType());
      76            2 :   ASSERT_TRUE(halves.ok()) << halves.status();
      77            1 :   EXPECT_EQ(halves->elements()[0].int64_value(), 1);
      78            1 :   EXPECT_EQ(halves->elements()[2].int64_value(), 5);
      79            1 : }
      80              : 
      81            1 : TEST(KllFuncsTest, MergeInt64AggregateReturnsHalves) {
      82            1 :   auto sketch_a = InitInt64({1, 2, 3});
      83            1 :   auto sketch_b = InitInt64({4, 5});
      84            2 :   ASSERT_TRUE(sketch_a.ok()) << sketch_a.status();
      85            2 :   ASSERT_TRUE(sketch_b.ok()) << sketch_b.status();
      86              : 
      87            1 :   auto merged = KllQuantilesMergeInt64Aggregate(
      88            1 :       {{*sketch_a, *sketch_b}, {Value::Int64(2)}}, Int64ArrayType());
      89            2 :   ASSERT_TRUE(merged.ok()) << merged.status();
      90            1 :   ASSERT_TRUE(merged->type()->IsArray());
      91            1 :   EXPECT_EQ(merged->elements().size(), 3u);
      92            1 :   EXPECT_EQ(merged->elements()[0].int64_value(), 1);
      93            1 :   EXPECT_EQ(merged->elements()[2].int64_value(), 5);
      94            1 : }
      95              : 
      96            1 : TEST(KllFuncsTest, InitWithWeightSkewsMedian) {
      97            1 :   std::vector<Value> inputs = {Value::Int64(1),
      98            1 :                                Value::Int64(2),
      99            1 :                                Value::Int64(3),
     100            1 :                                Value::Int64(4),
     101            1 :                                Value::Int64(5)};
     102            1 :   std::vector<Value> weights = {Value::Int64(1),
     103            1 :                                 Value::Int64(3),
     104            1 :                                 Value::Int64(1),
     105            1 :                                 Value::Int64(1),
     106            1 :                                 Value::Int64(1)};
     107            1 :   auto sketch = KllQuantilesInitInt64Values(inputs, 1000, &weights);
     108            2 :   ASSERT_TRUE(sketch.ok()) << sketch.status();
     109              : 
     110            1 :   auto halves = KllQuantilesExtractInt64Scalar({*sketch, Value::Int64(2)},
     111            1 :                                                Int64ArrayType());
     112            2 :   ASSERT_TRUE(halves.ok()) << halves.status();
     113            1 :   EXPECT_EQ(halves->elements()[0].int64_value(), 1);
     114            1 :   EXPECT_EQ(halves->elements()[1].int64_value(), 2);
     115            1 :   EXPECT_EQ(halves->elements()[2].int64_value(), 5);
     116            1 : }
     117              : 
     118            1 : TEST(KllFuncsTest, InvalidSketchBytesRejected) {
     119            1 :   Value invalid_sketch = Value::Bytes("not-a-sketch");
     120            1 :   Value num_quantiles = Value::Int64(2);
     121            1 :   auto got = KllQuantilesExtractInt64Scalar({invalid_sketch, num_quantiles},
     122            1 :                                             Int64ArrayType());
     123            1 :   EXPECT_FALSE(got.ok());
     124            1 : }
     125              : 
     126              : }  // namespace functions
     127              : }  // namespace semantic
     128              : }  // namespace engine
     129              : }  // namespace backend
     130              : }  // namespace bigquery_emulator
        

Generated by: LCOV version 2.0-1