Project

General

Profile

1 2094 aaronmk
--
2
-- PostgreSQL database dump
3
--
4
5
SET statement_timeout = 0;
6 11667 aaronmk
SET lock_timeout = 0;
7 2094 aaronmk
SET client_encoding = 'UTF8';
8 6213 aaronmk
SET standard_conforming_strings = on;
9 2094 aaronmk
SET check_function_bodies = false;
10
SET client_min_messages = warning;
11
12
--
13 8183 aaronmk
-- Name: util; Type: SCHEMA; Schema: -; Owner: -
14 2094 aaronmk
--
15
16 8183 aaronmk
CREATE SCHEMA util;
17 2094 aaronmk
18
19 4982 aaronmk
--
20 8183 aaronmk
-- Name: SCHEMA util; Type: COMMENT; Schema: -; Owner: -
21 4982 aaronmk
--
22
23 12235 aaronmk
COMMENT ON SCHEMA util IS '
24
IMPORTANT: Functions must always return NULL in place of '''' (the empty string). This ensures that empty strings do not find their way into VegBIEN.
25 4982 aaronmk
26 12447 aaronmk
NOTE: SQL-language functions should never be declared STRICT, because this prevents them from being inlined. inlining can create a significant speed improvement (7x+), by avoiding function calls and enabling additional constant folding. avoiding use of STRICT also makes functions *much* easier to troubleshoot, because they won''t mysteriously do nothing if called with only NULL arguments, even when you have added debug-print statements.
27 12235 aaronmk
';
28 4982 aaronmk
29 10378 aaronmk
30 8183 aaronmk
SET search_path = util, pg_catalog;
31 2107 aaronmk
32 2094 aaronmk
--
33 8183 aaronmk
-- Name: col_cast; Type: TYPE; Schema: util; Owner: -
34 8107 aaronmk
--
35
36
CREATE TYPE col_cast AS (
37
	col_name text,
38
	type regtype
39
);
40
41
42
--
43 8183 aaronmk
-- Name: col_ref; Type: TYPE; Schema: util; Owner: -
44 8106 aaronmk
--
45
46
CREATE TYPE col_ref AS (
47
	table_ regclass,
48
	name text
49
);
50
51
52
--
53 8183 aaronmk
-- Name: compass_dir; Type: TYPE; Schema: util; Owner: -
54 7673 aaronmk
--
55
56
CREATE TYPE compass_dir AS ENUM (
57
    'N',
58
    'E',
59
    'S',
60
    'W'
61
);
62
63
64
--
65 8183 aaronmk
-- Name: datatype; Type: TYPE; Schema: util; Owner: -
66 2610 aaronmk
--
67
68
CREATE TYPE datatype AS ENUM (
69
    'str',
70
    'float'
71
);
72
73
74
--
75 13491 aaronmk
-- Name: db_item; Type: TYPE; Schema: util; Owner: -
76
--
77
78
CREATE TYPE db_item AS (
79
	path text,
80
	def text
81
);
82
83
84
--
85 13889 aaronmk
-- Name: geocoord; Type: TYPE; Schema: util; Owner: -
86
--
87
88
CREATE TYPE geocoord AS (
89
	latitude_deg double precision,
90
	longitude_deg double precision
91
);
92
93
94
--
95 13802 aaronmk
-- Name: range; Type: TYPE; Schema: util; Owner: -
96
--
97
98
CREATE TYPE range AS (
99
	lower numeric,
100
	upper numeric,
101
	bounds text
102
);
103
104
105
--
106
-- Name: TYPE range; Type: COMMENT; Schema: util; Owner: -
107
--
108
109
COMMENT ON TYPE range IS '
110
allows wraparound ranges (which use a modulus system such as geocoordinates)
111
';
112
113
114
--
115 13488 aaronmk
-- Name: restore_views_info; Type: TYPE; Schema: util; Owner: -
116
--
117
118
CREATE TYPE restore_views_info AS (
119 13491 aaronmk
	views db_item[]
120 13488 aaronmk
);
121
122
123
--
124 8183 aaronmk
-- Name: _alt(anyelement, anyelement, anyelement, anyelement, anyelement, anyelement, anyelement, anyelement, anyelement, anyelement, anyelement, anyelement, anyelement); Type: FUNCTION; Schema: util; Owner: -
125 2596 aaronmk
--
126
127 4501 aaronmk
CREATE FUNCTION _alt("0" anyelement DEFAULT NULL::unknown, "1" anyelement DEFAULT NULL::unknown, "2" anyelement DEFAULT NULL::unknown, "3" anyelement DEFAULT NULL::unknown, "4" anyelement DEFAULT NULL::unknown, "5" anyelement DEFAULT NULL::unknown, "6" anyelement DEFAULT NULL::unknown, "7" anyelement DEFAULT NULL::unknown, "8" anyelement DEFAULT NULL::unknown, "9" anyelement DEFAULT NULL::unknown, "10" anyelement DEFAULT NULL::unknown, "11" anyelement DEFAULT NULL::unknown, "12" anyelement DEFAULT NULL::unknown) RETURNS anyelement
128 3422 aaronmk
    LANGUAGE sql IMMUTABLE
129
    AS $_$
130 4501 aaronmk
SELECT coalesce($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)
131 3422 aaronmk
$_$;
132
133
134
--
135 8183 aaronmk
-- Name: _and(boolean, boolean, boolean, boolean, boolean); Type: FUNCTION; Schema: util; Owner: -
136 5937 aaronmk
--
137
138 5956 aaronmk
CREATE FUNCTION _and("0" boolean DEFAULT NULL::boolean, "1" boolean DEFAULT NULL::boolean, "2" boolean DEFAULT NULL::boolean, "3" boolean DEFAULT NULL::boolean, "4" boolean DEFAULT NULL::boolean) RETURNS boolean
139 5937 aaronmk
    LANGUAGE sql IMMUTABLE
140
    AS $_$
141
SELECT bool_and(value)
142
FROM
143
(VALUES
144
      ($1)
145
    , ($2)
146 5956 aaronmk
    , ($3)
147
    , ($4)
148
    , ($5)
149 5937 aaronmk
)
150
AS v (value)
151
$_$;
152
153
154
--
155 8183 aaronmk
-- Name: FUNCTION _and("0" boolean, "1" boolean, "2" boolean, "3" boolean, "4" boolean); Type: COMMENT; Schema: util; Owner: -
156 5937 aaronmk
--
157
158 12235 aaronmk
COMMENT ON FUNCTION _and("0" boolean, "1" boolean, "2" boolean, "3" boolean, "4" boolean) IS '
159
_and() ignores NULL values, while AND combines them with the other values to potentially convert true to NULL. AND should be used with required fields, and _and() with optional fields.
160
';
161 5937 aaronmk
162
163
--
164 8183 aaronmk
-- Name: _avg(double precision, double precision, double precision, double precision, double precision); Type: FUNCTION; Schema: util; Owner: -
165 7704 aaronmk
--
166
167
CREATE FUNCTION _avg("0" double precision DEFAULT NULL::double precision, "1" double precision DEFAULT NULL::double precision, "2" double precision DEFAULT NULL::double precision, "3" double precision DEFAULT NULL::double precision, "4" double precision DEFAULT NULL::double precision) RETURNS double precision
168
    LANGUAGE sql IMMUTABLE
169
    AS $_$
170
SELECT avg(value)
171
FROM
172
(VALUES
173
      ($1)
174
    , ($2)
175
    , ($3)
176
    , ($4)
177
    , ($5)
178
)
179
AS v (value)
180
$_$;
181
182
183
--
184 8183 aaronmk
-- Name: _dms_to_dd(text); Type: FUNCTION; Schema: util; Owner: -
185 7679 aaronmk
--
186
187
CREATE FUNCTION _dms_to_dd(value text DEFAULT NULL::text) RETURNS double precision
188 12441 aaronmk
    LANGUAGE sql IMMUTABLE
189 7679 aaronmk
    AS $_$
190 8183 aaronmk
SELECT (g[1]||'1')::integer*util._dms_to_dd(deg := g[2]::double precision, min := g[3]::double precision, sec := g[4]::double precision, dir := g[5]::util.compass_dir)
191 7698 aaronmk
FROM
192
(
193
    SELECT regexp_matches($1, '^ *(-?)(\d{1,3}(?:\.\d*)?)(?:(?:deg|[°º])(?: *([\d.]+)(?:min|[''’]))?(?: *([\d.]+)(?:sec|["”]))?)? *([NESW])? *$')
194
    UNION ALL
195 7702 aaronmk
    SELECT ARRAY[g[1], g[2], g[3]||'.'||g[4], NULL, g[5]]
196
    FROM regexp_matches($1, '^ *(-?)(\d{2,3})(\d{2})(\d{3}) *([NESW])? *$') matches (g) -- [D]DDMMmmm, where MMmmm = MM.mmm
197 7698 aaronmk
)
198
matches (g)
199 7679 aaronmk
$_$;
200
201
202
--
203 8183 aaronmk
-- Name: _dms_to_dd(double precision, double precision, double precision, compass_dir); Type: FUNCTION; Schema: util; Owner: -
204 7672 aaronmk
--
205
206 7674 aaronmk
CREATE FUNCTION _dms_to_dd(deg double precision DEFAULT NULL::double precision, min double precision DEFAULT NULL::double precision, sec double precision DEFAULT NULL::double precision, dir compass_dir DEFAULT NULL::compass_dir) RETURNS double precision
207 7672 aaronmk
    LANGUAGE sql IMMUTABLE
208
    AS $_$
209 8183 aaronmk
SELECT sum(value)*COALESCE(util._map('N=>1,E=>1,S=>-1,W=>-1', $4::text)::integer, 1)
210 7672 aaronmk
FROM
211
(VALUES
212 7677 aaronmk
      ($1)
213 7672 aaronmk
    , ($2/60)
214
    , ($3/60/60)
215
)
216
AS v (value)
217
$_$;
218
219
220
--
221 8183 aaronmk
-- Name: _dms_to_dd(text, text, text, text); Type: FUNCTION; Schema: util; Owner: -
222 7723 aaronmk
--
223
224
CREATE FUNCTION _dms_to_dd(deg text DEFAULT NULL::text, min text DEFAULT NULL::text, sec text DEFAULT NULL::text, dir text DEFAULT NULL::text) RETURNS double precision
225
    LANGUAGE sql IMMUTABLE
226
    AS $_$
227 8183 aaronmk
SELECT util._dms_to_dd($1::double precision, $2::double precision, $3::double precision, $4::util.compass_dir)
228 7723 aaronmk
$_$;
229
230
231
--
232 8183 aaronmk
-- Name: _eq(anyelement, anyelement); Type: FUNCTION; Schema: util; Owner: -
233 4142 aaronmk
--
234
235
CREATE FUNCTION _eq("left" anyelement DEFAULT NULL::unknown, "right" anyelement DEFAULT NULL::unknown) RETURNS boolean
236
    LANGUAGE sql IMMUTABLE
237
    AS $_$
238
SELECT $1 = $2
239
$_$;
240
241
242
--
243 8183 aaronmk
-- Name: _fix_date(date, date); Type: FUNCTION; Schema: util; Owner: -
244 7396 aaronmk
--
245
246
CREATE FUNCTION _fix_date(value date DEFAULT NULL::date, threshold date DEFAULT NULL::date) RETURNS date
247
    LANGUAGE sql IMMUTABLE
248
    AS $_$
249
-- Fix dates after threshold date
250
-- This fixes e.g. 2-digit years before 1970 misinterpreted as 20xx
251
SELECT (CASE WHEN $1 > COALESCE($2, now()) THEN ($1 - '100 years'::interval)::date ELSE $1 END)
252
$_$;
253
254
255
--
256 8183 aaronmk
-- Name: _if(boolean, anyelement, anyelement); Type: FUNCTION; Schema: util; Owner: -
257 4147 aaronmk
--
258
259
CREATE FUNCTION _if(cond boolean DEFAULT NULL::boolean, "then" anyelement DEFAULT NULL::unknown, "else" anyelement DEFAULT NULL::unknown) RETURNS anyelement
260
    LANGUAGE sql IMMUTABLE
261
    AS $_$
262
SELECT (CASE WHEN $1 THEN $2 ELSE $3 END)
263
$_$;
264
265
266
--
267 8183 aaronmk
-- Name: _if(text, anyelement, anyelement); Type: FUNCTION; Schema: util; Owner: -
268 4147 aaronmk
--
269
270
CREATE FUNCTION _if(cond text DEFAULT NULL::text, "then" anyelement DEFAULT NULL::unknown, "else" anyelement DEFAULT NULL::unknown) RETURNS anyelement
271
    LANGUAGE sql IMMUTABLE
272
    AS $_$
273 8183 aaronmk
SELECT util._if($1 != '', $2, $3)
274 4147 aaronmk
$_$;
275
276
277
--
278 10699 aaronmk
-- Name: _join(text, text, text, text, text, text, text, text, text, text); Type: FUNCTION; Schema: util; Owner: -
279 4325 aaronmk
--
280
281 10699 aaronmk
CREATE FUNCTION _join("0" text DEFAULT NULL::text, "1" text DEFAULT NULL::text, "2" text DEFAULT NULL::text, "3" text DEFAULT NULL::text, "4" text DEFAULT NULL::text, "5" text DEFAULT NULL::text, "6" text DEFAULT NULL::text, "7" text DEFAULT NULL::text, "8" text DEFAULT NULL::text, "9" text DEFAULT NULL::text) RETURNS text
282 4325 aaronmk
    LANGUAGE sql IMMUTABLE
283
    AS $_$
284 7848 aaronmk
SELECT NULLIF(concat_ws('; ', $1, $2, $3, $4, $5, $6, $7, $8, $9, $10), '')
285 4325 aaronmk
$_$;
286
287
288
--
289 10699 aaronmk
-- Name: _join_words(text, text, text, text, text, text, text, text, text, text); Type: FUNCTION; Schema: util; Owner: -
290 5009 aaronmk
--
291
292 10699 aaronmk
CREATE FUNCTION _join_words("0" text DEFAULT NULL::text, "1" text DEFAULT NULL::text, "2" text DEFAULT NULL::text, "3" text DEFAULT NULL::text, "4" text DEFAULT NULL::text, "5" text DEFAULT NULL::text, "6" text DEFAULT NULL::text, "7" text DEFAULT NULL::text, "8" text DEFAULT NULL::text, "9" text DEFAULT NULL::text) RETURNS text
293 5009 aaronmk
    LANGUAGE sql IMMUTABLE
294
    AS $_$
295 7848 aaronmk
SELECT NULLIF(concat_ws(' ', $1, $2, $3, $4, $5, $6, $7, $8, $9, $10), '')
296 5009 aaronmk
$_$;
297
298
299
--
300 13355 aaronmk
-- Name: _km_to_m(double precision); Type: FUNCTION; Schema: util; Owner: -
301
--
302
303
CREATE FUNCTION _km_to_m(value double precision) RETURNS double precision
304
    LANGUAGE sql IMMUTABLE
305
    AS $_$
306
SELECT $1*1000.
307
$_$;
308
309
310
--
311 10699 aaronmk
-- Name: _label(text, text); Type: FUNCTION; Schema: util; Owner: -
312 3422 aaronmk
--
313
314 10699 aaronmk
CREATE FUNCTION _label(label text, value text) RETURNS text
315 4682 aaronmk
    LANGUAGE sql IMMUTABLE
316
    AS $_$
317
SELECT coalesce($1 || ': ', '') || $2
318
$_$;
319 2596 aaronmk
320
321
--
322 8825 aaronmk
-- Name: _lowercase(text); Type: FUNCTION; Schema: util; Owner: -
323
--
324
325
CREATE FUNCTION _lowercase(value text) RETURNS text
326 10388 aaronmk
    LANGUAGE sql IMMUTABLE
327 8825 aaronmk
    AS $_$
328
SELECT lower($1)
329
$_$;
330
331
332
--
333 11667 aaronmk
-- Name: _map(hstore, anyelement); Type: FUNCTION; Schema: util; Owner: -
334
--
335
336
CREATE FUNCTION _map(map hstore, value anyelement) RETURNS anyelement
337
    LANGUAGE plpgsql IMMUTABLE STRICT
338
    AS $$
339
DECLARE
340
    result value%TYPE := util._map(map, value::text)::unknown;
341
BEGIN
342
    RETURN result;
343
END;
344
$$;
345
346
347
--
348 8183 aaronmk
-- Name: _map(hstore, text); Type: FUNCTION; Schema: util; Owner: -
349 6222 aaronmk
--
350
351
CREATE FUNCTION _map(map hstore, value text) RETURNS text
352 7820 aaronmk
    LANGUAGE plpgsql IMMUTABLE STRICT
353 6222 aaronmk
    AS $$
354
DECLARE
355 6271 aaronmk
    match text := map -> value;
356 6222 aaronmk
BEGIN
357 6271 aaronmk
    IF match IS NULL AND NOT map ? value THEN -- no match rather than NULL match
358
        match := map -> '*'; -- use default entry
359
        IF match IS NULL AND NOT map ? '*' THEN match := '!'; -- no default
360
        END IF;
361
    END IF;
362
363
    -- Interpret result
364 6243 aaronmk
    IF match = '!' THEN RAISE 'Value not in map: %', value USING ERRCODE = 'data_exception';
365
    ELSIF match = '*' THEN RETURN value;
366
    ELSE RETURN match;
367 6222 aaronmk
    END IF;
368
END;
369
$$;
370
371
372
--
373 8183 aaronmk
-- Name: _max(anyelement, anyelement, anyelement, anyelement, anyelement, anyelement, anyelement, anyelement, anyelement, anyelement); Type: FUNCTION; Schema: util; Owner: -
374 5408 aaronmk
--
375
376
CREATE FUNCTION _max("0" anyelement DEFAULT NULL::unknown, "1" anyelement DEFAULT NULL::unknown, "2" anyelement DEFAULT NULL::unknown, "3" anyelement DEFAULT NULL::unknown, "4" anyelement DEFAULT NULL::unknown, "5" anyelement DEFAULT NULL::unknown, "6" anyelement DEFAULT NULL::unknown, "7" anyelement DEFAULT NULL::unknown, "8" anyelement DEFAULT NULL::unknown, "9" anyelement DEFAULT NULL::unknown) RETURNS anyelement
377
    LANGUAGE sql IMMUTABLE
378
    AS $_$
379 7289 aaronmk
SELECT GREATEST($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
380 5408 aaronmk
$_$;
381
382
383
--
384 8183 aaronmk
-- Name: _merge(anyelement, anyelement, anyelement, anyelement, anyelement, anyelement, anyelement, anyelement, anyelement, anyelement); Type: FUNCTION; Schema: util; Owner: -
385 2940 aaronmk
--
386
387 4150 aaronmk
CREATE FUNCTION _merge("0" anyelement DEFAULT NULL::unknown, "1" anyelement DEFAULT NULL::unknown, "2" anyelement DEFAULT NULL::unknown, "3" anyelement DEFAULT NULL::unknown, "4" anyelement DEFAULT NULL::unknown, "5" anyelement DEFAULT NULL::unknown, "6" anyelement DEFAULT NULL::unknown, "7" anyelement DEFAULT NULL::unknown, "8" anyelement DEFAULT NULL::unknown, "9" anyelement DEFAULT NULL::unknown) RETURNS anyelement
388 2940 aaronmk
    LANGUAGE sql IMMUTABLE
389
    AS $_$
390 8183 aaronmk
SELECT util.join_strs(value, '; ')
391 2940 aaronmk
FROM
392
(
393
    SELECT *
394
    FROM
395
    (
396
        SELECT
397
        DISTINCT ON (value)
398
        *
399
        FROM
400
        (VALUES
401 4012 aaronmk
              (1, $1)
402
            , (2, $2)
403
            , (3, $3)
404
            , (4, $4)
405
            , (5, $5)
406
            , (6, $6)
407
            , (7, $7)
408
            , (8, $8)
409
            , (9, $9)
410
            , (10, $10)
411 2940 aaronmk
        )
412
        AS v (sort_order, value)
413 4011 aaronmk
        WHERE value IS NOT NULL
414 2940 aaronmk
    )
415
    AS v
416
    ORDER BY sort_order
417
)
418
AS v
419
$_$;
420
421
422
--
423 8183 aaronmk
-- Name: _merge_prefix(text, text); Type: FUNCTION; Schema: util; Owner: -
424 7140 aaronmk
--
425
426
CREATE FUNCTION _merge_prefix(prefix text DEFAULT NULL::text, value text DEFAULT NULL::text) RETURNS text
427
    LANGUAGE sql IMMUTABLE
428
    AS $_$
429
SELECT _join_words((CASE WHEN $2 ~ ('^'||$1||E'\\y') THEN NULL ELSE $1 END), $2)
430
$_$;
431
432
433
--
434 8183 aaronmk
-- Name: _merge_words(anyelement, anyelement, anyelement, anyelement, anyelement, anyelement, anyelement, anyelement, anyelement, anyelement); Type: FUNCTION; Schema: util; Owner: -
435 6354 aaronmk
--
436
437
CREATE FUNCTION _merge_words("0" anyelement DEFAULT NULL::unknown, "1" anyelement DEFAULT NULL::unknown, "2" anyelement DEFAULT NULL::unknown, "3" anyelement DEFAULT NULL::unknown, "4" anyelement DEFAULT NULL::unknown, "5" anyelement DEFAULT NULL::unknown, "6" anyelement DEFAULT NULL::unknown, "7" anyelement DEFAULT NULL::unknown, "8" anyelement DEFAULT NULL::unknown, "9" anyelement DEFAULT NULL::unknown) RETURNS anyelement
438
    LANGUAGE sql IMMUTABLE
439
    AS $_$
440 8183 aaronmk
SELECT util.join_strs(value, ' ')
441 6354 aaronmk
FROM
442
(
443
    SELECT *
444
    FROM
445
    (
446
        SELECT
447
        DISTINCT ON (value)
448
        *
449
        FROM
450
        (VALUES
451
              (1, $1)
452
            , (2, $2)
453
            , (3, $3)
454
            , (4, $4)
455
            , (5, $5)
456
            , (6, $6)
457
            , (7, $7)
458
            , (8, $8)
459
            , (9, $9)
460
            , (10, $10)
461
        )
462
        AS v (sort_order, value)
463
        WHERE value IS NOT NULL
464
    )
465
    AS v
466
    ORDER BY sort_order
467
)
468
AS v
469
$_$;
470
471
472
--
473 8183 aaronmk
-- Name: _min(anyelement, anyelement, anyelement, anyelement, anyelement, anyelement, anyelement, anyelement, anyelement, anyelement); Type: FUNCTION; Schema: util; Owner: -
474 5408 aaronmk
--
475
476
CREATE FUNCTION _min("0" anyelement DEFAULT NULL::unknown, "1" anyelement DEFAULT NULL::unknown, "2" anyelement DEFAULT NULL::unknown, "3" anyelement DEFAULT NULL::unknown, "4" anyelement DEFAULT NULL::unknown, "5" anyelement DEFAULT NULL::unknown, "6" anyelement DEFAULT NULL::unknown, "7" anyelement DEFAULT NULL::unknown, "8" anyelement DEFAULT NULL::unknown, "9" anyelement DEFAULT NULL::unknown) RETURNS anyelement
477
    LANGUAGE sql IMMUTABLE
478
    AS $_$
479 7289 aaronmk
SELECT LEAST($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
480 5408 aaronmk
$_$;
481
482
483
--
484 8183 aaronmk
-- Name: _not(boolean); Type: FUNCTION; Schema: util; Owner: -
485 6316 aaronmk
--
486
487
CREATE FUNCTION _not(value boolean) RETURNS boolean
488 10388 aaronmk
    LANGUAGE sql IMMUTABLE
489 6316 aaronmk
    AS $_$
490
SELECT NOT $1
491
$_$;
492
493
494
--
495 8183 aaronmk
-- Name: _now(); Type: FUNCTION; Schema: util; Owner: -
496 7104 aaronmk
--
497
498
CREATE FUNCTION _now() RETURNS timestamp with time zone
499
    LANGUAGE sql STABLE
500
    AS $$
501
SELECT now()
502
$$;
503
504
505
--
506 11667 aaronmk
-- Name: _nullIf(anyelement, text, text); Type: FUNCTION; Schema: util; Owner: -
507
--
508
509
CREATE FUNCTION "_nullIf"(value anyelement, "null" text, type text) RETURNS anyelement
510
    LANGUAGE sql IMMUTABLE
511
    AS $_$
512
SELECT util."_nullIf"($1, $2, $3::util.datatype)
513
$_$;
514
515
516
--
517 8183 aaronmk
-- Name: _nullIf(anyelement, text, datatype); Type: FUNCTION; Schema: util; Owner: -
518 2949 aaronmk
--
519
520 4475 aaronmk
CREATE FUNCTION "_nullIf"(value anyelement, "null" text, type datatype DEFAULT 'str'::datatype) RETURNS anyelement
521 2949 aaronmk
    LANGUAGE plpgsql IMMUTABLE
522
    AS $$
523
DECLARE
524 8183 aaronmk
    type util.datatype NOT NULL := type; -- add NOT NULL
525 2949 aaronmk
BEGIN
526 4475 aaronmk
    IF type = 'str' THEN RETURN nullif(value::text, "null");
527 2722 aaronmk
    -- Invalid value is ignored, but invalid null value generates error
528 2949 aaronmk
    ELSIF type = 'float' THEN
529 2722 aaronmk
        DECLARE
530
            -- Outside the try block so that invalid null value generates error
531 2949 aaronmk
            "null" double precision := "null"::double precision;
532 2722 aaronmk
        BEGIN
533 2949 aaronmk
            RETURN nullif(value::double precision, "null");
534 2722 aaronmk
        EXCEPTION
535 2949 aaronmk
            WHEN data_exception THEN RETURN value; -- ignore invalid value
536 2722 aaronmk
        END;
537 2610 aaronmk
    END IF;
538
END;
539
$$;
540
541
542
--
543 8183 aaronmk
-- Name: _or(boolean, boolean, boolean, boolean, boolean); Type: FUNCTION; Schema: util; Owner: -
544 6355 aaronmk
--
545
546
CREATE FUNCTION _or("0" boolean DEFAULT NULL::boolean, "1" boolean DEFAULT NULL::boolean, "2" boolean DEFAULT NULL::boolean, "3" boolean DEFAULT NULL::boolean, "4" boolean DEFAULT NULL::boolean) RETURNS boolean
547
    LANGUAGE sql IMMUTABLE
548
    AS $_$
549
SELECT bool_or(value)
550
FROM
551
(VALUES
552
      ($1)
553
    , ($2)
554
    , ($3)
555
    , ($4)
556
    , ($5)
557
)
558
AS v (value)
559
$_$;
560
561
562
--
563 8183 aaronmk
-- Name: FUNCTION _or("0" boolean, "1" boolean, "2" boolean, "3" boolean, "4" boolean); Type: COMMENT; Schema: util; Owner: -
564 6437 aaronmk
--
565
566 12235 aaronmk
COMMENT ON FUNCTION _or("0" boolean, "1" boolean, "2" boolean, "3" boolean, "4" boolean) IS '
567
_or() ignores NULL values, while OR combines them with the other values to potentially convert false to NULL. OR should be used with required fields, and _or() with optional fields.
568
';
569 6437 aaronmk
570
571
--
572 8183 aaronmk
-- Name: _range(double precision, double precision); Type: FUNCTION; Schema: util; Owner: -
573 7706 aaronmk
--
574
575
CREATE FUNCTION _range("from" double precision DEFAULT NULL::double precision, "to" double precision DEFAULT NULL::double precision) RETURNS double precision
576
    LANGUAGE sql IMMUTABLE
577
    AS $_$
578
SELECT $2 - $1
579
$_$;
580
581
582
--
583 8183 aaronmk
-- Name: _split(text, text); Type: FUNCTION; Schema: util; Owner: -
584 6793 aaronmk
--
585
586
CREATE FUNCTION _split(value text DEFAULT NULL::text, separator text DEFAULT '; '::text) RETURNS SETOF text
587 10388 aaronmk
    LANGUAGE sql IMMUTABLE
588 6793 aaronmk
    AS $_$
589
SELECT regexp_split_to_table($1, $2)
590
$_$;
591
592
593
--
594 10594 aaronmk
-- Name: added_cols(regclass, regclass); Type: FUNCTION; Schema: util; Owner: -
595
--
596
597
CREATE FUNCTION added_cols(table_ regclass, names regclass) RETURNS SETOF text
598 12446 aaronmk
    LANGUAGE sql STABLE
599 10594 aaronmk
    AS $_$
600
SELECT util.derived_cols($1, $2)
601
UNION
602
SELECT util.eval2set($$
603
SELECT col
604
FROM util.col_names($$||quote_nullable($1)||$$::regclass) f (col)
605
JOIN $$||$2||$$ ON "to" = col
606
WHERE "from" LIKE ':%'
607
$$, NULL::text)
608
$_$;
609
610
611
--
612
-- Name: FUNCTION added_cols(table_ regclass, names regclass); Type: COMMENT; Schema: util; Owner: -
613
--
614
615 12235 aaronmk
COMMENT ON FUNCTION added_cols(table_ regclass, names regclass) IS '
616
gets table_''s added columns (all the columns not in the original data)
617
';
618 10594 aaronmk
619
620
--
621 9959 aaronmk
-- Name: all_same_final(anyarray); Type: FUNCTION; Schema: util; Owner: -
622
--
623
624
CREATE FUNCTION all_same_final(state anyarray) RETURNS boolean
625
    LANGUAGE sql IMMUTABLE
626
    AS $_$
627
SELECT $1 IS NULL/*no rows*/ OR util.not_empty($1)/*not no_match_sentinel*/
628
$_$;
629
630
631
--
632
-- Name: all_same_transform(anyarray, anyelement); Type: FUNCTION; Schema: util; Owner: -
633
--
634
635
CREATE FUNCTION all_same_transform(state anyarray, value anyelement) RETURNS anyarray
636
    LANGUAGE plpgsql IMMUTABLE
637
    AS $$
638
DECLARE
639
	value_cmp         state%TYPE = ARRAY[value];
640
	state             state%TYPE = COALESCE(state, value_cmp);
641
	no_match_sentinel state%TYPE = value_cmp[1:0]/*=ARRAY[]::state%TYPE*/;
642
BEGIN
643
	RETURN (CASE WHEN value_cmp IS NOT DISTINCT FROM state THEN state ELSE no_match_sentinel END);
644
END;
645
$$;
646
647
648
--
649 12320 aaronmk
-- Name: analyze_(regclass); Type: FUNCTION; Schema: util; Owner: -
650
--
651
652
CREATE FUNCTION analyze_(table_ regclass) RETURNS void
653
    LANGUAGE sql
654
    AS $_$
655
SELECT util.eval($$ANALYZE VERBOSE $$||$1)
656
$_$;
657
658
659
--
660 12369 aaronmk
-- Name: append_comment(regclass, text); Type: FUNCTION; Schema: util; Owner: -
661
--
662
663
CREATE FUNCTION append_comment(table_ regclass, comment text) RETURNS void
664 12446 aaronmk
    LANGUAGE sql
665 12369 aaronmk
    AS $_$
666
SELECT util.set_comment($1, concat(util.comment($1), $2))
667
$_$;
668
669
670
--
671
-- Name: FUNCTION append_comment(table_ regclass, comment text); Type: COMMENT; Schema: util; Owner: -
672
--
673
674
COMMENT ON FUNCTION append_comment(table_ regclass, comment text) IS '
675
comment: must start and end with a newline
676
';
677
678
679
--
680 10305 aaronmk
-- Name: array_fill(anyelement, integer); Type: FUNCTION; Schema: util; Owner: -
681
--
682
683
CREATE FUNCTION array_fill(value anyelement, length integer) RETURNS anyarray
684
    LANGUAGE sql IMMUTABLE
685
    AS $_$
686
SELECT pg_catalog.array_fill($1, ARRAY[$2])
687
$_$;
688
689
690
--
691 10303 aaronmk
-- Name: array_length(anyarray); Type: FUNCTION; Schema: util; Owner: -
692
--
693
694
CREATE FUNCTION array_length("array" anyarray) RETURNS integer
695 10354 aaronmk
    LANGUAGE sql IMMUTABLE
696 10303 aaronmk
    AS $_$
697 10321 aaronmk
SELECT util.array_length($1, 1)
698 10303 aaronmk
$_$;
699
700
701
--
702 10304 aaronmk
-- Name: array_length(anyarray, integer); Type: FUNCTION; Schema: util; Owner: -
703
--
704
705
CREATE FUNCTION array_length("array" anyarray, dimension integer) RETURNS integer
706 10354 aaronmk
    LANGUAGE sql IMMUTABLE
707 10304 aaronmk
    AS $_$
708 10354 aaronmk
SELECT CASE WHEN $1 IS NULL THEN NULL ELSE COALESCE(pg_catalog.array_length($1, $2), 0) END
709 10304 aaronmk
$_$;
710
711
712
--
713
-- Name: FUNCTION array_length("array" anyarray, dimension integer); Type: COMMENT; Schema: util; Owner: -
714
--
715
716 12235 aaronmk
COMMENT ON FUNCTION array_length("array" anyarray, dimension integer) IS '
717
returns 0 instead of NULL for empty arrays
718
';
719 10304 aaronmk
720
721
--
722 13453 aaronmk
-- Name: array_reverse(anyarray); Type: FUNCTION; Schema: util; Owner: -
723
--
724
725
CREATE FUNCTION array_reverse("array" anyarray) RETURNS anyarray
726
    LANGUAGE sql IMMUTABLE
727
    AS $_$
728 13489 aaronmk
SELECT array(SELECT elem FROM util.in_reverse($1) elem)
729 13453 aaronmk
$_$;
730
731
732
--
733 12662 aaronmk
-- Name: auto_rm_freq(regclass[], text); Type: FUNCTION; Schema: util; Owner: -
734 12655 aaronmk
--
735
736 12662 aaronmk
CREATE FUNCTION auto_rm_freq(tables regclass[], freq_col text DEFAULT 'copies'::text) RETURNS void
737 12655 aaronmk
    LANGUAGE sql
738
    AS $_$
739 12662 aaronmk
SELECT CASE WHEN util.freq_always_1($1, $2)
740 13097 aaronmk
THEN util.rm_freq($1, $2)
741 12685 aaronmk
ELSE util.try_create($$ALTER TABLE $$||util.parent($1[1])||$$ ADD COLUMN $$||quote_ident($2)||$$ bigint NOT NULL$$)
742 12662 aaronmk
END
743 12655 aaronmk
$_$;
744
745
746
--
747 13804 aaronmk
-- Name: bounding_box(range, range); Type: FUNCTION; Schema: util; Owner: -
748 13799 aaronmk
--
749
750 13811 aaronmk
CREATE FUNCTION bounding_box(latitude_range_deg range, longitude_range_deg range) RETURNS postgis.geography
751 13799 aaronmk
    LANGUAGE sql IMMUTABLE
752
    AS $_$
753 13887 aaronmk
SELECT util.bounding_box__no_dateline($1, $2)::postgis.geography
754 13799 aaronmk
$_$;
755
756
757
--
758 13804 aaronmk
-- Name: FUNCTION bounding_box(latitude_range_deg range, longitude_range_deg range); Type: COMMENT; Schema: util; Owner: -
759 13801 aaronmk
--
760
761 13804 aaronmk
COMMENT ON FUNCTION bounding_box(latitude_range_deg range, longitude_range_deg range) IS '
762 13801 aaronmk
usage:
763
SET search_path = util; -- for ~ operator
764
SELECT util.bounding_box(lower_lat ~ upper_lat, lower_long ~ upper_long);
765 13816 aaronmk
766
**WARNING**: the geography type stores all edges as arcs of great circles,
767
resulting in the latitude lines bulging outward from the true bounding box.
768
this will create false positives above and below the bounding box.
769 13801 aaronmk
';
770
771
772
--
773 13886 aaronmk
-- Name: bounding_box__no_dateline(range, range); Type: FUNCTION; Schema: util; Owner: -
774
--
775
776
CREATE FUNCTION bounding_box__no_dateline(latitude_range_deg range, longitude_range_deg range) RETURNS postgis.geometry
777
    LANGUAGE sql IMMUTABLE
778
    AS $_$
779
/* don't use st_makebox2d() because it doesn't support geocoordinate wraparound
780
(it is not SRID-aware) */
781
SELECT postgis.st_makeenvelope(
782
  /*xmin=*/$2.lower, /*ymin=*/$1.lower
783
, /*xmax=*/$2.upper, /*ymax=*/$1.upper
784
, /*WGS84*/4326
785
)
786
$_$;
787
788
789
--
790
-- Name: FUNCTION bounding_box__no_dateline(latitude_range_deg range, longitude_range_deg range); Type: COMMENT; Schema: util; Owner: -
791
--
792
793
COMMENT ON FUNCTION bounding_box__no_dateline(latitude_range_deg range, longitude_range_deg range) IS '
794
the generated bounding box is more accurate than util.bounding_box() (latitude
795
lines will be straight), but geocoordinate wraparound is not supported
796
797
usage:
798
SET search_path = util; -- for ~ operator
799
SELECT util.bounding_box__no_dateline(lower_lat ~ upper_lat, lower_long ~ upper_long);
800
';
801
802
803
--
804 13134 aaronmk
-- Name: cast(text, anyelement); Type: FUNCTION; Schema: util; Owner: -
805
--
806
807
CREATE FUNCTION "cast"(value text, ret_type_null anyelement) RETURNS anyelement
808
    LANGUAGE plpgsql IMMUTABLE
809
    AS $$
810
/* must use LANGUAGE plpgsql because LANGUAGE sql does not assignment-cast the
811
return value, causing a type mismatch */
812
BEGIN
813
	-- will then be assignment-cast to return type via INOUT
814
	RETURN value::cstring;
815
END;
816
$$;
817
818
819
--
820
-- Name: FUNCTION "cast"(value text, ret_type_null anyelement); Type: COMMENT; Schema: util; Owner: -
821
--
822
823
COMMENT ON FUNCTION "cast"(value text, ret_type_null anyelement) IS '
824
allows casting to an arbitrary type without eval()
825
826
usage:
827
SELECT util.cast(''value'', NULL::integer);
828
829
note that there does *not* need to be a cast from text to the output type,
830
because an INOUT cast is used instead
831
(http://www.postgresql.org/docs/9.3/static/sql-createcast.html#AEN69507)
832
833
ret_type_null: NULL::ret_type
834
';
835
836
837
--
838 8183 aaronmk
-- Name: cluster_index(regclass); Type: FUNCTION; Schema: util; Owner: -
839 8104 aaronmk
--
840
841
CREATE FUNCTION cluster_index(table_ regclass) RETURNS regclass
842 12446 aaronmk
    LANGUAGE sql STABLE
843 8104 aaronmk
    AS $_$
844
SELECT indexrelid FROM pg_index WHERE indrelid = $1 AND indisclustered
845
$_$;
846
847
848
--
849 8183 aaronmk
-- Name: cluster_once(regclass, regclass); Type: FUNCTION; Schema: util; Owner: -
850 8105 aaronmk
--
851
852
CREATE FUNCTION cluster_once(table_ regclass, index regclass) RETURNS void
853
    LANGUAGE plpgsql STRICT
854
    AS $_$
855
BEGIN
856
    -- not yet clustered (ARRAY[] compares NULLs literally)
857 8183 aaronmk
    IF ARRAY[util.cluster_index(table_)] != ARRAY[index] THEN
858 8105 aaronmk
        EXECUTE $$CLUSTER $$||table_||$$ USING $$||index;
859
    END IF;
860
END;
861
$_$;
862
863
864
--
865 8183 aaronmk
-- Name: FUNCTION cluster_once(table_ regclass, index regclass); Type: COMMENT; Schema: util; Owner: -
866 8105 aaronmk
--
867
868 12235 aaronmk
COMMENT ON FUNCTION cluster_once(table_ regclass, index regclass) IS '
869
idempotent
870
';
871 8105 aaronmk
872
873
--
874 12683 aaronmk
-- Name: coalesce(anyarray); Type: FUNCTION; Schema: util; Owner: -
875
--
876
877
CREATE FUNCTION "coalesce"(VARIADIC values_ anyarray) RETURNS anyelement
878
    LANGUAGE sql IMMUTABLE
879
    AS $_$
880
SELECT value
881
FROM unnest($1) value
882
WHERE value IS NOT NULL
883
LIMIT 1
884
$_$;
885
886
887
--
888
-- Name: FUNCTION "coalesce"(VARIADIC values_ anyarray); Type: COMMENT; Schema: util; Owner: -
889
--
890
891
COMMENT ON FUNCTION "coalesce"(VARIADIC values_ anyarray) IS '
892
uses:
893
* coalescing array elements or rows together
894
* forcing evaluation of all values of a COALESCE()
895
';
896
897
898
--
899 10986 aaronmk
-- Name: col__min(col_ref); Type: FUNCTION; Schema: util; Owner: -
900
--
901
902
CREATE FUNCTION col__min(col col_ref) RETURNS integer
903
    LANGUAGE sql STABLE
904
    AS $_$
905
SELECT util.eval2val($$
906
SELECT $$||quote_ident($1.name)||$$
907
FROM $$||$1.table_||$$
908
ORDER BY $$||quote_ident($1.name)||$$ ASC
909
LIMIT 1
910
$$, NULL::integer)
911
$_$;
912
913
914
--
915 10136 aaronmk
-- Name: col_comment(col_ref); Type: FUNCTION; Schema: util; Owner: -
916
--
917
918
CREATE FUNCTION col_comment(col col_ref) RETURNS text
919
    LANGUAGE plpgsql STABLE STRICT
920
    AS $$
921
DECLARE
922
	comment text;
923
BEGIN
924
	SELECT description
925
	FROM pg_attribute
926
	LEFT JOIN pg_description ON objoid = attrelid
927
		AND classoid = 'pg_class'::regclass AND objsubid = attnum
928
	WHERE attrelid = col.table_ AND attname = col.name
929
	INTO STRICT comment
930
	;
931
	RETURN comment;
932
EXCEPTION
933
	WHEN no_data_found THEN PERFORM util.raise_undefined_column(col);
934
END;
935
$$;
936
937
938
--
939 10130 aaronmk
-- Name: col_default_sql(col_ref); Type: FUNCTION; Schema: util; Owner: -
940
--
941
942
CREATE FUNCTION col_default_sql(col col_ref) RETURNS text
943
    LANGUAGE plpgsql STABLE STRICT
944
    AS $$
945
DECLARE
946
	default_sql text;
947
BEGIN
948
	SELECT adsrc
949
	FROM pg_attribute
950
	LEFT JOIN pg_attrdef ON adrelid = attrelid AND adnum = attnum
951
	WHERE attrelid = col.table_ AND attname = col.name
952
	INTO STRICT default_sql
953
	;
954
	RETURN default_sql;
955
EXCEPTION
956
	WHEN no_data_found THEN PERFORM util.raise_undefined_column(col);
957
END;
958
$$;
959
960
961
--
962 10134 aaronmk
-- Name: col_default_value(col_ref, anyelement); Type: FUNCTION; Schema: util; Owner: -
963
--
964
965
CREATE FUNCTION col_default_value(col col_ref, ret_type_null anyelement DEFAULT NULL::text) RETURNS anyelement
966
    LANGUAGE sql STABLE
967
    AS $_$
968
SELECT util.eval_expr_passthru(util.col_default_sql($1), $2)
969
$_$;
970
971
972
--
973
-- Name: FUNCTION col_default_value(col col_ref, ret_type_null anyelement); Type: COMMENT; Schema: util; Owner: -
974
--
975
976 12235 aaronmk
COMMENT ON FUNCTION col_default_value(col col_ref, ret_type_null anyelement) IS '
977
ret_type_null: NULL::ret_type
978
';
979 10134 aaronmk
980
981
--
982 8183 aaronmk
-- Name: col_exists(col_ref); Type: FUNCTION; Schema: util; Owner: -
983 8180 aaronmk
--
984
985
CREATE FUNCTION col_exists(col col_ref) RETURNS boolean
986
    LANGUAGE plpgsql STRICT
987
    AS $$
988
BEGIN
989 8183 aaronmk
    PERFORM util.col_type(col);
990 8180 aaronmk
    RETURN true;
991
EXCEPTION
992
    WHEN undefined_column THEN RETURN false;
993
END;
994
$$;
995
996
997
--
998 8183 aaronmk
-- Name: col_global_names(regtype); Type: FUNCTION; Schema: util; Owner: -
999 8084 aaronmk
--
1000
1001
CREATE FUNCTION col_global_names(type regtype, OUT name text, OUT global_name text) RETURNS SETOF record
1002 8097 aaronmk
    LANGUAGE plpgsql STABLE STRICT
1003 8084 aaronmk
    AS $$
1004
DECLARE
1005 8183 aaronmk
    prefix text := util.name(type)||'.';
1006 8084 aaronmk
BEGIN
1007
    RETURN QUERY
1008 8183 aaronmk
        SELECT name_, (CASE WHEN util.contains(search_for:='.', in_str:=name_) THEN '' ELSE prefix END)||name_
1009
        FROM util.col_names(type) f (name_);
1010 8084 aaronmk
END;
1011
$$;
1012
1013
1014
--
1015 8183 aaronmk
-- Name: col_names(regclass); Type: FUNCTION; Schema: util; Owner: -
1016 8151 aaronmk
--
1017
1018
CREATE FUNCTION col_names(table_ regclass) RETURNS SETOF text
1019 12446 aaronmk
    LANGUAGE sql STABLE
1020 8151 aaronmk
    AS $_$
1021
SELECT attname::text
1022
FROM pg_attribute
1023 10158 aaronmk
WHERE attrelid = $1 AND attnum >= 1 AND NOT attisdropped
1024 8151 aaronmk
ORDER BY attnum
1025
$_$;
1026
1027
1028
--
1029 11667 aaronmk
-- Name: col_names(regtype); Type: FUNCTION; Schema: util; Owner: -
1030
--
1031
1032
CREATE FUNCTION col_names(type regtype) RETURNS SETOF text
1033
    LANGUAGE plpgsql STABLE STRICT
1034
    AS $_$
1035
BEGIN
1036
    RETURN QUERY EXECUTE $$SELECT skeys(hstore(NULL::$$||type||$$))$$;
1037
END;
1038
$_$;
1039
1040
1041
--
1042 8183 aaronmk
-- Name: col_type(col_ref); Type: FUNCTION; Schema: util; Owner: -
1043 8106 aaronmk
--
1044
1045
CREATE FUNCTION col_type(col col_ref) RETURNS regtype
1046 8169 aaronmk
    LANGUAGE plpgsql STABLE STRICT
1047
    AS $$
1048
DECLARE
1049
    type regtype;
1050
BEGIN
1051
    SELECT atttypid FROM pg_attribute
1052
    WHERE attrelid = col.table_ AND attname = col.name
1053
    INTO STRICT type
1054
    ;
1055
    RETURN type;
1056
EXCEPTION
1057 8171 aaronmk
    WHEN no_data_found THEN
1058 8181 aaronmk
        RAISE undefined_column USING MESSAGE =
1059
            concat('undefined column: ', col.name);
1060 8169 aaronmk
END;
1061
$$;
1062 8106 aaronmk
1063
1064
--
1065 12368 aaronmk
-- Name: comment(oid); Type: FUNCTION; Schema: util; Owner: -
1066
--
1067
1068
CREATE FUNCTION comment(element oid) RETURNS text
1069 12446 aaronmk
    LANGUAGE sql STABLE
1070 12368 aaronmk
    AS $_$
1071
SELECT description FROM pg_description WHERE objoid = $1
1072
$_$;
1073
1074
1075
--
1076 11005 aaronmk
-- Name: concat_esc(text, text); Type: FUNCTION; Schema: util; Owner: -
1077
--
1078
1079
CREATE FUNCTION concat_esc("left" text, "right" text) RETURNS text
1080
    LANGUAGE sql IMMUTABLE
1081
    AS $_$
1082
SELECT util.esc_name__append($2, $1)
1083
$_$;
1084
1085
1086
--
1087 13895 aaronmk
-- Name: contained_within__no_dateline(postgis.geometry, postgis.geometry); Type: FUNCTION; Schema: util; Owner: -
1088
--
1089
1090
CREATE FUNCTION contained_within__no_dateline("inner" postgis.geometry, "outer" postgis.geometry) RETURNS boolean
1091
    LANGUAGE sql IMMUTABLE
1092
    SET search_path TO postgis
1093
    AS $_$
1094
/* search_path: st_coveredby() needs postgis to be in the search_path */
1095
/* must be st_coveredby() rather than st_within() to avoid unexpected behavior
1096
at the shape border */
1097
SELECT postgis.st_coveredby($1, $2)
1098
$_$;
1099
1100
1101
--
1102
-- Name: FUNCTION contained_within__no_dateline("inner" postgis.geometry, "outer" postgis.geometry); Type: COMMENT; Schema: util; Owner: -
1103
--
1104
1105
COMMENT ON FUNCTION contained_within__no_dateline("inner" postgis.geometry, "outer" postgis.geometry) IS '
1106
**WARNING**: this will not work on shapes that cross the date line, as the
1107
geometry type does not support geocoordinate wraparound
1108
';
1109
1110
1111
--
1112 13905 aaronmk
-- Name: contained_within__no_dateline(geocoord, postgis.geometry); Type: FUNCTION; Schema: util; Owner: -
1113
--
1114
1115
CREATE FUNCTION contained_within__no_dateline(point geocoord, region postgis.geometry) RETURNS boolean
1116
    LANGUAGE sql IMMUTABLE
1117
    AS $_$
1118
SELECT util.contained_within__no_dateline(util.geometry($1), $2)
1119
$_$;
1120
1121
1122
--
1123
-- Name: FUNCTION contained_within__no_dateline(point geocoord, region postgis.geometry); Type: COMMENT; Schema: util; Owner: -
1124
--
1125
1126
COMMENT ON FUNCTION contained_within__no_dateline(point geocoord, region postgis.geometry) IS '
1127
defining this in addition to contained_within_approx(geometry, geometry) enables
1128
specifying just `(lat, long)` without the ::util.geocoord type specifier
1129
';
1130
1131
1132
--
1133 13894 aaronmk
-- Name: contained_within_approx(postgis.geography, postgis.geography); Type: FUNCTION; Schema: util; Owner: -
1134 13822 aaronmk
--
1135
1136 13894 aaronmk
CREATE FUNCTION contained_within_approx("inner" postgis.geography, "outer" postgis.geography) RETURNS boolean
1137 13822 aaronmk
    LANGUAGE sql IMMUTABLE
1138
    SET search_path TO postgis
1139
    AS $_$
1140
/* search_path: st_coveredby() needs postgis to be in the search_path */
1141
SELECT postgis.st_coveredby($1, $2)
1142
$_$;
1143
1144
1145
--
1146 13894 aaronmk
-- Name: FUNCTION contained_within_approx("inner" postgis.geography, "outer" postgis.geography); Type: COMMENT; Schema: util; Owner: -
1147
--
1148
1149
COMMENT ON FUNCTION contained_within_approx("inner" postgis.geography, "outer" postgis.geography) IS '
1150
**WARNING**: the geography type stores all edges as arcs of great circles,
1151
resulting in the latitude lines of bounding boxes bulging outward from the true
1152
bounding box. this will create false positives above and below the bounding box.
1153
';
1154
1155
1156
--
1157 13898 aaronmk
-- Name: contained_within_approx(geocoord, postgis.geography); Type: FUNCTION; Schema: util; Owner: -
1158
--
1159
1160
CREATE FUNCTION contained_within_approx(point geocoord, region postgis.geography) RETURNS boolean
1161
    LANGUAGE sql IMMUTABLE
1162
    AS $_$
1163
SELECT util.contained_within_approx(util.geometry($1), $2)
1164
$_$;
1165
1166
1167
--
1168
-- Name: FUNCTION contained_within_approx(point geocoord, region postgis.geography); Type: COMMENT; Schema: util; Owner: -
1169
--
1170
1171
COMMENT ON FUNCTION contained_within_approx(point geocoord, region postgis.geography) IS '
1172
defining this in addition to contained_within_approx(geography, geography)
1173
enables specifying just `(lat, long)` without the ::util.geocoord type specifier
1174
';
1175
1176
1177
--
1178 8183 aaronmk
-- Name: contains(text, text); Type: FUNCTION; Schema: util; Owner: -
1179 8095 aaronmk
--
1180
1181
CREATE FUNCTION contains(search_for text, in_str text) RETURNS boolean
1182 10388 aaronmk
    LANGUAGE sql IMMUTABLE
1183 8095 aaronmk
    AS $_$
1184
SELECT position($1 in $2) > 0 /*1-based offset*/
1185
$_$;
1186
1187
1188
--
1189 13599 aaronmk
-- Name: copy(regclass, text); Type: FUNCTION; Schema: util; Owner: -
1190
--
1191
1192
CREATE FUNCTION copy(from_ regclass, to_ text) RETURNS void
1193
    LANGUAGE sql
1194
    AS $_$
1195
SELECT util.copy_struct($1, $2);
1196
SELECT util.copy_data($1, $2);
1197
$_$;
1198
1199
1200
--
1201 13598 aaronmk
-- Name: copy_data(regclass, regclass); Type: FUNCTION; Schema: util; Owner: -
1202
--
1203
1204
CREATE FUNCTION copy_data(from_ regclass, to_ regclass) RETURNS void
1205
    LANGUAGE sql
1206
    AS $_$
1207
SELECT util.eval($$INSERT INTO $$||$2||$$ SELECT * FROM $$||$1)
1208
$_$;
1209
1210
1211
--
1212 12288 aaronmk
-- Name: copy_struct(regclass, text); Type: FUNCTION; Schema: util; Owner: -
1213
--
1214
1215
CREATE FUNCTION copy_struct(from_ regclass, to_ text) RETURNS void
1216
    LANGUAGE sql
1217
    AS $_$
1218
SELECT util.eval($$CREATE TABLE $$||$2||$$ (LIKE $$||$1||$$ INCLUDING ALL)$$)
1219
$_$;
1220
1221
1222
--
1223 12649 aaronmk
-- Name: copy_types_and_data(regclass, text); Type: FUNCTION; Schema: util; Owner: -
1224
--
1225
1226
CREATE FUNCTION copy_types_and_data(from_ regclass, to_ text) RETURNS void
1227
    LANGUAGE sql
1228
    AS $_$
1229
SELECT util.materialize_view($2, $1)
1230
$_$;
1231
1232
1233
--
1234 13495 aaronmk
-- Name: create_if_not_exists(text, text); Type: FUNCTION; Schema: util; Owner: -
1235 8094 aaronmk
--
1236
1237 13495 aaronmk
CREATE FUNCTION create_if_not_exists(sql text, relation text DEFAULT NULL::text) RETURNS void
1238
    LANGUAGE plpgsql
1239 8094 aaronmk
    AS $$
1240
BEGIN
1241 13495 aaronmk
	/* always generate standard exception if exists, even if table definition
1242
	would be invalid (which generates a variety of exceptions) */
1243 13529 aaronmk
	IF util.relation_exists(relation) THEN
1244
		PERFORM util.raise('NOTICE', relation||' already exists, skipping');
1245
		RAISE duplicate_table;
1246
	END IF;
1247 12595 aaronmk
	PERFORM util.eval(sql);
1248 8094 aaronmk
EXCEPTION
1249 12676 aaronmk
WHEN   duplicate_table
1250
	OR duplicate_object -- eg. constraint
1251
	OR duplicate_column
1252
	OR duplicate_function
1253
THEN NULL;
1254 12595 aaronmk
WHEN invalid_table_definition THEN
1255
	IF SQLERRM LIKE 'multiple primary keys for table % are not allowed' THEN NULL;
1256
	ELSE RAISE;
1257
	END IF;
1258 8094 aaronmk
END;
1259
$$;
1260
1261
1262
--
1263 13495 aaronmk
-- Name: FUNCTION create_if_not_exists(sql text, relation text); Type: COMMENT; Schema: util; Owner: -
1264 8094 aaronmk
--
1265
1266 13495 aaronmk
COMMENT ON FUNCTION create_if_not_exists(sql text, relation text) IS '
1267 12235 aaronmk
idempotent
1268
';
1269 8094 aaronmk
1270
1271
--
1272 12378 aaronmk
-- Name: curr_func(text, anyelement); Type: FUNCTION; Schema: util; Owner: -
1273
--
1274
1275
CREATE FUNCTION curr_func(func text, schema_anchor anyelement) RETURNS text
1276 12590 aaronmk
    LANGUAGE sql STABLE
1277 12378 aaronmk
    AS $$
1278
SELECT util.schema_esc(schema_anchor)||'.'||quote_ident(func)
1279
$$;
1280
1281
1282
--
1283 12668 aaronmk
-- Name: debug_print_func_call(text); Type: FUNCTION; Schema: util; Owner: -
1284
--
1285
1286
CREATE FUNCTION debug_print_func_call(func_call text) RETURNS void
1287
    LANGUAGE sql IMMUTABLE
1288
    AS $_$
1289
SELECT util.raise('NOTICE', $$SELECT $$||$1)
1290
$_$;
1291
1292
1293
--
1294 12433 aaronmk
-- Name: debug_print_return_value(anyelement, boolean); Type: FUNCTION; Schema: util; Owner: -
1295 12430 aaronmk
--
1296
1297 12433 aaronmk
CREATE FUNCTION debug_print_return_value(value anyelement, encode boolean DEFAULT false) RETURNS anyelement
1298 12430 aaronmk
    LANGUAGE sql IMMUTABLE
1299
    AS $_$
1300 13447 aaronmk
SELECT util.debug_print_value('returns: ', $1, $2);
1301 12430 aaronmk
SELECT $1;
1302
$_$;
1303
1304
1305
--
1306 12250 aaronmk
-- Name: debug_print_sql(text); Type: FUNCTION; Schema: util; Owner: -
1307
--
1308
1309
CREATE FUNCTION debug_print_sql(sql text) RETURNS void
1310
    LANGUAGE sql IMMUTABLE
1311
    AS $_$
1312
/* newline before so the query starts at the beginning of the line.
1313
newline after to visually separate queries from one another. */
1314 12534 aaronmk
SELECT util.raise('NOTICE', $$
1315 12474 aaronmk
$$||util.runnable_sql($1)||$$
1316 12464 aaronmk
$$||COALESCE(util.explain2notice_msg_if_can($1), ''))
1317 12250 aaronmk
$_$;
1318
1319
1320
--
1321 13446 aaronmk
-- Name: debug_print_value(text, anyelement, boolean); Type: FUNCTION; Schema: util; Owner: -
1322
--
1323
1324
CREATE FUNCTION debug_print_value(label text, value anyelement, encode boolean DEFAULT false) RETURNS void
1325
    LANGUAGE sql IMMUTABLE
1326
    AS $_$
1327
SELECT util.raise('NOTICE', concat($1,
1328 13449 aaronmk
(CASE WHEN $3 THEN util.quote_typed($2) ELSE $2::text END))||$$
1329
$$)
1330 13446 aaronmk
$_$;
1331
1332
1333
--
1334 13448 aaronmk
-- Name: debug_print_var(text, anyelement, boolean); Type: FUNCTION; Schema: util; Owner: -
1335
--
1336
1337
CREATE FUNCTION debug_print_var(var text, value anyelement, encode boolean DEFAULT false) RETURNS void
1338
    LANGUAGE sql IMMUTABLE
1339
    AS $_$
1340
/* can't use EXECUTE in the caller because "No substitution of PL/pgSQL
1341
variables is done on the computed command string"
1342
(http://www.postgresql.org/docs/9.3/static/plpgsql-statements.html#PLPGSQL-STATEMENTS-EXECUTING-DYN) */
1343
SELECT util.debug_print_value($1||' = ', $2, $3)
1344
$_$;
1345
1346
1347
--
1348 10364 aaronmk
-- Name: derived_cols(regclass, regclass); Type: FUNCTION; Schema: util; Owner: -
1349
--
1350
1351
CREATE FUNCTION derived_cols(table_ regclass, names regclass) RETURNS SETOF text
1352 12446 aaronmk
    LANGUAGE sql STABLE
1353 10364 aaronmk
    AS $_$
1354
SELECT util.eval2set($$
1355
SELECT col
1356
FROM util.col_names($$||quote_nullable($1)||$$::regclass) f (col)
1357
LEFT JOIN $$||$2||$$ ON "to" = col
1358
WHERE "from" IS NULL
1359
$$, NULL::text)
1360
$_$;
1361
1362
1363
--
1364
-- Name: FUNCTION derived_cols(table_ regclass, names regclass); Type: COMMENT; Schema: util; Owner: -
1365
--
1366
1367 12235 aaronmk
COMMENT ON FUNCTION derived_cols(table_ regclass, names regclass) IS '
1368
gets table_''s derived columns (all the columns not in the names table)
1369
';
1370 10364 aaronmk
1371
1372
--
1373 12298 aaronmk
-- Name: diff(regclass, regclass, anyelement); Type: FUNCTION; Schema: util; Owner: -
1374 12044 aaronmk
--
1375
1376 12298 aaronmk
CREATE FUNCTION diff(left_table regclass, right_table regclass, col_type_null anyelement, OUT left_ anyelement, OUT right_ anyelement) RETURNS SETOF record
1377 12427 aaronmk
    LANGUAGE sql
1378 12044 aaronmk
    AS $_$
1379 12653 aaronmk
-- create a diff when the # of copies of a row differs between the tables
1380
SELECT util.to_freq($1);
1381
SELECT util.to_freq($2);
1382 12663 aaronmk
SELECT util.auto_rm_freq(ARRAY[$1, $2]);
1383 12653 aaronmk
1384
SELECT * FROM util.diff($1, $2, $3, has_freq := true)
1385 12298 aaronmk
$_$;
1386
1387
1388
--
1389
-- Name: FUNCTION diff(left_table regclass, right_table regclass, col_type_null anyelement, OUT left_ anyelement, OUT right_ anyelement); Type: COMMENT; Schema: util; Owner: -
1390
--
1391
1392
COMMENT ON FUNCTION diff(left_table regclass, right_table regclass, col_type_null anyelement, OUT left_ anyelement, OUT right_ anyelement) IS '
1393
usage:
1394
SELECT * FROM util.diff(''"left_table"''::regclass, ''"right_table"''::regclass, NULL::shared_base_type)
1395 12653 aaronmk
1396
col_type_null (*required*): NULL::shared_base_type
1397 12298 aaronmk
';
1398
1399
1400
--
1401 12491 aaronmk
-- Name: diff(text, text, anyelement, boolean); Type: FUNCTION; Schema: util; Owner: -
1402 12298 aaronmk
--
1403
1404 12491 aaronmk
CREATE FUNCTION diff(left__ text, right__ text, col_type_null anyelement, single_row boolean DEFAULT false, OUT left_ anyelement, OUT right_ anyelement) RETURNS SETOF record
1405 12429 aaronmk
    LANGUAGE plpgsql
1406
    SET search_path TO pg_temp
1407 12298 aaronmk
    AS $_$
1408 12429 aaronmk
/* must use LANGUAGE plpgsql because LANGUAGE sql does not support runtime
1409
changes of search_path (schema elements are bound at inline time rather than
1410
runtime) */
1411
/* function option search_path is needed to limit the effects of
1412 12492 aaronmk
`SET LOCAL search_path` to the current function */
1413 12429 aaronmk
BEGIN
1414 12491 aaronmk
	PERFORM util.use_schema($3); -- includes util.%== as default/fallback
1415 12429 aaronmk
1416 12565 aaronmk
	PERFORM util.mk_keys_func(pg_typeof($3));
1417 12429 aaronmk
	RETURN QUERY
1418 12554 aaronmk
		SELECT * FROM util.eval2col_pair(util.mk_diff_query($1, $2,
1419 12479 aaronmk
$$/* need to explicitly cast each side to the return type because this does not
1420 12284 aaronmk
happen automatically even when an implicit cast is available */
1421 12479 aaronmk
  left_::$$||util.typeof($3)||$$
1422
, right_::$$||util.typeof($3)
1423 12496 aaronmk
/* when using the util.%==(anyelement, anyelement) operator, you must cast to
1424
the *same* base type, *even though* this is optional when using a custom %== */
1425 12553 aaronmk
, util._if($4, $$true/*= CROSS JOIN*/$$,
1426
$$ left_::$$||util.typeof($3)||$$
1427 12496 aaronmk
%== right_::$$||util.typeof($3)||$$
1428
	-- refer to EXPLAIN output for expansion of %==$$
1429 12657 aaronmk
)
1430
,     $$         left_::$$||util.typeof($3)||$$
1431
IS DISTINCT FROM right_::$$||util.typeof($3)
1432
), $3)
1433 12429 aaronmk
	;
1434
END;
1435 12044 aaronmk
$_$;
1436
1437
1438
--
1439 12491 aaronmk
-- Name: FUNCTION diff(left__ text, right__ text, col_type_null anyelement, single_row boolean, OUT left_ anyelement, OUT right_ anyelement); Type: COMMENT; Schema: util; Owner: -
1440 12280 aaronmk
--
1441
1442 12491 aaronmk
COMMENT ON FUNCTION diff(left__ text, right__ text, col_type_null anyelement, single_row boolean, OUT left_ anyelement, OUT right_ anyelement) IS '
1443 12280 aaronmk
col_type_null (*required*): NULL::col_type
1444 12299 aaronmk
single_row: whether the tables consist of a single row, which should be
1445
	displayed side-by-side
1446 12282 aaronmk
1447 12498 aaronmk
to match up rows using a subset of the columns, create a custom keys() function
1448
which returns this subset as a record:
1449
-- note that OUT parameters for the returned fields are *not* needed
1450
CREATE OR REPLACE FUNCTION [schema].keys(value [schema].[base_type])
1451
  RETURNS record AS
1452
$BODY$
1453
SELECT ($1.key_field_0, $1.key_field_1)
1454
$BODY$
1455
  LANGUAGE sql IMMUTABLE
1456
  COST 100;
1457
1458
1459 12282 aaronmk
to run EXPLAIN on the FULL JOIN query:
1460
# run this function
1461
# look for a NOTICE containing the expanded query that it ran
1462
# run EXPLAIN on this expanded query
1463 12280 aaronmk
';
1464
1465
1466
--
1467 12653 aaronmk
-- Name: diff(regclass, regclass, anyelement, boolean); Type: FUNCTION; Schema: util; Owner: -
1468
--
1469
1470
CREATE FUNCTION diff(left_table regclass, right_table regclass, col_type_null anyelement, has_freq boolean, OUT left_ anyelement, OUT right_ anyelement) RETURNS SETOF record
1471
    LANGUAGE sql
1472
    AS $_$
1473
SELECT * FROM util.diff($1::text, $2::text, $3,
1474
	single_row := util.has_single_row($1) AND util.has_single_row($2))
1475
$_$;
1476
1477
1478
--
1479
-- Name: FUNCTION diff(left_table regclass, right_table regclass, col_type_null anyelement, has_freq boolean, OUT left_ anyelement, OUT right_ anyelement); Type: COMMENT; Schema: util; Owner: -
1480
--
1481
1482
COMMENT ON FUNCTION diff(left_table regclass, right_table regclass, col_type_null anyelement, has_freq boolean, OUT left_ anyelement, OUT right_ anyelement) IS '
1483
helper function used by diff(regclass, regclass)
1484
1485
usage:
1486
SELECT * FROM util.diff(''"left_freq_table"''::regclass, ''"right_freq_table"''::regclass, NULL::shared_base_type, has_freq := true)
1487
1488
col_type_null (*required*): NULL::shared_base_type
1489
';
1490
1491
1492
--
1493 8200 aaronmk
-- Name: do_optionally_ignore(text, boolean); Type: FUNCTION; Schema: util; Owner: -
1494
--
1495
1496
CREATE FUNCTION do_optionally_ignore(sql text, ignore boolean) RETURNS void
1497 12446 aaronmk
    LANGUAGE sql
1498 8200 aaronmk
    AS $_$
1499
SELECT CASE WHEN $2 THEN util.try_create($1) ELSE util.create_if_not_exists($1) END
1500
$_$;
1501
1502
1503
--
1504
-- Name: FUNCTION do_optionally_ignore(sql text, ignore boolean); Type: COMMENT; Schema: util; Owner: -
1505
--
1506
1507 12235 aaronmk
COMMENT ON FUNCTION do_optionally_ignore(sql text, ignore boolean) IS '
1508
idempotent
1509
';
1510 8200 aaronmk
1511
1512
--
1513 12292 aaronmk
-- Name: drop_column(col_ref, boolean); Type: FUNCTION; Schema: util; Owner: -
1514 10362 aaronmk
--
1515
1516 12292 aaronmk
CREATE FUNCTION drop_column(col col_ref, force boolean DEFAULT false) RETURNS void
1517 12446 aaronmk
    LANGUAGE sql
1518 10362 aaronmk
    AS $_$
1519
SELECT util.eval($$ALTER TABLE $$||$1.table_||$$ DROP COLUMN IF EXISTS $$||
1520 12292 aaronmk
quote_ident($1.name)||util._if($2, $$ CASCADE$$, ''::text))
1521 10362 aaronmk
$_$;
1522
1523
1524
--
1525 12292 aaronmk
-- Name: FUNCTION drop_column(col col_ref, force boolean); Type: COMMENT; Schema: util; Owner: -
1526 10362 aaronmk
--
1527
1528 12292 aaronmk
COMMENT ON FUNCTION drop_column(col col_ref, force boolean) IS '
1529 12235 aaronmk
idempotent
1530
';
1531 10362 aaronmk
1532
1533
--
1534 12660 aaronmk
-- Name: drop_column(regclass[], text, boolean); Type: FUNCTION; Schema: util; Owner: -
1535
--
1536
1537
CREATE FUNCTION drop_column(tables regclass[], col text, force boolean DEFAULT false) RETURNS void
1538
    LANGUAGE sql
1539
    AS $_$
1540 12686 aaronmk
SELECT util.drop_column((table_, $2), $3) FROM unnest($1) table_;
1541
SELECT NULL::void; -- don't fold away functions called in previous query
1542 12660 aaronmk
$_$;
1543
1544
1545
--
1546
-- Name: FUNCTION drop_column(tables regclass[], col text, force boolean); Type: COMMENT; Schema: util; Owner: -
1547
--
1548
1549
COMMENT ON FUNCTION drop_column(tables regclass[], col text, force boolean) IS '
1550
idempotent
1551
';
1552
1553
1554
--
1555 12587 aaronmk
-- Name: drop_relation(anyelement, boolean); Type: FUNCTION; Schema: util; Owner: -
1556 12331 aaronmk
--
1557
1558 12587 aaronmk
CREATE FUNCTION drop_relation(relation anyelement, force boolean DEFAULT false) RETURNS void
1559 12331 aaronmk
    LANGUAGE sql
1560
    AS $_$
1561 12353 aaronmk
/* use util.qual_name() instead of ::text so that the schema qualifier is always
1562
included in the debug SQL */
1563
SELECT util.drop_relation(util.relation_type($1), util.qual_name($1), $2)
1564 12331 aaronmk
$_$;
1565
1566
1567
--
1568 12343 aaronmk
-- Name: drop_relation(text, text, boolean); Type: FUNCTION; Schema: util; Owner: -
1569
--
1570
1571 12364 aaronmk
CREATE FUNCTION drop_relation(type text, relation_esc text, force boolean DEFAULT false) RETURNS void
1572 12343 aaronmk
    LANGUAGE sql
1573
    AS $_$
1574 12347 aaronmk
SELECT util.eval($$DROP $$||$1||$$ IF EXISTS $$||$2
1575 12343 aaronmk
||util._if($3, $$ CASCADE$$, ''::text))
1576
$_$;
1577
1578
1579
--
1580 12364 aaronmk
-- Name: FUNCTION drop_relation(type text, relation_esc text, force boolean); Type: COMMENT; Schema: util; Owner: -
1581 12343 aaronmk
--
1582
1583 12364 aaronmk
COMMENT ON FUNCTION drop_relation(type text, relation_esc text, force boolean) IS '
1584 12343 aaronmk
idempotent
1585
';
1586
1587
1588
--
1589 12413 aaronmk
-- Name: drop_relations_like(text, anyelement, boolean); Type: FUNCTION; Schema: util; Owner: -
1590
--
1591
1592
CREATE FUNCTION drop_relations_like(name_regexp text, schema_anchor anyelement, force boolean DEFAULT false) RETURNS void
1593
    LANGUAGE sql
1594
    AS $_$
1595 12502 aaronmk
SELECT util.drop_relations_like($1, util.schema_regexp($2), $3)
1596 12413 aaronmk
$_$;
1597
1598
1599
--
1600
-- Name: drop_relations_like(text, text, boolean); Type: FUNCTION; Schema: util; Owner: -
1601
--
1602
1603
CREATE FUNCTION drop_relations_like(name_regexp text, schema_regexp text DEFAULT ''::text, force boolean DEFAULT false) RETURNS void
1604
    LANGUAGE sql
1605
    AS $_$
1606 12668 aaronmk
SELECT util.debug_print_func_call(util.quote_func_call(
1607
'util.drop_relations_like', util.quote_typed($1), util.quote_typed($2),
1608
util.quote_typed($3)))
1609 12667 aaronmk
;
1610 12413 aaronmk
SELECT util.drop_relation(relation, $3)
1611
FROM util.show_relations_like($1, $2) relation
1612
;
1613
SELECT NULL::void; -- don't fold away functions called in previous query
1614
$_$;
1615
1616
1617
--
1618 12292 aaronmk
-- Name: drop_table(text, boolean); Type: FUNCTION; Schema: util; Owner: -
1619 10150 aaronmk
--
1620
1621 12292 aaronmk
CREATE FUNCTION drop_table(table_ text, force boolean DEFAULT false) RETURNS void
1622 12446 aaronmk
    LANGUAGE sql
1623 10150 aaronmk
    AS $_$
1624 12347 aaronmk
SELECT util.drop_relation('TABLE', $1, $2)
1625 10150 aaronmk
$_$;
1626
1627
1628
--
1629 12292 aaronmk
-- Name: FUNCTION drop_table(table_ text, force boolean); Type: COMMENT; Schema: util; Owner: -
1630 10150 aaronmk
--
1631
1632 12292 aaronmk
COMMENT ON FUNCTION drop_table(table_ text, force boolean) IS '
1633 12235 aaronmk
idempotent
1634
';
1635 10150 aaronmk
1636
1637
--
1638 12292 aaronmk
-- Name: drop_view(text, boolean); Type: FUNCTION; Schema: util; Owner: -
1639 12229 aaronmk
--
1640
1641 12292 aaronmk
CREATE FUNCTION drop_view(view_ text, force boolean DEFAULT false) RETURNS void
1642 12446 aaronmk
    LANGUAGE sql
1643 12229 aaronmk
    AS $_$
1644 12347 aaronmk
SELECT util.drop_relation('VIEW', $1, $2)
1645 12229 aaronmk
$_$;
1646
1647
1648
--
1649 12292 aaronmk
-- Name: FUNCTION drop_view(view_ text, force boolean); Type: COMMENT; Schema: util; Owner: -
1650 12229 aaronmk
--
1651
1652 12292 aaronmk
COMMENT ON FUNCTION drop_view(view_ text, force boolean) IS '
1653 12235 aaronmk
idempotent
1654
';
1655 12229 aaronmk
1656
1657
--
1658 10322 aaronmk
-- Name: empty_array(anyelement); Type: FUNCTION; Schema: util; Owner: -
1659
--
1660
1661
CREATE FUNCTION empty_array(elem_type_null anyelement DEFAULT NULL::text) RETURNS anyarray
1662
    LANGUAGE sql IMMUTABLE
1663
    AS $_$
1664
SELECT util.array_fill($1, 0)
1665
$_$;
1666
1667
1668
--
1669
-- Name: FUNCTION empty_array(elem_type_null anyelement); Type: COMMENT; Schema: util; Owner: -
1670
--
1671
1672 12235 aaronmk
COMMENT ON FUNCTION empty_array(elem_type_null anyelement) IS '
1673
constructs proper empty 1-dimensional array whose dimensions are not NULL ( ''{}''::text[] does not do this)
1674
';
1675 10322 aaronmk
1676
1677
--
1678 8183 aaronmk
-- Name: ensure_prefix(text, text); Type: FUNCTION; Schema: util; Owner: -
1679 8086 aaronmk
--
1680
1681
CREATE FUNCTION ensure_prefix(prefix text, str text) RETURNS text
1682 10388 aaronmk
    LANGUAGE sql IMMUTABLE
1683 8086 aaronmk
    AS $_$
1684 8183 aaronmk
SELECT (CASE WHEN util.has_prefix($1, $2) THEN $2 ELSE $1||$2 END)
1685 8086 aaronmk
$_$;
1686
1687
1688
--
1689 10987 aaronmk
-- Name: esc_name__append(text, text); Type: FUNCTION; Schema: util; Owner: -
1690
--
1691
1692
CREATE FUNCTION esc_name__append(suffix text, esc_name text) RETURNS text
1693
    LANGUAGE sql IMMUTABLE
1694
    AS $_$
1695
SELECT regexp_replace($2, '("?)$', $1||'\1')
1696
$_$;
1697
1698
1699
--
1700 13455 aaronmk
-- Name: eval(text[]); Type: FUNCTION; Schema: util; Owner: -
1701
--
1702
1703
CREATE FUNCTION eval(queries text[]) RETURNS void
1704
    LANGUAGE sql
1705
    AS $_$
1706
SELECT util.eval(query) FROM unnest($1) query;
1707
SELECT NULL::void; -- don't fold away functions called in previous query
1708
$_$;
1709
1710
1711
--
1712 12531 aaronmk
-- Name: eval(text, boolean); Type: FUNCTION; Schema: util; Owner: -
1713 9824 aaronmk
--
1714
1715 12531 aaronmk
CREATE FUNCTION eval(sql text, verbose_ boolean DEFAULT true) RETURNS void
1716 12558 aaronmk
    LANGUAGE plpgsql
1717 9824 aaronmk
    AS $$
1718
BEGIN
1719 13641 aaronmk
	sql = util.view_def_to_orig(sql); -- restore user's intent
1720 12531 aaronmk
	IF verbose_ THEN PERFORM util.debug_print_sql(sql); END IF;
1721 12251 aaronmk
	EXECUTE sql;
1722 9824 aaronmk
END;
1723
$$;
1724
1725
1726
--
1727 12181 aaronmk
-- Name: eval2col_pair(text, anyelement); Type: FUNCTION; Schema: util; Owner: -
1728
--
1729
1730
CREATE FUNCTION eval2col_pair(sql text, col_type_null anyelement, OUT left_ anyelement, OUT right_ anyelement) RETURNS SETOF record
1731
    LANGUAGE plpgsql
1732
    AS $$
1733
BEGIN
1734 12251 aaronmk
	PERFORM util.debug_print_sql(sql);
1735 12181 aaronmk
	RETURN QUERY EXECUTE sql;
1736
END;
1737
$$;
1738
1739
1740
--
1741
-- Name: FUNCTION eval2col_pair(sql text, col_type_null anyelement, OUT left_ anyelement, OUT right_ anyelement); Type: COMMENT; Schema: util; Owner: -
1742
--
1743
1744 12235 aaronmk
COMMENT ON FUNCTION eval2col_pair(sql text, col_type_null anyelement, OUT left_ anyelement, OUT right_ anyelement) IS '
1745
col_type_null (*required*): NULL::col_type
1746
';
1747 12181 aaronmk
1748
1749
--
1750 12301 aaronmk
-- Name: eval2records(text); Type: FUNCTION; Schema: util; Owner: -
1751
--
1752
1753
CREATE FUNCTION eval2records(sql text) RETURNS SETOF record
1754
    LANGUAGE plpgsql
1755
    AS $$
1756
BEGIN
1757
	PERFORM util.debug_print_sql(sql);
1758
	RETURN QUERY EXECUTE sql;
1759
END;
1760
$$;
1761
1762
1763
--
1764 12458 aaronmk
-- Name: eval2set(text, anyelement, boolean); Type: FUNCTION; Schema: util; Owner: -
1765 10363 aaronmk
--
1766
1767 12458 aaronmk
CREATE FUNCTION eval2set(sql text, ret_type_null anyelement DEFAULT NULL::text, verbose_ boolean DEFAULT true) RETURNS SETOF anyelement
1768 10363 aaronmk
    LANGUAGE plpgsql
1769
    AS $$
1770
BEGIN
1771 12458 aaronmk
	IF verbose_ THEN PERFORM util.debug_print_sql(sql); END IF;
1772 10363 aaronmk
	RETURN QUERY EXECUTE sql;
1773
END;
1774
$$;
1775
1776
1777
--
1778 10129 aaronmk
-- Name: eval2val(text, anyelement); Type: FUNCTION; Schema: util; Owner: -
1779 10128 aaronmk
--
1780
1781 10129 aaronmk
CREATE FUNCTION eval2val(sql text, ret_type_null anyelement DEFAULT NULL::text) RETURNS anyelement
1782 12514 aaronmk
    LANGUAGE plpgsql STABLE
1783 10128 aaronmk
    AS $$
1784
DECLARE
1785
	ret_val ret_type_null%TYPE;
1786
BEGIN
1787 12251 aaronmk
	PERFORM util.debug_print_sql(sql);
1788 10128 aaronmk
	EXECUTE sql INTO STRICT ret_val;
1789
	RETURN ret_val;
1790
END;
1791
$$;
1792
1793
1794
--
1795 10129 aaronmk
-- Name: FUNCTION eval2val(sql text, ret_type_null anyelement); Type: COMMENT; Schema: util; Owner: -
1796 10128 aaronmk
--
1797
1798 12235 aaronmk
COMMENT ON FUNCTION eval2val(sql text, ret_type_null anyelement) IS '
1799
ret_type_null: NULL::ret_type
1800
';
1801 10128 aaronmk
1802
1803
--
1804 10131 aaronmk
-- Name: eval_expr(text, anyelement); Type: FUNCTION; Schema: util; Owner: -
1805
--
1806
1807
CREATE FUNCTION eval_expr(sql text, ret_type_null anyelement DEFAULT NULL::text) RETURNS anyelement
1808
    LANGUAGE sql
1809
    AS $_$
1810 10132 aaronmk
SELECT util.eval2val($$SELECT $$||$1, $2)
1811 10131 aaronmk
$_$;
1812
1813
1814
--
1815
-- Name: FUNCTION eval_expr(sql text, ret_type_null anyelement); Type: COMMENT; Schema: util; Owner: -
1816
--
1817
1818 12235 aaronmk
COMMENT ON FUNCTION eval_expr(sql text, ret_type_null anyelement) IS '
1819
ret_type_null: NULL::ret_type
1820
';
1821 10131 aaronmk
1822
1823
--
1824 10133 aaronmk
-- Name: eval_expr_passthru(text, anyelement); Type: FUNCTION; Schema: util; Owner: -
1825
--
1826
1827
CREATE FUNCTION eval_expr_passthru(sql text, ret_type_null anyelement DEFAULT NULL::text) RETURNS anyelement
1828
    LANGUAGE sql
1829
    AS $_$
1830
SELECT CASE WHEN $1 IS NULL THEN NULL ELSE util.eval_expr($1, $2) END
1831
$_$;
1832
1833
1834
--
1835
-- Name: FUNCTION eval_expr_passthru(sql text, ret_type_null anyelement); Type: COMMENT; Schema: util; Owner: -
1836
--
1837
1838 12235 aaronmk
COMMENT ON FUNCTION eval_expr_passthru(sql text, ret_type_null anyelement) IS '
1839
sql: can be NULL, which will be passed through
1840
ret_type_null: NULL::ret_type
1841
';
1842 10133 aaronmk
1843
1844
--
1845 8183 aaronmk
-- Name: existing_cols(regclass, text[]); Type: FUNCTION; Schema: util; Owner: -
1846 8182 aaronmk
--
1847
1848
CREATE FUNCTION existing_cols(table_ regclass, VARIADIC col_names text[]) RETURNS SETOF text
1849 12446 aaronmk
    LANGUAGE sql STABLE
1850 8182 aaronmk
    AS $_$
1851
SELECT col_name
1852
FROM unnest($2) s (col_name)
1853 8183 aaronmk
WHERE util.col_exists(($1, col_name))
1854 8182 aaronmk
$_$;
1855
1856
1857
--
1858 11830 aaronmk
-- Name: explain(text); Type: FUNCTION; Schema: util; Owner: -
1859
--
1860
1861
CREATE FUNCTION explain(sql text) RETURNS SETOF text
1862
    LANGUAGE sql
1863 13496 aaronmk
    SET client_min_messages TO 'error'
1864 11830 aaronmk
    AS $_$
1865 13496 aaronmk
/* `client_min_messages = ERROR`: EXPLAIN apparently runs IMMUTABLE functions in
1866
the query, so this prevents displaying any log messages printed by them */
1867 12459 aaronmk
SELECT util.eval2set($$EXPLAIN $$||$1, verbose_ := false)
1868 11830 aaronmk
$_$;
1869
1870
1871
--
1872 11833 aaronmk
-- Name: explain2notice(text); Type: FUNCTION; Schema: util; Owner: -
1873
--
1874
1875
CREATE FUNCTION explain2notice(sql text) RETURNS void
1876 12449 aaronmk
    LANGUAGE sql
1877
    AS $_$
1878 12534 aaronmk
SELECT util.raise('NOTICE', util.explain2notice_msg($1))
1879 12449 aaronmk
$_$;
1880 12448 aaronmk
1881
1882
--
1883
-- Name: explain2notice_msg(text); Type: FUNCTION; Schema: util; Owner: -
1884
--
1885
1886
CREATE FUNCTION explain2notice_msg(sql text) RETURNS text
1887
    LANGUAGE sql
1888
    AS $_$
1889 12464 aaronmk
-- newline before and after to visually separate it from other debug info
1890 12756 aaronmk
SELECT COALESCE($$
1891 12464 aaronmk
EXPLAIN:
1892 12756 aaronmk
$$||util.fold_explain_msg(util.explain2str($1))||$$
1893
$$, '')
1894 11833 aaronmk
$_$;
1895
1896
1897
--
1898 12452 aaronmk
-- Name: explain2notice_msg_if_can(text); Type: FUNCTION; Schema: util; Owner: -
1899
--
1900
1901
CREATE FUNCTION explain2notice_msg_if_can(sql text) RETURNS text
1902 13403 aaronmk
    LANGUAGE plpgsql
1903
    AS $$
1904
BEGIN
1905
	RETURN util.explain2notice_msg(sql);
1906
EXCEPTION
1907 13601 aaronmk
WHEN   syntax_error
1908
	OR invalid_cursor_definition -- "cannot open multi-query plan as cursor"
1909
	THEN RETURN NULL; -- non-explainable query
1910 13403 aaronmk
	/* don't use util.is_explainable() because the list provided by Postgres
1911
	(http://www.postgresql.org/docs/9.3/static/sql-explain.html#AEN77691)
1912
	excludes some query types that are in fact EXPLAIN-able */
1913
END;
1914
$$;
1915 12452 aaronmk
1916
1917
--
1918 11832 aaronmk
-- Name: explain2str(text); Type: FUNCTION; Schema: util; Owner: -
1919
--
1920
1921
CREATE FUNCTION explain2str(sql text) RETURNS text
1922
    LANGUAGE sql
1923
    AS $_$
1924
SELECT util.join_strs(explain, $$
1925
$$) FROM util.explain($1)
1926
$_$;
1927
1928
1929 11835 aaronmk
SET default_tablespace = '';
1930
1931
SET default_with_oids = false;
1932
1933 11832 aaronmk
--
1934 11835 aaronmk
-- Name: explain; Type: TABLE; Schema: util; Owner: -; Tablespace:
1935 11831 aaronmk
--
1936
1937 11835 aaronmk
CREATE TABLE explain (
1938
    line text NOT NULL
1939
);
1940
1941
1942
--
1943
-- Name: explain2table(text, regclass); Type: FUNCTION; Schema: util; Owner: -
1944
--
1945
1946
CREATE FUNCTION explain2table(sql text, table_ regclass DEFAULT 'explain'::regclass) RETURNS void
1947 11831 aaronmk
    LANGUAGE sql
1948
    AS $_$
1949 11835 aaronmk
SELECT util.eval($$INSERT INTO $$||$2||$$ SELECT util.explain(
1950
$$||quote_nullable($1)||$$
1951 11831 aaronmk
)$$)
1952
$_$;
1953
1954
1955
--
1956 11836 aaronmk
-- Name: FUNCTION explain2table(sql text, table_ regclass); Type: COMMENT; Schema: util; Owner: -
1957
--
1958
1959 12235 aaronmk
COMMENT ON FUNCTION explain2table(sql text, table_ regclass) IS '
1960
usage:
1961 11836 aaronmk
PERFORM util.explain2table($$
1962
query
1963 12235 aaronmk
$$);
1964
';
1965 11836 aaronmk
1966
1967
--
1968 12450 aaronmk
-- Name: first_word(text); Type: FUNCTION; Schema: util; Owner: -
1969
--
1970
1971
CREATE FUNCTION first_word(str text) RETURNS text
1972
    LANGUAGE sql IMMUTABLE
1973
    AS $_$
1974 12461 aaronmk
SELECT match[1] FROM regexp_matches(util.ltrim_nl($1), '^(\S*)') match
1975 12450 aaronmk
$_$;
1976
1977
1978
--
1979 10323 aaronmk
-- Name: fix_array(anyarray); Type: FUNCTION; Schema: util; Owner: -
1980
--
1981
1982
CREATE FUNCTION fix_array("array" anyarray) RETURNS anyarray
1983 10355 aaronmk
    LANGUAGE sql IMMUTABLE
1984 10323 aaronmk
    AS $_$
1985 10355 aaronmk
SELECT CASE WHEN $1 IS NULL THEN NULL ELSE (
1986
	CASE WHEN pg_catalog.array_ndims($1) IS NULL THEN util.empty_array($1[1]) ELSE $1 END
1987
) END
1988 10323 aaronmk
$_$;
1989
1990
1991
--
1992
-- Name: FUNCTION fix_array("array" anyarray); Type: COMMENT; Schema: util; Owner: -
1993
--
1994
1995 12235 aaronmk
COMMENT ON FUNCTION fix_array("array" anyarray) IS '
1996
ensures that an array will always have proper non-NULL dimensions
1997
';
1998 10323 aaronmk
1999
2000
--
2001 12755 aaronmk
-- Name: fold_explain_msg(text); Type: FUNCTION; Schema: util; Owner: -
2002
--
2003
2004
CREATE FUNCTION fold_explain_msg(explain text) RETURNS text
2005
    LANGUAGE sql IMMUTABLE
2006
    AS $_$
2007
SELECT (CASE WHEN util.first_word($1) = 'Result' THEN NULL ELSE $1 END)
2008
$_$;
2009
2010
2011
--
2012 8321 aaronmk
-- Name: force_update_view(text, text); Type: FUNCTION; Schema: util; Owner: -
2013
--
2014
2015
CREATE FUNCTION force_update_view(view_ text, query text) RETURNS void
2016
    LANGUAGE plpgsql STRICT
2017
    AS $_$
2018
DECLARE
2019
	mk_view text = $$CREATE OR REPLACE VIEW $$||view_||$$ AS
2020
$$||query;
2021
BEGIN
2022
	EXECUTE mk_view;
2023
EXCEPTION
2024
WHEN invalid_table_definition THEN
2025 8323 aaronmk
	IF SQLERRM = 'cannot drop columns from view'
2026
	OR SQLERRM LIKE 'cannot change name of view column "%" to "%"'
2027
	THEN
2028 8321 aaronmk
		EXECUTE $$DROP VIEW $$||view_||$$ CASCADE$$;
2029
		EXECUTE mk_view;
2030
	ELSE RAISE USING ERRCODE = SQLSTATE, MESSAGE = SQLERRM;
2031
	END IF;
2032
END;
2033
$_$;
2034
2035
2036
--
2037
-- Name: FUNCTION force_update_view(view_ text, query text); Type: COMMENT; Schema: util; Owner: -
2038
--
2039
2040 12235 aaronmk
COMMENT ON FUNCTION force_update_view(view_ text, query text) IS '
2041
idempotent
2042
';
2043 8321 aaronmk
2044
2045
--
2046 12654 aaronmk
-- Name: freq_always_1(regclass, text); Type: FUNCTION; Schema: util; Owner: -
2047
--
2048
2049
CREATE FUNCTION freq_always_1(table_ regclass, freq_col text DEFAULT 'copies'::text) RETURNS boolean
2050
    LANGUAGE sql STABLE
2051
    AS $_$
2052
SELECT util.eval2val(
2053
$$SELECT NOT EXISTS( -- there is no row that is != 1
2054
	SELECT NULL
2055
	FROM $$||$1||$$
2056
	WHERE $$||quote_ident(freq_col)||$$ IS DISTINCT FROM 1
2057
	LIMIT 1
2058
)
2059
$$, NULL::boolean)
2060
$_$;
2061
2062
2063
--
2064 12661 aaronmk
-- Name: freq_always_1(regclass[], text); Type: FUNCTION; Schema: util; Owner: -
2065
--
2066
2067
CREATE FUNCTION freq_always_1(tables regclass[], freq_col text DEFAULT 'copies'::text) RETURNS boolean
2068
    LANGUAGE sql STABLE
2069
    AS $_$
2070
SELECT bool_and(util.freq_always_1(table_, $2)) FROM unnest($1) table_
2071
$_$;
2072
2073
2074
--
2075 13892 aaronmk
-- Name: geometry(geocoord); Type: FUNCTION; Schema: util; Owner: -
2076
--
2077
2078
CREATE FUNCTION geometry(geocoord geocoord) RETURNS postgis.geometry
2079
    LANGUAGE sql IMMUTABLE
2080
    SET client_min_messages TO 'warning'
2081
    AS $_$
2082
SELECT postgis.st_setsrid(postgis.st_point(
2083
/*x_lon=*/$1.longitude_deg, /*y_lat=*/$1.latitude_deg),
2084
/*WGS84*/4326)
2085
$_$;
2086
2087
2088
--
2089 13893 aaronmk
-- Name: FUNCTION geometry(geocoord geocoord); Type: COMMENT; Schema: util; Owner: -
2090
--
2091
2092
COMMENT ON FUNCTION geometry(geocoord geocoord) IS '
2093
*note*: it is not possible to create a cast for this, as a bug in pg_dump
2094
prevents the cast from being exported, even when no export filters are applied
2095
';
2096
2097
2098
--
2099 11655 aaronmk
-- Name: grants_users(); Type: FUNCTION; Schema: util; Owner: -
2100
--
2101
2102
CREATE FUNCTION grants_users() RETURNS SETOF text
2103
    LANGUAGE sql IMMUTABLE
2104
    AS $$
2105
VALUES ('bien_read'), ('public_')
2106
$$;
2107
2108
2109
--
2110 8183 aaronmk
-- Name: has_prefix(text, text); Type: FUNCTION; Schema: util; Owner: -
2111 8085 aaronmk
--
2112
2113
CREATE FUNCTION has_prefix(prefix text, str text) RETURNS boolean
2114 10388 aaronmk
    LANGUAGE sql IMMUTABLE
2115 8085 aaronmk
    AS $_$
2116
SELECT substring($2 for length($1)) = $1
2117
$_$;
2118
2119
2120
--
2121 12296 aaronmk
-- Name: has_single_row(regclass); Type: FUNCTION; Schema: util; Owner: -
2122
--
2123
2124
CREATE FUNCTION has_single_row(table_ regclass) RETURNS boolean
2125
    LANGUAGE sql STABLE
2126
    AS $_$
2127
SELECT util.eval2val($$SELECT COUNT(*) = 1 FROM $$||$1, NULL::boolean)
2128
$_$;
2129
2130
2131
--
2132 10307 aaronmk
-- Name: hstore(text[], text); Type: FUNCTION; Schema: util; Owner: -
2133
--
2134
2135
CREATE FUNCTION hstore(keys text[], value text) RETURNS hstore
2136
    LANGUAGE sql IMMUTABLE
2137
    AS $_$
2138 10324 aaronmk
SELECT hstore(util.fix_array($1), util.array_fill($2, util.array_length($1)))
2139 10307 aaronmk
$_$;
2140
2141
2142
--
2143
-- Name: FUNCTION hstore(keys text[], value text); Type: COMMENT; Schema: util; Owner: -
2144
--
2145
2146 12235 aaronmk
COMMENT ON FUNCTION hstore(keys text[], value text) IS '
2147
avoids repeating the same value for each key
2148
';
2149 10307 aaronmk
2150
2151
--
2152 12218 aaronmk
-- Name: ifnull(anyelement, anyelement); Type: FUNCTION; Schema: util; Owner: -
2153
--
2154
2155
CREATE FUNCTION ifnull(value anyelement, null_ anyelement) RETURNS anyelement
2156
    LANGUAGE sql IMMUTABLE
2157
    AS $_$
2158 12222 aaronmk
SELECT COALESCE($1, $2)
2159 12218 aaronmk
$_$;
2160
2161
2162
--
2163
-- Name: FUNCTION ifnull(value anyelement, null_ anyelement); Type: COMMENT; Schema: util; Owner: -
2164
--
2165
2166 12235 aaronmk
COMMENT ON FUNCTION ifnull(value anyelement, null_ anyelement) IS '
2167
equivalent to MySQL''s IFNULL() (Postgres auto-lowercases the name)
2168
';
2169 12218 aaronmk
2170
2171
--
2172 13904 aaronmk
-- Name: in_new_world(geocoord); Type: FUNCTION; Schema: util; Owner: -
2173
--
2174
2175
CREATE FUNCTION in_new_world(point geocoord) RETURNS boolean
2176
    LANGUAGE sql IMMUTABLE
2177
    AS $_$
2178
/* use function rather than operator+search_path to allow inlining, which
2179
enables util.new_world() to only be evaluated once */
2180
SELECT util.contained_within_approx($1, util.new_world())
2181
$_$;
2182
2183
2184
--
2185
-- Name: FUNCTION in_new_world(point geocoord); Type: COMMENT; Schema: util; Owner: -
2186
--
2187
2188
COMMENT ON FUNCTION in_new_world(point geocoord) IS '
2189
**WARNING**: this includes false positives above and below the New World
2190
bounding box, as described in util.bounding_box()
2191
';
2192
2193
2194
--
2195 13452 aaronmk
-- Name: in_reverse(anyarray); Type: FUNCTION; Schema: util; Owner: -
2196
--
2197
2198
CREATE FUNCTION in_reverse("array" anyarray) RETURNS SETOF anyelement
2199
    LANGUAGE sql IMMUTABLE
2200
    AS $_$
2201 13490 aaronmk
SELECT elem FROM unnest($1) elem ORDER BY row_number() OVER () DESC
2202 13452 aaronmk
$_$;
2203
2204
2205
--
2206 13907 aaronmk
-- Name: in_south_america(geocoord); Type: FUNCTION; Schema: util; Owner: -
2207
--
2208
2209
CREATE FUNCTION in_south_america(point geocoord) RETURNS boolean
2210
    LANGUAGE sql IMMUTABLE
2211
    AS $_$
2212
/* use function rather than operator+search_path to allow inlining, which
2213
enables util.south_america() to only be evaluated once */
2214
SELECT util.contained_within_approx($1, util.south_america())
2215
$_$;
2216
2217
2218
--
2219 12285 aaronmk
-- Name: inherit(regclass, regclass); Type: FUNCTION; Schema: util; Owner: -
2220
--
2221
2222
CREATE FUNCTION inherit(derived regclass, base regclass) RETURNS void
2223
    LANGUAGE sql
2224
    AS $_$
2225
SELECT util.eval($$ALTER TABLE $$||$1||$$ INHERIT $$||$2)
2226
$_$;
2227
2228
2229
--
2230 13136 aaronmk
-- Name: is_castable(text, anyelement); Type: FUNCTION; Schema: util; Owner: -
2231
--
2232
2233
CREATE FUNCTION is_castable(value text, ret_type_null anyelement) RETURNS boolean
2234
    LANGUAGE plpgsql IMMUTABLE
2235
    AS $$
2236
BEGIN
2237
	PERFORM util.cast(value, ret_type_null);
2238 13139 aaronmk
	-- must happen *after* cast check, because NULL is not valid for some types
2239
	IF value IS NULL THEN RETURN NULL; END IF; -- pass NULL through
2240 13136 aaronmk
	RETURN true;
2241
EXCEPTION
2242 13493 aaronmk
WHEN   data_exception
2243 13564 aaronmk
	OR invalid_schema_name -- eg. 'pg_temp.__'::regclass
2244 13493 aaronmk
	OR syntax_error_or_access_rule_violation -- eg. ::regclass
2245
	THEN
2246
	RETURN false;
2247 13136 aaronmk
END;
2248
$$;
2249
2250
2251
--
2252
-- Name: FUNCTION is_castable(value text, ret_type_null anyelement); Type: COMMENT; Schema: util; Owner: -
2253
--
2254
2255
COMMENT ON FUNCTION is_castable(value text, ret_type_null anyelement) IS '
2256 13139 aaronmk
passes NULL through. however, if NULL is not valid for the type, false will be
2257
returned instead.
2258
2259 13136 aaronmk
ret_type_null: NULL::ret_type
2260
';
2261
2262
2263
--
2264 10137 aaronmk
-- Name: is_constant(col_ref); Type: FUNCTION; Schema: util; Owner: -
2265
--
2266
2267
CREATE FUNCTION is_constant(col col_ref) RETURNS boolean
2268 12446 aaronmk
    LANGUAGE sql STABLE
2269 10137 aaronmk
    AS $_$
2270 12789 aaronmk
SELECT COALESCE(util.col_comment($1) LIKE '
2271
constant
2272
%', false)
2273 10137 aaronmk
$_$;
2274
2275
2276
--
2277 11659 aaronmk
-- Name: is_empty(anyarray); Type: FUNCTION; Schema: util; Owner: -
2278
--
2279
2280
CREATE FUNCTION is_empty("array" anyarray) RETURNS boolean
2281
    LANGUAGE sql IMMUTABLE
2282
    AS $_$
2283
SELECT util.array_length($1) = 0
2284
$_$;
2285
2286
2287
--
2288 12457 aaronmk
-- Name: is_explain(text); Type: FUNCTION; Schema: util; Owner: -
2289
--
2290
2291
CREATE FUNCTION is_explain(sql text) RETURNS boolean
2292
    LANGUAGE sql IMMUTABLE
2293
    AS $_$
2294
SELECT upper(util.first_word($1)) = 'EXPLAIN'
2295
$_$;
2296
2297
2298
--
2299 12451 aaronmk
-- Name: is_explainable(text); Type: FUNCTION; Schema: util; Owner: -
2300
--
2301
2302
CREATE FUNCTION is_explainable(sql text) RETURNS boolean
2303
    LANGUAGE sql IMMUTABLE
2304
    AS $_$
2305
SELECT upper(util.first_word($1)) = ANY(
2306
'{SELECT,INSERT,UPDATE,DELETE,VALUES,EXECUTE,DECLARE}'::text[]
2307
/*from http://www.postgresql.org/docs/9.3/static/sql-explain.html#AEN77691*/
2308
)
2309
$_$;
2310
2311
2312
--
2313 10391 aaronmk
-- Name: is_more_complete_than(anyelement, anyelement); Type: FUNCTION; Schema: util; Owner: -
2314
--
2315
2316
CREATE FUNCTION is_more_complete_than("left" anyelement, "right" anyelement) RETURNS boolean
2317
    LANGUAGE sql IMMUTABLE
2318
    AS $_$
2319
SELECT $1 IS NOT DISTINCT FROM $2 OR ($1 IS NOT NULL AND $2 IS NULL)
2320
$_$;
2321
2322
2323
--
2324 10613 aaronmk
-- Name: is_populated_more_often_than(anyelement, anyelement); Type: FUNCTION; Schema: util; Owner: -
2325
--
2326
2327
CREATE FUNCTION is_populated_more_often_than("left" anyelement, "right" anyelement) RETURNS boolean
2328
    LANGUAGE sql IMMUTABLE
2329
    AS $_$
2330
SELECT $1 IS NOT NULL >= $2 IS NOT NULL -- true > false
2331
$_$;
2332
2333
2334
--
2335 12480 aaronmk
-- Name: is_set_stmt(text); Type: FUNCTION; Schema: util; Owner: -
2336
--
2337
2338
CREATE FUNCTION is_set_stmt(sql text) RETURNS boolean
2339
    LANGUAGE sql IMMUTABLE
2340
    AS $_$
2341
SELECT upper(util.first_word($1)) = 'SET'
2342
$_$;
2343
2344
2345
--
2346 12330 aaronmk
-- Name: is_table(regclass); Type: FUNCTION; Schema: util; Owner: -
2347
--
2348
2349
CREATE FUNCTION is_table(relation regclass) RETURNS boolean
2350 12332 aaronmk
    LANGUAGE sql STABLE
2351 12330 aaronmk
    AS $_$
2352
SELECT relkind = 'r' FROM pg_class WHERE oid = $1
2353
$_$;
2354
2355
2356
--
2357 12329 aaronmk
-- Name: is_view(regclass); Type: FUNCTION; Schema: util; Owner: -
2358
--
2359
2360
CREATE FUNCTION is_view(relation regclass) RETURNS boolean
2361 12332 aaronmk
    LANGUAGE sql STABLE
2362 12329 aaronmk
    AS $_$
2363
SELECT relkind = 'v' FROM pg_class WHERE oid = $1
2364
$_$;
2365
2366
2367
--
2368 8183 aaronmk
-- Name: join_strs_transform(text, text, text); Type: FUNCTION; Schema: util; Owner: -
2369 4009 aaronmk
--
2370
2371 4053 aaronmk
CREATE FUNCTION join_strs_transform(state text, value text, delim text) RETURNS text
2372 12444 aaronmk
    LANGUAGE sql IMMUTABLE STRICT
2373 4009 aaronmk
    AS $_$
2374 4054 aaronmk
SELECT $1 || $3 || $2
2375 2595 aaronmk
$_$;
2376
2377
2378
--
2379 12444 aaronmk
-- Name: FUNCTION join_strs_transform(state text, value text, delim text); Type: COMMENT; Schema: util; Owner: -
2380
--
2381
2382
COMMENT ON FUNCTION join_strs_transform(state text, value text, delim text) IS '
2383
must be declared STRICT to use the special handling of STRICT aggregating functions
2384
';
2385
2386
2387
--
2388 12436 aaronmk
-- Name: keys(anyelement); Type: FUNCTION; Schema: util; Owner: -
2389
--
2390
2391
CREATE FUNCTION keys(value anyelement) RETURNS anyelement
2392
    LANGUAGE sql IMMUTABLE
2393
    AS $_$
2394
SELECT $1 -- compare on the entire value
2395
$_$;
2396
2397
2398
--
2399 13794 aaronmk
-- Name: keys_eq(anyelement, anyelement); Type: FUNCTION; Schema: util; Owner: -
2400
--
2401
2402
CREATE FUNCTION keys_eq(left_ anyelement, right_ anyelement) RETURNS boolean
2403
    LANGUAGE sql STABLE
2404
    AS $_$
2405
SELECT keys($1) = keys($2)
2406
$_$;
2407
2408
2409
--
2410
-- Name: FUNCTION keys_eq(left_ anyelement, right_ anyelement); Type: COMMENT; Schema: util; Owner: -
2411
--
2412
2413
COMMENT ON FUNCTION keys_eq(left_ anyelement, right_ anyelement) IS '
2414
needs to be declared STABLE instead of IMMUTABLE because it depends on the search_path (as described at http://vegpath.org/links/#PostgreSQL:%20Documentation:%209.3:%20Function%20Volatility%20Categories%20**)
2415
';
2416
2417
2418
--
2419 10989 aaronmk
-- Name: limit2row_num(integer, integer, integer); Type: FUNCTION; Schema: util; Owner: -
2420 10985 aaronmk
--
2421
2422 10989 aaronmk
CREATE FUNCTION limit2row_num(limit_ integer, offset_ integer DEFAULT NULL::integer, min_row_num integer DEFAULT 1) RETURNS integer
2423 10985 aaronmk
    LANGUAGE sql IMMUTABLE
2424
    AS $_$
2425 10989 aaronmk
SELECT COALESCE(util.offset2row_num($2, $3) + $1 - 1, 2147483647)
2426 10985 aaronmk
$_$;
2427
2428
2429
--
2430 13384 aaronmk
-- Name: loop_ignore_errors(text, text, anyelement); Type: FUNCTION; Schema: util; Owner: -
2431
--
2432
2433
CREATE FUNCTION loop_ignore_errors(iter_sql text, loop_body_sql text, loop_type_null anyelement DEFAULT NULL::text) RETURNS void
2434
    LANGUAGE plpgsql
2435
    AS $$
2436
DECLARE
2437
	errors_ct integer = 0;
2438
	loop_var loop_type_null%TYPE;
2439
BEGIN
2440
	FOR loop_var IN SELECT * FROM util.eval2set(iter_sql, loop_type_null)
2441
	LOOP
2442
		BEGIN
2443
			EXECUTE loop_body_sql USING loop_var;
2444
		EXCEPTION
2445
		WHEN OTHERS THEN
2446
			errors_ct = errors_ct+1;
2447
			PERFORM util.raise_error_warning(SQLERRM);
2448
		END;
2449
	END LOOP;
2450
	IF errors_ct > 0 THEN
2451
		-- can't raise exception because this would roll back the transaction
2452
		PERFORM util.raise_error_warning('there were '||errors_ct
2453
			||' errors: see the WARNINGs for details');
2454
	END IF;
2455
END;
2456
$$;
2457
2458
2459
--
2460 12275 aaronmk
-- Name: ltrim_nl(text); Type: FUNCTION; Schema: util; Owner: -
2461
--
2462
2463
CREATE FUNCTION ltrim_nl(str text) RETURNS text
2464
    LANGUAGE sql IMMUTABLE
2465
    AS $_$
2466
SELECT ltrim($1, $$
2467
$$)
2468
$_$;
2469
2470
2471
--
2472 10110 aaronmk
-- Name: map_filter_insert(); Type: FUNCTION; Schema: util; Owner: -
2473
--
2474
2475
CREATE FUNCTION map_filter_insert() RETURNS trigger
2476
    LANGUAGE plpgsql
2477
    AS $$
2478
BEGIN
2479
	IF new."from" LIKE ':%' THEN RETURN NULL; END IF; -- exclude metadata values
2480
	RETURN new;
2481
END;
2482
$$;
2483
2484
2485
--
2486 8183 aaronmk
-- Name: map_get(regclass, text); Type: FUNCTION; Schema: util; Owner: -
2487 8146 aaronmk
--
2488
2489
CREATE FUNCTION map_get(map regclass, key text) RETURNS text
2490
    LANGUAGE plpgsql STABLE STRICT
2491
    AS $_$
2492
DECLARE
2493
    value text;
2494
BEGIN
2495
    EXECUTE $$SELECT "to" FROM $$||map||$$ WHERE "from" = $1$$
2496 8149 aaronmk
        INTO value USING key;
2497 8146 aaronmk
    RETURN value;
2498
END;
2499
$_$;
2500
2501
2502
--
2503 10358 aaronmk
-- Name: map_nulls(text[], anyelement); Type: FUNCTION; Schema: util; Owner: -
2504 10325 aaronmk
--
2505
2506 10358 aaronmk
CREATE FUNCTION map_nulls(nulls text[], value anyelement) RETURNS anyelement
2507 10353 aaronmk
    LANGUAGE sql IMMUTABLE
2508 10325 aaronmk
    AS $_$
2509 10374 aaronmk
SELECT util._map(util.nulls_map($1), $2)
2510 10325 aaronmk
$_$;
2511
2512
2513
--
2514 10359 aaronmk
-- Name: FUNCTION map_nulls(nulls text[], value anyelement); Type: COMMENT; Schema: util; Owner: -
2515
--
2516
2517 12235 aaronmk
COMMENT ON FUNCTION map_nulls(nulls text[], value anyelement) IS '
2518
due to dynamic inlining[1], this is just as fast as util._map() which it wraps[2].
2519 10359 aaronmk
2520
[1] inlining of function calls, which is different from constant folding
2521
[2] _map()''s profiling query
2522
SELECT util._map(''"1"=>NULL, "2"=>NULL, "3"=>NULL, *=>*'', v) FROM unnest(array_fill(1, array[100000])) f (v)
2523
and map_nulls()''s profiling query
2524
SELECT util.map_nulls(array[1, 2, 3]::text[], v) FROM unnest(array_fill(1, array[100000])) f (v)
2525 10375 aaronmk
both take ~920 ms.
2526 12235 aaronmk
also, /inputs/REMIB/Specimen/postprocess.sql > country takes the same amount of time (56000 ms) to build with map_nulls() as with a literal hstore.
2527
';
2528 10359 aaronmk
2529
2530
--
2531 8183 aaronmk
-- Name: map_values(regclass); Type: FUNCTION; Schema: util; Owner: -
2532 8150 aaronmk
--
2533
2534
CREATE FUNCTION map_values(map regclass) RETURNS SETOF text
2535
    LANGUAGE plpgsql STABLE STRICT
2536
    AS $_$
2537
BEGIN
2538
    RETURN QUERY EXECUTE $$SELECT "to" FROM $$||map;
2539
END;
2540
$_$;
2541
2542
2543
--
2544 12228 aaronmk
-- Name: materialize_query(text, text); Type: FUNCTION; Schema: util; Owner: -
2545
--
2546
2547 12262 aaronmk
CREATE FUNCTION materialize_query(table_esc text, sql text) RETURNS void
2548 12228 aaronmk
    LANGUAGE sql
2549
    AS $_$
2550 12262 aaronmk
SELECT util.create_if_not_exists($$CREATE TABLE $$||$1||$$ AS
2551 12321 aaronmk
$$||util.ltrim_nl($2));
2552
-- make sure the created table has the correct estimated row count
2553
SELECT util.analyze_($1);
2554 12470 aaronmk
2555
SELECT util.append_comment($1, '
2556
contents generated from:
2557 13397 aaronmk
'||util.ltrim_nl(util.runnable_sql($2))||';
2558 12470 aaronmk
');
2559 12228 aaronmk
$_$;
2560
2561
2562
--
2563 12262 aaronmk
-- Name: FUNCTION materialize_query(table_esc text, sql text); Type: COMMENT; Schema: util; Owner: -
2564 12228 aaronmk
--
2565
2566 12262 aaronmk
COMMENT ON FUNCTION materialize_query(table_esc text, sql text) IS '
2567 12235 aaronmk
idempotent
2568
';
2569 12228 aaronmk
2570
2571
--
2572 12234 aaronmk
-- Name: materialize_view(text, regclass); Type: FUNCTION; Schema: util; Owner: -
2573
--
2574
2575 12262 aaronmk
CREATE FUNCTION materialize_view(table_esc text, view_ regclass) RETURNS void
2576 12234 aaronmk
    LANGUAGE sql
2577
    AS $_$
2578 13916 aaronmk
SELECT util.create_if_not_exists($$
2579
SELECT util.copy($$||util.quote_typed($2)||$$, $$||util.quote_typed($1)||$$)
2580
$$);
2581 12234 aaronmk
$_$;
2582
2583
2584
--
2585 12262 aaronmk
-- Name: FUNCTION materialize_view(table_esc text, view_ regclass); Type: COMMENT; Schema: util; Owner: -
2586 12234 aaronmk
--
2587
2588 12262 aaronmk
COMMENT ON FUNCTION materialize_view(table_esc text, view_ regclass) IS '
2589 12235 aaronmk
idempotent
2590
';
2591 12234 aaronmk
2592
2593
--
2594 8190 aaronmk
-- Name: mk_const_col(col_ref, anyelement); Type: FUNCTION; Schema: util; Owner: -
2595
--
2596
2597
CREATE FUNCTION mk_const_col(col col_ref, value anyelement) RETURNS void
2598 12446 aaronmk
    LANGUAGE sql
2599 8190 aaronmk
    AS $_$
2600 10135 aaronmk
SELECT util.create_if_not_exists($$
2601
ALTER TABLE $$||$1.table_||$$ ADD COLUMN $$
2602 8190 aaronmk
||quote_ident($1.name)||$$ $$||pg_typeof($2)||util.type_qual($2)||$$ DEFAULT $$
2603 10135 aaronmk
||quote_literal($2)||$$;
2604 12235 aaronmk
COMMENT ON COLUMN $$||$1.table_||$$.$$||quote_ident($1.name)||$$ IS '
2605
constant
2606
';
2607 10135 aaronmk
$$)
2608 8190 aaronmk
$_$;
2609
2610
2611
--
2612
-- Name: FUNCTION mk_const_col(col col_ref, value anyelement); Type: COMMENT; Schema: util; Owner: -
2613
--
2614
2615 12235 aaronmk
COMMENT ON FUNCTION mk_const_col(col col_ref, value anyelement) IS '
2616
idempotent
2617
';
2618 8190 aaronmk
2619
2620
--
2621 10296 aaronmk
-- Name: mk_derived_col(col_ref, text, boolean); Type: FUNCTION; Schema: util; Owner: -
2622 8187 aaronmk
--
2623
2624 10296 aaronmk
CREATE FUNCTION mk_derived_col(col col_ref, expr text, overwrite boolean DEFAULT false) RETURNS void
2625 8187 aaronmk
    LANGUAGE plpgsql STRICT
2626
    AS $_$
2627
DECLARE
2628
    type regtype = util.typeof(expr, col.table_::text::regtype);
2629
    col_name_sql text = quote_ident(col.name);
2630
BEGIN
2631 10296 aaronmk
    PERFORM util.create_if_not_exists((CASE WHEN overwrite THEN '' ELSE $$
2632
ALTER TABLE $$||col.table_||$$ ADD   COLUMN $$||col_name_sql||$$      $$||type||$$;$$ END)||$$
2633 8187 aaronmk
ALTER TABLE $$||col.table_||$$ ALTER COLUMN $$||col_name_sql||$$ TYPE $$||type||$$ USING
2634
$$||expr||$$;
2635
$$);
2636
END;
2637
$_$;
2638
2639
2640
--
2641 10296 aaronmk
-- Name: FUNCTION mk_derived_col(col col_ref, expr text, overwrite boolean); Type: COMMENT; Schema: util; Owner: -
2642 8188 aaronmk
--
2643
2644 12235 aaronmk
COMMENT ON FUNCTION mk_derived_col(col col_ref, expr text, overwrite boolean) IS '
2645
idempotent
2646
';
2647 8188 aaronmk
2648
2649
--
2650 12554 aaronmk
-- Name: mk_diff_query(text, text, text, text, text); Type: FUNCTION; Schema: util; Owner: -
2651 12475 aaronmk
--
2652
2653 12554 aaronmk
CREATE FUNCTION mk_diff_query(left_ text, right_ text, cols text DEFAULT 'left_, right_'::text, join_cond text DEFAULT 'left_ %== right_ -- refer to EXPLAIN output for expansion of %=='::text, filter text DEFAULT 'left_ IS DISTINCT FROM right_'::text) RETURNS text
2654 12475 aaronmk
    LANGUAGE sql IMMUTABLE
2655
    AS $_$
2656
SELECT
2657 12478 aaronmk
$$SELECT
2658 12554 aaronmk
$$||$3||$$
2659 12555 aaronmk
FROM      $$||$1||$$ left_
2660 12554 aaronmk
FULL JOIN $$||$2||$$ right_
2661
ON $$||$4||$$
2662
WHERE $$||$5||$$
2663 12475 aaronmk
ORDER BY left_, right_
2664
$$
2665
$_$;
2666
2667
2668
--
2669 13515 aaronmk
-- Name: mk_drop_from_create(text); Type: FUNCTION; Schema: util; Owner: -
2670
--
2671
2672
CREATE FUNCTION mk_drop_from_create(create_cmd text) RETURNS text
2673
    LANGUAGE sql IMMUTABLE
2674
    AS $_$
2675 13516 aaronmk
SELECT $$DROP $$||(util.regexp_match($1,
2676 13603 aaronmk
-- match first CREATE, *if* no DROP came before it
2677 13608 aaronmk
'(?m)\A(?:^(?!DROP\y).*\n)*?^CREATE(?: OR REPLACE)? ((?:)??[[:upper:]]+ .*?)(?: AS(?: (?:SELECT\y.*)?)?)?$'
2678 13515 aaronmk
	/* (?:)?? makes the surrounding () group non-greedy, so that (?: AS ?)?
2679
	works properly (due to nonstandard Postgres regexp behavior:
2680
	http://www.postgresql.org/docs/9.3/static/functions-matching.html#POSIX-MATCHING-RULES) */
2681 13603 aaronmk
))[1]||$$;$$
2682 13515 aaronmk
$_$;
2683
2684
2685
--
2686 12564 aaronmk
-- Name: mk_keys_func(regtype); Type: FUNCTION; Schema: util; Owner: -
2687
--
2688
2689
CREATE FUNCTION mk_keys_func(type regtype) RETURNS void
2690 12591 aaronmk
    LANGUAGE sql
2691 12564 aaronmk
    AS $_$
2692 12570 aaronmk
-- keys()
2693 12564 aaronmk
SELECT util.mk_keys_func($1, ARRAY(
2694
SELECT col FROM util.typed_cols($1) col
2695
WHERE (col).type != ANY('{bigint}'::regtype[]) -- not a count col
2696 12570 aaronmk
));
2697
2698 12571 aaronmk
-- values_()
2699 12570 aaronmk
SELECT util.mk_keys_func($1, COALESCE(
2700
	NULLIF(ARRAY(
2701
	SELECT col FROM util.typed_cols($1) col
2702
	WHERE (col).type = ANY('{bigint}'::regtype[]) -- is a count col
2703
	), ARRAY[]::util.col_cast[])
2704
, ARRAY(SELECT util.typed_cols($1))) -- no count cols, so use all cols
2705 12571 aaronmk
, 'values_');
2706 12564 aaronmk
$_$;
2707
2708
2709
--
2710 12569 aaronmk
-- Name: mk_keys_func(regtype, col_cast[], text); Type: FUNCTION; Schema: util; Owner: -
2711 12561 aaronmk
--
2712
2713 12569 aaronmk
CREATE FUNCTION mk_keys_func(type regtype, cols col_cast[], name text DEFAULT 'keys'::text) RETURNS void
2714 12591 aaronmk
    LANGUAGE sql
2715 12561 aaronmk
    AS $_$
2716 12567 aaronmk
SELECT util.create_if_not_exists($$
2717 12577 aaronmk
CREATE TYPE $$||util.prefixed_name($3||'_', $1)||$$ AS
2718
($$||util.mk_typed_cols_list($2)||$$);
2719 12671 aaronmk
COMMENT ON TYPE $$||util.prefixed_name($3||'_', $1)||$$ IS '
2720
autogenerated
2721
';
2722 12594 aaronmk
$$);
2723 12577 aaronmk
2724 12594 aaronmk
SELECT util.mk_keys_func($1, util.prefixed_name($3||'_', $1)::regtype, $3);
2725
$_$;
2726
2727
2728
--
2729
-- Name: mk_keys_func(regtype, regtype, text); Type: FUNCTION; Schema: util; Owner: -
2730
--
2731
2732
CREATE FUNCTION mk_keys_func(type regtype, return_type regtype, name text DEFAULT 'keys'::text) RETURNS void
2733
    LANGUAGE sql
2734
    AS $_$
2735
SELECT util.create_if_not_exists($$
2736 12581 aaronmk
CREATE FUNCTION $$||util.qual_name(util.schema($1), $3)||$$(value $$
2737 12577 aaronmk
||util.qual_name($1)||$$)
2738 12594 aaronmk
  RETURNS $$||util.qual_name($2)||$$ AS
2739 12561 aaronmk
$BODY1$
2740 12577 aaronmk
SELECT ROW($$||
2741 12594 aaronmk
(SELECT COALESCE(string_agg($$$1.$$||quote_ident((col).col_name), ', '), '')
2742
FROM util.typed_cols($2) col) ||$$)::$$||util.qual_name($2)||$$
2743 12561 aaronmk
$BODY1$
2744
  LANGUAGE sql IMMUTABLE
2745
  COST 100;
2746 12594 aaronmk
$$);
2747 12561 aaronmk
$_$;
2748
2749
2750
--
2751 8183 aaronmk
-- Name: mk_map_table(text); Type: FUNCTION; Schema: util; Owner: -
2752 8139 aaronmk
--
2753
2754
CREATE FUNCTION mk_map_table(table_ text) RETURNS void
2755 12446 aaronmk
    LANGUAGE sql
2756 8139 aaronmk
    AS $_$
2757 8183 aaronmk
SELECT util.create_if_not_exists($$
2758 8141 aaronmk
CREATE TABLE $$||$1||$$
2759 8139 aaronmk
(
2760 8183 aaronmk
    LIKE util.map INCLUDING ALL
2761 10110 aaronmk
);
2762
2763
CREATE TRIGGER map_filter_insert
2764
  BEFORE INSERT
2765
  ON $$||$1||$$
2766
  FOR EACH ROW
2767
  EXECUTE PROCEDURE util.map_filter_insert();
2768 8141 aaronmk
$$)
2769 8139 aaronmk
$_$;
2770
2771
2772
--
2773 12725 aaronmk
-- Name: mk_not_null(text); Type: FUNCTION; Schema: util; Owner: -
2774
--
2775
2776
CREATE FUNCTION mk_not_null(text) RETURNS text
2777
    LANGUAGE sql IMMUTABLE
2778
    AS $_$
2779
SELECT COALESCE($1, '<NULL>')
2780
$_$;
2781
2782
2783
--
2784 12556 aaronmk
-- Name: mk_out_params(col_cast[]); Type: FUNCTION; Schema: util; Owner: -
2785
--
2786
2787
CREATE FUNCTION mk_out_params(cols col_cast[]) RETURNS text
2788
    LANGUAGE sql IMMUTABLE
2789
    AS $_$
2790 12559 aaronmk
SELECT COALESCE(string_agg($$, OUT $$||(unnest).col_name||$$ $$||
2791
util.qual_name((unnest).type), ''), '')
2792 12556 aaronmk
FROM unnest($1)
2793
$_$;
2794
2795
2796
--
2797 12236 aaronmk
-- Name: mk_search_path(text[]); Type: FUNCTION; Schema: util; Owner: -
2798
--
2799
2800
CREATE FUNCTION mk_search_path(VARIADIC schemas text[]) RETURNS text
2801
    LANGUAGE sql IMMUTABLE
2802
    AS $_$
2803 12486 aaronmk
SELECT string_agg(quote_ident(unnest), ', ') FROM unnest($1||'util'::text)
2804 12236 aaronmk
$_$;
2805
2806
2807
--
2808 12486 aaronmk
-- Name: FUNCTION mk_search_path(VARIADIC schemas text[]); Type: COMMENT; Schema: util; Owner: -
2809
--
2810
2811
COMMENT ON FUNCTION mk_search_path(VARIADIC schemas text[]) IS '
2812
auto-appends util to the search_path to enable use of util operators
2813
';
2814
2815
2816
--
2817 13474 aaronmk
-- Name: mk_set_comment(regclass, text); Type: FUNCTION; Schema: util; Owner: -
2818
--
2819
2820
CREATE FUNCTION mk_set_comment(table_ regclass, comment text) RETURNS text
2821
    LANGUAGE sql STABLE
2822
    AS $_$
2823 13483 aaronmk
SELECT COALESCE($$COMMENT ON $$||util.relation_type($1)||$$ $$||$1||$$ IS $$
2824 13481 aaronmk
||quote_literal($2)/*pass NULL through*/||$$;$$, ''/*no comment*/)
2825 13474 aaronmk
$_$;
2826
2827
2828
--
2829 13504 aaronmk
-- Name: mk_set_relation_metadata(regclass); Type: FUNCTION; Schema: util; Owner: -
2830
--
2831
2832
CREATE FUNCTION mk_set_relation_metadata(relation regclass) RETURNS text
2833
    LANGUAGE sql STABLE
2834
    AS $_$
2835
SELECT util.show_grants_for($1)
2836
||util.show_set_comment($1)||$$
2837
$$
2838
$_$;
2839
2840
2841
--
2842 12467 aaronmk
-- Name: mk_set_search_path(boolean); Type: FUNCTION; Schema: util; Owner: -
2843
--
2844
2845
CREATE FUNCTION mk_set_search_path(for_printing boolean DEFAULT false) RETURNS text
2846
    LANGUAGE sql IMMUTABLE
2847
    AS $_$
2848
SELECT util.mk_set_search_path(current_setting('search_path'), $1)
2849
$_$;
2850
2851
2852
--
2853 12466 aaronmk
-- Name: mk_set_search_path(text, boolean); Type: FUNCTION; Schema: util; Owner: -
2854 12270 aaronmk
--
2855
2856 12466 aaronmk
CREATE FUNCTION mk_set_search_path(search_path text, for_printing boolean DEFAULT false) RETURNS text
2857 12270 aaronmk
    LANGUAGE sql IMMUTABLE
2858
    AS $_$
2859 12432 aaronmk
/* debug_print_return_value() needed because this function is used with EXECUTE
2860
rather than util.eval() (in order to affect the calling function), so the
2861
search_path would not otherwise be printed */
2862 12487 aaronmk
SELECT $$SET$$||util._if($2, $$ /*LOCAL*/$$::text, $$ LOCAL$$)
2863
||$$ search_path TO $$||$1
2864 12270 aaronmk
$_$;
2865
2866
2867
--
2868 10113 aaronmk
-- Name: mk_source_col(regclass); Type: FUNCTION; Schema: util; Owner: -
2869
--
2870
2871
CREATE FUNCTION mk_source_col(table_ regclass) RETURNS void
2872 12446 aaronmk
    LANGUAGE sql
2873 10113 aaronmk
    AS $_$
2874 12240 aaronmk
SELECT util.mk_const_col(($1, 'source'), util.schema($1))
2875 10113 aaronmk
$_$;
2876
2877
2878
--
2879
-- Name: FUNCTION mk_source_col(table_ regclass); Type: COMMENT; Schema: util; Owner: -
2880
--
2881
2882 12235 aaronmk
COMMENT ON FUNCTION mk_source_col(table_ regclass) IS '
2883
idempotent
2884
';
2885 10113 aaronmk
2886
2887
--
2888 11011 aaronmk
-- Name: mk_subset_by_row_num_func(regclass); Type: FUNCTION; Schema: util; Owner: -
2889
--
2890
2891
CREATE FUNCTION mk_subset_by_row_num_func(view_ regclass) RETURNS void
2892
    LANGUAGE plpgsql STRICT
2893
    AS $_$
2894
DECLARE
2895
	view_qual_name text = util.qual_name(view_);
2896
BEGIN
2897
	EXECUTE $$
2898
CREATE OR REPLACE FUNCTION $$||view_||$$(limit_ integer DEFAULT NULL::integer, offset_ integer DEFAULT NULL)
2899
  RETURNS SETOF $$||view_||$$ AS
2900
$BODY1$
2901
SELECT * FROM $$||view_qual_name||$$
2902
ORDER BY sort_col
2903
LIMIT $1 OFFSET $2
2904
$BODY1$
2905
  LANGUAGE sql STABLE
2906
  COST 100
2907
  ROWS 1000
2908
$$;
2909
2910
	PERFORM util.mk_subset_by_row_num_no_sort_func(view_);
2911
END;
2912
$_$;
2913
2914
2915
--
2916 8325 aaronmk
-- Name: mk_subset_by_row_num_func(regclass, text); Type: FUNCTION; Schema: util; Owner: -
2917
--
2918
2919
CREATE FUNCTION mk_subset_by_row_num_func(view_ regclass, row_num_col text) RETURNS void
2920
    LANGUAGE plpgsql STRICT
2921
    AS $_$
2922 10990 aaronmk
DECLARE
2923
	view_qual_name text = util.qual_name(view_);
2924
	row_num__min__fn text = util.esc_name__append('__row_num__min', view_qual_name);
2925 8325 aaronmk
BEGIN
2926
	EXECUTE $$
2927 10990 aaronmk
CREATE OR REPLACE FUNCTION $$||row_num__min__fn||$$()
2928
  RETURNS integer AS
2929
$BODY1$
2930
SELECT $$||quote_ident(row_num_col)||$$
2931
FROM $$||view_qual_name||$$
2932
ORDER BY $$||quote_ident(row_num_col)||$$ ASC
2933
LIMIT 1
2934
$BODY1$
2935
  LANGUAGE sql STABLE
2936
  COST 100;
2937
$$;
2938
2939
	EXECUTE $$
2940 8325 aaronmk
CREATE OR REPLACE FUNCTION $$||view_||$$(limit_ integer DEFAULT NULL::integer, offset_ integer DEFAULT NULL)
2941
  RETURNS SETOF $$||view_||$$ AS
2942
$BODY1$
2943 10990 aaronmk
SELECT * FROM $$||view_qual_name||$$
2944
WHERE $$||quote_ident(row_num_col)||$$ BETWEEN
2945
	util.offset2row_num(    $2, $$||row_num__min__fn||$$())
2946
AND util.limit2row_num ($1, $2, $$||row_num__min__fn||$$())
2947 10991 aaronmk
ORDER BY $$||quote_ident(row_num_col)||$$
2948 8325 aaronmk
$BODY1$
2949
  LANGUAGE sql STABLE
2950
  COST 100
2951
  ROWS 1000
2952
$$;
2953 11010 aaronmk
2954
	PERFORM util.mk_subset_by_row_num_no_sort_func(view_);
2955
END;
2956
$_$;
2957
2958
2959
--
2960
-- Name: mk_subset_by_row_num_no_sort_func(regclass); Type: FUNCTION; Schema: util; Owner: -
2961
--
2962
2963
CREATE FUNCTION mk_subset_by_row_num_no_sort_func(view_ regclass) RETURNS void
2964
    LANGUAGE plpgsql STRICT
2965
    AS $_$
2966
DECLARE
2967
	view_qual_name text = util.qual_name(view_);
2968
BEGIN
2969 8326 aaronmk
	EXECUTE $$
2970
CREATE OR REPLACE FUNCTION $$||view_||$$(no_sort boolean, limit_ integer DEFAULT NULL::integer, offset_ integer DEFAULT NULL)
2971
  RETURNS SETOF $$||view_||$$
2972
  SET enable_sort TO 'off'
2973
  AS
2974
$BODY1$
2975 10990 aaronmk
SELECT * FROM $$||view_qual_name||$$($2, $3)
2976 8326 aaronmk
$BODY1$
2977
  LANGUAGE sql STABLE
2978
  COST 100
2979
  ROWS 1000
2980
;
2981
COMMENT ON FUNCTION $$||view_||$$(no_sort boolean, limit_ integer, offset_ integer) IS '
2982
Use this for limit values greater than ~100,000 to avoid unwanted slow sorts.
2983
If you want to run EXPLAIN and get expanded output, use the regular subset
2984
function instead. (When a config param is set on a function, EXPLAIN produces
2985
just a function scan.)
2986
';
2987
$$;
2988 8325 aaronmk
END;
2989
$_$;
2990
2991
2992
--
2993 11010 aaronmk
-- Name: FUNCTION mk_subset_by_row_num_no_sort_func(view_ regclass); Type: COMMENT; Schema: util; Owner: -
2994
--
2995
2996 12235 aaronmk
COMMENT ON FUNCTION mk_subset_by_row_num_no_sort_func(view_ regclass) IS '
2997
creates subset function which turns off enable_sort
2998
';
2999 11010 aaronmk
3000
3001
--
3002 12576 aaronmk
-- Name: mk_typed_cols_list(col_cast[]); Type: FUNCTION; Schema: util; Owner: -
3003
--
3004
3005
CREATE FUNCTION mk_typed_cols_list(cols col_cast[]) RETURNS text
3006
    LANGUAGE sql IMMUTABLE
3007
    AS $_$
3008 12579 aaronmk
SELECT COALESCE(string_agg(quote_ident((unnest).col_name)||$$ $$||
3009 12576 aaronmk
util.qual_name((unnest).type), ', '), '')
3010
FROM unnest($1)
3011
$_$;
3012
3013
3014
--
3015 12242 aaronmk
-- Name: name(regclass); Type: FUNCTION; Schema: util; Owner: -
3016
--
3017
3018
CREATE FUNCTION name(table_ regclass) RETURNS text
3019
    LANGUAGE sql STABLE
3020
    AS $_$
3021
SELECT relname::text FROM pg_class WHERE oid = $1
3022
$_$;
3023
3024
3025
--
3026 8183 aaronmk
-- Name: name(regtype); Type: FUNCTION; Schema: util; Owner: -
3027 8083 aaronmk
--
3028
3029
CREATE FUNCTION name(type regtype) RETURNS text
3030 12446 aaronmk
    LANGUAGE sql STABLE
3031 8083 aaronmk
    AS $_$
3032
SELECT typname::text FROM pg_type WHERE oid = $1
3033
$_$;
3034
3035
3036
--
3037 12360 aaronmk
-- Name: name_was_truncated(text, integer); Type: FUNCTION; Schema: util; Owner: -
3038 12355 aaronmk
--
3039
3040 12360 aaronmk
CREATE FUNCTION name_was_truncated(name_ text, max_prefix_len integer DEFAULT 0) RETURNS boolean
3041 12355 aaronmk
    LANGUAGE sql IMMUTABLE
3042
    AS $_$
3043 12360 aaronmk
SELECT octet_length($1) >= util.namedatalen() - $2
3044 12355 aaronmk
$_$;
3045
3046
3047
--
3048 12354 aaronmk
-- Name: namedatalen(); Type: FUNCTION; Schema: util; Owner: -
3049
--
3050
3051
CREATE FUNCTION namedatalen() RETURNS integer
3052
    LANGUAGE sql IMMUTABLE
3053
    AS $$
3054
SELECT octet_length(repeat('_', 1024/*>63*/)::name::text)
3055
$$;
3056
3057
3058
--
3059 13805 aaronmk
-- Name: new_world(); Type: FUNCTION; Schema: util; Owner: -
3060
--
3061
3062
CREATE FUNCTION new_world() RETURNS postgis.geography
3063
    LANGUAGE sql IMMUTABLE
3064 13812 aaronmk
    SET search_path TO util
3065 13805 aaronmk
    AS $$
3066 13812 aaronmk
SELECT util.bounding_box(-56 ~ 83, 172 ~ -34)
3067 13805 aaronmk
$$;
3068
3069
3070
--
3071 9958 aaronmk
-- Name: not_empty(anyarray); Type: FUNCTION; Schema: util; Owner: -
3072
--
3073
3074
CREATE FUNCTION not_empty(value anyarray) RETURNS boolean
3075
    LANGUAGE sql IMMUTABLE
3076
    AS $_$
3077 10329 aaronmk
SELECT $1 IS NOT NULL AND util.array_length($1) > 0
3078 9958 aaronmk
$_$;
3079
3080
3081
--
3082 9956 aaronmk
-- Name: not_null(anyelement); Type: FUNCTION; Schema: util; Owner: -
3083
--
3084
3085
CREATE FUNCTION not_null(value anyelement) RETURNS boolean
3086 9957 aaronmk
    LANGUAGE sql IMMUTABLE
3087 9956 aaronmk
    AS $_$
3088
SELECT $1 IS NOT NULL
3089
$_$;
3090
3091
3092
--
3093 10373 aaronmk
-- Name: nulls_map(text[]); Type: FUNCTION; Schema: util; Owner: -
3094
--
3095
3096
CREATE FUNCTION nulls_map(nulls text[]) RETURNS hstore
3097
    LANGUAGE sql IMMUTABLE
3098
    AS $_$
3099
SELECT util.hstore($1, NULL) || '*=>*'
3100
$_$;
3101
3102
3103
--
3104
-- Name: FUNCTION nulls_map(nulls text[]); Type: COMMENT; Schema: util; Owner: -
3105
--
3106
3107 12235 aaronmk
COMMENT ON FUNCTION nulls_map(nulls text[]) IS '
3108
for use with _map()
3109
';
3110 10373 aaronmk
3111
3112
--
3113 13802 aaronmk
-- Name: numrange(range); Type: FUNCTION; Schema: util; Owner: -
3114
--
3115
3116
CREATE FUNCTION numrange(value range) RETURNS numrange
3117
    LANGUAGE sql IMMUTABLE
3118
    AS $_$
3119
SELECT numrange($1.lower, $1.upper, $1.bounds)
3120
$_$;
3121
3122
3123
--
3124 10989 aaronmk
-- Name: offset2row_num(integer, integer); Type: FUNCTION; Schema: util; Owner: -
3125 10984 aaronmk
--
3126
3127 10989 aaronmk
CREATE FUNCTION offset2row_num(offset_ integer, min_row_num integer DEFAULT 1) RETURNS integer
3128 10984 aaronmk
    LANGUAGE sql IMMUTABLE
3129
    AS $_$
3130 10989 aaronmk
SELECT $2 + COALESCE($1, 0)
3131 10984 aaronmk
$_$;
3132
3133
3134
--
3135 12659 aaronmk
-- Name: parent(regclass); Type: FUNCTION; Schema: util; Owner: -
3136
--
3137
3138
CREATE FUNCTION parent(table_ regclass) RETURNS regclass
3139
    LANGUAGE sql STABLE
3140
    AS $_$
3141
SELECT inhparent FROM pg_inherits WHERE inhrelid = $1
3142
$_$;
3143
3144
3145
--
3146 13637 aaronmk
-- Name: pg_get_viewdef(regclass); Type: FUNCTION; Schema: util; Owner: -
3147
--
3148
3149
CREATE FUNCTION pg_get_viewdef(view_ regclass) RETURNS text
3150 13638 aaronmk
    LANGUAGE sql STABLE
3151 13637 aaronmk
    AS $_$
3152 13640 aaronmk
SELECT util.view_def_to_orig(pg_catalog.pg_get_viewdef($1))
3153 13637 aaronmk
$_$;
3154
3155
3156
--
3157 12651 aaronmk
-- Name: populate_table(regclass, text); Type: FUNCTION; Schema: util; Owner: -
3158
--
3159
3160
CREATE FUNCTION populate_table(table_ regclass, sql text) RETURNS void
3161
    LANGUAGE sql
3162
    AS $_$
3163
SELECT util.eval($$INSERT INTO $$||$1||$$
3164
$$||util.ltrim_nl($2));
3165
-- make sure the created table has the correct estimated row count
3166
SELECT util.analyze_($1);
3167
$_$;
3168
3169
3170
--
3171 12575 aaronmk
-- Name: prefixed_name(text, anyelement); Type: FUNCTION; Schema: util; Owner: -
3172
--
3173
3174
CREATE FUNCTION prefixed_name(prefix text, type anyelement) RETURNS text
3175
    LANGUAGE sql IMMUTABLE
3176
    AS $_$
3177
SELECT util.qual_name(util.schema($2), $1||util.name($2))
3178
$_$;
3179
3180
3181
--
3182 12494 aaronmk
-- Name: prepend_comment(regclass, text); Type: FUNCTION; Schema: util; Owner: -
3183
--
3184
3185
CREATE FUNCTION prepend_comment(table_ regclass, comment text) RETURNS void
3186
    LANGUAGE sql
3187
    AS $_$
3188
SELECT util.set_comment($1, concat($2, util.comment($1)))
3189
$_$;
3190
3191
3192
--
3193
-- Name: FUNCTION prepend_comment(table_ regclass, comment text); Type: COMMENT; Schema: util; Owner: -
3194
--
3195
3196
COMMENT ON FUNCTION prepend_comment(table_ regclass, comment text) IS '
3197
comment: must start and end with a newline
3198
';
3199
3200
3201
--
3202 12260 aaronmk
-- Name: qual_name(text[]); Type: FUNCTION; Schema: util; Owner: -
3203
--
3204
3205
CREATE FUNCTION qual_name(VARIADIC elems text[]) RETURNS text
3206
    LANGUAGE sql IMMUTABLE
3207
    AS $_$
3208
SELECT string_agg(quote_ident(unnest), '.') FROM unnest($1)
3209
$_$;
3210
3211
3212
--
3213 10988 aaronmk
-- Name: qual_name(regclass); Type: FUNCTION; Schema: util; Owner: -
3214
--
3215
3216
CREATE FUNCTION qual_name(table_ regclass) RETURNS text
3217 12446 aaronmk
    LANGUAGE sql STABLE
3218 12267 aaronmk
    SET search_path TO pg_temp
3219 10988 aaronmk
    AS $_$
3220 12267 aaronmk
SELECT $1::text
3221 10988 aaronmk
$_$;
3222
3223
3224
--
3225 12267 aaronmk
-- Name: qual_name(regtype); Type: FUNCTION; Schema: util; Owner: -
3226
--
3227
3228
CREATE FUNCTION qual_name(type regtype) RETURNS text
3229 12446 aaronmk
    LANGUAGE sql STABLE
3230 12267 aaronmk
    SET search_path TO pg_temp
3231
    AS $_$
3232
SELECT $1::text
3233
$_$;
3234
3235
3236
--
3237
-- Name: FUNCTION qual_name(type regtype); Type: COMMENT; Schema: util; Owner: -
3238
--
3239
3240
COMMENT ON FUNCTION qual_name(type regtype) IS '
3241
a type''s schema-qualified name
3242
';
3243
3244
3245
--
3246 12268 aaronmk
-- Name: qual_name(unknown); Type: FUNCTION; Schema: util; Owner: -
3247
--
3248
3249
CREATE FUNCTION qual_name(type unknown) RETURNS text
3250 12446 aaronmk
    LANGUAGE sql STABLE
3251 12268 aaronmk
    AS $_$
3252
SELECT util.qual_name($1::text::regtype)
3253
$_$;
3254
3255
3256
--
3257 12376 aaronmk
-- Name: quote_func_call(regprocedure, text[]); Type: FUNCTION; Schema: util; Owner: -
3258
--
3259
3260
CREATE FUNCTION quote_func_call(func regprocedure, VARIADIC args_esc text[]) RETURNS text
3261
    LANGUAGE sql IMMUTABLE
3262
    AS $_$
3263
SELECT util.quote_func_call($1::regproc::text, VARIADIC $2)
3264
$_$;
3265
3266
3267
--
3268
-- Name: quote_func_call(text, text[]); Type: FUNCTION; Schema: util; Owner: -
3269
--
3270
3271
CREATE FUNCTION quote_func_call(func_esc text, VARIADIC args_esc text[]) RETURNS text
3272
    LANGUAGE sql IMMUTABLE
3273
    AS $_$
3274
SELECT $1||'('||concat_ws(', ', VARIADIC $2)||')'
3275
$_$;
3276
3277
3278
--
3279 12371 aaronmk
-- Name: quote_typed(anyelement); Type: FUNCTION; Schema: util; Owner: -
3280
--
3281
3282
CREATE FUNCTION quote_typed(value anyelement) RETURNS text
3283
    LANGUAGE sql IMMUTABLE
3284
    AS $_$
3285 12437 aaronmk
SELECT quote_nullable($1)||$$::$$||util.qual_name(pg_typeof($1))
3286 12371 aaronmk
$_$;
3287
3288
3289
--
3290 12530 aaronmk
-- Name: raise(text, text); Type: FUNCTION; Schema: util; Owner: -
3291
--
3292
3293
CREATE FUNCTION raise(type text, msg text) RETURNS void
3294
    LANGUAGE sql IMMUTABLE
3295 12560 aaronmk
    AS $_X$
3296 12530 aaronmk
SELECT util.eval($$
3297
CREATE OR REPLACE FUNCTION pg_temp.__raise()
3298
  RETURNS void AS
3299 12560 aaronmk
-- $__BODY1$ in case msg contains $BODY1$ (in SQL)
3300
$__BODY1$
3301 12530 aaronmk
BEGIN
3302
	RAISE $$||$1||$$ USING MESSAGE = $$||quote_nullable($2)||$$;
3303
END;
3304 12560 aaronmk
$__BODY1$
3305 12530 aaronmk
  LANGUAGE plpgsql IMMUTABLE
3306
  COST 100;
3307 12532 aaronmk
$$, verbose_ := false);
3308 12530 aaronmk
3309 12532 aaronmk
SELECT util.eval($$SELECT pg_temp.__raise()$$, verbose_ := false);
3310 12560 aaronmk
$_X$;
3311 12530 aaronmk
3312
3313
--
3314 12533 aaronmk
-- Name: FUNCTION raise(type text, msg text); Type: COMMENT; Schema: util; Owner: -
3315
--
3316
3317
COMMENT ON FUNCTION raise(type text, msg text) IS '
3318
type: a log level from
3319
http://www.postgresql.org/docs/9.3/static/plpgsql-errors-and-messages.html
3320
or a condition name from
3321
http://www.postgresql.org/docs/9.3/static/errcodes-appendix.html
3322
';
3323
3324
3325
--
3326 12536 aaronmk
-- Name: raise_error_warning(text); Type: FUNCTION; Schema: util; Owner: -
3327 12311 aaronmk
--
3328
3329 12536 aaronmk
CREATE FUNCTION raise_error_warning(msg text) RETURNS void
3330 12441 aaronmk
    LANGUAGE sql IMMUTABLE
3331 12311 aaronmk
    AS $_$
3332 12536 aaronmk
SELECT util.raise('WARNING', 'ERROR:  '||$1)
3333 12311 aaronmk
$_$;
3334
3335
3336
--
3337 10116 aaronmk
-- Name: raise_undefined_column(col_ref); Type: FUNCTION; Schema: util; Owner: -
3338
--
3339
3340
CREATE FUNCTION raise_undefined_column(col col_ref) RETURNS text
3341
    LANGUAGE plpgsql IMMUTABLE STRICT
3342
    AS $$
3343
BEGIN
3344
	RAISE undefined_column USING MESSAGE = concat('undefined column: ', col.name);
3345
END;
3346
$$;
3347
3348
3349
--
3350 13794 aaronmk
-- Name: range(numeric, numeric); Type: FUNCTION; Schema: util; Owner: -
3351
--
3352
3353 13803 aaronmk
CREATE FUNCTION range(lower numeric, upper numeric) RETURNS range
3354 13794 aaronmk
    LANGUAGE sql IMMUTABLE
3355
    AS $_$
3356 13803 aaronmk
SELECT ($1, $2, '[]')::util.range
3357 13794 aaronmk
$_$;
3358
3359
3360
--
3361 13512 aaronmk
-- Name: recreate(text, text[]); Type: FUNCTION; Schema: util; Owner: -
3362
--
3363
3364
CREATE FUNCTION recreate(cmd text, users text[] DEFAULT NULL::text[]) RETURNS void
3365
    LANGUAGE plpgsql
3366
    AS $_$
3367
DECLARE
3368
	PG_EXCEPTION_DETAIL text;
3369
	restore_views_info util.restore_views_info;
3370
BEGIN
3371
	restore_views_info = util.save_drop_views(users);
3372 13517 aaronmk
3373
	-- trigger the dependent_objects_still_exist exception
3374 13604 aaronmk
	PERFORM util.eval(COALESCE(util.mk_drop_from_create(cmd), '')||cmd);
3375 13517 aaronmk
		-- *not* CASCADE; it must trigger an exception
3376
3377 13512 aaronmk
	PERFORM util.restore_views(restore_views_info);
3378
EXCEPTION
3379
WHEN dependent_objects_still_exist THEN
3380
	IF users IS NOT NULL THEN RAISE; END IF; -- save_drop_views() didn't fix it
3381
	GET STACKED DIAGNOSTICS PG_EXCEPTION_DETAIL = PG_EXCEPTION_DETAIL;
3382
	users = array(SELECT * FROM util.regexp_matches_group(
3383
		PG_EXCEPTION_DETAIL, '(?m)^view (.*) depends on [[:lower:]]+ .*$'));
3384
		-- will be in forward dependency order
3385
	PERFORM util.debug_print_var('PG_EXCEPTION_DETAIL', PG_EXCEPTION_DETAIL);
3386
	PERFORM util.debug_print_var('users', users);
3387
	IF util.is_empty(users) THEN RAISE; END IF;
3388
	PERFORM util.recreate(cmd, users);
3389
END;
3390
$_$;
3391
3392
3393
--
3394
-- Name: FUNCTION recreate(cmd text, users text[]); Type: COMMENT; Schema: util; Owner: -
3395
--
3396
3397
COMMENT ON FUNCTION recreate(cmd text, users text[]) IS '
3398 13517 aaronmk
the appropriate drop statement will be added automatically.
3399
3400 13512 aaronmk
usage:
3401
SELECT util.recreate($$
3402 13524 aaronmk
CREATE VIEW schema.main_view AS _;
3403 13512 aaronmk
3404
-- manually restore views that need to be updated for the changes
3405 13524 aaronmk
CREATE VIEW schema.dependent_view AS _;
3406 13512 aaronmk
$$);
3407
3408
idempotent
3409
3410
users: not necessary to provide this because it will be autopopulated
3411
';
3412
3413
3414
--
3415 13525 aaronmk
-- Name: recreate_view(regclass, text, text); Type: FUNCTION; Schema: util; Owner: -
3416
--
3417
3418 13606 aaronmk
CREATE FUNCTION recreate_view(view_ regclass, view_query text DEFAULT NULL::text, dependent_view_changes text DEFAULT ''::text) RETURNS void
3419 13525 aaronmk
    LANGUAGE sql
3420
    AS $_$
3421
SELECT util.recreate($$
3422
CREATE VIEW $$||$1||$$ AS
3423 13606 aaronmk
$$||COALESCE($2, pg_get_viewdef($1))||$$;
3424 13525 aaronmk
$$||util.mk_set_relation_metadata($1)||$$
3425
3426
-- manually restore views that need to be updated for the changes
3427
$$||$3||$$
3428
$$);
3429
$_$;
3430
3431
3432
--
3433
-- Name: FUNCTION recreate_view(view_ regclass, view_query text, dependent_view_changes text); Type: COMMENT; Schema: util; Owner: -
3434
--
3435
3436
COMMENT ON FUNCTION recreate_view(view_ regclass, view_query text, dependent_view_changes text) IS '
3437
usage:
3438
SELECT util.recreate_view(''schema.main_view'', $$
3439
SELECT __
3440
$$, $$
3441
CREATE VIEW schema.dependent_view AS
3442
__;
3443
$$||util.mk_set_relation_metadata(''schema.dependent_view'')||$$
3444
$$);
3445
3446 13606 aaronmk
if view has already been modified:
3447
SELECT util.recreate_view(''schema.main_view'', dependent_view_changes := $$
3448
CREATE VIEW schema.dependent_view AS
3449
__;
3450
$$||util.mk_set_relation_metadata(''schema.dependent_view'')||$$
3451
$$);
3452
3453 13525 aaronmk
idempotent
3454
';
3455
3456
3457
--
3458 13514 aaronmk
-- Name: regexp_match(text, text); Type: FUNCTION; Schema: util; Owner: -
3459
--
3460
3461
CREATE FUNCTION regexp_match(str text, re text) RETURNS text[]
3462
    LANGUAGE sql IMMUTABLE
3463
    AS $_$
3464
SELECT match FROM regexp_matches($1, $2) match LIMIT 1/*only 1st match*/
3465
$_$;
3466
3467
3468
--
3469 11657 aaronmk
-- Name: regexp_matches_group(text, text, integer); Type: FUNCTION; Schema: util; Owner: -
3470
--
3471
3472
CREATE FUNCTION regexp_matches_group(str text, re text, group_ integer DEFAULT 1) RETURNS SETOF text
3473
    LANGUAGE sql IMMUTABLE
3474
    AS $_$
3475
SELECT regexp_matches[$3] FROM regexp_matches($1, $2, 'g')
3476
$_$;
3477
3478
3479
--
3480 12333 aaronmk
-- Name: regexp_quote(text); Type: FUNCTION; Schema: util; Owner: -
3481
--
3482
3483
CREATE FUNCTION regexp_quote(str text) RETURNS text
3484
    LANGUAGE sql IMMUTABLE
3485
    AS $_$
3486
SELECT regexp_replace($1, '\W', /*\char*/'\\\&', 'g')
3487
$_$;
3488
3489
3490
--
3491 12375 aaronmk
-- Name: regprocedure(text); Type: FUNCTION; Schema: util; Owner: -
3492
--
3493
3494
CREATE FUNCTION regprocedure(func text) RETURNS regprocedure
3495
    LANGUAGE sql IMMUTABLE
3496
    AS $_$
3497
SELECT (CASE WHEN right($1, 1) = ')'
3498 12377 aaronmk
THEN $1::regprocedure ELSE $1::regproc::regprocedure END)
3499 12375 aaronmk
$_$;
3500
3501
3502
--
3503 13492 aaronmk
-- Name: relation_exists(text); Type: FUNCTION; Schema: util; Owner: -
3504
--
3505
3506
CREATE FUNCTION relation_exists(relation text) RETURNS boolean
3507
    LANGUAGE sql STABLE
3508
    AS $_$
3509
SELECT $1 IS NOT NULL AND util.is_castable($1, NULL::regclass)
3510
$_$;
3511
3512
3513
--
3514 12344 aaronmk
-- Name: relation_type(regclass); Type: FUNCTION; Schema: util; Owner: -
3515
--
3516
3517
CREATE FUNCTION relation_type(relation regclass) RETURNS text
3518
    LANGUAGE sql STABLE
3519
    AS $_$
3520
SELECT util.relation_type(util.relation_type_char($1))
3521
$_$;
3522
3523
3524
--
3525 12340 aaronmk
-- Name: relation_type("char"); Type: FUNCTION; Schema: util; Owner: -
3526 12339 aaronmk
--
3527
3528 12340 aaronmk
CREATE FUNCTION relation_type(relation_type_char "char") RETURNS text
3529 12339 aaronmk
    LANGUAGE sql IMMUTABLE
3530
    AS $_$
3531 12593 aaronmk
SELECT 'c=>TYPE, r=>TABLE, v=>VIEW'::hstore -> $1
3532 12339 aaronmk
$_$;
3533
3534
3535
--
3536 12588 aaronmk
-- Name: relation_type(regtype); Type: FUNCTION; Schema: util; Owner: -
3537
--
3538
3539
CREATE FUNCTION relation_type(type regtype) RETURNS text
3540
    LANGUAGE sql IMMUTABLE
3541
    AS $$
3542
SELECT 'TYPE'::text
3543
$$;
3544
3545
3546
--
3547 12341 aaronmk
-- Name: relation_type_char(regclass); Type: FUNCTION; Schema: util; Owner: -
3548
--
3549
3550
CREATE FUNCTION relation_type_char(relation regclass) RETURNS "char"
3551
    LANGUAGE sql STABLE
3552
    AS $_$
3553
SELECT relkind FROM pg_class WHERE oid = $1
3554
$_$;
3555
3556
3557
--
3558 12293 aaronmk
-- Name: remake_diff_table(text, regclass, regclass, text); Type: FUNCTION; Schema: util; Owner: -
3559
--
3560
3561
CREATE FUNCTION remake_diff_table(diff_table text, left_table regclass, right_table regclass, type_table text) RETURNS void
3562
    LANGUAGE sql
3563
    AS $_$
3564
/* can't have in_table/out_table inherit from *each other*, because inheritance
3565
also causes the rows of the parent table to be included in the child table.
3566
instead, they need to inherit from a common, empty table. */
3567 12382 aaronmk
SELECT util.create_if_not_exists($$SELECT $$||util.quote_func_call(
3568
'util.copy_struct', util.quote_typed($2), util.quote_typed($4)));
3569 13098 aaronmk
SELECT util.rm_freq(ARRAY[$4]); -- left/right_table don't have freq yet
3570 12293 aaronmk
SELECT util.inherit($2, $4);
3571
SELECT util.inherit($3, $4);
3572
3573
SELECT util.rematerialize_query($1, $$
3574
SELECT * FROM util.diff(
3575 12419 aaronmk
  $$||util.quote_typed($2)||$$
3576
, $$||util.quote_typed($3)||$$
3577 12293 aaronmk
, NULL::$$||$4||$$)
3578
$$);
3579 12303 aaronmk
3580
/* the table unfortunately cannot be *materialized* in human-readable form,
3581
because this would create column name collisions between the two sides */
3582 12495 aaronmk
SELECT util.prepend_comment($1, '
3583 12303 aaronmk
to view this table in human-readable form (with each side''s tuple column
3584
expanded to its component fields):
3585 12572 aaronmk
SELECT (left_).*, ('||util.schema($4::regclass)||'.values_(right_)).* FROM '||$1||';
3586 13092 aaronmk
3587
to display NULL values that are extra or missing:
3588
SELECT * FROM '||$1||';
3589 12303 aaronmk
');
3590 12293 aaronmk
$_$;
3591
3592
3593
--
3594
-- Name: FUNCTION remake_diff_table(diff_table text, left_table regclass, right_table regclass, type_table text); Type: COMMENT; Schema: util; Owner: -
3595
--
3596
3597
COMMENT ON FUNCTION remake_diff_table(diff_table text, left_table regclass, right_table regclass, type_table text) IS '
3598
type_table (*required*): table to create as the shared base type
3599
';
3600
3601
3602
--
3603 12265 aaronmk
-- Name: rematerialize_query(text, text); Type: FUNCTION; Schema: util; Owner: -
3604
--
3605
3606
CREATE FUNCTION rematerialize_query(table_esc text, sql text) RETURNS void
3607
    LANGUAGE sql
3608
    AS $_$
3609
SELECT util.drop_table($1);
3610
SELECT util.materialize_query($1, $2);
3611
$_$;
3612
3613
3614
--
3615
-- Name: FUNCTION rematerialize_query(table_esc text, sql text); Type: COMMENT; Schema: util; Owner: -
3616
--
3617
3618
COMMENT ON FUNCTION rematerialize_query(table_esc text, sql text) IS '
3619
idempotent, but repeats action each time
3620
';
3621
3622
3623
--
3624 12247 aaronmk
-- Name: rematerialize_view(text, regclass); Type: FUNCTION; Schema: util; Owner: -
3625
--
3626
3627 12262 aaronmk
CREATE FUNCTION rematerialize_view(table_esc text, view_ regclass) RETURNS void
3628 12247 aaronmk
    LANGUAGE sql
3629
    AS $_$
3630
SELECT util.drop_table($1);
3631
SELECT util.materialize_view($1, $2);
3632
$_$;
3633
3634
3635
--
3636 12262 aaronmk
-- Name: FUNCTION rematerialize_view(table_esc text, view_ regclass); Type: COMMENT; Schema: util; Owner: -
3637 12247 aaronmk
--
3638
3639 12262 aaronmk
COMMENT ON FUNCTION rematerialize_view(table_esc text, view_ regclass) IS '
3640 12247 aaronmk
idempotent, but repeats action each time
3641
';
3642
3643
3644
--
3645 8183 aaronmk
-- Name: rename_cols(regclass, anyelement); Type: FUNCTION; Schema: util; Owner: -
3646 8137 aaronmk
--
3647
3648 8148 aaronmk
CREATE FUNCTION rename_cols(table_ regclass, renames anyelement) RETURNS void
3649 12446 aaronmk
    LANGUAGE sql
3650 8137 aaronmk
    AS $_$
3651 8212 aaronmk
SELECT util.try_create($$ALTER TABLE $$||$1||$$ RENAME $$
3652 8137 aaronmk
||quote_ident(name)||$$ TO $$||quote_ident($2 -> name))
3653 10309 aaronmk
FROM util.col_names($1::text::regtype) f (name);
3654
SELECT NULL::void; -- don't fold away functions called in previous query
3655 8137 aaronmk
$_$;
3656
3657
3658
--
3659 8183 aaronmk
-- Name: FUNCTION rename_cols(table_ regclass, renames anyelement); Type: COMMENT; Schema: util; Owner: -
3660 8137 aaronmk
--
3661
3662 12235 aaronmk
COMMENT ON FUNCTION rename_cols(table_ regclass, renames anyelement) IS '
3663
idempotent
3664
';
3665 8137 aaronmk
3666
3667
--
3668 12349 aaronmk
-- Name: rename_relation(regclass, text); Type: FUNCTION; Schema: util; Owner: -
3669
--
3670
3671
CREATE FUNCTION rename_relation(from_ regclass, to_ text) RETURNS void
3672
    LANGUAGE sql
3673
    AS $_$
3674 12353 aaronmk
/* use util.qual_name() instead of ::text so that the schema qualifier is always
3675
included in the debug SQL */
3676
SELECT util.rename_relation(util.qual_name($1), $2)
3677 12349 aaronmk
$_$;
3678
3679
3680
--
3681
-- Name: rename_relation(text, text); Type: FUNCTION; Schema: util; Owner: -
3682
--
3683
3684 12364 aaronmk
CREATE FUNCTION rename_relation(from_esc text, to_name text) RETURNS void
3685 12349 aaronmk
    LANGUAGE sql
3686
    AS $_$
3687
/* 'ALTER TABLE can be used with views too'
3688
(http://www.postgresql.org/docs/9.3/static/sql-alterview.html) */
3689 12363 aaronmk
SELECT util.eval($$ALTER TABLE IF EXISTS $$||$1||$$ RENAME TO $$
3690
||quote_ident($2))
3691 12349 aaronmk
$_$;
3692
3693
3694
--
3695 12364 aaronmk
-- Name: FUNCTION rename_relation(from_esc text, to_name text); Type: COMMENT; Schema: util; Owner: -
3696 12349 aaronmk
--
3697
3698 12364 aaronmk
COMMENT ON FUNCTION rename_relation(from_esc text, to_name text) IS '
3699 12349 aaronmk
idempotent
3700
';
3701
3702
3703
--
3704 12358 aaronmk
-- Name: replace_suffix(text, text, text, integer); Type: FUNCTION; Schema: util; Owner: -
3705 12350 aaronmk
--
3706
3707 12358 aaronmk
CREATE FUNCTION replace_suffix(str text, old_suffix text, new_suffix text, max_prefix_len integer DEFAULT 0) RETURNS text
3708 12350 aaronmk
    LANGUAGE sql IMMUTABLE
3709
    AS $_$
3710 12358 aaronmk
SELECT regexp_replace($1, util.truncated_prefixed_name_regexp($2, $4), '\1'||$3)
3711 12350 aaronmk
$_$;
3712
3713
3714
--
3715 12358 aaronmk
-- Name: FUNCTION replace_suffix(str text, old_suffix text, new_suffix text, max_prefix_len integer); Type: COMMENT; Schema: util; Owner: -
3716
--
3717
3718
COMMENT ON FUNCTION replace_suffix(str text, old_suffix text, new_suffix text, max_prefix_len integer) IS '
3719
max_prefix_len: when str may have been truncated (eg. as a table name) due to the prepending of a prefix, support prefixes up to this length
3720
';
3721
3722
3723
--
3724 10297 aaronmk
-- Name: reset_col_names(regclass, regclass); Type: FUNCTION; Schema: util; Owner: -
3725
--
3726
3727
CREATE FUNCTION reset_col_names(table_ regclass, names regclass) RETURNS void
3728 12446 aaronmk
    LANGUAGE sql
3729 10297 aaronmk
    AS $_$
3730 10596 aaronmk
SELECT util.eval($$DELETE FROM $$||$2||$$ WHERE "from" LIKE ':%'$$);
3731
SELECT util.mk_derived_col(($2, 'to'), $$"from"$$, overwrite := true);
3732 10297 aaronmk
SELECT util.set_col_names($1, $2);
3733
$_$;
3734
3735
3736
--
3737
-- Name: FUNCTION reset_col_names(table_ regclass, names regclass); Type: COMMENT; Schema: util; Owner: -
3738
--
3739
3740 12235 aaronmk
COMMENT ON FUNCTION reset_col_names(table_ regclass, names regclass) IS '
3741
idempotent.
3742
alters the names table, so it will need to be repopulated after running this function.
3743
';
3744 10297 aaronmk
3745
3746
--
3747 8183 aaronmk
-- Name: reset_map_table(text); Type: FUNCTION; Schema: util; Owner: -
3748 8143 aaronmk
--
3749
3750
CREATE FUNCTION reset_map_table(table_ text) RETURNS void
3751 12446 aaronmk
    LANGUAGE sql
3752 8143 aaronmk
    AS $_$
3753 10152 aaronmk
SELECT util.drop_table($1);
3754 8183 aaronmk
SELECT util.mk_map_table($1);
3755 8143 aaronmk
$_$;
3756
3757
3758
--
3759 13488 aaronmk
-- Name: restore_views(restore_views_info); Type: FUNCTION; Schema: util; Owner: -
3760 13486 aaronmk
--
3761
3762 13488 aaronmk
CREATE FUNCTION restore_views(restore_views_info) RETURNS void
3763 13486 aaronmk
    LANGUAGE sql
3764
    AS $_$
3765
SELECT util.debug_print_var('views', $1);
3766 13497 aaronmk
SELECT util.create_if_not_exists((view_).def, (view_).path)
3767
	/* need to specify view name for manual existence check, in case view def
3768
	becomes invalid, which would produce nonstandard (uncatchable) exception */
3769 13491 aaronmk
FROM unnest($1.views) view_; -- in forward dependency order
3770 13486 aaronmk
	/* create_if_not_exists() rather than eval(), because cmd might manually
3771
	re-create a deleted dependent view, causing it to already exist */
3772
SELECT NULL::void; -- don't fold away functions called in previous query
3773
$_$;
3774
3775
3776
--
3777 13096 aaronmk
-- Name: rm_freq(regclass[], text); Type: FUNCTION; Schema: util; Owner: -
3778
--
3779
3780
CREATE FUNCTION rm_freq(tables regclass[], freq_col text DEFAULT 'copies'::text) RETURNS void
3781
    LANGUAGE sql
3782
    AS $_$
3783
SELECT util.drop_column($1, $2, force := true)
3784
$_$;
3785
3786
3787
--
3788 12356 aaronmk
-- Name: rtrim_n(text, integer); Type: FUNCTION; Schema: util; Owner: -
3789
--
3790
3791
CREATE FUNCTION rtrim_n(str text, count integer) RETURNS text
3792
    LANGUAGE sql IMMUTABLE
3793
    AS $_$
3794
SELECT (CASE WHEN $2 <= 0 THEN $1 ELSE left($1, -$2) END)
3795
$_$;
3796
3797
3798
--
3799 12473 aaronmk
-- Name: runnable_sql(text); Type: FUNCTION; Schema: util; Owner: -
3800
--
3801
3802
CREATE FUNCTION runnable_sql(sql text) RETURNS text
3803
    LANGUAGE sql IMMUTABLE
3804
    AS $_$
3805 12481 aaronmk
SELECT (CASE WHEN util.is_set_stmt($1) THEN ''
3806
ELSE util.mk_set_search_path(for_printing := true)||$$;
3807
$$ END)||$1
3808 12473 aaronmk
$_$;
3809
3810
3811
--
3812 11652 aaronmk
-- Name: save_drop_view(text); Type: FUNCTION; Schema: util; Owner: -
3813
--
3814
3815
CREATE FUNCTION save_drop_view(view_ text) RETURNS text
3816
    LANGUAGE plpgsql STRICT
3817 13467 aaronmk
    AS $$
3818 11652 aaronmk
DECLARE
3819
	result text = NULL;
3820
BEGIN
3821
	BEGIN
3822 13470 aaronmk
		result = util.show_create_view(view_, replace := false);
3823
			/* replace: no `OR REPLACE` because that causes nonuniform errors
3824
			(eg. invalid_table_definition), instead of the standard
3825
			duplicate_table exception caught by util.create_if_not_exists() */
3826 13467 aaronmk
		PERFORM util.drop_view(view_);
3827 11652 aaronmk
	EXCEPTION
3828
		WHEN undefined_table THEN NULL;
3829
	END;
3830
	RETURN result;
3831
END;
3832 13467 aaronmk
$$;
3833 11652 aaronmk
3834
3835
--
3836 11660 aaronmk
-- Name: save_drop_views(text[]); Type: FUNCTION; Schema: util; Owner: -
3837
--
3838
3839 13488 aaronmk
CREATE FUNCTION save_drop_views(views text[]) RETURNS restore_views_info
3840 11660 aaronmk
    LANGUAGE sql
3841
    AS $_$
3842 13488 aaronmk
SELECT ROW(/*return in forward dependency order*/util.array_reverse(array(
3843 13491 aaronmk
SELECT (view_, util.save_drop_view(view_))::util.db_item
3844 13485 aaronmk
FROM unnest(/*drop in reverse dependency order*/util.array_reverse($1)) view_
3845 13488 aaronmk
)))::util.restore_views_info
3846 11660 aaronmk
$_$;
3847
3848
3849
--
3850 12244 aaronmk
-- Name: schema(oid); Type: FUNCTION; Schema: util; Owner: -
3851
--
3852
3853
CREATE FUNCTION schema(pg_namespace_oid oid) RETURNS text
3854
    LANGUAGE sql STABLE
3855
    AS $_$
3856
SELECT nspname::text FROM pg_namespace WHERE pg_namespace.oid = $1
3857
$_$;
3858
3859
3860
--
3861 12242 aaronmk
-- Name: schema(regclass); Type: FUNCTION; Schema: util; Owner: -
3862
--
3863
3864
CREATE FUNCTION schema(table_ regclass) RETURNS text
3865
    LANGUAGE sql STABLE
3866
    AS $_$
3867 12245 aaronmk
SELECT util.schema(relnamespace) FROM pg_class WHERE oid = $1
3868 12242 aaronmk
$_$;
3869
3870
3871
--
3872 10794 aaronmk
-- Name: schema(regtype); Type: FUNCTION; Schema: util; Owner: -
3873
--
3874
3875
CREATE FUNCTION schema(type regtype) RETURNS text
3876
    LANGUAGE sql STABLE
3877
    AS $_$
3878 12245 aaronmk
SELECT util.schema(typnamespace) FROM pg_type WHERE oid = $1
3879 10794 aaronmk
$_$;
3880
3881
3882
--
3883
-- Name: schema(anyelement); Type: FUNCTION; Schema: util; Owner: -
3884
--
3885
3886
CREATE FUNCTION schema(type_null anyelement) RETURNS text
3887
    LANGUAGE sql STABLE
3888
    AS $_$
3889
SELECT util.schema(pg_typeof($1))
3890
$_$;
3891
3892
3893
--
3894 12134 aaronmk
-- Name: schema_bundle_get_schemas(text); Type: FUNCTION; Schema: util; Owner: -
3895
--
3896
3897
CREATE FUNCTION schema_bundle_get_schemas(schema_bundle text) RETURNS SETOF text
3898
    LANGUAGE sql STABLE
3899
    AS $_$
3900
SELECT nspname::text FROM pg_namespace WHERE nspname ~ ('^'||$1||'(?=\y|_)')
3901
$_$;
3902
3903
3904
--
3905 12135 aaronmk
-- Name: FUNCTION schema_bundle_get_schemas(schema_bundle text); Type: COMMENT; Schema: util; Owner: -
3906
--
3907
3908 12235 aaronmk
COMMENT ON FUNCTION schema_bundle_get_schemas(schema_bundle text) IS '
3909
a schema bundle is a group of schemas with a common prefix
3910
';
3911 12135 aaronmk
3912
3913
--
3914
-- Name: schema_bundle_rename(text, text); Type: FUNCTION; Schema: util; Owner: -
3915
--
3916
3917
CREATE FUNCTION schema_bundle_rename(old text, new text) RETURNS void
3918
    LANGUAGE sql
3919
    AS $_$
3920
SELECT util.schema_rename(old_schema,
3921
	overlay(old_schema placing new from 1 for length(old))) -- replace prefix
3922
FROM util.schema_bundle_get_schemas($1) f (old_schema);
3923
SELECT NULL::void; -- don't fold away functions called in previous query
3924
$_$;
3925
3926
3927
--
3928
-- Name: schema_bundle_replace(text, text); Type: FUNCTION; Schema: util; Owner: -
3929
--
3930
3931
CREATE FUNCTION schema_bundle_replace(replace text, with_ text) RETURNS void
3932
    LANGUAGE plpgsql
3933
    AS $$
3934
BEGIN
3935
	-- don't schema_bundle_rm() the schema_bundle to keep!
3936
	IF replace = with_ THEN RETURN; END IF;
3937
3938
	PERFORM util.schema_bundle_rm(replace);
3939
	PERFORM util.schema_bundle_rename(with_, replace);
3940
END;
3941
$$;
3942
3943
3944
--
3945
-- Name: schema_bundle_rm(text); Type: FUNCTION; Schema: util; Owner: -
3946
--
3947
3948
CREATE FUNCTION schema_bundle_rm(schema_bundle text) RETURNS void
3949
    LANGUAGE sql
3950
    AS $_$
3951
SELECT util.schema_rm(schema)
3952
FROM util.schema_bundle_get_schemas($1) f (schema);
3953
SELECT NULL::void; -- don't fold away functions called in previous query
3954
$_$;
3955
3956
3957
--
3958 12238 aaronmk
-- Name: schema_esc(anyelement); Type: FUNCTION; Schema: util; Owner: -
3959 10795 aaronmk
--
3960
3961 12238 aaronmk
CREATE FUNCTION schema_esc(type_null anyelement) RETURNS text
3962 10795 aaronmk
    LANGUAGE sql STABLE
3963
    AS $_$
3964
SELECT quote_ident(util.schema($1))
3965
$_$;
3966
3967
3968
--
3969 12324 aaronmk
-- Name: schema_matches(text, text); Type: FUNCTION; Schema: util; Owner: -
3970
--
3971
3972
CREATE FUNCTION schema_matches(schema text, schema_regexp text) RETURNS boolean
3973 12334 aaronmk
    LANGUAGE sql IMMUTABLE
3974 12324 aaronmk
    AS $_$
3975
SELECT $1 ~ $2 AND /*in userspace*/$1 !~ '^(?:information_schema|pg_.*)$'
3976
$_$;
3977
3978
3979
--
3980 12304 aaronmk
-- Name: schema_oid(text); Type: FUNCTION; Schema: util; Owner: -
3981
--
3982
3983
CREATE FUNCTION schema_oid(schema text) RETURNS oid
3984
    LANGUAGE sql STABLE
3985
    AS $_$
3986
SELECT oid FROM pg_namespace WHERE nspname = $1
3987
$_$;
3988
3989
3990
--
3991 12504 aaronmk
-- Name: schema_regexp(regclass); Type: FUNCTION; Schema: util; Owner: -
3992
--
3993
3994
CREATE FUNCTION schema_regexp(relation regclass) RETURNS text
3995
    LANGUAGE sql IMMUTABLE
3996
    AS $_$
3997
SELECT util.schema_regexp(schema_anchor := $1)
3998
$_$;
3999
4000
4001
--
4002 12501 aaronmk
-- Name: schema_regexp(anyelement); Type: FUNCTION; Schema: util; Owner: -
4003
--
4004
4005
CREATE FUNCTION schema_regexp(schema_anchor anyelement) RETURNS text
4006
    LANGUAGE sql IMMUTABLE
4007
    AS $_$
4008
SELECT util.str_equality_regexp(util.schema($1))
4009
$_$;
4010
4011
4012
--
4013 12132 aaronmk
-- Name: schema_rename(text, text); Type: FUNCTION; Schema: util; Owner: -
4014
--
4015
4016
CREATE FUNCTION schema_rename(old text, new text) RETURNS void
4017
    LANGUAGE sql
4018
    AS $_$
4019
SELECT util.eval($$ALTER SCHEMA $$||quote_ident($1)||$$ RENAME TO $$||quote_ident($2));
4020
$_$;
4021
4022
4023
--
4024 12133 aaronmk
-- Name: schema_replace(text, text); Type: FUNCTION; Schema: util; Owner: -
4025
--
4026
4027
CREATE FUNCTION schema_replace(replace text, with_ text) RETURNS void
4028
    LANGUAGE plpgsql
4029
    AS $$
4030
BEGIN
4031
	-- don't schema_rm() the schema to keep!
4032
	IF replace = with_ THEN RETURN; END IF;
4033
4034
	PERFORM util.schema_rm(replace);
4035
	PERFORM util.schema_rename(with_, replace);
4036
END;
4037
$$;
4038
4039
4040
--
4041 12132 aaronmk
-- Name: schema_rm(text); Type: FUNCTION; Schema: util; Owner: -
4042
--
4043
4044
CREATE FUNCTION schema_rm(schema text) RETURNS void
4045
    LANGUAGE sql
4046
    AS $_$
4047
SELECT util.eval($$DROP SCHEMA IF EXISTS $$||quote_ident($1)||$$ CASCADE$$);
4048
$_$;
4049
4050
4051
--
4052 9825 aaronmk
-- Name: search_path_append(text); Type: FUNCTION; Schema: util; Owner: -
4053
--
4054
4055
CREATE FUNCTION search_path_append(schemas text) RETURNS void
4056 12446 aaronmk
    LANGUAGE sql
4057 9825 aaronmk
    AS $_$
4058
SELECT util.eval(
4059
$$SET search_path TO $$||current_setting('search_path')||$$, $$||$1);
4060
$_$;
4061
4062
4063
--
4064 13565 aaronmk
-- Name: seq__create(text, integer); Type: FUNCTION; Schema: util; Owner: -
4065
--
4066
4067
CREATE FUNCTION seq__create(seq text, start integer DEFAULT 0) RETURNS void
4068
    LANGUAGE sql
4069
    AS $_$
4070
SELECT util.create_if_not_exists($$CREATE SEQUENCE $$||$1||$$ MINVALUE $$||$2,
4071
$1)
4072
$_$;
4073
4074
4075
--
4076
-- Name: FUNCTION seq__create(seq text, start integer); Type: COMMENT; Schema: util; Owner: -
4077
--
4078
4079
COMMENT ON FUNCTION seq__create(seq text, start integer) IS '
4080
idempotent
4081
';
4082
4083
4084
--
4085 13566 aaronmk
-- Name: seq__reset(text, integer); Type: FUNCTION; Schema: util; Owner: -
4086
--
4087
4088
CREATE FUNCTION seq__reset(seq text, start integer DEFAULT 0) RETURNS void
4089
    LANGUAGE sql
4090
    AS $_$
4091
SELECT util.seq__create($1, $2);
4092
SELECT util.eval($$ALTER SEQUENCE $$||$1||$$ RESTART$$);
4093
$_$;
4094
4095
4096
--
4097
-- Name: FUNCTION seq__reset(seq text, start integer); Type: COMMENT; Schema: util; Owner: -
4098
--
4099
4100
COMMENT ON FUNCTION seq__reset(seq text, start integer) IS '
4101
creates sequence if doesn''t exist
4102
4103
idempotent
4104
4105
start: *note*: only used if sequence doesn''t exist
4106
';
4107
4108
4109
--
4110 8183 aaronmk
-- Name: set_col_names(regclass, regclass); Type: FUNCTION; Schema: util; Owner: -
4111 8153 aaronmk
--
4112
4113
CREATE FUNCTION set_col_names(table_ regclass, names regclass) RETURNS void
4114
    LANGUAGE plpgsql STRICT
4115
    AS $_$
4116
DECLARE
4117 8183 aaronmk
    old text[] = ARRAY(SELECT util.col_names(table_));
4118
    new text[] = ARRAY(SELECT util.map_values(names));
4119 8153 aaronmk
BEGIN
4120
    old = old[1:array_length(new, 1)]; -- truncate to same length
4121 10345 aaronmk
    PERFORM util.eval($$ALTER TABLE $$||$1||$$ RENAME $$||quote_ident(key)
4122
||$$ TO $$||quote_ident(value))
4123 10149 aaronmk
    FROM each(hstore(old, new))
4124
    WHERE value != key -- not same name
4125
    ;
4126 8153 aaronmk
END;
4127
$_$;
4128
4129
4130
--
4131 8183 aaronmk
-- Name: FUNCTION set_col_names(table_ regclass, names regclass); Type: COMMENT; Schema: util; Owner: -
4132 8153 aaronmk
--
4133
4134 12235 aaronmk
COMMENT ON FUNCTION set_col_names(table_ regclass, names regclass) IS '
4135
idempotent
4136
';
4137 8153 aaronmk
4138
4139
--
4140 10145 aaronmk
-- Name: set_col_names_with_metadata(regclass, regclass); Type: FUNCTION; Schema: util; Owner: -
4141
--
4142
4143
CREATE FUNCTION set_col_names_with_metadata(table_ regclass, names regclass) RETURNS void
4144
    LANGUAGE plpgsql STRICT
4145
    AS $_$
4146
DECLARE
4147
	row_ util.map;
4148
BEGIN
4149 10715 aaronmk
	-- rename any metadata cols rather than re-adding them with new names
4150
	BEGIN
4151
		PERFORM util.set_col_names(table_, names);
4152
	EXCEPTION
4153
		WHEN array_subscript_error THEN -- selective suppress
4154
			IF SQLERRM LIKE 'arrays must have same bounds' THEN NULL;
4155
				-- metadata cols not yet added
4156 12568 aaronmk
			ELSE RAISE;
4157 10715 aaronmk
			END IF;
4158
	END;
4159
4160 10157 aaronmk
	FOR row_ IN EXECUTE $$SELECT * FROM $$||names||$$ WHERE "from" LIKE ':%'$$
4161 10145 aaronmk
	LOOP
4162 10147 aaronmk
		PERFORM util.mk_const_col((table_, row_."to"),
4163
			substring(row_."from" from 2));
4164 10145 aaronmk
	END LOOP;
4165
4166
	PERFORM util.set_col_names(table_, names);
4167
END;
4168
$_$;
4169
4170
4171
--
4172
-- Name: FUNCTION set_col_names_with_metadata(table_ regclass, names regclass); Type: COMMENT; Schema: util; Owner: -
4173
--
4174
4175 12235 aaronmk
COMMENT ON FUNCTION set_col_names_with_metadata(table_ regclass, names regclass) IS '
4176
idempotent.
4177
the metadata mappings must be *last* in the names table.
4178
';
4179 10145 aaronmk
4180
4181
--
4182 8183 aaronmk
-- Name: set_col_types(regclass, col_cast[]); Type: FUNCTION; Schema: util; Owner: -
4183 8107 aaronmk
--
4184
4185
CREATE FUNCTION set_col_types(table_ regclass, col_casts col_cast[]) RETURNS void
4186 12733 aaronmk
    LANGUAGE sql
4187 8107 aaronmk
    AS $_$
4188 12734 aaronmk
SELECT util.eval(COALESCE(
4189
$$ALTER TABLE $$||$1||$$
4190 12732 aaronmk
$$||(
4191
	SELECT
4192
	string_agg($$ALTER COLUMN $$||col_name_sql||$$ TYPE $$||target_type
4193
	||$$ USING $$||col_name_sql||$$::$$||target_type, $$
4194
, $$)
4195
	FROM
4196
	(
4197
		SELECT
4198
		  quote_ident(col_name) AS col_name_sql
4199 12733 aaronmk
		, util.col_type(($1, col_name)) AS curr_type
4200 12732 aaronmk
		, type AS target_type
4201 12733 aaronmk
		FROM unnest($2)
4202 12732 aaronmk
	) s
4203
	WHERE curr_type != target_type
4204 12734 aaronmk
), ''))
4205 8107 aaronmk
$_$;
4206
4207
4208
--
4209 8183 aaronmk
-- Name: FUNCTION set_col_types(table_ regclass, col_casts col_cast[]); Type: COMMENT; Schema: util; Owner: -
4210 8107 aaronmk
--
4211
4212 12235 aaronmk
COMMENT ON FUNCTION set_col_types(table_ regclass, col_casts col_cast[]) IS '
4213
idempotent
4214
';
4215 8107 aaronmk
4216
4217
--
4218 12302 aaronmk
-- Name: set_comment(regclass, text); Type: FUNCTION; Schema: util; Owner: -
4219
--
4220
4221
CREATE FUNCTION set_comment(table_ regclass, comment text) RETURNS void
4222 12446 aaronmk
    LANGUAGE sql
4223 12302 aaronmk
    AS $_$
4224 13477 aaronmk
SELECT util.eval(util.mk_set_comment($1, $2))
4225 12302 aaronmk
$_$;
4226
4227
4228
--
4229 12482 aaronmk
-- Name: set_search_path(text, boolean); Type: FUNCTION; Schema: util; Owner: -
4230
--
4231
4232
CREATE FUNCTION set_search_path(search_path text, for_session boolean DEFAULT false) RETURNS void
4233
    LANGUAGE sql
4234
    AS $_$
4235
SELECT util.eval(util.mk_set_search_path($1, $2))
4236
$_$;
4237
4238
4239
--
4240 13468 aaronmk
-- Name: show_create_view(regclass, boolean); Type: FUNCTION; Schema: util; Owner: -
4241 11651 aaronmk
--
4242
4243 13468 aaronmk
CREATE FUNCTION show_create_view(view_ regclass, replace boolean DEFAULT true) RETURNS text
4244 11651 aaronmk
    LANGUAGE sql STABLE
4245
    AS $_$
4246 13468 aaronmk
SELECT $$CREATE$$||(CASE WHEN $2 THEN $$ OR REPLACE$$ ELSE '' END)||$$ VIEW $$
4247
||$1||$$ AS
4248 13838 aaronmk
$$||util.pg_get_viewdef($1)/*no ; because pg_get_viewdef() includes one*/||$$
4249 13505 aaronmk
$$||util.mk_set_relation_metadata($1)
4250 11651 aaronmk
$_$;
4251
4252
4253
--
4254 11655 aaronmk
-- Name: show_grants_for(regclass); Type: FUNCTION; Schema: util; Owner: -
4255
--
4256
4257
CREATE FUNCTION show_grants_for(table_ regclass) RETURNS text
4258
    LANGUAGE sql STABLE
4259
    AS $_$
4260 12269 aaronmk
SELECT string_agg(cmd, '')
4261 11655 aaronmk
FROM
4262
(
4263
	SELECT (CASE WHEN has_table_privilege(user_, $1, 'SELECT') THEN
4264
$$GRANT SELECT ON TABLE $$||$1||$$ TO $$||quote_ident(user_)||$$;
4265
$$ ELSE '' END) AS cmd
4266
	FROM util.grants_users() f (user_)
4267
) s
4268
$_$;
4269
4270
4271
--
4272 12325 aaronmk
-- Name: show_relations_like(text, text, character[]); Type: FUNCTION; Schema: util; Owner: -
4273
--
4274
4275 12670 aaronmk
CREATE FUNCTION show_relations_like(name_regexp text, schema_regexp text DEFAULT ''::text, types character[] DEFAULT ARRAY['c'::text, 'r'::text, 'v'::text]) RETURNS SETOF regclass
4276 12325 aaronmk
    LANGUAGE sql STABLE
4277
    AS $_$
4278
SELECT oid FROM pg_class
4279
WHERE relkind = ANY($3) AND relname ~ $1
4280
AND util.schema_matches(util.schema(relnamespace), $2)
4281
ORDER BY relname
4282
$_$;
4283
4284
4285
--
4286 13478 aaronmk
-- Name: show_set_comment(regclass); Type: FUNCTION; Schema: util; Owner: -
4287
--
4288
4289
CREATE FUNCTION show_set_comment(table_ regclass) RETURNS text
4290
    LANGUAGE sql STABLE
4291
    AS $_$
4292 13480 aaronmk
SELECT util.mk_set_comment($1, util.comment($1))
4293 13478 aaronmk
$_$;
4294
4295
4296
--
4297 12592 aaronmk
-- Name: show_types_like(text, text); Type: FUNCTION; Schema: util; Owner: -
4298
--
4299
4300
CREATE FUNCTION show_types_like(name_regexp text DEFAULT ''::text, schema_regexp text DEFAULT ''::text) RETURNS SETOF regtype
4301
    LANGUAGE sql STABLE
4302
    AS $_$
4303
SELECT oid
4304
FROM pg_type
4305
WHERE typname ~ $1 AND util.schema_matches(util.schema(typnamespace), $2)
4306
ORDER BY typname
4307
$_$;
4308
4309
4310
--
4311 12305 aaronmk
-- Name: show_views_like(text, text); Type: FUNCTION; Schema: util; Owner: -
4312
--
4313
4314 12385 aaronmk
CREATE FUNCTION show_views_like(name_regexp text, schema_regexp text DEFAULT ''::text) RETURNS SETOF regclass
4315 12305 aaronmk
    LANGUAGE sql STABLE
4316
    AS $_$
4317 12385 aaronmk
SELECT * FROM util.show_relations_like($1, $2, ARRAY['v'])
4318 12305 aaronmk
$_$;
4319
4320
4321
--
4322 13907 aaronmk
-- Name: south_america(); Type: FUNCTION; Schema: util; Owner: -
4323
--
4324
4325
CREATE FUNCTION south_america() RETURNS postgis.geometry
4326
    LANGUAGE sql IMMUTABLE
4327
    SET search_path TO util
4328
    AS $$
4329
SELECT util.bounding_box__no_dateline(-56 ~ 13, -82 ~ -34)
4330
$$;
4331
4332
4333
--
4334 12384 aaronmk
-- Name: str_equality_regexp(text); Type: FUNCTION; Schema: util; Owner: -
4335
--
4336
4337
CREATE FUNCTION str_equality_regexp(literal text) RETURNS text
4338
    LANGUAGE sql IMMUTABLE
4339
    AS $_$
4340
SELECT '^'||util.regexp_quote($1)||'$'
4341
$_$;
4342
4343
4344
--
4345 13909 aaronmk
-- Name: subspecies(text); Type: FUNCTION; Schema: util; Owner: -
4346
--
4347
4348
CREATE FUNCTION subspecies(taxon_name text) RETURNS text
4349
    LANGUAGE sql IMMUTABLE
4350
    AS $_$
4351
SELECT (regexp_matches($1, '\ysubsp\. (\S+)'))[1]
4352
$_$;
4353
4354
4355
--
4356 8183 aaronmk
-- Name: table2hstore(regclass); Type: FUNCTION; Schema: util; Owner: -
4357 8144 aaronmk
--
4358
4359
CREATE FUNCTION table2hstore(table_ regclass) RETURNS hstore
4360 8145 aaronmk
    LANGUAGE plpgsql STABLE STRICT
4361 8144 aaronmk
    AS $_$
4362
DECLARE
4363
    hstore hstore;
4364
BEGIN
4365
    EXECUTE $$SELECT hstore(ARRAY(SELECT unnest(ARRAY["from", "to"]) FROM $$||
4366
        table_||$$))$$ INTO STRICT hstore;
4367
    RETURN hstore;
4368
END;
4369
$_$;
4370
4371
4372
--
4373 10184 aaronmk
-- Name: table_flag__get(regclass, text); Type: FUNCTION; Schema: util; Owner: -
4374
--
4375
4376
CREATE FUNCTION table_flag__get(table_ regclass, flag text) RETURNS boolean
4377 12446 aaronmk
    LANGUAGE sql STABLE
4378 10184 aaronmk
    AS $_$
4379
SELECT COUNT(*) > 0 FROM pg_constraint
4380
WHERE conrelid = $1 AND contype = 'c' AND conname = $2
4381
$_$;
4382
4383
4384
--
4385
-- Name: FUNCTION table_flag__get(table_ regclass, flag text); Type: COMMENT; Schema: util; Owner: -
4386
--
4387
4388 12235 aaronmk
COMMENT ON FUNCTION table_flag__get(table_ regclass, flag text) IS '
4389
gets whether a status flag is set by the presence of a table constraint
4390
';
4391 10184 aaronmk
4392
4393
--
4394 10182 aaronmk
-- Name: table_flag__set(regclass, text); Type: FUNCTION; Schema: util; Owner: -
4395
--
4396
4397
CREATE FUNCTION table_flag__set(table_ regclass, flag text) RETURNS void
4398 12446 aaronmk
    LANGUAGE sql
4399 10182 aaronmk
    AS $_$
4400
SELECT util.create_if_not_exists($$ALTER TABLE $$||$1||$$ ADD CONSTRAINT $$
4401
||quote_ident($2)||$$ CHECK (true)$$)
4402
$_$;
4403
4404
4405
--
4406
-- Name: FUNCTION table_flag__set(table_ regclass, flag text); Type: COMMENT; Schema: util; Owner: -
4407
--
4408
4409 12235 aaronmk
COMMENT ON FUNCTION table_flag__set(table_ regclass, flag text) IS '
4410
stores a status flag by the presence of a table constraint.
4411
idempotent.
4412
';
4413 10182 aaronmk
4414
4415
--
4416 10185 aaronmk
-- Name: table_nulls_mapped__get(regclass); Type: FUNCTION; Schema: util; Owner: -
4417
--
4418
4419
CREATE FUNCTION table_nulls_mapped__get(table_ regclass) RETURNS boolean
4420 12446 aaronmk
    LANGUAGE sql STABLE
4421 10185 aaronmk
    AS $_$
4422
SELECT util.table_flag__get($1, 'nulls_mapped')
4423
$_$;
4424
4425
4426
--
4427
-- Name: FUNCTION table_nulls_mapped__get(table_ regclass); Type: COMMENT; Schema: util; Owner: -
4428
--
4429
4430 12235 aaronmk
COMMENT ON FUNCTION table_nulls_mapped__get(table_ regclass) IS '
4431
gets whether a table''s NULL-equivalent strings have been replaced with NULL
4432
';
4433 10185 aaronmk
4434
4435
--
4436 10183 aaronmk
-- Name: table_nulls_mapped__set(regclass); Type: FUNCTION; Schema: util; Owner: -
4437
--
4438
4439
CREATE FUNCTION table_nulls_mapped__set(table_ regclass) RETURNS void
4440 12446 aaronmk
    LANGUAGE sql
4441 10183 aaronmk
    AS $_$
4442
SELECT util.table_flag__set($1, 'nulls_mapped')
4443
$_$;
4444
4445
4446
--
4447
-- Name: FUNCTION table_nulls_mapped__set(table_ regclass); Type: COMMENT; Schema: util; Owner: -
4448
--
4449
4450 12235 aaronmk
COMMENT ON FUNCTION table_nulls_mapped__set(table_ regclass) IS '
4451
sets that a table''s NULL-equivalent strings have been replaced with NULL.
4452
idempotent.
4453
';
4454 10183 aaronmk
4455
4456
--
4457 12652 aaronmk
-- Name: to_freq(regclass); Type: FUNCTION; Schema: util; Owner: -
4458
--
4459
4460
CREATE FUNCTION to_freq(table_ regclass) RETURNS void
4461
    LANGUAGE sql
4462
    AS $_$
4463
-- save data before truncating main table
4464
SELECT util.copy_types_and_data($1, 'pg_temp.__copy');
4465
4466
-- repopulate main table w/ copies column
4467
SELECT util.truncate($1);
4468
SELECT util.eval($$ALTER TABLE $$||$1||$$ ADD COLUMN copies bigint NOT NULL$$);
4469
SELECT util.populate_table($1, $$
4470
SELECT (table_).*, copies
4471
FROM (
4472
	SELECT table_, COUNT(*) AS copies
4473
	FROM pg_temp.__copy table_
4474
	GROUP BY table_
4475
) s
4476
$$);
4477
4478
-- delete temp table so it doesn't stay around until end of connection
4479
SELECT util.drop_table('pg_temp.__copy');
4480
$_$;
4481
4482
4483
--
4484 8183 aaronmk
-- Name: to_global_col_names(regclass); Type: FUNCTION; Schema: util; Owner: -
4485 8088 aaronmk
--
4486
4487
CREATE FUNCTION to_global_col_names(table_ regclass) RETURNS void
4488
    LANGUAGE plpgsql STRICT
4489
    AS $_$
4490
DECLARE
4491
    row record;
4492
BEGIN
4493 8183 aaronmk
    FOR row IN SELECT * FROM util.col_global_names(table_::text::regtype)
4494 8088 aaronmk
    LOOP
4495
        IF row.global_name != row.name THEN
4496
            EXECUTE $$ALTER TABLE $$||table_||$$ RENAME $$
4497
                ||quote_ident(row.name)||$$ TO $$||quote_ident(row.global_name);
4498
        END IF;
4499
    END LOOP;
4500
END;
4501
$_$;
4502
4503
4504
--
4505 8183 aaronmk
-- Name: FUNCTION to_global_col_names(table_ regclass); Type: COMMENT; Schema: util; Owner: -
4506 8088 aaronmk
--
4507
4508 12235 aaronmk
COMMENT ON FUNCTION to_global_col_names(table_ regclass) IS '
4509
idempotent
4510
';
4511 8088 aaronmk
4512
4513
--
4514 12874 aaronmk
-- Name: trim(regclass, regclass, boolean); Type: FUNCTION; Schema: util; Owner: -
4515 10365 aaronmk
--
4516
4517 12874 aaronmk
CREATE FUNCTION "trim"(table_ regclass, names regclass, force boolean DEFAULT true) RETURNS void
4518 12446 aaronmk
    LANGUAGE sql
4519 10365 aaronmk
    AS $_$
4520 12874 aaronmk
SELECT util.drop_column(($1, col), $3) FROM util.added_cols($1, $2) f (col);
4521 10365 aaronmk
SELECT NULL::void; -- don't fold away functions called in previous query
4522
$_$;
4523
4524
4525
--
4526 12874 aaronmk
-- Name: FUNCTION "trim"(table_ regclass, names regclass, force boolean); Type: COMMENT; Schema: util; Owner: -
4527 10365 aaronmk
--
4528
4529 12874 aaronmk
COMMENT ON FUNCTION "trim"(table_ regclass, names regclass, force boolean) IS '
4530
trims table_ to include only columns in the original data
4531
4532
by default, cascadingly drops dependent columns so that they don''t prevent
4533
trim() from succeeding. note that this requires the dependent columns to then be
4534
manually re-created.
4535
4536
idempotent
4537 12235 aaronmk
';
4538 10365 aaronmk
4539
4540
--
4541 8183 aaronmk
-- Name: truncate(regclass); Type: FUNCTION; Schema: util; Owner: -
4542 8142 aaronmk
--
4543
4544
CREATE FUNCTION truncate(table_ regclass) RETURNS void
4545
    LANGUAGE plpgsql STRICT
4546
    AS $_$
4547
BEGIN
4548
    EXECUTE $$TRUNCATE $$||table_||$$ CASCADE$$;
4549
END;
4550
$_$;
4551
4552
4553
--
4554 8183 aaronmk
-- Name: FUNCTION truncate(table_ regclass); Type: COMMENT; Schema: util; Owner: -
4555 8142 aaronmk
--
4556
4557 12235 aaronmk
COMMENT ON FUNCTION truncate(table_ regclass) IS '
4558
idempotent
4559
';
4560 8142 aaronmk
4561
4562
--
4563 12357 aaronmk
-- Name: truncated_prefixed_name_regexp(text, integer); Type: FUNCTION; Schema: util; Owner: -
4564
--
4565
4566
CREATE FUNCTION truncated_prefixed_name_regexp(name text, max_prefix_len integer) RETURNS text
4567
    LANGUAGE sql IMMUTABLE
4568
    AS $_$
4569 12361 aaronmk
SELECT '^(.*)'||util._if(util.name_was_truncated($1, $2),
4570 12362 aaronmk
util.regexp_quote(util.rtrim_n($1, $2))||'.*', util.regexp_quote($1)) ||'$'
4571 12357 aaronmk
$_$;
4572
4573
4574
--
4575 13135 aaronmk
-- Name: try_cast(text, anyelement); Type: FUNCTION; Schema: util; Owner: -
4576
--
4577
4578
CREATE FUNCTION try_cast(value text, ret_type_null anyelement) RETURNS anyelement
4579
    LANGUAGE plpgsql IMMUTABLE
4580
    AS $$
4581
BEGIN
4582
	/* need explicit cast because some types not implicitly-castable, and also
4583
	to make the cast happen inside the try block. (*implicit* casts to the
4584
	return type happen at the end of the function, outside any block.) */
4585
	RETURN util.cast(value, ret_type_null);
4586
EXCEPTION
4587 13493 aaronmk
WHEN   data_exception
4588 13564 aaronmk
	OR invalid_schema_name -- eg. 'pg_temp.__'::regclass
4589 13493 aaronmk
	OR syntax_error_or_access_rule_violation -- eg. ::regclass
4590
	THEN
4591 13135 aaronmk
	PERFORM util.raise('WARNING', SQLERRM);
4592
	RETURN NULL;
4593
END;
4594
$$;
4595
4596
4597
--
4598
-- Name: FUNCTION try_cast(value text, ret_type_null anyelement); Type: COMMENT; Schema: util; Owner: -
4599
--
4600
4601
COMMENT ON FUNCTION try_cast(value text, ret_type_null anyelement) IS '
4602
ret_type_null: NULL::ret_type
4603
';
4604
4605
4606
--
4607 8199 aaronmk
-- Name: try_create(text); Type: FUNCTION; Schema: util; Owner: -
4608
--
4609
4610
CREATE FUNCTION try_create(sql text) RETURNS void
4611
    LANGUAGE plpgsql STRICT
4612
    AS $$
4613
BEGIN
4614 12658 aaronmk
	PERFORM util.eval(sql);
4615 8199 aaronmk
EXCEPTION
4616 12676 aaronmk
WHEN   not_null_violation
4617
		/* trying to add NOT NULL column to parent table, which cascades to
4618
		child table whose values for the new column will be NULL */
4619
	OR wrong_object_type -- trying to alter a view's columns
4620
	OR undefined_column
4621
	OR duplicate_column
4622
THEN NULL;
4623 12684 aaronmk
WHEN datatype_mismatch THEN
4624
	IF SQLERRM LIKE 'child table is missing column %' THEN NULL;
4625
	ELSE RAISE; -- rethrow
4626
	END IF;
4627 8199 aaronmk
END;
4628
$$;
4629
4630
4631
--
4632
-- Name: FUNCTION try_create(sql text); Type: COMMENT; Schema: util; Owner: -
4633
--
4634
4635 12235 aaronmk
COMMENT ON FUNCTION try_create(sql text) IS '
4636
idempotent
4637
';
4638 8199 aaronmk
4639
4640
--
4641 8209 aaronmk
-- Name: try_mk_derived_col(col_ref, text); Type: FUNCTION; Schema: util; Owner: -
4642
--
4643
4644
CREATE FUNCTION try_mk_derived_col(col col_ref, expr text) RETURNS void
4645 12446 aaronmk
    LANGUAGE sql
4646 8209 aaronmk
    AS $_$
4647
SELECT util.try_create($$SELECT util.mk_derived_col($$||quote_literal($1)||$$, $$||quote_literal($2)||$$)$$)
4648
$_$;
4649
4650
4651
--
4652
-- Name: FUNCTION try_mk_derived_col(col col_ref, expr text); Type: COMMENT; Schema: util; Owner: -
4653
--
4654
4655 12235 aaronmk
COMMENT ON FUNCTION try_mk_derived_col(col col_ref, expr text) IS '
4656
idempotent
4657
';
4658 8209 aaronmk
4659
4660
--
4661 8189 aaronmk
-- Name: type_qual(anyelement); Type: FUNCTION; Schema: util; Owner: -
4662
--
4663
4664
CREATE FUNCTION type_qual(value anyelement) RETURNS text
4665
    LANGUAGE sql IMMUTABLE
4666
    AS $_$
4667
SELECT CASE WHEN $1 IS NULL THEN '' ELSE $$ NOT NULL$$ END
4668
$_$;
4669
4670
4671
--
4672 10161 aaronmk
-- Name: FUNCTION type_qual(value anyelement); Type: COMMENT; Schema: util; Owner: -
4673
--
4674
4675 12235 aaronmk
COMMENT ON FUNCTION type_qual(value anyelement) IS '
4676
a type''s NOT NULL qualifier
4677
';
4678 10161 aaronmk
4679
4680
--
4681 12562 aaronmk
-- Name: typed_cols(regtype); Type: FUNCTION; Schema: util; Owner: -
4682
--
4683
4684
CREATE FUNCTION typed_cols(type regtype) RETURNS SETOF col_cast
4685 12590 aaronmk
    LANGUAGE sql STABLE
4686 12562 aaronmk
    AS $_$
4687
SELECT (attname::text, atttypid)::util.col_cast
4688
FROM pg_attribute
4689
WHERE attrelid = $1::text::regclass AND attnum >= 1 AND NOT attisdropped
4690
ORDER BY attnum
4691
$_$;
4692
4693
4694
--
4695 12438 aaronmk
-- Name: typeof(anyelement); Type: FUNCTION; Schema: util; Owner: -
4696
--
4697
4698
CREATE FUNCTION typeof(value anyelement) RETURNS text
4699
    LANGUAGE sql IMMUTABLE
4700
    AS $_$
4701
SELECT util.qual_name(pg_typeof($1))
4702
$_$;
4703
4704
4705
--
4706 8185 aaronmk
-- Name: typeof(text, regtype); Type: FUNCTION; Schema: util; Owner: -
4707
--
4708
4709 10160 aaronmk
CREATE FUNCTION typeof(expr text, table_ regtype DEFAULT NULL::regtype) RETURNS regtype
4710
    LANGUAGE plpgsql STABLE
4711 8185 aaronmk
    AS $_$
4712
DECLARE
4713
    type regtype;
4714
BEGIN
4715 10160 aaronmk
    EXECUTE $$SELECT pg_typeof($$||expr||$$)$$||
4716
COALESCE($$ FROM (SELECT (NULL::$$||table_||$$).*) _s$$, '') INTO STRICT type;
4717 8185 aaronmk
    RETURN type;
4718
END;
4719
$_$;
4720
4721
4722
--
4723 12490 aaronmk
-- Name: use_schema(anyelement); Type: FUNCTION; Schema: util; Owner: -
4724 12483 aaronmk
--
4725
4726 12490 aaronmk
CREATE FUNCTION use_schema(schema_anchor anyelement) RETURNS void
4727 12483 aaronmk
    LANGUAGE sql
4728
    AS $_$
4729 12488 aaronmk
SELECT util.set_search_path(util.mk_search_path(util.schema($1)))
4730 12483 aaronmk
$_$;
4731
4732
4733
--
4734 12490 aaronmk
-- Name: FUNCTION use_schema(schema_anchor anyelement); Type: COMMENT; Schema: util; Owner: -
4735 12488 aaronmk
--
4736
4737 12490 aaronmk
COMMENT ON FUNCTION use_schema(schema_anchor anyelement) IS '
4738 12488 aaronmk
auto-appends util to the search_path to enable use of util operators
4739
';
4740
4741
4742
--
4743 13639 aaronmk
-- Name: view_def_to_orig(text); Type: FUNCTION; Schema: util; Owner: -
4744
--
4745
4746
CREATE FUNCTION view_def_to_orig(view_def text) RETURNS text
4747
    LANGUAGE sql IMMUTABLE
4748
    AS $_$
4749 13841 aaronmk
SELECT CASE
4750
WHEN util.view_is_subset($1) THEN $1
4751
	-- list of cols from the same table is not an expanded * expression
4752
ELSE
4753 13645 aaronmk
regexp_replace(
4754
regexp_replace(
4755
$1
4756
,
4757 13644 aaronmk
/* unexpand expanded * expressions. any list of 6+ cols from the same table is
4758 13639 aaronmk
treated as a * expression. */
4759 13643 aaronmk
'((?:"[^"\s]+"|\w+)\.)(?:"[^"\s]+"|\w+)'||
4760
	/* 1st col, which lacks separator before.
4761
	*note*: can't prepend \y because it considers only \w chars, not " */
4762 13639 aaronmk
'(,[[:blank:]]*
4763 13642 aaronmk
[[:blank:]]*)\1(?:"[^"\s]+"|\w+)'|| -- 2nd col, which has separator before
4764
'(?:\2\1(?:"[^"\s]+"|\w+)){4,}', -- later cols, w/ same table name and separator
4765 13645 aaronmk
'\1*'/*prefix w/ table*/,
4766
'g')
4767
,
4768
/* merge .* expressions resulting from a SELECT * of a join. any list of
4769
multiple .* expressions is treated as a SELECT * . */
4770
'(?:"[^"\s]+"|\w+)\.\*'||
4771
	/* 1st table, which lacks separator before.
4772
	*note*: can't prepend \y because it considers only \w chars, not " */
4773
'(,[[:blank:]]*
4774
[[:blank:]]*)(?:"[^"\s]+"|\w+)\.\*'|| -- 2nd table, which has separator before
4775
'(?:\1(?:"[^"\s]+"|\w+)\.\*)*', -- later tables, w/ same separator
4776
'*',
4777
'g')
4778 13841 aaronmk
END
4779 13639 aaronmk
$_$;
4780
4781
4782
--
4783 13839 aaronmk
-- Name: view_is_automatically_updatable(text); Type: FUNCTION; Schema: util; Owner: -
4784
--
4785
4786
CREATE FUNCTION view_is_automatically_updatable(view_def text) RETURNS boolean
4787
    LANGUAGE sql IMMUTABLE
4788
    AS $_$
4789
SELECT $1 !~ '\y(?:JOIN|WITH|DISTINCT|GROUP BY|HAVING|LIMIT|OFFSET)\y'
4790
	/* from http://www.postgresql.org/docs/9.3/static/sql-createview.html#SQL-CREATEVIEW-UPDATABLE-VIEWS */
4791
$_$;
4792
4793
4794
--
4795 13840 aaronmk
-- Name: view_is_subset(text); Type: FUNCTION; Schema: util; Owner: -
4796
--
4797
4798
CREATE FUNCTION view_is_subset(view_def text) RETURNS boolean
4799
    LANGUAGE sql IMMUTABLE
4800
    AS $_$
4801
SELECT util.view_is_automatically_updatable($1)
4802
$_$;
4803
4804
4805
--
4806 9959 aaronmk
-- Name: all_same(anyelement); Type: AGGREGATE; Schema: util; Owner: -
4807
--
4808
4809
CREATE AGGREGATE all_same(anyelement) (
4810
    SFUNC = all_same_transform,
4811
    STYPE = anyarray,
4812
    FINALFUNC = all_same_final
4813
);
4814
4815
4816
--
4817
-- Name: AGGREGATE all_same(anyelement); Type: COMMENT; Schema: util; Owner: -
4818
--
4819
4820 12235 aaronmk
COMMENT ON AGGREGATE all_same(anyelement) IS '
4821
includes NULLs in comparison
4822
';
4823 9959 aaronmk
4824
4825
--
4826 8183 aaronmk
-- Name: join_strs(text, text); Type: AGGREGATE; Schema: util; Owner: -
4827 2595 aaronmk
--
4828
4829
CREATE AGGREGATE join_strs(text, text) (
4830 4052 aaronmk
    SFUNC = join_strs_transform,
4831 4010 aaronmk
    STYPE = text
4832 2595 aaronmk
);
4833
4834
4835 8147 aaronmk
--
4836 12423 aaronmk
-- Name: %==; Type: OPERATOR; Schema: util; Owner: -
4837
--
4838
4839
CREATE OPERATOR %== (
4840 13794 aaronmk
    PROCEDURE = keys_eq,
4841 12423 aaronmk
    LEFTARG = anyelement,
4842
    RIGHTARG = anyelement
4843
);
4844
4845
4846
--
4847
-- Name: OPERATOR %== (anyelement, anyelement); Type: COMMENT; Schema: util; Owner: -
4848
--
4849
4850
COMMENT ON OPERATOR %== (anyelement, anyelement) IS '
4851
returns whether the map-keys of the compared values are the same
4852
(mnemonic: % is the Perl symbol for a hash map)
4853
4854
should be overridden for types that store both keys and values
4855
4856
used in a FULL JOIN to select which columns to join on
4857
';
4858
4859
4860
--
4861 8183 aaronmk
-- Name: ->; Type: OPERATOR; Schema: util; Owner: -
4862 8147 aaronmk
--
4863
4864
CREATE OPERATOR -> (
4865
    PROCEDURE = map_get,
4866
    LEFTARG = regclass,
4867
    RIGHTARG = text
4868
);
4869
4870
4871 10308 aaronmk
--
4872
-- Name: =>; Type: OPERATOR; Schema: util; Owner: -
4873
--
4874
4875
CREATE OPERATOR => (
4876
    PROCEDURE = hstore,
4877 10357 aaronmk
    LEFTARG = text[],
4878 10608 aaronmk
    RIGHTARG = text
4879 10308 aaronmk
);
4880
4881
4882
--
4883 10608 aaronmk
-- Name: OPERATOR => (text[], text); Type: COMMENT; Schema: util; Owner: -
4884 10308 aaronmk
--
4885
4886 12235 aaronmk
COMMENT ON OPERATOR => (text[], text) IS '
4887
usage: array[''key1'', ...]::text[] => ''value''
4888
';
4889 10308 aaronmk
4890
4891 10391 aaronmk
--
4892 10613 aaronmk
-- Name: ?*>=; Type: OPERATOR; Schema: util; Owner: -
4893
--
4894
4895
CREATE OPERATOR ?*>= (
4896
    PROCEDURE = is_populated_more_often_than,
4897
    LEFTARG = anyelement,
4898
    RIGHTARG = anyelement
4899
);
4900
4901
4902
--
4903 10391 aaronmk
-- Name: ?>=; Type: OPERATOR; Schema: util; Owner: -
4904
--
4905
4906
CREATE OPERATOR ?>= (
4907
    PROCEDURE = is_more_complete_than,
4908
    LEFTARG = anyelement,
4909
    RIGHTARG = anyelement
4910
);
4911
4912
4913 11005 aaronmk
--
4914 13814 aaronmk
-- Name: @; Type: OPERATOR; Schema: util; Owner: -
4915
--
4916
4917
CREATE OPERATOR @ (
4918 13895 aaronmk
    PROCEDURE = contained_within__no_dateline,
4919
    LEFTARG = postgis.geometry,
4920
    RIGHTARG = postgis.geometry
4921
);
4922
4923
4924
--
4925 13906 aaronmk
-- Name: @; Type: OPERATOR; Schema: util; Owner: -
4926
--
4927
4928
CREATE OPERATOR @ (
4929
    PROCEDURE = contained_within__no_dateline,
4930
    LEFTARG = geocoord,
4931
    RIGHTARG = postgis.geometry
4932
);
4933
4934
4935
--
4936 11005 aaronmk
-- Name: ||%; Type: OPERATOR; Schema: util; Owner: -
4937
--
4938
4939
CREATE OPERATOR ||% (
4940
    PROCEDURE = concat_esc,
4941
    LEFTARG = text,
4942
    RIGHTARG = text
4943
);
4944
4945
4946
--
4947
-- Name: OPERATOR ||% (text, text); Type: COMMENT; Schema: util; Owner: -
4948
--
4949
4950 12235 aaronmk
COMMENT ON OPERATOR ||% (text, text) IS '
4951
% indicates an identifier, as in Perl hashes and one of the x86 assembler syntaxes for registers
4952
';
4953 11005 aaronmk
4954
4955 2107 aaronmk
--
4956 13790 aaronmk
-- Name: ~; Type: OPERATOR; Schema: util; Owner: -
4957
--
4958
4959
CREATE OPERATOR ~ (
4960 13794 aaronmk
    PROCEDURE = range,
4961 13790 aaronmk
    LEFTARG = numeric,
4962
    RIGHTARG = numeric
4963
);
4964
4965
4966 13897 aaronmk
--
4967
-- Name: ~@; Type: OPERATOR; Schema: util; Owner: -
4968
--
4969
4970
CREATE OPERATOR ~@ (
4971
    PROCEDURE = contained_within_approx,
4972
    LEFTARG = postgis.geography,
4973
    RIGHTARG = postgis.geography
4974
);
4975
4976
4977
--
4978
-- Name: OPERATOR ~@ (postgis.geography, postgis.geography); Type: COMMENT; Schema: util; Owner: -
4979
--
4980
4981
COMMENT ON OPERATOR ~@ (postgis.geography, postgis.geography) IS '
4982
can''t use && because it only compares 2D bounding boxes (which are geometry
4983
objects that do not support geocoordinate wraparound)
4984
';
4985
4986
4987 13900 aaronmk
--
4988
-- Name: ~@; Type: OPERATOR; Schema: util; Owner: -
4989
--
4990
4991
CREATE OPERATOR ~@ (
4992
    PROCEDURE = contained_within_approx,
4993
    LEFTARG = geocoord,
4994
    RIGHTARG = postgis.geography
4995
);
4996
4997
4998 13802 aaronmk
SET search_path = pg_catalog;
4999
5000 13790 aaronmk
--
5001 13802 aaronmk
-- Name: CAST (util.range AS numrange); Type: CAST; Schema: pg_catalog; Owner: -
5002
--
5003
5004
CREATE CAST (util.range AS numrange) WITH FUNCTION util.numrange(util.range) AS IMPLICIT;
5005
5006
5007
SET search_path = util, pg_catalog;
5008
5009
--
5010 8183 aaronmk
-- Name: map; Type: TABLE; Schema: util; Owner: -; Tablespace:
5011 8140 aaronmk
--
5012
5013
CREATE TABLE map (
5014
    "from" text NOT NULL,
5015 8158 aaronmk
    "to" text,
5016
    filter text,
5017
    notes text
5018 8140 aaronmk
);
5019
5020
5021
--
5022 11834 aaronmk
-- Data for Name: explain; Type: TABLE DATA; Schema: util; Owner: -
5023
--
5024
5025
5026
5027
--
5028 8183 aaronmk
-- Data for Name: map; Type: TABLE DATA; Schema: util; Owner: -
5029 8140 aaronmk
--
5030
5031
5032
5033
--
5034 10342 aaronmk
-- Name: map__unique__from; Type: CONSTRAINT; Schema: util; Owner: -; Tablespace:
5035 8140 aaronmk
--
5036
5037
ALTER TABLE ONLY map
5038 10342 aaronmk
    ADD CONSTRAINT map__unique__from UNIQUE ("from");
5039 8140 aaronmk
5040
5041
--
5042 10343 aaronmk
-- Name: map__unique__to; Type: CONSTRAINT; Schema: util; Owner: -; Tablespace:
5043
--
5044
5045
ALTER TABLE ONLY map
5046
    ADD CONSTRAINT map__unique__to UNIQUE ("to");
5047
5048
5049
--
5050 10110 aaronmk
-- Name: map_filter_insert; Type: TRIGGER; Schema: util; Owner: -
5051
--
5052
5053
CREATE TRIGGER map_filter_insert BEFORE INSERT ON map FOR EACH ROW EXECUTE PROCEDURE map_filter_insert();
5054
5055
5056
--
5057 2136 aaronmk
-- PostgreSQL database dump complete
5058
--