OSDN Git Service

56f90c597a8d222c43c187299373f69c4a9d85ac
[pg-rex/syncrep.git] / src / test / regress / sql / polymorphism.sql
1 -- Currently this tests polymorphic aggregates and indirectly does some
2 -- testing of polymorphic SQL functions.  It ought to be extended.
3
4
5 -- Legend:
6 -----------
7 -- A = type is ANY
8 -- P = type is polymorphic
9 -- N = type is non-polymorphic
10 -- B = aggregate base type
11 -- S = aggregate state type
12 -- R = aggregate return type
13 -- 1 = arg1 of a function
14 -- 2 = arg2 of a function
15 -- ag = aggregate
16 -- tf = trans (state) function
17 -- ff = final function
18 -- rt = return type of a function
19 -- -> = implies
20 -- => = allowed
21 -- !> = not allowed
22 -- E  = exists
23 -- NE = not-exists
24 -- 
25 -- Possible states:
26 -- ----------------
27 -- B = (A || P || N)
28 --   when (B = A) -> (tf2 = NE)
29 -- S = (P || N)
30 -- ff = (E || NE)
31 -- tf1 = (P || N)
32 -- tf2 = (NE || P || N)
33 -- R = (P || N)
34
35 -- create functions for use as tf and ff with the needed combinations of
36 -- argument polymorphism, but within the constraints of valid aggregate
37 -- functions, i.e. tf arg1 and tf return type must match
38
39 -- polymorphic single arg transfn
40 CREATE FUNCTION stfp(anyarray) RETURNS anyarray AS
41 'select $1' LANGUAGE SQL;
42 -- non-polymorphic single arg transfn
43 CREATE FUNCTION stfnp(int[]) RETURNS int[] AS
44 'select $1' LANGUAGE SQL;
45
46 -- dual polymorphic transfn
47 CREATE FUNCTION tfp(anyarray,anyelement) RETURNS anyarray AS
48 'select $1 || $2' LANGUAGE SQL;
49 -- dual non-polymorphic transfn
50 CREATE FUNCTION tfnp(int[],int) RETURNS int[] AS
51 'select $1 || $2' LANGUAGE SQL;
52
53 -- arg1 only polymorphic transfn
54 CREATE FUNCTION tf1p(anyarray,int) RETURNS anyarray AS
55 'select $1' LANGUAGE SQL;
56 -- arg2 only polymorphic transfn
57 CREATE FUNCTION tf2p(int[],anyelement) RETURNS int[] AS
58 'select $1' LANGUAGE SQL;
59
60 -- multi-arg polymorphic
61 CREATE FUNCTION sum3(anyelement,anyelement,anyelement) returns anyelement AS
62 'select $1+$2+$3' language sql strict;
63
64 -- finalfn polymorphic
65 CREATE FUNCTION ffp(anyarray) RETURNS anyarray AS
66 'select $1' LANGUAGE SQL;
67 -- finalfn non-polymorphic
68 CREATE FUNCTION ffnp(int[]) returns int[] as
69 'select $1' LANGUAGE SQL;
70
71 -- Try to cover all the possible states:
72 -- 
73 -- Note: in Cases 1 & 2, we are trying to return P. Therefore, if the transfn
74 -- is stfnp, tfnp, or tf2p, we must use ffp as finalfn, because stfnp, tfnp,
75 -- and tf2p do not return P. Conversely, in Cases 3 & 4, we are trying to
76 -- return N. Therefore, if the transfn is stfp, tfp, or tf1p, we must use ffnp
77 -- as finalfn, because stfp, tfp, and tf1p do not return N.
78 --
79 --     Case1 (R = P) && (B = A)
80 --     ------------------------
81 --     S    tf1
82 --     -------
83 --     N    N
84 -- should CREATE
85 CREATE AGGREGATE myaggp01a(*) (SFUNC = stfnp, STYPE = int4[],
86   FINALFUNC = ffp, INITCOND = '{}');
87
88 --     P    N
89 -- should ERROR: stfnp(anyarray) not matched by stfnp(int[])
90 CREATE AGGREGATE myaggp02a(*) (SFUNC = stfnp, STYPE = anyarray,
91   FINALFUNC = ffp, INITCOND = '{}');
92
93 --     N    P
94 -- should CREATE
95 CREATE AGGREGATE myaggp03a(*) (SFUNC = stfp, STYPE = int4[],
96   FINALFUNC = ffp, INITCOND = '{}');
97 CREATE AGGREGATE myaggp03b(*) (SFUNC = stfp, STYPE = int4[],
98   INITCOND = '{}');
99
100 --     P    P
101 -- should ERROR: we have no way to resolve S
102 CREATE AGGREGATE myaggp04a(*) (SFUNC = stfp, STYPE = anyarray,
103   FINALFUNC = ffp, INITCOND = '{}');
104 CREATE AGGREGATE myaggp04b(*) (SFUNC = stfp, STYPE = anyarray,
105   INITCOND = '{}');
106
107
108 --    Case2 (R = P) && ((B = P) || (B = N))
109 --    -------------------------------------
110 --    S    tf1      B    tf2
111 --    -----------------------
112 --    N    N        N    N
113 -- should CREATE
114 CREATE AGGREGATE myaggp05a(BASETYPE = int, SFUNC = tfnp, STYPE = int[],
115   FINALFUNC = ffp, INITCOND = '{}');
116
117 --    N    N        N    P
118 -- should CREATE
119 CREATE AGGREGATE myaggp06a(BASETYPE = int, SFUNC = tf2p, STYPE = int[],
120   FINALFUNC = ffp, INITCOND = '{}');
121
122 --    N    N        P    N
123 -- should ERROR: tfnp(int[], anyelement) not matched by tfnp(int[], int)
124 CREATE AGGREGATE myaggp07a(BASETYPE = anyelement, SFUNC = tfnp, STYPE = int[],
125   FINALFUNC = ffp, INITCOND = '{}');
126
127 --    N    N        P    P
128 -- should CREATE
129 CREATE AGGREGATE myaggp08a(BASETYPE = anyelement, SFUNC = tf2p, STYPE = int[],
130   FINALFUNC = ffp, INITCOND = '{}');
131
132 --    N    P        N    N
133 -- should CREATE
134 CREATE AGGREGATE myaggp09a(BASETYPE = int, SFUNC = tf1p, STYPE = int[],
135   FINALFUNC = ffp, INITCOND = '{}');
136 CREATE AGGREGATE myaggp09b(BASETYPE = int, SFUNC = tf1p, STYPE = int[],
137   INITCOND = '{}');
138
139 --    N    P        N    P
140 -- should CREATE
141 CREATE AGGREGATE myaggp10a(BASETYPE = int, SFUNC = tfp, STYPE = int[],
142   FINALFUNC = ffp, INITCOND = '{}');
143 CREATE AGGREGATE myaggp10b(BASETYPE = int, SFUNC = tfp, STYPE = int[],
144   INITCOND = '{}');
145
146 --    N    P        P    N
147 -- should ERROR: tf1p(int[],anyelement) not matched by tf1p(anyarray,int)
148 CREATE AGGREGATE myaggp11a(BASETYPE = anyelement, SFUNC = tf1p, STYPE = int[],
149   FINALFUNC = ffp, INITCOND = '{}');
150 CREATE AGGREGATE myaggp11b(BASETYPE = anyelement, SFUNC = tf1p, STYPE = int[],
151   INITCOND = '{}');
152
153 --    N    P        P    P
154 -- should ERROR: tfp(int[],anyelement) not matched by tfp(anyarray,anyelement)
155 CREATE AGGREGATE myaggp12a(BASETYPE = anyelement, SFUNC = tfp, STYPE = int[],
156   FINALFUNC = ffp, INITCOND = '{}');
157 CREATE AGGREGATE myaggp12b(BASETYPE = anyelement, SFUNC = tfp, STYPE = int[],
158   INITCOND = '{}');
159
160 --    P    N        N    N
161 -- should ERROR: tfnp(anyarray, int) not matched by tfnp(int[],int)
162 CREATE AGGREGATE myaggp13a(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray,
163   FINALFUNC = ffp, INITCOND = '{}');
164
165 --    P    N        N    P
166 -- should ERROR: tf2p(anyarray, int) not matched by tf2p(int[],anyelement)
167 CREATE AGGREGATE myaggp14a(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray,
168   FINALFUNC = ffp, INITCOND = '{}');
169
170 --    P    N        P    N
171 -- should ERROR: tfnp(anyarray, anyelement) not matched by tfnp(int[],int)
172 CREATE AGGREGATE myaggp15a(BASETYPE = anyelement, SFUNC = tfnp,
173   STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}');
174
175 --    P    N        P    P
176 -- should ERROR: tf2p(anyarray, anyelement) not matched by tf2p(int[],anyelement)
177 CREATE AGGREGATE myaggp16a(BASETYPE = anyelement, SFUNC = tf2p,
178   STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}');
179
180 --    P    P        N    N
181 -- should ERROR: we have no way to resolve S
182 CREATE AGGREGATE myaggp17a(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray,
183   FINALFUNC = ffp, INITCOND = '{}');
184 CREATE AGGREGATE myaggp17b(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray,
185   INITCOND = '{}');
186
187 --    P    P        N    P
188 -- should ERROR: tfp(anyarray, int) not matched by tfp(anyarray, anyelement)
189 CREATE AGGREGATE myaggp18a(BASETYPE = int, SFUNC = tfp, STYPE = anyarray,
190   FINALFUNC = ffp, INITCOND = '{}');
191 CREATE AGGREGATE myaggp18b(BASETYPE = int, SFUNC = tfp, STYPE = anyarray,
192   INITCOND = '{}');
193
194 --    P    P        P    N
195 -- should ERROR: tf1p(anyarray, anyelement) not matched by tf1p(anyarray, int)
196 CREATE AGGREGATE myaggp19a(BASETYPE = anyelement, SFUNC = tf1p,
197   STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}');
198 CREATE AGGREGATE myaggp19b(BASETYPE = anyelement, SFUNC = tf1p,
199   STYPE = anyarray, INITCOND = '{}');
200
201 --    P    P        P    P
202 -- should CREATE
203 CREATE AGGREGATE myaggp20a(BASETYPE = anyelement, SFUNC = tfp,
204   STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}');
205 CREATE AGGREGATE myaggp20b(BASETYPE = anyelement, SFUNC = tfp,
206   STYPE = anyarray, INITCOND = '{}');
207
208 --     Case3 (R = N) && (B = A)
209 --     ------------------------
210 --     S    tf1
211 --     -------
212 --     N    N
213 -- should CREATE
214 CREATE AGGREGATE myaggn01a(*) (SFUNC = stfnp, STYPE = int4[],
215   FINALFUNC = ffnp, INITCOND = '{}');
216 CREATE AGGREGATE myaggn01b(*) (SFUNC = stfnp, STYPE = int4[],
217   INITCOND = '{}');
218
219 --     P    N
220 -- should ERROR: stfnp(anyarray) not matched by stfnp(int[])
221 CREATE AGGREGATE myaggn02a(*) (SFUNC = stfnp, STYPE = anyarray,
222   FINALFUNC = ffnp, INITCOND = '{}');
223 CREATE AGGREGATE myaggn02b(*) (SFUNC = stfnp, STYPE = anyarray,
224   INITCOND = '{}');
225
226 --     N    P
227 -- should CREATE
228 CREATE AGGREGATE myaggn03a(*) (SFUNC = stfp, STYPE = int4[],
229   FINALFUNC = ffnp, INITCOND = '{}');
230
231 --     P    P
232 -- should ERROR: ffnp(anyarray) not matched by ffnp(int[])
233 CREATE AGGREGATE myaggn04a(*) (SFUNC = stfp, STYPE = anyarray,
234   FINALFUNC = ffnp, INITCOND = '{}');
235
236
237 --    Case4 (R = N) && ((B = P) || (B = N))
238 --    -------------------------------------
239 --    S    tf1      B    tf2
240 --    -----------------------
241 --    N    N        N    N
242 -- should CREATE
243 CREATE AGGREGATE myaggn05a(BASETYPE = int, SFUNC = tfnp, STYPE = int[],
244   FINALFUNC = ffnp, INITCOND = '{}');
245 CREATE AGGREGATE myaggn05b(BASETYPE = int, SFUNC = tfnp, STYPE = int[],
246   INITCOND = '{}');
247
248 --    N    N        N    P
249 -- should CREATE
250 CREATE AGGREGATE myaggn06a(BASETYPE = int, SFUNC = tf2p, STYPE = int[],
251   FINALFUNC = ffnp, INITCOND = '{}');
252 CREATE AGGREGATE myaggn06b(BASETYPE = int, SFUNC = tf2p, STYPE = int[],
253   INITCOND = '{}');
254
255 --    N    N        P    N
256 -- should ERROR: tfnp(int[], anyelement) not matched by tfnp(int[], int)
257 CREATE AGGREGATE myaggn07a(BASETYPE = anyelement, SFUNC = tfnp, STYPE = int[],
258   FINALFUNC = ffnp, INITCOND = '{}');
259 CREATE AGGREGATE myaggn07b(BASETYPE = anyelement, SFUNC = tfnp, STYPE = int[],
260   INITCOND = '{}');
261
262 --    N    N        P    P
263 -- should CREATE
264 CREATE AGGREGATE myaggn08a(BASETYPE = anyelement, SFUNC = tf2p, STYPE = int[],
265   FINALFUNC = ffnp, INITCOND = '{}');
266 CREATE AGGREGATE myaggn08b(BASETYPE = anyelement, SFUNC = tf2p, STYPE = int[],
267   INITCOND = '{}');
268
269 --    N    P        N    N
270 -- should CREATE
271 CREATE AGGREGATE myaggn09a(BASETYPE = int, SFUNC = tf1p, STYPE = int[],
272   FINALFUNC = ffnp, INITCOND = '{}');
273
274 --    N    P        N    P
275 -- should CREATE
276 CREATE AGGREGATE myaggn10a(BASETYPE = int, SFUNC = tfp, STYPE = int[],
277   FINALFUNC = ffnp, INITCOND = '{}');
278
279 --    N    P        P    N
280 -- should ERROR: tf1p(int[],anyelement) not matched by tf1p(anyarray,int)
281 CREATE AGGREGATE myaggn11a(BASETYPE = anyelement, SFUNC = tf1p, STYPE = int[],
282   FINALFUNC = ffnp, INITCOND = '{}');
283
284 --    N    P        P    P
285 -- should ERROR: tfp(int[],anyelement) not matched by tfp(anyarray,anyelement)
286 CREATE AGGREGATE myaggn12a(BASETYPE = anyelement, SFUNC = tfp, STYPE = int[],
287   FINALFUNC = ffnp, INITCOND = '{}');
288
289 --    P    N        N    N
290 -- should ERROR: tfnp(anyarray, int) not matched by tfnp(int[],int)
291 CREATE AGGREGATE myaggn13a(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray,
292   FINALFUNC = ffnp, INITCOND = '{}');
293 CREATE AGGREGATE myaggn13b(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray,
294   INITCOND = '{}');
295
296 --    P    N        N    P
297 -- should ERROR: tf2p(anyarray, int) not matched by tf2p(int[],anyelement)
298 CREATE AGGREGATE myaggn14a(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray,
299   FINALFUNC = ffnp, INITCOND = '{}');
300 CREATE AGGREGATE myaggn14b(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray,
301   INITCOND = '{}');
302
303 --    P    N        P    N
304 -- should ERROR: tfnp(anyarray, anyelement) not matched by tfnp(int[],int)
305 CREATE AGGREGATE myaggn15a(BASETYPE = anyelement, SFUNC = tfnp,
306   STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}');
307 CREATE AGGREGATE myaggn15b(BASETYPE = anyelement, SFUNC = tfnp,
308   STYPE = anyarray, INITCOND = '{}');
309
310 --    P    N        P    P
311 -- should ERROR: tf2p(anyarray, anyelement) not matched by tf2p(int[],anyelement)
312 CREATE AGGREGATE myaggn16a(BASETYPE = anyelement, SFUNC = tf2p,
313   STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}');
314 CREATE AGGREGATE myaggn16b(BASETYPE = anyelement, SFUNC = tf2p,
315   STYPE = anyarray, INITCOND = '{}');
316
317 --    P    P        N    N
318 -- should ERROR: ffnp(anyarray) not matched by ffnp(int[])
319 CREATE AGGREGATE myaggn17a(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray,
320   FINALFUNC = ffnp, INITCOND = '{}');
321
322 --    P    P        N    P
323 -- should ERROR: tfp(anyarray, int) not matched by tfp(anyarray, anyelement)
324 CREATE AGGREGATE myaggn18a(BASETYPE = int, SFUNC = tfp, STYPE = anyarray,
325   FINALFUNC = ffnp, INITCOND = '{}');
326
327 --    P    P        P    N
328 -- should ERROR: tf1p(anyarray, anyelement) not matched by tf1p(anyarray, int)
329 CREATE AGGREGATE myaggn19a(BASETYPE = anyelement, SFUNC = tf1p,
330   STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}');
331
332 --    P    P        P    P
333 -- should ERROR: ffnp(anyarray) not matched by ffnp(int[])
334 CREATE AGGREGATE myaggn20a(BASETYPE = anyelement, SFUNC = tfp,
335   STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}');
336
337 -- multi-arg polymorphic
338 CREATE AGGREGATE mysum2(anyelement,anyelement) (SFUNC = sum3,
339   STYPE = anyelement, INITCOND = '0');
340
341 -- create test data for polymorphic aggregates
342 create temp table t(f1 int, f2 int[], f3 text);
343 insert into t values(1,array[1],'a');
344 insert into t values(1,array[11],'b');
345 insert into t values(1,array[111],'c');
346 insert into t values(2,array[2],'a');
347 insert into t values(2,array[22],'b');
348 insert into t values(2,array[222],'c');
349 insert into t values(3,array[3],'a');
350 insert into t values(3,array[3],'b');
351
352 -- test the successfully created polymorphic aggregates
353 select f3, myaggp01a(*) from t group by f3;
354 select f3, myaggp03a(*) from t group by f3;
355 select f3, myaggp03b(*) from t group by f3;
356 select f3, myaggp05a(f1) from t group by f3;
357 select f3, myaggp06a(f1) from t group by f3;
358 select f3, myaggp08a(f1) from t group by f3;
359 select f3, myaggp09a(f1) from t group by f3;
360 select f3, myaggp09b(f1) from t group by f3;
361 select f3, myaggp10a(f1) from t group by f3;
362 select f3, myaggp10b(f1) from t group by f3;
363 select f3, myaggp20a(f1) from t group by f3;
364 select f3, myaggp20b(f1) from t group by f3;
365 select f3, myaggn01a(*) from t group by f3;
366 select f3, myaggn01b(*) from t group by f3;
367 select f3, myaggn03a(*) from t group by f3;
368 select f3, myaggn05a(f1) from t group by f3;
369 select f3, myaggn05b(f1) from t group by f3;
370 select f3, myaggn06a(f1) from t group by f3;
371 select f3, myaggn06b(f1) from t group by f3;
372 select f3, myaggn08a(f1) from t group by f3;
373 select f3, myaggn08b(f1) from t group by f3;
374 select f3, myaggn09a(f1) from t group by f3;
375 select f3, myaggn10a(f1) from t group by f3;
376 select mysum2(f1, f1 + 1) from t;
377
378 -- test inlining of polymorphic SQL functions
379 create function bleat(int) returns int as $$
380 begin
381   raise notice 'bleat %', $1;
382   return $1;
383 end$$ language plpgsql;
384
385 create function sql_if(bool, anyelement, anyelement) returns anyelement as $$
386 select case when $1 then $2 else $3 end $$ language sql;
387
388 -- Note this would fail with integer overflow, never mind wrong bleat() output,
389 -- if the CASE expression were not successfully inlined
390 select f1, sql_if(f1 > 0, bleat(f1), bleat(f1 + 1)) from int4_tbl;
391
392 select q2, sql_if(q2 > 0, q2, q2 + 1) from int8_tbl;
393
394 -- another kind of polymorphic aggregate
395
396 create function add_group(grp anyarray, ad anyelement, size integer)
397   returns anyarray
398   as $$
399 begin
400   if grp is null then
401     return array[ad];
402   end if;
403   if array_upper(grp, 1) < size then
404     return grp || ad;
405   end if;
406   return grp;
407 end;
408 $$
409   language plpgsql immutable;
410
411 create aggregate build_group(anyelement, integer) (
412   SFUNC = add_group,
413   STYPE = anyarray
414 );
415
416 select build_group(q1,3) from int8_tbl;
417
418 -- this should fail because stype isn't compatible with arg
419 create aggregate build_group(int8, integer) (
420   SFUNC = add_group,
421   STYPE = int2[]
422 );
423
424 -- but we can make a non-poly agg from a poly sfunc if types are OK
425 create aggregate build_group(int8, integer) (
426   SFUNC = add_group,
427   STYPE = int8[]
428 );
429
430 -- test variadic polymorphic functions
431
432 create function myleast(variadic anyarray) returns anyelement as $$
433   select min($1[i]) from generate_subscripts($1,1) g(i)
434 $$ language sql immutable strict;
435
436 select myleast(10, 1, 20, 33);
437 select myleast(1.1, 0.22, 0.55);
438 select myleast('z'::text);
439 select myleast(); -- fail
440
441 -- test with variadic call parameter
442 select myleast(variadic array[1,2,3,4,-1]);
443 select myleast(variadic array[1.1, -5.5]);
444
445 --test with empty variadic call parameter
446 select myleast(variadic array[]::int[]);
447
448 -- an example with some ordinary arguments too
449 create function concat(text, variadic anyarray) returns text as $$
450   select array_to_string($2, $1);
451 $$ language sql immutable strict;
452
453 select concat('%', 1, 2, 3, 4, 5);
454 select concat('|', 'a'::text, 'b', 'c');
455 select concat('|', variadic array[1,2,33]);
456 select concat('|', variadic array[]::int[]);
457
458 drop function concat(text, anyarray);
459
460 -- mix variadic with anyelement
461 create function formarray(anyelement, variadic anyarray) returns anyarray as $$
462   select array_prepend($1, $2);
463 $$ language sql immutable strict;
464
465 select formarray(1,2,3,4,5);
466 select formarray(1.1, variadic array[1.2,55.5]);
467 select formarray(1.1, array[1.2,55.5]); -- fail without variadic
468 select formarray(1, 'x'::text); -- fail, type mismatch
469 select formarray(1, variadic array['x'::text]); -- fail, type mismatch
470
471 drop function formarray(anyelement, variadic anyarray);
472
473 -- test pg_typeof() function
474 select pg_typeof(null);           -- unknown
475 select pg_typeof(0);              -- integer
476 select pg_typeof(0.0);            -- numeric
477 select pg_typeof(1+1 = 2);        -- boolean
478 select pg_typeof('x');            -- unknown
479 select pg_typeof('' || '');       -- text
480 select pg_typeof(pg_typeof(0));   -- regtype
481 select pg_typeof(array[1.2,55.5]); -- numeric[]
482 select pg_typeof(myleast(10, 1, 20, 33));  -- polymorphic input
483
484 -- test functions with parameter defaults
485 -- test basic functionality
486 create function dfunc(a int = 1, int = 2) returns int as $$
487   select $1 + $2;
488 $$ language sql;
489
490 select dfunc();
491 select dfunc(10);
492 select dfunc(10, 20);
493
494 drop function dfunc();  -- fail
495 drop function dfunc(int);  -- fail
496 drop function dfunc(int, int);  -- ok
497
498 -- fail, gap in arguments with defaults
499 create function dfunc(a int = 1, b int) returns int as $$
500   select $1 + $2;
501 $$ language sql;
502
503 -- check implicit coercion 
504 create function dfunc(a int DEFAULT 1.0, int DEFAULT '-1') returns int as $$
505   select $1 + $2;
506 $$ language sql;
507 select dfunc();
508 create function dfunc(a text DEFAULT 'Hello', b text DEFAULT 'World') returns text as $$
509   select $1 || ', ' || $2;
510 $$ language sql;
511
512 select dfunc();  -- fail; which dfunc should be called? int or text
513 select dfunc('Hi');  -- ok
514 select dfunc('Hi', 'City');  -- ok
515 select dfunc(0);  -- ok
516 select dfunc(10, 20);  -- ok
517
518 drop function dfunc(int, int);
519 drop function dfunc(text, text);
520
521 create function dfunc(int = 1, int = 2) returns int as $$
522   select 2; 
523 $$ language sql;
524
525 create function dfunc(int = 1, int = 2, int = 3, int = 4) returns int as $$
526   select 4;
527 $$ language sql;
528
529 -- Now, dfunc(nargs = 2) and dfunc(nargs = 4) are ambiguous when called
530 -- with 0 or 1 arguments.  For 2 arguments, a normall call of
531 -- dfunc(nargs = 2) takes place.
532
533 select dfunc();  -- fail
534 select dfunc(1);  -- fail
535 select dfunc(1, 2);  -- ok
536 select dfunc(1, 2, 3);  -- ok
537 select dfunc(1, 2, 3, 4);  -- ok
538
539 drop function dfunc(int, int);
540 drop function dfunc(int, int, int, int);
541
542 -- default values are not allowed for output parameters
543 create function dfunc(out int = 20) returns int as $$
544   select 1; 
545 $$ language sql;
546
547 -- polymorphic parameter test
548 create function dfunc(anyelement = 'World'::text) returns text as $$
549   select 'Hello, ' || $1::text;
550 $$ language sql;
551
552 select dfunc();
553 select dfunc(0);
554 select dfunc(to_date('20081215','YYYYMMDD'));
555 select dfunc('City'::text);
556
557 drop function dfunc(anyelement);
558
559 -- check null values
560 create function dfunc(int = null, int = null, int = null) returns int[] as $$
561   select array[$1, $2, $3];
562 $$ language sql;
563
564 select dfunc(1);
565 select dfunc(1, 2);
566 select dfunc(1, 2, 3);
567
568 drop function dfunc(int, int, int);
569
570 -- The conflict detection algorithm doesn't consider the actual parameter
571 -- types.  It detects any possible conflict for n arguments for some
572 -- function.  This is unwanted behavior, but solving it needs a move of
573 -- coercion routines.
574
575 create function dfunc(int = 1, int = 2, int = 3) returns int as $$
576   select 3;
577 $$ language sql;
578
579 create function dfunc(int = 1, int = 2) returns int as $$
580   select 2;
581 $$ language sql;
582
583 -- for n = 1 dfunc(narg=2) and dfunc(narg=3) are ambiguous
584 select dfunc(1);  -- fail
585
586 create function dfunc(text) returns text as $$
587   select $1;
588 $$ language sql;
589
590 -- Will fail, it detects ambiguity between dfunc(int, int, int) and
591 -- dfunc(int, int), but dfunc(text) isn't in conflict with either.
592 select dfunc('Hi');
593
594 drop function dfunc(int, int, int);
595 drop function dfunc(int, int);
596 drop function dfunc(text);