1 /* 2 * Copyright (C) 2024 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_TABLE_POINTER_MODULE_H_ 18 #define SRC_TRACE_PROCESSOR_PERFETTO_SQL_ENGINE_TABLE_POINTER_MODULE_H_ 19 20 #include <array> 21 #include <cstdint> 22 #include <optional> 23 24 #include "src/trace_processor/db/table.h" 25 #include "src/trace_processor/sqlite/bindings/sqlite_module.h" 26 27 namespace perfetto::trace_processor { 28 29 // SQLite module which allows iteration over a table pointer (i.e. a instance of 30 // Table which is being directly passed in as a SQL value). This allows for a 31 // dynamic, schema-less iteration over table pointers. This is generally not 32 // possible as SQLite reqiures the schema to be defined upfront but this class 33 // works around that by having a fixed schema but then allowing "binding" table 34 // pointer columns to SQLite columns dynamically at query time. 35 // 36 // Example: 37 // ``` 38 // -- Renaming the static columns defined by this table to the particular 39 // -- column names for this query. 40 // SELECT c0 AS node_id, c1 AS parent_node_id 41 // -- The call to this class 42 // FROM __intrinsic_table_ptr(( 43 // -- An aggregate function which returns the table pointer we want to 44 // -- iterate over. 45 // SELECT __intrinsic_dfs(g.source_node_id, g.dest_node_id, $start_node_id) 46 // FROM $graph_table g 47 // )) 48 // -- Informs this class about which SQLite column corresponds to which 49 // -- SQLite column. The SQLite columns bindings should be dense starting from 50 // -- 0. 51 // WHERE __intrinsic_table_ptr_bind(c0, 'node_id') 52 // AND __intrinsic_table_ptr_bind(c1, 'parent_node_id') 53 // ``` 54 // 55 // Note: this class is *not* intended to be used directly by end users. It is 56 // a building block intended for use by very low-level macros in the standard 57 // library. 58 struct TablePointerModule : sqlite::Module<TablePointerModule> { 59 static constexpr int kBindConstraint = SQLITE_INDEX_CONSTRAINT_FUNCTION + 1; 60 static constexpr int kBindableColumnCount = 16; 61 static constexpr int kTableColumnIndex = kBindableColumnCount; 62 static constexpr int kRowColumnIndex = kBindableColumnCount + 1; 63 static constexpr int kTableArgvIndex = 1; 64 static constexpr int kBoundColumnArgvOffset = 2; 65 66 using Context = void; 67 struct Vtab : sqlite::Module<TablePointerModule>::Vtab {}; 68 struct Cursor : sqlite::Module<TablePointerModule>::Cursor { 69 const Table* table = nullptr; 70 std::array<uint32_t, kBindableColumnCount> bound_col_to_table_index{}; 71 uint32_t col_count = 0; 72 std::optional<Table::Iterator> iterator; 73 }; 74 75 static constexpr auto kType = kEponymousOnly; 76 static constexpr bool kSupportsWrites = false; 77 78 static int Connect(sqlite3*, 79 void*, 80 int, 81 const char* const*, 82 sqlite3_vtab**, 83 char**); 84 static int Disconnect(sqlite3_vtab*); 85 86 static int BestIndex(sqlite3_vtab*, sqlite3_index_info*); 87 88 static int Open(sqlite3_vtab*, sqlite3_vtab_cursor**); 89 static int Close(sqlite3_vtab_cursor*); 90 91 static int Filter(sqlite3_vtab_cursor*, 92 int, 93 const char*, 94 int, 95 sqlite3_value**); 96 static int Next(sqlite3_vtab_cursor*); 97 static int Eof(sqlite3_vtab_cursor*); 98 static int Column(sqlite3_vtab_cursor*, sqlite3_context*, int); 99 static int Rowid(sqlite3_vtab_cursor*, sqlite_int64*); 100 101 static int FindFunction(sqlite3_vtab*, 102 int, 103 const char*, 104 FindFunctionFn**, 105 void**); 106 107 // This needs to happen at the end as it depends on the functions 108 // defined above. 109 static constexpr sqlite3_module kModule = CreateModule(); 110 }; 111 112 } // namespace perfetto::trace_processor 113 114 #endif // SRC_TRACE_PROCESSOR_PERFETTO_SQL_ENGINE_TABLE_POINTER_MODULE_H_ 115