• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(const 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     const 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     Query query;
113 
114     std::vector<SqlValue> table_function_arguments;
115   };
116   struct QueryCost {
117     double cost;
118     uint32_t rows;
119   };
120 
121   static constexpr bool kSupportsWrites = false;
122   static constexpr bool kDoesOverloadFunctions = false;
123 
124   static int Create(sqlite3*,
125                     void*,
126                     int,
127                     const char* const*,
128                     sqlite3_vtab**,
129                     char**);
130   static int Destroy(sqlite3_vtab*);
131 
132   static int Connect(sqlite3*,
133                      void*,
134                      int,
135                      const char* const*,
136                      sqlite3_vtab**,
137                      char**);
138   static int Disconnect(sqlite3_vtab*);
139 
140   static int BestIndex(sqlite3_vtab*, sqlite3_index_info*);
141 
142   static int Open(sqlite3_vtab*, sqlite3_vtab_cursor**);
143   static int Close(sqlite3_vtab_cursor*);
144 
145   static int Filter(sqlite3_vtab_cursor*,
146                     int,
147                     const char*,
148                     int,
149                     sqlite3_value**);
150   static int Next(sqlite3_vtab_cursor*);
151   static int Eof(sqlite3_vtab_cursor*);
152   static int Column(sqlite3_vtab_cursor*, sqlite3_context*, int);
153   static int Rowid(sqlite3_vtab_cursor*, sqlite_int64*);
154 
155   // static for testing.
156   static QueryCost EstimateCost(const Table::Schema&,
157                                 uint32_t row_count,
158                                 sqlite3_index_info* info,
159                                 const std::vector<int>&,
160                                 const std::vector<int>&);
161 
162   // This needs to happen at the end as it depends on the functions
163   // defined above.
164   static constexpr sqlite3_module kModule = CreateModule();
165 };
166 
167 }  // namespace perfetto::trace_processor
168 
169 #endif  // SRC_TRACE_PROCESSOR_SQLITE_DB_SQLITE_TABLE_H_
170