Skip to content

Commit fcc68f2

Browse files
craig[bot]yuzefovichwenyihu6tbgrail
committed
150387: builtins: fix `pg_collation_for` for CITEXT r=yuzefovich a=yuzefovich We missed a spot where we need to unwrap the DOidWrapper corresponding to DCIText. Fixes: #150386. Release note: None 150390: kvserver: pass NodeCapacityProviderConfig to NewNodeCapacityProvider r=tbg a=wenyihu6 Previously, NewNodeCapacityProvider took NodeCapacityProviderTestingKnobs directly and handled the logic for picking refresh intervals internally. This wasn't ideal, as it is preferred for configuration to be handled by the caller, keeping NewNodeCapacityProvider focused on its core logic. This change moves that logic to the caller, which now constructs the config with the appropriate interval values. The default setting is now also closer to the server configuration in pkg/base/config.go. Epic: none Release note: none 150391: valueside: fix missing support for CITEXT r=yuzefovich a=yuzefovich We forgot to add support for CITEXT in MarshalLegacy value encoding. We forgot to add support for CITEXT in MarshalLegacy value encoding. (This encoding type is used when multiple column families are present, and the CITEXT is included not in the zeroth column family.) No stable release with this bug, so we omit the release note. Fixes: #150389. Release none: None 150414: release: add support for s390x in custom release signing script r=rickystewart a=rail This commit adds support for the s390x architecture in the custom release signing script and introduces a new script to build CockroachDB releases for the s390x platform without telemetry. Release note: none Epic: none Co-authored-by: Yahor Yuzefovich <[email protected]> Co-authored-by: wenyihu6 <[email protected]> Co-authored-by: Tobias Grieger <[email protected]> Co-authored-by: Rail Aliiev <[email protected]>
5 parents fa1c75b + 6ce0576 + 6b826a1 + 7f260b6 + e4f2348 commit fcc68f2

File tree

11 files changed

+171
-46
lines changed

11 files changed

+171
-46
lines changed

build/teamcity/internal/cockroach/release/publish/sign-custom-release.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ log_into_gcloud
5353
mkdir -p artifacts
5454
cd artifacts
5555

56-
for platform in linux-amd64 linux-arm64; do
56+
for platform in linux-amd64 linux-arm64 linux-s390x; do
5757
tarball=${cockroach_archive_prefix}-${version}.${platform}.tgz
5858

5959
gsutil cp "gs://$gcs_staged_bucket/$tarball" "$tarball"
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/usr/bin/env bash
2+
3+
# Copyright 2025 The Cockroach Authors.
4+
#
5+
# Use of this software is governed by the CockroachDB Software License
6+
# included in the /LICENSE file.
7+
8+
9+
PLATFORM=linux-s390x TELEMETRY_DISABLED=true ./build/teamcity/internal/release/process/build-cockroach-release-per-platform.sh

pkg/base/config.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,21 @@ const (
9696
// DefaultLeaseRenewalCrossValidate is the default setting for if
9797
// we should validate descriptors on lease renewals.
9898
DefaultLeaseRenewalCrossValidate = false
99+
100+
// DefaultCPUUsageRefreshInterval controls how often cpu usage measurements
101+
// are sampled by NodeCapacityProvider.
102+
DefaultCPUUsageRefreshInterval = time.Second
103+
104+
// DefaultCPUCapacityRefreshInterval controls how often the total CPU capacity
105+
// of the node is re-calculated by NodeCapacityProvider. This is less frequent
106+
// than usage since capacity changes happen less often.
107+
DefaultCPUCapacityRefreshInterval = 10 * time.Second
108+
109+
// DefaultCPUUsageMovingAverageAge defines the effective time window size for
110+
// sampling cpu usage. With a value of 20, the 20th-to-last measurement
111+
// contributes meaningfully to the average, while earlier measurements have
112+
// diminishing impact.
113+
DefaultCPUUsageMovingAverageAge = 20
99114
)
100115

101116
// DefaultCertsDirectory is the default value for the cert directory flag.

pkg/kv/kvserver/load/node_capacity_provider.go

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -35,45 +35,35 @@ type NodeCapacityProvider struct {
3535
runtimeLoadMonitor *runtimeLoadMonitor
3636
}
3737

38+
// NodeCapacityProviderConfig holds the configuration for creating a
39+
// NodeCapacityProvider.
40+
type NodeCapacityProviderConfig struct {
41+
// CPUUsageRefreshInterval controls how often cpu usage measurements are
42+
// sampled.
43+
CPUUsageRefreshInterval time.Duration
44+
// CPUCapacityRefreshInterval controls how often the total CPU capacity is
45+
// polled.
46+
CPUCapacityRefreshInterval time.Duration
47+
// CPUUsageMovingAverageAge defines the effective time window size for the
48+
// moving average when sampling cpu usage.
49+
CPUUsageMovingAverageAge float64
50+
}
51+
3852
// NewNodeCapacityProvider creates a new NodeCapacityProvider that monitors CPU
39-
// metrics using the provided stores aggregator. The optional knobs parameter
40-
// allows customizing refresh intervals for testing.
53+
// metrics using the provided stores aggregator and configuration.
4154
func NewNodeCapacityProvider(
42-
stopper *stop.Stopper, stores StoresStatsAggregator, knobs *NodeCapacityProviderTestingKnobs,
55+
stopper *stop.Stopper, stores StoresStatsAggregator, config NodeCapacityProviderConfig,
4356
) *NodeCapacityProvider {
4457
if stopper == nil || stores == nil {
4558
panic("programming error: stopper or stores aggregator cannot be nil")
4659
}
4760

48-
// refreshIntervals define how frequently cpu metrics are updated.
49-
const (
50-
// defaultCPUUsageRefreshInterval controls how often cpu usage measurements
51-
// are taken.
52-
defaultCPUUsageRefreshInterval = time.Second
53-
// defaultCPUCapacityRefreshInterval controls how often the total CPU
54-
// capacity of the node is re-calculated. This is less frequent than usage
55-
// since capacity changes happen less often.
56-
defaultCPUCapacityRefreshInterval = 10 * time.Second
57-
)
58-
59-
// defaultMovingAverageAge defines the effective time window size. With a
60-
// value of 20, the 20th-to-last measurement contributes meaningfully to the
61-
// average, while earlier measurements have diminishing impact.
62-
const defaultMovingAverageAge = 20
63-
64-
usageInterval := defaultCPUUsageRefreshInterval
65-
capacityInterval := defaultCPUCapacityRefreshInterval
66-
if knobs != nil {
67-
usageInterval = knobs.CpuUsageRefreshInterval
68-
capacityInterval = knobs.CpuCapacityRefreshInterval
69-
}
70-
7161
monitor := &runtimeLoadMonitor{
7262
stopper: stopper,
73-
usageRefreshInterval: usageInterval,
74-
capacityRefreshInterval: capacityInterval,
63+
usageRefreshInterval: config.CPUUsageRefreshInterval,
64+
capacityRefreshInterval: config.CPUCapacityRefreshInterval,
7565
}
76-
monitor.mu.usageEWMA = ewma.NewMovingAverage(defaultMovingAverageAge)
66+
monitor.mu.usageEWMA = ewma.NewMovingAverage(config.CPUUsageMovingAverageAge)
7767
monitor.recordCPUCapacity(context.Background())
7868
return &NodeCapacityProvider{
7969
stores: stores,

pkg/kv/kvserver/load/node_capacity_provider_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,10 @@ func TestNodeCapacityProvider(t *testing.T) {
4040
storeCount: 3,
4141
}
4242

43-
provider := load.NewNodeCapacityProvider(stopper, mockStores, &load.NodeCapacityProviderTestingKnobs{
44-
CpuUsageRefreshInterval: 1 * time.Millisecond,
45-
CpuCapacityRefreshInterval: 1 * time.Millisecond,
43+
provider := load.NewNodeCapacityProvider(stopper, mockStores, load.NodeCapacityProviderConfig{
44+
CPUUsageRefreshInterval: 1 * time.Millisecond,
45+
CPUCapacityRefreshInterval: 1 * time.Millisecond,
46+
CPUUsageMovingAverageAge: 20,
4647
})
4748

4849
ctx, cancel := context.WithCancel(context.Background())

pkg/kv/kvserver/store_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,12 @@ func createTestStoreWithoutStart(
262262
stores := NewStores(cfg.AmbientCtx, cfg.Clock)
263263
nodeDesc := &roachpb.NodeDescriptor{NodeID: 1}
264264
if cfg.NodeCapacityProvider == nil {
265-
cfg.NodeCapacityProvider = load.NewNodeCapacityProvider(stopper, stores, nil)
265+
// Faster refresh intervals for testing.
266+
cfg.NodeCapacityProvider = load.NewNodeCapacityProvider(stopper, stores, load.NodeCapacityProviderConfig{
267+
CPUUsageRefreshInterval: 10 * time.Millisecond,
268+
CPUCapacityRefreshInterval: 10 * time.Millisecond,
269+
CPUUsageMovingAverageAge: 20,
270+
})
266271
}
267272

268273
rangeProv := &dummyFirstRangeProvider{}

pkg/server/server.go

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ import (
128128
"github.com/cockroachdb/errors"
129129
"github.com/cockroachdb/logtags"
130130
"github.com/cockroachdb/redact"
131-
sentry "github.com/getsentry/sentry-go"
131+
"github.com/getsentry/sentry-go"
132132
"google.golang.org/grpc/codes"
133133
)
134134

@@ -690,14 +690,19 @@ func NewServer(cfg Config, stopper *stop.Stopper) (serverctl.ServerStartupInterf
690690
policyRefresher = policyrefresher.NewPolicyRefresher(stopper, st, ctSender.GetLeaseholders,
691691
rpcContext.RemoteClocks.AllLatencies, knobs)
692692
}
693-
var nodeCapacityProvider *load.NodeCapacityProvider
694-
{
695-
var knobs *load.NodeCapacityProviderTestingKnobs
696-
if nodeCapacityProviderKnobs := cfg.TestingKnobs.NodeCapacityProviderKnobs; nodeCapacityProviderKnobs != nil {
697-
knobs = nodeCapacityProviderKnobs.(*load.NodeCapacityProviderTestingKnobs)
698-
}
699-
nodeCapacityProvider = load.NewNodeCapacityProvider(stopper, stores, knobs)
693+
694+
cpuUsageRefreshInterval := base.DefaultCPUUsageRefreshInterval
695+
cpuCapacityRefreshInterval := base.DefaultCPUCapacityRefreshInterval
696+
if ncpKnobs, _ := cfg.TestingKnobs.NodeCapacityProviderKnobs.(*load.NodeCapacityProviderTestingKnobs); ncpKnobs != nil {
697+
cpuUsageRefreshInterval = ncpKnobs.CpuUsageRefreshInterval
698+
cpuCapacityRefreshInterval = ncpKnobs.CpuCapacityRefreshInterval
699+
}
700+
nodeCapacityProviderConfig := load.NodeCapacityProviderConfig{
701+
CPUUsageRefreshInterval: cpuUsageRefreshInterval,
702+
CPUCapacityRefreshInterval: cpuCapacityRefreshInterval,
703+
CPUUsageMovingAverageAge: base.DefaultCPUUsageMovingAverageAge,
700704
}
705+
nodeCapacityProvider := load.NewNodeCapacityProvider(stopper, stores, nodeCapacityProviderConfig)
701706

702707
// The Executor will be further initialized later, as we create more
703708
// of the server's components. There's a circular dependency - many things

pkg/sql/logictest/testdata/logic_test/citext

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,84 @@ SELECT c FROM r WHERE c = ARRAY['tEsT', 'tEsTeR']::CITEXT[];
7979
----
8080
{test,TESTER}
8181

82+
subtest column_families
83+
84+
statement ok
85+
DROP TABLE IF EXISTS t;
86+
87+
statement ok
88+
CREATE TABLE t (
89+
k INT PRIMARY KEY,
90+
c CITEXT,
91+
FAMILY (k),
92+
FAMILY (c)
93+
)
94+
95+
onlyif config schema-locked-disabled
96+
query TT colnames
97+
SHOW CREATE TABLE t
98+
----
99+
table_name create_statement
100+
t CREATE TABLE public.t (
101+
k INT8 NOT NULL,
102+
c CITEXT NULL,
103+
CONSTRAINT t_pkey PRIMARY KEY (k ASC),
104+
FAMILY fam_0_k (k),
105+
FAMILY fam_1_c (c)
106+
);
107+
108+
statement ok
109+
INSERT INTO t VALUES (1, 'test')
110+
111+
query T
112+
SELECT pg_typeof(c) FROM t LIMIT 1;
113+
----
114+
citext
115+
116+
query T
117+
SELECT c FROM t WHERE c = 'tEsT';
118+
----
119+
test
120+
121+
statement ok
122+
DROP TABLE IF EXISTS r;
123+
124+
statement ok
125+
CREATE TABLE r (
126+
k INT PRIMARY KEY,
127+
c CITEXT[],
128+
FAMILY (k),
129+
FAMILY (c)
130+
)
131+
132+
onlyif config schema-locked-disabled
133+
query TT colnames
134+
SHOW CREATE TABLE r
135+
----
136+
table_name create_statement
137+
r CREATE TABLE public.r (
138+
k INT8 NOT NULL,
139+
c CITEXT[] NULL,
140+
CONSTRAINT r_pkey PRIMARY KEY (k ASC),
141+
FAMILY fam_0_k (k),
142+
FAMILY fam_1_c (c)
143+
);
144+
145+
statement ok
146+
INSERT INTO r VALUES (1, ARRAY['test', 'TESTER'])
147+
148+
query T
149+
SELECT pg_typeof(c) FROM r LIMIT 1;
150+
----
151+
citext[]
152+
153+
query T
154+
SELECT c FROM r WHERE c = ARRAY['tEsT', 'tEsTeR']::CITEXT[];
155+
----
156+
{test,TESTER}
157+
158+
subtest end
159+
82160
query error multiple COLLATE declarations
83161
CREATE TABLE s (c CITEXT COLLATE "en_US");
84162

@@ -191,10 +269,10 @@ statement ok
191269
CREATE TYPE IF NOT EXISTS ctype AS (id INT, c CITEXT);
192270

193271
statement ok
194-
CREATE TABLE composite_citext_tbl (a ctype);
272+
CREATE TABLE composite_citext_tbl (k INT PRIMARY KEY, a ctype);
195273

196274
statement ok
197-
INSERT INTO composite_citext_tbl VALUES (ROW(1, 'TeSt')), (ROW(2, 'TESTER')), (ROW(3, 'tEsT'));
275+
INSERT INTO composite_citext_tbl VALUES (1, ROW(1, 'TeSt')), (2, ROW(2, 'TESTER')), (3, ROW(3, 'tEsT'));
198276

199277
query T
200278
SELECT (a).c FROM composite_citext_tbl WHERE (a).c = 'test' ORDER BY (a).id;
@@ -214,3 +292,8 @@ query T
214292
SELECT cast('test'::TEXT AS CITEXT);
215293
----
216294
test
295+
296+
query T
297+
SELECT pg_collation_for('foo'::CITEXT);
298+
----
299+
"default"

pkg/sql/rowenc/valueside/legacy.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/cockroachdb/cockroach/pkg/geo"
1010
"github.com/cockroachdb/cockroach/pkg/roachpb"
1111
"github.com/cockroachdb/cockroach/pkg/sql/lex"
12+
"github.com/cockroachdb/cockroach/pkg/sql/oidext"
1213
"github.com/cockroachdb/cockroach/pkg/sql/pgrepl/lsn"
1314
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
1415
"github.com/cockroachdb/cockroach/pkg/sql/types"
@@ -195,6 +196,9 @@ func MarshalLegacy(colType *types.T, val tree.Datum) (roachpb.Value, error) {
195196
return r, nil
196197
}
197198
case types.CollatedStringFamily:
199+
if colType.Oid() == oidext.T_citext {
200+
val = tree.UnwrapDOidWrapper(val)
201+
}
198202
if v, ok := val.(*tree.DCollatedString); ok {
199203
if lex.LocaleNamesAreEqual(v.Locale, colType.Locale()) {
200204
r.SetString(v.Contents)
@@ -354,6 +358,9 @@ func UnmarshalLegacy(a *tree.DatumAlloc, typ *types.T, value roachpb.Value) (tre
354358
if err != nil {
355359
return nil, err
356360
}
361+
if typ.Oid() == oidext.T_citext {
362+
return a.NewDCIText(string(v))
363+
}
357364
return a.NewDCollatedString(string(v), typ.Locale())
358365
case types.UuidFamily:
359366
v, err := value.GetBytes()

pkg/sql/sem/builtins/pg_builtins.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1013,13 +1013,18 @@ var pgBuiltins = map[string]builtinDefinition{
10131013
Types: tree.ParamTypes{{Name: "str", Typ: types.AnyElement}},
10141014
ReturnType: tree.FixedReturnType(types.String),
10151015
Fn: func(_ context.Context, _ *eval.Context, args tree.Datums) (tree.Datum, error) {
1016+
d := args[0]
10161017
var collation string
1017-
switch t := args[0].(type) {
1018+
switch t := d.(type) {
10181019
case *tree.DString:
10191020
collation = "default"
10201021
case *tree.DCollatedString:
10211022
collation = t.Locale
10221023
default:
1024+
if w, ok := d.(*tree.DOidWrapper); ok && w.Oid == oidext.T_citext {
1025+
collation = "default"
1026+
break
1027+
}
10231028
return tree.DNull, pgerror.Newf(pgcode.DatatypeMismatch,
10241029
"collations are not supported by type: %s", t.ResolvedType())
10251030
}

0 commit comments

Comments
 (0)