tp: implement structs in trace processor
Change-Id: I729e7762950252db668e2ecb2829be72e63dce14
diff --git a/Android.bp b/Android.bp
index 6743cc3..7c6d340 100644
--- a/Android.bp
+++ b/Android.bp
@@ -2436,6 +2436,7 @@
":perfetto_src_trace_processor_perfetto_sql_intrinsics_operators_operators",
":perfetto_src_trace_processor_perfetto_sql_intrinsics_table_functions_interface",
":perfetto_src_trace_processor_perfetto_sql_intrinsics_table_functions_table_functions",
+ ":perfetto_src_trace_processor_perfetto_sql_intrinsics_types_types",
":perfetto_src_trace_processor_sorter_sorter",
":perfetto_src_trace_processor_sqlite_bindings_bindings",
":perfetto_src_trace_processor_sqlite_sqlite",
@@ -12920,6 +12921,7 @@
"src/trace_processor/perfetto_sql/intrinsics/functions/pprof_functions.cc",
"src/trace_processor/perfetto_sql/intrinsics/functions/sqlite3_str_split.cc",
"src/trace_processor/perfetto_sql/intrinsics/functions/stack_functions.cc",
+ "src/trace_processor/perfetto_sql/intrinsics/functions/struct.cc",
"src/trace_processor/perfetto_sql/intrinsics/functions/structural_tree_partition.cc",
"src/trace_processor/perfetto_sql/intrinsics/functions/to_ftrace.cc",
],
@@ -13071,6 +13073,11 @@
],
}
+// GN: //src/trace_processor/perfetto_sql/intrinsics/types:types
+filegroup {
+ name: "perfetto_src_trace_processor_perfetto_sql_intrinsics_types_types",
+}
+
// GN: //src/trace_processor/perfetto_sql/prelude:prelude
genrule {
name: "perfetto_src_trace_processor_perfetto_sql_prelude_prelude",
@@ -15168,6 +15175,7 @@
":perfetto_src_trace_processor_perfetto_sql_intrinsics_table_functions_interface",
":perfetto_src_trace_processor_perfetto_sql_intrinsics_table_functions_table_functions",
":perfetto_src_trace_processor_perfetto_sql_intrinsics_table_functions_unittests",
+ ":perfetto_src_trace_processor_perfetto_sql_intrinsics_types_types",
":perfetto_src_trace_processor_rpc_rpc",
":perfetto_src_trace_processor_rpc_unittests",
":perfetto_src_trace_processor_sorter_sorter",
@@ -16195,6 +16203,7 @@
":perfetto_src_trace_processor_perfetto_sql_intrinsics_operators_operators",
":perfetto_src_trace_processor_perfetto_sql_intrinsics_table_functions_interface",
":perfetto_src_trace_processor_perfetto_sql_intrinsics_table_functions_table_functions",
+ ":perfetto_src_trace_processor_perfetto_sql_intrinsics_types_types",
":perfetto_src_trace_processor_rpc_httpd",
":perfetto_src_trace_processor_rpc_rpc",
":perfetto_src_trace_processor_rpc_stdiod",
@@ -16593,6 +16602,7 @@
":perfetto_src_trace_processor_perfetto_sql_intrinsics_operators_operators",
":perfetto_src_trace_processor_perfetto_sql_intrinsics_table_functions_interface",
":perfetto_src_trace_processor_perfetto_sql_intrinsics_table_functions_table_functions",
+ ":perfetto_src_trace_processor_perfetto_sql_intrinsics_types_types",
":perfetto_src_trace_processor_sorter_sorter",
":perfetto_src_trace_processor_sqlite_bindings_bindings",
":perfetto_src_trace_processor_sqlite_sqlite",
diff --git a/BUILD b/BUILD
index d008693..52bb806 100644
--- a/BUILD
+++ b/BUILD
@@ -263,6 +263,7 @@
":src_trace_processor_perfetto_sql_intrinsics_table_functions_interface",
":src_trace_processor_perfetto_sql_intrinsics_table_functions_table_functions",
":src_trace_processor_perfetto_sql_intrinsics_table_functions_tables",
+ ":src_trace_processor_perfetto_sql_intrinsics_types_types",
":src_trace_processor_rpc_rpc",
":src_trace_processor_sorter_sorter",
":src_trace_processor_sqlite_bindings_bindings",
@@ -2359,6 +2360,8 @@
"src/trace_processor/perfetto_sql/intrinsics/functions/sqlite3_str_split.h",
"src/trace_processor/perfetto_sql/intrinsics/functions/stack_functions.cc",
"src/trace_processor/perfetto_sql/intrinsics/functions/stack_functions.h",
+ "src/trace_processor/perfetto_sql/intrinsics/functions/struct.cc",
+ "src/trace_processor/perfetto_sql/intrinsics/functions/struct.h",
"src/trace_processor/perfetto_sql/intrinsics/functions/structural_tree_partition.cc",
"src/trace_processor/perfetto_sql/intrinsics/functions/structural_tree_partition.h",
"src/trace_processor/perfetto_sql/intrinsics/functions/to_ftrace.cc",
@@ -2461,6 +2464,15 @@
],
)
+# GN target: //src/trace_processor/perfetto_sql/intrinsics/types:types
+perfetto_filegroup(
+ name = "src_trace_processor_perfetto_sql_intrinsics_types_types",
+ srcs = [
+ "src/trace_processor/perfetto_sql/intrinsics/types/struct.h",
+ "src/trace_processor/perfetto_sql/intrinsics/types/value.h",
+ ],
+)
+
# GN target: //src/trace_processor/perfetto_sql/prelude:prelude
perfetto_cc_amalgamated_sql(
name = "src_trace_processor_perfetto_sql_prelude_prelude",
@@ -2868,6 +2880,7 @@
name = "src_trace_processor_sqlite_bindings_bindings",
srcs = [
"src/trace_processor/sqlite/bindings/sqlite_aggregate_function.h",
+ "src/trace_processor/sqlite/bindings/sqlite_function.h",
"src/trace_processor/sqlite/bindings/sqlite_module.h",
"src/trace_processor/sqlite/bindings/sqlite_result.h",
"src/trace_processor/sqlite/bindings/sqlite_type.h",
@@ -6081,6 +6094,7 @@
":src_trace_processor_perfetto_sql_intrinsics_table_functions_interface",
":src_trace_processor_perfetto_sql_intrinsics_table_functions_table_functions",
":src_trace_processor_perfetto_sql_intrinsics_table_functions_tables",
+ ":src_trace_processor_perfetto_sql_intrinsics_types_types",
":src_trace_processor_sorter_sorter",
":src_trace_processor_sqlite_bindings_bindings",
":src_trace_processor_sqlite_sqlite",
@@ -6261,6 +6275,7 @@
":src_trace_processor_perfetto_sql_intrinsics_table_functions_interface",
":src_trace_processor_perfetto_sql_intrinsics_table_functions_table_functions",
":src_trace_processor_perfetto_sql_intrinsics_table_functions_tables",
+ ":src_trace_processor_perfetto_sql_intrinsics_types_types",
":src_trace_processor_rpc_httpd",
":src_trace_processor_rpc_rpc",
":src_trace_processor_rpc_stdiod",
@@ -6501,6 +6516,7 @@
":src_trace_processor_perfetto_sql_intrinsics_table_functions_interface",
":src_trace_processor_perfetto_sql_intrinsics_table_functions_table_functions",
":src_trace_processor_perfetto_sql_intrinsics_table_functions_tables",
+ ":src_trace_processor_perfetto_sql_intrinsics_types_types",
":src_trace_processor_sorter_sorter",
":src_trace_processor_sqlite_bindings_bindings",
":src_trace_processor_sqlite_sqlite",
diff --git a/src/trace_processor/perfetto_sql/engine/perfetto_sql_engine.h b/src/trace_processor/perfetto_sql/engine/perfetto_sql_engine.h
index a98ab99..f04a57a 100644
--- a/src/trace_processor/perfetto_sql/engine/perfetto_sql_engine.h
+++ b/src/trace_processor/perfetto_sql/engine/perfetto_sql_engine.h
@@ -115,6 +115,19 @@
std::unique_ptr<typename Function::Context> ctx,
bool deterministic = true);
+ // Registers a trace processor C++ function to be runnable from SQL.
+ //
+ // The format of the function is given by the |SqliteFunction|.
+ //
+ // |ctx|: context object for the function; this object *must*
+ // outlive the function so should likely be either static or
+ // scoped to the lifetime of TraceProcessor.
+ // |deterministic|: whether this function has deterministic output given the
+ // same set of arguments.
+ template <typename Function>
+ base::Status RegisterSqliteFunction(typename Function::UserDataContext* ctx,
+ bool deterministic = true);
+
// Registers a trace processor C++ aggregate function to be runnable from SQL.
//
// The format of the function is given by the |SqliteAggregateFunction|.
@@ -353,6 +366,15 @@
}
template <typename Function>
+base::Status PerfettoSqlEngine::RegisterSqliteFunction(
+ typename Function::UserDataContext* ctx,
+ bool deterministic) {
+ static_function_count_++;
+ return engine_->RegisterFunction(Function::kName, Function::kArgCount,
+ Function::Step, ctx, nullptr, deterministic);
+}
+
+template <typename Function>
base::Status PerfettoSqlEngine::RegisterSqliteAggregateFunction(
typename Function::UserDataContext* ctx,
bool deterministic) {
diff --git a/src/trace_processor/perfetto_sql/intrinsics/functions/BUILD.gn b/src/trace_processor/perfetto_sql/intrinsics/functions/BUILD.gn
index e8ff41b..04b3aa5 100644
--- a/src/trace_processor/perfetto_sql/intrinsics/functions/BUILD.gn
+++ b/src/trace_processor/perfetto_sql/intrinsics/functions/BUILD.gn
@@ -44,6 +44,8 @@
"sqlite3_str_split.h",
"stack_functions.cc",
"stack_functions.h",
+ "struct.cc",
+ "struct.h",
"structural_tree_partition.cc",
"structural_tree_partition.h",
"to_ftrace.cc",
@@ -79,6 +81,7 @@
"../../../util:sql_argument",
"../../../util:stdlib",
"../../engine",
+ "../types",
]
public_deps = [ ":interface" ]
}
diff --git a/src/trace_processor/perfetto_sql/intrinsics/functions/struct.cc b/src/trace_processor/perfetto_sql/intrinsics/functions/struct.cc
new file mode 100644
index 0000000..33dcde3
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/intrinsics/functions/struct.cc
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_processor/perfetto_sql/intrinsics/functions/struct.h"
+
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+#include <memory>
+#include <variant>
+
+#include "perfetto/base/status.h"
+#include "src/trace_processor/perfetto_sql/engine/function_util.h"
+#include "src/trace_processor/perfetto_sql/engine/perfetto_sql_engine.h"
+#include "src/trace_processor/perfetto_sql/intrinsics/types/struct.h"
+#include "src/trace_processor/sqlite/bindings/sqlite_function.h"
+#include "src/trace_processor/sqlite/bindings/sqlite_result.h"
+#include "src/trace_processor/sqlite/bindings/sqlite_type.h"
+#include "src/trace_processor/sqlite/bindings/sqlite_value.h"
+#include "src/trace_processor/sqlite/sqlite_utils.h"
+
+namespace perfetto::trace_processor {
+namespace {
+
+// An SQL scalar function which creates an struct.
+// TODO(lalitm): once we have some stability here, expand the comments
+// here.
+struct Struct : public SqliteFunction<Struct> {
+ static constexpr char kName[] = "__intrinsic_struct";
+ static constexpr int kArgCount = -1;
+
+ static void Step(sqlite3_context*, int argc, sqlite3_value** argv);
+};
+
+void Struct::Step(sqlite3_context* ctx, int rargc, sqlite3_value** argv) {
+ auto argc = static_cast<uint32_t>(rargc);
+ if (argc % 2 != 0) {
+ return sqlite::result::Error(
+ ctx, "STRUCT: must have an even number of arguments");
+ }
+ if (argc / 2 > perfetto_sql::Struct::kMaxFields) {
+ return sqlite::utils::SetError(
+ ctx, base::ErrStatus("STRUCT: only at most %d fields are supported",
+ perfetto_sql::Struct::kMaxFields));
+ }
+
+ auto s = std::make_unique<perfetto_sql::Struct>();
+ s->field_count = argc / 2;
+ for (uint32_t i = 0; i < s->field_count; ++i) {
+ if (sqlite::value::Type(argv[i]) != sqlite::Type::kText) {
+ return sqlite::result::Error(ctx, "STRUCT: field names must be strings");
+ }
+ auto& field = s->fields[i];
+ field.first = sqlite::value::Text(argv[i]);
+ switch (sqlite::value::Type(argv[s->field_count + i])) {
+ case sqlite::Type::kText:
+ field.second = sqlite::value::Text(argv[s->field_count + i]);
+ break;
+ case sqlite::Type::kInteger:
+ field.second = sqlite::value::Int64(argv[s->field_count + i]);
+ break;
+ case sqlite::Type::kFloat:
+ field.second = sqlite::value::Double(argv[s->field_count + i]);
+ break;
+ case sqlite::Type::kNull:
+ field.second = std::monostate();
+ break;
+ case sqlite::Type::kBlob:
+ return sqlite::result::Error(ctx, "STRUCT: blob fields not supported");
+ }
+ }
+ sqlite::result::RawPointer(ctx, s.release(), "STRUCT", [](void* ptr) {
+ std::unique_ptr<perfetto_sql::Struct>(
+ static_cast<perfetto_sql::Struct*>(ptr));
+ });
+}
+
+} // namespace
+
+base::Status RegisterStructFunctions(PerfettoSqlEngine& engine) {
+ return engine.RegisterSqliteFunction<Struct>(nullptr);
+}
+
+} // namespace perfetto::trace_processor
diff --git a/src/trace_processor/perfetto_sql/intrinsics/functions/struct.h b/src/trace_processor/perfetto_sql/intrinsics/functions/struct.h
new file mode 100644
index 0000000..0c5f49d
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/intrinsics/functions/struct.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_PERFETTO_SQL_INTRINSICS_FUNCTIONS_STRUCT_H_
+#define SRC_TRACE_PROCESSOR_PERFETTO_SQL_INTRINSICS_FUNCTIONS_STRUCT_H_
+
+#include "perfetto/base/status.h"
+
+namespace perfetto::trace_processor {
+
+class PerfettoSqlEngine;
+
+// Registers the following struct related functions with SQLite:
+// * __intrinsic_struct: a scalar function which allows creating a
+// struct from its component fields.
+// TODO(lalitm): once we have some stability here, expand the comments
+// here.
+base::Status RegisterStructFunctions(PerfettoSqlEngine& engine);
+
+} // namespace perfetto::trace_processor
+
+#endif // SRC_TRACE_PROCESSOR_PERFETTO_SQL_INTRINSICS_FUNCTIONS_STRUCT_H_
diff --git a/src/trace_processor/perfetto_sql/intrinsics/types/BUILD.gn b/src/trace_processor/perfetto_sql/intrinsics/types/BUILD.gn
new file mode 100644
index 0000000..230dc71
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/intrinsics/types/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("../../../../../gn/perfetto_tp_tables.gni")
+import("../../../../../gn/test.gni")
+
+assert(enable_perfetto_trace_processor_sqlite)
+
+source_set("types") {
+ sources = [
+ "struct.h",
+ "value.h",
+ ]
+ deps = [ "../../../../../gn:default_deps" ]
+}
diff --git a/src/trace_processor/perfetto_sql/intrinsics/types/struct.h b/src/trace_processor/perfetto_sql/intrinsics/types/struct.h
new file mode 100644
index 0000000..00011ed
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/intrinsics/types/struct.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_PERFETTO_SQL_INTRINSICS_TYPES_STRUCT_H_
+#define SRC_TRACE_PROCESSOR_PERFETTO_SQL_INTRINSICS_TYPES_STRUCT_H_
+
+#include <array>
+#include <cstdint>
+#include <string>
+#include <utility>
+
+#include "src/trace_processor/perfetto_sql/intrinsics/types/value.h"
+
+namespace perfetto::trace_processor::perfetto_sql {
+
+struct Struct {
+ static constexpr uint32_t kMaxFields = 8;
+ std::array<std::pair<std::string, Value>, kMaxFields> fields;
+ uint32_t field_count = 0;
+};
+
+} // namespace perfetto::trace_processor::perfetto_sql
+
+#endif // SRC_TRACE_PROCESSOR_PERFETTO_SQL_INTRINSICS_TYPES_STRUCT_H_
diff --git a/src/trace_processor/perfetto_sql/intrinsics/types/value.h b/src/trace_processor/perfetto_sql/intrinsics/types/value.h
new file mode 100644
index 0000000..6c541d1
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/intrinsics/types/value.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_PERFETTO_SQL_INTRINSICS_TYPES_VALUE_H_
+#define SRC_TRACE_PROCESSOR_PERFETTO_SQL_INTRINSICS_TYPES_VALUE_H_
+
+#include <cstdint>
+#include <string>
+#include <variant>
+
+namespace perfetto::trace_processor::perfetto_sql {
+
+using Value = std::variant<std::monostate, int64_t, double, std::string>;
+
+} // namespace perfetto::trace_processor::perfetto_sql
+
+#endif // SRC_TRACE_PROCESSOR_PERFETTO_SQL_INTRINSICS_TYPES_VALUE_H_
diff --git a/src/trace_processor/sqlite/bindings/BUILD.gn b/src/trace_processor/sqlite/bindings/BUILD.gn
index 10a903f..9205585 100644
--- a/src/trace_processor/sqlite/bindings/BUILD.gn
+++ b/src/trace_processor/sqlite/bindings/BUILD.gn
@@ -19,6 +19,7 @@
source_set("bindings") {
sources = [
"sqlite_aggregate_function.h",
+ "sqlite_function.h",
"sqlite_module.h",
"sqlite_result.h",
"sqlite_type.h",
diff --git a/src/trace_processor/sqlite/bindings/sqlite_function.h b/src/trace_processor/sqlite/bindings/sqlite_function.h
new file mode 100644
index 0000000..a97541f
--- /dev/null
+++ b/src/trace_processor/sqlite/bindings/sqlite_function.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_SQLITE_BINDINGS_SQLITE_FUNCTION_H_
+#define SRC_TRACE_PROCESSOR_SQLITE_BINDINGS_SQLITE_FUNCTION_H_
+
+#include <sqlite3.h> // IWYU pragma: export
+
+namespace perfetto::trace_processor {
+
+// Prototype for a function which can be registered with SQLite.
+//
+// See https://www.sqlite.org/c3ref/create_function.html for details on how
+// to implement the methods of this class.
+template <typename Impl>
+class SqliteFunction {
+ public:
+ // The type of the context object which will be passed to the function.
+ // Can be redefined in any sub-classes to override the context.
+ using UserDataContext = void;
+
+ // The xStep function which will be executed by SQLite to add a row of values
+ // to the current window.
+ //
+ // Implementations MUST define this function themselves; this function is
+ // declared but *not* defined so linker errors will be thrown if not defined.
+ static void Step(sqlite3_context*, int argc, sqlite3_value** argv);
+
+ // Returns the pointer to the user data structure which is passed when
+ // creating the function.
+ static auto GetUserData(sqlite3_context* ctx) {
+ return static_cast<typename Impl::UserDataContext*>(sqlite3_user_data(ctx));
+ }
+};
+
+} // namespace perfetto::trace_processor
+
+#endif // SRC_TRACE_PROCESSOR_SQLITE_BINDINGS_SQLITE_FUNCTION_H_
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index e8d202a..e58696e 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -81,6 +81,7 @@
#include "src/trace_processor/perfetto_sql/intrinsics/functions/pprof_functions.h"
#include "src/trace_processor/perfetto_sql/intrinsics/functions/sqlite3_str_split.h"
#include "src/trace_processor/perfetto_sql/intrinsics/functions/stack_functions.h"
+#include "src/trace_processor/perfetto_sql/intrinsics/functions/struct.h"
#include "src/trace_processor/perfetto_sql/intrinsics/functions/structural_tree_partition.h"
#include "src/trace_processor/perfetto_sql/intrinsics/functions/to_ftrace.h"
#include "src/trace_processor/perfetto_sql/intrinsics/functions/utils.h"
@@ -753,6 +754,11 @@
if (!status.ok())
PERFETTO_FATAL("%s", status.c_message());
}
+ {
+ base::Status status = RegisterStructFunctions(*engine_);
+ if (!status.ok())
+ PERFETTO_FATAL("%s", status.c_message());
+ }
TraceStorage* storage = context_.storage.get();