agora inbox for [email protected]  
help / color / mirror / Atom feed
[PATCH v16 3/7] Implement type regcollation.
10+ messages / 2 participants
[nested] [flat]

* [PATCH v16 3/7] Implement type regcollation.
@ 2019-12-05 17:59  Julien Rouhaud <[email protected]>
  0 siblings, 0 replies; 10+ messages in thread

From: Julien Rouhaud @ 2019-12-05 17:59 UTC (permalink / raw)

This will be helpful for a following commit.

Author: Julien Rouhaud
Reviewed-by: Thomas Munro and Michael Paquier
Discussion: https://postgr.es/m/CAEepm%3D0uEQCpfq_%2BLYFBdArCe4Ot98t1aR4eYiYTe%3DyavQygiQ%40mail.gmail.com
---
 doc/src/sgml/datatype.sgml            |  23 +++-
 doc/src/sgml/func.sgml                |  38 ++++---
 doc/src/sgml/ref/pgupgrade.sgml       |   4 +-
 src/backend/utils/adt/regproc.c       | 152 ++++++++++++++++++++++++++
 src/include/catalog/pg_cast.dat       |  14 +++
 src/include/catalog/pg_proc.dat       |  15 +++
 src/include/catalog/pg_type.dat       |   4 +
 src/test/regress/expected/regproc.out |  24 ++++
 src/test/regress/sql/regproc.sql      |   4 +
 9 files changed, 256 insertions(+), 22 deletions(-)

diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index 410eaedcb7..86d16e7b13 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -4496,6 +4496,10 @@ INSERT INTO mytable VALUES(-1);  -- fails
     <primary>regtype</primary>
    </indexterm>
 
+   <indexterm zone="datatype-oid">
+    <primary>regcollation</primary>
+   </indexterm>
+
    <indexterm zone="datatype-oid">
     <primary>regconfig</primary>
    </indexterm>
@@ -4522,12 +4526,12 @@ INSERT INTO mytable VALUES(-1);  -- fails
     system tables.
 
     Type <type>oid</type> represents an object identifier.  There are also
-    several alias types for <type>oid</type>: <type>regproc</type>,
-    <type>regprocedure</type>, <type>regoper</type>, <type>regoperator</type>,
-    <type>regclass</type>, <type>regtype</type>, <type>regrole</type>,
-    <type>regnamespace</type>, <type>regconfig</type>, and
-    <type>regdictionary</type>.  <xref linkend="datatype-oid-table"/> shows an
-    overview.
+    several alias types for <type>oid</type>: <type>regcollation</type>,
+    <type>regproc</type>, <type>regprocedure</type>, <type>regoper</type>,
+    <type>regoperator</type>, <type>regclass</type>, <type>regtype</type>,
+    <type>regrole</type>, <type>regnamespace</type>, <type>regconfig</type>,
+    and <type>regdictionary</type>.  <xref linkend="datatype-oid-table"/> shows
+    an overview.
    </para>
 
    <para>
@@ -4591,6 +4595,13 @@ SELECT * FROM pg_attribute
         <entry><literal>564182</literal></entry>
        </row>
 
+       <row>
+        <entry><type>regcollation</type></entry>
+        <entry><structname>pg_collation</structname></entry>
+        <entry>collation name</entry>
+        <entry><literal>"POSIX"</literal></entry>
+       </row>
+
        <row>
         <entry><type>regproc</type></entry>
         <entry><structname>pg_proc</structname></entry>
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index b2d991ac7f..02779ab713 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -18177,6 +18177,10 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
     <primary>to_regclass</primary>
    </indexterm>
 
+   <indexterm>
+    <primary>to_regcollation</primary>
+   </indexterm>
+
    <indexterm>
     <primary>to_regproc</primary>
    </indexterm>
@@ -18389,6 +18393,11 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
        <entry><type>regclass</type></entry>
        <entry>get the OID of the named relation</entry>
       </row>
+      <row>
+       <entry><literal><function>to_regcollation(<parameter>coll_name</parameter>)</function></literal></entry>
+       <entry><type>regcollation</type></entry>
+       <entry>get the OID of the named collation</entry>
+      </row>
       <row>
        <entry><literal><function>to_regproc(<parameter>func_name</parameter>)</function></literal></entry>
        <entry><type>regproc</type></entry>
@@ -18720,20 +18729,21 @@ SELECT collation for ('foo' COLLATE "de_DE");
   </para>
 
   <para>
-   The <function>to_regclass</function>, <function>to_regproc</function>,
-   <function>to_regprocedure</function>, <function>to_regoper</function>,
-   <function>to_regoperator</function>, <function>to_regtype</function>,
-   <function>to_regnamespace</function>, and <function>to_regrole</function>
-   functions translate relation, function, operator, type, schema, and role
-   names (given as <type>text</type>) to objects of
-   type <type>regclass</type>, <type>regproc</type>, <type>regprocedure</type>,
+   The <function>to_regclass</function>, <function>to_regcollation</function>,
+   <function>to_regproc</function>, <function>to_regprocedure</function>,
+   <function>to_regoper</function>, <function>to_regoperator</function>,
+   <function>to_regtype</function>, <function>to_regnamespace</function>, and
+   <function>to_regrole</function> functions translate relation, collation,
+   function, operator, type, schema, and role names (given as
+   <type>text</type>) to objects of type <type>regclass</type>,
+   <type>regcollation</type>, <type>regproc</type>, <type>regprocedure</type>,
    <type>regoper</type>, <type>regoperator</type>, <type>regtype</type>,
-   <type>regnamespace</type>, and <type>regrole</type>
-   respectively.  These functions differ from a cast from
-   text in that they don't accept a numeric OID, and that they return null
-   rather than throwing an error if the name is not found (or, for
-   <function>to_regproc</function> and <function>to_regoper</function>, if
-   the given name matches multiple objects).
+   <type>regnamespace</type>, and <type>regrole</type> respectively.  These
+   functions differ from a cast from text in that they don't accept a numeric
+   OID, and that they return null rather than throwing an error if the name is
+   not found (or, for <function>to_regproc</function> and
+   <function>to_regoper</function>, if the given name matches multiple
+   objects).
   </para>
 
    <indexterm>
@@ -21095,7 +21105,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup());
       <row>
        <entry>
         <indexterm><primary>pg_collation_actual_version</primary></indexterm>
-        <literal><function>pg_collation_actual_version(<type>oid</type>)</function></literal>
+        <literal><function>pg_collation_actual_version(<type>regcollation</type>)</function></literal>
        </entry>
        <entry><type>text</type></entry>
        <entry>Return actual version of collation from operating system</entry>
diff --git a/doc/src/sgml/ref/pgupgrade.sgml b/doc/src/sgml/ref/pgupgrade.sgml
index 6629d736b8..8e229135c2 100644
--- a/doc/src/sgml/ref/pgupgrade.sgml
+++ b/doc/src/sgml/ref/pgupgrade.sgml
@@ -773,8 +773,8 @@ psql --username=postgres --file=script.sql postgres
   <para>
    <application>pg_upgrade</application> does not support upgrading of databases
    containing table columns using these <type>reg*</type> OID-referencing system data types:
-   <type>regproc</type>, <type>regprocedure</type>, <type>regoper</type>,
-   <type>regoperator</type>, <type>regconfig</type>, and
+   <type>regcollation</type>, <type>regproc</type>, <type>regprocedure</type>,
+   <type>regoper</type>, <type>regoperator</type>, <type>regconfig</type>, and
    <type>regdictionary</type>.  (<type>regtype</type> can be upgraded.)
   </para>
 
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index f0fa52bc27..da8cc0cf6b 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -24,6 +24,7 @@
 #include "access/htup_details.h"
 #include "catalog/namespace.h"
 #include "catalog/pg_class.h"
+#include "catalog/pg_collation.h"
 #include "catalog/pg_operator.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_ts_config.h"
@@ -1043,6 +1044,157 @@ regclasssend(PG_FUNCTION_ARGS)
 }
 
 
+/*
+ * regcollationin		- converts "collationname" to collation 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_collation entry.
+ */
+Datum
+regcollationin(PG_FUNCTION_ARGS)
+{
+	char	   *collation_name_or_oid = PG_GETARG_CSTRING(0);
+	Oid			result = InvalidOid;
+	List	   *names;
+
+	/* '-' ? */
+	if (strcmp(collation_name_or_oid, "-") == 0)
+		PG_RETURN_OID(InvalidOid);
+
+	/* Numeric OID? */
+	if (collation_name_or_oid[0] >= '0' &&
+		collation_name_or_oid[0] <= '9' &&
+		strspn(collation_name_or_oid, "0123456789") == strlen(collation_name_or_oid))
+	{
+		result = DatumGetObjectId(DirectFunctionCall1(oidin,
+													  CStringGetDatum(collation_name_or_oid)));
+		PG_RETURN_OID(result);
+	}
+
+	/* Else it's a name, possibly schema-qualified */
+
+	/* The rest of this wouldn't work in bootstrap mode */
+	if (IsBootstrapProcessingMode())
+		elog(ERROR, "regcollation values must be OIDs in bootstrap mode");
+
+	/*
+	 * Normal case: parse the name into components and see if it matches any
+	 * pg_collation entries in the current search path.
+	 */
+	names = stringToQualifiedNameList(collation_name_or_oid);
+
+	result = get_collation_oid(names, false);
+
+	PG_RETURN_OID(result);
+}
+
+/*
+ * to_regcollation		- converts "collationname" to collation OID
+ *
+ * If the name is not found, we return NULL.
+ */
+Datum
+to_regcollation(PG_FUNCTION_ARGS)
+{
+	char	   *collation_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
+	Oid			result;
+	List	   *names;
+
+	/*
+	 * Parse the name into components and see if it matches any pg_collation
+	 * entries in the current search path.
+	 */
+	names = stringToQualifiedNameList(collation_name);
+
+	/* We might not even have permissions on this relation; don't lock it. */
+	result = get_collation_oid(names, true);
+
+	if (OidIsValid(result))
+		PG_RETURN_OID(result);
+	else
+		PG_RETURN_NULL();
+}
+
+/*
+ * regcollationout		- converts collation OID to "collation_name"
+ */
+Datum
+regcollationout(PG_FUNCTION_ARGS)
+{
+	Oid			collationid = PG_GETARG_OID(0);
+	char	   *result;
+	HeapTuple	collationtup;
+
+	if (collationid == InvalidOid)
+	{
+		result = pstrdup("-");
+		PG_RETURN_CSTRING(result);
+	}
+
+	collationtup = SearchSysCache1(COLLOID, ObjectIdGetDatum(collationid));
+
+	if (HeapTupleIsValid(collationtup))
+	{
+		Form_pg_collation collationform = (Form_pg_collation) GETSTRUCT(collationtup);
+		char	   *collationname = NameStr(collationform->collname);
+
+		/*
+		 * In bootstrap mode, skip the fancy namespace stuff and just return
+		 * the collation name.  (This path is only needed for debugging output
+		 * anyway.)
+		 */
+		if (IsBootstrapProcessingMode())
+			result = pstrdup(collationname);
+		else
+		{
+			char	   *nspname;
+
+			/*
+			 * Would this collation be found by regcollationin? If not, qualify it.
+			 */
+			if (CollationIsVisible(collationid))
+				nspname = NULL;
+			else
+				nspname = get_namespace_name(collationform->collnamespace);
+
+			result = quote_qualified_identifier(nspname, collationname);
+		}
+
+		ReleaseSysCache(collationtup);
+	}
+	else
+	{
+		/* If OID doesn't match any pg_collation entry, return it numerically */
+		result = (char *) palloc(NAMEDATALEN);
+		snprintf(result, NAMEDATALEN, "%u", collationid);
+	}
+
+	PG_RETURN_CSTRING(result);
+}
+
+/*
+ *		regcollationrecv			- converts external binary format to regcollation
+ */
+Datum
+regcollationrecv(PG_FUNCTION_ARGS)
+{
+	/* Exactly the same as oidrecv, so share code */
+	return oidrecv(fcinfo);
+}
+
+/*
+ *		regcollationsend			- converts regcollation to binary format
+ */
+Datum
+regcollationsend(PG_FUNCTION_ARGS)
+{
+	/* Exactly the same as oidsend, so share code */
+	return oidsend(fcinfo);
+}
+
+
 /*
  * regtypein		- converts "typename" to type OID
  *
diff --git a/src/include/catalog/pg_cast.dat b/src/include/catalog/pg_cast.dat
index 6ef8b8a4e7..01c5328ddd 100644
--- a/src/include/catalog/pg_cast.dat
+++ b/src/include/catalog/pg_cast.dat
@@ -189,6 +189,20 @@
   castcontext => 'a', castmethod => 'f' },
 { castsource => 'regclass', casttarget => 'int4', castfunc => '0',
   castcontext => 'a', castmethod => 'b' },
+{ castsource => 'oid', casttarget => 'regcollation', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'regcollation', casttarget => 'oid', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'int8', casttarget => 'regcollation', castfunc => 'oid',
+  castcontext => 'i', castmethod => 'f' },
+{ castsource => 'int2', casttarget => 'regcollation', castfunc => 'int4(int2)',
+  castcontext => 'i', castmethod => 'f' },
+{ castsource => 'int4', casttarget => 'regcollation', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'regcollation', casttarget => 'int8', castfunc => 'int8(oid)',
+  castcontext => 'a', castmethod => 'f' },
+{ castsource => 'regcollation', casttarget => 'int4', castfunc => '0',
+  castcontext => 'a', castmethod => 'b' },
 { castsource => 'oid', casttarget => 'regtype', castfunc => '0',
   castcontext => 'i', castmethod => 'b' },
 { castsource => 'regtype', casttarget => 'oid', castfunc => '0',
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 7fb574f9dc..c7c25e1eae 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -6666,6 +6666,15 @@
 { oid => '3495', descr => 'convert classname to regclass',
   proname => 'to_regclass', provolatile => 's', prorettype => 'regclass',
   proargtypes => 'text', prosrc => 'to_regclass' },
+{ oid => '9508', descr => 'I/O',
+  proname => 'regcollationin', provolatile => 's', prorettype => 'regcollation',
+  proargtypes => 'cstring', prosrc => 'regcollationin' },
+{ oid => '9509', descr => 'I/O',
+  proname => 'regcollationout', provolatile => 's', prorettype => 'cstring',
+  proargtypes => 'regcollation', prosrc => 'regcollationout' },
+{ oid => '9510', descr => 'convert classname to regcollation',
+  proname => 'to_regcollation', provolatile => 's', prorettype => 'regcollation',
+  proargtypes => 'text', prosrc => 'to_regcollation' },
 { oid => '2220', descr => 'I/O',
   proname => 'regtypein', provolatile => 's', prorettype => 'regtype',
   proargtypes => 'cstring', prosrc => 'regtypein' },
@@ -7446,6 +7455,12 @@
 { oid => '2453', descr => 'I/O',
   proname => 'regclasssend', prorettype => 'bytea', proargtypes => 'regclass',
   prosrc => 'regclasssend' },
+{ oid => '9511', descr => 'I/O',
+  proname => 'regcollationrecv', prorettype => 'regcollation',
+  proargtypes => 'internal', prosrc => 'regcollationrecv' },
+{ oid => '9512', descr => 'I/O',
+  proname => 'regcollationsend', prorettype => 'bytea', proargtypes => 'regcollation',
+  prosrc => 'regcollationsend' },
 { oid => '2454', descr => 'I/O',
   proname => 'regtyperecv', prorettype => 'regtype', proargtypes => 'internal',
   prosrc => 'regtyperecv' },
diff --git a/src/include/catalog/pg_type.dat b/src/include/catalog/pg_type.dat
index b00597d6ff..ad777e37c6 100644
--- a/src/include/catalog/pg_type.dat
+++ b/src/include/catalog/pg_type.dat
@@ -379,6 +379,10 @@
   typname => 'regclass', typlen => '4', typbyval => 't', typcategory => 'N',
   typinput => 'regclassin', typoutput => 'regclassout',
   typreceive => 'regclassrecv', typsend => 'regclasssend', typalign => 'i' },
+{ oid => '9506', array_type_oid => '9507', descr => 'registered collation',
+  typname => 'regcollation', typlen => '4', typbyval => 't', typcategory => 'N',
+  typinput => 'regcollationin', typoutput => 'regcollationout',
+  typreceive => 'regcollationrecv', typsend => 'regcollationsend', typalign => 'i' },
 { oid => '2206', array_type_oid => '2211', descr => 'registered type',
   typname => 'regtype', typlen => '4', typbyval => 't', typcategory => 'N',
   typinput => 'regtypein', typoutput => 'regtypeout',
diff --git a/src/test/regress/expected/regproc.out b/src/test/regress/expected/regproc.out
index ee4fcda866..16994e0909 100644
--- a/src/test/regress/expected/regproc.out
+++ b/src/test/regress/expected/regproc.out
@@ -40,6 +40,12 @@ SELECT regtype('int4');
  integer
 (1 row)
 
+SELECT regcollation('"POSIX"');
+ regcollation 
+--------------
+ "POSIX"
+(1 row)
+
 SELECT to_regoper('||/');
  to_regoper 
 ------------
@@ -76,6 +82,12 @@ SELECT to_regtype('int4');
  integer
 (1 row)
 
+SELECT to_regcollation('"POSIX"');
+ to_regcollation 
+-----------------
+ "POSIX"
+(1 row)
+
 -- with schemaname
 SELECT regoper('pg_catalog.||/');
  regoper 
@@ -113,6 +125,12 @@ SELECT regtype('pg_catalog.int4');
  integer
 (1 row)
 
+SELECT regcollation('pg_catalog."POSIX"');
+ regcollation 
+--------------
+ "POSIX"
+(1 row)
+
 SELECT to_regoper('pg_catalog.||/');
  to_regoper 
 ------------
@@ -143,6 +161,12 @@ SELECT to_regtype('pg_catalog.int4');
  integer
 (1 row)
 
+SELECT to_regcollation('pg_catalog."POSIX"');
+ to_regcollation 
+-----------------
+ "POSIX"
+(1 row)
+
 -- schemaname not applicable
 SELECT regrole('regress_regrole_test');
        regrole        
diff --git a/src/test/regress/sql/regproc.sql b/src/test/regress/sql/regproc.sql
index a60bc28901..5c8032800a 100644
--- a/src/test/regress/sql/regproc.sql
+++ b/src/test/regress/sql/regproc.sql
@@ -14,6 +14,7 @@ SELECT regproc('now');
 SELECT regprocedure('abs(numeric)');
 SELECT regclass('pg_class');
 SELECT regtype('int4');
+SELECT regcollation('"POSIX"');
 
 SELECT to_regoper('||/');
 SELECT to_regoperator('+(int4,int4)');
@@ -21,6 +22,7 @@ SELECT to_regproc('now');
 SELECT to_regprocedure('abs(numeric)');
 SELECT to_regclass('pg_class');
 SELECT to_regtype('int4');
+SELECT to_regcollation('"POSIX"');
 
 -- with schemaname
 
@@ -30,12 +32,14 @@ SELECT regproc('pg_catalog.now');
 SELECT regprocedure('pg_catalog.abs(numeric)');
 SELECT regclass('pg_catalog.pg_class');
 SELECT regtype('pg_catalog.int4');
+SELECT regcollation('pg_catalog."POSIX"');
 
 SELECT to_regoper('pg_catalog.||/');
 SELECT to_regproc('pg_catalog.now');
 SELECT to_regprocedure('pg_catalog.abs(numeric)');
 SELECT to_regclass('pg_catalog.pg_class');
 SELECT to_regtype('pg_catalog.int4');
+SELECT to_regcollation('pg_catalog."POSIX"');
 
 -- schemaname not applicable
 
-- 
2.20.1


--sdtB3X0nJg68CQEu
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
	filename="v16-0004-Track-collation-versions-for-indexes.patch"



^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* [PATCH 3/6] Implement type regcollation.
@ 2019-12-05 17:59  Julien Rouhaud <[email protected]>
  0 siblings, 0 replies; 10+ messages in thread

From: Julien Rouhaud @ 2019-12-05 17:59 UTC (permalink / raw)

This will be helpful for a following commit.

Author: Julien Rouhaud
Reviewed-by:
Discussion: https://postgr.es/m/CAEepm%3D0uEQCpfq_%2BLYFBdArCe4Ot98t1aR4eYiYTe%3DyavQygiQ%40mail.gmail.com
---
 src/backend/utils/adt/regproc.c | 152 ++++++++++++++++++++++++++++++++
 src/include/catalog/pg_cast.dat |  14 +++
 src/include/catalog/pg_proc.dat |  15 ++++
 src/include/catalog/pg_type.dat |   4 +
 4 files changed, 185 insertions(+)

diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index f0fa52bc27..da8cc0cf6b 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -24,6 +24,7 @@
 #include "access/htup_details.h"
 #include "catalog/namespace.h"
 #include "catalog/pg_class.h"
+#include "catalog/pg_collation.h"
 #include "catalog/pg_operator.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_ts_config.h"
@@ -1043,6 +1044,157 @@ regclasssend(PG_FUNCTION_ARGS)
 }
 
 
+/*
+ * regcollationin		- converts "collationname" to collation 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_collation entry.
+ */
+Datum
+regcollationin(PG_FUNCTION_ARGS)
+{
+	char	   *collation_name_or_oid = PG_GETARG_CSTRING(0);
+	Oid			result = InvalidOid;
+	List	   *names;
+
+	/* '-' ? */
+	if (strcmp(collation_name_or_oid, "-") == 0)
+		PG_RETURN_OID(InvalidOid);
+
+	/* Numeric OID? */
+	if (collation_name_or_oid[0] >= '0' &&
+		collation_name_or_oid[0] <= '9' &&
+		strspn(collation_name_or_oid, "0123456789") == strlen(collation_name_or_oid))
+	{
+		result = DatumGetObjectId(DirectFunctionCall1(oidin,
+													  CStringGetDatum(collation_name_or_oid)));
+		PG_RETURN_OID(result);
+	}
+
+	/* Else it's a name, possibly schema-qualified */
+
+	/* The rest of this wouldn't work in bootstrap mode */
+	if (IsBootstrapProcessingMode())
+		elog(ERROR, "regcollation values must be OIDs in bootstrap mode");
+
+	/*
+	 * Normal case: parse the name into components and see if it matches any
+	 * pg_collation entries in the current search path.
+	 */
+	names = stringToQualifiedNameList(collation_name_or_oid);
+
+	result = get_collation_oid(names, false);
+
+	PG_RETURN_OID(result);
+}
+
+/*
+ * to_regcollation		- converts "collationname" to collation OID
+ *
+ * If the name is not found, we return NULL.
+ */
+Datum
+to_regcollation(PG_FUNCTION_ARGS)
+{
+	char	   *collation_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
+	Oid			result;
+	List	   *names;
+
+	/*
+	 * Parse the name into components and see if it matches any pg_collation
+	 * entries in the current search path.
+	 */
+	names = stringToQualifiedNameList(collation_name);
+
+	/* We might not even have permissions on this relation; don't lock it. */
+	result = get_collation_oid(names, true);
+
+	if (OidIsValid(result))
+		PG_RETURN_OID(result);
+	else
+		PG_RETURN_NULL();
+}
+
+/*
+ * regcollationout		- converts collation OID to "collation_name"
+ */
+Datum
+regcollationout(PG_FUNCTION_ARGS)
+{
+	Oid			collationid = PG_GETARG_OID(0);
+	char	   *result;
+	HeapTuple	collationtup;
+
+	if (collationid == InvalidOid)
+	{
+		result = pstrdup("-");
+		PG_RETURN_CSTRING(result);
+	}
+
+	collationtup = SearchSysCache1(COLLOID, ObjectIdGetDatum(collationid));
+
+	if (HeapTupleIsValid(collationtup))
+	{
+		Form_pg_collation collationform = (Form_pg_collation) GETSTRUCT(collationtup);
+		char	   *collationname = NameStr(collationform->collname);
+
+		/*
+		 * In bootstrap mode, skip the fancy namespace stuff and just return
+		 * the collation name.  (This path is only needed for debugging output
+		 * anyway.)
+		 */
+		if (IsBootstrapProcessingMode())
+			result = pstrdup(collationname);
+		else
+		{
+			char	   *nspname;
+
+			/*
+			 * Would this collation be found by regcollationin? If not, qualify it.
+			 */
+			if (CollationIsVisible(collationid))
+				nspname = NULL;
+			else
+				nspname = get_namespace_name(collationform->collnamespace);
+
+			result = quote_qualified_identifier(nspname, collationname);
+		}
+
+		ReleaseSysCache(collationtup);
+	}
+	else
+	{
+		/* If OID doesn't match any pg_collation entry, return it numerically */
+		result = (char *) palloc(NAMEDATALEN);
+		snprintf(result, NAMEDATALEN, "%u", collationid);
+	}
+
+	PG_RETURN_CSTRING(result);
+}
+
+/*
+ *		regcollationrecv			- converts external binary format to regcollation
+ */
+Datum
+regcollationrecv(PG_FUNCTION_ARGS)
+{
+	/* Exactly the same as oidrecv, so share code */
+	return oidrecv(fcinfo);
+}
+
+/*
+ *		regcollationsend			- converts regcollation to binary format
+ */
+Datum
+regcollationsend(PG_FUNCTION_ARGS)
+{
+	/* Exactly the same as oidsend, so share code */
+	return oidsend(fcinfo);
+}
+
+
 /*
  * regtypein		- converts "typename" to type OID
  *
diff --git a/src/include/catalog/pg_cast.dat b/src/include/catalog/pg_cast.dat
index 6ef8b8a4e7..01c5328ddd 100644
--- a/src/include/catalog/pg_cast.dat
+++ b/src/include/catalog/pg_cast.dat
@@ -189,6 +189,20 @@
   castcontext => 'a', castmethod => 'f' },
 { castsource => 'regclass', casttarget => 'int4', castfunc => '0',
   castcontext => 'a', castmethod => 'b' },
+{ castsource => 'oid', casttarget => 'regcollation', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'regcollation', casttarget => 'oid', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'int8', casttarget => 'regcollation', castfunc => 'oid',
+  castcontext => 'i', castmethod => 'f' },
+{ castsource => 'int2', casttarget => 'regcollation', castfunc => 'int4(int2)',
+  castcontext => 'i', castmethod => 'f' },
+{ castsource => 'int4', casttarget => 'regcollation', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'regcollation', casttarget => 'int8', castfunc => 'int8(oid)',
+  castcontext => 'a', castmethod => 'f' },
+{ castsource => 'regcollation', casttarget => 'int4', castfunc => '0',
+  castcontext => 'a', castmethod => 'b' },
 { castsource => 'oid', casttarget => 'regtype', castfunc => '0',
   castcontext => 'i', castmethod => 'b' },
 { castsource => 'regtype', casttarget => 'oid', castfunc => '0',
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 07a86c7b7b..f8fb62c623 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -6666,6 +6666,15 @@
 { oid => '3495', descr => 'convert classname to regclass',
   proname => 'to_regclass', provolatile => 's', prorettype => 'regclass',
   proargtypes => 'text', prosrc => 'to_regclass' },
+{ oid => '9508', descr => 'I/O',
+  proname => 'regcollationin', provolatile => 's', prorettype => 'regcollation',
+  proargtypes => 'cstring', prosrc => 'regcollationin' },
+{ oid => '9509', descr => 'I/O',
+  proname => 'regcollationout', provolatile => 's', prorettype => 'cstring',
+  proargtypes => 'regcollation', prosrc => 'regcollationout' },
+{ oid => '9510', descr => 'convert classname to regcollation',
+  proname => 'to_regcollation', provolatile => 's', prorettype => 'regcollation',
+  proargtypes => 'text', prosrc => 'to_regcollation' },
 { oid => '2220', descr => 'I/O',
   proname => 'regtypein', provolatile => 's', prorettype => 'regtype',
   proargtypes => 'cstring', prosrc => 'regtypein' },
@@ -7452,6 +7461,12 @@
 { oid => '2453', descr => 'I/O',
   proname => 'regclasssend', prorettype => 'bytea', proargtypes => 'regclass',
   prosrc => 'regclasssend' },
+{ oid => '9511', descr => 'I/O',
+  proname => 'regcollationrecv', prorettype => 'regcollation',
+  proargtypes => 'internal', prosrc => 'regcollationrecv' },
+{ oid => '9512', descr => 'I/O',
+  proname => 'regcollationsend', prorettype => 'bytea', proargtypes => 'regcollation',
+  prosrc => 'regcollationsend' },
 { oid => '2454', descr => 'I/O',
   proname => 'regtyperecv', prorettype => 'regtype', proargtypes => 'internal',
   prosrc => 'regtyperecv' },
diff --git a/src/include/catalog/pg_type.dat b/src/include/catalog/pg_type.dat
index 4cf2b9df7b..e4d9406730 100644
--- a/src/include/catalog/pg_type.dat
+++ b/src/include/catalog/pg_type.dat
@@ -379,6 +379,10 @@
   typname => 'regclass', typlen => '4', typbyval => 't', typcategory => 'N',
   typinput => 'regclassin', typoutput => 'regclassout',
   typreceive => 'regclassrecv', typsend => 'regclasssend', typalign => 'i' },
+{ oid => '9506', array_type_oid => '9507', descr => 'registered collation',
+  typname => 'regcollation', typlen => '4', typbyval => 't', typcategory => 'N',
+  typinput => 'regcollationin', typoutput => 'regcollationout',
+  typreceive => 'regcollationrecv', typsend => 'regcollationsend', typalign => 'i' },
 { oid => '2206', array_type_oid => '2211', descr => 'registered type',
   typname => 'regtype', typlen => '4', typbyval => 't', typcategory => 'N',
   typinput => 'regtypein', typoutput => 'regtypeout',
-- 
2.25.1


--6jmy5gypzsv7ulgm
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="0004-Track-collation-versions-for-indexes-v11.patch"



^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* [PATCH 3/6] Implement type regcollation.
@ 2019-12-05 17:59  Julien Rouhaud <[email protected]>
  0 siblings, 0 replies; 10+ messages in thread

From: Julien Rouhaud @ 2019-12-05 17:59 UTC (permalink / raw)

This will be helpful for a following commit.

Author: Julien Rouhaud
Reviewed-by:
Discussion: https://postgr.es/m/CAEepm%3D0uEQCpfq_%2BLYFBdArCe4Ot98t1aR4eYiYTe%3DyavQygiQ%40mail.gmail.com
---
 src/backend/utils/adt/regproc.c | 152 ++++++++++++++++++++++++++++++++
 src/include/catalog/pg_cast.dat |  14 +++
 src/include/catalog/pg_proc.dat |  15 ++++
 src/include/catalog/pg_type.dat |   4 +
 4 files changed, 185 insertions(+)

diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index f0fa52bc27..da8cc0cf6b 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -24,6 +24,7 @@
 #include "access/htup_details.h"
 #include "catalog/namespace.h"
 #include "catalog/pg_class.h"
+#include "catalog/pg_collation.h"
 #include "catalog/pg_operator.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_ts_config.h"
@@ -1043,6 +1044,157 @@ regclasssend(PG_FUNCTION_ARGS)
 }
 
 
+/*
+ * regcollationin		- converts "collationname" to collation 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_collation entry.
+ */
+Datum
+regcollationin(PG_FUNCTION_ARGS)
+{
+	char	   *collation_name_or_oid = PG_GETARG_CSTRING(0);
+	Oid			result = InvalidOid;
+	List	   *names;
+
+	/* '-' ? */
+	if (strcmp(collation_name_or_oid, "-") == 0)
+		PG_RETURN_OID(InvalidOid);
+
+	/* Numeric OID? */
+	if (collation_name_or_oid[0] >= '0' &&
+		collation_name_or_oid[0] <= '9' &&
+		strspn(collation_name_or_oid, "0123456789") == strlen(collation_name_or_oid))
+	{
+		result = DatumGetObjectId(DirectFunctionCall1(oidin,
+													  CStringGetDatum(collation_name_or_oid)));
+		PG_RETURN_OID(result);
+	}
+
+	/* Else it's a name, possibly schema-qualified */
+
+	/* The rest of this wouldn't work in bootstrap mode */
+	if (IsBootstrapProcessingMode())
+		elog(ERROR, "regcollation values must be OIDs in bootstrap mode");
+
+	/*
+	 * Normal case: parse the name into components and see if it matches any
+	 * pg_collation entries in the current search path.
+	 */
+	names = stringToQualifiedNameList(collation_name_or_oid);
+
+	result = get_collation_oid(names, false);
+
+	PG_RETURN_OID(result);
+}
+
+/*
+ * to_regcollation		- converts "collationname" to collation OID
+ *
+ * If the name is not found, we return NULL.
+ */
+Datum
+to_regcollation(PG_FUNCTION_ARGS)
+{
+	char	   *collation_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
+	Oid			result;
+	List	   *names;
+
+	/*
+	 * Parse the name into components and see if it matches any pg_collation
+	 * entries in the current search path.
+	 */
+	names = stringToQualifiedNameList(collation_name);
+
+	/* We might not even have permissions on this relation; don't lock it. */
+	result = get_collation_oid(names, true);
+
+	if (OidIsValid(result))
+		PG_RETURN_OID(result);
+	else
+		PG_RETURN_NULL();
+}
+
+/*
+ * regcollationout		- converts collation OID to "collation_name"
+ */
+Datum
+regcollationout(PG_FUNCTION_ARGS)
+{
+	Oid			collationid = PG_GETARG_OID(0);
+	char	   *result;
+	HeapTuple	collationtup;
+
+	if (collationid == InvalidOid)
+	{
+		result = pstrdup("-");
+		PG_RETURN_CSTRING(result);
+	}
+
+	collationtup = SearchSysCache1(COLLOID, ObjectIdGetDatum(collationid));
+
+	if (HeapTupleIsValid(collationtup))
+	{
+		Form_pg_collation collationform = (Form_pg_collation) GETSTRUCT(collationtup);
+		char	   *collationname = NameStr(collationform->collname);
+
+		/*
+		 * In bootstrap mode, skip the fancy namespace stuff and just return
+		 * the collation name.  (This path is only needed for debugging output
+		 * anyway.)
+		 */
+		if (IsBootstrapProcessingMode())
+			result = pstrdup(collationname);
+		else
+		{
+			char	   *nspname;
+
+			/*
+			 * Would this collation be found by regcollationin? If not, qualify it.
+			 */
+			if (CollationIsVisible(collationid))
+				nspname = NULL;
+			else
+				nspname = get_namespace_name(collationform->collnamespace);
+
+			result = quote_qualified_identifier(nspname, collationname);
+		}
+
+		ReleaseSysCache(collationtup);
+	}
+	else
+	{
+		/* If OID doesn't match any pg_collation entry, return it numerically */
+		result = (char *) palloc(NAMEDATALEN);
+		snprintf(result, NAMEDATALEN, "%u", collationid);
+	}
+
+	PG_RETURN_CSTRING(result);
+}
+
+/*
+ *		regcollationrecv			- converts external binary format to regcollation
+ */
+Datum
+regcollationrecv(PG_FUNCTION_ARGS)
+{
+	/* Exactly the same as oidrecv, so share code */
+	return oidrecv(fcinfo);
+}
+
+/*
+ *		regcollationsend			- converts regcollation to binary format
+ */
+Datum
+regcollationsend(PG_FUNCTION_ARGS)
+{
+	/* Exactly the same as oidsend, so share code */
+	return oidsend(fcinfo);
+}
+
+
 /*
  * regtypein		- converts "typename" to type OID
  *
diff --git a/src/include/catalog/pg_cast.dat b/src/include/catalog/pg_cast.dat
index 6ef8b8a4e7..01c5328ddd 100644
--- a/src/include/catalog/pg_cast.dat
+++ b/src/include/catalog/pg_cast.dat
@@ -189,6 +189,20 @@
   castcontext => 'a', castmethod => 'f' },
 { castsource => 'regclass', casttarget => 'int4', castfunc => '0',
   castcontext => 'a', castmethod => 'b' },
+{ castsource => 'oid', casttarget => 'regcollation', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'regcollation', casttarget => 'oid', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'int8', casttarget => 'regcollation', castfunc => 'oid',
+  castcontext => 'i', castmethod => 'f' },
+{ castsource => 'int2', casttarget => 'regcollation', castfunc => 'int4(int2)',
+  castcontext => 'i', castmethod => 'f' },
+{ castsource => 'int4', casttarget => 'regcollation', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'regcollation', casttarget => 'int8', castfunc => 'int8(oid)',
+  castcontext => 'a', castmethod => 'f' },
+{ castsource => 'regcollation', casttarget => 'int4', castfunc => '0',
+  castcontext => 'a', castmethod => 'b' },
 { castsource => 'oid', casttarget => 'regtype', castfunc => '0',
   castcontext => 'i', castmethod => 'b' },
 { castsource => 'regtype', casttarget => 'oid', castfunc => '0',
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 07a86c7b7b..f8fb62c623 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -6666,6 +6666,15 @@
 { oid => '3495', descr => 'convert classname to regclass',
   proname => 'to_regclass', provolatile => 's', prorettype => 'regclass',
   proargtypes => 'text', prosrc => 'to_regclass' },
+{ oid => '9508', descr => 'I/O',
+  proname => 'regcollationin', provolatile => 's', prorettype => 'regcollation',
+  proargtypes => 'cstring', prosrc => 'regcollationin' },
+{ oid => '9509', descr => 'I/O',
+  proname => 'regcollationout', provolatile => 's', prorettype => 'cstring',
+  proargtypes => 'regcollation', prosrc => 'regcollationout' },
+{ oid => '9510', descr => 'convert classname to regcollation',
+  proname => 'to_regcollation', provolatile => 's', prorettype => 'regcollation',
+  proargtypes => 'text', prosrc => 'to_regcollation' },
 { oid => '2220', descr => 'I/O',
   proname => 'regtypein', provolatile => 's', prorettype => 'regtype',
   proargtypes => 'cstring', prosrc => 'regtypein' },
@@ -7452,6 +7461,12 @@
 { oid => '2453', descr => 'I/O',
   proname => 'regclasssend', prorettype => 'bytea', proargtypes => 'regclass',
   prosrc => 'regclasssend' },
+{ oid => '9511', descr => 'I/O',
+  proname => 'regcollationrecv', prorettype => 'regcollation',
+  proargtypes => 'internal', prosrc => 'regcollationrecv' },
+{ oid => '9512', descr => 'I/O',
+  proname => 'regcollationsend', prorettype => 'bytea', proargtypes => 'regcollation',
+  prosrc => 'regcollationsend' },
 { oid => '2454', descr => 'I/O',
   proname => 'regtyperecv', prorettype => 'regtype', proargtypes => 'internal',
   prosrc => 'regtyperecv' },
diff --git a/src/include/catalog/pg_type.dat b/src/include/catalog/pg_type.dat
index 4cf2b9df7b..e4d9406730 100644
--- a/src/include/catalog/pg_type.dat
+++ b/src/include/catalog/pg_type.dat
@@ -379,6 +379,10 @@
   typname => 'regclass', typlen => '4', typbyval => 't', typcategory => 'N',
   typinput => 'regclassin', typoutput => 'regclassout',
   typreceive => 'regclassrecv', typsend => 'regclasssend', typalign => 'i' },
+{ oid => '9506', array_type_oid => '9507', descr => 'registered collation',
+  typname => 'regcollation', typlen => '4', typbyval => 't', typcategory => 'N',
+  typinput => 'regcollationin', typoutput => 'regcollationout',
+  typreceive => 'regcollationrecv', typsend => 'regcollationsend', typalign => 'i' },
 { oid => '2206', array_type_oid => '2211', descr => 'registered type',
   typname => 'regtype', typlen => '4', typbyval => 't', typcategory => 'N',
   typinput => 'regtypein', typoutput => 'regtypeout',
-- 
2.20.1


--mP3DRpeJDSE+ciuQ
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
	filename="0004-Track-collation-versions-for-indexes-v12.patch"



^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* [PATCH v14 3/7] Implement type regcollation.
@ 2019-12-05 17:59  Julien Rouhaud <[email protected]>
  0 siblings, 0 replies; 10+ messages in thread

From: Julien Rouhaud @ 2019-12-05 17:59 UTC (permalink / raw)

This will be helpful for a following commit.

Author: Julien Rouhaud
Reviewed-by: Thomas Munro
Discussion: https://postgr.es/m/CAEepm%3D0uEQCpfq_%2BLYFBdArCe4Ot98t1aR4eYiYTe%3DyavQygiQ%40mail.gmail.com
---
 doc/src/sgml/datatype.sgml      |   4 +
 src/backend/utils/adt/regproc.c | 152 ++++++++++++++++++++++++++++++++
 src/include/catalog/pg_cast.dat |  14 +++
 src/include/catalog/pg_proc.dat |  15 ++++
 src/include/catalog/pg_type.dat |   4 +
 5 files changed, 189 insertions(+)

diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index 410eaedcb7..9a86d645a0 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -4496,6 +4496,10 @@ INSERT INTO mytable VALUES(-1);  -- fails
     <primary>regtype</primary>
    </indexterm>
 
+   <indexterm zone="datatype-oid">
+    <primary>regcollation</primary>
+   </indexterm>
+
    <indexterm zone="datatype-oid">
     <primary>regconfig</primary>
    </indexterm>
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index f0fa52bc27..da8cc0cf6b 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -24,6 +24,7 @@
 #include "access/htup_details.h"
 #include "catalog/namespace.h"
 #include "catalog/pg_class.h"
+#include "catalog/pg_collation.h"
 #include "catalog/pg_operator.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_ts_config.h"
@@ -1043,6 +1044,157 @@ regclasssend(PG_FUNCTION_ARGS)
 }
 
 
+/*
+ * regcollationin		- converts "collationname" to collation 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_collation entry.
+ */
+Datum
+regcollationin(PG_FUNCTION_ARGS)
+{
+	char	   *collation_name_or_oid = PG_GETARG_CSTRING(0);
+	Oid			result = InvalidOid;
+	List	   *names;
+
+	/* '-' ? */
+	if (strcmp(collation_name_or_oid, "-") == 0)
+		PG_RETURN_OID(InvalidOid);
+
+	/* Numeric OID? */
+	if (collation_name_or_oid[0] >= '0' &&
+		collation_name_or_oid[0] <= '9' &&
+		strspn(collation_name_or_oid, "0123456789") == strlen(collation_name_or_oid))
+	{
+		result = DatumGetObjectId(DirectFunctionCall1(oidin,
+													  CStringGetDatum(collation_name_or_oid)));
+		PG_RETURN_OID(result);
+	}
+
+	/* Else it's a name, possibly schema-qualified */
+
+	/* The rest of this wouldn't work in bootstrap mode */
+	if (IsBootstrapProcessingMode())
+		elog(ERROR, "regcollation values must be OIDs in bootstrap mode");
+
+	/*
+	 * Normal case: parse the name into components and see if it matches any
+	 * pg_collation entries in the current search path.
+	 */
+	names = stringToQualifiedNameList(collation_name_or_oid);
+
+	result = get_collation_oid(names, false);
+
+	PG_RETURN_OID(result);
+}
+
+/*
+ * to_regcollation		- converts "collationname" to collation OID
+ *
+ * If the name is not found, we return NULL.
+ */
+Datum
+to_regcollation(PG_FUNCTION_ARGS)
+{
+	char	   *collation_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
+	Oid			result;
+	List	   *names;
+
+	/*
+	 * Parse the name into components and see if it matches any pg_collation
+	 * entries in the current search path.
+	 */
+	names = stringToQualifiedNameList(collation_name);
+
+	/* We might not even have permissions on this relation; don't lock it. */
+	result = get_collation_oid(names, true);
+
+	if (OidIsValid(result))
+		PG_RETURN_OID(result);
+	else
+		PG_RETURN_NULL();
+}
+
+/*
+ * regcollationout		- converts collation OID to "collation_name"
+ */
+Datum
+regcollationout(PG_FUNCTION_ARGS)
+{
+	Oid			collationid = PG_GETARG_OID(0);
+	char	   *result;
+	HeapTuple	collationtup;
+
+	if (collationid == InvalidOid)
+	{
+		result = pstrdup("-");
+		PG_RETURN_CSTRING(result);
+	}
+
+	collationtup = SearchSysCache1(COLLOID, ObjectIdGetDatum(collationid));
+
+	if (HeapTupleIsValid(collationtup))
+	{
+		Form_pg_collation collationform = (Form_pg_collation) GETSTRUCT(collationtup);
+		char	   *collationname = NameStr(collationform->collname);
+
+		/*
+		 * In bootstrap mode, skip the fancy namespace stuff and just return
+		 * the collation name.  (This path is only needed for debugging output
+		 * anyway.)
+		 */
+		if (IsBootstrapProcessingMode())
+			result = pstrdup(collationname);
+		else
+		{
+			char	   *nspname;
+
+			/*
+			 * Would this collation be found by regcollationin? If not, qualify it.
+			 */
+			if (CollationIsVisible(collationid))
+				nspname = NULL;
+			else
+				nspname = get_namespace_name(collationform->collnamespace);
+
+			result = quote_qualified_identifier(nspname, collationname);
+		}
+
+		ReleaseSysCache(collationtup);
+	}
+	else
+	{
+		/* If OID doesn't match any pg_collation entry, return it numerically */
+		result = (char *) palloc(NAMEDATALEN);
+		snprintf(result, NAMEDATALEN, "%u", collationid);
+	}
+
+	PG_RETURN_CSTRING(result);
+}
+
+/*
+ *		regcollationrecv			- converts external binary format to regcollation
+ */
+Datum
+regcollationrecv(PG_FUNCTION_ARGS)
+{
+	/* Exactly the same as oidrecv, so share code */
+	return oidrecv(fcinfo);
+}
+
+/*
+ *		regcollationsend			- converts regcollation to binary format
+ */
+Datum
+regcollationsend(PG_FUNCTION_ARGS)
+{
+	/* Exactly the same as oidsend, so share code */
+	return oidsend(fcinfo);
+}
+
+
 /*
  * regtypein		- converts "typename" to type OID
  *
diff --git a/src/include/catalog/pg_cast.dat b/src/include/catalog/pg_cast.dat
index 6ef8b8a4e7..01c5328ddd 100644
--- a/src/include/catalog/pg_cast.dat
+++ b/src/include/catalog/pg_cast.dat
@@ -189,6 +189,20 @@
   castcontext => 'a', castmethod => 'f' },
 { castsource => 'regclass', casttarget => 'int4', castfunc => '0',
   castcontext => 'a', castmethod => 'b' },
+{ castsource => 'oid', casttarget => 'regcollation', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'regcollation', casttarget => 'oid', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'int8', casttarget => 'regcollation', castfunc => 'oid',
+  castcontext => 'i', castmethod => 'f' },
+{ castsource => 'int2', casttarget => 'regcollation', castfunc => 'int4(int2)',
+  castcontext => 'i', castmethod => 'f' },
+{ castsource => 'int4', casttarget => 'regcollation', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'regcollation', casttarget => 'int8', castfunc => 'int8(oid)',
+  castcontext => 'a', castmethod => 'f' },
+{ castsource => 'regcollation', casttarget => 'int4', castfunc => '0',
+  castcontext => 'a', castmethod => 'b' },
 { castsource => 'oid', casttarget => 'regtype', castfunc => '0',
   castcontext => 'i', castmethod => 'b' },
 { castsource => 'regtype', casttarget => 'oid', castfunc => '0',
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 7fb574f9dc..c7c25e1eae 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -6666,6 +6666,15 @@
 { oid => '3495', descr => 'convert classname to regclass',
   proname => 'to_regclass', provolatile => 's', prorettype => 'regclass',
   proargtypes => 'text', prosrc => 'to_regclass' },
+{ oid => '9508', descr => 'I/O',
+  proname => 'regcollationin', provolatile => 's', prorettype => 'regcollation',
+  proargtypes => 'cstring', prosrc => 'regcollationin' },
+{ oid => '9509', descr => 'I/O',
+  proname => 'regcollationout', provolatile => 's', prorettype => 'cstring',
+  proargtypes => 'regcollation', prosrc => 'regcollationout' },
+{ oid => '9510', descr => 'convert classname to regcollation',
+  proname => 'to_regcollation', provolatile => 's', prorettype => 'regcollation',
+  proargtypes => 'text', prosrc => 'to_regcollation' },
 { oid => '2220', descr => 'I/O',
   proname => 'regtypein', provolatile => 's', prorettype => 'regtype',
   proargtypes => 'cstring', prosrc => 'regtypein' },
@@ -7446,6 +7455,12 @@
 { oid => '2453', descr => 'I/O',
   proname => 'regclasssend', prorettype => 'bytea', proargtypes => 'regclass',
   prosrc => 'regclasssend' },
+{ oid => '9511', descr => 'I/O',
+  proname => 'regcollationrecv', prorettype => 'regcollation',
+  proargtypes => 'internal', prosrc => 'regcollationrecv' },
+{ oid => '9512', descr => 'I/O',
+  proname => 'regcollationsend', prorettype => 'bytea', proargtypes => 'regcollation',
+  prosrc => 'regcollationsend' },
 { oid => '2454', descr => 'I/O',
   proname => 'regtyperecv', prorettype => 'regtype', proargtypes => 'internal',
   prosrc => 'regtyperecv' },
diff --git a/src/include/catalog/pg_type.dat b/src/include/catalog/pg_type.dat
index b00597d6ff..ad777e37c6 100644
--- a/src/include/catalog/pg_type.dat
+++ b/src/include/catalog/pg_type.dat
@@ -379,6 +379,10 @@
   typname => 'regclass', typlen => '4', typbyval => 't', typcategory => 'N',
   typinput => 'regclassin', typoutput => 'regclassout',
   typreceive => 'regclassrecv', typsend => 'regclasssend', typalign => 'i' },
+{ oid => '9506', array_type_oid => '9507', descr => 'registered collation',
+  typname => 'regcollation', typlen => '4', typbyval => 't', typcategory => 'N',
+  typinput => 'regcollationin', typoutput => 'regcollationout',
+  typreceive => 'regcollationrecv', typsend => 'regcollationsend', typalign => 'i' },
 { oid => '2206', array_type_oid => '2211', descr => 'registered type',
   typname => 'regtype', typlen => '4', typbyval => 't', typcategory => 'N',
   typinput => 'regtypein', typoutput => 'regtypeout',
-- 
2.20.1


--wRRV7LY7NUeQGEoC
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
	filename="v14-0004-Track-collation-versions-for-indexes.patch"



^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* [PATCH v15 3/7] Implement type regcollation.
@ 2019-12-05 17:59  Julien Rouhaud <[email protected]>
  0 siblings, 0 replies; 10+ messages in thread

From: Julien Rouhaud @ 2019-12-05 17:59 UTC (permalink / raw)

This will be helpful for a following commit.

Author: Julien Rouhaud
Reviewed-by: Thomas Munro
Discussion: https://postgr.es/m/CAEepm%3D0uEQCpfq_%2BLYFBdArCe4Ot98t1aR4eYiYTe%3DyavQygiQ%40mail.gmail.com
---
 doc/src/sgml/datatype.sgml      |   4 +
 src/backend/utils/adt/regproc.c | 152 ++++++++++++++++++++++++++++++++
 src/include/catalog/pg_cast.dat |  14 +++
 src/include/catalog/pg_proc.dat |  15 ++++
 src/include/catalog/pg_type.dat |   4 +
 5 files changed, 189 insertions(+)

diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index 410eaedcb7..9a86d645a0 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -4496,6 +4496,10 @@ INSERT INTO mytable VALUES(-1);  -- fails
     <primary>regtype</primary>
    </indexterm>
 
+   <indexterm zone="datatype-oid">
+    <primary>regcollation</primary>
+   </indexterm>
+
    <indexterm zone="datatype-oid">
     <primary>regconfig</primary>
    </indexterm>
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index f0fa52bc27..da8cc0cf6b 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -24,6 +24,7 @@
 #include "access/htup_details.h"
 #include "catalog/namespace.h"
 #include "catalog/pg_class.h"
+#include "catalog/pg_collation.h"
 #include "catalog/pg_operator.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_ts_config.h"
@@ -1043,6 +1044,157 @@ regclasssend(PG_FUNCTION_ARGS)
 }
 
 
+/*
+ * regcollationin		- converts "collationname" to collation 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_collation entry.
+ */
+Datum
+regcollationin(PG_FUNCTION_ARGS)
+{
+	char	   *collation_name_or_oid = PG_GETARG_CSTRING(0);
+	Oid			result = InvalidOid;
+	List	   *names;
+
+	/* '-' ? */
+	if (strcmp(collation_name_or_oid, "-") == 0)
+		PG_RETURN_OID(InvalidOid);
+
+	/* Numeric OID? */
+	if (collation_name_or_oid[0] >= '0' &&
+		collation_name_or_oid[0] <= '9' &&
+		strspn(collation_name_or_oid, "0123456789") == strlen(collation_name_or_oid))
+	{
+		result = DatumGetObjectId(DirectFunctionCall1(oidin,
+													  CStringGetDatum(collation_name_or_oid)));
+		PG_RETURN_OID(result);
+	}
+
+	/* Else it's a name, possibly schema-qualified */
+
+	/* The rest of this wouldn't work in bootstrap mode */
+	if (IsBootstrapProcessingMode())
+		elog(ERROR, "regcollation values must be OIDs in bootstrap mode");
+
+	/*
+	 * Normal case: parse the name into components and see if it matches any
+	 * pg_collation entries in the current search path.
+	 */
+	names = stringToQualifiedNameList(collation_name_or_oid);
+
+	result = get_collation_oid(names, false);
+
+	PG_RETURN_OID(result);
+}
+
+/*
+ * to_regcollation		- converts "collationname" to collation OID
+ *
+ * If the name is not found, we return NULL.
+ */
+Datum
+to_regcollation(PG_FUNCTION_ARGS)
+{
+	char	   *collation_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
+	Oid			result;
+	List	   *names;
+
+	/*
+	 * Parse the name into components and see if it matches any pg_collation
+	 * entries in the current search path.
+	 */
+	names = stringToQualifiedNameList(collation_name);
+
+	/* We might not even have permissions on this relation; don't lock it. */
+	result = get_collation_oid(names, true);
+
+	if (OidIsValid(result))
+		PG_RETURN_OID(result);
+	else
+		PG_RETURN_NULL();
+}
+
+/*
+ * regcollationout		- converts collation OID to "collation_name"
+ */
+Datum
+regcollationout(PG_FUNCTION_ARGS)
+{
+	Oid			collationid = PG_GETARG_OID(0);
+	char	   *result;
+	HeapTuple	collationtup;
+
+	if (collationid == InvalidOid)
+	{
+		result = pstrdup("-");
+		PG_RETURN_CSTRING(result);
+	}
+
+	collationtup = SearchSysCache1(COLLOID, ObjectIdGetDatum(collationid));
+
+	if (HeapTupleIsValid(collationtup))
+	{
+		Form_pg_collation collationform = (Form_pg_collation) GETSTRUCT(collationtup);
+		char	   *collationname = NameStr(collationform->collname);
+
+		/*
+		 * In bootstrap mode, skip the fancy namespace stuff and just return
+		 * the collation name.  (This path is only needed for debugging output
+		 * anyway.)
+		 */
+		if (IsBootstrapProcessingMode())
+			result = pstrdup(collationname);
+		else
+		{
+			char	   *nspname;
+
+			/*
+			 * Would this collation be found by regcollationin? If not, qualify it.
+			 */
+			if (CollationIsVisible(collationid))
+				nspname = NULL;
+			else
+				nspname = get_namespace_name(collationform->collnamespace);
+
+			result = quote_qualified_identifier(nspname, collationname);
+		}
+
+		ReleaseSysCache(collationtup);
+	}
+	else
+	{
+		/* If OID doesn't match any pg_collation entry, return it numerically */
+		result = (char *) palloc(NAMEDATALEN);
+		snprintf(result, NAMEDATALEN, "%u", collationid);
+	}
+
+	PG_RETURN_CSTRING(result);
+}
+
+/*
+ *		regcollationrecv			- converts external binary format to regcollation
+ */
+Datum
+regcollationrecv(PG_FUNCTION_ARGS)
+{
+	/* Exactly the same as oidrecv, so share code */
+	return oidrecv(fcinfo);
+}
+
+/*
+ *		regcollationsend			- converts regcollation to binary format
+ */
+Datum
+regcollationsend(PG_FUNCTION_ARGS)
+{
+	/* Exactly the same as oidsend, so share code */
+	return oidsend(fcinfo);
+}
+
+
 /*
  * regtypein		- converts "typename" to type OID
  *
diff --git a/src/include/catalog/pg_cast.dat b/src/include/catalog/pg_cast.dat
index 6ef8b8a4e7..01c5328ddd 100644
--- a/src/include/catalog/pg_cast.dat
+++ b/src/include/catalog/pg_cast.dat
@@ -189,6 +189,20 @@
   castcontext => 'a', castmethod => 'f' },
 { castsource => 'regclass', casttarget => 'int4', castfunc => '0',
   castcontext => 'a', castmethod => 'b' },
+{ castsource => 'oid', casttarget => 'regcollation', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'regcollation', casttarget => 'oid', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'int8', casttarget => 'regcollation', castfunc => 'oid',
+  castcontext => 'i', castmethod => 'f' },
+{ castsource => 'int2', casttarget => 'regcollation', castfunc => 'int4(int2)',
+  castcontext => 'i', castmethod => 'f' },
+{ castsource => 'int4', casttarget => 'regcollation', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'regcollation', casttarget => 'int8', castfunc => 'int8(oid)',
+  castcontext => 'a', castmethod => 'f' },
+{ castsource => 'regcollation', casttarget => 'int4', castfunc => '0',
+  castcontext => 'a', castmethod => 'b' },
 { castsource => 'oid', casttarget => 'regtype', castfunc => '0',
   castcontext => 'i', castmethod => 'b' },
 { castsource => 'regtype', casttarget => 'oid', castfunc => '0',
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 7fb574f9dc..c7c25e1eae 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -6666,6 +6666,15 @@
 { oid => '3495', descr => 'convert classname to regclass',
   proname => 'to_regclass', provolatile => 's', prorettype => 'regclass',
   proargtypes => 'text', prosrc => 'to_regclass' },
+{ oid => '9508', descr => 'I/O',
+  proname => 'regcollationin', provolatile => 's', prorettype => 'regcollation',
+  proargtypes => 'cstring', prosrc => 'regcollationin' },
+{ oid => '9509', descr => 'I/O',
+  proname => 'regcollationout', provolatile => 's', prorettype => 'cstring',
+  proargtypes => 'regcollation', prosrc => 'regcollationout' },
+{ oid => '9510', descr => 'convert classname to regcollation',
+  proname => 'to_regcollation', provolatile => 's', prorettype => 'regcollation',
+  proargtypes => 'text', prosrc => 'to_regcollation' },
 { oid => '2220', descr => 'I/O',
   proname => 'regtypein', provolatile => 's', prorettype => 'regtype',
   proargtypes => 'cstring', prosrc => 'regtypein' },
@@ -7446,6 +7455,12 @@
 { oid => '2453', descr => 'I/O',
   proname => 'regclasssend', prorettype => 'bytea', proargtypes => 'regclass',
   prosrc => 'regclasssend' },
+{ oid => '9511', descr => 'I/O',
+  proname => 'regcollationrecv', prorettype => 'regcollation',
+  proargtypes => 'internal', prosrc => 'regcollationrecv' },
+{ oid => '9512', descr => 'I/O',
+  proname => 'regcollationsend', prorettype => 'bytea', proargtypes => 'regcollation',
+  prosrc => 'regcollationsend' },
 { oid => '2454', descr => 'I/O',
   proname => 'regtyperecv', prorettype => 'regtype', proargtypes => 'internal',
   prosrc => 'regtyperecv' },
diff --git a/src/include/catalog/pg_type.dat b/src/include/catalog/pg_type.dat
index b00597d6ff..ad777e37c6 100644
--- a/src/include/catalog/pg_type.dat
+++ b/src/include/catalog/pg_type.dat
@@ -379,6 +379,10 @@
   typname => 'regclass', typlen => '4', typbyval => 't', typcategory => 'N',
   typinput => 'regclassin', typoutput => 'regclassout',
   typreceive => 'regclassrecv', typsend => 'regclasssend', typalign => 'i' },
+{ oid => '9506', array_type_oid => '9507', descr => 'registered collation',
+  typname => 'regcollation', typlen => '4', typbyval => 't', typcategory => 'N',
+  typinput => 'regcollationin', typoutput => 'regcollationout',
+  typreceive => 'regcollationrecv', typsend => 'regcollationsend', typalign => 'i' },
 { oid => '2206', array_type_oid => '2211', descr => 'registered type',
   typname => 'regtype', typlen => '4', typbyval => 't', typcategory => 'N',
   typinput => 'regtypein', typoutput => 'regtypeout',
-- 
2.20.1


--bp/iNruPH9dso1Pn
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
	filename="v15-0004-Track-collation-versions-for-indexes.patch"



^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* [PATCH 3/6] Implement type regcollation.
@ 2019-12-05 17:59  Julien Rouhaud <[email protected]>
  0 siblings, 0 replies; 10+ messages in thread

From: Julien Rouhaud @ 2019-12-05 17:59 UTC (permalink / raw)

This will be helpful for a following commit.

Author: Julien Rouhaud
Reviewed-by:
Discussion: https://postgr.es/m/CAEepm%3D0uEQCpfq_%2BLYFBdArCe4Ot98t1aR4eYiYTe%3DyavQygiQ%40mail.gmail.com
---
 src/backend/utils/adt/regproc.c | 152 ++++++++++++++++++++++++++++++++
 src/include/catalog/pg_cast.dat |  14 +++
 src/include/catalog/pg_proc.dat |  15 ++++
 src/include/catalog/pg_type.dat |   4 +
 4 files changed, 185 insertions(+)

diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index f0fa52bc27..da8cc0cf6b 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -24,6 +24,7 @@
 #include "access/htup_details.h"
 #include "catalog/namespace.h"
 #include "catalog/pg_class.h"
+#include "catalog/pg_collation.h"
 #include "catalog/pg_operator.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_ts_config.h"
@@ -1043,6 +1044,157 @@ regclasssend(PG_FUNCTION_ARGS)
 }
 
 
+/*
+ * regcollationin		- converts "collationname" to collation 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_collation entry.
+ */
+Datum
+regcollationin(PG_FUNCTION_ARGS)
+{
+	char	   *collation_name_or_oid = PG_GETARG_CSTRING(0);
+	Oid			result = InvalidOid;
+	List	   *names;
+
+	/* '-' ? */
+	if (strcmp(collation_name_or_oid, "-") == 0)
+		PG_RETURN_OID(InvalidOid);
+
+	/* Numeric OID? */
+	if (collation_name_or_oid[0] >= '0' &&
+		collation_name_or_oid[0] <= '9' &&
+		strspn(collation_name_or_oid, "0123456789") == strlen(collation_name_or_oid))
+	{
+		result = DatumGetObjectId(DirectFunctionCall1(oidin,
+													  CStringGetDatum(collation_name_or_oid)));
+		PG_RETURN_OID(result);
+	}
+
+	/* Else it's a name, possibly schema-qualified */
+
+	/* The rest of this wouldn't work in bootstrap mode */
+	if (IsBootstrapProcessingMode())
+		elog(ERROR, "regcollation values must be OIDs in bootstrap mode");
+
+	/*
+	 * Normal case: parse the name into components and see if it matches any
+	 * pg_collation entries in the current search path.
+	 */
+	names = stringToQualifiedNameList(collation_name_or_oid);
+
+	result = get_collation_oid(names, false);
+
+	PG_RETURN_OID(result);
+}
+
+/*
+ * to_regcollation		- converts "collationname" to collation OID
+ *
+ * If the name is not found, we return NULL.
+ */
+Datum
+to_regcollation(PG_FUNCTION_ARGS)
+{
+	char	   *collation_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
+	Oid			result;
+	List	   *names;
+
+	/*
+	 * Parse the name into components and see if it matches any pg_collation
+	 * entries in the current search path.
+	 */
+	names = stringToQualifiedNameList(collation_name);
+
+	/* We might not even have permissions on this relation; don't lock it. */
+	result = get_collation_oid(names, true);
+
+	if (OidIsValid(result))
+		PG_RETURN_OID(result);
+	else
+		PG_RETURN_NULL();
+}
+
+/*
+ * regcollationout		- converts collation OID to "collation_name"
+ */
+Datum
+regcollationout(PG_FUNCTION_ARGS)
+{
+	Oid			collationid = PG_GETARG_OID(0);
+	char	   *result;
+	HeapTuple	collationtup;
+
+	if (collationid == InvalidOid)
+	{
+		result = pstrdup("-");
+		PG_RETURN_CSTRING(result);
+	}
+
+	collationtup = SearchSysCache1(COLLOID, ObjectIdGetDatum(collationid));
+
+	if (HeapTupleIsValid(collationtup))
+	{
+		Form_pg_collation collationform = (Form_pg_collation) GETSTRUCT(collationtup);
+		char	   *collationname = NameStr(collationform->collname);
+
+		/*
+		 * In bootstrap mode, skip the fancy namespace stuff and just return
+		 * the collation name.  (This path is only needed for debugging output
+		 * anyway.)
+		 */
+		if (IsBootstrapProcessingMode())
+			result = pstrdup(collationname);
+		else
+		{
+			char	   *nspname;
+
+			/*
+			 * Would this collation be found by regcollationin? If not, qualify it.
+			 */
+			if (CollationIsVisible(collationid))
+				nspname = NULL;
+			else
+				nspname = get_namespace_name(collationform->collnamespace);
+
+			result = quote_qualified_identifier(nspname, collationname);
+		}
+
+		ReleaseSysCache(collationtup);
+	}
+	else
+	{
+		/* If OID doesn't match any pg_collation entry, return it numerically */
+		result = (char *) palloc(NAMEDATALEN);
+		snprintf(result, NAMEDATALEN, "%u", collationid);
+	}
+
+	PG_RETURN_CSTRING(result);
+}
+
+/*
+ *		regcollationrecv			- converts external binary format to regcollation
+ */
+Datum
+regcollationrecv(PG_FUNCTION_ARGS)
+{
+	/* Exactly the same as oidrecv, so share code */
+	return oidrecv(fcinfo);
+}
+
+/*
+ *		regcollationsend			- converts regcollation to binary format
+ */
+Datum
+regcollationsend(PG_FUNCTION_ARGS)
+{
+	/* Exactly the same as oidsend, so share code */
+	return oidsend(fcinfo);
+}
+
+
 /*
  * regtypein		- converts "typename" to type OID
  *
diff --git a/src/include/catalog/pg_cast.dat b/src/include/catalog/pg_cast.dat
index 6ef8b8a4e7..01c5328ddd 100644
--- a/src/include/catalog/pg_cast.dat
+++ b/src/include/catalog/pg_cast.dat
@@ -189,6 +189,20 @@
   castcontext => 'a', castmethod => 'f' },
 { castsource => 'regclass', casttarget => 'int4', castfunc => '0',
   castcontext => 'a', castmethod => 'b' },
+{ castsource => 'oid', casttarget => 'regcollation', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'regcollation', casttarget => 'oid', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'int8', casttarget => 'regcollation', castfunc => 'oid',
+  castcontext => 'i', castmethod => 'f' },
+{ castsource => 'int2', casttarget => 'regcollation', castfunc => 'int4(int2)',
+  castcontext => 'i', castmethod => 'f' },
+{ castsource => 'int4', casttarget => 'regcollation', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'regcollation', casttarget => 'int8', castfunc => 'int8(oid)',
+  castcontext => 'a', castmethod => 'f' },
+{ castsource => 'regcollation', casttarget => 'int4', castfunc => '0',
+  castcontext => 'a', castmethod => 'b' },
 { castsource => 'oid', casttarget => 'regtype', castfunc => '0',
   castcontext => 'i', castmethod => 'b' },
 { castsource => 'regtype', casttarget => 'oid', castfunc => '0',
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 226c904c04..f6503428cc 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -6663,6 +6663,15 @@
 { oid => '3495', descr => 'convert classname to regclass',
   proname => 'to_regclass', provolatile => 's', prorettype => 'regclass',
   proargtypes => 'text', prosrc => 'to_regclass' },
+{ oid => '9508', descr => 'I/O',
+  proname => 'regcollationin', provolatile => 's', prorettype => 'regcollation',
+  proargtypes => 'cstring', prosrc => 'regcollationin' },
+{ oid => '9509', descr => 'I/O',
+  proname => 'regcollationout', provolatile => 's', prorettype => 'cstring',
+  proargtypes => 'regcollation', prosrc => 'regcollationout' },
+{ oid => '9510', descr => 'convert classname to regcollation',
+  proname => 'to_regcollation', provolatile => 's', prorettype => 'regcollation',
+  proargtypes => 'text', prosrc => 'to_regcollation' },
 { oid => '2220', descr => 'I/O',
   proname => 'regtypein', provolatile => 's', prorettype => 'regtype',
   proargtypes => 'cstring', prosrc => 'regtypein' },
@@ -7449,6 +7458,12 @@
 { oid => '2453', descr => 'I/O',
   proname => 'regclasssend', prorettype => 'bytea', proargtypes => 'regclass',
   prosrc => 'regclasssend' },
+{ oid => '9511', descr => 'I/O',
+  proname => 'regcollationrecv', prorettype => 'regcollation',
+  proargtypes => 'internal', prosrc => 'regcollationrecv' },
+{ oid => '9512', descr => 'I/O',
+  proname => 'regcollationsend', prorettype => 'bytea', proargtypes => 'regcollation',
+  prosrc => 'regcollationsend' },
 { oid => '2454', descr => 'I/O',
   proname => 'regtyperecv', prorettype => 'regtype', proargtypes => 'internal',
   prosrc => 'regtyperecv' },
diff --git a/src/include/catalog/pg_type.dat b/src/include/catalog/pg_type.dat
index fe2c4eabb4..012c17bb68 100644
--- a/src/include/catalog/pg_type.dat
+++ b/src/include/catalog/pg_type.dat
@@ -379,6 +379,10 @@
   typname => 'regclass', typlen => '4', typbyval => 't', typcategory => 'N',
   typinput => 'regclassin', typoutput => 'regclassout',
   typreceive => 'regclassrecv', typsend => 'regclasssend', typalign => 'i' },
+{ oid => '9506', array_type_oid => '9507', descr => 'registered collation',
+  typname => 'regcollation', typlen => '4', typbyval => 't', typcategory => 'N',
+  typinput => 'regcollationin', typoutput => 'regcollationout',
+  typreceive => 'regcollationrecv', typsend => 'regcollationsend', typalign => 'i' },
 { oid => '2206', array_type_oid => '2211', descr => 'registered type',
   typname => 'regtype', typlen => '4', typbyval => 't', typcategory => 'N',
   typinput => 'regtypein', typoutput => 'regtypeout',
-- 
2.20.1


--6c2NcOVqGQ03X4Wi
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
	filename="0004-Track-collation-versions-for-indexes-v8.patch"



^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* [PATCH 3/6] Implement type regcollation.
@ 2019-12-05 17:59  Julien Rouhaud <[email protected]>
  0 siblings, 0 replies; 10+ messages in thread

From: Julien Rouhaud @ 2019-12-05 17:59 UTC (permalink / raw)

This will be helpful for a following commit.

Author: Julien Rouhaud
Reviewed-by:
Discussion: https://postgr.es/m/CAEepm%3D0uEQCpfq_%2BLYFBdArCe4Ot98t1aR4eYiYTe%3DyavQygiQ%40mail.gmail.com
---
 src/backend/utils/adt/regproc.c | 152 ++++++++++++++++++++++++++++++++
 src/include/catalog/pg_cast.dat |  14 +++
 src/include/catalog/pg_proc.dat |  15 ++++
 src/include/catalog/pg_type.dat |   4 +
 4 files changed, 185 insertions(+)

diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index f0fa52bc27..da8cc0cf6b 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -24,6 +24,7 @@
 #include "access/htup_details.h"
 #include "catalog/namespace.h"
 #include "catalog/pg_class.h"
+#include "catalog/pg_collation.h"
 #include "catalog/pg_operator.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_ts_config.h"
@@ -1043,6 +1044,157 @@ regclasssend(PG_FUNCTION_ARGS)
 }
 
 
+/*
+ * regcollationin		- converts "collationname" to collation 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_collation entry.
+ */
+Datum
+regcollationin(PG_FUNCTION_ARGS)
+{
+	char	   *collation_name_or_oid = PG_GETARG_CSTRING(0);
+	Oid			result = InvalidOid;
+	List	   *names;
+
+	/* '-' ? */
+	if (strcmp(collation_name_or_oid, "-") == 0)
+		PG_RETURN_OID(InvalidOid);
+
+	/* Numeric OID? */
+	if (collation_name_or_oid[0] >= '0' &&
+		collation_name_or_oid[0] <= '9' &&
+		strspn(collation_name_or_oid, "0123456789") == strlen(collation_name_or_oid))
+	{
+		result = DatumGetObjectId(DirectFunctionCall1(oidin,
+													  CStringGetDatum(collation_name_or_oid)));
+		PG_RETURN_OID(result);
+	}
+
+	/* Else it's a name, possibly schema-qualified */
+
+	/* The rest of this wouldn't work in bootstrap mode */
+	if (IsBootstrapProcessingMode())
+		elog(ERROR, "regcollation values must be OIDs in bootstrap mode");
+
+	/*
+	 * Normal case: parse the name into components and see if it matches any
+	 * pg_collation entries in the current search path.
+	 */
+	names = stringToQualifiedNameList(collation_name_or_oid);
+
+	result = get_collation_oid(names, false);
+
+	PG_RETURN_OID(result);
+}
+
+/*
+ * to_regcollation		- converts "collationname" to collation OID
+ *
+ * If the name is not found, we return NULL.
+ */
+Datum
+to_regcollation(PG_FUNCTION_ARGS)
+{
+	char	   *collation_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
+	Oid			result;
+	List	   *names;
+
+	/*
+	 * Parse the name into components and see if it matches any pg_collation
+	 * entries in the current search path.
+	 */
+	names = stringToQualifiedNameList(collation_name);
+
+	/* We might not even have permissions on this relation; don't lock it. */
+	result = get_collation_oid(names, true);
+
+	if (OidIsValid(result))
+		PG_RETURN_OID(result);
+	else
+		PG_RETURN_NULL();
+}
+
+/*
+ * regcollationout		- converts collation OID to "collation_name"
+ */
+Datum
+regcollationout(PG_FUNCTION_ARGS)
+{
+	Oid			collationid = PG_GETARG_OID(0);
+	char	   *result;
+	HeapTuple	collationtup;
+
+	if (collationid == InvalidOid)
+	{
+		result = pstrdup("-");
+		PG_RETURN_CSTRING(result);
+	}
+
+	collationtup = SearchSysCache1(COLLOID, ObjectIdGetDatum(collationid));
+
+	if (HeapTupleIsValid(collationtup))
+	{
+		Form_pg_collation collationform = (Form_pg_collation) GETSTRUCT(collationtup);
+		char	   *collationname = NameStr(collationform->collname);
+
+		/*
+		 * In bootstrap mode, skip the fancy namespace stuff and just return
+		 * the collation name.  (This path is only needed for debugging output
+		 * anyway.)
+		 */
+		if (IsBootstrapProcessingMode())
+			result = pstrdup(collationname);
+		else
+		{
+			char	   *nspname;
+
+			/*
+			 * Would this collation be found by regcollationin? If not, qualify it.
+			 */
+			if (CollationIsVisible(collationid))
+				nspname = NULL;
+			else
+				nspname = get_namespace_name(collationform->collnamespace);
+
+			result = quote_qualified_identifier(nspname, collationname);
+		}
+
+		ReleaseSysCache(collationtup);
+	}
+	else
+	{
+		/* If OID doesn't match any pg_collation entry, return it numerically */
+		result = (char *) palloc(NAMEDATALEN);
+		snprintf(result, NAMEDATALEN, "%u", collationid);
+	}
+
+	PG_RETURN_CSTRING(result);
+}
+
+/*
+ *		regcollationrecv			- converts external binary format to regcollation
+ */
+Datum
+regcollationrecv(PG_FUNCTION_ARGS)
+{
+	/* Exactly the same as oidrecv, so share code */
+	return oidrecv(fcinfo);
+}
+
+/*
+ *		regcollationsend			- converts regcollation to binary format
+ */
+Datum
+regcollationsend(PG_FUNCTION_ARGS)
+{
+	/* Exactly the same as oidsend, so share code */
+	return oidsend(fcinfo);
+}
+
+
 /*
  * regtypein		- converts "typename" to type OID
  *
diff --git a/src/include/catalog/pg_cast.dat b/src/include/catalog/pg_cast.dat
index 6ef8b8a4e7..01c5328ddd 100644
--- a/src/include/catalog/pg_cast.dat
+++ b/src/include/catalog/pg_cast.dat
@@ -189,6 +189,20 @@
   castcontext => 'a', castmethod => 'f' },
 { castsource => 'regclass', casttarget => 'int4', castfunc => '0',
   castcontext => 'a', castmethod => 'b' },
+{ castsource => 'oid', casttarget => 'regcollation', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'regcollation', casttarget => 'oid', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'int8', casttarget => 'regcollation', castfunc => 'oid',
+  castcontext => 'i', castmethod => 'f' },
+{ castsource => 'int2', casttarget => 'regcollation', castfunc => 'int4(int2)',
+  castcontext => 'i', castmethod => 'f' },
+{ castsource => 'int4', casttarget => 'regcollation', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'regcollation', casttarget => 'int8', castfunc => 'int8(oid)',
+  castcontext => 'a', castmethod => 'f' },
+{ castsource => 'regcollation', casttarget => 'int4', castfunc => '0',
+  castcontext => 'a', castmethod => 'b' },
 { castsource => 'oid', casttarget => 'regtype', castfunc => '0',
   castcontext => 'i', castmethod => 'b' },
 { castsource => 'regtype', casttarget => 'oid', castfunc => '0',
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 226c904c04..f6503428cc 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -6663,6 +6663,15 @@
 { oid => '3495', descr => 'convert classname to regclass',
   proname => 'to_regclass', provolatile => 's', prorettype => 'regclass',
   proargtypes => 'text', prosrc => 'to_regclass' },
+{ oid => '9508', descr => 'I/O',
+  proname => 'regcollationin', provolatile => 's', prorettype => 'regcollation',
+  proargtypes => 'cstring', prosrc => 'regcollationin' },
+{ oid => '9509', descr => 'I/O',
+  proname => 'regcollationout', provolatile => 's', prorettype => 'cstring',
+  proargtypes => 'regcollation', prosrc => 'regcollationout' },
+{ oid => '9510', descr => 'convert classname to regcollation',
+  proname => 'to_regcollation', provolatile => 's', prorettype => 'regcollation',
+  proargtypes => 'text', prosrc => 'to_regcollation' },
 { oid => '2220', descr => 'I/O',
   proname => 'regtypein', provolatile => 's', prorettype => 'regtype',
   proargtypes => 'cstring', prosrc => 'regtypein' },
@@ -7449,6 +7458,12 @@
 { oid => '2453', descr => 'I/O',
   proname => 'regclasssend', prorettype => 'bytea', proargtypes => 'regclass',
   prosrc => 'regclasssend' },
+{ oid => '9511', descr => 'I/O',
+  proname => 'regcollationrecv', prorettype => 'regcollation',
+  proargtypes => 'internal', prosrc => 'regcollationrecv' },
+{ oid => '9512', descr => 'I/O',
+  proname => 'regcollationsend', prorettype => 'bytea', proargtypes => 'regcollation',
+  prosrc => 'regcollationsend' },
 { oid => '2454', descr => 'I/O',
   proname => 'regtyperecv', prorettype => 'regtype', proargtypes => 'internal',
   prosrc => 'regtyperecv' },
diff --git a/src/include/catalog/pg_type.dat b/src/include/catalog/pg_type.dat
index fe2c4eabb4..012c17bb68 100644
--- a/src/include/catalog/pg_type.dat
+++ b/src/include/catalog/pg_type.dat
@@ -379,6 +379,10 @@
   typname => 'regclass', typlen => '4', typbyval => 't', typcategory => 'N',
   typinput => 'regclassin', typoutput => 'regclassout',
   typreceive => 'regclassrecv', typsend => 'regclasssend', typalign => 'i' },
+{ oid => '9506', array_type_oid => '9507', descr => 'registered collation',
+  typname => 'regcollation', typlen => '4', typbyval => 't', typcategory => 'N',
+  typinput => 'regcollationin', typoutput => 'regcollationout',
+  typreceive => 'regcollationrecv', typsend => 'regcollationsend', typalign => 'i' },
 { oid => '2206', array_type_oid => '2211', descr => 'registered type',
   typname => 'regtype', typlen => '4', typbyval => 't', typcategory => 'N',
   typinput => 'regtypein', typoutput => 'regtypeout',
-- 
2.20.1


--Q68bSM7Ycu6FN28Q
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
	filename="0004-Track-collation-versions-for-indexes-v9.patch"



^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* [PATCH v17 3/7] Implement type regcollation.
@ 2019-12-05 17:59  Julien Rouhaud <[email protected]>
  0 siblings, 0 replies; 10+ messages in thread

From: Julien Rouhaud @ 2019-12-05 17:59 UTC (permalink / raw)

This will be helpful for a following commit.

Author: Julien Rouhaud
Reviewed-by: Thomas Munro and Michael Paquier
Discussion: https://postgr.es/m/CAEepm%3D0uEQCpfq_%2BLYFBdArCe4Ot98t1aR4eYiYTe%3DyavQygiQ%40mail.gmail.com
---
 doc/src/sgml/datatype.sgml            |  14 +++
 doc/src/sgml/func.sgml                |  32 ++++--
 doc/src/sgml/ref/pgupgrade.sgml       |   1 +
 src/backend/utils/adt/regproc.c       | 153 ++++++++++++++++++++++++++
 src/include/catalog/pg_cast.dat       |  14 +++
 src/include/catalog/pg_proc.dat       |  15 +++
 src/include/catalog/pg_type.dat       |   4 +
 src/test/regress/expected/regproc.out |  40 +++++++
 src/test/regress/sql/regproc.sql      |   7 ++
 9 files changed, 269 insertions(+), 11 deletions(-)

diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index 157fe4e727..ffe497a63a 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -4476,6 +4476,10 @@ INSERT INTO mytable VALUES(-1);  -- fails
     <primary>regclass</primary>
    </indexterm>
 
+   <indexterm zone="datatype-oid">
+    <primary>regcollation</primary>
+   </indexterm>
+
    <indexterm zone="datatype-oid">
     <primary>regconfig</primary>
    </indexterm>
@@ -4496,6 +4500,10 @@ INSERT INTO mytable VALUES(-1);  -- fails
     <primary>regoperator</primary>
    </indexterm>
 
+   <indexterm zone="datatype-oid">
+    <primary>regtype</primary>
+   </indexterm>
+
    <indexterm zone="datatype-oid">
     <primary>regproc</primary>
    </indexterm>
@@ -4602,6 +4610,12 @@ SELECT * FROM pg_attribute
         <entry><literal>pg_type</literal></entry>
        </row>
 
+       <row>
+        <entry><type>regcollation</type></entry>
+        <entry><structname>pg_collation</structname></entry>
+        <entry>collation name</entry>
+        <entry><literal>"POSIX"</literal></entry>
+       </row>
 
        <row>
         <entry><type>regconfig</type></entry>
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 710b51ff7c..b84502295e 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -18177,6 +18177,10 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
     <primary>to_regclass</primary>
    </indexterm>
 
+   <indexterm>
+    <primary>to_regcollation</primary>
+   </indexterm>
+
    <indexterm>
     <primary>to_regnamespace</primary>
    </indexterm>
@@ -18389,6 +18393,11 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
        <entry><type>regclass</type></entry>
        <entry>get the OID of the named relation</entry>
       </row>
+      <row>
+       <entry><literal><function>to_regcollation(<parameter>coll_name</parameter>)</function></literal></entry>
+       <entry><type>regcollation</type></entry>
+       <entry>get the OID of the named collation</entry>
+      </row>
       <row>
        <entry><literal><function>to_regnamespace(<parameter>schema_name</parameter>)</function></literal></entry>
        <entry><type>regnamespace</type></entry>
@@ -18721,17 +18730,18 @@ SELECT collation for ('foo' COLLATE "de_DE");
 
   <para>
    The functions <function>to_regclass</function>,
-   <function>to_regnamespace</function>, <function>to_regoper</function>,
-   <function>to_regoperator</function>, <function>to_regrole</function>,
-   <function>to_regproc</function>, <function>to_regprocedure</function>, and
-   <function>to_regtype</function>, functions translate relation, schema,
-   operator, role, function, and type names (given as <type>text</type>) to
-   objects of the corresponding <type>reg*</type> type (see <xref
-   linkend="datatype-oid"/> about the types).  These functions differ from a
-   cast from text in that they don't accept a numeric OID, and that they
-   return null rather than throwing an error if the name is not found (or, for
-   <function>to_regproc</function> and <function>to_regoper</function>, if the
-   given name matches multiple objects).
+   <function>to_regcollation</function>, <function>to_regnamespace</function>,
+   <function>to_regoper</function>, <function>to_regoperator</function>,
+   <function>to_regrole</function>, <function>to_regproc</function>,
+   <function>to_regprocedure</function>, and <function>to_regtype</function>,
+   functions translate relation, collation, schema, operator, role, function,
+   and type names (given as <type>text</type>) to objects of the corresponding
+   <type>reg*</type> type (see <xref linkend="datatype-oid"/> about the types).
+   These functions differ from a cast from text in that they don't accept a
+   numeric OID, and that they return null rather than throwing an error if the
+   name is not found (or, for <function>to_regproc</function> and
+   <function>to_regoper</function>, if the given name matches multiple
+   objects).
   </para>
 
    <indexterm>
diff --git a/doc/src/sgml/ref/pgupgrade.sgml b/doc/src/sgml/ref/pgupgrade.sgml
index 9e4b2d69a4..5e396f41fb 100644
--- a/doc/src/sgml/ref/pgupgrade.sgml
+++ b/doc/src/sgml/ref/pgupgrade.sgml
@@ -775,6 +775,7 @@ psql --username=postgres --file=script.sql postgres
    containing table columns using these <type>reg*</type> OID-referencing system data types:
    <simplelist>
     <member><type>regconfig</type></member>
+    <member><type>regcollation</type></member>
     <member><type>regdictionary</type></member>
     <member><type>regnamespace</type></member>
     <member><type>regoper</type></member>
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index f0fa52bc27..c800d797ac 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -24,6 +24,7 @@
 #include "access/htup_details.h"
 #include "catalog/namespace.h"
 #include "catalog/pg_class.h"
+#include "catalog/pg_collation.h"
 #include "catalog/pg_operator.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_ts_config.h"
@@ -1043,6 +1044,158 @@ regclasssend(PG_FUNCTION_ARGS)
 }
 
 
+/*
+ * regcollationin		- converts "collationname" to collation 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_collation entry.
+ */
+Datum
+regcollationin(PG_FUNCTION_ARGS)
+{
+	char	   *collation_name_or_oid = PG_GETARG_CSTRING(0);
+	Oid			result = InvalidOid;
+	List	   *names;
+
+	/* '-' ? */
+	if (strcmp(collation_name_or_oid, "-") == 0)
+		PG_RETURN_OID(InvalidOid);
+
+	/* Numeric OID? */
+	if (collation_name_or_oid[0] >= '0' &&
+		collation_name_or_oid[0] <= '9' &&
+		strspn(collation_name_or_oid, "0123456789") == strlen(collation_name_or_oid))
+	{
+		result = DatumGetObjectId(DirectFunctionCall1(oidin,
+													  CStringGetDatum(collation_name_or_oid)));
+		PG_RETURN_OID(result);
+	}
+
+	/* Else it's a name, possibly schema-qualified */
+
+	/* The rest of this wouldn't work in bootstrap mode */
+	if (IsBootstrapProcessingMode())
+		elog(ERROR, "regcollation values must be OIDs in bootstrap mode");
+
+	/*
+	 * Normal case: parse the name into components and see if it matches any
+	 * pg_collation entries in the current search path.
+	 */
+	names = stringToQualifiedNameList(collation_name_or_oid);
+
+	result = get_collation_oid(names, false);
+
+	PG_RETURN_OID(result);
+}
+
+/*
+ * to_regcollation		- converts "collationname" to collation OID
+ *
+ * If the name is not found, we return NULL.
+ */
+Datum
+to_regcollation(PG_FUNCTION_ARGS)
+{
+	char	   *collation_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
+	Oid			result;
+	List	   *names;
+
+	/*
+	 * Parse the name into components and see if it matches any pg_collation
+	 * entries in the current search path.
+	 */
+	names = stringToQualifiedNameList(collation_name);
+
+	/* We might not even have permissions on this relation; don't lock it. */
+	result = get_collation_oid(names, true);
+
+	if (OidIsValid(result))
+		PG_RETURN_OID(result);
+	else
+		PG_RETURN_NULL();
+}
+
+/*
+ * regcollationout		- converts collation OID to "collation_name"
+ */
+Datum
+regcollationout(PG_FUNCTION_ARGS)
+{
+	Oid			collationid = PG_GETARG_OID(0);
+	char	   *result;
+	HeapTuple	collationtup;
+
+	if (collationid == InvalidOid)
+	{
+		result = pstrdup("-");
+		PG_RETURN_CSTRING(result);
+	}
+
+	collationtup = SearchSysCache1(COLLOID, ObjectIdGetDatum(collationid));
+
+	if (HeapTupleIsValid(collationtup))
+	{
+		Form_pg_collation collationform = (Form_pg_collation) GETSTRUCT(collationtup);
+		char	   *collationname = NameStr(collationform->collname);
+
+		/*
+		 * In bootstrap mode, skip the fancy namespace stuff and just return
+		 * the collation name.  (This path is only needed for debugging output
+		 * anyway.)
+		 */
+		if (IsBootstrapProcessingMode())
+			result = pstrdup(collationname);
+		else
+		{
+			char	   *nspname;
+
+			/*
+			 * Would this collation be found by regcollationin? If not,
+			 * qualify it.
+			 */
+			if (CollationIsVisible(collationid))
+				nspname = NULL;
+			else
+				nspname = get_namespace_name(collationform->collnamespace);
+
+			result = quote_qualified_identifier(nspname, collationname);
+		}
+
+		ReleaseSysCache(collationtup);
+	}
+	else
+	{
+		/* If OID doesn't match any pg_collation entry, return it numerically */
+		result = (char *) palloc(NAMEDATALEN);
+		snprintf(result, NAMEDATALEN, "%u", collationid);
+	}
+
+	PG_RETURN_CSTRING(result);
+}
+
+/*
+ *		regcollationrecv			- converts external binary format to regcollation
+ */
+Datum
+regcollationrecv(PG_FUNCTION_ARGS)
+{
+	/* Exactly the same as oidrecv, so share code */
+	return oidrecv(fcinfo);
+}
+
+/*
+ *		regcollationsend			- converts regcollation to binary format
+ */
+Datum
+regcollationsend(PG_FUNCTION_ARGS)
+{
+	/* Exactly the same as oidsend, so share code */
+	return oidsend(fcinfo);
+}
+
+
 /*
  * regtypein		- converts "typename" to type OID
  *
diff --git a/src/include/catalog/pg_cast.dat b/src/include/catalog/pg_cast.dat
index 6ef8b8a4e7..01c5328ddd 100644
--- a/src/include/catalog/pg_cast.dat
+++ b/src/include/catalog/pg_cast.dat
@@ -189,6 +189,20 @@
   castcontext => 'a', castmethod => 'f' },
 { castsource => 'regclass', casttarget => 'int4', castfunc => '0',
   castcontext => 'a', castmethod => 'b' },
+{ castsource => 'oid', casttarget => 'regcollation', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'regcollation', casttarget => 'oid', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'int8', casttarget => 'regcollation', castfunc => 'oid',
+  castcontext => 'i', castmethod => 'f' },
+{ castsource => 'int2', casttarget => 'regcollation', castfunc => 'int4(int2)',
+  castcontext => 'i', castmethod => 'f' },
+{ castsource => 'int4', casttarget => 'regcollation', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'regcollation', casttarget => 'int8', castfunc => 'int8(oid)',
+  castcontext => 'a', castmethod => 'f' },
+{ castsource => 'regcollation', casttarget => 'int4', castfunc => '0',
+  castcontext => 'a', castmethod => 'b' },
 { castsource => 'oid', casttarget => 'regtype', castfunc => '0',
   castcontext => 'i', castmethod => 'b' },
 { castsource => 'regtype', casttarget => 'oid', castfunc => '0',
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 7fb574f9dc..c7c25e1eae 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -6666,6 +6666,15 @@
 { oid => '3495', descr => 'convert classname to regclass',
   proname => 'to_regclass', provolatile => 's', prorettype => 'regclass',
   proargtypes => 'text', prosrc => 'to_regclass' },
+{ oid => '9508', descr => 'I/O',
+  proname => 'regcollationin', provolatile => 's', prorettype => 'regcollation',
+  proargtypes => 'cstring', prosrc => 'regcollationin' },
+{ oid => '9509', descr => 'I/O',
+  proname => 'regcollationout', provolatile => 's', prorettype => 'cstring',
+  proargtypes => 'regcollation', prosrc => 'regcollationout' },
+{ oid => '9510', descr => 'convert classname to regcollation',
+  proname => 'to_regcollation', provolatile => 's', prorettype => 'regcollation',
+  proargtypes => 'text', prosrc => 'to_regcollation' },
 { oid => '2220', descr => 'I/O',
   proname => 'regtypein', provolatile => 's', prorettype => 'regtype',
   proargtypes => 'cstring', prosrc => 'regtypein' },
@@ -7446,6 +7455,12 @@
 { oid => '2453', descr => 'I/O',
   proname => 'regclasssend', prorettype => 'bytea', proargtypes => 'regclass',
   prosrc => 'regclasssend' },
+{ oid => '9511', descr => 'I/O',
+  proname => 'regcollationrecv', prorettype => 'regcollation',
+  proargtypes => 'internal', prosrc => 'regcollationrecv' },
+{ oid => '9512', descr => 'I/O',
+  proname => 'regcollationsend', prorettype => 'bytea', proargtypes => 'regcollation',
+  prosrc => 'regcollationsend' },
 { oid => '2454', descr => 'I/O',
   proname => 'regtyperecv', prorettype => 'regtype', proargtypes => 'internal',
   prosrc => 'regtyperecv' },
diff --git a/src/include/catalog/pg_type.dat b/src/include/catalog/pg_type.dat
index b00597d6ff..ad777e37c6 100644
--- a/src/include/catalog/pg_type.dat
+++ b/src/include/catalog/pg_type.dat
@@ -379,6 +379,10 @@
   typname => 'regclass', typlen => '4', typbyval => 't', typcategory => 'N',
   typinput => 'regclassin', typoutput => 'regclassout',
   typreceive => 'regclassrecv', typsend => 'regclasssend', typalign => 'i' },
+{ oid => '9506', array_type_oid => '9507', descr => 'registered collation',
+  typname => 'regcollation', typlen => '4', typbyval => 't', typcategory => 'N',
+  typinput => 'regcollationin', typoutput => 'regcollationout',
+  typreceive => 'regcollationrecv', typsend => 'regcollationsend', typalign => 'i' },
 { oid => '2206', array_type_oid => '2211', descr => 'registered type',
   typname => 'regtype', typlen => '4', typbyval => 't', typcategory => 'N',
   typinput => 'regtypein', typoutput => 'regtypeout',
diff --git a/src/test/regress/expected/regproc.out b/src/test/regress/expected/regproc.out
index ee4fcda866..e45ff5483f 100644
--- a/src/test/regress/expected/regproc.out
+++ b/src/test/regress/expected/regproc.out
@@ -40,6 +40,12 @@ SELECT regtype('int4');
  integer
 (1 row)
 
+SELECT regcollation('"POSIX"');
+ regcollation 
+--------------
+ "POSIX"
+(1 row)
+
 SELECT to_regoper('||/');
  to_regoper 
 ------------
@@ -76,6 +82,12 @@ SELECT to_regtype('int4');
  integer
 (1 row)
 
+SELECT to_regcollation('"POSIX"');
+ to_regcollation 
+-----------------
+ "POSIX"
+(1 row)
+
 -- with schemaname
 SELECT regoper('pg_catalog.||/');
  regoper 
@@ -113,6 +125,12 @@ SELECT regtype('pg_catalog.int4');
  integer
 (1 row)
 
+SELECT regcollation('pg_catalog."POSIX"');
+ regcollation 
+--------------
+ "POSIX"
+(1 row)
+
 SELECT to_regoper('pg_catalog.||/');
  to_regoper 
 ------------
@@ -143,6 +161,12 @@ SELECT to_regtype('pg_catalog.int4');
  integer
 (1 row)
 
+SELECT to_regcollation('pg_catalog."POSIX"');
+ to_regcollation 
+-----------------
+ "POSIX"
+(1 row)
+
 -- schemaname not applicable
 SELECT regrole('regress_regrole_test');
        regrole        
@@ -244,6 +268,10 @@ SELECT regtype('ng_catalog.int4');
 ERROR:  schema "ng_catalog" does not exist
 LINE 1: SELECT regtype('ng_catalog.int4');
                        ^
+SELECT regcollation('ng_catalog."POSIX"');
+ERROR:  schema "ng_catalog" does not exist
+LINE 1: SELECT regcollation('ng_catalog."POSIX"');
+                            ^
 -- schemaname not applicable
 SELECT regrole('regress_regrole_test');
 ERROR:  role "regress_regrole_test" does not exist
@@ -315,6 +343,12 @@ SELECT to_regtype('int3');
  
 (1 row)
 
+SELECT to_regcollation('notacollation');
+ to_regcollation 
+-----------------
+ 
+(1 row)
+
 -- with schemaname
 SELECT to_regoper('ng_catalog.||/');
  to_regoper 
@@ -352,6 +386,12 @@ SELECT to_regtype('ng_catalog.int4');
  
 (1 row)
 
+SELECT to_regcollation('ng_catalog."POSIX"');
+ to_regcollation 
+-----------------
+ 
+(1 row)
+
 -- schemaname not applicable
 SELECT to_regrole('regress_regrole_test');
  to_regrole 
diff --git a/src/test/regress/sql/regproc.sql b/src/test/regress/sql/regproc.sql
index a60bc28901..faab0c15ce 100644
--- a/src/test/regress/sql/regproc.sql
+++ b/src/test/regress/sql/regproc.sql
@@ -14,6 +14,7 @@ SELECT regproc('now');
 SELECT regprocedure('abs(numeric)');
 SELECT regclass('pg_class');
 SELECT regtype('int4');
+SELECT regcollation('"POSIX"');
 
 SELECT to_regoper('||/');
 SELECT to_regoperator('+(int4,int4)');
@@ -21,6 +22,7 @@ SELECT to_regproc('now');
 SELECT to_regprocedure('abs(numeric)');
 SELECT to_regclass('pg_class');
 SELECT to_regtype('int4');
+SELECT to_regcollation('"POSIX"');
 
 -- with schemaname
 
@@ -30,12 +32,14 @@ SELECT regproc('pg_catalog.now');
 SELECT regprocedure('pg_catalog.abs(numeric)');
 SELECT regclass('pg_catalog.pg_class');
 SELECT regtype('pg_catalog.int4');
+SELECT regcollation('pg_catalog."POSIX"');
 
 SELECT to_regoper('pg_catalog.||/');
 SELECT to_regproc('pg_catalog.now');
 SELECT to_regprocedure('pg_catalog.abs(numeric)');
 SELECT to_regclass('pg_catalog.pg_class');
 SELECT to_regtype('pg_catalog.int4');
+SELECT to_regcollation('pg_catalog."POSIX"');
 
 -- schemaname not applicable
 
@@ -70,6 +74,7 @@ SELECT regproc('ng_catalog.now');
 SELECT regprocedure('ng_catalog.abs(numeric)');
 SELECT regclass('ng_catalog.pg_class');
 SELECT regtype('ng_catalog.int4');
+SELECT regcollation('ng_catalog."POSIX"');
 
 -- schemaname not applicable
 
@@ -92,6 +97,7 @@ SELECT to_regproc('know');
 SELECT to_regprocedure('absinthe(numeric)');
 SELECT to_regclass('pg_classes');
 SELECT to_regtype('int3');
+SELECT to_regcollation('notacollation');
 
 -- with schemaname
 
@@ -101,6 +107,7 @@ SELECT to_regproc('ng_catalog.now');
 SELECT to_regprocedure('ng_catalog.abs(numeric)');
 SELECT to_regclass('ng_catalog.pg_class');
 SELECT to_regtype('ng_catalog.int4');
+SELECT to_regcollation('ng_catalog."POSIX"');
 
 -- schemaname not applicable
 
-- 
2.20.1


--FCuugMFkClbJLl1L
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
	filename="v17-0004-Track-collation-versions-for-indexes.patch"



^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* [PATCH v16 3/7] Implement type regcollation.
@ 2019-12-05 17:59  Julien Rouhaud <[email protected]>
  0 siblings, 0 replies; 10+ messages in thread

From: Julien Rouhaud @ 2019-12-05 17:59 UTC (permalink / raw)

This will be helpful for a following commit.

Author: Julien Rouhaud
Reviewed-by: Thomas Munro and Michael Paquier
Discussion: https://postgr.es/m/CAEepm%3D0uEQCpfq_%2BLYFBdArCe4Ot98t1aR4eYiYTe%3DyavQygiQ%40mail.gmail.com
---
 doc/src/sgml/datatype.sgml            |  23 +++-
 doc/src/sgml/func.sgml                |  36 +++---
 doc/src/sgml/ref/pgupgrade.sgml       |   4 +-
 src/backend/utils/adt/regproc.c       | 152 ++++++++++++++++++++++++++
 src/include/catalog/pg_cast.dat       |  14 +++
 src/include/catalog/pg_proc.dat       |  15 +++
 src/include/catalog/pg_type.dat       |   4 +
 src/test/regress/expected/regproc.out |  40 +++++++
 src/test/regress/sql/regproc.sql      |   7 ++
 9 files changed, 274 insertions(+), 21 deletions(-)

diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index 410eaedcb7..86d16e7b13 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -4496,6 +4496,10 @@ INSERT INTO mytable VALUES(-1);  -- fails
     <primary>regtype</primary>
    </indexterm>
 
+   <indexterm zone="datatype-oid">
+    <primary>regcollation</primary>
+   </indexterm>
+
    <indexterm zone="datatype-oid">
     <primary>regconfig</primary>
    </indexterm>
@@ -4522,12 +4526,12 @@ INSERT INTO mytable VALUES(-1);  -- fails
     system tables.
 
     Type <type>oid</type> represents an object identifier.  There are also
-    several alias types for <type>oid</type>: <type>regproc</type>,
-    <type>regprocedure</type>, <type>regoper</type>, <type>regoperator</type>,
-    <type>regclass</type>, <type>regtype</type>, <type>regrole</type>,
-    <type>regnamespace</type>, <type>regconfig</type>, and
-    <type>regdictionary</type>.  <xref linkend="datatype-oid-table"/> shows an
-    overview.
+    several alias types for <type>oid</type>: <type>regcollation</type>,
+    <type>regproc</type>, <type>regprocedure</type>, <type>regoper</type>,
+    <type>regoperator</type>, <type>regclass</type>, <type>regtype</type>,
+    <type>regrole</type>, <type>regnamespace</type>, <type>regconfig</type>,
+    and <type>regdictionary</type>.  <xref linkend="datatype-oid-table"/> shows
+    an overview.
    </para>
 
    <para>
@@ -4591,6 +4595,13 @@ SELECT * FROM pg_attribute
         <entry><literal>564182</literal></entry>
        </row>
 
+       <row>
+        <entry><type>regcollation</type></entry>
+        <entry><structname>pg_collation</structname></entry>
+        <entry>collation name</entry>
+        <entry><literal>"POSIX"</literal></entry>
+       </row>
+
        <row>
         <entry><type>regproc</type></entry>
         <entry><structname>pg_proc</structname></entry>
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 64726779d8..fd1bba9959 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -18177,6 +18177,10 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
     <primary>to_regclass</primary>
    </indexterm>
 
+   <indexterm>
+    <primary>to_regcollation</primary>
+   </indexterm>
+
    <indexterm>
     <primary>to_regproc</primary>
    </indexterm>
@@ -18389,6 +18393,11 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
        <entry><type>regclass</type></entry>
        <entry>get the OID of the named relation</entry>
       </row>
+      <row>
+       <entry><literal><function>to_regcollation(<parameter>coll_name</parameter>)</function></literal></entry>
+       <entry><type>regcollation</type></entry>
+       <entry>get the OID of the named collation</entry>
+      </row>
       <row>
        <entry><literal><function>to_regproc(<parameter>func_name</parameter>)</function></literal></entry>
        <entry><type>regproc</type></entry>
@@ -18720,20 +18729,21 @@ SELECT collation for ('foo' COLLATE "de_DE");
   </para>
 
   <para>
-   The <function>to_regclass</function>, <function>to_regproc</function>,
-   <function>to_regprocedure</function>, <function>to_regoper</function>,
-   <function>to_regoperator</function>, <function>to_regtype</function>,
-   <function>to_regnamespace</function>, and <function>to_regrole</function>
-   functions translate relation, function, operator, type, schema, and role
-   names (given as <type>text</type>) to objects of
-   type <type>regclass</type>, <type>regproc</type>, <type>regprocedure</type>,
+   The <function>to_regclass</function>, <function>to_regcollation</function>,
+   <function>to_regproc</function>, <function>to_regprocedure</function>,
+   <function>to_regoper</function>, <function>to_regoperator</function>,
+   <function>to_regtype</function>, <function>to_regnamespace</function>, and
+   <function>to_regrole</function> functions translate relation, collation,
+   function, operator, type, schema, and role names (given as
+   <type>text</type>) to objects of type <type>regclass</type>,
+   <type>regcollation</type>, <type>regproc</type>, <type>regprocedure</type>,
    <type>regoper</type>, <type>regoperator</type>, <type>regtype</type>,
-   <type>regnamespace</type>, and <type>regrole</type>
-   respectively.  These functions differ from a cast from
-   text in that they don't accept a numeric OID, and that they return null
-   rather than throwing an error if the name is not found (or, for
-   <function>to_regproc</function> and <function>to_regoper</function>, if
-   the given name matches multiple objects).
+   <type>regnamespace</type>, and <type>regrole</type> respectively.  These
+   functions differ from a cast from text in that they don't accept a numeric
+   OID, and that they return null rather than throwing an error if the name is
+   not found (or, for <function>to_regproc</function> and
+   <function>to_regoper</function>, if the given name matches multiple
+   objects).
   </para>
 
    <indexterm>
diff --git a/doc/src/sgml/ref/pgupgrade.sgml b/doc/src/sgml/ref/pgupgrade.sgml
index 6629d736b8..8e229135c2 100644
--- a/doc/src/sgml/ref/pgupgrade.sgml
+++ b/doc/src/sgml/ref/pgupgrade.sgml
@@ -773,8 +773,8 @@ psql --username=postgres --file=script.sql postgres
   <para>
    <application>pg_upgrade</application> does not support upgrading of databases
    containing table columns using these <type>reg*</type> OID-referencing system data types:
-   <type>regproc</type>, <type>regprocedure</type>, <type>regoper</type>,
-   <type>regoperator</type>, <type>regconfig</type>, and
+   <type>regcollation</type>, <type>regproc</type>, <type>regprocedure</type>,
+   <type>regoper</type>, <type>regoperator</type>, <type>regconfig</type>, and
    <type>regdictionary</type>.  (<type>regtype</type> can be upgraded.)
   </para>
 
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index f0fa52bc27..da8cc0cf6b 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -24,6 +24,7 @@
 #include "access/htup_details.h"
 #include "catalog/namespace.h"
 #include "catalog/pg_class.h"
+#include "catalog/pg_collation.h"
 #include "catalog/pg_operator.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_ts_config.h"
@@ -1043,6 +1044,157 @@ regclasssend(PG_FUNCTION_ARGS)
 }
 
 
+/*
+ * regcollationin		- converts "collationname" to collation 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_collation entry.
+ */
+Datum
+regcollationin(PG_FUNCTION_ARGS)
+{
+	char	   *collation_name_or_oid = PG_GETARG_CSTRING(0);
+	Oid			result = InvalidOid;
+	List	   *names;
+
+	/* '-' ? */
+	if (strcmp(collation_name_or_oid, "-") == 0)
+		PG_RETURN_OID(InvalidOid);
+
+	/* Numeric OID? */
+	if (collation_name_or_oid[0] >= '0' &&
+		collation_name_or_oid[0] <= '9' &&
+		strspn(collation_name_or_oid, "0123456789") == strlen(collation_name_or_oid))
+	{
+		result = DatumGetObjectId(DirectFunctionCall1(oidin,
+													  CStringGetDatum(collation_name_or_oid)));
+		PG_RETURN_OID(result);
+	}
+
+	/* Else it's a name, possibly schema-qualified */
+
+	/* The rest of this wouldn't work in bootstrap mode */
+	if (IsBootstrapProcessingMode())
+		elog(ERROR, "regcollation values must be OIDs in bootstrap mode");
+
+	/*
+	 * Normal case: parse the name into components and see if it matches any
+	 * pg_collation entries in the current search path.
+	 */
+	names = stringToQualifiedNameList(collation_name_or_oid);
+
+	result = get_collation_oid(names, false);
+
+	PG_RETURN_OID(result);
+}
+
+/*
+ * to_regcollation		- converts "collationname" to collation OID
+ *
+ * If the name is not found, we return NULL.
+ */
+Datum
+to_regcollation(PG_FUNCTION_ARGS)
+{
+	char	   *collation_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
+	Oid			result;
+	List	   *names;
+
+	/*
+	 * Parse the name into components and see if it matches any pg_collation
+	 * entries in the current search path.
+	 */
+	names = stringToQualifiedNameList(collation_name);
+
+	/* We might not even have permissions on this relation; don't lock it. */
+	result = get_collation_oid(names, true);
+
+	if (OidIsValid(result))
+		PG_RETURN_OID(result);
+	else
+		PG_RETURN_NULL();
+}
+
+/*
+ * regcollationout		- converts collation OID to "collation_name"
+ */
+Datum
+regcollationout(PG_FUNCTION_ARGS)
+{
+	Oid			collationid = PG_GETARG_OID(0);
+	char	   *result;
+	HeapTuple	collationtup;
+
+	if (collationid == InvalidOid)
+	{
+		result = pstrdup("-");
+		PG_RETURN_CSTRING(result);
+	}
+
+	collationtup = SearchSysCache1(COLLOID, ObjectIdGetDatum(collationid));
+
+	if (HeapTupleIsValid(collationtup))
+	{
+		Form_pg_collation collationform = (Form_pg_collation) GETSTRUCT(collationtup);
+		char	   *collationname = NameStr(collationform->collname);
+
+		/*
+		 * In bootstrap mode, skip the fancy namespace stuff and just return
+		 * the collation name.  (This path is only needed for debugging output
+		 * anyway.)
+		 */
+		if (IsBootstrapProcessingMode())
+			result = pstrdup(collationname);
+		else
+		{
+			char	   *nspname;
+
+			/*
+			 * Would this collation be found by regcollationin? If not, qualify it.
+			 */
+			if (CollationIsVisible(collationid))
+				nspname = NULL;
+			else
+				nspname = get_namespace_name(collationform->collnamespace);
+
+			result = quote_qualified_identifier(nspname, collationname);
+		}
+
+		ReleaseSysCache(collationtup);
+	}
+	else
+	{
+		/* If OID doesn't match any pg_collation entry, return it numerically */
+		result = (char *) palloc(NAMEDATALEN);
+		snprintf(result, NAMEDATALEN, "%u", collationid);
+	}
+
+	PG_RETURN_CSTRING(result);
+}
+
+/*
+ *		regcollationrecv			- converts external binary format to regcollation
+ */
+Datum
+regcollationrecv(PG_FUNCTION_ARGS)
+{
+	/* Exactly the same as oidrecv, so share code */
+	return oidrecv(fcinfo);
+}
+
+/*
+ *		regcollationsend			- converts regcollation to binary format
+ */
+Datum
+regcollationsend(PG_FUNCTION_ARGS)
+{
+	/* Exactly the same as oidsend, so share code */
+	return oidsend(fcinfo);
+}
+
+
 /*
  * regtypein		- converts "typename" to type OID
  *
diff --git a/src/include/catalog/pg_cast.dat b/src/include/catalog/pg_cast.dat
index 6ef8b8a4e7..01c5328ddd 100644
--- a/src/include/catalog/pg_cast.dat
+++ b/src/include/catalog/pg_cast.dat
@@ -189,6 +189,20 @@
   castcontext => 'a', castmethod => 'f' },
 { castsource => 'regclass', casttarget => 'int4', castfunc => '0',
   castcontext => 'a', castmethod => 'b' },
+{ castsource => 'oid', casttarget => 'regcollation', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'regcollation', casttarget => 'oid', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'int8', casttarget => 'regcollation', castfunc => 'oid',
+  castcontext => 'i', castmethod => 'f' },
+{ castsource => 'int2', casttarget => 'regcollation', castfunc => 'int4(int2)',
+  castcontext => 'i', castmethod => 'f' },
+{ castsource => 'int4', casttarget => 'regcollation', castfunc => '0',
+  castcontext => 'i', castmethod => 'b' },
+{ castsource => 'regcollation', casttarget => 'int8', castfunc => 'int8(oid)',
+  castcontext => 'a', castmethod => 'f' },
+{ castsource => 'regcollation', casttarget => 'int4', castfunc => '0',
+  castcontext => 'a', castmethod => 'b' },
 { castsource => 'oid', casttarget => 'regtype', castfunc => '0',
   castcontext => 'i', castmethod => 'b' },
 { castsource => 'regtype', casttarget => 'oid', castfunc => '0',
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 7fb574f9dc..c7c25e1eae 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -6666,6 +6666,15 @@
 { oid => '3495', descr => 'convert classname to regclass',
   proname => 'to_regclass', provolatile => 's', prorettype => 'regclass',
   proargtypes => 'text', prosrc => 'to_regclass' },
+{ oid => '9508', descr => 'I/O',
+  proname => 'regcollationin', provolatile => 's', prorettype => 'regcollation',
+  proargtypes => 'cstring', prosrc => 'regcollationin' },
+{ oid => '9509', descr => 'I/O',
+  proname => 'regcollationout', provolatile => 's', prorettype => 'cstring',
+  proargtypes => 'regcollation', prosrc => 'regcollationout' },
+{ oid => '9510', descr => 'convert classname to regcollation',
+  proname => 'to_regcollation', provolatile => 's', prorettype => 'regcollation',
+  proargtypes => 'text', prosrc => 'to_regcollation' },
 { oid => '2220', descr => 'I/O',
   proname => 'regtypein', provolatile => 's', prorettype => 'regtype',
   proargtypes => 'cstring', prosrc => 'regtypein' },
@@ -7446,6 +7455,12 @@
 { oid => '2453', descr => 'I/O',
   proname => 'regclasssend', prorettype => 'bytea', proargtypes => 'regclass',
   prosrc => 'regclasssend' },
+{ oid => '9511', descr => 'I/O',
+  proname => 'regcollationrecv', prorettype => 'regcollation',
+  proargtypes => 'internal', prosrc => 'regcollationrecv' },
+{ oid => '9512', descr => 'I/O',
+  proname => 'regcollationsend', prorettype => 'bytea', proargtypes => 'regcollation',
+  prosrc => 'regcollationsend' },
 { oid => '2454', descr => 'I/O',
   proname => 'regtyperecv', prorettype => 'regtype', proargtypes => 'internal',
   prosrc => 'regtyperecv' },
diff --git a/src/include/catalog/pg_type.dat b/src/include/catalog/pg_type.dat
index b00597d6ff..ad777e37c6 100644
--- a/src/include/catalog/pg_type.dat
+++ b/src/include/catalog/pg_type.dat
@@ -379,6 +379,10 @@
   typname => 'regclass', typlen => '4', typbyval => 't', typcategory => 'N',
   typinput => 'regclassin', typoutput => 'regclassout',
   typreceive => 'regclassrecv', typsend => 'regclasssend', typalign => 'i' },
+{ oid => '9506', array_type_oid => '9507', descr => 'registered collation',
+  typname => 'regcollation', typlen => '4', typbyval => 't', typcategory => 'N',
+  typinput => 'regcollationin', typoutput => 'regcollationout',
+  typreceive => 'regcollationrecv', typsend => 'regcollationsend', typalign => 'i' },
 { oid => '2206', array_type_oid => '2211', descr => 'registered type',
   typname => 'regtype', typlen => '4', typbyval => 't', typcategory => 'N',
   typinput => 'regtypein', typoutput => 'regtypeout',
diff --git a/src/test/regress/expected/regproc.out b/src/test/regress/expected/regproc.out
index ee4fcda866..e45ff5483f 100644
--- a/src/test/regress/expected/regproc.out
+++ b/src/test/regress/expected/regproc.out
@@ -40,6 +40,12 @@ SELECT regtype('int4');
  integer
 (1 row)
 
+SELECT regcollation('"POSIX"');
+ regcollation 
+--------------
+ "POSIX"
+(1 row)
+
 SELECT to_regoper('||/');
  to_regoper 
 ------------
@@ -76,6 +82,12 @@ SELECT to_regtype('int4');
  integer
 (1 row)
 
+SELECT to_regcollation('"POSIX"');
+ to_regcollation 
+-----------------
+ "POSIX"
+(1 row)
+
 -- with schemaname
 SELECT regoper('pg_catalog.||/');
  regoper 
@@ -113,6 +125,12 @@ SELECT regtype('pg_catalog.int4');
  integer
 (1 row)
 
+SELECT regcollation('pg_catalog."POSIX"');
+ regcollation 
+--------------
+ "POSIX"
+(1 row)
+
 SELECT to_regoper('pg_catalog.||/');
  to_regoper 
 ------------
@@ -143,6 +161,12 @@ SELECT to_regtype('pg_catalog.int4');
  integer
 (1 row)
 
+SELECT to_regcollation('pg_catalog."POSIX"');
+ to_regcollation 
+-----------------
+ "POSIX"
+(1 row)
+
 -- schemaname not applicable
 SELECT regrole('regress_regrole_test');
        regrole        
@@ -244,6 +268,10 @@ SELECT regtype('ng_catalog.int4');
 ERROR:  schema "ng_catalog" does not exist
 LINE 1: SELECT regtype('ng_catalog.int4');
                        ^
+SELECT regcollation('ng_catalog."POSIX"');
+ERROR:  schema "ng_catalog" does not exist
+LINE 1: SELECT regcollation('ng_catalog."POSIX"');
+                            ^
 -- schemaname not applicable
 SELECT regrole('regress_regrole_test');
 ERROR:  role "regress_regrole_test" does not exist
@@ -315,6 +343,12 @@ SELECT to_regtype('int3');
  
 (1 row)
 
+SELECT to_regcollation('notacollation');
+ to_regcollation 
+-----------------
+ 
+(1 row)
+
 -- with schemaname
 SELECT to_regoper('ng_catalog.||/');
  to_regoper 
@@ -352,6 +386,12 @@ SELECT to_regtype('ng_catalog.int4');
  
 (1 row)
 
+SELECT to_regcollation('ng_catalog."POSIX"');
+ to_regcollation 
+-----------------
+ 
+(1 row)
+
 -- schemaname not applicable
 SELECT to_regrole('regress_regrole_test');
  to_regrole 
diff --git a/src/test/regress/sql/regproc.sql b/src/test/regress/sql/regproc.sql
index a60bc28901..faab0c15ce 100644
--- a/src/test/regress/sql/regproc.sql
+++ b/src/test/regress/sql/regproc.sql
@@ -14,6 +14,7 @@ SELECT regproc('now');
 SELECT regprocedure('abs(numeric)');
 SELECT regclass('pg_class');
 SELECT regtype('int4');
+SELECT regcollation('"POSIX"');
 
 SELECT to_regoper('||/');
 SELECT to_regoperator('+(int4,int4)');
@@ -21,6 +22,7 @@ SELECT to_regproc('now');
 SELECT to_regprocedure('abs(numeric)');
 SELECT to_regclass('pg_class');
 SELECT to_regtype('int4');
+SELECT to_regcollation('"POSIX"');
 
 -- with schemaname
 
@@ -30,12 +32,14 @@ SELECT regproc('pg_catalog.now');
 SELECT regprocedure('pg_catalog.abs(numeric)');
 SELECT regclass('pg_catalog.pg_class');
 SELECT regtype('pg_catalog.int4');
+SELECT regcollation('pg_catalog."POSIX"');
 
 SELECT to_regoper('pg_catalog.||/');
 SELECT to_regproc('pg_catalog.now');
 SELECT to_regprocedure('pg_catalog.abs(numeric)');
 SELECT to_regclass('pg_catalog.pg_class');
 SELECT to_regtype('pg_catalog.int4');
+SELECT to_regcollation('pg_catalog."POSIX"');
 
 -- schemaname not applicable
 
@@ -70,6 +74,7 @@ SELECT regproc('ng_catalog.now');
 SELECT regprocedure('ng_catalog.abs(numeric)');
 SELECT regclass('ng_catalog.pg_class');
 SELECT regtype('ng_catalog.int4');
+SELECT regcollation('ng_catalog."POSIX"');
 
 -- schemaname not applicable
 
@@ -92,6 +97,7 @@ SELECT to_regproc('know');
 SELECT to_regprocedure('absinthe(numeric)');
 SELECT to_regclass('pg_classes');
 SELECT to_regtype('int3');
+SELECT to_regcollation('notacollation');
 
 -- with schemaname
 
@@ -101,6 +107,7 @@ SELECT to_regproc('ng_catalog.now');
 SELECT to_regprocedure('ng_catalog.abs(numeric)');
 SELECT to_regclass('ng_catalog.pg_class');
 SELECT to_regtype('ng_catalog.int4');
+SELECT to_regcollation('ng_catalog."POSIX"');
 
 -- schemaname not applicable
 
-- 
2.20.1


--fUYQa+Pmc3FrFX/N
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
	filename="v16-0004-Track-collation-versions-for-indexes.patch"



^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* [PATCH v1 1/1] teach vacuumlo to handle domains over oid
@ 2026-05-14 03:05  Nathan Bossart <[email protected]>
  0 siblings, 0 replies; 10+ messages in thread

From: Nathan Bossart @ 2026-05-14 03:05 UTC (permalink / raw)

---
 contrib/vacuumlo/vacuumlo.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/contrib/vacuumlo/vacuumlo.c b/contrib/vacuumlo/vacuumlo.c
index 8102569466b..230f6958fc1 100644
--- a/contrib/vacuumlo/vacuumlo.c
+++ b/contrib/vacuumlo/vacuumlo.c
@@ -191,13 +191,25 @@ vacuumlo(const char *database, const struct _param *param)
 	 * delete...
 	 */
 	buf[0] = '\0';
+	if (PQserverVersion(conn) >= 140000)
+		strcat(buf, "WITH RECURSIVE cte AS "
+			   "(SELECT oid AS oid2, oid, typname, typbasetype FROM pg_type "
+			   "UNION ALL "
+			   "SELECT t2.oid2, t.oid, t.typname, t.typbasetype FROM pg_type t "
+			   "JOIN cte t2 ON t.oid = t2.typbasetype) ");
 	strcat(buf, "SELECT s.nspname, c.relname, a.attname ");
 	strcat(buf, "FROM pg_class c, pg_attribute a, pg_namespace s, pg_type t ");
+	if (PQserverVersion(conn) >= 140000)
+		strcat(buf, ", cte ");
 	strcat(buf, "WHERE a.attnum > 0 AND NOT a.attisdropped ");
 	strcat(buf, "      AND a.attrelid = c.oid ");
 	strcat(buf, "      AND a.atttypid = t.oid ");
 	strcat(buf, "      AND c.relnamespace = s.oid ");
-	strcat(buf, "      AND t.typname in ('oid', 'lo') ");
+	if (PQserverVersion(conn) >= 140000)
+		strcat(buf, "  AND t.oid = cte.oid2 "
+			   "       AND cte.typname = 'oid' ");
+	else
+		strcat(buf, "  AND t.typname in ('oid', 'lo') ");
 	strcat(buf, "      AND c.relkind in (" CppAsString2(RELKIND_RELATION) ", " CppAsString2(RELKIND_MATVIEW) ")");
 	strcat(buf, "      AND s.nspname !~ '^pg_'");
 	res = PQexec(conn, buf);
-- 
2.50.1 (Apple Git-155)


--K++Jp4URl2Oj0VAw--





^ permalink  raw  reply  [nested|flat] 10+ messages in thread


end of thread, other threads:[~2026-05-14 03:05 UTC | newest]

Thread overview: 10+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2019-12-05 17:59 [PATCH v17 3/7] Implement type regcollation. Julien Rouhaud <[email protected]>
2019-12-05 17:59 [PATCH 3/6] Implement type regcollation. Julien Rouhaud <[email protected]>
2019-12-05 17:59 [PATCH 3/6] Implement type regcollation. Julien Rouhaud <[email protected]>
2019-12-05 17:59 [PATCH 3/6] Implement type regcollation. Julien Rouhaud <[email protected]>
2019-12-05 17:59 [PATCH v16 3/7] Implement type regcollation. Julien Rouhaud <[email protected]>
2019-12-05 17:59 [PATCH v16 3/7] Implement type regcollation. Julien Rouhaud <[email protected]>
2019-12-05 17:59 [PATCH v14 3/7] Implement type regcollation. Julien Rouhaud <[email protected]>
2019-12-05 17:59 [PATCH v15 3/7] Implement type regcollation. Julien Rouhaud <[email protected]>
2019-12-05 17:59 [PATCH 3/6] Implement type regcollation. Julien Rouhaud <[email protected]>
2026-05-14 03:05 [PATCH v1 1/1] teach vacuumlo to handle domains over oid Nathan Bossart <[email protected]>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox