mirror of
https://github.com/postgres/postgres.git
synced 2025-07-07 00:36:50 +03:00
Implement OR REPLACE option for CREATE AGGREGATE.
Aggregates have acquired a dozen or so optional attributes in recent years for things like parallel query and moving-aggregate mode; the lack of an OR REPLACE option to add or change these for an existing agg makes extension upgrades gratuitously hard. Rectify.
This commit is contained in:
@ -160,6 +160,77 @@ WHERE aggfnoid = 'myavg'::REGPROC;
|
||||
myavg | numeric_avg_accum | numeric_avg_combine | internal | numeric_avg_serialize | numeric_avg_deserialize | s
|
||||
(1 row)
|
||||
|
||||
DROP AGGREGATE myavg (numeric);
|
||||
-- create or replace aggregate
|
||||
CREATE AGGREGATE myavg (numeric)
|
||||
(
|
||||
stype = internal,
|
||||
sfunc = numeric_avg_accum,
|
||||
finalfunc = numeric_avg
|
||||
);
|
||||
CREATE OR REPLACE AGGREGATE myavg (numeric)
|
||||
(
|
||||
stype = internal,
|
||||
sfunc = numeric_avg_accum,
|
||||
finalfunc = numeric_avg,
|
||||
serialfunc = numeric_avg_serialize,
|
||||
deserialfunc = numeric_avg_deserialize,
|
||||
combinefunc = numeric_avg_combine,
|
||||
finalfunc_modify = shareable -- just to test a non-default setting
|
||||
);
|
||||
-- Ensure all these functions made it into the catalog again
|
||||
SELECT aggfnoid, aggtransfn, aggcombinefn, aggtranstype::regtype,
|
||||
aggserialfn, aggdeserialfn, aggfinalmodify
|
||||
FROM pg_aggregate
|
||||
WHERE aggfnoid = 'myavg'::REGPROC;
|
||||
aggfnoid | aggtransfn | aggcombinefn | aggtranstype | aggserialfn | aggdeserialfn | aggfinalmodify
|
||||
----------+-------------------+---------------------+--------------+-----------------------+-------------------------+----------------
|
||||
myavg | numeric_avg_accum | numeric_avg_combine | internal | numeric_avg_serialize | numeric_avg_deserialize | s
|
||||
(1 row)
|
||||
|
||||
-- can change stype:
|
||||
CREATE OR REPLACE AGGREGATE myavg (numeric)
|
||||
(
|
||||
stype = numeric,
|
||||
sfunc = numeric_add
|
||||
);
|
||||
SELECT aggfnoid, aggtransfn, aggcombinefn, aggtranstype::regtype,
|
||||
aggserialfn, aggdeserialfn, aggfinalmodify
|
||||
FROM pg_aggregate
|
||||
WHERE aggfnoid = 'myavg'::REGPROC;
|
||||
aggfnoid | aggtransfn | aggcombinefn | aggtranstype | aggserialfn | aggdeserialfn | aggfinalmodify
|
||||
----------+-------------+--------------+--------------+-------------+---------------+----------------
|
||||
myavg | numeric_add | - | numeric | - | - | r
|
||||
(1 row)
|
||||
|
||||
-- can't change return type:
|
||||
CREATE OR REPLACE AGGREGATE myavg (numeric)
|
||||
(
|
||||
stype = numeric,
|
||||
sfunc = numeric_add,
|
||||
finalfunc = numeric_out
|
||||
);
|
||||
ERROR: cannot change return type of existing function
|
||||
HINT: Use DROP AGGREGATE myavg(numeric) first.
|
||||
-- can't change to a different kind:
|
||||
CREATE OR REPLACE AGGREGATE myavg (order by numeric)
|
||||
(
|
||||
stype = numeric,
|
||||
sfunc = numeric_add
|
||||
);
|
||||
ERROR: cannot change routine kind
|
||||
DETAIL: "myavg" is an ordinary aggregate function.
|
||||
-- can't change plain function to aggregate:
|
||||
create function sum4(int8,int8,int8,int8) returns int8 as
|
||||
'select $1 + $2 + $3 + $4' language sql strict immutable;
|
||||
CREATE OR REPLACE AGGREGATE sum3 (int8,int8,int8)
|
||||
(
|
||||
stype = int8,
|
||||
sfunc = sum4
|
||||
);
|
||||
ERROR: cannot change routine kind
|
||||
DETAIL: "sum3" is a function.
|
||||
drop function sum4(int8,int8,int8,int8);
|
||||
DROP AGGREGATE myavg (numeric);
|
||||
-- invalid: bad parallel-safety marking
|
||||
CREATE AGGREGATE mysum (int)
|
||||
|
@ -174,6 +174,71 @@ WHERE aggfnoid = 'myavg'::REGPROC;
|
||||
|
||||
DROP AGGREGATE myavg (numeric);
|
||||
|
||||
-- create or replace aggregate
|
||||
CREATE AGGREGATE myavg (numeric)
|
||||
(
|
||||
stype = internal,
|
||||
sfunc = numeric_avg_accum,
|
||||
finalfunc = numeric_avg
|
||||
);
|
||||
|
||||
CREATE OR REPLACE AGGREGATE myavg (numeric)
|
||||
(
|
||||
stype = internal,
|
||||
sfunc = numeric_avg_accum,
|
||||
finalfunc = numeric_avg,
|
||||
serialfunc = numeric_avg_serialize,
|
||||
deserialfunc = numeric_avg_deserialize,
|
||||
combinefunc = numeric_avg_combine,
|
||||
finalfunc_modify = shareable -- just to test a non-default setting
|
||||
);
|
||||
|
||||
-- Ensure all these functions made it into the catalog again
|
||||
SELECT aggfnoid, aggtransfn, aggcombinefn, aggtranstype::regtype,
|
||||
aggserialfn, aggdeserialfn, aggfinalmodify
|
||||
FROM pg_aggregate
|
||||
WHERE aggfnoid = 'myavg'::REGPROC;
|
||||
|
||||
-- can change stype:
|
||||
CREATE OR REPLACE AGGREGATE myavg (numeric)
|
||||
(
|
||||
stype = numeric,
|
||||
sfunc = numeric_add
|
||||
);
|
||||
SELECT aggfnoid, aggtransfn, aggcombinefn, aggtranstype::regtype,
|
||||
aggserialfn, aggdeserialfn, aggfinalmodify
|
||||
FROM pg_aggregate
|
||||
WHERE aggfnoid = 'myavg'::REGPROC;
|
||||
|
||||
-- can't change return type:
|
||||
CREATE OR REPLACE AGGREGATE myavg (numeric)
|
||||
(
|
||||
stype = numeric,
|
||||
sfunc = numeric_add,
|
||||
finalfunc = numeric_out
|
||||
);
|
||||
|
||||
-- can't change to a different kind:
|
||||
CREATE OR REPLACE AGGREGATE myavg (order by numeric)
|
||||
(
|
||||
stype = numeric,
|
||||
sfunc = numeric_add
|
||||
);
|
||||
|
||||
-- can't change plain function to aggregate:
|
||||
create function sum4(int8,int8,int8,int8) returns int8 as
|
||||
'select $1 + $2 + $3 + $4' language sql strict immutable;
|
||||
|
||||
CREATE OR REPLACE AGGREGATE sum3 (int8,int8,int8)
|
||||
(
|
||||
stype = int8,
|
||||
sfunc = sum4
|
||||
);
|
||||
|
||||
drop function sum4(int8,int8,int8,int8);
|
||||
|
||||
DROP AGGREGATE myavg (numeric);
|
||||
|
||||
-- invalid: bad parallel-safety marking
|
||||
CREATE AGGREGATE mysum (int)
|
||||
(
|
||||
|
Reference in New Issue
Block a user