/* * Copyright (C) 2023 The Android Open Source Project * * 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 SRC_TRACE_PROCESSOR_PRELUDE_FUNCTIONS_SQL_FUNCTION_H_ #define SRC_TRACE_PROCESSOR_PRELUDE_FUNCTIONS_SQL_FUNCTION_H_ #include #include #include "perfetto/base/status.h" #include "perfetto/trace_processor/basic_types.h" namespace perfetto { namespace trace_processor { // Prototype for a C++ function which can be registered with SQLite. // // Usage // // Define a subclass of this struct as follows: // struct YourFunction : public SqlFunction { // // Optional if you want a custom context object (i.e. an object // // passed in at registration time which will be passed to Run on // // every invocation) // struct YourContext { /* define context fields here */ }; // // static base::Status Run(/* see parameters below */) { // /* function body here */ // } // // static base::Status Cleanup(/* see parameters below */) { // /* function body here */ // } // } // // Then, register this function with SQLite using RegisterFunction (see below); // you'll likely want to do this in TraceProcessorImpl: // RegisterFunction(/* see arguments below */) struct SqlFunction { // The type of the context object which will be passed to the function. // Can be redefined in any sub-classes to override the context. using Context = void; // Indicates whether this function is "void" (i.e. doesn't actually want // to return a value). While the function will still return null in SQL // (because SQLite does not actually allow null functions), for accounting // purposes, this null will be ignored when verifying whether this statement // has any output. // Can be redefined in any sub-classes to override it. // If this is set to true, subclasses must not modify |out| or |destructors|. static constexpr bool kVoidReturn = false; // Struct which holds destructors for strings/bytes returned from the // function. Passed as an argument to |Run| to allow implementations to // override the destructors. struct Destructors { // This matches SQLITE_TRANSIENT constant which we cannot use because it // expands to a C-style cast, causing compiler warnings. sqlite3_destructor_type string_destructor = reinterpret_cast(-1); sqlite3_destructor_type bytes_destructor = reinterpret_cast(-1); }; // The function which will be executed with the arguments from SQL. // // Implementations MUST define this function themselves; this function is // declared but *not* defined so linker errors will be thrown if not defined. // // |ctx|: the context object passed at registration time. // |argc|: number of arguments. // |argv|: arguments to the function. // |out|: the return value of the function. // |destructors|: destructors for string/bytes return values. static base::Status Run(Context* ctx, size_t argc, sqlite3_value** argv, SqlValue& out, Destructors& destructors); // Executed after the result from |Run| is reported to SQLite. // Allows implementations to verify post-conditions without needing to worry // about overwriting return types. // // Implementations do not need to define this function; a default no-op // implementation will be used in this case. static base::Status VerifyPostConditions(Context*); // Executed after the result from |Run| is reported to SQLite. // Allows any pending state to be cleaned up post-copy of results by SQLite: // this function will be called even if |Run| or |PostRun| returned errors. // // Implementations do not need to define this function; a default no-op // implementation will be used in this case. static void Cleanup(Context*); }; } // namespace trace_processor } // namespace perfetto #endif // SRC_TRACE_PROCESSOR_PRELUDE_FUNCTIONS_SQL_FUNCTION_H_