• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef SRC_TRACE_PROCESSOR_PRELUDE_FUNCTIONS_SQL_FUNCTION_H_
18 #define SRC_TRACE_PROCESSOR_PRELUDE_FUNCTIONS_SQL_FUNCTION_H_
19 
20 #include <sqlite3.h>
21 #include <memory>
22 
23 #include "perfetto/base/status.h"
24 #include "perfetto/trace_processor/basic_types.h"
25 
26 namespace perfetto {
27 namespace trace_processor {
28 
29 // Prototype for a C++ function which can be registered with SQLite.
30 //
31 // Usage
32 //
33 // Define a subclass of this struct as follows:
34 // struct YourFunction : public SqlFunction {
35 //   // Optional if you want a custom context object (i.e. an object
36 //   // passed in at registration time which will be passed to Run on
37 //   // every invocation)
38 //   struct YourContext { /* define context fields here */ };
39 //
40 //   static base::Status Run(/* see parameters below */) {
41 //     /* function body here */
42 //   }
43 //
44 //   static base::Status Cleanup(/* see parameters below */) {
45 //     /* function body here */
46 //   }
47 // }
48 //
49 // Then, register this function with SQLite using RegisterFunction (see below);
50 // you'll likely want to do this in TraceProcessorImpl:
51 // RegisterFunction<YourFunction>(/* see arguments below */)
52 struct SqlFunction {
53   // The type of the context object which will be passed to the function.
54   // Can be redefined in any sub-classes to override the context.
55   using Context = void;
56 
57   // Indicates whether this function is "void" (i.e. doesn't actually want
58   // to return a value). While the function will still return null in SQL
59   // (because SQLite does not actually allow null functions), for accounting
60   // purposes, this null will be ignored when verifying whether this statement
61   // has any output.
62   // Can be redefined in any sub-classes to override it.
63   // If this is set to true, subclasses must not modify |out| or |destructors|.
64   static constexpr bool kVoidReturn = false;
65 
66   // Struct which holds destructors for strings/bytes returned from the
67   // function. Passed as an argument to |Run| to allow implementations to
68   // override the destructors.
69   struct Destructors {
70     // This matches SQLITE_TRANSIENT constant which we cannot use because it
71     // expands to a C-style cast, causing compiler warnings.
72     sqlite3_destructor_type string_destructor =
73         reinterpret_cast<sqlite3_destructor_type>(-1);
74     sqlite3_destructor_type bytes_destructor =
75         reinterpret_cast<sqlite3_destructor_type>(-1);
76   };
77 
78   // The function which will be executed with the arguments from SQL.
79   //
80   // Implementations MUST define this function themselves; this function is
81   // declared but *not* defined so linker errors will be thrown if not defined.
82   //
83   // |ctx|:         the context object passed at registration time.
84   // |argc|:        number of arguments.
85   // |argv|:        arguments to the function.
86   // |out|:         the return value of the function.
87   // |destructors|: destructors for string/bytes return values.
88   static base::Status Run(Context* ctx,
89                           size_t argc,
90                           sqlite3_value** argv,
91                           SqlValue& out,
92                           Destructors& destructors);
93 
94   // Executed after the result from |Run| is reported to SQLite.
95   // Allows implementations to verify post-conditions without needing to worry
96   // about overwriting return types.
97   //
98   // Implementations do not need to define this function; a default no-op
99   // implementation will be used in this case.
100   static base::Status VerifyPostConditions(Context*);
101 
102   // Executed after the result from |Run| is reported to SQLite.
103   // Allows any pending state to be cleaned up post-copy of results by SQLite:
104   // this function will be called even if |Run| or |PostRun| returned errors.
105   //
106   // Implementations do not need to define this function; a default no-op
107   // implementation will be used in this case.
108   static void Cleanup(Context*);
109 };
110 
111 }  // namespace trace_processor
112 }  // namespace perfetto
113 
114 #endif  // SRC_TRACE_PROCESSOR_PRELUDE_FUNCTIONS_SQL_FUNCTION_H_
115