diff --git a/measure-backend/sql-statements/.sqlfluff b/measure-backend/sql-statements/.sqlfluff deleted file mode 100644 index 428fb9d0d..000000000 --- a/measure-backend/sql-statements/.sqlfluff +++ /dev/null @@ -1,8 +0,0 @@ -[sqlfluff] -dialect = postgres - -[sqlfluff:indentation] -tab_space_size = 2 - -[sqlfluff:rules:capitalisation.keywords] -capitalisation_policy = lower \ No newline at end of file diff --git a/measure-backend/sql-statements/README.md b/measure-backend/sql-statements/README.md deleted file mode 100644 index ff061b3fb..000000000 --- a/measure-backend/sql-statements/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# SQL Statements - -In this directory, you'll find all the adhoq SQL queries being used to develop Measure's backend databases. All queries are for reference and ease of access. They are not directly accessed or executed by any app. - -## Linting - -SQL statements in this directory is linted using [sqlfluff](https://sqlfluff.com/). Find the configuration in `.sqlfluff` file. \ No newline at end of file diff --git a/measure-backend/sql-statements/clickhouse/.sqlfluff b/measure-backend/sql-statements/clickhouse/.sqlfluff deleted file mode 100644 index 82e6ae018..000000000 --- a/measure-backend/sql-statements/clickhouse/.sqlfluff +++ /dev/null @@ -1,8 +0,0 @@ -[sqlfluff] -dialect = clickhouse - -[sqlfluff:indentation] -tab_space_size = 2 - -[sqlfluff:rules:capitalisation.keywords] -capitalisation_policy = lower \ No newline at end of file diff --git a/measure-backend/sql-statements/clickhouse/create-events-table-1.sql b/measure-backend/sql-statements/clickhouse/create-events-table-1.sql deleted file mode 100644 index e21a0280c..000000000 --- a/measure-backend/sql-statements/clickhouse/create-events-table-1.sql +++ /dev/null @@ -1,87 +0,0 @@ -/* -create events table -*/ - -create table if not exists events_test_1 -( - `id` UUID, - `timestamp` DateTime64(9, 'UTC'), - `severity_text` LowCardinality(FixedString(10)), - `resource.session_id` UUID, - `resource.device_name` FixedString(32), - `resource.device_model` FixedString(32), - `resource.device_manufacturer` FixedString(32), - `resource.device_type` LowCardinality(FixedString(32)), - `resource.device_is_foldable` Bool, - `resource.device_is_physical` Bool, - `resource.device_density_dpi` UInt16, - `resource.device_width_px` UInt16, - `resource.device_height_px` UInt16, - `resource.device_density` UInt8, - `resource.os_name` FixedString(32), - `resource.os_version` FixedString(32), - `resource.platform` LowCardinality(FixedString(32)), - `resource.app_version` FixedString(32), - `resource.app_build` FixedString(32), - `resource.app_unique_id` FixedString(128), - `resource.measure_sdk_version` FixedString(16), - `body.type` LowCardinality(FixedString(32)), - /* string */ - `body.string` String, - /* exceptions */ - `body.exception.exceptions` String, /* should this be an Array type?? or perhaps store in a different table? */ - `body.exception.handled` Bool, - /* gesture_long_click */ - `body.gesture_long_click.target` FixedString(128), - `body.gesture_long_click.target_user_readable_name` FixedString(128), - `body.gesture_long_click.target_id` FixedString(128), - `body.gesture_long_click.touch_down_time` DateTime('UTC'), - `body.gesture_long_click.touch_up_time` DateTime('UTC'), - `body.gesture_long_click.width` UInt16, - `body.gesture_long_click.height` UInt16, - `body.gesture_long_click.x` UInt16, - `body.gesture_long_click.y` UInt16, - /* gesture_click */ - `body.gesture_click.target` FixedString(128), - `body.gesture_click.target_user_readable_name` FixedString(128), - `body.gesture_click.target_id` FixedString(128), - `body.gesture_click.touch_down_time` DateTime('UTC'), - `body.gesture_click.touch_up_time` DateTime('UTC'), - `body.gesture_click.width` UInt16, - `body.gesture_click.height` UInt16, - `body.gesture_click.x` UInt16, - `body.gesture_click.y` UInt16, - /* gesture_scroll */ - `body.gesture_scroll.target` FixedString(128), - `body.gesture_scroll.target_user_readable_name` FixedString(128), - `body.gesture_scroll.target_id` FixedString(128), - `body.gesture_scroll.touch_down_time` DateTime('UTC'), - `body.gesture_scroll.touch_up_time` DateTime('UTC'), - `body.gesture_scroll.x` UInt16, - `body.gesture_scroll.y` UInt16, - `body.gesture_scroll.end_x` UInt16, - `body.gesture_scroll.end_y` UInt16, - `body.gesture_scroll.velocity_px` UInt16, - `body.gesture_scroll.direction` UInt16, - /* http_request */ - `body.http_request.request_id` UUID, - `body.http_request.request_url` String, - `body.http_request.method` LowCardinality(FixedString(16)), - `body.http_request.http_protocol_version` LowCardinality(FixedString(16)), - `body.http_request.request_body_size` UInt32, - `body.http_request.request_body` String, - `body.http_request.request_headers` Map(String, String), - /* http_response */ - `body.http_response.request_id` UUID, - `body.http_response.request_url` String, - `body.http_response.method` LowCardinality(FixedString(16)), - `body.http_response.latency_ms` UInt16, - `body.http_response.status_code` UInt16, - `body.http_response.response_body` String, - `body.http_response.response_headers` Map(String, String), - /* attributes */ - `attributes` Map(String, String) - -) -engine = MergeTree -primary key (id, timestamp) diff --git a/measure-backend/sql-statements/clickhouse/create-events-table-2.sql b/measure-backend/sql-statements/clickhouse/create-events-table-2.sql deleted file mode 100644 index ff8dd6dd8..000000000 --- a/measure-backend/sql-statements/clickhouse/create-events-table-2.sql +++ /dev/null @@ -1,131 +0,0 @@ -/* -create events table -*/ - -create table if not exists events_test_2 -( - `id` UUID, - `type` LowCardinality(FixedString(32)), - `session_id` UUID, - `timestamp` DateTime64(9, 'UTC'), - `thread_name` FixedString(32), - `resource.device_name` FixedString(32), - `resource.device_model` FixedString(32), - `resource.device_manufacturer` FixedString(32), - `resource.device_type` LowCardinality(FixedString(32)), - `resource.device_is_foldable` Bool, - `resource.device_is_physical` Bool, - `resource.device_density_dpi` UInt16, - `resource.device_width_px` UInt16, - `resource.device_height_px` UInt16, - `resource.device_density` Float32, - `resource.os_name` FixedString(32), - `resource.os_version` FixedString(32), - `resource.platform` LowCardinality(FixedString(32)), - `resource.app_version` FixedString(32), - `resource.app_build` FixedString(32), - `resource.app_unique_id` FixedString(128), - `resource.measure_sdk_version` FixedString(16), - /* anr */ - `anr.thread_name` LowCardinality(String), - `anr.handled` Bool, - /* delimits with underscore because clickhouse treats dot as a nested data structure and tries to match the length of exception.exceptions & exception.threads */ - `anr_exceptions` Array(Tuple(LowCardinality(String), LowCardinality(String), Array(Tuple(Int32, Int32, LowCardinality(String), LowCardinality(String), LowCardinality(String), LowCardinality(String))))), - `anr_threads` Array(Tuple(LowCardinality(String), Array(Tuple(Int32, Int32, LowCardinality(String), LowCardinality(String), LowCardinality(String), LowCardinality(String))))), - /* exceptions */ - `exception.thread_name` LowCardinality(String), - `exception.handled` Bool, - /* delimits with underscore because clickhouse treats dot as a nested data structure and tries to match the length of exception.exceptions & exception.threads */ - `exception_exceptions` Array(Tuple(LowCardinality(String), LowCardinality(String), Array(Tuple(Int32, Int32, LowCardinality(String), LowCardinality(String), LowCardinality(String), LowCardinality(String))))), - `exception_threads` Array(Tuple(LowCardinality(String), Array(Tuple(Int32, Int32, LowCardinality(String), LowCardinality(String), LowCardinality(String), LowCardinality(String))))), - /* app_exit */ - `app_exit.reason` LowCardinality(FixedString(64)), - `app_exit.importance` LowCardinality(FixedString(32)), - `app_exit.trace` String, - `app_exit.process_name` String, - `app_exit.pid` String, - `app_exit.timestamp` DateTime64(9, 'UTC'), - /* string */ - `string.severity_text` LowCardinality(FixedString(10)), - `string.string` String, - /* gesture_long_click */ - `gesture_long_click.target` FixedString(128), - `gesture_long_click.target_id` FixedString(128), - `gesture_long_click.touch_down_time` UInt32, - `gesture_long_click.touch_up_time` UInt32, - `gesture_long_click.width` UInt16, - `gesture_long_click.height` UInt16, - `gesture_long_click.x` Float32, - `gesture_long_click.y` Float32, - /* gesture_click */ - `gesture_click.target` FixedString(128), - `gesture_click.target_id` FixedString(128), - `gesture_click.touch_down_time` UInt32, - `gesture_click.touch_up_time` UInt32, - `gesture_click.width` UInt16, - `gesture_click.height` UInt16, - `gesture_click.x` Float32, - `gesture_click.y` Float32, - /* gesture_scroll */ - `gesture_scroll.target` FixedString(128), - `gesture_scroll.target_id` FixedString(128), - `gesture_scroll.touch_down_time` UInt32, - `gesture_scroll.touch_up_time` UInt32, - `gesture_scroll.x` Float32, - `gesture_scroll.y` Float32, - `gesture_scroll.end_x` Float32, - `gesture_scroll.end_y` Float32, - `gesture_scroll.direction` FixedString(8), - /* http_request */ - `http_request.request_id` UUID, - `http_request.request_url` String, - `http_request.method` LowCardinality(FixedString(16)), - `http_request.http_protocol_version` LowCardinality(FixedString(16)), - `http_request.request_body_size` UInt32, - `http_request.request_body` String, - `http_request.request_headers` Map(String, String), - /* http_response */ - `http_response.request_id` UUID, - `http_response.request_url` String, - `http_response.method` LowCardinality(FixedString(16)), - `http_response.latency_ms` UInt16, - `http_response.status_code` UInt16, - `http_response.response_body` String, - `http_response.response_headers` Map(String, String), - /* lifecycle_activity */ - `lifecycle_activity.type` FixedString(32), - `lifecycle_activity.class_name` FixedString(128), - `lifecycle_activity.intent` String, - `lifecycle_activity.saved_instance_state` Bool, - /* lifecycle_fragment */ - `lifecycle_fragment.type` FixedString(32), - `lifecycle_fragment.class_name` FixedString(128), - `lifecycle_fragment.parent_activity` String, - `lifecycle_fragment.tag` String, - /* lifecycle_app */ - `lifecycle_app.type` FixedString(32), - /* cold launch */ - `cold_launch.process_start_uptime` UInt32, - `cold_launch.process_start_requested_uptime` UInt32, - `cold_launch.content_provider_attach_uptime` UInt32, - `cold_launch.on_next_draw_uptime` UInt32, - `cold_launch.launched_activity` FixedString(128), - `cold_launch.has_saved_state` Bool, - `cold_launch.intent_data` String, - /* warm launch */ - `warm_launch.app_visible_uptime` UInt32, - `warm_launch.on_next_draw_uptime` UInt32, - `warm_launch.launched_activity` FixedString(128), - `warm_launch.has_saved_state` Bool, - `warm_launch.intent_data` String, - /* hot launch */ - `hot_launch.app_visible_uptime` UInt32, - `hot_launch.on_next_draw_uptime` UInt32, - `hot_launch.launched_activity` FixedString(128), - `hot_launch.has_saved_state` Bool, - `hot_launch.intent_data` String, - /* attributes */ - `attributes` Map(String, String) -) -engine = MergeTree -primary key (id, timestamp) diff --git a/measure-backend/sql-statements/clickhouse/insert_events_table.sql b/measure-backend/sql-statements/clickhouse/insert_events_table.sql deleted file mode 100644 index 37f046241..000000000 --- a/measure-backend/sql-statements/clickhouse/insert_events_table.sql +++ /dev/null @@ -1,13 +0,0 @@ -/* -insert sample data to events table -*/ - -insert into events_test_1 (id, resource.session_id, timestamp, body.type, resource.device_name, resource.device_model) values - - (toUUID('a922b7d5-b53a-41f9-ae29-6bb17abca34d'), toUUID('025d8f63-9985-4325-a085-617c6b29fabb'), now(), 'exception', 'samsung', 's23'), - (toUUID('214f6409-fb1c-4503-b2ab-abd05af33a0a'), toUUID('025d8f63-9985-4325-a085-617c6b29fabb'), now() + 20, 'exception', 'samsung', 's23'), - (toUUID('846eb14d-a3a1-4908-bfb5-5da7a5279dca'), toUUID('025d8f63-9985-4325-a085-617c6b29fabb'), now() + 25, 'exception', 'samsung', 's23'), - (toUUID('524bff3c-3691-42a5-b94b-c883ffd6fbf0'), toUUID('3121bcf9-5708-4572-a2a7-7087844f65fe'), now() + 10, 'exception', 'apple', 'iphone 14'), - (toUUID('f3813b3b-d7ad-4dee-96c0-d241cc00dd74'), toUUID('3121bcf9-5708-4572-a2a7-7087844f65fe'), now() + 26, 'exception', 'apple', 'iphone 14'), - (toUUID('8507c8e1-bb93-4052-a5f7-642e1c051322'), toUUID('3121bcf9-5708-4572-a2a7-7087844f65fe'), now() + 28, 'exception', 'apple', 'iphone 14'), - (toUUID('71a4ff5d-a767-420e-b1fe-1fc57eabb81d'), toUUID('49b52292-06c0-498c-8686-b4c92dce0bd2'), today(), 'exception', 'samsung', 'galaxy s'); \ No newline at end of file diff --git a/measure-backend/sql-statements/clickhouse/playground.sql b/measure-backend/sql-statements/clickhouse/playground.sql deleted file mode 100644 index 4b7df6310..000000000 --- a/measure-backend/sql-statements/clickhouse/playground.sql +++ /dev/null @@ -1,131 +0,0 @@ --- use this file to write and test draft queries -/* -create events table -*/ - -create table if not exists events -( - `id` UUID, - `timestamp` DateTime64(9, 'UTC'), - `resource.session_id` UUID, - `resource.device_name` FixedString(32), - `resource.device_model` FixedString(32), - `resource.device_manufacturer` FixedString(32), - `resource.device_type` LowCardinality(FixedString(32)), - `resource.device_is_foldable` Bool, - `resource.device_is_physical` Bool, - `resource.device_density_dpi` UInt8, - `resource.device_width_px` UInt8, - `resource.device_height_px` UInt8, - `resource.device_density` UInt8, - `resource.os_name` FixedString(32), - `resource.os_version` FixedString(32), - `resource.platform` LowCardinality(FixedString(32)), - `resource.app_version` FixedString(32), - `resource.app_build` FixedString(32), - `resource.app_unique_id` FixedString(128), - `resource.app_first_install_time` DateTime('UTC'), - `resource.app_last_update_time` DateTime('UTC'), - `resource.measure_sdk_version` FixedString(16), - /* string */ - `body.string` String, - /* exceptions */ - `body.exception.exceptions` String, /* should this be an Array type?? or perhaps store in a different table? */ - `body.exception.handled` Bool, - /* gesture_long_click */ - `body.gesture_long_click.target` FixedString(128), - `body.gesture_long_click.target_user_readable_name` FixedString(128), - `body.gesture_long_click.target_id` FixedString(32), - `body.gesture_long_click.touch_down_time` DateTime('UTC'), - `body.gesture_long_click.touch_up_time` DateTime('UTC'), - `body.gesture_long_click.width` UInt8, - `body.gesture_long_click.height` UInt8, - `body.gesture_long_click.x` UInt8, - `body.gesture_long_click.y` UInt8, - /* gesture_click */ - `body.gesture_click.target` FixedString(128), - `body.gesture_click.target_user_readable_name` FixedString(128), - `body.gesture_click.target_id` FixedString(128), - `body.gesture_click.touch_down_time` DateTime('UTC'), - `body.gesture_click.touch_up_time` DateTime('UTC'), - `body.gesture_click.width` UInt16, - `body.gesture_click.height` UInt16, - `body.gesture_click.x` UInt16, - `body.gesture_click.y` UInt16, - /* gesture_scroll */ - `body.gesture_scroll.target` FixedString(128), - `body.gesture_scroll.target_user_readable_name` FixedString(128), - `body.gesture_scroll.target_id` FixedString(128), - `body.gesture_scroll.touch_down_time` DateTime('UTC'), - `body.gesture_scroll.touch_up_time` DateTime('UTC'), - `body.gesture_scroll.x` UInt16, - `body.gesture_scroll.y` UInt16, - `body.gesture_scroll.end_x` UInt16, - `body.gesture_scroll.end_y` UInt16, - `body.gesture_scroll.velocity_px` UInt16, - `body.gesture_scroll.velocity_px` UInt16, - `body.gesture_scroll.direction` UInt16, - /* http_request */ - `body.http_request.id` UUID, - `body.http_request.url` String, - `body.http_request.method` LowCardinality(FixedString(16)), - `body.http_request.content_type` FixedString(128), - /* `body.http_request.network_transport` FixedString(32), */ - `body.http_request.user_agent` FixedString(128), /* should appear as part of the headers */ - `body.http_request.protocol_version` LowCardinality(FixedString(16)), - `body.http_request.body_size` UInt32, - `body.http_request.body` String, - `body.http_request.headers` Map(String, String), - /* http_response */ - `body.http_response.request_id` UUID, - `body.http_response.request_url` String, - `body.http_response.method` LowCardinality(FixedString(16)), - `body.http_response.content_type` FixedString(128), - `body.http_response.status_code` UInt16, - `body.http_response.body` String, - `body.http_response.headers` Map(String, String) - -) -engine = MergeTree -primary key (id, timestamp) - - -/* -insert sample data to events table -*/ - -insert into events (id, session_id, timestamp, type, resource.device_name, resource.device_model) values - - (toUUID('a922b7d5-b53a-41f9-ae29-6bb17abca34d'), toUUID('025d8f63-9985-4325-a085-617c6b29fabb'), now(), 'exception', 'samsung', 's23'), - (toUUID('214f6409-fb1c-4503-b2ab-abd05af33a0a'), toUUID('025d8f63-9985-4325-a085-617c6b29fabb'), now() + 20, 'exception', 'samsung', 's23'), - (toUUID('846eb14d-a3a1-4908-bfb5-5da7a5279dca'), toUUID('025d8f63-9985-4325-a085-617c6b29fabb'), now() + 25, 'exception', 'samsung', 's23'), - (toUUID('524bff3c-3691-42a5-b94b-c883ffd6fbf0'), toUUID('3121bcf9-5708-4572-a2a7-7087844f65fe'), now() + 10, 'exception', 'apple', 'iphone 14'), - (toUUID('f3813b3b-d7ad-4dee-96c0-d241cc00dd74'), toUUID('3121bcf9-5708-4572-a2a7-7087844f65fe'), now() + 26, 'exception', 'apple', 'iphone 14'), - (toUUID('8507c8e1-bb93-4052-a5f7-642e1c051322'), toUUID('3121bcf9-5708-4572-a2a7-7087844f65fe'), now() + 28, 'exception', 'apple', 'iphone 14'), - (toUUID('71a4ff5d-a767-420e-b1fe-1fc57eabb81d'), toUUID('49b52292-06c0-498c-8686-b4c92dce0bd2'), today(), 'exception', 'samsung', 'galaxy s'); - -insert into events (id, session_id, timestamp, type, resource.device_name, resource.device_model) values - - (toUUID('8e64877b-7a6d-409b-b608-55bd520cc11e'), toUUID('025d8f63-9985-4325-a085-617c6b29fabb'), now(), 'anr', 'samsung', 's23'); - - -/* -delete rows from a table -*/ - -delete from events where type='anr'; -delete from events where id='a922b7d5-b53a-41f9-ae29-6bb17abca34d'; - -/* -add new column -*/ - -alter table events add column if not exists `resource.device_manufacturer` FixedString(32) after `resource.device_model`; - - -/* -insert with device_manufacturer -*/ -insert into events (id, session_id, timestamp, type, resource.device_name, resource.device_model, resource.device_manufacturer) values - - (toUUID('8e64877b-7a6d-409b-b608-55bd520cc11e'), toUUID('025d8f63-9985-4325-a085-617c6b29fabb'), now(), 'anr', 'samsung', 's23', 'samsung'); \ No newline at end of file diff --git a/measure-backend/sql-statements/ddl-statements.sql b/measure-backend/sql-statements/ddl-statements.sql deleted file mode 100644 index d91877b0d..000000000 --- a/measure-backend/sql-statements/ddl-statements.sql +++ /dev/null @@ -1,11 +0,0 @@ -/* -events table schema -*/ -create table if not exists -public.events ( - id uuid not null default gen_random_uuid(), - session_id uuid default null, - type character varying not null, - created_at timestamp with time zone null default now(), - constraint events_pkey primary key (id) -) tablespace pg_default; \ No newline at end of file diff --git a/measure-backend/sql-statements/postgres/create-mapping-table.sql b/measure-backend/sql-statements/postgres/create-mapping-table.sql deleted file mode 100644 index 497afc36f..000000000 --- a/measure-backend/sql-statements/postgres/create-mapping-table.sql +++ /dev/null @@ -1,23 +0,0 @@ -create table if not exists mapping_files ( - id uuid primary key not null, - app_unique_id varchar(256) not null, - version_name varchar(256) not null, - version_code varchar(256) not null, - mapping_type varchar(32) not null, - key varchar(256) not null, - location varchar not null, - fnv1_hash varchar(34) not null, - file_size int default 0, - last_updated timestamptz not null -) - -comment on column mapping_files.id is 'unique id for each mapping file'; -comment on column mapping_files.app_unique_id is 'unique identifier of the app'; -comment on column mapping_files.version_name is 'user visible version number of the app'; -comment on column mapping_files.version_code is 'incremental build number of the app'; -comment on column mapping_files.mapping_type is 'type of the mapping file, like proguard etc'; -comment on column mapping_files.key is 'key of the mapping file stored in remote object store'; -comment on column mapping_files.location is 'url of the mapping file stored in remote object store'; -comment on column mapping_files.fnv1_hash is '64 bit fnv1 hash of the mapping file bytes'; -comment on column mapping_files.file_size is 'size of mapping file in bytes'; -comment on column mapping_files.last_updated is 'utc timestamp at the time of mapping file upload'; \ No newline at end of file diff --git a/measure-backend/sql-statements/postgres/create-session-table.sql b/measure-backend/sql-statements/postgres/create-session-table.sql deleted file mode 100644 index ff6cc059f..000000000 --- a/measure-backend/sql-statements/postgres/create-session-table.sql +++ /dev/null @@ -1,15 +0,0 @@ -create table if not exists sessions ( - id uuid primary key not null, - event_count int default 0, - attachment_count int default 0, - bytes_in int default 0, - symbolication_attempts_count int default 0, - timestamp timestamptz not null -) - -comment on column sessions.id is 'unique uuidv4 session id'; -comment on column sessions.event_count is 'number of events in the session'; -comment on column sessions.attachment_count is 'number of attachments in the session'; -comment on column sessions.bytes_in is 'total session payload size in bytes'; -comment on column sessions.symbolication_attempts_count is 'number of times symbolication was attempted for this session'; -comment on column sessions.timestamp is 'utc timestamp at the time of session insertion'; \ No newline at end of file diff --git a/measure-backend/sql-statements/postgres/create-sessions-attachments.sql b/measure-backend/sql-statements/postgres/create-sessions-attachments.sql deleted file mode 100644 index 59eaf0aa2..000000000 --- a/measure-backend/sql-statements/postgres/create-sessions-attachments.sql +++ /dev/null @@ -1,19 +0,0 @@ -create table if not exists sessions_attachments ( - id uuid primary key not null, - session_id uuid references sessions(id) on delete cascade, - name varchar(256) not null, - extension varchar(32) not null, - type varchar(32) not null, - key varchar(256) not null, - location varchar not null, - timestamp timestamptz not null -); - -comment on column sessions_attachments.id is 'unique id for each session attachment'; -comment on column sessions_attachments.session_id is 'session_id of the containing session'; -comment on column sessions_attachments.name is 'original name of the attachment file'; -comment on column sessions_attachments.extension is 'original extension of the attachment file'; -comment on column sessions_attachments.type is 'type of attachment, like screenshot etc'; -comment on column sessions_attachments.key is 'key of the attachment file stored in remote object store'; -comment on column sessions_attachments.location is 'url of the attachment file stored in remote object store'; -comment on column sessions_attachments.timestamp is 'utc timestamp at the time of attachment file upload'; \ No newline at end of file