Merge "trace_processor: make schema more explicit in tables"
diff --git a/src/trace_processor/counters_table.cc b/src/trace_processor/counters_table.cc
index 1cc4026..df5723d 100644
--- a/src/trace_processor/counters_table.cc
+++ b/src/trace_processor/counters_table.cc
@@ -36,17 +36,18 @@
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, "
- "value_delta UNSIGNED BIG INT, "
- "ref UNSIGNED INT, "
- "ref_type TEXT, "
- "PRIMARY KEY(name, ts, ref)"
- ") WITHOUT ROWID;";
+Table::Schema CountersTable::CreateSchema(int, const char* const*) {
+ return Schema(
+ {
+ Table::Column(Column::kTimestamp, "ts", ColumnType::kUlong),
+ Table::Column(Column::kName, "name", ColumnType::kString),
+ Table::Column(Column::kValue, "value", ColumnType::kUlong),
+ Table::Column(Column::kDuration, "dur", ColumnType::kUlong),
+ Table::Column(Column::kValueDelta, "value_delta", ColumnType::kUlong),
+ Table::Column(Column::kRef, "ref", ColumnType::kUint),
+ Table::Column(Column::kRefType, "ref_type", ColumnType::kString),
+ },
+ {Column::kName, Column::kTimestamp, Column::kRef});
}
std::unique_ptr<Table::Cursor> CountersTable::CreateCursor() {
diff --git a/src/trace_processor/counters_table.h b/src/trace_processor/counters_table.h
index 5ef21ba..83e41d7 100644
--- a/src/trace_processor/counters_table.h
+++ b/src/trace_processor/counters_table.h
@@ -43,7 +43,7 @@
CountersTable(sqlite3*, const TraceStorage*);
// Table implementation.
- std::string CreateTableStmt(int argc, const char* const* argv) override;
+ Table::Schema CreateSchema(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 a5b34e4..fab28e7 100644
--- a/src/trace_processor/process_table.cc
+++ b/src/trace_processor/process_table.cc
@@ -36,13 +36,14 @@
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;";
+Table::Schema ProcessTable::CreateSchema(int, const char* const*) {
+ return Schema(
+ {
+ Table::Column(Column::kUpid, "upid", ColumnType::kInt),
+ Table::Column(Column::kName, "name", ColumnType::kString),
+ Table::Column(Column::kPid, "pid", ColumnType::kUint),
+ },
+ {Column::kUpid});
}
std::unique_ptr<Table::Cursor> ProcessTable::CreateCursor() {
diff --git a/src/trace_processor/process_table.h b/src/trace_processor/process_table.h
index 33c5a30..9ba9ce5 100644
--- a/src/trace_processor/process_table.h
+++ b/src/trace_processor/process_table.h
@@ -37,7 +37,7 @@
ProcessTable(sqlite3*, const TraceStorage*);
// Table implementation.
- std::string CreateTableStmt(int argc, const char* const* argv) override;
+ Table::Schema CreateSchema(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 ab01a6d..bf0acf4 100644
--- a/src/trace_processor/sched_slice_table.cc
+++ b/src/trace_processor/sched_slice_table.cc
@@ -96,14 +96,15 @@
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, "
- "PRIMARY KEY(cpu, ts)"
- ") WITHOUT ROWID;";
+Table::Schema SchedSliceTable::CreateSchema(int, const char* const*) {
+ return Schema(
+ {
+ Table::Column(Column::kTimestamp, "ts", ColumnType::kUlong),
+ Table::Column(Column::kCpu, "cpu", ColumnType::kUint),
+ Table::Column(Column::kDuration, "dur", ColumnType::kUlong),
+ Table::Column(Column::kUtid, "utid", ColumnType::kUint),
+ },
+ {Column::kCpu, Column::kTimestamp});
}
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 582dded..255a3bb 100644
--- a/src/trace_processor/sched_slice_table.h
+++ b/src/trace_processor/sched_slice_table.h
@@ -45,7 +45,7 @@
static void RegisterTable(sqlite3* db, const TraceStorage* storage);
// Table implementation.
- std::string CreateTableStmt(int argc, const char* const* argv) override;
+ Table::Schema CreateSchema(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 e271d93..ee486bd 100644
--- a/src/trace_processor/slice_table.cc
+++ b/src/trace_processor/slice_table.cc
@@ -35,20 +35,20 @@
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;";
+Table::Schema SliceTable::CreateSchema(int, const char* const*) {
+ return Schema(
+ {
+ Table::Column(Column::kTimestamp, "ts", ColumnType::kUlong),
+ Table::Column(Column::kDuration, "dur", ColumnType::kUlong),
+ Table::Column(Column::kUtid, "utid", ColumnType::kUint),
+ Table::Column(Column::kCategory, "cat", ColumnType::kString),
+ Table::Column(Column::kName, "name", ColumnType::kString),
+ Table::Column(Column::kDepth, "depth", ColumnType::kInt),
+ Table::Column(Column::kStackId, "stack_id", ColumnType::kUlong),
+ Table::Column(Column::kParentStackId, "parent_stack_id",
+ ColumnType::kUlong),
+ },
+ {Column::kUtid, Column::kTimestamp, Column::kDepth});
}
std::unique_ptr<Table::Cursor> SliceTable::CreateCursor() {
diff --git a/src/trace_processor/slice_table.h b/src/trace_processor/slice_table.h
index 8cbf2a7..d575a10 100644
--- a/src/trace_processor/slice_table.h
+++ b/src/trace_processor/slice_table.h
@@ -52,7 +52,7 @@
static void RegisterTable(sqlite3* db, const TraceStorage* storage);
// Table implementation.
- std::string CreateTableStmt(int argc, const char* const* argv) override;
+ Table::Schema CreateSchema(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/span_operator_table.cc b/src/trace_processor/span_operator_table.cc
index 55ee520..cceba72 100644
--- a/src/trace_processor/span_operator_table.cc
+++ b/src/trace_processor/span_operator_table.cc
@@ -33,7 +33,7 @@
constexpr uint64_t kU64Max = std::numeric_limits<uint64_t>::max();
-std::vector<SpanOperatorTable::ColumnDefinition> GetColumnsForTable(
+std::vector<Table::Column> GetColumnsForTable(
sqlite3* db,
const std::string& raw_table_name) {
char sql[1024];
@@ -50,7 +50,7 @@
ScopedStmt stmt(raw_stmt);
PERFETTO_DCHECK(sqlite3_column_count(*stmt) == 2);
- std::vector<SpanOperatorTable::ColumnDefinition> columns;
+ std::vector<Table::Column> columns;
while (true) {
err = sqlite3_step(raw_stmt);
if (err == SQLITE_DONE)
@@ -62,29 +62,24 @@
const char* name =
reinterpret_cast<const char*>(sqlite3_column_text(*stmt, 0));
- const char* type =
+ const char* raw_type =
reinterpret_cast<const char*>(sqlite3_column_text(*stmt, 1));
- if (!name || !type || !*name || !*type) {
+ if (!name || !raw_type || !*name || !*raw_type) {
PERFETTO_ELOG("Schema has invalid column values");
return {};
}
- SpanOperatorTable::ColumnDefinition column;
- column.name = name;
- column.type_name = type;
-
- std::transform(column.type_name.begin(), column.type_name.end(),
- column.type_name.begin(), ::toupper);
- if (column.type_name == "UNSIGNED BIG INT") {
- column.type = SpanOperatorTable::Value::Type::kULong;
- } else if (column.type_name == "UNSIGNED INT") {
- column.type = SpanOperatorTable::Value::Type::kUInt;
- } else if (column.type_name == "TEXT") {
- column.type = SpanOperatorTable::Value::Type::kText;
+ Table::ColumnType type;
+ if (strcmp(raw_type, "UNSIGNED BIG INT") == 0) {
+ type = Table::ColumnType::kUlong;
+ } else if (strcmp(raw_type, "UNSIGNED INT") == 0) {
+ type = Table::ColumnType::kUint;
+ } else if (strcmp(raw_type, "STRING") == 0) {
+ type = Table::ColumnType::kString;
} else {
PERFETTO_FATAL("Unknown column type on table %s", raw_table_name.c_str());
}
- columns.emplace_back(column);
+ columns.emplace_back(columns.size(), name, type);
}
return columns;
}
@@ -99,12 +94,12 @@
Table::Register<SpanOperatorTable>(db, storage, "span");
}
-std::string SpanOperatorTable::CreateTableStmt(int argc,
- const char* const* argv) {
+Table::Schema SpanOperatorTable::CreateSchema(int argc,
+ const char* const* argv) {
// argv[0] - argv[2] are SQLite populated fields which are always present.
if (argc < 6) {
PERFETTO_ELOG("SPAN JOIN expected at least 3 args, received %d", argc - 3);
- return "";
+ return Table::Schema({}, {});
}
// The order arguments is (t1_name, t2_name, join_col).
@@ -120,8 +115,8 @@
// are actually valid to be joined i.e. they have the ts and dur columns and
// have the join column.
- auto filter_fn = [this](const ColumnDefinition& it) {
- return it.name == "ts" || it.name == "dur" || it.name == join_col_;
+ auto filter_fn = [this](const Table::Column& it) {
+ return it.name() == "ts" || it.name() == "dur" || it.name() == join_col_;
};
auto t1_remove_it =
std::remove_if(t1_defn_.cols.begin(), t1_defn_.cols.end(), filter_fn);
@@ -130,23 +125,19 @@
std::remove_if(t2_defn_.cols.begin(), t2_defn_.cols.end(), filter_fn);
t2_defn_.cols.erase(t2_remove_it, t2_defn_.cols.end());
- // Create the statement as the combination of the unique columns of the two
- // tables.
- std::string create_stmt;
- create_stmt +=
- "CREATE TABLE x("
- "ts UNSIGNED BIG INT, "
- "dur UNSIGNED BIG INT, ";
- create_stmt += join_col_ + " UNSIGNED INT, ";
+ std::vector<Table::Column> columns = {
+ Table::Column(Column::kTimestamp, "ts", ColumnType::kUlong),
+ Table::Column(Column::kDuration, "dur", ColumnType::kUlong),
+ Table::Column(Column::kJoinValue, join_col_, ColumnType::kUlong),
+ };
+ size_t index = kReservedColumns;
for (const auto& col : t1_defn_.cols) {
- create_stmt += col.name + " " + col.type_name + ", ";
+ columns.emplace_back(index++, col.name(), col.type());
}
for (const auto& col : t2_defn_.cols) {
- create_stmt += col.name + " " + col.type_name + ", ";
+ columns.emplace_back(index++, col.name(), col.type());
}
- create_stmt += "PRIMARY KEY(ts, " + join_col_ + ")) WITHOUT ROWID;";
- PERFETTO_DLOG("Create statement: %s", create_stmt.c_str());
- return create_stmt;
+ return Schema(columns, {Column::kTimestamp, kJoinValue});
}
std::unique_ptr<Table::Cursor> SpanOperatorTable::CreateCursor() {
@@ -187,7 +178,7 @@
std::string sql;
sql += "SELECT ts, dur, " + table_->join_col_;
for (const auto& col : def.cols) {
- sql += ", " + col.name;
+ sql += ", " + col.name();
}
sql += " FROM " + def.name;
sql += " WHERE 1";
@@ -206,7 +197,7 @@
auto index_pair = table_->GetTableAndColumnIndex(c);
bool is_constraint_in_current_table = index_pair.first == is_t1;
if (is_constraint_in_current_table) {
- col_name = def.cols[index_pair.second].name;
+ col_name = def.cols[index_pair.second].name();
}
}
@@ -352,19 +343,21 @@
size_t off = static_cast<size_t>(i - kReservedColumns);
Value* value = &pull_span->values[off];
- value->type = table_desc.cols[off].type;
+ value->type = table_desc.cols[off].type();
switch (value->type) {
- case Value::Type::kULong:
+ case Table::ColumnType::kUlong:
value->ulong_value =
static_cast<uint64_t>(sqlite3_column_int64(stmt, i));
break;
- case Value::Type::kUInt:
+ case Table::ColumnType::kUint:
value->uint_value = static_cast<uint32_t>(sqlite3_column_int(stmt, i));
break;
- case Value::Type::kText:
+ case Table::ColumnType::kString:
value->text_value =
reinterpret_cast<const char*>(sqlite3_column_text(stmt, i));
break;
+ case Table::ColumnType::kInt:
+ PERFETTO_CHECK(false);
}
}
@@ -440,14 +433,14 @@
sqlite3_context* context,
SpanOperatorTable::Value value) {
switch (value.type) {
- case Value::Type::kUInt:
+ case Table::ColumnType::kUint:
sqlite3_result_int(context, static_cast<int>(value.uint_value));
break;
- case Value::Type::kULong:
+ case Table::ColumnType::kUlong:
sqlite3_result_int64(context,
static_cast<sqlite3_int64>(value.ulong_value));
break;
- case Value::Type::kText:
+ case Table::ColumnType::kString: {
// Note: If you could guarantee that you never sqlite3_step() the cursor
// before accessing the values here, you could avoid string copies and
// pass through the const char* obtained in ExtractNext
@@ -456,6 +449,9 @@
sqlite3_result_text(context, value.text_value.c_str(), -1,
kSqliteTransient);
break;
+ }
+ case Table::ColumnType::kInt:
+ PERFETTO_CHECK(false);
}
}
diff --git a/src/trace_processor/span_operator_table.h b/src/trace_processor/span_operator_table.h
index 24d21ac..55c8c42 100644
--- a/src/trace_processor/span_operator_table.h
+++ b/src/trace_processor/span_operator_table.h
@@ -74,31 +74,18 @@
// Represents possible values of a SQLite joined table.
struct Value {
- enum Type {
- kText = 0,
- kULong = 1,
- kUInt = 2,
- };
-
- Type type;
+ Table::ColumnType type;
std::string text_value;
uint64_t ulong_value;
uint32_t uint_value;
};
- // Stores the definition of a column
- struct ColumnDefinition {
- std::string name;
- std::string type_name;
- Value::Type type = Value::Type::kText;
- };
-
SpanOperatorTable(sqlite3*, const TraceStorage*);
static void RegisterTable(sqlite3* db, const TraceStorage* storage);
// Table implementation.
- std::string CreateTableStmt(int argc, const char* const* argv) override;
+ Table::Schema CreateSchema(int argc, const char* const* argv) override;
std::unique_ptr<Table::Cursor> CreateCursor() override;
int BestIndex(const QueryConstraints& qc, BestIndexInfo* info) override;
@@ -108,7 +95,7 @@
// Contains the definition of the child tables.
struct TableDefinition {
std::string name;
- std::vector<ColumnDefinition> cols;
+ std::vector<Table::Column> cols;
std::string join_col_name;
};
diff --git a/src/trace_processor/string_table.cc b/src/trace_processor/string_table.cc
index 9e204d1..adbcabe 100644
--- a/src/trace_processor/string_table.cc
+++ b/src/trace_processor/string_table.cc
@@ -35,12 +35,13 @@
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;";
+Table::Schema StringTable::CreateSchema(int, const char* const*) {
+ return Schema(
+ {
+ Table::Column(Column::kStringId, "id", ColumnType::kUlong),
+ Table::Column(Column::kString, "str", ColumnType::kString),
+ },
+ {Column::kStringId});
}
std::unique_ptr<Table::Cursor> StringTable::CreateCursor() {
diff --git a/src/trace_processor/string_table.h b/src/trace_processor/string_table.h
index 1d5efc7..e74d834 100644
--- a/src/trace_processor/string_table.h
+++ b/src/trace_processor/string_table.h
@@ -41,7 +41,7 @@
static void RegisterTable(sqlite3* db, const TraceStorage* storage);
// Table implementation.
- std::string CreateTableStmt(int argc, const char* const* argv) override;
+ Table::Schema CreateSchema(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 ac0e4b8..d81b467 100644
--- a/src/trace_processor/table.cc
+++ b/src/trace_processor/table.cc
@@ -41,6 +41,20 @@
return static_cast<Table::Cursor*>(cursor);
}
+std::string TypeToString(Table::ColumnType type) {
+ switch (type) {
+ case Table::ColumnType::kString:
+ return "STRING";
+ case Table::ColumnType::kUint:
+ return "UNSIGNED INT";
+ case Table::ColumnType::kUlong:
+ return "UNSIGNED BIG INT";
+ case Table::ColumnType::kInt:
+ return "INT";
+ }
+ PERFETTO_CHECK(false);
+}
+
} // namespace
// static
@@ -66,15 +80,15 @@
const TableDescriptor* xdesc = static_cast<const TableDescriptor*>(arg);
auto table = xdesc->factory(xdb, xdesc->storage);
- auto create_stmt = table->CreateTableStmt(argc, argv);
- if (create_stmt.empty())
- return SQLITE_ERROR;
+ auto schema = table->CreateSchema(argc, argv);
+ auto create_stmt = schema.ToCreateTableStmt();
int res = sqlite3_declare_vtab(xdb, create_stmt.c_str());
if (res != SQLITE_OK)
return res;
// Freed in xDisconnect().
+ table->schema_ = schema;
table->name_ = xdesc->name;
*tab = table.release();
@@ -230,5 +244,41 @@
return Filter(table->qc_cache_, argv);
}
+Table::Column::Column(size_t index,
+ std::string name,
+ ColumnType type,
+ bool hidden)
+ : index_(index), name_(name), type_(type), hidden_(hidden) {}
+
+Table::Schema::Schema(std::vector<Column> columns,
+ std::vector<size_t> primary_keys)
+ : columns_(std::move(columns)), primary_keys_(std::move(primary_keys)) {
+ for (size_t i = 0; i < columns_.size(); i++) {
+ PERFETTO_CHECK(columns_[i].index() == i);
+ }
+ for (auto key : primary_keys_) {
+ PERFETTO_CHECK(key < columns_.size());
+ }
+}
+
+Table::Schema::Schema() = default;
+Table::Schema::Schema(const Schema&) = default;
+Table::Schema& Table::Schema::operator=(const Schema&) = default;
+
+std::string Table::Schema::ToCreateTableStmt() {
+ std::string stmt = "CREATE TABLE x(";
+ for (const auto& col : columns_) {
+ stmt += " " + col.name() + " " + TypeToString(col.type()) + ",";
+ }
+ stmt += " PRIMARY KEY(";
+ for (size_t i = 0; i < primary_keys_.size(); i++) {
+ if (i != 0)
+ stmt += ", ";
+ stmt += columns_[primary_keys_[i]].name();
+ }
+ stmt += ")) WITHOUT ROWID;";
+ return stmt;
+}
+
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/table.h b/src/trace_processor/table.h
index 26992f9..ba84d37 100644
--- a/src/trace_processor/table.h
+++ b/src/trace_processor/table.h
@@ -39,6 +39,34 @@
using Factory =
std::function<std::unique_ptr<Table>(sqlite3*, const TraceStorage*)>;
+ // Allowed types for columns in a table.
+ enum ColumnType {
+ kString = 1,
+ kUlong = 2,
+ kUint = 3,
+ kInt = 4,
+ };
+
+ // Describes a column of this table.
+ class Column {
+ public:
+ Column(size_t index,
+ std::string name,
+ ColumnType type,
+ bool hidden = false);
+
+ size_t index() const { return index_; }
+ const std::string& name() const { return name_; }
+ ColumnType type() const { return type_; }
+ bool hidden() const { return hidden_; }
+
+ private:
+ size_t index_ = 0;
+ std::string name_;
+ ColumnType type_ = ColumnType::kString;
+ bool hidden_ = false;
+ };
+
// When set it logs all BestIndex and Filter actions on the console.
static bool debug;
@@ -76,6 +104,30 @@
std::vector<bool> omit;
};
+ // The schema of the table. Created by subclasses to allow the table class to
+ // do filtering and inform SQLite about the CREATE table statement.
+ class Schema {
+ public:
+ Schema();
+ Schema(std::vector<Column>, std::vector<size_t> primary_keys);
+
+ // This class is explicitly copiable.
+ Schema(const Schema&) noexcept;
+ Schema& operator=(const Schema& t);
+
+ std::string ToCreateTableStmt();
+
+ const std::vector<Column>& columns() { return columns_; }
+ const std::vector<size_t> primary_keys() { return primary_keys_; }
+
+ private:
+ // The names and types of the columns of the table.
+ std::vector<Column> columns_;
+
+ // The primary keys of the table given by an offset into |columns|.
+ std::vector<size_t> primary_keys_;
+ };
+
Table();
// Called by derived classes to register themselves with the SQLite db.
@@ -88,7 +140,7 @@
}
// Methods to be implemented by derived table classes.
- virtual std::string CreateTableStmt(int argc, const char* const* argv) = 0;
+ virtual Schema CreateSchema(int argc, const char* const* argv) = 0;
virtual std::unique_ptr<Cursor> CreateCursor() = 0;
virtual int BestIndex(const QueryConstraints& qc, BestIndexInfo* info) = 0;
@@ -121,6 +173,8 @@
Table& operator=(const Table&) = delete;
std::string name_;
+ Schema schema_;
+
QueryConstraints qc_cache_;
int qc_hash_ = 0;
int best_index_num_ = 0;
diff --git a/src/trace_processor/thread_table.cc b/src/trace_processor/thread_table.cc
index c130c3c..4b6f2be 100644
--- a/src/trace_processor/thread_table.cc
+++ b/src/trace_processor/thread_table.cc
@@ -36,14 +36,15 @@
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;";
+Table::Schema ThreadTable::CreateSchema(int, const char* const*) {
+ return Schema(
+ {
+ Table::Column(Column::kUtid, "utid", ColumnType::kInt),
+ Table::Column(Column::kUpid, "upid", ColumnType::kInt),
+ Table::Column(Column::kName, "name", ColumnType::kString),
+ Table::Column(Column::kTid, "tid", ColumnType::kInt),
+ },
+ {Column::kUtid});
}
std::unique_ptr<Table::Cursor> ThreadTable::CreateCursor() {
diff --git a/src/trace_processor/thread_table.h b/src/trace_processor/thread_table.h
index 9b19b1b..ff6ef74 100644
--- a/src/trace_processor/thread_table.h
+++ b/src/trace_processor/thread_table.h
@@ -37,7 +37,7 @@
ThreadTable(sqlite3*, const TraceStorage*);
// Table implementation.
- std::string CreateTableStmt(int argc, const char* const* argv) override;
+ Table::Schema CreateSchema(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/window_operator_table.cc b/src/trace_processor/window_operator_table.cc
index 3648081..0c4dbc4 100644
--- a/src/trace_processor/window_operator_table.cc
+++ b/src/trace_processor/window_operator_table.cc
@@ -32,20 +32,25 @@
Table::Register<WindowOperatorTable>(db, storage, "window", true);
}
-std::string WindowOperatorTable::CreateTableStmt(int, const char* const*) {
- return "CREATE TABLE x("
- // These are the operator columns:
- "rowid HIDDEN UNSIGNED BIG INT, "
- "quantum HIDDEN UNSIGNED BIG INT, "
- "window_start HIDDEN UNSIGNED BIG INT, "
- "window_dur HIDDEN UNSIGNED BIG INT, "
- // These are the ouput columns:
- "ts UNSIGNED BIG INT, "
- "dur UNSIGNED BIG INT, "
- "cpu UNSIGNED INT, "
- "quantum_ts UNSIGNED BIG INT, "
- "PRIMARY KEY(rowid)"
- ") WITHOUT ROWID;";
+Table::Schema WindowOperatorTable::CreateSchema(int, const char* const*) {
+ const bool kHidden = true;
+ return Schema(
+ {
+ // These are the operator columns:
+ Table::Column(Column::kRowId, "rowid", ColumnType::kUlong, kHidden),
+ Table::Column(Column::kQuantum, "quantum", ColumnType::kUlong,
+ kHidden),
+ Table::Column(Column::kWindowStart, "window_start",
+ ColumnType::kUlong, kHidden),
+ Table::Column(Column::kWindowDur, "window_dur", ColumnType::kUlong,
+ kHidden),
+ // These are the ouput columns:
+ Table::Column(Column::kTs, "ts", ColumnType::kUlong),
+ Table::Column(Column::kDuration, "dur", ColumnType::kUlong),
+ Table::Column(Column::kCpu, "cpu", ColumnType::kUint),
+ Table::Column(Column::kQuantumTs, "quantum_ts", ColumnType::kUlong),
+ },
+ {Column::kRowId});
}
std::unique_ptr<Table::Cursor> WindowOperatorTable::CreateCursor() {
diff --git a/src/trace_processor/window_operator_table.h b/src/trace_processor/window_operator_table.h
index 8b2ac93..37b8f30 100644
--- a/src/trace_processor/window_operator_table.h
+++ b/src/trace_processor/window_operator_table.h
@@ -45,7 +45,7 @@
WindowOperatorTable(sqlite3*, const TraceStorage*);
// Table implementation.
- std::string CreateTableStmt(int argc, const char* const* argv) override;
+ Table::Schema CreateSchema(int argc, const char* const* argv) override;
std::unique_ptr<Table::Cursor> CreateCursor() override;
int BestIndex(const QueryConstraints&, BestIndexInfo*) override;
int Update(int, sqlite3_value**, sqlite3_int64*) override;