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

            Line data    Source code
       1              : #include "backend/engine/semantic/functions/range_funcs.h"
       2              : 
       3              : #include <memory>
       4              : #include <string>
       5              : #include <vector>
       6              : 
       7              : #include "absl/status/statusor.h"
       8              : #include "absl/strings/str_cat.h"
       9              : #include "backend/engine/semantic/value.h"
      10              : #include "googlesql/public/analyzer.h"
      11              : #include "googlesql/public/analyzer_options.h"
      12              : #include "googlesql/public/analyzer_output.h"
      13              : #include "googlesql/public/builtin_function_options.h"
      14              : #include "googlesql/public/language_options.h"
      15              : #include "googlesql/public/options.pb.h"
      16              : #include "googlesql/public/simple_catalog.h"
      17              : #include "googlesql/public/types/type_factory.h"
      18              : #include "googlesql/public/value.h"
      19              : #include "googlesql/resolved_ast/resolved_ast.h"
      20              : #include "gtest/gtest.h"
      21              : 
      22              : namespace bigquery_emulator {
      23              : namespace backend {
      24              : namespace engine {
      25              : namespace semantic {
      26              : namespace functions {
      27              : namespace {
      28              : 
      29              : using ::googlesql::Value;
      30              : 
      31            6 : ::googlesql::AnalyzerOptions MakeAnalyzerOptions() {
      32            6 :   ::googlesql::LanguageOptions language;
      33            6 :   language.EnableMaximumLanguageFeatures();
      34            6 :   language.set_product_mode(::googlesql::PRODUCT_EXTERNAL);
      35            6 :   ::googlesql::AnalyzerOptions options(language);
      36            6 :   options.CreateDefaultArenasIfNotSet();
      37            6 :   return options;
      38            6 : }
      39              : 
      40              : class RangeFuncsTest : public ::testing::Test {
      41              :  protected:
      42            3 :   void SetUp() override {
      43            3 :     type_factory_ = std::make_unique<::googlesql::TypeFactory>();
      44            3 :     catalog_ = std::make_unique<::googlesql::SimpleCatalog>(
      45            3 :         "range_funcs_catalog", type_factory_.get());
      46            3 :     catalog_->AddBuiltinFunctions(
      47            3 :         ::googlesql::BuiltinFunctionOptions::AllReleasedFunctions());
      48            3 :   }
      49              : 
      50            6 :   absl::StatusOr<Value> LiteralValue(absl::string_view literal_sql) {
      51            6 :     last_output_.reset();
      52            6 :     const std::string sql = absl::StrCat("SELECT ", literal_sql);
      53            6 :     absl::Status s = ::googlesql::AnalyzeStatement(sql,
      54            6 :                                                    MakeAnalyzerOptions(),
      55            6 :                                                    catalog_.get(),
      56            6 :                                                    type_factory_.get(),
      57            6 :                                                    &last_output_);
      58            6 :     if (!s.ok()) return s;
      59            6 :     if (last_output_ == nullptr) {
      60            0 :       return absl::InternalError("analyzer returned null output");
      61            0 :     }
      62            6 :     const auto* stmt = last_output_->resolved_statement()
      63            6 :                            ->GetAs<::googlesql::ResolvedQueryStmt>();
      64            6 :     if (stmt == nullptr) {
      65            0 :       return absl::InternalError("expected ResolvedQueryStmt");
      66            0 :     }
      67            6 :     const auto* project =
      68            6 :         stmt->query()->GetAs<::googlesql::ResolvedProjectScan>();
      69            6 :     if (project == nullptr || project->expr_list_size() == 0) {
      70            0 :       return absl::InternalError("expected literal project scan");
      71            0 :     }
      72            6 :     const auto* lit =
      73            6 :         project->expr_list(0)->expr()->GetAs<::googlesql::ResolvedLiteral>();
      74            6 :     if (lit == nullptr) {
      75            0 :       return absl::InternalError("expected ResolvedLiteral");
      76            0 :     }
      77            6 :     return lit->value();
      78            6 :   }
      79              : 
      80              :   std::unique_ptr<::googlesql::TypeFactory> type_factory_{};
      81              :   std::unique_ptr<::googlesql::SimpleCatalog> catalog_{};
      82              :   std::unique_ptr<const ::googlesql::AnalyzerOutput> last_output_{};
      83              : };
      84              : 
      85            1 : TEST_F(RangeFuncsTest, RangeOverlapsDetectsOverlap) {
      86            1 :   auto a_or = LiteralValue("RANGE<DATE> '[2001-11-12, 2001-11-14)'");
      87            1 :   auto b_or = LiteralValue("RANGE<DATE> '[2001-11-13, 2001-11-15)'");
      88            2 :   ASSERT_TRUE(a_or.ok()) << a_or.status();
      89            2 :   ASSERT_TRUE(b_or.ok()) << b_or.status();
      90            1 :   Value a = *std::move(a_or);
      91            1 :   Value b = *std::move(b_or);
      92            1 :   auto v = RangeOverlaps({a, b});
      93            2 :   ASSERT_TRUE(v.ok()) << v.status();
      94            1 :   EXPECT_TRUE(v->bool_value());
      95            1 : }
      96              : 
      97            1 : TEST_F(RangeFuncsTest, RangeOverlapsAdjacentRangesDoNotOverlap) {
      98            1 :   auto a_or = LiteralValue("RANGE<DATE> '[2001-11-12, 2001-11-14)'");
      99            1 :   auto b_or = LiteralValue("RANGE<DATE> '[2001-11-14, 2001-11-15)'");
     100            2 :   ASSERT_TRUE(a_or.ok()) << a_or.status();
     101            2 :   ASSERT_TRUE(b_or.ok()) << b_or.status();
     102            1 :   Value a = *std::move(a_or);
     103            1 :   Value b = *std::move(b_or);
     104            1 :   auto v = RangeOverlaps({a, b});
     105            2 :   ASSERT_TRUE(v.ok()) << v.status();
     106            1 :   EXPECT_FALSE(v->bool_value());
     107            1 : }
     108              : 
     109            1 : TEST_F(RangeFuncsTest, RangeStartAndCtorBuildLdiffSlice) {
     110            1 :   auto p1_or = LiteralValue("RANGE<DATE> '[2001-11-12, 2001-11-14)'");
     111            1 :   auto p2_or = LiteralValue("RANGE<DATE> '[2001-11-13, 2001-11-15)'");
     112            2 :   ASSERT_TRUE(p1_or.ok()) << p1_or.status();
     113            2 :   ASSERT_TRUE(p2_or.ok()) << p2_or.status();
     114            1 :   Value p1 = *std::move(p1_or);
     115            1 :   Value p2 = *std::move(p2_or);
     116            1 :   auto start1 = RangeStart({p1});
     117            1 :   auto start2 = RangeStart({p2});
     118            2 :   ASSERT_TRUE(start1.ok()) << start1.status();
     119            2 :   ASSERT_TRUE(start2.ok()) << start2.status();
     120            1 :   auto range = RangeCtor({*start1, *start2}, p1.type());
     121            2 :   ASSERT_TRUE(range.ok()) << range.status();
     122            1 :   EXPECT_EQ(range->type_kind(), ::googlesql::TYPE_RANGE);
     123            1 :   std::string lit = range->GetSQLLiteral();
     124           38 :   for (char& c : lit) {
     125           38 :     if (c == '"') c = '\'';
     126           38 :   }
     127            1 :   EXPECT_EQ(lit, "RANGE<DATE> '[2001-11-12, 2001-11-13)'");
     128            1 : }
     129              : 
     130              : }  // namespace
     131              : }  // namespace functions
     132              : }  // namespace semantic
     133              : }  // namespace engine
     134              : }  // namespace backend
     135              : }  // namespace bigquery_emulator
        

Generated by: LCOV version 2.0-1