backend/query/query_engine.h (71 lines of code) (raw):

// // Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #ifndef THIRD_PARTY_CLOUD_SPANNER_EMULATOR_BACKEND_QUERY_QUERY_ENGINE_H_ #define THIRD_PARTY_CLOUD_SPANNER_EMULATOR_BACKEND_QUERY_QUERY_ENGINE_H_ #include <memory> #include <optional> #include <string> #include "google/protobuf/struct.pb.h" #include "google/spanner/v1/spanner.pb.h" #include "zetasql/public/analyzer_options.h" #include "zetasql/public/type.h" #include "zetasql/public/value.h" #include "absl/memory/memory.h" #include "absl/status/status.h" #include "absl/status/statusor.h" #include "backend/query/change_stream/change_stream_query_validator.h" #include "backend/query/function_catalog.h" #include "backend/query/query_context.h" #include "backend/schema/catalog/schema.h" #include "absl/status/status.h" namespace google { namespace spanner { namespace emulator { namespace backend { // Query specifies the input of a query request. struct Query { // The SQL string to be executed. std::string sql; // The query parameters. Values in this map have already been deserialized as // their type was provided in the query. std::map<std::string, zetasql::Value> declared_params; // Parameters that did not have a type supplied. They will be deserialized in // the backend once the ZetaSQL analyzer provides types. std::map<std::string, google::protobuf::Value> undeclared_params; // If not empty,the current query is an internal query against a non public // partition or data table of this change stream std::optional<std::string> change_stream_internal_lookup; }; // Returns true if the given query is a DML statement. bool IsDMLQuery(const std::string& query); // Returns the returning clause of a DML statement. const zetasql::ResolvedReturningClause* GetReturningClause( const zetasql::ResolvedStatement* resolved_statement); // QueryResult specifies the output of a query request. struct QueryResult { // A row cursor containing the query result rows. It's null for DML requests // with returning clause. std::unique_ptr<RowCursor> rows; // Map containing the types of all query parameters. zetasql::QueryParametersMap parameter_types; // The number of modified rows. int64_t modified_row_count = 0; // The number of rows in the returned row cursor. int64_t num_output_rows = 0; // Query execution elapsed time. absl::Duration elapsed_time; }; // QueryEngine handles SQL-related requests. class QueryEngine { public: explicit QueryEngine(zetasql::TypeFactory* type_factory) : type_factory_(type_factory), function_catalog_(type_factory) {} // Returns the name of the table that a given DML query modifies. absl::StatusOr<std::string> GetDmlTargetTable(const Query& query, const Schema* schema) const; // Executes a SQL query (SELECT query or DML). // Skip execution if validate_only is true. absl::StatusOr<QueryResult> ExecuteSql(const Query& query, const QueryContext& context) const; // Executes a SQL query (SELECT query or DML) using the given query mode. absl::StatusOr<QueryResult> ExecuteSql( const Query& query, const QueryContext& context, v1::ExecuteSqlRequest_QueryMode query_mode) const; // Returns OK if query is partitionable. absl::Status IsPartitionable(const Query& query, const QueryContext& context) const; // Returns OK if the 'query' is a DML statement that can be executed through // partitioned DML. absl::Status IsValidPartitionedDML(const Query& query, const QueryContext& context) const; // Returns an empty change stream metadata if current query is a valid regular // query. Returns the complete change stream metadata if current query is a // valid change stream query. Returns corresponding error status if current // query is an invalid regular query, a non-change stream tvf query or an // invalid change stream tvf query. static absl::StatusOr<ChangeStreamQueryValidator::ChangeStreamMetadata> TryGetChangeStreamMetadata(const Query& query, const Schema* schema, bool in_read_write_txn = false); zetasql::TypeFactory* type_factory() const { return type_factory_; } const FunctionCatalog* function_catalog() const { return &function_catalog_; } void SetLatestSchemaForFunctionCatalog(const Schema* schema) { function_catalog_.SetLatestSchema(schema); } private: static std::string GetTimeZone(const Schema* schema); zetasql::TypeFactory* type_factory_; FunctionCatalog function_catalog_; }; } // namespace backend } // namespace emulator } // namespace spanner } // namespace google #endif // THIRD_PARTY_CLOUD_SPANNER_EMULATOR_BACKEND_QUERY_QUERY_ENGINE_H_