diff --git a/pkg/sql/logictest/testdata/logic_test/collatedstring b/pkg/sql/logictest/testdata/logic_test/collatedstring index 6ea77c8ae63b..b10d56b50691 100644 --- a/pkg/sql/logictest/testdata/logic_test/collatedstring +++ b/pkg/sql/logictest/testdata/logic_test/collatedstring @@ -402,3 +402,28 @@ SELECT id, a, length(a), b, length(b::string) FROM t50015 ORDER BY id ASC 1 hello 5 hello 5 2 hello 5 hello 5 3 hello hello 11 hello hello 11 + +statement ok +CREATE TABLE t54989( + no_collation_str text, + no_collation_str_array text[], + collated_str text COLLATE en, + default_collation text COLLATE "default" +) + +query TT +SELECT + a.attname AS column_name, + collname AS collation +FROM pg_attribute a +LEFT JOIN pg_collation co ON a.attcollation = co.oid +JOIN pg_class c ON a.attrelid = c.oid +JOIN pg_namespace n ON c.relnamespace = n.oid +WHERE c.relname = 't54989' +ORDER BY column_name +---- +collated_str en +default_collation default +no_collation_str default +no_collation_str_array default +rowid NULL diff --git a/pkg/sql/logictest/testdata/logic_test/pg_catalog b/pkg/sql/logictest/testdata/logic_test/pg_catalog index c6be1646bab9..31497765a41b 100644 --- a/pkg/sql/logictest/testdata/logic_test/pg_catalog +++ b/pkg/sql/logictest/testdata/logic_test/pg_catalog @@ -595,12 +595,12 @@ JOIN pg_catalog.pg_namespace n ON c.relnamespace = n.oid WHERE n.nspname = 'public' ---- relname attname typname attcollation collname -t1 d varchar 3903121477 en-US -t1 h _bpchar 3903121477 en-US -t1 i _varchar 3903121477 en-US -t1 j char 3903121477 en-US +t1 d varchar 3403232968 default +t1 h _bpchar 3403232968 default +t1 i _varchar 3403232968 default +t1 j char 3403232968 default +t3 c text 3403232968 default t1 k varchar 999873346 sv -t3 c text 3903121477 en-US ## pg_catalog.pg_am @@ -701,11 +701,11 @@ ORDER BY indexrelid indexrelid indrelid indnatts indisunique indisprimary indisexclusion indimmediate indisclustered indisvalid indcheckxmin indisready indislive indisreplident indkey indcollation indclass indoption indexprs indpred 144368028 32 1 true true false true false true false false true false 1 0 0 2 NULL NULL 404104299 39 1 true true false true false true false false true false 1 0 0 2 NULL NULL -543291288 23 1 false false false false false true false false true false 1 3903121477 0 2 NULL NULL -543291289 23 1 false false false false false true false false true false 2 3903121477 0 2 NULL NULL -543291291 23 2 true true false true false true false false true false 1 2 3903121477 3903121477 0 0 2 2 NULL NULL -803027558 26 3 true true false true false true false false true false 1 2 3 0 0 3903121477 0 0 0 2 2 2 NULL NULL -1062763829 25 4 true true false true false true false false true false 1 2 3 4 0 0 3903121477 3903121477 0 0 0 0 2 2 2 2 NULL NULL +543291288 23 1 false false false false false true false false true false 1 3403232968 0 2 NULL NULL +543291289 23 1 false false false false false true false false true false 2 3403232968 0 2 NULL NULL +543291291 23 2 true true false true false true false false true false 1 2 3403232968 3403232968 0 0 2 2 NULL NULL +803027558 26 3 true true false true false true false false true false 1 2 3 0 0 3403232968 0 0 0 2 2 2 NULL NULL +1062763829 25 4 true true false true false true false false true false 1 2 3 4 0 0 3403232968 3403232968 0 0 0 0 2 2 2 2 NULL NULL 1276104432 12 2 true true false true false true false false true false 1 6 0 0 0 0 2 2 NULL NULL 1322500096 28 1 true true false true false true false false true false 1 0 0 2 NULL NULL 1489445036 35 2 false false false false false true false false true false 2 1 0 0 0 0 2 2 NULL NULL @@ -714,27 +714,27 @@ indexrelid indrelid indnatts indisunique indisprimary indisexclusion indim 1628632028 19 1 false false false false false true false false true false 5 0 0 2 NULL NULL 1628632029 19 1 false false false false false true false false true false 4 0 0 2 NULL NULL 1628632031 19 1 true true false true false true false false true false 1 0 0 2 NULL NULL -1841972634 6 1 true true false true false true false false true false 1 3903121477 0 2 NULL NULL +1841972634 6 1 true true false true false true false false true false 1 3403232968 0 2 NULL NULL 2008917577 37 1 true true false true false true false false true false 1 0 0 2 NULL NULL 2008917578 37 1 false false false false false true false false true false 5 0 0 2 NULL NULL 2101708905 5 1 true true false true false true false false true false 1 0 0 2 NULL NULL -2148104569 21 2 true true false true false true false false true false 1 2 3903121477 3903121477 0 0 2 2 NULL NULL +2148104569 21 2 true true false true false true false false true false 1 2 3403232968 3403232968 0 0 2 2 NULL NULL 2361445172 8 1 true true false true false true false false true false 1 0 0 2 NULL NULL 2407840836 24 3 true true false true false true false false true false 1 2 3 0 0 0 0 0 0 2 2 2 NULL NULL -2621181440 15 2 false false false false false true false false true false 2 3 3903121477 0 0 0 2 2 NULL NULL -2621181441 15 2 false false false false false true false false true false 6 7 3903121477 0 0 0 2 2 NULL NULL +2621181440 15 2 false false false false false true false false true false 2 3 3403232968 0 0 0 2 2 NULL NULL +2621181441 15 2 false false false false false true false false true false 6 7 3403232968 0 0 0 2 2 NULL NULL 2621181443 15 1 true true false true false true false false true false 1 0 0 2 NULL NULL 2667577107 31 1 true true false true false true false false true false 1 0 0 2 NULL NULL 2834522046 34 1 true true false true false true false false true false 1 0 0 2 NULL NULL -2927313374 2 2 true true false true false true false false true false 1 2 0 3903121477 0 0 2 2 NULL NULL -3094258317 33 2 true true false true false true false false true false 1 2 3903121477 3903121477 0 0 2 2 NULL NULL +2927313374 2 2 true true false true false true false false true false 1 2 0 3403232968 0 0 2 2 NULL NULL +3094258317 33 2 true true false true false true false false true false 1 2 3403232968 3403232968 0 0 2 2 NULL NULL 3353994584 36 1 true true false true false true false false true false 1 0 0 2 NULL NULL -3446785912 4 1 true true false true false true false false true false 1 3903121477 0 2 NULL NULL +3446785912 4 1 true true false true false true false false true false 1 3403232968 0 2 NULL NULL 3493181576 20 2 true true false true false true false false true false 1 2 0 0 0 0 2 2 NULL NULL 3706522183 11 4 true true false true false true false false true false 1 2 4 3 0 0 0 0 0 0 0 0 2 2 2 2 NULL NULL 3752917847 27 2 true true false true false true false false true false 1 2 0 0 0 0 2 2 NULL NULL -3966258450 14 1 true true false true false true false false true false 1 3903121477 0 2 NULL NULL -4012654114 30 3 true true false true false true false false true false 1 2 3 0 0 3903121477 0 0 0 2 2 2 NULL NULL +3966258450 14 1 true true false true false true false false true false 1 3403232968 0 2 NULL NULL +4012654114 30 3 true true false true false true false false true false 1 2 3 0 0 3403232968 0 0 0 2 2 2 NULL NULL 4225994721 13 2 true true false true false true false false true false 1 7 0 0 0 0 2 2 NULL NULL # From #26504 @@ -1358,14 +1358,14 @@ ORDER BY oid oid typname typndims typcollation typdefaultbin typdefault typacl 16 bool 0 0 NULL NULL NULL 17 bytea 0 0 NULL NULL NULL -18 char 0 3903121477 NULL NULL NULL -19 name 0 3903121477 NULL NULL NULL +18 char 0 3403232968 NULL NULL NULL +19 name 0 3403232968 NULL NULL NULL 20 int8 0 0 NULL NULL NULL 21 int2 0 0 NULL NULL NULL 22 int2vector 0 0 NULL NULL NULL 23 int4 0 0 NULL NULL NULL 24 regproc 0 0 NULL NULL NULL -25 text 0 3903121477 NULL NULL NULL +25 text 0 3403232968 NULL NULL NULL 26 oid 0 0 NULL NULL NULL 30 oidvector 0 0 NULL NULL NULL 700 float4 0 0 NULL NULL NULL @@ -1374,23 +1374,23 @@ oid typname typndims typcollation typdefaultbin typdefault typacl 869 inet 0 0 NULL NULL NULL 1000 _bool 0 0 NULL NULL NULL 1001 _bytea 0 0 NULL NULL NULL -1002 _char 0 3903121477 NULL NULL NULL -1003 _name 0 3903121477 NULL NULL NULL +1002 _char 0 3403232968 NULL NULL NULL +1003 _name 0 3403232968 NULL NULL NULL 1005 _int2 0 0 NULL NULL NULL 1006 _int2vector 0 0 NULL NULL NULL 1007 _int4 0 0 NULL NULL NULL 1008 _regproc 0 0 NULL NULL NULL -1009 _text 0 3903121477 NULL NULL NULL +1009 _text 0 3403232968 NULL NULL NULL 1013 _oidvector 0 0 NULL NULL NULL -1014 _bpchar 0 3903121477 NULL NULL NULL -1015 _varchar 0 3903121477 NULL NULL NULL +1014 _bpchar 0 3403232968 NULL NULL NULL +1015 _varchar 0 3403232968 NULL NULL NULL 1016 _int8 0 0 NULL NULL NULL 1021 _float4 0 0 NULL NULL NULL 1022 _float8 0 0 NULL NULL NULL 1028 _oid 0 0 NULL NULL NULL 1041 _inet 0 0 NULL NULL NULL -1042 bpchar 0 3903121477 NULL NULL NULL -1043 varchar 0 3903121477 NULL NULL NULL +1042 bpchar 0 3403232968 NULL NULL NULL +1043 varchar 0 3403232968 NULL NULL NULL 1082 date 0 0 NULL NULL NULL 1083 time 0 0 NULL NULL NULL 1114 timestamp 0 0 NULL NULL NULL @@ -1416,7 +1416,7 @@ oid typname typndims typcollation typdefaultbin typdefault typacl 2210 _regclass 0 0 NULL NULL NULL 2211 _regtype 0 0 NULL NULL NULL 2249 record 0 0 NULL NULL NULL -2277 anyarray 0 3903121477 NULL NULL NULL +2277 anyarray 0 3403232968 NULL NULL NULL 2283 anyelement 0 0 NULL NULL NULL 2287 _record 0 0 NULL NULL NULL 2950 uuid 0 0 NULL NULL NULL diff --git a/pkg/sql/pg_catalog.go b/pkg/sql/pg_catalog.go index 3051ce156084..aa4ff8204d0e 100644 --- a/pkg/sql/pg_catalog.go +++ b/pkg/sql/pg_catalog.go @@ -57,7 +57,6 @@ var ( const ( indexTypeForwardIndex = "prefix" indexTypeInvertedIndex = "inverted" - defaultCollationTag = "en-US" ) // Bitmasks for pg_index.indoption. Each column in the index has a bitfield @@ -664,9 +663,8 @@ https://www.postgresql.org/docs/9.5/catalog-pg-collation.html`, h := makeOidHasher() return forEachDatabaseDesc(ctx, p, dbContext, false /* requiresPrivileges */, func(db *dbdesc.Immutable) error { namespaceOid := h.NamespaceOid(db.GetID(), pgCatalogName) - for _, tag := range collate.Supported() { - collName := tag.String() - if err := addRow( + add := func(collName string) error { + return addRow( h.CollationOid(collName), // oid tree.NewDString(collName), // collname namespaceOid, // collnamespace @@ -676,7 +674,14 @@ https://www.postgresql.org/docs/9.5/catalog-pg-collation.html`, // required by LC_COLLATE and LC_CTYPE. tree.DNull, // collcollate tree.DNull, // collctype - ); err != nil { + ) + } + if err := add(tree.DefaultCollationTag); err != nil { + return err + } + for _, tag := range collate.Supported() { + collName := tag.String() + if err := add(collName); err != nil { return err } } @@ -2456,13 +2461,13 @@ func typColl(typ *types.T, h oidHasher) tree.Datum { case types.AnyFamily: return oidZero case types.StringFamily: - return h.CollationOid(defaultCollationTag) + return h.CollationOid(tree.DefaultCollationTag) case types.CollatedStringFamily: return h.CollationOid(typ.Locale()) } if typ.Equivalent(types.StringArray) { - return h.CollationOid(defaultCollationTag) + return h.CollationOid(tree.DefaultCollationTag) } return oidZero } diff --git a/pkg/sql/sem/tree/BUILD.bazel b/pkg/sql/sem/tree/BUILD.bazel index f7c2127a37f0..c8d9b334aa65 100644 --- a/pkg/sql/sem/tree/BUILD.bazel +++ b/pkg/sql/sem/tree/BUILD.bazel @@ -17,6 +17,7 @@ go_library( "casts.go", "changefeed.go", "col_name.go", + "collatedstring.go", "comment_on_column.go", "comment_on_database.go", "comment_on_index.go", diff --git a/pkg/sql/sem/tree/collatedstring.go b/pkg/sql/sem/tree/collatedstring.go new file mode 100644 index 000000000000..01f69a0474b8 --- /dev/null +++ b/pkg/sql/sem/tree/collatedstring.go @@ -0,0 +1,14 @@ +// Copyright 2020 The Cockroach Authors. +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package tree + +// DefaultCollationTag is the "default" collation for strings. +const DefaultCollationTag = "default" diff --git a/pkg/sql/sem/tree/create.go b/pkg/sql/sem/tree/create.go index c89320b463aa..9f0ef00cbc7c 100644 --- a/pkg/sql/sem/tree/create.go +++ b/pkg/sql/sem/tree/create.go @@ -460,15 +460,21 @@ func NewColumnTableDef( switch t := c.Qualification.(type) { case ColumnCollation: locale := string(t) - _, err := language.Parse(locale) - if err != nil { - return nil, pgerror.Wrapf(err, pgcode.Syntax, "invalid locale %s", locale) - } - collatedTyp, err := processCollationOnType(name, d.Type, t) - if err != nil { - return nil, err + // In postgres, all strings have collations defaulting to "default". + // In CRDB, collated strings are treated separately to string family types. + // To most behave like postgres, set the CollatedString type if a non-"default" + // collation is used. + if locale != DefaultCollationTag { + _, err := language.Parse(locale) + if err != nil { + return nil, pgerror.Wrapf(err, pgcode.Syntax, "invalid locale %s", locale) + } + collatedTyp, err := processCollationOnType(name, d.Type, t) + if err != nil { + return nil, err + } + d.Type = collatedTyp } - d.Type = collatedTyp case *ColumnDefault: if d.HasDefaultExpr() { return nil, pgerror.Newf(pgcode.Syntax,