xref: /aosp_15_r20/external/perfetto/src/trace_processor/perfetto_sql/engine/runtime_table_function.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
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_PERFETTO_SQL_ENGINE_RUNTIME_TABLE_FUNCTION_H_
18 #define SRC_TRACE_PROCESSOR_PERFETTO_SQL_ENGINE_RUNTIME_TABLE_FUNCTION_H_
19 
20 #include <cstddef>
21 #include <cstdint>
22 #include <memory>
23 #include <optional>
24 #include <vector>
25 
26 #include "perfetto/base/logging.h"
27 #include "src/trace_processor/perfetto_sql/parser/function_util.h"
28 #include "src/trace_processor/sqlite/bindings/sqlite_module.h"
29 #include "src/trace_processor/sqlite/module_lifecycle_manager.h"
30 #include "src/trace_processor/sqlite/sql_source.h"
31 #include "src/trace_processor/sqlite/sqlite_engine.h"
32 #include "src/trace_processor/util/sql_argument.h"
33 
34 namespace perfetto::trace_processor {
35 
36 class PerfettoSqlEngine;
37 
38 // The implementation of the SqliteTableLegacy interface for table functions
39 // defined at runtime using SQL.
40 struct RuntimeTableFunctionModule
41     : public sqlite::Module<RuntimeTableFunctionModule> {
42   struct State {
43     PerfettoSqlEngine* engine;
44     SqlSource sql_defn_str;
45 
46     FunctionPrototype prototype;
47     std::vector<sql_argument::ArgumentDefinition> return_values;
48 
49     std::optional<SqliteEngine::PreparedStatement> temporary_create_stmt;
50 
IsReturnValueColumnRuntimeTableFunctionModule::State51     bool IsReturnValueColumn(size_t i) const {
52       PERFETTO_DCHECK(i < TotalColumnCount());
53       return i < return_values.size();
54     }
55 
IsArgumentColumnRuntimeTableFunctionModule::State56     bool IsArgumentColumn(size_t i) const {
57       PERFETTO_DCHECK(i < TotalColumnCount());
58       return i >= return_values.size() &&
59              (i - return_values.size()) < prototype.arguments.size();
60     }
61 
IsPrimaryKeyColumnRuntimeTableFunctionModule::State62     bool IsPrimaryKeyColumn(size_t i) const {
63       PERFETTO_DCHECK(i < TotalColumnCount());
64       return i == (return_values.size() + prototype.arguments.size());
65     }
66 
TotalColumnCountRuntimeTableFunctionModule::State67     size_t TotalColumnCount() const {
68       static constexpr uint32_t kPrimaryKeyColumns = 1;
69       return prototype.arguments.size() + return_values.size() +
70              kPrimaryKeyColumns;
71     }
72   };
73   struct Context {
74     std::unique_ptr<State> temporary_create_state;
75     sqlite::ModuleStateManager<RuntimeTableFunctionModule> manager;
76   };
77   struct Vtab : sqlite::Module<RuntimeTableFunctionModule>::Vtab {
78     sqlite::ModuleStateManager<RuntimeTableFunctionModule>::PerVtabState* state;
79     std::optional<SqliteEngine::PreparedStatement> reusable_stmt;
80   };
81   struct Cursor : sqlite::Module<RuntimeTableFunctionModule>::Cursor {
82     std::optional<SqliteEngine::PreparedStatement> stmt;
83     bool is_eof = false;
84     int next_call_count = 0;
85   };
86 
87   static constexpr bool kSupportsWrites = false;
88   static constexpr bool kDoesOverloadFunctions = false;
89 
90   static int Create(sqlite3*,
91                     void*,
92                     int,
93                     const char* const*,
94                     sqlite3_vtab**,
95                     char**);
96   static int Destroy(sqlite3_vtab*);
97 
98   static int Connect(sqlite3*,
99                      void*,
100                      int,
101                      const char* const*,
102                      sqlite3_vtab**,
103                      char**);
104   static int Disconnect(sqlite3_vtab*);
105 
106   static int BestIndex(sqlite3_vtab*, sqlite3_index_info*);
107 
108   static int Open(sqlite3_vtab*, sqlite3_vtab_cursor**);
109   static int Close(sqlite3_vtab_cursor*);
110 
111   static int Filter(sqlite3_vtab_cursor*,
112                     int,
113                     const char*,
114                     int,
115                     sqlite3_value**);
116   static int Next(sqlite3_vtab_cursor*);
117   static int Eof(sqlite3_vtab_cursor*);
118   static int Column(sqlite3_vtab_cursor*, sqlite3_context*, int);
119   static int Rowid(sqlite3_vtab_cursor*, sqlite_int64*);
120 
121   // This needs to happen at the end as it depends on the functions
122   // defined above.
123   static constexpr sqlite3_module kModule = CreateModule();
124 };
125 
126 }  // namespace perfetto::trace_processor
127 
128 #endif  // SRC_TRACE_PROCESSOR_PERFETTO_SQL_ENGINE_RUNTIME_TABLE_FUNCTION_H_
129