From 249b87e52bdaed9535ff79403e2c174687175f57 Mon Sep 17 00:00:00 2001
From: Oliver Tan
Date: Mon, 9 Aug 2021 08:53:41 +1000
Subject: [PATCH 1/3] sessiondatapb: move SequenceCache to LocalOnlySessionData
This actually affects the results of my session migration test, so I
think we actually need to include it.
Release note: None
---
pkg/sql/exec_util.go | 2 +-
pkg/sql/planner.go | 2 +-
pkg/sql/sessiondata/BUILD.bazel | 1 -
pkg/sql/sessiondata/session_data.go | 4 -
pkg/sql/sessiondatapb/BUILD.bazel | 1 +
.../local_only_session_data.pb.go | 600 +++++++++++++++---
.../local_only_session_data.proto | 19 +
.../sequence_cache.go | 37 +-
8 files changed, 538 insertions(+), 128 deletions(-)
rename pkg/sql/{sessiondata => sessiondatapb}/sequence_cache.go (60%)
diff --git a/pkg/sql/exec_util.go b/pkg/sql/exec_util.go
index e45b043285de..7c69de8e820b 100644
--- a/pkg/sql/exec_util.go
+++ b/pkg/sql/exec_util.go
@@ -2617,7 +2617,7 @@ func (m *sessionDataMutator) SetNoticeDisplaySeverity(severity pgnotice.DisplayS
// initSequenceCache creates an empty sequence cache instance for the session.
func (m *sessionDataMutator) initSequenceCache() {
- m.data.SequenceCache = sessiondata.SequenceCache{}
+ m.data.SequenceCache = sessiondatapb.SequenceCache{}
}
// SetIntervalStyle sets the IntervalStyle for the given session.
diff --git a/pkg/sql/planner.go b/pkg/sql/planner.go
index 44f45d4ffc6a..dcb46af811c4 100644
--- a/pkg/sql/planner.go
+++ b/pkg/sql/planner.go
@@ -506,7 +506,7 @@ func (p *planner) ExecCfg() *ExecutorConfig {
// GetOrInitSequenceCache returns the sequence cache for the session.
// If the sequence cache has not been used yet, it initializes the cache
// inside the session data.
-func (p *planner) GetOrInitSequenceCache() sessiondata.SequenceCache {
+func (p *planner) GetOrInitSequenceCache() sessiondatapb.SequenceCache {
if p.SessionData().SequenceCache == nil {
p.sessionDataMutator.initSequenceCache()
}
diff --git a/pkg/sql/sessiondata/BUILD.bazel b/pkg/sql/sessiondata/BUILD.bazel
index 827762bdff54..88a9e13a6ba1 100644
--- a/pkg/sql/sessiondata/BUILD.bazel
+++ b/pkg/sql/sessiondata/BUILD.bazel
@@ -5,7 +5,6 @@ go_library(
srcs = [
"internal.go",
"search_path.go",
- "sequence_cache.go",
"sequence_state.go",
"session_data.go",
],
diff --git a/pkg/sql/sessiondata/session_data.go b/pkg/sql/sessiondata/session_data.go
index 7be2a0a60d30..5eefb1da406d 100644
--- a/pkg/sql/sessiondata/session_data.go
+++ b/pkg/sql/sessiondata/session_data.go
@@ -137,10 +137,6 @@ type LocalUnmigratableSessionData struct {
// descpb.ID -> descpb.ID, but cannot be stored as such due to package
// dependencies. Temporary tables are not supported in session migrations.
DatabaseIDToTempSchemaID map[uint32]uint32
- // SequenceCache stores sequence values which have been cached using the
- // CACHE sequence option.
- // Cached sequence options are not yet supported during session migrations.
- SequenceCache SequenceCache
///////////////////////////////////////////////////////////////////////////
// WARNING: consider whether a session parameter you're adding needs to //
diff --git a/pkg/sql/sessiondatapb/BUILD.bazel b/pkg/sql/sessiondatapb/BUILD.bazel
index 48e44d285bd4..84bf5fc888ab 100644
--- a/pkg/sql/sessiondatapb/BUILD.bazel
+++ b/pkg/sql/sessiondatapb/BUILD.bazel
@@ -6,6 +6,7 @@ go_library(
name = "sessiondatapb",
srcs = [
"local_only_session_data.go",
+ "sequence_cache.go",
"session_data.go",
],
embed = [":sessiondatapb_go_proto"],
diff --git a/pkg/sql/sessiondatapb/local_only_session_data.pb.go b/pkg/sql/sessiondatapb/local_only_session_data.pb.go
index 66a71c85891d..b98df8cd626f 100644
--- a/pkg/sql/sessiondatapb/local_only_session_data.pb.go
+++ b/pkg/sql/sessiondatapb/local_only_session_data.pb.go
@@ -7,6 +7,7 @@ import (
fmt "fmt"
_ "github.com/gogo/protobuf/gogoproto"
proto "github.com/gogo/protobuf/proto"
+ github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys"
io "io"
math "math"
math_bits "math/bits"
@@ -169,6 +170,9 @@ type LocalOnlySessionData struct {
SerialNormalizationMode SerialNormalizationMode `protobuf:"varint,42,opt,name=serial_normalization_mode,json=serialNormalizationMode,proto3,casttype=SerialNormalizationMode" json:"serial_normalization_mode,omitempty"`
// NewSchemaChangerMode indicates whether to use the new schema changer.
NewSchemaChangerMode NewSchemaChangerMode `protobuf:"varint,43,opt,name=new_schema_changer_mode,json=newSchemaChangerMode,proto3,casttype=NewSchemaChangerMode" json:"new_schema_changer_mode,omitempty"`
+ // SequenceCache stores sequence values which have been cached using the
+ // CACHE sequence option.
+ SequenceCache SequenceCache `protobuf:"bytes,44,rep,name=sequence_cache,json=sequenceCache,proto3,casttype=SequenceCache" json:"sequence_cache,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
}
func (m *LocalOnlySessionData) Reset() { *m = LocalOnlySessionData{} }
@@ -200,8 +204,55 @@ func (m *LocalOnlySessionData) XXX_DiscardUnknown() {
var xxx_messageInfo_LocalOnlySessionData proto.InternalMessageInfo
+// SequenceCacheEntry is an entry in a SequenceCache.
+type SequenceCacheEntry struct {
+ // CachedVersion stores the descpb.DescriptorVersion that cached values are associated with.
+ // The version is checked to determine if cache needs to be invalidated. The version is stored as
+ // a uint32 to prevent an import cycle with the descpb package.
+ CachedVersion uint32 `protobuf:"varint,1,opt,name=cached_version,json=cachedVersion,proto3" json:"cached_version,omitempty"`
+ // CurrentValue stores the present value of the sequence to be given out.
+ CurrentValue int64 `protobuf:"varint,2,opt,name=current_value,json=currentValue,proto3" json:"current_value,omitempty"`
+ // Increment stores the amount to Increment the currentVal by each time the
+ // currentVal is used. This value corresponds to descpb.TableDescriptor_SequenceOpts.Increment.
+ Increment int64 `protobuf:"varint,3,opt,name=increment,proto3" json:"increment,omitempty"`
+ // NumValues represents the number of values to cache. The cache is considered
+ // to be empty when NumValues is 0.
+ NumValues int64 `protobuf:"varint,4,opt,name=num_values,json=numValues,proto3" json:"num_values,omitempty"`
+}
+
+func (m *SequenceCacheEntry) Reset() { *m = SequenceCacheEntry{} }
+func (m *SequenceCacheEntry) String() string { return proto.CompactTextString(m) }
+func (*SequenceCacheEntry) ProtoMessage() {}
+func (*SequenceCacheEntry) Descriptor() ([]byte, []int) {
+ return fileDescriptor_21ead158cf36da28, []int{1}
+}
+func (m *SequenceCacheEntry) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *SequenceCacheEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+}
+func (m *SequenceCacheEntry) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_SequenceCacheEntry.Merge(m, src)
+}
+func (m *SequenceCacheEntry) XXX_Size() int {
+ return m.Size()
+}
+func (m *SequenceCacheEntry) XXX_DiscardUnknown() {
+ xxx_messageInfo_SequenceCacheEntry.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SequenceCacheEntry proto.InternalMessageInfo
+
func init() {
proto.RegisterType((*LocalOnlySessionData)(nil), "cockroach.sql.sessiondatapb.LocalOnlySessionData")
+ proto.RegisterMapType((SequenceCache)(nil), "cockroach.sql.sessiondatapb.LocalOnlySessionData.SequenceCacheEntry")
+ proto.RegisterType((*SequenceCacheEntry)(nil), "cockroach.sql.sessiondatapb.SequenceCacheEntry")
}
func init() {
@@ -209,101 +260,111 @@ func init() {
}
var fileDescriptor_21ead158cf36da28 = []byte{
- // 1495 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x96, 0x5f, 0x53, 0x1b, 0xbb,
- 0x19, 0xc6, 0x71, 0xcf, 0xe9, 0x69, 0x8e, 0x08, 0x09, 0x6c, 0x4c, 0xbc, 0x40, 0xb0, 0x81, 0x90,
- 0x84, 0x34, 0x2d, 0xb4, 0xd3, 0x3f, 0x93, 0xb6, 0xd3, 0x69, 0x83, 0xc1, 0xcd, 0x1f, 0x12, 0x1c,
- 0x1b, 0xca, 0x34, 0xed, 0x8c, 0x46, 0xec, 0xbe, 0xb6, 0x55, 0xb4, 0xd2, 0x5a, 0xd2, 0x02, 0xe6,
- 0x43, 0x74, 0x3a, 0xd3, 0x2f, 0x95, 0xcb, 0x5c, 0xe6, 0x8a, 0x69, 0x9d, 0x6f, 0xc1, 0x55, 0x47,
- 0xaf, 0x76, 0x8d, 0x9d, 0x26, 0xd3, 0x3b, 0xd0, 0xf3, 0x7b, 0x1e, 0x4b, 0xaf, 0x5e, 0x49, 0x4b,
- 0xb6, 0x4c, 0x5f, 0x6c, 0x19, 0x30, 0x86, 0x2b, 0x19, 0x33, 0xcb, 0xd2, 0xe3, 0x2d, 0xa1, 0x22,
- 0x26, 0xa8, 0x92, 0x62, 0x40, 0x73, 0x81, 0x3a, 0x65, 0x33, 0xd5, 0xca, 0xaa, 0x60, 0x29, 0x52,
- 0xd1, 0x89, 0x56, 0x2c, 0xea, 0x6d, 0x9a, 0xbe, 0xd8, 0x9c, 0xb0, 0x2e, 0x96, 0xbb, 0xaa, 0xab,
- 0x90, 0xdb, 0x72, 0x7f, 0x79, 0xcb, 0xda, 0x3f, 0xee, 0x92, 0xf2, 0x9e, 0x0b, 0xdd, 0x97, 0x62,
- 0xd0, 0xf6, 0x86, 0x1d, 0x66, 0x59, 0xf0, 0x13, 0x12, 0x18, 0x76, 0x0a, 0xd4, 0xb2, 0x63, 0x01,
- 0x86, 0xa6, 0x1a, 0x3a, 0xfc, 0x3c, 0x2c, 0xad, 0x94, 0x36, 0xbe, 0x6f, 0xcd, 0x3a, 0xe5, 0x00,
- 0x85, 0x26, 0x8e, 0x07, 0x7f, 0x25, 0x4b, 0x2a, 0xb5, 0x3c, 0xe1, 0x17, 0xa0, 0x69, 0xe7, 0x84,
- 0x46, 0xcc, 0x44, 0x2c, 0x06, 0x43, 0x05, 0x4f, 0xb8, 0x0d, 0x7f, 0xb0, 0x52, 0xda, 0xf8, 0x66,
- 0xfb, 0xde, 0xf0, 0xb2, 0x16, 0xee, 0x17, 0x58, 0xe3, 0x55, 0x3d, 0x87, 0xf6, 0x1c, 0xd3, 0x0a,
- 0x47, 0x01, 0x8d, 0x93, 0x09, 0x25, 0xf8, 0x25, 0xb9, 0x69, 0x6c, 0x62, 0xa9, 0xe5, 0x09, 0xa8,
- 0xcc, 0x86, 0xdf, 0x60, 0xda, 0xdc, 0xd5, 0x65, 0x6d, 0xc6, 0x0d, 0x6d, 0xee, 0x64, 0x9a, 0x59,
- 0xae, 0x64, 0x6b, 0xda, 0x61, 0x07, 0x9e, 0x0a, 0x9e, 0x93, 0x0a, 0x8f, 0x05, 0x50, 0x2e, 0x47,
- 0xa5, 0x2a, 0x02, 0xbe, 0xfd, 0x5a, 0x40, 0xd9, 0x39, 0x5e, 0xc8, 0xbc, 0x0e, 0x45, 0x12, 0x25,
- 0xf7, 0x8b, 0x24, 0xab, 0x99, 0x34, 0x2c, 0x72, 0xf0, 0xff, 0xa4, 0xfe, 0xf0, 0x6b, 0xa9, 0x35,
- 0x9f, 0x7a, 0x70, 0xed, 0xfd, 0xec, 0x07, 0x7e, 0x4d, 0x2a, 0x52, 0x59, 0x1e, 0x01, 0x8d, 0xb9,
- 0x49, 0x05, 0x73, 0x9b, 0x7b, 0x0a, 0x9a, 0xdb, 0x41, 0xf8, 0xdd, 0x4a, 0x69, 0x63, 0xa6, 0x35,
- 0xef, 0xe5, 0x1d, 0xaf, 0xb6, 0x73, 0x31, 0xd8, 0x24, 0x77, 0x34, 0x28, 0x1d, 0x83, 0xa6, 0x7f,
- 0x57, 0x5c, 0x16, 0xd5, 0xfe, 0x91, 0x9b, 0x48, 0x6b, 0x2e, 0x97, 0x5e, 0x3a, 0xc5, 0x17, 0xf2,
- 0x67, 0xa4, 0x1c, 0x43, 0x87, 0x65, 0xc2, 0x52, 0x7b, 0x2e, 0x69, 0xaa, 0xb9, 0xc2, 0x1f, 0xb9,
- 0x81, 0x86, 0x20, 0xd7, 0x0e, 0xce, 0x65, 0x33, 0x57, 0x82, 0x9f, 0x93, 0xf9, 0x71, 0x87, 0x06,
- 0x16, 0x63, 0xf7, 0x85, 0xdf, 0xaf, 0x94, 0x36, 0x6e, 0x8c, 0x5b, 0x5a, 0xc0, 0x62, 0xd7, 0x43,
- 0xc1, 0x36, 0xa9, 0x8e, 0x5b, 0x32, 0x03, 0xb4, 0xa3, 0x84, 0x50, 0x67, 0xa0, 0xd1, 0x6f, 0x42,
- 0x82, 0xde, 0xc5, 0x6b, 0xef, 0xa1, 0x81, 0x46, 0x8e, 0xb8, 0x18, 0x13, 0xec, 0x93, 0xf5, 0x94,
- 0x69, 0xcb, 0x99, 0x10, 0x03, 0x57, 0x13, 0xab, 0xf9, 0x71, 0x66, 0x21, 0xa6, 0xa9, 0x60, 0xd2,
- 0xb8, 0x11, 0xd7, 0x7c, 0x71, 0x38, 0x8d, 0x49, 0xab, 0x23, 0x76, 0xe7, 0x1a, 0x6d, 0x3a, 0x72,
- 0x27, 0x07, 0x83, 0xa7, 0xe4, 0xba, 0xbd, 0x70, 0x4a, 0x3d, 0x6e, 0xac, 0xea, 0x6a, 0x96, 0x98,
- 0xf0, 0x26, 0x86, 0xdc, 0x1d, 0xe9, 0x87, 0x06, 0x9e, 0x8f, 0xd4, 0xe0, 0x8f, 0x64, 0x79, 0xd2,
- 0x99, 0x64, 0xc2, 0x72, 0x1a, 0x29, 0x41, 0x8d, 0x65, 0xd6, 0x84, 0x33, 0x68, 0x5f, 0x18, 0xb7,
- 0xbf, 0x76, 0x48, 0x5d, 0x89, 0xb6, 0x03, 0x82, 0xdf, 0x92, 0x05, 0x3c, 0xb6, 0xdc, 0x0e, 0x68,
- 0x41, 0xc5, 0xd4, 0x00, 0xd3, 0x51, 0x2f, 0xbc, 0x85, 0xee, 0x4a, 0x01, 0x14, 0xa7, 0x23, 0x6e,
- 0xa3, 0x1c, 0xac, 0x92, 0x9b, 0x86, 0x75, 0x80, 0x66, 0x69, 0xcc, 0x2c, 0x98, 0xf0, 0x36, 0xe2,
- 0xd3, 0x6e, 0xec, 0xd0, 0x0f, 0x05, 0x7f, 0x21, 0x4b, 0xee, 0x70, 0x82, 0xa6, 0x42, 0xa9, 0x93,
- 0x2c, 0xcd, 0x5b, 0xa1, 0xa3, 0xdc, 0x41, 0x34, 0xe1, 0xac, 0x73, 0x6c, 0x2f, 0x0d, 0x2f, 0x6b,
- 0x95, 0x26, 0x62, 0x7b, 0x48, 0x61, 0x57, 0x34, 0x94, 0x6e, 0xbc, 0x32, 0xad, 0x4a, 0xfa, 0x25,
- 0xe1, 0xc4, 0xb8, 0xfe, 0xba, 0xe0, 0xdd, 0x0b, 0xd6, 0xc5, 0x4c, 0x0a, 0xd2, 0x57, 0x7d, 0x0e,
- 0x27, 0x31, 0xe7, 0x25, 0xc7, 0xef, 0x7a, 0x21, 0x78, 0x46, 0x96, 0x35, 0xf4, 0x33, 0xae, 0x81,
- 0xc2, 0x79, 0x2a, 0x78, 0xc4, 0xad, 0x6b, 0xb2, 0x84, 0xe9, 0x01, 0x3d, 0x81, 0x81, 0x09, 0x03,
- 0xbf, 0xf3, 0x39, 0xb4, 0x9b, 0x33, 0x4d, 0x8f, 0xbc, 0x82, 0x81, 0x71, 0x47, 0xa1, 0xa3, 0x74,
- 0x04, 0xd4, 0x5d, 0x31, 0xa9, 0xe2, 0xd2, 0x52, 0x0d, 0xc6, 0x32, 0x6d, 0xc3, 0x3b, 0x68, 0x9e,
- 0x47, 0xb9, 0x5d, 0xa8, 0x2d, 0x2f, 0x06, 0x4f, 0xc9, 0x02, 0x73, 0x1d, 0xe4, 0x2e, 0xaa, 0x94,
- 0x69, 0xa0, 0xcc, 0xb8, 0x62, 0x63, 0xc3, 0x84, 0x65, 0xef, 0x44, 0xa0, 0xe9, 0xf5, 0x67, 0x66,
- 0x3f, 0xb5, 0xae, 0x47, 0xdc, 0x22, 0x2d, 0x24, 0x69, 0x71, 0xd1, 0x15, 0x8b, 0x9c, 0xf7, 0x8b,
- 0x74, 0x92, 0xbf, 0xe9, 0x8a, 0x45, 0xee, 0x93, 0x75, 0x9e, 0xe4, 0x8b, 0x8b, 0x94, 0xc8, 0x12,
- 0x49, 0xb1, 0xff, 0xdc, 0xb9, 0xe6, 0xb2, 0x3b, 0x0a, 0xb8, 0xeb, 0x7b, 0xb3, 0x60, 0xeb, 0x88,
- 0x36, 0xc7, 0xc8, 0x22, 0xf0, 0x57, 0xa4, 0x12, 0x6b, 0x95, 0x52, 0x90, 0x59, 0x42, 0x4f, 0x99,
- 0xc8, 0x60, 0x94, 0x51, 0xc1, 0x8c, 0xb2, 0x93, 0x77, 0x65, 0x96, 0xfc, 0xd9, 0x89, 0x85, 0xed,
- 0x88, 0x3c, 0x56, 0xa7, 0xa0, 0x35, 0x8f, 0x8b, 0x9e, 0xd4, 0xd0, 0x75, 0xf7, 0xd1, 0x85, 0x92,
- 0x40, 0x23, 0x25, 0x3b, 0xfc, 0x7a, 0x32, 0x21, 0x06, 0xad, 0x17, 0x06, 0x6c, 0xd0, 0x16, 0xe2,
- 0xef, 0x94, 0x84, 0x3a, 0xc2, 0x45, 0xf0, 0x1f, 0xc8, 0xbd, 0x1e, 0x33, 0x3d, 0x6a, 0x7a, 0x4c,
- 0xc7, 0x10, 0x53, 0x2e, 0x63, 0x38, 0x1f, 0xab, 0xcc, 0x82, 0x6f, 0x78, 0xc7, 0xb4, 0x3d, 0xf2,
- 0xc2, 0x13, 0x45, 0xc0, 0x6f, 0xc8, 0x82, 0x3b, 0xa1, 0xb8, 0x1d, 0x9d, 0x4c, 0x08, 0x5f, 0x5a,
- 0x6a, 0x22, 0x26, 0x4d, 0xb8, 0xe8, 0x4f, 0x5b, 0x01, 0x34, 0x32, 0x21, 0xb0, 0xbe, 0x6d, 0xa7,
- 0x06, 0xbf, 0x23, 0x8b, 0xa3, 0xe2, 0x1a, 0x10, 0x10, 0x59, 0x6c, 0x64, 0xdf, 0xfe, 0xe1, 0x92,
- 0x3f, 0x2c, 0x05, 0xd1, 0x46, 0xa0, 0xa1, 0xb4, 0x3f, 0x0a, 0xc1, 0x06, 0x99, 0xe5, 0xd2, 0x80,
- 0xb6, 0xb4, 0xc3, 0x8c, 0xa5, 0x29, 0xb3, 0xbd, 0xf0, 0x1e, 0x5a, 0x6e, 0xf9, 0xf1, 0x06, 0x33,
- 0xb6, 0xc9, 0x6c, 0x2f, 0x78, 0x4e, 0x56, 0x99, 0xb0, 0xa0, 0x8b, 0x0d, 0xb4, 0x83, 0x14, 0x68,
- 0x17, 0x24, 0x68, 0x26, 0x46, 0xeb, 0x5c, 0x46, 0xeb, 0x32, 0x82, 0x7e, 0xf7, 0x0e, 0x06, 0x29,
- 0xfc, 0xc9, 0x53, 0xc5, 0x5a, 0x7f, 0x4a, 0x02, 0x33, 0x90, 0x51, 0x4f, 0x2b, 0xa9, 0x32, 0x43,
- 0x23, 0x95, 0xb8, 0x1b, 0xb8, 0xea, 0x9b, 0x67, 0x4c, 0xa9, 0xa3, 0x10, 0x3c, 0x24, 0xb7, 0x7d,
- 0x3c, 0x35, 0xd0, 0xc7, 0x8a, 0x84, 0x35, 0x64, 0x67, 0xfc, 0x70, 0x1b, 0xfa, 0xae, 0x10, 0xc1,
- 0x01, 0x79, 0x94, 0x73, 0x99, 0xe4, 0xfd, 0x0c, 0xe8, 0x19, 0xb7, 0x3d, 0x95, 0x59, 0xbf, 0x19,
- 0x6e, 0x77, 0x8d, 0xd5, 0x8c, 0x4b, 0x6b, 0xc2, 0x55, 0xf4, 0xdf, 0xf7, 0xf8, 0x21, 0xd2, 0x47,
- 0x1e, 0xc6, 0x6d, 0xa9, 0x5f, 0xa3, 0xc1, 0xef, 0xc9, 0x92, 0xb1, 0xd9, 0x31, 0x8d, 0x98, 0x65,
- 0x42, 0x75, 0x3f, 0x6f, 0xf9, 0x35, 0x4c, 0x0a, 0x1d, 0x52, 0xf7, 0xc4, 0x64, 0xe7, 0xbf, 0x25,
- 0x0f, 0xe0, 0x3c, 0x05, 0xcd, 0x13, 0x90, 0x96, 0x09, 0xb7, 0xd8, 0x14, 0x6f, 0xe5, 0xbc, 0x8a,
- 0x1a, 0xce, 0x34, 0x77, 0xb7, 0xd4, 0x7d, 0xfc, 0x4a, 0x58, 0x1b, 0x87, 0xeb, 0x39, 0xeb, 0x0b,
- 0xd9, 0xca, 0xc9, 0xe0, 0x6f, 0xe4, 0x49, 0xa4, 0xd2, 0xc1, 0xe4, 0x09, 0x3a, 0xeb, 0x81, 0xa4,
- 0x31, 0x70, 0x69, 0x41, 0x0b, 0x60, 0xa7, 0x6e, 0x0c, 0xa7, 0x1a, 0xae, 0xe3, 0x0c, 0x1f, 0x39,
- 0xcb, 0xf8, 0x49, 0x3a, 0xea, 0x81, 0xdc, 0x99, 0xe0, 0x71, 0xe2, 0xee, 0xe6, 0x2d, 0xaa, 0x6d,
- 0x35, 0xb0, 0x84, 0x6a, 0x70, 0x9d, 0x83, 0xaf, 0x72, 0xf8, 0xc0, 0x37, 0x53, 0x5e, 0x77, 0xd4,
- 0x5b, 0xd7, 0xb2, 0x7f, 0x5b, 0x4d, 0x26, 0xac, 0xa1, 0xc7, 0x59, 0xc7, 0x5d, 0xaf, 0x86, 0x5f,
- 0x40, 0xf8, 0xb0, 0x78, 0x5b, 0x51, 0xda, 0x46, 0xa5, 0xcd, 0x2f, 0xc0, 0xbd, 0x30, 0xa9, 0x56,
- 0x29, 0xeb, 0x32, 0xeb, 0xbe, 0x14, 0xd2, 0xcc, 0x52, 0x7c, 0x7e, 0xb9, 0xec, 0x86, 0x8f, 0x7c,
- 0xcf, 0x8f, 0xf4, 0x17, 0x4e, 0xde, 0xcf, 0xd5, 0xe0, 0x5f, 0x25, 0x32, 0x51, 0x2a, 0x7c, 0xf0,
- 0x4c, 0x5f, 0xe0, 0xdd, 0x85, 0x05, 0x49, 0x54, 0x0c, 0xe1, 0x06, 0x7e, 0x5e, 0x34, 0x86, 0x97,
- 0xb5, 0xda, 0xee, 0x18, 0xed, 0x9e, 0xbc, 0xf6, 0xdb, 0xbd, 0x66, 0xce, 0xbe, 0x56, 0x31, 0x5c,
- 0xfd, 0x7f, 0xa4, 0x55, 0x83, 0xcf, 0x00, 0xd3, 0x17, 0xe3, 0x40, 0xd0, 0x20, 0x33, 0x6e, 0x1e,
- 0xd4, 0x4d, 0x04, 0x7f, 0xff, 0x31, 0xfe, 0xfe, 0xda, 0xf0, 0xb2, 0x36, 0x9d, 0x07, 0xe6, 0xbf,
- 0x75, 0x3b, 0xff, 0x77, 0xf7, 0x1c, 0x22, 0xcc, 0x9e, 0x76, 0xc6, 0x76, 0x5f, 0x60, 0xce, 0x11,
- 0x59, 0x30, 0xa0, 0x39, 0x13, 0x54, 0x2a, 0x9d, 0x30, 0xc1, 0x2f, 0xb0, 0xbe, 0x3e, 0xf3, 0xc7,
- 0x98, 0xb9, 0x74, 0x75, 0x59, 0xab, 0xb4, 0x11, 0x7a, 0x33, 0xce, 0x60, 0x58, 0xc5, 0x7c, 0x59,
- 0x08, 0xf6, 0x49, 0x45, 0xc2, 0x19, 0x35, 0x51, 0x0f, 0x12, 0x46, 0xa3, 0x1e, 0x93, 0x5d, 0xd0,
- 0x3e, 0xf6, 0x09, 0xc6, 0x86, 0x57, 0x97, 0xb5, 0xf2, 0x1b, 0x38, 0x6b, 0x23, 0x51, 0xf7, 0x00,
- 0x66, 0x96, 0xe5, 0x17, 0x46, 0x5f, 0x7e, 0x7b, 0x63, 0x65, 0x76, 0x75, 0x7b, 0xeb, 0xfd, 0x7f,
- 0xaa, 0x53, 0xef, 0x87, 0xd5, 0xd2, 0x87, 0x61, 0xb5, 0xf4, 0x71, 0x58, 0x2d, 0xfd, 0x7b, 0x58,
- 0x2d, 0xfd, 0xf3, 0x53, 0x75, 0xea, 0xc3, 0xa7, 0xea, 0xd4, 0xc7, 0x4f, 0xd5, 0xa9, 0x77, 0x33,
- 0x13, 0xdf, 0xd5, 0xc7, 0xdf, 0xe1, 0x87, 0xf4, 0x2f, 0xfe, 0x1b, 0x00, 0x00, 0xff, 0xff, 0xe4,
- 0xaf, 0xd6, 0x25, 0xae, 0x0b, 0x00, 0x00,
+ // 1661 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x97, 0xdd, 0x72, 0x1b, 0xb7,
+ 0x15, 0xc7, 0xcd, 0x38, 0x49, 0x6d, 0xc8, 0xb4, 0x65, 0x44, 0x0e, 0x57, 0x92, 0x45, 0x4a, 0xb2,
+ 0x1d, 0x2b, 0x4d, 0x2a, 0xb5, 0xe9, 0xc7, 0xb8, 0xe9, 0x74, 0xda, 0x88, 0x12, 0x6b, 0xc7, 0x4e,
+ 0xa4, 0x2c, 0xe5, 0x78, 0x9a, 0x76, 0x06, 0x03, 0xed, 0x1e, 0x92, 0xa8, 0xb0, 0xc0, 0x12, 0xc0,
+ 0x4a, 0xa2, 0x2e, 0x3a, 0xd3, 0x37, 0xe8, 0x4c, 0xaf, 0xfb, 0x3e, 0xb9, 0xcc, 0x65, 0xae, 0x34,
+ 0xad, 0xfc, 0x16, 0xbe, 0xea, 0xe0, 0x60, 0x97, 0x1f, 0xb6, 0x92, 0xde, 0x89, 0xe7, 0xff, 0x3b,
+ 0xff, 0x05, 0x0e, 0x0e, 0x3e, 0x44, 0xb6, 0xec, 0x50, 0x6e, 0x59, 0xb0, 0x56, 0x68, 0x95, 0x72,
+ 0xc7, 0xf3, 0xc3, 0x2d, 0xa9, 0x13, 0x2e, 0x99, 0x56, 0x72, 0xc4, 0x4a, 0x81, 0x79, 0x65, 0x33,
+ 0x37, 0xda, 0x69, 0xba, 0x9c, 0xe8, 0xe4, 0xc8, 0x68, 0x9e, 0x0c, 0x36, 0xed, 0x50, 0x6e, 0xce,
+ 0xa4, 0x2e, 0x2d, 0xf4, 0x75, 0x5f, 0x23, 0xb7, 0xe5, 0xff, 0x0a, 0x29, 0xeb, 0xff, 0x88, 0xc8,
+ 0xc2, 0x33, 0x6f, 0xba, 0xa7, 0xe4, 0xa8, 0x1b, 0x12, 0x76, 0xb8, 0xe3, 0xf4, 0x63, 0x42, 0x2d,
+ 0x3f, 0x06, 0xe6, 0xf8, 0xa1, 0x04, 0xcb, 0x72, 0x03, 0x3d, 0x71, 0x1a, 0xd5, 0x56, 0x6b, 0x1b,
+ 0xd7, 0xe3, 0x79, 0xaf, 0x1c, 0xa0, 0xb0, 0x8f, 0x71, 0xfa, 0x17, 0xb2, 0xac, 0x73, 0x27, 0x32,
+ 0x71, 0x06, 0x86, 0xf5, 0x8e, 0x58, 0xc2, 0x6d, 0xc2, 0x53, 0xb0, 0x4c, 0x8a, 0x4c, 0xb8, 0xe8,
+ 0xad, 0xd5, 0xda, 0xc6, 0xd5, 0xed, 0xbb, 0x17, 0xe7, 0xad, 0x68, 0xaf, 0xc2, 0x3a, 0x4f, 0xdb,
+ 0x25, 0xf4, 0xcc, 0x33, 0x71, 0x34, 0x36, 0xe8, 0x1c, 0xcd, 0x28, 0xf4, 0x57, 0xe4, 0x86, 0x75,
+ 0x99, 0x63, 0x4e, 0x64, 0xa0, 0x0b, 0x17, 0x5d, 0x45, 0xb7, 0xdb, 0xaf, 0xce, 0x5b, 0x75, 0x1f,
+ 0xda, 0xdc, 0x29, 0x0c, 0x77, 0x42, 0xab, 0x78, 0xce, 0x63, 0x07, 0x81, 0xa2, 0x8f, 0x49, 0x43,
+ 0xa4, 0x12, 0x98, 0x50, 0xe3, 0x52, 0x55, 0x06, 0x6f, 0xff, 0x90, 0xc1, 0x82, 0xcf, 0x78, 0xa2,
+ 0xca, 0x3a, 0x54, 0x4e, 0x8c, 0xdc, 0xab, 0x9c, 0x9c, 0xe1, 0xca, 0xf2, 0xc4, 0xc3, 0x6f, 0xb8,
+ 0xbe, 0xf3, 0x43, 0xae, 0xad, 0xe0, 0x7a, 0x30, 0xc9, 0x7d, 0xed, 0x03, 0xbf, 0x21, 0x0d, 0xa5,
+ 0x9d, 0x48, 0x80, 0xa5, 0xc2, 0xe6, 0x92, 0xfb, 0xc5, 0x3d, 0x06, 0x23, 0xdc, 0x28, 0x7a, 0x77,
+ 0xb5, 0xb6, 0x51, 0x8f, 0xef, 0x04, 0x79, 0x27, 0xa8, 0xdd, 0x52, 0xa4, 0x9b, 0xe4, 0x3d, 0x03,
+ 0xda, 0xa4, 0x60, 0xd8, 0xdf, 0xb4, 0x50, 0x55, 0xb5, 0x7f, 0xe2, 0x07, 0x12, 0xdf, 0x2e, 0xa5,
+ 0xcf, 0xbd, 0x12, 0x0a, 0xf9, 0x73, 0xb2, 0x90, 0x42, 0x8f, 0x17, 0xd2, 0x31, 0x77, 0xaa, 0x58,
+ 0x6e, 0x84, 0xc6, 0x8f, 0x5c, 0xc3, 0x04, 0x5a, 0x6a, 0x07, 0xa7, 0x6a, 0xbf, 0x54, 0xe8, 0x2f,
+ 0xc8, 0x9d, 0xe9, 0x0c, 0x03, 0x3c, 0xc5, 0xee, 0x8b, 0xae, 0xaf, 0xd6, 0x36, 0xae, 0x4d, 0xa7,
+ 0xc4, 0xc0, 0x53, 0xdf, 0x43, 0x74, 0x9b, 0x34, 0xa7, 0x53, 0x0a, 0x0b, 0xac, 0xa7, 0xa5, 0xd4,
+ 0x27, 0x60, 0x30, 0xdf, 0x46, 0x04, 0x73, 0x97, 0x26, 0xb9, 0xcf, 0x2d, 0x74, 0x4a, 0xc4, 0xdb,
+ 0x58, 0xba, 0x47, 0xee, 0xe7, 0xdc, 0x38, 0xc1, 0xa5, 0x1c, 0xf9, 0x9a, 0x38, 0x23, 0x0e, 0x0b,
+ 0x07, 0x29, 0xcb, 0x25, 0x57, 0xd6, 0x47, 0x7c, 0xf3, 0xa5, 0xd1, 0x1c, 0x3a, 0xad, 0x8d, 0xd9,
+ 0x9d, 0x09, 0xba, 0xef, 0xc9, 0x9d, 0x12, 0xa4, 0x8f, 0xc8, 0xa4, 0xbd, 0x70, 0x48, 0x03, 0x61,
+ 0x9d, 0xee, 0x1b, 0x9e, 0xd9, 0xe8, 0x06, 0x9a, 0xbc, 0x3f, 0xd6, 0x9f, 0x5b, 0x78, 0x3c, 0x56,
+ 0xe9, 0x1f, 0xc9, 0xca, 0x6c, 0x66, 0x56, 0x48, 0x27, 0x58, 0xa2, 0x25, 0xb3, 0x8e, 0x3b, 0x1b,
+ 0xd5, 0x31, 0x7d, 0x71, 0x3a, 0xfd, 0x0b, 0x8f, 0xb4, 0xb5, 0xec, 0x7a, 0x80, 0x7e, 0x4a, 0x16,
+ 0x71, 0xdb, 0x0a, 0x37, 0x62, 0x15, 0x95, 0x32, 0x0b, 0xdc, 0x24, 0x83, 0xe8, 0x26, 0x66, 0x37,
+ 0x2a, 0xa0, 0xda, 0x1d, 0x69, 0x17, 0x65, 0xba, 0x46, 0x6e, 0x58, 0xde, 0x03, 0x56, 0xe4, 0x29,
+ 0x77, 0x60, 0xa3, 0x5b, 0x88, 0xcf, 0xf9, 0xd8, 0xf3, 0x10, 0xa2, 0x7f, 0x26, 0xcb, 0x7e, 0x73,
+ 0x82, 0x61, 0x52, 0xeb, 0xa3, 0x22, 0x2f, 0x5b, 0xa1, 0xa7, 0xfd, 0x46, 0xb4, 0xd1, 0xbc, 0xcf,
+ 0xd8, 0x5e, 0xbe, 0x38, 0x6f, 0x35, 0xf6, 0x11, 0x7b, 0x86, 0x14, 0x76, 0x45, 0x47, 0x9b, 0xce,
+ 0x53, 0x1b, 0x37, 0xf2, 0xcb, 0x84, 0x23, 0xeb, 0xfb, 0xeb, 0x4c, 0xf4, 0xcf, 0x78, 0x1f, 0x3d,
+ 0x19, 0xa8, 0x50, 0xf5, 0xdb, 0x38, 0x88, 0xdb, 0x41, 0xf2, 0xfc, 0x6e, 0x10, 0xe8, 0x67, 0x64,
+ 0xc5, 0xc0, 0xb0, 0x10, 0x06, 0x18, 0x9c, 0xe6, 0x52, 0x24, 0xc2, 0xf9, 0x26, 0xcb, 0xb8, 0x19,
+ 0xb1, 0x23, 0x18, 0xd9, 0x88, 0x86, 0x95, 0x2f, 0xa1, 0xdd, 0x92, 0xd9, 0x0f, 0xc8, 0x53, 0x18,
+ 0x59, 0xbf, 0x15, 0x7a, 0xda, 0x24, 0xc0, 0xfc, 0x11, 0x93, 0x6b, 0xa1, 0x1c, 0x33, 0x60, 0x1d,
+ 0x37, 0x2e, 0x7a, 0x0f, 0x93, 0xef, 0xa0, 0xdc, 0xad, 0xd4, 0x38, 0x88, 0xf4, 0x11, 0x59, 0xe4,
+ 0xbe, 0x83, 0xfc, 0x41, 0x95, 0x73, 0x03, 0x8c, 0x5b, 0x5f, 0x6c, 0x6c, 0x98, 0x68, 0x21, 0x64,
+ 0x22, 0xb0, 0x1f, 0xf4, 0xcf, 0xec, 0x5e, 0xee, 0x7c, 0x8f, 0xf8, 0x49, 0x3a, 0xc8, 0xf2, 0xea,
+ 0xa0, 0xab, 0x26, 0x79, 0x27, 0x4c, 0xd2, 0x4b, 0xe1, 0xa4, 0xab, 0x26, 0xb9, 0x47, 0xee, 0x8b,
+ 0xac, 0x9c, 0x5c, 0xa2, 0x65, 0x91, 0x29, 0x86, 0xfd, 0xe7, 0xf7, 0xb5, 0x50, 0xfd, 0xb1, 0xc1,
+ 0xfb, 0xa1, 0x37, 0x2b, 0xb6, 0x8d, 0xe8, 0xfe, 0x14, 0x59, 0x19, 0xfe, 0x9a, 0x34, 0x52, 0xa3,
+ 0x73, 0x06, 0xaa, 0xc8, 0xd8, 0x31, 0x97, 0x05, 0x8c, 0x3d, 0x1a, 0xe8, 0xb1, 0xe0, 0xe5, 0x5d,
+ 0x55, 0x64, 0x5f, 0x7b, 0xb1, 0x4a, 0x7b, 0x41, 0x3e, 0xd4, 0xc7, 0x60, 0x8c, 0x48, 0xab, 0x9e,
+ 0x34, 0xd0, 0xf7, 0xe7, 0xd1, 0x99, 0x56, 0xc0, 0x12, 0xad, 0x7a, 0x62, 0x32, 0x98, 0x08, 0x8d,
+ 0xee, 0x57, 0x09, 0xd8, 0xa0, 0x31, 0xe2, 0xdf, 0x68, 0x05, 0x6d, 0x84, 0x2b, 0xe3, 0x3f, 0x90,
+ 0xbb, 0x03, 0x6e, 0x07, 0xcc, 0x0e, 0xb8, 0x49, 0x21, 0x65, 0x42, 0xa5, 0x70, 0x3a, 0x55, 0x99,
+ 0xc5, 0xd0, 0xf0, 0x9e, 0xe9, 0x06, 0xe4, 0x49, 0x20, 0x2a, 0x83, 0xdf, 0x92, 0x45, 0xbf, 0x43,
+ 0x71, 0x39, 0x7a, 0x85, 0x94, 0xa1, 0xb4, 0xcc, 0x26, 0x5c, 0xd9, 0x68, 0x29, 0xec, 0xb6, 0x0a,
+ 0xe8, 0x14, 0x52, 0x62, 0x7d, 0xbb, 0x5e, 0xa5, 0xbf, 0x23, 0x4b, 0xe3, 0xe2, 0x5a, 0x90, 0x90,
+ 0x38, 0x6c, 0xe4, 0xd0, 0xfe, 0xd1, 0x72, 0xd8, 0x2c, 0x15, 0xd1, 0x45, 0xa0, 0xa3, 0x4d, 0xd8,
+ 0x0a, 0x74, 0x83, 0xcc, 0x0b, 0x65, 0xc1, 0x38, 0xd6, 0xe3, 0xd6, 0xb1, 0x9c, 0xbb, 0x41, 0x74,
+ 0x17, 0x53, 0x6e, 0x86, 0x78, 0x87, 0x5b, 0xb7, 0xcf, 0xdd, 0x80, 0x3e, 0x26, 0x6b, 0x5c, 0x3a,
+ 0x30, 0xd5, 0x02, 0xba, 0x51, 0x0e, 0xac, 0x0f, 0x0a, 0x0c, 0x97, 0xe3, 0x79, 0xae, 0x60, 0xea,
+ 0x0a, 0x82, 0x61, 0xf5, 0x0e, 0x46, 0x39, 0xfc, 0x29, 0x50, 0xd5, 0x5c, 0x7f, 0x46, 0xa8, 0x1d,
+ 0xa9, 0x64, 0x60, 0xb4, 0xd2, 0x85, 0x65, 0x89, 0xce, 0xfc, 0x09, 0xdc, 0x0c, 0xcd, 0x33, 0xa5,
+ 0xb4, 0x51, 0xa0, 0x1f, 0x90, 0x5b, 0xc1, 0x9e, 0x59, 0x18, 0x62, 0x45, 0xa2, 0x16, 0xb2, 0xf5,
+ 0x10, 0xee, 0xc2, 0xd0, 0x17, 0x82, 0x1e, 0x90, 0x87, 0x25, 0x57, 0x28, 0x31, 0x2c, 0x80, 0x9d,
+ 0x08, 0x37, 0xd0, 0x85, 0x0b, 0x8b, 0xe1, 0x57, 0xd7, 0x3a, 0xc3, 0x85, 0x72, 0x36, 0x5a, 0xc3,
+ 0xfc, 0x7b, 0x01, 0x7f, 0x8e, 0xf4, 0x8b, 0x00, 0xe3, 0xb2, 0xb4, 0x27, 0x28, 0xfd, 0x3d, 0x59,
+ 0xb6, 0xae, 0x38, 0x64, 0x09, 0x77, 0x5c, 0xea, 0xfe, 0xeb, 0x2d, 0xbf, 0x8e, 0x4e, 0x91, 0x47,
+ 0xda, 0x81, 0x98, 0xed, 0xfc, 0xaf, 0xc8, 0x03, 0x38, 0xcd, 0xc1, 0x88, 0x0c, 0x94, 0xe3, 0xd2,
+ 0x4f, 0x36, 0xc7, 0x53, 0xb9, 0xac, 0xa2, 0x81, 0x13, 0x23, 0xfc, 0x29, 0x75, 0x0f, 0x5f, 0x09,
+ 0xeb, 0xd3, 0x70, 0xbb, 0x64, 0x43, 0x21, 0xe3, 0x92, 0xa4, 0x7f, 0x25, 0x1f, 0x25, 0x3a, 0x1f,
+ 0xcd, 0xee, 0xa0, 0x93, 0x01, 0x28, 0x96, 0x82, 0x50, 0x0e, 0x8c, 0x04, 0x7e, 0xec, 0x63, 0x38,
+ 0xd4, 0xe8, 0x3e, 0x8e, 0xf0, 0xa1, 0x4f, 0x99, 0xde, 0x49, 0x2f, 0x06, 0xa0, 0x76, 0x66, 0x78,
+ 0x1c, 0xb8, 0x3f, 0x79, 0xab, 0x6a, 0x3b, 0x03, 0x3c, 0x63, 0x06, 0x7c, 0xe7, 0xe0, 0xad, 0x1c,
+ 0x3d, 0x08, 0xcd, 0x54, 0xd6, 0x1d, 0xf5, 0x78, 0x22, 0x87, 0xbb, 0xd5, 0x16, 0xd2, 0x59, 0x76,
+ 0x58, 0xf4, 0xfc, 0xf1, 0x6a, 0xc5, 0x19, 0x44, 0x1f, 0x54, 0x77, 0x2b, 0x4a, 0xdb, 0xa8, 0x74,
+ 0xc5, 0x19, 0xf8, 0x1b, 0x26, 0x37, 0x3a, 0xe7, 0x7d, 0xee, 0xfc, 0x4b, 0x21, 0x2f, 0x1c, 0xc3,
+ 0xeb, 0x57, 0xa8, 0x7e, 0xf4, 0x30, 0xf4, 0xfc, 0x58, 0x7f, 0xe2, 0xe5, 0xbd, 0x52, 0xa5, 0xff,
+ 0xaa, 0x91, 0x99, 0x52, 0xe1, 0x85, 0x67, 0x87, 0x12, 0xcf, 0x2e, 0x2c, 0x48, 0xa6, 0x53, 0x88,
+ 0x36, 0xf0, 0x79, 0xd1, 0xb9, 0x38, 0x6f, 0xb5, 0x76, 0xa7, 0x68, 0x7f, 0xe5, 0x75, 0xbf, 0x7a,
+ 0xb6, 0x5f, 0xb2, 0x5f, 0xe8, 0x14, 0x5e, 0xfd, 0x7f, 0x24, 0x6e, 0xc1, 0x6b, 0x80, 0x1d, 0xca,
+ 0x69, 0x80, 0x76, 0x48, 0xdd, 0x8f, 0x83, 0xf9, 0x81, 0xe0, 0xf7, 0x3f, 0xc4, 0xef, 0xaf, 0x5f,
+ 0x9c, 0xb7, 0xe6, 0x4a, 0xc3, 0xf2, 0x5b, 0xb7, 0xca, 0x9f, 0xbb, 0xa7, 0x90, 0xa0, 0xf7, 0x9c,
+ 0x4f, 0xec, 0x0e, 0x25, 0xfa, 0xbc, 0x20, 0x8b, 0x16, 0x8c, 0xe0, 0x92, 0x29, 0x6d, 0x32, 0x2e,
+ 0xc5, 0x19, 0xd6, 0x37, 0x78, 0xfe, 0x14, 0x3d, 0x97, 0x5f, 0x9d, 0xb7, 0x1a, 0x5d, 0x84, 0xbe,
+ 0x9c, 0x66, 0xd0, 0xac, 0x61, 0x2f, 0x17, 0xe8, 0x1e, 0x69, 0x28, 0x38, 0x61, 0x36, 0x19, 0x40,
+ 0xc6, 0x59, 0x32, 0xe0, 0xaa, 0x0f, 0x26, 0xd8, 0x7e, 0x84, 0xb6, 0xd1, 0xab, 0xf3, 0xd6, 0xc2,
+ 0x97, 0x70, 0xd2, 0x45, 0xa2, 0x1d, 0x00, 0xf4, 0x5c, 0x50, 0x97, 0x44, 0xe9, 0xdf, 0xc9, 0x4d,
+ 0x0b, 0xc3, 0x02, 0x54, 0x02, 0x2c, 0xe1, 0xc9, 0x00, 0xa2, 0x8f, 0x57, 0xaf, 0x6e, 0xcc, 0x7d,
+ 0xb2, 0xb3, 0xf9, 0x23, 0xcf, 0xea, 0xcd, 0xcb, 0x1e, 0xcf, 0x9b, 0xdd, 0xd2, 0xa7, 0xed, 0x6d,
+ 0x76, 0x95, 0x33, 0xa3, 0xf0, 0x2e, 0x9c, 0x89, 0xc7, 0x75, 0x3b, 0xfd, 0x73, 0x69, 0x48, 0xe8,
+ 0x9b, 0x79, 0x74, 0x9e, 0x5c, 0x3d, 0x82, 0x11, 0x3e, 0xbc, 0xeb, 0xb1, 0xff, 0x93, 0xee, 0x92,
+ 0x77, 0xf0, 0x96, 0xc0, 0x57, 0xf5, 0xdc, 0x27, 0x5b, 0x3f, 0x3a, 0xbc, 0x37, 0x1d, 0xe3, 0x90,
+ 0xfd, 0xe9, 0x5b, 0x8f, 0x6a, 0x9f, 0xbf, 0x7d, 0x6d, 0x75, 0x7e, 0x6d, 0xfd, 0xdf, 0xb5, 0x4b,
+ 0xbf, 0xfc, 0x80, 0xdc, 0xc4, 0x32, 0xa4, 0xec, 0x18, 0x8c, 0xb7, 0x2c, 0x07, 0x51, 0x0f, 0xd1,
+ 0xaf, 0x43, 0x90, 0xde, 0x23, 0xf5, 0xa4, 0x30, 0x06, 0x94, 0x63, 0x93, 0x61, 0x5d, 0x8d, 0x6f,
+ 0x94, 0x41, 0xbc, 0xb3, 0xe8, 0x5d, 0x72, 0x5d, 0xa8, 0xc4, 0x80, 0xef, 0xb7, 0xf0, 0x7e, 0x8f,
+ 0x27, 0x01, 0xba, 0x42, 0xc8, 0xf8, 0xee, 0xb3, 0xe1, 0x75, 0x1e, 0x5f, 0xaf, 0xee, 0x3b, 0xbb,
+ 0xbd, 0xf5, 0xed, 0x7f, 0x9b, 0x57, 0xbe, 0xbd, 0x68, 0xd6, 0xbe, 0xbb, 0x68, 0xd6, 0xbe, 0xbf,
+ 0x68, 0xd6, 0xfe, 0x73, 0xd1, 0xac, 0xfd, 0xf3, 0x65, 0xf3, 0xca, 0x77, 0x2f, 0x9b, 0x57, 0xbe,
+ 0x7f, 0xd9, 0xbc, 0xf2, 0x4d, 0x7d, 0x66, 0xd2, 0x87, 0xef, 0xe2, 0xff, 0x36, 0xbf, 0xfc, 0x5f,
+ 0x00, 0x00, 0x00, 0xff, 0xff, 0x7e, 0xe5, 0xb2, 0x03, 0x41, 0x0d, 0x00, 0x00,
}
func (m *LocalOnlySessionData) Marshal() (dAtA []byte, err error) {
@@ -326,6 +387,37 @@ func (m *LocalOnlySessionData) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
+ if len(m.SequenceCache) > 0 {
+ keysForSequenceCache := make([]uint32, 0, len(m.SequenceCache))
+ for k := range m.SequenceCache {
+ keysForSequenceCache = append(keysForSequenceCache, uint32(k))
+ }
+ github_com_gogo_protobuf_sortkeys.Uint32s(keysForSequenceCache)
+ for iNdEx := len(keysForSequenceCache) - 1; iNdEx >= 0; iNdEx-- {
+ v := m.SequenceCache[uint32(keysForSequenceCache[iNdEx])]
+ baseI := i
+ if v != nil {
+ {
+ size, err := v.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x12
+ }
+ i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(keysForSequenceCache[iNdEx]))
+ i--
+ dAtA[i] = 0x8
+ i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(baseI-i))
+ i--
+ dAtA[i] = 0x2
+ i--
+ dAtA[i] = 0xe2
+ }
+ }
if m.NewSchemaChangerMode != 0 {
i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.NewSchemaChangerMode))
i--
@@ -737,6 +829,49 @@ func (m *LocalOnlySessionData) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
+func (m *SequenceCacheEntry) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *SequenceCacheEntry) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *SequenceCacheEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.NumValues != 0 {
+ i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.NumValues))
+ i--
+ dAtA[i] = 0x20
+ }
+ if m.Increment != 0 {
+ i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.Increment))
+ i--
+ dAtA[i] = 0x18
+ }
+ if m.CurrentValue != 0 {
+ i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.CurrentValue))
+ i--
+ dAtA[i] = 0x10
+ }
+ if m.CachedVersion != 0 {
+ i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.CachedVersion))
+ i--
+ dAtA[i] = 0x8
+ }
+ return len(dAtA) - i, nil
+}
+
func encodeVarintLocalOnlySessionData(dAtA []byte, offset int, v uint64) int {
offset -= sovLocalOnlySessionData(v)
base := offset
@@ -882,6 +1017,40 @@ func (m *LocalOnlySessionData) Size() (n int) {
if m.NewSchemaChangerMode != 0 {
n += 2 + sovLocalOnlySessionData(uint64(m.NewSchemaChangerMode))
}
+ if len(m.SequenceCache) > 0 {
+ for k, v := range m.SequenceCache {
+ _ = k
+ _ = v
+ l = 0
+ if v != nil {
+ l = v.Size()
+ l += 1 + sovLocalOnlySessionData(uint64(l))
+ }
+ mapEntrySize := 1 + sovLocalOnlySessionData(uint64(k)) + l
+ n += mapEntrySize + 2 + sovLocalOnlySessionData(uint64(mapEntrySize))
+ }
+ }
+ return n
+}
+
+func (m *SequenceCacheEntry) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.CachedVersion != 0 {
+ n += 1 + sovLocalOnlySessionData(uint64(m.CachedVersion))
+ }
+ if m.CurrentValue != 0 {
+ n += 1 + sovLocalOnlySessionData(uint64(m.CurrentValue))
+ }
+ if m.Increment != 0 {
+ n += 1 + sovLocalOnlySessionData(uint64(m.Increment))
+ }
+ if m.NumValues != 0 {
+ n += 1 + sovLocalOnlySessionData(uint64(m.NumValues))
+ }
return n
}
@@ -1772,6 +1941,247 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
break
}
}
+ case 44:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field SequenceCache", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowLocalOnlySessionData
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthLocalOnlySessionData
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthLocalOnlySessionData
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.SequenceCache == nil {
+ m.SequenceCache = make(SequenceCache)
+ }
+ var mapkey uint32
+ var mapvalue *SequenceCacheEntry
+ for iNdEx < postIndex {
+ entryPreIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowLocalOnlySessionData
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ if fieldNum == 1 {
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowLocalOnlySessionData
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ mapkey |= uint32(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ } else if fieldNum == 2 {
+ var mapmsglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowLocalOnlySessionData
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ mapmsglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if mapmsglen < 0 {
+ return ErrInvalidLengthLocalOnlySessionData
+ }
+ postmsgIndex := iNdEx + mapmsglen
+ if postmsgIndex < 0 {
+ return ErrInvalidLengthLocalOnlySessionData
+ }
+ if postmsgIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ mapvalue = &SequenceCacheEntry{}
+ if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil {
+ return err
+ }
+ iNdEx = postmsgIndex
+ } else {
+ iNdEx = entryPreIndex
+ skippy, err := skipLocalOnlySessionData(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthLocalOnlySessionData
+ }
+ if (iNdEx + skippy) > postIndex {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+ m.SequenceCache[mapkey] = mapvalue
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipLocalOnlySessionData(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthLocalOnlySessionData
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *SequenceCacheEntry) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowLocalOnlySessionData
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: SequenceCacheEntry: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: SequenceCacheEntry: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field CachedVersion", wireType)
+ }
+ m.CachedVersion = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowLocalOnlySessionData
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.CachedVersion |= uint32(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 2:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field CurrentValue", wireType)
+ }
+ m.CurrentValue = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowLocalOnlySessionData
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.CurrentValue |= int64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 3:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Increment", wireType)
+ }
+ m.Increment = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowLocalOnlySessionData
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.Increment |= int64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 4:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field NumValues", wireType)
+ }
+ m.NumValues = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowLocalOnlySessionData
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.NumValues |= int64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
default:
iNdEx = preIndex
skippy, err := skipLocalOnlySessionData(dAtA[iNdEx:])
diff --git a/pkg/sql/sessiondatapb/local_only_session_data.proto b/pkg/sql/sessiondatapb/local_only_session_data.proto
index 12334796c103..d2d3b97f7fe1 100644
--- a/pkg/sql/sessiondatapb/local_only_session_data.proto
+++ b/pkg/sql/sessiondatapb/local_only_session_data.proto
@@ -165,6 +165,9 @@ message LocalOnlySessionData {
int64 serial_normalization_mode = 42 [(gogoproto.casttype)="SerialNormalizationMode"];
// NewSchemaChangerMode indicates whether to use the new schema changer.
int64 new_schema_changer_mode = 43 [(gogoproto.casttype)="NewSchemaChangerMode"];
+ // SequenceCache stores sequence values which have been cached using the
+ // CACHE sequence option.
+ map sequence_cache = 44 [(gogoproto.casttype)="SequenceCache"];
///////////////////////////////////////////////////////////////////////////
// WARNING: consider whether a session parameter you're adding needs to //
@@ -172,3 +175,19 @@ message LocalOnlySessionData {
// in the SessionData message instead. //
///////////////////////////////////////////////////////////////////////////
}
+
+// SequenceCacheEntry is an entry in a SequenceCache.
+message SequenceCacheEntry {
+ // CachedVersion stores the descpb.DescriptorVersion that cached values are associated with.
+ // The version is checked to determine if cache needs to be invalidated. The version is stored as
+ // a uint32 to prevent an import cycle with the descpb package.
+ uint32 cached_version = 1;
+ // CurrentValue stores the present value of the sequence to be given out.
+ int64 current_value = 2;
+ // Increment stores the amount to Increment the currentVal by each time the
+ // currentVal is used. This value corresponds to descpb.TableDescriptor_SequenceOpts.Increment.
+ int64 increment = 3;
+ // NumValues represents the number of values to cache. The cache is considered
+ // to be empty when NumValues is 0.
+ int64 num_values = 4;
+}
diff --git a/pkg/sql/sessiondata/sequence_cache.go b/pkg/sql/sessiondatapb/sequence_cache.go
similarity index 60%
rename from pkg/sql/sessiondata/sequence_cache.go
rename to pkg/sql/sessiondatapb/sequence_cache.go
index d3503b937b60..71bfddc966a9 100644
--- a/pkg/sql/sessiondata/sequence_cache.go
+++ b/pkg/sql/sessiondatapb/sequence_cache.go
@@ -8,7 +8,7 @@
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.
-package sessiondata
+package sessiondatapb
// SequenceCache stores sequence values that have already been created in KV
// and are available to be given out as sequence numbers. Values for sequences
@@ -20,22 +20,7 @@ package sessiondata
// new descriptor versions may not monotonically increase. For example, the sequence schema
// may be altered in a txn, so the cache sees a new version V and invalidates/repopulates itself. Then,
// the txn may get rolled back, so the cache will see version V-1 and invalidate/repopulate itself again.
-type SequenceCache map[uint32]*sequenceCacheEntry
-
-type sequenceCacheEntry struct {
- // cachedVersion stores the descpb.DescriptorVersion that cached values are associated with.
- // The version is checked to determine if cache needs to be invalidated. The version is stored as
- // a uint32 to prevent an import cycle with the descpb package.
- cachedVersion uint32
- // currentValue stores the present value of the sequence to be given out.
- currentValue int64
- // increment stores the amount to increment the currentVal by each time the
- // currentVal is used. This value corresponds to descpb.TableDescriptor_SequenceOpts.Increment.
- increment int64
- // numValues represents the number of values to cache. The cache is considered
- // to be empty when numValues is 0.
- numValues int64
-}
+type SequenceCache map[uint32]*SequenceCacheEntry
// NextValue fetches the next value in the sequence cache. If the values in the cache have all been
// given out or if the descriptor version has changed, then fetchNextValues() is used to repopulate the cache.
@@ -44,14 +29,14 @@ func (sc SequenceCache) NextValue(
) (int64, error) {
// Create entry for this sequence ID if there are no existing entries.
if _, found := sc[seqID]; !found {
- sc[seqID] = &sequenceCacheEntry{}
+ sc[seqID] = &SequenceCacheEntry{}
}
cacheEntry := sc[seqID]
- if cacheEntry.numValues > 0 && cacheEntry.cachedVersion == clientVersion {
- cacheEntry.currentValue += cacheEntry.increment
- cacheEntry.numValues--
- return cacheEntry.currentValue - cacheEntry.increment, nil
+ if cacheEntry.NumValues > 0 && cacheEntry.CachedVersion == clientVersion {
+ cacheEntry.CurrentValue += cacheEntry.Increment
+ cacheEntry.NumValues--
+ return cacheEntry.CurrentValue - cacheEntry.Increment, nil
}
currentValue, increment, numValues, err := fetchNextValues()
@@ -61,9 +46,9 @@ func (sc SequenceCache) NextValue(
// One value must be returned, and the rest of the values are stored.
val := currentValue
- cacheEntry.currentValue = currentValue + increment
- cacheEntry.increment = increment
- cacheEntry.numValues = numValues - 1
- cacheEntry.cachedVersion = clientVersion
+ cacheEntry.CurrentValue = currentValue + increment
+ cacheEntry.Increment = increment
+ cacheEntry.NumValues = numValues - 1
+ cacheEntry.CachedVersion = clientVersion
return val, nil
}
From 2a91d4ce45cec029c110889efb2c5b16e7af5158 Mon Sep 17 00:00:00 2001
From: Oliver Tan
Date: Fri, 20 Aug 2021 08:48:30 +1000
Subject: [PATCH 2/3] builtins: implement session serialization and
deserialization
Release note (sql change): Implement the
crdb_internal.serialize_session() and
crdb_internal.deserialize_session(bytes) builtins, the former outputs
the session settings in a string that can be deserialized into another
session by the latter.
---
docs/generated/sql/functions.md | 4 +
pkg/sql/BUILD.bazel | 1 +
pkg/sql/sem/builtins/BUILD.bazel | 1 +
pkg/sql/sem/builtins/builtins.go | 90 +++++
pkg/sql/session_migration_test.go | 135 +++++++
pkg/sql/sessiondata/session_data.go | 7 +
pkg/sql/sessiondatapb/BUILD.bazel | 1 +
pkg/sql/sessiondatapb/session_migration.pb.go | 361 ++++++++++++++++++
pkg/sql/sessiondatapb/session_migration.proto | 24 ++
pkg/sql/testdata/session_migration/errors | 31 ++
pkg/sql/testdata/session_migration/sequence | 38 ++
.../session_migration/session_migration | 55 +++
12 files changed, 748 insertions(+)
create mode 100644 pkg/sql/session_migration_test.go
create mode 100644 pkg/sql/sessiondatapb/session_migration.pb.go
create mode 100644 pkg/sql/sessiondatapb/session_migration.proto
create mode 100644 pkg/sql/testdata/session_migration/errors
create mode 100644 pkg/sql/testdata/session_migration/sequence
create mode 100644 pkg/sql/testdata/session_migration/session_migration
diff --git a/docs/generated/sql/functions.md b/docs/generated/sql/functions.md
index aac5ab83e788..ec8d6101f748 100644
--- a/docs/generated/sql/functions.md
+++ b/docs/generated/sql/functions.md
@@ -2801,6 +2801,8 @@ SELECT * FROM crdb_internal.check_consistency(true, ‘\x02’, ‘\x04’)
crdb_internal.create_join_token() → string | Creates a join token for use when adding a new node to a secure cluster.
|
+crdb_internal.deserialize_session(session: bytes) → bool | This function deserializes the serialized variables into the current session.
+ |
crdb_internal.encode_key(table_id: int, index_id: int, row_tuple: anyelement) → bytes | Generate the key for a row on a particular table and index.
|
crdb_internal.force_assertion_error(msg: string) → int | This function is used only by CockroachDB’s developers for testing purposes.
@@ -2864,6 +2866,8 @@ SELECT * FROM crdb_internal.check_consistency(true, ‘\x02’, ‘\x04’)
|
crdb_internal.round_decimal_values(val: decimal[], scale: int) → decimal[] | This function is used internally to round decimal array values during mutations.
|
+crdb_internal.serialize_session() → bytes | This function serializes the variables in the current session.
+ |
crdb_internal.set_trace_verbose(trace_id: int, verbosity: bool) → bool | Returns true if root span was found and verbosity was set, false otherwise.
|
crdb_internal.set_vmodule(vmodule_string: string) → int | Set the equivalent of the --vmodule flag on the gateway node processing this request; it affords control over the logging verbosity of different files. Example syntax: crdb_internal.set_vmodule('recordio=2,file=1,gfs*=3') . Reset with: crdb_internal.set_vmodule('') . Raising the verbosity can severely affect performance.
diff --git a/pkg/sql/BUILD.bazel b/pkg/sql/BUILD.bazel
index c5eb99b5a6d8..c79c17e3f5d0 100644
--- a/pkg/sql/BUILD.bazel
+++ b/pkg/sql/BUILD.bazel
@@ -483,6 +483,7 @@ go_test(
"schema_changer_test.go",
"scrub_test.go",
"sequence_test.go",
+ "session_migration_test.go",
"set_zone_config_test.go",
"show_create_all_tables_builtin_test.go",
"show_fingerprints_test.go",
diff --git a/pkg/sql/sem/builtins/BUILD.bazel b/pkg/sql/sem/builtins/BUILD.bazel
index 86e14cda1d8f..1910643c6d00 100644
--- a/pkg/sql/sem/builtins/BUILD.bazel
+++ b/pkg/sql/sem/builtins/BUILD.bazel
@@ -78,6 +78,7 @@ go_library(
"//pkg/util/json",
"//pkg/util/log",
"//pkg/util/mon",
+ "//pkg/util/protoutil",
"//pkg/util/ring",
"//pkg/util/syncutil",
"//pkg/util/timeofday",
diff --git a/pkg/sql/sem/builtins/builtins.go b/pkg/sql/sem/builtins/builtins.go
index 66ea0f7841a9..549defa2ffa9 100644
--- a/pkg/sql/sem/builtins/builtins.go
+++ b/pkg/sql/sem/builtins/builtins.go
@@ -71,6 +71,7 @@ import (
"github.com/cockroachdb/cockroach/pkg/util/ipaddr"
"github.com/cockroachdb/cockroach/pkg/util/json"
"github.com/cockroachdb/cockroach/pkg/util/log"
+ "github.com/cockroachdb/cockroach/pkg/util/protoutil"
"github.com/cockroachdb/cockroach/pkg/util/timeofday"
"github.com/cockroachdb/cockroach/pkg/util/timetz"
"github.com/cockroachdb/cockroach/pkg/util/timeutil"
@@ -5862,6 +5863,95 @@ table's zone configuration this will return NULL.`,
Volatility: tree.VolatilityVolatile,
},
),
+
+ "crdb_internal.serialize_session": makeBuiltin(
+ tree.FunctionProperties{
+ Category: categorySystemInfo,
+ },
+ tree.Overload{
+ Types: tree.ArgTypes{},
+ ReturnType: tree.FixedReturnType(types.Bytes),
+ Fn: func(evalCtx *tree.EvalContext, args tree.Datums) (tree.Datum, error) {
+ if !evalCtx.TxnImplicit {
+ return nil, pgerror.Newf(
+ pgcode.InvalidTransactionState,
+ "cannot serialize a session which is inside a transaction",
+ )
+ }
+
+ sd := evalCtx.SessionData
+ if sd == nil {
+ return nil, pgerror.Newf(
+ pgcode.InvalidTransactionState,
+ "no session is active",
+ )
+ }
+
+ if len(sd.DatabaseIDToTempSchemaID) > 0 {
+ return nil, pgerror.Newf(
+ pgcode.InvalidTransactionState,
+ "cannot serialize session with temporary schemas",
+ )
+ }
+
+ var m sessiondatapb.MigratableSession
+ m.SessionData = sd.SessionData
+ sessiondata.MarshalNonLocal(sd, &m.SessionData)
+ m.LocalOnlySessionData = sd.LocalOnlySessionData
+
+ b, err := protoutil.Marshal(&m)
+ if err != nil {
+ return nil, err
+ }
+ return tree.NewDBytes(tree.DBytes(b)), nil
+ },
+ Info: `This function serializes the variables in the current session.`,
+ Volatility: tree.VolatilityVolatile,
+ },
+ ),
+
+ "crdb_internal.deserialize_session": makeBuiltin(
+ tree.FunctionProperties{
+ Category: categorySystemInfo,
+ },
+ tree.Overload{
+ Types: tree.ArgTypes{{"session", types.Bytes}},
+ ReturnType: tree.FixedReturnType(types.Bool),
+ Fn: func(evalCtx *tree.EvalContext, args tree.Datums) (tree.Datum, error) {
+ if !evalCtx.TxnImplicit {
+ return nil, pgerror.Newf(
+ pgcode.InvalidTransactionState,
+ "cannot deserialize a session which is inside a transaction",
+ )
+ }
+
+ var m sessiondatapb.MigratableSession
+ if err := protoutil.Unmarshal([]byte(tree.MustBeDBytes(args[0])), &m); err != nil {
+ return nil, pgerror.WithCandidateCode(
+ errors.Wrapf(err, "error deserializing session"),
+ pgcode.InvalidParameterValue,
+ )
+ }
+ sd, err := sessiondata.UnmarshalNonLocal(m.SessionData)
+ if err != nil {
+ return nil, err
+ }
+ sd.SessionData = m.SessionData
+ sd.LocalUnmigratableSessionData = evalCtx.SessionData.LocalUnmigratableSessionData
+ sd.LocalOnlySessionData = m.LocalOnlySessionData
+ if sd.SessionUser().Normalized() != evalCtx.SessionData.SessionUser().Normalized() {
+ return nil, pgerror.Newf(
+ pgcode.InsufficientPrivilege,
+ "can only serialize matching session users",
+ )
+ }
+ *evalCtx.SessionData = *sd
+ return tree.MakeDBool(true), nil
+ },
+ Info: `This function deserializes the serialized variables into the current session.`,
+ Volatility: tree.VolatilityVolatile,
+ },
+ ),
}
var lengthImpls = func(incBitOverload bool) builtinDefinition {
diff --git a/pkg/sql/session_migration_test.go b/pkg/sql/session_migration_test.go
new file mode 100644
index 000000000000..b9eeee6644d1
--- /dev/null
+++ b/pkg/sql/session_migration_test.go
@@ -0,0 +1,135 @@
+// Copyright 2021 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 sql_test
+
+import (
+ "context"
+ gosql "database/sql"
+ "fmt"
+ "strings"
+ "testing"
+
+ "github.com/cockroachdb/cockroach/pkg/base"
+ "github.com/cockroachdb/cockroach/pkg/testutils/serverutils"
+ "github.com/cockroachdb/cockroach/pkg/testutils/sqlutils"
+ "github.com/cockroachdb/cockroach/pkg/testutils/testcluster"
+ "github.com/cockroachdb/cockroach/pkg/util/leaktest"
+ "github.com/cockroachdb/cockroach/pkg/util/log"
+ "github.com/cockroachdb/datadriven"
+ "github.com/stretchr/testify/require"
+)
+
+// TestSessionMigration tests migrating a session as a data driven test.
+// It supports the following directives:
+// * reset: resets the connection.
+// * exec: executes a SQL command
+// * query: executes a SQL command and returns the output
+// * dump_vars: dumps variables into a variable called with the given input.
+// * compare_vars: compares two dumped variables.
+func TestSessionMigration(t *testing.T) {
+ defer leaktest.AfterTest(t)()
+ defer log.Scope(t).Close(t)
+
+ ctx := context.Background()
+ datadriven.Walk(t, "testdata/session_migration", func(t *testing.T, path string) {
+ tc := testcluster.StartTestCluster(t, 1, base.TestClusterArgs{})
+ defer tc.Stopper().Stop(ctx)
+
+ openConnFunc := func() *gosql.DB {
+ return serverutils.OpenDBConn(
+ t,
+ tc.Server(0).ServingSQLAddr(),
+ "defaultdb", /* database */
+ false, /* insecure */
+ tc.Server(0).Stopper(),
+ )
+ }
+ dbConn := openConnFunc()
+ defer func() {
+ _ = dbConn.Close()
+ }()
+
+ vars := make(map[string]string)
+ datadriven.RunTest(t, path, func(t *testing.T, d *datadriven.TestData) string {
+ getQuery := func() string {
+ q := d.Input
+ for k, v := range vars {
+ q = strings.ReplaceAll(q, k, v)
+ }
+ return q
+ }
+ switch d.Cmd {
+ case "reset":
+ require.NoError(t, dbConn.Close())
+ dbConn = openConnFunc()
+ return ""
+ case "exec":
+ _, err := dbConn.Exec(getQuery())
+ if err != nil {
+ return err.Error()
+ }
+ return ""
+ case "dump_vars":
+ require.NotEmpty(t, d.Input, "expected table name")
+ _, err := dbConn.Exec(fmt.Sprintf("CREATE TABLE %s AS SELECT * FROM [SHOW ALL]", d.Input))
+ require.NoError(t, err)
+ return ""
+ case "compare_vars":
+ tables := strings.Split(d.Input, "\n")
+ require.Len(t, tables, 2, "require 2 tables to compare against")
+
+ q := `SELECT dump.variable, dump.value, dump2.variable, dump2.value
+FROM dump
+FULL OUTER JOIN dump2
+ON ( dump.variable = dump2.variable )
+WHERE dump.variable IS NULL OR dump2.variable IS NULL OR dump.variable != dump2.variable`
+ for _, repl := range []struct {
+ from string
+ to string
+ }{
+ {"dump2", tables[1]},
+ {"dump", tables[0]},
+ } {
+ q = strings.ReplaceAll(q, repl.from, repl.to)
+ }
+ rows, err := dbConn.Query(q)
+ require.NoError(t, err)
+ ret, err := sqlutils.RowsToDataDrivenOutput(rows)
+ require.NoError(t, err)
+ return ret
+ case "query":
+ q := d.Input
+ for k, v := range vars {
+ q = strings.ReplaceAll(q, k, v)
+ }
+ rows, err := dbConn.Query(getQuery())
+ if err != nil {
+ return err.Error()
+ }
+ ret, err := sqlutils.RowsToDataDrivenOutput(rows)
+ require.NoError(t, err)
+ return ret
+ case "let":
+ row := dbConn.QueryRow(getQuery())
+ var v string
+ require.NoError(t, row.Err())
+ require.NoError(t, row.Scan(&v))
+ require.Len(t, d.CmdArgs, 1, "only one argument permitted for let")
+ for _, arg := range d.CmdArgs {
+ vars[arg.Key] = v
+ }
+ return ""
+ }
+ t.Fatalf("unknown command: %s", d.Cmd)
+ return "unexpected"
+ })
+ })
+}
diff --git a/pkg/sql/sessiondata/session_data.go b/pkg/sql/sessiondata/session_data.go
index 5eefb1da406d..80f1d90883ec 100644
--- a/pkg/sql/sessiondata/session_data.go
+++ b/pkg/sql/sessiondata/session_data.go
@@ -14,6 +14,7 @@ import (
"net"
"time"
+ "github.com/cockroachdb/cockroach/pkg/security"
"github.com/cockroachdb/cockroach/pkg/sql/sessiondatapb"
"github.com/cockroachdb/cockroach/pkg/util/duration"
"github.com/cockroachdb/cockroach/pkg/util/timeutil"
@@ -125,6 +126,12 @@ func (s *SessionData) GetDateStyle() pgdate.DateStyle {
return s.DataConversionConfig.DateStyle
}
+// SessionUser retrieves the session_user.
+// This currently returns current_user, as session_user is not implemented.
+func (s *SessionData) SessionUser() security.SQLUsername {
+ return s.User()
+}
+
// LocalUnmigratableSessionData contains session parameters that cannot
// be propagated to remote nodes and cannot be migrated to another
// session.
diff --git a/pkg/sql/sessiondatapb/BUILD.bazel b/pkg/sql/sessiondatapb/BUILD.bazel
index 84bf5fc888ab..9cde792673dc 100644
--- a/pkg/sql/sessiondatapb/BUILD.bazel
+++ b/pkg/sql/sessiondatapb/BUILD.bazel
@@ -20,6 +20,7 @@ proto_library(
srcs = [
"local_only_session_data.proto",
"session_data.proto",
+ "session_migration.proto",
],
strip_import_prefix = "/pkg",
visibility = ["//visibility:public"],
diff --git a/pkg/sql/sessiondatapb/session_migration.pb.go b/pkg/sql/sessiondatapb/session_migration.pb.go
new file mode 100644
index 000000000000..52819c005e13
--- /dev/null
+++ b/pkg/sql/sessiondatapb/session_migration.pb.go
@@ -0,0 +1,361 @@
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: sql/sessiondatapb/session_migration.proto
+
+package sessiondatapb
+
+import (
+ fmt "fmt"
+ _ "github.com/gogo/protobuf/gogoproto"
+ proto "github.com/gogo/protobuf/proto"
+ io "io"
+ math "math"
+ math_bits "math/bits"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
+
+// MigratableSession represents a serialization of a session that can be
+// migrated between SQL sessions.
+type MigratableSession struct {
+ SessionData SessionData `protobuf:"bytes,1,opt,name=session_data,json=sessionData,proto3" json:"session_data"`
+ LocalOnlySessionData LocalOnlySessionData `protobuf:"bytes,2,opt,name=local_only_session_data,json=localOnlySessionData,proto3" json:"local_only_session_data"`
+}
+
+func (m *MigratableSession) Reset() { *m = MigratableSession{} }
+func (m *MigratableSession) String() string { return proto.CompactTextString(m) }
+func (*MigratableSession) ProtoMessage() {}
+func (*MigratableSession) Descriptor() ([]byte, []int) {
+ return fileDescriptor_e44b77d7af899ce0, []int{0}
+}
+func (m *MigratableSession) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *MigratableSession) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+}
+func (m *MigratableSession) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_MigratableSession.Merge(m, src)
+}
+func (m *MigratableSession) XXX_Size() int {
+ return m.Size()
+}
+func (m *MigratableSession) XXX_DiscardUnknown() {
+ xxx_messageInfo_MigratableSession.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_MigratableSession proto.InternalMessageInfo
+
+func init() {
+ proto.RegisterType((*MigratableSession)(nil), "cockroach.sql.sessiondatapb.MigratableSession")
+}
+
+func init() {
+ proto.RegisterFile("sql/sessiondatapb/session_migration.proto", fileDescriptor_e44b77d7af899ce0)
+}
+
+var fileDescriptor_e44b77d7af899ce0 = []byte{
+ // 239 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x2c, 0x2e, 0xcc, 0xd1,
+ 0x2f, 0x4e, 0x2d, 0x2e, 0xce, 0xcc, 0xcf, 0x4b, 0x49, 0x2c, 0x49, 0x2c, 0x48, 0x82, 0xf1, 0xe2,
+ 0x73, 0x33, 0xd3, 0x8b, 0x12, 0x4b, 0x32, 0xf3, 0xf3, 0xf4, 0x0a, 0x8a, 0xf2, 0x4b, 0xf2, 0x85,
+ 0xa4, 0x93, 0xf3, 0x93, 0xb3, 0x8b, 0xf2, 0x13, 0x93, 0x33, 0xf4, 0x8a, 0x0b, 0x73, 0xf4, 0x50,
+ 0x34, 0x49, 0x89, 0xa4, 0xe7, 0xa7, 0xe7, 0x83, 0xd5, 0xe9, 0x83, 0x58, 0x10, 0x2d, 0x52, 0x2a,
+ 0xb8, 0x4d, 0x07, 0x71, 0xa1, 0xaa, 0xf4, 0x31, 0x55, 0xe5, 0xe4, 0x27, 0x27, 0xe6, 0xc4, 0xe7,
+ 0xe7, 0xe5, 0x54, 0xc6, 0x63, 0x6a, 0x50, 0xba, 0xc6, 0xc8, 0x25, 0xe8, 0x0b, 0x76, 0x5d, 0x62,
+ 0x52, 0x4e, 0x6a, 0x30, 0x44, 0x81, 0x50, 0x20, 0x17, 0x0f, 0xb2, 0x5a, 0x09, 0x46, 0x05, 0x46,
+ 0x0d, 0x6e, 0x23, 0x0d, 0x3d, 0x3c, 0xce, 0xd6, 0x83, 0xea, 0x75, 0x49, 0x2c, 0x49, 0x74, 0x62,
+ 0x39, 0x71, 0x4f, 0x9e, 0x21, 0x88, 0xbb, 0x18, 0x21, 0x24, 0x94, 0xc7, 0x25, 0x8e, 0xc3, 0x25,
+ 0x12, 0x4c, 0x60, 0xd3, 0x0d, 0xf1, 0x9a, 0xee, 0x03, 0xd2, 0xeb, 0x9f, 0x97, 0x53, 0x89, 0x69,
+ 0x8d, 0x48, 0x0e, 0x36, 0x39, 0xfd, 0x13, 0x0f, 0xe5, 0x18, 0x4e, 0x3c, 0x92, 0x63, 0xbc, 0xf0,
+ 0x48, 0x8e, 0xf1, 0xc6, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8,
+ 0xf0, 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, 0x86, 0x28, 0x5e, 0x14, 0x1b, 0x92, 0xd8, 0xc0, 0x01,
+ 0x62, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x9a, 0xec, 0xc3, 0xcb, 0xc7, 0x01, 0x00, 0x00,
+}
+
+func (m *MigratableSession) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *MigratableSession) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *MigratableSession) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ {
+ size, err := m.LocalOnlySessionData.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintSessionMigration(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x12
+ {
+ size, err := m.SessionData.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintSessionMigration(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ return len(dAtA) - i, nil
+}
+
+func encodeVarintSessionMigration(dAtA []byte, offset int, v uint64) int {
+ offset -= sovSessionMigration(v)
+ base := offset
+ for v >= 1<<7 {
+ dAtA[offset] = uint8(v&0x7f | 0x80)
+ v >>= 7
+ offset++
+ }
+ dAtA[offset] = uint8(v)
+ return base
+}
+func (m *MigratableSession) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = m.SessionData.Size()
+ n += 1 + l + sovSessionMigration(uint64(l))
+ l = m.LocalOnlySessionData.Size()
+ n += 1 + l + sovSessionMigration(uint64(l))
+ return n
+}
+
+func sovSessionMigration(x uint64) (n int) {
+ return (math_bits.Len64(x|1) + 6) / 7
+}
+func sozSessionMigration(x uint64) (n int) {
+ return sovSessionMigration(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (m *MigratableSession) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowSessionMigration
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: MigratableSession: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: MigratableSession: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field SessionData", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowSessionMigration
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthSessionMigration
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthSessionMigration
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if err := m.SessionData.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field LocalOnlySessionData", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowSessionMigration
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthSessionMigration
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthSessionMigration
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if err := m.LocalOnlySessionData.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipSessionMigration(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthSessionMigration
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func skipSessionMigration(dAtA []byte) (n int, err error) {
+ l := len(dAtA)
+ iNdEx := 0
+ depth := 0
+ for iNdEx < l {
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return 0, ErrIntOverflowSessionMigration
+ }
+ if iNdEx >= l {
+ return 0, io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= (uint64(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ wireType := int(wire & 0x7)
+ switch wireType {
+ case 0:
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return 0, ErrIntOverflowSessionMigration
+ }
+ if iNdEx >= l {
+ return 0, io.ErrUnexpectedEOF
+ }
+ iNdEx++
+ if dAtA[iNdEx-1] < 0x80 {
+ break
+ }
+ }
+ case 1:
+ iNdEx += 8
+ case 2:
+ var length int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return 0, ErrIntOverflowSessionMigration
+ }
+ if iNdEx >= l {
+ return 0, io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ length |= (int(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if length < 0 {
+ return 0, ErrInvalidLengthSessionMigration
+ }
+ iNdEx += length
+ case 3:
+ depth++
+ case 4:
+ if depth == 0 {
+ return 0, ErrUnexpectedEndOfGroupSessionMigration
+ }
+ depth--
+ case 5:
+ iNdEx += 4
+ default:
+ return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
+ }
+ if iNdEx < 0 {
+ return 0, ErrInvalidLengthSessionMigration
+ }
+ if depth == 0 {
+ return iNdEx, nil
+ }
+ }
+ return 0, io.ErrUnexpectedEOF
+}
+
+var (
+ ErrInvalidLengthSessionMigration = fmt.Errorf("proto: negative length found during unmarshaling")
+ ErrIntOverflowSessionMigration = fmt.Errorf("proto: integer overflow")
+ ErrUnexpectedEndOfGroupSessionMigration = fmt.Errorf("proto: unexpected end of group")
+)
diff --git a/pkg/sql/sessiondatapb/session_migration.proto b/pkg/sql/sessiondatapb/session_migration.proto
new file mode 100644
index 000000000000..df33af03edf2
--- /dev/null
+++ b/pkg/sql/sessiondatapb/session_migration.proto
@@ -0,0 +1,24 @@
+// Copyright 2021 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.
+
+syntax = "proto3";
+package cockroach.sql.sessiondatapb;
+option go_package = "sessiondatapb";
+
+import "gogoproto/gogo.proto";
+import "sql/sessiondatapb/session_data.proto";
+import "sql/sessiondatapb/local_only_session_data.proto";
+
+// MigratableSession represents a serialization of a session that can be
+// migrated between SQL sessions.
+message MigratableSession {
+ cockroach.sql.sessiondatapb.SessionData session_data = 1 [(gogoproto.nullable)=false];
+ cockroach.sql.sessiondatapb.LocalOnlySessionData local_only_session_data = 2 [(gogoproto.nullable)=false];
+}
diff --git a/pkg/sql/testdata/session_migration/errors b/pkg/sql/testdata/session_migration/errors
new file mode 100644
index 000000000000..22d9a520f79a
--- /dev/null
+++ b/pkg/sql/testdata/session_migration/errors
@@ -0,0 +1,31 @@
+# This file contains error checks for session migration.
+
+exec
+SELECT crdb_internal.deserialize_session('invalid proto')
+----
+pq: crdb_internal.deserialize_session(): error deserializing session: unexpected EOF
+
+exec
+SET experimental_enable_temp_tables = true;
+CREATE TEMP TABLE temp_tbl()
+----
+
+query
+SELECT crdb_internal.serialize_session()
+----
+pq: crdb_internal.serialize_session(): cannot serialize session with temporary schemas
+
+reset
+----
+
+exec
+BEGIN
+----
+
+query
+SELECT crdb_internal.serialize_session()
+----
+pq: crdb_internal.serialize_session(): cannot serialize a session which is inside a transaction
+
+reset
+----
diff --git a/pkg/sql/testdata/session_migration/sequence b/pkg/sql/testdata/session_migration/sequence
new file mode 100644
index 000000000000..129d6fb274e7
--- /dev/null
+++ b/pkg/sql/testdata/session_migration/sequence
@@ -0,0 +1,38 @@
+exec
+SET serial_normalization = sql_sequence_cached;
+CREATE TABLE serial (
+ cached SERIAL
+);
+INSERT INTO serial (cached) VALUES (DEFAULT)
+----
+
+query
+SELECT pg_get_serial_sequence('serial', 'cached')
+----
+public.serial_cached_seq
+
+query
+SELECT * FROM serial ORDER BY cached
+----
+1
+
+let $x
+SELECT encode(crdb_internal.serialize_session(), 'hex')
+----
+
+reset
+----
+
+exec
+SELECT crdb_internal.deserialize_session(decode('$x', 'hex'))
+----
+
+exec
+INSERT INTO serial (cached) VALUES (DEFAULT)
+----
+
+query
+SELECT * FROM serial ORDER BY cached
+----
+1
+2
diff --git a/pkg/sql/testdata/session_migration/session_migration b/pkg/sql/testdata/session_migration/session_migration
new file mode 100644
index 000000000000..a4de1f5423ec
--- /dev/null
+++ b/pkg/sql/testdata/session_migration/session_migration
@@ -0,0 +1,55 @@
+# This file contains basic tests for session_migration.
+
+exec
+CREATE DATABASE d; USE d
+----
+
+exec
+SET extra_float_digits = -1;
+SET enable_zigzag_join = false;
+SET search_path = public
+----
+
+let $x
+SELECT encode(crdb_internal.serialize_session(), 'hex')
+----
+
+dump_vars
+old_state
+----
+
+reset
+----
+
+query
+SHOW database
+----
+defaultdb
+
+exec
+SELECT crdb_internal.deserialize_session( decode('$x', 'hex') )
+----
+
+query
+SHOW database
+----
+d
+
+dump_vars
+new_state
+----
+
+compare_vars
+old_state
+new_state
+----
+
+exec
+SELECT crdb_internal.deserialize_session(
+ decode(
+ '0a4a0a0964656661756c74646212102420636f636b726f6163682064656d6f1a04757365722204100222002802380842035554434a0524757365724a067075626c69635a0060808080207a00122b10904e3002380840026001680170017801880101d80101e00101f00101f80101900201b002808001c80201',
+ 'hex'
+ )
+)
+----
+pq: crdb_internal.deserialize_session(): can only serialize matching session users
From fcdb3105e96b7949f2555ff28d7df7077afc2496 Mon Sep 17 00:00:00 2001
From: Oliver Tan
Date: Fri, 20 Aug 2021 09:11:11 +1000
Subject: [PATCH 3/3] builtins: prevent serializing prepared statements
Release note: None
---
pkg/sql/conn_executor.go | 49 +++++++++++--------
pkg/sql/faketreeeval/evalctx.go | 11 +++++
pkg/sql/sem/builtins/builtins.go | 7 +++
pkg/sql/sem/tree/eval.go | 8 +++
.../session_migration/session_migration | 17 +++++++
5 files changed, 71 insertions(+), 21 deletions(-)
diff --git a/pkg/sql/conn_executor.go b/pkg/sql/conn_executor.go
index ef5511e52d37..8a0d4e04e9f5 100644
--- a/pkg/sql/conn_executor.go
+++ b/pkg/sql/conn_executor.go
@@ -1372,6 +1372,12 @@ type prepStmtNamespace struct {
portals map[string]PreparedPortal
}
+// HasPrepared returns true if there are prepared statements or portals
+// in the session.
+func (ns prepStmtNamespace) HasPrepared() bool {
+ return len(ns.prepStmts) > 0 || len(ns.portals) > 0
+}
+
func (ns prepStmtNamespace) String() string {
var sb strings.Builder
sb.WriteString("Prep stmts: ")
@@ -2309,27 +2315,28 @@ func (ex *connExecutor) initEvalCtx(ctx context.Context, evalCtx *extendedEvalCo
*evalCtx = extendedEvalContext{
EvalContext: tree.EvalContext{
- Planner: p,
- PrivilegedAccessor: p,
- SessionAccessor: p,
- ClientNoticeSender: p,
- Sequence: p,
- Tenant: p,
- JoinTokenCreator: p,
- SessionData: ex.sessionData,
- Settings: ex.server.cfg.Settings,
- TestingKnobs: ex.server.cfg.EvalContextTestingKnobs,
- ClusterID: ex.server.cfg.ClusterID(),
- ClusterName: ex.server.cfg.RPCContext.ClusterName(),
- NodeID: ex.server.cfg.NodeID,
- Codec: ex.server.cfg.Codec,
- Locality: ex.server.cfg.Locality,
- ReCache: ex.server.reCache,
- InternalExecutor: &ie,
- DB: ex.server.cfg.DB,
- SQLLivenessReader: ex.server.cfg.SQLLivenessReader,
- SQLStatsController: ex.server.sqlStatsController,
- CompactEngineSpan: ex.server.cfg.CompactEngineSpanFunc,
+ Planner: p,
+ PrivilegedAccessor: p,
+ SessionAccessor: p,
+ ClientNoticeSender: p,
+ Sequence: p,
+ Tenant: p,
+ JoinTokenCreator: p,
+ PreparedStatementState: &ex.extraTxnState.prepStmtsNamespace,
+ SessionData: ex.sessionData,
+ Settings: ex.server.cfg.Settings,
+ TestingKnobs: ex.server.cfg.EvalContextTestingKnobs,
+ ClusterID: ex.server.cfg.ClusterID(),
+ ClusterName: ex.server.cfg.RPCContext.ClusterName(),
+ NodeID: ex.server.cfg.NodeID,
+ Codec: ex.server.cfg.Codec,
+ Locality: ex.server.cfg.Locality,
+ ReCache: ex.server.reCache,
+ InternalExecutor: &ie,
+ DB: ex.server.cfg.DB,
+ SQLLivenessReader: ex.server.cfg.SQLLivenessReader,
+ SQLStatsController: ex.server.sqlStatsController,
+ CompactEngineSpan: ex.server.cfg.CompactEngineSpanFunc,
},
SessionMutator: ex.dataMutator,
VirtualSchemas: ex.server.cfg.VirtualSchemas,
diff --git a/pkg/sql/faketreeeval/evalctx.go b/pkg/sql/faketreeeval/evalctx.go
index 40e7678d2a68..d82db085a2b8 100644
--- a/pkg/sql/faketreeeval/evalctx.go
+++ b/pkg/sql/faketreeeval/evalctx.go
@@ -433,3 +433,14 @@ func (c *DummyTenantOperator) UpdateTenantResourceLimits(
) error {
return errors.WithStack(errEvalTenant)
}
+
+// DummyPreparedStatementState implements the tree.PreparedStatementState
+// interface.
+type DummyPreparedStatementState struct{}
+
+var _ tree.PreparedStatementState = (*DummyPreparedStatementState)(nil)
+
+// HasPrepared is part of the tree.PreparedStatementState interface.
+func (ps *DummyPreparedStatementState) HasPrepared() bool {
+ return false
+}
diff --git a/pkg/sql/sem/builtins/builtins.go b/pkg/sql/sem/builtins/builtins.go
index 549defa2ffa9..374dd1a1fd23 100644
--- a/pkg/sql/sem/builtins/builtins.go
+++ b/pkg/sql/sem/builtins/builtins.go
@@ -5879,6 +5879,13 @@ table's zone configuration this will return NULL.`,
)
}
+ if evalCtx.PreparedStatementState.HasPrepared() {
+ return nil, pgerror.Newf(
+ pgcode.InvalidTransactionState,
+ "cannot serialize a session which has portals or prepared statements",
+ )
+ }
+
sd := evalCtx.SessionData
if sd == nil {
return nil, pgerror.Newf(
diff --git a/pkg/sql/sem/tree/eval.go b/pkg/sql/sem/tree/eval.go
index 28db1940d0f2..a6cd988ee208 100644
--- a/pkg/sql/sem/tree/eval.go
+++ b/pkg/sql/sem/tree/eval.go
@@ -3258,6 +3258,12 @@ type EvalSessionAccessor interface {
HasRoleOption(ctx context.Context, roleOption roleoption.Option) (bool, error)
}
+// PreparedStatementState is a limited interface that exposes metadata about
+// prepared statements.
+type PreparedStatementState interface {
+ HasPrepared() bool
+}
+
// ClientNoticeSender is a limited interface to send notices to the
// client.
//
@@ -3531,6 +3537,8 @@ type EvalContext struct {
JoinTokenCreator JoinTokenCreator
+ PreparedStatementState PreparedStatementState
+
// The transaction in which the statement is executing.
Txn *kv.Txn
// A handle to the database.
diff --git a/pkg/sql/testdata/session_migration/session_migration b/pkg/sql/testdata/session_migration/session_migration
index a4de1f5423ec..1e88558bed05 100644
--- a/pkg/sql/testdata/session_migration/session_migration
+++ b/pkg/sql/testdata/session_migration/session_migration
@@ -44,6 +44,10 @@ old_state
new_state
----
+reset
+----
+
+# We cannot deserialize a different session_user.
exec
SELECT crdb_internal.deserialize_session(
decode(
@@ -53,3 +57,16 @@ SELECT crdb_internal.deserialize_session(
)
----
pq: crdb_internal.deserialize_session(): can only serialize matching session users
+
+reset
+----
+
+# We cannot serialized prepared statements
+exec
+PREPARE stmt AS SELECT 1
+----
+
+exec
+SELECT crdb_internal.serialize_session()
+----
+pq: crdb_internal.serialize_session(): cannot serialize a session which has portals or prepared statements
|