CREATE TABLE IF NOT EXISTS umami.event_data_pivot
(
    website_id      UUID,
    session_id      UUID,
    event_id        UUID,
    event_name      LowCardinality(String),
    url_path        String,
    created_at      DateTime('UTC'),
    property_keys   AggregateFunction(groupArray, String),
    property_values AggregateFunction(groupArray, String),
    property_types  AggregateFunction(groupArray, UInt32)
)
ENGINE = AggregatingMergeTree()
PARTITION BY toYYYYMM(created_at)
ORDER BY (website_id, event_name, created_at, event_id)
SETTINGS index_granularity = 8192;

CREATE MATERIALIZED VIEW IF NOT EXISTS umami.event_data_pivot_mv
TO umami.event_data_pivot
AS SELECT
    website_id,
    session_id,
    event_id,
    event_name,
    url_path,
    created_at,
    groupArrayState(data_key) AS property_keys,
    groupArrayState(multiIf(
        data_type IN (1, 3, 5), ifNull(string_value, ''),
        data_type = 2, toString(ifNull(number_value, 0)),
        data_type = 4, toString(ifNull(date_value, toDateTime(0))),
        ''
    )) AS property_values,
    groupArrayState(data_type) AS property_types
FROM umami.event_data
GROUP BY website_id, session_id, event_id, event_name, url_path, created_at;

-- Backfill existing event data
INSERT INTO umami.event_data_pivot
SELECT
    website_id,
    session_id,
    event_id,
    event_name,
    url_path,
    created_at,
    groupArrayState(data_key),
    groupArrayState(multiIf(
        data_type IN (1, 3, 5), ifNull(string_value, ''),
        data_type = 2, toString(ifNull(number_value, 0)),
        data_type = 4, toString(ifNull(date_value, toDateTime(0))),
        ''
    )),
    groupArrayState(data_type)
FROM umami.event_data
GROUP BY website_id, session_id, event_id, event_name, url_path, created_at;

ALTER TABLE umami.session_data
MODIFY SETTING deduplicate_merge_projection_mode = 'drop';

ALTER TABLE umami.session_data
ADD PROJECTION session_data_property_filter_projection (
    SELECT *
    ORDER BY (
        website_id,
        data_key,
        data_type,
        string_value,
        number_value,
        date_value,
        session_id
    )
);

ALTER TABLE umami.session_data MATERIALIZE PROJECTION session_data_property_filter_projection;
