\set ECHO 0 BEGIN; \set QUIET 1 \i sql/explanation.sql -- Need to mock md5() so that it emits known values, so the tests will pass. CREATE SCHEMA mock; CREATE TEMPORARY SEQUENCE md5seq; CREATE TEMPORARY TABLE md5s ( md5 TEXT, id INTEGER DEFAULT NEXTVAL('md5seq') ); INSERT INTO md5s VALUES ('6e9d7e0628d306480fece89e8483fe6e'), ('b012abc1673778343cb1b89aae1e9b94'), ('029dde3a3c872f0c960f03d2ecfaf5ee'), ('3e4c4968cee7653037613c234a953be1'), ('dd3d1b1fb6c70be827075e01b306250c'), ('037a8fe70739ed1be6a3006d0ab80c82'), ('2c4e922dc19ce9f01a3bf08fbd76b041'), ('709b2febd8e560dd8830f4c7277c3758'), ('9dd89be09ea07a1000a21cbfc09121c7'), ('8dc3d35ab978f6c6e46f7927e7b86d21'), ('3d7c72f13ae7571da70f434b5bc9e0af'); CREATE FUNCTION mock.md5(TEXT) RETURNS TEXT LANGUAGE plpgsql AS $$ DECLARE rec md5s; BEGIN SELECT * INTO rec FROM md5s WHERE id = (SELECT MIN(id) FROM md5s); DELETE FROM md5s WHERE id = rec.id; RETURN rec.md5; END; $$; -- Mock now(), too. CREATE FUNCTION mock.now() RETURNS TIMESTAMPTZ LANGUAGE SQL AS $$ SELECT '2010-11-08 19:21:19.817375+00'::timestamptz; $$; SET search_path = mock,public,pg_catalog; SET DateStyle = 'ISO'; SET IntervalStyle = 'postgres'; SET timezone = 'UTC'; -- Okay, now on with the tests. Create a table to query against. CREATE TABLE foo(id int); \set QUIET 0 -- Plan an explain and an explain analyze. SELECT * FROM explanation('select * from foo'); -- Plan an explain analyze. Omit imes because it varies. :-( SELECT planned_at = NOW() AS have_planned_at, node_id, parent_id, node_type, total_runtime IS NOT NULL AS have_total_runtime, strategy, operation, startup_cost, total_cost, plan_rows, plan_width, actual_startup_time IS NOT NULL AS have_actual_startup_time, actual_total_time IS NOT NULL AS have_actual_Total_time, actual_rows, actual_loops, parent_relationship, sort_key, sort_method, sort_space_used, sort_space_type, join_type, join_filter, hash_cond, relation_name, alias, scan_direction, index_name, index_cond, recheck_cond, tid_cond, merge_cond, subplan_name, function_name, function_call, filter, one_time_filter, command, shared_hit_blocks, shared_read_blocks, shared_written_blocks, local_hit_blocks, local_read_blocks, local_written_blocks, temp_read_blocks, temp_written_blocks, output, hash_buckets, hash_batches, original_hash_batches, peak_memory_usage, schema, cte_name FROM explanation( query := 'select * from foo', analyzed := true); -- Make sure parse_node() recurses. SELECT * FROM parse_node($$ Aggregate Sorted 258.13 262.31 4 324 0.121 0.121 0 1 Sort Outer 258.13 258.14 4 324 0.117 0.117 0 1 d.name d.version d.abstract d.description d.relstatus d.owner d.sha1 d.meta quicksort 25 Memory Nested Loop Outer Left 16.75 258.09 4 324 0.009 0.009 0 1 (semver_cmp(d.version, dt.version) = 0) Hash Join Outer Inner 16.75 253.06 4 292 0.009 0.009 0 1 (de.distribution = d.name) (semver_cmp(d.version, de.dist_version) = 0) Seq Scan Outer distribution_extensions de 0.00 15.10 510 128 0.008 0.008 0 1 Hash Inner 13.00 13.00 300 228 0.000 0.000 0 0 Seq Scan Outer distributions d 0.00 13.00 300 228 0.000 0.000 0 0 Index Scan Inner NoMovement distribution_tags_pkey distribution_tags dt 0.00 0.46 3 96 0.000 0.000 0 0 (d.name = dt.distribution) Function Scan SubPlan SubPlan 1 unnest g 0.00 1.00 100 32 0.000 0.000 0 0 (x IS NOT NULL) $$); -- Make sure parse_trigger() works. SELECT * FROM parse_triggers(ARRAY[ $$ Harry Melissa users 14 $$, $$ Josh Jeff wankers 2 $$ ]::xml[]); ROLLBACK;