1 /* 2 * Copyright (C) 2023 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_RUNTIME_TABLE_FUNCTION_H_ 18 #define SRC_TRACE_PROCESSOR_PERFETTO_SQL_ENGINE_RUNTIME_TABLE_FUNCTION_H_ 19 20 #include <cstddef> 21 #include <cstdint> 22 #include <memory> 23 #include <optional> 24 #include <vector> 25 26 #include "perfetto/base/logging.h" 27 #include "src/trace_processor/perfetto_sql/parser/function_util.h" 28 #include "src/trace_processor/sqlite/bindings/sqlite_module.h" 29 #include "src/trace_processor/sqlite/module_lifecycle_manager.h" 30 #include "src/trace_processor/sqlite/sql_source.h" 31 #include "src/trace_processor/sqlite/sqlite_engine.h" 32 #include "src/trace_processor/util/sql_argument.h" 33 34 namespace perfetto::trace_processor { 35 36 class PerfettoSqlEngine; 37 38 // The implementation of the SqliteTableLegacy interface for table functions 39 // defined at runtime using SQL. 40 struct RuntimeTableFunctionModule 41 : public sqlite::Module<RuntimeTableFunctionModule> { 42 struct State { 43 PerfettoSqlEngine* engine; 44 SqlSource sql_defn_str; 45 46 FunctionPrototype prototype; 47 std::vector<sql_argument::ArgumentDefinition> return_values; 48 49 std::optional<SqliteEngine::PreparedStatement> temporary_create_stmt; 50 IsReturnValueColumnRuntimeTableFunctionModule::State51 bool IsReturnValueColumn(size_t i) const { 52 PERFETTO_DCHECK(i < TotalColumnCount()); 53 return i < return_values.size(); 54 } 55 IsArgumentColumnRuntimeTableFunctionModule::State56 bool IsArgumentColumn(size_t i) const { 57 PERFETTO_DCHECK(i < TotalColumnCount()); 58 return i >= return_values.size() && 59 (i - return_values.size()) < prototype.arguments.size(); 60 } 61 IsPrimaryKeyColumnRuntimeTableFunctionModule::State62 bool IsPrimaryKeyColumn(size_t i) const { 63 PERFETTO_DCHECK(i < TotalColumnCount()); 64 return i == (return_values.size() + prototype.arguments.size()); 65 } 66 TotalColumnCountRuntimeTableFunctionModule::State67 size_t TotalColumnCount() const { 68 static constexpr uint32_t kPrimaryKeyColumns = 1; 69 return prototype.arguments.size() + return_values.size() + 70 kPrimaryKeyColumns; 71 } 72 }; 73 struct Context { 74 std::unique_ptr<State> temporary_create_state; 75 sqlite::ModuleStateManager<RuntimeTableFunctionModule> manager; 76 }; 77 struct Vtab : sqlite::Module<RuntimeTableFunctionModule>::Vtab { 78 sqlite::ModuleStateManager<RuntimeTableFunctionModule>::PerVtabState* state; 79 std::optional<SqliteEngine::PreparedStatement> reusable_stmt; 80 }; 81 struct Cursor : sqlite::Module<RuntimeTableFunctionModule>::Cursor { 82 std::optional<SqliteEngine::PreparedStatement> stmt; 83 bool is_eof = false; 84 int next_call_count = 0; 85 }; 86 87 static constexpr bool kSupportsWrites = false; 88 static constexpr bool kDoesOverloadFunctions = false; 89 90 static int Create(sqlite3*, 91 void*, 92 int, 93 const char* const*, 94 sqlite3_vtab**, 95 char**); 96 static int Destroy(sqlite3_vtab*); 97 98 static int Connect(sqlite3*, 99 void*, 100 int, 101 const char* const*, 102 sqlite3_vtab**, 103 char**); 104 static int Disconnect(sqlite3_vtab*); 105 106 static int BestIndex(sqlite3_vtab*, sqlite3_index_info*); 107 108 static int Open(sqlite3_vtab*, sqlite3_vtab_cursor**); 109 static int Close(sqlite3_vtab_cursor*); 110 111 static int Filter(sqlite3_vtab_cursor*, 112 int, 113 const char*, 114 int, 115 sqlite3_value**); 116 static int Next(sqlite3_vtab_cursor*); 117 static int Eof(sqlite3_vtab_cursor*); 118 static int Column(sqlite3_vtab_cursor*, sqlite3_context*, int); 119 static int Rowid(sqlite3_vtab_cursor*, sqlite_int64*); 120 121 // This needs to happen at the end as it depends on the functions 122 // defined above. 123 static constexpr sqlite3_module kModule = CreateModule(); 124 }; 125 126 } // namespace perfetto::trace_processor 127 128 #endif // SRC_TRACE_PROCESSOR_PERFETTO_SQL_ENGINE_RUNTIME_TABLE_FUNCTION_H_ 129