Merge "tp: centralise all sqlite_result_* function calls" into main
diff --git a/docs/contributing/common-tasks.md b/docs/contributing/common-tasks.md
index feb7aaa..11d4f14 100644
--- a/docs/contributing/common-tasks.md
+++ b/docs/contributing/common-tasks.md
@@ -16,22 +16,23 @@
 
 ## Contribute to SQL standard library
 
-1. Add or edit an SQL file inside `perfetto/src/trace_processor/stdlib/`.
-2. For a new file inside an existing module add the file to the corresponding `BUILD.gn`.
-3. For a new module (subdirectory of `/stdlib/`), module name (directory name) has to be added to the list in `/stdlib/BUILD.gn`.
+1. Add or edit an SQL file inside `perfetto/src/trace_processor/stdlib/`. This SQL file will be a new standard library module.
+2. For a new file inside an existing package add the file to the corresponding `BUILD.gn`.
+3. For a new package (subdirectory of `/stdlib/`), the package name (directory name) has to be added to the list in `/stdlib/BUILD.gn`.
 
 Files inside the standard library have to be formatted in a very specific way, as its structure is used to generate documentation. There are presubmit checks, but they are not infallible.
 
-- Running the file cannot generate any data. There can be only
-  `CREATE PERFETTO FUNCTION`, `CREATE PERFETTO TABLE` and `CREATE PERFETTO VIEW` statements inside.
-- The name of each table/view/function needs to start with `{module_name}_` or `{internal_}`.
-  The names of views/tables/functions are must be `[a-z_]`. When a module is imported (using the `IMPORT` function), objects prefixed with internal should not be used.
-  - The only exception is the `common` module. The name of functions/views/tables inside should not be prefixed with `common_`, as they are supposed to be module agnostic and widely used.
+- Running the file cannot generate any data. There can be only `CREATE PERFETTO {FUNCTION|TABLE|VIEW|MACRO}` statements inside.
+- The name of each standard library object needs to start with `{module_name}_` or be prefixed with an underscore(`_`) for internal objects.
+  The names must only contain lower and upper case letters and underscores. When a module is included (using the `INCLUDE PERFETTO MODULE`) the internal objects  should not be treated as an API. 
 - Every table or view should have [a schema](/docs/analysis/perfetto-sql-syntax.md#tableview-schema).
+
+### Documentation
+
 - Every non internal object, as well as its function arguments and columns in its schema have to be prefixed with an SQL comment documenting it.
-  Any text is going to be parsed as markdown, so usage of markdown functionality (code, links, lists) is encouraged.
-  Whitespaces in anything apart from descriptions are ignored, so comments can be formatted neatly.
-  If the line with description exceeds 80 chars, description can be continued in following lines.
+- Any text is going to be parsed as markdown, so usage of markdown functionality (code, links, lists) is encouraged.
+Whitespaces in anything apart from descriptions are ignored, so comments can be formatted neatly.
+If the line with description exceeds 80 chars, description can be continued in following lines.
   - **Table/view**: each has to have schema, object description and a comment above each column's definition in the schema.
     - Description is any text in the comment above `CREATE PERFETTO {TABLE,VIEW}` statement.
     - Column's comment is the text immediately above column definition in the schema.
@@ -65,9 +66,9 @@
   slice.name AS slice_name,
   COUNT(*) AS event_count
 FROM slice
-INNER JOIN thread_track ON slice.track_id = thread_track.id
-INNER JOIN thread ON thread.utid = thread_track.utid
-INNER JOIN process ON thread.upid = process.upid
+JOIN thread_track ON slice.track_id = thread_track.id
+JOIN thread ON thread.utid = thread_track.utid
+JOIN process ON thread.upid = process.upid
 WHERE
   slice.name GLOB 'binder*'
 GROUP BY
@@ -75,17 +76,6 @@
   slice_name;
 ```
 
-Example of function in module `common`:
-```sql
--- Extracts an int value with the given name from the metadata table.
-CREATE PERFETTO FUNCTION extract_int_metadata(
-  -- The name of the metadata entry.
-  name STRING)
--- int_value for the given name. NULL if there's no such entry.
-RETURNS LONG
-AS SELECT int_value FROM metadata WHERE name = ($name)
-```
-
 Example of table function in module `android`:
 ```sql
 -- Given a launch id and GLOB for a slice name, returns columns for matching slices.
@@ -108,7 +98,12 @@
   arg_set_id INT
 )
 AS
-SELECT slice_name, slice_ts, slice_dur, thread_name, arg_set_id
+SELECT 
+  slice_name, 
+  slice_ts, 
+  slice_dur, 
+  thread_name, 
+  arg_set_id
 FROM thread_slices_for_all_launches
 WHERE launch_id = $launch_id AND slice_name GLOB $slice_name;
 ```
diff --git a/src/trace_processor/perfetto_sql/stdlib/time/conversion.sql b/src/trace_processor/perfetto_sql/stdlib/time/conversion.sql
index 9a284d0..0aa736d 100644
--- a/src/trace_processor/perfetto_sql/stdlib/time/conversion.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/time/conversion.sql
@@ -83,3 +83,75 @@
 -- Time duration in nanoseconds.
 RETURNS INT AS
 SELECT $days * 24 * 60 * 60 * 1000 * 1000 * 1000;
+
+-- Returns the provided nanosecond duration, which is the default
+-- representation of time durations in trace processor. Provided for
+-- consistency with other functions.
+CREATE PERFETTO FUNCTION time_to_ns(
+  -- Time duration in nanoseconds.
+  nanos INT
+)
+-- Time duration in nanoseconds.
+RETURNS INT AS
+SELECT $nanos;
+
+-- Converts a duration in nanoseconds to microseconds. Nanoseconds is the default
+-- representation of time durations in trace processor.
+CREATE PERFETTO FUNCTION time_to_us(
+-- Time duration in nanoseconds.
+  nanos INT
+)
+-- Time duration in microseconds.
+RETURNS INT AS
+SELECT $nanos / 1000;
+
+-- Converts a duration in nanoseconds to millseconds. Nanoseconds is the default
+-- representation of time durations in trace processor.
+CREATE PERFETTO FUNCTION time_to_ms(
+  -- Time duration in nanoseconds.
+  nanos INT
+)
+-- Time duration in milliseconds.
+RETURNS INT AS
+SELECT $nanos / (1000 * 1000);
+
+-- Converts a duration in nanoseconds to seconds. Nanoseconds is the default
+-- representation of time durations in trace processor.
+CREATE PERFETTO FUNCTION time_to_s(
+  -- Time duration in nanoseconds.
+  nanos INT
+)
+-- Time duration in seconds.
+RETURNS INT AS
+SELECT $nanos / (1000 * 1000 * 1000);
+
+-- Converts a duration in nanoseconds to minutes. Nanoseconds is the default
+-- representation of time durations in trace processor.
+CREATE PERFETTO FUNCTION time_to_min(
+  -- Time duration in nanoseconds.
+  nanos INT
+)
+-- Time duration in minutes.
+RETURNS INT AS
+SELECT $nanos / (60 * 1000 * 1000 * 1000);
+
+-- Converts a duration in nanoseconds to hours. Nanoseconds is the default
+-- representation of time durations in trace processor.
+CREATE PERFETTO FUNCTION time_to_hours(
+  -- Time duration in nanoseconds.
+  nanos INT
+)
+-- Time duration in hours.
+RETURNS INT AS
+SELECT $nanos / (60 * 60 * 1000 * 1000 * 1000);
+
+-- Converts a duration in nanoseconds to days. Nanoseconds is the default
+-- representation of time durations in trace processor.
+CREATE PERFETTO FUNCTION time_to_days(
+  -- Time duration in nanoseconds.
+  nanos INT
+)
+-- Time duration in days.
+RETURNS INT AS
+SELECT $nanos / (24 * 60 * 60 * 1000 * 1000 * 1000);
+