aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/common/scankey.c8
-rw-r--r--src/backend/bootstrap/bootstrap.c9
-rw-r--r--src/backend/catalog/genbki.pl8
-rw-r--r--src/backend/catalog/information_schema.sql6
-rw-r--r--src/backend/utils/cache/catcache.c13
-rw-r--r--src/include/catalog/catversion.h2
-rw-r--r--src/include/catalog/indexing.h6
-rw-r--r--src/test/regress/expected/opr_sanity.out21
-rw-r--r--src/test/regress/sql/opr_sanity.sql19
9 files changed, 60 insertions, 32 deletions
diff --git a/src/backend/access/common/scankey.c b/src/backend/access/common/scankey.c
index 781516c56a5..5be4fe85eb1 100644
--- a/src/backend/access/common/scankey.c
+++ b/src/backend/access/common/scankey.c
@@ -64,9 +64,9 @@ ScanKeyEntryInitialize(ScanKey entry,
* It cannot handle NULL arguments, unary operators, or nondefault operators,
* but we need none of those features for most hardwired lookups.
*
- * We set collation to DEFAULT_COLLATION_OID always. This is appropriate
- * for textual columns in system catalogs, and it will be ignored for
- * non-textual columns, so it's not worth trying to be more finicky.
+ * We set collation to C_COLLATION_OID always. This is the correct value
+ * for all collation-aware columns in system catalogs, and it will be ignored
+ * for other column types, so it's not worth trying to be more finicky.
*
* Note: CurrentMemoryContext at call should be as long-lived as the ScanKey
* itself, because that's what will be used for any subsidiary info attached
@@ -83,7 +83,7 @@ ScanKeyInit(ScanKey entry,
entry->sk_attno = attributeNumber;
entry->sk_strategy = strategy;
entry->sk_subtype = InvalidOid;
- entry->sk_collation = DEFAULT_COLLATION_OID;
+ entry->sk_collation = C_COLLATION_OID;
entry->sk_argument = argument;
fmgr_info(procedure, &entry->sk_func);
}
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index 7caab64ce78..8e42255e82f 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -744,6 +744,15 @@ DefineAttr(char *name, char *type, int attnum, int nullness)
attrtypes[attnum]->attndims = 0;
}
+ /*
+ * If a system catalog column is collation-aware, force it to use C
+ * collation, so that its behavior is independent of the database's
+ * collation. This is essential to allow template0 to be cloned with a
+ * different database collation.
+ */
+ if (OidIsValid(attrtypes[attnum]->attcollation))
+ attrtypes[attnum]->attcollation = C_COLLATION_OID;
+
attrtypes[attnum]->attstattarget = -1;
attrtypes[attnum]->attcacheoff = -1;
attrtypes[attnum]->atttypmod = -1;
diff --git a/src/backend/catalog/genbki.pl b/src/backend/catalog/genbki.pl
index 8e2a2480be6..115e4c61bf0 100644
--- a/src/backend/catalog/genbki.pl
+++ b/src/backend/catalog/genbki.pl
@@ -167,6 +167,9 @@ my $GenbkiNextOid = $FirstGenbkiObjectId;
my $BOOTSTRAP_SUPERUSERID =
Catalog::FindDefinedSymbolFromData($catalog_data{pg_authid},
'BOOTSTRAP_SUPERUSERID');
+my $C_COLLATION_OID =
+ Catalog::FindDefinedSymbolFromData($catalog_data{pg_collation},
+ 'C_COLLATION_OID');
my $PG_CATALOG_NAMESPACE =
Catalog::FindDefinedSymbolFromData($catalog_data{pg_namespace},
'PG_CATALOG_NAMESPACE');
@@ -693,7 +696,10 @@ sub morph_row_for_pgattr
# set attndims if it's an array type
$row->{attndims} = $type->{typcategory} eq 'A' ? '1' : '0';
- $row->{attcollation} = $type->{typcollation};
+
+ # collation-aware catalog columns must use C collation
+ $row->{attcollation} = $type->{typcollation} != 0 ?
+ $C_COLLATION_OID : 0;
if (defined $attr->{forcenotnull})
{
diff --git a/src/backend/catalog/information_schema.sql b/src/backend/catalog/information_schema.sql
index 6227a8f3d0d..0fbcfa8bf13 100644
--- a/src/backend/catalog/information_schema.sql
+++ b/src/backend/catalog/information_schema.sql
@@ -208,7 +208,7 @@ CREATE DOMAIN cardinal_number AS integer
* CHARACTER_DATA domain
*/
-CREATE DOMAIN character_data AS character varying;
+CREATE DOMAIN character_data AS character varying COLLATE "C";
/*
@@ -216,7 +216,7 @@ CREATE DOMAIN character_data AS character varying;
* SQL_IDENTIFIER domain
*/
-CREATE DOMAIN sql_identifier AS character varying;
+CREATE DOMAIN sql_identifier AS character varying COLLATE "C";
/*
@@ -243,7 +243,7 @@ CREATE DOMAIN time_stamp AS timestamp(2) with time zone
* YES_OR_NO domain
*/
-CREATE DOMAIN yes_or_no AS character varying(3)
+CREATE DOMAIN yes_or_no AS character varying(3) COLLATE "C"
CONSTRAINT yes_or_no_check CHECK (value IN ('YES', 'NO'));
diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index b31fd5acea7..4176ced9237 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -22,6 +22,7 @@
#include "access/tuptoaster.h"
#include "access/valid.h"
#include "access/xact.h"
+#include "catalog/pg_collation.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_type.h"
#include "miscadmin.h"
@@ -1014,8 +1015,8 @@ CatalogCacheInitializeCache(CatCache *cache)
/* Fill in sk_strategy as well --- always standard equality */
cache->cc_skey[i].sk_strategy = BTEqualStrategyNumber;
cache->cc_skey[i].sk_subtype = InvalidOid;
- /* Currently, there are no catcaches on collation-aware data types */
- cache->cc_skey[i].sk_collation = InvalidOid;
+ /* If a catcache key requires a collation, it must be C collation */
+ cache->cc_skey[i].sk_collation = C_COLLATION_OID;
CACHE4_elog(DEBUG2, "CatalogCacheInitializeCache %s %d %p",
cache->cc_relname,
@@ -1961,10 +1962,10 @@ CatCacheCopyKeys(TupleDesc tupdesc, int nkeys, int *attnos,
NameData srcname;
/*
- * Must be careful in case the caller passed a C string where a
- * NAME is wanted: convert the given argument to a correctly
- * padded NAME. Otherwise the memcpy() done by datumCopy() could
- * fall off the end of memory.
+ * Must be careful in case the caller passed a C string where a NAME
+ * is wanted: convert the given argument to a correctly padded NAME.
+ * Otherwise the memcpy() done by datumCopy() could fall off the end
+ * of memory.
*/
if (att->atttypid == NAMEOID)
{
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 3e38f2d9113..aa27471437a 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 201812181
+#define CATALOG_VERSION_NO 201812182
#endif
diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h
index 2359b4c6291..f0c52d945a7 100644
--- a/src/include/catalog/indexing.h
+++ b/src/include/catalog/indexing.h
@@ -310,10 +310,10 @@ DECLARE_UNIQUE_INDEX(pg_default_acl_oid_index, 828, on pg_default_acl using btre
DECLARE_UNIQUE_INDEX(pg_db_role_setting_databaseid_rol_index, 2965, on pg_db_role_setting using btree(setdatabase oid_ops, setrole oid_ops));
#define DbRoleSettingDatidRolidIndexId 2965
-DECLARE_UNIQUE_INDEX(pg_seclabel_object_index, 3597, on pg_seclabel using btree(objoid oid_ops, classoid oid_ops, objsubid int4_ops, provider text_pattern_ops));
+DECLARE_UNIQUE_INDEX(pg_seclabel_object_index, 3597, on pg_seclabel using btree(objoid oid_ops, classoid oid_ops, objsubid int4_ops, provider text_ops));
#define SecLabelObjectIndexId 3597
-DECLARE_UNIQUE_INDEX(pg_shseclabel_object_index, 3593, on pg_shseclabel using btree(objoid oid_ops, classoid oid_ops, provider text_pattern_ops));
+DECLARE_UNIQUE_INDEX(pg_shseclabel_object_index, 3593, on pg_shseclabel using btree(objoid oid_ops, classoid oid_ops, provider text_ops));
#define SharedSecLabelObjectIndexId 3593
DECLARE_UNIQUE_INDEX(pg_extension_oid_index, 3080, on pg_extension using btree(oid oid_ops));
@@ -333,7 +333,7 @@ DECLARE_UNIQUE_INDEX(pg_policy_polrelid_polname_index, 3258, on pg_policy using
DECLARE_UNIQUE_INDEX(pg_replication_origin_roiident_index, 6001, on pg_replication_origin using btree(roident oid_ops));
#define ReplicationOriginIdentIndex 6001
-DECLARE_UNIQUE_INDEX(pg_replication_origin_roname_index, 6002, on pg_replication_origin using btree(roname text_pattern_ops));
+DECLARE_UNIQUE_INDEX(pg_replication_origin_roname_index, 6002, on pg_replication_origin using btree(roname text_ops));
#define ReplicationOriginNameIndex 6002
DECLARE_UNIQUE_INDEX(pg_partitioned_table_partrelid_index, 3351, on pg_partitioned_table using btree(partrelid oid_ops));
diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out
index 6072f6bdb1f..6dca1b7bf34 100644
--- a/src/test/regress/expected/opr_sanity.out
+++ b/src/test/regress/expected/opr_sanity.out
@@ -2060,18 +2060,25 @@ ORDER BY 1;
-- a representational error in pg_index, but simply wrong catalog design.
-- It's bad because we expect to be able to clone template0 and assign the
-- copy a different database collation. It would especially not work for
--- shared catalogs. Note that although text columns will show a collation
--- in indcollation, they're still okay to index with text_pattern_ops,
--- so allow that case.
+-- shared catalogs.
+SELECT relname, attname, attcollation
+FROM pg_class c, pg_attribute a
+WHERE c.oid = attrelid AND c.oid < 16384 AND
+ c.relkind != 'v' AND -- we don't care about columns in views
+ attcollation != 0 AND
+ attcollation != (SELECT oid FROM pg_collation WHERE collname = 'C');
+ relname | attname | attcollation
+---------+---------+--------------
+(0 rows)
+
+-- Double-check that collation-sensitive indexes have "C" collation, too.
SELECT indexrelid::regclass, indrelid::regclass, iclass, icoll
FROM (SELECT indexrelid, indrelid,
unnest(indclass) as iclass, unnest(indcollation) as icoll
FROM pg_index
WHERE indrelid < 16384) ss
-WHERE icoll != 0 AND iclass !=
- (SELECT oid FROM pg_opclass
- WHERE opcname = 'text_pattern_ops' AND opcmethod =
- (SELECT oid FROM pg_am WHERE amname = 'btree'));
+WHERE icoll != 0 AND
+ icoll != (SELECT oid FROM pg_collation WHERE collname = 'C');
indexrelid | indrelid | iclass | icoll
------------+----------+--------+-------
(0 rows)
diff --git a/src/test/regress/sql/opr_sanity.sql b/src/test/regress/sql/opr_sanity.sql
index 91c68f4204e..64eca7e9153 100644
--- a/src/test/regress/sql/opr_sanity.sql
+++ b/src/test/regress/sql/opr_sanity.sql
@@ -1333,16 +1333,21 @@ ORDER BY 1;
-- a representational error in pg_index, but simply wrong catalog design.
-- It's bad because we expect to be able to clone template0 and assign the
-- copy a different database collation. It would especially not work for
--- shared catalogs. Note that although text columns will show a collation
--- in indcollation, they're still okay to index with text_pattern_ops,
--- so allow that case.
+-- shared catalogs.
+
+SELECT relname, attname, attcollation
+FROM pg_class c, pg_attribute a
+WHERE c.oid = attrelid AND c.oid < 16384 AND
+ c.relkind != 'v' AND -- we don't care about columns in views
+ attcollation != 0 AND
+ attcollation != (SELECT oid FROM pg_collation WHERE collname = 'C');
+
+-- Double-check that collation-sensitive indexes have "C" collation, too.
SELECT indexrelid::regclass, indrelid::regclass, iclass, icoll
FROM (SELECT indexrelid, indrelid,
unnest(indclass) as iclass, unnest(indcollation) as icoll
FROM pg_index
WHERE indrelid < 16384) ss
-WHERE icoll != 0 AND iclass !=
- (SELECT oid FROM pg_opclass
- WHERE opcname = 'text_pattern_ops' AND opcmethod =
- (SELECT oid FROM pg_am WHERE amname = 'btree'));
+WHERE icoll != 0 AND
+ icoll != (SELECT oid FROM pg_collation WHERE collname = 'C');