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