xref: /aosp_15_r20/external/perfetto/src/trace_processor/perfetto_sql/engine/table_pointer_module.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
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