1
0
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:
Andrew Gierth
2019-03-19 01:16:50 +00:00
parent f2004f19ed
commit 01bde4fa4c
13 changed files with 235 additions and 24 deletions

View File

@ -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)

View File

@ -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)
(