1 /* 2 * Copyright (C) 2018 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_SQLITE_TABLE_H_ 18 #define SRC_TRACE_PROCESSOR_SQLITE_SQLITE_TABLE_H_ 19 20 #include <sqlite3.h> 21 22 #include <functional> 23 #include <limits> 24 #include <memory> 25 #include <optional> 26 #include <string> 27 #include <vector> 28 29 #include "perfetto/base/status.h" 30 #include "perfetto/ext/base/flat_hash_map.h" 31 #include "perfetto/ext/base/status_or.h" 32 #include "perfetto/ext/base/utils.h" 33 #include "perfetto/trace_processor/basic_types.h" 34 #include "src/trace_processor/db/table.h" 35 #include "src/trace_processor/sqlite/query_constraints.h" 36 37 namespace perfetto { 38 namespace trace_processor { 39 40 class SqliteEngine; 41 class TypedSqliteTableBase; 42 43 // Abstract base class representing a SQLite virtual table. Implements the 44 // common bookeeping required across all tables and allows subclasses to 45 // implement a friendlier API than that required by SQLite. 46 class SqliteTable : public sqlite3_vtab { 47 public: 48 // Custom opcodes used by subclasses of SqliteTable. 49 // Stored here as we need a central repository of opcodes to prevent clashes 50 // between different sub-classes. 51 enum CustomFilterOpcode { 52 kSourceGeqOpCode = SQLITE_INDEX_CONSTRAINT_FUNCTION + 1, 53 }; 54 // Describes a column of this table. 55 class Column { 56 public: 57 Column(size_t idx, 58 std::string name, 59 SqlValue::Type type, 60 bool hidden = false); 61 index()62 size_t index() const { return index_; } name()63 const std::string& name() const { return name_; } type()64 SqlValue::Type type() const { return type_; } 65 hidden()66 bool hidden() const { return hidden_; } set_hidden(bool hidden)67 void set_hidden(bool hidden) { hidden_ = hidden; } 68 69 private: 70 size_t index_ = 0; 71 std::string name_; 72 SqlValue::Type type_ = SqlValue::Type::kNull; 73 bool hidden_ = false; 74 }; 75 76 // Abstract base class representing an SQLite Cursor. Presents a friendlier 77 // API for subclasses to implement. 78 class BaseCursor : public sqlite3_vtab_cursor { 79 public: 80 // Enum for the history of calls to Filter. 81 enum class FilterHistory : uint32_t { 82 // Indicates that constraint set passed is the different to the 83 // previous Filter call. 84 kDifferent = 0, 85 86 // Indicates that the constraint set passed is the same as the previous 87 // Filter call. 88 // This can be useful for subclasses to perform optimizations on repeated 89 // nested subqueries. 90 kSame = 1, 91 }; 92 93 explicit BaseCursor(SqliteTable* table); 94 virtual ~BaseCursor(); 95 96 // Methods to be implemented by derived table classes. 97 // Note: these methods are intentionally not virtual for performance 98 // reasons. As these methods are not defined, there will be compile errors 99 // thrown if any of these methods are missing. 100 101 // Called to intialise the cursor with the constraints of the query. 102 base::Status Filter(const QueryConstraints& qc, 103 sqlite3_value**, 104 FilterHistory); 105 106 // Called to forward the cursor to the next row in the table. 107 base::Status Next(); 108 109 // Called to check if the cursor has reached eof. Column will be called iff 110 // this method returns true. 111 bool Eof(); 112 113 // Used to extract the value from the column at index |N|. 114 base::Status Column(sqlite3_context* context, int N); 115 table()116 SqliteTable* table() const { return table_; } 117 118 protected: 119 BaseCursor(BaseCursor&) = delete; 120 BaseCursor& operator=(const BaseCursor&) = delete; 121 122 BaseCursor(BaseCursor&&) noexcept = default; 123 BaseCursor& operator=(BaseCursor&&) = default; 124 125 private: 126 SqliteTable* table_ = nullptr; 127 }; 128 129 // The schema of the table. Created by subclasses to allow the table class to 130 // do filtering and inform SQLite about the CREATE table statement. 131 class Schema { 132 public: 133 Schema(); 134 Schema(std::vector<Column>, std::vector<size_t> primary_keys); 135 136 // This class is explicitly copiable. 137 Schema(const Schema&); 138 Schema& operator=(const Schema& t); 139 140 std::string ToCreateTableStmt() const; 141 columns()142 const std::vector<Column>& columns() const { return columns_; } mutable_columns()143 std::vector<Column>* mutable_columns() { return &columns_; } 144 primary_keys()145 const std::vector<size_t> primary_keys() { return primary_keys_; } 146 147 private: 148 // The names and types of the columns of the table. 149 std::vector<Column> columns_; 150 151 // The primary keys of the table given by an offset into |columns|. 152 std::vector<size_t> primary_keys_; 153 }; 154 155 enum TableType { 156 // A table which automatically exists in the main schema and cannot be 157 // created with CREATE VIRTUAL TABLE. 158 // Note: the name value here matches the naming in the vtable docs of 159 // SQLite. 160 kEponymousOnly, 161 162 // A table which must be explicitly created using a CREATE VIRTUAL TABLE 163 // statement (i.e. does exist automatically). 164 kExplicitCreate, 165 }; 166 167 // Public for unique_ptr destructor calls. 168 virtual ~SqliteTable(); 169 170 // When set it logs all BestIndex and Filter actions on the console. 171 static bool debug; 172 173 protected: 174 // Populated by a BestIndex call to allow subclasses to tweak SQLite's 175 // handling of sets of constraints. 176 struct BestIndexInfo { 177 // Contains bools which indicate whether SQLite should omit double checking 178 // the constraint at that index. 179 // 180 // If there are no constraints, SQLite will be told it can omit checking for 181 // the whole query. 182 std::vector<bool> sqlite_omit_constraint; 183 184 // Indicates that SQLite should not double check the result of the order by 185 // clause. 186 // 187 // If there are no order by clauses, this value will be ignored and SQLite 188 // will be told that it can omit double checking (i.e. this value will 189 // implicitly be taken to be true). 190 bool sqlite_omit_order_by = false; 191 192 // Stores the estimated cost of this query. 193 double estimated_cost = 0; 194 195 // Estimated row count. 196 int64_t estimated_rows = 0; 197 }; 198 199 SqliteTable(); 200 201 // Methods to be implemented by derived table classes. 202 virtual base::Status Init(int argc, const char* const* argv, Schema*) = 0; 203 virtual std::unique_ptr<BaseCursor> CreateCursor() = 0; 204 virtual int BestIndex(const QueryConstraints& qc, BestIndexInfo* info) = 0; 205 206 // Optional metods to implement. 207 using FindFunctionFn = void (*)(sqlite3_context*, int, sqlite3_value**); 208 virtual base::Status ModifyConstraints(QueryConstraints* qc); 209 virtual int FindFunction(const char* name, FindFunctionFn* fn, void** args); 210 211 // At registration time, the function should also pass true for |read_write|. 212 virtual base::Status Update(int, sqlite3_value**, sqlite3_int64*); 213 214 bool ReadConstraints(int idxNum, const char* idxStr, int argc); 215 schema()216 const Schema& schema() const { return schema_; } module_name()217 const std::string& module_name() const { return module_name_; } name()218 const std::string& name() const { return name_; } 219 220 private: 221 template <typename, typename> 222 friend class TypedSqliteTable; 223 friend class TypedSqliteTableBase; 224 225 SqliteTable(const SqliteTable&) = delete; 226 SqliteTable& operator=(const SqliteTable&) = delete; 227 228 // The engine class this table is registered with. Used for restoring/saving 229 // the table. 230 SqliteEngine* engine_ = nullptr; 231 232 // This name of the table. For tables created using CREATE VIRTUAL TABLE, this 233 // will be the name of the table specified by the query. For automatically 234 // created tables, this will be the same as the module name passed to 235 // RegisterTable. 236 std::string name_; 237 238 // The module name is the name passed to RegisterTable. This is differs from 239 // the table name (|name_|) where the table was created using CREATE VIRTUAL 240 // TABLE. 241 std::string module_name_; 242 243 Schema schema_; 244 245 QueryConstraints qc_cache_; 246 int qc_hash_ = 0; 247 int best_index_num_ = 0; 248 }; 249 250 class TypedSqliteTableBase : public SqliteTable { 251 protected: 252 struct BaseModuleArg { 253 sqlite3_module module; 254 SqliteEngine* engine; 255 }; 256 257 ~TypedSqliteTableBase() override; 258 259 static int xDestroy(sqlite3_vtab*); 260 static int xDestroyFatal(sqlite3_vtab*); 261 262 static int xConnectRestoreTable(sqlite3* xdb, 263 void* arg, 264 int argc, 265 const char* const* argv, 266 sqlite3_vtab** tab, 267 char** pzErr); 268 static int xDisconnectSaveTable(sqlite3_vtab*); 269 270 static int xOpen(sqlite3_vtab*, sqlite3_vtab_cursor**); 271 static int xBestIndex(sqlite3_vtab*, sqlite3_index_info*); 272 273 static base::Status DeclareAndAssignVtab(std::unique_ptr<SqliteTable> table, 274 sqlite3_vtab** tab); 275 276 base::Status InitInternal(SqliteEngine* engine, 277 int argc, 278 const char* const* argv); 279 SetStatusAndReturn(base::Status status)280 int SetStatusAndReturn(base::Status status) { 281 if (!status.ok()) { 282 sqlite3_free(zErrMsg); 283 zErrMsg = sqlite3_mprintf("%s", status.c_message()); 284 return SQLITE_ERROR; 285 } 286 return SQLITE_OK; 287 } 288 }; 289 290 template <typename SubTable, typename Context> 291 class TypedSqliteTable : public TypedSqliteTableBase { 292 public: 293 struct ModuleArg : BaseModuleArg { 294 Context context; 295 }; 296 CreateModuleArg(SqliteEngine * engine,Context ctx,TableType table_type,bool updatable)297 static std::unique_ptr<ModuleArg> CreateModuleArg(SqliteEngine* engine, 298 Context ctx, 299 TableType table_type, 300 bool updatable) { 301 auto arg = std::make_unique<ModuleArg>(); 302 arg->module = CreateModule(table_type, updatable); 303 arg->engine = engine; 304 arg->context = std::move(ctx); 305 return arg; 306 } 307 308 private: CreateModule(TableType table_type,bool updatable)309 static constexpr sqlite3_module CreateModule(TableType table_type, 310 bool updatable) { 311 sqlite3_module module; 312 memset(&module, 0, sizeof(sqlite3_module)); 313 switch (table_type) { 314 case TableType::kEponymousOnly: 315 // Neither xCreate nor xDestroy should ever be called for 316 // eponymous-only tables. 317 module.xCreate = nullptr; 318 module.xDestroy = &xDestroyFatal; 319 320 // xConnect and xDisconnect will automatically be called with 321 // |module_name| == |name|. 322 module.xConnect = &xCreate; 323 module.xDisconnect = &xDestroy; 324 break; 325 case TableType::kExplicitCreate: 326 // xConnect and xDestroy will be called when the table is CREATE-ed and 327 // DROP-ed respectively. 328 module.xCreate = &xCreate; 329 module.xDestroy = &xDestroy; 330 331 // xConnect and xDisconnect can be called at any time. 332 module.xConnect = &xConnectRestoreTable; 333 module.xDisconnect = &xDisconnectSaveTable; 334 break; 335 } 336 module.xOpen = &xOpen; 337 module.xClose = &xClose; 338 module.xBestIndex = &xBestIndex; 339 module.xFindFunction = &xFindFunction; 340 module.xFilter = &xFilter; 341 module.xNext = &xNext; 342 module.xEof = &xEof; 343 module.xColumn = &xColumn; 344 module.xRowid = &xRowid; 345 if (updatable) { 346 module.xUpdate = &xUpdate; 347 } 348 return module; 349 } 350 xCreate(sqlite3 * xdb,void * arg,int argc,const char * const * argv,sqlite3_vtab ** tab,char ** pzErr)351 static int xCreate(sqlite3* xdb, 352 void* arg, 353 int argc, 354 const char* const* argv, 355 sqlite3_vtab** tab, 356 char** pzErr) { 357 auto* xdesc = static_cast<ModuleArg*>(arg); 358 std::unique_ptr<SubTable> table( 359 new SubTable(xdb, std::move(xdesc->context))); 360 base::Status status = table->InitInternal(xdesc->engine, argc, argv); 361 if (!status.ok()) { 362 *pzErr = sqlite3_mprintf("%s", status.c_message()); 363 return SQLITE_ERROR; 364 } 365 status = DeclareAndAssignVtab(std::move(table), tab); 366 if (!status.ok()) { 367 *pzErr = sqlite3_mprintf("%s", status.c_message()); 368 return SQLITE_ERROR; 369 } 370 return SQLITE_OK; 371 } xClose(sqlite3_vtab_cursor * c)372 static int xClose(sqlite3_vtab_cursor* c) { 373 delete static_cast<typename SubTable::Cursor*>(c); 374 return SQLITE_OK; 375 } xFindFunction(sqlite3_vtab * t,int,const char * name,void (** fn)(sqlite3_context *,int,sqlite3_value **),void ** args)376 static int xFindFunction(sqlite3_vtab* t, 377 int, 378 const char* name, 379 void (**fn)(sqlite3_context*, int, sqlite3_value**), 380 void** args) { 381 return static_cast<SubTable*>(t)->FindFunction(name, fn, args); 382 } xFilter(sqlite3_vtab_cursor * vc,int i,const char * s,int a,sqlite3_value ** v)383 static int xFilter(sqlite3_vtab_cursor* vc, 384 int i, 385 const char* s, 386 int a, 387 sqlite3_value** v) { 388 auto* cursor = static_cast<typename SubTable::Cursor*>(vc); 389 bool is_cached = cursor->table()->ReadConstraints(i, s, a); 390 auto history = is_cached ? BaseCursor::FilterHistory::kSame 391 : BaseCursor::FilterHistory::kDifferent; 392 auto* table = static_cast<SubTable*>(cursor->table()); 393 return table->SetStatusAndReturn( 394 cursor->Filter(cursor->table()->qc_cache_, v, history)); 395 } xNext(sqlite3_vtab_cursor * c)396 static int xNext(sqlite3_vtab_cursor* c) { 397 auto* cursor = static_cast<typename SubTable::Cursor*>(c); 398 auto* table = static_cast<SubTable*>(cursor->table()); 399 return table->SetStatusAndReturn(cursor->Next()); 400 } xEof(sqlite3_vtab_cursor * c)401 static int xEof(sqlite3_vtab_cursor* c) { 402 return static_cast<int>(static_cast<typename SubTable::Cursor*>(c)->Eof()); 403 } xColumn(sqlite3_vtab_cursor * c,sqlite3_context * a,int b)404 static int xColumn(sqlite3_vtab_cursor* c, sqlite3_context* a, int b) { 405 auto* cursor = static_cast<typename SubTable::Cursor*>(c); 406 auto* table = static_cast<SubTable*>(cursor->table()); 407 return table->SetStatusAndReturn(cursor->Column(a, b)); 408 } xRowid(sqlite3_vtab_cursor *,sqlite3_int64 *)409 static int xRowid(sqlite3_vtab_cursor*, sqlite3_int64*) { 410 return SQLITE_ERROR; 411 } xUpdate(sqlite3_vtab * t,int a,sqlite3_value ** v,sqlite3_int64 * r)412 static int xUpdate(sqlite3_vtab* t, 413 int a, 414 sqlite3_value** v, 415 sqlite3_int64* r) { 416 auto* table = static_cast<SubTable*>(t); 417 return table->SetStatusAndReturn(table->Update(a, v, r)); 418 } 419 }; 420 421 } // namespace trace_processor 422 } // namespace perfetto 423 424 #endif // SRC_TRACE_PROCESSOR_SQLITE_SQLITE_TABLE_H_ 425