123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- GENERATE_ISSUE_TSVECTOR = """
- CREATE OR REPLACE FUNCTION generate_issue_tsvector(jsonb) RETURNS tsvector AS $$
- BEGIN
- RETURN strip(jsonb_to_tsvector($1, '["string"]'));
- EXCEPTION WHEN program_limit_exceeded THEN
- RETURN null;
- END;
- $$ LANGUAGE plpgsql;;
- """
- # https://stackoverflow.com/a/42998229/443457
- JSONB_RECURSIVE_MERGE = """
- create or replace function remove_dupes(p_array jsonb)
- returns jsonb
- as
- $$
- select jsonb_agg(distinct e)
- from jsonb_array_elements(p_array) as t(e);
- $$
- language sql;
- create or replace function jsonb_merge_deep(jsonb, jsonb)
- returns jsonb
- language sql
- immutable
- as $func$
- select case jsonb_typeof($1)
- when 'object' then case jsonb_typeof($2)
- when 'object' then (
- select jsonb_object_agg(k, case
- when e2.v is null then e1.v
- when e1.v is null then e2.v
- else jsonb_merge_deep(e1.v, e2.v)
- end)
- from jsonb_each($1) e1(k, v)
- full join jsonb_each($2) e2(k, v) using (k)
- )
- else $2
- end
- when 'array' then remove_dupes($1 || $2)
- else $2
- end
- $func$;
- """
- # Limits:
- # Don't update search_vector past it's postgresql system limit
- # Don't update issue tags (used in filtering) beyond 10MB
- UPDATE_ISSUE_INDEX = """
- CREATE OR REPLACE FUNCTION concat_tsvector(tsvector, tsvector) RETURNS tsvector AS $$
- BEGIN
- RETURN $1 || $2;
- EXCEPTION WHEN program_limit_exceeded THEN
- RETURN $1;
- END;
- $$ LANGUAGE plpgsql;;
- CREATE OR REPLACE FUNCTION collect_tag (jsonb, hstore)
- returns jsonb language sql
- as $$
- SELECT jsonb_merge_deep(jsonb_object_agg(y.key, y.values), $1) FROM (
- SELECT (a).key, array_agg(distinct(a).value) as values FROM (
- select each($2) as a
- ) t GROUP by key
- ) y
- $$;
- CREATE OR REPLACE AGGREGATE agg_collect_tags (hstore) (
- sfunc = collect_tag,
- stype = jsonb,
- initcond = '{}'
- );
- DROP PROCEDURE IF EXISTS update_issue_index;
- CREATE OR REPLACE PROCEDURE update_issue_index(update_issue_id integer)
- LANGUAGE SQL
- AS $$
- WITH event_agg as (
- SELECT COUNT(events_event.event_id) as new_count,
- MAX(events_event.created) as new_last_seen,
- MAX(events_event.level) as new_level,
- agg_collect_tags(events_event.tags) as new_tags
- FROM events_event
- LEFT JOIN issues_issue ON issues_issue.id = events_event.issue_id
- WHERE events_event.issue_id=update_issue_id
- AND events_event.created > issues_issue.last_seen
- ), event_vector as (
- SELECT strip(COALESCE(generate_issue_tsvector(data), ''::tsvector)) as vector
- FROM events_event
- LEFT JOIN issues_issue on issues_issue.id = events_event.issue_id
- WHERE events_event.issue_id=update_issue_id
- AND events_event.created > issues_issue.last_seen
- limit 1
- )
- UPDATE issues_issue
- SET
- count = event_agg.new_count + issues_issue.count,
- last_seen = GREATEST(event_agg.new_last_seen, issues_issue.last_seen),
- level = GREATEST(event_agg.new_level, issues_issue.level),
- search_vector = CASE WHEN pg_column_size(COALESCE(search_vector, ''::tsvector)) < 500000 THEN concat_tsvector(COALESCE(search_vector, ''::tsvector), event_vector.vector) ELSE search_vector END,
- tags = CASE WHEN pg_column_size(tags) < 10000000 THEN COALESCE(jsonb_merge_deep(event_agg.new_tags, tags), '{}') ELSE tags END
- FROM event_agg, event_vector
- WHERE issues_issue.id = update_issue_id;
- $$;
- """
|