trace_processor: migrate raw table to macro tables

Context: go/perfetto-tp-refactor
Bug: 135177627
Change-Id: I688edee7b5c39c270b3c9c72d41e40558ba705d4
diff --git a/Android.bp b/Android.bp
index f3f690c..d721882 100644
--- a/Android.bp
+++ b/Android.bp
@@ -5933,12 +5933,12 @@
   name: "perfetto_src_trace_processor_lib",
   srcs: [
     "src/trace_processor/filtered_row_index.cc",
-    "src/trace_processor/raw_table.cc",
     "src/trace_processor/read_trace.cc",
     "src/trace_processor/row_iterators.cc",
     "src/trace_processor/sched_slice_table.cc",
     "src/trace_processor/span_join_operator_table.cc",
     "src/trace_processor/sql_stats_table.cc",
+    "src/trace_processor/sqlite_raw_table.cc",
     "src/trace_processor/stats_table.cc",
     "src/trace_processor/storage_columns.cc",
     "src/trace_processor/storage_schema.cc",
diff --git a/BUILD b/BUILD
index cf45542..b62b186 100644
--- a/BUILD
+++ b/BUILD
@@ -799,8 +799,6 @@
     srcs = [
         "src/trace_processor/filtered_row_index.cc",
         "src/trace_processor/filtered_row_index.h",
-        "src/trace_processor/raw_table.cc",
-        "src/trace_processor/raw_table.h",
         "src/trace_processor/read_trace.cc",
         "src/trace_processor/row_iterators.cc",
         "src/trace_processor/row_iterators.h",
@@ -810,6 +808,8 @@
         "src/trace_processor/span_join_operator_table.h",
         "src/trace_processor/sql_stats_table.cc",
         "src/trace_processor/sql_stats_table.h",
+        "src/trace_processor/sqlite_raw_table.cc",
+        "src/trace_processor/sqlite_raw_table.h",
         "src/trace_processor/stats_table.cc",
         "src/trace_processor/stats_table.h",
         "src/trace_processor/storage_columns.cc",
diff --git a/src/trace_processor/BUILD.gn b/src/trace_processor/BUILD.gn
index 75571e6..0455917 100644
--- a/src/trace_processor/BUILD.gn
+++ b/src/trace_processor/BUILD.gn
@@ -287,8 +287,6 @@
   sources = [
     "filtered_row_index.cc",
     "filtered_row_index.h",
-    "raw_table.cc",
-    "raw_table.h",
     "read_trace.cc",
     "row_iterators.cc",
     "row_iterators.h",
@@ -298,6 +296,8 @@
     "span_join_operator_table.h",
     "sql_stats_table.cc",
     "sql_stats_table.h",
+    "sqlite_raw_table.cc",
+    "sqlite_raw_table.h",
     "stats_table.cc",
     "stats_table.h",
     "storage_columns.cc",
diff --git a/src/trace_processor/args_tracker.cc b/src/trace_processor/args_tracker.cc
index 678bf57..703f8ee 100644
--- a/src/trace_processor/args_tracker.cc
+++ b/src/trace_processor/args_tracker.cc
@@ -72,7 +72,7 @@
         context_->global_args_tracker->AddArgSet(args_, i, next_rid_idx);
     switch (table_id) {
       case TableId::kRawEvents:
-        storage->mutable_raw_events()->set_arg_set_id(row, set_id);
+        storage->mutable_raw_table()->mutable_arg_set_id()->Set(row, set_id);
         break;
       case TableId::kCounterValues:
         storage->mutable_counter_table()->mutable_arg_set_id()->Set(row,
diff --git a/src/trace_processor/export_json.cc b/src/trace_processor/export_json.cc
index 04e3a5d..960ae18 100644
--- a/src/trace_processor/export_json.cc
+++ b/src/trace_processor/export_json.cc
@@ -756,12 +756,12 @@
                                         uint32_t index) {
   const auto& thread_table = storage->thread_table();
   const auto& process_table = storage->process_table();
-  const auto& events = storage->raw_events();
+  const auto& events = storage->raw_table();
 
   Json::Value event;
-  event["ts"] = Json::Int64(events.timestamps()[index] / 1000);
+  event["ts"] = Json::Int64(events.ts()[index] / 1000);
 
-  UniqueTid utid = static_cast<UniqueTid>(events.utids()[index]);
+  UniqueTid utid = static_cast<UniqueTid>(events.utid()[index]);
   event["tid"] = static_cast<int32_t>(thread_table.tid()[utid]);
   event["pid"] = 0;
 
@@ -771,7 +771,7 @@
 
   // Raw legacy events store all other params in the arg set. Make a copy of
   // the converted args here, parse, and then remove the legacy params.
-  event["args"] = args_builder.GetArgs(events.arg_set_ids()[index]);
+  event["args"] = args_builder.GetArgs(events.arg_set_id()[index]);
   const Json::Value& legacy_args = event["args"][kLegacyEventArgsKey];
 
   PERFETTO_DCHECK(legacy_args.isMember(kLegacyEventCategoryKey));
@@ -849,25 +849,25 @@
   base::Optional<StringId> raw_chrome_metadata_event_id =
       storage->string_pool().GetId("chrome_event.metadata");
 
-  const auto& events = storage->raw_events();
-  for (uint32_t i = 0; i < events.raw_event_count(); ++i) {
+  const auto& events = storage->raw_table();
+  for (uint32_t i = 0; i < events.row_count(); ++i) {
     if (raw_legacy_event_key_id &&
-        events.name_ids()[i] == *raw_legacy_event_key_id) {
+        events.name()[i] == *raw_legacy_event_key_id) {
       Json::Value event = ConvertLegacyRawEventToJson(storage, args_builder, i);
       writer->WriteCommonEvent(event);
     } else if (raw_legacy_system_trace_event_id &&
-               events.name_ids()[i] == *raw_legacy_system_trace_event_id) {
-      Json::Value args = args_builder.GetArgs(events.arg_set_ids()[i]);
+               events.name()[i] == *raw_legacy_system_trace_event_id) {
+      Json::Value args = args_builder.GetArgs(events.arg_set_id()[i]);
       PERFETTO_DCHECK(args.isMember("data"));
       writer->AddSystemTraceData(args["data"].asString());
     } else if (raw_legacy_user_trace_event_id &&
-               events.name_ids()[i] == *raw_legacy_user_trace_event_id) {
-      Json::Value args = args_builder.GetArgs(events.arg_set_ids()[i]);
+               events.name()[i] == *raw_legacy_user_trace_event_id) {
+      Json::Value args = args_builder.GetArgs(events.arg_set_id()[i]);
       PERFETTO_DCHECK(args.isMember("data"));
       writer->AddUserTraceData(args["data"].asString());
     } else if (raw_chrome_metadata_event_id &&
-               events.name_ids()[i] == *raw_chrome_metadata_event_id) {
-      Json::Value args = args_builder.GetArgs(events.arg_set_ids()[i]);
+               events.name()[i] == *raw_chrome_metadata_event_id) {
+      Json::Value args = args_builder.GetArgs(events.arg_set_id()[i]);
       writer->MergeMetadata(args);
     }
   }
diff --git a/src/trace_processor/export_json_unittest.cc b/src/trace_processor/export_json_unittest.cc
index e572d67..6dd10cc 100644
--- a/src/trace_processor/export_json_unittest.cc
+++ b/src/trace_processor/export_json_unittest.cc
@@ -374,8 +374,9 @@
 
   TraceStorage* storage = context_.storage.get();
 
-  uint32_t row = storage->mutable_raw_events()->AddRawEvent(
-      0, storage->InternString("chrome_event.metadata"), 0, 0);
+  RawId id = storage->mutable_raw_table()->Insert(
+      {0, storage->InternString("chrome_event.metadata"), 0, 0});
+  uint32_t row = *storage->raw_table().id().IndexOf(id);
 
   StringId name1_id = storage->InternString(base::StringView(kName1));
   StringId name2_id = storage->InternString(base::StringView(kName2));
@@ -1052,9 +1053,10 @@
   UniquePid upid = context_.process_tracker->GetOrCreateProcess(kProcessID);
   context_.storage->mutable_thread_table()->mutable_upid()->Set(utid, upid);
 
-  uint32_t row = storage->mutable_raw_events()->AddRawEvent(
-      kTimestamp, storage->InternString("track_event.legacy_event"), /*cpu=*/0,
-      utid);
+  RawId id = storage->mutable_raw_table()->Insert(
+      {kTimestamp, storage->InternString("track_event.legacy_event"), /*cpu=*/0,
+       utid});
+  uint32_t row = *storage->raw_table().id().IndexOf(id);
 
   auto add_arg = [&](const char* key, Variadic value) {
     StringId key_id = storage->InternString(key);
@@ -1128,22 +1130,25 @@
 
   TraceStorage* storage = context_.storage.get();
 
-  uint32_t row = storage->mutable_raw_events()->AddRawEvent(
-      0, storage->InternString("chrome_event.legacy_system_trace"), 0, 0);
+  RawId id = storage->mutable_raw_table()->Insert(
+      {0, storage->InternString("chrome_event.legacy_system_trace"), 0, 0});
+  uint32_t row = *storage->raw_table().id().IndexOf(id);
 
   StringId data_id = storage->InternString("data");
   StringId ftrace_data_id = storage->InternString(kLegacyFtraceData);
   context_.args_tracker->AddArg(TableId::kRawEvents, row, data_id, data_id,
                                 Variadic::String(ftrace_data_id));
 
-  row = storage->mutable_raw_events()->AddRawEvent(
-      0, storage->InternString("chrome_event.legacy_user_trace"), 0, 0);
+  id = storage->mutable_raw_table()->Insert(
+      {0, storage->InternString("chrome_event.legacy_user_trace"), 0, 0});
+  row = *storage->raw_table().id().IndexOf(id);
   StringId json_data1_id = storage->InternString(kLegacyJsonData1);
   context_.args_tracker->AddArg(TableId::kRawEvents, row, data_id, data_id,
                                 Variadic::String(json_data1_id));
 
-  row = storage->mutable_raw_events()->AddRawEvent(
-      0, storage->InternString("chrome_event.legacy_user_trace"), 0, 0);
+  id = storage->mutable_raw_table()->Insert(
+      {0, storage->InternString("chrome_event.legacy_user_trace"), 0, 0});
+  row = *storage->raw_table().id().IndexOf(id);
   StringId json_data2_id = storage->InternString(kLegacyJsonData2);
   context_.args_tracker->AddArg(TableId::kRawEvents, row, data_id, data_id,
                                 Variadic::String(json_data2_id));
@@ -1319,8 +1324,9 @@
 
   TraceStorage* storage = context_.storage.get();
 
-  uint32_t row = storage->mutable_raw_events()->AddRawEvent(
-      0, storage->InternString("chrome_event.metadata"), 0, 0);
+  RawId id = storage->mutable_raw_table()->Insert(
+      {0, storage->InternString("chrome_event.metadata"), 0, 0});
+  uint32_t row = *storage->raw_table().id().IndexOf(id);
 
   StringId name1_id = storage->InternString(base::StringView(kName1));
   StringId name2_id = storage->InternString(base::StringView(kName2));
diff --git a/src/trace_processor/importers/ftrace/ftrace_parser.cc b/src/trace_processor/importers/ftrace/ftrace_parser.cc
index 8cf435c..79b1e72 100644
--- a/src/trace_processor/importers/ftrace/ftrace_parser.cc
+++ b/src/trace_processor/importers/ftrace/ftrace_parser.cc
@@ -358,8 +358,9 @@
   protos::pbzero::GenericFtraceEvent::Decoder evt(blob.data, blob.size);
   StringId event_id = context_->storage->InternString(evt.event_name());
   UniqueTid utid = context_->process_tracker->GetOrCreateThread(tid);
-  uint32_t row = context_->storage->mutable_raw_events()->AddRawEvent(
-      ts, event_id, cpu, utid);
+  RawId id =
+      context_->storage->mutable_raw_table()->Insert({ts, event_id, cpu, utid});
+  uint32_t row = *context_->storage->raw_table().id().IndexOf(id);
 
   for (auto it = evt.field(); it; ++it) {
     protos::pbzero::GenericFtraceEvent::Field::Decoder fld(*it);
@@ -396,8 +397,10 @@
   MessageDescriptor* m = GetMessageDescriptorForId(ftrace_id);
   const auto& message_strings = ftrace_message_strings_[ftrace_id];
   UniqueTid utid = context_->process_tracker->GetOrCreateThread(tid);
-  uint32_t raw_event_row = context_->storage->mutable_raw_events()->AddRawEvent(
-      ts, message_strings.message_name_id, cpu, utid);
+  RawId id = context_->storage->mutable_raw_table()->Insert(
+      {ts, message_strings.message_name_id, cpu, utid});
+  uint32_t raw_event_row = *context_->storage->raw_table().id().IndexOf(id);
+
   for (auto fld = decoder.ReadField(); fld.valid(); fld = decoder.ReadField()) {
     if (PERFETTO_UNLIKELY(fld.id() >= kMaxFtraceEventFields)) {
       PERFETTO_DLOG(
diff --git a/src/trace_processor/importers/ftrace/sched_event_tracker.cc b/src/trace_processor/importers/ftrace/sched_event_tracker.cc
index 052f051..4bf01c2 100644
--- a/src/trace_processor/importers/ftrace/sched_event_tracker.cc
+++ b/src/trace_processor/importers/ftrace/sched_event_tracker.cc
@@ -194,8 +194,9 @@
                                                    int32_t next_prio) {
   // Push the raw event - this is done as the raw ftrace event codepath does
   // not insert sched_switch.
-  uint32_t row = context_->storage->mutable_raw_events()->AddRawEvent(
-      ts, sched_switch_id_, cpu, prev_utid);
+  RawId id = context_->storage->mutable_raw_table()->Insert(
+      {ts, sched_switch_id_, cpu, prev_utid});
+  uint32_t row = *context_->storage->raw_table().id().IndexOf(id);
 
   // Note: this ordering is important. The events should be pushed in the same
   // order as the order of fields in the proto; this is used by the raw table to
@@ -273,8 +274,9 @@
   auto curr_utid = pending_sched->last_utid;
 
   // Add an entry to the raw table.
-  uint32_t row = context_->storage->mutable_raw_events()->AddRawEvent(
-      ts, sched_waking_id_, cpu, curr_utid);
+  RawId id = context_->storage->mutable_raw_table()->Insert(
+      {ts, sched_waking_id_, cpu, curr_utid});
+  uint32_t row = *context_->storage->raw_table().id().IndexOf(id);
 
   // "success" is hardcoded as always 1 by the kernel, with a TODO to remove it.
   static constexpr int32_t kHardcodedSuccess = 1;
diff --git a/src/trace_processor/importers/proto/proto_trace_parser.cc b/src/trace_processor/importers/proto/proto_trace_parser.cc
index e27bdcb..eab7895 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser.cc
@@ -515,8 +515,9 @@
   protos::pbzero::ChromeEventBundle::Decoder bundle(blob.data, blob.size);
   ArgsTracker args(context_);
   if (bundle.has_metadata()) {
-    uint32_t row = storage->mutable_raw_events()->AddRawEvent(
-        ts, raw_chrome_metadata_event_id_, 0, 0);
+    RawId id = storage->mutable_raw_table()->Insert(
+        {ts, raw_chrome_metadata_event_id_, 0, 0});
+    uint32_t row = *storage->raw_table().id().IndexOf(id);
 
     // Metadata is proxied via a special event in the raw table to JSON export.
     for (auto it = bundle.metadata(); it; ++it) {
@@ -541,8 +542,9 @@
   }
 
   if (bundle.has_legacy_ftrace_output()) {
-    uint32_t row = storage->mutable_raw_events()->AddRawEvent(
-        ts, raw_chrome_legacy_system_trace_event_id_, 0, 0);
+    RawId id = storage->mutable_raw_table()->Insert(
+        {ts, raw_chrome_legacy_system_trace_event_id_, 0, 0});
+    uint32_t row = *storage->raw_table().id().IndexOf(id);
 
     std::string data;
     for (auto it = bundle.legacy_ftrace_output(); it; ++it) {
@@ -560,8 +562,9 @@
           protos::pbzero::ChromeLegacyJsonTrace::USER_TRACE) {
         continue;
       }
-      uint32_t row = storage->mutable_raw_events()->AddRawEvent(
-          ts, raw_chrome_legacy_user_trace_event_id_, 0, 0);
+      RawId id = storage->mutable_raw_table()->Insert(
+          {ts, raw_chrome_legacy_user_trace_event_id_, 0, 0});
+      uint32_t row = *storage->raw_table().id().IndexOf(id);
       Variadic value =
           Variadic::String(storage->InternString(legacy_trace.data()));
       args.AddArg(TableId::kRawEvents, row, data_name_id_, data_name_id_,
diff --git a/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc b/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
index c5b7e42..aa8c1ff 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
@@ -337,8 +337,8 @@
 
   Tokenize();
 
-  const auto& raw = context_.storage->raw_events();
-  ASSERT_EQ(raw.raw_event_count(), 2u);
+  const auto& raw = context_.storage->raw_table();
+  ASSERT_EQ(raw.row_count(), 2u);
   const auto& args = context_.storage->arg_table();
   ASSERT_EQ(args.row_count(), 6u);
   ASSERT_EQ(args.int_value()[0], 123);
@@ -388,13 +388,14 @@
 
   Tokenize();
 
-  const auto& raw = storage_->raw_events();
+  const auto& raw = storage_->raw_table();
 
-  ASSERT_EQ(raw.raw_event_count(), 1u);
-  ASSERT_EQ(raw.timestamps().back(), 100);
-  ASSERT_EQ(storage_->thread_table().tid()[raw.utids().back()], 10u);
+  ASSERT_EQ(raw.row_count(), 1u);
+  ASSERT_EQ(raw.ts()[raw.row_count() - 1], 100);
+  ASSERT_EQ(storage_->thread_table().tid()[raw.utid()[raw.row_count() - 1]],
+            10u);
 
-  auto set_id = raw.arg_set_ids().back();
+  auto set_id = raw.arg_set_id()[raw.row_count() - 1];
 
   const auto& args = storage_->arg_table();
   RowMap rm = args.FilterToRowMap({args.arg_set_id().eq(set_id)});
@@ -2108,15 +2109,15 @@
 
   ::testing::Mock::VerifyAndClearExpectations(storage_);
 
-  // Verify raw_events and args contents.
-  const auto& raw_events = storage_->raw_events();
-  EXPECT_EQ(raw_events.raw_event_count(), 1u);
-  EXPECT_EQ(raw_events.timestamps()[0], 1010000);
-  EXPECT_EQ(raw_events.name_ids()[0],
+  // Verify raw_table and args contents.
+  const auto& raw_table = storage_->raw_table();
+  EXPECT_EQ(raw_table.row_count(), 1u);
+  EXPECT_EQ(raw_table.ts()[0], 1010000);
+  EXPECT_EQ(raw_table.name()[0],
             storage_->InternString("track_event.legacy_event"));
-  EXPECT_EQ(raw_events.cpus()[0], 0u);
-  EXPECT_EQ(raw_events.utids()[0], 1u);
-  EXPECT_EQ(raw_events.arg_set_ids()[0], 1u);
+  EXPECT_EQ(raw_table.cpu()[0], 0u);
+  EXPECT_EQ(raw_table.utid()[0], 1u);
+  EXPECT_EQ(raw_table.arg_set_id()[0], 1u);
 
   EXPECT_GE(storage_->arg_table().row_count(), 13u);
 
@@ -2215,8 +2216,8 @@
   context_.sorter->ExtractEventsForced();
 
   // Metadata should have created a raw event.
-  const auto& raw_events = storage_->raw_events();
-  EXPECT_EQ(raw_events.raw_event_count(), 1u);
+  const auto& raw_table = storage_->raw_table();
+  EXPECT_EQ(raw_table.row_count(), 1u);
 }
 
 TEST_F(ProtoTraceParserTest, ParseChromeMetadataEventIntoRawTable) {
@@ -2245,12 +2246,12 @@
   Tokenize();
   context_.sorter->ExtractEventsForced();
 
-  // Verify raw_events and args contents.
-  const auto& raw_events = storage_->raw_events();
-  EXPECT_EQ(raw_events.raw_event_count(), 1u);
-  EXPECT_EQ(raw_events.name_ids()[0],
+  // Verify raw_table and args contents.
+  const auto& raw_table = storage_->raw_table();
+  EXPECT_EQ(raw_table.row_count(), 1u);
+  EXPECT_EQ(raw_table.name()[0],
             storage_->InternString("chrome_event.metadata"));
-  EXPECT_EQ(raw_events.arg_set_ids()[0], 1u);
+  EXPECT_EQ(raw_table.arg_set_id()[0], 1u);
 
   EXPECT_EQ(storage_->arg_table().row_count(), 2u);
   EXPECT_TRUE(HasArg(1u, storage_->InternString(kStringName),
@@ -2279,12 +2280,12 @@
 
   context_.sorter->ExtractEventsForced();
 
-  // Verify raw_events and args contents.
-  const auto& raw_events = storage_->raw_events();
-  EXPECT_EQ(raw_events.raw_event_count(), 1u);
-  EXPECT_EQ(raw_events.name_ids()[0],
+  // Verify raw_table and args contents.
+  const auto& raw_table = storage_->raw_table();
+  EXPECT_EQ(raw_table.row_count(), 1u);
+  EXPECT_EQ(raw_table.name()[0],
             storage_->InternString("chrome_event.legacy_system_trace"));
-  EXPECT_EQ(raw_events.arg_set_ids()[0], 1u);
+  EXPECT_EQ(raw_table.arg_set_id()[0], 1u);
 
   EXPECT_EQ(storage_->arg_table().row_count(), 1u);
   EXPECT_TRUE(HasArg(1u, storage_->InternString("data"),
@@ -2310,12 +2311,12 @@
 
   context_.sorter->ExtractEventsForced();
 
-  // Verify raw_events and args contents.
-  const auto& raw_events = storage_->raw_events();
-  EXPECT_EQ(raw_events.raw_event_count(), 1u);
-  EXPECT_EQ(raw_events.name_ids()[0],
+  // Verify raw_table and args contents.
+  const auto& raw_table = storage_->raw_table();
+  EXPECT_EQ(raw_table.row_count(), 1u);
+  EXPECT_EQ(raw_table.name()[0],
             storage_->InternString("chrome_event.legacy_user_trace"));
-  EXPECT_EQ(raw_events.arg_set_ids()[0], 1u);
+  EXPECT_EQ(raw_table.arg_set_id()[0], 1u);
 
   EXPECT_EQ(storage_->arg_table().row_count(), 1u);
   EXPECT_TRUE(
diff --git a/src/trace_processor/importers/proto/track_event_parser.cc b/src/trace_processor/importers/proto/track_event_parser.cc
index 720db46..a07e170 100644
--- a/src/trace_processor/importers/proto/track_event_parser.cc
+++ b/src/trace_processor/importers/proto/track_event_parser.cc
@@ -756,8 +756,9 @@
     return;
   }
 
-  uint32_t row = context_->storage->mutable_raw_events()->AddRawEvent(
-      ts, raw_legacy_event_id_, 0, *utid);
+  RawId id = context_->storage->mutable_raw_table()->Insert(
+      {ts, raw_legacy_event_id_, 0, *utid});
+  uint32_t row = *context_->storage->raw_table().id().IndexOf(id);
 
   ArgsTracker args(context_);
   ArgsTracker::BoundInserter inserter(&args, TableId::kRawEvents, row);
diff --git a/src/trace_processor/sqlite/BUILD.gn b/src/trace_processor/sqlite/BUILD.gn
index 07b39c0..5a81353 100644
--- a/src/trace_processor/sqlite/BUILD.gn
+++ b/src/trace_processor/sqlite/BUILD.gn
@@ -31,8 +31,10 @@
     "../../../gn:default_deps",
     "../../../gn:sqlite",
     "../../../include/perfetto/trace_processor",
+    "../../../protos/perfetto/trace/ftrace:zero",
     "../../base",
     "../db:lib",
+    "../types",
   ]
 }
 
diff --git a/src/trace_processor/raw_table.cc b/src/trace_processor/sqlite_raw_table.cc
similarity index 85%
rename from src/trace_processor/raw_table.cc
rename to src/trace_processor/sqlite_raw_table.cc
index 9fd262a..3177a96 100644
--- a/src/trace_processor/raw_table.cc
+++ b/src/trace_processor/sqlite_raw_table.cc
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "src/trace_processor/raw_table.h"
+#include "src/trace_processor/sqlite_raw_table.h"
 
 #include <inttypes.h>
 
@@ -50,10 +50,10 @@
 }
 }  // namespace
 
-RawTable::RawTable(sqlite3* db, const TraceStorage* storage)
-    : storage_(storage) {
+SqliteRawTable::SqliteRawTable(sqlite3* db, const TraceStorage* storage)
+    : DbSqliteTable(db, &storage->raw_table()), storage_(storage) {
   auto fn = [](sqlite3_context* ctx, int argc, sqlite3_value** argv) {
-    auto* thiz = static_cast<RawTable*>(sqlite3_user_data(ctx));
+    auto* thiz = static_cast<SqliteRawTable*>(sqlite3_user_data(ctx));
     thiz->ToSystrace(ctx, argc, argv);
   };
   sqlite3_create_function(db, "to_ftrace", 1,
@@ -61,41 +61,13 @@
                           nullptr);
 }
 
-void RawTable::RegisterTable(sqlite3* db, const TraceStorage* storage) {
-  SqliteTable::Register<RawTable>(db, storage, "raw");
+SqliteRawTable::~SqliteRawTable() = default;
+
+void SqliteRawTable::RegisterTable(sqlite3* db, const TraceStorage* storage) {
+  SqliteTable::Register<SqliteRawTable>(db, storage, "raw");
 }
 
-StorageSchema RawTable::CreateStorageSchema() {
-  const auto& raw = storage_->raw_events();
-  return StorageSchema::Builder()
-      .AddGenericNumericColumn("id", RowAccessor())
-      .AddOrderedNumericColumn("ts", &raw.timestamps())
-      .AddStringColumn("name", &raw.name_ids(), &storage_->string_pool())
-      .AddNumericColumn("cpu", &raw.cpus())
-      .AddNumericColumn("utid", &raw.utids())
-      .AddNumericColumn("arg_set_id", &raw.arg_set_ids())
-      .Build({"name", "ts"});
-}
-
-uint32_t RawTable::RowCount() {
-  return static_cast<uint32_t>(storage_->raw_events().raw_event_count());
-}
-
-int RawTable::BestIndex(const QueryConstraints& qc, BestIndexInfo* info) {
-  info->estimated_cost = RowCount();
-  info->sqlite_omit_order_by = true;
-
-  // Only the string columns are handled by SQLite
-  size_t name_index = schema().ColumnIndexFromName("name");
-  for (size_t i = 0; i < qc.constraints().size(); i++) {
-    info->sqlite_omit_constraint[i] =
-        qc.constraints()[i].column != static_cast<int>(name_index);
-  }
-
-  return SQLITE_OK;
-}
-
-bool RawTable::ParseGfpFlags(Variadic value, base::StringWriter* writer) {
+bool SqliteRawTable::ParseGfpFlags(Variadic value, base::StringWriter* writer) {
   const auto& metadata_table = storage_->metadata_table();
 
   auto opt_name_idx = metadata_table.name().IndexOf(
@@ -118,9 +90,9 @@
   return true;
 }
 
-void RawTable::FormatSystraceArgs(NullTermStringView event_name,
-                                  ArgSetId arg_set_id,
-                                  base::StringWriter* writer) {
+void SqliteRawTable::FormatSystraceArgs(NullTermStringView event_name,
+                                        ArgSetId arg_set_id,
+                                        base::StringWriter* writer) {
   const auto& set_ids = storage_->arg_table().arg_set_id();
 
   // TODO(lalitm): this code is quite hacky for performance reasons. We assume
@@ -236,17 +208,17 @@
     write_value_at_index(BT::kToThreadFieldNumber - 1, write_value);
     write_arg(BT::kReplyFieldNumber - 1, write_value);
     writer->AppendString(" flags=0x");
-    write_value_at_index(
-        BT::kFlagsFieldNumber - 1, [writer](const Variadic& value) {
-          PERFETTO_DCHECK(value.type == Variadic::Type::kUint);
-          writer->AppendHexInt(value.uint_value);
-        });
+    write_value_at_index(BT::kFlagsFieldNumber - 1,
+                         [writer](const Variadic& value) {
+                           PERFETTO_DCHECK(value.type == Variadic::Type::kUint);
+                           writer->AppendHexInt(value.uint_value);
+                         });
     writer->AppendString(" code=0x");
-    write_value_at_index(
-        BT::kCodeFieldNumber - 1, [writer](const Variadic& value) {
-          PERFETTO_DCHECK(value.type == Variadic::Type::kUint);
-          writer->AppendHexInt(value.uint_value);
-        });
+    write_value_at_index(BT::kCodeFieldNumber - 1,
+                         [writer](const Variadic& value) {
+                           PERFETTO_DCHECK(value.type == Variadic::Type::kUint);
+                           writer->AppendHexInt(value.uint_value);
+                         });
     return;
   } else if (event_name == "binder_transaction_alloc_buf") {
     using BTAB = protos::pbzero::BinderTransactionAllocBufFtraceEvent;
@@ -371,17 +343,17 @@
   }
 }
 
-void RawTable::ToSystrace(sqlite3_context* ctx,
-                          int argc,
-                          sqlite3_value** argv) {
+void SqliteRawTable::ToSystrace(sqlite3_context* ctx,
+                                int argc,
+                                sqlite3_value** argv) {
   if (argc != 1 || sqlite3_value_type(argv[0]) != SQLITE_INTEGER) {
     sqlite3_result_error(ctx, "Usage: to_ftrace(id)", -1);
     return;
   }
   uint32_t row = static_cast<uint32_t>(sqlite3_value_int64(argv[0]));
-  const auto& raw_evts = storage_->raw_events();
+  const auto& raw_evts = storage_->raw_table();
 
-  UniqueTid utid = raw_evts.utids()[row];
+  UniqueTid utid = raw_evts.utid()[row];
   uint32_t tgid = 0;
   auto opt_upid = storage_->thread_table().upid()[utid];
   if (opt_upid.has_value()) {
@@ -392,12 +364,11 @@
   char line[4096];
   base::StringWriter writer(line, sizeof(line));
 
-  ftrace_utils::FormatSystracePrefix(raw_evts.timestamps()[row],
-                                     raw_evts.cpus()[row],
+  ftrace_utils::FormatSystracePrefix(raw_evts.ts()[row], raw_evts.cpu()[row],
                                      storage_->thread_table().tid()[utid], tgid,
                                      base::StringView(name), &writer);
 
-  const auto& event_name = storage_->GetString(raw_evts.name_ids()[row]);
+  const auto& event_name = storage_->GetString(raw_evts.name()[row]);
   writer.AppendChar(' ');
   if (event_name == "print") {
     writer.AppendString("tracing_mark_write");
@@ -406,7 +377,7 @@
   }
   writer.AppendChar(':');
 
-  FormatSystraceArgs(event_name, raw_evts.arg_set_ids()[row], &writer);
+  FormatSystraceArgs(event_name, raw_evts.arg_set_id()[row], &writer);
   sqlite3_result_text(ctx, writer.CreateStringCopy(), -1, free);
 }
 
diff --git a/src/trace_processor/raw_table.h b/src/trace_processor/sqlite_raw_table.h
similarity index 74%
rename from src/trace_processor/raw_table.h
rename to src/trace_processor/sqlite_raw_table.h
index e4506b4..99ebff2 100644
--- a/src/trace_processor/raw_table.h
+++ b/src/trace_processor/sqlite_raw_table.h
@@ -14,27 +14,25 @@
  * limitations under the License.
  */
 
-#ifndef SRC_TRACE_PROCESSOR_RAW_TABLE_H_
-#define SRC_TRACE_PROCESSOR_RAW_TABLE_H_
+#ifndef SRC_TRACE_PROCESSOR_SQLITE_RAW_TABLE_H_
+#define SRC_TRACE_PROCESSOR_SQLITE_RAW_TABLE_H_
 
 #include "perfetto/base/logging.h"
-#include "src/trace_processor/storage_table.h"
+#include "perfetto/ext/base/string_writer.h"
+#include "src/trace_processor/sqlite/db_sqlite_table.h"
 #include "src/trace_processor/trace_storage.h"
+#include "src/trace_processor/types/variadic.h"
 
 namespace perfetto {
 namespace trace_processor {
 
-class RawTable : public StorageTable {
+class SqliteRawTable : public DbSqliteTable {
  public:
+  SqliteRawTable(sqlite3*, const TraceStorage*);
+  virtual ~SqliteRawTable();
+
   static void RegisterTable(sqlite3* db, const TraceStorage* storage);
 
-  RawTable(sqlite3*, const TraceStorage*);
-
-  // Table implementation.
-  StorageSchema CreateStorageSchema() override;
-  uint32_t RowCount() override;
-  int BestIndex(const QueryConstraints&, BestIndexInfo*) override;
-
  private:
   void FormatSystraceArgs(NullTermStringView event_name,
                           ArgSetId arg_set_id,
@@ -48,4 +46,4 @@
 }  // namespace trace_processor
 }  // namespace perfetto
 
-#endif  // SRC_TRACE_PROCESSOR_RAW_TABLE_H_
+#endif  // SRC_TRACE_PROCESSOR_SQLITE_RAW_TABLE_H_
diff --git a/src/trace_processor/tables/metadata_tables.h b/src/trace_processor/tables/metadata_tables.h
index e1684c8..dfcb98b 100644
--- a/src/trace_processor/tables/metadata_tables.h
+++ b/src/trace_processor/tables/metadata_tables.h
@@ -23,6 +23,17 @@
 namespace trace_processor {
 namespace tables {
 
+#define PERFETTO_TP_RAW_TABLE_DEF(NAME, PARENT, C) \
+  NAME(RawTable, "raw")                            \
+  PERFETTO_TP_ROOT_TABLE(PARENT, C)                \
+  C(int64_t, ts, Column::Flag::kSorted)            \
+  C(StringPool::Id, name)                          \
+  C(uint32_t, cpu)                                 \
+  C(uint32_t, utid)                                \
+  C(uint32_t, arg_set_id)
+
+PERFETTO_TP_TABLE(PERFETTO_TP_RAW_TABLE_DEF);
+
 #define PERFETTO_TP_ARG_TABLE_DEF(NAME, PARENT, C) \
   NAME(ArgTable, "args")                           \
   PERFETTO_TP_ROOT_TABLE(PARENT, C)                \
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index 7e21a0a..5692b0b 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -25,7 +25,6 @@
 #include "perfetto/ext/base/string_utils.h"
 #include "src/trace_processor/importers/ftrace/sched_event_tracker.h"
 #include "src/trace_processor/metadata_tracker.h"
-#include "src/trace_processor/raw_table.h"
 #include "src/trace_processor/register_additional_modules.h"
 #include "src/trace_processor/sched_slice_table.h"
 #include "src/trace_processor/span_join_operator_table.h"
@@ -33,6 +32,7 @@
 #include "src/trace_processor/sqlite/db_sqlite_table.h"
 #include "src/trace_processor/sqlite/sqlite3_str_split.h"
 #include "src/trace_processor/sqlite/sqlite_table.h"
+#include "src/trace_processor/sqlite_raw_table.h"
 #include "src/trace_processor/stats_table.h"
 #include "src/trace_processor/types/variadic.h"
 #include "src/trace_processor/window_operator_table.h"
@@ -380,16 +380,18 @@
 
   SetupMetrics(this, *db_, &sql_metrics_);
 
-  SchedSliceTable::RegisterTable(*db_, context_.storage.get());
-  SqlStatsTable::RegisterTable(*db_, context_.storage.get());
-  SpanJoinOperatorTable::RegisterTable(*db_, context_.storage.get());
-  WindowOperatorTable::RegisterTable(*db_, context_.storage.get());
-  StatsTable::RegisterTable(*db_, context_.storage.get());
-  RawTable::RegisterTable(*db_, context_.storage.get());
-
-  // New style db-backed tables.
   const TraceStorage* storage = context_.storage.get();
 
+  SchedSliceTable::RegisterTable(*db_, storage);
+  SqlStatsTable::RegisterTable(*db_, storage);
+  SpanJoinOperatorTable::RegisterTable(*db_, storage);
+  WindowOperatorTable::RegisterTable(*db_, storage);
+  StatsTable::RegisterTable(*db_, storage);
+
+  // New style tables but with some custom logic.
+  SqliteRawTable::RegisterTable(*db_, context_.storage.get());
+
+  // New style db-backed tables.
   DbSqliteTable::RegisterTable(*db_, &storage->arg_table(),
                                storage->arg_table().table_name());
   DbSqliteTable::RegisterTable(*db_, &storage->thread_table(),
diff --git a/src/trace_processor/trace_storage.cc b/src/trace_processor/trace_storage.cc
index 4ee0bcc..cd5a61d 100644
--- a/src/trace_processor/trace_storage.cc
+++ b/src/trace_processor/trace_storage.cc
@@ -140,9 +140,8 @@
   int64_t end_ns = std::numeric_limits<int64_t>::min();
   MaybeUpdateMinMax(slices_.start_ns().begin(), slices_.start_ns().end(),
                     &start_ns, &end_ns);
-  MaybeUpdateMinMax(raw_events_.timestamps().begin(),
-                    raw_events_.timestamps().end(), &start_ns, &end_ns);
 
+  DbTableMaybeUpdateMinMax(raw_table_.ts(), &start_ns, &end_ns);
   DbTableMaybeUpdateMinMax(counter_table_.ts(), &start_ns, &end_ns);
   DbTableMaybeUpdateMinMax(slice_table_.ts(), &start_ns, &end_ns);
   DbTableMaybeUpdateMinMax(heap_profile_allocation_table_.ts(), &start_ns,
diff --git a/src/trace_processor/trace_storage.h b/src/trace_processor/trace_storage.h
index 26e1e00..18067d6 100644
--- a/src/trace_processor/trace_storage.h
+++ b/src/trace_processor/trace_storage.h
@@ -88,6 +88,8 @@
 
 using MetadataId = tables::MetadataTable::Id;
 
+using RawId = tables::RawTable::Id;
+
 // TODO(lalitm): this is a temporary hack while migrating the counters table and
 // will be removed when the migration is complete.
 static const TrackId kInvalidTrackId =
@@ -328,42 +330,6 @@
     std::deque<int64_t> times_ended_;
   };
 
-  class RawEvents {
-   public:
-    inline uint32_t AddRawEvent(int64_t timestamp,
-                                StringId name_id,
-                                uint32_t cpu,
-                                UniqueTid utid) {
-      timestamps_.emplace_back(timestamp);
-      name_ids_.emplace_back(name_id);
-      cpus_.emplace_back(cpu);
-      utids_.emplace_back(utid);
-      arg_set_ids_.emplace_back(kInvalidArgSetId);
-      return static_cast<uint32_t>(raw_event_count() - 1);
-    }
-
-    void set_arg_set_id(uint32_t row, ArgSetId id) { arg_set_ids_[row] = id; }
-
-    size_t raw_event_count() const { return timestamps_.size(); }
-
-    const std::deque<int64_t>& timestamps() const { return timestamps_; }
-
-    const std::deque<StringId>& name_ids() const { return name_ids_; }
-
-    const std::deque<uint32_t>& cpus() const { return cpus_; }
-
-    const std::deque<UniqueTid>& utids() const { return utids_; }
-
-    const std::deque<ArgSetId>& arg_set_ids() const { return arg_set_ids_; }
-
-   private:
-    std::deque<int64_t> timestamps_;
-    std::deque<StringId> name_ids_;
-    std::deque<uint32_t> cpus_;
-    std::deque<UniqueTid> utids_;
-    std::deque<ArgSetId> arg_set_ids_;
-  };
-
   struct Stats {
     using IndexMap = std::map<int, int64_t>;
     int64_t value = 0;
@@ -570,8 +536,8 @@
   const tables::ArgTable& arg_table() const { return arg_table_; }
   tables::ArgTable* mutable_arg_table() { return &arg_table_; }
 
-  const RawEvents& raw_events() const { return raw_events_; }
-  RawEvents* mutable_raw_events() { return &raw_events_; }
+  const tables::RawTable& raw_table() const { return raw_table_; }
+  tables::RawTable* mutable_raw_table() { return &raw_table_; }
 
   const tables::StackProfileMappingTable& stack_profile_mapping_table() const {
     return stack_profile_mapping_table_;
@@ -828,7 +794,7 @@
   // the timestamp and the pid. The args for the raw event will be in the
   // args table. This table can be used to generate a text version of the
   // trace.
-  RawEvents raw_events_;
+  tables::RawTable raw_table_{&string_pool_, nullptr};
   tables::AndroidLogTable android_log_table_{&string_pool_, nullptr};
 
   tables::StackProfileMappingTable stack_profile_mapping_table_{&string_pool_,