1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-30 11:03:19 +03:00

Add ALTER OPERATOR command, for changing selectivity estimator functions.

Other options cannot be changed, as it's not totally clear if cached plans
would need to be invalidated if one of the other options change. Selectivity
estimator functions only change plan costs, not correctness of plans, so
those should be safe.

Original patch by Uriy Zhuravlev, heavily edited by me.
This commit is contained in:
Heikki Linnakangas
2015-07-14 18:17:55 +03:00
parent 705d397cd9
commit 321eed5f0f
13 changed files with 499 additions and 65 deletions

View File

@ -0,0 +1,76 @@
CREATE OR REPLACE FUNCTION alter_op_test_fn(boolean, boolean)
RETURNS boolean AS $$ SELECT NULL::BOOLEAN; $$ LANGUAGE sql IMMUTABLE;
CREATE OPERATOR === (
LEFTARG = boolean,
RIGHTARG = boolean,
PROCEDURE = alter_op_test_fn,
COMMUTATOR = ===,
NEGATOR = !==,
RESTRICT = contsel,
JOIN = contjoinsel,
HASHES, MERGES
);
--
-- Reset and set params
--
ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = NONE);
ALTER OPERATOR === (boolean, boolean) SET (JOIN = NONE);
SELECT oprrest, oprjoin FROM pg_operator WHERE oprname = '==='
AND oprleft = 'boolean'::regtype AND oprright = 'boolean'::regtype;
oprrest | oprjoin
---------+---------
- | -
(1 row)
ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = contsel);
ALTER OPERATOR === (boolean, boolean) SET (JOIN = contjoinsel);
SELECT oprrest, oprjoin FROM pg_operator WHERE oprname = '==='
AND oprleft = 'boolean'::regtype AND oprright = 'boolean'::regtype;
oprrest | oprjoin
---------+-------------
contsel | contjoinsel
(1 row)
ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = NONE, JOIN = NONE);
SELECT oprrest, oprjoin FROM pg_operator WHERE oprname = '==='
AND oprleft = 'boolean'::regtype AND oprright = 'boolean'::regtype;
oprrest | oprjoin
---------+---------
- | -
(1 row)
ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = contsel, JOIN = contjoinsel);
SELECT oprrest, oprjoin FROM pg_operator WHERE oprname = '==='
AND oprleft = 'boolean'::regtype AND oprright = 'boolean'::regtype;
oprrest | oprjoin
---------+-------------
contsel | contjoinsel
(1 row)
--
-- Test invalid options.
--
ALTER OPERATOR === (boolean, boolean) SET (COMMUTATOR = ====);
ERROR: operator attribute "commutator" can not be changed
ALTER OPERATOR === (boolean, boolean) SET (NEGATOR = ====);
ERROR: operator attribute "negator" can not be changed
ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = non_existent_func);
ERROR: function non_existent_func(internal, oid, internal, integer) does not exist
ALTER OPERATOR === (boolean, boolean) SET (JOIN = non_existent_func);
ERROR: function non_existent_func(internal, oid, internal, smallint, internal) does not exist
ALTER OPERATOR === (boolean, boolean) SET (COMMUTATOR = !==);
ERROR: operator attribute "commutator" can not be changed
ALTER OPERATOR === (boolean, boolean) SET (NEGATOR = !==);
ERROR: operator attribute "negator" can not be changed
--
-- Test permission check. Must be owner to ALTER OPERATOR.
--
CREATE USER regtest_alter_user;
SET SESSION AUTHORIZATION regtest_alter_user_user;
ERROR: role "regtest_alter_user_user" does not exist
ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = NONE);
RESET SESSION AUTHORIZATION;
-- Clean up
DROP USER regression_alter_user;
ERROR: role "regression_alter_user" does not exist
DROP OPERATOR === (boolean, boolean);

View File

@ -89,7 +89,7 @@ test: brin gin gist spgist privileges security_label collate matview lock replic
# ----------
# Another group of parallel tests
# ----------
test: alter_generic misc psql async
test: alter_generic alter_operator misc psql async
# rules cannot run concurrently with any test that creates a view
test: rules

View File

@ -111,6 +111,7 @@ test: replica_identity
test: rowsecurity
test: object_address
test: alter_generic
test: alter_operator
test: misc
test: psql
test: async

View File

@ -0,0 +1,64 @@
CREATE OR REPLACE FUNCTION alter_op_test_fn(boolean, boolean)
RETURNS boolean AS $$ SELECT NULL::BOOLEAN; $$ LANGUAGE sql IMMUTABLE;
CREATE OPERATOR === (
LEFTARG = boolean,
RIGHTARG = boolean,
PROCEDURE = alter_op_test_fn,
COMMUTATOR = ===,
NEGATOR = !==,
RESTRICT = contsel,
JOIN = contjoinsel,
HASHES, MERGES
);
--
-- Reset and set params
--
ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = NONE);
ALTER OPERATOR === (boolean, boolean) SET (JOIN = NONE);
SELECT oprrest, oprjoin FROM pg_operator WHERE oprname = '==='
AND oprleft = 'boolean'::regtype AND oprright = 'boolean'::regtype;
ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = contsel);
ALTER OPERATOR === (boolean, boolean) SET (JOIN = contjoinsel);
SELECT oprrest, oprjoin FROM pg_operator WHERE oprname = '==='
AND oprleft = 'boolean'::regtype AND oprright = 'boolean'::regtype;
ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = NONE, JOIN = NONE);
SELECT oprrest, oprjoin FROM pg_operator WHERE oprname = '==='
AND oprleft = 'boolean'::regtype AND oprright = 'boolean'::regtype;
ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = contsel, JOIN = contjoinsel);
SELECT oprrest, oprjoin FROM pg_operator WHERE oprname = '==='
AND oprleft = 'boolean'::regtype AND oprright = 'boolean'::regtype;
--
-- Test invalid options.
--
ALTER OPERATOR === (boolean, boolean) SET (COMMUTATOR = ====);
ALTER OPERATOR === (boolean, boolean) SET (NEGATOR = ====);
ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = non_existent_func);
ALTER OPERATOR === (boolean, boolean) SET (JOIN = non_existent_func);
ALTER OPERATOR === (boolean, boolean) SET (COMMUTATOR = !==);
ALTER OPERATOR === (boolean, boolean) SET (NEGATOR = !==);
--
-- Test permission check. Must be owner to ALTER OPERATOR.
--
CREATE USER regtest_alter_user;
SET SESSION AUTHORIZATION regtest_alter_user_user;
ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = NONE);
RESET SESSION AUTHORIZATION;
-- Clean up
DROP USER regression_alter_user;
DROP OPERATOR === (boolean, boolean);