1
SELECT name, setting FROM pg_settings WHERE name LIKE 'enable%';
3
-------------------+---------
16
CREATE TABLE foo2(fooid int, f2 int);
17
INSERT INTO foo2 VALUES(1, 11);
18
INSERT INTO foo2 VALUES(2, 22);
19
INSERT INTO foo2 VALUES(1, 111);
20
CREATE FUNCTION foot(int) returns setof foo2 as 'SELECT * FROM foo2 WHERE fooid = $1;' LANGUAGE SQL;
21
-- supposed to fail with ERROR
22
select * from foo2, foot(foo2.fooid) z where foo2.f2 = z.f2;
23
ERROR: function expression in FROM cannot refer to other relations of same query level
24
LINE 1: select * from foo2, foot(foo2.fooid) z where foo2.f2 = z.f2;
26
-- function in subselect
27
select * from foo2 where f2 in (select f2 from foot(foo2.fooid) z where z.fooid = foo2.fooid) ORDER BY 1,2;
35
-- function in subselect
36
select * from foo2 where f2 in (select f2 from foot(1) z where z.fooid = foo2.fooid) ORDER BY 1,2;
43
-- function in subselect
44
select * from foo2 where f2 in (select f2 from foot(foo2.fooid) z where z.fooid = 1) ORDER BY 1,2;
52
select foot.fooid, foot.f2 from foot(sin(pi()/2)::int) ORDER BY 1,2;
59
CREATE TABLE foo (fooid int, foosubid int, fooname text, primary key(fooid,foosubid));
60
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "foo_pkey" for table "foo"
61
INSERT INTO foo VALUES(1,1,'Joe');
62
INSERT INTO foo VALUES(1,2,'Ed');
63
INSERT INTO foo VALUES(2,1,'Mary');
64
-- sql, proretset = f, prorettype = b
65
CREATE FUNCTION getfoo(int) RETURNS int AS 'SELECT $1;' LANGUAGE SQL;
66
SELECT * FROM getfoo(1) AS t1;
72
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo(1);
73
SELECT * FROM vw_getfoo;
79
-- sql, proretset = t, prorettype = b
81
DROP FUNCTION getfoo(int);
82
CREATE FUNCTION getfoo(int) RETURNS setof int AS 'SELECT fooid FROM foo WHERE fooid = $1;' LANGUAGE SQL;
83
SELECT * FROM getfoo(1) AS t1;
90
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo(1);
91
SELECT * FROM vw_getfoo;
98
-- sql, proretset = t, prorettype = b
100
DROP FUNCTION getfoo(int);
101
CREATE FUNCTION getfoo(int) RETURNS setof text AS 'SELECT fooname FROM foo WHERE fooid = $1;' LANGUAGE SQL;
102
SELECT * FROM getfoo(1) AS t1;
109
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo(1);
110
SELECT * FROM vw_getfoo;
117
-- sql, proretset = f, prorettype = c
119
DROP FUNCTION getfoo(int);
120
CREATE FUNCTION getfoo(int) RETURNS foo AS 'SELECT * FROM foo WHERE fooid = $1;' LANGUAGE SQL;
121
SELECT * FROM getfoo(1) AS t1;
122
fooid | foosubid | fooname
123
-------+----------+---------
127
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo(1);
128
SELECT * FROM vw_getfoo;
129
fooid | foosubid | fooname
130
-------+----------+---------
134
-- sql, proretset = t, prorettype = c
136
DROP FUNCTION getfoo(int);
137
CREATE FUNCTION getfoo(int) RETURNS setof foo AS 'SELECT * FROM foo WHERE fooid = $1;' LANGUAGE SQL;
138
SELECT * FROM getfoo(1) AS t1;
139
fooid | foosubid | fooname
140
-------+----------+---------
145
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo(1);
146
SELECT * FROM vw_getfoo;
147
fooid | foosubid | fooname
148
-------+----------+---------
153
-- sql, proretset = f, prorettype = record
155
DROP FUNCTION getfoo(int);
156
CREATE FUNCTION getfoo(int) RETURNS RECORD AS 'SELECT * FROM foo WHERE fooid = $1;' LANGUAGE SQL;
157
SELECT * FROM getfoo(1) AS t1(fooid int, foosubid int, fooname text);
158
fooid | foosubid | fooname
159
-------+----------+---------
163
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo(1) AS
164
(fooid int, foosubid int, fooname text);
165
SELECT * FROM vw_getfoo;
166
fooid | foosubid | fooname
167
-------+----------+---------
171
-- sql, proretset = t, prorettype = record
173
DROP FUNCTION getfoo(int);
174
CREATE FUNCTION getfoo(int) RETURNS setof record AS 'SELECT * FROM foo WHERE fooid = $1;' LANGUAGE SQL;
175
SELECT * FROM getfoo(1) AS t1(fooid int, foosubid int, fooname text);
176
fooid | foosubid | fooname
177
-------+----------+---------
182
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo(1) AS
183
(fooid int, foosubid int, fooname text);
184
SELECT * FROM vw_getfoo;
185
fooid | foosubid | fooname
186
-------+----------+---------
191
-- plpgsql, proretset = f, prorettype = b
193
DROP FUNCTION getfoo(int);
194
CREATE FUNCTION getfoo(int) RETURNS int AS 'DECLARE fooint int; BEGIN SELECT fooid into fooint FROM foo WHERE fooid = $1; RETURN fooint; END;' LANGUAGE plpgsql;
195
SELECT * FROM getfoo(1) AS t1;
201
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo(1);
202
SELECT * FROM vw_getfoo;
208
-- plpgsql, proretset = f, prorettype = c
210
DROP FUNCTION getfoo(int);
211
CREATE FUNCTION getfoo(int) RETURNS foo AS 'DECLARE footup foo%ROWTYPE; BEGIN SELECT * into footup FROM foo WHERE fooid = $1; RETURN footup; END;' LANGUAGE plpgsql;
212
SELECT * FROM getfoo(1) AS t1;
213
fooid | foosubid | fooname
214
-------+----------+---------
218
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo(1);
219
SELECT * FROM vw_getfoo;
220
fooid | foosubid | fooname
221
-------+----------+---------
226
DROP FUNCTION getfoo(int);
227
DROP FUNCTION foot(int);
231
CREATE TABLE foorescan (fooid int, foosubid int, fooname text, primary key(fooid,foosubid));
232
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "foorescan_pkey" for table "foorescan"
233
INSERT INTO foorescan values(5000,1,'abc.5000.1');
234
INSERT INTO foorescan values(5001,1,'abc.5001.1');
235
INSERT INTO foorescan values(5002,1,'abc.5002.1');
236
INSERT INTO foorescan values(5003,1,'abc.5003.1');
237
INSERT INTO foorescan values(5004,1,'abc.5004.1');
238
INSERT INTO foorescan values(5005,1,'abc.5005.1');
239
INSERT INTO foorescan values(5006,1,'abc.5006.1');
240
INSERT INTO foorescan values(5007,1,'abc.5007.1');
241
INSERT INTO foorescan values(5008,1,'abc.5008.1');
242
INSERT INTO foorescan values(5009,1,'abc.5009.1');
243
INSERT INTO foorescan values(5000,2,'abc.5000.2');
244
INSERT INTO foorescan values(5001,2,'abc.5001.2');
245
INSERT INTO foorescan values(5002,2,'abc.5002.2');
246
INSERT INTO foorescan values(5003,2,'abc.5003.2');
247
INSERT INTO foorescan values(5004,2,'abc.5004.2');
248
INSERT INTO foorescan values(5005,2,'abc.5005.2');
249
INSERT INTO foorescan values(5006,2,'abc.5006.2');
250
INSERT INTO foorescan values(5007,2,'abc.5007.2');
251
INSERT INTO foorescan values(5008,2,'abc.5008.2');
252
INSERT INTO foorescan values(5009,2,'abc.5009.2');
253
INSERT INTO foorescan values(5000,3,'abc.5000.3');
254
INSERT INTO foorescan values(5001,3,'abc.5001.3');
255
INSERT INTO foorescan values(5002,3,'abc.5002.3');
256
INSERT INTO foorescan values(5003,3,'abc.5003.3');
257
INSERT INTO foorescan values(5004,3,'abc.5004.3');
258
INSERT INTO foorescan values(5005,3,'abc.5005.3');
259
INSERT INTO foorescan values(5006,3,'abc.5006.3');
260
INSERT INTO foorescan values(5007,3,'abc.5007.3');
261
INSERT INTO foorescan values(5008,3,'abc.5008.3');
262
INSERT INTO foorescan values(5009,3,'abc.5009.3');
263
INSERT INTO foorescan values(5000,4,'abc.5000.4');
264
INSERT INTO foorescan values(5001,4,'abc.5001.4');
265
INSERT INTO foorescan values(5002,4,'abc.5002.4');
266
INSERT INTO foorescan values(5003,4,'abc.5003.4');
267
INSERT INTO foorescan values(5004,4,'abc.5004.4');
268
INSERT INTO foorescan values(5005,4,'abc.5005.4');
269
INSERT INTO foorescan values(5006,4,'abc.5006.4');
270
INSERT INTO foorescan values(5007,4,'abc.5007.4');
271
INSERT INTO foorescan values(5008,4,'abc.5008.4');
272
INSERT INTO foorescan values(5009,4,'abc.5009.4');
273
INSERT INTO foorescan values(5000,5,'abc.5000.5');
274
INSERT INTO foorescan values(5001,5,'abc.5001.5');
275
INSERT INTO foorescan values(5002,5,'abc.5002.5');
276
INSERT INTO foorescan values(5003,5,'abc.5003.5');
277
INSERT INTO foorescan values(5004,5,'abc.5004.5');
278
INSERT INTO foorescan values(5005,5,'abc.5005.5');
279
INSERT INTO foorescan values(5006,5,'abc.5006.5');
280
INSERT INTO foorescan values(5007,5,'abc.5007.5');
281
INSERT INTO foorescan values(5008,5,'abc.5008.5');
282
INSERT INTO foorescan values(5009,5,'abc.5009.5');
283
CREATE FUNCTION foorescan(int,int) RETURNS setof foorescan AS 'SELECT * FROM foorescan WHERE fooid >= $1 and fooid < $2 ;' LANGUAGE SQL;
284
--invokes ExecReScanFunctionScan
285
SELECT * FROM foorescan f WHERE f.fooid IN (SELECT fooid FROM foorescan(5002,5004)) ORDER BY 1,2;
286
fooid | foosubid | fooname
287
-------+----------+------------
288
5002 | 1 | abc.5002.1
289
5002 | 2 | abc.5002.2
290
5002 | 3 | abc.5002.3
291
5002 | 4 | abc.5002.4
292
5002 | 5 | abc.5002.5
293
5003 | 1 | abc.5003.1
294
5003 | 2 | abc.5003.2
295
5003 | 3 | abc.5003.3
296
5003 | 4 | abc.5003.4
297
5003 | 5 | abc.5003.5
300
CREATE VIEW vw_foorescan AS SELECT * FROM foorescan(5002,5004);
301
--invokes ExecReScanFunctionScan
302
SELECT * FROM foorescan f WHERE f.fooid IN (SELECT fooid FROM vw_foorescan) ORDER BY 1,2;
303
fooid | foosubid | fooname
304
-------+----------+------------
305
5002 | 1 | abc.5002.1
306
5002 | 2 | abc.5002.2
307
5002 | 3 | abc.5002.3
308
5002 | 4 | abc.5002.4
309
5002 | 5 | abc.5002.5
310
5003 | 1 | abc.5003.1
311
5003 | 2 | abc.5003.2
312
5003 | 3 | abc.5003.3
313
5003 | 4 | abc.5003.4
314
5003 | 5 | abc.5003.5
317
CREATE TABLE barrescan (fooid int primary key);
318
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "barrescan_pkey" for table "barrescan"
319
INSERT INTO barrescan values(5003);
320
INSERT INTO barrescan values(5004);
321
INSERT INTO barrescan values(5005);
322
INSERT INTO barrescan values(5006);
323
INSERT INTO barrescan values(5007);
324
INSERT INTO barrescan values(5008);
325
CREATE FUNCTION foorescan(int) RETURNS setof foorescan AS 'SELECT * FROM foorescan WHERE fooid = $1;' LANGUAGE SQL;
326
--invokes ExecReScanFunctionScan with chgParam != NULL
327
SELECT f.* FROM barrescan b, foorescan f WHERE f.fooid = b.fooid AND b.fooid IN (SELECT fooid FROM foorescan(b.fooid)) ORDER BY 1,2;
328
fooid | foosubid | fooname
329
-------+----------+------------
330
5003 | 1 | abc.5003.1
331
5003 | 2 | abc.5003.2
332
5003 | 3 | abc.5003.3
333
5003 | 4 | abc.5003.4
334
5003 | 5 | abc.5003.5
335
5004 | 1 | abc.5004.1
336
5004 | 2 | abc.5004.2
337
5004 | 3 | abc.5004.3
338
5004 | 4 | abc.5004.4
339
5004 | 5 | abc.5004.5
340
5005 | 1 | abc.5005.1
341
5005 | 2 | abc.5005.2
342
5005 | 3 | abc.5005.3
343
5005 | 4 | abc.5005.4
344
5005 | 5 | abc.5005.5
345
5006 | 1 | abc.5006.1
346
5006 | 2 | abc.5006.2
347
5006 | 3 | abc.5006.3
348
5006 | 4 | abc.5006.4
349
5006 | 5 | abc.5006.5
350
5007 | 1 | abc.5007.1
351
5007 | 2 | abc.5007.2
352
5007 | 3 | abc.5007.3
353
5007 | 4 | abc.5007.4
354
5007 | 5 | abc.5007.5
355
5008 | 1 | abc.5008.1
356
5008 | 2 | abc.5008.2
357
5008 | 3 | abc.5008.3
358
5008 | 4 | abc.5008.4
359
5008 | 5 | abc.5008.5
362
SELECT b.fooid, max(f.foosubid) FROM barrescan b, foorescan f WHERE f.fooid = b.fooid AND b.fooid IN (SELECT fooid FROM foorescan(b.fooid)) GROUP BY b.fooid ORDER BY 1,2;
373
CREATE VIEW fooview1 AS SELECT f.* FROM barrescan b, foorescan f WHERE f.fooid = b.fooid AND b.fooid IN (SELECT fooid FROM foorescan(b.fooid)) ORDER BY 1,2;
374
SELECT * FROM fooview1 AS fv WHERE fv.fooid = 5004;
375
fooid | foosubid | fooname
376
-------+----------+------------
377
5004 | 1 | abc.5004.1
378
5004 | 2 | abc.5004.2
379
5004 | 3 | abc.5004.3
380
5004 | 4 | abc.5004.4
381
5004 | 5 | abc.5004.5
384
CREATE VIEW fooview2 AS SELECT b.fooid, max(f.foosubid) AS maxsubid FROM barrescan b, foorescan f WHERE f.fooid = b.fooid AND b.fooid IN (SELECT fooid FROM foorescan(b.fooid)) GROUP BY b.fooid ORDER BY 1,2;
385
SELECT * FROM fooview2 AS fv WHERE fv.maxsubid = 5;
396
DROP VIEW vw_foorescan;
399
DROP FUNCTION foorescan(int,int);
400
DROP FUNCTION foorescan(int);
401
DROP TABLE foorescan;
402
DROP TABLE barrescan;
404
-- Test cases involving OUT parameters
406
CREATE FUNCTION foo(in f1 int, out f2 int)
407
AS 'select $1+1' LANGUAGE sql;
414
SELECT * FROM foo(42);
420
SELECT * FROM foo(42) AS p(x);
426
-- explicit spec of return type is OK
427
CREATE OR REPLACE FUNCTION foo(in f1 int, out f2 int) RETURNS int
428
AS 'select $1+1' LANGUAGE sql;
429
-- error, wrong result type
430
CREATE OR REPLACE FUNCTION foo(in f1 int, out f2 int) RETURNS float
431
AS 'select $1+1' LANGUAGE sql;
432
ERROR: function result type must be integer because of OUT parameters
433
-- with multiple OUT params you must get a RECORD result
434
CREATE OR REPLACE FUNCTION foo(in f1 int, out f2 int, out f3 text) RETURNS int
435
AS 'select $1+1' LANGUAGE sql;
436
ERROR: function result type must be record because of OUT parameters
437
CREATE OR REPLACE FUNCTION foo(in f1 int, out f2 int, out f3 text)
439
AS 'select $1+1' LANGUAGE sql;
440
ERROR: cannot change return type of existing function
441
HINT: Use DROP FUNCTION first.
442
CREATE OR REPLACE FUNCTION foor(in f1 int, out f2 int, out text)
443
AS $$select $1-1, $1::text || 'z'$$ LANGUAGE sql;
444
SELECT f1, foor(f1) FROM int4_tbl;
446
-------------+----------------------------
448
123456 | (123455,123456z)
449
-123456 | (-123457,-123456z)
450
2147483647 | (2147483646,2147483647z)
451
-2147483647 | (-2147483648,-2147483647z)
454
SELECT * FROM foor(42);
460
SELECT * FROM foor(42) AS p(a,b);
466
CREATE OR REPLACE FUNCTION foob(in f1 int, inout f2 int, out text)
467
AS $$select $2-1, $1::text || 'z'$$ LANGUAGE sql;
468
SELECT f1, foob(f1, f1/2) FROM int4_tbl;
470
-------------+----------------------------
472
123456 | (61727,123456z)
473
-123456 | (-61729,-123456z)
474
2147483647 | (1073741822,2147483647z)
475
-2147483647 | (-1073741824,-2147483647z)
478
SELECT * FROM foob(42, 99);
484
SELECT * FROM foob(42, 99) AS p(a,b);
490
-- Can reference function with or without OUT params for DROP, etc
491
DROP FUNCTION foo(int);
492
DROP FUNCTION foor(in f2 int, out f1 int, out text);
493
DROP FUNCTION foob(in f1 int, inout f2 int);
495
-- For my next trick, polymorphic OUT parameters
497
CREATE FUNCTION dup (f1 anyelement, f2 out anyelement, f3 out anyarray)
498
AS 'select $1, array[$1,$1]' LANGUAGE sql;
505
SELECT dup('xyz'); -- fails
506
ERROR: could not determine polymorphic type because input has type "unknown"
507
SELECT dup('xyz'::text);
513
SELECT * FROM dup('xyz'::text);
519
-- fails, as we are attempting to rename first argument
520
CREATE OR REPLACE FUNCTION dup (inout f2 anyelement, out f3 anyarray)
521
AS 'select $1, array[$1,$1]' LANGUAGE sql;
522
ERROR: cannot change name of input parameter "f1"
523
HINT: Use DROP FUNCTION first.
524
DROP FUNCTION dup(anyelement);
525
-- equivalent behavior, though different name exposed for input arg
526
CREATE OR REPLACE FUNCTION dup (inout f2 anyelement, out f3 anyarray)
527
AS 'select $1, array[$1,$1]' LANGUAGE sql;
534
DROP FUNCTION dup(anyelement);
535
-- fails, no way to deduce outputs
536
CREATE FUNCTION bad (f1 int, out f2 anyelement, out f3 anyarray)
537
AS 'select $1, array[$1,$1]' LANGUAGE sql;
538
ERROR: cannot determine result data type
539
DETAIL: A function returning a polymorphic type must have at least one polymorphic argument.
543
CREATE OR REPLACE FUNCTION foo()
545
AS $$ SELECT a FROM generate_series(1,5) a(a) $$ LANGUAGE sql;
557
CREATE OR REPLACE FUNCTION foo(int)
558
RETURNS TABLE(a int, b int)
560
FROM generate_series(1,$1) a(a),
561
generate_series(1,$1) b(b) $$ LANGUAGE sql;
562
SELECT * FROM foo(3);
576
DROP FUNCTION foo(int);
578
-- some tests on SQL functions with RETURNING
580
create temp table tt(f1 serial, data text);
581
NOTICE: CREATE TABLE will create implicit sequence "tt_f1_seq" for serial column "tt.f1"
582
create function insert_tt(text) returns int as
583
$$ insert into tt(data) values($1) returning f1 $$
585
select insert_tt('foo');
591
select insert_tt('bar');
604
-- insert will execute to completion even if function needs just 1 row
605
create or replace function insert_tt(text) returns int as
606
$$ insert into tt(data) values($1),($1||$1) returning f1 $$
608
select insert_tt('fool');
623
-- setof does what's expected
624
create or replace function insert_tt2(text,text) returns setof int as
625
$$ insert into tt(data) values($1),($2) returning f1 $$
627
select insert_tt2('foolish','barrish');
634
select * from insert_tt2('baz','quux');
654
-- limit doesn't prevent execution to completion
655
select insert_tt2('foolish','barrish') limit 1;
676
-- triggers will fire, too
677
create function noticetrigger() returns trigger as $$
679
raise notice 'noticetrigger % %', new.f1, new.data;
681
end $$ language plpgsql;
682
create trigger tnoticetrigger after insert on tt for each row
683
execute procedure noticetrigger();
684
select insert_tt2('foolme','barme') limit 1;
685
NOTICE: noticetrigger 11 foolme
686
CONTEXT: SQL function "insert_tt2" statement 1
687
NOTICE: noticetrigger 12 barme
688
CONTEXT: SQL function "insert_tt2" statement 1
712
create temp table tt_log(f1 int, data text);
713
create rule insert_tt_rule as on insert to tt do also
714
insert into tt_log values(new.*);
715
select insert_tt2('foollog','barlog') limit 1;
716
NOTICE: noticetrigger 13 foollog
717
CONTEXT: SQL function "insert_tt2" statement 1
718
NOTICE: noticetrigger 14 barlog
719
CONTEXT: SQL function "insert_tt2" statement 1
744
-- note that nextval() gets executed a second time in the rule expansion,
745
-- which is expected.
746
select * from tt_log;
753
-- test case for a whole-row-variable bug
754
create function foo1(n integer, out a text, out b text)
757
as $$ select 'foo ' || i, 'bar ' || i from generate_series(1,$1) i $$;
759
select t.a, t, t.a from foo1(10000) t limit 1;
761
-------+-------------------+-------
762
foo 1 | ("foo 1","bar 1") | foo 1
766
select t.a, t, t.a from foo1(10000) t limit 1;
768
-------+-------------------+-------
769
foo 1 | ("foo 1","bar 1") | foo 1
772
drop function foo1(n integer);
773
-- test use of SQL functions returning record
774
-- this is supported in some cases where the query doesn't specify
775
-- the actual record type ...
776
create function array_to_set(anyarray) returns setof record as $$
777
select i AS "index", $1[i] AS "value" from generate_subscripts($1, 1) i
778
$$ language sql strict immutable;
779
select array_to_set(array['one', 'two']);
786
select * from array_to_set(array['one', 'two']) as t(f1 int,f2 text);
793
select * from array_to_set(array['one', 'two']); -- fail
794
ERROR: a column definition list is required for functions returning "record"
795
LINE 1: select * from array_to_set(array['one', 'two']);
797
create temp table foo(f1 int8, f2 int8);
798
create function testfoo() returns record as $$
799
insert into foo values (1,2) returning *;
807
select * from testfoo() as t(f1 int8,f2 int8);
813
select * from testfoo(); -- fail
814
ERROR: a column definition list is required for functions returning "record"
815
LINE 1: select * from testfoo();
817
drop function testfoo();
818
create function testfoo() returns setof record as $$
819
insert into foo values (1,2), (3,4) returning *;
828
select * from testfoo() as t(f1 int8,f2 int8);
835
select * from testfoo(); -- fail
836
ERROR: a column definition list is required for functions returning "record"
837
LINE 1: select * from testfoo();
839
drop function testfoo();
841
-- Check some cases involving dropped columns in a rowtype result
843
create temp table users (userid text, email text, todrop bool, enabled bool);
844
insert into users values ('id','email',true,true);
845
insert into users values ('id2','email2',true,true);
846
alter table users drop column todrop;
847
create or replace function get_first_user() returns users as
848
$$ SELECT * FROM users ORDER BY userid LIMIT 1; $$
850
SELECT get_first_user();
856
SELECT * FROM get_first_user();
857
userid | email | enabled
858
--------+-------+---------
862
create or replace function get_users() returns setof users as
863
$$ SELECT * FROM users ORDER BY userid; $$
872
SELECT * FROM get_users();
873
userid | email | enabled
874
--------+--------+---------
879
drop function get_first_user();
880
drop function get_users();
882
-- this won't get inlined because of type coercion, but it shouldn't fail
883
create or replace function foobar() returns setof text as
884
$$ select 'foo'::varchar union all select 'bar'::varchar ; $$
893
select * from foobar();
900
drop function foobar();
901
-- check handling of a SQL function with multiple OUT params (bug #5777)
902
create or replace function foobar(out integer, out numeric) as
903
$$ select (1, 2.1) $$ language sql;
904
select * from foobar();
910
create or replace function foobar(out integer, out numeric) as
911
$$ select (1, 2) $$ language sql;
912
select * from foobar(); -- fail
913
ERROR: function return row and query-specified return row do not match
914
DETAIL: Returned type integer at ordinal position 2, but query expects numeric.
915
create or replace function foobar(out integer, out numeric) as
916
$$ select (1, 2.1, 3) $$ language sql;
917
select * from foobar(); -- fail
918
ERROR: function return row and query-specified return row do not match
919
DETAIL: Returned row contains 3 attributes, but query expects 2.
920
drop function foobar();