Line data Source code
1 : #ifndef BIGQUERY_EMULATOR_BACKEND_ENGINE_SEMANTIC_EXECUTOR_TEST_FIXTURE_H_
2 : #define BIGQUERY_EMULATOR_BACKEND_ENGINE_SEMANTIC_EXECUTOR_TEST_FIXTURE_H_
3 :
4 : #include <memory>
5 : #include <string>
6 :
7 : #include "absl/status/status.h"
8 : #include "absl/status/statusor.h"
9 : #include "backend/engine/engine.h"
10 : #include "backend/engine/semantic/executor.h"
11 : #include "backend/storage/storage.h"
12 : #include "googlesql/public/analyzer.h"
13 : #include "googlesql/public/analyzer_options.h"
14 : #include "googlesql/public/analyzer_output.h"
15 : #include "googlesql/public/builtin_function_options.h"
16 : #include "googlesql/public/catalog.h"
17 : #include "googlesql/public/language_options.h"
18 : #include "googlesql/public/options.pb.h"
19 : #include "googlesql/public/simple_catalog.h"
20 : #include "googlesql/public/types/type_factory.h"
21 : #include "googlesql/resolved_ast/resolved_ast.h"
22 : #include "gtest/gtest.h"
23 :
24 : namespace bigquery_emulator {
25 : namespace backend {
26 : namespace engine {
27 : namespace semantic {
28 :
29 : // NOTE: deliberately NOT in an anonymous namespace. Both
30 : // `executor_test.cc` and `executor_analytic_test.cc` link into the
31 : // same `cc_test` binary and share the `SemanticExecutorTest` suite
32 : // name; an anonymous namespace would give each TU a distinct fixture
33 : // type, which gtest rejects ("must use the same test fixture class").
34 :
35 33 : inline ::googlesql::AnalyzerOptions MakeAnalyzerOptions() {
36 33 : ::googlesql::LanguageOptions language;
37 33 : language.EnableMaximumLanguageFeatures();
38 33 : language.set_product_mode(::googlesql::PRODUCT_EXTERNAL);
39 33 : ::googlesql::AnalyzerOptions options(language);
40 33 : options.CreateDefaultArenasIfNotSet();
41 33 : return options;
42 33 : }
43 :
44 : class SemanticExecutorTest : public ::testing::Test {
45 : protected:
46 34 : void SetUp() override {
47 34 : type_factory_ = std::make_unique<::googlesql::TypeFactory>();
48 34 : catalog_ = std::make_unique<::googlesql::SimpleCatalog>(
49 34 : "exec_catalog", type_factory_.get());
50 34 : catalog_->AddBuiltinFunctions(
51 34 : ::googlesql::BuiltinFunctionOptions::AllReleasedFunctions());
52 34 : }
53 :
54 : const ::googlesql::ResolvedStatement* Analyze(
55 32 : absl::string_view sql, const ::googlesql::AnalyzerOptions& options) {
56 32 : last_output_.reset();
57 32 : absl::Status s = ::googlesql::AnalyzeStatement(
58 32 : sql, options, catalog_.get(), type_factory_.get(), &last_output_);
59 64 : EXPECT_TRUE(s.ok()) << s;
60 32 : if (!s.ok() || last_output_ == nullptr) return nullptr;
61 32 : return last_output_->resolved_statement();
62 32 : }
63 :
64 33 : QueryRequest MakeRequest(absl::string_view sql) {
65 33 : QueryRequest req;
66 33 : req.project_id = "test-project";
67 33 : req.sql = std::string(sql);
68 33 : return req;
69 33 : }
70 :
71 : // Drain a single-row output and return the first cell.
72 : absl::StatusOr<storage::Value> RunForFirstCell(
73 : const std::string& sql,
74 : ::googlesql::AnalyzerOptions options = MakeAnalyzerOptions(),
75 7 : QueryRequest req = QueryRequest{}) {
76 7 : const auto* stmt = Analyze(sql, options);
77 7 : if (stmt == nullptr) return absl::InternalError("analyzer failed");
78 7 : if (req.sql.empty()) req = MakeRequest(sql);
79 7 : SemanticExecutor exec;
80 7 : auto source = exec.ExecuteQuery(req, *stmt, catalog_.get());
81 7 : if (!source.ok()) return source.status();
82 7 : storage::Row row;
83 7 : auto has = (*source)->Next(&row);
84 7 : if (!has.ok()) return has.status();
85 7 : if (!*has) return absl::InternalError("executor returned no rows");
86 7 : if (row.cells.empty()) return absl::InternalError("row has no cells");
87 7 : return row.cells[0];
88 7 : }
89 :
90 : std::unique_ptr<::googlesql::TypeFactory> type_factory_{};
91 : std::unique_ptr<::googlesql::SimpleCatalog> catalog_{};
92 : std::unique_ptr<const ::googlesql::AnalyzerOutput> last_output_{};
93 : };
94 :
95 : } // namespace semantic
96 : } // namespace engine
97 : } // namespace backend
98 : } // namespace bigquery_emulator
99 :
100 : #endif // BIGQUERY_EMULATOR_BACKEND_ENGINE_SEMANTIC_EXECUTOR_TEST_FIXTURE_H_
|