diff --git a/pkg/ccl/multiregionccl/regional_by_row_test.go b/pkg/ccl/multiregionccl/regional_by_row_test.go index 4007fe944594..8940b117bb23 100644 --- a/pkg/ccl/multiregionccl/regional_by_row_test.go +++ b/pkg/ccl/multiregionccl/regional_by_row_test.go @@ -799,6 +799,7 @@ USE t; for _, rbrChange := range regionalByRowChanges { for _, regionChange := range regionChanges { t.Run(fmt.Sprintf("setup %s executing %s with racing %s", rbrChange.setup, rbrChange.cmd, regionChange.cmd), func(t *testing.T) { + defer log.Scope(t).Close(t) interruptStartCh := make(chan struct{}) interruptEndCh := make(chan struct{}) performInterrupt := false diff --git a/pkg/ccl/streamingccl/streamingest/replication_stream_e2e_test.go b/pkg/ccl/streamingccl/streamingest/replication_stream_e2e_test.go index 96643875d496..3f505dc8fe7d 100644 --- a/pkg/ccl/streamingccl/streamingest/replication_stream_e2e_test.go +++ b/pkg/ccl/streamingccl/streamingest/replication_stream_e2e_test.go @@ -590,9 +590,6 @@ func TestTenantStreamingCutoverOnSourceFailure(t *testing.T) { cutoverOutput := replicationtestutils.DecimalTimeToHLC(t, cutoverStr) require.Equal(c.T, cutoverTime, cutoverOutput) - // Resume ingestion. - c.DestSysSQL.Exec(t, fmt.Sprintf("RESUME JOB %d", ingestionJobID)) - // Ingestion job should succeed despite source failure due to the successful cutover jobutils.WaitForJobToSucceed(t, c.DestSysSQL, jobspb.JobID(ingestionJobID)) } diff --git a/pkg/cmd/roachtest/tests/activerecord.go b/pkg/cmd/roachtest/tests/activerecord.go index 30b083557cb3..d1084b69c62b 100644 --- a/pkg/cmd/roachtest/tests/activerecord.go +++ b/pkg/cmd/roachtest/tests/activerecord.go @@ -159,7 +159,7 @@ func registerActiveRecord(r registry.Registry) { "installing gems", fmt.Sprintf( `cd /mnt/data1/activerecord-cockroachdb-adapter/ && `+ - `RAILS_VERSION=%s sudo bundle install`, supportedRailsVersion), + `sudo RAILS_VERSION=%s bundle install`, supportedRailsVersion), ); err != nil { t.Fatal(err) } @@ -172,8 +172,9 @@ func registerActiveRecord(r registry.Registry) { t.Status("running activerecord test suite") result, err := c.RunWithDetailsSingleNode(ctx, t.L(), node, - `cd /mnt/data1/activerecord-cockroachdb-adapter/ && `+ - `sudo RUBYOPT="-W0" TESTOPTS="-v" bundle exec rake test`, + fmt.Sprintf( + `cd /mnt/data1/activerecord-cockroachdb-adapter/ && `+ + `sudo RAILS_VERSION=%s RUBYOPT="-W0" TESTOPTS="-v" bundle exec rake test`, supportedRailsVersion), ) // Fatal for a roachprod or SSH error. A roachprod error is when result.Err==nil. diff --git a/pkg/sql/execinfrapb/processors_bulk_io.proto b/pkg/sql/execinfrapb/processors_bulk_io.proto index 0eb6c97c0fd4..2a340b433448 100644 --- a/pkg/sql/execinfrapb/processors_bulk_io.proto +++ b/pkg/sql/execinfrapb/processors_bulk_io.proto @@ -407,7 +407,7 @@ message GenerativeSplitAndScatterSpec { repeated roachpb.Span spans = 10 [(gogoproto.nullable) = false]; repeated jobs.jobspb.RestoreDetails.BackupLocalityInfo backup_locality_info = 11 [(gogoproto.nullable) = false]; // HighWater is the high watermark of the previous run of restore. - optional bytes high_water = 12 [(gogoproto.nullable) = false]; + optional bytes high_water = 12; // User who initiated the restore. optional string user_proto = 13 [(gogoproto.nullable) = false, (gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/security/username.SQLUsernameProto"]; // ChunkSize is the number of import spans per chunk. diff --git a/pkg/sql/logictest/testdata/logic_test/builtin_function b/pkg/sql/logictest/testdata/logic_test/builtin_function index 0d5cd8c50020..c9750ebdcd18 100644 --- a/pkg/sql/logictest/testdata/logic_test/builtin_function +++ b/pkg/sql/logictest/testdata/logic_test/builtin_function @@ -2517,6 +2517,18 @@ SELECT array_to_string(NULL, ','), array_to_string(NULL, 'foo', 'zerp') ---- NULL NULL +# Builtin array_to_string should recursively search nested arrays. +query T +SELECT array_to_string(ARRAY[ARRAY[ARRAY[5,6], ARRAY[2,3]], ARRAY[ARRAY[7,8], ARRAY[4,44]]], ' '); +---- +5 6 2 3 7 8 4 44 + +# Builtin array_to_string should recursively search nested arrays. +query T +SELECT array_to_string(ARRAY[(SELECT ARRAY[1,2]::int2vector)],' '); +---- +1 2 + # Examples from https://www.postgresql.org/docs/9.3/functions-string.html#FUNCTIONS-STRING-FORMAT query T SELECT format('Hello %s', 'World') diff --git a/pkg/sql/sem/builtins/builtins.go b/pkg/sql/sem/builtins/builtins.go index 456ceb5ef0c4..cc3074495ff3 100644 --- a/pkg/sql/sem/builtins/builtins.go +++ b/pkg/sql/sem/builtins/builtins.go @@ -9860,6 +9860,13 @@ func arrayToString( evalCtx *eval.Context, arr *tree.DArray, delim string, nullStr *string, ) (tree.Datum, error) { f := evalCtx.FmtCtx(tree.FmtArrayToString) + arrayToStringHelper(evalCtx, arr, delim, nullStr, f) + return tree.NewDString(f.CloseAndGetString()), nil +} + +func arrayToStringHelper( + evalCtx *eval.Context, arr *tree.DArray, delim string, nullStr *string, f *tree.FmtCtx, +) { for i := range arr.Array { if arr.Array[i] == tree.DNull { @@ -9868,13 +9875,17 @@ func arrayToString( } f.WriteString(*nullStr) } else { - f.FormatNode(arr.Array[i]) + if nestedArray, ok := arr.Array[i].(*tree.DArray); ok { + // "Unpack" nested arrays to be consistent with postgres. + arrayToStringHelper(evalCtx, nestedArray, delim, nullStr, f) + } else { + f.FormatNode(arr.Array[i]) + } } if i < len(arr.Array)-1 { f.WriteString(delim) } } - return tree.NewDString(f.CloseAndGetString()), nil } // encodeEscape implements the encode(..., 'escape') Postgres builtin. It's