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