File: log.sql

package info (click to toggle)
sqlsmith 1.4-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, sid, trixie
  • size: 540 kB
  • sloc: cpp: 3,221; sql: 175; makefile: 33; sh: 1
file content (176 lines) | stat: -rw-r--r-- 5,548 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
-- schema for --log-to

create table instance (
    id bigserial primary key,
    rev text,      -- sqlsmith git revision
    target text,   -- target connstr
    hostname text, -- hostname of sqlsmith instance
    version text,   -- target version()
    seed text,   -- RNG seed

    -- not referenced by sqlsmith:
    t timestamptz default now(),
    client inet default inet_client_addr(),
    port integer default inet_client_port()
);

comment on table instance is 'details about an sqlsmith instance';

create table error (
    id bigint references instance(id),
    msg text,    -- error message
    query text,  -- failed query
    target text, -- conninfo of the target
    sqlstate text, -- sqlstate of error
    
    -- not referenced by sqlsmith:
    t timestamptz default now(),
    errid bigserial primary key
);

comment on table error is 'observed errors';

create table stat (
   id bigint references instance(id),
   generated bigint,    -- number of generated ASTs
   level float,         -- avg. height of ASTs
   nodes float,         -- avg. number of nodes in ASTs
   retries float,       -- avg. number of retries needed for ASTs
   updated timestamptz,
   impedance jsonb      -- impedance report
);

comment on table stat is 'statistics about ASTs and productions';

-- grant role smith just enough rights to do the logging
create role smith login;
grant insert,select on table instance to smith;
grant insert on table error to smith;
grant update,insert,select on table stat to smith;
grant usage on all sequences in schema public to smith;

-- stuff beyond this line is not referenced by sqlsmith

create or replace function firstline(msg text) returns text as $$
    select split_part(msg, E'\n', 1);
$$ language sql immutable;

create view base_error as
       select id, firstline(msg) as error, query, t, errid from error;

comment on view base_error is 'like error, but truncate msg to first line';

drop view if exists report;
create view report as
       select count(1), max(t) as last_seen, error
       from base_error group by 3 order by count desc;


create or replace view state_report as
 SELECT count(1) AS count,
    sqlstate,
    min(substring(firstline(e.msg),1,80)) AS sample,
    array_agg(DISTINCT i.hostname) AS hosts
   FROM error e
     JOIN instance i ON i.id = e.id
  WHERE e.t > (now() - '24:00:00'::interval)
  GROUP BY sqlstate
  ORDER BY (count(1));

comment on view state_report is 'an sqlstate-grouped report';

comment on view report is 'same report as sqlsmith''s verbose output';

drop view if exists report24h;
create view report24h as
       select count(1), error, max(e.t) as last_seen
       from base_error e join instance i on (e.id = i.id)
       where i.t > now() - interval '1 days'
       	     group by 2 order by count desc;

create or replace view reporthosts as
 SELECT count(1) AS count,
    substring(firstline(e.msg),1,80) as firstline,
    array_agg(DISTINCT i.hostname) AS hosts
   FROM error e
     JOIN instance i ON i.id = e.id
  WHERE e.t > (now() - '24:00:00'::interval)
  GROUP BY 2
  ORDER BY (count(1));

create view instance_activity as
       select i.hostname, i.target, max(e.t)
       	      from instance i join error e on (i.id = e.id)
	      group by i.hostname, i.target
              order by max desc;

comment on view instance_activity is 'time of last error message from instance';

create view instance_speed as
    select hostname,
        generated/extract(epoch from (updated-t)) as "queries/s"
    from stat natural join instance
    where updated > now() - interval '1 minutes';

comment on view instance_speed is 'query speed of recently active instances';

-- Filtering boring errors

create table boring_sqlstates (sqlstate text primary key);
comment on table boring_sqlstates is 'sqlstates to reject';
grant select on boring_sqlstates to public;
\copy boring_sqlstates from boring_sqlstates.txt

create table known(error text);
comment on table known is 'error messages to reject';
\copy known from known.txt

create table known_re(re text);
comment on table known_re is 'regular expressions to match error messages to reject';
\copy known_re from known_re.txt

create or replace function discard_known() returns trigger as $$
begin
	if exists (select 1 from boring_sqlstates b where new.sqlstate = b.sqlstate)
	   or exists (select 1 from known where firstline(new.msg) = error)
	then
	   return NULL;
        end if;
	
	if new.msg ~ ANY (select re from known_re)
        then
	   return NULL;
	end if;
	return new;
end
$$ language plpgsql;

create trigger discard_known before insert on error
    for each row execute procedure discard_known();

-- YMMV.
create index on error(t);

-- Following views are used for debugging sqlsmith
create view impedance as
    select id, generated, level, nodes, updated,
    	   prod, ok, bad, js.retries, limited, failed
    from stat, jsonb_to_recordset(impedance->'impedance')
    	 js(prod text, ok bigint, bad bigint, retries bigint, limited bigint, failed bigint)
    where impedance is not null;

comment on view impedance is 'stat table with normalized jsonb';

create view impedance_report as
  select rev, prod,
  	 sum(generated) as generated, sum(ok) as ok,
	 sum(bad) as bad,
	 sum(retries) as retries,
	 sum(limited)as limited,
	 sum(failed) as failed
  from impedance natural join instance
  where rev = (select max(rev) from instance where version ~* 'postgres')
  group by rev, prod
  order by retries;

comment on view impedance_report is 'impedance report for latest revision';