1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Add new OID alias type regdatabase.

This provides a convenient way to look up a database's OID.  For
example, the query

    SELECT * FROM pg_shdepend
    WHERE dbid = (SELECT oid FROM pg_database
                  WHERE datname = current_database());

can now be simplified to

    SELECT * FROM pg_shdepend
    WHERE dbid = current_database()::regdatabase;

Like the regrole type, regdatabase has cluster-wide scope, so we
disallow regdatabase constants from appearing in stored
expressions.

Bumps catversion.

Author: Ian Lawrence Barwick <barwick@gmail.com>
Reviewed-by: Greg Sabino Mullane <htamfids@gmail.com>
Reviewed-by: Jian He <jian.universality@gmail.com>
Reviewed-by: Fabrízio de Royes Mello <fabriziomello@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/aBpjJhyHpM2LYcG0%40nathan
This commit is contained in:
Nathan Bossart
2025-06-30 15:38:54 -05:00
parent f20a347e1a
commit bd09f024a1
18 changed files with 424 additions and 4 deletions

View File

@ -39,6 +39,7 @@
#include "catalog/pg_aggregate.h" #include "catalog/pg_aggregate.h"
#include "catalog/pg_authid.h" #include "catalog/pg_authid.h"
#include "catalog/pg_collation.h" #include "catalog/pg_collation.h"
#include "catalog/pg_database.h"
#include "catalog/pg_namespace.h" #include "catalog/pg_namespace.h"
#include "catalog/pg_operator.h" #include "catalog/pg_operator.h"
#include "catalog/pg_opfamily.h" #include "catalog/pg_opfamily.h"
@ -455,6 +456,11 @@ foreign_expr_walker(Node *node,
AuthIdRelationId, fpinfo)) AuthIdRelationId, fpinfo))
return false; return false;
break; break;
case REGDATABASEOID:
if (!is_shippable(DatumGetObjectId(c->constvalue),
DatabaseRelationId, fpinfo))
return false;
break;
} }
} }

View File

@ -4737,6 +4737,10 @@ INSERT INTO mytable VALUES(-1); -- fails
<primary>regconfig</primary> <primary>regconfig</primary>
</indexterm> </indexterm>
<indexterm zone="datatype-oid">
<primary>regdatabase</primary>
</indexterm>
<indexterm zone="datatype-oid"> <indexterm zone="datatype-oid">
<primary>regdictionary</primary> <primary>regdictionary</primary>
</indexterm> </indexterm>
@ -4878,6 +4882,13 @@ SELECT * FROM pg_attribute
<entry><literal>english</literal></entry> <entry><literal>english</literal></entry>
</row> </row>
<row>
<entry><type>regdatabase</type></entry>
<entry><structname>pg_database</structname></entry>
<entry>database name</entry>
<entry><literal>template1</literal></entry>
</row>
<row> <row>
<entry><type>regdictionary</type></entry> <entry><type>regdictionary</type></entry>
<entry><structname>pg_ts_dict</structname></entry> <entry><structname>pg_ts_dict</structname></entry>
@ -5049,8 +5060,8 @@ WHERE ...
be dropped without first removing the default expression. The be dropped without first removing the default expression. The
alternative of <literal>nextval('my_seq'::text)</literal> does not alternative of <literal>nextval('my_seq'::text)</literal> does not
create a dependency. create a dependency.
(<type>regrole</type> is an exception to this property. Constants of this (<type>regdatabase</type> and <type>regrole</type> are exceptions to this
type are not allowed in stored expressions.) property. Constants of these types are not allowed in stored expressions.)
</para> </para>
<para> <para>

View File

@ -26750,6 +26750,23 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id'));
</para></entry> </para></entry>
</row> </row>
<row>
<entry role="func_table_entry"><para role="func_signature">
<indexterm>
<primary>to_regdatabase</primary>
</indexterm>
<function>to_regdatabase</function> ( <type>text</type> )
<returnvalue>regdatabase</returnvalue>
</para>
<para>
Translates a textual database name to its OID. A similar result is
obtained by casting the string to type <type>regdatabase</type> (see
<xref linkend="datatype-oid"/>); however, this function will return
<literal>NULL</literal> rather than throwing an error if the name is
not found.
</para></entry>
</row>
<row> <row>
<entry role="func_table_entry"><para role="func_signature"> <entry role="func_table_entry"><para role="func_signature">
<indexterm> <indexterm>

View File

@ -1110,7 +1110,8 @@ psql --username=postgres --file=script.sql postgres
<member><type>regproc</type></member> <member><type>regproc</type></member>
<member><type>regprocedure</type></member> <member><type>regprocedure</type></member>
</simplelist> </simplelist>
(<type>regclass</type>, <type>regrole</type>, and <type>regtype</type> can be upgraded.) (<type>regclass</type>, <type>regdatabase</type>, <type>regrole</type>, and
<type>regtype</type> can be upgraded.)
</para> </para>
<para> <para>

View File

@ -109,6 +109,8 @@ static const struct typinfo TypInfo[] = {
F_REGROLEIN, F_REGROLEOUT}, F_REGROLEIN, F_REGROLEOUT},
{"regnamespace", REGNAMESPACEOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid, {"regnamespace", REGNAMESPACEOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
F_REGNAMESPACEIN, F_REGNAMESPACEOUT}, F_REGNAMESPACEIN, F_REGNAMESPACEOUT},
{"regdatabase", REGDATABASEOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
F_REGDATABASEIN, F_REGDATABASEOUT},
{"text", TEXTOID, 0, -1, false, TYPALIGN_INT, TYPSTORAGE_EXTENDED, DEFAULT_COLLATION_OID, {"text", TEXTOID, 0, -1, false, TYPALIGN_INT, TYPSTORAGE_EXTENDED, DEFAULT_COLLATION_OID,
F_TEXTIN, F_TEXTOUT}, F_TEXTIN, F_TEXTOUT},
{"oid", OIDOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid, {"oid", OIDOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,

View File

@ -1850,6 +1850,17 @@ find_expr_references_walker(Node *node,
errmsg("constant of the type %s cannot be used here", errmsg("constant of the type %s cannot be used here",
"regrole"))); "regrole")));
break; break;
/*
* Dependencies for regdatabase should be shared among all
* databases, so explicitly inhibit to have dependencies.
*/
case REGDATABASEOID:
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("constant of the type %s cannot be used here",
"regdatabase")));
break;
} }
} }
return false; return false;

View File

@ -30,6 +30,7 @@
#include "catalog/pg_ts_config.h" #include "catalog/pg_ts_config.h"
#include "catalog/pg_ts_dict.h" #include "catalog/pg_ts_dict.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "commands/dbcommands.h"
#include "lib/stringinfo.h" #include "lib/stringinfo.h"
#include "mb/pg_wchar.h" #include "mb/pg_wchar.h"
#include "miscadmin.h" #include "miscadmin.h"
@ -1763,6 +1764,123 @@ regnamespacesend(PG_FUNCTION_ARGS)
return oidsend(fcinfo); return oidsend(fcinfo);
} }
/*
* regdatabasein - converts database name to database OID
*
* We also accept a numeric OID, for symmetry with the output routine.
*
* '-' signifies unknown (OID 0). In all other cases, the input must
* match an existing pg_database entry.
*/
Datum
regdatabasein(PG_FUNCTION_ARGS)
{
char *db_name_or_oid = PG_GETARG_CSTRING(0);
Node *escontext = fcinfo->context;
Oid result;
List *names;
/* Handle "-" or numeric OID */
if (parseDashOrOid(db_name_or_oid, &result, escontext))
PG_RETURN_OID(result);
/* The rest of this wouldn't work in bootstrap mode */
if (IsBootstrapProcessingMode())
elog(ERROR, "regdatabase values must be OIDs in bootstrap mode");
/* Normal case: see if the name matches any pg_database entry. */
names = stringToQualifiedNameList(db_name_or_oid, escontext);
if (names == NIL)
PG_RETURN_NULL();
if (list_length(names) != 1)
ereturn(escontext, (Datum) 0,
(errcode(ERRCODE_INVALID_NAME),
errmsg("invalid name syntax")));
result = get_database_oid(strVal(linitial(names)), true);
if (!OidIsValid(result))
ereturn(escontext, (Datum) 0,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("database \"%s\" does not exist",
strVal(linitial(names)))));
PG_RETURN_OID(result);
}
/*
* to_regdatabase - converts database name to database OID
*
* If the name is not found, we return NULL.
*/
Datum
to_regdatabase(PG_FUNCTION_ARGS)
{
char *db_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
Datum result;
ErrorSaveContext escontext = {T_ErrorSaveContext};
if (!DirectInputFunctionCallSafe(regdatabasein, db_name,
InvalidOid, -1,
(Node *) &escontext,
&result))
PG_RETURN_NULL();
PG_RETURN_DATUM(result);
}
/*
* regdatabaseout - converts database OID to database name
*/
Datum
regdatabaseout(PG_FUNCTION_ARGS)
{
Oid dboid = PG_GETARG_OID(0);
char *result;
if (dboid == InvalidOid)
{
result = pstrdup("-");
PG_RETURN_CSTRING(result);
}
result = get_database_name(dboid);
if (result)
{
/* pstrdup is not really necessary, but it avoids a compiler warning */
result = pstrdup(quote_identifier(result));
}
else
{
/* If OID doesn't match any database, return it numerically */
result = (char *) palloc(NAMEDATALEN);
snprintf(result, NAMEDATALEN, "%u", dboid);
}
PG_RETURN_CSTRING(result);
}
/*
* regdatabaserecv - converts external binary format to regdatabase
*/
Datum
regdatabaserecv(PG_FUNCTION_ARGS)
{
/* Exactly the same as oidrecv, so share code */
return oidrecv(fcinfo);
}
/*
* regdatabasesend - converts regdatabase to binary format
*/
Datum
regdatabasesend(PG_FUNCTION_ARGS)
{
/* Exactly the same as oidsend, so share code */
return oidsend(fcinfo);
}
/* /*
* text_regclass: convert text to regclass * text_regclass: convert text to regclass
* *

View File

@ -4619,6 +4619,7 @@ convert_to_scalar(Datum value, Oid valuetypid, Oid collid, double *scaledvalue,
case REGDICTIONARYOID: case REGDICTIONARYOID:
case REGROLEOID: case REGROLEOID:
case REGNAMESPACEOID: case REGNAMESPACEOID:
case REGDATABASEOID:
*scaledvalue = convert_numeric_to_scalar(value, valuetypid, *scaledvalue = convert_numeric_to_scalar(value, valuetypid,
&failure); &failure);
*scaledlobound = convert_numeric_to_scalar(lobound, boundstypid, *scaledlobound = convert_numeric_to_scalar(lobound, boundstypid,
@ -4751,6 +4752,7 @@ convert_numeric_to_scalar(Datum value, Oid typid, bool *failure)
case REGDICTIONARYOID: case REGDICTIONARYOID:
case REGROLEOID: case REGROLEOID:
case REGNAMESPACEOID: case REGNAMESPACEOID:
case REGDATABASEOID:
/* we can treat OIDs as integers... */ /* we can treat OIDs as integers... */
return (double) DatumGetObjectId(value); return (double) DatumGetObjectId(value);
} }

View File

@ -317,6 +317,7 @@ GetCCHashEqFuncs(Oid keytype, CCHashFN *hashfunc, RegProcedure *eqfunc, CCFastEq
case REGDICTIONARYOID: case REGDICTIONARYOID:
case REGROLEOID: case REGROLEOID:
case REGNAMESPACEOID: case REGNAMESPACEOID:
case REGDATABASEOID:
*hashfunc = int4hashfast; *hashfunc = int4hashfast;
*fasteqfunc = int4eqfast; *fasteqfunc = int4eqfast;
*eqfunc = F_OIDEQ; *eqfunc = F_OIDEQ;

View File

@ -168,6 +168,7 @@ static DataTypesUsageChecks data_types_usage_checks[] =
/* pg_class.oid is preserved, so 'regclass' is OK */ /* pg_class.oid is preserved, so 'regclass' is OK */
" 'regcollation', " " 'regcollation', "
" 'regconfig', " " 'regconfig', "
/* pg_database.oid is preserved, so 'regdatabase' is OK */
" 'regdictionary', " " 'regdictionary', "
" 'regnamespace', " " 'regnamespace', "
" 'regoper', " " 'regoper', "

View File

@ -57,6 +57,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 202506291 #define CATALOG_VERSION_NO 202506301
#endif #endif

View File

@ -281,6 +281,20 @@
castcontext => 'a', castmethod => 'f' }, castcontext => 'a', castmethod => 'f' },
{ castsource => 'regnamespace', casttarget => 'int4', castfunc => '0', { castsource => 'regnamespace', casttarget => 'int4', castfunc => '0',
castcontext => 'a', castmethod => 'b' }, castcontext => 'a', castmethod => 'b' },
{ castsource => 'oid', casttarget => 'regdatabase', castfunc => '0',
castcontext => 'i', castmethod => 'b' },
{ castsource => 'regdatabase', casttarget => 'oid', castfunc => '0',
castcontext => 'i', castmethod => 'b' },
{ castsource => 'int8', casttarget => 'regdatabase', castfunc => 'oid',
castcontext => 'i', castmethod => 'f' },
{ castsource => 'int2', casttarget => 'regdatabase', castfunc => 'int4(int2)',
castcontext => 'i', castmethod => 'f' },
{ castsource => 'int4', casttarget => 'regdatabase', castfunc => '0',
castcontext => 'i', castmethod => 'b' },
{ castsource => 'regdatabase', casttarget => 'int8', castfunc => 'int8(oid)',
castcontext => 'a', castmethod => 'f' },
{ castsource => 'regdatabase', casttarget => 'int4', castfunc => '0',
castcontext => 'a', castmethod => 'b' },
# String category # String category
{ castsource => 'text', casttarget => 'bpchar', castfunc => '0', { castsource => 'text', casttarget => 'bpchar', castfunc => '0',

View File

@ -7455,6 +7455,17 @@
prorettype => 'regnamespace', proargtypes => 'text', prorettype => 'regnamespace', proargtypes => 'text',
prosrc => 'to_regnamespace' }, prosrc => 'to_regnamespace' },
{ oid => '8321', descr => 'I/O',
proname => 'regdatabasein', provolatile => 's', prorettype => 'regdatabase',
proargtypes => 'cstring', prosrc => 'regdatabasein' },
{ oid => '8322', descr => 'I/O',
proname => 'regdatabaseout', provolatile => 's', prorettype => 'cstring',
proargtypes => 'regdatabase', prosrc => 'regdatabaseout' },
{ oid => '8323', descr => 'convert database name to regdatabase',
proname => 'to_regdatabase', provolatile => 's',
prorettype => 'regdatabase', proargtypes => 'text',
prosrc => 'to_regdatabase' },
{ oid => '6210', descr => 'test whether string is valid input for data type', { oid => '6210', descr => 'test whether string is valid input for data type',
proname => 'pg_input_is_valid', provolatile => 's', prorettype => 'bool', proname => 'pg_input_is_valid', provolatile => 's', prorettype => 'bool',
proargtypes => 'text text', prosrc => 'pg_input_is_valid' }, proargtypes => 'text text', prosrc => 'pg_input_is_valid' },
@ -8313,6 +8324,12 @@
{ oid => '4088', descr => 'I/O', { oid => '4088', descr => 'I/O',
proname => 'regnamespacesend', prorettype => 'bytea', proname => 'regnamespacesend', prorettype => 'bytea',
proargtypes => 'regnamespace', prosrc => 'regnamespacesend' }, proargtypes => 'regnamespace', prosrc => 'regnamespacesend' },
{ oid => '8324', descr => 'I/O',
proname => 'regdatabaserecv', prorettype => 'regdatabase',
proargtypes => 'internal', prosrc => 'regdatabaserecv' },
{ oid => '8325', descr => 'I/O',
proname => 'regdatabasesend', prorettype => 'bytea',
proargtypes => 'regdatabase', prosrc => 'regdatabasesend' },
{ oid => '2456', descr => 'I/O', { oid => '2456', descr => 'I/O',
proname => 'bit_recv', prorettype => 'bit', proname => 'bit_recv', prorettype => 'bit',
proargtypes => 'internal oid int4', prosrc => 'bit_recv' }, proargtypes => 'internal oid int4', prosrc => 'bit_recv' },

View File

@ -399,6 +399,11 @@
typinput => 'regnamespacein', typoutput => 'regnamespaceout', typinput => 'regnamespacein', typoutput => 'regnamespaceout',
typreceive => 'regnamespacerecv', typsend => 'regnamespacesend', typreceive => 'regnamespacerecv', typsend => 'regnamespacesend',
typalign => 'i' }, typalign => 'i' },
{ oid => '8326', array_type_oid => '8327', descr => 'registered database',
typname => 'regdatabase', typlen => '4', typbyval => 't', typcategory => 'N',
typinput => 'regdatabasein', typoutput => 'regdatabaseout',
typreceive => 'regdatabaserecv', typsend => 'regdatabasesend',
typalign => 'i' },
# uuid # uuid
{ oid => '2950', array_type_oid => '2951', descr => 'UUID', { oid => '2950', array_type_oid => '2951', descr => 'UUID',

View File

@ -192,6 +192,18 @@ SELECT regnamespace('"pg_catalog"');
pg_catalog pg_catalog
(1 row) (1 row)
SELECT regdatabase('template1');
regdatabase
-------------
template1
(1 row)
SELECT regdatabase('"template1"');
regdatabase
-------------
template1
(1 row)
SELECT to_regrole('regress_regrole_test'); SELECT to_regrole('regress_regrole_test');
to_regrole to_regrole
---------------------- ----------------------
@ -216,6 +228,132 @@ SELECT to_regnamespace('"pg_catalog"');
pg_catalog pg_catalog
(1 row) (1 row)
SELECT to_regdatabase('template1');
to_regdatabase
----------------
template1
(1 row)
SELECT to_regdatabase('"template1"');
to_regdatabase
----------------
template1
(1 row)
-- special "single dash" case
SELECT regproc('-')::oid;
regproc
---------
0
(1 row)
SELECT regprocedure('-')::oid;
regprocedure
--------------
0
(1 row)
SELECT regclass('-')::oid;
regclass
----------
0
(1 row)
SELECT regcollation('-')::oid;
regcollation
--------------
0
(1 row)
SELECT regtype('-')::oid;
regtype
---------
0
(1 row)
SELECT regconfig('-')::oid;
regconfig
-----------
0
(1 row)
SELECT regdictionary('-')::oid;
regdictionary
---------------
0
(1 row)
SELECT regrole('-')::oid;
regrole
---------
0
(1 row)
SELECT regnamespace('-')::oid;
regnamespace
--------------
0
(1 row)
SELECT regdatabase('-')::oid;
regdatabase
-------------
0
(1 row)
SELECT to_regproc('-')::oid;
to_regproc
------------
0
(1 row)
SELECT to_regprocedure('-')::oid;
to_regprocedure
-----------------
0
(1 row)
SELECT to_regclass('-')::oid;
to_regclass
-------------
0
(1 row)
SELECT to_regcollation('-')::oid;
to_regcollation
-----------------
0
(1 row)
SELECT to_regtype('-')::oid;
to_regtype
------------
0
(1 row)
SELECT to_regrole('-')::oid;
to_regrole
------------
0
(1 row)
SELECT to_regnamespace('-')::oid;
to_regnamespace
-----------------
0
(1 row)
SELECT to_regdatabase('-')::oid;
to_regdatabase
----------------
0
(1 row)
-- constant cannot be used here
CREATE TABLE regrole_test (rolid OID DEFAULT 'regress_regrole_test'::regrole);
ERROR: constant of the type regrole cannot be used here
CREATE TABLE regdatabase_test (datid OID DEFAULT 'template1'::regdatabase);
ERROR: constant of the type regdatabase cannot be used here
/* If objects don't exist, raise errors. */ /* If objects don't exist, raise errors. */
DROP ROLE regress_regrole_test; DROP ROLE regress_regrole_test;
-- without schemaname -- without schemaname
@ -305,6 +443,18 @@ SELECT regnamespace('foo.bar');
ERROR: invalid name syntax ERROR: invalid name syntax
LINE 1: SELECT regnamespace('foo.bar'); LINE 1: SELECT regnamespace('foo.bar');
^ ^
SELECT regdatabase('Nonexistent');
ERROR: database "nonexistent" does not exist
LINE 1: SELECT regdatabase('Nonexistent');
^
SELECT regdatabase('"Nonexistent"');
ERROR: database "Nonexistent" does not exist
LINE 1: SELECT regdatabase('"Nonexistent"');
^
SELECT regdatabase('foo.bar');
ERROR: invalid name syntax
LINE 1: SELECT regdatabase('foo.bar');
^
/* If objects don't exist, return NULL with no error. */ /* If objects don't exist, return NULL with no error. */
-- without schemaname -- without schemaname
SELECT to_regoper('||//'); SELECT to_regoper('||//');
@ -447,6 +597,24 @@ SELECT to_regnamespace('foo.bar');
(1 row) (1 row)
SELECT to_regdatabase('Nonexistent');
to_regdatabase
----------------
(1 row)
SELECT to_regdatabase('"Nonexistent"');
to_regdatabase
----------------
(1 row)
SELECT to_regdatabase('foo.bar');
to_regdatabase
----------------
(1 row)
-- Test to_regtypemod -- Test to_regtypemod
SELECT to_regtypemod('text'); SELECT to_regtypemod('text');
to_regtypemod to_regtypemod
@ -569,6 +737,12 @@ SELECT * FROM pg_input_error_info('no_such_type', 'regtype');
type "no_such_type" does not exist | | | 42704 type "no_such_type" does not exist | | | 42704
(1 row) (1 row)
SELECT * FROM pg_input_error_info('Nonexistent', 'regdatabase');
message | detail | hint | sql_error_code
---------------------------------------+--------+------+----------------
database "nonexistent" does not exist | | | 42704
(1 row)
-- Some cases that should be soft errors, but are not yet -- Some cases that should be soft errors, but are not yet
SELECT * FROM pg_input_error_info('incorrect type name syntax', 'regtype'); SELECT * FROM pg_input_error_info('incorrect type name syntax', 'regtype');
ERROR: syntax error at or near "type" ERROR: syntax error at or near "type"

View File

@ -711,6 +711,7 @@ CREATE TABLE tab_core_types AS SELECT
'regtype'::regtype type, 'regtype'::regtype type,
'pg_monitor'::regrole, 'pg_monitor'::regrole,
'pg_class'::regclass::oid, 'pg_class'::regclass::oid,
'template1'::regdatabase,
'(1,1)'::tid, '2'::xid, '3'::cid, '(1,1)'::tid, '2'::xid, '3'::cid,
'10:20:10,14,15'::txid_snapshot, '10:20:10,14,15'::txid_snapshot,
'10:20:10,14,15'::pg_snapshot, '10:20:10,14,15'::pg_snapshot,

View File

@ -47,11 +47,42 @@ SELECT regrole('regress_regrole_test');
SELECT regrole('"regress_regrole_test"'); SELECT regrole('"regress_regrole_test"');
SELECT regnamespace('pg_catalog'); SELECT regnamespace('pg_catalog');
SELECT regnamespace('"pg_catalog"'); SELECT regnamespace('"pg_catalog"');
SELECT regdatabase('template1');
SELECT regdatabase('"template1"');
SELECT to_regrole('regress_regrole_test'); SELECT to_regrole('regress_regrole_test');
SELECT to_regrole('"regress_regrole_test"'); SELECT to_regrole('"regress_regrole_test"');
SELECT to_regnamespace('pg_catalog'); SELECT to_regnamespace('pg_catalog');
SELECT to_regnamespace('"pg_catalog"'); SELECT to_regnamespace('"pg_catalog"');
SELECT to_regdatabase('template1');
SELECT to_regdatabase('"template1"');
-- special "single dash" case
SELECT regproc('-')::oid;
SELECT regprocedure('-')::oid;
SELECT regclass('-')::oid;
SELECT regcollation('-')::oid;
SELECT regtype('-')::oid;
SELECT regconfig('-')::oid;
SELECT regdictionary('-')::oid;
SELECT regrole('-')::oid;
SELECT regnamespace('-')::oid;
SELECT regdatabase('-')::oid;
SELECT to_regproc('-')::oid;
SELECT to_regprocedure('-')::oid;
SELECT to_regclass('-')::oid;
SELECT to_regcollation('-')::oid;
SELECT to_regtype('-')::oid;
SELECT to_regrole('-')::oid;
SELECT to_regnamespace('-')::oid;
SELECT to_regdatabase('-')::oid;
-- constant cannot be used here
CREATE TABLE regrole_test (rolid OID DEFAULT 'regress_regrole_test'::regrole);
CREATE TABLE regdatabase_test (datid OID DEFAULT 'template1'::regdatabase);
/* If objects don't exist, raise errors. */ /* If objects don't exist, raise errors. */
@ -88,6 +119,9 @@ SELECT regrole('foo.bar');
SELECT regnamespace('Nonexistent'); SELECT regnamespace('Nonexistent');
SELECT regnamespace('"Nonexistent"'); SELECT regnamespace('"Nonexistent"');
SELECT regnamespace('foo.bar'); SELECT regnamespace('foo.bar');
SELECT regdatabase('Nonexistent');
SELECT regdatabase('"Nonexistent"');
SELECT regdatabase('foo.bar');
/* If objects don't exist, return NULL with no error. */ /* If objects don't exist, return NULL with no error. */
@ -122,6 +156,9 @@ SELECT to_regrole('foo.bar');
SELECT to_regnamespace('Nonexistent'); SELECT to_regnamespace('Nonexistent');
SELECT to_regnamespace('"Nonexistent"'); SELECT to_regnamespace('"Nonexistent"');
SELECT to_regnamespace('foo.bar'); SELECT to_regnamespace('foo.bar');
SELECT to_regdatabase('Nonexistent');
SELECT to_regdatabase('"Nonexistent"');
SELECT to_regdatabase('foo.bar');
-- Test to_regtypemod -- Test to_regtypemod
SELECT to_regtypemod('text'); SELECT to_regtypemod('text');
@ -147,6 +184,7 @@ SELECT * FROM pg_input_error_info('ng_catalog.abs(numeric)', 'regprocedure');
SELECT * FROM pg_input_error_info('ng_catalog.abs(numeric', 'regprocedure'); SELECT * FROM pg_input_error_info('ng_catalog.abs(numeric', 'regprocedure');
SELECT * FROM pg_input_error_info('regress_regrole_test', 'regrole'); SELECT * FROM pg_input_error_info('regress_regrole_test', 'regrole');
SELECT * FROM pg_input_error_info('no_such_type', 'regtype'); SELECT * FROM pg_input_error_info('no_such_type', 'regtype');
SELECT * FROM pg_input_error_info('Nonexistent', 'regdatabase');
-- Some cases that should be soft errors, but are not yet -- Some cases that should be soft errors, but are not yet
SELECT * FROM pg_input_error_info('incorrect type name syntax', 'regtype'); SELECT * FROM pg_input_error_info('incorrect type name syntax', 'regtype');

View File

@ -539,6 +539,7 @@ CREATE TABLE tab_core_types AS SELECT
'regtype'::regtype type, 'regtype'::regtype type,
'pg_monitor'::regrole, 'pg_monitor'::regrole,
'pg_class'::regclass::oid, 'pg_class'::regclass::oid,
'template1'::regdatabase,
'(1,1)'::tid, '2'::xid, '3'::cid, '(1,1)'::tid, '2'::xid, '3'::cid,
'10:20:10,14,15'::txid_snapshot, '10:20:10,14,15'::txid_snapshot,
'10:20:10,14,15'::pg_snapshot, '10:20:10,14,15'::pg_snapshot,