Merge "ftrace format_parser: accept events with only common_fields"
diff --git a/Android.bp b/Android.bp
index 54ee44e..2cea732 100644
--- a/Android.bp
+++ b/Android.bp
@@ -9448,6 +9448,7 @@
         "src/trace_processor/importers/proto/memory_tracker_snapshot_parser.cc",
         "src/trace_processor/importers/proto/metadata_minimal_module.cc",
         "src/trace_processor/importers/proto/metadata_tracker.cc",
+        "src/trace_processor/importers/proto/packet_analyzer.cc",
         "src/trace_processor/importers/proto/packet_sequence_state_generation.cc",
         "src/trace_processor/importers/proto/perf_sample_tracker.cc",
         "src/trace_processor/importers/proto/profile_module.cc",
@@ -10875,6 +10876,7 @@
         "src/tracing/test/api_integrationtest_main.cc",
         "src/tracing/test/tracing_module.cc",
         "src/tracing/test/tracing_module2.cc",
+        "src/tracing/test/tracing_module3.cc",
     ],
 }
 
diff --git a/BUILD b/BUILD
index c604211..5173afc 100644
--- a/BUILD
+++ b/BUILD
@@ -1403,6 +1403,8 @@
         "src/trace_processor/importers/proto/metadata_minimal_module.h",
         "src/trace_processor/importers/proto/metadata_tracker.cc",
         "src/trace_processor/importers/proto/metadata_tracker.h",
+        "src/trace_processor/importers/proto/packet_analyzer.cc",
+        "src/trace_processor/importers/proto/packet_analyzer.h",
         "src/trace_processor/importers/proto/packet_sequence_state.h",
         "src/trace_processor/importers/proto/packet_sequence_state_generation.cc",
         "src/trace_processor/importers/proto/perf_sample_tracker.cc",
diff --git a/CHANGELOG b/CHANGELOG
index 1218a5d..36e88af 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -8,6 +8,13 @@
     *
   SDK:
     * Add perfetto::Tracing::ActivateTriggers() function.
+    * Made it possible to declare track event categories in a C++ namespace
+      with PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE, allowing multiple category
+      sets to be used in one same translation unit. Correspondingly, the
+      PERFETTO_COMPONENT_EXPORT and PERFETTO_TRACK_EVENT_NAMESPACE macros have
+      been deprecated in favor of this new functionality.
+    * Deprecated the PERFETTO_COMPONENT_EXPORT macro in favor of
+      PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE_WITH_ATTRS.
 
 
 v31.0 - 2022-11-10:
diff --git a/OWNERS b/OWNERS
index dee7d70..5c57ecb 100644
--- a/OWNERS
+++ b/OWNERS
@@ -11,6 +11,7 @@
 
 # Trace Processor, metrics, infra.
 lalitm@google.com
+mayzner@google.com
 
 # Callstack / memory profilers, traced_probes & Linux internals.
 ddiproietto@google.com
diff --git a/docs/design-docs/api-and-abi.md b/docs/design-docs/api-and-abi.md
index c930c95..e93a4b0 100644
--- a/docs/design-docs/api-and-abi.md
+++ b/docs/design-docs/api-and-abi.md
@@ -254,7 +254,7 @@
 any doesn't use any unix socket. Instead it uses the functionally equivalent
 Mojo endpoints [`Producer{Client,Host}` and `Consumer{Client,Host}`][mojom].
 
-### Shared memory
+### {#shmem-abi} Shared memory
 
 This section describes the binary interface of the memory buffer shared between
 a producer process and the tracing service (SMB).
@@ -396,7 +396,7 @@
 IPC (the Producer ID is not spoofable and is tied to the IPC socket file
 descriptor).
 
-### Proto definitions
+### {#protos} Proto definitions
 
 The following protobuf messages are part of the overall trace protocol ABI and
 are updated maintaining backward-compatibility, unless marked as experimental
diff --git a/include/perfetto/tracing/data_source.h b/include/perfetto/tracing/data_source.h
index 3c50046..5065c5b 100644
--- a/include/perfetto/tracing/data_source.h
+++ b/include/perfetto/tracing/data_source.h
@@ -46,6 +46,11 @@
 
 #include "protos/perfetto/trace/trace_packet.pbzero.h"
 
+// DEPRECATED: Instead of using this macro, prefer specifying symbol linkage
+// attributes explicitly using the `_WITH_ATTRS` macro variants (e.g.,
+// PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS_WITH_ATTRS). This avoids
+// potential macro definition collisions between two libraries using Perfetto.
+//
 // PERFETTO_COMPONENT_EXPORT is used to mark symbols in Perfetto's headers
 // (typically templates) that are defined by the user outside of Perfetto and
 // should be made visible outside the current module. (e.g., in Chrome's
diff --git a/include/perfetto/tracing/internal/track_event_macros.h b/include/perfetto/tracing/internal/track_event_macros.h
index aedc4d0..c0dfb2b 100644
--- a/include/perfetto/tracing/internal/track_event_macros.h
+++ b/include/perfetto/tracing/internal/track_event_macros.h
@@ -41,14 +41,13 @@
 //   byte 0                      byte 1
 //   (inst0, inst1, ..., inst7), (inst0, inst1, ..., inst7)
 //
-#define PERFETTO_INTERNAL_DECLARE_CATEGORIES(...)                             \
+#define PERFETTO_INTERNAL_DECLARE_CATEGORIES(attrs, ...)                      \
   namespace internal {                                                        \
   constexpr ::perfetto::Category kCategories[] = {__VA_ARGS__};               \
   constexpr size_t kCategoryCount =                                           \
       sizeof(kCategories) / sizeof(kCategories[0]);                           \
   /* The per-instance enable/disable state per category */                    \
-  PERFETTO_COMPONENT_EXPORT extern std::atomic<uint8_t>                       \
-      g_category_state_storage[kCategoryCount];                               \
+  attrs extern std::atomic<uint8_t> g_category_state_storage[kCategoryCount]; \
   /* The category registry which mediates access to the above structures. */  \
   /* The registry is used for two purposes: */                                \
   /**/                                                                        \
@@ -69,32 +68,29 @@
   /* TODO(skyostil): Unify these using a C++17 inline constexpr variable. */  \
   constexpr ::perfetto::internal::TrackEventCategoryRegistry                  \
       kConstExprCategoryRegistry(kCategoryCount, &kCategories[0], nullptr);   \
-  PERFETTO_COMPONENT_EXPORT extern const ::perfetto::internal::               \
-      TrackEventCategoryRegistry kCategoryRegistry;                           \
+  attrs extern const ::perfetto::internal::TrackEventCategoryRegistry         \
+      kCategoryRegistry;                                                      \
   static_assert(kConstExprCategoryRegistry.ValidateCategories(),              \
                 "Invalid category names found");                              \
   }  // namespace internal
 
 // In a .cc file, declares storage for each category's runtime state.
-#define PERFETTO_INTERNAL_CATEGORY_STORAGE()             \
-  namespace internal {                                   \
-  PERFETTO_COMPONENT_EXPORT std::atomic<uint8_t>         \
-      g_category_state_storage[kCategoryCount];          \
-  PERFETTO_EXPORT_COMPONENT const ::perfetto::internal:: \
-      TrackEventCategoryRegistry kCategoryRegistry(      \
-          kCategoryCount,                                \
-          &kCategories[0],                               \
-          &g_category_state_storage[0]);                 \
+#define PERFETTO_INTERNAL_CATEGORY_STORAGE(attrs)                      \
+  namespace internal {                                                 \
+  attrs std::atomic<uint8_t> g_category_state_storage[kCategoryCount]; \
+  attrs const ::perfetto::internal::TrackEventCategoryRegistry         \
+      kCategoryRegistry(kCategoryCount,                                \
+                        &kCategories[0],                               \
+                        &g_category_state_storage[0]);                 \
   }  // namespace internal
 
 // Defines the TrackEvent data source for the current track event namespace.
 // `virtual ~TrackEvent` is added to avoid `-Wweak-vtables` warning.
 // Learn more : aosp/2019906
-#define PERFETTO_INTERNAL_DECLARE_TRACK_EVENT_DATA_SOURCE() \
-  struct PERFETTO_COMPONENT_EXPORT TrackEvent               \
-      : public ::perfetto::internal::TrackEventDataSource<  \
-            TrackEvent, &internal::kCategoryRegistry> {     \
-    virtual ~TrackEvent();                                  \
+#define PERFETTO_INTERNAL_DECLARE_TRACK_EVENT_DATA_SOURCE(attrs)               \
+  struct attrs TrackEvent : public ::perfetto::internal::TrackEventDataSource< \
+                                TrackEvent, &internal::kCategoryRegistry> {    \
+    virtual ~TrackEvent();                                                     \
   }
 
 #define PERFETTO_INTERNAL_DEFINE_TRACK_EVENT_DATA_SOURCE() \
@@ -104,9 +100,9 @@
 // index into the current category registry. A build error will be generated if
 // the category hasn't been registered or added to the list of allowed dynamic
 // categories. See PERFETTO_DEFINE_CATEGORIES.
-#define PERFETTO_GET_CATEGORY_INDEX(category)                                  \
-  ::PERFETTO_TRACK_EVENT_NAMESPACE::internal::kConstExprCategoryRegistry.Find( \
-      category,                                                                \
+#define PERFETTO_GET_CATEGORY_INDEX(category)                                \
+  PERFETTO_TRACK_EVENT_NAMESPACE::internal::kConstExprCategoryRegistry.Find( \
+      category,                                                              \
       ::PERFETTO_TRACK_EVENT_NAMESPACE::internal::IsDynamicCategory(category))
 
 // Generate a unique variable name with a given prefix.
@@ -118,14 +114,15 @@
 // if so, emits one trace event with the given arguments.
 #define PERFETTO_INTERNAL_TRACK_EVENT(category, name, ...)                     \
   do {                                                                         \
-    perfetto::internal::ValidateEventNameType<decltype(name)>();               \
-    namespace tns = ::PERFETTO_TRACK_EVENT_NAMESPACE;                          \
+    ::perfetto::internal::ValidateEventNameType<decltype(name)>();             \
+    namespace tns = PERFETTO_TRACK_EVENT_NAMESPACE;                            \
     /* Compute the category index outside the lambda to work around a */       \
     /* GCC 7 bug */                                                            \
     static constexpr auto PERFETTO_UID(                                        \
         kCatIndex_ADD_TO_PERFETTO_DEFINE_CATEGORIES_IF_FAILS_) =               \
         PERFETTO_GET_CATEGORY_INDEX(category);                                 \
-    if (tns::internal::IsDynamicCategory(category)) {                          \
+    if (::PERFETTO_TRACK_EVENT_NAMESPACE::internal::IsDynamicCategory(         \
+            category)) {                                                       \
       tns::TrackEvent::CallIfEnabled(                                          \
           [&](uint32_t instances) PERFETTO_NO_THREAD_SAFETY_ANALYSIS {         \
             tns::TrackEvent::TraceForCategory(instances, category, name,       \
@@ -180,11 +177,11 @@
     }()                                                                       \
   }
 
-#define PERFETTO_INTERNAL_CATEGORY_ENABLED(category)                         \
-  (::PERFETTO_TRACK_EVENT_NAMESPACE::internal::IsDynamicCategory(category)   \
-       ? ::PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::                      \
-             IsDynamicCategoryEnabled(::perfetto::DynamicCategory(category)) \
-       : ::PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::IsCategoryEnabled(    \
+#define PERFETTO_INTERNAL_CATEGORY_ENABLED(category)                           \
+  (::PERFETTO_TRACK_EVENT_NAMESPACE::internal::IsDynamicCategory(category)     \
+       ? PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::IsDynamicCategoryEnabled( \
+             ::perfetto::DynamicCategory(category))                            \
+       : PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::IsCategoryEnabled(        \
              PERFETTO_GET_CATEGORY_INDEX(category)))
 
 // Emits an empty trace packet into the trace to ensure that the service can
@@ -197,12 +194,12 @@
 // read the last trace packet from an incomplete SMB chunk (crbug.com/1021571
 // and b/162206162) when scraping the SMB. Adding an empty trace packet ensures
 // that all prior events can be scraped by the service.
-#define PERFETTO_INTERNAL_ADD_EMPTY_EVENT()                                  \
-  do {                                                                       \
-    ::PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::Trace(                     \
-        [](::PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::TraceContext ctx) { \
-          ctx.AddEmptyTracePacket();                                         \
-        });                                                                  \
+#define PERFETTO_INTERNAL_ADD_EMPTY_EVENT()                                \
+  do {                                                                     \
+    PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::Trace(                     \
+        [](PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::TraceContext ctx) { \
+          ctx.AddEmptyTracePacket();                                       \
+        });                                                                \
   } while (false)
 
 #endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_MACROS_H_
diff --git a/include/perfetto/tracing/track_event.h b/include/perfetto/tracing/track_event.h
index c3e86d3..2651927 100644
--- a/include/perfetto/tracing/track_event.h
+++ b/include/perfetto/tracing/track_event.h
@@ -116,6 +116,9 @@
 //  '----------------------------------'
 //
 
+// DEPRECATED: Please use PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE to implement
+// multiple track event category sets in one program.
+//
 // Each compilation unit can be in exactly one track event namespace,
 // allowing the overall program to use multiple track event data sources and
 // category lists if necessary. Use this macro to select the namespace for the
@@ -125,7 +128,7 @@
 // registration (see quickstart above) needs to happen for both namespaces
 // separately.
 #ifndef PERFETTO_TRACK_EVENT_NAMESPACE
-#define PERFETTO_TRACK_EVENT_NAMESPACE perfetto
+#define PERFETTO_TRACK_EVENT_NAMESPACE perfetto_track_event
 #endif
 
 // Deprecated; see perfetto::Category().
@@ -170,28 +173,85 @@
   PERFETTO_INTERNAL_SWALLOW_SEMICOLON()
 
 // Register the set of available categories by passing a list of categories to
-// this macro: PERFETTO_CATEGORY(cat1), PERFETTO_CATEGORY(cat2), ...
-#define PERFETTO_DEFINE_CATEGORIES(...)                        \
-  namespace PERFETTO_TRACK_EVENT_NAMESPACE {                   \
-  /* The list of category names */                             \
-  PERFETTO_INTERNAL_DECLARE_CATEGORIES(__VA_ARGS__)            \
-  /* The track event data source for this set of categories */ \
-  PERFETTO_INTERNAL_DECLARE_TRACK_EVENT_DATA_SOURCE();         \
-  } /* namespace PERFETTO_TRACK_EVENT_NAMESPACE */             \
-  PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(                 \
-      PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent,              \
-      perfetto::internal::TrackEventDataSourceTraits)
+// this macro: perfetto::Category("cat1"), perfetto::Category("cat2"), ...
+// `ns` is the name of the namespace in which the categories should be declared.
+// `attrs` are linkage attributes for the underlying data source. See
+// PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS_WITH_ATTRS.
+//
+// Implementation note: the extra namespace (PERFETTO_TRACK_EVENT_NAMESPACE) is
+// kept here only for backward compatibility.
+#define PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE_WITH_ATTRS(ns, attrs, ...) \
+  namespace ns {                                                           \
+  namespace PERFETTO_TRACK_EVENT_NAMESPACE {                               \
+  /* The list of category names */                                         \
+  PERFETTO_INTERNAL_DECLARE_CATEGORIES(attrs, __VA_ARGS__)                 \
+  /* The track event data source for this set of categories */             \
+  PERFETTO_INTERNAL_DECLARE_TRACK_EVENT_DATA_SOURCE(attrs);                \
+  } /* namespace PERFETTO_TRACK_EVENT_NAMESPACE  */                        \
+  using PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent;                        \
+  } /* namespace ns */                                                     \
+  PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS_WITH_ATTRS(                  \
+      attrs, ns::PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent,               \
+      ::perfetto::internal::TrackEventDataSourceTraits)
+
+// Register the set of available categories by passing a list of categories to
+// this macro: perfetto::Category("cat1"), perfetto::Category("cat2"), ...
+// `ns` is the name of the namespace in which the categories should be declared.
+#define PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE(ns, ...) \
+  PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE_WITH_ATTRS(    \
+      ns, PERFETTO_COMPONENT_EXPORT, __VA_ARGS__)
+
+// Make categories in a given namespace the default ones used by track events
+// for the current translation unit. Can only be used *once* in a given global
+// or namespace scope.
+#define PERFETTO_USE_CATEGORIES_FROM_NAMESPACE(ns)                         \
+  namespace PERFETTO_TRACK_EVENT_NAMESPACE {                               \
+  using ::ns::PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent;                  \
+  namespace internal {                                                     \
+  using ::ns::PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry; \
+  using ::ns::PERFETTO_TRACK_EVENT_NAMESPACE::internal::                   \
+      kConstExprCategoryRegistry;                                          \
+  } /* namespace internal */                                               \
+  } /* namespace PERFETTO_TRACK_EVENT_NAMESPACE */                         \
+  PERFETTO_INTERNAL_SWALLOW_SEMICOLON()
+
+// Make categories in a given namespace the default ones used by track events
+// for the current block scope. Can only be used in a function or block scope.
+#define PERFETTO_USE_CATEGORIES_FROM_NAMESPACE_SCOPED(ns) \
+  namespace PERFETTO_TRACK_EVENT_NAMESPACE = ns::PERFETTO_TRACK_EVENT_NAMESPACE
+
+// Register categories in the default (global) namespace. Warning: only one set
+// of global categories can be defined in a single program. Create namespaced
+// categories with PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE to work around this
+// limitation.
+#define PERFETTO_DEFINE_CATEGORIES(...)                           \
+  PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE(perfetto, __VA_ARGS__); \
+  PERFETTO_USE_CATEGORIES_FROM_NAMESPACE(perfetto)
+
+// Allocate storage for each category by using this macro once per track event
+// namespace. `ns` is the name of the namespace in which the categories should
+// be declared and `attrs` specify linkage attributes for the data source.
+#define PERFETTO_TRACK_EVENT_STATIC_STORAGE_IN_NAMESPACE_WITH_ATTRS(ns, attrs) \
+  namespace ns {                                                               \
+  namespace PERFETTO_TRACK_EVENT_NAMESPACE {                                   \
+  PERFETTO_INTERNAL_CATEGORY_STORAGE(attrs)                                    \
+  PERFETTO_INTERNAL_DEFINE_TRACK_EVENT_DATA_SOURCE()                           \
+  } /* namespace PERFETTO_TRACK_EVENT_NAMESPACE */                             \
+  } /* namespace ns */                                                         \
+  PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS_WITH_ATTRS(                       \
+      attrs, ns::PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent,                   \
+      ::perfetto::internal::TrackEventDataSourceTraits)
 
 // Allocate storage for each category by using this macro once per track event
 // namespace.
-#define PERFETTO_TRACK_EVENT_STATIC_STORAGE()        \
-  namespace PERFETTO_TRACK_EVENT_NAMESPACE {         \
-  PERFETTO_INTERNAL_CATEGORY_STORAGE()               \
-  PERFETTO_INTERNAL_DEFINE_TRACK_EVENT_DATA_SOURCE() \
-  } /* namespace PERFETTO_TRACK_EVENT_NAMESPACE */   \
-  PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(        \
-      PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent,    \
-      perfetto::internal::TrackEventDataSourceTraits)
+#define PERFETTO_TRACK_EVENT_STATIC_STORAGE_IN_NAMESPACE(ns)   \
+  PERFETTO_TRACK_EVENT_STATIC_STORAGE_IN_NAMESPACE_WITH_ATTRS( \
+      ns, PERFETTO_COMPONENT_EXPORT)
+
+// Allocate storage for each category by using this macro once per track event
+// namespace.
+#define PERFETTO_TRACK_EVENT_STATIC_STORAGE() \
+  PERFETTO_TRACK_EVENT_STATIC_STORAGE_IN_NAMESPACE(perfetto)
 
 // Ignore GCC warning about a missing argument for a variadic macro parameter.
 #if defined(__GNUC__) || defined(__clang__)
diff --git a/include/perfetto/tracing/track_event_legacy.h b/include/perfetto/tracing/track_event_legacy.h
index af339ab..373e2a5 100644
--- a/include/perfetto/tracing/track_event_legacy.h
+++ b/include/perfetto/tracing/track_event_legacy.h
@@ -1277,7 +1277,7 @@
     static int PERFETTO_UID(prev) = -1;                              \
     int PERFETTO_UID(curr) =                                         \
         ::perfetto::internal::TrackEventInternal::GetSessionCount(); \
-    if (::PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::IsEnabled() && \
+    if (PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::IsEnabled() &&   \
         (PERFETTO_UID(prev) != PERFETTO_UID(curr))) {                \
       *(ret) = true;                                                 \
       PERFETTO_UID(prev) = PERFETTO_UID(curr);                       \
@@ -1312,29 +1312,29 @@
 // non-zero indicates at least one tracing session for this category is active.
 // Note that callers should not make any assumptions at what each bit represents
 // in the status byte. Does not support dynamic categories.
-#define TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category)                \
-  reinterpret_cast<const uint8_t*>(                                         \
-      [&] {                                                                 \
-        static_assert(                                                      \
-            !std::is_same<::perfetto::DynamicCategory,                      \
-                          decltype(category)>::value,                       \
-            "Enabled flag pointers are not supported for dynamic trace "    \
-            "categories.");                                                 \
-      },                                                                    \
-      PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry           \
-          .GetCategoryState(                                                \
-              ::PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry \
+#define TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category)              \
+  reinterpret_cast<const uint8_t*>(                                       \
+      [&] {                                                               \
+        static_assert(                                                    \
+            !std::is_same<::perfetto::DynamicCategory,                    \
+                          decltype(category)>::value,                     \
+            "Enabled flag pointers are not supported for dynamic trace "  \
+            "categories.");                                               \
+      },                                                                  \
+      PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry         \
+          .GetCategoryState(                                              \
+              PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry \
                   .Find(category, /*is_dynamic=*/false)))
 
 // Given a pointer returned by TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED,
 // yields a pointer to the name of the corresponding category group.
-#define TRACE_EVENT_API_GET_CATEGORY_GROUP_NAME(category_enabled_ptr)       \
-  ::PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry             \
-      .GetCategory(                                                         \
-          category_enabled_ptr -                                            \
-          reinterpret_cast<const uint8_t*>(                                 \
-              ::PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry \
-                  .GetCategoryState(0u)))                                   \
+#define TRACE_EVENT_API_GET_CATEGORY_GROUP_NAME(category_enabled_ptr)     \
+  PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry             \
+      .GetCategory(                                                       \
+          category_enabled_ptr -                                          \
+          reinterpret_cast<const uint8_t*>(                               \
+              PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry \
+                  .GetCategoryState(0u)))                                 \
       ->name
 
 #endif  // PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
diff --git a/python/generators/diff_tests/runner.py b/python/generators/diff_tests/runner.py
index 2405c03..9cae14a 100644
--- a/python/generators/diff_tests/runner.py
+++ b/python/generators/diff_tests/runner.py
@@ -37,16 +37,12 @@
 # Performance result of running the test.
 @dataclass
 class PerfResult:
-  test_type: TestType
-  trace_path: str
-  query_path_or_metric: str
+  test: DiffTest
   ingest_time_ns: int
   real_time_ns: int
 
   def __init__(self, test: DiffTest, perf_lines: List[str]):
-    self.test_type = test.type
-    self.trace_path = test.trace_path
-    self.query_path_or_metric = test.query_path
+    self.test = test
 
     assert len(perf_lines) == 1
     perf_numbers = perf_lines[0].split(',')
@@ -202,18 +198,29 @@
 
   # Run a query based Diff Test.
   def __run_query_test(self, gen_trace_path: str) -> TestResult:
+    # Fetch expected text.
     if self.test.expected_path:
       with open(self.test.expected_path, 'r') as expected_file:
         expected = expected_file.read()
     else:
       expected = self.test.blueprint.out.contents
+
+    # Fetch query.
+    if self.test.blueprint.is_query_file():
+      query = self.test.query_path
+    else:
+      tmp_query_file = tempfile.NamedTemporaryFile(delete=False)
+      with open(tmp_query_file.name, 'w') as query_file:
+        query_file.write(self.test.blueprint.query)
+      query = tmp_query_file.name
+
     tmp_perf_file = tempfile.NamedTemporaryFile(delete=False)
     cmd = [
         self.trace_processor_path,
         '--analyze-trace-proto-content',
         '--crop-track-events',
         '-q',
-        self.test.query_path,
+        query,
         '--perf-file',
         tmp_perf_file.name,
         gen_trace_path,
@@ -225,6 +232,9 @@
         env=get_env(ROOT_DIR))
     (stdout, stderr) = tp.communicate()
 
+    if not self.test.blueprint.is_query_file():
+      tmp_query_file.close()
+      os.remove(tmp_query_file.name)
     perf_lines = [line.decode('utf8') for line in tmp_perf_file.readlines()]
     tmp_perf_file.close()
     os.remove(tmp_perf_file.name)
@@ -237,6 +247,10 @@
             extension_descriptor_paths: List[str], keep_input,
             rebase) -> Tuple[TestResult, str]:
     is_generated_trace = True
+    # We can't use delete=True here. When using that on Windows, the
+    # resulting file is opened in exclusive mode (in turn that's a subtle
+    # side-effect of the underlying CreateFile(FILE_ATTRIBUTE_TEMPORARY))
+    # and TP fails to open the passed path.
     if self.test.trace_path.endswith('.py'):
       gen_trace_file = tempfile.NamedTemporaryFile(delete=False)
       serialize_python_trace(ROOT_DIR, self.trace_descriptor_path,
@@ -258,9 +272,6 @@
     str = f"{self.colors.yellow('[ RUN      ]')} {self.test.name}\n"
 
     if self.test.type == TestType.QUERY:
-      if not os.path.exists(self.test.query_path):
-        return None, str + f"Query file not found {self.test.query_path}"
-
       result = self.__run_query_test(gen_trace_path)
     elif self.test.type == TestType.METRIC:
       result = self.__run_metrics_test(
@@ -326,18 +337,6 @@
       ]
     result_str = ""
 
-    if not os.path.exists(self.test.trace_path):
-      result_str += f"Trace file not found {self.test.trace_path}\n"
-      return self.test.name, result_str, None
-    elif self.test.expected_path and not os.path.exists(
-        self.test.expected_path):
-      result_str = f"Expected file not found {self.test.expected_path}"
-      return self.test.name, result_str, None
-
-    # We can't use delete=True here. When using that on Windows, the
-    # resulting file is opened in exclusive mode (in turn that's a subtle
-    # side-effect of the underlying CreateFile(FILE_ATTRIBUTE_TEMPORARY))
-    # and TP fails to open the passed path.
     result, run_str = self.__run(metrics_descriptor_paths,
                                  extension_descriptor_paths, keep_input, rebase)
     result_str += run_str
diff --git a/python/generators/diff_tests/testing.py b/python/generators/diff_tests/testing.py
index a713f72..4e61ddd 100644
--- a/python/generators/diff_tests/testing.py
+++ b/python/generators/diff_tests/testing.py
@@ -104,18 +104,24 @@
     if blueprint.is_query_file():
       self.query_path = os.path.abspath(
           os.path.join(index_dir, blueprint.query.filename))
+      if not os.path.exists(self.query_path):
+        raise AssertionError(f"Query file for {self.name} does not exist.")
     else:
       self.query_path = None
 
     if blueprint.is_trace_file():
       self.trace_path = os.path.abspath(
           os.path.join(index_dir, blueprint.trace.filename))
+      if not os.path.exists(self.trace_path):
+        raise AssertionError(f"Trace file for {self.name} does not exist.")
     else:
       self.trace_path = None
 
     if blueprint.is_out_file():
       self.expected_path = os.path.abspath(
           os.path.join(index_dir, blueprint.out.filename))
+      if not os.path.exists(self.expected_path):
+        raise AssertionError(f"Out file for {self.name} does not exist.")
     else:
       self.expected_path = None
 
@@ -125,9 +131,6 @@
     # Assertions until string passing is supported
     if not (self.blueprint.is_trace_file()):
       raise AssertionError("Test parameters should be passed as files.")
-    if (self.type == TestType.QUERY and not self.blueprint.is_query_file()):
-      raise AssertionError(
-          "Only METRIC tests can have `query` passed as string.")
 
     query_metric_pattern = re.compile(query_metric_filter)
     trace_pattern = re.compile(trace_filter)
diff --git a/python/perfetto/experimental/slice_breakdown/breakdown.py b/python/perfetto/experimental/slice_breakdown/breakdown.py
index 5debd2d..d808123 100644
--- a/python/perfetto/experimental/slice_breakdown/breakdown.py
+++ b/python/perfetto/experimental/slice_breakdown/breakdown.py
@@ -186,14 +186,15 @@
     The same as |compute_breakdown| but only containing slices which happened
     during app startup.
   """
-  tp.metric(['android_startup'])
 
   # Verify there was only one startup in the trace matching the package
   # name.
   filter = "WHERE package = '{}'".format(package_name) if package_name else ''
   launches = tp.query(f'''
+    SELECT IMPORT('android.startups');
+
     SELECT ts, ts_end, dur
-    FROM launches
+    FROM android_startups
     {filter}
   ''').as_pandas_dataframe()
   if len(launches) == 0:
diff --git a/python/tools/slice_breakdown.py b/python/tools/slice_breakdown.py
index 9c481ba..633050b 100644
--- a/python/tools/slice_breakdown.py
+++ b/python/tools/slice_breakdown.py
@@ -18,6 +18,12 @@
 
 import argparse
 import sys
+import os
+
+PYTHON_DIR = os.path.join(
+    os.path.dirname(
+        os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "python")
+sys.path.append(os.path.join(PYTHON_DIR))
 
 from perfetto.experimental.slice_breakdown import compute_breakdown
 from perfetto.experimental.slice_breakdown import compute_breakdown_for_startup
diff --git a/src/trace_processor/OWNERS b/src/trace_processor/OWNERS
index c360c78..33d3273 100644
--- a/src/trace_processor/OWNERS
+++ b/src/trace_processor/OWNERS
@@ -1,5 +1,6 @@
 # For core Trace Processor changes.
 lalitm@google.com
+mayzner@google.com
 
 # For most Android-related metrics.
 ilkos@google.com
diff --git a/src/trace_processor/importers/common/args_tracker.h b/src/trace_processor/importers/common/args_tracker.h
index 43324a1..1c08247 100644
--- a/src/trace_processor/importers/common/args_tracker.h
+++ b/src/trace_processor/importers/common/args_tracker.h
@@ -147,6 +147,11 @@
         id);
   }
 
+  BoundInserter AddArgsTo(tables::ExperimentalProtoPathTable::Id id) {
+    return AddArgsTo(context_->storage->mutable_experimental_proto_path_table(),
+                     id);
+  }
+
   // Returns a CompactArgSet which contains the args inserted into this
   // ArgsTracker. Requires that every arg in this tracker was inserted for the
   // "arg_set_id" column given by |column| at the given |row_number|.
diff --git a/src/trace_processor/importers/proto/BUILD.gn b/src/trace_processor/importers/proto/BUILD.gn
index 7a46eae..2026e4a 100644
--- a/src/trace_processor/importers/proto/BUILD.gn
+++ b/src/trace_processor/importers/proto/BUILD.gn
@@ -36,6 +36,8 @@
     "metadata_minimal_module.h",
     "metadata_tracker.cc",
     "metadata_tracker.h",
+    "packet_analyzer.cc",
+    "packet_analyzer.h",
     "packet_sequence_state.h",
     "packet_sequence_state_generation.cc",
     "perf_sample_tracker.cc",
diff --git a/src/trace_processor/importers/proto/additional_modules.cc b/src/trace_processor/importers/proto/additional_modules.cc
index 0b1f11f..c9799b0 100644
--- a/src/trace_processor/importers/proto/additional_modules.cc
+++ b/src/trace_processor/importers/proto/additional_modules.cc
@@ -18,7 +18,6 @@
 #include "src/trace_processor/importers/ftrace/ftrace_module_impl.h"
 #include "src/trace_processor/importers/proto/android_camera_event_module.h"
 #include "src/trace_processor/importers/proto/android_probes_module.h"
-#include "src/trace_processor/importers/proto/content_analyzer.h"
 #include "src/trace_processor/importers/proto/graphics_event_module.h"
 #include "src/trace_processor/importers/proto/heap_graph_module.h"
 #include "src/trace_processor/importers/proto/metadata_module.h"
@@ -39,10 +38,6 @@
   context->modules.emplace_back(new AndroidCameraEventModule(context));
   context->modules.emplace_back(new MetadataModule(context));
 
-  if (context->config.analyze_trace_proto_content) {
-    context->modules.emplace_back(new ContentAnalyzerModule(context));
-  }
-
   // Ftrace module is special, because it has one extra method for parsing
   // ftrace packets. So we need to store a pointer to it separately.
   context->modules.emplace_back(new FtraceModuleImpl(context));
diff --git a/src/trace_processor/importers/proto/content_analyzer.cc b/src/trace_processor/importers/proto/content_analyzer.cc
index 8aac624..cc231c2 100644
--- a/src/trace_processor/importers/proto/content_analyzer.cc
+++ b/src/trace_processor/importers/proto/content_analyzer.cc
@@ -14,11 +14,10 @@
  * limitations under the License.
  */
 
-#include <numeric>
-#include <utility>
+#include "src/trace_processor/importers/proto/content_analyzer.h"
 
-#include "perfetto/ext/base/flat_hash_map.h"
 #include "perfetto/ext/base/string_utils.h"
+#include "src/trace_processor/importers/common/args_tracker.h"
 #include "src/trace_processor/importers/proto/content_analyzer.h"
 #include "src/trace_processor/storage/trace_storage.h"
 
@@ -27,7 +26,7 @@
 namespace perfetto {
 namespace trace_processor {
 
-ContentAnalyzerModule::ContentAnalyzerModule(TraceProcessorContext* context)
+ProtoContentAnalyzer::ProtoContentAnalyzer(TraceProcessorContext* context)
     : context_(context),
       pool_([]() {
         DescriptorPool pool;
@@ -39,84 +38,95 @@
         }
         return pool;
       }()),
-      computer_(&pool_, ".perfetto.protos.TracePacket") {
-  RegisterForAllFields(context_);
-}
+      computer_(&pool_, ".perfetto.protos.TracePacket") {}
 
-ModuleResult ContentAnalyzerModule::TokenizePacket(
-    const protos::pbzero::TracePacket_Decoder&,
-    TraceBlobView* packet,
-    int64_t /*packet_timestamp*/,
-    PacketSequenceState*,
-    uint32_t /*field_id*/) {
-  computer_.Reset(packet->data(), packet->length());
+ProtoContentAnalyzer::~ProtoContentAnalyzer() = default;
+
+void ProtoContentAnalyzer::ProcessPacket(
+    const TraceBlobView& packet,
+    const SampleAnnotation& packet_annotations) {
+  auto& map = aggregated_samples_[packet_annotations];
+  computer_.Reset(packet.data(), packet.length());
   for (auto sample = computer_.GetNext(); sample.has_value();
        sample = computer_.GetNext()) {
-    auto* value = aggregated_samples_.Find(computer_.GetPath());
+    auto* value = map.Find(computer_.GetPath());
     if (value)
       *value += *sample;
     else
-      aggregated_samples_.Insert(computer_.GetPath(), *sample);
+      map.Insert(computer_.GetPath(), *sample);
   }
-  return ModuleResult::Ignored();
 }
 
-void ContentAnalyzerModule::NotifyEndOfFile() {
+void ProtoContentAnalyzer::NotifyEndOfFile() {
   // TODO(kraskevich): consider generating a flamegraph-compatable table once
   // Perfetto UI supports custom flamegraphs (b/227644078).
-  base::FlatHashMap<util::SizeProfileComputer::FieldPath,
-                    tables::ExperimentalProtoPathTable::Id,
-                    util::SizeProfileComputer::FieldPathHasher>
-      path_ids;
-  for (auto sample = aggregated_samples_.GetIterator(); sample; ++sample) {
-    std::string path_string;
-    base::Optional<tables::ExperimentalProtoPathTable::Id> previous_path_id;
-    util::SizeProfileComputer::FieldPath path;
-    for (const auto& field : sample.key()) {
-      if (field.has_field_name()) {
+  for (auto annotated_map = aggregated_samples_.GetIterator(); annotated_map;
+       ++annotated_map) {
+    base::FlatHashMap<util::SizeProfileComputer::FieldPath,
+                      tables::ExperimentalProtoPathTable::Id,
+                      util::SizeProfileComputer::FieldPathHasher>
+        path_ids;
+    for (auto sample = annotated_map.value().GetIterator(); sample; ++sample) {
+      std::string path_string;
+      base::Optional<tables::ExperimentalProtoPathTable::Id> previous_path_id;
+      util::SizeProfileComputer::FieldPath path;
+      for (const auto& field : sample.key()) {
+        if (field.has_field_name()) {
+          if (!path_string.empty()) {
+            path_string += '.';
+          }
+          path_string.append(field.field_name());
+        }
         if (!path_string.empty()) {
           path_string += '.';
         }
-        path_string.append(field.field_name());
-      }
-      if (!path_string.empty()) {
-        path_string += '.';
-      }
-      path_string.append(field.type_name());
+        path_string.append(field.type_name());
 
-      path.push_back(field);
-      // Reuses existing path from |path_ids| if possible.
-      auto* path_id = path_ids.Find(path);
-      if (path_id) {
-        previous_path_id = *path_id;
-        continue;
-      }
-      // Create a new row in experimental_proto_path.
-      tables::ExperimentalProtoPathTable::Row path_row;
-      if (field.has_field_name()) {
-        path_row.field_name = context_->storage->InternString(
-            base::StringView(field.field_name()));
-      }
-      path_row.field_type =
-          context_->storage->InternString(base::StringView(field.type_name()));
-      if (previous_path_id.has_value())
-        path_row.parent_id = *previous_path_id;
+        path.push_back(field);
+        // Reuses existing path from |path_ids| if possible.
+        {
+          auto* path_id = path_ids.Find(path);
+          if (path_id) {
+            previous_path_id = *path_id;
+            continue;
+          }
+        }
+        // Create a new row in experimental_proto_path.
+        tables::ExperimentalProtoPathTable::Row path_row;
+        if (field.has_field_name()) {
+          path_row.field_name = context_->storage->InternString(
+              base::StringView(field.field_name()));
+        }
+        path_row.field_type = context_->storage->InternString(
+            base::StringView(field.type_name()));
+        if (previous_path_id.has_value())
+          path_row.parent_id = *previous_path_id;
 
-      previous_path_id =
-          context_->storage->mutable_experimental_proto_path_table()
-              ->Insert(path_row)
-              .id;
-      path_ids[path] = *previous_path_id;
+        auto path_id =
+            context_->storage->mutable_experimental_proto_path_table()
+                ->Insert(path_row)
+                .id;
+        if (!previous_path_id.has_value()) {
+          // Add annotations to the current row as an args set.
+          auto inserter = context_->args_tracker->AddArgsTo(path_id);
+          for (auto& annotation : annotated_map.key()) {
+            inserter.AddArg(annotation.first,
+                            Variadic::String(annotation.second));
+          }
+        }
+        previous_path_id = path_id;
+        path_ids[path] = path_id;
+      }
+
+      // Add a content row referring to |previous_path_id|.
+      tables::ExperimentalProtoContentTable::Row content_row;
+      content_row.path =
+          context_->storage->InternString(base::StringView(path_string));
+      content_row.path_id = *previous_path_id;
+      content_row.total_size = static_cast<int64_t>(sample.value());
+      context_->storage->mutable_experimental_proto_content_table()->Insert(
+          content_row);
     }
-
-    // Add a content row referring to |previous_path_id|.
-    tables::ExperimentalProtoContentTable::Row content_row;
-    content_row.path =
-        context_->storage->InternString(base::StringView(path_string));
-    content_row.path_id = *previous_path_id;
-    content_row.total_size = static_cast<int64_t>(sample.value());
-    context_->storage->mutable_experimental_proto_content_table()->Insert(
-        content_row);
   }
   aggregated_samples_.Clear();
 }
diff --git a/src/trace_processor/importers/proto/content_analyzer.h b/src/trace_processor/importers/proto/content_analyzer.h
index cc8af5d..27ccded 100644
--- a/src/trace_processor/importers/proto/content_analyzer.h
+++ b/src/trace_processor/importers/proto/content_analyzer.h
@@ -17,33 +17,49 @@
 #ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_CONTENT_ANALYZER_H_
 #define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_CONTENT_ANALYZER_H_
 
+#include <utility>
+#include <vector>
+
 #include "perfetto/ext/base/flat_hash_map.h"
 #include "perfetto/trace_processor/trace_blob_view.h"
-#include "src/trace_processor/importers/proto/proto_importer_module.h"
+#include "src/trace_processor/importers/proto/packet_analyzer.h"
+#include "src/trace_processor/storage/trace_storage.h"
 #include "src/trace_processor/types/trace_processor_context.h"
 #include "src/trace_processor/util/proto_profiler.h"
 
 namespace perfetto {
 namespace trace_processor {
 
-// Computes a trace proto size breakdown by field path, and exports the data to
-// an SQL table.
-class ContentAnalyzerModule : public ProtoImporterModule {
+// Interface for a module that processes track event information.
+class ProtoContentAnalyzer : public PacketAnalyzer {
  public:
   using PathToSamplesMap =
       base::FlatHashMap<util::SizeProfileComputer::FieldPath,
                         size_t,
                         util::SizeProfileComputer::FieldPathHasher>;
+  using SampleAnnotation = PacketAnalyzer::SampleAnnotation;
 
-  explicit ContentAnalyzerModule(TraceProcessorContext* context);
+  struct SampleAnnotationHasher {
+    using argument_type = SampleAnnotation;
+    using result_type = size_t;
 
-  ~ContentAnalyzerModule() override = default;
+    result_type operator()(const argument_type& p) const {
+      base::Hasher hash;
+      for (auto v : p) {
+        hash.Update(v.first.raw_id());
+        hash.Update(v.second.raw_id());
+      }
+      return static_cast<size_t>(hash.digest());
+    }
+  };
+  using AnnotatedSamplesMap = base::
+      FlatHashMap<SampleAnnotation, PathToSamplesMap, SampleAnnotationHasher>;
 
-  ModuleResult TokenizePacket(const protos::pbzero::TracePacket_Decoder&,
-                              TraceBlobView* packet,
-                              int64_t packet_timestamp,
-                              PacketSequenceState*,
-                              uint32_t field_id) override;
+  ProtoContentAnalyzer(TraceProcessorContext* context);
+  ~ProtoContentAnalyzer() override;
+
+  void ProcessPacket(const TraceBlobView& packet,
+                     const SampleAnnotation& annotation) override;
 
   void NotifyEndOfFile() override;
 
@@ -51,7 +67,7 @@
   TraceProcessorContext* context_;
   DescriptorPool pool_;
   util::SizeProfileComputer computer_;
-  PathToSamplesMap aggregated_samples_;
+  AnnotatedSamplesMap aggregated_samples_;
 };
 
 }  // namespace trace_processor
diff --git a/src/trace_processor/importers/proto/packet_analyzer.cc b/src/trace_processor/importers/proto/packet_analyzer.cc
new file mode 100644
index 0000000..d3ad6b9
--- /dev/null
+++ b/src/trace_processor/importers/proto/packet_analyzer.cc
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+#include "src/trace_processor/importers/proto/packet_analyzer.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+PacketAnalyzer::~PacketAnalyzer() = default;
+
+}
+}  // namespace perfetto
diff --git a/src/trace_processor/importers/proto/packet_analyzer.h b/src/trace_processor/importers/proto/packet_analyzer.h
new file mode 100644
index 0000000..b60412c
--- /dev/null
+++ b/src/trace_processor/importers/proto/packet_analyzer.h
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PACKET_ANALYZER_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PACKET_ANALYZER_H_
+
+#include <utility>
+#include <vector>
+
+#include "perfetto/trace_processor/trace_blob_view.h"
+#include "src/trace_processor/storage/trace_storage.h"
+#include "src/trace_processor/types/destructible.h"
+#include "src/trace_processor/types/trace_processor_context.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+// Interface for processing packet information.
+class PacketAnalyzer : public Destructible {
+ public:
+  using SampleAnnotation = std::vector<std::pair<StringId, StringId>>;
+
+  PacketAnalyzer() = default;
+  ~PacketAnalyzer() override;
+
+  static PacketAnalyzer* Get(TraceProcessorContext* context) {
+    if (!context->content_analyzer)
+      return nullptr;
+    return static_cast<PacketAnalyzer*>(context->content_analyzer.get());
+  }
+
+  virtual void ProcessPacket(const TraceBlobView& packet,
+                             const SampleAnnotation& packet_annotation) = 0;
+
+  virtual void NotifyEndOfFile() = 0;
+};
+
+}  // namespace trace_processor
+}  // namespace perfetto
+
+#endif  // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PACKET_ANALYZER_H_
diff --git a/src/trace_processor/importers/proto/proto_trace_reader.cc b/src/trace_processor/importers/proto/proto_trace_reader.cc
index 3946293..f955e6e 100644
--- a/src/trace_processor/importers/proto/proto_trace_reader.cc
+++ b/src/trace_processor/importers/proto/proto_trace_reader.cc
@@ -31,6 +31,7 @@
 #include "src/trace_processor/importers/common/track_tracker.h"
 #include "src/trace_processor/importers/ftrace/ftrace_module.h"
 #include "src/trace_processor/importers/proto/metadata_tracker.h"
+#include "src/trace_processor/importers/proto/packet_analyzer.h"
 #include "src/trace_processor/importers/proto/packet_sequence_state.h"
 #include "src/trace_processor/importers/proto/proto_incremental_state.h"
 #include "src/trace_processor/sorter/trace_sorter.h"
@@ -52,7 +53,10 @@
 namespace trace_processor {
 
 ProtoTraceReader::ProtoTraceReader(TraceProcessorContext* ctx)
-    : context_(ctx) {}
+    : context_(ctx),
+      skipped_packet_key_id_(ctx->storage->InternString("skipped_packet")),
+      invalid_incremental_state_key_id_(
+          ctx->storage->InternString("invalid_incremental_state")) {}
 ProtoTraceReader::~ProtoTraceReader() = default;
 
 util::Status ProtoTraceReader::Parse(TraceBlobView blob) {
@@ -136,6 +140,14 @@
     }
 
     if (!state->IsIncrementalStateValid()) {
+      if (context_->content_analyzer) {
+        // Account for the skipped packet for trace proto content analysis,
+        // with a special annotation.
+        PacketAnalyzer::SampleAnnotation annotation;
+        annotation.push_back(
+            {skipped_packet_key_id_, invalid_incremental_state_key_id_});
+        PacketAnalyzer::Get(context_)->ProcessPacket(packet, annotation);
+      }
       context_->storage->IncrementStats(stats::tokenizer_skipped_packets);
       return util::OkStatus();
     }
@@ -199,6 +211,10 @@
   }
   latest_timestamp_ = std::max(timestamp, latest_timestamp_);
 
+  if (context_->content_analyzer && !decoder.has_track_event()) {
+    PacketAnalyzer::Get(context_)->ProcessPacket(packet, {});
+  }
+
   auto& modules = context_->modules_by_field;
   for (uint32_t field_id = 1; field_id < modules.size(); ++field_id) {
     if (!modules[field_id].empty() && decoder.Get(field_id).valid()) {
diff --git a/src/trace_processor/importers/proto/proto_trace_reader.h b/src/trace_processor/importers/proto/proto_trace_reader.h
index 3d14671..471503a 100644
--- a/src/trace_processor/importers/proto/proto_trace_reader.h
+++ b/src/trace_processor/importers/proto/proto_trace_reader.h
@@ -96,6 +96,9 @@
   // Stores incremental state and references to interned data, e.g. for track
   // event protos.
   std::unique_ptr<ProtoIncrementalState> incremental_state;
+
+  StringId skipped_packet_key_id_;
+  StringId invalid_incremental_state_key_id_;
 };
 
 }  // namespace trace_processor
diff --git a/src/trace_processor/importers/proto/track_event_parser.cc b/src/trace_processor/importers/proto/track_event_parser.cc
index d741592..ab74bb1 100644
--- a/src/trace_processor/importers/proto/track_event_parser.cc
+++ b/src/trace_processor/importers/proto/track_event_parser.cc
@@ -30,6 +30,7 @@
 #include "src/trace_processor/importers/common/process_tracker.h"
 #include "src/trace_processor/importers/common/track_tracker.h"
 #include "src/trace_processor/importers/json/json_utils.h"
+#include "src/trace_processor/importers/proto/packet_analyzer.h"
 #include "src/trace_processor/importers/proto/packet_sequence_state.h"
 #include "src/trace_processor/importers/proto/profile_packet_utils.h"
 #include "src/trace_processor/importers/proto/track_event_tracker.h"
@@ -263,6 +264,14 @@
     category_id_ = ParseTrackEventCategory();
     name_id_ = ParseTrackEventName();
 
+    if (context_->content_analyzer) {
+      PacketAnalyzer::SampleAnnotation annotation;
+      annotation.push_back({parser_->event_category_key_id_, category_id_});
+      annotation.push_back({parser_->event_name_key_id_, name_id_});
+      PacketAnalyzer::Get(context_)->ProcessPacket(
+          event_data_->trace_packet_data.packet, annotation);
+    }
+
     RETURN_IF_ERROR(ParseTrackAssociation());
 
     // Counter-type events don't support arguments (those are on the
@@ -1478,6 +1487,8 @@
           context->storage->InternString("chrome.process_label")),
       chrome_process_type_id_(
           context_->storage->InternString("chrome.process_type")),
+      event_category_key_id_(context_->storage->InternString("event.category")),
+      event_name_key_id_(context_->storage->InternString("event.name")),
       chrome_string_lookup_(context->storage.get()),
       counter_unit_ids_{{kNullStringId, context_->storage->InternString("ns"),
                          context_->storage->InternString("count"),
diff --git a/src/trace_processor/importers/proto/track_event_parser.h b/src/trace_processor/importers/proto/track_event_parser.h
index 71340b3..86e05a9 100644
--- a/src/trace_processor/importers/proto/track_event_parser.h
+++ b/src/trace_processor/importers/proto/track_event_parser.h
@@ -123,6 +123,8 @@
   const StringId chrome_crash_trace_id_name_id_;
   const StringId chrome_process_label_flat_key_id_;
   const StringId chrome_process_type_id_;
+  const StringId event_category_key_id_;
+  const StringId event_name_key_id_;
 
   ChromeStringLookup chrome_string_lookup_;
   std::array<StringId, 4> counter_unit_ids_;
diff --git a/src/trace_processor/tables/trace_proto_tables.h b/src/trace_processor/tables/trace_proto_tables.h
index 4a7b720..9a268ff 100644
--- a/src/trace_processor/tables/trace_proto_tables.h
+++ b/src/trace_processor/tables/trace_proto_tables.h
@@ -29,7 +29,8 @@
   PERFETTO_TP_ROOT_TABLE(PARENT, C)                                    \
   C(base::Optional<ExperimentalProtoPathTable::Id>, parent_id)         \
   C(StringPool::Id, field_type)                                        \
-  C(base::Optional<StringPool::Id>, field_name)
+  C(base::Optional<StringPool::Id>, field_name)                        \
+  C(base::Optional<uint32_t>, arg_set_id)
 
 PERFETTO_TP_TABLE(PERFETTO_TP_EXPERIMENTAL_PROTO_PATH_TABLE_DEF);
 
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index b2a554c..aa6de45 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -52,6 +52,7 @@
 #include "src/trace_processor/importers/json/json_utils.h"
 #include "src/trace_processor/importers/ninja/ninja_log_parser.h"
 #include "src/trace_processor/importers/proto/additional_modules.h"
+#include "src/trace_processor/importers/proto/content_analyzer.h"
 #include "src/trace_processor/importers/proto/metadata_tracker.h"
 #include "src/trace_processor/importers/systrace/systrace_trace_parser.h"
 #include "src/trace_processor/iterator_impl.h"
@@ -699,6 +700,10 @@
     context_.json_trace_parser.reset(new JsonTraceParser(&context_));
   }
 
+  if (context_.config.analyze_trace_proto_content) {
+    context_.content_analyzer.reset(new ProtoContentAnalyzer(&context_));
+  }
+
   RegisterAdditionalModules(&context_);
 
   sqlite3* db = nullptr;
diff --git a/src/trace_processor/trace_processor_storage_impl.cc b/src/trace_processor/trace_processor_storage_impl.cc
index 4509d8d..3bea7eb 100644
--- a/src/trace_processor/trace_processor_storage_impl.cc
+++ b/src/trace_processor/trace_processor_storage_impl.cc
@@ -33,6 +33,7 @@
 #include "src/trace_processor/importers/proto/default_modules.h"
 #include "src/trace_processor/importers/proto/heap_profile_tracker.h"
 #include "src/trace_processor/importers/proto/metadata_tracker.h"
+#include "src/trace_processor/importers/proto/packet_analyzer.h"
 #include "src/trace_processor/importers/proto/perf_sample_tracker.h"
 #include "src/trace_processor/importers/proto/proto_importer_module.h"
 #include "src/trace_processor/importers/proto/proto_trace_reader.h"
@@ -134,6 +135,9 @@
   for (std::unique_ptr<ProtoImporterModule>& module : context_.modules) {
     module->NotifyEndOfFile();
   }
+  if (context_.content_analyzer) {
+    PacketAnalyzer::Get(&context_)->NotifyEndOfFile();
+  }
   context_.event_tracker->FlushPendingEvents();
   context_.slice_tracker->FlushPendingSlices();
   context_.heap_profile_tracker->NotifyEndOfFile();
diff --git a/src/trace_processor/types/trace_processor_context.h b/src/trace_processor/types/trace_processor_context.h
index e28a9d5..12aa16b 100644
--- a/src/trace_processor/types/trace_processor_context.h
+++ b/src/trace_processor/types/trace_processor_context.h
@@ -54,6 +54,7 @@
 class HeapProfileTracker;
 class PerfSampleTracker;
 class MetadataTracker;
+class PacketAnalyzer;
 class ProtoImporterModule;
 class TrackEventModule;
 class ProcessTracker;
@@ -117,6 +118,7 @@
   std::unique_ptr<Destructible> systrace_parser;         // SystraceParser
   std::unique_ptr<Destructible> thread_state_tracker;    // ThreadStateTracker
   std::unique_ptr<Destructible> i2c_tracker;             // I2CTracker
+  std::unique_ptr<Destructible> content_analyzer;
 
   // These fields are trace readers which will be called by |forwarding_parser|
   // once the format of the trace is discovered. They are placed here as they
diff --git a/src/trace_processor/util/proto_profiler.cc b/src/trace_processor/util/proto_profiler.cc
index c3ec5bd..1bcd3ff 100644
--- a/src/trace_processor/util/proto_profiler.cc
+++ b/src/trace_processor/util/proto_profiler.cc
@@ -131,6 +131,7 @@
     if (type == ProtoWireType::kLengthDelimited && is_message_type) {
       auto message_idx =
           pool_->FindDescriptorIdx(field_descriptor->resolved_type_name());
+
       if (!message_idx) {
         PERFETTO_ELOG("Cannot find descriptor for type %s",
                       field_descriptor->resolved_type_name().c_str());
@@ -139,10 +140,10 @@
 
       protozero::ProtoDecoder decoder(field.data(), field.size());
       const ProtoDescriptor* descriptor = &pool_->descriptors()[*message_idx];
-      state_stack_.push_back(
-          State{descriptor, std::move(decoder), field.size(), 0U});
       field_path_.emplace_back(field.id(), field_descriptor, *message_idx,
                                descriptor);
+      state_stack_.push_back(
+          State{descriptor, std::move(decoder), field.size(), 0U});
       return GetNext();
     } else {
       field_path_.emplace_back(field.id(), field_descriptor,
diff --git a/src/tracing/test/BUILD.gn b/src/tracing/test/BUILD.gn
index ba0fd7e..51f2348 100644
--- a/src/tracing/test/BUILD.gn
+++ b/src/tracing/test/BUILD.gn
@@ -122,6 +122,7 @@
       "tracing_module.cc",
       "tracing_module.h",
       "tracing_module2.cc",
+      "tracing_module3.cc",
       "tracing_module_categories.h",
     ]
   }
diff --git a/src/tracing/test/api_integrationtest.cc b/src/tracing/test/api_integrationtest.cc
index cd0776a..2d210e4 100644
--- a/src/tracing/test/api_integrationtest.cc
+++ b/src/tracing/test/api_integrationtest.cc
@@ -114,6 +114,12 @@
     perfetto::Category(TRACE_DISABLED_BY_DEFAULT("cat")));
 PERFETTO_TRACK_EVENT_STATIC_STORAGE();
 
+// Test declaring an extra set of categories in a namespace in addition to the
+// default one.
+PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE(other_ns,
+                                        perfetto::Category("other_ns"));
+PERFETTO_TRACK_EVENT_STATIC_STORAGE_IN_NAMESPACE(other_ns);
+
 // For testing interning of complex objects.
 using SourceLocation = std::tuple<const char* /* file_name */,
                                   const char* /* function_name */,
@@ -1473,14 +1479,17 @@
   EXPECT_EQ(1u, muxer.data_sources.size());
 
   tracing_module::InitializeCategories();
-  EXPECT_EQ(2u, muxer.data_sources.size());
+  EXPECT_EQ(3u, muxer.data_sources.size());
 
   // Both data sources have the same name but distinct static data (i.e.,
   // individual instance states).
   EXPECT_EQ("track_event", muxer.data_sources[0].dsd.name());
   EXPECT_EQ("track_event", muxer.data_sources[1].dsd.name());
+  EXPECT_EQ("track_event", muxer.data_sources[2].dsd.name());
   EXPECT_NE(muxer.data_sources[0].static_state,
             muxer.data_sources[1].static_state);
+  EXPECT_NE(muxer.data_sources[0].static_state,
+            muxer.data_sources[2].static_state);
 }
 
 TEST_P(PerfettoApiTest, TrackEventDescriptor) {
@@ -1585,6 +1594,41 @@
   }
 }
 
+TEST_P(PerfettoApiTest, TrackEventNamespaces) {
+  perfetto::TrackEvent::Register();
+  other_ns::TrackEvent::Register();
+  tracing_module::InitializeCategories();
+
+  auto* tracing_session =
+      NewTraceWithCategories({"test", "cat1", "extra", "other_ns"});
+  tracing_session->get()->StartBlocking();
+
+  // Default namespace.
+  TRACE_EVENT_INSTANT("test", "MainNamespaceEvent");
+
+  // Other namespace in a block scope.
+  {
+    PERFETTO_USE_CATEGORIES_FROM_NAMESPACE_SCOPED(other_ns);
+    TRACE_EVENT_INSTANT("other_ns", "OtherNamespaceEvent");
+  }
+
+  // Back to the default namespace.
+  TRACE_EVENT_INSTANT("test", "MainNamespaceEvent2");
+
+  // More namespaces defined in another module.
+  tracing_module::EmitTrackEventsFromAllNamespaces();
+
+  auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
+  EXPECT_THAT(
+      slices,
+      ElementsAre("I:test.MainNamespaceEvent", "I:other_ns.OtherNamespaceEvent",
+                  "I:test.MainNamespaceEvent2",
+                  "B:cat1.DefaultNamespaceFromModule",
+                  "B:extra.ExtraNamespaceFromModule",
+                  "B:extra.OverrideNamespaceFromModule",
+                  "B:extra.DefaultNamespace", "B:cat1.DefaultNamespace"));
+}
+
 TEST_P(PerfettoApiTest, TrackEventDynamicCategories) {
   // Setup the trace config.
   perfetto::TraceConfig cfg;
diff --git a/src/tracing/test/tracing_module.cc b/src/tracing/test/tracing_module.cc
index 55e14ed..d2ade28 100644
--- a/src/tracing/test/tracing_module.cc
+++ b/src/tracing/test/tracing_module.cc
@@ -24,12 +24,49 @@
 // This file is for checking that multiple sets of trace event categories can be
 // combined into the same program.
 
-PERFETTO_TRACK_EVENT_STATIC_STORAGE();
+PERFETTO_TRACK_EVENT_STATIC_STORAGE_IN_NAMESPACE(tracing_module);
+PERFETTO_TRACK_EVENT_STATIC_STORAGE_IN_NAMESPACE_WITH_ATTRS(
+    tracing_extra,
+    PERFETTO_SDK_EXPORT);
+
+namespace tracing_extra {
+namespace {
+
+void EmitEventFromExtraNamespace() {
+  TRACE_EVENT_BEGIN("extra", "ExtraNamespaceFromModule");
+  TRACE_EVENT_BEGIN("extra2", "ExtraNamespaceFromModuleNotEnabled");
+}
+
+}  // namespace
+}  // namespace tracing_extra
 
 namespace tracing_module {
 
+// The following two functions test selecting the category set on a
+// per-namespace level.
+namespace test_ns1 {
+PERFETTO_USE_CATEGORIES_FROM_NAMESPACE(tracing_extra);
+
+void EmitEvent();
+void EmitEvent() {
+  TRACE_EVENT_BEGIN("extra", "DefaultNamespace");
+}
+
+}  // namespace test_ns1
+
+namespace test_ns2 {
+PERFETTO_USE_CATEGORIES_FROM_NAMESPACE(tracing_module);
+
+void EmitEvent();
+void EmitEvent() {
+  TRACE_EVENT_BEGIN("cat1", "DefaultNamespace");
+}
+
+}  // namespace test_ns2
+
 void InitializeCategories() {
   TrackEvent::Register();
+  tracing_extra::TrackEvent::Register();
 }
 
 void AddSessionObserver(perfetto::TrackEventSessionObserver* observer) {
@@ -55,6 +92,22 @@
   TRACE_EVENT_END("foo");
 }
 
+void EmitTrackEventsFromAllNamespaces() {
+  // Since we're in the `tracing_module` namespace, that registry is used by
+  // default.
+  TRACE_EVENT_BEGIN("cat1", "DefaultNamespaceFromModule");
+
+  // Emit an event from the other namespace.
+  tracing_extra::EmitEventFromExtraNamespace();
+
+  // Make the other namespace the default.
+  PERFETTO_USE_CATEGORIES_FROM_NAMESPACE_SCOPED(tracing_extra);
+  TRACE_EVENT_BEGIN("extra", "OverrideNamespaceFromModule");
+
+  test_ns1::EmitEvent();
+  test_ns2::EmitEvent();
+}
+
 perfetto::internal::TrackEventIncrementalState* GetIncrementalState() {
   perfetto::internal::TrackEventIncrementalState* state = nullptr;
   TrackEvent::Trace([&state](TrackEvent::TraceContext ctx) {
diff --git a/src/tracing/test/tracing_module.h b/src/tracing/test/tracing_module.h
index 13e143d..cda9e43 100644
--- a/src/tracing/test/tracing_module.h
+++ b/src/tracing/test/tracing_module.h
@@ -34,6 +34,7 @@
 bool IsEnabled();
 void EmitTrackEvents();
 void EmitTrackEvents2();
+void EmitTrackEventsFromAllNamespaces();
 perfetto::internal::TrackEventIncrementalState* GetIncrementalState();
 
 // These functions are used to check the instruction size overhead track events.
@@ -50,4 +51,6 @@
 
 }  // namespace tracing_module
 
+void TestDeprecatedNamespacing();
+
 #endif  // SRC_TRACING_TEST_TRACING_MODULE_H_
diff --git a/src/tracing/test/tracing_module3.cc b/src/tracing/test/tracing_module3.cc
new file mode 100644
index 0000000..4d417a8
--- /dev/null
+++ b/src/tracing/test/tracing_module3.cc
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+#include "src/tracing/test/tracing_module.h"
+
+// This file checks that the deprecated track event namespacing mechanism
+// (PERFETTO_TRACK_EVENT_NAMESPACE) keeps working.
+
+#define PERFETTO_TRACK_EVENT_NAMESPACE deprecated_ns
+#include "perfetto/tracing.h"
+
+PERFETTO_DEFINE_CATEGORIES(PERFETTO_CATEGORY(cat1));
+PERFETTO_TRACK_EVENT_STATIC_STORAGE();
+
+void TestDeprecatedNamespacing() {
+  deprecated_ns::TrackEvent::Register();
+  TRACE_EVENT_BEGIN("cat1", "DeprecatedNamespaceEvent");
+}
diff --git a/src/tracing/test/tracing_module_categories.h b/src/tracing/test/tracing_module_categories.h
index 03c0425..9b1dd7b 100644
--- a/src/tracing/test/tracing_module_categories.h
+++ b/src/tracing/test/tracing_module_categories.h
@@ -22,21 +22,29 @@
 // ones defined in api_integrationtest.cc, but events for both sets of
 // categories can be written to the same trace writer.
 
-#define PERFETTO_TRACK_EVENT_NAMESPACE tracing_module
 #define PERFETTO_ENABLE_LEGACY_TRACE_EVENTS 1
 
 #include "perfetto/tracing.h"
 
 // Note: Using the old syntax here to ensure backwards compatibility.
-PERFETTO_DEFINE_CATEGORIES(PERFETTO_CATEGORY(cat1),
-                           PERFETTO_CATEGORY(cat2),
-                           PERFETTO_CATEGORY(cat3),
-                           PERFETTO_CATEGORY(cat4),
-                           PERFETTO_CATEGORY(cat5),
-                           PERFETTO_CATEGORY(cat6),
-                           PERFETTO_CATEGORY(cat7),
-                           PERFETTO_CATEGORY(cat8),
-                           PERFETTO_CATEGORY(cat9),
-                           PERFETTO_CATEGORY(foo));
+PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE(tracing_module,
+                                        PERFETTO_CATEGORY(cat1),
+                                        PERFETTO_CATEGORY(cat2),
+                                        PERFETTO_CATEGORY(cat3),
+                                        PERFETTO_CATEGORY(cat4),
+                                        PERFETTO_CATEGORY(cat5),
+                                        PERFETTO_CATEGORY(cat6),
+                                        PERFETTO_CATEGORY(cat7),
+                                        PERFETTO_CATEGORY(cat8),
+                                        PERFETTO_CATEGORY(cat9),
+                                        PERFETTO_CATEGORY(foo));
+
+// Define a second set of categories in a different namespace with custom
+// linkage attributes.
+PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE_WITH_ATTRS(
+    tracing_extra,
+    PERFETTO_SDK_EXPORT,
+    perfetto::Category("extra"),
+    perfetto::Category("extra2"));
 
 #endif  // SRC_TRACING_TEST_TRACING_MODULE_CATEGORIES_H_
diff --git a/test/cts/heapprofd_java_test_cts.cc b/test/cts/heapprofd_java_test_cts.cc
index 7d81128..10bc985 100644
--- a/test/cts/heapprofd_java_test_cts.cc
+++ b/test/cts/heapprofd_java_test_cts.cc
@@ -89,6 +89,51 @@
   return helper.trace();
 }
 
+std::vector<protos::gen::TracePacket> TriggerOomHeapDump(std::string app_name) {
+  base::TestTaskRunner task_runner;
+
+  // (re)start the target app's main activity
+  if (IsAppRunning(app_name)) {
+    StopApp(app_name, "old.app.stopped", &task_runner);
+    task_runner.RunUntilCheckpoint("old.app.stopped", 10000 /*ms*/);
+  }
+
+  // set up tracing
+  TestHelper helper(&task_runner);
+  helper.ConnectConsumer();
+  helper.WaitForConsumerConnect();
+
+  TraceConfig trace_config;
+  trace_config.add_buffers()->set_size_kb(40 * 1024);
+  trace_config.set_unique_session_name(RandomSessionName().c_str());
+  trace_config.set_data_source_stop_timeout_ms(60000);
+
+  auto* trigger_config = trace_config.mutable_trigger_config();
+  trigger_config->set_trigger_mode(perfetto::protos::gen::TraceConfig::TriggerConfig::START_TRACING);
+  trigger_config->set_trigger_timeout_ms(60000);
+  auto* oom_trigger = trigger_config->add_triggers();
+  oom_trigger->set_name("com.android.telemetry.art-outofmemory");
+  oom_trigger->set_stop_delay_ms(10000);
+
+  auto* ds_config = trace_config.add_data_sources()->mutable_config();
+  ds_config->set_name("android.java_hprof.oom");
+  ds_config->set_target_buffer(0);
+
+  // start tracing
+  helper.StartTracing(trace_config);
+  StartAppActivity(app_name, "JavaOomActivity", "target.app.running", &task_runner,
+                   /*delay_ms=*/100);
+
+  helper.WaitForTracingDisabled();
+  helper.ReadData();
+  helper.WaitForReadData();
+
+  PERFETTO_CHECK(IsAppRunning(app_name));
+  StopApp(app_name, "new.app.stopped", &task_runner);
+  task_runner.RunUntilCheckpoint("new.app.stopped", 10000 /*ms*/);
+  return helper.trace();
+}
+
 void AssertGraphPresent(std::vector<protos::gen::TracePacket> packets) {
   ASSERT_GT(packets.size(), 0u);
 
@@ -184,5 +229,13 @@
   AssertGraphPresent(packets);
 }
 
+TEST(HeapprofdJavaCtsTest, DebuggableAppOom) {
+  if (IsUserBuild()) return;
+
+  std::string app_name = "android.perfetto.cts.app.debuggable";
+  const auto& packets = TriggerOomHeapDump(app_name);
+  AssertGraphPresent(packets);
+}
+
 }  // namespace
 }  // namespace perfetto
diff --git a/test/cts/test_apps/AndroidManifest_debuggable.xml b/test/cts/test_apps/AndroidManifest_debuggable.xml
index cb746c1..291469e 100755
--- a/test/cts/test_apps/AndroidManifest_debuggable.xml
+++ b/test/cts/test_apps/AndroidManifest_debuggable.xml
@@ -58,5 +58,18 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity-alias>
+        <activity
+          android:name="android.perfetto.cts.app.JavaOomActivity"
+          android:exported="true">
+        </activity>
+        <activity-alias
+          android:name="android.perfetto.cts.app.debuggable.JavaOomActivity"
+          android:targetActivity="android.perfetto.cts.app.JavaOomActivity"
+          android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity-alias>
     </application>
 </manifest>
diff --git a/test/cts/test_apps/src/android/perfetto/cts/app/JavaOomActivity.java b/test/cts/test_apps/src/android/perfetto/cts/app/JavaOomActivity.java
new file mode 100644
index 0000000..4165a92
--- /dev/null
+++ b/test/cts/test_apps/src/android/perfetto/cts/app/JavaOomActivity.java
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+package android.perfetto.cts.app;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+import java.util.ArrayList;
+
+public class JavaOomActivity extends Activity {
+    @Override
+    public void onCreate(Bundle state) {
+        super.onCreate(state);
+
+        new Thread(new Runnable() {
+            public void run() {
+                try {
+                    runAllocationLoop();
+                } catch (Exception ex) {
+                    ex.printStackTrace();
+                }
+            }
+        }).start();
+    }
+
+    private static void runAllocationLoop() {
+        ArrayList<byte[]> leaky = new ArrayList<>();
+        try {
+            for (;;) {
+                leaky.add(new byte[1024 * 1024]);
+                try {
+                    Thread.sleep(10);
+                } catch (InterruptedException ignored) {
+                }
+            }
+        } catch (OutOfMemoryError e) {
+          leaky.clear();
+        }
+    }
+}
diff --git a/test/trace_processor/android/index.py b/test/trace_processor/android/index.py
index fde770e..d5c01d2 100644
--- a/test/trace_processor/android/index.py
+++ b/test/trace_processor/android/index.py
@@ -24,13 +24,36 @@
   def test_game_intervention_list_test(self):
     return DiffTestBlueprint(
         trace=Path('game_intervention_list_test.textproto'),
-        query=Path('game_intervention_list_test.sql'),
+        query="""
+SELECT
+  package_name,
+  uid,
+  current_mode,
+  standard_mode_supported,
+  standard_mode_downscale,
+  standard_mode_use_angle,
+  standard_mode_fps,
+  perf_mode_supported,
+  perf_mode_downscale,
+  perf_mode_use_angle,
+  perf_mode_fps,
+  battery_mode_supported,
+  battery_mode_downscale,
+  battery_mode_use_angle,
+  battery_mode_fps
+FROM android_game_intervention_list
+ORDER BY package_name;
+""",
         out=Path('game_intervention_list_test.out'))
 
   def test_android_system_property_counter(self):
     return DiffTestBlueprint(
         trace=Path('android_system_property.textproto'),
-        query=Path('android_system_property_counter_test.sql'),
+        query="""
+SELECT t.id, t.type, t.name, c.id, c.ts, c.type, c.value
+FROM counter_track t JOIN counter c ON t.id = c.track_id
+WHERE name = 'ScreenState';
+""",
         out=Csv("""
 "id","type","name","id","ts","type","value"
 0,"counter_track","ScreenState",0,1000,"counter",2.000000
@@ -40,23 +63,48 @@
   def test_android_system_property_slice(self):
     return DiffTestBlueprint(
         trace=Path('android_system_property.textproto'),
-        query=Path('android_system_property_slice_test.sql'),
+        query="""
+SELECT t.id, t.type, t.name, s.id, s.ts, s.dur, s.type, s.name
+FROM track t JOIN slice s ON s.track_id = t.id
+WHERE t.name = 'DeviceStateChanged';
+""",
         out=Path('android_system_property_slice.out'))
 
   def test_android_bugreport_logs_test(self):
     return DiffTestBlueprint(
         trace=Path('../../data/bugreport-crosshatch-SPB5.zip'),
-        query=Path('android_bugreport_logs_test.sql'),
+        query="""
+WITH
+initial AS (SELECT
+    (SELECT count(*) FROM android_logs) AS cnt,
+    ts, prio, tag, msg FROM android_logs
+  ORDER BY ts ASC
+  LIMIT 100
+),
+latest AS (SELECT
+    (SELECT count(*) FROM android_logs) AS cnt,
+    ts, prio, tag, msg FROM android_logs
+  ORDER BY ts DESC
+  LIMIT 100
+)
+SELECT * FROM initial UNION ALL SELECT * FROM latest;
+""",
         out=Path('android_bugreport_logs_test.out'))
 
   def test_android_bugreport_dumpstate_test(self):
     return DiffTestBlueprint(
         trace=Path('../../data/bugreport-crosshatch-SPB5.zip'),
-        query=Path('android_bugreport_dumpstate_test.sql'),
+        query="""
+SELECT section, service, count(line) AS linecount FROM android_dumpstate
+GROUP BY section, service;
+""",
         out=Path('android_bugreport_dumpstate_test.out'))
 
   def test_android_bugreport_dumpsys_test(self):
     return DiffTestBlueprint(
         trace=Path('../../data/bugreport-crosshatch-SPB5.zip'),
-        query=Path('android_bugreport_dumpsys_test.sql'),
+        query="""
+SELECT section, service, line FROM android_dumpstate
+WHERE service = 'color_display';
+""",
         out=Path('android_bugreport_dumpsys_test.out'))
diff --git a/test/trace_processor/atrace/index.py b/test/trace_processor/atrace/index.py
index ab2683e..9e3f89b 100644
--- a/test/trace_processor/atrace/index.py
+++ b/test/trace_processor/atrace/index.py
@@ -24,7 +24,10 @@
   def test_bad_print_textproto_list_slices(self):
     return DiffTestBlueprint(
         trace=Path('bad_print.textproto'),
-        query=Path('../common/list_slices_test.sql'),
+        query="""
+SELECT ts, dur, name
+FROM slice;
+""",
         out=Csv("""
 "ts","dur","name"
 74662603048,2,"valid_print"
@@ -33,7 +36,10 @@
   def test_bad_print_systrace_list_slices(self):
     return DiffTestBlueprint(
         trace=Path('bad_print.systrace'),
-        query=Path('../common/list_slices_test.sql'),
+        query="""
+SELECT ts, dur, name
+FROM slice;
+""",
         out=Csv("""
 "ts","dur","name"
 10852771242000,3000,"some event"
@@ -42,7 +48,13 @@
   def test_instant_atrace_instant_with_thread(self):
     return DiffTestBlueprint(
         trace=Path('instant_atrace.py'),
-        query=Path('instant_with_thread_test.sql'),
+        query="""
+SELECT thread.name AS thread_name, instant.name AS track_name, instant.ts
+FROM slice instant
+JOIN thread_track ON instant.track_id = thread_track.id
+JOIN thread USING (utid)
+WHERE dur = 0;
+""",
         out=Csv("""
 "thread_name","track_name","ts"
 "t2","t2_event",51
@@ -52,7 +64,17 @@
   def test_instant_async_atrace_instant_async(self):
     return DiffTestBlueprint(
         trace=Path('instant_async_atrace.py'),
-        query=Path('instant_async_test.sql'),
+        query="""
+SELECT
+  process.name AS process_name,
+  process_track.name AS track_name,
+  instant.name AS instant_name,
+  ts
+FROM slice instant
+JOIN process_track ON instant.track_id = process_track.id
+JOIN process USING (upid)
+WHERE dur = 0;
+""",
         out=Csv("""
 "process_name","track_name","instant_name","ts"
 "p2","track_p2","ev1",51
@@ -62,7 +84,10 @@
   def test_android_b2b_async_begin_list_slices(self):
     return DiffTestBlueprint(
         trace=Path('android_b2b_async_begin.textproto'),
-        query=Path('../common/list_slices_test.sql'),
+        query="""
+SELECT ts, dur, name
+FROM slice;
+""",
         out=Csv("""
 "ts","dur","name"
 1000,30,"multistart"
@@ -73,13 +98,33 @@
   def test_process_track_slices_android_async_slice(self):
     return DiffTestBlueprint(
         trace=Path('android_async_slice.textproto'),
-        query=Path('../common/process_track_slices_test.sql'),
+        query="""
+SELECT
+  ts,
+  dur,
+  pid,
+  slice.name AS slice_name,
+  process_track.name AS track_name
+FROM slice
+JOIN process_track ON slice.track_id = process_track.id
+JOIN process USING (upid);
+""",
         out=Path('process_track_slices_android_async_slice.out'))
 
   def test_async_track_atrace_process_track_slices(self):
     return DiffTestBlueprint(
         trace=Path('async_track_atrace.py'),
-        query=Path('../common/process_track_slices_test.sql'),
+        query="""
+SELECT
+  ts,
+  dur,
+  pid,
+  slice.name AS slice_name,
+  process_track.name AS track_name
+FROM slice
+JOIN process_track ON slice.track_id = process_track.id
+JOIN process USING (upid);
+""",
         out=Csv("""
 "ts","dur","pid","slice_name","track_name"
 50,25,1,"ev","track"
@@ -90,7 +135,13 @@
   def test_sys_write_and_atrace(self):
     return DiffTestBlueprint(
         trace=Path('sys_write_and_atrace.py'),
-        query=Path('sys_write_and_atrace_test.sql'),
+        query="""
+SELECT slice.ts, slice.dur, slice.name, slice.depth
+FROM slice
+JOIN thread_track ON (slice.track_id = thread_track.id)
+JOIN thread USING (utid)
+WHERE tid = 42;
+""",
         out=Csv("""
 "ts","dur","name","depth"
 100,100,"sys_write",0
diff --git a/test/trace_processor/chrome/index b/test/trace_processor/chrome/index
index 7b25bf0..ca64b68 100644
--- a/test/trace_processor/chrome/index
+++ b/test/trace_processor/chrome/index
@@ -116,4 +116,5 @@
 ../../data/chrome_custom_navigation_trace.gz chrome_custom_navigation_tasks_test.sql chrome_custom_navigation_tasks.out
 
 # Trace proto content
-../../data/chrome_scroll_without_vsync.pftrace proto_content_test.sql proto_content.out
\ No newline at end of file
+../../data/chrome_scroll_without_vsync.pftrace proto_content_test.sql proto_content.out
+../../data/chrome_scroll_without_vsync.pftrace proto_content_path_test.sql proto_content_path.out
\ No newline at end of file
diff --git a/test/trace_processor/chrome/index.py b/test/trace_processor/chrome/index.py
index 5239d3a..a99b6f8 100644
--- a/test/trace_processor/chrome/index.py
+++ b/test/trace_processor/chrome/index.py
@@ -30,43 +30,165 @@
   def test_scroll_jank(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
-        query=Path('scroll_jank_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/scroll_jank.sql');
+
+SELECT
+  gesture_scroll_id,
+  trace_id,
+  jank,
+  ts,
+  dur,
+  jank_budget
+FROM scroll_jank;
+""",
         out=Path('scroll_jank.out'))
 
   def test_event_latency_to_breakdowns(self):
     return DiffTestBlueprint(
         trace=Path('../../data/event_latency_with_args.perfetto-trace'),
-        query=Path('event_latency_to_breakdowns_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/event_latency_to_breakdowns.sql');
+
+SELECT
+  event_latency_ts,
+  event_latency_dur,
+  event_type,
+  GenerationToRendererCompositorNs,
+  GenerationToBrowserMainNs,
+  BrowserMainToRendererCompositorNs,
+  RendererCompositorQueueingDelayNs,
+  unknown_stages_seen
+FROM event_latency_to_breakdowns
+ORDER BY event_latency_id
+LIMIT 30;
+""",
         out=Path('event_latency_to_breakdowns.out'))
 
   def test_event_latency_scroll_jank(self):
     return DiffTestBlueprint(
         trace=Path('../../data/event_latency_with_args.perfetto-trace'),
-        query=Path('event_latency_scroll_jank_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/event_latency_scroll_jank.sql');
+
+SELECT
+  jank,
+  next_jank,
+  prev_jank,
+  gesture_begin_ts,
+  gesture_end_ts,
+  ts,
+  dur,
+  event_type,
+  next_ts,
+  next_dur,
+  prev_ts,
+  prev_dur
+FROM scroll_event_latency_jank
+ORDER BY jank DESC
+LIMIT 10;
+""",
         out=Path('event_latency_scroll_jank.out'))
 
   def test_event_latency_scroll_jank_cause(self):
     return DiffTestBlueprint(
         trace=Path('../../data/event_latency_with_args.perfetto-trace'),
-        query=Path('event_latency_scroll_jank_cause_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/event_latency_scroll_jank_cause.sql');
+
+SELECT
+  dur,
+  ts,
+  event_type,
+  next_jank,
+  prev_jank,
+  next_delta_dur_ns,
+  prev_delta_dur_ns,
+  cause_of_jank,
+  max_delta_dur_ns,
+  sub_cause_of_jank
+FROM event_latency_scroll_jank_cause
+ORDER by ts;
+""",
         out=Path('event_latency_scroll_jank_cause.out'))
 
   def test_scroll_flow_event(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
-        query=Path('scroll_flow_event_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/scroll_flow_event.sql');
+
+SELECT
+  trace_id,
+  ts,
+  dur,
+  jank,
+  step,
+  ancestor_end,
+  maybe_next_ancestor_ts,
+  next_ts,
+  next_trace_id,
+  next_step
+FROM scroll_flow_event
+ORDER BY gesture_scroll_id, trace_id, ts;
+""",
         out=Path('scroll_flow_event.out'))
 
   def test_scroll_flow_event_general_validation(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
-        query=Path('scroll_flow_event_general_validation_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/scroll_flow_event.sql');
+
+SELECT
+  -- Each trace_id (in our example trace not true in general) has 8 steps. There
+  -- are 139 scrolls. So we expect 1112 rows in total 72 of which are janky.
+  (
+    SELECT
+      COUNT(*)
+    FROM (
+      SELECT
+        trace_id,
+        COUNT(*)
+      FROM scroll_flow_event
+      GROUP BY trace_id
+    )
+  ) AS total_scroll_updates,
+  (
+    SELECT COUNT(*) FROM scroll_flow_event
+  ) AS total_flow_event_steps,
+  (
+    SELECT COUNT(*) FROM scroll_flow_event WHERE jank
+  ) AS total_janky_flow_event_steps,
+  (
+    SELECT COUNT(*) FROM (SELECT step FROM scroll_flow_event GROUP BY step)
+  ) AS number_of_unique_steps;
+""",
         out=Path('scroll_flow_event_general_validation.out'))
 
   def test_scroll_jank_cause(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
-        query=Path('scroll_jank_cause_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/scroll_jank_cause.sql');
+
+SELECT
+  COUNT(*) AS total,
+  SUM(jank) AS total_jank,
+  SUM(explained_jank + unexplained_jank) AS sum_explained_and_unexplained,
+  SUM(
+    CASE WHEN explained_jank THEN
+      unexplained_jank
+      ELSE
+        CASE WHEN jank AND NOT unexplained_jank THEN
+          1
+          ELSE
+            0
+        END
+    END
+  ) AS error_rows
+FROM scroll_jank_cause;
+""",
         out=Csv("""
 "total","total_jank","sum_explained_and_unexplained","error_rows"
 139,7,7,0
@@ -75,7 +197,21 @@
   def test_scroll_flow_event_queuing_delay(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
-        query=Path('scroll_flow_event_queuing_delay_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/scroll_flow_event_queuing_delay.sql');
+
+SELECT
+  trace_id,
+  jank,
+  step,
+  next_step,
+  ancestor_end,
+  maybe_next_ancestor_ts,
+  queuing_time_ns
+FROM scroll_flow_event_queuing_delay
+WHERE trace_id = 2954 OR trace_id = 2956 OR trace_id = 2960
+ORDER BY trace_id, ts;
+""",
         out=Path('scroll_flow_event_queuing_delay.out'))
 
   def test_scroll_flow_event_general_validation_2(self):
@@ -88,26 +224,89 @@
   def test_scroll_jank_cause_queuing_delay(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
-        query=Path('scroll_jank_cause_queuing_delay_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/scroll_jank_cause_queuing_delay.sql');
+
+SELECT
+  process_name,
+  thread_name,
+  trace_id,
+  jank,
+  dur_overlapping_ns,
+  metric_name
+FROM scroll_jank_cause_queuing_delay
+WHERE trace_id = 2918 OR trace_id = 2926
+ORDER BY trace_id ASC, ts ASC;
+""",
         out=Path('scroll_jank_cause_queuing_delay.out'))
 
   def test_scroll_jank_cause_queuing_delay_restricted(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
-        query=Path('scroll_jank_cause_queuing_delay_restricted_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/scroll_jank_cause_queuing_delay.sql');
+
+SELECT
+  process_name,
+  thread_name,
+  trace_id,
+  jank,
+  dur_overlapping_ns,
+  restricted_metric_name
+FROM scroll_jank_cause_queuing_delay
+WHERE trace_id = 2918 OR trace_id = 2926
+ORDER BY trace_id ASC, ts ASC;
+""",
         out=Path('scroll_jank_cause_queuing_delay_restricted.out'))
 
   def test_scroll_jank_cause_queuing_delay_general_validation(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
-        query=Path(
-            'scroll_jank_cause_queuing_delay_general_validation_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/scroll_jank_cause_queuing_delay.sql');
+
+SELECT
+  COUNT(*) AS total,
+  (
+    SELECT DISTINCT
+      (avg_no_jank_dur_overlapping_ns)
+    FROM scroll_jank_cause_queuing_delay
+    WHERE
+      location = "LatencyInfo.Flow"
+      AND jank
+  ) AS janky_latency_info_non_jank_avg_dur,
+  (
+    SELECT DISTINCT
+      (avg_no_jank_dur_overlapping_ns)
+    FROM scroll_jank_cause_queuing_delay
+    WHERE
+      location = "LatencyInfo.Flow"
+      AND NOT jank
+  ) AS non_janky_latency_info_non_jank_avg_dur
+FROM (
+  SELECT
+    trace_id
+  FROM scroll_jank_cause_queuing_delay
+  GROUP BY trace_id
+);
+""",
         out=Path('scroll_jank_cause_queuing_delay_general_validation.out'))
 
   def test_chrome_thread_slice(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
-        query=Path('chrome_thread_slice_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/chrome_thread_slice.sql');
+
+SELECT
+  EXTRACT_ARG(arg_set_id, 'chrome_latency_info.trace_id') AS trace_id,
+  dur,
+  thread_dur
+FROM chrome_thread_slice
+WHERE
+  name = 'LatencyInfo.Flow'
+  AND EXTRACT_ARG(arg_set_id, 'chrome_latency_info.trace_id') = 2734;
+""",
         out=Csv("""
 "trace_id","dur","thread_dur"
 2734,25000,25000
@@ -121,26 +320,67 @@
     return DiffTestBlueprint(
         trace=Path(
             '../../data/scrolling_with_blocked_nonblocked_frames.pftrace'),
-        query=Path('chrome_input_to_browser_intervals_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/chrome_input_to_browser_intervals.sql');
+
+SELECT
+  *
+FROM chrome_input_to_browser_intervals
+WHERE window_start_ts >= 60934320005158
+  AND window_start_ts <= 60934338798158;
+""",
         out=Path('chrome_input_to_browser_intervals.out'))
 
   def test_chrome_scroll_jank_caused_by_scheduling_test(self):
     return DiffTestBlueprint(
         trace=Path('../../data/fling_with_input_delay.pftrace'),
-        query=Path('chrome_scroll_jank_caused_by_scheduling_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/chrome_scroll_jank_caused_by_scheduling.sql',
+  'dur_causes_jank_ms',
+/* dur_causes_jank_ms = */ '5');
+
+SELECT
+  full_name,
+  total_duration_ms,
+  total_thread_duration_ms,
+  count,
+  window_start_ts,
+  window_end_ts,
+  scroll_type
+FROM chrome_scroll_jank_caused_by_scheduling;
+""",
         out=Path('chrome_scroll_jank_caused_by_scheduling_test.out'))
 
   def test_chrome_tasks_delaying_input_processing_test(self):
     return DiffTestBlueprint(
         trace=Path('../../data/fling_with_input_delay.pftrace'),
-        query=Path('chrome_tasks_delaying_input_processing_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/chrome_tasks_delaying_input_processing.sql',
+  'duration_causing_jank_ms',
+ /* duration_causing_jank_ms = */ '8');
+
+SELECT
+  full_name,
+  duration_ms,
+  thread_dur_ms
+FROM chrome_tasks_delaying_input_processing;
+""",
         out=Path('chrome_tasks_delaying_input_processing_test.out'))
 
   def test_long_task_tracking_trace_chrome_long_tasks_delaying_input_processing_test(
       self):
     return DiffTestBlueprint(
         trace=Path('../../data/long_task_tracking_trace'),
-        query=Path('chrome_long_tasks_delaying_input_processing_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/chrome_long_tasks_delaying_input_processing.sql');
+
+SELECT
+  full_name,
+  duration_ms,
+  slice_id
+FROM chrome_tasks_delaying_input_processing
+ORDER BY slice_id;
+""",
         out=Path(
             'long_task_tracking_trace_chrome_long_tasks_delaying_input_processing_test.out'
         ))
@@ -149,9 +389,17 @@
       self):
     return DiffTestBlueprint(
         trace=Path('../../data/fling_with_input_delay.pftrace'),
-        query=Path(
-            'experimental_reliable_chrome_tasks_delaying_input_processing_test.sql'
-        ),
+        query="""
+SELECT RUN_METRIC(
+    'chrome/experimental_reliable_chrome_tasks_delaying_input_processing.sql',
+    'duration_causing_jank_ms', '8');
+
+SELECT
+  full_name,
+  duration_ms,
+  thread_dur_ms
+FROM chrome_tasks_delaying_input_processing;
+""",
         out=Path(
             'experimental_reliable_chrome_tasks_delaying_input_processing_test.out'
         ))
@@ -160,7 +408,15 @@
     return DiffTestBlueprint(
         trace=Path(
             '../../data/scrolling_with_blocked_nonblocked_frames.pftrace'),
-        query=Path('chrome_scroll_inputs_per_frame_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/chrome_scroll_inputs_per_frame.sql');
+
+SELECT
+  count_for_frame,
+  ts
+FROM chrome_scroll_inputs_per_frame
+WHERE ts = 60934316798158;
+""",
         out=Csv("""
 "count_for_frame","ts"
 4,60934316798158
@@ -169,7 +425,16 @@
   def test_chrome_thread_slice_repeated(self):
     return DiffTestBlueprint(
         trace=Path('../track_event/track_event_counters.textproto'),
-        query=Path('chrome_thread_slice_repeated_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/chrome_thread_slice.sql');
+
+SELECT
+  name,
+  ts,
+  dur,
+  thread_dur
+FROM chrome_thread_slice;
+""",
         out=Csv("""
 "name","ts","dur","thread_dur"
 "event1_on_t1",1000,100,10000
@@ -208,7 +473,11 @@
   def test_chrome_long_latency_metric(self):
     return DiffTestBlueprint(
         trace=Path('../chrome/long_event_latency.textproto'),
-        query=Path('chrome_long_latency_metric_test.sql'),
+        query="""
+SELECT RUN_METRIC('experimental/chrome_long_latency.sql');
+
+SELECT * FROM long_latency_with_process_info;
+""",
         out=Csv("""
 "ts","event_type","process_name","process_id"
 200111000,"FirstGestureScrollUpdate,GestureScrollUpdate","Renderer",1001
@@ -219,13 +488,29 @@
   def test_scroll_jank_mojo_simple_watcher(self):
     return DiffTestBlueprint(
         trace=Path('scroll_jank_mojo_simple_watcher.py'),
-        query=Path('scroll_jank_mojo_simple_watcher_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/scroll_jank_cause_queuing_delay.sql');
+
+SELECT
+  trace_id,
+  jank,
+  dur_overlapping_ns,
+  metric_name
+FROM scroll_jank_cause_queuing_delay
+ORDER BY trace_id ASC, ts ASC;
+""",
         out=Path('scroll_jank_mojo_simple_watcher.out'))
 
   def test_scroll_jank_gpu_check(self):
     return DiffTestBlueprint(
         trace=Path('scroll_jank_gpu_check.py'),
-        query=Path('scroll_jank_gpu_check_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/scroll_jank.sql');
+
+SELECT ts, jank
+FROM scroll_jank
+ORDER BY ts ASC;
+""",
         out=Csv("""
 "ts","jank"
 15000000,0
@@ -236,25 +521,77 @@
   def test_touch_jank(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_touch_gesture_scroll.pftrace'),
-        query=Path('touch_jank_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/touch_jank.sql');
+
+SELECT
+  touch_id,
+  trace_id,
+  jank,
+  ts,
+  dur,
+  jank_budget
+FROM touch_jank;
+""",
         out=Path('touch_jank.out'))
 
   def test_touch_flow_event(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_touch_gesture_scroll.pftrace'),
-        query=Path('touch_flow_event_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/touch_flow_event.sql');
+
+SELECT
+  trace_id,
+  ts,
+  dur,
+  jank,
+  step,
+  ancestor_end,
+  maybe_next_ancestor_ts,
+  next_ts,
+  next_trace_id,
+  next_step
+FROM touch_flow_event
+ORDER BY touch_id, trace_id, ts;
+""",
         out=Path('touch_flow_event.out'))
 
   def test_touch_flow_event_queuing_delay(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_touch_gesture_scroll.pftrace'),
-        query=Path('touch_flow_event_queuing_delay_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/touch_flow_event_queuing_delay.sql');
+
+SELECT
+  trace_id,
+  jank,
+  step,
+  next_step,
+  ancestor_end,
+  maybe_next_ancestor_ts,
+  queuing_time_ns
+FROM touch_flow_event_queuing_delay
+WHERE trace_id = 6915 OR trace_id = 6911 OR trace_id = 6940
+ORDER BY trace_id, ts;
+""",
         out=Path('touch_flow_event_queuing_delay.out'))
 
   def test_touch_jank_synth(self):
     return DiffTestBlueprint(
         trace=Path('touch_jank.py'),
-        query=Path('touch_jank_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/touch_jank.sql');
+
+SELECT
+  touch_id,
+  trace_id,
+  jank,
+  ts,
+  dur,
+  jank_budget
+FROM touch_jank;
+""",
         out=Csv("""
 "touch_id","trace_id","jank","ts","dur","jank_budget"
 87654,34577,0,0,10000000,-31333333.350000
@@ -265,61 +602,209 @@
   def test_touch_flow_event_synth(self):
     return DiffTestBlueprint(
         trace=Path('touch_jank.py'),
-        query=Path('touch_flow_event_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/touch_flow_event.sql');
+
+SELECT
+  trace_id,
+  ts,
+  dur,
+  jank,
+  step,
+  ancestor_end,
+  maybe_next_ancestor_ts,
+  next_ts,
+  next_trace_id,
+  next_step
+FROM touch_flow_event
+ORDER BY touch_id, trace_id, ts;
+""",
         out=Path('touch_flow_event_synth.out'))
 
   def test_touch_flow_event_queuing_delay_synth(self):
     return DiffTestBlueprint(
         trace=Path('touch_jank.py'),
-        query=Path('touch_flow_event_queuing_delay_full_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/touch_flow_event_queuing_delay.sql');
+
+SELECT
+  trace_id,
+  jank,
+  step,
+  next_step,
+  ancestor_end,
+  maybe_next_ancestor_ts,
+  queuing_time_ns
+FROM touch_flow_event_queuing_delay
+ORDER BY trace_id, ts;
+""",
         out=Path('touch_flow_event_queuing_delay_synth.out'))
 
   def test_memory_snapshot_general_validation(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_memory_snapshot.pftrace'),
-        query=Path('memory_snapshot_general_validation_test.sql'),
+        query="""
+SELECT
+  (
+    SELECT COUNT(*) FROM memory_snapshot
+  ) AS total_snapshots,
+  (
+    SELECT COUNT(*) FROM process
+  ) AS total_processes,
+  (
+    SELECT COUNT(*) FROM process_memory_snapshot
+  ) AS total_process_snapshots,
+  (
+    SELECT COUNT(*) FROM memory_snapshot_node
+  ) AS total_nodes,
+  (
+    SELECT COUNT(*) FROM memory_snapshot_edge
+  ) AS total_edges,
+  (
+    SELECT COUNT(DISTINCT args.id)
+    FROM args
+    JOIN memory_snapshot_node
+      ON args.arg_set_id = memory_snapshot_node.arg_set_id
+  ) AS total_node_args,
+  (
+    SELECT COUNT(*) FROM profiler_smaps
+    JOIN memory_snapshot ON timestamp = ts
+  ) AS total_smaps;
+""",
         out=Path('memory_snapshot_general_validation.out'))
 
   def test_memory_snapshot_os_dump_events(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_memory_snapshot.pftrace'),
-        query=Path('memory_snapshot_os_dump_events_test.sql'),
+        query="""
+SELECT
+  p.upid,
+  pid,
+  p.name,
+  timestamp,
+  detail_level,
+  pf.value AS private_footprint_kb,
+  prs.value AS peak_resident_set_kb,
+  EXTRACT_ARG(p.arg_set_id, 'is_peak_rss_resettable') AS is_peak_rss_resettable
+FROM process p
+LEFT JOIN memory_snapshot
+LEFT JOIN (
+  SELECT id, upid
+  FROM process_counter_track
+  WHERE name = 'chrome.private_footprint_kb'
+  ) AS pct_pf
+  ON p.upid = pct_pf.upid
+LEFT JOIN counter pf ON timestamp = pf.ts AND pct_pf.id = pf.track_id
+LEFT JOIN (
+  SELECT id, upid
+  FROM process_counter_track
+  WHERE name = 'chrome.peak_resident_set_kb'
+  ) AS pct_prs
+  ON p.upid = pct_prs.upid
+LEFT JOIN counter prs ON timestamp = prs.ts AND pct_prs.id = prs.track_id
+ORDER BY timestamp;
+""",
         out=Path('memory_snapshot_os_dump_events.out'))
 
   def test_memory_snapshot_chrome_dump_events(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_memory_snapshot.pftrace'),
-        query=Path('memory_snapshot_chrome_dump_events_test.sql'),
+        query="""
+SELECT
+  pms.id AS process_snapshot_id,
+  upid,
+  snapshot_id,
+  timestamp,
+  detail_level
+FROM memory_snapshot ms
+LEFT JOIN process_memory_snapshot pms
+  ON ms.id = pms.snapshot_id;
+""",
         out=Path('memory_snapshot_chrome_dump_events.out'))
 
   def test_memory_snapshot_nodes(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_memory_snapshot.pftrace'),
-        query=Path('memory_snapshot_nodes_test.sql'),
+        query="""
+SELECT
+  id,
+  process_snapshot_id,
+  parent_node_id,
+  path,
+  size,
+  effective_size
+FROM memory_snapshot_node
+LIMIT 20;
+""",
         out=Path('memory_snapshot_nodes.out'))
 
   def test_memory_snapshot_edges(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_memory_snapshot.pftrace'),
-        query=Path('memory_snapshot_edges_test.sql'),
+        query="""
+SELECT
+  id,
+  source_node_id,
+  target_node_id,
+  importance
+FROM memory_snapshot_edge
+LIMIT 20;
+""",
         out=Path('memory_snapshot_edges.out'))
 
   def test_memory_snapshot_node_args(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_memory_snapshot.pftrace'),
-        query=Path('memory_snapshot_node_args_test.sql'),
+        query="""
+SELECT
+  node.id AS node_id,
+  key,
+  value_type,
+  int_value,
+  string_value
+FROM memory_snapshot_node node
+JOIN args ON node.arg_set_id = args.arg_set_id
+LIMIT 20;
+""",
         out=Path('memory_snapshot_node_args.out'))
 
   def test_memory_snapshot_smaps(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_memory_snapshot.pftrace'),
-        query=Path('memory_snapshot_smaps_test.sql'),
+        query="""
+SELECT
+  process.upid,
+  process.name,
+  smap.ts,
+  path,
+  size_kb,
+  private_dirty_kb,
+  swap_kb,
+  file_name,
+  start_address,
+  module_timestamp,
+  module_debugid,
+  module_debug_path,
+  protection_flags,
+  private_clean_resident_kb,
+  shared_dirty_resident_kb,
+  shared_clean_resident_kb,
+  locked_kb,
+  proportional_resident_kb
+FROM process
+JOIN profiler_smaps smap ON process.upid = smap.upid
+JOIN memory_snapshot ms ON ms.timestamp = smap.ts
+LIMIT 20;
+""",
         out=Path('memory_snapshot_smaps.out'))
 
   def test_combined_rail_modes(self):
     return DiffTestBlueprint(
         trace=Path('combined_rail_modes.py'),
-        query=Path('combined_rail_modes_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/rail_modes.sql');
+SELECT * FROM combined_overall_rail_slices;
+""",
         out=Csv("""
 "id","ts","dur","rail_mode"
 1,0,10000,"response"
@@ -330,7 +815,10 @@
   def test_cpu_time_by_combined_rail_mode(self):
     return DiffTestBlueprint(
         trace=Path('cpu_time_by_combined_rail_mode.py'),
-        query=Path('cpu_time_by_combined_rail_mode_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/cpu_time_by_rail_mode.sql');
+SELECT * FROM cpu_time_by_rail_mode;
+""",
         out=Csv("""
 "id","ts","dur","rail_mode","cpu_dur"
 1,0,10000,"response",26000
@@ -343,7 +831,10 @@
   def test_actual_power_by_combined_rail_mode(self):
     return DiffTestBlueprint(
         trace=Path('actual_power_by_combined_rail_mode.py'),
-        query=Path('actual_power_by_combined_rail_mode_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/actual_power_by_rail_mode.sql');
+SELECT * FROM real_power_by_rail_mode;
+""",
         out=Csv("""
 "id","ts","dur","rail_mode","subsystem","joules","drain_w"
 1,0,10000000,"response","cellular",0.000000,0.000000
@@ -361,7 +852,10 @@
   def test_estimated_power_by_combined_rail_mode(self):
     return DiffTestBlueprint(
         trace=Path('estimated_power_by_combined_rail_mode.py'),
-        query=Path('estimated_power_by_combined_rail_mode_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/estimated_power_by_rail_mode.sql');
+SELECT * FROM power_by_rail_mode;
+""",
         out=Csv("""
 "id","ts","dur","rail_mode","mas","ma"
 1,0,10000000,"response",0.554275,55.427500
@@ -374,7 +868,10 @@
   def test_modified_rail_modes(self):
     return DiffTestBlueprint(
         trace=Path('modified_rail_modes.py'),
-        query=Path('modified_rail_modes_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/rail_modes.sql');
+SELECT * FROM modified_rail_slices;
+""",
         out=Csv("""
 "id","ts","dur","mode"
 2,0,1000000000,"response"
@@ -387,7 +884,10 @@
   def test_modified_rail_modes_no_vsyncs(self):
     return DiffTestBlueprint(
         trace=Path('modified_rail_modes_no_vsyncs.py'),
-        query=Path('modified_rail_modes_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/rail_modes.sql');
+SELECT * FROM modified_rail_slices;
+""",
         out=Csv("""
 "id","ts","dur","mode"
 2,0,1000000000,"response"
@@ -398,7 +898,10 @@
   def test_modified_rail_modes_with_input(self):
     return DiffTestBlueprint(
         trace=Path('modified_rail_modes_with_input.py'),
-        query=Path('modified_rail_modes_with_input_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/rail_modes.sql');
+SELECT * FROM modified_rail_slices;
+""",
         out=Csv("""
 "id","ts","dur","mode"
 2,0,1000000000,"response"
@@ -413,7 +916,10 @@
   def test_modified_rail_modes_long(self):
     return DiffTestBlueprint(
         trace=Path('modified_rail_modes_long.py'),
-        query=Path('modified_rail_modes_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/rail_modes.sql');
+SELECT * FROM modified_rail_slices;
+""",
         out=Csv("""
 "id","ts","dur","mode"
 2,0,1000000000,"response"
@@ -423,7 +929,10 @@
   def test_modified_rail_modes_extra_long(self):
     return DiffTestBlueprint(
         trace=Path('modified_rail_modes_extra_long.py'),
-        query=Path('modified_rail_modes_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/rail_modes.sql');
+SELECT * FROM modified_rail_slices;
+""",
         out=Csv("""
 "id","ts","dur","mode"
 """))
@@ -431,7 +940,10 @@
   def test_chrome_processes(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
-        query=Path('chrome_processes_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/chrome_processes.sql');
+SELECT pid, name, process_type FROM chrome_process;
+""",
         out=Csv("""
 "pid","name","process_type"
 18250,"Renderer","Renderer"
@@ -443,25 +955,47 @@
   def test_chrome_processes_android_systrace(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_android_systrace.pftrace'),
-        query=Path('chrome_processes_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/chrome_processes.sql');
+SELECT pid, name, process_type FROM chrome_process;
+""",
         out=Path('chrome_processes_android_systrace.out'))
 
   def test_chrome_threads(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
-        query=Path('chrome_threads_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/chrome_processes.sql');
+SELECT tid, name, is_main_thread, canonical_name
+FROM chrome_thread
+ORDER BY tid, name;
+""",
         out=Path('chrome_threads.out'))
 
   def test_chrome_threads_android_systrace(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_android_systrace.pftrace'),
-        query=Path('chrome_threads_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/chrome_processes.sql');
+SELECT tid, name, is_main_thread, canonical_name
+FROM chrome_thread
+ORDER BY tid, name;
+""",
         out=Path('chrome_threads_android_systrace.out'))
 
   def test_chrome_processes_type(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
-        query=Path('chrome_processes_type_test.sql'),
+        query="""
+SELECT pid, name, string_value AS chrome_process_type
+FROM
+  process
+JOIN
+  (SELECT * FROM args WHERE key = "chrome.process_type") chrome_process_args
+  ON
+    process.arg_set_id = chrome_process_args.arg_set_id
+ORDER BY pid;
+""",
         out=Csv("""
 "pid","name","chrome_process_type"
 17547,"Browser","Browser"
@@ -473,13 +1007,31 @@
   def test_chrome_processes_type_android_systrace(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_android_systrace.pftrace'),
-        query=Path('chrome_processes_type_test.sql'),
+        query="""
+SELECT pid, name, string_value AS chrome_process_type
+FROM
+  process
+JOIN
+  (SELECT * FROM args WHERE key = "chrome.process_type") chrome_process_args
+  ON
+    process.arg_set_id = chrome_process_args.arg_set_id
+ORDER BY pid;
+""",
         out=Path('chrome_processes_type_android_systrace.out'))
 
   def test_track_with_chrome_process(self):
     return DiffTestBlueprint(
         trace=Path('track_with_chrome_process.textproto'),
-        query=Path('chrome_processes_type_test.sql'),
+        query="""
+SELECT pid, name, string_value AS chrome_process_type
+FROM
+  process
+JOIN
+  (SELECT * FROM args WHERE key = "chrome.process_type") chrome_process_args
+  ON
+    process.arg_set_id = chrome_process_args.arg_set_id
+ORDER BY pid;
+""",
         out=Csv("""
 "pid","name","chrome_process_type"
 5,"p5","[NULL]"
@@ -565,14 +1117,36 @@
         trace=Path(
             '../../data/chrome_page_load_all_categories_not_extended.pftrace.gz'
         ),
-        query=Path('chrome_tasks_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/chrome_tasks.sql');
+
+SELECT full_name, task_type, count() AS count
+FROM chrome_tasks
+GROUP BY full_name, task_type
+ORDER BY count DESC
+LIMIT 50;
+""",
         out=Path('chrome_tasks.out'))
 
   def test_top_level_java_choreographer_slices_top_level_java_chrome_tasks_test(
       self):
     return DiffTestBlueprint(
         trace=Path('../../data/top_level_java_choreographer_slices'),
-        query=Path('top_level_java_chrome_tasks_test.sql'),
+        query="""
+SELECT RUN_METRIC(
+  'chrome/chrome_tasks_template.sql',
+  'slice_table_name', 'slice',
+  'function_prefix', ''
+);
+
+SELECT
+  full_name,
+  task_type
+FROM chrome_tasks
+WHERE category = "toplevel,Java"
+AND ts < 263904000000000
+GROUP BY full_name, task_type;
+""",
         out=Path(
             'top_level_java_choreographer_slices_top_level_java_chrome_tasks_test.out'
         ))
@@ -580,7 +1154,28 @@
   def test_chrome_stack_samples_for_task_test(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_stack_traces_symbolized_trace.pftrace'),
-        query=Path('chrome_stack_samples_for_task_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/chrome_stack_samples_for_task.sql',
+    'target_duration_ms', '0.000001',
+    'thread_name', '"CrBrowserMain"',
+    'task_name', '"sendTouchEvent"');
+
+SELECT
+  sample.description,
+  sample.ts,
+  sample.depth
+FROM chrome_stack_samples_for_task sample
+JOIN (
+    SELECT
+      ts,
+      dur
+    FROM slice
+    WHERE ts = 696373965001470
+) test_slice
+ON sample.ts >= test_slice.ts
+  AND sample.ts <= test_slice.ts + test_slice.dur
+ORDER BY sample.ts, sample.depth;
+""",
         out=Path('chrome_stack_samples_for_task_test.out'))
 
   def test_unsymbolized_args(self):
@@ -606,7 +1201,9 @@
   def test_async_trace_1_count_slices(self):
     return DiffTestBlueprint(
         trace=Path('../../data/async-trace-1.json'),
-        query=Path('count_slices_test.sql'),
+        query="""
+SELECT COUNT(1) FROM slice;
+""",
         out=Csv("""
 "COUNT(1)"
 16
@@ -615,7 +1212,9 @@
   def test_async_trace_2_count_slices(self):
     return DiffTestBlueprint(
         trace=Path('../../data/async-trace-2.json'),
-        query=Path('count_slices_test.sql'),
+        query="""
+SELECT COUNT(1) FROM slice;
+""",
         out=Csv("""
 "COUNT(1)"
 35
@@ -640,7 +1239,9 @@
   def test_chrome_log_message(self):
     return DiffTestBlueprint(
         trace=Path('chrome_log_message.textproto'),
-        query=Path('chrome_log_message_test.sql'),
+        query="""
+SELECT utid, tag, msg FROM android_logs;
+""",
         out=Csv("""
 "utid","tag","msg"
 1,"foo.cc:123","log message"
@@ -658,7 +1259,15 @@
   def test_chrome_missing_processes_default_trace(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
-        query=Path('chrome_missing_processes_test.sql'),
+        query="""
+SELECT upid, pid, reliable_from
+FROM
+  experimental_missing_chrome_processes
+JOIN
+  process
+  USING(upid)
+ORDER BY upid;
+""",
         out=Csv("""
 "upid","pid","reliable_from"
 """))
@@ -666,7 +1275,15 @@
   def test_chrome_missing_processes(self):
     return DiffTestBlueprint(
         trace=Path('chrome_missing_processes.textproto'),
-        query=Path('chrome_missing_processes_test.sql'),
+        query="""
+SELECT upid, pid, reliable_from
+FROM
+  experimental_missing_chrome_processes
+JOIN
+  process
+  USING(upid)
+ORDER BY upid;
+""",
         out=Csv("""
 "upid","pid","reliable_from"
 2,100,1000000000
@@ -676,7 +1293,15 @@
   def test_chrome_missing_processes_args(self):
     return DiffTestBlueprint(
         trace=Path('chrome_missing_processes.textproto'),
-        query=Path('chrome_missing_processes_args_test.sql'),
+        query="""
+SELECT arg_set_id, key, int_value
+FROM
+  slice
+JOIN
+  args
+  USING(arg_set_id)
+ORDER BY arg_set_id, key;
+""",
         out=Csv("""
 "arg_set_id","key","int_value"
 2,"chrome_active_processes.pid[0]",10
@@ -687,7 +1312,15 @@
   def test_chrome_missing_processes_2(self):
     return DiffTestBlueprint(
         trace=Path('chrome_missing_processes_extension.textproto'),
-        query=Path('chrome_missing_processes_test.sql'),
+        query="""
+SELECT upid, pid, reliable_from
+FROM
+  experimental_missing_chrome_processes
+JOIN
+  process
+  USING(upid)
+ORDER BY upid;
+""",
         out=Csv("""
 "upid","pid","reliable_from"
 2,100,1000000000
@@ -697,7 +1330,15 @@
   def test_chrome_missing_processes_extension_args(self):
     return DiffTestBlueprint(
         trace=Path('chrome_missing_processes_extension.textproto'),
-        query=Path('chrome_missing_processes_args_test.sql'),
+        query="""
+SELECT arg_set_id, key, int_value
+FROM
+  slice
+JOIN
+  args
+  USING(arg_set_id)
+ORDER BY arg_set_id, key;
+""",
         out=Csv("""
 "arg_set_id","key","int_value"
 2,"active_processes.pid[0]",10
@@ -708,7 +1349,19 @@
   def test_chrome_custom_navigation_tasks(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_custom_navigation_trace.gz'),
-        query=Path('chrome_custom_navigation_tasks_test.sql'),
+        query="""
+SELECT RUN_METRIC('chrome/chrome_tasks.sql');
+
+SELECT full_name, task_type, count() AS count
+FROM chrome_tasks
+WHERE full_name GLOB 'FrameHost::BeginNavigation*'
+  OR full_name GLOB 'FrameHost::DidCommitProvisionalLoad*'
+  OR full_name GLOB 'FrameHost::DidCommitSameDocumentNavigation*'
+  OR full_name GLOB 'FrameHost::DidStopLoading*'
+GROUP BY full_name, task_type
+ORDER BY count DESC
+LIMIT 50;
+""",
         out=Csv("""
 "full_name","task_type","count"
 "FrameHost::BeginNavigation (SUBFRAME)","navigation_task",5
@@ -720,5 +1373,12 @@
   def test_proto_content(self):
     return DiffTestBlueprint(
         trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
-        query=Path('proto_content_test.sql'),
+        query="""
+SELECT path, SUM(total_size) as total_size
+FROM experimental_proto_content as content 
+JOIN experimental_proto_path as frame ON content.path_id = frame.id
+GROUP BY path
+ORDER BY total_size DESC, path
+LIMIT 10;
+""",
         out=Path('proto_content.out'))
diff --git a/test/trace_processor/chrome/proto_content.out b/test/trace_processor/chrome/proto_content.out
index 4fe24cd..6c37864 100644
--- a/test/trace_processor/chrome/proto_content.out
+++ b/test/trace_processor/chrome/proto_content.out
@@ -1,10 +1,10 @@
 "path","total_size"
-"TracePacket",364911
+"TracePacket",364932
 "TracePacket.#track_event.TrackEvent",254590
-"TracePacket.#trusted_uid.int32",95254
+"TracePacket.#trusted_uid.int32",95260
 "TracePacket.#track_event.TrackEvent.#debug_annotations.DebugAnnotation.#string_value.string",73911
 "TracePacket.#timestamp.uint64",66933
-"TracePacket.#trusted_packet_sequence_id.uint32",39088
+"TracePacket.#trusted_packet_sequence_id.uint32",39091
 "TracePacket.#sequence_flags.uint32",39020
 "TracePacket.#track_event.TrackEvent.#extra_counter_values.int64",36079
 "TracePacket.#track_event.TrackEvent.#chrome_latency_info.ChromeLatencyInfo",33452
diff --git a/test/trace_processor/chrome/proto_content_path.out b/test/trace_processor/chrome/proto_content_path.out
new file mode 100644
index 0000000..adc324f
--- /dev/null
+++ b/test/trace_processor/chrome/proto_content_path.out
@@ -0,0 +1,11 @@
+"total_size","field_type","field_name","parent_id","event_category","event_name"
+137426,"TracePacket","[NULL]","[NULL]","[NULL]","[NULL]"
+59475,"TrackEvent","#track_event",415,"[NULL]","[NULL]"
+37903,"TrackEvent","#track_event",17,"[NULL]","[NULL]"
+35904,"int32","#trusted_uid",17,"[NULL]","[NULL]"
+35705,"TracePacket","[NULL]","[NULL]","input,benchmark","LatencyInfo.Flow"
+29403,"TracePacket","[NULL]","[NULL]","cc,input","[NULL]"
+24703,"ChromeLatencyInfo","#chrome_latency_info",18,"[NULL]","[NULL]"
+22620,"uint64","#time_us",26,"[NULL]","[NULL]"
+18711,"TrackEvent","#track_event",1467,"[NULL]","[NULL]"
+15606,"uint64","#timestamp",17,"[NULL]","[NULL]"
diff --git a/test/trace_processor/chrome/proto_content_path_test.sql b/test/trace_processor/chrome/proto_content_path_test.sql
new file mode 100644
index 0000000..5aafd97
--- /dev/null
+++ b/test/trace_processor/chrome/proto_content_path_test.sql
@@ -0,0 +1,23 @@
+--
+-- Copyright 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
+--
+--     https://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.
+
+SELECT content.total_size,
+  frame.field_type, frame.field_name,
+  frame.parent_id,
+  EXTRACT_ARG(frame.arg_set_id, 'event.category') AS event_category,
+  EXTRACT_ARG(frame.arg_set_id, 'event.name') AS event_name
+FROM experimental_proto_path AS frame JOIN experimental_proto_content AS content ON content.path_id = frame.id
+ORDER BY total_size DESC, path
+LIMIT 10;
diff --git a/test/trace_processor/chrome/proto_content_test.sql b/test/trace_processor/chrome/proto_content_test.sql
index 4ef9770..a0baba0 100644
--- a/test/trace_processor/chrome/proto_content_test.sql
+++ b/test/trace_processor/chrome/proto_content_test.sql
@@ -13,7 +13,8 @@
 -- See the License for the specific language governing permissions and
 -- limitations under the License.
 
-SELECT path, total_size
-FROM experimental_proto_content
+SELECT path, SUM(total_size) as total_size
+FROM experimental_proto_content as content JOIN experimental_proto_path as frame ON content.path_id = frame.id
+GROUP BY path
 ORDER BY total_size DESC, path
 LIMIT 10;
diff --git a/test/trace_processor/cros/index.py b/test/trace_processor/cros/index.py
index b18ff58..5da5d86 100644
--- a/test/trace_processor/cros/index.py
+++ b/test/trace_processor/cros/index.py
@@ -24,5 +24,17 @@
   def test_cros_ec_sensorhub_data(self):
     return DiffTestBlueprint(
         trace=Path('cros_ec_sensorhub_data.textproto'),
-        query=Path('cros_ec_sensorhub_data_test.sql'),
+        query="""
+SELECT
+  t.name,
+  c.ts,
+  c.value,
+  EXTRACT_ARG(c.arg_set_id, 'ec_num') AS ec_num,
+  EXTRACT_ARG(c.arg_set_id, 'ec_delta') AS ec_delta,
+  EXTRACT_ARG(c.arg_set_id, 'sample_ts') AS sample_ts
+FROM counter c
+JOIN track t
+  ON c.track_id = t.id
+WHERE t.name = 'cros_ec.cros_ec_sensorhub_data.0';
+""",
         out=Path('cros_ec_sensorhub_data.out'))
diff --git a/test/trace_processor/dynamic/index.py b/test/trace_processor/dynamic/index.py
index 7fc8882..bdbdb28 100644
--- a/test/trace_processor/dynamic/index.py
+++ b/test/trace_processor/dynamic/index.py
@@ -24,19 +24,33 @@
   def test_ancestor_slice(self):
     return DiffTestBlueprint(
         trace=Path('relationship_tables.textproto'),
-        query=Path('ancestor_slice_test.sql'),
+        query="""
+SELECT slice.name AS currentSliceName, ancestor.name AS ancestorSliceName
+FROM slice LEFT JOIN ancestor_slice(slice.id) AS ancestor
+ORDER BY slice.ts ASC, ancestor.ts ASC, slice.name ASC, ancestor.name ASC;
+""",
         out=Path('ancestor_slice.out'))
 
   def test_descendant_slice(self):
     return DiffTestBlueprint(
         trace=Path('relationship_tables.textproto'),
-        query=Path('descendant_slice_test.sql'),
+        query="""
+SELECT slice.name AS currentSliceName, descendant.name AS descendantSliceName
+FROM slice LEFT JOIN descendant_slice(slice.id) AS descendant
+ORDER BY slice.ts ASC, descendant.ts ASC, slice.name ASC, descendant.name ASC;
+""",
         out=Path('descendant_slice.out'))
 
   def test_ancestor_slice_by_stack(self):
     return DiffTestBlueprint(
         trace=Path('slice_stacks.textproto'),
-        query=Path('ancestor_slice_by_stack_test.sql'),
+        query="""
+SELECT ts, name FROM ancestor_slice_by_stack((
+  SELECT stack_id FROM slice
+  WHERE name = 'event_depth_2'
+  LIMIT 1
+  ));
+""",
         out=Csv("""
 "ts","name"
 1000,"event_depth_0"
@@ -48,7 +62,13 @@
   def test_descendant_slice_by_stack(self):
     return DiffTestBlueprint(
         trace=Path('slice_stacks.textproto'),
-        query=Path('descendant_slice_by_stack_test.sql'),
+        query="""
+SELECT ts, name FROM descendant_slice_by_stack((
+  SELECT stack_id FROM slice
+  WHERE name = 'event_depth_0'
+  LIMIT 1
+  ));
+""",
         out=Csv("""
 "ts","name"
 2000,"event_depth_1"
@@ -66,19 +86,38 @@
   def test_perf_sample_sc_annotated_callstack(self):
     return DiffTestBlueprint(
         trace=Path('../../data/perf_sample_sc.pb'),
-        query=Path('annotated_callstack_test.sql'),
+        query="""
+SELECT eac.id, eac.depth, eac.frame_id, eac.annotation,
+       spf.name
+FROM experimental_annotated_callstack eac
+JOIN perf_sample ps
+  ON (eac.start_id = ps.callsite_id)
+JOIN stack_profile_frame spf
+  ON (eac.frame_id = spf.id)
+ORDER BY eac.start_id ASC, eac.depth ASC;
+""",
         out=Path('perf_sample_sc_annotated_callstack.out'))
 
   def test_various_clocks_abs_time_str(self):
     return DiffTestBlueprint(
         trace=Path('various_clocks.textproto'),
-        query=Path('abs_time_str_test.sql'),
+        query="""
+SELECT
+  ABS_TIME_STR(15) AS t15,
+  ABS_TIME_STR(25) AS t25,
+  ABS_TIME_STR(35) AS t35;
+""",
         out=Path('various_clocks_abs_time_str.out'))
 
   def test_empty_abs_time_str(self):
     return DiffTestBlueprint(
         trace=Path('../common/empty.textproto'),
-        query=Path('abs_time_str_test.sql'),
+        query="""
+SELECT
+  ABS_TIME_STR(15) AS t15,
+  ABS_TIME_STR(25) AS t25,
+  ABS_TIME_STR(35) AS t35;
+""",
         out=Csv("""
 "t15","t25","t35"
 "[NULL]","[NULL]","[NULL]"
@@ -87,7 +126,12 @@
   def test_various_clocks_to_monotonic(self):
     return DiffTestBlueprint(
         trace=Path('various_clocks.textproto'),
-        query=Path('to_monotonic_test.sql'),
+        query="""
+SELECT
+  TO_MONOTONIC(25) AS t15,
+  TO_MONOTONIC(35) AS t20,
+  TO_MONOTONIC(50) AS t25;
+""",
         out=Csv("""
 "t15","t20","t25"
 15,20,25
@@ -96,7 +140,12 @@
   def test_empty_to_monotonic(self):
     return DiffTestBlueprint(
         trace=Path('../common/empty.textproto'),
-        query=Path('to_monotonic_test.sql'),
+        query="""
+SELECT
+  TO_MONOTONIC(25) AS t15,
+  TO_MONOTONIC(35) AS t20,
+  TO_MONOTONIC(50) AS t25;
+""",
         out=Csv("""
 "t15","t20","t25"
 "[NULL]","[NULL]","[NULL]"
diff --git a/test/trace_processor/fs/index.py b/test/trace_processor/fs/index.py
index b6aef30..00bf2cc 100644
--- a/test/trace_processor/fs/index.py
+++ b/test/trace_processor/fs/index.py
@@ -24,11 +24,33 @@
   def test_f2fs_iostat(self):
     return DiffTestBlueprint(
         trace=Path('f2fs_iostat.textproto'),
-        query=Path('f2fs_iostat_test.sql'),
+        query="""
+SELECT
+  name,
+  ts,
+  value
+FROM
+  counter AS c
+JOIN
+  counter_track AS ct
+  ON c.track_id = ct.id
+ORDER BY name, ts;
+""",
         out=Path('f2fs_iostat.out'))
 
   def test_f2fs_iostat_latency(self):
     return DiffTestBlueprint(
         trace=Path('f2fs_iostat_latency.textproto'),
-        query=Path('f2fs_iostat_latency_test.sql'),
+        query="""
+SELECT
+  name,
+  ts,
+  value
+FROM
+  counter AS c
+JOIN
+  counter_track AS ct
+  ON c.track_id = ct.id
+ORDER BY name, ts;
+""",
         out=Path('f2fs_iostat_latency.out'))
diff --git a/test/trace_processor/fuchsia/index.py b/test/trace_processor/fuchsia/index.py
index 941590a..c051b99 100644
--- a/test/trace_processor/fuchsia/index.py
+++ b/test/trace_processor/fuchsia/index.py
@@ -24,7 +24,19 @@
   def test_fuchsia_smoke(self):
     return DiffTestBlueprint(
         trace=Path('../../data/fuchsia_trace.fxt'),
-        query=Path('../common/smoke_test.sql'),
+        query="""
+SELECT
+  ts,
+  cpu,
+  dur,
+  end_state,
+  priority,
+  tid
+FROM sched
+JOIN thread USING(utid)
+ORDER BY ts
+LIMIT 10;
+""",
         out=Csv("""
 "ts","cpu","dur","end_state","priority","tid"
 19675868967,2,79022,"S",20,4344
@@ -42,7 +54,13 @@
   def test_fuchsia_smoke_slices(self):
     return DiffTestBlueprint(
         trace=Path('../../data/fuchsia_trace.fxt'),
-        query=Path('../common/smoke_slices_test.sql'),
+        query="""
+SELECT track.type AS type, depth, count(*) AS count
+FROM slice
+JOIN track ON slice.track_id = track.id
+GROUP BY track.type, depth
+ORDER BY track.type, depth;
+""",
         out=Csv("""
 "type","depth","count"
 "thread_track",0,2153
@@ -52,7 +70,15 @@
   def test_fuchsia_smoke_instants(self):
     return DiffTestBlueprint(
         trace=Path('../../data/fuchsia_trace.fxt'),
-        query=Path('smoke_instants_test.sql'),
+        query="""
+SELECT
+  ts,
+  name
+FROM slice
+WHERE
+  dur = 0
+LIMIT 10;
+""",
         out=Csv("""
 "ts","name"
 21442756010,"task_start"
@@ -70,7 +96,14 @@
   def test_fuchsia_smoke_counters(self):
     return DiffTestBlueprint(
         trace=Path('../../data/fuchsia_trace.fxt'),
-        query=Path('smoke_counters_test.sql'),
+        query="""
+SELECT
+  ts,
+  value,
+  name
+FROM counters
+LIMIT 10;
+""",
         out=Csv("""
 "ts","value","name"
 20329439768,30.331177,"cpu_usage:average_cpu_percentage"
@@ -83,7 +116,14 @@
   def test_fuchsia_smoke_flow(self):
     return DiffTestBlueprint(
         trace=Path('../../data/fuchsia_trace.fxt'),
-        query=Path('smoke_flow_test.sql'),
+        query="""
+SELECT
+  id,
+  slice_out,
+  slice_in
+FROM flow
+LIMIT 10;
+""",
         out=Csv("""
 "id","slice_out","slice_in"
 0,0,1
@@ -101,7 +141,14 @@
   def test_fuchsia_smoke_type(self):
     return DiffTestBlueprint(
         trace=Path('../../data/fuchsia_trace.fxt'),
-        query=Path('smoke_type_test.sql'),
+        query="""
+SELECT
+  id,
+  name,
+  type
+FROM track
+LIMIT 10;
+""",
         out=Csv("""
 "id","name","type"
 0,"[NULL]","thread_track"
@@ -119,13 +166,26 @@
   def test_fuchsia_workstation_smoke_slices(self):
     return DiffTestBlueprint(
         trace=Path('../../data/fuchsia_workstation.fxt'),
-        query=Path('../common/smoke_slices_test.sql'),
+        query="""
+SELECT track.type AS type, depth, count(*) AS count
+FROM slice
+JOIN track ON slice.track_id = track.id
+GROUP BY track.type, depth
+ORDER BY track.type, depth;
+""",
         out=Path('fuchsia_workstation_smoke_slices.out'))
 
   def test_fuchsia_workstation_smoke_args(self):
     return DiffTestBlueprint(
         trace=Path('../../data/fuchsia_workstation.fxt'),
-        query=Path('smoke_args_test.sql'),
+        query="""
+SELECT
+  key,
+  COUNT(*)
+FROM args
+GROUP BY key
+LIMIT 10;
+""",
         out=Csv("""
 "key","COUNT(*)"
 "Dart Arguments",3
diff --git a/test/trace_processor/functions/index.py b/test/trace_processor/functions/index.py
index 89f8281..2f7f1d2 100644
--- a/test/trace_processor/functions/index.py
+++ b/test/trace_processor/functions/index.py
@@ -24,7 +24,19 @@
   def test_first_non_null_frame(self):
     return DiffTestBlueprint(
         trace=Path('../common/empty.textproto'),
-        query=Path('first_non_null_frame_test.sql'),
+        query="""
+CREATE TABLE TEST(id INTEGER, val INTEGER);
+
+INSERT INTO TEST
+VALUES (1, 1), (2, NULL), (3, 3), (4, 4), (5, NULL), (6, NULL), (7, NULL);
+
+SELECT
+  id,
+  LAST_NON_NULL(val)
+  OVER (ORDER BY id ASC ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING) AS val
+FROM TEST
+ORDER BY id ASC;
+""",
         out=Csv("""
 "id","val"
 1,3
@@ -39,7 +51,23 @@
   def test_first_non_null_partition(self):
     return DiffTestBlueprint(
         trace=Path('../common/empty.textproto'),
-        query=Path('first_non_null_partition_test.sql'),
+        query="""
+CREATE TABLE TEST(id INTEGER, part TEXT, val INTEGER);
+
+INSERT INTO TEST
+VALUES
+(1, 'A', 1),
+(2, 'A', NULL),
+(3, 'A', 3),
+(4, 'B', NULL),
+(5, 'B', 5),
+(6, 'B', NULL),
+(7, 'B', 7);
+
+SELECT id, LAST_NON_NULL(val) OVER (PARTITION BY part ORDER BY id ASC) AS val
+FROM TEST
+ORDER BY id ASC;
+""",
         out=Csv("""
 "id","val"
 1,1
@@ -54,7 +82,16 @@
   def test_first_non_null(self):
     return DiffTestBlueprint(
         trace=Path('../common/empty.textproto'),
-        query=Path('first_non_null_test.sql'),
+        query="""
+CREATE TABLE TEST(id INTEGER, val INTEGER);
+
+INSERT INTO TEST
+VALUES (1, 1), (2, NULL), (3, 3), (4, 4), (5, NULL), (6, NULL), (7, NULL);
+
+SELECT id, LAST_NON_NULL(val) OVER (ORDER BY id ASC) AS val
+FROM TEST
+ORDER BY id ASC;
+""",
         out=Csv("""
 "id","val"
 1,1
diff --git a/test/trace_processor/graphics/index.py b/test/trace_processor/graphics/index.py
index 12d25a6..38e21d2 100644
--- a/test/trace_processor/graphics/index.py
+++ b/test/trace_processor/graphics/index.py
@@ -24,7 +24,13 @@
   def test_gpu_counters(self):
     return DiffTestBlueprint(
         trace=Path('gpu_counters.py'),
-        query=Path('gpu_counters_test.sql'),
+        query="""
+SELECT "ts", "value", "name", "gpu_id", "description", "unit"
+FROM counter
+JOIN gpu_counter_track
+  ON counter.track_id = gpu_counter_track.id
+ORDER BY "ts";
+""",
         out=Csv("""
 "ts","value","name","gpu_id","description","unit"
 11,5.000000,"Vertex / Second",0,"Number of vertices per second","25/22"
@@ -41,7 +47,12 @@
   def test_gpu_counter_specs(self):
     return DiffTestBlueprint(
         trace=Path('gpu_counter_specs.textproto'),
-        query=Path('gpu_counter_specs_test.sql'),
+        query="""
+SELECT group_id, c.name, c.description, unit
+FROM gpu_counter_group AS g
+JOIN gpu_counter_track AS c
+  ON g.track_id = c.id;
+""",
         out=Csv("""
 "group_id","name","description","unit"
 0,"GPU Frequency","clock speed","/22"
@@ -66,13 +77,30 @@
   def test_vulkan_api_events(self):
     return DiffTestBlueprint(
         trace=Path('vulkan_api_events.py'),
-        query=Path('vulkan_api_events_test.sql'),
+        query="""
+SELECT track.name AS track_name, gpu_track.description AS track_desc, ts, dur,
+  gpu_slice.name AS slice_name, depth, flat_key, int_value,
+  gpu_slice.context_id, command_buffer, submission_id
+FROM gpu_track
+LEFT JOIN track USING (id)
+JOIN gpu_slice ON gpu_track.id = gpu_slice.track_id
+LEFT JOIN args ON gpu_slice.arg_set_id = args.arg_set_id
+ORDER BY ts;
+""",
         out=Path('vulkan_api_events.out'))
 
   def test_gpu_log(self):
     return DiffTestBlueprint(
         trace=Path('gpu_log.py'),
-        query=Path('gpu_log_test.sql'),
+        query="""
+SELECT scope, track.name AS track_name, ts, dur, gpu_slice.name AS slice_name,
+  key, string_value AS value
+FROM gpu_track
+LEFT JOIN track USING (id)
+LEFT JOIN gpu_slice ON gpu_track.id = gpu_slice.track_id
+LEFT JOIN args USING (arg_set_id)
+ORDER BY ts, slice_name, key;
+""",
         out=Csv("""
 "scope","track_name","ts","dur","slice_name","key","value"
 "gpu_log","GPU Log",1,0,"VERBOSE","message","message0"
@@ -92,7 +120,14 @@
   def test_graphics_frame_events(self):
     return DiffTestBlueprint(
         trace=Path('graphics_frame_events.py'),
-        query=Path('graphics_frame_events_test.sql'),
+        query="""
+SELECT ts, gpu_track.name AS track_name, dur, frame_slice.name AS slice_name,
+  frame_number, layer_name
+FROM gpu_track
+LEFT JOIN frame_slice ON gpu_track.id = frame_slice.track_id
+WHERE scope = 'graphics_frame_event'
+ORDER BY ts;
+""",
         out=Path('graphics_frame_events.out'))
 
   def test_gpu_mem_total(self):
@@ -123,7 +158,11 @@
   def test_clock_sync(self):
     return DiffTestBlueprint(
         trace=Path('clock_sync.py'),
-        query=Path('clock_sync_test.sql'),
+        query="""
+SELECT ts, cast(value AS integer) AS int_value
+FROM counters
+WHERE name GLOB 'gpu_counter*';
+""",
         out=Csv("""
 "ts","int_value"
 1,3
@@ -140,7 +179,12 @@
   def test_frame_missed_event_frame_missed(self):
     return DiffTestBlueprint(
         trace=Path('frame_missed.py'),
-        query=Path('frame_missed_event_test.sql'),
+        query="""
+SELECT RUN_METRIC('android/android_surfaceflinger.sql');
+
+SELECT ts, dur
+FROM android_surfaceflinger_event;
+""",
         out=Csv("""
 "ts","dur"
 100,1
@@ -181,7 +225,25 @@
     return DiffTestBlueprint(
         trace=Path('gpu_metric.py'),
         query=Metric('android_gpu'),
-        out=Path('gpu_metric.out'))
+        out=TextProto(r"""
+android_gpu {
+  processes {
+    name: "app_1"
+    mem_max: 8
+    mem_min: 2
+    mem_avg: 3
+  }
+  processes {
+    name: "app_2"
+    mem_max: 10
+    mem_min: 6
+    mem_avg: 8
+  }
+  mem_max: 4
+  mem_min: 1
+  mem_avg: 2
+}
+"""))
 
   def test_gpu_frequency_metric(self):
     return DiffTestBlueprint(
@@ -230,7 +292,12 @@
   def test_composition_layer_count(self):
     return DiffTestBlueprint(
         trace=Path('composition_layer.py'),
-        query=Path('composition_layer_count_test.sql'),
+        query="""
+SELECT RUN_METRIC('android/android_hwcomposer.sql');
+
+SELECT AVG(value)
+FROM total_layers;
+""",
         out=Csv("""
 "AVG(value)"
 3.000000
@@ -245,7 +312,18 @@
   def test_composer_execution(self):
     return DiffTestBlueprint(
         trace=Path('composer_execution.py'),
-        query=Path('composer_execution_test.sql'),
+        query="""
+SELECT RUN_METRIC('android/composer_execution.sql',
+  'output', 'hwc_execution_spans');
+
+SELECT
+  validation_type,
+  COUNT(*) AS count,
+  SUM(execution_time_ns) AS total
+FROM hwc_execution_spans
+GROUP BY validation_type
+ORDER BY validation_type;
+""",
         out=Csv("""
 "validation_type","count","total"
 "separated_validation",1,200
@@ -257,18 +335,80 @@
     return DiffTestBlueprint(
         trace=Path('display_metrics.py'),
         query=Metric('display_metrics'),
-        out=Path('display_metrics.out'))
+        out=TextProto(r"""
+display_metrics {
+  total_duplicate_frames: 0
+  duplicate_frames_logged: 0
+  total_dpu_underrun_count: 0
+  refresh_rate_switches: 5
+  refresh_rate_stats {
+    refresh_rate_fps: 60
+    count: 2
+    total_dur_ms: 2
+    avg_dur_ms: 1
+  }
+  refresh_rate_stats {
+    refresh_rate_fps: 90
+    count: 2
+    total_dur_ms: 2
+    avg_dur_ms: 1
+  }
+  refresh_rate_stats {
+    refresh_rate_fps: 120
+    count: 1
+    total_dur_ms: 2
+    avg_dur_ms: 2
+  }
+  update_power_state {
+    avg_runtime_micro_secs: 4000
+  }
+}
+"""))
 
   def test_dpu_vote_clock_bw(self):
     return DiffTestBlueprint(
         trace=Path('dpu_vote_clock_bw.textproto'),
         query=Metric('android_hwcomposer'),
-        out=Path('dpu_vote_clock_bw.out'))
+        out=TextProto(r"""
+android_hwcomposer {
+  skipped_validation_count: 0
+  unskipped_validation_count: 0
+  separated_validation_count: 0
+  unknown_validation_count: 0
+  dpu_vote_metrics {
+    tid: 237
+    avg_dpu_vote_clock: 206250
+    avg_dpu_vote_avg_bw: 210000
+    avg_dpu_vote_peak_bw: 205000
+    avg_dpu_vote_rt_bw: 271000
+  }
+  dpu_vote_metrics {
+    tid: 299
+    avg_dpu_vote_clock: 250000
+  }
+}
+"""))
 
   def test_drm_vblank_gpu_track(self):
     return DiffTestBlueprint(
         trace=Path('drm_vblank.textproto'),
-        query=Path('drm_gpu_track_test.sql'),
+        query="""
+SELECT
+  gpu_track.name,
+  ts,
+  dur,
+  slice.name,
+  flat_key,
+  int_value,
+  string_value
+FROM
+  gpu_track
+JOIN slice
+  ON slice.track_id = gpu_track.id
+JOIN args
+  ON slice.arg_set_id = args.arg_set_id
+ORDER BY ts;
+""",
         out=Csv("""
 "name","ts","dur","name","flat_key","int_value","string_value"
 "vblank-0",6159770881976,0,"signal","vblank seqno",3551,"[NULL]"
@@ -278,7 +418,23 @@
   def test_drm_sched_gpu_track(self):
     return DiffTestBlueprint(
         trace=Path('drm_sched.textproto'),
-        query=Path('drm_gpu_track_test.sql'),
+        query="""
+SELECT
+  gpu_track.name,
+  ts,
+  dur,
+  slice.name,
+  flat_key,
+  int_value,
+  string_value
+FROM
+  gpu_track
+JOIN slice
+  ON slice.track_id = gpu_track.id
+JOIN args
+  ON slice.arg_set_id = args.arg_set_id
+ORDER BY ts;
+""",
         out=Csv("""
 "name","ts","dur","name","flat_key","int_value","string_value"
 "sched-ring0",9246165349383,4729073,"job","gpu sched job",13481,"[NULL]"
@@ -290,7 +446,23 @@
   def test_drm_sched_thread_track(self):
     return DiffTestBlueprint(
         trace=Path('drm_sched.textproto'),
-        query=Path('drm_thread_track_test.sql'),
+        query="""
+SELECT
+  utid,
+  ts,
+  dur,
+  slice.name,
+  flat_key,
+  int_value,
+  string_value
+FROM
+  thread_track
+JOIN slice
+  ON slice.track_id = thread_track.id
+JOIN args
+  ON slice.arg_set_id = args.arg_set_id
+ORDER BY ts;
+""",
         out=Csv("""
 "utid","ts","dur","name","flat_key","int_value","string_value"
 1,9246165326050,0,"drm_sched_job","gpu sched ring","[NULL]","ring0"
@@ -306,7 +478,23 @@
   def test_drm_dma_fence_gpu_track(self):
     return DiffTestBlueprint(
         trace=Path('drm_dma_fence.textproto'),
-        query=Path('drm_gpu_track_test.sql'),
+        query="""
+SELECT
+  gpu_track.name,
+  ts,
+  dur,
+  slice.name,
+  flat_key,
+  int_value,
+  string_value
+FROM
+  gpu_track
+JOIN slice
+  ON slice.track_id = gpu_track.id
+JOIN args
+  ON slice.arg_set_id = args.arg_set_id
+ORDER BY ts;
+""",
         out=Csv("""
 "name","ts","dur","name","flat_key","int_value","string_value"
 "fence-gpu-ring-0-1",11303602488073,12813,"fence","fence seqno",16665,"[NULL]"
@@ -318,7 +506,23 @@
   def test_drm_dma_fence_thread_track(self):
     return DiffTestBlueprint(
         trace=Path('drm_dma_fence.textproto'),
-        query=Path('drm_thread_track_test.sql'),
+        query="""
+SELECT
+  utid,
+  ts,
+  dur,
+  slice.name,
+  flat_key,
+  int_value,
+  string_value
+FROM
+  thread_track
+JOIN slice
+  ON slice.track_id = thread_track.id
+JOIN args
+  ON slice.arg_set_id = args.arg_set_id
+ORDER BY ts;
+""",
         out=Csv("""
 "utid","ts","dur","name","flat_key","int_value","string_value"
 3,11303702851231,4867658,"dma_fence_wait","fence context",9,"[NULL]"
@@ -328,7 +532,11 @@
   def test_v4l2_vidioc_slice(self):
     return DiffTestBlueprint(
         trace=Path('v4l2_vidioc.textproto'),
-        query=Path('v4l2_vidioc_slice_test.sql'),
+        query="""
+SELECT ts, dur, name
+FROM slice
+WHERE category = 'Video 4 Linux 2';
+""",
         out=Csv("""
 "ts","dur","name"
 593268475912,0,"VIDIOC_QBUF minor=0 seq=0 type=9 index=19"
@@ -340,13 +548,22 @@
   def test_v4l2_vidioc_flow(self):
     return DiffTestBlueprint(
         trace=Path('v4l2_vidioc.textproto'),
-        query=Path('v4l2_vidioc_flow_test.sql'),
+        query="""
+SELECT qbuf.ts, qbuf.dur, qbuf.name, dqbuf.ts, dqbuf.dur, dqbuf.name
+FROM flow
+JOIN slice qbuf ON flow.slice_out = qbuf.id
+JOIN slice dqbuf ON flow.slice_in = dqbuf.id;
+""",
         out=Path('v4l2_vidioc_flow.out'))
 
   def test_virtio_video_slice(self):
     return DiffTestBlueprint(
         trace=Path('virtio_video.textproto'),
-        query=Path('virtio_video_slice_test.sql'),
+        query="""
+SELECT slice.ts, slice.dur, slice.name, track.name
+FROM slice
+JOIN track ON slice.track_id = track.id;
+""",
         out=Csv("""
 "ts","dur","name","name"
 593125003271,84500592,"Resource #102","virtio_video stream #4 OUTPUT"
@@ -360,7 +577,15 @@
   def test_virtio_gpu_test(self):
     return DiffTestBlueprint(
         trace=Path('virtio_gpu.textproto'),
-        query=Path('virtio_gpu_test.sql'),
+        query="""
+SELECT
+  ts,
+  dur,
+  name
+FROM
+  slice
+ORDER BY ts;
+""",
         out=Csv("""
 "ts","dur","name"
 1345090723759,1180312,"SUBMIT_3D"
@@ -370,7 +595,9 @@
   def test_mali_test(self):
     return DiffTestBlueprint(
         trace=Path('mali.textproto'),
-        query=Path('mali_test.sql'),
+        query="""
+SELECT ts, dur, name FROM slice WHERE name GLOB "mali_KCPU_CQS*";
+""",
         out=Csv("""
 "ts","dur","name"
 751796307210,4313965,"mali_KCPU_CQS_WAIT"
@@ -380,7 +607,9 @@
   def test_mali_fence_test(self):
     return DiffTestBlueprint(
         trace=Path('mali_fence.textproto'),
-        query=Path('mali_fence_test.sql'),
+        query="""
+SELECT ts, dur, name FROM slice WHERE name GLOB "mali_KCPU_FENCE*";
+""",
         out=Csv("""
 "ts","dur","name"
 751796307210,4313965,"mali_KCPU_FENCE_WAIT"
diff --git a/test/trace_processor/memory/index.py b/test/trace_processor/memory/index.py
index 7c41575..68ff601 100644
--- a/test/trace_processor/memory/index.py
+++ b/test/trace_processor/memory/index.py
@@ -88,7 +88,24 @@
     return DiffTestBlueprint(
         trace=Path('android_ion.py'),
         query=Metric('android_ion'),
-        out=Path('android_ion.out'))
+        out=TextProto(r"""
+android_ion {
+  buffer {
+    name: "adsp"
+    avg_size_bytes: 1000.0
+    min_size_bytes: 1000.0
+    max_size_bytes: 1100.0
+    total_alloc_size_bytes: 1100.0
+  }
+  buffer {
+    name: "system"
+    avg_size_bytes: 1497.4874371859296
+    min_size_bytes: 1000.0
+    max_size_bytes: 2000.0
+    total_alloc_size_bytes: 2000.0
+  }
+}
+"""))
 
   def test_android_ion_stat(self):
     return DiffTestBlueprint(
@@ -121,7 +138,11 @@
   def test_android_dma_buffer_tracks(self):
     return DiffTestBlueprint(
         trace=Path('android_dma_heap_stat.textproto'),
-        query=Path('dma_buffer_tracks_test.sql'),
+        query="""
+SELECT track.name, slice.ts, slice.dur, slice.name
+FROM slice JOIN track ON slice.track_id = track.id
+WHERE track.name = 'mem.dma_buffer';
+""",
         out=Csv("""
 "name","ts","dur","name"
 "mem.dma_buffer",100,100,"1 kB"
@@ -146,7 +167,9 @@
   def test_shrink_slab(self):
     return DiffTestBlueprint(
         trace=Path('shrink_slab.textproto'),
-        query=Path('shrink_slab_test.sql'),
+        query="""
+SELECT ts, dur, name FROM slice WHERE name = 'mm_vmscan_shrink_slab';
+""",
         out=Csv("""
 "ts","dur","name"
 36448185787847,692,"mm_vmscan_shrink_slab"
@@ -155,7 +178,9 @@
   def test_cma(self):
     return DiffTestBlueprint(
         trace=Path('cma.textproto'),
-        query=Path('cma_test.sql'),
+        query="""
+SELECT ts, dur, name FROM slice WHERE name = 'mm_cma_alloc';
+""",
         out=Csv("""
 "ts","dur","name"
 74288080958099,110151652,"mm_cma_alloc"
diff --git a/test/trace_processor/network/index.py b/test/trace_processor/network/index.py
index c63d620..73fe879 100644
--- a/test/trace_processor/network/index.py
+++ b/test/trace_processor/network/index.py
@@ -24,7 +24,21 @@
   def test_netif_receive_skb(self):
     return DiffTestBlueprint(
         trace=Path('netif_receive_skb.textproto'),
-        query=Path('netif_receive_skb_test.sql'),
+        query="""
+SELECT
+  ts,
+  REPLACE(name, " Received KB", "") AS dev,
+  EXTRACT_ARG(arg_set_id, 'cpu') AS cpu,
+  EXTRACT_ARG(arg_set_id, 'len') AS len
+FROM
+  counter AS c
+LEFT JOIN
+  counter_track AS t
+  ON c.track_id = t.id
+WHERE
+  name GLOB "* Received KB"
+ORDER BY ts;
+""",
         out=Csv("""
 "ts","dev","cpu","len"
 10000,"rmnet0",0,1000
@@ -37,7 +51,21 @@
   def test_net_dev_xmit(self):
     return DiffTestBlueprint(
         trace=Path('net_dev_xmit.textproto'),
-        query=Path('net_dev_xmit_test.sql'),
+        query="""
+SELECT
+  ts,
+  REPLACE(name, " Transmitted KB", "") AS dev,
+  EXTRACT_ARG(arg_set_id, 'cpu') AS cpu,
+  EXTRACT_ARG(arg_set_id, 'len') AS len
+FROM
+  counter AS c
+LEFT JOIN
+  counter_track AS t
+  ON c.track_id = t.id
+WHERE
+  name GLOB "* Transmitted KB"
+ORDER BY ts;
+""",
         out=Csv("""
 "ts","dev","cpu","len"
 10000,"rmnet0",0,1000
@@ -55,7 +83,20 @@
   def test_inet_sock_set_state(self):
     return DiffTestBlueprint(
         trace=Path('inet_sock_set_state.textproto'),
-        query=Path('inet_sock_set_state_test.sql'),
+        query="""
+SELECT
+  ts,
+  s.name,
+  dur,
+  t.name
+FROM
+  slice AS s
+LEFT JOIN track AS t
+  ON s.track_id = t.id
+WHERE
+  t.name GLOB "TCP stream#*"
+ORDER BY ts;
+""",
         out=Csv("""
 "ts","name","dur","name"
 10000000,"TCP_SYN_SENT(pid=123)",100000000,"TCP stream#1"
@@ -69,7 +110,19 @@
   def test_tcp_retransmit_skb(self):
     return DiffTestBlueprint(
         trace=Path('tcp_retransmit_skb.textproto'),
-        query=Path('tcp_retransmit_skb_test.sql'),
+        query="""
+SELECT
+  ts,
+  s.name,
+  dur
+FROM
+  slice AS s
+LEFT JOIN track AS t
+  ON s.track_id = t.id
+WHERE
+  t.name = "TCP Retransmit Skb"
+ORDER BY ts;
+""",
         out=Csv("""
 "ts","name","dur"
 110000000,"sport=56789,dport=5001",0
@@ -79,7 +132,24 @@
   def test_napi_gro_receive(self):
     return DiffTestBlueprint(
         trace=Path('napi_gro_receive.textproto'),
-        query=Path('napi_gro_receive_test.sql'),
+        query="""
+SELECT
+  ts,
+  s.name,
+  dur,
+  cat,
+  t.name,
+  EXTRACT_ARG(arg_set_id, 'ret') AS ret,
+  EXTRACT_ARG(arg_set_id, 'len') AS len
+FROM
+  slice AS s
+LEFT JOIN
+  track AS t
+  ON s.track_id = t.id
+WHERE
+  t.name GLOB "Napi Gro Cpu *"
+ORDER BY ts;
+""",
         out=Csv("""
 "ts","name","dur","cat","name","ret","len"
 10000,"rmnet0",20,"napi_gro","Napi Gro Cpu 2",2,1000
@@ -90,7 +160,20 @@
   def test_kfree_skb(self):
     return DiffTestBlueprint(
         trace=Path('kfree_skb.textproto'),
-        query=Path('kfree_skb_test.sql'),
+        query="""
+SELECT
+  ts,
+  value,
+  EXTRACT_ARG(arg_set_id, 'protocol') AS prot
+FROM
+  counter AS c
+LEFT JOIN
+  counter_track AS t
+  ON c.track_id = t.id
+WHERE
+  name GLOB "Kfree Skb IP Prot"
+ORDER BY ts;
+""",
         out=Csv("""
 "ts","value","prot"
 10000,1.000000,"IP"
diff --git a/test/trace_processor/parsing/index.py b/test/trace_processor/parsing/index.py
index 604f457..e308c58 100644
--- a/test/trace_processor/parsing/index.py
+++ b/test/trace_processor/parsing/index.py
@@ -24,7 +24,14 @@
   def test_ts_desc_filter_android_sched_and_ps(self):
     return DiffTestBlueprint(
         trace=Path('../../data/android_sched_and_ps.pb'),
-        query=Path('ts_desc_filter_test.sql'),
+        query="""
+SELECT ts
+FROM sched
+JOIN thread USING(utid)
+WHERE tid = 23850
+ORDER BY ts DESC
+LIMIT 10;
+""",
         out=Csv("""
 "ts"
 81492536383477
@@ -42,7 +49,12 @@
   def test_android_sched_and_ps_end_reason_eq(self):
     return DiffTestBlueprint(
         trace=Path('../../data/android_sched_and_ps.pb'),
-        query=Path('end_reason_eq_test.sql'),
+        query="""
+SELECT end_state, count(*)
+FROM sched
+WHERE end_state = 'D'
+GROUP BY end_state;
+""",
         out=Csv("""
 "end_state","count(*)"
 "D",10503
@@ -51,7 +63,12 @@
   def test_android_sched_and_ps_end_reason_neq(self):
     return DiffTestBlueprint(
         trace=Path('../../data/android_sched_and_ps.pb'),
-        query=Path('end_reason_neq_test.sql'),
+        query="""
+SELECT end_state, count(*)
+FROM sched
+WHERE end_state != 'D'
+GROUP BY end_state;
+""",
         out=Csv("""
 "end_state","count(*)"
 "DK",30
@@ -70,7 +87,12 @@
   def test_ftrace_with_tracing_start_list_sched_slice_spans(self):
     return DiffTestBlueprint(
         trace=Path('ftrace_with_tracing_start.py'),
-        query=Path('list_sched_slice_spans_test.sql'),
+        query="""
+SELECT ts, dur, tid
+FROM sched
+JOIN thread USING(utid)
+ORDER BY ts;
+""",
         out=Csv("""
 "ts","dur","tid"
 100,10,1
@@ -80,7 +102,13 @@
   def test_rss_stat_mm_id(self):
     return DiffTestBlueprint(
         trace=Path('rss_stat_mm_id.py'),
-        query=Path('rss_stat_test.sql'),
+        query="""
+SELECT c.ts, t.name, p.pid, p.name, c.value
+FROM counter c
+JOIN process_counter_track t ON c.track_id = t.id
+JOIN process p USING (upid)
+ORDER BY ts, pid;
+""",
         out=Csv("""
 "ts","name","pid","name","value"
 90,"mem.rss.file",3,"kthreadd_child",9.000000
@@ -92,7 +120,13 @@
   def test_rss_stat_mm_id_clone(self):
     return DiffTestBlueprint(
         trace=Path('rss_stat_mm_id_clone.py'),
-        query=Path('rss_stat_test.sql'),
+        query="""
+SELECT c.ts, t.name, p.pid, p.name, c.value
+FROM counter c
+JOIN process_counter_track t ON c.track_id = t.id
+JOIN process p USING (upid)
+ORDER BY ts, pid;
+""",
         out=Csv("""
 "ts","name","pid","name","value"
 100,"mem.rss.file",3,"kernel_thread",10.000000
@@ -108,7 +142,13 @@
   def test_rss_stat_mm_id_reuse(self):
     return DiffTestBlueprint(
         trace=Path('rss_stat_mm_id_reuse.py'),
-        query=Path('rss_stat_test.sql'),
+        query="""
+SELECT c.ts, t.name, p.pid, p.name, c.value
+FROM counter c
+JOIN process_counter_track t ON c.track_id = t.id
+JOIN process p USING (upid)
+ORDER BY ts, pid;
+""",
         out=Csv("""
 "ts","name","pid","name","value"
 100,"mem.rss.file",10,"parent_process",100.000000
@@ -118,7 +158,13 @@
   def test_rss_stat_legacy(self):
     return DiffTestBlueprint(
         trace=Path('rss_stat_legacy.py'),
-        query=Path('rss_stat_test.sql'),
+        query="""
+SELECT c.ts, t.name, p.pid, p.name, c.value
+FROM counter c
+JOIN process_counter_track t ON c.track_id = t.id
+JOIN process p USING (upid)
+ORDER BY ts, pid;
+""",
         out=Csv("""
 "ts","name","pid","name","value"
 90,"mem.rss.file",3,"kthreadd_child",9.000000
@@ -131,7 +177,16 @@
   def test_rss_stat_after_free(self):
     return DiffTestBlueprint(
         trace=Path('rss_stat_after_free.py'),
-        query=Path('rss_stat_after_free_test.sql'),
+        query="""
+SELECT
+  pid,
+  max(c.ts) AS last_rss,
+  p.end_ts AS process_end
+FROM counter c
+JOIN process_counter_track t ON c.track_id = t.id
+JOIN process p USING(upid)
+GROUP BY upid;
+""",
         out=Csv("""
 "pid","last_rss","process_end"
 10,100,101
@@ -149,7 +204,12 @@
   def test_memory_counters_args_string_is_null(self):
     return DiffTestBlueprint(
         trace=Path('../../data/memory_counters.pb'),
-        query=Path('args_string_is_null_test.sql'),
+        query="""
+SELECT string_value
+FROM args
+WHERE string_value IS NULL
+LIMIT 10;
+""",
         out=Csv("""
 "string_value"
 "[NULL]"
@@ -167,7 +227,12 @@
   def test_memory_counters_args_string_is_not_null(self):
     return DiffTestBlueprint(
         trace=Path('../../data/memory_counters.pb'),
-        query=Path('args_string_is_not_null_test.sql'),
+        query="""
+SELECT string_value
+FROM args
+WHERE string_value IS NOT NULL
+LIMIT 10;
+""",
         out=Csv("""
 "string_value"
 "traced_probes"
@@ -185,7 +250,11 @@
   def test_memory_counters_b120605557(self):
     return DiffTestBlueprint(
         trace=Path('../../data/memory_counters.pb'),
-        query=Path('b120605557_test.sql'),
+        query="""
+SELECT count(*)
+FROM counter
+JOIN counter_track ON counter_track.id = counter.track_id;
+""",
         out=Csv("""
 "count(*)"
 98688
@@ -194,7 +263,13 @@
   def test_global_memory_counter_memory_counters(self):
     return DiffTestBlueprint(
         trace=Path('../../data/memory_counters.pb'),
-        query=Path('global_memory_counter_test.sql'),
+        query="""
+SELECT ts, value, name
+FROM counter
+JOIN counter_track ON counter.track_id = counter_track.id
+WHERE name = 'MemAvailable' AND counter_track.type = 'counter_track'
+LIMIT 10;
+""",
         out=Csv("""
 "ts","value","name"
 22240334823167,2696392704.000000,"MemAvailable"
@@ -212,7 +287,12 @@
   def test_ion_stat(self):
     return DiffTestBlueprint(
         trace=Path('ion_stat.textproto'),
-        query=Path('ion_stat_test.sql'),
+        query="""
+SELECT t.name, c.ts, c.value
+FROM counter c
+JOIN track t ON c.track_id = t.id
+WHERE t.name GLOB 'mem.ion*';
+""",
         out=Csv("""
 "name","ts","value"
 "mem.ion",1234,200.000000
@@ -222,13 +302,21 @@
   def test_sched_slices_sched_switch_original(self):
     return DiffTestBlueprint(
         trace=Path('../../data/sched_switch_original.pb'),
-        query=Path('sched_slices_test.sql'),
+        query="""
+SELECT ts, cpu, dur, ts_end, end_state, priority, tid, name
+FROM sched JOIN thread ON sched.utid = thread.utid
+ORDER BY cpu, sched.ts ASC;
+""",
         out=Path('sched_slices_sched_switch_original.out'))
 
   def test_sched_slices_sched_switch_compact(self):
     return DiffTestBlueprint(
         trace=Path('../../data/sched_switch_compact.pb'),
-        query=Path('sched_slices_test.sql'),
+        query="""
+SELECT ts, cpu, dur, ts_end, end_state, priority, tid, name
+FROM sched JOIN thread ON sched.utid = thread.utid
+ORDER BY cpu, sched.ts ASC;
+""",
         out=Path('sched_slices_sched_switch_compact.out'))
 
   def test_sched_waking_raw_compact_sched(self):
@@ -240,25 +328,48 @@
   def test_sched_waking_instants_compact_sched(self):
     return DiffTestBlueprint(
         trace=Path('../../data/compact_sched.pb'),
-        query=Path('sched_waking_instants_test.sql'),
+        query="""
+SELECT ts, thread.name, thread.tid
+FROM thread_state
+JOIN thread USING (utid)
+WHERE state = 'R'
+ORDER BY ts;
+""",
         out=Path('sched_waking_instants_compact_sched.out'))
 
   def test_mm_event(self):
     return DiffTestBlueprint(
         trace=Path('../../data/mm_event.pb'),
-        query=Path('mm_event_test.sql'),
+        query="""
+SELECT ts, name, value
+FROM counter
+JOIN counter_track
+  ON counter.track_id = counter_track.id
+WHERE name GLOB 'mem.mm.*'
+ORDER BY ts
+LIMIT 40;
+""",
         out=Path('mm_event.out'))
 
   def test_print_systrace_lmk_userspace(self):
     return DiffTestBlueprint(
         trace=Path('../../data/lmk_userspace.pb'),
-        query=Path('print_systrace_test.sql'),
+        query="""
+SELECT to_ftrace(id)
+FROM raw;
+""",
         out=Path('print_systrace_lmk_userspace.out'))
 
   def test_kernel_tmw_counter_process_counter_and_track(self):
     return DiffTestBlueprint(
         trace=Path('kernel_tmw_counter.textproto'),
-        query=Path('process_counter_and_track_test.sql'),
+        query="""
+SELECT ts, pct.name, value, pid
+FROM counter c
+JOIN process_counter_track pct ON c.track_id = pct.id
+JOIN process USING (upid)
+ORDER BY ts;
+""",
         out=Csv("""
 "ts","name","value","pid"
 795572805481,"g2d_frame_hw#15",0.000000,237
@@ -273,7 +384,13 @@
   def test_kernel_dpu_tmw_counter_process_counter_and_track(self):
     return DiffTestBlueprint(
         trace=Path('kernel_dpu_tmw_counter.textproto'),
-        query=Path('process_counter_and_track_test.sql'),
+        query="""
+SELECT ts, pct.name, value, pid
+FROM counter c
+JOIN process_counter_track pct ON c.track_id = pct.id
+JOIN process USING (upid)
+ORDER BY ts;
+""",
         out=Csv("""
 "ts","name","value","pid"
 795572805481,"dpu_vote_clock",123.000000,237
@@ -285,31 +402,48 @@
   def test_print_systrace_unsigned(self):
     return DiffTestBlueprint(
         trace=Path('print_systrace_unsigned.py'),
-        query=Path('print_systrace_test.sql'),
+        query="""
+SELECT to_ftrace(id)
+FROM raw;
+""",
         out=Path('print_systrace_unsigned.out'))
 
   def test_cgroup_attach_task_pre_s_print_systrace(self):
     return DiffTestBlueprint(
         trace=Path('cgroup_attach_task_pre_s.textproto'),
-        query=Path('print_systrace_test.sql'),
+        query="""
+SELECT to_ftrace(id)
+FROM raw;
+""",
         out=Path('cgroup_attach_task_pre_s_print_systrace.out'))
 
   def test_cgroup_attach_task_post_s_print_systrace(self):
     return DiffTestBlueprint(
         trace=Path('cgroup_attach_task_post_s.textproto'),
-        query=Path('print_systrace_test.sql'),
+        query="""
+SELECT to_ftrace(id)
+FROM raw;
+""",
         out=Path('cgroup_attach_task_post_s_print_systrace.out'))
 
   def test_systrace_html(self):
     return DiffTestBlueprint(
         trace=Path('../../data/systrace.html'),
-        query=Path('systrace_html_test.sql'),
+        query="""
+SELECT ts, cpu, dur, ts_end, utid, end_state, priority, upid, name, tid
+FROM sched
+JOIN thread USING(utid)
+ORDER BY ts;
+""",
         out=Path('systrace_html.out'))
 
   def test_sched_smoke_trailing_empty(self):
     return DiffTestBlueprint(
         trace=Path('../../data/trailing_empty.systrace'),
-        query=Path('sched_smoke_test.sql'),
+        query="""
+SELECT COUNT(1)
+FROM sched;
+""",
         out=Csv("""
 "COUNT(1)"
 2
@@ -318,7 +452,12 @@
   def test_lmk_userspace_lmk(self):
     return DiffTestBlueprint(
         trace=Path('../../data/lmk_userspace.pb'),
-        query=Path('lmk_test.sql'),
+        query="""
+SELECT ts, process.pid
+FROM instant
+JOIN process_track ON instant.track_id = process_track.id
+JOIN process USING (upid);
+""",
         out=Csv("""
 "ts","pid"
 732246100696424,17924
@@ -330,7 +469,13 @@
   def test_oom_kill(self):
     return DiffTestBlueprint(
         trace=Path('../common/oom_kill.textproto'),
-        query=Path('oom_kill_test.sql'),
+        query="""
+SELECT ts, instant.name, process.pid, process.name
+FROM instant
+JOIN thread_track ON instant.track_id = thread_track.id
+JOIN thread USING (utid)
+JOIN process USING (upid);
+""",
         out=Csv("""
 "ts","name","pid","name"
 1234,"mem.oom_kill",1000,"com.google.android.gm"
@@ -360,7 +505,9 @@
   def test_android_log_ring_buffer_mode(self):
     return DiffTestBlueprint(
         trace=Path('../../data/android_log_ring_buffer_mode.pb'),
-        query=Path('android_log_ring_buffer_mode_test.sql'),
+        query="""
+SELECT count(*) FROM android_logs;
+""",
         out=Csv("""
 "count(*)"
 26
@@ -375,19 +522,34 @@
   def test_process_stats_poll_oom_score(self):
     return DiffTestBlueprint(
         trace=Path('../../data/process_stats_poll.pb'),
-        query=Path('oom_score_poll_test.sql'),
+        query="""
+SELECT ts, name, value, upid
+FROM counter c
+JOIN process_counter_track t
+  ON c.track_id = t.id
+WHERE name = "oom_score_adj"
+ORDER BY ts
+LIMIT 20;
+""",
         out=Path('process_stats_poll_oom_score.out'))
 
   def test_android_sched_and_ps_stats(self):
     return DiffTestBlueprint(
         trace=Path('../../data/android_sched_and_ps.pb'),
-        query=Path('stats_test.sql'),
+        query="""
+SELECT name, idx, severity, source, value
+FROM stats WHERE name GLOB 'ftrace_cpu_*' OR name GLOB 'traced_buf_*';
+""",
         out=Path('android_sched_and_ps_stats.out'))
 
   def test_sys_syscall(self):
     return DiffTestBlueprint(
         trace=Path('syscall.py'),
-        query=Path('sys_test.sql'),
+        query="""
+SELECT ts, dur, name
+FROM slices
+LIMIT 10;
+""",
         out=Csv("""
 "ts","dur","name"
 100,6,"sys_io_setup"
@@ -397,7 +559,11 @@
   def test_thread_time_in_thread_slice(self):
     return DiffTestBlueprint(
         trace=Path('flow_events_json_v2.json'),
-        query=Path('thread_time_in_thread_slice_test.sql'),
+        query="""
+SELECT
+  name, thread_ts, thread_dur
+FROM slice;
+""",
         out=Csv("""
 "name","thread_ts","thread_dur"
 "SenderB",1000,5000
@@ -412,7 +578,14 @@
   def test_initial_display_state(self):
     return DiffTestBlueprint(
         trace=Path('initial_display_state.textproto'),
-        query=Path('initial_display_state_test.sql'),
+        query="""
+SELECT t.name,
+       c.ts,
+       c.value
+FROM counter_track t
+JOIN counter c ON t.id = c.track_id
+WHERE t.name = 'ScreenState';
+""",
         out=Csv("""
 "name","ts","value"
 "ScreenState",1,2.000000
@@ -422,7 +595,9 @@
   def test_config_metadata(self):
     return DiffTestBlueprint(
         trace=Path('config_metadata.textproto'),
-        query=Path('metadata_test.sql'),
+        query="""
+SELECT name, str_value FROM metadata WHERE str_value IS NOT NULL ORDER BY name;
+""",
         out=Csv("""
 "name","str_value"
 "android_build_fingerprint","the fingerprint"
@@ -445,13 +620,21 @@
   def test_chrome_metadata(self):
     return DiffTestBlueprint(
         trace=Path('chrome_metadata.textproto'),
-        query=Path('chrome_metadata_test.sql'),
+        query="""
+SELECT * FROM metadata;
+""",
         out=Path('chrome_metadata.out'))
 
   def test_cpu(self):
     return DiffTestBlueprint(
         trace=Path('cpu_info.textproto'),
-        query=Path('cpu_test.sql'),
+        query="""
+SELECT
+  id,
+  cluster_id,
+  processor
+FROM cpu;
+""",
         out=Csv("""
 "id","cluster_id","processor"
 0,0,"AArch64 Processor rev 13 (aarch64)"
@@ -467,13 +650,22 @@
   def test_cpu_freq(self):
     return DiffTestBlueprint(
         trace=Path('cpu_info.textproto'),
-        query=Path('cpu_freq_test.sql'),
+        query="""
+SELECT
+  freq,
+  GROUP_CONCAT(cpu_id) AS cpus
+FROM cpu_freq
+GROUP BY freq
+ORDER BY freq;
+""",
         out=Path('cpu_freq.out'))
 
   def test_android_sched_and_ps_trace_size(self):
     return DiffTestBlueprint(
         trace=Path('../../data/android_sched_and_ps.pb'),
-        query=Path('trace_size_test.sql'),
+        query="""
+SELECT int_value FROM metadata WHERE name = 'trace_size_bytes';
+""",
         out=Csv("""
 "int_value"
 18761615
@@ -496,7 +688,16 @@
   def test_process_metadata_matching(self):
     return DiffTestBlueprint(
         trace=Path('process_metadata_matching.textproto'),
-        query=Path('process_metadata_matching_test.sql'),
+        query="""
+CREATE TABLE TEST_TMP AS
+SELECT RUN_METRIC('android/process_metadata.sql');
+
+DROP TABLE TEST_TMP;
+
+SELECT upid, process_name, uid, shared_uid, package_name, version_code
+FROM process_metadata_table
+WHERE upid != 0;
+""",
         out=Csv("""
 "upid","process_name","uid","shared_uid","package_name","version_code"
 1,"init",0,"[NULL]","[NULL]","[NULL]"
@@ -509,7 +710,11 @@
   def test_flow_events_json_v1(self):
     return DiffTestBlueprint(
         trace=Path('flow_events_json_v1.json'),
-        query=Path('flow_events_test.sql'),
+        query="""
+SELECT t1.name AS slice_out, t2.name AS slice_in FROM flow t
+JOIN slice t1 ON t.slice_out = t1.slice_id
+JOIN slice t2 ON t.slice_in = t2.slice_id;
+""",
         out=Csv("""
 "slice_out","slice_in"
 "SenderB","Blergh"
@@ -520,7 +725,11 @@
   def test_flow_events_json_v2(self):
     return DiffTestBlueprint(
         trace=Path('flow_events_json_v2.json'),
-        query=Path('flow_events_test.sql'),
+        query="""
+SELECT t1.name AS slice_out, t2.name AS slice_in FROM flow t
+JOIN slice t1 ON t.slice_out = t1.slice_id
+JOIN slice t2 ON t.slice_in = t2.slice_id;
+""",
         out=Csv("""
 "slice_out","slice_in"
 "SenderB","Blergh"
@@ -532,7 +741,9 @@
   def test_display_time_unit_slices(self):
     return DiffTestBlueprint(
         trace=Path('../../data/display_time_unit.json'),
-        query=Path('slices_test.sql'),
+        query="""
+SELECT ts, dur, name FROM slice ORDER BY ts DESC;
+""",
         out=Csv("""
 "ts","dur","name"
 -7794778920422990592,211463000000,"add_graph"
@@ -541,7 +752,13 @@
   def test_sched_blocked_proto_sched_blocked_reason(self):
     return DiffTestBlueprint(
         trace=Path('sched_blocked_proto.py'),
-        query=Path('sched_blocked_reason_test.sql'),
+        query="""
+SELECT ts, tid, io_wait
+FROM thread_state
+JOIN thread USING (utid)
+WHERE state = 'D'
+ORDER BY ts;
+""",
         out=Csv("""
 "ts","tid","io_wait"
 100,1,0
@@ -551,7 +768,13 @@
   def test_sched_blocked_systrace_sched_blocked_reason(self):
     return DiffTestBlueprint(
         trace=Path('sched_blocked_systrace.systrace'),
-        query=Path('sched_blocked_reason_test.sql'),
+        query="""
+SELECT ts, tid, io_wait
+FROM thread_state
+JOIN thread USING (utid)
+WHERE state = 'D'
+ORDER BY ts;
+""",
         out=Csv("""
 "ts","tid","io_wait"
 20258854000,269,0
@@ -561,7 +784,16 @@
   def test_sched_blocked_reason_symbolized_sched_blocked_reason_function(self):
     return DiffTestBlueprint(
         trace=Path('sched_blocked_reason_symbolized.textproto'),
-        query=Path('sched_blocked_reason_function_test.sql'),
+        query="""
+SELECT
+  ts,
+  thread.tid AS pid,
+  blocked_function AS func
+FROM thread_state
+JOIN thread USING (utid)
+WHERE state = 'D'
+ORDER BY ts;
+""",
         out=Csv("""
 "ts","pid","func"
 999000,105,"some_fn"
@@ -576,13 +808,18 @@
   def test_sched_blocked_reason_symbolized_to_systrace(self):
     return DiffTestBlueprint(
         trace=Path('sched_blocked_reason_symbolized.textproto'),
-        query=Path('../common/to_systrace_test.sql'),
+        query="""
+SELECT to_ftrace(id) AS line
+FROM raw;
+""",
         out=Path('sched_blocked_reason_symbolized_to_systrace.out'))
 
   def test_decimal_timestamp_slices(self):
     return DiffTestBlueprint(
         trace=Path('../../data/decimal_timestamp.json'),
-        query=Path('slices_test.sql'),
+        query="""
+SELECT ts, dur, name FROM slice ORDER BY ts DESC;
+""",
         out=Csv("""
 "ts","dur","name"
 5100,500100,"name.exec"
@@ -591,7 +828,14 @@
   def test_counters_json_counters(self):
     return DiffTestBlueprint(
         trace=Path('../../data/counters.json'),
-        query=Path('json_counters_test.sql'),
+        query="""
+SELECT
+  process_counter_track.name,
+  counter.ts,
+  counter.value
+FROM counter
+JOIN process_counter_track ON (counter.track_id = process_counter_track.id);
+""",
         out=Csv("""
 "name","ts","value"
 "ctr cats",0,0.000000
@@ -602,7 +846,20 @@
   def test_instants_json_instants(self):
     return DiffTestBlueprint(
         trace=Path('../../data/instants.json'),
-        query=Path('json_instants_test.sql'),
+        query="""
+SELECT
+  slice.ts,
+  slice.name AS slice_name,
+  thread.tid,
+  process.pid
+FROM slice
+JOIN track ON (slice.track_id = track.id)
+LEFT JOIN thread_track ON (slice.track_id = thread_track.id)
+LEFT JOIN thread ON (thread_track.utid = thread.utid)
+LEFT JOIN process_track ON (slice.track_id = process_track.id)
+LEFT JOIN process ON (process_track.upid = process.upid)
+WHERE dur = 0;
+""",
         out=Csv("""
 "ts","slice_name","tid","pid"
 1234523300,"Thread",2347,"[NULL]"
@@ -627,7 +884,10 @@
   def test_sched_smoke_trailing_empty_2(self):
     return DiffTestBlueprint(
         trace=Path('../../data/atrace_b_193721088.atr'),
-        query=Path('sched_smoke_test.sql'),
+        query="""
+SELECT COUNT(1)
+FROM sched;
+""",
         out=Csv("""
 "COUNT(1)"
 2
@@ -647,7 +907,10 @@
   def test_atrace_compressed_sched_count(self):
     return DiffTestBlueprint(
         trace=Path('../../data/atrace_compressed.ctrace'),
-        query=Path('sched_smoke_test.sql'),
+        query="""
+SELECT COUNT(1)
+FROM sched;
+""",
         out=Csv("""
 "COUNT(1)"
 1120
@@ -656,7 +919,10 @@
   def test_atrace_uncompressed_sched_count(self):
     return DiffTestBlueprint(
         trace=Path('../../data/atrace_uncompressed_b_208691037'),
-        query=Path('sched_smoke_test.sql'),
+        query="""
+SELECT COUNT(1)
+FROM sched;
+""",
         out=Csv("""
 "COUNT(1)"
 9
@@ -678,7 +944,27 @@
     return DiffTestBlueprint(
         trace=Path('android_binder.py'),
         query=Metric('android_binder'),
-        out=Path('android_binder.out'))
+        out=TextProto(r"""
+android_binder {
+  process_breakdown {
+    process_name: "test_process_a"
+    pid: 1
+    slice_name: "binder transaction"
+    count: 2
+  }
+  process_breakdown {
+    process_name: "test_process_b"
+    pid: 2
+    slice_name: "binder reply"
+    count: 1
+  }
+  process_breakdown {
+    process_name: "test_process_c"
+    pid: 3
+    slice_name: "binder reply"
+    count: 1
+  }
+}"""))
 
   def test_statsd_atoms_all_atoms(self):
     return DiffTestBlueprint(
@@ -689,7 +975,13 @@
   def test_funcgraph_trace_funcgraph_test(self):
     return DiffTestBlueprint(
         trace=Path('funcgraph_trace.textproto'),
-        query=Path('funcgraph_test.sql'),
+        query="""
+SELECT ts, dur, tid, s.name, depth
+FROM slices s
+JOIN thread_track tt ON (s.track_id = tt.id)
+JOIN thread USING (utid)
+WHERE tid = 385482;
+""",
         out=Csv("""
 "ts","dur","tid","name","depth"
 679375600673065,3797,385482,"__handle_mm_fault",0
diff --git a/test/trace_processor/performance/index.py b/test/trace_processor/performance/index.py
index 0065dd0..d0dbf1f 100644
--- a/test/trace_processor/performance/index.py
+++ b/test/trace_processor/performance/index.py
@@ -30,7 +30,20 @@
   def test_cpu_frequency_limits(self):
     return DiffTestBlueprint(
         trace=Path('cpu_frequency_limits.textproto'),
-        query=Path('cpu_frequency_limits_test.sql'),
+        query="""
+SELECT
+  ts,
+  value,
+  REPLACE(name, " Freq Limit", "") AS cpu
+FROM
+  counter AS c
+LEFT JOIN
+  counter_track AS t
+  ON c.track_id = t.id
+WHERE
+  name GLOB "* Freq Limit"
+ORDER BY ts;
+""",
         out=Csv("""
 "ts","value","cpu"
 90000000,2800000.000000,"Cpu 6 Max"
diff --git a/test/trace_processor/power/index.py b/test/trace_processor/power/index.py
index 5ab287f..65bac5f 100644
--- a/test/trace_processor/power/index.py
+++ b/test/trace_processor/power/index.py
@@ -24,7 +24,13 @@
   def test_power_rails_power_rails(self):
     return DiffTestBlueprint(
         trace=Path('../../data/power_rails.pb'),
-        query=Path('power_rails_test.sql'),
+        query="""
+SELECT name, AVG(value), COUNT(*)
+FROM counters
+WHERE name GLOB "power.*"
+GROUP BY name
+LIMIT 20;
+""",
         out=Csv("""
 "name","AVG(value)","COUNT(*)"
 "power.PPVAR_VPH_PWR_ABH_uws",7390700.360656,61
@@ -34,7 +40,12 @@
   def test_power_rails_event_power_rails_custom_clock(self):
     return DiffTestBlueprint(
         trace=Path('power_rails_custom_clock.textproto'),
-        query=Path('power_rails_event_test.sql'),
+        query="""
+SELECT ts, value
+FROM counters
+WHERE name GLOB "power.*"
+LIMIT 20;
+""",
         out=Csv("""
 "ts","value"
 104000000,333.000000
@@ -46,7 +57,12 @@
   def test_power_rails_timestamp_sort(self):
     return DiffTestBlueprint(
         trace=Path('power_rails.textproto'),
-        query=Path('power_rails_timestamp_sort_test.sql'),
+        query="""
+SELECT ts, value, t.name AS name
+FROM counter c JOIN counter_track t ON t.id = c.track_id
+ORDER BY ts
+LIMIT 20;
+""",
         out=Csv("""
 "ts","value","name"
 3000000,333.000000,"power.test_rail_uws"
@@ -59,7 +75,13 @@
   def test_power_rails_well_known_power_rails(self):
     return DiffTestBlueprint(
         trace=Path('power_rails_well_known.textproto'),
-        query=Path('power_rails_test.sql'),
+        query="""
+SELECT name, AVG(value), COUNT(*)
+FROM counters
+WHERE name GLOB "power.*"
+GROUP BY name
+LIMIT 20;
+""",
         out=Csv("""
 "name","AVG(value)","COUNT(*)"
 "power.rails.cpu.mid",333.000000,3
@@ -75,7 +97,13 @@
   def test_wakesource_wakesource(self):
     return DiffTestBlueprint(
         trace=Path('wakesource.textproto'),
-        query=Path('wakesource_test.sql'),
+        query="""
+SELECT ts, dur, slice.name
+FROM slice
+JOIN track ON slice.track_id = track.id
+WHERE track.name GLOB 'Wakelock*'
+ORDER BY ts;
+""",
         out=Csv("""
 "ts","dur","name"
 34298714043271,7872467,"Wakelock(s2mpw02-power-keys)"
@@ -87,7 +115,20 @@
   def test_suspend_resume(self):
     return DiffTestBlueprint(
         trace=Path('suspend_resume.textproto'),
-        query=Path('suspend_resume_test.sql'),
+        query="""
+SELECT
+  s.ts,
+  s.dur,
+  s.name AS action
+FROM
+  slice AS s
+JOIN
+  track AS t
+  ON s.track_id = t.id
+WHERE
+  t.name = 'Suspend/Resume Latency'
+ORDER BY s.ts;
+""",
         out=Csv("""
 "ts","dur","action"
 10000,10000,"suspend_enter(3)"
@@ -118,7 +159,10 @@
   def test_energy_breakdown_table_test(self):
     return DiffTestBlueprint(
         trace=Path('energy_breakdown.textproto'),
-        query=Path('energy_breakdown_table_test.sql'),
+        query="""
+SELECT consumer_id, name, consumer_type, ordinal
+FROM energy_counter_track;
+""",
         out=Csv("""
 "consumer_id","name","consumer_type","ordinal"
 0,"CPUCL0","CPU_CLUSTER",0
@@ -127,7 +171,12 @@
   def test_energy_breakdown_event_test(self):
     return DiffTestBlueprint(
         trace=Path('energy_breakdown.textproto'),
-        query=Path('energy_breakdown_event_test.sql'),
+        query="""
+SELECT ts, value
+FROM counter
+JOIN energy_counter_track ON counter.track_id = energy_counter_track.id
+ORDER BY ts;
+""",
         out=Csv("""
 "ts","value"
 1030255882785,98567522.000000
@@ -136,7 +185,10 @@
   def test_energy_breakdown_uid_table_test(self):
     return DiffTestBlueprint(
         trace=Path('energy_breakdown_uid.textproto'),
-        query=Path('energy_breakdown_uid_table_test.sql'),
+        query="""
+SELECT uid, name
+FROM uid_counter_track;
+""",
         out=Csv("""
 "uid","name"
 10234,"GPU"
@@ -147,7 +199,12 @@
   def test_energy_breakdown_uid_event_test(self):
     return DiffTestBlueprint(
         trace=Path('energy_breakdown_uid.textproto'),
-        query=Path('energy_breakdown_uid_event_test.sql'),
+        query="""
+SELECT ts, value
+FROM counter
+JOIN uid_counter_track ON counter.track_id = uid_counter_track.id
+ORDER BY ts;
+""",
         out=Csv("""
 "ts","value"
 1026753926322,3004536.000000
@@ -158,7 +215,10 @@
   def test_energy_per_uid_table_test(self):
     return DiffTestBlueprint(
         trace=Path('energy_breakdown_uid.textproto'),
-        query=Path('energy_per_uid_table_test.sql'),
+        query="""
+SELECT consumer_id, uid
+FROM energy_per_uid_counter_track;
+""",
         out=Csv("""
 "consumer_id","uid"
 3,10234
@@ -169,13 +229,20 @@
   def test_cpu_counters_p_state_test(self):
     return DiffTestBlueprint(
         trace=Path('../../data/cpu_counters.pb'),
-        query=Path('p_state_test.sql'),
+        query="""
+SELECT RUN_METRIC("android/p_state.sql");
+
+SELECT * FROM P_STATE_OVER_INTERVAL(2579596465618, 2579606465618);
+""",
         out=Path('cpu_counters_p_state_test.out'))
 
   def test_cpu_powerups_test(self):
     return DiffTestBlueprint(
         trace=Path('../../data/cpu_powerups_1.pb'),
-        query=Path('cpu_powerups_test.sql'),
+        query="""
+SELECT IMPORT("chrome.cpu_powerups");
+SELECT * FROM chrome_cpu_power_first_toplevel_slice_after_powerup;
+""",
         out=Csv("""
 "slice_id","previous_power_state"
 424,2
diff --git a/test/trace_processor/process_tracking/index.py b/test/trace_processor/process_tracking/index.py
index e163252..5f1d6db 100644
--- a/test/trace_processor/process_tracking/index.py
+++ b/test/trace_processor/process_tracking/index.py
@@ -24,7 +24,13 @@
   def test_process_tracking(self):
     return DiffTestBlueprint(
         trace=Path('synth_process_tracking.py'),
-        query=Path('../common/process_tracking_test.sql'),
+        query="""
+SELECT tid, pid, process.name AS pname, thread.name AS tname
+FROM thread
+LEFT JOIN process USING(upid)
+WHERE tid > 0
+ORDER BY tid;
+""",
         out=Csv("""
 "tid","pid","pname","tname"
 10,10,"process1","p1-t0"
@@ -45,7 +51,13 @@
   def test_process_tracking_process_tracking_short_lived_1(self):
     return DiffTestBlueprint(
         trace=Path('process_tracking_short_lived_1.py'),
-        query=Path('../common/process_tracking_test.sql'),
+        query="""
+SELECT tid, pid, process.name AS pname, thread.name AS tname
+FROM thread
+LEFT JOIN process USING(upid)
+WHERE tid > 0
+ORDER BY tid;
+""",
         out=Csv("""
 "tid","pid","pname","tname"
 10,10,"parent","parent"
@@ -55,7 +67,13 @@
   def test_process_tracking_process_tracking_short_lived_2(self):
     return DiffTestBlueprint(
         trace=Path('process_tracking_short_lived_2.py'),
-        query=Path('../common/process_tracking_test.sql'),
+        query="""
+SELECT tid, pid, process.name AS pname, thread.name AS tname
+FROM thread
+LEFT JOIN process USING(upid)
+WHERE tid > 0
+ORDER BY tid;
+""",
         out=Csv("""
 "tid","pid","pname","tname"
 10,10,"parent","parent"
@@ -65,7 +83,11 @@
   def test_process_tracking_uid(self):
     return DiffTestBlueprint(
         trace=Path('synth_process_tracking.py'),
-        query=Path('process_tracking_uid_test.sql'),
+        query="""
+SELECT pid, uid
+FROM process
+ORDER BY pid;
+""",
         out=Csv("""
 "pid","uid"
 0,"[NULL]"
@@ -78,7 +100,13 @@
   def test_process_tracking_process_tracking_exec(self):
     return DiffTestBlueprint(
         trace=Path('process_tracking_exec.py'),
-        query=Path('../common/process_tracking_test.sql'),
+        query="""
+SELECT tid, pid, process.name AS pname, thread.name AS tname
+FROM thread
+LEFT JOIN process USING(upid)
+WHERE tid > 0
+ORDER BY tid;
+""",
         out=Csv("""
 "tid","pid","pname","tname"
 10,10,"parent","parent"
@@ -88,7 +116,15 @@
   def test_process_parent_pid_process_parent_pid_tracking_1(self):
     return DiffTestBlueprint(
         trace=Path('process_parent_pid_tracking_1.py'),
-        query=Path('process_parent_pid_test.sql'),
+        query="""
+SELECT
+  child.pid AS child_pid,
+  parent.pid AS parent_pid
+FROM process AS child
+JOIN process AS parent
+  ON child.parent_upid = parent.upid
+ORDER BY child_pid;
+""",
         out=Csv("""
 "child_pid","parent_pid"
 10,0
@@ -98,7 +134,15 @@
   def test_process_parent_pid_process_parent_pid_tracking_2(self):
     return DiffTestBlueprint(
         trace=Path('process_parent_pid_tracking_2.py'),
-        query=Path('process_parent_pid_test.sql'),
+        query="""
+SELECT
+  child.pid AS child_pid,
+  parent.pid AS parent_pid
+FROM process AS child
+JOIN process AS parent
+  ON child.parent_upid = parent.upid
+ORDER BY child_pid;
+""",
         out=Csv("""
 "child_pid","parent_pid"
 10,0
@@ -108,7 +152,13 @@
   def test_process_tracking_reused_thread_print(self):
     return DiffTestBlueprint(
         trace=Path('reused_thread_print.py'),
-        query=Path('../common/process_tracking_test.sql'),
+        query="""
+SELECT tid, pid, process.name AS pname, thread.name AS tname
+FROM thread
+LEFT JOIN process USING(upid)
+WHERE tid > 0
+ORDER BY tid;
+""",
         out=Csv("""
 "tid","pid","pname","tname"
 10,10,"parent","[NULL]"
@@ -119,7 +169,13 @@
   def test_slice_with_pid_sde_tracing_mark_write(self):
     return DiffTestBlueprint(
         trace=Path('sde_tracing_mark_write.textproto'),
-        query=Path('slice_with_pid_test.sql'),
+        query="""
+SELECT s.name, dur, tid, pid
+FROM slice s
+JOIN thread_track t ON s.track_id = t.id
+JOIN thread USING(utid)
+LEFT JOIN process USING(upid);
+""",
         out=Csv("""
 "name","dur","tid","pid"
 "test_event",1,403,403
@@ -128,7 +184,13 @@
   def test_unknown_thread_name_tracking(self):
     return DiffTestBlueprint(
         trace=Path('unknown_thread_name.systrace'),
-        query=Path('../common/process_tracking_test.sql'),
+        query="""
+SELECT tid, pid, process.name AS pname, thread.name AS tname
+FROM thread
+LEFT JOIN process USING(upid)
+WHERE tid > 0
+ORDER BY tid;
+""",
         out=Csv("""
 "tid","pid","pname","tname"
 19999,"[NULL]","[NULL]","real_name"
diff --git a/test/trace_processor/profiling/index.py b/test/trace_processor/profiling/index.py
index 0a38a4a..0dab91e 100644
--- a/test/trace_processor/profiling/index.py
+++ b/test/trace_processor/profiling/index.py
@@ -24,7 +24,9 @@
   def test_heap_profile_jit(self):
     return DiffTestBlueprint(
         trace=Path('heap_profile_jit.textproto'),
-        query=Path('heap_profile_frames_test.sql'),
+        query="""
+SELECT name, mapping, rel_pc FROM stack_profile_frame ORDER BY name;
+""",
         out=Csv("""
 "name","mapping","rel_pc"
 "java_frame_1",0,4096
@@ -52,7 +54,9 @@
   def test_heap_profile_dump_max_legacy(self):
     return DiffTestBlueprint(
         trace=Path('heap_profile_dump_max_legacy.textproto'),
-        query=Path('heap_profile_tracker_new_stack_test.sql'),
+        query="""
+SELECT * FROM heap_profile_allocation;
+""",
         out=Csv("""
 "id","type","ts","upid","heap_name","callsite_id","count","size"
 0,"heap_profile_allocation",-10,2,"malloc",2,0,1000
@@ -62,7 +66,9 @@
   def test_heap_profile_dump_max(self):
     return DiffTestBlueprint(
         trace=Path('heap_profile_dump_max.textproto'),
-        query=Path('heap_profile_tracker_new_stack_test.sql'),
+        query="""
+SELECT * FROM heap_profile_allocation;
+""",
         out=Csv("""
 "id","type","ts","upid","heap_name","callsite_id","count","size"
 0,"heap_profile_allocation",-10,2,"malloc",2,6,1000
@@ -72,7 +78,10 @@
   def test_profiler_smaps(self):
     return DiffTestBlueprint(
         trace=Path('profiler_smaps.textproto'),
-        query=Path('profiler_smaps_test.sql'),
+        query="""
+SELECT id, type, upid, ts, path, size_kb, private_dirty_kb, swap_kb
+FROM profiler_smaps;
+""",
         out=Csv("""
 "id","type","upid","ts","path","size_kb","private_dirty_kb","swap_kb"
 0,"profiler_smaps",2,10,"/system/lib64/libc.so",20,4,4
@@ -83,102 +92,275 @@
     return DiffTestBlueprint(
         trace=Path('profiler_smaps.textproto'),
         query=Metric('profiler_smaps'),
-        out=Path('profiler_smaps_metric.out'))
+        out=TextProto(r"""
+profiler_smaps {
+  instance {
+    process {
+      name: "system_server"
+      uid: 1000
+    }
+    mappings {
+      path: "[anon: libc_malloc]"
+      size_kb: 30
+      private_dirty_kb: 10
+      swap_kb: 10
+    }
+    mappings {
+      path: "/system/lib64/libc.so"
+      size_kb: 20
+      private_dirty_kb: 4
+      swap_kb: 4
+    }
+  }
+}
+"""))
 
   def test_heap_graph_flamegraph(self):
     return DiffTestBlueprint(
         trace=Path('heap_graph_baseapk.textproto'),
-        query=Path('heap_graph_flamegraph_test.sql'),
+        query="""
+SELECT
+  id,
+  depth,
+  name,
+  map_name,
+  count,
+  cumulative_count,
+  size,
+  cumulative_size,
+  parent_id
+FROM experimental_flamegraph
+WHERE upid = (SELECT max(upid) FROM heap_graph_object)
+  AND profile_type = 'graph'
+  AND ts = (SELECT max(graph_sample_ts) FROM heap_graph_object)
+LIMIT 10;
+""",
         out=Path('heap_graph_flamegraph.out'))
 
   def test_heap_graph_object(self):
     return DiffTestBlueprint(
         trace=Path('heap_graph_baseapk.textproto'),
-        query=Path('heap_graph_object_test.sql'),
+        query="""
+SELECT o.id,
+       o.type,
+       o.upid,
+       o.graph_sample_ts,
+       o.self_size,
+       o.reference_set_id,
+       o.reachable,
+       c.name AS type_name,
+       c.deobfuscated_name AS deobfuscated_type_name,
+       o.root_type
+FROM heap_graph_object o JOIN heap_graph_class c ON o.type_id = c.id;
+""",
         out=Path('heap_graph_object.out'))
 
   def test_heap_graph_reference(self):
     return DiffTestBlueprint(
         trace=Path('heap_graph_baseapk.textproto'),
-        query=Path('heap_graph_reference_test.sql'),
+        query="""
+SELECT * FROM heap_graph_reference;
+""",
         out=Path('heap_graph_reference.out'))
 
   def test_heap_graph_object_2(self):
     return DiffTestBlueprint(
         trace=Path('heap_graph_deobfuscate_pkg.textproto'),
-        query=Path('heap_graph_object_test.sql'),
+        query="""
+SELECT o.id,
+       o.type,
+       o.upid,
+       o.graph_sample_ts,
+       o.self_size,
+       o.reference_set_id,
+       o.reachable,
+       c.name AS type_name,
+       c.deobfuscated_name AS deobfuscated_type_name,
+       o.root_type
+FROM heap_graph_object o JOIN heap_graph_class c ON o.type_id = c.id;
+""",
         out=Path('heap_graph_object.out'))
 
   def test_heap_graph_duplicate_flamegraph(self):
     return DiffTestBlueprint(
         trace=Path('heap_graph_duplicate.textproto'),
-        query=Path('heap_graph_flamegraph_test.sql'),
+        query="""
+SELECT
+  id,
+  depth,
+  name,
+  map_name,
+  count,
+  cumulative_count,
+  size,
+  cumulative_size,
+  parent_id
+FROM experimental_flamegraph
+WHERE upid = (SELECT max(upid) FROM heap_graph_object)
+  AND profile_type = 'graph'
+  AND ts = (SELECT max(graph_sample_ts) FROM heap_graph_object)
+LIMIT 10;
+""",
         out=Path('heap_graph_duplicate_flamegraph.out'))
 
   def test_heap_graph_flamegraph_2(self):
     return DiffTestBlueprint(
         trace=Path('heap_graph.textproto'),
-        query=Path('heap_graph_flamegraph_test.sql'),
+        query="""
+SELECT
+  id,
+  depth,
+  name,
+  map_name,
+  count,
+  cumulative_count,
+  size,
+  cumulative_size,
+  parent_id
+FROM experimental_flamegraph
+WHERE upid = (SELECT max(upid) FROM heap_graph_object)
+  AND profile_type = 'graph'
+  AND ts = (SELECT max(graph_sample_ts) FROM heap_graph_object)
+LIMIT 10;
+""",
         out=Path('heap_graph_flamegraph.out'))
 
   def test_heap_graph_object_3(self):
     return DiffTestBlueprint(
         trace=Path('heap_graph.textproto'),
-        query=Path('heap_graph_object_test.sql'),
+        query="""
+SELECT o.id,
+       o.type,
+       o.upid,
+       o.graph_sample_ts,
+       o.self_size,
+       o.reference_set_id,
+       o.reachable,
+       c.name AS type_name,
+       c.deobfuscated_name AS deobfuscated_type_name,
+       o.root_type
+FROM heap_graph_object o JOIN heap_graph_class c ON o.type_id = c.id;
+""",
         out=Path('heap_graph_object.out'))
 
   def test_heap_graph_reference_2(self):
     return DiffTestBlueprint(
         trace=Path('heap_graph.textproto'),
-        query=Path('heap_graph_reference_test.sql'),
+        query="""
+SELECT * FROM heap_graph_reference;
+""",
         out=Path('heap_graph_reference.out'))
 
   def test_heap_graph_two_locations(self):
     return DiffTestBlueprint(
         trace=Path('heap_graph_two_locations.textproto'),
-        query=Path('heap_graph_object_test.sql'),
+        query="""
+SELECT o.id,
+       o.type,
+       o.upid,
+       o.graph_sample_ts,
+       o.self_size,
+       o.reference_set_id,
+       o.reachable,
+       c.name AS type_name,
+       c.deobfuscated_name AS deobfuscated_type_name,
+       o.root_type
+FROM heap_graph_object o JOIN heap_graph_class c ON o.type_id = c.id;
+""",
         out=Path('heap_graph_two_locations.out'))
 
   def test_heap_graph_object_4(self):
     return DiffTestBlueprint(
         trace=Path('heap_graph_legacy.textproto'),
-        query=Path('heap_graph_object_test.sql'),
+        query="""
+SELECT o.id,
+       o.type,
+       o.upid,
+       o.graph_sample_ts,
+       o.self_size,
+       o.reference_set_id,
+       o.reachable,
+       c.name AS type_name,
+       c.deobfuscated_name AS deobfuscated_type_name,
+       o.root_type
+FROM heap_graph_object o JOIN heap_graph_class c ON o.type_id = c.id;
+""",
         out=Path('heap_graph_object.out'))
 
   def test_heap_graph_reference_3(self):
     return DiffTestBlueprint(
         trace=Path('heap_graph_legacy.textproto'),
-        query=Path('heap_graph_reference_test.sql'),
+        query="""
+SELECT * FROM heap_graph_reference;
+""",
         out=Path('heap_graph_reference.out'))
 
   def test_heap_graph_interleaved_object(self):
     return DiffTestBlueprint(
         trace=Path('heap_graph_interleaved.textproto'),
-        query=Path('heap_graph_object_test.sql'),
+        query="""
+SELECT o.id,
+       o.type,
+       o.upid,
+       o.graph_sample_ts,
+       o.self_size,
+       o.reference_set_id,
+       o.reachable,
+       c.name AS type_name,
+       c.deobfuscated_name AS deobfuscated_type_name,
+       o.root_type
+FROM heap_graph_object o JOIN heap_graph_class c ON o.type_id = c.id;
+""",
         out=Path('heap_graph_interleaved_object.out'))
 
   def test_heap_graph_interleaved_reference(self):
     return DiffTestBlueprint(
         trace=Path('heap_graph_interleaved.textproto'),
-        query=Path('heap_graph_reference_test.sql'),
+        query="""
+SELECT * FROM heap_graph_reference;
+""",
         out=Path('heap_graph_interleaved_reference.out'))
 
   def test_heap_graph_flamegraph_system_server_heap_graph(self):
     return DiffTestBlueprint(
         trace=Path('../../data/system-server-heap-graph-new.pftrace'),
-        query=Path('heap_graph_flamegraph_test.sql'),
+        query="""
+SELECT
+  id,
+  depth,
+  name,
+  map_name,
+  count,
+  cumulative_count,
+  size,
+  cumulative_size,
+  parent_id
+FROM experimental_flamegraph
+WHERE upid = (SELECT max(upid) FROM heap_graph_object)
+  AND profile_type = 'graph'
+  AND ts = (SELECT max(graph_sample_ts) FROM heap_graph_object)
+LIMIT 10;
+""",
         out=Path('heap_graph_flamegraph_system-server-heap-graph.out'))
 
   def test_heap_profile_flamegraph_system_server_native_profile(self):
     return DiffTestBlueprint(
         trace=Path('../../data/system-server-native-profile'),
-        query=Path('heap_profile_flamegraph_test.sql'),
+        query="""
+SELECT * FROM experimental_flamegraph
+WHERE ts = 605908369259172
+  AND upid = 1
+  AND profile_type = 'native'
+LIMIT 10;
+""",
         out=Path('heap_profile_flamegraph_system-server-native-profile.out'))
 
   def test_heap_profile_tracker_new_stack(self):
     return DiffTestBlueprint(
         trace=Path('heap_profile_tracker_new_stack.textproto'),
-        query=Path('heap_profile_tracker_new_stack_test.sql'),
+        query="""
+SELECT * FROM heap_profile_allocation;
+""",
         out=Csv("""
 "id","type","ts","upid","heap_name","callsite_id","count","size"
 0,"heap_profile_allocation",0,0,"malloc",0,1,1
@@ -190,7 +372,9 @@
   def test_heap_profile_tracker_twoheaps(self):
     return DiffTestBlueprint(
         trace=Path('heap_profile_tracker_twoheaps.textproto'),
-        query=Path('heap_profile_tracker_twoheaps_test.sql'),
+        query="""
+SELECT * FROM heap_profile_allocation;
+""",
         out=Csv("""
 "id","type","ts","upid","heap_name","callsite_id","count","size"
 0,"heap_profile_allocation",0,0,"malloc",0,1,1
@@ -202,13 +386,32 @@
   def test_heap_graph_flamegraph_focused(self):
     return DiffTestBlueprint(
         trace=Path('heap_graph_branching.textproto'),
-        query=Path('heap_graph_flamegraph_focused_test.sql'),
+        query="""
+SELECT
+  id,
+  depth,
+  name,
+  count,
+  cumulative_count,
+  size,
+  cumulative_size,
+  parent_id
+FROM experimental_flamegraph
+WHERE upid = (SELECT max(upid) FROM heap_graph_object)
+  AND profile_type = 'graph'
+  AND ts = (SELECT max(graph_sample_ts) FROM heap_graph_object)
+  AND focus_str = 'left'
+LIMIT 10;
+""",
         out=Path('heap_graph_flamegraph_focused.out'))
 
   def test_heap_graph_superclass(self):
     return DiffTestBlueprint(
         trace=Path('heap_graph_superclass.textproto'),
-        query=Path('heap_graph_superclass_test.sql'),
+        query="""
+SELECT c.id, c.superclass_id, c.name, s.name AS superclass_name, c.location
+FROM heap_graph_class c LEFT JOIN heap_graph_class s ON c.superclass_id = s.id;
+""",
         out=Csv("""
 "id","superclass_id","name","superclass_name","location"
 0,"[NULL]","java.lang.Class<java.lang.Object>","[NULL]","l1"
@@ -222,7 +425,12 @@
   def test_heap_graph_native_size(self):
     return DiffTestBlueprint(
         trace=Path('heap_graph_native_size.textproto'),
-        query=Path('heap_graph_native_size_test.sql'),
+        query="""
+SELECT c.name AS type_name,
+       o.native_size
+FROM heap_graph_object o JOIN heap_graph_class c ON o.type_id = c.id
+WHERE o.root_type = "ROOT_JAVA_FRAME";
+""",
         out=Csv("""
 "type_name","native_size"
 "android.graphics.Bitmap",123456
@@ -232,7 +440,25 @@
   def test_heap_graph_flamegraph_matches_objects(self):
     return DiffTestBlueprint(
         trace=Path('heap_graph_huge_size.textproto'),
-        query=Path('heap_graph_flamegraph_matches_objects_test.sql'),
+        query="""
+SELECT
+  obj.upid AS upid,
+  obj.graph_sample_ts AS ts,
+  SUM(obj.self_size + obj.native_size) AS total_objects_size,
+  (
+    SELECT SUM(cumulative_size)
+    FROM experimental_flamegraph
+    WHERE experimental_flamegraph.upid = obj.upid
+      AND experimental_flamegraph.ts = obj.graph_sample_ts
+      AND profile_type = 'graph'
+      AND depth = 0 -- only the roots
+  ) AS total_flamegraph_size
+FROM
+  heap_graph_object AS obj
+WHERE
+  obj.reachable != 0
+GROUP BY obj.upid, obj.graph_sample_ts;
+""",
         out=Csv("""
 "upid","ts","total_objects_size","total_flamegraph_size"
 1,10,3000000036,3000000036
@@ -241,13 +467,31 @@
   def test_heap_graph_flamegraph_3(self):
     return DiffTestBlueprint(
         trace=Path('heap_graph_legacy.textproto'),
-        query=Path('heap_graph_flamegraph_test.sql'),
+        query="""
+SELECT
+  id,
+  depth,
+  name,
+  map_name,
+  count,
+  cumulative_count,
+  size,
+  cumulative_size,
+  parent_id
+FROM experimental_flamegraph
+WHERE upid = (SELECT max(upid) FROM heap_graph_object)
+  AND profile_type = 'graph'
+  AND ts = (SELECT max(graph_sample_ts) FROM heap_graph_object)
+LIMIT 10;
+""",
         out=Path('heap_graph_flamegraph.out'))
 
   def test_stack_profile_tracker_empty_callstack(self):
     return DiffTestBlueprint(
         trace=Path('stack_profile_tracker_empty_callstack.textproto'),
-        query=Path('stack_profile_tracker_empty_callstack_test.sql'),
+        query="""
+SELECT count(1) AS count FROM heap_profile_allocation;
+""",
         out=Csv("""
 "count"
 0
@@ -257,7 +501,34 @@
     return DiffTestBlueprint(
         trace=Path('heap_profile_no_symbols.textproto'),
         query=Metric('unsymbolized_frames'),
-        out=Path('unsymbolized_frames.out'))
+        out=TextProto(r"""
+unsymbolized_frames {
+  frames {
+    module: "/liblib.so"
+    build_id: "6275696c642d6964"
+    address: 4096
+    google_lookup_id: "6275696c642d6964"
+  }
+  frames {
+    module: "/liblib.so"
+    build_id: "6275696c642d6964"
+    address: 8192
+    google_lookup_id: "6275696c642d6964"
+  }
+  frames {
+    module: "/libmonochrome_64.so"
+    build_id: "7f0715c286f8b16c10e4ad349cda3b9b56c7a773"
+    address: 4096
+    google_lookup_id: "c215077ff8866cb110e4ad349cda3b9b0"
+  }
+  frames {
+    module: "/libmonochrome_64.so"
+    build_id: "7f0715c286f8b16c10e4ad349cda3b9b56c7a773"
+    address: 8192
+    google_lookup_id: "c215077ff8866cb110e4ad349cda3b9b0"
+  }
+}
+"""))
 
   def test_simpleperf_event(self):
     return DiffTestBlueprint(
@@ -269,7 +540,37 @@
     return DiffTestBlueprint(
         trace=Path('heap_graph.textproto'),
         query=Metric('java_heap_stats'),
-        out=Path('java_heap_stats.out'))
+        out=TextProto(r"""
+java_heap_stats {
+  instance_stats {
+    upid: 2
+    process {
+      name: "system_server"
+      uid: 1000
+    }
+    samples {
+      ts: 10
+      heap_size: 1760
+      heap_native_size: 0
+      reachable_heap_size: 352
+      reachable_heap_native_size: 0
+      obj_count: 6
+      reachable_obj_count: 3
+      anon_rss_and_swap_size: 4096000
+      roots {
+        root_type: "ROOT_JAVA_FRAME"
+        type_name: "DeobfuscatedA[]"
+        obj_count: 1
+      }
+      roots {
+        root_type: "ROOT_JAVA_FRAME"
+        type_name: "FactoryProducerDelegateImplActor"
+        obj_count: 1
+      }
+    }
+  }
+}
+"""))
 
   def test_heap_stats_closest_proc(self):
     return DiffTestBlueprint(
@@ -286,31 +587,98 @@
   def test_perf_sample_rvc(self):
     return DiffTestBlueprint(
         trace=Path('../../data/perf_sample.pb'),
-        query=Path('perf_sample_test.sql'),
+        query="""
+SELECT ps.ts, ps.cpu, ps.cpu_mode, ps.unwind_error, ps.perf_session_id,
+       pct.name AS cntr_name, pct.is_timebase,
+       thread.tid,
+       spf.name
+FROM experimental_annotated_callstack eac
+JOIN perf_sample ps
+  ON (eac.start_id = ps.callsite_id)
+JOIN perf_counter_track pct
+  USING(perf_session_id, cpu)
+JOIN thread
+  USING(utid)
+JOIN stack_profile_frame spf
+  ON (eac.frame_id = spf.id)
+ORDER BY ps.ts ASC, eac.depth ASC;
+""",
         out=Path('perf_sample_rvc.out'))
 
   def test_perf_sample_sc(self):
     return DiffTestBlueprint(
         trace=Path('../../data/perf_sample_sc.pb'),
-        query=Path('perf_sample_test.sql'),
+        query="""
+SELECT ps.ts, ps.cpu, ps.cpu_mode, ps.unwind_error, ps.perf_session_id,
+       pct.name AS cntr_name, pct.is_timebase,
+       thread.tid,
+       spf.name
+FROM experimental_annotated_callstack eac
+JOIN perf_sample ps
+  ON (eac.start_id = ps.callsite_id)
+JOIN perf_counter_track pct
+  USING(perf_session_id, cpu)
+JOIN thread
+  USING(utid)
+JOIN stack_profile_frame spf
+  ON (eac.frame_id = spf.id)
+ORDER BY ps.ts ASC, eac.depth ASC;
+""",
         out=Path('perf_sample_sc.out'))
 
   def test_stack_profile_symbols(self):
     return DiffTestBlueprint(
         trace=Path('../../data/heapprofd_standalone_client_example-trace'),
-        query=Path('stack_profile_symbols_test.sql'),
+        query="""
+SELECT name, source_file, line_number FROM stack_profile_symbol;
+""",
         out=Path('stack_profile_symbols.out'))
 
   def test_callstack_sampling_flamegraph(self):
     return DiffTestBlueprint(
         trace=Path('../../data/callstack_sampling.pftrace'),
-        query=Path('callstack_sampling_flamegraph_test.sql'),
+        query="""
+SELECT ef.*
+FROM experimental_flamegraph ef
+JOIN process USING (upid)
+WHERE pid = 1728
+  AND profile_type = 'perf'
+  AND ts <= 7689491063351
+LIMIT 10;
+""",
         out=Path('callstack_sampling_flamegraph.out'))
 
   def test_callstack_sampling_flamegraph_multi_process(self):
     return DiffTestBlueprint(
         trace=Path('../../data/callstack_sampling.pftrace'),
-        query=Path('callstack_sampling_flamegraph_multi_process_test.sql'),
+        query="""
+SELECT count(*) AS count, 'BothProcesses' AS description
+FROM experimental_flamegraph
+WHERE
+  upid_group = (
+    SELECT group_concat(DISTINCT upid)
+    FROM perf_sample JOIN thread t USING (utid) JOIN process p USING (upid)
+  )
+  AND profile_type = 'perf'
+  AND ts <= 7689491063351
+  AND size > 0
+UNION ALL
+SELECT count(*) AS count, 'FirstProcess' AS description
+FROM experimental_flamegraph
+JOIN process USING (upid)
+WHERE pid = 1728
+  AND profile_type = 'perf'
+  AND ts <= 7689491063351
+  AND size > 0
+UNION ALL
+SELECT count(*) AS count, 'SecondProcess' AS description
+FROM experimental_flamegraph
+JOIN process USING (upid)
+WHERE pid = 703
+  AND profile_type = 'perf'
+  AND ts <= 7689491063351
+  AND size > 0;
+""",
         out=Csv("""
 "count","description"
 658,"BothProcesses"
@@ -321,7 +689,9 @@
   def test_no_build_id(self):
     return DiffTestBlueprint(
         trace=Path('heap_profile_data_local_tmp.textproto'),
-        query=Path('no_build_id_test.sql'),
+        query="""
+SELECT value FROM stats WHERE name = 'symbolization_tmp_build_id_not_found';
+""",
         out=Csv("""
 "value"
 1
diff --git a/test/trace_processor/smoke/index.py b/test/trace_processor/smoke/index.py
index afa1bbd..2abee18 100644
--- a/test/trace_processor/smoke/index.py
+++ b/test/trace_processor/smoke/index.py
@@ -24,7 +24,19 @@
   def test_sfgate_smoke(self):
     return DiffTestBlueprint(
         trace=Path('../../data/sfgate.json'),
-        query=Path('../common/smoke_test.sql'),
+        query="""
+SELECT
+  ts,
+  cpu,
+  dur,
+  end_state,
+  priority,
+  tid
+FROM sched
+JOIN thread USING(utid)
+ORDER BY ts
+LIMIT 10;
+""",
         out=Csv("""
 "ts","cpu","dur","end_state","priority","tid"
 """))
@@ -32,7 +44,13 @@
   def test_sfgate_smoke_slices(self):
     return DiffTestBlueprint(
         trace=Path('../../data/sfgate.json'),
-        query=Path('../common/smoke_slices_test.sql'),
+        query="""
+SELECT track.type AS type, depth, count(*) AS count
+FROM slice
+JOIN track ON slice.track_id = track.id
+GROUP BY track.type, depth
+ORDER BY track.type, depth;
+""",
         out=Csv("""
 "type","depth","count"
 "thread_track",0,16888
@@ -50,7 +68,19 @@
   def test_android_sched_and_ps_smoke(self):
     return DiffTestBlueprint(
         trace=Path('../../data/android_sched_and_ps.pb'),
-        query=Path('../common/smoke_test.sql'),
+        query="""
+SELECT
+  ts,
+  cpu,
+  dur,
+  end_state,
+  priority,
+  tid
+FROM sched
+JOIN thread USING(utid)
+ORDER BY ts
+LIMIT 10;
+""",
         out=Csv("""
 "ts","cpu","dur","end_state","priority","tid"
 81473010031230,2,78021,"S",120,26204
@@ -68,7 +98,19 @@
   def test_compressed_smoke(self):
     return DiffTestBlueprint(
         trace=Path('../../data/compressed.pb'),
-        query=Path('../common/smoke_test.sql'),
+        query="""
+SELECT
+  ts,
+  cpu,
+  dur,
+  end_state,
+  priority,
+  tid
+FROM sched
+JOIN thread USING(utid)
+ORDER BY ts
+LIMIT 10;
+""",
         out=Csv("""
 "ts","cpu","dur","end_state","priority","tid"
 170601497673450,2,53646,"DK",120,6790
@@ -86,7 +128,19 @@
   def test_synth_1_smoke(self):
     return DiffTestBlueprint(
         trace=Path('../common/synth_1.py'),
-        query=Path('../common/smoke_test.sql'),
+        query="""
+SELECT
+  ts,
+  cpu,
+  dur,
+  end_state,
+  priority,
+  tid
+FROM sched
+JOIN thread USING(utid)
+ORDER BY ts
+LIMIT 10;
+""",
         out=Csv("""
 "ts","cpu","dur","end_state","priority","tid"
 1,0,99,"R",0,3
@@ -102,11 +156,46 @@
   def test_thread_cpu_time_example_android_trace_30s(self):
     return DiffTestBlueprint(
         trace=Path('../../data/example_android_trace_30s.pb'),
-        query=Path('thread_cpu_time_test.sql'),
+        query="""
+SELECT
+  tid,
+  pid,
+  thread.name AS threadName,
+  process.name AS processName,
+  total_dur AS totalDur
+FROM
+  thread
+LEFT JOIN process USING(upid)
+LEFT JOIN
+  (SELECT upid, sum(dur) AS total_dur
+    FROM sched JOIN thread USING(utid)
+    WHERE dur != -1
+    GROUP BY upid
+  ) USING(upid)
+WHERE utid != 0
+ORDER BY total_dur DESC, pid, tid;
+""",
         out=Path('thread_cpu_time_example_android_trace_30s.out'))
 
   def test_proxy_power(self):
     return DiffTestBlueprint(
         trace=Path('../../data/cpu_counters.pb'),
-        query=Path('proxy_power_test.sql'),
+        query="""
+SELECT RUN_METRIC('android/android_proxy_power.sql');
+
+DROP VIEW device;
+
+CREATE TABLE device (name STRING);
+
+INSERT INTO device VALUES ('walleye');
+
+SELECT
+  tid,
+  SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
+FROM power_per_thread
+JOIN thread USING (utid)
+GROUP BY utid
+ORDER BY power_mas DESC
+LIMIT 10;
+""",
         out=Path('proxy_power.out'))
diff --git a/test/trace_processor/span_join/index.py b/test/trace_processor/span_join/index.py
index c5bba0b..2c39a63 100644
--- a/test/trace_processor/span_join/index.py
+++ b/test/trace_processor/span_join/index.py
@@ -74,7 +74,29 @@
   def test_span_join_unpartitioned_empty(self):
     return DiffTestBlueprint(
         trace=Path('../../data/android_sched_and_ps.pb'),
-        query=Path('span_join_unpartitioned_empty_test.sql'),
+        query="""
+CREATE TABLE t1(
+  ts BIGINT,
+  dur BIGINT,
+  PRIMARY KEY (ts, dur)
+) WITHOUT ROWID;
+
+CREATE TABLE t2(
+  ts BIGINT,
+  dur BIGINT,
+  PRIMARY KEY (ts, dur)
+) WITHOUT ROWID;
+
+INSERT INTO t2(ts, dur)
+VALUES
+(1, 2),
+(5, 0),
+(1, 1);
+
+CREATE VIRTUAL TABLE sp USING span_join(t1, t2);
+
+SELECT ts, dur FROM sp;
+""",
         out=Csv("""
 "ts","dur"
 """))
@@ -88,7 +110,30 @@
   def test_span_outer_join_empty(self):
     return DiffTestBlueprint(
         trace=Path('../common/synth_1.py'),
-        query=Path('span_outer_join_empty_test.sql'),
+        query="""
+CREATE TABLE t1(
+  ts BIGINT,
+  dur BIGINT,
+  part BIGINT,
+  PRIMARY KEY (part, ts)
+) WITHOUT ROWID;
+
+CREATE TABLE t2(
+  ts BIGINT,
+  dur BIGINT,
+  part BIGINT,
+  PRIMARY KEY (part, ts)
+) WITHOUT ROWID;
+
+INSERT INTO t1(ts, dur, part)
+VALUES (500, 100, 10);
+
+
+CREATE VIRTUAL TABLE sp USING span_outer_join(t1 PARTITIONED part,
+                                              t2 PARTITIONED part);
+
+SELECT * FROM sp;
+""",
         out=Csv("""
 "ts","dur","part"
 500,100,10
@@ -97,7 +142,24 @@
   def test_span_outer_join_unpartitioned_empty(self):
     return DiffTestBlueprint(
         trace=Path('../common/synth_1.py'),
-        query=Path('span_outer_join_unpartitioned_empty_test.sql'),
+        query="""
+CREATE TABLE t1(
+  ts BIGINT,
+  dur BIGINT,
+  PRIMARY KEY (ts)
+) WITHOUT ROWID;
+
+CREATE TABLE t2(
+  ts BIGINT,
+  dur BIGINT,
+  PRIMARY KEY (ts)
+) WITHOUT ROWID;
+
+
+CREATE VIRTUAL TABLE sp USING span_outer_join(t1, t2);
+
+SELECT * FROM sp;
+""",
         out=Csv("""
 "ts","dur"
 """))
@@ -105,7 +167,29 @@
   def test_span_outer_join_unpartitioned_left_empty(self):
     return DiffTestBlueprint(
         trace=Path('../common/synth_1.py'),
-        query=Path('span_outer_join_unpartitioned_left_empty_test.sql'),
+        query="""
+CREATE TABLE t1(
+  ts BIGINT,
+  dur BIGINT,
+  PRIMARY KEY (ts)
+) WITHOUT ROWID;
+
+CREATE TABLE t2(
+  ts BIGINT,
+  dur BIGINT,
+  PRIMARY KEY (ts)
+) WITHOUT ROWID;
+
+INSERT INTO t2(ts, dur)
+VALUES
+(100, 400),
+(500, 50),
+(600, 100);
+
+CREATE VIRTUAL TABLE sp USING span_outer_join(t1, t2);
+
+SELECT * FROM sp;
+""",
         out=Csv("""
 "ts","dur"
 100,400
@@ -116,7 +200,29 @@
   def test_span_outer_join_unpartitioned_right_empty(self):
     return DiffTestBlueprint(
         trace=Path('../common/synth_1.py'),
-        query=Path('span_outer_join_unpartitioned_right_empty_test.sql'),
+        query="""
+CREATE TABLE t1(
+  ts BIGINT,
+  dur BIGINT,
+  PRIMARY KEY (ts)
+) WITHOUT ROWID;
+
+CREATE TABLE t2(
+  ts BIGINT,
+  dur BIGINT,
+  PRIMARY KEY (ts)
+) WITHOUT ROWID;
+
+INSERT INTO t1(ts, dur)
+VALUES
+(100, 400),
+(500, 50),
+(600, 100);
+
+CREATE VIRTUAL TABLE sp USING span_outer_join(t1, t2);
+
+SELECT * FROM sp;
+""",
         out=Csv("""
 "ts","dur"
 100,400
@@ -133,7 +239,25 @@
   def test_span_outer_join_mixed_empty(self):
     return DiffTestBlueprint(
         trace=Path('../common/synth_1.py'),
-        query=Path('span_outer_join_mixed_empty_test.sql'),
+        query="""
+CREATE TABLE t1(
+  ts BIGINT,
+  dur BIGINT,
+  part BIGINT,
+  PRIMARY KEY (part, ts)
+) WITHOUT ROWID;
+
+CREATE TABLE t2(
+  ts BIGINT,
+  dur BIGINT,
+  PRIMARY KEY (ts)
+) WITHOUT ROWID;
+
+
+CREATE VIRTUAL TABLE sp USING span_outer_join(t1 PARTITIONED part, t2);
+
+SELECT * FROM sp;
+""",
         out=Csv("""
 "ts","dur","part"
 """))
@@ -141,7 +265,30 @@
   def test_span_outer_join_mixed_left_empty(self):
     return DiffTestBlueprint(
         trace=Path('../common/synth_1.py'),
-        query=Path('span_outer_join_mixed_left_empty_test.sql'),
+        query="""
+CREATE TABLE t1(
+  ts BIGINT,
+  dur BIGINT,
+  part BIGINT,
+  PRIMARY KEY (part, ts)
+) WITHOUT ROWID;
+
+CREATE TABLE t2(
+  ts BIGINT,
+  dur BIGINT,
+  PRIMARY KEY (ts)
+) WITHOUT ROWID;
+
+INSERT INTO t2(ts, dur)
+VALUES
+(100, 400),
+(500, 50),
+(600, 100);
+
+CREATE VIRTUAL TABLE sp USING span_outer_join(t1 PARTITIONED part, t2);
+
+SELECT * FROM sp;
+""",
         out=Csv("""
 "ts","dur","part"
 """))
@@ -149,7 +296,30 @@
   def test_span_outer_join_mixed_left_empty_rev(self):
     return DiffTestBlueprint(
         trace=Path('../common/synth_1.py'),
-        query=Path('span_outer_join_mixed_left_empty_rev_test.sql'),
+        query="""
+CREATE TABLE t1(
+  ts BIGINT,
+  dur BIGINT,
+  part BIGINT,
+  PRIMARY KEY (part, ts)
+) WITHOUT ROWID;
+
+CREATE TABLE t2(
+  ts BIGINT,
+  dur BIGINT,
+  PRIMARY KEY (ts)
+) WITHOUT ROWID;
+
+INSERT INTO t1(ts, dur, part)
+VALUES
+(100, 400, 0),
+(100, 50, 1),
+(600, 100, 1);
+
+CREATE VIRTUAL TABLE sp USING span_outer_join(t2, t1 PARTITIONED part);
+
+SELECT * FROM sp;
+""",
         out=Csv("""
 "ts","dur","part"
 100,400,0
@@ -160,7 +330,31 @@
   def test_span_outer_join_mixed_right_empty(self):
     return DiffTestBlueprint(
         trace=Path('../common/synth_1.py'),
-        query=Path('span_outer_join_mixed_right_empty_test.sql'),
+        query="""
+CREATE TABLE t1(
+  ts BIGINT,
+  dur BIGINT,
+  part BIGINT,
+  PRIMARY KEY (part, ts)
+) WITHOUT ROWID;
+
+CREATE TABLE t2(
+  ts BIGINT,
+  dur BIGINT,
+  b BIGINT,
+  PRIMARY KEY (ts)
+) WITHOUT ROWID;
+
+INSERT INTO t1(ts, dur, part)
+VALUES
+(100, 400, 0),
+(100, 50, 1),
+(600, 100, 1);
+
+CREATE VIRTUAL TABLE sp USING span_outer_join(t1 PARTITIONED part, t2);
+
+SELECT * FROM sp;
+""",
         out=Csv("""
 "ts","dur","part","b"
 100,400,0,"[NULL]"
@@ -171,7 +365,31 @@
   def test_span_outer_join_mixed_right_empty_rev(self):
     return DiffTestBlueprint(
         trace=Path('../common/synth_1.py'),
-        query=Path('span_outer_join_mixed_right_empty_rev_test.sql'),
+        query="""
+CREATE TABLE t1(
+  ts BIGINT,
+  dur BIGINT,
+  part BIGINT,
+  PRIMARY KEY (part, ts)
+) WITHOUT ROWID;
+
+CREATE TABLE t2(
+  ts BIGINT,
+  dur BIGINT,
+  b BIGINT,
+  PRIMARY KEY (ts)
+) WITHOUT ROWID;
+
+INSERT INTO t2(ts, dur)
+VALUES
+(100, 400),
+(500, 50),
+(600, 100);
+
+CREATE VIRTUAL TABLE sp USING span_outer_join(t2, t1 PARTITIONED part);
+
+SELECT * FROM sp;
+""",
         out=Csv("""
 "ts","dur","part","b"
 """))
@@ -209,7 +427,30 @@
   def test_span_left_join_empty_right(self):
     return DiffTestBlueprint(
         trace=Path('../common/synth_1.py'),
-        query=Path('span_left_join_empty_right_test.sql'),
+        query="""
+CREATE TABLE t1(
+  ts BIGINT,
+  dur BIGINT,
+  part BIGINT,
+  PRIMARY KEY (part, ts)
+) WITHOUT ROWID;
+
+CREATE TABLE t2(
+  ts BIGINT,
+  dur BIGINT,
+  part BIGINT,
+  PRIMARY KEY (part, ts)
+) WITHOUT ROWID;
+
+INSERT INTO t1(ts, dur, part)
+VALUES
+(500, 500, 100);
+
+CREATE VIRTUAL TABLE sp USING span_left_join(t1 PARTITIONED part,
+                                             t2 PARTITIONED part);
+
+SELECT * FROM sp;
+""",
         out=Csv("""
 "ts","dur","part"
 500,500,100
@@ -218,7 +459,32 @@
   def test_span_left_join_unordered_android_sched_and_ps(self):
     return DiffTestBlueprint(
         trace=Path('../common/synth_1.py'),
-        query=Path('span_left_join_unordered_test.sql'),
+        query="""
+CREATE TABLE t1(
+  ts BIGINT,
+  dur BIGINT,
+  part BIGINT,
+  PRIMARY KEY (part, ts)
+) WITHOUT ROWID;
+
+CREATE TABLE t2(
+  ts BIGINT,
+  dur BIGINT,
+  part BIGINT,
+  PRIMARY KEY (part, ts)
+) WITHOUT ROWID;
+
+INSERT INTO t1(ts, dur, part)
+VALUES (500, 100, 10);
+
+INSERT INTO t2(ts, dur, part)
+VALUES (500, 100, 5);
+
+CREATE VIRTUAL TABLE sp USING span_left_join(t1 PARTITIONED part,
+                                             t2 PARTITIONED part);
+
+SELECT * FROM sp;
+""",
         out=Csv("""
 "ts","dur","part"
 500,100,10
diff --git a/test/trace_processor/startup/index.py b/test/trace_processor/startup/index.py
index f7d5d96..647591c 100644
--- a/test/trace_processor/startup/index.py
+++ b/test/trace_processor/startup/index.py
@@ -115,7 +115,36 @@
     return DiffTestBlueprint(
         trace=Path('android_startup_battery.py'),
         query=Metric('android_batt'),
-        out=Path('android_batt_counters.out'))
+        out=TextProto(r"""
+android_batt{
+   battery_counters{
+      timestamp_ns: 20
+      charge_counter_uah: 52
+      capacity_percent: 0.2
+      current_ua: 10
+      current_avg_ua: 12
+   }
+   battery_counters {
+      timestamp_ns: 52
+      charge_counter_uah: 32
+      capacity_percent: 0.8
+      current_ua: 8
+      current_avg_ua: 93
+   }
+   battery_counters {
+      timestamp_ns: 80
+      charge_counter_uah: 15
+      capacity_percent: 0.5
+      current_ua: 9
+      current_avg_ua: 5
+   }
+   battery_counters {
+      timestamp_ns: 92
+      charge_counter_uah: 21
+      capacity_percent: 0.3
+      current_avg_ua: 25
+   }
+}"""))
 
   def test_android_startup_cpu(self):
     return DiffTestBlueprint(
diff --git a/test/trace_processor/tables/index.py b/test/trace_processor/tables/index.py
index c589a28..b4fde95 100644
--- a/test/trace_processor/tables/index.py
+++ b/test/trace_processor/tables/index.py
@@ -24,7 +24,9 @@
   def test_android_sched_and_ps_smoke_window(self):
     return DiffTestBlueprint(
         trace=Path('../../data/android_sched_and_ps.pb'),
-        query=Path('smoke_window_test.sql'),
+        query="""
+SELECT * FROM "window";
+""",
         out=Csv("""
 "ts","dur","quantum_ts"
 0,9223372036854775807,0
@@ -33,7 +35,15 @@
   def test_synth_1_filter_sched(self):
     return DiffTestBlueprint(
         trace=Path('../common/synth_1.py'),
-        query=Path('filter_sched_test.sql'),
+        query="""
+SELECT ts, cpu, dur FROM sched
+WHERE
+  cpu = 1
+  AND dur > 50
+  AND dur <= 100
+  AND ts >= 100
+  AND ts <= 400;
+""",
         out=Csv("""
 "ts","cpu","dur"
 170,1,80
@@ -42,7 +52,9 @@
   def test_android_sched_and_ps_b119496959(self):
     return DiffTestBlueprint(
         trace=Path('../../data/android_sched_and_ps.pb'),
-        query=Path('b119496959_test.sql'),
+        query="""
+SELECT ts, cpu FROM sched WHERE ts >= 81473797418963 LIMIT 10;
+""",
         out=Csv("""
 "ts","cpu"
 81473797824982,3
@@ -60,7 +72,11 @@
   def test_android_sched_and_ps_b119301023(self):
     return DiffTestBlueprint(
         trace=Path('../../data/android_sched_and_ps.pb'),
-        query=Path('b119301023_test.sql'),
+        query="""
+SELECT ts FROM sched
+WHERE ts > 0.1 + 1e9
+LIMIT 10;
+""",
         out=Csv("""
 "ts"
 81473010031230
@@ -78,7 +94,12 @@
   def test_synth_1_filter_counter(self):
     return DiffTestBlueprint(
         trace=Path('../common/synth_1.py'),
-        query=Path('filter_counter_test.sql'),
+        query="""
+SELECT COUNT(*)
+FROM counter
+WHERE
+  track_id = 0;
+""",
         out=Csv("""
 "COUNT(*)"
 2
@@ -87,7 +108,9 @@
   def test_memory_counters_b120278869_neg_ts_end(self):
     return DiffTestBlueprint(
         trace=Path('../../data/memory_counters.pb'),
-        query=Path('b120278869_neg_ts_end_test.sql'),
+        query="""
+SELECT count(*) FROM counters WHERE -1 < ts;
+""",
         out=Csv("""
 "count(*)"
 98688
@@ -96,7 +119,15 @@
   def test_counters_where_cpu_counters_where_cpu(self):
     return DiffTestBlueprint(
         trace=Path('counters_where_cpu.py'),
-        query=Path('counters_where_cpu_test.sql'),
+        query="""
+SELECT
+  ts,
+  lead(ts, 1, ts) OVER (PARTITION BY name ORDER BY ts) - ts AS dur,
+  value
+FROM counter c
+JOIN cpu_counter_track t ON t.id = c.track_id
+WHERE cpu = 1;
+""",
         out=Csv("""
 "ts","dur","value"
 1000,1,3000.000000
@@ -106,7 +137,20 @@
   def test_counters_group_by_freq_counters_group_by_freq(self):
     return DiffTestBlueprint(
         trace=Path('counters_group_by_freq.py'),
-        query=Path('counters_group_by_freq_test.sql'),
+        query="""
+SELECT
+  value,
+  sum(dur) AS dur_sum
+FROM (
+  SELECT value,
+    lead(ts) OVER (PARTITION BY name, track_id ORDER BY ts) - ts AS dur
+  FROM counter
+  JOIN counter_track ON counter.track_id = counter_track.id
+)
+WHERE value > 0
+GROUP BY value
+ORDER BY dur_sum DESC;
+""",
         out=Csv("""
 "value","dur_sum"
 4000.000000,2
@@ -116,7 +160,22 @@
   def test_filter_row_vector_example_android_trace_30s(self):
     return DiffTestBlueprint(
         trace=Path('../../data/example_android_trace_30s.pb'),
-        query=Path('filter_row_vector_test.sql'),
+        query="""
+SELECT ts
+FROM counter
+WHERE
+  ts > 72563651549
+  AND track_id = (
+    SELECT t.id
+    FROM process_counter_track t
+    JOIN process p USING (upid)
+    WHERE
+      t.name = 'Heap size (KB)'
+      AND p.pid = 1204
+  )
+  AND value != 17952.000000
+LIMIT 20;
+""",
         out=Path('filter_row_vector_example_android_trace_30s.out'))
 
   def test_counter_dur_example_android_trace_30s(self):
@@ -140,13 +199,48 @@
   def test_nulls(self):
     return DiffTestBlueprint(
         trace=Path('../common/synth_1.py'),
-        query=Path('nulls_test.sql'),
+        query="""
+CREATE TABLE null_test (
+  primary_key INTEGER PRIMARY KEY,
+  int_nulls INTEGER,
+  string_nulls STRING,
+  double_nulls DOUBLE,
+  start_int_nulls INTEGER,
+  start_string_nulls STRING,
+  start_double_nulls DOUBLE,
+  all_nulls INTEGER
+);
+
+INSERT INTO null_test(
+  int_nulls,
+  string_nulls,
+  double_nulls,
+  start_int_nulls,
+  start_string_nulls,
+  start_double_nulls
+)
+VALUES
+(1, "test", 2.0, NULL, NULL, NULL),
+(2, NULL, NULL, NULL, "test", NULL),
+(1, "other", NULL, NULL, NULL, NULL),
+(4, NULL, NULL, NULL, NULL, 1.0),
+(NULL, "test", 1.0, 1, NULL, NULL);
+
+SELECT * FROM null_test;
+""",
         out=Path('nulls.out'))
 
   def test_thread_main_thread(self):
     return DiffTestBlueprint(
         trace=Path('thread_main_thread.textproto'),
-        query=Path('thread_main_thread_test.sql'),
+        query="""
+SELECT
+  tid,
+  is_main_thread
+FROM thread
+WHERE tid IN (5, 7, 11, 12, 99)
+ORDER BY tid;
+""",
         out=Csv("""
 "tid","is_main_thread"
 5,1
@@ -185,7 +279,11 @@
   def test_ftrace_setup_errors(self):
     return DiffTestBlueprint(
         trace=Path('../../data/ftrace_error_stats.pftrace'),
-        query=Path('ftrace_setup_errors_test.sql'),
+        query="""
+SELECT value FROM stats WHERE name = 'ftrace_setup_errors'
+UNION ALL
+SELECT str_value FROM metadata WHERE name = 'ftrace_setup_errors';
+""",
         out=Csv("""
 "value"
 3
diff --git a/test/trace_processor/track_event/index.py b/test/trace_processor/track_event/index.py
index a54bde6..fbc493f 100644
--- a/test/trace_processor/track_event/index.py
+++ b/test/trace_processor/track_event/index.py
@@ -24,7 +24,13 @@
   def test_track_event_same_tids_threads(self):
     return DiffTestBlueprint(
         trace=Path('track_event_same_tids.textproto'),
-        query=Path('../common/process_tracking_test.sql'),
+        query="""
+SELECT tid, pid, process.name AS pname, thread.name AS tname
+FROM thread
+LEFT JOIN process USING(upid)
+WHERE tid > 0
+ORDER BY tid;
+""",
         out=Csv("""
 "tid","pid","pname","tname"
 1,5,"[NULL]","t1"
@@ -36,7 +42,25 @@
   def test_track_event_same_tids_slices(self):
     return DiffTestBlueprint(
         trace=Path('track_event_same_tids.textproto'),
-        query=Path('track_event_slices_test.sql'),
+        query="""
+SELECT
+  track.name AS track,
+  process.name AS process,
+  thread.name AS thread,
+  thread_process.name AS thread_process,
+  slice.ts,
+  slice.dur,
+  slice.category,
+  slice.name
+FROM slice
+LEFT JOIN track ON slice.track_id = track.id
+LEFT JOIN process_track ON slice.track_id = process_track.id
+LEFT JOIN process ON process_track.upid = process.upid
+LEFT JOIN thread_track ON slice.track_id = thread_track.id
+LEFT JOIN thread ON thread_track.utid = thread.utid
+LEFT JOIN process thread_process ON thread.upid = thread_process.upid
+ORDER BY ts ASC;
+""",
         out=Csv("""
 "track","process","thread","thread_process","ts","dur","category","name"
 "[NULL]","[NULL]","t1","[NULL]",1000,0,"cat","name1"
@@ -46,7 +70,25 @@
   def test_track_event_typed_args_slices(self):
     return DiffTestBlueprint(
         trace=Path('track_event_typed_args.textproto'),
-        query=Path('track_event_slices_test.sql'),
+        query="""
+SELECT
+  track.name AS track,
+  process.name AS process,
+  thread.name AS thread,
+  thread_process.name AS thread_process,
+  slice.ts,
+  slice.dur,
+  slice.category,
+  slice.name
+FROM slice
+LEFT JOIN track ON slice.track_id = track.id
+LEFT JOIN process_track ON slice.track_id = process_track.id
+LEFT JOIN process ON process_track.upid = process.upid
+LEFT JOIN thread_track ON slice.track_id = thread_track.id
+LEFT JOIN thread ON thread_track.utid = thread.utid
+LEFT JOIN process thread_process ON thread.upid = thread_process.upid
+ORDER BY ts ASC;
+""",
         out=Csv("""
 "track","process","thread","thread_process","ts","dur","category","name"
 "[NULL]","[NULL]","t1","[NULL]",1000,0,"cat","name1"
@@ -66,13 +108,37 @@
   def test_track_event_tracks_slices(self):
     return DiffTestBlueprint(
         trace=Path('track_event_tracks.textproto'),
-        query=Path('track_event_slices_test.sql'),
+        query="""
+SELECT
+  track.name AS track,
+  process.name AS process,
+  thread.name AS thread,
+  thread_process.name AS thread_process,
+  slice.ts,
+  slice.dur,
+  slice.category,
+  slice.name
+FROM slice
+LEFT JOIN track ON slice.track_id = track.id
+LEFT JOIN process_track ON slice.track_id = process_track.id
+LEFT JOIN process ON process_track.upid = process.upid
+LEFT JOIN thread_track ON slice.track_id = thread_track.id
+LEFT JOIN thread ON thread_track.utid = thread.utid
+LEFT JOIN process thread_process ON thread.upid = thread_process.upid
+ORDER BY ts ASC;
+""",
         out=Path('track_event_tracks_slices.out'))
 
   def test_track_event_tracks_processes(self):
     return DiffTestBlueprint(
         trace=Path('track_event_tracks.textproto'),
-        query=Path('track_event_processes_test.sql'),
+        query="""
+SELECT
+  id,
+  name,
+  extract_arg(arg_set_id, "chrome.host_app_package_name") AS host_app
+FROM process;
+""",
         out=Csv("""
 "id","name","host_app"
 0,"[NULL]","[NULL]"
@@ -83,7 +149,31 @@
   def test_track_event_tracks(self):
     return DiffTestBlueprint(
         trace=Path('track_event_tracks.textproto'),
-        query=Path('track_event_tracks_test.sql'),
+        query="""
+WITH track_with_name AS (
+  SELECT
+    COALESCE(
+      t1.name,
+      'thread=' || thread.name,
+      'process=' || process.name,
+      'tid=' || thread.tid,
+      'pid=' || process.pid
+    ) AS full_name,
+    *
+  FROM track t1
+  LEFT JOIN thread_track t2 USING (id)
+  LEFT JOIN thread USING (utid)
+  LEFT JOIN process_track t3 USING (id)
+  LEFT JOIN process ON t3.upid = process.id
+  ORDER BY id
+)
+SELECT t1.full_name AS name, t2.full_name AS parent_name,
+       EXTRACT_ARG(t1.source_arg_set_id, 'has_first_packet_on_sequence')
+       AS has_first_packet_on_sequence
+FROM track_with_name t1
+LEFT JOIN track_with_name t2 ON t1.parent_id = t2.id
+ORDER BY 1, 2;
+""",
         out=Csv("""
 "name","parent_name","has_first_packet_on_sequence"
 "Default Track","[NULL]","[NULL]"
@@ -104,7 +194,25 @@
   def test_track_event_instant_slices(self):
     return DiffTestBlueprint(
         trace=Path('track_event_instant.textproto'),
-        query=Path('track_event_slices_test.sql'),
+        query="""
+SELECT
+  track.name AS track,
+  process.name AS process,
+  thread.name AS thread,
+  thread_process.name AS thread_process,
+  slice.ts,
+  slice.dur,
+  slice.category,
+  slice.name
+FROM slice
+LEFT JOIN track ON slice.track_id = track.id
+LEFT JOIN process_track ON slice.track_id = process_track.id
+LEFT JOIN process ON process_track.upid = process.upid
+LEFT JOIN thread_track ON slice.track_id = thread_track.id
+LEFT JOIN thread ON thread_track.utid = thread.utid
+LEFT JOIN process thread_process ON thread.upid = thread_process.upid
+ORDER BY ts ASC;
+""",
         out=Csv("""
 "track","process","thread","thread_process","ts","dur","category","name"
 "[NULL]","[NULL]","t1","[NULL]",1000,0,"cat","instant_on_t1"
@@ -115,13 +223,53 @@
   def test_legacy_async_event(self):
     return DiffTestBlueprint(
         trace=Path('legacy_async_event.textproto'),
-        query=Path('track_event_slice_with_args_test.sql'),
+        query="""
+SELECT
+  track.name AS track,
+  process.name AS process,
+  thread.name AS thread,
+  thread_process.name AS thread_process,
+  slice.ts,
+  slice.dur,
+  slice.category,
+  slice.name,
+  args.key,
+  args.string_value,
+  args.int_value
+FROM slice
+LEFT JOIN track ON slice.track_id = track.id
+LEFT JOIN process_track ON slice.track_id = process_track.id
+LEFT JOIN process ON process_track.upid = process.upid
+LEFT JOIN thread_track ON slice.track_id = thread_track.id
+LEFT JOIN thread ON thread_track.utid = thread.utid
+LEFT JOIN process thread_process ON thread.upid = thread_process.upid
+LEFT JOIN args ON slice.arg_set_id = args.arg_set_id
+ORDER BY ts ASC;
+""",
         out=Path('legacy_async_event.out'))
 
   def test_track_event_with_atrace(self):
     return DiffTestBlueprint(
         trace=Path('track_event_with_atrace.textproto'),
-        query=Path('track_event_slices_test.sql'),
+        query="""
+SELECT
+  track.name AS track,
+  process.name AS process,
+  thread.name AS thread,
+  thread_process.name AS thread_process,
+  slice.ts,
+  slice.dur,
+  slice.category,
+  slice.name
+FROM slice
+LEFT JOIN track ON slice.track_id = track.id
+LEFT JOIN process_track ON slice.track_id = process_track.id
+LEFT JOIN process ON process_track.upid = process.upid
+LEFT JOIN thread_track ON slice.track_id = thread_track.id
+LEFT JOIN thread ON thread_track.utid = thread.utid
+LEFT JOIN process thread_process ON thread.upid = thread_process.upid
+ORDER BY ts ASC;
+""",
         out=Csv("""
 "track","process","thread","thread_process","ts","dur","category","name"
 "[NULL]","[NULL]","t1","[NULL]",10000,1000,"cat","event1"
@@ -138,7 +286,25 @@
   def test_track_event_counters_slices(self):
     return DiffTestBlueprint(
         trace=Path('track_event_counters.textproto'),
-        query=Path('track_event_slices_test.sql'),
+        query="""
+SELECT
+  track.name AS track,
+  process.name AS process,
+  thread.name AS thread,
+  thread_process.name AS thread_process,
+  slice.ts,
+  slice.dur,
+  slice.category,
+  slice.name
+FROM slice
+LEFT JOIN track ON slice.track_id = track.id
+LEFT JOIN process_track ON slice.track_id = process_track.id
+LEFT JOIN process ON process_track.upid = process.upid
+LEFT JOIN thread_track ON slice.track_id = thread_track.id
+LEFT JOIN thread ON thread_track.utid = thread.utid
+LEFT JOIN process thread_process ON thread.upid = thread_process.upid
+ORDER BY ts ASC;
+""",
         out=Csv("""
 "track","process","thread","thread_process","ts","dur","category","name"
 "[NULL]","[NULL]","t1","Browser",1000,100,"cat","event1_on_t1"
@@ -153,13 +319,48 @@
   def test_track_event_counters_counters(self):
     return DiffTestBlueprint(
         trace=Path('track_event_counters.textproto'),
-        query=Path('track_event_counters_test.sql'),
+        query="""
+SELECT
+  counter_track.name AS counter_name,
+  process.name AS process,
+  thread.name AS thread,
+  thread_process.name AS thread_process,
+  counter_track.unit AS unit,
+  counter.ts,
+  counter.value
+FROM counter
+LEFT JOIN counter_track ON counter.track_id = counter_track.id
+LEFT JOIN process_counter_track ON counter.track_id = process_counter_track.id
+LEFT JOIN process ON process_counter_track.upid = process.upid
+LEFT JOIN thread_counter_track ON counter.track_id = thread_counter_track.id
+LEFT JOIN thread ON thread_counter_track.utid = thread.utid
+LEFT JOIN process thread_process ON thread.upid = thread_process.upid
+ORDER BY ts ASC;
+""",
         out=Path('track_event_counters_counters.out'))
 
   def test_track_event_monotonic_trace_clock_slices(self):
     return DiffTestBlueprint(
         trace=Path('track_event_monotonic_trace_clock.textproto'),
-        query=Path('track_event_slices_test.sql'),
+        query="""
+SELECT
+  track.name AS track,
+  process.name AS process,
+  thread.name AS thread,
+  thread_process.name AS thread_process,
+  slice.ts,
+  slice.dur,
+  slice.category,
+  slice.name
+FROM slice
+LEFT JOIN track ON slice.track_id = track.id
+LEFT JOIN process_track ON slice.track_id = process_track.id
+LEFT JOIN process ON process_track.upid = process.upid
+LEFT JOIN thread_track ON slice.track_id = thread_track.id
+LEFT JOIN thread ON thread_track.utid = thread.utid
+LEFT JOIN process thread_process ON thread.upid = thread_process.upid
+ORDER BY ts ASC;
+""",
         out=Csv("""
 "track","process","thread","thread_process","ts","dur","category","name"
 "name1","[NULL]","[NULL]","[NULL]",1000,0,"cat","name1"
@@ -175,7 +376,11 @@
   def test_flow_events_track_event(self):
     return DiffTestBlueprint(
         trace=Path('flow_events_track_event.textproto'),
-        query=Path('flow_events_test.sql'),
+        query="""
+SELECT t1.name AS slice_out, t2.name AS slice_in FROM flow t
+JOIN slice t1 ON t.slice_out = t1.slice_id
+JOIN slice t2 ON t.slice_in = t2.slice_id;
+""",
         out=Csv("""
 "slice_out","slice_in"
 "FlowSlice1Start","FlowSlice1End"
@@ -190,7 +395,11 @@
   def test_flow_events_proto_v2(self):
     return DiffTestBlueprint(
         trace=Path('flow_events_proto_v2.textproto'),
-        query=Path('flow_events_test.sql'),
+        query="""
+SELECT t1.name AS slice_out, t2.name AS slice_in FROM flow t
+JOIN slice t1 ON t.slice_out = t1.slice_id
+JOIN slice t2 ON t.slice_in = t2.slice_id;
+""",
         out=Csv("""
 "slice_out","slice_in"
 "FlowBeginSlice","FlowEndSlice_1"
@@ -201,7 +410,11 @@
   def test_flow_events_proto_v1(self):
     return DiffTestBlueprint(
         trace=Path('flow_events_proto_v1.textproto'),
-        query=Path('flow_events_test.sql'),
+        query="""
+SELECT t1.name AS slice_out, t2.name AS slice_in FROM flow t
+JOIN slice t1 ON t.slice_out = t1.slice_id
+JOIN slice t2 ON t.slice_in = t2.slice_id;
+""",
         out=Csv("""
 "slice_out","slice_in"
 "FlowBeginSlice","FlowEndSlice_1"
@@ -212,7 +425,10 @@
   def test_experimental_slice_layout_depth(self):
     return DiffTestBlueprint(
         trace=Path('experimental_slice_layout_depth.py'),
-        query=Path('experimental_slice_layout_depth_test.sql'),
+        query="""
+SELECT layout_depth FROM experimental_slice_layout
+WHERE filter_track_ids = (SELECT group_concat(track_id, ',') FROM slice);
+""",
         out=Csv("""
 "layout_depth"
 0
@@ -223,7 +439,9 @@
   def test_merging_regression(self):
     return DiffTestBlueprint(
         trace=Path('../../data/trace_with_descriptor.pftrace'),
-        query=Path('merging_regression_test.sql'),
+        query="""
+SELECT ts FROM slice ORDER BY ts LIMIT 10;
+""",
         out=Csv("""
 "ts"
 605361018360000
@@ -241,7 +459,11 @@
   def test_range_of_interest(self):
     return DiffTestBlueprint(
         trace=Path('range_of_interest.textproto'),
-        query=Path('range_of_interest_test.sql'),
+        query="""
+SELECT ts, name
+FROM slice
+ORDER BY ts;
+""",
         out=Csv("""
 "ts","name"
 12000,"slice3"
diff --git a/test/trace_processor/track_event/track_event_args_test.sql b/test/trace_processor/track_event/track_event_args_test.sql
index a760456..7d8ced6 100644
--- a/test/trace_processor/track_event/track_event_args_test.sql
+++ b/test/trace_processor/track_event/track_event_args_test.sql
@@ -13,4 +13,4 @@
 -- See the License for the specific language governing permissions and
 -- limitations under the License.
 --
-SELECT flat_key, key, int_value, string_value FROM args ORDER BY arg_set_id, key ASC;
+SELECT flat_key, key, int_value, string_value FROM args ORDER BY key, display_value, arg_set_id, key ASC;
diff --git a/test/trace_processor/track_event/track_event_chrome_histogram_sample_args.out b/test/trace_processor/track_event/track_event_chrome_histogram_sample_args.out
index c2265c9..4cf08d4 100644
--- a/test/trace_processor/track_event/track_event_chrome_histogram_sample_args.out
+++ b/test/trace_processor/track_event/track_event_chrome_histogram_sample_args.out
@@ -1,24 +1,26 @@
 "flat_key","key","int_value","string_value"
+"chrome_histogram_sample.name","chrome_histogram_sample.name","[NULL]","Compositing.Display.DrawToSwapUs"
+"chrome_histogram_sample.name","chrome_histogram_sample.name","[NULL]","CompositorLatency.TotalLatency"
+"chrome_histogram_sample.name","chrome_histogram_sample.name","[NULL]","Graphics.Smoothness.Checkerboarding.MainThreadAnimation"
+"chrome_histogram_sample.name","chrome_histogram_sample.name","[NULL]","Memory.GPU.PeakMemoryUsage.PageLoad"
+"chrome_histogram_sample.name_hash","chrome_histogram_sample.name_hash",10,"[NULL]"
+"chrome_histogram_sample.name_hash","chrome_histogram_sample.name_hash",20,"[NULL]"
+"chrome_histogram_sample.name_hash","chrome_histogram_sample.name_hash",30,"[NULL]"
+"chrome_histogram_sample.name_hash","chrome_histogram_sample.name_hash",40,"[NULL]"
+"chrome_histogram_sample.name_hash","chrome_histogram_sample.name_hash",50,"[NULL]"
+"chrome_histogram_sample.name_hash","chrome_histogram_sample.name_hash",60,"[NULL]"
+"chrome_histogram_sample.name_iid","chrome_histogram_sample.name_iid",1,"[NULL]"
+"chrome_histogram_sample.name_iid","chrome_histogram_sample.name_iid",2,"[NULL]"
+"chrome_histogram_sample.name_iid","chrome_histogram_sample.name_iid",3,"[NULL]"
+"chrome_histogram_sample.name_iid","chrome_histogram_sample.name_iid",4,"[NULL]"
+"chrome_histogram_sample.sample","chrome_histogram_sample.sample",100,"[NULL]"
+"chrome_histogram_sample.sample","chrome_histogram_sample.sample",200,"[NULL]"
+"chrome_histogram_sample.sample","chrome_histogram_sample.sample",300,"[NULL]"
+"chrome_histogram_sample.sample","chrome_histogram_sample.sample",400,"[NULL]"
+"chrome_histogram_sample.sample","chrome_histogram_sample.sample",500,"[NULL]"
+"chrome_histogram_sample.sample","chrome_histogram_sample.sample",600,"[NULL]"
+"event.category","event.category","[NULL]","disabled-by-default-histogram_samples"
+"event.name","event.name","[NULL]","[NULL]"
 "is_root_in_scope","is_root_in_scope",1,"[NULL]"
 "source","source","[NULL]","descriptor"
 "source_id","source_id",0,"[NULL]"
-"chrome_histogram_sample.name","chrome_histogram_sample.name","[NULL]","Compositing.Display.DrawToSwapUs"
-"chrome_histogram_sample.name_hash","chrome_histogram_sample.name_hash",10,"[NULL]"
-"chrome_histogram_sample.name_iid","chrome_histogram_sample.name_iid",1,"[NULL]"
-"chrome_histogram_sample.sample","chrome_histogram_sample.sample",100,"[NULL]"
-"chrome_histogram_sample.name","chrome_histogram_sample.name","[NULL]","CompositorLatency.TotalLatency"
-"chrome_histogram_sample.name_hash","chrome_histogram_sample.name_hash",20,"[NULL]"
-"chrome_histogram_sample.name_iid","chrome_histogram_sample.name_iid",2,"[NULL]"
-"chrome_histogram_sample.sample","chrome_histogram_sample.sample",200,"[NULL]"
-"chrome_histogram_sample.name","chrome_histogram_sample.name","[NULL]","Graphics.Smoothness.Checkerboarding.MainThreadAnimation"
-"chrome_histogram_sample.name_hash","chrome_histogram_sample.name_hash",30,"[NULL]"
-"chrome_histogram_sample.name_iid","chrome_histogram_sample.name_iid",3,"[NULL]"
-"chrome_histogram_sample.sample","chrome_histogram_sample.sample",300,"[NULL]"
-"chrome_histogram_sample.name_hash","chrome_histogram_sample.name_hash",40,"[NULL]"
-"chrome_histogram_sample.name_iid","chrome_histogram_sample.name_iid",4,"[NULL]"
-"chrome_histogram_sample.sample","chrome_histogram_sample.sample",400,"[NULL]"
-"chrome_histogram_sample.name_hash","chrome_histogram_sample.name_hash",50,"[NULL]"
-"chrome_histogram_sample.sample","chrome_histogram_sample.sample",500,"[NULL]"
-"chrome_histogram_sample.name","chrome_histogram_sample.name","[NULL]","Memory.GPU.PeakMemoryUsage.PageLoad"
-"chrome_histogram_sample.name_hash","chrome_histogram_sample.name_hash",60,"[NULL]"
-"chrome_histogram_sample.sample","chrome_histogram_sample.sample",600,"[NULL]"
diff --git a/test/trace_processor/track_event/track_event_merged_debug_annotations_args.out b/test/trace_processor/track_event/track_event_merged_debug_annotations_args.out
index 8cecb1d..a4e2871 100644
--- a/test/trace_processor/track_event/track_event_merged_debug_annotations_args.out
+++ b/test/trace_processor/track_event/track_event_merged_debug_annotations_args.out
@@ -1,11 +1,4 @@
 "flat_key","key","int_value","string_value"
-"is_root_in_scope","is_root_in_scope",1,"[NULL]"
-"source","source","[NULL]","descriptor"
-"source_id","source_id",1,"[NULL]"
-"source","source","[NULL]","chrome"
-"source_id","source_id",1234,"[NULL]"
-"source_id_is_process_scoped","source_id_is_process_scoped",0,"[NULL]"
-"source_scope","source_scope","[NULL]","cat"
 "debug.debug1.key1","debug.debug1.key1",10,"[NULL]"
 "debug.debug1.key2","debug.debug1.key2[0]",20,"[NULL]"
 "debug.debug1.key2","debug.debug1.key2[1]",21,"[NULL]"
@@ -24,4 +17,15 @@
 "debug.debug4.key1","debug.debug4.key1",10,"[NULL]"
 "debug.debug4.key2","debug.debug4.key2[0]",20,"[NULL]"
 "debug.debug4.key2","debug.debug4.key2[1]",21,"[NULL]"
+"event.category","event.category","[NULL]","cat"
+"event.category","event.category","[NULL]","cat"
+"event.name","event.name","[NULL]","[NULL]"
+"event.name","event.name","[NULL]","name1"
+"is_root_in_scope","is_root_in_scope",1,"[NULL]"
 "legacy_event.passthrough_utid","legacy_event.passthrough_utid",1,"[NULL]"
+"source","source","[NULL]","chrome"
+"source","source","[NULL]","descriptor"
+"source_id","source_id",1,"[NULL]"
+"source_id","source_id",1234,"[NULL]"
+"source_id_is_process_scoped","source_id_is_process_scoped",0,"[NULL]"
+"source_scope","source_scope","[NULL]","cat"
diff --git a/test/trace_processor/track_event/track_event_typed_args_args.out b/test/trace_processor/track_event/track_event_typed_args_args.out
index fae18d7..cb6ade4 100644
--- a/test/trace_processor/track_event/track_event_typed_args_args.out
+++ b/test/trace_processor/track_event/track_event_typed_args_args.out
@@ -1,27 +1,39 @@
 "flat_key","key","int_value","string_value"
-"is_root_in_scope","is_root_in_scope",1,"[NULL]"
-"source","source","[NULL]","descriptor"
-"source_id","source_id",1,"[NULL]"
-"chrome_user_event.action","chrome_user_event.action","[NULL]","NewTab"
-"chrome_legacy_ipc.message_class","chrome_legacy_ipc.message_class","[NULL]","CLASS_AUTOMATION"
-"chrome_legacy_ipc.message_line","chrome_legacy_ipc.message_line",10,"[NULL]"
+"chrome_app_state","chrome_app_state","[NULL]","APP_STATE_FOREGROUND"
 "chrome_keyed_service.name","chrome_keyed_service.name","[NULL]","MediaRouter"
 "chrome_latency_info.component_info.component_type","chrome_latency_info.component_info[0].component_type","[NULL]","COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL"
 "chrome_latency_info.component_info.time_us","chrome_latency_info.component_info[0].time_us",1201,"[NULL]"
 "chrome_latency_info.component_info.time_us","chrome_latency_info.component_info[1].time_us",928310,"[NULL]"
 "chrome_latency_info.is_coalesced","chrome_latency_info.is_coalesced",1,"[NULL]"
 "chrome_latency_info.trace_id","chrome_latency_info.trace_id",7,"[NULL]"
-"int_extension_for_testing","int_extension_for_testing[0]",42,"[NULL]"
-"int_extension_for_testing","int_extension_for_testing[1]",1337,"[NULL]"
-"nested_message_extension_for_testing.arg1","nested_message_extension_for_testing.arg1","[NULL]","value"
-"nested_message_extension_for_testing.arg2.key","nested_message_extension_for_testing.arg2.key","[NULL]","value"
-"nested_message_extension_for_testing.child_field_for_testing","nested_message_extension_for_testing.child_field_for_testing","[NULL]","nesting test"
-"string_extension_for_testing","string_extension_for_testing","[NULL]","an extension string!"
-"chrome_app_state","chrome_app_state","[NULL]","APP_STATE_FOREGROUND"
+"chrome_legacy_ipc.message_class","chrome_legacy_ipc.message_class","[NULL]","CLASS_AUTOMATION"
+"chrome_legacy_ipc.message_line","chrome_legacy_ipc.message_line",10,"[NULL]"
 "chrome_memory_pressure_notification.file_name","chrome_memory_pressure_notification.file_name","[NULL]","another_source.cc"
 "chrome_memory_pressure_notification.function_name","chrome_memory_pressure_notification.function_name","[NULL]","AnotherSourceFunction"
 "chrome_memory_pressure_notification.line_number","chrome_memory_pressure_notification.line_number",1337,"[NULL]"
+"chrome_user_event.action","chrome_user_event.action","[NULL]","NewTab"
+"event.category","event.category","[NULL]","cat"
+"event.category","event.category","[NULL]","cat"
+"event.category","event.category","[NULL]","cat"
+"event.category","event.category","[NULL]","cat"
+"event.category","event.category","[NULL]","cat"
+"event.category","event.category","[NULL]","cat"
+"event.name","event.name","[NULL]","name1"
+"event.name","event.name","[NULL]","name2"
+"event.name","event.name","[NULL]","name3"
+"event.name","event.name","[NULL]","name4"
+"event.name","event.name","[NULL]","name5"
+"event.name","event.name","[NULL]","name6"
+"int_extension_for_testing","int_extension_for_testing[0]",42,"[NULL]"
+"int_extension_for_testing","int_extension_for_testing[1]",1337,"[NULL]"
+"is_root_in_scope","is_root_in_scope",1,"[NULL]"
+"nested_message_extension_for_testing.arg1","nested_message_extension_for_testing.arg1","[NULL]","value"
+"nested_message_extension_for_testing.arg2.key","nested_message_extension_for_testing.arg2.key","[NULL]","value"
+"nested_message_extension_for_testing.child_field_for_testing","nested_message_extension_for_testing.child_field_for_testing","[NULL]","nesting test"
+"source","source","[NULL]","descriptor"
 "source.file_name","source.file_name","[NULL]","source.cc"
 "source.function_name","source.function_name","[NULL]","SourceFunction"
 "source.line_number","source.line_number",0,"[NULL]"
+"source_id","source_id",1,"[NULL]"
 "source_location_iid","source_location_iid",1,"[NULL]"
+"string_extension_for_testing","string_extension_for_testing","[NULL]","an extension string!"
diff --git a/test/trace_processor/translation/chrome_args_test.sql b/test/trace_processor/translation/chrome_args_test.sql
index fc4bf5b..542df14 100644
--- a/test/trace_processor/translation/chrome_args_test.sql
+++ b/test/trace_processor/translation/chrome_args_test.sql
@@ -13,4 +13,4 @@
 -- See the License for the specific language governing permissions and
 -- limitations under the License.
 --
-SELECT flat_key, key, int_value, string_value FROM args ORDER BY arg_set_id, key ASC;
+SELECT flat_key, key, int_value, string_value FROM args ORDER BY key, display_value, arg_set_id ASC;
diff --git a/test/trace_processor/translation/chrome_histogram.out b/test/trace_processor/translation/chrome_histogram.out
index 484b008..1e4b7a2 100644
--- a/test/trace_processor/translation/chrome_histogram.out
+++ b/test/trace_processor/translation/chrome_histogram.out
@@ -1,10 +1,16 @@
 "flat_key","key","int_value","string_value"
+"chrome_histogram_sample.name","chrome_histogram_sample.name","[NULL]","histogram_name1"
+"chrome_histogram_sample.name","chrome_histogram_sample.name","[NULL]","histogram_name2"
+"chrome_histogram_sample.name_hash","chrome_histogram_sample.name_hash",10,"[NULL]"
+"chrome_histogram_sample.name_hash","chrome_histogram_sample.name_hash",20,"[NULL]"
+"chrome_histogram_sample.name_hash","chrome_histogram_sample.name_hash",30,"[NULL]"
+"chrome_histogram_sample.sample","chrome_histogram_sample.sample",100,"[NULL]"
+"event.category","event.category","[NULL]","cat1"
+"event.category","event.category","[NULL]","cat2"
+"event.category","event.category","[NULL]","cat3"
+"event.name","event.name","[NULL]","slice1"
+"event.name","event.name","[NULL]","slice2"
+"event.name","event.name","[NULL]","slice3"
 "is_root_in_scope","is_root_in_scope",1,"[NULL]"
 "source","source","[NULL]","descriptor"
 "source_id","source_id",12345,"[NULL]"
-"chrome_histogram_sample.name","chrome_histogram_sample.name","[NULL]","histogram_name1"
-"chrome_histogram_sample.name_hash","chrome_histogram_sample.name_hash",10,"[NULL]"
-"chrome_histogram_sample.sample","chrome_histogram_sample.sample",100,"[NULL]"
-"chrome_histogram_sample.name","chrome_histogram_sample.name","[NULL]","histogram_name2"
-"chrome_histogram_sample.name_hash","chrome_histogram_sample.name_hash",20,"[NULL]"
-"chrome_histogram_sample.name_hash","chrome_histogram_sample.name_hash",30,"[NULL]"
diff --git a/test/trace_processor/translation/chrome_performance_mark.out b/test/trace_processor/translation/chrome_performance_mark.out
index ae86237..c3afe4c 100644
--- a/test/trace_processor/translation/chrome_performance_mark.out
+++ b/test/trace_processor/translation/chrome_performance_mark.out
@@ -1,8 +1,10 @@
 "flat_key","key","int_value","string_value"
-"is_root_in_scope","is_root_in_scope",1,"[NULL]"
-"source","source","[NULL]","descriptor"
-"source_id","source_id",12345,"[NULL]"
 "chrome_hashed_performance_mark.mark","chrome_hashed_performance_mark.mark","[NULL]","mark2"
 "chrome_hashed_performance_mark.mark_hash","chrome_hashed_performance_mark.mark_hash",20,"[NULL]"
 "chrome_hashed_performance_mark.site","chrome_hashed_performance_mark.site","[NULL]","site1"
 "chrome_hashed_performance_mark.site_hash","chrome_hashed_performance_mark.site_hash",10,"[NULL]"
+"event.category","event.category","[NULL]","cat1"
+"event.name","event.name","[NULL]","slice1"
+"is_root_in_scope","is_root_in_scope",1,"[NULL]"
+"source","source","[NULL]","descriptor"
+"source_id","source_id",12345,"[NULL]"
diff --git a/test/trace_processor/translation/chrome_user_event.out b/test/trace_processor/translation/chrome_user_event.out
index 6532ef8..a198369 100644
--- a/test/trace_processor/translation/chrome_user_event.out
+++ b/test/trace_processor/translation/chrome_user_event.out
@@ -1,9 +1,15 @@
 "flat_key","key","int_value","string_value"
+"chrome_user_event.action","chrome_user_event.action","[NULL]","action1"
+"chrome_user_event.action","chrome_user_event.action","[NULL]","action2"
+"chrome_user_event.action_hash","chrome_user_event.action_hash",10,"[NULL]"
+"chrome_user_event.action_hash","chrome_user_event.action_hash",20,"[NULL]"
+"chrome_user_event.action_hash","chrome_user_event.action_hash",30,"[NULL]"
+"event.category","event.category","[NULL]","cat1"
+"event.category","event.category","[NULL]","cat2"
+"event.category","event.category","[NULL]","cat3"
+"event.name","event.name","[NULL]","slice1"
+"event.name","event.name","[NULL]","slice2"
+"event.name","event.name","[NULL]","slice3"
 "is_root_in_scope","is_root_in_scope",1,"[NULL]"
 "source","source","[NULL]","descriptor"
 "source_id","source_id",12345,"[NULL]"
-"chrome_user_event.action","chrome_user_event.action","[NULL]","action1"
-"chrome_user_event.action_hash","chrome_user_event.action_hash",10,"[NULL]"
-"chrome_user_event.action","chrome_user_event.action","[NULL]","action2"
-"chrome_user_event.action_hash","chrome_user_event.action_hash",20,"[NULL]"
-"chrome_user_event.action_hash","chrome_user_event.action_hash",30,"[NULL]"
diff --git a/test/trace_processor/translation/index.py b/test/trace_processor/translation/index.py
index 9f256d6..894ba0e 100644
--- a/test/trace_processor/translation/index.py
+++ b/test/trace_processor/translation/index.py
@@ -39,14 +39,20 @@
         query=Path('chrome_args_test.sql'),
         out=Csv("""
 "flat_key","key","int_value","string_value"
+"chrome_user_event.action","chrome_user_event.action","[NULL]","action1"
+"chrome_user_event.action","chrome_user_event.action","[NULL]","action2"
+"chrome_user_event.action_hash","chrome_user_event.action_hash",10,"[NULL]"
+"chrome_user_event.action_hash","chrome_user_event.action_hash",20,"[NULL]"
+"chrome_user_event.action_hash","chrome_user_event.action_hash",30,"[NULL]"
+"event.category","event.category","[NULL]","cat1"
+"event.category","event.category","[NULL]","cat2"
+"event.category","event.category","[NULL]","cat3"
+"event.name","event.name","[NULL]","slice1"
+"event.name","event.name","[NULL]","slice2"
+"event.name","event.name","[NULL]","slice3"
 "is_root_in_scope","is_root_in_scope",1,"[NULL]"
 "source","source","[NULL]","descriptor"
 "source_id","source_id",12345,"[NULL]"
-"chrome_user_event.action","chrome_user_event.action","[NULL]","action1"
-"chrome_user_event.action_hash","chrome_user_event.action_hash",10,"[NULL]"
-"chrome_user_event.action","chrome_user_event.action","[NULL]","action2"
-"chrome_user_event.action_hash","chrome_user_event.action_hash",20,"[NULL]"
-"chrome_user_event.action_hash","chrome_user_event.action_hash",30,"[NULL]"
 """))
 
   def test_chrome_performance_mark(self):
@@ -58,7 +64,9 @@
   def test_slice_name(self):
     return DiffTestBlueprint(
         trace=Path('slice_name.textproto'),
-        query=Path('slice_name_test.sql'),
+        query="""
+SELECT name FROM slice ORDER BY name;
+""",
         out=Csv("""
 "name"
 "mapped_name1"
@@ -70,7 +78,9 @@
   def test_slice_name_2(self):
     return DiffTestBlueprint(
         trace=Path('slice_name_negative_timestamp.textproto'),
-        query=Path('slice_name_test.sql'),
+        query="""
+SELECT name FROM slice ORDER BY name;
+""",
         out=Csv("""
 "name"
 "mapped_name1"
diff --git a/test/trace_processor/translation/java_class_name_arg.out b/test/trace_processor/translation/java_class_name_arg.out
index df1ebfb..057e63f 100644
--- a/test/trace_processor/translation/java_class_name_arg.out
+++ b/test/trace_processor/translation/java_class_name_arg.out
@@ -1,10 +1,12 @@
 "flat_key","key","int_value","string_value"
-"is_root_in_scope","is_root_in_scope",1,"[NULL]"
-"source","source","[NULL]","descriptor"
-"source_id","source_id",0,"[NULL]"
 "android_view_dump.activity.name","android_view_dump.activity[0].name","[NULL]","A1"
 "android_view_dump.activity.view.class_name","android_view_dump.activity[0].view[0].class_name","[NULL]","class_A"
 "android_view_dump.activity.view.class_name","android_view_dump.activity[0].view[1].class_name","[NULL]","def"
 "android_view_dump.activity.view.class_name","android_view_dump.activity[0].view[2].class_name","[NULL]","ghi"
 "android_view_dump.activity.name","android_view_dump.activity[1].name","[NULL]","B1"
 "android_view_dump.activity.view.class_name","android_view_dump.activity[1].view[0].class_name","[NULL]","class_J"
+"event.category","event.category","[NULL]","cat1"
+"event.name","event.name","[NULL]","name1"
+"is_root_in_scope","is_root_in_scope",1,"[NULL]"
+"source","source","[NULL]","descriptor"
+"source_id","source_id",0,"[NULL]"
diff --git a/test/trace_processor/translation/native_symbol_arg.out b/test/trace_processor/translation/native_symbol_arg.out
index c8bff01..2c00ad2 100644
--- a/test/trace_processor/translation/native_symbol_arg.out
+++ b/test/trace_processor/translation/native_symbol_arg.out
@@ -1,12 +1,20 @@
 "flat_key","key","int_value","string_value"
+"chrome_mojo_event_info.mojo_interface_tag","chrome_mojo_event_info.mojo_interface_tag","[NULL]","Class::Method"
+"chrome_mojo_event_info.mojo_interface_tag","chrome_mojo_event_info.mojo_interface_tag","[NULL]","Func"
+"chrome_mojo_event_info.mojo_interface_tag","chrome_mojo_event_info.mojo_interface_tag","[NULL]","storage.mojom.Directory"
+"chrome_mojo_event_info.mojo_interface_tag","chrome_mojo_event_info.mojo_interface_tag","[NULL]","storage.mojom.File"
+"chrome_mojo_event_info.mojo_method_name","chrome_mojo_event_info.mojo_method_name","[NULL]","Class::Method"
+"chrome_mojo_event_info.mojo_method_name","chrome_mojo_event_info.mojo_method_name","[NULL]","Func"
+"chrome_mojo_event_info.mojo_method_name","chrome_mojo_event_info.mojo_method_name","[NULL]","storage::mojom::Directory::OpenFile"
+"chrome_mojo_event_info.mojo_method_name","chrome_mojo_event_info.mojo_method_name","[NULL]","storage::mojom::File::Close"
+"event.category","event.category","[NULL]","cat1"
+"event.category","event.category","[NULL]","cat1"
+"event.category","event.category","[NULL]","cat1"
+"event.category","event.category","[NULL]","cat1"
+"event.name","event.name","[NULL]","slice1"
+"event.name","event.name","[NULL]","slice2"
+"event.name","event.name","[NULL]","slice3"
+"event.name","event.name","[NULL]","slice4"
 "is_root_in_scope","is_root_in_scope",1,"[NULL]"
 "source","source","[NULL]","descriptor"
 "source_id","source_id",12345,"[NULL]"
-"chrome_mojo_event_info.mojo_interface_tag","chrome_mojo_event_info.mojo_interface_tag","[NULL]","storage.mojom.Directory"
-"chrome_mojo_event_info.mojo_method_name","chrome_mojo_event_info.mojo_method_name","[NULL]","storage::mojom::Directory::OpenFile"
-"chrome_mojo_event_info.mojo_interface_tag","chrome_mojo_event_info.mojo_interface_tag","[NULL]","storage.mojom.File"
-"chrome_mojo_event_info.mojo_method_name","chrome_mojo_event_info.mojo_method_name","[NULL]","storage::mojom::File::Close"
-"chrome_mojo_event_info.mojo_interface_tag","chrome_mojo_event_info.mojo_interface_tag","[NULL]","Class::Method"
-"chrome_mojo_event_info.mojo_method_name","chrome_mojo_event_info.mojo_method_name","[NULL]","Class::Method"
-"chrome_mojo_event_info.mojo_interface_tag","chrome_mojo_event_info.mojo_interface_tag","[NULL]","Func"
-"chrome_mojo_event_info.mojo_method_name","chrome_mojo_event_info.mojo_method_name","[NULL]","Func"
diff --git a/test/trace_processor/ufs/index.py b/test/trace_processor/ufs/index.py
index 4081061..1c29f2d 100644
--- a/test/trace_processor/ufs/index.py
+++ b/test/trace_processor/ufs/index.py
@@ -24,7 +24,19 @@
   def test_ufshcd_command(self):
     return DiffTestBlueprint(
         trace=Path('ufshcd_command.textproto'),
-        query=Path('ufshcd_command_test.sql'),
+        query="""
+SELECT
+  ts,
+  value
+FROM
+  counter AS c
+JOIN
+  counter_track AS ct
+  ON c.track_id = ct.id
+WHERE
+  ct.name = "io.ufs.command.count"
+ORDER BY ts;
+""",
         out=Csv("""
 "ts","value"
 10000,1.000000
@@ -36,7 +48,13 @@
   def test_ufshcd_command_tag(self):
     return DiffTestBlueprint(
         trace=Path('ufshcd_command_tag.textproto'),
-        query=Path('ufshcd_command_tag_test.sql'),
+        query="""
+SELECT ts, dur, slice.name
+FROM slice
+JOIN track ON slice.track_id = track.id
+WHERE track.name GLOB 'io.ufs.command.tag*'
+ORDER BY ts;
+""",
         out=Csv("""
 "ts","dur","name"
 10000,800,"READ (10)"
diff --git a/tools/diff_test_trace_processor.py b/tools/diff_test_trace_processor.py
index 2c66ea1..1236f9d 100755
--- a/tools/diff_test_trace_processor.py
+++ b/tools/diff_test_trace_processor.py
@@ -85,23 +85,15 @@
 
     metrics = []
     sorted_data = sorted(
-        results.perf_data,
-        key=lambda x: (x.test_type.name, x.trace_path, x.query_path_or_metric))
+        results.perf_data, key=lambda x: (x.test.type.name, x.test.name))
     for perf_args in sorted_data:
-      trace_short_path = os.path.relpath(perf_args.trace_path, test_dir)
-
-      query_short_path_or_metric = perf_args.query_path_or_metric
-      if perf_args.test_type == TestType.QUERY:
-        query_short_path_or_metric = os.path.relpath(
-            perf_args.query_path_or_metric, trace_processor_dir)
-
       metrics.append({
           'metric': 'tp_perf_test_ingest_time',
           'value': float(perf_args.ingest_time_ns) / 1.0e9,
           'unit': 's',
           'tags': {
-              'test_name': f"{trace_short_path}-{query_short_path_or_metric}",
-              'test_type': perf_args.test_type.name,
+              'test_name': perf_args.test.name,
+              'test_type': perf_args.test.type.name,
           },
           'labels': {},
       })
@@ -110,8 +102,8 @@
           'value': float(perf_args.real_time_ns) / 1.0e9,
           'unit': 's',
           'tags': {
-              'test_name': f"{trace_short_path}-{query_short_path_or_metric}",
-              'test_type': perf_args.test_type.name,
+              'test_name': perf_args.test.name,
+              'test_type': perf_args.test.type.name,
           },
           'labels': {},
       })
diff --git a/ui/src/controller/trace_stream.ts b/ui/src/controller/trace_stream.ts
index f6c9da6..a980665 100644
--- a/ui/src/controller/trace_stream.ts
+++ b/ui/src/controller/trace_stream.ts
@@ -44,14 +44,14 @@
     this.reader.onloadend = () => this.onLoad();
   }
 
-  onLoad() {
-    const res = assertExists(this.reader.result) as ArrayBuffer;
+  private onLoad() {
     const pendingRead = assertExists(this.pendingRead);
     this.pendingRead = undefined;
     if (this.reader.error) {
       pendingRead.reject(this.reader.error);
       return;
     }
+    const res = assertExists(this.reader.result) as ArrayBuffer;
     this.bytesRead += res.byteLength;
     pendingRead.resolve({
       data: new Uint8Array(res),