diff --git a/doc/src/sgml/ref/alter_type.sgml b/doc/src/sgml/ref/alter_type.sgml
index 64bf266373..21887e88a0 100644
--- a/doc/src/sgml/ref/alter_type.sgml
+++ b/doc/src/sgml/ref/alter_type.sgml
@@ -194,6 +194,14 @@ ALTER TYPE name SET (
+
+
+ SUBSCRIPT can be set to the name of a type-specific
+ subscripting handler function, or NONE to remove
+ the type's subscripting handler function. Using this option
+ requires superuser privilege.
+
+
STORAGE
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 29fe52d2ce..7c0b2c3bf0 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -94,6 +94,7 @@ typedef struct
bool updateTypmodin;
bool updateTypmodout;
bool updateAnalyze;
+ bool updateSubscript;
/* New values for relevant attributes */
char storage;
Oid receiveOid;
@@ -101,6 +102,7 @@ typedef struct
Oid typmodinOid;
Oid typmodoutOid;
Oid analyzeOid;
+ Oid subscriptOid;
} AlterTypeRecurseParams;
/* Potentially set by pg_upgrade_support functions */
@@ -3885,6 +3887,18 @@ AlterType(AlterTypeStmt *stmt)
/* Replacing an analyze function requires superuser. */
requireSuper = true;
}
+ else if (strcmp(defel->defname, "subscript") == 0)
+ {
+ if (defel->arg != NULL)
+ atparams.subscriptOid =
+ findTypeSubscriptingFunction(defGetQualifiedName(defel),
+ typeOid);
+ else
+ atparams.subscriptOid = InvalidOid; /* NONE, remove function */
+ atparams.updateSubscript = true;
+ /* Replacing a subscript function requires superuser. */
+ requireSuper = true;
+ }
/*
* The rest of the options that CREATE accepts cannot be changed.
@@ -4042,6 +4056,11 @@ AlterTypeRecurse(Oid typeOid, bool isImplicitArray,
replaces[Anum_pg_type_typanalyze - 1] = true;
values[Anum_pg_type_typanalyze - 1] = ObjectIdGetDatum(atparams->analyzeOid);
}
+ if (atparams->updateSubscript)
+ {
+ replaces[Anum_pg_type_typsubscript - 1] = true;
+ values[Anum_pg_type_typsubscript - 1] = ObjectIdGetDatum(atparams->subscriptOid);
+ }
newtup = heap_modify_tuple(tup, RelationGetDescr(catalog),
values, nulls, replaces);
@@ -4098,6 +4117,7 @@ AlterTypeRecurse(Oid typeOid, bool isImplicitArray,
atparams->updateReceive = false; /* domains use F_DOMAIN_RECV */
atparams->updateTypmodin = false; /* domains don't have typmods */
atparams->updateTypmodout = false;
+ atparams->updateSubscript = false; /* domains don't have subscriptors */
/* Skip the scan if nothing remains to be done */
if (!(atparams->updateStorage ||
diff --git a/src/test/regress/expected/create_type.out b/src/test/regress/expected/create_type.out
index f85afcb31e..14394cc95c 100644
--- a/src/test/regress/expected/create_type.out
+++ b/src/test/regress/expected/create_type.out
@@ -260,38 +260,40 @@ ALTER TYPE myvarchar SET (
receive = myvarcharrecv,
typmod_in = varchartypmodin,
typmod_out = varchartypmodout,
- analyze = array_typanalyze -- bogus, but it doesn't matter
+ -- these are bogus, but it's safe as long as we don't use the type:
+ analyze = ts_typanalyze,
+ subscript = raw_array_subscript_handler
);
SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout,
- typanalyze, typstorage
+ typanalyze, typsubscript, typstorage
FROM pg_type WHERE typname = 'myvarchar';
- typinput | typoutput | typreceive | typsend | typmodin | typmodout | typanalyze | typstorage
--------------+--------------+---------------+---------------+-----------------+------------------+------------------+------------
- myvarcharin | myvarcharout | myvarcharrecv | myvarcharsend | varchartypmodin | varchartypmodout | array_typanalyze | x
+ typinput | typoutput | typreceive | typsend | typmodin | typmodout | typanalyze | typsubscript | typstorage
+-------------+--------------+---------------+---------------+-----------------+------------------+---------------+-----------------------------+------------
+ myvarcharin | myvarcharout | myvarcharrecv | myvarcharsend | varchartypmodin | varchartypmodout | ts_typanalyze | raw_array_subscript_handler | x
(1 row)
SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout,
- typanalyze, typstorage
+ typanalyze, typsubscript, typstorage
FROM pg_type WHERE typname = '_myvarchar';
- typinput | typoutput | typreceive | typsend | typmodin | typmodout | typanalyze | typstorage
-----------+-----------+------------+------------+-----------------+------------------+------------------+------------
- array_in | array_out | array_recv | array_send | varchartypmodin | varchartypmodout | array_typanalyze | x
+ typinput | typoutput | typreceive | typsend | typmodin | typmodout | typanalyze | typsubscript | typstorage
+----------+-----------+------------+------------+-----------------+------------------+------------------+-------------------------+------------
+ array_in | array_out | array_recv | array_send | varchartypmodin | varchartypmodout | array_typanalyze | array_subscript_handler | x
(1 row)
SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout,
- typanalyze, typstorage
+ typanalyze, typsubscript, typstorage
FROM pg_type WHERE typname = 'myvarchardom';
- typinput | typoutput | typreceive | typsend | typmodin | typmodout | typanalyze | typstorage
------------+--------------+-------------+---------------+----------+-----------+------------------+------------
- domain_in | myvarcharout | domain_recv | myvarcharsend | - | - | array_typanalyze | x
+ typinput | typoutput | typreceive | typsend | typmodin | typmodout | typanalyze | typsubscript | typstorage
+-----------+--------------+-------------+---------------+----------+-----------+---------------+--------------+------------
+ domain_in | myvarcharout | domain_recv | myvarcharsend | - | - | ts_typanalyze | - | x
(1 row)
SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout,
- typanalyze, typstorage
+ typanalyze, typsubscript, typstorage
FROM pg_type WHERE typname = '_myvarchardom';
- typinput | typoutput | typreceive | typsend | typmodin | typmodout | typanalyze | typstorage
-----------+-----------+------------+------------+----------+-----------+------------------+------------
- array_in | array_out | array_recv | array_send | - | - | array_typanalyze | x
+ typinput | typoutput | typreceive | typsend | typmodin | typmodout | typanalyze | typsubscript | typstorage
+----------+-----------+------------+------------+----------+-----------+------------------+-------------------------+------------
+ array_in | array_out | array_recv | array_send | - | - | array_typanalyze | array_subscript_handler | x
(1 row)
-- ensure dependencies are straight
diff --git a/src/test/regress/sql/create_type.sql b/src/test/regress/sql/create_type.sql
index 584ece0670..a32a9e6795 100644
--- a/src/test/regress/sql/create_type.sql
+++ b/src/test/regress/sql/create_type.sql
@@ -207,23 +207,25 @@ ALTER TYPE myvarchar SET (
receive = myvarcharrecv,
typmod_in = varchartypmodin,
typmod_out = varchartypmodout,
- analyze = array_typanalyze -- bogus, but it doesn't matter
+ -- these are bogus, but it's safe as long as we don't use the type:
+ analyze = ts_typanalyze,
+ subscript = raw_array_subscript_handler
);
SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout,
- typanalyze, typstorage
+ typanalyze, typsubscript, typstorage
FROM pg_type WHERE typname = 'myvarchar';
SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout,
- typanalyze, typstorage
+ typanalyze, typsubscript, typstorage
FROM pg_type WHERE typname = '_myvarchar';
SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout,
- typanalyze, typstorage
+ typanalyze, typsubscript, typstorage
FROM pg_type WHERE typname = 'myvarchardom';
SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout,
- typanalyze, typstorage
+ typanalyze, typsubscript, typstorage
FROM pg_type WHERE typname = '_myvarchardom';
-- ensure dependencies are straight