Line data Source code
1 : #include "backend/engine/semantic/error.h"
2 : #include "backend/engine/semantic/eval_expr.h"
3 : #include "backend/engine/semantic/eval_expr_test_fixture.h"
4 : #include "backend/engine/semantic/expression_column_bindings.h"
5 : #include "backend/engine/semantic/frame_stack.h"
6 : #include "googlesql/public/analyzer.h"
7 : #include "googlesql/public/type.h"
8 : #include "googlesql/public/value.h"
9 : #include "googlesql/resolved_ast/resolved_ast.h"
10 : #include "googlesql/resolved_ast/resolved_node_kind.pb.h"
11 : #include "gtest/gtest.h"
12 :
13 : namespace bigquery_emulator {
14 : namespace backend {
15 : namespace engine {
16 : namespace semantic {
17 : namespace {
18 :
19 1 : TEST_F(EvalExprTest, ResolvedExpressionColumnBindsFromColumnsByName) {
20 1 : FrameStack variables;
21 1 : ASSERT_TRUE(variables.Declare("base", ::googlesql::Value::Int64(10)).ok());
22 :
23 1 : ::googlesql::AnalyzerOptions options = MakeAnalyzerOptions();
24 1 : ASSERT_TRUE(
25 1 : RegisterExpressionColumnsOnAnalyzerOptions(variables, options).ok());
26 :
27 1 : std::unique_ptr<const ::googlesql::AnalyzerOutput> output;
28 1 : absl::Status analyzed = ::googlesql::AnalyzeExpression(
29 1 : "base + 5", options, catalog_.get(), type_factory_.get(), &output);
30 2 : ASSERT_TRUE(analyzed.ok()) << analyzed;
31 1 : ASSERT_NE(output, nullptr);
32 1 : ASSERT_NE(output->resolved_expr(), nullptr);
33 :
34 1 : EvalContext ctx;
35 1 : absl::flat_hash_map<std::string, ::googlesql::Value> columns_by_name;
36 1 : PopulateEvalContextExpressionColumns(variables, ctx, &columns_by_name);
37 :
38 1 : absl::StatusOr<Value> result = EvalExpr(*output->resolved_expr(), ctx);
39 2 : ASSERT_TRUE(result.ok()) << result.status();
40 1 : EXPECT_TRUE(result->type()->IsInt64());
41 1 : EXPECT_EQ(result->int64_value(), 15);
42 1 : }
43 :
44 1 : TEST_F(EvalExprTest, ResolvedExpressionColumnFallsBackToScriptVariables) {
45 1 : std::unique_ptr<::googlesql::ResolvedExpressionColumn> col =
46 1 : ::googlesql::MakeResolvedExpressionColumn(::googlesql::types::Int64Type(),
47 1 : "counter");
48 1 : FrameStack variables;
49 1 : ASSERT_TRUE(variables.Declare("counter", ::googlesql::Value::Int64(42)).ok());
50 :
51 1 : EvalContext ctx;
52 1 : ctx.script_variables = &variables;
53 1 : absl::StatusOr<Value> result = EvalExpr(*col, ctx);
54 2 : ASSERT_TRUE(result.ok()) << result.status();
55 1 : EXPECT_EQ(result->int64_value(), 42);
56 1 : }
57 :
58 1 : TEST_F(EvalExprTest, ResolvedExpressionColumnMissingBindingSurfacesError) {
59 1 : std::unique_ptr<::googlesql::ResolvedExpressionColumn> col =
60 1 : ::googlesql::MakeResolvedExpressionColumn(::googlesql::types::Int64Type(),
61 1 : "missing");
62 :
63 1 : EvalContext ctx;
64 1 : absl::StatusOr<Value> result = EvalExpr(*col, ctx);
65 1 : ASSERT_FALSE(result.ok());
66 1 : EXPECT_EQ(GetSemanticErrorReason(result.status()),
67 1 : SemanticErrorReason::kInvalidArgument);
68 1 : }
69 :
70 : TEST_F(EvalExprTest,
71 1 : ResolvedCatalogColumnRefGraphPropertySurfacesNotImplemented) {
72 1 : std::unique_ptr<::googlesql::ResolvedCatalogColumnRef> ref =
73 1 : ::googlesql::MakeResolvedCatalogColumnRef(::googlesql::types::Int64Type(),
74 1 : /*column=*/nullptr,
75 1 : "graph_prop");
76 :
77 1 : EvalContext ctx;
78 1 : absl::StatusOr<Value> result = EvalExpr(*ref, ctx);
79 1 : ASSERT_FALSE(result.ok());
80 1 : EXPECT_EQ(GetSemanticErrorReason(result.status()),
81 1 : SemanticErrorReason::kNotImplemented);
82 1 : }
83 :
84 : } // namespace
85 : } // namespace semantic
86 : } // namespace engine
87 : } // namespace backend
88 : } // namespace bigquery_emulator
|