Merge changes I8ed3c55e,I021610d7 into main
* changes:
tp: Migrate stdlib to CREATE PERFETTO INDEX
tp: Fix validation
diff --git a/python/generators/sql_processing/utils.py b/python/generators/sql_processing/utils.py
index 567e888..d8408d7 100644
--- a/python/generators/sql_processing/utils.py
+++ b/python/generators/sql_processing/utils.py
@@ -192,22 +192,12 @@
# Given SQL string check whether there is (not allowlisted) usage of
# CREATE TABLE {name} AS.
-def check_banned_create_table_as(sql: str, filename: str, stdlib_path: str,
- allowlist: Dict[str, List[str]]) -> List[str]:
+def check_banned_create_table_as(sql: str, filename: str,
+ stdlib_path: str) -> List[str]:
errors = []
for _, matches in match_pattern(CREATE_TABLE_AS_PATTERN, sql).items():
name = matches[0]
- # Normalize paths before checking presence in the allowlist so it will
- # work on Windows for the Chrome stdlib presubmit.
- allowlist_normpath = dict(
- (os.path.normpath(path), tables) for path, tables in allowlist.items())
- allowlist_key = os.path.normpath(filename[len(stdlib_path):])
- if allowlist_key not in allowlist_normpath:
- errors.append(f"CREATE TABLE '{name}' is deprecated. "
- "Use CREATE PERFETTO TABLE instead.\n"
- f"Offending file: {filename}\n")
- continue
- if name not in allowlist_normpath[allowlist_key]:
+ if name != "trace_bounds":
errors.append(
f"Table '{name}' uses CREATE TABLE which is deprecated "
"and this table is not allowlisted. Use CREATE PERFETTO TABLE.\n"
diff --git a/src/trace_processor/db/column/dense_null_overlay.cc b/src/trace_processor/db/column/dense_null_overlay.cc
index 426c6d2..b31d8cb 100644
--- a/src/trace_processor/db/column/dense_null_overlay.cc
+++ b/src/trace_processor/db/column/dense_null_overlay.cc
@@ -95,6 +95,9 @@
if (op == FilterOp::kIsNull || op == FilterOp::kIsNotNull) {
return SearchValidationResult::kOk;
}
+ if (sql_val.is_null()) {
+ return SearchValidationResult::kNoData;
+ }
return inner_->ValidateSearchConstraints(op, sql_val);
}
diff --git a/src/trace_processor/db/column/id_storage.cc b/src/trace_processor/db/column/id_storage.cc
index 1ebe459..74a8147 100644
--- a/src/trace_processor/db/column/id_storage.cc
+++ b/src/trace_processor/db/column/id_storage.cc
@@ -60,12 +60,6 @@
if (op == FilterOp::kIsNotNull) {
return SearchValidationResult::kAllData;
}
- if (op == FilterOp::kIsNull) {
- return SearchValidationResult::kNoData;
- }
- PERFETTO_DFATAL(
- "Invalid filter operation. NULL should only be compared with 'IS NULL' "
- "and 'IS NOT NULL'");
return SearchValidationResult::kNoData;
}
diff --git a/src/trace_processor/db/column/null_overlay.cc b/src/trace_processor/db/column/null_overlay.cc
index 372d3b0..4e88682 100644
--- a/src/trace_processor/db/column/null_overlay.cc
+++ b/src/trace_processor/db/column/null_overlay.cc
@@ -148,6 +148,9 @@
if (op == FilterOp::kIsNull || op == FilterOp::kIsNotNull) {
return SearchValidationResult::kOk;
}
+ if (sql_val.is_null()) {
+ return SearchValidationResult::kNoData;
+ }
return inner_->ValidateSearchConstraints(op, sql_val);
}
diff --git a/src/trace_processor/db/column/numeric_storage.cc b/src/trace_processor/db/column/numeric_storage.cc
index 3612356..768c087 100644
--- a/src/trace_processor/db/column/numeric_storage.cc
+++ b/src/trace_processor/db/column/numeric_storage.cc
@@ -257,12 +257,7 @@
if (op == FilterOp::kIsNotNull) {
return SearchValidationResult::kAllData;
}
- if (op == FilterOp::kIsNull) {
- return SearchValidationResult::kNoData;
- }
- PERFETTO_FATAL(
- "Invalid path. NULL should only be compared with 'IS NULL' and 'IS NOT "
- "NULL'");
+ return SearchValidationResult::kNoData;
}
// FilterOp checks. Switch so that we get a warning if new FilterOp is not
diff --git a/src/trace_processor/db/column/range_overlay.cc b/src/trace_processor/db/column/range_overlay.cc
index dee7838..9c9e05a 100644
--- a/src/trace_processor/db/column/range_overlay.cc
+++ b/src/trace_processor/db/column/range_overlay.cc
@@ -51,6 +51,10 @@
SearchValidationResult RangeOverlay::ChainImpl::ValidateSearchConstraints(
FilterOp op,
SqlValue sql_val) const {
+ if (sql_val.is_null() &&
+ !(op == FilterOp::kIsNotNull || op == FilterOp::kIsNull)) {
+ return SearchValidationResult::kNoData;
+ }
return inner_->ValidateSearchConstraints(op, sql_val);
}
diff --git a/src/trace_processor/db/column/selector_overlay.cc b/src/trace_processor/db/column/selector_overlay.cc
index 9e957cb..7e858cf 100644
--- a/src/trace_processor/db/column/selector_overlay.cc
+++ b/src/trace_processor/db/column/selector_overlay.cc
@@ -52,6 +52,10 @@
SearchValidationResult SelectorOverlay::ChainImpl::ValidateSearchConstraints(
FilterOp op,
SqlValue sql_val) const {
+ if (sql_val.is_null() &&
+ !(op == FilterOp::kIsNotNull || op == FilterOp::kIsNull)) {
+ return SearchValidationResult::kNoData;
+ }
return inner_->ValidateSearchConstraints(op, sql_val);
}
diff --git a/src/trace_processor/db/column/set_id_storage.cc b/src/trace_processor/db/column/set_id_storage.cc
index 42ab4ea..c37460e 100644
--- a/src/trace_processor/db/column/set_id_storage.cc
+++ b/src/trace_processor/db/column/set_id_storage.cc
@@ -82,12 +82,7 @@
if (op == FilterOp::kIsNotNull) {
return SearchValidationResult::kAllData;
}
- if (op == FilterOp::kIsNull) {
- return SearchValidationResult::kNoData;
- }
- PERFETTO_FATAL(
- "Invalid filter operation. NULL should only be compared with 'IS NULL' "
- "and 'IS NOT NULL'");
+ return SearchValidationResult::kNoData;
}
// FilterOp checks. Switch so that we get a warning if new FilterOp is not
diff --git a/src/trace_processor/db/column/string_storage.cc b/src/trace_processor/db/column/string_storage.cc
index 1d25dbb..3aa00e9 100644
--- a/src/trace_processor/db/column/string_storage.cc
+++ b/src/trace_processor/db/column/string_storage.cc
@@ -254,6 +254,10 @@
// Type checks.
switch (val.type) {
case SqlValue::kNull:
+ if (op != FilterOp::kIsNotNull && op != FilterOp::kIsNull) {
+ return SearchValidationResult::kNoData;
+ }
+ break;
case SqlValue::kString:
break;
case SqlValue::kLong:
diff --git a/src/trace_processor/db/query_executor.cc b/src/trace_processor/db/query_executor.cc
index 8880ae9..26a416b 100644
--- a/src/trace_processor/db/query_executor.cc
+++ b/src/trace_processor/db/query_executor.cc
@@ -84,12 +84,14 @@
}
}
- // Comparison of NULL with any operation apart from |IS_NULL| and
- // |IS_NOT_NULL| should return no rows.
- if (c.value.is_null() && c.op != FilterOp::kIsNull &&
- c.op != FilterOp::kIsNotNull) {
- rm->Clear();
- return;
+ switch (chain.ValidateSearchConstraints(c.op, c.value)) {
+ case SearchValidationResult::kNoData:
+ rm->Clear();
+ return;
+ case SearchValidationResult::kAllData:
+ return;
+ case SearchValidationResult::kOk:
+ break;
}
uint32_t rm_last = rm->Get(rm_size - 1);
diff --git a/src/trace_processor/perfetto_sql/engine/perfetto_sql_engine.cc b/src/trace_processor/perfetto_sql/engine/perfetto_sql_engine.cc
index a6aa6f2..ceeddf9 100644
--- a/src/trace_processor/perfetto_sql/engine/perfetto_sql_engine.cc
+++ b/src/trace_processor/perfetto_sql/engine/perfetto_sql_engine.cc
@@ -648,12 +648,9 @@
q.orders = obs;
RowMap sorted_rm = t->QueryToRowMap(q);
- PERFETTO_CHECK(sorted_rm.IsIndexVector());
- std::vector<uint32_t> sorted_indices =
- std::move(sorted_rm).TakeAsIndexVector();
-
RETURN_IF_ERROR(t->SetIndex(index.name, std::move(col_idxs),
- std::move(sorted_indices), index.replace));
+ std::move(sorted_rm).TakeAsIndexVector(),
+ index.replace));
return base::OkStatus();
}
diff --git a/src/trace_processor/perfetto_sql/engine/perfetto_sql_parser.cc b/src/trace_processor/perfetto_sql/engine/perfetto_sql_parser.cc
index 13edd57..78eaf41 100644
--- a/src/trace_processor/perfetto_sql/engine/perfetto_sql_parser.cc
+++ b/src/trace_processor/perfetto_sql/engine/perfetto_sql_parser.cc
@@ -350,7 +350,7 @@
token = tokenizer_.NextNonWhitespace();
if (token.token_type != SqliteTokenType::TK_LP) {
base::StackString<1024> err(
- "Expected parenthesis after table name, received %*s.",
+ "Expected parenthesis after table name, received '%*s'.",
static_cast<int>(token.str.size()), token.str.data());
return ErrorAtToken(token, err.c_str());
}
@@ -359,18 +359,12 @@
do {
Token col_name_tok = tokenizer_.NextNonWhitespace();
- if (col_name_tok.token_type != SqliteTokenType::TK_ID) {
- base::StackString<1024> err("Invalid column name %.*s",
- static_cast<int>(col_name_tok.str.size()),
- col_name_tok.str.data());
- return ErrorAtToken(col_name_tok, err.c_str());
- }
cols.push_back(std::string(col_name_tok.str));
token = tokenizer_.NextNonWhitespace();
} while (token.token_type == SqliteTokenType::TK_COMMA);
if (token.token_type != SqliteTokenType::TK_RP) {
- base::StackString<1024> err("Expected closed parenthesis, received %*s.",
+ base::StackString<1024> err("Expected closed parenthesis, received '%*s'.",
static_cast<int>(token.str.size()),
token.str.data());
return ErrorAtToken(token, err.c_str());
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/binder.sql b/src/trace_processor/perfetto_sql/stdlib/android/binder.sql
index 70e0c7a..2991dee 100644
--- a/src/trace_processor/perfetto_sql/stdlib/android/binder.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/android/binder.sql
@@ -157,7 +157,7 @@
binder_txn_id,
binder_reply_id;
-CREATE TABLE _oom_score AS
+CREATE PERFETTO TABLE _oom_score AS
SELECT
process.upid,
CAST(c.value AS INT) AS value,
@@ -168,7 +168,7 @@
JOIN process USING (upid)
WHERE t.name = 'oom_score_adj';
-CREATE INDEX _oom_score_idx ON _oom_score(upid, ts);
+CREATE PERFETTO INDEX _oom_score_idx ON _oom_score(upid, ts);
-- Breakdown synchronous binder transactions per txn.
-- It returns data about the client and server ends of every binder transaction.
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/monitor_contention.sql b/src/trace_processor/perfetto_sql/stdlib/android/monitor_contention.sql
index 005f867..c7ad3bf 100644
--- a/src/trace_processor/perfetto_sql/stdlib/android/monitor_contention.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/android/monitor_contention.sql
@@ -121,29 +121,62 @@
GROUP BY slice.id;
-- Contains parsed monitor contention slices.
---
--- @column blocking_method Name of the method holding the lock.
--- @column blocked_methhod Name of the method trying to acquire the lock.
--- @column short_blocking_method Blocking_method without arguments and return types.
--- @column short_blocked_method Blocked_method without arguments and return types.
--- @column blocking_src File location of blocking_method in form <filename:linenumber>.
--- @column blocked_src File location of blocked_method in form <filename:linenumber>.
--- @column waiter_count Zero indexed number of threads trying to acquire the lock.
--- @column blocking_utid Utid of thread holding the lock.
--- @column blocking_thread_name Thread name of thread holding the lock.
--- @column upid Upid of process experiencing lock contention.
--- @column process_name Process name of process experiencing lock contention.
--- @column id Slice id of lock contention.
--- @column ts Timestamp of lock contention start.
--- @column dur Wall clock duration of lock contention.
--- @column monotonic_dur Monotonic clock duration of lock contention.
--- @column track_id Thread track id of blocked thread.
--- @column is_blocked_main_thread Whether the blocked thread is the main thread.
--- @column is_blocking_main_thread Whether the blocking thread is the main thread.
--- @column binder_reply_id Slice id of binder reply slice if lock contention was part of a binder txn.
--- @column binder_reply_ts Timestamp of binder reply slice if lock contention was part of a binder txn.
--- @column binder_reply_tid Tid of binder reply slice if lock contention was part of a binder txn.
-CREATE TABLE android_monitor_contention AS
+CREATE PERFETTO TABLE android_monitor_contention(
+-- Name of the method holding the lock.
+blocking_method STRING,
+-- Blocked_method without arguments and return types.
+blocked_method STRING,
+-- Blocking_method without arguments and return types.
+short_blocking_method STRING,
+-- Blocked_method without arguments and return types.
+short_blocked_method STRING,
+-- File location of blocking_method in form <filename:linenumber>.
+blocking_src STRING,
+-- File location of blocked_method in form <filename:linenumber>.
+blocked_src STRING,
+-- Zero indexed number of threads trying to acquire the lock.
+waiter_count INT,
+-- Utid of thread holding the lock.
+blocked_utid INT,
+-- Thread name of thread holding the lock.
+blocked_thread_name STRING,
+-- Utid of thread holding the lock.
+blocking_utid INT,
+-- Thread name of thread holding the lock.
+blocking_thread_name STRING,
+-- Tid of thread holding the lock.
+blocking_tid INT,
+-- Upid of process experiencing lock contention.
+upid INT,
+-- Process name of process experiencing lock contention.
+process_name STRING,
+-- Slice id of lock contention.
+id INT,
+-- Timestamp of lock contention start.
+ts INT,
+-- Wall clock duration of lock contention.
+dur INT,
+-- Monotonic clock duration of lock contention.
+monotonic_dur INT,
+-- Thread track id of blocked thread.
+track_id INT,
+-- Whether the blocked thread is the main thread.
+is_blocked_thread_main INT,
+-- Tid of the blocked thread
+blocked_thread_tid INT,
+-- Whether the blocking thread is the main thread.
+is_blocking_thread_main INT,
+-- Tid of thread holding the lock.
+blocking_thread_tid INT,
+-- Slice id of binder reply slice if lock contention was part of a binder txn.
+binder_reply_id INT,
+-- Timestamp of binder reply slice if lock contention was part of a binder txn.
+binder_reply_ts INT,
+-- Tid of binder reply slice if lock contention was part of a binder txn.
+binder_reply_tid INT,
+-- Pid of process experiencing lock contention.
+pid INT
+) AS
SELECT
android_extract_android_monitor_contention_blocking_method(slice.name) AS blocking_method,
android_extract_android_monitor_contention_blocked_method(slice.name) AS blocked_method,
@@ -192,10 +225,10 @@
AND short_blocked_method IS NOT NULL
GROUP BY slice.id;
-CREATE INDEX _android_monitor_contention_blocking_utid_idx
+CREATE PERFETTO INDEX _android_monitor_contention_blocking_utid_idx
ON android_monitor_contention (blocking_utid, ts);
-CREATE INDEX _android_monitor_contention_id_idx
+CREATE PERFETTO INDEX _android_monitor_contention_id_idx
ON android_monitor_contention (id);
-- Monitor contention slices that are blocked by another monitor contention slice.
@@ -214,7 +247,7 @@
-- Monitor contention slices that are neither blocking nor blocked by another monitor contention
-- slice. They neither have |parent_id| nor |child_id| fields.
-CREATE TABLE _isolated AS
+CREATE PERFETTO TABLE _isolated AS
WITH parents_and_children AS (
SELECT id FROM _children
UNION ALL
@@ -227,31 +260,66 @@
SELECT * FROM android_monitor_contention JOIN isolated USING (id);
-- Contains parsed monitor contention slices with the parent-child relationships.
---
--- @column parent_id Id of monitor contention slice blocking this contention.
--- @column blocking_method Name of the method holding the lock.
--- @column blocked_methhod Name of the method trying to acquire the lock.
--- @column short_blocking_method Blocking_method without arguments and return types.
--- @column short_blocked_method Blocked_method without arguments and return types.
--- @column blocking_src File location of blocking_method in form <filename:linenumber>.
--- @column blocked_src File location of blocked_method in form <filename:linenumber>.
--- @column waiter_count Zero indexed number of threads trying to acquire the lock.
--- @column blocking_utid Utid of thread holding the lock.
--- @column blocking_thread_name Thread name of thread holding the lock.
--- @column upid Upid of process experiencing lock contention.
--- @column process_name Process name of process experiencing lock contention.
--- @column id Slice id of lock contention.
--- @column ts Timestamp of lock contention start.
--- @column dur Wall clock duration of lock contention.
--- @column monotonic_dur Monotonic clock duration of lock contention.
--- @column track_id Thread track id of blocked thread.
--- @column is_blocked_main_thread Whether the blocked thread is the main thread.
--- @column is_blocking_main_thread Whether the blocking thread is the main thread.
--- @column binder_reply_id Slice id of binder reply slice if lock contention was part of a binder txn.
--- @column binder_reply_ts Timestamp of binder reply slice if lock contention was part of a binder txn.
--- @column binder_reply_tid Tid of binder reply slice if lock contention was part of a binder txn.
--- @column child_id Id of monitor contention slice blocked by this contention.
-CREATE TABLE android_monitor_contention_chain AS
+CREATE PERFETTO TABLE android_monitor_contention_chain(
+-- Id of monitor contention slice blocking this contention.
+parent_id INT,
+-- Name of the method holding the lock.
+blocking_method STRING,
+-- Blocked_method without arguments and return types.
+blocked_method STRING,
+-- Blocking_method without arguments and return types.
+short_blocking_method STRING,
+-- Blocked_method without arguments and return types.
+short_blocked_method STRING,
+-- File location of blocking_method in form <filename:linenumber>.
+blocking_src STRING,
+-- File location of blocked_method in form <filename:linenumber>.
+blocked_src STRING,
+-- Zero indexed number of threads trying to acquire the lock.
+waiter_count INT,
+-- Utid of thread holding the lock.
+blocked_utid INT,
+-- Thread name of thread holding the lock.
+blocked_thread_name STRING,
+-- Utid of thread holding the lock.
+blocking_utid INT,
+-- Thread name of thread holding the lock.
+blocking_thread_name STRING,
+-- Tid of thread holding the lock.
+blocking_tid INT,
+-- Upid of process experiencing lock contention.
+upid INT,
+-- Process name of process experiencing lock contention.
+process_name STRING,
+-- Slice id of lock contention.
+id INT,
+-- Timestamp of lock contention start.
+ts INT,
+-- Wall clock duration of lock contention.
+dur INT,
+-- Monotonic clock duration of lock contention.
+monotonic_dur INT,
+-- Thread track id of blocked thread.
+track_id INT,
+-- Whether the blocked thread is the main thread.
+is_blocked_thread_main INT,
+-- Tid of the blocked thread
+blocked_thread_tid INT,
+-- Whether the blocking thread is the main thread.
+is_blocking_thread_main INT,
+-- Tid of thread holding the lock.
+blocking_thread_tid INT,
+-- Slice id of binder reply slice if lock contention was part of a binder txn.
+binder_reply_id INT,
+-- Timestamp of binder reply slice if lock contention was part of a binder txn.
+binder_reply_ts INT,
+-- Tid of binder reply slice if lock contention was part of a binder txn.
+binder_reply_tid INT,
+-- Pid of process experiencing lock contention.
+pid INT,
+-- Id of monitor contention slice blocked by this contention.
+child_id INT
+) AS
SELECT NULL AS parent_id, *, NULL AS child_id FROM _isolated
UNION ALL
SELECT c.*, p.child_id FROM _children c
@@ -260,7 +328,7 @@
SELECT c.parent_id, p.* FROM _parents p
LEFT JOIN _children c USING(id);
-CREATE INDEX _android_monitor_contention_chain_idx
+CREATE PERFETTO INDEX _android_monitor_contention_chain_idx
ON android_monitor_contention_chain (blocking_method, blocking_utid, ts);
-- First blocked node on a lock, i.e nodes with |waiter_count| = 0. The |dur| here is adjusted
diff --git a/src/trace_processor/perfetto_sql/stdlib/chrome/tasks.sql b/src/trace_processor/perfetto_sql/stdlib/chrome/tasks.sql
index a177cba..35c9335 100644
--- a/src/trace_processor/perfetto_sql/stdlib/chrome/tasks.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/chrome/tasks.sql
@@ -105,7 +105,7 @@
--
-- Note: this might include messages received within a sync mojo call.
-- TODO(altimin): This should use EXTEND_TABLE when it becomes available.
-CREATE TABLE _chrome_mojo_slices AS
+CREATE PERFETTO TABLE _chrome_mojo_slices AS
WITH
-- Select all new-style (post crrev.com/c/3270337) mojo slices and
-- generate |task_name| for them.
@@ -153,17 +153,16 @@
FROM slice
WHERE
category GLOB "*toplevel*" AND name = "Connector::DispatchMessage"
-)
+),
+merged AS (
-- Merge all mojo slices.
SELECT * FROM new_mojo_slices
UNION ALL
SELECT * FROM old_associated_mojo_slices
UNION ALL
-SELECT * FROM old_non_associated_mojo_slices;
-
--- As we lookup by ID on |_chrome_mojo_slices| table, add an index on
--- id to make lookups fast.
-CREATE INDEX _chrome_mojo_slices_idx ON _chrome_mojo_slices(id);
+SELECT * FROM old_non_associated_mojo_slices
+)
+SELECT * FROM merged ORDER BY id;
-- This table contains a list of slices corresponding to the _representative_
-- Chrome Java view operations.
@@ -178,7 +177,7 @@
-- capture toolbar screenshot.
-- @column is_hardware_screenshot BOOL Whether this slice is a part of accelerated
-- capture toolbar screenshot.
-CREATE TABLE _chrome_java_views AS
+CREATE PERFETTO TABLE _chrome_java_views AS
WITH
-- .draw, .onLayout and .onMeasure parts of the java view names don't add much, strip them.
java_slices_with_trimmed_names AS (
@@ -363,7 +362,7 @@
GROUP BY root.id;
-- A list of tasks executed by Chrome scheduler.
-CREATE TABLE _chrome_scheduler_tasks AS
+CREATE PERFETTO TABLE _chrome_scheduler_tasks AS
SELECT
id
FROM slice
@@ -476,7 +475,7 @@
-- @column task_name STRING Name for the given task.
-- @column task_type STRING Type of the task (e.g. "scheduler").
-- @column scheduling_delay INT
-CREATE TABLE _chrome_tasks AS
+CREATE PERFETTO TABLE _chrome_tasks AS
WITH
-- Select slices from "toplevel" category which do not have another
-- "toplevel" slice as ancestor. The possible cases include sync mojo messages
diff --git a/src/trace_processor/perfetto_sql/stdlib/slices/flat_slices.sql b/src/trace_processor/perfetto_sql/stdlib/slices/flat_slices.sql
index 9456911..066314b 100644
--- a/src/trace_processor/perfetto_sql/stdlib/slices/flat_slices.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/slices/flat_slices.sql
@@ -53,7 +53,7 @@
-- @column upid Alias for `process.upid`.
-- @column pid Alias for `process.pid`.
-- @column process_name Alias for `process.name`.
-CREATE TABLE _slice_flattened
+CREATE PERFETTO TABLE _slice_flattened
AS
WITH
root_slices AS (
@@ -86,10 +86,8 @@
JOIN thread_slice
USING (id);
-CREATE
- INDEX _slice_flattened_id_idx
+CREATE PERFETTO INDEX _slice_flattened_id_idx
ON _slice_flattened(slice_id);
-CREATE
- INDEX _slice_flattened_ts_idx
+CREATE PERFETTO INDEX _slice_flattened_ts_idx
ON _slice_flattened(ts);
diff --git a/src/trace_processor/perfetto_sql/stdlib/wattson/curves/utils.sql b/src/trace_processor/perfetto_sql/stdlib/wattson/curves/utils.sql
index 8e07e17..333a532 100644
--- a/src/trace_processor/perfetto_sql/stdlib/wattson/curves/utils.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/wattson/curves/utils.sql
@@ -23,7 +23,7 @@
JOIN _wattson_device as device ON dc.device = device.name
JOIN _dev_cpu_policy_map as cp ON dc.policy = cp.policy;
-CREATE TABLE _filtered_curves_1d AS
+CREATE PERFETTO TABLE _filtered_curves_1d AS
SELECT policy, freq_khz, -1 as idle, active as curve_value
FROM _filtered_curves_1d_raw
UNION
@@ -36,7 +36,7 @@
SELECT policy, freq_khz, 255, static
FROM _filtered_curves_1d_raw;
-CREATE INDEX freq_1d ON _filtered_curves_1d(policy, freq_khz, idle);
+CREATE PERFETTO INDEX freq_1d ON _filtered_curves_1d(policy, freq_khz, idle);
-- 2D LUT; with dependency on another CPU
CREATE PERFETTO TABLE _filtered_curves_2d_raw AS
@@ -52,7 +52,7 @@
JOIN _wattson_device as device ON dc.device = device.name
JOIN _dev_cpu_policy_map as cp ON dc.other_policy = cp.policy;
-CREATE TABLE _filtered_curves_2d AS
+CREATE PERFETTO TABLE _filtered_curves_2d AS
SELECT freq_khz, other_policy, other_freq_khz, -1 as idle, active as curve_value
FROM _filtered_curves_2d_raw
UNION
@@ -65,7 +65,7 @@
SELECT freq_khz, other_policy, other_freq_khz, 255, static
FROM _filtered_curves_2d_raw;
-CREATE INDEX freq_2d
+CREATE PERFETTO INDEX freq_2d
ON _filtered_curves_2d(freq_khz, other_policy, other_freq_khz, idle);
-- L3 cache LUT
@@ -80,14 +80,14 @@
JOIN _wattson_device as device ON dc.device = device.name
JOIN _dev_cpu_policy_map as cp ON dc.other_policy = cp.policy;
-CREATE TABLE _filtered_curves_l3 AS
+CREATE PERFETTO TABLE _filtered_curves_l3 AS
SELECT
- freq_khz, other_policy, other_freq_khz, 'hit' as action, l3_hit as curve_value
+ freq_khz, other_policy, other_freq_khz, 'hit' AS action, l3_hit as curve_value
FROM _filtered_curves_l3_raw
UNION
SELECT
- freq_khz, other_policy, other_freq_khz, 'miss', l3_miss
+ freq_khz, other_policy, other_freq_khz, 'miss' AS action, l3_miss
FROM _filtered_curves_l3_raw;
-CREATE INDEX freq_l3
+CREATE PERFETTO INDEX freq_l3
ON _filtered_curves_l3(freq_khz, other_policy, other_freq_khz, action);
diff --git a/tools/check_sql_metrics.py b/tools/check_sql_metrics.py
index aa394c2..cd82c6d 100755
--- a/tools/check_sql_metrics.py
+++ b/tools/check_sql_metrics.py
@@ -27,12 +27,36 @@
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(os.path.join(ROOT_DIR))
-from python.generators.sql_processing.utils import check_banned_create_table_as
from python.generators.sql_processing.utils import check_banned_create_view_as
from python.generators.sql_processing.utils import check_banned_words
from python.generators.sql_processing.utils import match_pattern
from python.generators.sql_processing.utils import DROP_TABLE_VIEW_PATTERN
from python.generators.sql_processing.utils import CREATE_TABLE_VIEW_PATTERN
+from python.generators.sql_processing.utils import CREATE_TABLE_AS_PATTERN
+
+
+def check_if_create_table_allowlisted(
+ sql: str, filename: str, stdlib_path: str,
+ allowlist: Dict[str, List[str]]) -> List[str]:
+ errors = []
+ for _, matches in match_pattern(CREATE_TABLE_AS_PATTERN, sql).items():
+ name = matches[0]
+ # Normalize paths before checking presence in the allowlist so it will
+ # work on Windows for the Chrome stdlib presubmit.
+ allowlist_normpath = dict(
+ (os.path.normpath(path), tables) for path, tables in allowlist.items())
+ allowlist_key = os.path.normpath(filename[len(stdlib_path):])
+ if allowlist_key not in allowlist_normpath:
+ errors.append(f"CREATE TABLE '{name}' is deprecated. "
+ "Use CREATE PERFETTO TABLE instead.\n"
+ f"Offending file: {filename}\n")
+ continue
+ if name not in allowlist_normpath[allowlist_key]:
+ errors.append(
+ f"Table '{name}' uses CREATE TABLE which is deprecated "
+ "and this table is not allowlisted. Use CREATE PERFETTO TABLE.\n"
+ f"Offending file: {filename}\n")
+ return errors
# Allowlist path are relative to the metrics root.
CREATE_TABLE_ALLOWLIST = {
@@ -99,10 +123,10 @@
sql, CREATE_TABLE_VIEW_PATTERN)
drop_table_view_dir = match_drop_view_pattern_to_dict(
sql, DROP_TABLE_VIEW_PATTERN)
- errors += check_banned_create_table_as(sql,
- path.split(ROOT_DIR)[1],
- metrics_sources.split(ROOT_DIR)[1],
- CREATE_TABLE_ALLOWLIST)
+ errors += check_if_create_table_allowlisted(
+ sql,
+ path.split(ROOT_DIR)[1],
+ metrics_sources.split(ROOT_DIR)[1], CREATE_TABLE_ALLOWLIST)
errors += check_banned_create_view_as(sql, path.split(ROOT_DIR)[1])
for name, [line, type] in create_table_view_dir.items():
if name not in drop_table_view_dir:
diff --git a/tools/check_sql_modules.py b/tools/check_sql_modules.py
index 17d0115..7765697 100755
--- a/tools/check_sql_modules.py
+++ b/tools/check_sql_modules.py
@@ -32,27 +32,6 @@
from python.generators.sql_processing.utils import check_banned_words
from python.generators.sql_processing.utils import check_banned_include_all
-# Allowlist path are relative to the stdlib root.
-CREATE_TABLE_ALLOWLIST = {
- '/prelude/trace_bounds.sql': ['trace_bounds'],
- '/android/binder.sql': ['_oom_score'],
- '/android/monitor_contention.sql': [
- '_isolated', 'android_monitor_contention_chain',
- 'android_monitor_contention'
- ],
- '/chrome/tasks.sql': [
- '_chrome_mojo_slices', '_chrome_java_views', '_chrome_scheduler_tasks',
- '_chrome_tasks'
- ],
- '/sched/thread_executing_span.sql': [
- '_wakeup_graph', '_thread_executing_span_graph', '_critical_path'
- ],
- '/slices/flat_slices.sql': ['_slice_flattened'],
- '/wattson/curves/utils.sql': [
- '_filtered_curves_1d', '_filtered_curves_2d', '_filtered_curves_l3'
- ],
-}
-
def main():
parser = argparse.ArgumentParser()
@@ -126,7 +105,7 @@
errors += check_banned_create_table_as(
sql,
path.split(ROOT_DIR)[1],
- args.stdlib_sources.split(ROOT_DIR)[1], CREATE_TABLE_ALLOWLIST)
+ args.stdlib_sources.split(ROOT_DIR)[1])
errors += check_banned_create_view_as(sql, path.split(ROOT_DIR)[1])
errors += check_banned_include_all(sql, path.split(ROOT_DIR)[1])