Skip to content

Commit 8c15a29

Browse files
committed
Allow ALTER TYPE to update an existing type's typsubscript value.
This is essential if we'd like to allow existing extension data types to support subscripting in future, since dropping and recreating the type isn't a practical thing for an extension upgrade script, and direct manipulation of pg_type isn't a great answer either. There was some discussion about also allowing alteration of typelem, but it's less clear whether that's a good idea or not, so for now I forebore. Discussion: https://postgr.es/m/3724341.1607551174@sss.pgh.pa.us
1 parent 653aa60 commit 8c15a29

File tree

4 files changed

+54
-22
lines changed

4 files changed

+54
-22
lines changed

doc/src/sgml/ref/alter_type.sgml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,14 @@ ALTER TYPE <replaceable class="parameter">name</replaceable> SET ( <replaceable
194194
requires superuser privilege.
195195
</para>
196196
</listitem>
197+
<listitem>
198+
<para>
199+
<literal>SUBSCRIPT</literal> can be set to the name of a type-specific
200+
subscripting handler function, or <literal>NONE</literal> to remove
201+
the type's subscripting handler function. Using this option
202+
requires superuser privilege.
203+
</para>
204+
</listitem>
197205
<listitem>
198206
<para>
199207
<literal>STORAGE</literal><indexterm>

src/backend/commands/typecmds.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,15 @@ typedef struct
9494
bool updateTypmodin;
9595
bool updateTypmodout;
9696
bool updateAnalyze;
97+
bool updateSubscript;
9798
/* New values for relevant attributes */
9899
char storage;
99100
Oid receiveOid;
100101
Oid sendOid;
101102
Oid typmodinOid;
102103
Oid typmodoutOid;
103104
Oid analyzeOid;
105+
Oid subscriptOid;
104106
} AlterTypeRecurseParams;
105107

106108
/* Potentially set by pg_upgrade_support functions */
@@ -3885,6 +3887,18 @@ AlterType(AlterTypeStmt *stmt)
38853887
/* Replacing an analyze function requires superuser. */
38863888
requireSuper = true;
38873889
}
3890+
else if (strcmp(defel->defname, "subscript") == 0)
3891+
{
3892+
if (defel->arg != NULL)
3893+
atparams.subscriptOid =
3894+
findTypeSubscriptingFunction(defGetQualifiedName(defel),
3895+
typeOid);
3896+
else
3897+
atparams.subscriptOid = InvalidOid; /* NONE, remove function */
3898+
atparams.updateSubscript = true;
3899+
/* Replacing a subscript function requires superuser. */
3900+
requireSuper = true;
3901+
}
38883902

38893903
/*
38903904
* The rest of the options that CREATE accepts cannot be changed.
@@ -4042,6 +4056,11 @@ AlterTypeRecurse(Oid typeOid, bool isImplicitArray,
40424056
replaces[Anum_pg_type_typanalyze - 1] = true;
40434057
values[Anum_pg_type_typanalyze - 1] = ObjectIdGetDatum(atparams->analyzeOid);
40444058
}
4059+
if (atparams->updateSubscript)
4060+
{
4061+
replaces[Anum_pg_type_typsubscript - 1] = true;
4062+
values[Anum_pg_type_typsubscript - 1] = ObjectIdGetDatum(atparams->subscriptOid);
4063+
}
40454064

40464065
newtup = heap_modify_tuple(tup, RelationGetDescr(catalog),
40474066
values, nulls, replaces);
@@ -4098,6 +4117,7 @@ AlterTypeRecurse(Oid typeOid, bool isImplicitArray,
40984117
atparams->updateReceive = false; /* domains use F_DOMAIN_RECV */
40994118
atparams->updateTypmodin = false; /* domains don't have typmods */
41004119
atparams->updateTypmodout = false;
4120+
atparams->updateSubscript = false; /* domains don't have subscriptors */
41014121

41024122
/* Skip the scan if nothing remains to be done */
41034123
if (!(atparams->updateStorage ||

src/test/regress/expected/create_type.out

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -260,38 +260,40 @@ ALTER TYPE myvarchar SET (
260260
receive = myvarcharrecv,
261261
typmod_in = varchartypmodin,
262262
typmod_out = varchartypmodout,
263-
analyze = array_typanalyze -- bogus, but it doesn't matter
263+
-- these are bogus, but it's safe as long as we don't use the type:
264+
analyze = ts_typanalyze,
265+
subscript = raw_array_subscript_handler
264266
);
265267
SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout,
266-
typanalyze, typstorage
268+
typanalyze, typsubscript, typstorage
267269
FROM pg_type WHERE typname = 'myvarchar';
268-
typinput | typoutput | typreceive | typsend | typmodin | typmodout | typanalyze | typstorage
269-
-------------+--------------+---------------+---------------+-----------------+------------------+------------------+------------
270-
myvarcharin | myvarcharout | myvarcharrecv | myvarcharsend | varchartypmodin | varchartypmodout | array_typanalyze | x
270+
typinput | typoutput | typreceive | typsend | typmodin | typmodout | typanalyze | typsubscript | typstorage
271+
-------------+--------------+---------------+---------------+-----------------+------------------+---------------+-----------------------------+------------
272+
myvarcharin | myvarcharout | myvarcharrecv | myvarcharsend | varchartypmodin | varchartypmodout | ts_typanalyze | raw_array_subscript_handler | x
271273
(1 row)
272274

273275
SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout,
274-
typanalyze, typstorage
276+
typanalyze, typsubscript, typstorage
275277
FROM pg_type WHERE typname = '_myvarchar';
276-
typinput | typoutput | typreceive | typsend | typmodin | typmodout | typanalyze | typstorage
277-
----------+-----------+------------+------------+-----------------+------------------+------------------+------------
278-
array_in | array_out | array_recv | array_send | varchartypmodin | varchartypmodout | array_typanalyze | x
278+
typinput | typoutput | typreceive | typsend | typmodin | typmodout | typanalyze | typsubscript | typstorage
279+
----------+-----------+------------+------------+-----------------+------------------+------------------+-------------------------+------------
280+
array_in | array_out | array_recv | array_send | varchartypmodin | varchartypmodout | array_typanalyze | array_subscript_handler | x
279281
(1 row)
280282

281283
SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout,
282-
typanalyze, typstorage
284+
typanalyze, typsubscript, typstorage
283285
FROM pg_type WHERE typname = 'myvarchardom';
284-
typinput | typoutput | typreceive | typsend | typmodin | typmodout | typanalyze | typstorage
285-
-----------+--------------+-------------+---------------+----------+-----------+------------------+------------
286-
domain_in | myvarcharout | domain_recv | myvarcharsend | - | - | array_typanalyze | x
286+
typinput | typoutput | typreceive | typsend | typmodin | typmodout | typanalyze | typsubscript | typstorage
287+
-----------+--------------+-------------+---------------+----------+-----------+---------------+--------------+------------
288+
domain_in | myvarcharout | domain_recv | myvarcharsend | - | - | ts_typanalyze | - | x
287289
(1 row)
288290

289291
SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout,
290-
typanalyze, typstorage
292+
typanalyze, typsubscript, typstorage
291293
FROM pg_type WHERE typname = '_myvarchardom';
292-
typinput | typoutput | typreceive | typsend | typmodin | typmodout | typanalyze | typstorage
293-
----------+-----------+------------+------------+----------+-----------+------------------+------------
294-
array_in | array_out | array_recv | array_send | - | - | array_typanalyze | x
294+
typinput | typoutput | typreceive | typsend | typmodin | typmodout | typanalyze | typsubscript | typstorage
295+
----------+-----------+------------+------------+----------+-----------+------------------+-------------------------+------------
296+
array_in | array_out | array_recv | array_send | - | - | array_typanalyze | array_subscript_handler | x
295297
(1 row)
296298

297299
-- ensure dependencies are straight

src/test/regress/sql/create_type.sql

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -207,23 +207,25 @@ ALTER TYPE myvarchar SET (
207207
receive = myvarcharrecv,
208208
typmod_in = varchartypmodin,
209209
typmod_out = varchartypmodout,
210-
analyze = array_typanalyze -- bogus, but it doesn't matter
210+
-- these are bogus, but it's safe as long as we don't use the type:
211+
analyze = ts_typanalyze,
212+
subscript = raw_array_subscript_handler
211213
);
212214

213215
SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout,
214-
typanalyze, typstorage
216+
typanalyze, typsubscript, typstorage
215217
FROM pg_type WHERE typname = 'myvarchar';
216218

217219
SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout,
218-
typanalyze, typstorage
220+
typanalyze, typsubscript, typstorage
219221
FROM pg_type WHERE typname = '_myvarchar';
220222

221223
SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout,
222-
typanalyze, typstorage
224+
typanalyze, typsubscript, typstorage
223225
FROM pg_type WHERE typname = 'myvarchardom';
224226

225227
SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout,
226-
typanalyze, typstorage
228+
typanalyze, typsubscript, typstorage
227229
FROM pg_type WHERE typname = '_myvarchardom';
228230

229231
-- ensure dependencies are straight

0 commit comments

Comments
 (0)