Line data Source code
1 : #ifndef BIGQUERY_EMULATOR_BACKEND_ENGINE_SEMANTIC_EXECUTOR_H_
2 : #define BIGQUERY_EMULATOR_BACKEND_ENGINE_SEMANTIC_EXECUTOR_H_
3 :
4 : // `SemanticExecutor` is the local row/array/value interpreter the
5 : // `LocalCoordinatorEngine` dispatches to whenever
6 : // `RouteClassifier::Classify` picks the `kSemanticExecutor` route.
7 : //
8 : // Today's surface (per
9 : // `docs/ENGINE_POLICY.md`) is scalar-only
10 : // SELECT: a `ResolvedQueryStmt` whose `query()` is a
11 : // `ResolvedProjectScan` over a `ResolvedSingleRowScan` (no FROM
12 : // clause). The executor walks the resolved AST, evaluates each
13 : // output column's expression via `EvalExpr`, converts the result
14 : // into `storage::Value`, and streams a single one-row Arrow batch.
15 : // Downstream plans add FROM-clause shapes that compose with
16 : // `DuckDbExecutor` through a `RowSource` adapter.
17 :
18 : #include <memory>
19 :
20 : #include "absl/status/status.h"
21 : #include "absl/status/statusor.h"
22 : #include "backend/engine/coordinator/executor.h"
23 : #include "backend/engine/engine.h"
24 : #include "backend/engine/semantic/frame_stack.h"
25 : #include "backend/storage/storage.h"
26 : #include "googlesql/public/analyzer.h"
27 :
28 : namespace googlesql {
29 : class Catalog;
30 : class ResolvedQueryStmt;
31 : class ResolvedStatement;
32 : } // namespace googlesql
33 :
34 : namespace bigquery_emulator {
35 : namespace backend {
36 : namespace engine {
37 : namespace semantic {
38 :
39 : // Execute an already-resolved SELECT with optional script-variable
40 : // bindings (used by the coordinator script driver for final SELECT
41 : // statements inside BEGIN..END blocks).
42 : [[nodiscard]] absl::StatusOr<std::unique_ptr<RowSource>>
43 : ExecuteResolvedQueryStmt(const QueryRequest& request,
44 : const ::googlesql::ResolvedQueryStmt& query_stmt,
45 : const FrameStack* script_variables = nullptr,
46 : const ::googlesql::SystemVariableValuesMap*
47 : script_system_variables = nullptr);
48 :
49 : // `SemanticExecutor` implements `coordinator::Executor` and so
50 : // installs cleanly into the coordinator's per-route dispatch
51 : // table. Beyond the SELECT path the executor also owns the
52 : // storage-aware DML routes (`backend/engine/semantic/dml/`,
53 : // `docs/ENGINE_POLICY.md`); `storage` is a
54 : // non-owning pointer passed through from the coordinator and used
55 : // by the DML path to mutate target tables. `storage` may be null
56 : // in unit tests that exercise only the SELECT path.
57 : class SemanticExecutor : public coordinator::Executor {
58 : public:
59 16 : SemanticExecutor() = default;
60 0 : explicit SemanticExecutor(storage::Storage* storage) : storage_(storage) {}
61 : ~SemanticExecutor() override;
62 :
63 : SemanticExecutor(const SemanticExecutor&) = delete;
64 : SemanticExecutor& operator=(const SemanticExecutor&) = delete;
65 :
66 : [[nodiscard]] absl::StatusOr<std::unique_ptr<RowSource>> ExecuteQuery(
67 : const QueryRequest& request,
68 : const ::googlesql::ResolvedStatement& stmt,
69 : ::googlesql::Catalog* catalog) override;
70 :
71 : // DML routes through the storage-aware local DML executor in
72 : // `backend/engine/semantic/dml/`. Statements the DML executor
73 : // does not yet handle surface a structured `kNotImplemented`
74 : // so the gateway envelope is the same as for any other
75 : // "planned but not landed" route. DDL stays on the
76 : // control-op executor and the semantic executor surfaces a
77 : // clean error if it ever sees one.
78 : [[nodiscard]] absl::StatusOr<DmlResult> ExecuteDml(
79 : const QueryRequest& request,
80 : const ::googlesql::ResolvedStatement& stmt,
81 : ::googlesql::Catalog* catalog) override;
82 :
83 : [[nodiscard]] absl::Status ExecuteDdl(
84 : const QueryRequest& request,
85 : const ::googlesql::ResolvedStatement& stmt,
86 : ::googlesql::Catalog* catalog) override;
87 :
88 : private:
89 : storage::Storage* storage_ = nullptr; // not owned; may be null
90 : };
91 :
92 : } // namespace semantic
93 : } // namespace engine
94 : } // namespace backend
95 : } // namespace bigquery_emulator
96 :
97 : #endif // BIGQUERY_EMULATOR_BACKEND_ENGINE_SEMANTIC_EXECUTOR_H_
|