2003-07-01 21:10:53 +02:00
|
|
|
-- Currently this tests polymorphic aggregates and indirectly does some
|
|
|
|
-- testing of polymorphic SQL functions. It ought to be extended.
|
2009-10-08 04:39:25 +02:00
|
|
|
-- Tests for other features related to function-calling have snuck in, too.
|
2003-07-01 21:10:53 +02:00
|
|
|
-- Legend:
|
|
|
|
-----------
|
|
|
|
-- A = type is ANY
|
|
|
|
-- P = type is polymorphic
|
|
|
|
-- N = type is non-polymorphic
|
|
|
|
-- B = aggregate base type
|
|
|
|
-- S = aggregate state type
|
|
|
|
-- R = aggregate return type
|
|
|
|
-- 1 = arg1 of a function
|
|
|
|
-- 2 = arg2 of a function
|
|
|
|
-- ag = aggregate
|
|
|
|
-- tf = trans (state) function
|
|
|
|
-- ff = final function
|
|
|
|
-- rt = return type of a function
|
|
|
|
-- -> = implies
|
|
|
|
-- => = allowed
|
|
|
|
-- !> = not allowed
|
|
|
|
-- E = exists
|
|
|
|
-- NE = not-exists
|
2009-10-08 04:39:25 +02:00
|
|
|
--
|
2003-07-01 21:10:53 +02:00
|
|
|
-- Possible states:
|
|
|
|
-- ----------------
|
|
|
|
-- B = (A || P || N)
|
|
|
|
-- when (B = A) -> (tf2 = NE)
|
|
|
|
-- S = (P || N)
|
|
|
|
-- ff = (E || NE)
|
|
|
|
-- tf1 = (P || N)
|
|
|
|
-- tf2 = (NE || P || N)
|
|
|
|
-- R = (P || N)
|
|
|
|
-- create functions for use as tf and ff with the needed combinations of
|
|
|
|
-- argument polymorphism, but within the constraints of valid aggregate
|
|
|
|
-- functions, i.e. tf arg1 and tf return type must match
|
|
|
|
-- polymorphic single arg transfn
|
2006-02-27 17:09:50 +01:00
|
|
|
CREATE FUNCTION stfp(anyarray) RETURNS anyarray AS
|
|
|
|
'select $1' LANGUAGE SQL;
|
2003-07-01 21:10:53 +02:00
|
|
|
-- non-polymorphic single arg transfn
|
2006-02-27 17:09:50 +01:00
|
|
|
CREATE FUNCTION stfnp(int[]) RETURNS int[] AS
|
|
|
|
'select $1' LANGUAGE SQL;
|
2003-07-01 21:10:53 +02:00
|
|
|
-- dual polymorphic transfn
|
2006-02-27 17:09:50 +01:00
|
|
|
CREATE FUNCTION tfp(anyarray,anyelement) RETURNS anyarray AS
|
|
|
|
'select $1 || $2' LANGUAGE SQL;
|
2003-07-01 21:10:53 +02:00
|
|
|
-- dual non-polymorphic transfn
|
2006-02-27 17:09:50 +01:00
|
|
|
CREATE FUNCTION tfnp(int[],int) RETURNS int[] AS
|
|
|
|
'select $1 || $2' LANGUAGE SQL;
|
2003-07-01 21:10:53 +02:00
|
|
|
-- arg1 only polymorphic transfn
|
2006-02-27 17:09:50 +01:00
|
|
|
CREATE FUNCTION tf1p(anyarray,int) RETURNS anyarray AS
|
|
|
|
'select $1' LANGUAGE SQL;
|
2003-07-01 21:10:53 +02:00
|
|
|
-- arg2 only polymorphic transfn
|
2006-02-27 17:09:50 +01:00
|
|
|
CREATE FUNCTION tf2p(int[],anyelement) RETURNS int[] AS
|
|
|
|
'select $1' LANGUAGE SQL;
|
2006-07-27 21:52:07 +02:00
|
|
|
-- multi-arg polymorphic
|
|
|
|
CREATE FUNCTION sum3(anyelement,anyelement,anyelement) returns anyelement AS
|
|
|
|
'select $1+$2+$3' language sql strict;
|
2003-07-01 21:10:53 +02:00
|
|
|
-- finalfn polymorphic
|
2006-02-27 17:09:50 +01:00
|
|
|
CREATE FUNCTION ffp(anyarray) RETURNS anyarray AS
|
|
|
|
'select $1' LANGUAGE SQL;
|
2003-07-01 21:10:53 +02:00
|
|
|
-- finalfn non-polymorphic
|
|
|
|
CREATE FUNCTION ffnp(int[]) returns int[] as
|
2006-02-27 17:09:50 +01:00
|
|
|
'select $1' LANGUAGE SQL;
|
2003-07-01 21:10:53 +02:00
|
|
|
-- Try to cover all the possible states:
|
2009-10-08 04:39:25 +02:00
|
|
|
--
|
2003-07-01 21:10:53 +02:00
|
|
|
-- Note: in Cases 1 & 2, we are trying to return P. Therefore, if the transfn
|
|
|
|
-- is stfnp, tfnp, or tf2p, we must use ffp as finalfn, because stfnp, tfnp,
|
|
|
|
-- and tf2p do not return P. Conversely, in Cases 3 & 4, we are trying to
|
|
|
|
-- return N. Therefore, if the transfn is stfp, tfp, or tf1p, we must use ffnp
|
|
|
|
-- as finalfn, because stfp, tfp, and tf1p do not return N.
|
|
|
|
--
|
|
|
|
-- Case1 (R = P) && (B = A)
|
|
|
|
-- ------------------------
|
|
|
|
-- S tf1
|
|
|
|
-- -------
|
|
|
|
-- N N
|
|
|
|
-- should CREATE
|
2006-07-27 21:52:07 +02:00
|
|
|
CREATE AGGREGATE myaggp01a(*) (SFUNC = stfnp, STYPE = int4[],
|
2003-07-01 21:10:53 +02:00
|
|
|
FINALFUNC = ffp, INITCOND = '{}');
|
|
|
|
-- P N
|
|
|
|
-- should ERROR: stfnp(anyarray) not matched by stfnp(int[])
|
2006-07-27 21:52:07 +02:00
|
|
|
CREATE AGGREGATE myaggp02a(*) (SFUNC = stfnp, STYPE = anyarray,
|
2003-07-01 21:10:53 +02:00
|
|
|
FINALFUNC = ffp, INITCOND = '{}');
|
2003-09-25 08:58:07 +02:00
|
|
|
ERROR: cannot determine transition data type
|
2007-04-02 05:49:42 +02:00
|
|
|
DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
|
2003-07-01 21:10:53 +02:00
|
|
|
-- N P
|
|
|
|
-- should CREATE
|
2006-07-27 21:52:07 +02:00
|
|
|
CREATE AGGREGATE myaggp03a(*) (SFUNC = stfp, STYPE = int4[],
|
2003-07-01 21:10:53 +02:00
|
|
|
FINALFUNC = ffp, INITCOND = '{}');
|
2006-07-27 21:52:07 +02:00
|
|
|
CREATE AGGREGATE myaggp03b(*) (SFUNC = stfp, STYPE = int4[],
|
2003-07-01 21:10:53 +02:00
|
|
|
INITCOND = '{}');
|
|
|
|
-- P P
|
|
|
|
-- should ERROR: we have no way to resolve S
|
2006-07-27 21:52:07 +02:00
|
|
|
CREATE AGGREGATE myaggp04a(*) (SFUNC = stfp, STYPE = anyarray,
|
2003-07-01 21:10:53 +02:00
|
|
|
FINALFUNC = ffp, INITCOND = '{}');
|
2003-09-25 08:58:07 +02:00
|
|
|
ERROR: cannot determine transition data type
|
2007-04-02 05:49:42 +02:00
|
|
|
DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
|
2006-07-27 21:52:07 +02:00
|
|
|
CREATE AGGREGATE myaggp04b(*) (SFUNC = stfp, STYPE = anyarray,
|
2003-07-01 21:10:53 +02:00
|
|
|
INITCOND = '{}');
|
2003-09-25 08:58:07 +02:00
|
|
|
ERROR: cannot determine transition data type
|
2007-04-02 05:49:42 +02:00
|
|
|
DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
|
2003-07-01 21:10:53 +02:00
|
|
|
-- Case2 (R = P) && ((B = P) || (B = N))
|
|
|
|
-- -------------------------------------
|
|
|
|
-- S tf1 B tf2
|
|
|
|
-- -----------------------
|
|
|
|
-- N N N N
|
|
|
|
-- should CREATE
|
|
|
|
CREATE AGGREGATE myaggp05a(BASETYPE = int, SFUNC = tfnp, STYPE = int[],
|
|
|
|
FINALFUNC = ffp, INITCOND = '{}');
|
|
|
|
-- N N N P
|
|
|
|
-- should CREATE
|
|
|
|
CREATE AGGREGATE myaggp06a(BASETYPE = int, SFUNC = tf2p, STYPE = int[],
|
|
|
|
FINALFUNC = ffp, INITCOND = '{}');
|
|
|
|
-- N N P N
|
|
|
|
-- should ERROR: tfnp(int[], anyelement) not matched by tfnp(int[], int)
|
|
|
|
CREATE AGGREGATE myaggp07a(BASETYPE = anyelement, SFUNC = tfnp, STYPE = int[],
|
|
|
|
FINALFUNC = ffp, INITCOND = '{}');
|
2003-07-04 04:51:34 +02:00
|
|
|
ERROR: function tfnp(integer[], anyelement) does not exist
|
2003-07-01 21:10:53 +02:00
|
|
|
-- N N P P
|
|
|
|
-- should CREATE
|
|
|
|
CREATE AGGREGATE myaggp08a(BASETYPE = anyelement, SFUNC = tf2p, STYPE = int[],
|
|
|
|
FINALFUNC = ffp, INITCOND = '{}');
|
|
|
|
-- N P N N
|
|
|
|
-- should CREATE
|
|
|
|
CREATE AGGREGATE myaggp09a(BASETYPE = int, SFUNC = tf1p, STYPE = int[],
|
|
|
|
FINALFUNC = ffp, INITCOND = '{}');
|
|
|
|
CREATE AGGREGATE myaggp09b(BASETYPE = int, SFUNC = tf1p, STYPE = int[],
|
|
|
|
INITCOND = '{}');
|
|
|
|
-- N P N P
|
|
|
|
-- should CREATE
|
|
|
|
CREATE AGGREGATE myaggp10a(BASETYPE = int, SFUNC = tfp, STYPE = int[],
|
|
|
|
FINALFUNC = ffp, INITCOND = '{}');
|
|
|
|
CREATE AGGREGATE myaggp10b(BASETYPE = int, SFUNC = tfp, STYPE = int[],
|
|
|
|
INITCOND = '{}');
|
|
|
|
-- N P P N
|
|
|
|
-- should ERROR: tf1p(int[],anyelement) not matched by tf1p(anyarray,int)
|
|
|
|
CREATE AGGREGATE myaggp11a(BASETYPE = anyelement, SFUNC = tf1p, STYPE = int[],
|
|
|
|
FINALFUNC = ffp, INITCOND = '{}');
|
2003-07-04 04:51:34 +02:00
|
|
|
ERROR: function tf1p(integer[], anyelement) does not exist
|
2003-07-01 21:10:53 +02:00
|
|
|
CREATE AGGREGATE myaggp11b(BASETYPE = anyelement, SFUNC = tf1p, STYPE = int[],
|
|
|
|
INITCOND = '{}');
|
2003-07-04 04:51:34 +02:00
|
|
|
ERROR: function tf1p(integer[], anyelement) does not exist
|
2003-07-01 21:10:53 +02:00
|
|
|
-- N P P P
|
|
|
|
-- should ERROR: tfp(int[],anyelement) not matched by tfp(anyarray,anyelement)
|
|
|
|
CREATE AGGREGATE myaggp12a(BASETYPE = anyelement, SFUNC = tfp, STYPE = int[],
|
|
|
|
FINALFUNC = ffp, INITCOND = '{}');
|
2003-07-04 04:51:34 +02:00
|
|
|
ERROR: function tfp(integer[], anyelement) does not exist
|
2003-07-01 21:10:53 +02:00
|
|
|
CREATE AGGREGATE myaggp12b(BASETYPE = anyelement, SFUNC = tfp, STYPE = int[],
|
|
|
|
INITCOND = '{}');
|
2003-07-04 04:51:34 +02:00
|
|
|
ERROR: function tfp(integer[], anyelement) does not exist
|
2003-07-01 21:10:53 +02:00
|
|
|
-- P N N N
|
|
|
|
-- should ERROR: tfnp(anyarray, int) not matched by tfnp(int[],int)
|
|
|
|
CREATE AGGREGATE myaggp13a(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray,
|
|
|
|
FINALFUNC = ffp, INITCOND = '{}');
|
2003-09-25 08:58:07 +02:00
|
|
|
ERROR: cannot determine transition data type
|
2007-04-02 05:49:42 +02:00
|
|
|
DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
|
2003-07-01 21:10:53 +02:00
|
|
|
-- P N N P
|
|
|
|
-- should ERROR: tf2p(anyarray, int) not matched by tf2p(int[],anyelement)
|
|
|
|
CREATE AGGREGATE myaggp14a(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray,
|
|
|
|
FINALFUNC = ffp, INITCOND = '{}');
|
2003-09-25 08:58:07 +02:00
|
|
|
ERROR: cannot determine transition data type
|
2007-04-02 05:49:42 +02:00
|
|
|
DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
|
2003-07-01 21:10:53 +02:00
|
|
|
-- P N P N
|
|
|
|
-- should ERROR: tfnp(anyarray, anyelement) not matched by tfnp(int[],int)
|
|
|
|
CREATE AGGREGATE myaggp15a(BASETYPE = anyelement, SFUNC = tfnp,
|
|
|
|
STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}');
|
2003-07-04 04:51:34 +02:00
|
|
|
ERROR: function tfnp(anyarray, anyelement) does not exist
|
2003-07-01 21:10:53 +02:00
|
|
|
-- P N P P
|
|
|
|
-- should ERROR: tf2p(anyarray, anyelement) not matched by tf2p(int[],anyelement)
|
|
|
|
CREATE AGGREGATE myaggp16a(BASETYPE = anyelement, SFUNC = tf2p,
|
|
|
|
STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}');
|
2003-07-04 04:51:34 +02:00
|
|
|
ERROR: function tf2p(anyarray, anyelement) does not exist
|
2003-07-01 21:10:53 +02:00
|
|
|
-- P P N N
|
|
|
|
-- should ERROR: we have no way to resolve S
|
|
|
|
CREATE AGGREGATE myaggp17a(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray,
|
|
|
|
FINALFUNC = ffp, INITCOND = '{}');
|
2003-09-25 08:58:07 +02:00
|
|
|
ERROR: cannot determine transition data type
|
2007-04-02 05:49:42 +02:00
|
|
|
DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
|
2003-07-01 21:10:53 +02:00
|
|
|
CREATE AGGREGATE myaggp17b(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray,
|
|
|
|
INITCOND = '{}');
|
2003-09-25 08:58:07 +02:00
|
|
|
ERROR: cannot determine transition data type
|
2007-04-02 05:49:42 +02:00
|
|
|
DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
|
2003-07-01 21:10:53 +02:00
|
|
|
-- P P N P
|
|
|
|
-- should ERROR: tfp(anyarray, int) not matched by tfp(anyarray, anyelement)
|
|
|
|
CREATE AGGREGATE myaggp18a(BASETYPE = int, SFUNC = tfp, STYPE = anyarray,
|
|
|
|
FINALFUNC = ffp, INITCOND = '{}');
|
2003-09-25 08:58:07 +02:00
|
|
|
ERROR: cannot determine transition data type
|
2007-04-02 05:49:42 +02:00
|
|
|
DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
|
2003-07-01 21:10:53 +02:00
|
|
|
CREATE AGGREGATE myaggp18b(BASETYPE = int, SFUNC = tfp, STYPE = anyarray,
|
|
|
|
INITCOND = '{}');
|
2003-09-25 08:58:07 +02:00
|
|
|
ERROR: cannot determine transition data type
|
2007-04-02 05:49:42 +02:00
|
|
|
DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
|
2003-07-01 21:10:53 +02:00
|
|
|
-- P P P N
|
|
|
|
-- should ERROR: tf1p(anyarray, anyelement) not matched by tf1p(anyarray, int)
|
|
|
|
CREATE AGGREGATE myaggp19a(BASETYPE = anyelement, SFUNC = tf1p,
|
|
|
|
STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}');
|
2003-07-04 04:51:34 +02:00
|
|
|
ERROR: function tf1p(anyarray, anyelement) does not exist
|
2003-07-01 21:10:53 +02:00
|
|
|
CREATE AGGREGATE myaggp19b(BASETYPE = anyelement, SFUNC = tf1p,
|
|
|
|
STYPE = anyarray, INITCOND = '{}');
|
2003-07-04 04:51:34 +02:00
|
|
|
ERROR: function tf1p(anyarray, anyelement) does not exist
|
2003-07-01 21:10:53 +02:00
|
|
|
-- P P P P
|
|
|
|
-- should CREATE
|
|
|
|
CREATE AGGREGATE myaggp20a(BASETYPE = anyelement, SFUNC = tfp,
|
|
|
|
STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}');
|
|
|
|
CREATE AGGREGATE myaggp20b(BASETYPE = anyelement, SFUNC = tfp,
|
|
|
|
STYPE = anyarray, INITCOND = '{}');
|
|
|
|
-- Case3 (R = N) && (B = A)
|
|
|
|
-- ------------------------
|
|
|
|
-- S tf1
|
|
|
|
-- -------
|
|
|
|
-- N N
|
|
|
|
-- should CREATE
|
2006-07-27 21:52:07 +02:00
|
|
|
CREATE AGGREGATE myaggn01a(*) (SFUNC = stfnp, STYPE = int4[],
|
2003-07-01 21:10:53 +02:00
|
|
|
FINALFUNC = ffnp, INITCOND = '{}');
|
2006-07-27 21:52:07 +02:00
|
|
|
CREATE AGGREGATE myaggn01b(*) (SFUNC = stfnp, STYPE = int4[],
|
2003-07-01 21:10:53 +02:00
|
|
|
INITCOND = '{}');
|
|
|
|
-- P N
|
|
|
|
-- should ERROR: stfnp(anyarray) not matched by stfnp(int[])
|
2006-07-27 21:52:07 +02:00
|
|
|
CREATE AGGREGATE myaggn02a(*) (SFUNC = stfnp, STYPE = anyarray,
|
2003-07-01 21:10:53 +02:00
|
|
|
FINALFUNC = ffnp, INITCOND = '{}');
|
2003-09-25 08:58:07 +02:00
|
|
|
ERROR: cannot determine transition data type
|
2007-04-02 05:49:42 +02:00
|
|
|
DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
|
2006-07-27 21:52:07 +02:00
|
|
|
CREATE AGGREGATE myaggn02b(*) (SFUNC = stfnp, STYPE = anyarray,
|
2003-07-01 21:10:53 +02:00
|
|
|
INITCOND = '{}');
|
2003-09-25 08:58:07 +02:00
|
|
|
ERROR: cannot determine transition data type
|
2007-04-02 05:49:42 +02:00
|
|
|
DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
|
2003-07-01 21:10:53 +02:00
|
|
|
-- N P
|
|
|
|
-- should CREATE
|
2006-07-27 21:52:07 +02:00
|
|
|
CREATE AGGREGATE myaggn03a(*) (SFUNC = stfp, STYPE = int4[],
|
2003-07-01 21:10:53 +02:00
|
|
|
FINALFUNC = ffnp, INITCOND = '{}');
|
|
|
|
-- P P
|
|
|
|
-- should ERROR: ffnp(anyarray) not matched by ffnp(int[])
|
2006-07-27 21:52:07 +02:00
|
|
|
CREATE AGGREGATE myaggn04a(*) (SFUNC = stfp, STYPE = anyarray,
|
2003-07-01 21:10:53 +02:00
|
|
|
FINALFUNC = ffnp, INITCOND = '{}');
|
2003-09-25 08:58:07 +02:00
|
|
|
ERROR: cannot determine transition data type
|
2007-04-02 05:49:42 +02:00
|
|
|
DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
|
2003-07-01 21:10:53 +02:00
|
|
|
-- Case4 (R = N) && ((B = P) || (B = N))
|
|
|
|
-- -------------------------------------
|
|
|
|
-- S tf1 B tf2
|
|
|
|
-- -----------------------
|
|
|
|
-- N N N N
|
|
|
|
-- should CREATE
|
|
|
|
CREATE AGGREGATE myaggn05a(BASETYPE = int, SFUNC = tfnp, STYPE = int[],
|
|
|
|
FINALFUNC = ffnp, INITCOND = '{}');
|
|
|
|
CREATE AGGREGATE myaggn05b(BASETYPE = int, SFUNC = tfnp, STYPE = int[],
|
|
|
|
INITCOND = '{}');
|
|
|
|
-- N N N P
|
|
|
|
-- should CREATE
|
|
|
|
CREATE AGGREGATE myaggn06a(BASETYPE = int, SFUNC = tf2p, STYPE = int[],
|
|
|
|
FINALFUNC = ffnp, INITCOND = '{}');
|
|
|
|
CREATE AGGREGATE myaggn06b(BASETYPE = int, SFUNC = tf2p, STYPE = int[],
|
|
|
|
INITCOND = '{}');
|
|
|
|
-- N N P N
|
|
|
|
-- should ERROR: tfnp(int[], anyelement) not matched by tfnp(int[], int)
|
|
|
|
CREATE AGGREGATE myaggn07a(BASETYPE = anyelement, SFUNC = tfnp, STYPE = int[],
|
|
|
|
FINALFUNC = ffnp, INITCOND = '{}');
|
2003-07-04 04:51:34 +02:00
|
|
|
ERROR: function tfnp(integer[], anyelement) does not exist
|
2003-07-01 21:10:53 +02:00
|
|
|
CREATE AGGREGATE myaggn07b(BASETYPE = anyelement, SFUNC = tfnp, STYPE = int[],
|
|
|
|
INITCOND = '{}');
|
2003-07-04 04:51:34 +02:00
|
|
|
ERROR: function tfnp(integer[], anyelement) does not exist
|
2003-07-01 21:10:53 +02:00
|
|
|
-- N N P P
|
|
|
|
-- should CREATE
|
|
|
|
CREATE AGGREGATE myaggn08a(BASETYPE = anyelement, SFUNC = tf2p, STYPE = int[],
|
|
|
|
FINALFUNC = ffnp, INITCOND = '{}');
|
|
|
|
CREATE AGGREGATE myaggn08b(BASETYPE = anyelement, SFUNC = tf2p, STYPE = int[],
|
|
|
|
INITCOND = '{}');
|
|
|
|
-- N P N N
|
|
|
|
-- should CREATE
|
|
|
|
CREATE AGGREGATE myaggn09a(BASETYPE = int, SFUNC = tf1p, STYPE = int[],
|
|
|
|
FINALFUNC = ffnp, INITCOND = '{}');
|
|
|
|
-- N P N P
|
|
|
|
-- should CREATE
|
|
|
|
CREATE AGGREGATE myaggn10a(BASETYPE = int, SFUNC = tfp, STYPE = int[],
|
|
|
|
FINALFUNC = ffnp, INITCOND = '{}');
|
|
|
|
-- N P P N
|
|
|
|
-- should ERROR: tf1p(int[],anyelement) not matched by tf1p(anyarray,int)
|
|
|
|
CREATE AGGREGATE myaggn11a(BASETYPE = anyelement, SFUNC = tf1p, STYPE = int[],
|
|
|
|
FINALFUNC = ffnp, INITCOND = '{}');
|
2003-07-04 04:51:34 +02:00
|
|
|
ERROR: function tf1p(integer[], anyelement) does not exist
|
2003-07-01 21:10:53 +02:00
|
|
|
-- N P P P
|
|
|
|
-- should ERROR: tfp(int[],anyelement) not matched by tfp(anyarray,anyelement)
|
|
|
|
CREATE AGGREGATE myaggn12a(BASETYPE = anyelement, SFUNC = tfp, STYPE = int[],
|
|
|
|
FINALFUNC = ffnp, INITCOND = '{}');
|
2003-07-04 04:51:34 +02:00
|
|
|
ERROR: function tfp(integer[], anyelement) does not exist
|
2003-07-01 21:10:53 +02:00
|
|
|
-- P N N N
|
|
|
|
-- should ERROR: tfnp(anyarray, int) not matched by tfnp(int[],int)
|
|
|
|
CREATE AGGREGATE myaggn13a(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray,
|
|
|
|
FINALFUNC = ffnp, INITCOND = '{}');
|
2003-09-25 08:58:07 +02:00
|
|
|
ERROR: cannot determine transition data type
|
2007-04-02 05:49:42 +02:00
|
|
|
DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
|
2003-07-01 21:10:53 +02:00
|
|
|
CREATE AGGREGATE myaggn13b(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray,
|
|
|
|
INITCOND = '{}');
|
2003-09-25 08:58:07 +02:00
|
|
|
ERROR: cannot determine transition data type
|
2007-04-02 05:49:42 +02:00
|
|
|
DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
|
2003-07-01 21:10:53 +02:00
|
|
|
-- P N N P
|
|
|
|
-- should ERROR: tf2p(anyarray, int) not matched by tf2p(int[],anyelement)
|
|
|
|
CREATE AGGREGATE myaggn14a(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray,
|
|
|
|
FINALFUNC = ffnp, INITCOND = '{}');
|
2003-09-25 08:58:07 +02:00
|
|
|
ERROR: cannot determine transition data type
|
2007-04-02 05:49:42 +02:00
|
|
|
DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
|
2003-07-01 21:10:53 +02:00
|
|
|
CREATE AGGREGATE myaggn14b(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray,
|
|
|
|
INITCOND = '{}');
|
2003-09-25 08:58:07 +02:00
|
|
|
ERROR: cannot determine transition data type
|
2007-04-02 05:49:42 +02:00
|
|
|
DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
|
2003-07-01 21:10:53 +02:00
|
|
|
-- P N P N
|
|
|
|
-- should ERROR: tfnp(anyarray, anyelement) not matched by tfnp(int[],int)
|
|
|
|
CREATE AGGREGATE myaggn15a(BASETYPE = anyelement, SFUNC = tfnp,
|
|
|
|
STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}');
|
2003-07-04 04:51:34 +02:00
|
|
|
ERROR: function tfnp(anyarray, anyelement) does not exist
|
2003-07-01 21:10:53 +02:00
|
|
|
CREATE AGGREGATE myaggn15b(BASETYPE = anyelement, SFUNC = tfnp,
|
|
|
|
STYPE = anyarray, INITCOND = '{}');
|
2003-07-04 04:51:34 +02:00
|
|
|
ERROR: function tfnp(anyarray, anyelement) does not exist
|
2003-07-01 21:10:53 +02:00
|
|
|
-- P N P P
|
|
|
|
-- should ERROR: tf2p(anyarray, anyelement) not matched by tf2p(int[],anyelement)
|
|
|
|
CREATE AGGREGATE myaggn16a(BASETYPE = anyelement, SFUNC = tf2p,
|
|
|
|
STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}');
|
2003-07-04 04:51:34 +02:00
|
|
|
ERROR: function tf2p(anyarray, anyelement) does not exist
|
2003-07-01 21:10:53 +02:00
|
|
|
CREATE AGGREGATE myaggn16b(BASETYPE = anyelement, SFUNC = tf2p,
|
|
|
|
STYPE = anyarray, INITCOND = '{}');
|
2003-07-04 04:51:34 +02:00
|
|
|
ERROR: function tf2p(anyarray, anyelement) does not exist
|
2003-07-01 21:10:53 +02:00
|
|
|
-- P P N N
|
|
|
|
-- should ERROR: ffnp(anyarray) not matched by ffnp(int[])
|
|
|
|
CREATE AGGREGATE myaggn17a(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray,
|
|
|
|
FINALFUNC = ffnp, INITCOND = '{}');
|
2003-09-25 08:58:07 +02:00
|
|
|
ERROR: cannot determine transition data type
|
2007-04-02 05:49:42 +02:00
|
|
|
DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
|
2003-07-01 21:10:53 +02:00
|
|
|
-- P P N P
|
|
|
|
-- should ERROR: tfp(anyarray, int) not matched by tfp(anyarray, anyelement)
|
|
|
|
CREATE AGGREGATE myaggn18a(BASETYPE = int, SFUNC = tfp, STYPE = anyarray,
|
|
|
|
FINALFUNC = ffnp, INITCOND = '{}');
|
2003-09-25 08:58:07 +02:00
|
|
|
ERROR: cannot determine transition data type
|
2007-04-02 05:49:42 +02:00
|
|
|
DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
|
2003-07-01 21:10:53 +02:00
|
|
|
-- P P P N
|
|
|
|
-- should ERROR: tf1p(anyarray, anyelement) not matched by tf1p(anyarray, int)
|
|
|
|
CREATE AGGREGATE myaggn19a(BASETYPE = anyelement, SFUNC = tf1p,
|
|
|
|
STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}');
|
2003-07-04 04:51:34 +02:00
|
|
|
ERROR: function tf1p(anyarray, anyelement) does not exist
|
2003-07-01 21:10:53 +02:00
|
|
|
-- P P P P
|
|
|
|
-- should ERROR: ffnp(anyarray) not matched by ffnp(int[])
|
|
|
|
CREATE AGGREGATE myaggn20a(BASETYPE = anyelement, SFUNC = tfp,
|
|
|
|
STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}');
|
2003-07-04 04:51:34 +02:00
|
|
|
ERROR: function ffnp(anyarray) does not exist
|
2006-07-27 21:52:07 +02:00
|
|
|
-- multi-arg polymorphic
|
|
|
|
CREATE AGGREGATE mysum2(anyelement,anyelement) (SFUNC = sum3,
|
|
|
|
STYPE = anyelement, INITCOND = '0');
|
2003-07-01 21:10:53 +02:00
|
|
|
-- create test data for polymorphic aggregates
|
|
|
|
create temp table t(f1 int, f2 int[], f3 text);
|
|
|
|
insert into t values(1,array[1],'a');
|
|
|
|
insert into t values(1,array[11],'b');
|
|
|
|
insert into t values(1,array[111],'c');
|
|
|
|
insert into t values(2,array[2],'a');
|
|
|
|
insert into t values(2,array[22],'b');
|
|
|
|
insert into t values(2,array[222],'c');
|
|
|
|
insert into t values(3,array[3],'a');
|
|
|
|
insert into t values(3,array[3],'b');
|
|
|
|
-- test the successfully created polymorphic aggregates
|
2009-02-09 22:18:28 +01:00
|
|
|
select f3, myaggp01a(*) from t group by f3 order by f3;
|
2003-07-01 21:10:53 +02:00
|
|
|
f3 | myaggp01a
|
|
|
|
----+-----------
|
2009-02-09 22:18:28 +01:00
|
|
|
a | {}
|
2005-03-24 20:14:49 +01:00
|
|
|
b | {}
|
2003-07-01 21:10:53 +02:00
|
|
|
c | {}
|
|
|
|
(3 rows)
|
|
|
|
|
2009-02-09 22:18:28 +01:00
|
|
|
select f3, myaggp03a(*) from t group by f3 order by f3;
|
2003-07-01 21:10:53 +02:00
|
|
|
f3 | myaggp03a
|
|
|
|
----+-----------
|
2009-02-09 22:18:28 +01:00
|
|
|
a | {}
|
2005-03-24 20:14:49 +01:00
|
|
|
b | {}
|
2003-07-01 21:10:53 +02:00
|
|
|
c | {}
|
|
|
|
(3 rows)
|
|
|
|
|
2009-02-09 22:18:28 +01:00
|
|
|
select f3, myaggp03b(*) from t group by f3 order by f3;
|
2003-07-01 21:10:53 +02:00
|
|
|
f3 | myaggp03b
|
|
|
|
----+-----------
|
2009-02-09 22:18:28 +01:00
|
|
|
a | {}
|
2005-03-24 20:14:49 +01:00
|
|
|
b | {}
|
2003-07-01 21:10:53 +02:00
|
|
|
c | {}
|
|
|
|
(3 rows)
|
|
|
|
|
2009-02-09 22:18:28 +01:00
|
|
|
select f3, myaggp05a(f1) from t group by f3 order by f3;
|
2003-07-01 21:10:53 +02:00
|
|
|
f3 | myaggp05a
|
|
|
|
----+-----------
|
2009-02-09 22:18:28 +01:00
|
|
|
a | {1,2,3}
|
2005-03-24 20:14:49 +01:00
|
|
|
b | {1,2,3}
|
2003-07-01 21:10:53 +02:00
|
|
|
c | {1,2}
|
|
|
|
(3 rows)
|
|
|
|
|
2009-02-09 22:18:28 +01:00
|
|
|
select f3, myaggp06a(f1) from t group by f3 order by f3;
|
2003-07-01 21:10:53 +02:00
|
|
|
f3 | myaggp06a
|
|
|
|
----+-----------
|
2009-02-09 22:18:28 +01:00
|
|
|
a | {}
|
2005-03-24 20:14:49 +01:00
|
|
|
b | {}
|
2003-07-01 21:10:53 +02:00
|
|
|
c | {}
|
|
|
|
(3 rows)
|
|
|
|
|
2009-02-09 22:18:28 +01:00
|
|
|
select f3, myaggp08a(f1) from t group by f3 order by f3;
|
2003-07-01 21:10:53 +02:00
|
|
|
f3 | myaggp08a
|
|
|
|
----+-----------
|
2009-02-09 22:18:28 +01:00
|
|
|
a | {}
|
2005-03-24 20:14:49 +01:00
|
|
|
b | {}
|
2003-07-01 21:10:53 +02:00
|
|
|
c | {}
|
|
|
|
(3 rows)
|
|
|
|
|
2009-02-09 22:18:28 +01:00
|
|
|
select f3, myaggp09a(f1) from t group by f3 order by f3;
|
2003-07-01 21:10:53 +02:00
|
|
|
f3 | myaggp09a
|
|
|
|
----+-----------
|
2009-02-09 22:18:28 +01:00
|
|
|
a | {}
|
2005-03-24 20:14:49 +01:00
|
|
|
b | {}
|
2003-07-01 21:10:53 +02:00
|
|
|
c | {}
|
|
|
|
(3 rows)
|
|
|
|
|
2009-02-09 22:18:28 +01:00
|
|
|
select f3, myaggp09b(f1) from t group by f3 order by f3;
|
2003-07-01 21:10:53 +02:00
|
|
|
f3 | myaggp09b
|
|
|
|
----+-----------
|
2009-02-09 22:18:28 +01:00
|
|
|
a | {}
|
2005-03-24 20:14:49 +01:00
|
|
|
b | {}
|
2003-07-01 21:10:53 +02:00
|
|
|
c | {}
|
|
|
|
(3 rows)
|
|
|
|
|
2009-02-09 22:18:28 +01:00
|
|
|
select f3, myaggp10a(f1) from t group by f3 order by f3;
|
2003-07-01 21:10:53 +02:00
|
|
|
f3 | myaggp10a
|
|
|
|
----+-----------
|
2009-02-09 22:18:28 +01:00
|
|
|
a | {1,2,3}
|
2005-03-24 20:14:49 +01:00
|
|
|
b | {1,2,3}
|
2003-07-01 21:10:53 +02:00
|
|
|
c | {1,2}
|
|
|
|
(3 rows)
|
|
|
|
|
2009-02-09 22:18:28 +01:00
|
|
|
select f3, myaggp10b(f1) from t group by f3 order by f3;
|
2003-07-01 21:10:53 +02:00
|
|
|
f3 | myaggp10b
|
|
|
|
----+-----------
|
2009-02-09 22:18:28 +01:00
|
|
|
a | {1,2,3}
|
2005-03-24 20:14:49 +01:00
|
|
|
b | {1,2,3}
|
2003-07-01 21:10:53 +02:00
|
|
|
c | {1,2}
|
|
|
|
(3 rows)
|
|
|
|
|
2009-02-09 22:18:28 +01:00
|
|
|
select f3, myaggp20a(f1) from t group by f3 order by f3;
|
2003-07-01 21:10:53 +02:00
|
|
|
f3 | myaggp20a
|
|
|
|
----+-----------
|
2009-02-09 22:18:28 +01:00
|
|
|
a | {1,2,3}
|
2005-03-24 20:14:49 +01:00
|
|
|
b | {1,2,3}
|
2003-07-01 21:10:53 +02:00
|
|
|
c | {1,2}
|
|
|
|
(3 rows)
|
|
|
|
|
2009-02-09 22:18:28 +01:00
|
|
|
select f3, myaggp20b(f1) from t group by f3 order by f3;
|
2003-07-01 21:10:53 +02:00
|
|
|
f3 | myaggp20b
|
|
|
|
----+-----------
|
2009-02-09 22:18:28 +01:00
|
|
|
a | {1,2,3}
|
2005-03-24 20:14:49 +01:00
|
|
|
b | {1,2,3}
|
2003-07-01 21:10:53 +02:00
|
|
|
c | {1,2}
|
|
|
|
(3 rows)
|
|
|
|
|
2009-02-09 22:18:28 +01:00
|
|
|
select f3, myaggn01a(*) from t group by f3 order by f3;
|
2003-07-01 21:10:53 +02:00
|
|
|
f3 | myaggn01a
|
|
|
|
----+-----------
|
2009-02-09 22:18:28 +01:00
|
|
|
a | {}
|
2005-03-24 20:14:49 +01:00
|
|
|
b | {}
|
2003-07-01 21:10:53 +02:00
|
|
|
c | {}
|
|
|
|
(3 rows)
|
|
|
|
|
2009-02-09 22:18:28 +01:00
|
|
|
select f3, myaggn01b(*) from t group by f3 order by f3;
|
2003-07-01 21:10:53 +02:00
|
|
|
f3 | myaggn01b
|
|
|
|
----+-----------
|
2009-02-09 22:18:28 +01:00
|
|
|
a | {}
|
2005-03-24 20:14:49 +01:00
|
|
|
b | {}
|
2003-07-01 21:10:53 +02:00
|
|
|
c | {}
|
|
|
|
(3 rows)
|
|
|
|
|
2009-02-09 22:18:28 +01:00
|
|
|
select f3, myaggn03a(*) from t group by f3 order by f3;
|
2003-07-01 21:10:53 +02:00
|
|
|
f3 | myaggn03a
|
|
|
|
----+-----------
|
2009-02-09 22:18:28 +01:00
|
|
|
a | {}
|
2005-03-24 20:14:49 +01:00
|
|
|
b | {}
|
2003-07-01 21:10:53 +02:00
|
|
|
c | {}
|
|
|
|
(3 rows)
|
|
|
|
|
2009-02-09 22:18:28 +01:00
|
|
|
select f3, myaggn05a(f1) from t group by f3 order by f3;
|
2003-07-01 21:10:53 +02:00
|
|
|
f3 | myaggn05a
|
|
|
|
----+-----------
|
2009-02-09 22:18:28 +01:00
|
|
|
a | {1,2,3}
|
2005-03-24 20:14:49 +01:00
|
|
|
b | {1,2,3}
|
2003-07-01 21:10:53 +02:00
|
|
|
c | {1,2}
|
|
|
|
(3 rows)
|
|
|
|
|
2009-02-09 22:18:28 +01:00
|
|
|
select f3, myaggn05b(f1) from t group by f3 order by f3;
|
2003-07-01 21:10:53 +02:00
|
|
|
f3 | myaggn05b
|
|
|
|
----+-----------
|
2009-02-09 22:18:28 +01:00
|
|
|
a | {1,2,3}
|
2005-03-24 20:14:49 +01:00
|
|
|
b | {1,2,3}
|
2003-07-01 21:10:53 +02:00
|
|
|
c | {1,2}
|
|
|
|
(3 rows)
|
|
|
|
|
2009-02-09 22:18:28 +01:00
|
|
|
select f3, myaggn06a(f1) from t group by f3 order by f3;
|
2003-07-01 21:10:53 +02:00
|
|
|
f3 | myaggn06a
|
|
|
|
----+-----------
|
2009-02-09 22:18:28 +01:00
|
|
|
a | {}
|
2005-03-24 20:14:49 +01:00
|
|
|
b | {}
|
2003-07-01 21:10:53 +02:00
|
|
|
c | {}
|
|
|
|
(3 rows)
|
|
|
|
|
2009-02-09 22:18:28 +01:00
|
|
|
select f3, myaggn06b(f1) from t group by f3 order by f3;
|
2003-07-01 21:10:53 +02:00
|
|
|
f3 | myaggn06b
|
|
|
|
----+-----------
|
2009-02-09 22:18:28 +01:00
|
|
|
a | {}
|
2005-03-24 20:14:49 +01:00
|
|
|
b | {}
|
2003-07-01 21:10:53 +02:00
|
|
|
c | {}
|
|
|
|
(3 rows)
|
|
|
|
|
2009-02-09 22:18:28 +01:00
|
|
|
select f3, myaggn08a(f1) from t group by f3 order by f3;
|
2003-07-01 21:10:53 +02:00
|
|
|
f3 | myaggn08a
|
|
|
|
----+-----------
|
2009-02-09 22:18:28 +01:00
|
|
|
a | {}
|
2005-03-24 20:14:49 +01:00
|
|
|
b | {}
|
2003-07-01 21:10:53 +02:00
|
|
|
c | {}
|
|
|
|
(3 rows)
|
|
|
|
|
2009-02-09 22:18:28 +01:00
|
|
|
select f3, myaggn08b(f1) from t group by f3 order by f3;
|
2003-07-01 21:10:53 +02:00
|
|
|
f3 | myaggn08b
|
|
|
|
----+-----------
|
2009-02-09 22:18:28 +01:00
|
|
|
a | {}
|
2005-03-24 20:14:49 +01:00
|
|
|
b | {}
|
2003-07-01 21:10:53 +02:00
|
|
|
c | {}
|
|
|
|
(3 rows)
|
|
|
|
|
2009-02-09 22:18:28 +01:00
|
|
|
select f3, myaggn09a(f1) from t group by f3 order by f3;
|
2003-07-01 21:10:53 +02:00
|
|
|
f3 | myaggn09a
|
|
|
|
----+-----------
|
2009-02-09 22:18:28 +01:00
|
|
|
a | {}
|
2005-03-24 20:14:49 +01:00
|
|
|
b | {}
|
2003-07-01 21:10:53 +02:00
|
|
|
c | {}
|
|
|
|
(3 rows)
|
|
|
|
|
2009-02-09 22:18:28 +01:00
|
|
|
select f3, myaggn10a(f1) from t group by f3 order by f3;
|
2003-07-01 21:10:53 +02:00
|
|
|
f3 | myaggn10a
|
|
|
|
----+-----------
|
2009-02-09 22:18:28 +01:00
|
|
|
a | {1,2,3}
|
2005-03-24 20:14:49 +01:00
|
|
|
b | {1,2,3}
|
2003-07-01 21:10:53 +02:00
|
|
|
c | {1,2}
|
|
|
|
(3 rows)
|
|
|
|
|
2006-07-27 21:52:07 +02:00
|
|
|
select mysum2(f1, f1 + 1) from t;
|
|
|
|
mysum2
|
|
|
|
--------
|
|
|
|
38
|
|
|
|
(1 row)
|
|
|
|
|
2007-05-01 20:53:52 +02:00
|
|
|
-- test inlining of polymorphic SQL functions
|
|
|
|
create function bleat(int) returns int as $$
|
|
|
|
begin
|
|
|
|
raise notice 'bleat %', $1;
|
|
|
|
return $1;
|
|
|
|
end$$ language plpgsql;
|
|
|
|
create function sql_if(bool, anyelement, anyelement) returns anyelement as $$
|
|
|
|
select case when $1 then $2 else $3 end $$ language sql;
|
|
|
|
-- Note this would fail with integer overflow, never mind wrong bleat() output,
|
|
|
|
-- if the CASE expression were not successfully inlined
|
|
|
|
select f1, sql_if(f1 > 0, bleat(f1), bleat(f1 + 1)) from int4_tbl;
|
|
|
|
NOTICE: bleat 1
|
|
|
|
NOTICE: bleat 123456
|
|
|
|
NOTICE: bleat -123455
|
|
|
|
NOTICE: bleat 2147483647
|
|
|
|
NOTICE: bleat -2147483646
|
|
|
|
f1 | sql_if
|
|
|
|
-------------+-------------
|
|
|
|
0 | 1
|
|
|
|
123456 | 123456
|
|
|
|
-123456 | -123455
|
|
|
|
2147483647 | 2147483647
|
|
|
|
-2147483647 | -2147483646
|
|
|
|
(5 rows)
|
|
|
|
|
|
|
|
select q2, sql_if(q2 > 0, q2, q2 + 1) from int8_tbl;
|
|
|
|
q2 | sql_if
|
|
|
|
-------------------+-------------------
|
|
|
|
456 | 456
|
|
|
|
4567890123456789 | 4567890123456789
|
|
|
|
123 | 123
|
|
|
|
4567890123456789 | 4567890123456789
|
|
|
|
-4567890123456789 | -4567890123456788
|
|
|
|
(5 rows)
|
|
|
|
|
2011-12-01 18:44:16 +01:00
|
|
|
-- another sort of polymorphic aggregate
|
|
|
|
CREATE AGGREGATE array_cat_accum (anyarray)
|
|
|
|
(
|
|
|
|
sfunc = array_cat,
|
|
|
|
stype = anyarray,
|
|
|
|
initcond = '{}'
|
|
|
|
);
|
|
|
|
SELECT array_cat_accum(i)
|
|
|
|
FROM (VALUES (ARRAY[1,2]), (ARRAY[3,4])) as t(i);
|
|
|
|
array_cat_accum
|
|
|
|
-----------------
|
|
|
|
{1,2,3,4}
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
SELECT array_cat_accum(i)
|
|
|
|
FROM (VALUES (ARRAY[row(1,2),row(3,4)]), (ARRAY[row(5,6),row(7,8)])) as t(i);
|
|
|
|
array_cat_accum
|
|
|
|
-----------------------------------
|
|
|
|
{"(1,2)","(3,4)","(5,6)","(7,8)"}
|
|
|
|
(1 row)
|
|
|
|
|
2008-01-11 19:39:41 +01:00
|
|
|
-- another kind of polymorphic aggregate
|
|
|
|
create function add_group(grp anyarray, ad anyelement, size integer)
|
|
|
|
returns anyarray
|
|
|
|
as $$
|
|
|
|
begin
|
|
|
|
if grp is null then
|
|
|
|
return array[ad];
|
|
|
|
end if;
|
|
|
|
if array_upper(grp, 1) < size then
|
|
|
|
return grp || ad;
|
|
|
|
end if;
|
|
|
|
return grp;
|
|
|
|
end;
|
|
|
|
$$
|
|
|
|
language plpgsql immutable;
|
|
|
|
create aggregate build_group(anyelement, integer) (
|
|
|
|
SFUNC = add_group,
|
|
|
|
STYPE = anyarray
|
|
|
|
);
|
|
|
|
select build_group(q1,3) from int8_tbl;
|
|
|
|
build_group
|
|
|
|
----------------------------
|
|
|
|
{123,123,4567890123456789}
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
-- this should fail because stype isn't compatible with arg
|
|
|
|
create aggregate build_group(int8, integer) (
|
|
|
|
SFUNC = add_group,
|
|
|
|
STYPE = int2[]
|
|
|
|
);
|
|
|
|
ERROR: function add_group(smallint[], bigint, integer) does not exist
|
|
|
|
-- but we can make a non-poly agg from a poly sfunc if types are OK
|
|
|
|
create aggregate build_group(int8, integer) (
|
|
|
|
SFUNC = add_group,
|
|
|
|
STYPE = int8[]
|
|
|
|
);
|
2008-12-14 20:45:52 +01:00
|
|
|
-- check that we can apply functions taking ANYARRAY to pg_stats
|
|
|
|
select distinct array_ndims(histogram_bounds) from pg_stats
|
|
|
|
where histogram_bounds is not null;
|
|
|
|
array_ndims
|
|
|
|
-------------
|
|
|
|
1
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
-- such functions must protect themselves if varying element type isn't OK
|
2011-03-14 17:52:03 +01:00
|
|
|
-- (WHERE clause here is to avoid possibly getting a collation error instead)
|
|
|
|
select max(histogram_bounds) from pg_stats where tablename = 'pg_am';
|
2008-12-14 20:45:52 +01:00
|
|
|
ERROR: cannot compare arrays of different element types
|
2008-07-16 03:30:23 +02:00
|
|
|
-- test variadic polymorphic functions
|
|
|
|
create function myleast(variadic anyarray) returns anyelement as $$
|
|
|
|
select min($1[i]) from generate_subscripts($1,1) g(i)
|
|
|
|
$$ language sql immutable strict;
|
|
|
|
select myleast(10, 1, 20, 33);
|
|
|
|
myleast
|
|
|
|
---------
|
|
|
|
1
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select myleast(1.1, 0.22, 0.55);
|
|
|
|
myleast
|
|
|
|
---------
|
|
|
|
0.22
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select myleast('z'::text);
|
|
|
|
myleast
|
|
|
|
---------
|
|
|
|
z
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select myleast(); -- fail
|
|
|
|
ERROR: function myleast() does not exist
|
|
|
|
LINE 1: select myleast();
|
|
|
|
^
|
|
|
|
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
|
|
|
|
-- test with variadic call parameter
|
|
|
|
select myleast(variadic array[1,2,3,4,-1]);
|
|
|
|
myleast
|
|
|
|
---------
|
|
|
|
-1
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select myleast(variadic array[1.1, -5.5]);
|
|
|
|
myleast
|
|
|
|
---------
|
|
|
|
-5.5
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
--test with empty variadic call parameter
|
|
|
|
select myleast(variadic array[]::int[]);
|
|
|
|
myleast
|
|
|
|
---------
|
|
|
|
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
-- an example with some ordinary arguments too
|
|
|
|
create function concat(text, variadic anyarray) returns text as $$
|
|
|
|
select array_to_string($2, $1);
|
|
|
|
$$ language sql immutable strict;
|
|
|
|
select concat('%', 1, 2, 3, 4, 5);
|
|
|
|
concat
|
|
|
|
-----------
|
|
|
|
1%2%3%4%5
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select concat('|', 'a'::text, 'b', 'c');
|
|
|
|
concat
|
|
|
|
--------
|
|
|
|
a|b|c
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select concat('|', variadic array[1,2,33]);
|
|
|
|
concat
|
|
|
|
--------
|
|
|
|
1|2|33
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select concat('|', variadic array[]::int[]);
|
|
|
|
concat
|
|
|
|
--------
|
|
|
|
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
drop function concat(text, anyarray);
|
|
|
|
-- mix variadic with anyelement
|
|
|
|
create function formarray(anyelement, variadic anyarray) returns anyarray as $$
|
|
|
|
select array_prepend($1, $2);
|
|
|
|
$$ language sql immutable strict;
|
|
|
|
select formarray(1,2,3,4,5);
|
|
|
|
formarray
|
|
|
|
-------------
|
|
|
|
{1,2,3,4,5}
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select formarray(1.1, variadic array[1.2,55.5]);
|
|
|
|
formarray
|
|
|
|
----------------
|
|
|
|
{1.1,1.2,55.5}
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select formarray(1.1, array[1.2,55.5]); -- fail without variadic
|
|
|
|
ERROR: function formarray(numeric, numeric[]) does not exist
|
|
|
|
LINE 1: select formarray(1.1, array[1.2,55.5]);
|
|
|
|
^
|
|
|
|
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
|
|
|
|
select formarray(1, 'x'::text); -- fail, type mismatch
|
|
|
|
ERROR: function formarray(integer, text) does not exist
|
|
|
|
LINE 1: select formarray(1, 'x'::text);
|
|
|
|
^
|
|
|
|
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
|
|
|
|
select formarray(1, variadic array['x'::text]); -- fail, type mismatch
|
|
|
|
ERROR: function formarray(integer, text[]) does not exist
|
|
|
|
LINE 1: select formarray(1, variadic array['x'::text]);
|
|
|
|
^
|
|
|
|
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
|
|
|
|
drop function formarray(anyelement, variadic anyarray);
|
2008-11-03 18:51:13 +01:00
|
|
|
-- test pg_typeof() function
|
|
|
|
select pg_typeof(null); -- unknown
|
|
|
|
pg_typeof
|
|
|
|
-----------
|
|
|
|
unknown
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select pg_typeof(0); -- integer
|
|
|
|
pg_typeof
|
|
|
|
-----------
|
|
|
|
integer
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select pg_typeof(0.0); -- numeric
|
|
|
|
pg_typeof
|
|
|
|
-----------
|
|
|
|
numeric
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select pg_typeof(1+1 = 2); -- boolean
|
|
|
|
pg_typeof
|
|
|
|
-----------
|
|
|
|
boolean
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select pg_typeof('x'); -- unknown
|
|
|
|
pg_typeof
|
|
|
|
-----------
|
|
|
|
unknown
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select pg_typeof('' || ''); -- text
|
|
|
|
pg_typeof
|
|
|
|
-----------
|
|
|
|
text
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select pg_typeof(pg_typeof(0)); -- regtype
|
|
|
|
pg_typeof
|
|
|
|
-----------
|
|
|
|
regtype
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select pg_typeof(array[1.2,55.5]); -- numeric[]
|
|
|
|
pg_typeof
|
|
|
|
-----------
|
|
|
|
numeric[]
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select pg_typeof(myleast(10, 1, 20, 33)); -- polymorphic input
|
|
|
|
pg_typeof
|
|
|
|
-----------
|
|
|
|
integer
|
|
|
|
(1 row)
|
|
|
|
|
2008-12-18 19:20:35 +01:00
|
|
|
-- test functions with default parameters
|
2008-12-04 18:51:28 +01:00
|
|
|
-- test basic functionality
|
|
|
|
create function dfunc(a int = 1, int = 2) returns int as $$
|
|
|
|
select $1 + $2;
|
|
|
|
$$ language sql;
|
|
|
|
select dfunc();
|
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
3
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select dfunc(10);
|
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
12
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select dfunc(10, 20);
|
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
30
|
|
|
|
(1 row)
|
|
|
|
|
2008-12-18 19:20:35 +01:00
|
|
|
select dfunc(10, 20, 30); -- fail
|
|
|
|
ERROR: function dfunc(integer, integer, integer) does not exist
|
|
|
|
LINE 1: select dfunc(10, 20, 30);
|
|
|
|
^
|
|
|
|
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
|
2008-12-04 18:51:28 +01:00
|
|
|
drop function dfunc(); -- fail
|
|
|
|
ERROR: function dfunc() does not exist
|
|
|
|
drop function dfunc(int); -- fail
|
|
|
|
ERROR: function dfunc(integer) does not exist
|
|
|
|
drop function dfunc(int, int); -- ok
|
2008-12-18 19:20:35 +01:00
|
|
|
-- fail: defaults must be at end of argument list
|
2008-12-04 18:51:28 +01:00
|
|
|
create function dfunc(a int = 1, b int) returns int as $$
|
|
|
|
select $1 + $2;
|
|
|
|
$$ language sql;
|
2008-12-18 19:20:35 +01:00
|
|
|
ERROR: input parameters after one with a default value must also have defaults
|
|
|
|
-- however, this should work:
|
|
|
|
create function dfunc(a int = 1, out sum int, b int = 2) as $$
|
|
|
|
select $1 + $2;
|
|
|
|
$$ language sql;
|
|
|
|
select dfunc();
|
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
3
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
-- verify it lists properly
|
|
|
|
\df dfunc
|
2009-10-08 04:39:25 +02:00
|
|
|
List of functions
|
2009-04-21 17:49:06 +02:00
|
|
|
Schema | Name | Result data type | Argument data types | Type
|
|
|
|
--------+-------+------------------+-----------------------------------------------------------+--------
|
|
|
|
public | dfunc | integer | a integer DEFAULT 1, OUT sum integer, b integer DEFAULT 2 | normal
|
2008-12-18 19:20:35 +01:00
|
|
|
(1 row)
|
|
|
|
|
|
|
|
drop function dfunc(int, int);
|
|
|
|
-- check implicit coercion
|
2008-12-04 18:51:28 +01:00
|
|
|
create function dfunc(a int DEFAULT 1.0, int DEFAULT '-1') returns int as $$
|
|
|
|
select $1 + $2;
|
|
|
|
$$ language sql;
|
|
|
|
select dfunc();
|
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
0
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
create function dfunc(a text DEFAULT 'Hello', b text DEFAULT 'World') returns text as $$
|
|
|
|
select $1 || ', ' || $2;
|
|
|
|
$$ language sql;
|
2008-12-18 19:20:35 +01:00
|
|
|
select dfunc(); -- fail: which dfunc should be called? int or text
|
|
|
|
ERROR: function dfunc() is not unique
|
|
|
|
LINE 1: select dfunc();
|
|
|
|
^
|
|
|
|
HINT: Could not choose a best candidate function. You might need to add explicit type casts.
|
2008-12-04 18:51:28 +01:00
|
|
|
select dfunc('Hi'); -- ok
|
|
|
|
dfunc
|
|
|
|
-----------
|
|
|
|
Hi, World
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select dfunc('Hi', 'City'); -- ok
|
|
|
|
dfunc
|
|
|
|
----------
|
|
|
|
Hi, City
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select dfunc(0); -- ok
|
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
-1
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select dfunc(10, 20); -- ok
|
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
30
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
drop function dfunc(int, int);
|
|
|
|
drop function dfunc(text, text);
|
|
|
|
create function dfunc(int = 1, int = 2) returns int as $$
|
2008-12-18 19:20:35 +01:00
|
|
|
select 2;
|
2008-12-04 18:51:28 +01:00
|
|
|
$$ language sql;
|
|
|
|
create function dfunc(int = 1, int = 2, int = 3, int = 4) returns int as $$
|
|
|
|
select 4;
|
|
|
|
$$ language sql;
|
|
|
|
-- Now, dfunc(nargs = 2) and dfunc(nargs = 4) are ambiguous when called
|
2008-12-18 19:20:35 +01:00
|
|
|
-- with 0 to 2 arguments.
|
2008-12-04 18:51:28 +01:00
|
|
|
select dfunc(); -- fail
|
2008-12-18 19:20:35 +01:00
|
|
|
ERROR: function dfunc() is not unique
|
|
|
|
LINE 1: select dfunc();
|
|
|
|
^
|
|
|
|
HINT: Could not choose a best candidate function. You might need to add explicit type casts.
|
2008-12-04 18:51:28 +01:00
|
|
|
select dfunc(1); -- fail
|
2008-12-18 19:20:35 +01:00
|
|
|
ERROR: function dfunc(integer) is not unique
|
|
|
|
LINE 1: select dfunc(1);
|
|
|
|
^
|
|
|
|
HINT: Could not choose a best candidate function. You might need to add explicit type casts.
|
|
|
|
select dfunc(1, 2); -- fail
|
|
|
|
ERROR: function dfunc(integer, integer) is not unique
|
|
|
|
LINE 1: select dfunc(1, 2);
|
|
|
|
^
|
|
|
|
HINT: Could not choose a best candidate function. You might need to add explicit type casts.
|
2008-12-04 18:51:28 +01:00
|
|
|
select dfunc(1, 2, 3); -- ok
|
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
4
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select dfunc(1, 2, 3, 4); -- ok
|
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
4
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
drop function dfunc(int, int);
|
|
|
|
drop function dfunc(int, int, int, int);
|
|
|
|
-- default values are not allowed for output parameters
|
|
|
|
create function dfunc(out int = 20) returns int as $$
|
2008-12-18 19:20:35 +01:00
|
|
|
select 1;
|
2008-12-04 18:51:28 +01:00
|
|
|
$$ language sql;
|
2008-12-18 19:20:35 +01:00
|
|
|
ERROR: only input parameters can have default values
|
2008-12-04 18:51:28 +01:00
|
|
|
-- polymorphic parameter test
|
|
|
|
create function dfunc(anyelement = 'World'::text) returns text as $$
|
|
|
|
select 'Hello, ' || $1::text;
|
|
|
|
$$ language sql;
|
|
|
|
select dfunc();
|
|
|
|
dfunc
|
|
|
|
--------------
|
|
|
|
Hello, World
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select dfunc(0);
|
|
|
|
dfunc
|
|
|
|
----------
|
|
|
|
Hello, 0
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select dfunc(to_date('20081215','YYYYMMDD'));
|
|
|
|
dfunc
|
|
|
|
-------------------
|
|
|
|
Hello, 12-15-2008
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select dfunc('City'::text);
|
|
|
|
dfunc
|
|
|
|
-------------
|
|
|
|
Hello, City
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
drop function dfunc(anyelement);
|
2008-12-18 19:20:35 +01:00
|
|
|
-- check defaults for variadics
|
|
|
|
create function dfunc(a variadic int[]) returns int as
|
|
|
|
$$ select array_upper($1, 1) $$ language sql;
|
|
|
|
select dfunc(); -- fail
|
|
|
|
ERROR: function dfunc() does not exist
|
|
|
|
LINE 1: select dfunc();
|
|
|
|
^
|
|
|
|
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
|
|
|
|
select dfunc(10);
|
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
1
|
2008-12-04 18:51:28 +01:00
|
|
|
(1 row)
|
|
|
|
|
2008-12-18 19:20:35 +01:00
|
|
|
select dfunc(10,20);
|
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
2
|
2008-12-04 18:51:28 +01:00
|
|
|
(1 row)
|
|
|
|
|
2008-12-18 19:20:35 +01:00
|
|
|
create or replace function dfunc(a variadic int[] default array[]::int[]) returns int as
|
|
|
|
$$ select array_upper($1, 1) $$ language sql;
|
|
|
|
select dfunc(); -- now ok
|
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
|
2008-12-04 18:51:28 +01:00
|
|
|
(1 row)
|
|
|
|
|
2008-12-18 19:20:35 +01:00
|
|
|
select dfunc(10);
|
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
1
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select dfunc(10,20);
|
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
2
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
-- can't remove the default once it exists
|
|
|
|
create or replace function dfunc(a variadic int[]) returns int as
|
|
|
|
$$ select array_upper($1, 1) $$ language sql;
|
|
|
|
ERROR: cannot remove parameter defaults from existing function
|
|
|
|
HINT: Use DROP FUNCTION first.
|
|
|
|
\df dfunc
|
2009-10-08 04:39:25 +02:00
|
|
|
List of functions
|
2009-04-21 17:49:06 +02:00
|
|
|
Schema | Name | Result data type | Argument data types | Type
|
|
|
|
--------+-------+------------------+-------------------------------------------------+--------
|
|
|
|
public | dfunc | integer | VARIADIC a integer[] DEFAULT ARRAY[]::integer[] | normal
|
2008-12-18 19:20:35 +01:00
|
|
|
(1 row)
|
|
|
|
|
|
|
|
drop function dfunc(a variadic int[]);
|
|
|
|
-- Ambiguity should be reported only if there's not a better match available
|
2008-12-04 18:51:28 +01:00
|
|
|
create function dfunc(int = 1, int = 2, int = 3) returns int as $$
|
|
|
|
select 3;
|
|
|
|
$$ language sql;
|
|
|
|
create function dfunc(int = 1, int = 2) returns int as $$
|
|
|
|
select 2;
|
|
|
|
$$ language sql;
|
|
|
|
create function dfunc(text) returns text as $$
|
|
|
|
select $1;
|
|
|
|
$$ language sql;
|
2008-12-18 19:20:35 +01:00
|
|
|
-- dfunc(narg=2) and dfunc(narg=3) are ambiguous
|
|
|
|
select dfunc(1); -- fail
|
|
|
|
ERROR: function dfunc(integer) is not unique
|
|
|
|
LINE 1: select dfunc(1);
|
|
|
|
^
|
|
|
|
HINT: Could not choose a best candidate function. You might need to add explicit type casts.
|
|
|
|
-- but this works since the ambiguous functions aren't preferred anyway
|
2008-12-04 18:51:28 +01:00
|
|
|
select dfunc('Hi');
|
2008-12-18 19:20:35 +01:00
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
Hi
|
|
|
|
(1 row)
|
|
|
|
|
2008-12-04 18:51:28 +01:00
|
|
|
drop function dfunc(int, int, int);
|
|
|
|
drop function dfunc(int, int);
|
|
|
|
drop function dfunc(text);
|
2009-10-08 04:39:25 +02:00
|
|
|
--
|
|
|
|
-- Tests for named- and mixed-notation function calling
|
|
|
|
--
|
|
|
|
create function dfunc(a int, b int, c int = 0, d int = 0)
|
|
|
|
returns table (a int, b int, c int, d int) as $$
|
|
|
|
select $1, $2, $3, $4;
|
|
|
|
$$ language sql;
|
|
|
|
select (dfunc(10,20,30)).*;
|
|
|
|
a | b | c | d
|
|
|
|
----+----+----+---
|
|
|
|
10 | 20 | 30 | 0
|
|
|
|
(1 row)
|
|
|
|
|
2010-05-30 20:10:41 +02:00
|
|
|
select (dfunc(a := 10, b := 20, c := 30)).*;
|
2009-10-08 04:39:25 +02:00
|
|
|
a | b | c | d
|
|
|
|
----+----+----+---
|
|
|
|
10 | 20 | 30 | 0
|
|
|
|
(1 row)
|
|
|
|
|
2010-05-30 20:10:41 +02:00
|
|
|
select * from dfunc(a := 10, b := 20);
|
2009-10-08 04:39:25 +02:00
|
|
|
a | b | c | d
|
|
|
|
----+----+---+---
|
|
|
|
10 | 20 | 0 | 0
|
|
|
|
(1 row)
|
|
|
|
|
2010-05-30 20:10:41 +02:00
|
|
|
select * from dfunc(b := 10, a := 20);
|
2009-10-08 04:39:25 +02:00
|
|
|
a | b | c | d
|
|
|
|
----+----+---+---
|
|
|
|
20 | 10 | 0 | 0
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select * from dfunc(0); -- fail
|
|
|
|
ERROR: function dfunc(integer) does not exist
|
|
|
|
LINE 1: select * from dfunc(0);
|
|
|
|
^
|
|
|
|
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
|
|
|
|
select * from dfunc(1,2);
|
|
|
|
a | b | c | d
|
|
|
|
---+---+---+---
|
|
|
|
1 | 2 | 0 | 0
|
|
|
|
(1 row)
|
|
|
|
|
2010-05-30 20:10:41 +02:00
|
|
|
select * from dfunc(1,2,c := 3);
|
2009-10-08 04:39:25 +02:00
|
|
|
a | b | c | d
|
|
|
|
---+---+---+---
|
|
|
|
1 | 2 | 3 | 0
|
|
|
|
(1 row)
|
|
|
|
|
2010-05-30 20:10:41 +02:00
|
|
|
select * from dfunc(1,2,d := 3);
|
2009-10-08 04:39:25 +02:00
|
|
|
a | b | c | d
|
|
|
|
---+---+---+---
|
|
|
|
1 | 2 | 0 | 3
|
|
|
|
(1 row)
|
|
|
|
|
2010-05-30 20:10:41 +02:00
|
|
|
select * from dfunc(x := 20, b := 10, x := 30); -- fail, duplicate name
|
2009-10-08 04:39:25 +02:00
|
|
|
ERROR: argument name "x" used more than once
|
2010-05-30 20:10:41 +02:00
|
|
|
LINE 1: select * from dfunc(x := 20, b := 10, x := 30);
|
|
|
|
^
|
|
|
|
select * from dfunc(10, b := 20, 30); -- fail, named args must be last
|
2009-10-08 04:39:25 +02:00
|
|
|
ERROR: positional argument cannot follow named argument
|
2010-05-30 20:10:41 +02:00
|
|
|
LINE 1: select * from dfunc(10, b := 20, 30);
|
2009-10-08 04:39:25 +02:00
|
|
|
^
|
2010-05-30 20:10:41 +02:00
|
|
|
select * from dfunc(x := 10, b := 20, c := 30); -- fail, unknown param
|
|
|
|
ERROR: function dfunc(x := integer, b := integer, c := integer) does not exist
|
|
|
|
LINE 1: select * from dfunc(x := 10, b := 20, c := 30);
|
2009-10-08 04:39:25 +02:00
|
|
|
^
|
|
|
|
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
|
2010-05-30 20:10:41 +02:00
|
|
|
select * from dfunc(10, 10, a := 20); -- fail, a overlaps positional parameter
|
|
|
|
ERROR: function dfunc(integer, integer, a := integer) does not exist
|
|
|
|
LINE 1: select * from dfunc(10, 10, a := 20);
|
2009-10-08 04:39:25 +02:00
|
|
|
^
|
|
|
|
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
|
2010-05-30 20:10:41 +02:00
|
|
|
select * from dfunc(1,c := 2,d := 3); -- fail, no value for b
|
|
|
|
ERROR: function dfunc(integer, c := integer, d := integer) does not exist
|
|
|
|
LINE 1: select * from dfunc(1,c := 2,d := 3);
|
2009-10-08 04:39:25 +02:00
|
|
|
^
|
|
|
|
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
|
|
|
|
drop function dfunc(int, int, int, int);
|
|
|
|
-- test with different parameter types
|
|
|
|
create function dfunc(a varchar, b numeric, c date = current_date)
|
|
|
|
returns table (a varchar, b numeric, c date) as $$
|
|
|
|
select $1, $2, $3;
|
|
|
|
$$ language sql;
|
|
|
|
select (dfunc('Hello World', 20, '2009-07-25'::date)).*;
|
|
|
|
a | b | c
|
|
|
|
-------------+----+------------
|
|
|
|
Hello World | 20 | 07-25-2009
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select * from dfunc('Hello World', 20, '2009-07-25'::date);
|
|
|
|
a | b | c
|
|
|
|
-------------+----+------------
|
|
|
|
Hello World | 20 | 07-25-2009
|
|
|
|
(1 row)
|
|
|
|
|
2010-05-30 20:10:41 +02:00
|
|
|
select * from dfunc(c := '2009-07-25'::date, a := 'Hello World', b := 20);
|
2009-10-08 04:39:25 +02:00
|
|
|
a | b | c
|
|
|
|
-------------+----+------------
|
|
|
|
Hello World | 20 | 07-25-2009
|
|
|
|
(1 row)
|
|
|
|
|
2010-05-30 20:10:41 +02:00
|
|
|
select * from dfunc('Hello World', b := 20, c := '2009-07-25'::date);
|
2009-10-08 04:39:25 +02:00
|
|
|
a | b | c
|
|
|
|
-------------+----+------------
|
|
|
|
Hello World | 20 | 07-25-2009
|
|
|
|
(1 row)
|
|
|
|
|
2010-05-30 20:10:41 +02:00
|
|
|
select * from dfunc('Hello World', c := '2009-07-25'::date, b := 20);
|
2009-10-08 04:39:25 +02:00
|
|
|
a | b | c
|
|
|
|
-------------+----+------------
|
|
|
|
Hello World | 20 | 07-25-2009
|
|
|
|
(1 row)
|
|
|
|
|
2010-05-30 20:10:41 +02:00
|
|
|
select * from dfunc('Hello World', c := 20, b := '2009-07-25'::date); -- fail
|
|
|
|
ERROR: function dfunc(unknown, c := integer, b := date) does not exist
|
|
|
|
LINE 1: select * from dfunc('Hello World', c := 20, b := '2009-07-25...
|
2009-10-08 04:39:25 +02:00
|
|
|
^
|
|
|
|
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
|
|
|
|
drop function dfunc(varchar, numeric, date);
|
|
|
|
-- test out parameters with named params
|
|
|
|
create function dfunc(a varchar = 'def a', out _a varchar, c numeric = NULL, out _c numeric)
|
|
|
|
returns record as $$
|
|
|
|
select $1, $2;
|
|
|
|
$$ language sql;
|
|
|
|
select (dfunc()).*;
|
|
|
|
_a | _c
|
|
|
|
-------+----
|
|
|
|
def a |
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select * from dfunc();
|
|
|
|
_a | _c
|
|
|
|
-------+----
|
|
|
|
def a |
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select * from dfunc('Hello', 100);
|
|
|
|
_a | _c
|
|
|
|
-------+-----
|
|
|
|
Hello | 100
|
|
|
|
(1 row)
|
|
|
|
|
2010-05-30 20:10:41 +02:00
|
|
|
select * from dfunc(a := 'Hello', c := 100);
|
2009-10-08 04:39:25 +02:00
|
|
|
_a | _c
|
|
|
|
-------+-----
|
|
|
|
Hello | 100
|
|
|
|
(1 row)
|
|
|
|
|
2010-05-30 20:10:41 +02:00
|
|
|
select * from dfunc(c := 100, a := 'Hello');
|
2009-10-08 04:39:25 +02:00
|
|
|
_a | _c
|
|
|
|
-------+-----
|
|
|
|
Hello | 100
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select * from dfunc('Hello');
|
|
|
|
_a | _c
|
|
|
|
-------+----
|
|
|
|
Hello |
|
|
|
|
(1 row)
|
|
|
|
|
2010-05-30 20:10:41 +02:00
|
|
|
select * from dfunc('Hello', c := 100);
|
2009-10-08 04:39:25 +02:00
|
|
|
_a | _c
|
|
|
|
-------+-----
|
|
|
|
Hello | 100
|
|
|
|
(1 row)
|
|
|
|
|
2010-05-30 20:10:41 +02:00
|
|
|
select * from dfunc(c := 100);
|
2009-10-08 04:39:25 +02:00
|
|
|
_a | _c
|
|
|
|
-------+-----
|
|
|
|
def a | 100
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
-- fail, can no longer change an input parameter's name
|
|
|
|
create or replace function dfunc(a varchar = 'def a', out _a varchar, x numeric = NULL, out _c numeric)
|
|
|
|
returns record as $$
|
|
|
|
select $1, $2;
|
|
|
|
$$ language sql;
|
|
|
|
ERROR: cannot change name of input parameter "c"
|
|
|
|
HINT: Use DROP FUNCTION first.
|
|
|
|
create or replace function dfunc(a varchar = 'def a', out _a varchar, numeric = NULL, out _c numeric)
|
|
|
|
returns record as $$
|
|
|
|
select $1, $2;
|
|
|
|
$$ language sql;
|
|
|
|
ERROR: cannot change name of input parameter "c"
|
|
|
|
HINT: Use DROP FUNCTION first.
|
|
|
|
drop function dfunc(varchar, numeric);
|
|
|
|
--fail, named parameters are not unique
|
|
|
|
create function testfoo(a int, a int) returns int as $$ select 1;$$ language sql;
|
|
|
|
ERROR: parameter name "a" used more than once
|
|
|
|
create function testfoo(int, out a int, out a int) returns int as $$ select 1;$$ language sql;
|
|
|
|
ERROR: parameter name "a" used more than once
|
|
|
|
create function testfoo(out a int, inout a int) returns int as $$ select 1;$$ language sql;
|
|
|
|
ERROR: parameter name "a" used more than once
|
|
|
|
create function testfoo(a int, inout a int) returns int as $$ select 1;$$ language sql;
|
|
|
|
ERROR: parameter name "a" used more than once
|
|
|
|
-- valid
|
|
|
|
create function testfoo(a int, out a int) returns int as $$ select $1;$$ language sql;
|
|
|
|
select testfoo(37);
|
|
|
|
testfoo
|
|
|
|
---------
|
|
|
|
37
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
drop function testfoo(int);
|
|
|
|
create function testfoo(a int) returns table(a int) as $$ select $1;$$ language sql;
|
|
|
|
select * from testfoo(37);
|
|
|
|
a
|
|
|
|
----
|
|
|
|
37
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
drop function testfoo(int);
|
|
|
|
-- test polymorphic params and defaults
|
|
|
|
create function dfunc(a anyelement, b anyelement = null, flag bool = true)
|
|
|
|
returns anyelement as $$
|
|
|
|
select case when $3 then $1 else $2 end;
|
|
|
|
$$ language sql;
|
|
|
|
select dfunc(1,2);
|
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
1
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select dfunc('a'::text, 'b'); -- positional notation with default
|
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
a
|
|
|
|
(1 row)
|
|
|
|
|
2010-05-30 20:10:41 +02:00
|
|
|
select dfunc(a := 1, b := 2);
|
2009-10-08 04:39:25 +02:00
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
1
|
|
|
|
(1 row)
|
|
|
|
|
2010-05-30 20:10:41 +02:00
|
|
|
select dfunc(a := 'a'::text, b := 'b');
|
2009-10-08 04:39:25 +02:00
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
a
|
|
|
|
(1 row)
|
|
|
|
|
2010-05-30 20:10:41 +02:00
|
|
|
select dfunc(a := 'a'::text, b := 'b', flag := false); -- named notation
|
2009-10-08 04:39:25 +02:00
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
b
|
|
|
|
(1 row)
|
|
|
|
|
2010-05-30 20:10:41 +02:00
|
|
|
select dfunc(b := 'b'::text, a := 'a'); -- named notation with default
|
2009-10-08 04:39:25 +02:00
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
a
|
|
|
|
(1 row)
|
|
|
|
|
2010-05-30 20:10:41 +02:00
|
|
|
select dfunc(a := 'a'::text, flag := true); -- named notation with default
|
2009-10-08 04:39:25 +02:00
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
a
|
|
|
|
(1 row)
|
|
|
|
|
2010-05-30 20:10:41 +02:00
|
|
|
select dfunc(a := 'a'::text, flag := false); -- named notation with default
|
2009-10-08 04:39:25 +02:00
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
|
|
|
|
(1 row)
|
|
|
|
|
2010-05-30 20:10:41 +02:00
|
|
|
select dfunc(b := 'b'::text, a := 'a', flag := true); -- named notation
|
2009-10-08 04:39:25 +02:00
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
a
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select dfunc('a'::text, 'b', false); -- full positional notation
|
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
b
|
|
|
|
(1 row)
|
|
|
|
|
2010-05-30 20:10:41 +02:00
|
|
|
select dfunc('a'::text, 'b', flag := false); -- mixed notation
|
2009-10-08 04:39:25 +02:00
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
b
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select dfunc('a'::text, 'b', true); -- full positional notation
|
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
a
|
|
|
|
(1 row)
|
|
|
|
|
2010-05-30 20:10:41 +02:00
|
|
|
select dfunc('a'::text, 'b', flag := true); -- mixed notation
|
2009-10-08 04:39:25 +02:00
|
|
|
dfunc
|
|
|
|
-------
|
|
|
|
a
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
-- check reverse-listing of named-arg calls
|
|
|
|
CREATE VIEW dfview AS
|
|
|
|
SELECT q1, q2,
|
2010-05-30 20:10:41 +02:00
|
|
|
dfunc(q1,q2, flag := q1>q2) as c3,
|
|
|
|
dfunc(q1, flag := q1<q2, b := q2) as c4
|
2009-10-08 04:39:25 +02:00
|
|
|
FROM int8_tbl;
|
|
|
|
select * from dfview;
|
|
|
|
q1 | q2 | c3 | c4
|
|
|
|
------------------+-------------------+------------------+-------------------
|
|
|
|
123 | 456 | 456 | 123
|
|
|
|
123 | 4567890123456789 | 4567890123456789 | 123
|
|
|
|
4567890123456789 | 123 | 4567890123456789 | 123
|
|
|
|
4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789
|
|
|
|
4567890123456789 | -4567890123456789 | 4567890123456789 | -4567890123456789
|
|
|
|
(5 rows)
|
|
|
|
|
2009-11-03 15:52:10 +01:00
|
|
|
\d+ dfview
|
|
|
|
View "public.dfview"
|
|
|
|
Column | Type | Modifiers | Storage | Description
|
|
|
|
--------+--------+-----------+---------+-------------
|
|
|
|
q1 | bigint | | plain |
|
|
|
|
q2 | bigint | | plain |
|
|
|
|
c3 | bigint | | plain |
|
|
|
|
c4 | bigint | | plain |
|
2009-10-08 04:39:25 +02:00
|
|
|
View definition:
|
2012-02-19 17:43:46 +01:00
|
|
|
SELECT int8_tbl.q1, int8_tbl.q2,
|
|
|
|
dfunc(int8_tbl.q1, int8_tbl.q2, flag := int8_tbl.q1 > int8_tbl.q2) AS c3,
|
|
|
|
dfunc(int8_tbl.q1, flag := int8_tbl.q1 < int8_tbl.q2, b := int8_tbl.q2) AS c4
|
2009-10-08 04:39:25 +02:00
|
|
|
FROM int8_tbl;
|
|
|
|
|
|
|
|
drop view dfview;
|
|
|
|
drop function dfunc(anyelement, anyelement, bool);
|