Migrate create_view_function to Perfetto SQL.

R=lalitm@google.com

Change-Id: I4fd050eb75540a2a8255e42a33de0b0b31fdd8a7
diff --git a/python/generators/sql_processing/docs_parse.py b/python/generators/sql_processing/docs_parse.py
index 079a600..8f17b1b 100644
--- a/python/generators/sql_processing/docs_parse.py
+++ b/python/generators/sql_processing/docs_parse.py
@@ -230,14 +230,14 @@
     self._validate_only_contains_annotations(doc.annotations, {'@arg', '@ret'})
 
     ret_type, ret_desc = self._parse_ret(doc.annotations, ret)
-    name = self._parse_name(upper=True)
+    name = self._parse_name()
 
     if not is_snake_case(name):
       self._error('Function name %s is not snake_case (should be %s) ' %
                   (name, name.casefold()))
 
     return Function(
-        name=self._parse_name(upper=True),
+        name=name,
         desc=self._parse_desc_not_empty(doc.description),
         args=self._parse_args(doc.annotations, args),
         return_type=ret_type,
@@ -273,8 +273,14 @@
 
     self._validate_only_contains_annotations(doc.annotations,
                                              {'@arg', '@column'})
+    name = self._parse_name()
+
+    if not is_snake_case(name):
+      self._error('Function name %s is not snake_case (should be %s) ' %
+                  (name, name.casefold()))
+
     return TableFunction(
-        name=self._parse_name(upper=True),
+        name=name,
         desc=self._parse_desc_not_empty(doc.description),
         cols=self._parse_columns(doc.annotations, columns),
         args=self._parse_args(doc.annotations, args),
diff --git a/python/generators/sql_processing/utils.py b/python/generators/sql_processing/utils.py
index 97d7d8f..c701ceb 100644
--- a/python/generators/sql_processing/utils.py
+++ b/python/generators/sql_processing/utils.py
@@ -130,6 +130,12 @@
                     'Use CREATE PERFETTO FUNCTION instead.\n'
                     f'Offending file: {path}')
 
+    if 'create_view_function' in line.casefold():
+      errors.append(
+          'CREATE_VIEW_FUNCTION is deprecated in trace processor. '
+          'Use CREATE PERFETTO FUNCTION $name RETURNS TABLE instead.\n'
+          f'Offending file: {path}')
+
     if 'import(' in line.casefold():
       errors.append('SELECT IMPORT is deprecated in trace processor. '
                     'Use INCLUDE PERFETTO MODULE instead.\n'
diff --git a/python/test/stdlib_unittest.py b/python/test/stdlib_unittest.py
index d1a90be..479c603 100644
--- a/python/test/stdlib_unittest.py
+++ b/python/test/stdlib_unittest.py
@@ -104,7 +104,7 @@
 {ARGS_STR}
 {COLS_STR}
 SELECT CREATE_VIEW_FUNCTION(
-  'FOO_VIEW_FN({ARGS_SQL_STR})',
+  'foo_view_fn({ARGS_SQL_STR})',
   '{COLS_SQL_STR}',
   '{SQL_STR}'
 );
@@ -112,7 +112,7 @@
     self.assertListEqual(res.errors, [])
 
     fn = res.table_functions[0]
-    self.assertEqual(fn.name, 'FOO_VIEW_FN')
+    self.assertEqual(fn.name, 'foo_view_fn')
     self.assertEqual(fn.desc, 'First line. Second line.')
     self.assertEqual(
         fn.args, {
diff --git a/src/trace_processor/metrics/sql/android/android_startup.sql b/src/trace_processor/metrics/sql/android/android_startup.sql
index 5a92db8..d2efb76 100644
--- a/src/trace_processor/metrics/sql/android/android_startup.sql
+++ b/src/trace_processor/metrics/sql/android/android_startup.sql
@@ -43,20 +43,16 @@
 -- Returns the slices for forked processes. Never present in hot starts.
 -- Prefer this over process start_ts, since the process might have
 -- been preforked.
-SELECT CREATE_VIEW_FUNCTION(
-  'ZYGOTE_FORK_FOR_LAUNCH(startup_id INT)',
-  'ts INT, dur INT',
-  '
-    SELECT slice.ts, slice.dur
-    FROM android_startups l
-    JOIN slice ON (
-      l.ts < slice.ts AND
-      slice.ts + slice.dur < l.ts_end AND
-      STR_SPLIT(slice.name, ": ", 1) = l.package
-    )
-    WHERE l.startup_id = $startup_id AND slice.name GLOB "Start proc: *"
-  '
-);
+CREATE PERFETTO FUNCTION zygote_fork_for_launch(startup_id INT)
+RETURNS TABLE(ts INT, dur INT) AS
+SELECT slice.ts, slice.dur
+FROM android_startups l
+JOIN slice ON (
+  l.ts < slice.ts AND
+  slice.ts + slice.dur < l.ts_end AND
+  STR_SPLIT(slice.name, ': ', 1) = l.package
+)
+WHERE l.startup_id = $startup_id AND slice.name GLOB 'Start proc: *';
 
 -- Returns the fully drawn slice proto given a launch id.
 CREATE PERFETTO FUNCTION report_fully_drawn_for_launch(startup_id INT)
@@ -79,17 +75,14 @@
 );
 
 -- Given a launch id and GLOB for a slice name, returns the N longest slice name and duration.
-SELECT CREATE_VIEW_FUNCTION(
-  'GET_LONG_SLICES_FOR_LAUNCH(startup_id INT, slice_name STRING, top_n INT)',
-  'slice_name STRING, slice_dur INT',
-  '
-    SELECT slice_name, slice_dur
-    FROM android_thread_slices_for_all_startups s
-    WHERE s.startup_id = $startup_id AND s.slice_name GLOB $slice_name
-    ORDER BY slice_dur DESC
-    LIMIT $top_n
-  '
-);
+CREATE PERFETTO FUNCTION get_long_slices_for_launch(
+  startup_id INT, slice_name STRING, top_n INT)
+RETURNS TABLE(slice_name STRING, slice_dur INT) AS
+SELECT slice_name, slice_dur
+FROM android_thread_slices_for_all_startups s
+WHERE s.startup_id = $startup_id AND s.slice_name GLOB $slice_name
+ORDER BY slice_dur DESC
+LIMIT $top_n;
 
 -- Define the view
 DROP VIEW IF EXISTS startup_view;
diff --git a/src/trace_processor/metrics/sql/android/jank/relevant_slices.sql b/src/trace_processor/metrics/sql/android/jank/relevant_slices.sql
index 9c891af..0814320 100644
--- a/src/trace_processor/metrics/sql/android/jank/relevant_slices.sql
+++ b/src/trace_processor/metrics/sql/android/jank/relevant_slices.sql
@@ -190,30 +190,30 @@
 -- slice for each of the layers. GROUP BY to deduplicate these rows.
 GROUP BY cuj_id, app_upid, app_vsync, sf_upid, sf_vsync;
 
-SELECT CREATE_VIEW_FUNCTION(
-  'FIND_ANDROID_JANK_CUJ_SF_MAIN_THREAD_SLICE(slice_name_glob STRING)',
-  'cuj_id INT, utid INT, vsync INT, id INT, name STRING, ts LONG, dur LONG, ts_end LONG',
-  '
-  WITH sf_vsync AS (
-    SELECT DISTINCT cuj_id, sf_vsync AS vsync
-    FROM android_jank_cuj_app_to_sf_match)
-  SELECT
-    cuj_id,
-    utid,
-    sf_vsync.vsync,
-    slice.id,
-    slice.name,
-    slice.ts,
-    slice.dur,
-    slice.ts + slice.dur AS ts_end
-  FROM slice
-  JOIN android_jank_cuj_sf_main_thread main_thread USING (track_id)
-  JOIN sf_vsync
-    ON vsync_from_name(slice.name) = sf_vsync.vsync
-  WHERE slice.name GLOB $slice_name_glob AND slice.dur > 0
-  ORDER BY cuj_id, vsync;
-  '
-);
+CREATE PERFETTO FUNCTION find_android_jank_cuj_sf_main_thread_slice(
+  slice_name_glob STRING)
+RETURNS TABLE(
+  cuj_id INT, utid INT, vsync INT, id INT,
+  name STRING, ts LONG, dur LONG, ts_end LONG)
+AS
+WITH sf_vsync AS (
+  SELECT DISTINCT cuj_id, sf_vsync AS vsync
+  FROM android_jank_cuj_app_to_sf_match)
+SELECT
+  cuj_id,
+  utid,
+  sf_vsync.vsync,
+  slice.id,
+  slice.name,
+  slice.ts,
+  slice.dur,
+  slice.ts + slice.dur AS ts_end
+FROM slice
+JOIN android_jank_cuj_sf_main_thread main_thread USING (track_id)
+JOIN sf_vsync
+  ON vsync_from_name(slice.name) = sf_vsync.vsync
+WHERE slice.name GLOB $slice_name_glob AND slice.dur > 0
+ORDER BY cuj_id, vsync;
 
 DROP TABLE IF EXISTS android_jank_cuj_sf_commit_slice;
 CREATE PERFETTO TABLE android_jank_cuj_sf_commit_slice AS
diff --git a/src/trace_processor/metrics/sql/android/jank/relevant_threads.sql b/src/trace_processor/metrics/sql/android/jank/relevant_threads.sql
index b647721..d3fc193 100644
--- a/src/trace_processor/metrics/sql/android/jank/relevant_threads.sql
+++ b/src/trace_processor/metrics/sql/android/jank/relevant_threads.sql
@@ -25,22 +25,18 @@
   -- Some CUJs use a dedicated thread for Choreographer callbacks
   OR (p.main_thread_override = thread.name);
 
-SELECT CREATE_VIEW_FUNCTION(
-  'ANDROID_JANK_CUJ_APP_THREAD(thread_name STRING)',
-  'cuj_id INT, upid INT, utid INT, name STRING, track_id INT',
-  '
-  SELECT
-    cuj_id,
-    cuj.upid,
-    utid,
-    thread.name,
-    thread_track.id AS track_id
-  FROM thread
-  JOIN android_jank_cuj cuj USING (upid)
-  JOIN thread_track USING (utid)
-  WHERE thread.name = $thread_name;
-  '
-);
+CREATE PERFETTO FUNCTION android_jank_cuj_app_thread(thread_name STRING)
+RETURNS TABLE(cuj_id INT, upid INT, utid INT, name STRING, track_id INT) AS
+SELECT
+  cuj_id,
+  cuj.upid,
+  utid,
+  thread.name,
+  thread_track.id AS track_id
+FROM thread
+JOIN android_jank_cuj cuj USING (upid)
+JOIN thread_track USING (utid)
+WHERE thread.name = $thread_name;
 
 DROP TABLE IF EXISTS android_jank_cuj_render_thread;
 CREATE PERFETTO TABLE android_jank_cuj_render_thread AS
@@ -68,17 +64,13 @@
 JOIN thread_track USING (utid)
 WHERE thread.is_main_thread;
 
-SELECT CREATE_VIEW_FUNCTION(
-  'ANDROID_JANK_CUJ_SF_THREAD(thread_name STRING)',
-  'upid INT, utid INT, name STRING, track_id INT',
-  '
-  SELECT upid, utid, thread.name, thread_track.id AS track_id
-  FROM thread
-  JOIN android_jank_cuj_sf_process sf_process USING (upid)
-  JOIN thread_track USING (utid)
-  WHERE thread.name = $thread_name;
-  '
-);
+CREATE PERFETTO FUNCTION android_jank_cuj_sf_thread(thread_name STRING)
+RETURNS TABLE(upid INT, utid INT, name STRING, track_id INT) AS
+SELECT upid, utid, thread.name, thread_track.id AS track_id
+FROM thread
+JOIN android_jank_cuj_sf_process sf_process USING (upid)
+JOIN thread_track USING (utid)
+WHERE thread.name = $thread_name;
 
 DROP TABLE IF EXISTS android_jank_cuj_sf_gpu_completion_thread;
 CREATE PERFETTO TABLE android_jank_cuj_sf_gpu_completion_thread AS
diff --git a/src/trace_processor/metrics/sql/android/p_state.sql b/src/trace_processor/metrics/sql/android/p_state.sql
index 79d2155..b334fcd 100644
--- a/src/trace_processor/metrics/sql/android/p_state.sql
+++ b/src/trace_processor/metrics/sql/android/p_state.sql
@@ -38,35 +38,32 @@
   p_state_cpu_idle_counter PARTITIONED cpu
 );
 
+CREATE PERFETTO FUNCTION p_state_over_interval(
+  start_ns LONG, end_ns LONG)
+RETURNS TABLE(cpu INT, freq_khz INT, idle_value INT, dur_ns INT)
+AS
+WITH sched_freq_idle_windowed AS (
+  SELECT
+    freq_khz,
+    idle_value,
+    cpu,
+    IIF(ts + dur <= $end_ns, ts + dur, $end_ns) - IIF(ts >= $start_ns, ts, $start_ns) AS dur
+  FROM
+    p_state_sched_freq_idle
+  WHERE
+    ts + dur > $start_ns
+    AND ts < $end_ns
+)
 SELECT
-  CREATE_VIEW_FUNCTION(
-    'P_STATE_OVER_INTERVAL(start_ns LONG, end_ns LONG)',
-    'cpu INT, freq_khz INT, idle_value INT, dur_ns INT',
-    '
-    WITH sched_freq_idle_windowed AS (
-      SELECT
-        freq_khz,
-        idle_value,
-        cpu,
-        IIF(ts + dur <= $end_ns, ts + dur, $end_ns) - IIF(ts >= $start_ns, ts, $start_ns) AS dur
-      FROM
-        p_state_sched_freq_idle
-      WHERE
-        ts + dur > $start_ns
-        AND ts < $end_ns
-    )
-    SELECT
-      cast(cpu AS int) AS cpu,
-      cast(freq_khz AS int) AS freq_khz,
-      cast(idle_value AS int) AS idle_value,
-      cast(sum(dur) AS int) AS dur_ns
-    FROM
-      sched_freq_idle_windowed
-    WHERE
-      freq_khz > 0
-    GROUP BY
-      cpu,
-      freq_khz,
-      idle_value
-  '
-  );
+  cast(cpu AS int) AS cpu,
+  cast(freq_khz AS int) AS freq_khz,
+  cast(idle_value AS int) AS idle_value,
+  cast(sum(dur) AS int) AS dur_ns
+FROM
+  sched_freq_idle_windowed
+WHERE
+  freq_khz > 0
+GROUP BY
+  cpu,
+  freq_khz,
+  idle_value;
diff --git a/src/trace_processor/metrics/sql/android/startup/slice_functions.sql b/src/trace_processor/metrics/sql/android/startup/slice_functions.sql
index e003302..7a12590 100644
--- a/src/trace_processor/metrics/sql/android/startup/slice_functions.sql
+++ b/src/trace_processor/metrics/sql/android/startup/slice_functions.sql
@@ -138,17 +138,14 @@
   ELSE $loc
 END || ": " || $status || "/" || $filter_str || "/" || $reason;
 
-SELECT CREATE_VIEW_FUNCTION(
-  'BINDER_TRANSACTION_REPLY_SLICES_FOR_LAUNCH(startup_id INT, threshold DOUBLE)',
-  'name STRING',
-  '
-    SELECT reply.name AS name
-    FROM ANDROID_BINDER_TRANSACTION_SLICES_FOR_STARTUP($startup_id, $threshold) request
-    JOIN following_flow(request.id) arrow
-    JOIN slice reply ON reply.id = arrow.slice_in
-    WHERE reply.dur > $threshold AND request.is_main_thread
-  '
-);
+CREATE PERFETTO FUNCTION binder_transaction_reply_slices_for_launch(
+  startup_id INT, threshold DOUBLE)
+RETURNS TABLE(name STRING) AS
+SELECT reply.name AS name
+FROM android_binder_transaction_slices_for_startup($startup_id, $threshold) request
+JOIN following_flow(request.id) arrow
+JOIN slice reply ON reply.id = arrow.slice_in
+WHERE reply.dur > $threshold AND request.is_main_thread;
 
 -- Given a launch id, return if unlock is running by systemui during the launch.
 CREATE PERFETTO FUNCTION is_unlock_running_during_launch(startup_id LONG)
diff --git a/src/trace_processor/metrics/sql/chrome/chrome_long_tasks.sql b/src/trace_processor/metrics/sql/chrome/chrome_long_tasks.sql
index e80913e..e483965 100644
--- a/src/trace_processor/metrics/sql/chrome/chrome_long_tasks.sql
+++ b/src/trace_processor/metrics/sql/chrome/chrome_long_tasks.sql
@@ -23,30 +23,38 @@
 -- names. For example, LongTaskTracker slices may have associated IPC
 -- metadata, or InterestingTask slices for input may have associated IPC to
 -- determine whether the task is fling/etc.
-SELECT CREATE_VIEW_FUNCTION(
-  'SELECT_LONG_TASK_SLICES(name STRING)',
-  'interface_name STRING, ipc_hash INT, message_type STRING, id INT, task_name STRING',
-  '
-    WITH slices_with_mojo_data AS (
-      SELECT
-          EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.mojo_interface_tag") AS interface_name,
-          EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.ipc_hash") AS ipc_hash,
-          CASE
-            WHEN EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.is_reply") THEN "reply"
-            ELSE "message"
-          END AS message_type,
-          id
-      FROM slice
-      WHERE
-        category GLOB "*scheduler.long_tasks*"
-        AND name = $name
-    )
-    SELECT
-      *,
-      printf("%s %s(hash=%s)", interface_name, message_type, ipc_hash) as task_name
-    FROM slices_with_mojo_data;
-  '
-);
+CREATE PERFETTO FUNCTION select_long_task_slices(name STRING)
+RETURNS TABLE(
+  interface_name STRING,
+  ipc_hash INT,
+  message_type STRING,
+  id INT,
+  task_name STRING)
+AS
+WITH slices_with_mojo_data AS (
+  SELECT
+      EXTRACT_ARG(
+        arg_set_id,
+        "chrome_mojo_event_info.mojo_interface_tag"
+      ) AS interface_name,
+      EXTRACT_ARG(
+        arg_set_id,
+        "chrome_mojo_event_info.ipc_hash"
+      ) AS ipc_hash,
+      CASE
+        WHEN EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.is_reply") THEN "reply"
+        ELSE "message"
+      END AS message_type,
+      id
+  FROM slice
+  WHERE
+    category GLOB "*scheduler.long_tasks*"
+    AND name = $name
+)
+SELECT
+  *,
+  printf("%s %s(hash=%s)", interface_name, message_type, ipc_hash) as task_name
+FROM slices_with_mojo_data;
 
 CREATE PERFETTO FUNCTION is_long_choreographer_task(dur LONG)
 RETURNS BOOL AS
diff --git a/src/trace_processor/metrics/sql/chrome/chrome_tasks_delaying_input_processing_base.sql b/src/trace_processor/metrics/sql/chrome/chrome_tasks_delaying_input_processing_base.sql
index ba96dc3..3cf320c 100644
--- a/src/trace_processor/metrics/sql/chrome/chrome_tasks_delaying_input_processing_base.sql
+++ b/src/trace_processor/metrics/sql/chrome/chrome_tasks_delaying_input_processing_base.sql
@@ -23,23 +23,20 @@
 -- browser interval. This may differ based on whether the scenario is for
 -- topLevel events or LongTask events.
 
-SELECT CREATE_VIEW_FUNCTION(
-  '{{function_prefix}}SELECT_SLOW_BROWSER_TASKS()',
-  'full_name STRING, dur INT, ts INT, id INT, upid INT, thread_dur INT',
-  'SELECT
-    task_table.full_name AS full_name,
-    task_table.dur AS dur,
-    task_table.ts AS ts,
-    task_table.id AS id,
-    task_table.upid AS upid,
-    thread_dur
-  FROM
-    {{task_table_name}} task_table
-  WHERE
-    task_table.dur >= {{duration_causing_jank_ms}} * 1e6
-    AND task_table.thread_name = "CrBrowserMain"
-  '
-);
+CREATE PERFETTO FUNCTION {{function_prefix}}SELECT_SLOW_BROWSER_TASKS()
+RETURNS TABLE(full_name STRING, dur INT, ts INT, id INT, upid INT, thread_dur INT) AS
+SELECT
+  task_table.full_name AS full_name,
+  task_table.dur AS dur,
+  task_table.ts AS ts,
+  task_table.id AS id,
+  task_table.upid AS upid,
+  thread_dur
+FROM
+  {{task_table_name}} task_table
+WHERE
+  task_table.dur >= {{duration_causing_jank_ms}} * 1e6
+  AND task_table.thread_name = "CrBrowserMain";
 
 -- Get the tasks that was running for more than 8ms within windows
 -- that we could have started processing input but did not on the
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/startup/startups.sql b/src/trace_processor/perfetto_sql/stdlib/android/startup/startups.sql
index 521f2fc..2cfdce0 100644
--- a/src/trace_processor/perfetto_sql/stdlib/android/startup/startups.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/android/startup/startups.sql
@@ -211,15 +211,18 @@
 -- @column slice_dur      Duration of the slice.
 -- @column thread_name    Name of the thread with the slice.
 -- @column arg_set_id     Arg set id.
-SELECT CREATE_VIEW_FUNCTION(
-  'ANDROID_SLICES_FOR_STARTUP_AND_SLICE_NAME(startup_id INT, slice_name STRING)',
-  'slice_name STRING, slice_ts INT, slice_dur INT, thread_name STRING, arg_set_id INT',
-  '
-    SELECT slice_name, slice_ts, slice_dur, thread_name, arg_set_id
-    FROM android_thread_slices_for_all_startups
-    WHERE startup_id = $startup_id AND slice_name GLOB $slice_name
-  '
-);
+CREATE PERFETTO FUNCTION android_slices_for_startup_and_slice_name(
+  startup_id INT, slice_name STRING)
+RETURNS TABLE(
+  slice_name STRING,
+  slice_ts INT,
+  slice_dur INT,
+  thread_name STRING,
+  arg_set_id INT
+) AS
+SELECT slice_name, slice_ts, slice_dur, thread_name, arg_set_id
+FROM android_thread_slices_for_all_startups
+WHERE startup_id = $startup_id AND slice_name GLOB $slice_name;
 
 -- Returns binder transaction slices for a given startup id with duration over threshold.
 --
@@ -231,18 +234,30 @@
 -- @column process        Name of the process with slice.
 -- @column arg_set_id     Arg set id.
 -- @column is_main_thread Whether is main thread.
-SELECT CREATE_VIEW_FUNCTION(
-  'ANDROID_BINDER_TRANSACTION_SLICES_FOR_STARTUP(startup_id INT, threshold DOUBLE)',
-  'id INT, slice_dur INT, thread_name STRING, process STRING, arg_set_id INT, is_main_thread BOOL',
-  '
-    SELECT slice_id as id, slice_dur, thread_name, process.name as process, s.arg_set_id, is_main_thread
-    FROM android_thread_slices_for_all_startups s
-    JOIN process ON (
-      EXTRACT_ARG(s.arg_set_id, "destination process") = process.pid
-    )
-    WHERE startup_id = $startup_id AND slice_name GLOB "binder transaction" AND slice_dur > $threshold
-  '
-);
+CREATE PERFETTO FUNCTION android_binder_transaction_slices_for_startup(
+  startup_id INT, threshold DOUBLE)
+RETURNS TABLE(
+  id INT,
+  slice_dur INT,
+  thread_name STRING,
+  process STRING,
+  arg_set_id INT,
+  is_main_thread BOOL
+) AS
+SELECT
+  slice_id as id,
+  slice_dur,
+  thread_name,
+  process.name as process,
+  s.arg_set_id,
+  is_main_thread
+FROM android_thread_slices_for_all_startups s
+JOIN process ON (
+  EXTRACT_ARG(s.arg_set_id, "destination process") = process.pid
+)
+WHERE startup_id = $startup_id
+  AND slice_name GLOB "binder transaction"
+  AND slice_dur > $threshold;
 
 -- Returns duration of startup for slice name.
 --
@@ -251,11 +266,13 @@
 -- @arg startup_id LONG   Startup id.
 -- @arg slice_name STRING Slice name.
 -- @ret INT               Sum of duration.
-CREATE PERFETTO FUNCTION android_sum_dur_for_startup_and_slice(startup_id LONG, slice_name STRING)
+CREATE PERFETTO FUNCTION android_sum_dur_for_startup_and_slice(
+  startup_id LONG, slice_name STRING)
 RETURNS INT AS
 SELECT SUM(slice_dur)
 FROM android_thread_slices_for_all_startups
-WHERE startup_id = $startup_id AND slice_name GLOB $slice_name;
+WHERE startup_id = $startup_id
+  AND slice_name GLOB $slice_name;
 
 -- Returns duration of startup for slice name on main thread.
 --
@@ -264,8 +281,11 @@
 -- @arg startup_id LONG   Startup id.
 -- @arg slice_name STRING Slice name.
 -- @ret INT               Sum of duration.
-CREATE PERFETTO FUNCTION android_sum_dur_on_main_thread_for_startup_and_slice(startup_id LONG, slice_name STRING)
+CREATE PERFETTO FUNCTION android_sum_dur_on_main_thread_for_startup_and_slice(
+  startup_id LONG, slice_name STRING)
 RETURNS INT AS
 SELECT SUM(slice_dur)
 FROM android_thread_slices_for_all_startups
-WHERE startup_id = $startup_id AND slice_name GLOB $slice_name AND is_main_thread;
+WHERE startup_id = $startup_id
+  AND slice_name GLOB $slice_name
+  AND is_main_thread;
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/thread.sql b/src/trace_processor/perfetto_sql/stdlib/android/thread.sql
index 3d6fa46..592b476 100644
--- a/src/trace_processor/perfetto_sql/stdlib/android/thread.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/android/thread.sql
@@ -28,34 +28,36 @@
 -- @column pid                     Process pid creating threads.
 -- @column thread_name_prefix      String prefix of thread names created.
 -- @column max_count_per_sec       Max number of threads created within a time window.
-SELECT CREATE_VIEW_FUNCTION(
-    'ANDROID_THREAD_CREATION_SPAM(min_thread_dur FLOAT, sliding_window_dur FLOAT)',
-    'process_name STRING, pid INT, thread_name_prefix STRING, max_count_per_sec INT',
-    '
-    WITH
-      x AS (
-        SELECT
-          pid,
-          upid,
-          INTERNAL_THREAD_PREFIX(thread.name) AS thread_name_prefix,
-          process.name AS process_name,
-          COUNT(thread.start_ts)
-            OVER (
-              PARTITION BY upid, thread.name
-              ORDER BY thread.start_ts
-              RANGE BETWEEN CURRENT ROW AND CAST($sliding_window_dur AS INT64) FOLLOWING
-            ) AS count
-        FROM thread
-        JOIN process
-          USING (upid)
-        WHERE
-          ($min_thread_dur AND (thread.end_ts - thread.start_ts) <= $min_thread_dur)
-          OR $min_thread_dur IS NULL
-      )
-    SELECT process_name, pid, thread_name_prefix, MAX(count) AS max_count_per_sec
-    FROM x
-    GROUP BY upid, thread_name_prefix
-    HAVING max_count_per_sec > 0
-    ORDER BY count DESC;
-    '
-);
+CREATE PERFETTO FUNCTION android_thread_creation_spam(
+  min_thread_dur FLOAT, sliding_window_dur FLOAT)
+RETURNS TABLE(
+  process_name STRING,
+  pid INT,
+  thread_name_prefix STRING,
+  max_count_per_sec INT
+) AS
+WITH
+x AS (
+  SELECT
+    pid,
+    upid,
+    INTERNAL_THREAD_PREFIX(thread.name) AS thread_name_prefix,
+    process.name AS process_name,
+    COUNT(thread.start_ts)
+      OVER (
+        PARTITION BY upid, thread.name
+        ORDER BY thread.start_ts
+        RANGE BETWEEN CURRENT ROW AND CAST($sliding_window_dur AS INT64) FOLLOWING
+      ) AS count
+  FROM thread
+  JOIN process
+    USING (upid)
+  WHERE
+    ($min_thread_dur AND (thread.end_ts - thread.start_ts) <= $min_thread_dur)
+    OR $min_thread_dur IS NULL
+)
+SELECT process_name, pid, thread_name_prefix, MAX(count) AS max_count_per_sec
+FROM x
+GROUP BY upid, thread_name_prefix
+HAVING max_count_per_sec > 0
+ORDER BY count DESC;
diff --git a/src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/utils.sql b/src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/utils.sql
index 167bca2..44e6e1e 100644
--- a/src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/utils.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/utils.sql
@@ -95,20 +95,22 @@
 -- @column ipc_hash            Hash of the IPC call.
 -- @column message_type        Message type (e.g. reply).
 -- @column id                  The slice ID.
-SELECT CREATE_VIEW_FUNCTION(
-  'CHROME_SELECT_LONG_TASK_SLICES(name STRING)',
-  'interface_name STRING, ipc_hash INT, message_type STRING, id INT',
-  'SELECT
-      EXTRACT_ARG(s.arg_set_id, "chrome_mojo_event_info.mojo_interface_tag") AS interface_name,
-      EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.ipc_hash") AS ipc_hash,
-      CASE
-        WHEN EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.is_reply") THEN "reply"
-        ELSE "message"
-      END AS message_type,
-      s.id
-    FROM slice s
-    WHERE
-      category GLOB "*scheduler.long_tasks*"
-      AND name = $name
-  '
-);
+CREATE PERFETTO FUNCTION chrome_select_long_task_slices(name STRING)
+RETURNS TABLE(
+  interface_name STRING,
+  ipc_hash INT,
+  message_type STRING,
+  id INT
+) AS
+SELECT
+  EXTRACT_ARG(s.arg_set_id, "chrome_mojo_event_info.mojo_interface_tag") AS interface_name,
+  EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.ipc_hash") AS ipc_hash,
+  CASE
+    WHEN EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.is_reply") THEN "reply"
+    ELSE "message"
+  END AS message_type,
+  s.id
+FROM slice s
+WHERE
+  category GLOB "*scheduler.long_tasks*"
+  AND name = $name;
diff --git a/src/trace_processor/perfetto_sql/stdlib/chrome/tasks.sql b/src/trace_processor/perfetto_sql/stdlib/chrome/tasks.sql
index cd45beb..6890ce7 100644
--- a/src/trace_processor/perfetto_sql/stdlib/chrome/tasks.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/chrome/tasks.sql
@@ -43,7 +43,8 @@
 LIMIT 1;
 
 -- Human-readable aliases for a few key navigation tasks.
-CREATE PERFETTO FUNCTION internal_human_readable_navigation_task_name(task_name STRING)
+CREATE PERFETTO FUNCTION internal_human_readable_navigation_task_name(
+  task_name STRING)
 RETURNS STRING AS
 SELECT
   CASE
@@ -310,22 +311,20 @@
 -- @column kind          The type of Java slice.
 -- @column ts            The timestamp of the slice.
 -- @column name          The name of the slice.
-SELECT CREATE_VIEW_FUNCTION(
-  'INTERNAL_SELECT_BEGIN_MAIN_FRAME_JAVA_SLICES(name STRING)',
-  'id INT, kind STRING, ts LONG, dur LONG, name STRING',
-  'SELECT
-      id,
-      "SingleThreadProxy::BeginMainFrame" AS kind,
-      ts,
-      dur,
-      name
-    FROM slice
-    WHERE
-      (name = $name
-        AND internal_get_posted_from(arg_set_id) =
-            "cc/trees/single_thread_proxy.cc:ScheduledActionSendBeginMainFrame")
-  '
-);
+CREATE PERFETTO FUNCTION internal_select_begin_main_frame_java_slices(
+  name STRING)
+RETURNS TABLE(id INT, kind STRING, ts LONG, dur LONG, name STRING) AS
+SELECT
+  id,
+  "SingleThreadProxy::BeginMainFrame" AS kind,
+  ts,
+  dur,
+  name
+FROM slice
+WHERE
+  (name = $name
+    AND internal_get_posted_from(arg_set_id) =
+        "cc/trees/single_thread_proxy.cc:ScheduledActionSendBeginMainFrame");
 
 -- A list of Chrome tasks which were performing operations with Java views,
 -- together with the names of the these views.
@@ -436,17 +435,15 @@
 ORDER by depth, ts
 LIMIT 1;
 
-SELECT CREATE_VIEW_FUNCTION('INTERNAL_DESCENDANT_MOJO_SLICE(slice_id INT)',
-  'task_name STRING',
-  '
-  SELECT
-    printf("%s %s (hash=%d)",
-      mojo.interface_name, mojo.message_type, mojo.ipc_hash) AS task_name
-  FROM slice task
-  JOIN internal_chrome_mojo_slices mojo
-    ON mojo.id = internal_get_descendant_mojo_slice_candidate($slice_id)
-  WHERE task.id = $slice_id
-  ');
+CREATE PERFETTO FUNCTION internal_descendant_mojo_slice(slice_id INT)
+RETURNS TABLE(task_name STRING) AS
+SELECT
+  printf("%s %s (hash=%d)",
+    mojo.interface_name, mojo.message_type, mojo.ipc_hash) AS task_name
+FROM slice task
+JOIN internal_chrome_mojo_slices mojo
+  ON mojo.id = internal_get_descendant_mojo_slice_candidate($slice_id)
+WHERE task.id = $slice_id;
 
 -- A list of "Chrome tasks": top-level execution units (e.g. scheduler tasks /
 -- IPCs / system callbacks) run by Chrome. For a given thread, the tasks
diff --git a/src/trace_processor/perfetto_sql/stdlib/common/counters.sql b/src/trace_processor/perfetto_sql/stdlib/common/counters.sql
index 91e023d..a7f3157 100644
--- a/src/trace_processor/perfetto_sql/stdlib/common/counters.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/common/counters.sql
@@ -34,9 +34,8 @@
 -- @column track_name          Name of the counter track.
 -- @column track_arg_set_id    Counter track set id.
 -- @column arg_set_id          Counter arg set id.
-SELECT CREATE_VIEW_FUNCTION(
-  'COUNTER_WITH_DUR_FOR_TRACK(counter_track_id INT)',
-  '
+CREATE PERFETTO FUNCTION counter_with_dur_for_track(counter_track_id INT)
+RETURNS TABLE(
     ts LONG,
     dur LONG,
     value DOUBLE,
@@ -44,21 +43,18 @@
     track_name STRING,
     track_arg_set_id INT,
     arg_set_id INT
-  ',
-  '
-    SELECT
-        ts,
-        LEAD(ts, 1, trace_end()) OVER(ORDER BY ts) - ts AS dur,
-        value,
-        track.id AS track_id,
-        track.name AS track_name,
-        track.source_arg_set_id AS track_arg_set_id,
-        counter.arg_set_id AS arg_set_id
-    FROM counter
-    JOIN counter_track track ON track.id = counter.track_id
-    WHERE track.id = $counter_track_id
-  '
-);
+) AS
+SELECT
+  ts,
+  LEAD(ts, 1, trace_end()) OVER(ORDER BY ts) - ts AS dur,
+  value,
+  track.id AS track_id,
+  track.name AS track_name,
+  track.source_arg_set_id AS track_arg_set_id,
+  counter.arg_set_id AS arg_set_id
+FROM counter
+JOIN counter_track track ON track.id = counter.track_id
+WHERE track.id = $counter_track_id;
 
 -- COUNTER_WITH_DUR_FOR_TRACK but in a specified time.
 -- Does calculation over the table ends - creates an artificial counter value at
@@ -75,33 +71,30 @@
 -- @column track_name          Name of the counter track.
 -- @column track_arg_set_id    Counter track set id.
 -- @column arg_set_id          Counter arg set id.
-SELECT CREATE_VIEW_FUNCTION(
-  'COUNTER_FOR_TIME_RANGE(counter_track_id INT, start_ts LONG, end_ts LONG)',
-  '
-    ts LONG,
-    dur LONG,
-    value DOUBLE,
-    track_id INT,
-    track_name STRING,
-    track_arg_set_id INT,
-    arg_set_id INT
-  ',
-  '
-  SELECT
-    IIF(ts < $start_ts, $start_ts, ts) AS ts,
-    IIF(
-      ts < $start_ts,
-      dur - ($start_ts - ts),
-      IIF(ts + dur > $end_ts, $end_ts - ts, dur)) AS dur,
-    value,
-    track_id,
-    track_name,
-    track_arg_set_id,
-    arg_set_id
-  FROM COUNTER_WITH_DUR_FOR_TRACK($counter_track_id)
-  WHERE TRUE
-    AND ts + dur >= $start_ts
-    AND ts < $end_ts
-  ORDER BY ts ASC;
-'
-);
\ No newline at end of file
+CREATE PERFETTO FUNCTION COUNTER_FOR_TIME_RANGE(
+  counter_track_id INT, start_ts LONG, end_ts LONG)
+RETURNS TABLE(
+  ts LONG,
+  dur LONG,
+  value DOUBLE,
+  track_id INT,
+  track_name STRING,
+  track_arg_set_id INT,
+  arg_set_id INT
+) AS
+SELECT
+  IIF(ts < $start_ts, $start_ts, ts) AS ts,
+  IIF(
+    ts < $start_ts,
+    dur - ($start_ts - ts),
+    IIF(ts + dur > $end_ts, $end_ts - ts, dur)) AS dur,
+  value,
+  track_id,
+  track_name,
+  track_arg_set_id,
+  arg_set_id
+FROM counter_with_dur_for_track($counter_track_id)
+WHERE TRUE
+  AND ts + dur >= $start_ts
+  AND ts < $end_ts
+ORDER BY ts ASC;
diff --git a/src/trace_processor/perfetto_sql/stdlib/common/percentiles.sql b/src/trace_processor/perfetto_sql/stdlib/common/percentiles.sql
index bbba1eb..8b3da9d 100644
--- a/src/trace_processor/perfetto_sql/stdlib/common/percentiles.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/common/percentiles.sql
@@ -16,15 +16,13 @@
 INCLUDE PERFETTO MODULE common.counters;
 INCLUDE PERFETTO MODULE common.timestamps;
 
-SELECT CREATE_VIEW_FUNCTION(
-    'INTERNAL_NUMBER_GENERATOR(to INT)',
-    'num INT',
-    'WITH NUMS AS
-        (SELECT 1 num UNION SELECT num + 1
-        from NUMS
-        WHERE num < $to)
-    SELECT num FROM NUMS;'
-);
+CREATE PERFETTO FUNCTION internal_number_generator(to INT)
+RETURNS TABLE(num INT) AS
+WITH nums AS
+    (SELECT 1 num UNION SELECT num + 1
+    from NUMS
+    WHERE num < $to)
+SELECT num FROM nums;
 
 --
 -- Get durations for percentile
@@ -46,44 +44,43 @@
 -- @arg end_ts LONG          Timestamp of end of time range.
 -- @column percentile        All of the numbers from 1 to 100.
 -- @column value             Value for the percentile.
-SELECT CREATE_VIEW_FUNCTION(
-    'COUNTER_PERCENTILES_FOR_TIME_RANGE(counter_track_id INT, start_ts LONG, end_ts LONG)',
-    'percentile INT, value DOUBLE',
-    'WITH percentiles_for_value AS (
-        SELECT
-            value,
-            (CAST(SUM(dur) OVER(ORDER BY value ASC) AS DOUBLE) /
-                ($end_ts - MAX($start_ts, earliest_timestamp_for_counter_track($counter_track_id)))) * 100
-            AS percentile_for_value
-        FROM COUNTER_FOR_TIME_RANGE($counter_track_id, $start_ts, $end_ts)
-        ORDER BY value ASC
-    ),
-    with_gaps AS (
-        SELECT
-            CAST(percentile_for_value AS INT) AS percentile,
-            MIN(value) AS value
-        FROM percentiles_for_value
-        GROUP BY percentile
-        ORDER BY percentile ASC)
+CREATE PERFETTO FUNCTION counter_percentiles_for_time_range(
+  counter_track_id INT, start_ts LONG, end_ts LONG)
+RETURNS TABLE(percentile INT, value DOUBLE) AS
+WITH percentiles_for_value AS (
     SELECT
-        num AS percentile,
-        IFNULL(value, MIN(value) OVER (ORDER BY percentile DESC)) AS value
-    FROM INTERNAL_NUMBER_GENERATOR(100) AS nums
-    LEFT JOIN with_gaps ON with_gaps.percentile = nums.num
-    ORDER BY percentile DESC
-    '
-);
+        value,
+        (CAST(SUM(dur) OVER(ORDER BY value ASC) AS DOUBLE) /
+            ($end_ts - MAX($start_ts, earliest_timestamp_for_counter_track($counter_track_id)))) * 100
+        AS percentile_for_value
+    FROM COUNTER_FOR_TIME_RANGE($counter_track_id, $start_ts, $end_ts)
+    ORDER BY value ASC
+),
+with_gaps AS (
+    SELECT
+        CAST(percentile_for_value AS INT) AS percentile,
+        MIN(value) AS value
+    FROM percentiles_for_value
+    GROUP BY percentile
+    ORDER BY percentile ASC)
+SELECT
+    num AS percentile,
+    IFNULL(value, MIN(value) OVER (ORDER BY percentile DESC)) AS value
+FROM INTERNAL_NUMBER_GENERATOR(100) AS nums
+LEFT JOIN with_gaps ON with_gaps.percentile = nums.num
+ORDER BY percentile DESC;
 
 -- All percentiles (range 1-100) for counter track ID.
 --
 -- @arg counter_track_id INT Id of the counter track.
 -- @column percentile        All of the numbers from 1 to 100.
 -- @column value             Value for the percentile.
-SELECT CREATE_VIEW_FUNCTION(
-    'COUNTER_PERCENTILES_FOR_TRACK(counter_track_id INT)',
-    'percentile INT, value DOUBLE',
-    'SELECT * FROM COUNTER_PERCENTILES_FOR_TIME_RANGE($counter_track_id, trace_start(), trace_end());'
-);
+CREATE PERFETTO FUNCTION counter_percentiles_for_track(
+  counter_track_id INT)
+RETURNS TABLE(percentile INT, value DOUBLE) AS
+SELECT *
+FROM counter_percentiles_for_time_range(
+  $counter_track_id, trace_start(), trace_end());
 
 -- Value for specific percentile (range 1-100) for counter track ID in time range.
 --
@@ -98,7 +95,7 @@
                                                           end_ts LONG)
 RETURNS DOUBLE AS
 SELECT value
-FROM COUNTER_PERCENTILES_FOR_TIME_RANGE($counter_track_id, $start_ts, $end_ts)
+FROM counter_percentiles_for_time_range($counter_track_id, $start_ts, $end_ts)
 WHERE percentile = $percentile;
 
 -- Value for specific percentile (range 1-100) for counter track ID.
diff --git a/src/trace_processor/perfetto_sql/stdlib/experimental/thread_executing_span.sql b/src/trace_processor/perfetto_sql/stdlib/experimental/thread_executing_span.sql
index 5b7bf03..f839818 100644
--- a/src/trace_processor/perfetto_sql/stdlib/experimental/thread_executing_span.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/experimental/thread_executing_span.sql
@@ -347,9 +347,8 @@
 -- @column is_leaf            Whether this span is the leaf in the slice tree.
 -- @column depth              Tree depth from |root_id|
 -- @column root_id            Thread state id used to start the recursion. Helpful for SQL JOINs
-SELECT CREATE_VIEW_FUNCTION(
-'EXPERIMENTAL_THREAD_EXECUTING_SPAN_DESCENDANTS(root_id INT)',
-'
+CREATE PERFETTO FUNCTION experimental_thread_executing_span_descendants(root_id INT)
+RETURNS TABLE(
   parent_id LONG,
   id LONG,
   ts LONG,
@@ -373,8 +372,7 @@
   is_leaf INT,
   depth INT,
   root_id INT
-',
-'
+) AS
 WITH chain AS (
   SELECT
     *,
@@ -390,8 +388,7 @@
   FROM experimental_thread_executing_span_graph graph
   JOIN chain ON chain.id = graph.parent_id
 )
-SELECT * FROM chain
-');
+SELECT * FROM chain;
 
 -- All thread_executing_spans that are ancestors of |leaf_id|.
 --
@@ -426,9 +423,8 @@
 -- @column leaf_blocked_dur        Thread state duration blocked of the |leaf_id|.
 -- @column leaf_blocked_state      Thread state of the |leaf_id|.
 -- @column leaf_blocked_function   Thread state blocked_function of the |leaf_id|.
-SELECT CREATE_VIEW_FUNCTION(
-'EXPERIMENTAL_THREAD_EXECUTING_SPAN_ANCESTORS(leaf_id INT, leaf_utid INT)',
-'
+CREATE PERFETTO FUNCTION experimental_thread_executing_span_ancestors(leaf_id INT, leaf_utid INT)
+RETURNS TABLE(
   parent_id LONG,
   id LONG,
   ts LONG,
@@ -457,8 +453,7 @@
   leaf_blocked_dur LONG,
   leaf_blocked_state STRING,
   leaf_blocked_function STRING
-',
-'
+) AS
 WITH
 chain AS (
   SELECT
@@ -486,8 +481,7 @@
   FROM experimental_thread_executing_span_graph graph
   JOIN chain ON chain.parent_id = graph.id AND chain.ts >= (leaf_ts - leaf_blocked_dur)
 )
-SELECT * FROM chain
-');
+SELECT * FROM chain;
 
 -- Gets the thread_executing_span id a thread_state belongs to. Returns NULL if thread state is
 -- sleeping and not blocked on an interrupt.