Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0dab5ef

Browse files
committed
Fix ALTER OPERATOR to update dependencies properly.
Fix an oversight in commit321eed5: replacing an operator'sselectivity functions needs to result in a corresponding update inpg_depend. We have a function that can handle that, but it was notcalled by AlterOperator().To fix this without enlarging pg_operator.h's #include list beyondwhat clients can safely include, split off the function definitionsinto a new file pg_operator_fn.h, similarly to what we've done forsome other catalog header files. It's not entirely clear whetherany client-side code needs to include pg_operator.h, but it seemsprudent to assume that there is some such code somewhere.
1 parente5d06f2 commit0dab5ef

File tree

6 files changed

+163
-42
lines changed

6 files changed

+163
-42
lines changed

‎src/backend/catalog/pg_operator.c

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include"catalog/objectaccess.h"
2727
#include"catalog/pg_namespace.h"
2828
#include"catalog/pg_operator.h"
29+
#include"catalog/pg_operator_fn.h"
2930
#include"catalog/pg_proc.h"
3031
#include"catalog/pg_type.h"
3132
#include"miscadmin.h"
@@ -61,8 +62,6 @@ static Oid get_other_operator(List *otherOp,
6162
OidleftTypeId,OidrightTypeId,
6263
boolisCommutator);
6364

64-
staticObjectAddressmakeOperatorDependencies(HeapTupletuple);
65-
6665

6766
/*
6867
* Check whether a proposed operator name is legal
@@ -270,7 +269,7 @@ OperatorShellMake(const char *operatorName,
270269
CatalogUpdateIndexes(pg_operator_desc,tup);
271270

272271
/* Add dependencies for the entry */
273-
makeOperatorDependencies(tup);
272+
makeOperatorDependencies(tup, false);
274273

275274
heap_freetuple(tup);
276275

@@ -340,6 +339,7 @@ OperatorCreate(const char *operatorName,
340339
{
341340
Relationpg_operator_desc;
342341
HeapTupletup;
342+
boolisUpdate;
343343
boolnulls[Natts_pg_operator];
344344
boolreplaces[Natts_pg_operator];
345345
Datumvalues[Natts_pg_operator];
@@ -350,7 +350,6 @@ OperatorCreate(const char *operatorName,
350350
negatorId;
351351
boolselfCommutator= false;
352352
NameDataoname;
353-
TupleDesctupDesc;
354353
inti;
355354
ObjectAddressaddress;
356355

@@ -515,6 +514,8 @@ OperatorCreate(const char *operatorName,
515514
*/
516515
if (operatorObjectId)
517516
{
517+
isUpdate= true;
518+
518519
tup=SearchSysCacheCopy1(OPEROID,
519520
ObjectIdGetDatum(operatorObjectId));
520521
if (!HeapTupleIsValid(tup))
@@ -531,8 +532,10 @@ OperatorCreate(const char *operatorName,
531532
}
532533
else
533534
{
534-
tupDesc=pg_operator_desc->rd_att;
535-
tup=heap_form_tuple(tupDesc,values,nulls);
535+
isUpdate= false;
536+
537+
tup=heap_form_tuple(RelationGetDescr(pg_operator_desc),
538+
values,nulls);
536539

537540
operatorObjectId=simple_heap_insert(pg_operator_desc,tup);
538541
}
@@ -541,7 +544,7 @@ OperatorCreate(const char *operatorName,
541544
CatalogUpdateIndexes(pg_operator_desc,tup);
542545

543546
/* Add dependencies for the entry */
544-
address=makeOperatorDependencies(tup);
547+
address=makeOperatorDependencies(tup,isUpdate);
545548

546549
/* Post creation hook for new operator */
547550
InvokeObjectPostCreateHook(OperatorRelationId,operatorObjectId,0);
@@ -759,14 +762,15 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId)
759762
}
760763

761764
/*
762-
* Create dependencies for a new operator (either a freshly inserted
763-
* complete operator, a new shell operator, or a just-updated shell).
765+
* Create dependencies for an operator (either a freshly inserted
766+
* complete operator, a new shell operator, a just-updated shell,
767+
* or an operator that's being modified by ALTER OPERATOR).
764768
*
765769
* NB: the OidIsValid tests in this routine are necessary, in case
766770
* the given operator is a shell.
767771
*/
768-
staticObjectAddress
769-
makeOperatorDependencies(HeapTupletuple)
772+
ObjectAddress
773+
makeOperatorDependencies(HeapTupletuple,boolisUpdate)
770774
{
771775
Form_pg_operatoroper= (Form_pg_operator)GETSTRUCT(tuple);
772776
ObjectAddressmyself,
@@ -777,11 +781,14 @@ makeOperatorDependencies(HeapTuple tuple)
777781
myself.objectSubId=0;
778782

779783
/*
780-
*In casewe are updatinga shell, delete any existing entries, except
784+
*Ifwe are updatingthe operator, delete any existing entries, except
781785
* for extension membership which should remain the same.
782786
*/
783-
deleteDependencyRecordsFor(myself.classId,myself.objectId, true);
784-
deleteSharedDependencyRecordsFor(myself.classId,myself.objectId,0);
787+
if (isUpdate)
788+
{
789+
deleteDependencyRecordsFor(myself.classId,myself.objectId, true);
790+
deleteSharedDependencyRecordsFor(myself.classId,myself.objectId,0);
791+
}
785792

786793
/* Dependency on namespace */
787794
if (OidIsValid(oper->oprnamespace))

‎src/backend/commands/operatorcmds.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include"catalog/indexing.h"
4141
#include"catalog/objectaccess.h"
4242
#include"catalog/pg_operator.h"
43+
#include"catalog/pg_operator_fn.h"
4344
#include"catalog/pg_type.h"
4445
#include"commands/alter.h"
4546
#include"commands/defrem.h"
@@ -500,9 +501,9 @@ AlterOperator(AlterOperatorStmt *stmt)
500501
simple_heap_update(catalog,&tup->t_self,tup);
501502
CatalogUpdateIndexes(catalog,tup);
502503

503-
InvokeObjectPostAlterHook(OperatorRelationId,oprId,0);
504+
address=makeOperatorDependencies(tup, true);
504505

505-
ObjectAddressSet(address,OperatorRelationId,oprId);
506+
InvokeObjectPostAlterHook(OperatorRelationId,oprId,0);
506507

507508
heap_close(catalog,NoLock);
508509

‎src/include/catalog/pg_operator.h

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323
#definePG_OPERATOR_H
2424

2525
#include"catalog/genbki.h"
26-
#include"catalog/objectaddress.h"
27-
#include"nodes/pg_list.h"
2826

2927
/* ----------------
3028
*pg_operator definition. cpp turns this into
@@ -1826,19 +1824,4 @@ DESCR("delete array element");
18261824
DATA(insertOID=3287 ("#-"PGNSPPGUIDbff38021009380200jsonb_delete_path-- ));
18271825
DESCR("delete path");
18281826

1829-
/*
1830-
* function prototypes
1831-
*/
1832-
externObjectAddressOperatorCreate(constchar*operatorName,
1833-
OidoperatorNamespace,
1834-
OidleftTypeId,
1835-
OidrightTypeId,
1836-
OidprocedureId,
1837-
List*commutatorName,
1838-
List*negatorName,
1839-
OidrestrictionId,
1840-
OidjoinId,
1841-
boolcanMerge,
1842-
boolcanHash);
1843-
18441827
#endif/* PG_OPERATOR_H */

‎src/include/catalog/pg_operator_fn.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* pg_operator_fn.h
4+
* prototypes for functions in catalog/pg_operator.c
5+
*
6+
*
7+
* Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
8+
* Portions Copyright (c) 1994, Regents of the University of California
9+
*
10+
* src/include/catalog/pg_operator_fn.h
11+
*
12+
*-------------------------------------------------------------------------
13+
*/
14+
#ifndefPG_OPERATOR_FN_H
15+
#definePG_OPERATOR_FN_H
16+
17+
#include"catalog/objectaddress.h"
18+
#include"nodes/pg_list.h"
19+
20+
externObjectAddressOperatorCreate(constchar*operatorName,
21+
OidoperatorNamespace,
22+
OidleftTypeId,
23+
OidrightTypeId,
24+
OidprocedureId,
25+
List*commutatorName,
26+
List*negatorName,
27+
OidrestrictionId,
28+
OidjoinId,
29+
boolcanMerge,
30+
boolcanHash);
31+
32+
externObjectAddressmakeOperatorDependencies(HeapTupletuple,boolisUpdate);
33+
34+
#endif/* PG_OPERATOR_FN_H */

‎src/test/regress/expected/alter_operator.out

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,29 @@
1-
CREATEOR REPLACEFUNCTION alter_op_test_fn(boolean, boolean)
1+
CREATE FUNCTION alter_op_test_fn(boolean, boolean)
22
RETURNS boolean AS $$ SELECT NULL::BOOLEAN; $$ LANGUAGE sql IMMUTABLE;
3+
CREATE FUNCTION customcontsel(internal, oid, internal, integer)
4+
RETURNS float8 AS 'contsel' LANGUAGE internal STABLE STRICT;
35
CREATE OPERATOR === (
46
LEFTARG = boolean,
57
RIGHTARG = boolean,
68
PROCEDURE = alter_op_test_fn,
79
COMMUTATOR = ===,
810
NEGATOR = !==,
9-
RESTRICT =contsel,
11+
RESTRICT =customcontsel,
1012
JOIN = contjoinsel,
1113
HASHES, MERGES
1214
);
15+
SELECT pg_describe_object(refclassid,refobjid,refobjsubid) as ref, deptype
16+
FROM pg_depend
17+
WHERE classid = 'pg_operator'::regclass AND
18+
objid = '===(bool,bool)'::regoperator
19+
ORDER BY 1;
20+
ref | deptype
21+
-------------------------------------------------------+---------
22+
function alter_op_test_fn(boolean,boolean) | n
23+
function customcontsel(internal,oid,internal,integer) | n
24+
schema public | n
25+
(3 rows)
26+
1327
--
1428
-- Reset and set params
1529
--
@@ -22,6 +36,17 @@ SELECT oprrest, oprjoin FROM pg_operator WHERE oprname = '==='
2236
- | -
2337
(1 row)
2438

39+
SELECT pg_describe_object(refclassid,refobjid,refobjsubid) as ref, deptype
40+
FROM pg_depend
41+
WHERE classid = 'pg_operator'::regclass AND
42+
objid = '===(bool,bool)'::regoperator
43+
ORDER BY 1;
44+
ref | deptype
45+
--------------------------------------------+---------
46+
function alter_op_test_fn(boolean,boolean) | n
47+
schema public | n
48+
(2 rows)
49+
2550
ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = contsel);
2651
ALTER OPERATOR === (boolean, boolean) SET (JOIN = contjoinsel);
2752
SELECT oprrest, oprjoin FROM pg_operator WHERE oprname = '==='
@@ -31,6 +56,17 @@ SELECT oprrest, oprjoin FROM pg_operator WHERE oprname = '==='
3156
contsel | contjoinsel
3257
(1 row)
3358

59+
SELECT pg_describe_object(refclassid,refobjid,refobjsubid) as ref, deptype
60+
FROM pg_depend
61+
WHERE classid = 'pg_operator'::regclass AND
62+
objid = '===(bool,bool)'::regoperator
63+
ORDER BY 1;
64+
ref | deptype
65+
--------------------------------------------+---------
66+
function alter_op_test_fn(boolean,boolean) | n
67+
schema public | n
68+
(2 rows)
69+
3470
ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = NONE, JOIN = NONE);
3571
SELECT oprrest, oprjoin FROM pg_operator WHERE oprname = '==='
3672
AND oprleft = 'boolean'::regtype AND oprright = 'boolean'::regtype;
@@ -39,14 +75,37 @@ SELECT oprrest, oprjoin FROM pg_operator WHERE oprname = '==='
3975
- | -
4076
(1 row)
4177

42-
ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = contsel, JOIN = contjoinsel);
78+
SELECT pg_describe_object(refclassid,refobjid,refobjsubid) as ref, deptype
79+
FROM pg_depend
80+
WHERE classid = 'pg_operator'::regclass AND
81+
objid = '===(bool,bool)'::regoperator
82+
ORDER BY 1;
83+
ref | deptype
84+
--------------------------------------------+---------
85+
function alter_op_test_fn(boolean,boolean) | n
86+
schema public | n
87+
(2 rows)
88+
89+
ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = customcontsel, JOIN = contjoinsel);
4390
SELECT oprrest, oprjoin FROM pg_operator WHERE oprname = '==='
4491
AND oprleft = 'boolean'::regtype AND oprright = 'boolean'::regtype;
45-
oprrest | oprjoin
46-
---------+-------------
47-
contsel | contjoinsel
92+
oprrest | oprjoin
93+
---------------+-------------
94+
customcontsel | contjoinsel
4895
(1 row)
4996

97+
SELECT pg_describe_object(refclassid,refobjid,refobjsubid) as ref, deptype
98+
FROM pg_depend
99+
WHERE classid = 'pg_operator'::regclass AND
100+
objid = '===(bool,bool)'::regoperator
101+
ORDER BY 1;
102+
ref | deptype
103+
-------------------------------------------------------+---------
104+
function alter_op_test_fn(boolean,boolean) | n
105+
function customcontsel(internal,oid,internal,integer) | n
106+
schema public | n
107+
(3 rows)
108+
50109
--
51110
-- Test invalid options.
52111
--
@@ -73,3 +132,5 @@ ERROR: must be owner of operator ===
73132
RESET SESSION AUTHORIZATION;
74133
DROP USER regtest_alter_user;
75134
DROP OPERATOR === (boolean, boolean);
135+
DROP FUNCTION customcontsel(internal, oid, internal, integer);
136+
DROP FUNCTION alter_op_test_fn(boolean, boolean);

‎src/test/regress/sql/alter_operator.sql

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
1-
CREATEOR REPLACEFUNCTIONalter_op_test_fn(boolean,boolean)
1+
CREATEFUNCTIONalter_op_test_fn(boolean,boolean)
22
RETURNSbooleanAS $$SELECTNULL::BOOLEAN; $$ LANGUAGE sql IMMUTABLE;
33

4+
CREATEFUNCTIONcustomcontsel(internal,oid, internal,integer)
5+
RETURNS float8AS'contsel' LANGUAGE internal STABLE STRICT;
6+
47
CREATE OPERATOR=== (
58
LEFTARG=boolean,
69
RIGHTARG=boolean,
710
PROCEDURE= alter_op_test_fn,
811
COMMUTATOR====,
912
NEGATOR=!==,
10-
RESTRICT=contsel,
13+
RESTRICT=customcontsel,
1114
JOIN= contjoinsel,
1215
HASHES, MERGES
1316
);
1417

18+
SELECT pg_describe_object(refclassid,refobjid,refobjsubid)as ref, deptype
19+
FROM pg_depend
20+
WHERE classid='pg_operator'::regclassAND
21+
objid='===(bool,bool)'::regoperator
22+
ORDER BY1;
23+
1524
--
1625
-- Reset and set params
1726
--
@@ -22,22 +31,46 @@ ALTER OPERATOR === (boolean, boolean) SET (JOIN = NONE);
2231
SELECT oprrest, oprjoinFROM pg_operatorWHERE oprname='==='
2332
AND oprleft='boolean'::regtypeAND oprright='boolean'::regtype;
2433

34+
SELECT pg_describe_object(refclassid,refobjid,refobjsubid)as ref, deptype
35+
FROM pg_depend
36+
WHERE classid='pg_operator'::regclassAND
37+
objid='===(bool,bool)'::regoperator
38+
ORDER BY1;
39+
2540
ALTEROPERATOR=== (boolean,boolean)SET (RESTRICT= contsel);
2641
ALTEROPERATOR=== (boolean,boolean)SET (JOIN= contjoinsel);
2742

2843
SELECT oprrest, oprjoinFROM pg_operatorWHERE oprname='==='
2944
AND oprleft='boolean'::regtypeAND oprright='boolean'::regtype;
3045

46+
SELECT pg_describe_object(refclassid,refobjid,refobjsubid)as ref, deptype
47+
FROM pg_depend
48+
WHERE classid='pg_operator'::regclassAND
49+
objid='===(bool,bool)'::regoperator
50+
ORDER BY1;
51+
3152
ALTEROPERATOR=== (boolean,boolean)SET (RESTRICT= NONE,JOIN= NONE);
3253

3354
SELECT oprrest, oprjoinFROM pg_operatorWHERE oprname='==='
3455
AND oprleft='boolean'::regtypeAND oprright='boolean'::regtype;
3556

36-
ALTEROPERATOR=== (boolean,boolean)SET (RESTRICT= contsel,JOIN= contjoinsel);
57+
SELECT pg_describe_object(refclassid,refobjid,refobjsubid)as ref, deptype
58+
FROM pg_depend
59+
WHERE classid='pg_operator'::regclassAND
60+
objid='===(bool,bool)'::regoperator
61+
ORDER BY1;
62+
63+
ALTEROPERATOR=== (boolean,boolean)SET (RESTRICT= customcontsel,JOIN= contjoinsel);
3764

3865
SELECT oprrest, oprjoinFROM pg_operatorWHERE oprname='==='
3966
AND oprleft='boolean'::regtypeAND oprright='boolean'::regtype;
4067

68+
SELECT pg_describe_object(refclassid,refobjid,refobjsubid)as ref, deptype
69+
FROM pg_depend
70+
WHERE classid='pg_operator'::regclassAND
71+
objid='===(bool,bool)'::regoperator
72+
ORDER BY1;
73+
4174
--
4275
-- Test invalid options.
4376
--
@@ -60,3 +93,5 @@ ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = NONE);
6093
RESET SESSION AUTHORIZATION;
6194
DROPUSER regtest_alter_user;
6295
DROPOPERATOR=== (boolean,boolean);
96+
DROPFUNCTION customcontsel(internal,oid, internal,integer);
97+
DROPFUNCTION alter_op_test_fn(boolean,boolean);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp