trace_processor: split registration from schema generation
For span tables, we will need to discover the schema at
xCreate/xConnect time i.e. we won't know the schema of the table up
front.
Split these two orthogonal concepts to allow for span tables.
Change-Id: Ia62c44df8b4c6891d7637966578e8b32889bc6b3
diff --git a/src/trace_processor/counters_table.cc b/src/trace_processor/counters_table.cc
index 29fb6bf..86cf70c 100644
--- a/src/trace_processor/counters_table.cc
+++ b/src/trace_processor/counters_table.cc
@@ -29,19 +29,23 @@
} // namespace
-CountersTable::CountersTable(const TraceStorage* storage) : storage_(storage) {}
+CountersTable::CountersTable(sqlite3*, const TraceStorage* storage)
+ : storage_(storage) {}
void CountersTable::RegisterTable(sqlite3* db, const TraceStorage* storage) {
- Table::Register<CountersTable>(db, storage,
- "CREATE TABLE counters("
- "ts UNSIGNED BIG INT, "
- "name text, "
- "value UNSIGNED BIG INT, "
- "dur UNSIGNED BIG INT, "
- "ref UNSIGNED INT, "
- "reftype TEXT, "
- "PRIMARY KEY(name, ts, ref)"
- ") WITHOUT ROWID;");
+ Table::Register<CountersTable>(db, storage, "counters");
+}
+
+std::string CountersTable::CreateTableStmt(int, const char* const*) {
+ return "CREATE TABLE x("
+ "ts UNSIGNED BIG INT, "
+ "name text, "
+ "value UNSIGNED BIG INT, "
+ "dur UNSIGNED BIG INT, "
+ "ref UNSIGNED INT, "
+ "reftype TEXT, "
+ "PRIMARY KEY(name, ts, ref)"
+ ") WITHOUT ROWID;";
}
std::unique_ptr<Table::Cursor> CountersTable::CreateCursor() {
diff --git a/src/trace_processor/counters_table.h b/src/trace_processor/counters_table.h
index 53dacba..a28f366 100644
--- a/src/trace_processor/counters_table.h
+++ b/src/trace_processor/counters_table.h
@@ -39,9 +39,10 @@
static void RegisterTable(sqlite3* db, const TraceStorage* storage);
- CountersTable(const TraceStorage*);
+ CountersTable(sqlite3*, const TraceStorage*);
// Table implementation.
+ std::string CreateTableStmt(int argc, const char* const* argv) override;
std::unique_ptr<Table::Cursor> CreateCursor() override;
int BestIndex(const QueryConstraints&, BestIndexInfo*) override;
diff --git a/src/trace_processor/process_table.cc b/src/trace_processor/process_table.cc
index e999617..a5b34e4 100644
--- a/src/trace_processor/process_table.cc
+++ b/src/trace_processor/process_table.cc
@@ -29,16 +29,20 @@
} // namespace
-ProcessTable::ProcessTable(const TraceStorage* storage) : storage_(storage) {}
+ProcessTable::ProcessTable(sqlite3*, const TraceStorage* storage)
+ : storage_(storage) {}
void ProcessTable::RegisterTable(sqlite3* db, const TraceStorage* storage) {
- Table::Register<ProcessTable>(db, storage,
- "CREATE TABLE process("
- "upid UNSIGNED INT, "
- "name TEXT, "
- "pid UNSIGNED INT, "
- "PRIMARY KEY(upid)"
- ") WITHOUT ROWID;");
+ Table::Register<ProcessTable>(db, storage, "process");
+}
+
+std::string ProcessTable::CreateTableStmt(int, const char* const*) {
+ return "CREATE TABLE x("
+ "upid UNSIGNED INT, "
+ "name TEXT, "
+ "pid UNSIGNED INT, "
+ "PRIMARY KEY(upid)"
+ ") WITHOUT ROWID;";
}
std::unique_ptr<Table::Cursor> ProcessTable::CreateCursor() {
diff --git a/src/trace_processor/process_table.h b/src/trace_processor/process_table.h
index 64bd1f5..33c5a30 100644
--- a/src/trace_processor/process_table.h
+++ b/src/trace_processor/process_table.h
@@ -34,9 +34,10 @@
static void RegisterTable(sqlite3* db, const TraceStorage* storage);
- ProcessTable(const TraceStorage*);
+ ProcessTable(sqlite3*, const TraceStorage*);
// Table implementation.
+ std::string CreateTableStmt(int argc, const char* const* argv) override;
std::unique_ptr<Table::Cursor> CreateCursor() override;
int BestIndex(const QueryConstraints&, BestIndexInfo*) override;
diff --git a/src/trace_processor/sched_slice_table.cc b/src/trace_processor/sched_slice_table.cc
index 2813dd7..ee0bff7 100644
--- a/src/trace_processor/sched_slice_table.cc
+++ b/src/trace_processor/sched_slice_table.cc
@@ -89,19 +89,22 @@
} // namespace
-SchedSliceTable::SchedSliceTable(const TraceStorage* storage)
+SchedSliceTable::SchedSliceTable(sqlite3*, const TraceStorage* storage)
: storage_(storage) {}
void SchedSliceTable::RegisterTable(sqlite3* db, const TraceStorage* storage) {
- Table::Register<SchedSliceTable>(db, storage,
- "CREATE TABLE sched("
- "ts UNSIGNED BIG INT, "
- "cpu UNSIGNED INT, "
- "dur UNSIGNED BIG INT, "
- "utid UNSIGNED INT, "
- "cycles UNSIGNED BIG INT, "
- "PRIMARY KEY(cpu, ts)"
- ") WITHOUT ROWID;");
+ Table::Register<SchedSliceTable>(db, storage, "sched");
+}
+
+std::string SchedSliceTable::CreateTableStmt(int, const char* const*) {
+ return "CREATE TABLE sched("
+ "ts UNSIGNED BIG INT, "
+ "cpu UNSIGNED INT, "
+ "dur UNSIGNED BIG INT, "
+ "utid UNSIGNED INT, "
+ "cycles UNSIGNED BIG INT, "
+ "PRIMARY KEY(cpu, ts)"
+ ") WITHOUT ROWID;";
}
std::unique_ptr<Table::Cursor> SchedSliceTable::CreateCursor() {
diff --git a/src/trace_processor/sched_slice_table.h b/src/trace_processor/sched_slice_table.h
index f3e1750..25e4ee1 100644
--- a/src/trace_processor/sched_slice_table.h
+++ b/src/trace_processor/sched_slice_table.h
@@ -41,11 +41,12 @@
kCycles = 4,
};
- SchedSliceTable(const TraceStorage* storage);
+ SchedSliceTable(sqlite3*, const TraceStorage* storage);
static void RegisterTable(sqlite3* db, const TraceStorage* storage);
// Table implementation.
+ std::string CreateTableStmt(int argc, const char* const* argv) override;
std::unique_ptr<Table::Cursor> CreateCursor() override;
int BestIndex(const QueryConstraints&, BestIndexInfo*) override;
diff --git a/src/trace_processor/slice_table.cc b/src/trace_processor/slice_table.cc
index cbf82c8..e271d93 100644
--- a/src/trace_processor/slice_table.cc
+++ b/src/trace_processor/slice_table.cc
@@ -28,23 +28,27 @@
namespace perfetto {
namespace trace_processor {
-SliceTable::SliceTable(const TraceStorage* storage) : storage_(storage) {}
+SliceTable::SliceTable(sqlite3*, const TraceStorage* storage)
+ : storage_(storage) {}
void SliceTable::RegisterTable(sqlite3* db, const TraceStorage* storage) {
- Table::Register<SliceTable>(db, storage,
- "CREATE TABLE slices("
- "ts UNSIGNED BIG INT, "
- "dur UNSIGNED BIG INT, "
- "utid UNSIGNED INT,"
- "cat STRING,"
- "name STRING,"
- "depth INT,"
- "stack_id UNSIGNED BIG INT,"
- "parent_stack_id UNSIGNED BIG INT,"
- "PRIMARY KEY(utid, ts, depth)"
- ") WITHOUT ROWID;");
+ Table::Register<SliceTable>(db, storage, "slices");
+}
+
+std::string SliceTable::CreateTableStmt(int, const char* const*) {
// TODO(primiano): add support for ts_lower_bound. It requires the guarantee
// that slices are pushed in the storage monotonically.
+ return "CREATE TABLE x("
+ "ts UNSIGNED BIG INT, "
+ "dur UNSIGNED BIG INT, "
+ "utid UNSIGNED INT,"
+ "cat STRING,"
+ "name STRING,"
+ "depth INT,"
+ "stack_id UNSIGNED BIG INT,"
+ "parent_stack_id UNSIGNED BIG INT,"
+ "PRIMARY KEY(utid, ts, depth)"
+ ") WITHOUT ROWID;";
}
std::unique_ptr<Table::Cursor> SliceTable::CreateCursor() {
diff --git a/src/trace_processor/slice_table.h b/src/trace_processor/slice_table.h
index b821ec8..8cbf2a7 100644
--- a/src/trace_processor/slice_table.h
+++ b/src/trace_processor/slice_table.h
@@ -47,11 +47,12 @@
kParentStackId = 7,
};
- SliceTable(const TraceStorage* storage);
+ SliceTable(sqlite3*, const TraceStorage* storage);
static void RegisterTable(sqlite3* db, const TraceStorage* storage);
// Table implementation.
+ std::string CreateTableStmt(int argc, const char* const* argv) override;
std::unique_ptr<Table::Cursor> CreateCursor() override;
int BestIndex(const QueryConstraints&, BestIndexInfo*) override;
diff --git a/src/trace_processor/string_table.cc b/src/trace_processor/string_table.cc
index 7324d0c..9e204d1 100644
--- a/src/trace_processor/string_table.cc
+++ b/src/trace_processor/string_table.cc
@@ -28,15 +28,19 @@
namespace perfetto {
namespace trace_processor {
-StringTable::StringTable(const TraceStorage* storage) : storage_(storage) {}
+StringTable::StringTable(sqlite3*, const TraceStorage* storage)
+ : storage_(storage) {}
void StringTable::RegisterTable(sqlite3* db, const TraceStorage* storage) {
- Table::Register<StringTable>(db, storage,
- "CREATE TABLE strings("
- "id UNSIGNED BIG INT, "
- "str STRING,"
- "PRIMARY KEY(id)"
- ") WITHOUT ROWID;");
+ Table::Register<StringTable>(db, storage, "strings");
+}
+
+std::string StringTable::CreateTableStmt(int, const char* const*) {
+ return "CREATE TABLE x("
+ "id UNSIGNED BIG INT, "
+ "str STRING,"
+ "PRIMARY KEY(id)"
+ ") WITHOUT ROWID;";
}
std::unique_ptr<Table::Cursor> StringTable::CreateCursor() {
diff --git a/src/trace_processor/string_table.h b/src/trace_processor/string_table.h
index 324969f..1d5efc7 100644
--- a/src/trace_processor/string_table.h
+++ b/src/trace_processor/string_table.h
@@ -36,11 +36,12 @@
kString = 1,
};
- StringTable(const TraceStorage* storage);
+ StringTable(sqlite3*, const TraceStorage* storage);
static void RegisterTable(sqlite3* db, const TraceStorage* storage);
// Table implementation.
+ std::string CreateTableStmt(int argc, const char* const* argv) override;
std::unique_ptr<Table::Cursor> CreateCursor() override;
int BestIndex(const QueryConstraints&, BestIndexInfo*) override;
diff --git a/src/trace_processor/table.cc b/src/trace_processor/table.cc
index d21a014..75eac08 100644
--- a/src/trace_processor/table.cc
+++ b/src/trace_processor/table.cc
@@ -27,10 +27,9 @@
namespace {
struct TableDescriptor {
- std::string name;
- std::string create_statement;
Table::Factory factory;
const TraceStorage* storage = nullptr;
+ std::string name;
sqlite3_module module = {};
};
@@ -52,34 +51,31 @@
void Table::RegisterInternal(sqlite3* db,
const TraceStorage* storage,
- const std::string& create_statement,
+ const std::string& table_name,
Factory factory) {
- const std::string prefix = "CREATE TABLE ";
- PERFETTO_CHECK(create_statement.substr(0, prefix.size()) == prefix);
- size_t name_end = create_statement.find("(");
- PERFETTO_CHECK(name_end != std::string::npos && name_end > prefix.size());
- auto table_name =
- create_statement.substr(prefix.size(), name_end - prefix.size());
- PERFETTO_CHECK(table_name.size() > 0 && isalnum(table_name.front()) &&
- isalnum(table_name.back()));
-
std::unique_ptr<TableDescriptor> desc(new TableDescriptor());
- desc->name = table_name;
- desc->create_statement = create_statement;
desc->storage = storage;
desc->factory = factory;
+ desc->name = table_name;
sqlite3_module* module = &desc->module;
memset(module, 0, sizeof(*module));
- module->xConnect = [](sqlite3* xdb, void* arg, int, const char* const*,
- sqlite3_vtab** tab, char**) {
+ module->xConnect = [](sqlite3* xdb, void* arg, int argc,
+ const char* const* argv, sqlite3_vtab** tab, char**) {
const TableDescriptor* xdesc = static_cast<const TableDescriptor*>(arg);
- int res = sqlite3_declare_vtab(xdb, xdesc->create_statement.c_str());
+ auto table = xdesc->factory(xdb, xdesc->storage);
+
+ auto create_stmt = table->CreateTableStmt(argc, argv);
+ if (create_stmt.empty())
+ return SQLITE_ERROR;
+
+ int res = sqlite3_declare_vtab(xdb, create_stmt.c_str());
if (res != SQLITE_OK)
return res;
// Freed in xDisconnect().
- *tab = xdesc->factory(xdesc->storage, xdesc->name).release();
+ table->name_ = xdesc->name;
+ *tab = table.release();
return SQLITE_OK;
};
diff --git a/src/trace_processor/table.h b/src/trace_processor/table.h
index 9118d08..f5da6f3 100644
--- a/src/trace_processor/table.h
+++ b/src/trace_processor/table.h
@@ -37,8 +37,7 @@
class Table : public sqlite3_vtab {
public:
using Factory =
- std::function<std::unique_ptr<Table>(const TraceStorage*,
- const std::string& name)>;
+ std::function<std::unique_ptr<Table>(sqlite3*, const TraceStorage*)>;
// When set it logs all BestIndex and Filter actions on the console.
static bool debug;
@@ -80,11 +79,12 @@
template <typename T>
static void Register(sqlite3* db,
const TraceStorage* storage,
- const std::string& create_statement) {
- RegisterInternal(db, storage, create_statement, GetFactory<T>());
+ const std::string& name) {
+ RegisterInternal(db, storage, name, GetFactory<T>());
}
// Methods to be implemented by derived table classes.
+ virtual std::string CreateTableStmt(int argc, const char* const* argv) = 0;
virtual std::unique_ptr<Cursor> CreateCursor() = 0;
virtual int BestIndex(const QueryConstraints& qc, BestIndexInfo* info) = 0;
@@ -95,16 +95,14 @@
private:
template <typename TableType>
static Factory GetFactory() {
- return [](const TraceStorage* storage, const std::string& name) {
- auto table = std::unique_ptr<Table>(new TableType(storage));
- table->name_ = name;
- return table;
+ return [](sqlite3* db, const TraceStorage* storage) {
+ return std::unique_ptr<Table>(new TableType(db, storage));
};
}
static void RegisterInternal(sqlite3* db,
const TraceStorage*,
- const std::string& create,
+ const std::string& name,
Factory);
// Overriden functions from sqlite3_vtab.
diff --git a/src/trace_processor/thread_table.cc b/src/trace_processor/thread_table.cc
index 34287ce..c130c3c 100644
--- a/src/trace_processor/thread_table.cc
+++ b/src/trace_processor/thread_table.cc
@@ -29,17 +29,21 @@
} // namespace
-ThreadTable::ThreadTable(const TraceStorage* storage) : storage_(storage) {}
+ThreadTable::ThreadTable(sqlite3*, const TraceStorage* storage)
+ : storage_(storage) {}
void ThreadTable::RegisterTable(sqlite3* db, const TraceStorage* storage) {
- Table::Register<ThreadTable>(db, storage,
- "CREATE TABLE thread("
- "utid UNSIGNED INT, "
- "upid UNSIGNED INT, "
- "name TEXT, "
- "tid UNSIGNED INT, "
- "PRIMARY KEY(utid)"
- ") WITHOUT ROWID;");
+ Table::Register<ThreadTable>(db, storage, "thread");
+}
+
+std::string ThreadTable::CreateTableStmt(int, const char* const*) {
+ return "CREATE TABLE x("
+ "utid UNSIGNED INT, "
+ "upid UNSIGNED INT, "
+ "name TEXT, "
+ "tid UNSIGNED INT, "
+ "PRIMARY KEY(utid)"
+ ") WITHOUT ROWID;";
}
std::unique_ptr<Table::Cursor> ThreadTable::CreateCursor() {
diff --git a/src/trace_processor/thread_table.h b/src/trace_processor/thread_table.h
index d5b3609..9b19b1b 100644
--- a/src/trace_processor/thread_table.h
+++ b/src/trace_processor/thread_table.h
@@ -34,9 +34,10 @@
static void RegisterTable(sqlite3* db, const TraceStorage* storage);
- ThreadTable(const TraceStorage*);
+ ThreadTable(sqlite3*, const TraceStorage*);
// Table implementation.
+ std::string CreateTableStmt(int argc, const char* const* argv) override;
std::unique_ptr<Table::Cursor> CreateCursor() override;
int BestIndex(const QueryConstraints&, BestIndexInfo*) override;