diff --git a/pkg/acceptance/testdata/java/src/main/java/MainTest.java b/pkg/acceptance/testdata/java/src/main/java/MainTest.java index f1ac9750fd63..b68c787630f4 100644 --- a/pkg/acceptance/testdata/java/src/main/java/MainTest.java +++ b/pkg/acceptance/testdata/java/src/main/java/MainTest.java @@ -177,6 +177,15 @@ public void testTime() throws Exception { Assert.assertEquals("01:02:03.456", actual); } + @Test + public void testTimeTZ() throws Exception { + PreparedStatement stmt = conn.prepareStatement("SELECT '01:02:03.456-07:00'::TIMETZ"); + ResultSet rs = stmt.executeQuery(); + rs.next(); + String actual = new SimpleDateFormat("HH:mm:ss.SSSZ").format(rs.getTime(1)); + Assert.assertEquals("08:02:03.456+0000", actual); + } + @Test public void testUUID() throws Exception { UUID uuid = UUID.randomUUID(); diff --git a/pkg/blobs/bench_test.go b/pkg/blobs/bench_test.go index c1c79e93382e..755a9e73bdd3 100644 --- a/pkg/blobs/bench_test.go +++ b/pkg/blobs/bench_test.go @@ -24,6 +24,10 @@ import ( "github.com/cockroachdb/cockroach/pkg/util/hlc" ) +// filesize should be at least 1 GB when running these benchmarks. +// Reduced to 129 K for CI. +const filesize = 129 * 1 << 10 + type benchmarkTestCase struct { localNodeID roachpb.NodeID remoteNodeID roachpb.NodeID @@ -68,7 +72,7 @@ func BenchmarkStreamingReadFile(b *testing.B) { localExternalDir: localExternalDir, remoteExternalDir: remoteExternalDir, blobClient: blobClient, - fileSize: 1 << 30, // 1 GB + fileSize: filesize, fileName: "test/largefile.csv", } benchmarkStreamingReadFile(b, params) @@ -119,7 +123,7 @@ func BenchmarkStreamingWriteFile(b *testing.B) { localExternalDir: localExternalDir, remoteExternalDir: remoteExternalDir, blobClient: blobClient, - fileSize: 1 << 30, // 1 GB + fileSize: filesize, fileName: "test/largefile.csv", } benchmarkStreamingWriteFile(b, params) diff --git a/pkg/ccl/backupccl/backup.go b/pkg/ccl/backupccl/backup.go index 68a9b1c6d3c0..1da108098e50 100644 --- a/pkg/ccl/backupccl/backup.go +++ b/pkg/ccl/backupccl/backup.go @@ -938,7 +938,7 @@ func VerifyUsableExportTarget( // TODO(dt): If we audit exactly what not-exists error each ExternalStorage // returns (and then wrap/tag them), we could narrow this check. r.Close() - return pgerror.Newf(pgcode.DuplicateFile, + return pgerror.Newf(pgcode.FileAlreadyExists, "%s already contains a %s file", readable, BackupDescriptorName) } @@ -946,13 +946,13 @@ func VerifyUsableExportTarget( // TODO(dt): If we audit exactly what not-exists error each ExternalStorage // returns (and then wrap/tag them), we could narrow this check. r.Close() - return pgerror.Newf(pgcode.DuplicateFile, + return pgerror.Newf(pgcode.FileAlreadyExists, "%s already contains a %s file", readable, BackupManifestName) } if r, err := exportStore.ReadFile(ctx, BackupDescriptorCheckpointName); err == nil { r.Close() - return pgerror.Newf(pgcode.DuplicateFile, + return pgerror.Newf(pgcode.FileAlreadyExists, "%s already contains a %s file (is another operation already in progress?)", readable, BackupDescriptorCheckpointName) } diff --git a/pkg/sql/logictest/testdata/logic_test/timetz b/pkg/sql/logictest/testdata/logic_test/timetz index efc36d14521b..7323890ff7ef 100644 --- a/pkg/sql/logictest/testdata/logic_test/timetz +++ b/pkg/sql/logictest/testdata/logic_test/timetz @@ -526,3 +526,116 @@ query R SELECT extract(epoch from timetz '12:00:00+04') ---- 28800 + +# Adapted from `src/test/regress/expected/timetz.out` in postgres +subtest regress_postgres + +statement ok +CREATE TABLE TIMETZ_TBL (id serial primary key, f1 time(2) with time zone) + +# Changed PDT/PST/EDT -> zone offsets, as pgdate does not support abbreviations. +statement ok +INSERT INTO TIMETZ_TBL (f1) VALUES ('00:01-07') + +statement ok +INSERT INTO TIMETZ_TBL (f1) VALUES ('01:00-07') + +statement ok +INSERT INTO TIMETZ_TBL (f1) VALUES ('02:03-07') + +statement ok +INSERT INTO TIMETZ_TBL (f1) VALUES ('07:07-05') + +statement ok +INSERT INTO TIMETZ_TBL (f1) VALUES ('08:08-04') + +statement ok +INSERT INTO TIMETZ_TBL (f1) VALUES ('11:59-07') + +statement ok +INSERT INTO TIMETZ_TBL (f1) VALUES ('12:00-07') + +statement ok +INSERT INTO TIMETZ_TBL (f1) VALUES ('12:01-07') + +statement ok +INSERT INTO TIMETZ_TBL (f1) VALUES ('23:59-07') + +statement ok +INSERT INTO TIMETZ_TBL (f1) VALUES ('11:59:59.99 PM-07') + +statement ok +INSERT INTO TIMETZ_TBL (f1) VALUES ('2003-03-07 15:36:39 America/New_York') + +statement ok +INSERT INTO TIMETZ_TBL (f1) VALUES ('2003-07-07 15:36:39 America/New_York') + +# pgdate supports this, but postgres does not. +# INSERT INTO TIMETZ_TBL (f1) VALUES ('15:36:39 America/New_York') + +# this should fail (timezone not specified without a date) +query error could not parse "1970-01-01 15:36:39 m2" as TimeTZ +INSERT INTO TIMETZ_TBL (f1) VALUES ('15:36:39 m2') + +# this should fail (dynamic timezone abbreviation without a date) +query error could not parse "1970-01-01 15:36:39 MSK m2" as TimeTZ +INSERT INTO TIMETZ_TBL (f1) VALUES ('15:36:39 MSK m2') + +query T +SELECT f1::string AS "Time TZ" FROM TIMETZ_TBL ORDER BY id +---- +00:01:00-07:00:00 +01:00:00-07:00:00 +02:03:00-07:00:00 +07:07:00-05:00:00 +08:08:00-04:00:00 +11:59:00-07:00:00 +12:00:00-07:00:00 +12:01:00-07:00:00 +23:59:00-07:00:00 +23:59:59.99-07:00:00 +15:36:39-05:00:00 +15:36:39-04:00:00 + +query T +SELECT f1::string AS "Three" FROM TIMETZ_TBL WHERE f1 < '05:06:07-07' ORDER BY id +---- +00:01:00-07:00:00 +01:00:00-07:00:00 +02:03:00-07:00:00 + +query T +SELECT f1::string AS "Seven" FROM TIMETZ_TBL WHERE f1 > '05:06:07-07' ORDER BY id +---- +07:07:00-05:00:00 +08:08:00-04:00:00 +11:59:00-07:00:00 +12:00:00-07:00:00 +12:01:00-07:00:00 +23:59:00-07:00:00 +23:59:59.99-07:00:00 +15:36:39-05:00:00 +15:36:39-04:00:00 + +query T +SELECT f1::string AS "None" FROM TIMETZ_TBL WHERE f1 < '00:00-07' ORDER BY id +---- + +query T +SELECT f1::string AS "Ten" FROM TIMETZ_TBL WHERE f1 >= '00:00-07' ORDER BY id +---- +00:01:00-07:00:00 +01:00:00-07:00:00 +02:03:00-07:00:00 +07:07:00-05:00:00 +08:08:00-04:00:00 +11:59:00-07:00:00 +12:00:00-07:00:00 +12:01:00-07:00:00 +23:59:00-07:00:00 +23:59:59.99-07:00:00 +15:36:39-05:00:00 +15:36:39-04:00:00 + +query error pq: unsupported binary operator: \+ +SELECT f1 + time with time zone '00:01' AS "Illegal" FROM TIMETZ_TBL ORDER BY id diff --git a/pkg/sql/pgwire/pgcode/codes.go b/pkg/sql/pgwire/pgcode/codes.go index 4c7ac52edcde..2ed4d4463c94 100644 --- a/pkg/sql/pgwire/pgcode/codes.go +++ b/pkg/sql/pgwire/pgcode/codes.go @@ -222,6 +222,7 @@ const ( InvalidSchemaDefinition = "42P15" InvalidTableDefinition = "42P16" InvalidObjectDefinition = "42P17" + FileAlreadyExists = "42C01" // Class 44 - WITH CHECK OPTION Violation WithCheckOptionViolation = "44000" // Class 53 - Insufficient Resources diff --git a/pkg/storage/engine/pebble.go b/pkg/storage/engine/pebble.go index d4bced4c94b7..c6e073eb5146 100644 --- a/pkg/storage/engine/pebble.go +++ b/pkg/storage/engine/pebble.go @@ -17,6 +17,7 @@ import ( "io" "io/ioutil" "os" + "sort" "github.com/cockroachdb/cockroach/pkg/base" "github.com/cockroachdb/cockroach/pkg/roachpb" @@ -487,7 +488,10 @@ func (p *Pebble) Get(key MVCCKey) ([]byte, error) { // GetCompactionStats implements the Engine interface. func (p *Pebble) GetCompactionStats() string { - return p.db.Metrics().String() + // NB: The initial blank line matches the formatting used by RocksDB and + // ensures that compaction stats display will not contain the log prefix + // (this method is only used for logging purposes). + return "\n" + p.db.Metrics().String() } // GetTickersAndHistograms implements the Engine interface. @@ -879,6 +883,8 @@ func (p *Pebble) GetSSTables() (sstables SSTableInfos) { sstables = append(sstables, info) } } + + sort.Sort(sstables) return sstables } diff --git a/pkg/storage/engine/rocksdb.go b/pkg/storage/engine/rocksdb.go index fe3fceae3037..1360e7f70cc2 100644 --- a/pkg/storage/engine/rocksdb.go +++ b/pkg/storage/engine/rocksdb.go @@ -33,6 +33,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/util" "github.com/cockroachdb/cockroach/pkg/util/envutil" "github.com/cockroachdb/cockroach/pkg/util/hlc" + "github.com/cockroachdb/cockroach/pkg/util/humanizeutil" "github.com/cockroachdb/cockroach/pkg/util/log" "github.com/cockroachdb/cockroach/pkg/util/protoutil" "github.com/cockroachdb/cockroach/pkg/util/syncutil" @@ -1261,7 +1262,13 @@ func (r *RocksDB) GetTickersAndHistograms() (*enginepb.TickersAndHistograms, err // GetCompactionStats returns the internal RocksDB compaction stats. See // https://github.com/facebook/rocksdb/wiki/RocksDB-Tuning-Guide#rocksdb-statistics. func (r *RocksDB) GetCompactionStats() string { - return cStringToGoString(C.DBGetCompactionStats(r.rdb)) + s := cStringToGoString(C.DBGetCompactionStats(r.rdb)) + + "estimated_pending_compaction_bytes: " + stats, err := r.GetStats() + if err != nil { + return s + err.Error() + } + return s + humanizeutil.IBytes(stats.PendingCompactionBytesEstimate) } // GetEnvStats returns stats for the RocksDB env. This may include encryption stats. diff --git a/pkg/storage/store.go b/pkg/storage/store.go index 1cd6704c47b7..5399fba51785 100644 --- a/pkg/storage/store.go +++ b/pkg/storage/store.go @@ -53,7 +53,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/util/contextutil" "github.com/cockroachdb/cockroach/pkg/util/envutil" "github.com/cockroachdb/cockroach/pkg/util/hlc" - "github.com/cockroachdb/cockroach/pkg/util/humanizeutil" "github.com/cockroachdb/cockroach/pkg/util/limit" "github.com/cockroachdb/cockroach/pkg/util/log" "github.com/cockroachdb/cockroach/pkg/util/metric" @@ -2354,8 +2353,7 @@ func (s *Store) ComputeMetrics(ctx context.Context, tick int) error { // stats. if tick%logSSTInfoTicks == 1 /* every 10m */ { log.Infof(ctx, "sstables (read amplification = %d):\n%s", readAmp, sstables) - log.Infof(ctx, "%sestimated_pending_compaction_bytes: %s", - s.engine.GetCompactionStats(), humanizeutil.IBytes(stats.PendingCompactionBytesEstimate)) + log.Infof(ctx, "%s", s.engine.GetCompactionStats()) } return nil } diff --git a/pkg/util/timetz/timetz.go b/pkg/util/timetz/timetz.go index 955e9aebf704..ccb1422a2edc 100644 --- a/pkg/util/timetz/timetz.go +++ b/pkg/util/timetz/timetz.go @@ -104,8 +104,7 @@ func ParseTimeTZ(now time.Time, s string, precision time.Duration) (TimeTZ, erro t, err := pgdate.ParseTimestamp(now, pgdate.ParseModeYMD, s) if err != nil { // Build our own error message to avoid exposing the dummy date. - return TimeTZ{}, pgerror.Wrapf( - err, + return TimeTZ{}, pgerror.Newf( pgcode.InvalidTextRepresentation, "could not parse %q as TimeTZ", s,