xref: /aosp_15_r20/external/perfetto/src/trace_processor/sqlite/db_sqlite_table.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2019 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_SQLITE_DB_SQLITE_TABLE_H_
18 #define SRC_TRACE_PROCESSOR_SQLITE_DB_SQLITE_TABLE_H_
19 
20 #include <sqlite3.h>
21 #include <cstdint>
22 #include <memory>
23 #include <optional>
24 #include <string>
25 #include <vector>
26 
27 #include "perfetto/trace_processor/basic_types.h"
28 #include "src/trace_processor/db/column/types.h"
29 #include "src/trace_processor/db/runtime_table.h"
30 #include "src/trace_processor/db/table.h"
31 #include "src/trace_processor/perfetto_sql/intrinsics/table_functions/static_table_function.h"
32 #include "src/trace_processor/sqlite/bindings/sqlite_module.h"
33 #include "src/trace_processor/sqlite/module_lifecycle_manager.h"
34 
35 namespace perfetto::trace_processor {
36 
37 enum class TableComputation {
38   // Table is statically defined.
39   kStatic,
40 
41   // Table is defined as a function.
42   kTableFunction,
43 
44   // Table is defined in runtime.
45   kRuntime
46 };
47 
48 // Implements the SQLite table interface for db tables.
49 struct DbSqliteModule : public sqlite::Module<DbSqliteModule> {
50   struct State {
51     State(Table*, Table::Schema);
52     explicit State(std::unique_ptr<RuntimeTable>);
53     explicit State(std::unique_ptr<StaticTableFunction>);
54 
55     TableComputation computation;
56     Table::Schema schema;
57     int argument_count = 0;
58 
59     // Only valid when computation == TableComputation::kStatic.
60     Table* static_table = nullptr;
61 
62     // Only valid when computation == TableComputation::kRuntime.
63     std::unique_ptr<RuntimeTable> runtime_table;
64 
65     // Only valid when computation == TableComputation::kTableFunction.
66     std::unique_ptr<StaticTableFunction> static_table_function;
67 
68    private:
69     State(TableComputation, Table::Schema);
70   };
71   struct Context {
72     std::unique_ptr<State> temporary_create_state;
73     sqlite::ModuleStateManager<DbSqliteModule> manager;
74   };
75   struct Vtab : public sqlite::Module<DbSqliteModule>::Vtab {
76     sqlite::ModuleStateManager<DbSqliteModule>::PerVtabState* state;
77     int best_index_num = 0;
78     std::string table_name;
79   };
80   struct Cursor : public sqlite::Module<DbSqliteModule>::Cursor {
81     enum class Mode {
82       kSingleRow,
83       kTable,
84     };
85 
86     const Table* upstream_table = nullptr;
87 
88     // Only valid for |db_sqlite_table_->computation_| ==
89     // TableComputation::kDynamic.
90     std::unique_ptr<Table> dynamic_table;
91 
92     // Only valid for Mode::kSingleRow.
93     std::optional<uint32_t> single_row;
94 
95     // Only valid for Mode::kTable.
96     std::optional<Table::Iterator> iterator;
97 
98     bool eof = true;
99 
100     // Stores a sorted version of |db_table| sorted on a repeated equals
101     // constraint. This allows speeding up repeated subqueries in joins
102     // significantly.
103     std::optional<Table> sorted_cache_table;
104 
105     // Stores the count of repeated equality queries to decide whether it is
106     // wortwhile to sort |db_table| to create |sorted_cache_table|.
107     uint32_t repeated_cache_count = 0;
108 
109     Mode mode = Mode::kSingleRow;
110 
111     int last_idx_num = -1;
112 
113     Query query;
114 
115     std::vector<SqlValue> table_function_arguments;
116   };
117   struct QueryCost {
118     double cost;
119     uint32_t rows;
120   };
121 
122   static constexpr bool kSupportsWrites = false;
123   static constexpr bool kDoesOverloadFunctions = false;
124 
125   static int Create(sqlite3*,
126                     void*,
127                     int,
128                     const char* const*,
129                     sqlite3_vtab**,
130                     char**);
131   static int Destroy(sqlite3_vtab*);
132 
133   static int Connect(sqlite3*,
134                      void*,
135                      int,
136                      const char* const*,
137                      sqlite3_vtab**,
138                      char**);
139   static int Disconnect(sqlite3_vtab*);
140 
141   static int BestIndex(sqlite3_vtab*, sqlite3_index_info*);
142 
143   static int Open(sqlite3_vtab*, sqlite3_vtab_cursor**);
144   static int Close(sqlite3_vtab_cursor*);
145 
146   static int Filter(sqlite3_vtab_cursor*,
147                     int,
148                     const char*,
149                     int,
150                     sqlite3_value**);
151   static int Next(sqlite3_vtab_cursor*);
152   static int Eof(sqlite3_vtab_cursor*);
153   static int Column(sqlite3_vtab_cursor*, sqlite3_context*, int);
154   static int Rowid(sqlite3_vtab_cursor*, sqlite_int64*);
155 
156   // static for testing.
157   static QueryCost EstimateCost(const Table::Schema&,
158                                 uint32_t row_count,
159                                 sqlite3_index_info* info,
160                                 const std::vector<int>&,
161                                 const std::vector<int>&);
162 
163   // This needs to happen at the end as it depends on the functions
164   // defined above.
165   static constexpr sqlite3_module kModule = CreateModule();
166 };
167 
168 }  // namespace perfetto::trace_processor
169 
170 #endif  // SRC_TRACE_PROCESSOR_SQLITE_DB_SQLITE_TABLE_H_
171