From 3628ed90e89437f0a74da0570e1c1dca24ca8b26 Mon Sep 17 00:00:00 2001 From: Bilal Akhtar Date: Wed, 29 Apr 2020 11:07:22 -0400 Subject: [PATCH 1/7] storage,libroach: Check for MaxKeys when reading from intent history We weren't checking for MaxKeys (or TargetBytes) being reached in the case where we read from intent history in the MVCC scanner. All other cases go through addAndAdvance(), which had these checks. Almost certainly fixes #46652. Would be very surprised if it was something else. Release note (bug fix): Fixes a bug where a read operation in a transaction would error out for exceeding the maximum count of results returned. --- c-deps/libroach/mvcc.h | 6 + pkg/storage/pebble_mvcc_scanner.go | 8 ++ pkg/storage/testdata/mvcc_histories/max_keys | 111 ++++++++++++++++++ .../testdata/mvcc_histories/target_bytes | 51 ++++++++ 4 files changed, 176 insertions(+) diff --git a/c-deps/libroach/mvcc.h b/c-deps/libroach/mvcc.h index c7a326b90397..b766a0563b2a 100644 --- a/c-deps/libroach/mvcc.h +++ b/c-deps/libroach/mvcc.h @@ -407,6 +407,12 @@ template class mvccScanner { // sequence, read that value. const bool found = getFromIntentHistory(); if (found) { + if (target_bytes_ > 0 && kvs_->NumBytes() >= target_bytes_) { + max_keys_ = kvs_->Count(); + } + if (max_keys_ > 0 && kvs_->Count() == max_keys_) { + return false; + } return advanceKey(); } // 11. If no value in the intent history has a sequence number equal to diff --git a/pkg/storage/pebble_mvcc_scanner.go b/pkg/storage/pebble_mvcc_scanner.go index 1f2627efce96..331109d4b5a5 100644 --- a/pkg/storage/pebble_mvcc_scanner.go +++ b/pkg/storage/pebble_mvcc_scanner.go @@ -409,6 +409,14 @@ func (p *pebbleMVCCScanner) getAndAdvance() bool { // history that has a sequence number equal to or less than the read // sequence, read that value. if p.getFromIntentHistory() { + if p.targetBytes > 0 && p.results.bytes >= p.targetBytes { + // When the target bytes are met or exceeded, stop producing more + // keys. We implement this by reducing maxKeys to the current + // number of keys. + // + // TODO(bilal): see if this can be implemented more transparently. + p.maxKeys = p.results.count + } if p.maxKeys > 0 && p.results.count == p.maxKeys { return false } diff --git a/pkg/storage/testdata/mvcc_histories/max_keys b/pkg/storage/testdata/mvcc_histories/max_keys index d60598152680..3ce655dede5f 100644 --- a/pkg/storage/testdata/mvcc_histories/max_keys +++ b/pkg/storage/testdata/mvcc_histories/max_keys @@ -86,3 +86,114 @@ scan: "e" -> /BYTES/val-e @0.000000001,0 scan: "e" -> /BYTES/val-e @0.000000001,0 scan: "c" -> /BYTES/val-c @0.000000001,0 scan: "a" -> /BYTES/val-a @0.000000001,0 + +# Regression test for #46652: Test appropriate termination when the MaxKeys-th +# key is in the intent history. + +run ok +with t=A ts=11,0 max=3 + txn_begin + txn_step seq=10 + put k=k v=a + put k=l v=a + put k=m v=a + put k=n v=a + txn_step seq=20 + put k=k v=b + put k=l v=b + put k=m v=b + put k=n v=b + txn_step seq=30 + put k=k v=c + put k=l v=c + put k=m v=c + put k=n v=c + txn_step seq=20 + scan k=k end=o + scan k=k end=o reverse=true +---- +scan: "k" -> /BYTES/b @0,0 +scan: "l" -> /BYTES/b @0,0 +scan: "m" -> /BYTES/b @0,0 +scan: resume span ["n","o") +scan: "n" -> /BYTES/b @0,0 +scan: "m" -> /BYTES/b @0,0 +scan: "l" -> /BYTES/b @0,0 +scan: resume span ["k","k\x00") +>> at end: +txn: "A" meta={id=00000000 key=/Min pri=0.00000000 epo=0 ts=0.000000011,0 min=0,0 seq=20} lock=true stat=PENDING rts=0.000000011,0 wto=false max=0,0 +data: "a"/0.000000001,0 -> /BYTES/val-a +data: "aa"/0.000000002,0 -> / +data: "aa"/0.000000001,0 -> /BYTES/val-aa +data: "c"/0.000000001,0 -> /BYTES/val-c +data: "e"/0.000000001,0 -> /BYTES/val-e +meta: "k"/0,0 -> txn={id=00000000 key=/Min pri=0.00000000 epo=0 ts=0.000000011,0 min=0,0 seq=30} ts=0.000000011,0 del=false klen=12 vlen=6 ih={{10 /BYTES/a}{20 /BYTES/b}} +data: "k"/0.000000011,0 -> /BYTES/c +meta: "l"/0,0 -> txn={id=00000000 key=/Min pri=0.00000000 epo=0 ts=0.000000011,0 min=0,0 seq=30} ts=0.000000011,0 del=false klen=12 vlen=6 ih={{10 /BYTES/a}{20 /BYTES/b}} +data: "l"/0.000000011,0 -> /BYTES/c +meta: "m"/0,0 -> txn={id=00000000 key=/Min pri=0.00000000 epo=0 ts=0.000000011,0 min=0,0 seq=30} ts=0.000000011,0 del=false klen=12 vlen=6 ih={{10 /BYTES/a}{20 /BYTES/b}} +data: "m"/0.000000011,0 -> /BYTES/c +meta: "n"/0,0 -> txn={id=00000000 key=/Min pri=0.00000000 epo=0 ts=0.000000011,0 min=0,0 seq=30} ts=0.000000011,0 del=false klen=12 vlen=6 ih={{10 /BYTES/a}{20 /BYTES/b}} +data: "n"/0.000000011,0 -> /BYTES/c + +run ok +with t=A ts=11,0 max=3 + txn_step seq=30 + resolve_intent k=k status=COMMITTED + resolve_intent k=l status=COMMITTED + resolve_intent k=m status=COMMITTED + resolve_intent k=n status=COMMITTED +---- +>> at end: +txn: "A" meta={id=00000000 key=/Min pri=0.00000000 epo=0 ts=0.000000011,0 min=0,0 seq=30} lock=true stat=PENDING rts=0.000000011,0 wto=false max=0,0 +data: "a"/0.000000001,0 -> /BYTES/val-a +data: "aa"/0.000000002,0 -> / +data: "aa"/0.000000001,0 -> /BYTES/val-aa +data: "c"/0.000000001,0 -> /BYTES/val-c +data: "e"/0.000000001,0 -> /BYTES/val-e +data: "k"/0.000000011,0 -> /BYTES/c +data: "l"/0.000000011,0 -> /BYTES/c +data: "m"/0.000000011,0 -> /BYTES/c +data: "n"/0.000000011,0 -> /BYTES/c + +# Same case as above, except with a committed value at the key after MaxKeys. + +run ok +with t=B ts=12,0 max=3 + txn_begin + txn_step seq=10 + put k=k v=a + put k=l v=a + put k=m v=a + txn_step seq=20 + put k=k v=b + put k=l v=b + put k=m v=b + txn_step seq=30 + put k=k v=c + put k=l v=c + put k=m v=c + txn_step seq=20 + scan k=k end=o +---- +scan: "k" -> /BYTES/b @0,0 +scan: "l" -> /BYTES/b @0,0 +scan: "m" -> /BYTES/b @0,0 +scan: resume span ["n","o") +>> at end: +txn: "B" meta={id=00000000 key=/Min pri=0.00000000 epo=0 ts=0.000000012,0 min=0,0 seq=20} lock=true stat=PENDING rts=0.000000012,0 wto=false max=0,0 +data: "a"/0.000000001,0 -> /BYTES/val-a +data: "aa"/0.000000002,0 -> / +data: "aa"/0.000000001,0 -> /BYTES/val-aa +data: "c"/0.000000001,0 -> /BYTES/val-c +data: "e"/0.000000001,0 -> /BYTES/val-e +meta: "k"/0,0 -> txn={id=00000000 key=/Min pri=0.00000000 epo=0 ts=0.000000012,0 min=0,0 seq=30} ts=0.000000012,0 del=false klen=12 vlen=6 ih={{10 /BYTES/a}{20 /BYTES/b}} +data: "k"/0.000000012,0 -> /BYTES/c +data: "k"/0.000000011,0 -> /BYTES/c +meta: "l"/0,0 -> txn={id=00000000 key=/Min pri=0.00000000 epo=0 ts=0.000000012,0 min=0,0 seq=30} ts=0.000000012,0 del=false klen=12 vlen=6 ih={{10 /BYTES/a}{20 /BYTES/b}} +data: "l"/0.000000012,0 -> /BYTES/c +data: "l"/0.000000011,0 -> /BYTES/c +meta: "m"/0,0 -> txn={id=00000000 key=/Min pri=0.00000000 epo=0 ts=0.000000012,0 min=0,0 seq=30} ts=0.000000012,0 del=false klen=12 vlen=6 ih={{10 /BYTES/a}{20 /BYTES/b}} +data: "m"/0.000000012,0 -> /BYTES/c +data: "m"/0.000000011,0 -> /BYTES/c +data: "n"/0.000000011,0 -> /BYTES/c diff --git a/pkg/storage/testdata/mvcc_histories/target_bytes b/pkg/storage/testdata/mvcc_histories/target_bytes index e2048338aa9e..71377fd432c0 100644 --- a/pkg/storage/testdata/mvcc_histories/target_bytes +++ b/pkg/storage/testdata/mvcc_histories/target_bytes @@ -246,3 +246,54 @@ scan: "c" -> /BYTES/ghijkllkjihg @0.000000123,45 scan: "aa" -> / @0.000000250,1 scan: "a" -> /BYTES/abcdef @0.000000123,45 scan: 98 bytes (target 65) + +# Regression test for a bug simiar to #46652: Test appropriate termination when +# the TargetBytes-th kv pair is in the intent history. + +run ok +with t=A ts=11,0 targetbytes=32 + txn_begin + txn_step seq=10 + put k=k v=a + put k=l v=a + put k=m v=a + put k=n v=a + txn_step seq=20 + put k=k v=b + put k=l v=b + put k=m v=b + put k=n v=b + txn_step seq=30 + put k=k v=c + put k=l v=c + put k=m v=c + put k=n v=c + txn_step seq=20 + scan k=k end=o + scan k=k end=o reverse=true +---- +scan: "k" -> /BYTES/b @0,0 +scan: "l" -> /BYTES/b @0,0 +scan: resume span ["m","o") +scan: 32 bytes (target 32) +scan: "n" -> /BYTES/b @0,0 +scan: "m" -> /BYTES/b @0,0 +scan: resume span ["k","l\x00") +scan: 32 bytes (target 32) +>> at end: +txn: "A" meta={id=00000000 key=/Min pri=0.00000000 epo=0 ts=0.000000011,0 min=0,0 seq=20} lock=true stat=PENDING rts=0.000000011,0 wto=false max=0,0 +data: "a"/0.000000123,45 -> /BYTES/abcdef +data: "a"/0.000000001,0 -> /BYTES/nevergoingtobeseen +data: "aa"/0.000000250,1 -> / +data: "aa"/0.000000001,0 -> /BYTES/willbetombstoned +data: "c"/0.000000123,45 -> /BYTES/ghijkllkjihg +data: "e"/0.000000123,45 -> /BYTES/mnopqr +data: "e"/0.000000001,0 -> /BYTES/sameasabove +meta: "k"/0,0 -> txn={id=00000000 key=/Min pri=0.00000000 epo=0 ts=0.000000011,0 min=0,0 seq=30} ts=0.000000011,0 del=false klen=12 vlen=6 ih={{10 /BYTES/a}{20 /BYTES/b}} +data: "k"/0.000000011,0 -> /BYTES/c +meta: "l"/0,0 -> txn={id=00000000 key=/Min pri=0.00000000 epo=0 ts=0.000000011,0 min=0,0 seq=30} ts=0.000000011,0 del=false klen=12 vlen=6 ih={{10 /BYTES/a}{20 /BYTES/b}} +data: "l"/0.000000011,0 -> /BYTES/c +meta: "m"/0,0 -> txn={id=00000000 key=/Min pri=0.00000000 epo=0 ts=0.000000011,0 min=0,0 seq=30} ts=0.000000011,0 del=false klen=12 vlen=6 ih={{10 /BYTES/a}{20 /BYTES/b}} +data: "m"/0.000000011,0 -> /BYTES/c +meta: "n"/0,0 -> txn={id=00000000 key=/Min pri=0.00000000 epo=0 ts=0.000000011,0 min=0,0 seq=30} ts=0.000000011,0 del=false klen=12 vlen=6 ih={{10 /BYTES/a}{20 /BYTES/b}} +data: "n"/0.000000011,0 -> /BYTES/c From 67a1d4d7b14baaba74c50dc642dd9022b774e98b Mon Sep 17 00:00:00 2001 From: Rebecca Taft Date: Wed, 29 Apr 2020 10:42:06 -0500 Subject: [PATCH 2/7] opt: add rule to eliminate Exists when input has zero rows This commit adds a new rule, EliminateExistsZeroRows, which converts an Exists subquery to False when it's known that the input produces zero rows. Informs #47058 Release note (performance improvement): The optimizer can now detect when an Exists subquery can be eliminated because the input has zero rows. This leads to better plans in some cases. --- pkg/sql/opt/norm/rules/scalar.opt | 5 ++++ pkg/sql/opt/norm/testdata/rules/join | 4 +-- pkg/sql/opt/norm/testdata/rules/scalar | 34 ++++++++++++++------------ 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/pkg/sql/opt/norm/rules/scalar.opt b/pkg/sql/opt/norm/rules/scalar.opt index ad5e38003f0e..1d9f2edef4f3 100644 --- a/pkg/sql/opt/norm/rules/scalar.opt +++ b/pkg/sql/opt/norm/rules/scalar.opt @@ -90,6 +90,11 @@ $result ) +# EliminateExistsZeroRows converts an Exists subquery to False when it's known +# that the input produces zero rows. +[EliminateExistsZeroRows, Normalize] +(Exists $input:* & (HasZeroRows $input)) => (False) + # EliminateExistsProject discards a Project input to the Exists operator. The # Project operator never changes the row cardinality of its input, and row # cardinality is the only thing that Exists cares about, so Project is a no-op. diff --git a/pkg/sql/opt/norm/testdata/rules/join b/pkg/sql/opt/norm/testdata/rules/join index 9e1685bbd37e..7749f0201d4f 100644 --- a/pkg/sql/opt/norm/testdata/rules/join +++ b/pkg/sql/opt/norm/testdata/rules/join @@ -2165,7 +2165,7 @@ scan a # SimplifyZeroCardinalitySemiJoin # -------------------------------------------------- # TODO(justin): figure out if there's a good way to make this still apply. -norm disable=SimplifyZeroCardinalityGroup expect=SimplifyZeroCardinalitySemiJoin +norm disable=(SimplifyZeroCardinalityGroup,EliminateExistsZeroRows) expect=SimplifyZeroCardinalitySemiJoin SELECT * FROM a WHERE EXISTS(SELECT * FROM (VALUES (k)) OFFSET 1) ---- values @@ -2178,7 +2178,7 @@ values # EliminateAntiJoin # -------------------------------------------------- # TODO(justin): figure out if there's a good way to make this still apply. -norm disable=SimplifyZeroCardinalityGroup expect=EliminateAntiJoin +norm disable=(SimplifyZeroCardinalityGroup,EliminateExistsZeroRows) expect=EliminateAntiJoin SELECT * FROM a WHERE NOT EXISTS(SELECT * FROM (VALUES (k)) OFFSET 1) ---- scan a diff --git a/pkg/sql/opt/norm/testdata/rules/scalar b/pkg/sql/opt/norm/testdata/rules/scalar index 772d554e7247..7e729f43d138 100644 --- a/pkg/sql/opt/norm/testdata/rules/scalar +++ b/pkg/sql/opt/norm/testdata/rules/scalar @@ -249,6 +249,20 @@ values ├── fd: ()-->(1) └── (true IN (NULL, NULL, ('201.249.149.90/18' & '97a7:3650:3dd8:d4e9:35fe:6cfb:a714:1c17/61') << 'e22f:2067:2ed2:7b07:b167:206f:f17b:5b7d/82'),) +# -------------------------------------------------- +# EliminateExistsZeroRows +# -------------------------------------------------- + +norm expect=EliminateExistsZeroRows +SELECT EXISTS(SELECT * FROM (VALUES (1)) WHERE false) +---- +values + ├── columns: exists:2!null + ├── cardinality: [1 - 1] + ├── key: () + ├── fd: ()-->(2) + └── (false,) + # -------------------------------------------------- # EliminateExistsProject # -------------------------------------------------- @@ -524,21 +538,11 @@ anti-join (hash) norm expect-not=EliminateExistsLimit SELECT * FROM a a1 WHERE EXISTS(SELECT i FROM a a2 where a1.i = a2.i LIMIT 0) ---- -select - ├── columns: k:1!null i:2 f:3 s:4 j:5 arr:6 - ├── key: (1) - ├── fd: (1)-->(2-6) - ├── scan a1 - │ ├── columns: a1.k:1!null a1.i:2 a1.f:3 a1.s:4 a1.j:5 a1.arr:6 - │ ├── key: (1) - │ └── fd: (1)-->(2-6) - └── filters - └── exists [subquery] - └── values - ├── columns: a2.i:8!null - ├── cardinality: [0 - 0] - ├── key: () - └── fd: ()-->(8) +values + ├── columns: k:1!null i:2!null f:3!null s:4!null j:5!null arr:6!null + ├── cardinality: [0 - 0] + ├── key: () + └── fd: ()-->(1-6) # Don't eliminate a limit from a non-correlated subquery. norm expect-not=EliminateExistsLimit From 080aad02ebf2d5873d13c4660aa4d901dad52159 Mon Sep 17 00:00:00 2001 From: Nathan VanBenschoten Date: Tue, 28 Apr 2020 17:56:12 -0400 Subject: [PATCH 3/7] keys: support tenant ID prefix in GetRowPrefixLength and EnsureSafeSplitKey This addresses a few TODOs. The changes are tested in `TestEnsureSafeSplitKey`. --- pkg/keys/keys.go | 59 ++++++++++++++++++++---------------- pkg/keys/keys_test.go | 69 ++++++++++++++++++++++++++++++++----------- 2 files changed, 85 insertions(+), 43 deletions(-) diff --git a/pkg/keys/keys.go b/pkg/keys/keys.go index 12a2be61d3d1..8451e868b6a4 100644 --- a/pkg/keys/keys.go +++ b/pkg/keys/keys.go @@ -689,44 +689,53 @@ func DecodeTableIDIndexID(key []byte) ([]byte, uint32, uint32, error) { // prefix of every key for the same row. (Any key with this maximal prefix is // also guaranteed to be part of the input key's row.) // For secondary index keys, the row prefix is defined as the entire key. -// -// TODO(nvanbenschoten): support tenant ID prefix. func GetRowPrefixLength(key roachpb.Key) (int, error) { n := len(key) - if encoding.PeekType(key) != encoding.Int { + + // Strip tenant ID prefix to get a "SQL key" starting with a table ID. + sqlKey, _, err := DecodeTenantPrefix(key) + if err != nil { + return 0, errors.Errorf("%s: not a valid table key", key) + } + sqlN := len(sqlKey) + + if encoding.PeekType(sqlKey) != encoding.Int { // Not a table key, so the row prefix is the entire key. return n, nil } - // The column ID length is encoded as a varint and we take advantage of the - // fact that the column ID itself will be encoded in 0-9 bytes and thus the - // length of the column ID data will fit in a single byte. - buf := key[n-1:] - if encoding.PeekType(buf) != encoding.Int { - // The last byte is not a valid column ID suffix. + // The column family ID length is encoded as a varint and we take advantage + // of the fact that the column family ID itself will be encoded in 0-9 bytes + // and thus the length of the column family ID data will fit in a single + // byte. + colFamIDLenByte := sqlKey[sqlN-1:] + if encoding.PeekType(colFamIDLenByte) != encoding.Int { + // The last byte is not a valid column family ID suffix. return 0, errors.Errorf("%s: not a valid table key", key) } - // Strip off the family ID / column ID suffix from the buf. The last byte of the buf - // contains the length of the column ID suffix (which might be 0 if the buf - // does not contain a column ID suffix). - _, colIDLen, err := encoding.DecodeUvarintAscending(buf) + // Strip off the column family ID suffix from the buf. The last byte of the + // buf contains the length of the column family ID suffix, which might be 0 + // if the buf does not contain a column ID suffix or if the column family is + // 0 (see the optimization in MakeFamilyKey). + _, colFamIDLen, err := encoding.DecodeUvarintAscending(colFamIDLenByte) if err != nil { return 0, err } - // Note how this next comparison (and by extension the code after it) is overflow-safe. There - // are more intuitive ways of writing this that aren't as safe. See #18628. - if colIDLen > uint64(n-1) { - // The column ID length was impossible. colIDLen is the length of - // the encoded column ID suffix. We add 1 to account for the byte - // holding the length of the encoded column ID and if that total - // (colIDLen+1) is greater than the key suffix (n == len(buf)) - // then we bail. Note that we don't consider this an error because - // EnsureSafeSplitKey can be called on keys that look like table - // keys but which do not have a column ID length suffix (e.g - // by SystemConfig.ComputeSplitKey). + // Note how this next comparison (and by extension the code after it) is + // overflow-safe. There are more intuitive ways of writing this that aren't + // as safe. See #18628. + if colFamIDLen > uint64(sqlN-1) { + // The column family ID length was impossible. colFamIDLen is the length + // of the encoded column family ID suffix. We add 1 to account for the + // byte holding the length of the encoded column family ID and if that + // total (colFamIDLen+1) is greater than the key suffix (sqlN == + // len(sqlKey)) then we bail. Note that we don't consider this an error + // because EnsureSafeSplitKey can be called on keys that look like table + // keys but which do not have a column family ID length suffix (e.g by + // SystemConfig.ComputeSplitKey). return 0, errors.Errorf("%s: malformed table key", key) } - return len(key) - int(colIDLen) - 1, nil + return n - int(colFamIDLen) - 1, nil } // EnsureSafeSplitKey transforms an SQL table key such that it is a valid split key diff --git a/pkg/keys/keys_test.go b/pkg/keys/keys_test.go index 77868e81c593..798c1a3ddd2c 100644 --- a/pkg/keys/keys_test.go +++ b/pkg/keys/keys_test.go @@ -526,26 +526,53 @@ func TestMakeFamilyKey(t *testing.T) { } func TestEnsureSafeSplitKey(t *testing.T) { - e := func(vals ...uint64) roachpb.Key { - var k roachpb.Key + tenSysCodec := SystemSQLCodec + ten5Codec := MakeSQLCodec(roachpb.MakeTenantID(5)) + encInt := encoding.EncodeUvarintAscending + encInts := func(c SQLCodec, vals ...uint64) roachpb.Key { + k := c.TenantPrefix() for _, v := range vals { - k = encoding.EncodeUvarintAscending(k, v) + k = encInt(k, v) } return k } + es := func(vals ...uint64) roachpb.Key { + return encInts(tenSysCodec, vals...) + } + e5 := func(vals ...uint64) roachpb.Key { + return encInts(ten5Codec, vals...) + } goodData := []struct { in roachpb.Key expected roachpb.Key }{ - {e(1, 2, 0), e(1, 2)}, // /Table/1/2/0 -> /Table/1/2 - {e(1, 2, 1), e(1)}, // /Table/1/2/1 -> /Table/1 - {e(1, 2, 2), e()}, // /Table/1/2/2 -> /Table - {e(1, 2, 3, 0), e(1, 2, 3)}, // /Table/1/2/3/0 -> /Table/1/2/3 - {e(1, 2, 3, 1), e(1, 2)}, // /Table/1/2/3/1 -> /Table/1/2 - {e(1, 2, 200, 2), e(1, 2)}, // /Table/1/2/200/2 -> /Table/1/2 - {e(1, 2, 3, 4, 1), e(1, 2, 3)}, // /Table/1/2/3/4/1 -> /Table/1/2/3 - // TODO(nvanbenschoten): add test cases for tenant keys. + {es(), es()}, // Not a table key + {es(1, 2, 0), es(1, 2)}, // /Table/1/2/0 -> /Table/1/2 + {es(1, 2, 1), es(1)}, // /Table/1/2/1 -> /Table/1 + {es(1, 2, 2), es()}, // /Table/1/2/2 -> /Table + {es(1, 2, 3, 0), es(1, 2, 3)}, // /Table/1/2/3/0 -> /Table/1/2/3 + {es(1, 2, 3, 1), es(1, 2)}, // /Table/1/2/3/1 -> /Table/1/2 + {es(1, 2, 200, 2), es(1, 2)}, // /Table/1/2/200/2 -> /Table/1/2 + {es(1, 2, 3, 4, 1), es(1, 2, 3)}, // /Table/1/2/3/4/1 -> /Table/1/2/3 + // Same test cases, but for tenant 5. + {e5(), e5()}, // Not a table key + {e5(1, 2, 0), e5(1, 2)}, // /Tenant/5/Table/1/2/0 -> /Tenant/5/Table/1/2 + {e5(1, 2, 1), e5(1)}, // /Tenant/5/Table/1/2/1 -> /Tenant/5/Table/1 + {e5(1, 2, 2), e5()}, // /Tenant/5/Table/1/2/2 -> /Tenant/5/Table + {e5(1, 2, 3, 0), e5(1, 2, 3)}, // /Tenant/5/Table/1/2/3/0 -> /Tenant/5/Table/1/2/3 + {e5(1, 2, 3, 1), e5(1, 2)}, // /Tenant/5/Table/1/2/3/1 -> /Tenant/5/Table/1/2 + {e5(1, 2, 200, 2), e5(1, 2)}, // /Tenant/5/Table/1/2/200/2 -> /Tenant/5/Table/1/2 + {e5(1, 2, 3, 4, 1), e5(1, 2, 3)}, // /Tenant/5/Table/1/2/3/4/1 -> /Tenant/5/Table/1/2/3 + // Test cases using SQL encoding functions. + {MakeFamilyKey(tenSysCodec.IndexPrefix(1, 2), 0), es(1, 2)}, // /Table/1/2/0 -> /Table/1/2 + {MakeFamilyKey(tenSysCodec.IndexPrefix(1, 2), 1), es(1, 2)}, // /Table/1/2/1 -> /Table/1/2 + {MakeFamilyKey(encInt(tenSysCodec.IndexPrefix(1, 2), 3), 0), es(1, 2, 3)}, // /Table/1/2/3/0 -> /Table/1/2/3 + {MakeFamilyKey(encInt(tenSysCodec.IndexPrefix(1, 2), 3), 1), es(1, 2, 3)}, // /Table/1/2/3/1 -> /Table/1/2/3 + {MakeFamilyKey(ten5Codec.IndexPrefix(1, 2), 0), e5(1, 2)}, // /Tenant/5/Table/1/2/0 -> /Table/1/2 + {MakeFamilyKey(ten5Codec.IndexPrefix(1, 2), 1), e5(1, 2)}, // /Tenant/5/Table/1/2/1 -> /Table/1/2 + {MakeFamilyKey(encInt(ten5Codec.IndexPrefix(1, 2), 3), 0), e5(1, 2, 3)}, // /Tenant/5/Table/1/2/3/0 -> /Table/1/2/3 + {MakeFamilyKey(encInt(ten5Codec.IndexPrefix(1, 2), 3), 1), e5(1, 2, 3)}, // /Tenant/5/Table/1/2/3/1 -> /Table/1/2/3 } for i, d := range goodData { out, err := EnsureSafeSplitKey(d.in) @@ -572,18 +599,24 @@ func TestEnsureSafeSplitKey(t *testing.T) { err string }{ // Column ID suffix size is too large. - {e(1), "malformed table key"}, - {e(1, 2), "malformed table key"}, + {es(1), "malformed table key"}, + {es(1, 2), "malformed table key"}, // The table ID is invalid. - {e(200)[:1], "insufficient bytes to decode uvarint value"}, + {es(200)[:1], "insufficient bytes to decode uvarint value"}, // The index ID is invalid. - {e(1, 200)[:2], "insufficient bytes to decode uvarint value"}, + {es(1, 200)[:2], "insufficient bytes to decode uvarint value"}, // The column ID suffix is invalid. - {e(1, 2, 200)[:3], "insufficient bytes to decode uvarint value"}, + {es(1, 2, 200)[:3], "insufficient bytes to decode uvarint value"}, // Exercises a former overflow bug. We decode a uint(18446744073709551610) which, if casted // to int carelessly, results in -6. - {encoding.EncodeVarintAscending(SystemSQLCodec.TablePrefix(999), 322434), "malformed table key"}, - // TODO(nvanbenschoten): add test cases for tenant keys. + {encoding.EncodeVarintAscending(tenSysCodec.TablePrefix(999), 322434), "malformed table key"}, + // Same test cases, but for tenant 5. + {e5(1), "malformed table key"}, + {e5(1, 2), "malformed table key"}, + {e5(200)[:3], "insufficient bytes to decode uvarint value"}, + {e5(1, 200)[:4], "insufficient bytes to decode uvarint value"}, + {e5(1, 2, 200)[:5], "insufficient bytes to decode uvarint value"}, + {encoding.EncodeVarintAscending(ten5Codec.TablePrefix(999), 322434), "malformed table key"}, } for i, d := range errorData { _, err := EnsureSafeSplitKey(d.in) From 5b9102ab4c5c7ca337d3dadd9d7c55250ce5b7ed Mon Sep 17 00:00:00 2001 From: Nathan VanBenschoten Date: Tue, 28 Apr 2020 19:35:40 -0400 Subject: [PATCH 4/7] libroach: support tenant ID prefix in C++ RowCounter impl These changes are all modeled off of the corresponding Go impls. --- c-deps/libroach/encoding.cc | 18 ++++++++++++- c-deps/libroach/encoding.h | 14 +++++----- c-deps/libroach/encoding_test.cc | 32 ++++++++++++++++++++++ c-deps/libroach/keys.h | 1 + c-deps/libroach/row_counter.cc | 46 ++++++++++++++++++-------------- c-deps/libroach/row_counter.h | 2 -- pkg/keys/constants.go | 11 +++++--- pkg/keys/gen_cpp_keys.go | 1 + pkg/keys/sql.go | 2 +- 9 files changed, 93 insertions(+), 34 deletions(-) diff --git a/c-deps/libroach/encoding.cc b/c-deps/libroach/encoding.cc index 1187dd6978a4..29e3c682e79f 100644 --- a/c-deps/libroach/encoding.cc +++ b/c-deps/libroach/encoding.cc @@ -276,7 +276,23 @@ WARN_UNUSED_RESULT bool IsInt(rocksdb::Slice* buf) { return false; } -WARN_UNUSED_RESULT bool DecodeTablePrefix(rocksdb::Slice* buf, uint64_t* tbl) { +WARN_UNUSED_RESULT bool StripTenantPrefix(rocksdb::Slice* buf) { + if (buf->size() == 0) { + return true; + } + // kTenantPrefix is guaranteed to be a single byte. + if ((*buf)[0] != kTenantPrefix[0]) { + return true; + } + buf->remove_prefix(1); + uint64_t tid; + return DecodeUvarint64(buf, &tid); +} + +WARN_UNUSED_RESULT bool DecodeTenantAndTablePrefix(rocksdb::Slice* buf, uint64_t* tbl) { + if (!StripTenantPrefix(buf)) { + return false; + } if (!IsInt(buf) || !DecodeUvarint64(buf, tbl)) { return false; } diff --git a/c-deps/libroach/encoding.h b/c-deps/libroach/encoding.h index ef89821d5778..a38fac36d84b 100644 --- a/c-deps/libroach/encoding.h +++ b/c-deps/libroach/encoding.h @@ -118,11 +118,13 @@ rocksdb::Slice KeyPrefix(const rocksdb::Slice& src); // if it is of type int. WARN_UNUSED_RESULT bool IsInt(rocksdb::Slice* buf); -// DecodeTablePrefix validates that the given key has a table prefix. On -// completion, buf holds the remainder of the key (with the prefix removed) and -// tbl stores the decoded descriptor ID of the table. -// -// TODO(nvanbenschoten): support tenant ID prefix. -WARN_UNUSED_RESULT bool DecodeTablePrefix(rocksdb::Slice* buf, uint64_t* tbl); +// StripTenantPrefix validates that the given key has a tenant prefix. On +// completion, buf holds the remainder of the key (with the prefix removed). +WARN_UNUSED_RESULT bool StripTenantPrefix(rocksdb::Slice* buf); + +// DecodeTenantAndTablePrefix validates that the given key has a tenant and +// table prefix. On completion, buf holds the remainder of the key (with the +// prefix removed) and tbl stores the decoded descriptor ID of the table. +WARN_UNUSED_RESULT bool DecodeTenantAndTablePrefix(rocksdb::Slice* buf, uint64_t* tbl); } // namespace cockroach diff --git a/c-deps/libroach/encoding_test.cc b/c-deps/libroach/encoding_test.cc index 11b2584d79ce..39d4b9f4582b 100644 --- a/c-deps/libroach/encoding_test.cc +++ b/c-deps/libroach/encoding_test.cc @@ -76,3 +76,35 @@ TEST(Libroach, Encoding) { EXPECT_EQ(*it, out); } } + +TEST(Libroach, DecodeTenantAndTablePrefix) { + // clang-format off + std::vector> cases{ + {{'\x89'}, 1LLU}, + {{'\xf6', '\xff'}, 255LLU}, + {{'\xf7', '\xff', '\xff'}, 65535LLU}, + {{'\xf8', '\xff', '\xff', '\xff'}, 16777215LLU}, + {{'\xf9', '\xff', '\xff', '\xff', '\xff'}, 4294967295LLU}, + {{'\xfa', '\xff', '\xff', '\xff', '\xff', '\xff'}, 1099511627775LLU}, + {{'\xfb', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff'}, 281474976710655LLU}, + {{'\xfc', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff'}, 72057594037927935LLU}, + {{'\xfd', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff'}, 18446744073709551615LLU}, + {{'\xfe', '\x8d', '\x89'}, 1LLU}, + {{'\xfe', '\x8d', '\xf6', '\xff'}, 255LLU}, + {{'\xfe', '\x8d', '\xf7', '\xff', '\xff'}, 65535LLU}, + {{'\xfe', '\x8d', '\xf8', '\xff', '\xff', '\xff'}, 16777215LLU}, + {{'\xfe', '\x8d', '\xf9', '\xff', '\xff', '\xff', '\xff'}, 4294967295LLU}, + {{'\xfe', '\x8d', '\xfa', '\xff', '\xff', '\xff', '\xff', '\xff'}, 1099511627775LLU}, + {{'\xfe', '\x8d', '\xfb', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff'}, 281474976710655LLU}, + {{'\xfe', '\x8d', '\xfc', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff'}, 72057594037927935LLU}, + {{'\xfe', '\x8d', '\xfd', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff'}, 18446744073709551615LLU}, + }; + // clang-format on + + for (auto it = cases.begin(); it != cases.end(); it++) { + rocksdb::Slice slice(it->first); + uint64_t tbl = 0; + EXPECT_TRUE(DecodeTenantAndTablePrefix(&slice, &tbl)); + EXPECT_EQ(it->second, tbl); + } +} diff --git a/c-deps/libroach/keys.h b/c-deps/libroach/keys.h index 863d40120abd..85fe7d9abf86 100644 --- a/c-deps/libroach/keys.h +++ b/c-deps/libroach/keys.h @@ -10,6 +10,7 @@ const rocksdb::Slice kLocalRangeIDPrefix("\x01\x69", 2); const rocksdb::Slice kLocalRangeIDReplicatedInfix("\x72", 1); const rocksdb::Slice kLocalRangeAppliedStateSuffix("\x72\x61\x73\x6b", 4); const rocksdb::Slice kMeta2KeyMax("\x03\xff\xff", 3); +const rocksdb::Slice kTenantPrefix("\xfe", 1); const rocksdb::Slice kMinKey("", 0); const rocksdb::Slice kMaxKey("\xff\xff", 2); diff --git a/c-deps/libroach/row_counter.cc b/c-deps/libroach/row_counter.cc index 1a0959c94a23..97b56232549a 100644 --- a/c-deps/libroach/row_counter.cc +++ b/c-deps/libroach/row_counter.cc @@ -17,40 +17,46 @@ using namespace cockroach; int RowCounter::GetRowPrefixLength(rocksdb::Slice* key) { size_t n = key->size(); - if (!IsInt(key)) { + // Strip tenant ID prefix to get a "SQL key" starting with a table ID. + rocksdb::Slice buf = rocksdb::Slice(*key); + if (!StripTenantPrefix(&buf)) { + return 0; + } + size_t sql_n = key->size(); + + if (!IsInt(&buf)) { // Not a table key, so the row prefix is the entire key. return n; } - // The column ID length is encoded as a varint and we take advantage of the - // fact that the column ID itself will be encoded in 0-9 bytes and thus the - // length of the column ID data will fit in a single byte. - rocksdb::Slice buf = rocksdb::Slice(*key); - buf.remove_prefix(n - 1); + // The column family ID length is encoded as a varint and we take advantage of + // the fact that the column family ID itself will be encoded in 0-9 bytes and + // thus the length of the column family ID data will fit in a single byte. + buf.remove_prefix(sql_n - 1); if (!IsInt(&buf)) { - // The last byte is not a valid column ID suffix. + // The last byte is not a valid column family ID suffix. return 0; } - uint64_t col_id_len; - if (!DecodeUvarint64(&buf, &col_id_len)) { + uint64_t col_fam_id_len; + if (!DecodeUvarint64(&buf, &col_fam_id_len)) { return 0; } - if (col_id_len > uint64_t(n - 1)) { - // The column ID length was impossible. colIDLen is the length of - // the encoded column ID suffix. We add 1 to account for the byte - // holding the length of the encoded column ID and if that total - // (colIDLen+1) is greater than the key suffix (n == len(buf)) - // then we bail. Note that we don't consider this an error because - // EnsureSafeSplitKey can be called on keys that look like table - // keys but which do not have a column ID length suffix (e.g - // by SystemConfig.ComputeSplitKey). + if (col_fam_id_len > uint64_t(sql_n - 1)) { + // The column family ID length was impossible. colFamIDLen is the length of + // the encoded column family ID suffix. We add 1 to account for the byte + // holding the length of the encoded column family ID and if that total + // (colFamIDLen+1) is greater than the key suffix (sqlN == len(sqlKey)) then + // we bail. Note that we don't consider this an error because + // EnsureSafeSplitKey can be called on keys that look like table keys but + // which do not have a column family ID length suffix (e.g by + // SystemConfig.ComputeSplitKey). return 0; } - return n - int(col_id_len) - 1; + return n - int(col_fam_id_len) - 1; } // EnsureSafeSplitKey transforms the SQL table key argumnet such that it is a @@ -95,7 +101,7 @@ bool RowCounter::Count(const rocksdb::Slice& key) { prev_key.assign(decoded_key.data(), decoded_key.size()); uint64_t tbl; - if (!DecodeTablePrefix(&decoded_key, &tbl)) { + if (!DecodeTenantAndTablePrefix(&decoded_key, &tbl)) { return false; } diff --git a/c-deps/libroach/row_counter.h b/c-deps/libroach/row_counter.h index 662f1c163116..48b71fa8b9d5 100644 --- a/c-deps/libroach/row_counter.h +++ b/c-deps/libroach/row_counter.h @@ -23,8 +23,6 @@ const int MaxReservedDescID = 49; // RowCounter counts how many distinct rows appear in the KVs that is is shown // via `Count`. Note: the `DataSize` field of the BulkOpSummary is *not* // populated by this and should be set separately. -// -// TODO(nvanbenschoten): support tenant ID prefix. struct RowCounter { RowCounter(cockroach::roachpb::BulkOpSummary* summary) : summary(summary) {} bool Count(const rocksdb::Slice& key); diff --git a/pkg/keys/constants.go b/pkg/keys/constants.go index 005cc89026db..e76fdd201eb0 100644 --- a/pkg/keys/constants.go +++ b/pkg/keys/constants.go @@ -191,7 +191,8 @@ var ( // possible suggested compaction keys for a store. LocalStoreSuggestedCompactionsMax = LocalStoreSuggestedCompactionsMin.PrefixEnd() - // The global keyspace includes the meta{1,2}, system, and SQL keys. + // The global keyspace includes the meta{1,2}, system, system tenant SQL + // keys, and non-system tenant SQL keys. // 1. Meta keys // @@ -261,7 +262,7 @@ var ( // TimeseriesKeyMax is the maximum value for any timeseries data. TimeseriesKeyMax = TimeseriesPrefix.PrefixEnd() - // 3. SQL keys + // 3. System tenant SQL keys // // TODO(nvanbenschoten): Figure out what to do with all of these. At a // minimum, prefix them all with "System". @@ -287,8 +288,10 @@ var ( // UserTableDataMin is the start key of user structured data. UserTableDataMin = SystemSQLCodec.TablePrefix(MinUserDescID) - // tenantPrefix is the prefix for all non-system tenant keys. - tenantPrefix = roachpb.Key{tenantPrefixByte} + // 4. Non-system tenant SQL keys + // + // TenantPrefix is the prefix for all non-system tenant keys. + TenantPrefix = roachpb.Key{tenantPrefixByte} TenantTableDataMin = MakeTenantPrefix(roachpb.MinTenantID) TenantTableDataMax = MakeTenantPrefix(roachpb.MaxTenantID).PrefixEnd() ) diff --git a/pkg/keys/gen_cpp_keys.go b/pkg/keys/gen_cpp_keys.go index acfd098be99e..e2d2345faef7 100644 --- a/pkg/keys/gen_cpp_keys.go +++ b/pkg/keys/gen_cpp_keys.go @@ -69,6 +69,7 @@ namespace cockroach { genKey(keys.LocalRangeIDReplicatedInfix, "LocalRangeIDReplicatedInfix") genKey(keys.LocalRangeAppliedStateSuffix, "LocalRangeAppliedStateSuffix") genKey(keys.Meta2KeyMax, "Meta2KeyMax") + genKey(keys.TenantPrefix, "TenantPrefix") genKey(keys.MinKey, "MinKey") genKey(keys.MaxKey, "MaxKey") fmt.Fprintf(f, "\n") diff --git a/pkg/keys/sql.go b/pkg/keys/sql.go index edfa0a0f4d44..a787a717a342 100644 --- a/pkg/keys/sql.go +++ b/pkg/keys/sql.go @@ -23,7 +23,7 @@ func MakeTenantPrefix(tenID roachpb.TenantID) roachpb.Key { if tenID == roachpb.SystemTenantID { return nil } - return encoding.EncodeUvarintAscending(tenantPrefix, tenID.ToUint64()) + return encoding.EncodeUvarintAscending(TenantPrefix, tenID.ToUint64()) } // DecodeTenantPrefix determines the tenant ID from the key prefix, returning From 493fc81143a4c5fc99de6f4982ece068f44f2bb2 Mon Sep 17 00:00:00 2001 From: Nathan VanBenschoten Date: Tue, 28 Apr 2020 19:41:54 -0400 Subject: [PATCH 5/7] storage: remove use of TODOSQLCodec in RowCounter.Count --- pkg/storage/row_counter.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/storage/row_counter.go b/pkg/storage/row_counter.go index e56024aeb7d2..814c337a6259 100644 --- a/pkg/storage/row_counter.go +++ b/pkg/storage/row_counter.go @@ -51,7 +51,11 @@ func (r *RowCounter) Count(key roachpb.Key) error { r.prev = append(r.prev[:0], row...) - _, tableID, indexID, err := keys.TODOSQLCodec.DecodeIndexPrefix(row) + rem, _, err := keys.DecodeTenantPrefix(row) + if err != nil { + return err + } + _, tableID, indexID, err := keys.DecodeTableIDIndexID(rem) if err != nil { return err } From c360bd49d4c6f136a1396d957fa3ff5cf73af1fd Mon Sep 17 00:00:00 2001 From: Peter Mattis Date: Mon, 13 Apr 2020 16:44:33 -0400 Subject: [PATCH 6/7] cli: add --cert-principal-map to client commands Add support for the `--cert-principal-map` flag to the certs and client commands. Anywhere we were accepting the `--certs-dir` flag, we now also accept the `--cert-principal-map` flag. Fixes #47300 Fixes #47754 Fixes #48116 Release note (cli change): Support the `--cert-principal-map` flag in the `cert *` and "client" commands such as `sql`, `init`, and `quit`. --- pkg/cli/cert.go | 3 -- pkg/cli/context.go | 12 +++---- pkg/cli/flags.go | 20 +++++++---- pkg/cli/flags_test.go | 8 +++-- .../test_cert_advisory_validation.tcl | 33 +++++++++++++++---- 5 files changed, 51 insertions(+), 25 deletions(-) diff --git a/pkg/cli/cert.go b/pkg/cli/cert.go index 771385a8a153..e10b919f40ee 100644 --- a/pkg/cli/cert.go +++ b/pkg/cli/cert.go @@ -203,9 +203,6 @@ List certificates and keys found in the certificate directory. // runListCerts loads and lists all certs. func runListCerts(cmd *cobra.Command, args []string) error { - if err := security.SetCertPrincipalMap(certCtx.certPrincipalMap); err != nil { - return err - } cm, err := security.NewCertificateManager(baseCfg.SSLCertsDir) if err != nil { return errors.Wrap(err, "cannot load certificates") diff --git a/pkg/cli/context.go b/pkg/cli/context.go index 49b9fc27cdb8..d111dc3f929b 100644 --- a/pkg/cli/context.go +++ b/pkg/cli/context.go @@ -77,6 +77,7 @@ func initCLIDefaults() { cliCtx.cmdTimeout = 0 // no timeout cliCtx.clientConnHost = "" cliCtx.clientConnPort = base.DefaultPort + cliCtx.certPrincipalMap = nil cliCtx.sqlConnURL = "" cliCtx.sqlConnUser = "" cliCtx.sqlConnPasswd = "" @@ -173,8 +174,6 @@ func initCLIDefaults() { authCtx.validityPeriod = 1 * time.Hour - certCtx.certPrincipalMap = nil - initPreFlagsDefaults() // Clear the "Changed" state of all the registered command-line flags. @@ -217,6 +216,9 @@ type cliContext struct { // clientConnPort is the port name/number to use to connect to a server. clientConnPort string + // certPrincipalMap is the cert-principal:db-principal map. + certPrincipalMap []string + // for CLI commands that use the SQL interface, these parameters // determine how to connect to the server. sqlConnURL, sqlConnUser, sqlConnDBName string @@ -405,9 +407,3 @@ var demoCtx struct { insecure bool geoLibsDir string } - -// certCtx captures the command-line parameters of the `cert` command. -// Defaults set by InitCLIDefaults() above. -var certCtx struct { - certPrincipalMap []string -} diff --git a/pkg/cli/flags.go b/pkg/cli/flags.go index 5538d8037b23..f84c09db155e 100644 --- a/pkg/cli/flags.go +++ b/pkg/cli/flags.go @@ -240,7 +240,9 @@ func init() { // Every command but start will inherit the following setting. AddPersistentPreRunE(cockroachCmd, func(cmd *cobra.Command, _ []string) error { - extraClientFlagInit() + if err := extraClientFlagInit(); err != nil { + return err + } return setDefaultStderrVerbosity(cmd, log.Severity_WARNING) }) @@ -441,12 +443,11 @@ func init() { f := cmd.Flags() // All certs commands need the certificate directory. StringFlag(f, &baseCfg.SSLCertsDir, cliflags.CertsDir, baseCfg.SSLCertsDir) + // All certs commands get the certificate principal map. + StringSlice(f, &cliCtx.certPrincipalMap, + cliflags.CertPrincipalMap, cliCtx.certPrincipalMap) } - // The list certs command needs the certificate principal map. - StringSlice(listCertsCmd.Flags(), &certCtx.certPrincipalMap, - cliflags.CertPrincipalMap, certCtx.certPrincipalMap) - for _, cmd := range []*cobra.Command{createCACertCmd, createClientCACertCmd} { f := cmd.Flags() // CA certificates have a longer expiration time. @@ -495,6 +496,9 @@ func init() { // Certificate flags. StringFlag(f, &baseCfg.SSLCertsDir, cliflags.CertsDir, baseCfg.SSLCertsDir) + // Certificate principal map. + StringSlice(f, &cliCtx.certPrincipalMap, + cliflags.CertPrincipalMap, cliCtx.certPrincipalMap) } // Auth commands. @@ -878,7 +882,10 @@ func extraServerFlagInit(cmd *cobra.Command) error { return nil } -func extraClientFlagInit() { +func extraClientFlagInit() error { + if err := security.SetCertPrincipalMap(cliCtx.certPrincipalMap); err != nil { + return err + } serverCfg.Addr = net.JoinHostPort(cliCtx.clientConnHost, cliCtx.clientConnPort) serverCfg.AdvertiseAddr = serverCfg.Addr serverCfg.SQLAddr = net.JoinHostPort(cliCtx.clientConnHost, cliCtx.clientConnPort) @@ -894,6 +901,7 @@ func extraClientFlagInit() { if sqlCtx.debugMode { sqlCtx.echo = true } + return nil } func setDefaultStderrVerbosity(cmd *cobra.Command, defaultSeverity log.Severity) error { diff --git a/pkg/cli/flags_test.go b/pkg/cli/flags_test.go index 1a0890940d2e..f2c0323586c7 100644 --- a/pkg/cli/flags_test.go +++ b/pkg/cli/flags_test.go @@ -799,7 +799,9 @@ func TestServerJoinSettings(t *testing.T) { t.Fatalf("Parse(%#v) got unexpected error: %v", td.args, err) } - extraClientFlagInit() + if err := extraClientFlagInit(); err != nil { + t.Fatal(err) + } var actual []string myHostname, _ := os.Hostname() @@ -861,7 +863,9 @@ func TestClientConnSettings(t *testing.T) { t.Fatalf("Parse(%#v) got unexpected error: %v", td.args, err) } - extraClientFlagInit() + if err := extraClientFlagInit(); err != nil { + t.Fatal(err) + } if td.expectedAddr != serverCfg.Addr { t.Errorf("%d. serverCfg.Addr expected '%s', but got '%s'. td.args was '%#v'.", i, td.expectedAddr, serverCfg.Addr, td.args) diff --git a/pkg/cli/interactive_tests/test_cert_advisory_validation.tcl b/pkg/cli/interactive_tests/test_cert_advisory_validation.tcl index de08050f2d35..3529d256a8b5 100644 --- a/pkg/cli/interactive_tests/test_cert_advisory_validation.tcl +++ b/pkg/cli/interactive_tests/test_cert_advisory_validation.tcl @@ -11,7 +11,8 @@ set prompt ":/# " eexpect $prompt # create some cert without an IP address in there. -set certs_dir "./my-safe-directory" +set db_dir "logs/db" +set certs_dir "logs/my-safe-directory" send "mkdir -p $certs_dir\r" eexpect $prompt @@ -21,7 +22,7 @@ send "$argv cert create-node localhost --certs-dir=$certs_dir --ca-key=$certs_di eexpect $prompt start_test "Check that the server reports a warning if attempting to advertise an IP address not in cert." -send "$argv start-single-node --certs-dir=$certs_dir --advertise-addr=127.0.0.1\r" +send "$argv start-single-node --store=$db_dir --certs-dir=$certs_dir --advertise-addr=127.0.0.1\r" eexpect "advertise address" eexpect "127.0.0.1" eexpect "not in node certificate" @@ -32,7 +33,7 @@ eexpect $prompt end_test start_test "Check that the server reports no warning if the avertise addr is in the cert." -send "$argv start-single-node --certs-dir=$certs_dir --advertise-addr=localhost\r" +send "$argv start-single-node --store=$db_dir --certs-dir=$certs_dir --advertise-addr=localhost\r" expect { "not in node certificate" { report "unexpected warning" @@ -51,13 +52,13 @@ send "COCKROACH_CERT_NODE_USER=foo.bar $argv cert create-node localhost --certs- eexpect $prompt start_test "Check that the server reports an error if the node cert does not contain a node principal." -send "$argv start-single-node --certs-dir=$certs_dir --advertise-addr=localhost\r" +send "$argv start-single-node --store=$db_dir --certs-dir=$certs_dir --advertise-addr=localhost\r" eexpect "cannot load certificates" expect $prompt end_test start_test "Check that the cert principal map can allow the use of non-standard cert principal." -send "$argv start-single-node --certs-dir=$certs_dir --cert-principal-map=foo.bar:node --advertise-addr=localhost\r" +send "$argv start-single-node --store=$db_dir --certs-dir=$certs_dir --cert-principal-map=foo.bar:node --advertise-addr=localhost\r" eexpect "node starting" interrupt eexpect "interrupted" @@ -65,7 +66,7 @@ expect $prompt end_test start_test "Check that the cert principal map can allow the use of a SAN principal." -send "$argv start-single-node --certs-dir=$certs_dir --cert-principal-map=localhost:node --advertise-addr=localhost\r" +send "$argv start-single-node --store=$db_dir --certs-dir=$certs_dir --cert-principal-map=localhost:node --advertise-addr=localhost\r" eexpect "node starting" interrupt eexpect "interrupted" @@ -77,3 +78,23 @@ send "$argv cert list --certs-dir=$certs_dir --cert-principal-map=foo.bar:node\r eexpect "Certificate directory:" expect $prompt end_test + +start_test "Check that 'cert create-client' can utilize cert principal map." +send "$argv cert create-client root.crdb.io --certs-dir=$certs_dir --ca-key=$certs_dir/ca.key --cert-principal-map=foo.bar:node\r" +eexpect $prompt +send "mv $certs_dir/client.root.crdb.io.crt $certs_dir/client.root.crt; mv $certs_dir/client.root.crdb.io.key $certs_dir/client.root.key\r" +eexpect $prompt +end_test + +start_test "Check that the client commands can use cert principal map." +system "$argv start-single-node --store=$db_dir --certs-dir=$certs_dir --cert-principal-map=foo.bar:node,root.crdb.io:root --advertise-addr=localhost --background >>expect-cmd.log 2>&1" +send "$argv sql --certs-dir=$certs_dir --cert-principal-map=foo.bar:node,root.crdb.io:root -e \"select 'hello'\"\r" +eexpect "hello" +expect $prompt +send "$argv node ls --certs-dir=$certs_dir --cert-principal-map=foo.bar:node,root.crdb.io:root\r" +eexpect "1 row" +expect $prompt +send "$argv quit --certs-dir=$certs_dir --cert-principal-map=foo.bar:node,root.crdb.io:root\r" +eexpect "ok" +expect $prompt +end_test From 3afec705e249364c174fb858242cd39c08a18621 Mon Sep 17 00:00:00 2001 From: richardjcai Date: Fri, 3 Apr 2020 13:16:35 -0400 Subject: [PATCH 7/7] Add LogicalColumnID field to ColumnDescriptor. The LogicalColumnID field mimics the ColumnID field however LogicalColumnID may be swapped between two columns whereas ColumnID cannot. LogicalColumnID is referenced for virtual tables (pg_catalog, information_schema) and most notably affects column ordering for SHOW COLUMNS. This LogicalColumnID field support swapping the order of two columns - currently only used for ALTER COLUMN TYPE when a shadow column is created and swapped with it's original column. Does not affect existing behaviour. Release note: None --- pkg/sql/information_schema.go | 10 +- .../logictest/testdata/logic_test/pg_catalog | 23 + pkg/sql/pg_catalog.go | 14 +- pkg/sql/sqlbase/structured.go | 11 + pkg/sql/sqlbase/structured.pb.go | 593 ++++++++++-------- pkg/sql/sqlbase/structured.proto | 8 + pkg/sql/sqlbase/structured_test.go | 21 + 7 files changed, 389 insertions(+), 291 deletions(-) diff --git a/pkg/sql/information_schema.go b/pkg/sql/information_schema.go index 4c0fee087744..04ed34225817 100644 --- a/pkg/sql/information_schema.go +++ b/pkg/sql/information_schema.go @@ -387,11 +387,11 @@ https://www.postgresql.org/docs/9.5/infoschema-columns.html`, collationName = tree.NewDString(locale) } return addRow( - dbNameStr, // table_catalog - scNameStr, // table_schema - tree.NewDString(table.Name), // table_name - tree.NewDString(column.Name), // column_name - tree.NewDInt(tree.DInt(column.ID)), // ordinal_position + dbNameStr, // table_catalog + scNameStr, // table_schema + tree.NewDString(table.Name), // table_name + tree.NewDString(column.Name), // column_name + tree.NewDInt(tree.DInt(column.GetLogicalColumnID())), // ordinal_position dStringPtrOrNull(column.DefaultExpr), // column_default yesOrNoDatum(column.Nullable), // is_nullable tree.NewDString(column.Type.InformationSchemaName()), // data_type diff --git a/pkg/sql/logictest/testdata/logic_test/pg_catalog b/pkg/sql/logictest/testdata/logic_test/pg_catalog index 6d1b48120740..9b402a7de9b3 100644 --- a/pkg/sql/logictest/testdata/logic_test/pg_catalog +++ b/pkg/sql/logictest/testdata/logic_test/pg_catalog @@ -2279,3 +2279,26 @@ indexname indexdef primary CREATE UNIQUE INDEX "primary" ON test.public.geospatial_table USING btree (id ASC) idxa CREATE INDEX idxa ON test.public.geospatial_table USING gin (a ASC) idxb CREATE INDEX idxb ON test.public.geospatial_table USING gin (b ASC) + +subtest regression_46799 +statement ok +create table t(x INT DEFAULT 1, y INT DEFAULT 1); + +query I +select adnum from pg_attrdef WHERE adrelid = 85 +---- +1 +2 +3 + +statement ok +alter table t drop column y; +alter table t add column y int default 1; + +# make sure after adding and dropping the same column, the adnum for the re-added column increases. +query I +select adnum from pg_attrdef WHERE adrelid = 85 +---- +1 +3 +4 diff --git a/pkg/sql/pg_catalog.go b/pkg/sql/pg_catalog.go index 5e6e815152b1..48d00f8291d9 100644 --- a/pkg/sql/pg_catalog.go +++ b/pkg/sql/pg_catalog.go @@ -412,11 +412,11 @@ CREATE TABLE pg_catalog.pg_attrdef ( defSrc = tree.NewDString(ctx.String()) } return addRow( - h.ColumnOid(table.ID, column.ID), // oid - tableOid(table.ID), // adrelid - tree.NewDInt(tree.DInt(colNum)), // adnum - defSrc, // adbin - defSrc, // adsrc + h.ColumnOid(table.ID, column.ID), // oid + tableOid(table.ID), // adrelid + tree.NewDInt(tree.DInt(column.GetLogicalColumnID())), // adnum + defSrc, // adbin + defSrc, // adsrc ) }) }) @@ -502,7 +502,7 @@ CREATE TABLE pg_catalog.pg_attribute ( // Columns for table. if err := forEachColumnInTable(table, func(column *sqlbase.ColumnDescriptor) error { tableID := tableOid(table.ID) - return addColumn(column, tableID, column.ID) + return addColumn(column, tableID, column.GetLogicalColumnID()) }); err != nil { return err } @@ -512,7 +512,7 @@ CREATE TABLE pg_catalog.pg_attribute ( return forEachColumnInIndex(table, index, func(column *sqlbase.ColumnDescriptor) error { idxID := h.IndexOid(table.ID, index.ID) - return addColumn(column, idxID, column.ID) + return addColumn(column, idxID, column.GetLogicalColumnID()) }, ) }) diff --git a/pkg/sql/sqlbase/structured.go b/pkg/sql/sqlbase/structured.go index 6b497df45a37..7e0b1f830654 100644 --- a/pkg/sql/sqlbase/structured.go +++ b/pkg/sql/sqlbase/structured.go @@ -4130,3 +4130,14 @@ func GenerateUniqueConstraintName(prefix string, nameExistsFunc func(name string } return name } + +// GetLogicalColumnID returns the LogicalColumnID of the ColumnDescriptor +// if the LogicalColumnID is set (non-zero). Returns the ID of the +// ColumnDescriptor if the LogicalColumnID is not set. +func (desc ColumnDescriptor) GetLogicalColumnID() ColumnID { + if desc.LogicalColumnID != 0 { + return desc.LogicalColumnID + } + + return desc.ID +} diff --git a/pkg/sql/sqlbase/structured.pb.go b/pkg/sql/sqlbase/structured.pb.go index 81410f403381..f7c8d9962e57 100644 --- a/pkg/sql/sqlbase/structured.pb.go +++ b/pkg/sql/sqlbase/structured.pb.go @@ -74,7 +74,7 @@ func (x *ConstraintValidity) UnmarshalJSON(data []byte) error { return nil } func (ConstraintValidity) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{0} + return fileDescriptor_structured_b4380afd7e608b0d, []int{0} } type ForeignKeyReference_Action int32 @@ -119,7 +119,7 @@ func (x *ForeignKeyReference_Action) UnmarshalJSON(data []byte) error { return nil } func (ForeignKeyReference_Action) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{0, 0} + return fileDescriptor_structured_b4380afd7e608b0d, []int{0, 0} } // Match is the algorithm used to compare composite keys. @@ -159,7 +159,7 @@ func (x *ForeignKeyReference_Match) UnmarshalJSON(data []byte) error { return nil } func (ForeignKeyReference_Match) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{0, 1} + return fileDescriptor_structured_b4380afd7e608b0d, []int{0, 1} } // The direction of a column in the index. @@ -196,7 +196,7 @@ func (x *IndexDescriptor_Direction) UnmarshalJSON(data []byte) error { return nil } func (IndexDescriptor_Direction) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{7, 0} + return fileDescriptor_structured_b4380afd7e608b0d, []int{7, 0} } // The type of the index. @@ -233,7 +233,7 @@ func (x *IndexDescriptor_Type) UnmarshalJSON(data []byte) error { return nil } func (IndexDescriptor_Type) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{7, 1} + return fileDescriptor_structured_b4380afd7e608b0d, []int{7, 1} } type ConstraintToUpdate_ConstraintType int32 @@ -276,7 +276,7 @@ func (x *ConstraintToUpdate_ConstraintType) UnmarshalJSON(data []byte) error { return nil } func (ConstraintToUpdate_ConstraintType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{8, 0} + return fileDescriptor_structured_b4380afd7e608b0d, []int{8, 0} } // A descriptor within a mutation is unavailable for reads, writes @@ -341,7 +341,7 @@ func (x *DescriptorMutation_State) UnmarshalJSON(data []byte) error { return nil } func (DescriptorMutation_State) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{10, 0} + return fileDescriptor_structured_b4380afd7e608b0d, []int{10, 0} } // Direction of mutation. @@ -384,7 +384,7 @@ func (x *DescriptorMutation_Direction) UnmarshalJSON(data []byte) error { return nil } func (DescriptorMutation_Direction) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{10, 1} + return fileDescriptor_structured_b4380afd7e608b0d, []int{10, 1} } // State is set if this TableDescriptor is in the process of being added or deleted. @@ -435,7 +435,7 @@ func (x *TableDescriptor_State) UnmarshalJSON(data []byte) error { return nil } func (TableDescriptor_State) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{11, 0} + return fileDescriptor_structured_b4380afd7e608b0d, []int{11, 0} } // AuditMode indicates which auditing actions to take when this table is used. @@ -472,7 +472,7 @@ func (x *TableDescriptor_AuditMode) UnmarshalJSON(data []byte) error { return nil } func (TableDescriptor_AuditMode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{11, 1} + return fileDescriptor_structured_b4380afd7e608b0d, []int{11, 1} } type ForeignKeyReference struct { @@ -494,7 +494,7 @@ func (m *ForeignKeyReference) Reset() { *m = ForeignKeyReference{} } func (m *ForeignKeyReference) String() string { return proto.CompactTextString(m) } func (*ForeignKeyReference) ProtoMessage() {} func (*ForeignKeyReference) Descriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{0} + return fileDescriptor_structured_b4380afd7e608b0d, []int{0} } func (m *ForeignKeyReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -556,7 +556,7 @@ func (m *ForeignKeyConstraint) Reset() { *m = ForeignKeyConstraint{} } func (m *ForeignKeyConstraint) String() string { return proto.CompactTextString(m) } func (*ForeignKeyConstraint) ProtoMessage() {} func (*ForeignKeyConstraint) Descriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{1} + return fileDescriptor_structured_b4380afd7e608b0d, []int{1} } func (m *ForeignKeyConstraint) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -597,13 +597,20 @@ type ColumnDescriptor struct { // Expression to use to compute the value of this column if this is a // computed column. ComputeExpr *string `protobuf:"bytes,11,opt,name=compute_expr,json=computeExpr" json:"compute_expr,omitempty"` + // LogicalColumnID must be accessed through the accessor, since it is set + // lazily, it is incorrect to access it directly. + // LogicalColumnID represents a column's number in catalog tables. + // This only differs from ID when the Column order is swapped or + // the ColumnDescriptor must be remade while remaining visual ordering. + // This does not exist in TableDescriptors pre 20.2. + LogicalColumnID ColumnID `protobuf:"varint,13,opt,name=logical_id,json=logicalId,casttype=ColumnID" json:"logical_id"` } func (m *ColumnDescriptor) Reset() { *m = ColumnDescriptor{} } func (m *ColumnDescriptor) String() string { return proto.CompactTextString(m) } func (*ColumnDescriptor) ProtoMessage() {} func (*ColumnDescriptor) Descriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{2} + return fileDescriptor_structured_b4380afd7e608b0d, []int{2} } func (m *ColumnDescriptor) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -659,7 +666,7 @@ func (m *ColumnFamilyDescriptor) Reset() { *m = ColumnFamilyDescriptor{} func (m *ColumnFamilyDescriptor) String() string { return proto.CompactTextString(m) } func (*ColumnFamilyDescriptor) ProtoMessage() {} func (*ColumnFamilyDescriptor) Descriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{3} + return fileDescriptor_structured_b4380afd7e608b0d, []int{3} } func (m *ColumnFamilyDescriptor) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -705,7 +712,7 @@ func (m *InterleaveDescriptor) Reset() { *m = InterleaveDescriptor{} } func (m *InterleaveDescriptor) String() string { return proto.CompactTextString(m) } func (*InterleaveDescriptor) ProtoMessage() {} func (*InterleaveDescriptor) Descriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{4} + return fileDescriptor_structured_b4380afd7e608b0d, []int{4} } func (m *InterleaveDescriptor) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -749,7 +756,7 @@ func (m *InterleaveDescriptor_Ancestor) Reset() { *m = InterleaveDescrip func (m *InterleaveDescriptor_Ancestor) String() string { return proto.CompactTextString(m) } func (*InterleaveDescriptor_Ancestor) ProtoMessage() {} func (*InterleaveDescriptor_Ancestor) Descriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{4, 0} + return fileDescriptor_structured_b4380afd7e608b0d, []int{4, 0} } func (m *InterleaveDescriptor_Ancestor) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -804,7 +811,7 @@ func (m *ShardedDescriptor) Reset() { *m = ShardedDescriptor{} } func (m *ShardedDescriptor) String() string { return proto.CompactTextString(m) } func (*ShardedDescriptor) ProtoMessage() {} func (*ShardedDescriptor) Descriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{5} + return fileDescriptor_structured_b4380afd7e608b0d, []int{5} } func (m *ShardedDescriptor) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -849,7 +856,7 @@ func (m *PartitioningDescriptor) Reset() { *m = PartitioningDescriptor{} func (m *PartitioningDescriptor) String() string { return proto.CompactTextString(m) } func (*PartitioningDescriptor) ProtoMessage() {} func (*PartitioningDescriptor) Descriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{6} + return fileDescriptor_structured_b4380afd7e608b0d, []int{6} } func (m *PartitioningDescriptor) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -892,7 +899,7 @@ func (m *PartitioningDescriptor_List) Reset() { *m = PartitioningDescrip func (m *PartitioningDescriptor_List) String() string { return proto.CompactTextString(m) } func (*PartitioningDescriptor_List) ProtoMessage() {} func (*PartitioningDescriptor_List) Descriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{6, 0} + return fileDescriptor_structured_b4380afd7e608b0d, []int{6, 0} } func (m *PartitioningDescriptor_List) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -937,7 +944,7 @@ func (m *PartitioningDescriptor_Range) Reset() { *m = PartitioningDescri func (m *PartitioningDescriptor_Range) String() string { return proto.CompactTextString(m) } func (*PartitioningDescriptor_Range) ProtoMessage() {} func (*PartitioningDescriptor_Range) Descriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{6, 1} + return fileDescriptor_structured_b4380afd7e608b0d, []int{6, 1} } func (m *PartitioningDescriptor_Range) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1086,7 +1093,7 @@ func (m *IndexDescriptor) Reset() { *m = IndexDescriptor{} } func (m *IndexDescriptor) String() string { return proto.CompactTextString(m) } func (*IndexDescriptor) ProtoMessage() {} func (*IndexDescriptor) Descriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{7} + return fileDescriptor_structured_b4380afd7e608b0d, []int{7} } func (m *IndexDescriptor) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1137,7 +1144,7 @@ func (m *ConstraintToUpdate) Reset() { *m = ConstraintToUpdate{} } func (m *ConstraintToUpdate) String() string { return proto.CompactTextString(m) } func (*ConstraintToUpdate) ProtoMessage() {} func (*ConstraintToUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{8} + return fileDescriptor_structured_b4380afd7e608b0d, []int{8} } func (m *ConstraintToUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1180,7 +1187,7 @@ func (m *PrimaryKeySwap) Reset() { *m = PrimaryKeySwap{} } func (m *PrimaryKeySwap) String() string { return proto.CompactTextString(m) } func (*PrimaryKeySwap) ProtoMessage() {} func (*PrimaryKeySwap) Descriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{9} + return fileDescriptor_structured_b4380afd7e608b0d, []int{9} } func (m *PrimaryKeySwap) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1235,7 +1242,7 @@ func (m *DescriptorMutation) Reset() { *m = DescriptorMutation{} } func (m *DescriptorMutation) String() string { return proto.CompactTextString(m) } func (*DescriptorMutation) ProtoMessage() {} func (*DescriptorMutation) Descriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{10} + return fileDescriptor_structured_b4380afd7e608b0d, []int{10} } func (m *DescriptorMutation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1584,7 +1591,7 @@ func (m *TableDescriptor) Reset() { *m = TableDescriptor{} } func (m *TableDescriptor) String() string { return proto.CompactTextString(m) } func (*TableDescriptor) ProtoMessage() {} func (*TableDescriptor) Descriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{11} + return fileDescriptor_structured_b4380afd7e608b0d, []int{11} } func (m *TableDescriptor) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1884,7 +1891,7 @@ func (m *TableDescriptor_SchemaChangeLease) Reset() { *m = TableDescript func (m *TableDescriptor_SchemaChangeLease) String() string { return proto.CompactTextString(m) } func (*TableDescriptor_SchemaChangeLease) ProtoMessage() {} func (*TableDescriptor_SchemaChangeLease) Descriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{11, 0} + return fileDescriptor_structured_b4380afd7e608b0d, []int{11, 0} } func (m *TableDescriptor_SchemaChangeLease) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1925,7 +1932,7 @@ func (m *TableDescriptor_CheckConstraint) Reset() { *m = TableDescriptor func (m *TableDescriptor_CheckConstraint) String() string { return proto.CompactTextString(m) } func (*TableDescriptor_CheckConstraint) ProtoMessage() {} func (*TableDescriptor_CheckConstraint) Descriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{11, 1} + return fileDescriptor_structured_b4380afd7e608b0d, []int{11, 1} } func (m *TableDescriptor_CheckConstraint) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2031,7 +2038,7 @@ func (m *TableDescriptor_NameInfo) Reset() { *m = TableDescriptor_NameIn func (m *TableDescriptor_NameInfo) String() string { return proto.CompactTextString(m) } func (*TableDescriptor_NameInfo) ProtoMessage() {} func (*TableDescriptor_NameInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{11, 2} + return fileDescriptor_structured_b4380afd7e608b0d, []int{11, 2} } func (m *TableDescriptor_NameInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2071,7 +2078,7 @@ func (m *TableDescriptor_Reference) Reset() { *m = TableDescriptor_Refer func (m *TableDescriptor_Reference) String() string { return proto.CompactTextString(m) } func (*TableDescriptor_Reference) ProtoMessage() {} func (*TableDescriptor_Reference) Descriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{11, 3} + return fileDescriptor_structured_b4380afd7e608b0d, []int{11, 3} } func (m *TableDescriptor_Reference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2108,7 +2115,7 @@ func (m *TableDescriptor_MutationJob) Reset() { *m = TableDescriptor_Mut func (m *TableDescriptor_MutationJob) String() string { return proto.CompactTextString(m) } func (*TableDescriptor_MutationJob) ProtoMessage() {} func (*TableDescriptor_MutationJob) Descriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{11, 4} + return fileDescriptor_structured_b4380afd7e608b0d, []int{11, 4} } func (m *TableDescriptor_MutationJob) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2151,7 +2158,7 @@ func (m *TableDescriptor_SequenceOpts) Reset() { *m = TableDescriptor_Se func (m *TableDescriptor_SequenceOpts) String() string { return proto.CompactTextString(m) } func (*TableDescriptor_SequenceOpts) ProtoMessage() {} func (*TableDescriptor_SequenceOpts) Descriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{11, 5} + return fileDescriptor_structured_b4380afd7e608b0d, []int{11, 5} } func (m *TableDescriptor_SequenceOpts) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2191,7 +2198,7 @@ func (m *TableDescriptor_SequenceOpts_SequenceOwner) String() string { } func (*TableDescriptor_SequenceOpts_SequenceOwner) ProtoMessage() {} func (*TableDescriptor_SequenceOpts_SequenceOwner) Descriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{11, 5, 0} + return fileDescriptor_structured_b4380afd7e608b0d, []int{11, 5, 0} } func (m *TableDescriptor_SequenceOpts_SequenceOwner) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2231,7 +2238,7 @@ func (m *TableDescriptor_Replacement) Reset() { *m = TableDescriptor_Rep func (m *TableDescriptor_Replacement) String() string { return proto.CompactTextString(m) } func (*TableDescriptor_Replacement) ProtoMessage() {} func (*TableDescriptor_Replacement) Descriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{11, 6} + return fileDescriptor_structured_b4380afd7e608b0d, []int{11, 6} } func (m *TableDescriptor_Replacement) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2268,7 +2275,7 @@ func (m *TableDescriptor_GCDescriptorMutation) Reset() { *m = TableDescr func (m *TableDescriptor_GCDescriptorMutation) String() string { return proto.CompactTextString(m) } func (*TableDescriptor_GCDescriptorMutation) ProtoMessage() {} func (*TableDescriptor_GCDescriptorMutation) Descriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{11, 7} + return fileDescriptor_structured_b4380afd7e608b0d, []int{11, 7} } func (m *TableDescriptor_GCDescriptorMutation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2307,7 +2314,7 @@ func (m *DatabaseDescriptor) Reset() { *m = DatabaseDescriptor{} } func (m *DatabaseDescriptor) String() string { return proto.CompactTextString(m) } func (*DatabaseDescriptor) ProtoMessage() {} func (*DatabaseDescriptor) Descriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{12} + return fileDescriptor_structured_b4380afd7e608b0d, []int{12} } func (m *DatabaseDescriptor) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2365,7 +2372,7 @@ func (m *Descriptor) Reset() { *m = Descriptor{} } func (m *Descriptor) String() string { return proto.CompactTextString(m) } func (*Descriptor) ProtoMessage() {} func (*Descriptor) Descriptor() ([]byte, []int) { - return fileDescriptor_structured_c64a18584f227d86, []int{13} + return fileDescriptor_structured_b4380afd7e608b0d, []int{13} } func (m *Descriptor) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2717,6 +2724,9 @@ func (this *ColumnDescriptor) Equal(that interface{}) bool { } else if that1.ComputeExpr != nil { return false } + if this.LogicalColumnID != that1.LogicalColumnID { + return false + } return true } func (this *ColumnFamilyDescriptor) Equal(that interface{}) bool { @@ -4077,6 +4087,9 @@ func (m *ColumnDescriptor) MarshalTo(dAtA []byte) (int, error) { i = encodeVarintStructured(dAtA, i, uint64(num)) } } + dAtA[i] = 0x68 + i++ + i = encodeVarintStructured(dAtA, i, uint64(m.LogicalColumnID)) return i, nil } @@ -5523,6 +5536,7 @@ func (m *ColumnDescriptor) Size() (n int) { n += 1 + sovStructured(uint64(e)) } } + n += 1 + sovStructured(uint64(m.LogicalColumnID)) return n } @@ -7088,6 +7102,25 @@ func (m *ColumnDescriptor) Unmarshal(dAtA []byte) error { } else { return fmt.Errorf("proto: wrong wireType = %d for field OwnsSequenceIds", wireType) } + case 13: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LogicalColumnID", wireType) + } + m.LogicalColumnID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStructured + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.LogicalColumnID |= (ColumnID(b) & 0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipStructured(dAtA[iNdEx:]) @@ -12172,247 +12205,249 @@ var ( ) func init() { - proto.RegisterFile("sql/sqlbase/structured.proto", fileDescriptor_structured_c64a18584f227d86) -} - -var fileDescriptor_structured_c64a18584f227d86 = []byte{ - // 3804 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x5a, 0xcb, 0x6f, 0x1b, 0xd7, - 0x7a, 0xd7, 0xf0, 0xcd, 0x6f, 0x48, 0x6a, 0x78, 0x24, 0xdb, 0xb4, 0xe2, 0x2b, 0xca, 0x74, 0x9c, - 0xe8, 0xde, 0x24, 0x92, 0x23, 0xf7, 0xe1, 0x9b, 0x16, 0x17, 0xe1, 0x4b, 0x16, 0x2d, 0x99, 0x54, - 0x46, 0x72, 0x7c, 0x5b, 0xdc, 0x76, 0x3a, 0xe2, 0x1c, 0x52, 0x13, 0x0f, 0x67, 0xe8, 0x99, 0xa1, - 0x2c, 0x01, 0x5d, 0xb5, 0x9b, 0xae, 0x8a, 0xfe, 0x03, 0x05, 0x82, 0x22, 0x68, 0xb3, 0xed, 0xa6, - 0xdd, 0x15, 0xe8, 0xa6, 0xc8, 0xae, 0x17, 0xe8, 0xe6, 0xa2, 0x0b, 0xa1, 0x55, 0x36, 0xdd, 0x76, - 0xd3, 0x02, 0x59, 0x15, 0xe7, 0x35, 0x0f, 0x8a, 0x52, 0x29, 0xfb, 0xde, 0x1d, 0xe7, 0xfb, 0xce, - 0xf7, 0x3b, 0xaf, 0xef, 0x7d, 0x08, 0xf7, 0xbc, 0xd7, 0xd6, 0xa6, 0xf7, 0xda, 0x3a, 0xd2, 0x3d, - 0xbc, 0xe9, 0xf9, 0xee, 0xa4, 0xef, 0x4f, 0x5c, 0x6c, 0x6c, 0x8c, 0x5d, 0xc7, 0x77, 0xd0, 0xad, - 0xbe, 0xd3, 0x7f, 0xe5, 0x3a, 0x7a, 0xff, 0x78, 0xc3, 0x7b, 0x6d, 0x6d, 0xf0, 0x71, 0x2b, 0x95, - 0x89, 0x6f, 0x5a, 0x9b, 0xc7, 0x56, 0x7f, 0xd3, 0x37, 0x47, 0xd8, 0xf3, 0xf5, 0xd1, 0x98, 0x09, - 0xac, 0xbc, 0x17, 0x85, 0x1b, 0xbb, 0xe6, 0x89, 0x69, 0xe1, 0x21, 0xe6, 0xcc, 0xbb, 0x43, 0xec, - 0x6c, 0x0e, 0xb1, 0x63, 0xda, 0x06, 0x3e, 0xdd, 0xec, 0x3b, 0xf6, 0xc0, 0x1c, 0x72, 0xd6, 0xf2, - 0xd0, 0x19, 0x3a, 0xf4, 0xe7, 0x26, 0xf9, 0xc5, 0xa8, 0xb5, 0x3f, 0x4b, 0xc3, 0xd2, 0xb6, 0xe3, - 0x62, 0x73, 0x68, 0xef, 0xe2, 0x33, 0x15, 0x0f, 0xb0, 0x8b, 0xed, 0x3e, 0x46, 0x6b, 0x90, 0xf6, - 0xf5, 0x23, 0x0b, 0x57, 0xa4, 0x35, 0x69, 0xbd, 0xd8, 0x80, 0xef, 0xce, 0xab, 0x0b, 0x3f, 0x9c, - 0x57, 0x13, 0x9d, 0x96, 0xca, 0x18, 0xe8, 0x21, 0xa4, 0xe9, 0x2c, 0x95, 0x04, 0x1d, 0xb1, 0xc8, - 0x47, 0x64, 0x3b, 0x84, 0x48, 0x86, 0x51, 0x2e, 0xaa, 0x40, 0xca, 0xd6, 0x47, 0xb8, 0x92, 0x5c, - 0x93, 0xd6, 0xf3, 0x8d, 0x14, 0x19, 0xa5, 0x52, 0x0a, 0xda, 0x85, 0xdc, 0x89, 0x6e, 0x99, 0x86, - 0xe9, 0x9f, 0x55, 0x52, 0x6b, 0xd2, 0x7a, 0x69, 0xeb, 0xc7, 0x1b, 0x33, 0x0f, 0x63, 0xa3, 0xe9, - 0xd8, 0x9e, 0xef, 0xea, 0xa6, 0xed, 0x7f, 0xc9, 0x05, 0x38, 0x50, 0x00, 0x80, 0x1e, 0x41, 0xd9, - 0x3b, 0xd6, 0x5d, 0x6c, 0x68, 0x63, 0x17, 0x0f, 0xcc, 0x53, 0xcd, 0xc2, 0x76, 0x25, 0xbd, 0x26, - 0xad, 0xa7, 0xf9, 0xd0, 0x45, 0xc6, 0xde, 0xa7, 0xdc, 0x3d, 0x6c, 0xa3, 0x43, 0xc8, 0x3b, 0xb6, - 0x66, 0x60, 0x0b, 0xfb, 0xb8, 0x92, 0xa1, 0xf3, 0x7f, 0x7a, 0xc5, 0xfc, 0x33, 0x0e, 0x68, 0xa3, - 0xde, 0xf7, 0x4d, 0xc7, 0x16, 0xeb, 0x70, 0xec, 0x16, 0x05, 0xe2, 0xa8, 0x93, 0xb1, 0xa1, 0xfb, - 0xb8, 0x92, 0x7d, 0x67, 0xd4, 0x17, 0x14, 0x08, 0xed, 0x41, 0x7a, 0xa4, 0xfb, 0xfd, 0xe3, 0x4a, - 0x8e, 0x22, 0x3e, 0xba, 0x01, 0xe2, 0x73, 0x22, 0xc7, 0x01, 0x19, 0x48, 0xed, 0x25, 0x64, 0xd8, - 0x3c, 0xa8, 0x08, 0xf9, 0x6e, 0x4f, 0xab, 0x37, 0x0f, 0x3b, 0xbd, 0xae, 0xb2, 0x80, 0x0a, 0x90, - 0x53, 0xdb, 0x07, 0x87, 0x6a, 0xa7, 0x79, 0xa8, 0x48, 0xe4, 0xeb, 0xa0, 0x7d, 0xa8, 0x75, 0x5f, - 0xec, 0xed, 0x29, 0x09, 0xb4, 0x08, 0x32, 0xf9, 0x6a, 0xb5, 0xb7, 0xeb, 0x2f, 0xf6, 0x0e, 0x95, - 0x24, 0x92, 0x21, 0xdb, 0xac, 0x1f, 0x34, 0xeb, 0xad, 0xb6, 0x92, 0x5a, 0x49, 0x7d, 0xfb, 0xcd, - 0xea, 0x42, 0xed, 0x11, 0xa4, 0xe9, 0x74, 0x08, 0x20, 0x73, 0xd0, 0x79, 0xbe, 0xbf, 0xd7, 0x56, - 0x16, 0x50, 0x0e, 0x52, 0xdb, 0x04, 0x42, 0x22, 0x12, 0xfb, 0x75, 0xf5, 0xb0, 0x53, 0xdf, 0x53, - 0x12, 0x4c, 0xe2, 0xb3, 0xd4, 0x7f, 0x7d, 0x5d, 0x95, 0x6a, 0xff, 0x96, 0x81, 0xe5, 0x70, 0xed, - 0xe1, 0x6d, 0xa3, 0x26, 0x2c, 0x3a, 0xae, 0x39, 0x34, 0x6d, 0x8d, 0xea, 0x9c, 0x66, 0x1a, 0x5c, - 0x1f, 0xdf, 0x23, 0xfb, 0xb9, 0x38, 0xaf, 0x16, 0x7b, 0x94, 0x7d, 0x48, 0xb8, 0x9d, 0x16, 0x57, - 0xd0, 0xa2, 0x13, 0x21, 0x1a, 0x68, 0x17, 0xca, 0x1c, 0xa4, 0xef, 0x58, 0x93, 0x91, 0xad, 0x99, - 0x86, 0x57, 0x49, 0xac, 0x25, 0xd7, 0x8b, 0x8d, 0xea, 0xc5, 0x79, 0x75, 0x91, 0x41, 0x34, 0x29, - 0xaf, 0xd3, 0xf2, 0x7e, 0x38, 0xaf, 0xe6, 0xc4, 0x87, 0xca, 0xa7, 0xe7, 0xdf, 0x86, 0x87, 0x5e, - 0xc2, 0x2d, 0x57, 0x9c, 0xad, 0x11, 0x05, 0x4c, 0x52, 0xc0, 0x07, 0x17, 0xe7, 0xd5, 0xa5, 0xe0, - 0xf0, 0x8d, 0xd9, 0xa0, 0x4b, 0xee, 0xf4, 0x00, 0xc3, 0x43, 0x3d, 0x88, 0x90, 0xc3, 0xed, 0xa6, - 0xe8, 0x76, 0xab, 0x7c, 0xbb, 0xe5, 0x10, 0x3a, 0xbe, 0xe5, 0xb2, 0x3b, 0xc5, 0x30, 0x02, 0xc3, - 0x4b, 0x5f, 0x6b, 0x78, 0x99, 0x77, 0x35, 0xbc, 0x98, 0x19, 0x65, 0x7f, 0x23, 0x66, 0x94, 0xfb, - 0xb5, 0x9b, 0x51, 0xfe, 0xd7, 0x60, 0x46, 0xa8, 0x0e, 0x4b, 0x16, 0x1e, 0xea, 0xfd, 0x33, 0x8d, - 0xab, 0x17, 0x73, 0x87, 0x40, 0x6f, 0xac, 0x3c, 0xe5, 0x0e, 0x2b, 0x92, 0x5a, 0x66, 0xa3, 0x99, - 0xba, 0x51, 0x32, 0xea, 0xc0, 0x1d, 0x0e, 0x11, 0xb9, 0x7b, 0x06, 0x23, 0x5f, 0x05, 0x73, 0x8b, - 0x49, 0x84, 0x9a, 0x40, 0x59, 0xcc, 0x92, 0x9e, 0xa5, 0x72, 0x05, 0xa5, 0xf8, 0x2c, 0x95, 0x2b, - 0x2a, 0xa5, 0xda, 0xb7, 0x49, 0x50, 0x98, 0x7e, 0xb5, 0xb0, 0xd7, 0x77, 0xcd, 0xb1, 0xef, 0xb8, - 0x81, 0x56, 0x48, 0x97, 0xb4, 0xe2, 0x03, 0x48, 0x98, 0x06, 0x77, 0xe6, 0xb7, 0xb9, 0xbe, 0x25, - 0xa8, 0x82, 0x85, 0x9a, 0x9b, 0x30, 0x0d, 0xb4, 0x07, 0x29, 0xff, 0x6c, 0xcc, 0x1c, 0x7a, 0xa1, - 0xf1, 0x84, 0x8c, 0xfc, 0xf7, 0xf3, 0xea, 0xa3, 0xa1, 0xe9, 0x1f, 0x4f, 0x8e, 0x36, 0xfa, 0xce, - 0x68, 0x33, 0x38, 0x55, 0xe3, 0x28, 0xfc, 0xbd, 0x39, 0x7e, 0x35, 0x24, 0x61, 0x6b, 0x93, 0x08, - 0x7b, 0x1b, 0x87, 0x2a, 0x45, 0x41, 0x6b, 0x90, 0xb3, 0x27, 0x96, 0x45, 0x43, 0x0d, 0xd1, 0xf5, - 0x9c, 0xb8, 0x34, 0x41, 0x45, 0xf7, 0xa1, 0x60, 0xe0, 0x81, 0x3e, 0xb1, 0x7c, 0x0d, 0x9f, 0x8e, - 0x5d, 0xa6, 0xcf, 0xaa, 0xcc, 0x69, 0xed, 0xd3, 0xb1, 0x8b, 0xee, 0x41, 0xe6, 0xd8, 0x34, 0x0c, - 0x6c, 0x53, 0x75, 0x16, 0x10, 0x9c, 0x86, 0xb6, 0xa0, 0x3c, 0xf1, 0xb0, 0xa7, 0x79, 0xf8, 0xf5, - 0x84, 0x1c, 0x18, 0x35, 0x57, 0xa0, 0xe6, 0x9a, 0xe1, 0xe6, 0xb3, 0x48, 0x06, 0x1c, 0x70, 0x3e, - 0xb1, 0xc6, 0xfb, 0x50, 0xe8, 0x3b, 0xa3, 0xf1, 0xc4, 0xc7, 0x6c, 0x52, 0x99, 0x4d, 0xca, 0x69, - 0x74, 0xd2, 0x2d, 0x28, 0x3b, 0x6f, 0xec, 0x29, 0xd8, 0x42, 0x1c, 0x96, 0x0c, 0x88, 0xc0, 0x06, - 0x97, 0x94, 0x53, 0xf2, 0xcf, 0x52, 0xb9, 0xbc, 0x02, 0xcf, 0x52, 0xb9, 0xac, 0x92, 0xab, 0xfd, - 0x65, 0x02, 0x6e, 0xb3, 0x43, 0xde, 0xd6, 0x47, 0xa6, 0x75, 0xf6, 0xae, 0x17, 0xc6, 0x50, 0xf8, - 0x85, 0xd1, 0xbd, 0x50, 0x3f, 0x45, 0xc4, 0x98, 0xa7, 0xa2, 0x7b, 0x21, 0xb4, 0x2e, 0x21, 0xa1, - 0x27, 0x00, 0x11, 0x57, 0x96, 0xa2, 0x9b, 0xb8, 0x7b, 0x71, 0x5e, 0xcd, 0xcf, 0x76, 0x60, 0xf9, - 0x7e, 0xc4, 0x6d, 0x95, 0xc5, 0xed, 0x04, 0x08, 0xf4, 0x8a, 0x8a, 0x8d, 0x07, 0x7c, 0x4d, 0x8b, - 0x2d, 0x36, 0x40, 0x88, 0xc7, 0x1d, 0xac, 0x11, 0x63, 0x1a, 0x3c, 0x22, 0xfc, 0x63, 0x02, 0x96, - 0x3b, 0xb6, 0x8f, 0x5d, 0x0b, 0xeb, 0x27, 0x38, 0x72, 0x1c, 0x3f, 0x87, 0xbc, 0x6e, 0xf7, 0xb1, - 0xe7, 0x3b, 0xae, 0x57, 0x91, 0xd6, 0x92, 0xeb, 0xf2, 0xd6, 0x6f, 0x5d, 0x61, 0xc6, 0xb3, 0xe4, - 0x37, 0xea, 0x5c, 0x98, 0x9f, 0x64, 0x08, 0xb6, 0xf2, 0x4f, 0x12, 0xe4, 0x04, 0x17, 0x3d, 0x82, - 0xdc, 0x54, 0xc4, 0xb9, 0xc5, 0x77, 0x93, 0x8d, 0x3b, 0xde, 0xac, 0xcf, 0xdd, 0xed, 0x6f, 0x43, - 0x8e, 0x1a, 0xae, 0x16, 0xdc, 0xc9, 0x8a, 0x90, 0xe0, 0xb6, 0x1b, 0x4d, 0x8e, 0xb2, 0x74, 0x6c, - 0xc7, 0x40, 0xcd, 0x59, 0x79, 0x4b, 0x92, 0xca, 0xdf, 0x11, 0xe7, 0x77, 0x10, 0xcf, 0x5c, 0x2e, - 0xa5, 0x32, 0xec, 0xcc, 0xf8, 0xc9, 0xfd, 0x83, 0x04, 0x65, 0x22, 0x60, 0x60, 0x23, 0x72, 0x6c, - 0x0f, 0x00, 0x4c, 0x4f, 0xf3, 0x18, 0x9d, 0xee, 0x48, 0x58, 0x49, 0xde, 0xf4, 0xf8, 0xf0, 0x40, - 0xd5, 0x12, 0x97, 0x54, 0xed, 0xa7, 0x50, 0xa4, 0xb2, 0xda, 0xd1, 0xa4, 0xff, 0x0a, 0xfb, 0x1e, - 0x5d, 0x61, 0xba, 0xb1, 0xcc, 0x57, 0x58, 0xa0, 0x08, 0x0d, 0xc6, 0x53, 0x0b, 0x5e, 0xe4, 0xeb, - 0x92, 0xf6, 0xa5, 0x2e, 0x69, 0x1f, 0x5f, 0xf8, 0xff, 0x26, 0xe1, 0xf6, 0xbe, 0xee, 0xfa, 0x26, - 0x71, 0xdd, 0xa6, 0x3d, 0x8c, 0xac, 0xfe, 0x21, 0xc8, 0xf6, 0x64, 0xc4, 0x15, 0xcc, 0xe3, 0x17, - 0xc2, 0xd6, 0x07, 0xf6, 0x64, 0xc4, 0x74, 0xc7, 0x23, 0x9e, 0xc9, 0x32, 0x3d, 0x9f, 0xc6, 0x76, - 0x79, 0x6b, 0xeb, 0x0a, 0xb5, 0x98, 0x3d, 0xc7, 0xc6, 0x9e, 0xe9, 0xf9, 0x62, 0xcf, 0x04, 0x05, - 0xf5, 0x20, 0xed, 0xea, 0xf6, 0x10, 0x53, 0x7b, 0x91, 0xb7, 0x1e, 0xdf, 0x0c, 0x4e, 0x25, 0xa2, - 0x22, 0x5e, 0x50, 0x9c, 0x95, 0xbf, 0x96, 0x20, 0x45, 0x66, 0xb9, 0xc6, 0xa4, 0x6f, 0x43, 0xe6, - 0x44, 0xb7, 0x26, 0x98, 0xe5, 0x27, 0x05, 0x95, 0x7f, 0xa1, 0x3f, 0x82, 0x45, 0x6f, 0x72, 0x34, - 0x8e, 0x4c, 0x45, 0x6f, 0x40, 0xde, 0xfa, 0xe4, 0x46, 0xab, 0x0a, 0x52, 0xe1, 0x38, 0x16, 0xbb, - 0x80, 0x95, 0xd7, 0x90, 0xa6, 0xab, 0xbe, 0x66, 0x7d, 0xf7, 0xa1, 0xe0, 0x3b, 0x1a, 0x3e, 0xed, - 0x5b, 0x13, 0xcf, 0x3c, 0x61, 0x9a, 0x52, 0x50, 0x65, 0xdf, 0x69, 0x0b, 0x12, 0x7a, 0x08, 0xa5, - 0x81, 0xeb, 0x8c, 0x34, 0xd3, 0x16, 0x83, 0x68, 0xa0, 0x50, 0x8b, 0x84, 0xda, 0x11, 0xc4, 0x98, - 0xca, 0xfe, 0xb7, 0x0c, 0x8b, 0xd4, 0x30, 0xe6, 0x72, 0x7b, 0x0f, 0x23, 0x6e, 0xef, 0x56, 0xcc, - 0xed, 0x05, 0xd6, 0x45, 0xbc, 0xde, 0x3d, 0xc8, 0x4c, 0x6c, 0xf3, 0xf5, 0x84, 0xcd, 0x1f, 0xc4, - 0x04, 0x46, 0x9b, 0x43, 0x2b, 0xd1, 0xc7, 0x80, 0x88, 0x2b, 0xc0, 0x5a, 0x6c, 0x60, 0x9a, 0x0e, - 0x54, 0x28, 0xa7, 0x79, 0xa5, 0x07, 0xcd, 0xdc, 0xc0, 0x83, 0xee, 0x80, 0x82, 0x4f, 0x7d, 0x57, - 0x8f, 0x26, 0x93, 0x59, 0x2a, 0xbf, 0x7a, 0x71, 0x5e, 0x2d, 0xb5, 0x09, 0x6f, 0x36, 0x48, 0x09, - 0x47, 0x78, 0x06, 0xd1, 0x92, 0x32, 0xc7, 0x30, 0x4c, 0x17, 0xd3, 0x14, 0xc8, 0xab, 0xe4, 0xd6, - 0x92, 0xd7, 0xa4, 0x3a, 0x53, 0xc7, 0xbe, 0xd1, 0x12, 0x82, 0xaa, 0xc2, 0xa0, 0x02, 0x82, 0x87, - 0x0e, 0x40, 0x1e, 0xb0, 0xcc, 0x48, 0x7b, 0x85, 0xcf, 0x68, 0x0e, 0x25, 0x6f, 0xfd, 0x64, 0xfe, - 0x1c, 0xaa, 0x91, 0x21, 0x57, 0x50, 0x91, 0x54, 0x18, 0x04, 0x4c, 0xf4, 0x12, 0x8a, 0x91, 0xd4, - 0xe7, 0xe8, 0x8c, 0x06, 0xe6, 0xb7, 0x83, 0x2d, 0x84, 0x40, 0x8d, 0x33, 0xf4, 0x05, 0x80, 0x19, - 0x04, 0x00, 0x1a, 0xbf, 0xe5, 0xad, 0x8f, 0x6e, 0x10, 0x29, 0x84, 0x7f, 0x09, 0x41, 0xd0, 0x4b, - 0x28, 0x85, 0x5f, 0x74, 0xb1, 0x85, 0x1b, 0x2f, 0x96, 0xa1, 0x16, 0x23, 0x38, 0x0d, 0x92, 0x43, - 0x2f, 0x93, 0xcc, 0xc2, 0xf1, 0x4c, 0x1f, 0x47, 0xd5, 0xa0, 0x48, 0xd5, 0xa0, 0x76, 0x71, 0x5e, - 0x45, 0x4d, 0xc1, 0x9f, 0xad, 0x0a, 0xa8, 0x3f, 0xc5, 0x67, 0x8a, 0x15, 0x53, 0x60, 0x82, 0x58, - 0x0a, 0x15, 0xeb, 0x20, 0x54, 0xe1, 0x4b, 0x8a, 0x15, 0x51, 0x6f, 0x56, 0xf4, 0x14, 0x62, 0xbe, - 0x67, 0xf1, 0xed, 0x7d, 0x4f, 0x0c, 0x08, 0xb5, 0x79, 0x2e, 0xa9, 0xd0, 0x7c, 0xfc, 0xa3, 0x39, - 0x95, 0xf4, 0xf0, 0x6c, 0x2c, 0x0e, 0x92, 0x25, 0x91, 0x8f, 0x01, 0xf5, 0x5d, 0xac, 0xfb, 0xd8, - 0x20, 0xd9, 0x9a, 0x65, 0xf6, 0x4d, 0xdf, 0x3a, 0xab, 0x94, 0x23, 0x76, 0x5f, 0xe6, 0xfc, 0x76, - 0xc0, 0x46, 0x4f, 0x20, 0x7b, 0x82, 0x5d, 0xcf, 0x74, 0xec, 0x0a, 0xa2, 0xce, 0x64, 0x95, 0xe7, - 0xda, 0xb7, 0xa7, 0xe6, 0xfb, 0x92, 0x8d, 0x52, 0xc5, 0x70, 0xb4, 0x03, 0x45, 0x6c, 0xf7, 0x1d, - 0xc3, 0xb4, 0x87, 0x1a, 0x5d, 0xfe, 0x52, 0x98, 0xef, 0xfc, 0x70, 0x5e, 0x7d, 0x6f, 0x4a, 0xbe, - 0xcd, 0xc7, 0x92, 0x65, 0xab, 0x05, 0x1c, 0xf9, 0x42, 0x3b, 0x90, 0x15, 0x31, 0x79, 0x99, 0x9e, - 0xe9, 0xfa, 0x15, 0x47, 0x70, 0x29, 0xa2, 0xf3, 0x7d, 0x09, 0x71, 0x92, 0x47, 0x1b, 0xa6, 0x47, - 0x72, 0x11, 0xa3, 0x72, 0x2b, 0x9a, 0x47, 0x0b, 0x2a, 0x6a, 0x02, 0x0c, 0xb1, 0xa3, 0xb1, 0x9e, - 0x50, 0xe5, 0x36, 0x9d, 0x6e, 0x35, 0x32, 0xdd, 0x10, 0x3b, 0x1b, 0xa2, 0x73, 0x44, 0x0a, 0xbf, - 0x81, 0x39, 0x14, 0x29, 0xc2, 0x10, 0x3b, 0x8c, 0x50, 0x5b, 0x85, 0x7c, 0xe0, 0x11, 0x50, 0x16, - 0x92, 0xf5, 0x83, 0x26, 0x2b, 0xf1, 0x5b, 0xed, 0x83, 0xa6, 0x22, 0xd5, 0xee, 0x43, 0x8a, 0x6e, - 0x4c, 0x86, 0xec, 0x76, 0x4f, 0x7d, 0x59, 0x57, 0x5b, 0xac, 0xad, 0xd0, 0xe9, 0x7e, 0xd9, 0x56, - 0x0f, 0xdb, 0x2d, 0x45, 0xf8, 0xfc, 0x7f, 0x4e, 0x02, 0x0a, 0xab, 0xcb, 0x43, 0x87, 0x57, 0x68, - 0x43, 0x58, 0xec, 0x07, 0x54, 0x76, 0xb8, 0xd2, 0x5a, 0x62, 0xbd, 0xb4, 0xf5, 0xe4, 0xff, 0xad, - 0x50, 0x05, 0x46, 0x94, 0x14, 0x2a, 0x4a, 0xa9, 0x1f, 0xa3, 0x46, 0x72, 0x9d, 0xc4, 0x54, 0x7c, - 0x51, 0x21, 0xdd, 0x3f, 0xc6, 0xfd, 0x57, 0x3c, 0xc2, 0xfe, 0xce, 0x15, 0x13, 0xd3, 0x34, 0x30, - 0xa2, 0x94, 0x4d, 0x22, 0x13, 0x4e, 0x2d, 0x42, 0x3f, 0x85, 0x42, 0x6a, 0xdc, 0x75, 0xa6, 0xae, - 0xf5, 0x46, 0xb3, 0x3a, 0x21, 0xc2, 0x1b, 0x45, 0x3c, 0xe7, 0x13, 0x58, 0xb4, 0x1d, 0x5f, 0x23, - 0x75, 0x12, 0xb7, 0x70, 0x5a, 0xfd, 0x14, 0x1b, 0x0a, 0xd7, 0xc3, 0xd0, 0x9e, 0x8b, 0xb6, 0xe3, - 0x77, 0x27, 0x96, 0xc5, 0x08, 0xb5, 0xcf, 0xa0, 0x14, 0x3f, 0x23, 0x94, 0x87, 0x74, 0x73, 0xa7, - 0xdd, 0xdc, 0x55, 0x16, 0xd0, 0x22, 0xc8, 0xdb, 0x3d, 0xb5, 0xdd, 0x79, 0xda, 0xd5, 0x76, 0xdb, - 0x7f, 0xc0, 0xda, 0x40, 0xdd, 0x9e, 0x68, 0x03, 0x05, 0x15, 0x4c, 0x5a, 0xc9, 0xd4, 0xfe, 0x47, - 0x82, 0xd2, 0xbe, 0x6b, 0x8e, 0x74, 0xf7, 0x6c, 0x17, 0x9f, 0x1d, 0xbc, 0xd1, 0xc7, 0xe8, 0x73, - 0x58, 0xb6, 0xf1, 0x1b, 0x6d, 0xcc, 0xa8, 0x5a, 0x90, 0x11, 0x4b, 0xb3, 0x7b, 0x84, 0x65, 0x1b, - 0xbf, 0xe1, 0x08, 0x1d, 0x9e, 0x10, 0x7f, 0x0c, 0xb2, 0x63, 0xf1, 0x22, 0x18, 0x8b, 0x3e, 0x8d, - 0x1c, 0x15, 0x02, 0xc7, 0x62, 0x35, 0x2f, 0x0d, 0xd2, 0x32, 0x99, 0x4f, 0x8c, 0x4e, 0xce, 0x18, - 0x6d, 0xe3, 0x37, 0x62, 0xf4, 0xe7, 0xb0, 0x4c, 0xb0, 0x2f, 0xad, 0x2e, 0x75, 0xc5, 0xea, 0x1c, - 0xcb, 0x88, 0xaf, 0x8e, 0x2b, 0xef, 0xbf, 0xa4, 0x01, 0x85, 0x57, 0xff, 0x7c, 0xe2, 0xeb, 0xd4, - 0x1e, 0xea, 0x90, 0xe1, 0x17, 0x21, 0xd1, 0x0b, 0xfe, 0xf0, 0x4a, 0x9d, 0x8d, 0x17, 0xe5, 0x3b, - 0x0b, 0x2a, 0x17, 0x44, 0x3f, 0x8b, 0x36, 0x55, 0xe5, 0xad, 0x0f, 0xe6, 0xf3, 0x88, 0x3b, 0x0b, - 0xa2, 0xdb, 0xba, 0x0b, 0x69, 0xcf, 0xd7, 0x7d, 0x96, 0xf4, 0x94, 0xb6, 0x36, 0xaf, 0x90, 0xbf, - 0xbc, 0xf8, 0x8d, 0x03, 0x22, 0x26, 0xb4, 0x96, 0x62, 0xa0, 0x97, 0x90, 0x0f, 0x12, 0x09, 0xde, - 0xa1, 0x7d, 0x3c, 0x3f, 0x60, 0xe0, 0x27, 0x84, 0x17, 0x09, 0xb0, 0x50, 0x1d, 0xe4, 0x11, 0x1f, - 0x16, 0x96, 0x8b, 0x6b, 0x3c, 0x97, 0x03, 0x81, 0x40, 0x73, 0xba, 0xc8, 0x97, 0x0a, 0x42, 0xa8, - 0x43, 0xfd, 0x9d, 0xeb, 0x58, 0xd6, 0x91, 0xde, 0x7f, 0x45, 0xbb, 0x4e, 0x81, 0xbf, 0x13, 0x54, - 0xb4, 0x4b, 0x32, 0x32, 0xa1, 0xe5, 0xb4, 0x87, 0x24, 0xcf, 0xd1, 0xe7, 0x12, 0x5e, 0x64, 0x67, - 0x41, 0x8d, 0x88, 0xa3, 0x1e, 0x94, 0xc6, 0x31, 0x4d, 0xe7, 0xe9, 0xcf, 0xc3, 0xab, 0x62, 0x60, - 0x6c, 0xf0, 0xce, 0x82, 0x3a, 0x25, 0x5e, 0xfb, 0x1c, 0xd2, 0xf4, 0xc4, 0x89, 0xa7, 0x7c, 0xd1, - 0xdd, 0xed, 0xf6, 0x5e, 0x76, 0x99, 0xf1, 0xb5, 0xda, 0x7b, 0xed, 0xc3, 0xb6, 0xd6, 0xeb, 0xee, - 0x11, 0xe3, 0xbb, 0x0b, 0xb7, 0x38, 0xa1, 0xde, 0x6d, 0x69, 0x2f, 0xd5, 0x8e, 0x60, 0x25, 0x6a, - 0xeb, 0x51, 0x57, 0x9c, 0x83, 0x54, 0xb7, 0xd7, 0x6d, 0x2b, 0x0b, 0xd4, 0x29, 0xb7, 0x5a, 0x8a, - 0x44, 0x9d, 0xb2, 0xda, 0xdb, 0x17, 0x36, 0xdb, 0x28, 0x00, 0x18, 0xc1, 0x2d, 0x3d, 0x4b, 0xe5, - 0x32, 0x4a, 0xb6, 0xf6, 0xe7, 0x0f, 0x60, 0x71, 0xca, 0x91, 0x5d, 0x93, 0x79, 0xaf, 0xd1, 0xcc, - 0x3b, 0x19, 0x3a, 0x99, 0x20, 0xf3, 0x4e, 0xf0, 0xa4, 0xfb, 0x31, 0xe4, 0xc7, 0xba, 0x8b, 0x6d, - 0x3f, 0xb4, 0x2a, 0xd1, 0x99, 0xc8, 0xed, 0x53, 0x46, 0x30, 0x3c, 0xc7, 0x06, 0x76, 0x88, 0x50, - 0x10, 0x88, 0x99, 0x26, 0xdc, 0xe5, 0x86, 0x58, 0xbe, 0x26, 0x06, 0xef, 0x43, 0x79, 0xe4, 0x18, - 0xe6, 0xc0, 0xec, 0x33, 0x35, 0xf2, 0xcd, 0x11, 0x6b, 0x3f, 0xca, 0x5b, 0x3f, 0x8a, 0xdc, 0xc9, - 0xc4, 0x37, 0xad, 0x8d, 0x63, 0xab, 0xbf, 0x71, 0x28, 0x5e, 0x51, 0xf8, 0x8e, 0x94, 0xa8, 0x34, - 0x61, 0xa2, 0xa7, 0x90, 0x15, 0x05, 0x66, 0x8e, 0xa6, 0x75, 0xf3, 0x9a, 0xaf, 0x08, 0xc5, 0x5c, - 0x1a, 0x6d, 0x43, 0xc9, 0xc6, 0xa7, 0xd1, 0x7e, 0x48, 0x3e, 0xa6, 0xe0, 0x85, 0x2e, 0x3e, 0x9d, - 0xdd, 0x0c, 0x29, 0xd8, 0x21, 0xc7, 0x40, 0x5f, 0x40, 0x31, 0xe6, 0xa9, 0x68, 0x67, 0x71, 0x6e, - 0x9f, 0x10, 0xe4, 0x5b, 0x11, 0x07, 0x86, 0xb6, 0x21, 0x2b, 0x5c, 0xa5, 0x4c, 0xf7, 0x78, 0x33, - 0x30, 0x21, 0x8c, 0x1a, 0x50, 0xa4, 0x5b, 0x0c, 0x3c, 0x68, 0x21, 0xcc, 0xa0, 0x2e, 0xce, 0xab, - 0x32, 0xd9, 0xe1, 0x8c, 0xae, 0x87, 0x6c, 0x07, 0x74, 0x03, 0x3d, 0x03, 0x08, 0x5e, 0xaf, 0x48, - 0xaa, 0x7b, 0x5d, 0x35, 0xb1, 0x2f, 0x06, 0x86, 0x4b, 0x52, 0x23, 0xd2, 0xe8, 0x39, 0xe4, 0x85, - 0x6f, 0x60, 0x39, 0xee, 0xd5, 0xa6, 0x7e, 0xd9, 0x53, 0x09, 0xff, 0x14, 0x20, 0x90, 0x14, 0xc0, - 0xc2, 0xba, 0x87, 0x79, 0xa2, 0xfb, 0x64, 0xce, 0x14, 0xe0, 0xa0, 0x7f, 0x8c, 0x47, 0x7a, 0xf3, - 0x98, 0x14, 0xd1, 0x7b, 0x44, 0xbe, 0x91, 0xa8, 0x48, 0x2a, 0x83, 0x42, 0x5d, 0x50, 0xe8, 0x91, - 0x45, 0x1d, 0x9f, 0x42, 0x4f, 0xed, 0x7d, 0x7e, 0x6a, 0x25, 0x72, 0x6a, 0x57, 0x3a, 0x3f, 0xaa, - 0x53, 0xcf, 0x43, 0x07, 0xf8, 0xfb, 0x50, 0x1a, 0x38, 0xee, 0x48, 0xf7, 0x35, 0x61, 0x3c, 0xe5, - 0xb0, 0x24, 0xfe, 0xe1, 0xbc, 0x5a, 0xdc, 0xa6, 0x5c, 0x61, 0x38, 0xc5, 0x41, 0xf4, 0x13, 0xed, - 0x88, 0x38, 0xb1, 0x44, 0xdd, 0xfa, 0xc7, 0xf3, 0xee, 0xf0, 0x72, 0x90, 0xe8, 0x42, 0x86, 0xe6, - 0x38, 0x5e, 0x65, 0x99, 0x9e, 0xfb, 0x5b, 0xe6, 0x4b, 0x2a, 0x47, 0x41, 0xbf, 0x80, 0x92, 0x41, - 0x28, 0x24, 0xb9, 0x66, 0x25, 0xf7, 0x2d, 0x8a, 0xbb, 0x39, 0x27, 0x2e, 0x29, 0xc7, 0x3b, 0xf6, - 0xc0, 0x11, 0x95, 0x96, 0x00, 0x63, 0x65, 0x7a, 0x0f, 0x72, 0x03, 0x7d, 0x64, 0x5a, 0x26, 0xf6, - 0x2a, 0xb7, 0x29, 0xee, 0x27, 0xd7, 0x5a, 0xf9, 0x74, 0x3b, 0x56, 0x44, 0x19, 0x01, 0x12, 0x18, - 0x3b, 0x25, 0x9c, 0x91, 0x4b, 0xbd, 0x73, 0xd9, 0xd8, 0x45, 0x3b, 0x36, 0xd6, 0x9a, 0xa5, 0xc6, - 0xce, 0xbf, 0x0c, 0xf4, 0x00, 0xe0, 0xc4, 0xc4, 0x6f, 0xb4, 0xd7, 0x13, 0xec, 0x9e, 0x55, 0x2a, - 0x11, 0xdf, 0x9b, 0x27, 0xf4, 0x2f, 0x08, 0x19, 0x7d, 0x0a, 0x79, 0x03, 0x8f, 0xb1, 0x6d, 0x78, - 0x3d, 0xbb, 0x72, 0x97, 0xe6, 0x3a, 0x4b, 0x17, 0xe7, 0xd5, 0x7c, 0x4b, 0x10, 0xb9, 0x6f, 0x0d, - 0x47, 0xa1, 0xaf, 0xa0, 0xc0, 0x3e, 0xb0, 0xd1, 0xb3, 0x1b, 0x67, 0x95, 0x15, 0xba, 0xe9, 0x47, - 0x73, 0x1e, 0x66, 0x58, 0xb7, 0x06, 0xad, 0xbe, 0x56, 0x04, 0x4d, 0x8d, 0x61, 0xa3, 0x5f, 0x40, - 0x41, 0x68, 0xf7, 0x33, 0xe7, 0xc8, 0xab, 0xbc, 0x77, 0x6d, 0x1f, 0x6e, 0x7a, 0xae, 0xe7, 0xa1, - 0xa8, 0xf0, 0x5d, 0x51, 0x34, 0xf4, 0x73, 0x28, 0x06, 0xad, 0x76, 0x67, 0xec, 0x7b, 0x95, 0x7b, - 0xd4, 0x38, 0x1f, 0xcf, 0xab, 0xba, 0x5c, 0xb6, 0x37, 0xa6, 0x2d, 0xca, 0xc8, 0x17, 0xba, 0x0f, - 0x79, 0xc3, 0x75, 0xc6, 0x2c, 0x86, 0xfc, 0x68, 0x4d, 0x5a, 0x4f, 0x06, 0xc5, 0x93, 0xeb, 0x8c, - 0x69, 0x70, 0xd0, 0xa0, 0xe4, 0xe2, 0xb1, 0xa5, 0xf7, 0xf1, 0x88, 0x44, 0x37, 0x67, 0x50, 0x59, - 0xa5, 0xb3, 0x6f, 0xcd, 0x7d, 0x90, 0x81, 0xb0, 0x50, 0xcc, 0x08, 0x5e, 0x6f, 0x80, 0x5e, 0x00, - 0xe8, 0x13, 0xc3, 0xf4, 0xb5, 0x91, 0x63, 0xe0, 0x4a, 0xf5, 0xda, 0xf7, 0xa9, 0x69, 0xf0, 0x3a, - 0x11, 0x7c, 0xee, 0x18, 0x38, 0x68, 0x6a, 0x0b, 0x02, 0xfa, 0x14, 0x64, 0xba, 0xb5, 0xaf, 0x9c, - 0x23, 0xa2, 0x9b, 0x6b, 0x74, 0x73, 0x65, 0x7e, 0x97, 0xf9, 0x96, 0xeb, 0x8c, 0x9f, 0x39, 0x47, - 0x54, 0x63, 0xf8, 0x4f, 0x03, 0x79, 0x50, 0x18, 0xf6, 0xb5, 0xd0, 0x9d, 0xde, 0xa7, 0xb7, 0xf8, - 0x7b, 0x73, 0xae, 0xe5, 0x69, 0x73, 0x86, 0x83, 0x5d, 0x12, 0x71, 0xe1, 0x69, 0x53, 0xd0, 0x3c, - 0x55, 0x1e, 0xf6, 0x83, 0x0f, 0xf4, 0x21, 0x14, 0x58, 0x85, 0xce, 0x0d, 0xa0, 0x16, 0x31, 0x00, - 0x99, 0x71, 0x98, 0x09, 0x74, 0x81, 0x97, 0xf2, 0x9a, 0xee, 0x69, 0xce, 0x80, 0xdd, 0xd9, 0x83, - 0xf9, 0xe3, 0x7e, 0x89, 0x49, 0xd7, 0xbd, 0xde, 0x80, 0x5e, 0x6c, 0x1f, 0x0a, 0xce, 0xc4, 0x3f, - 0x72, 0x26, 0xb6, 0xa1, 0x0d, 0x5e, 0x79, 0x95, 0xf7, 0xe9, 0x6e, 0x6f, 0x54, 0x9a, 0x05, 0xbb, - 0xeb, 0x71, 0xa0, 0xed, 0x5d, 0x4f, 0x95, 0x05, 0xea, 0xf6, 0x2b, 0x0f, 0xfd, 0x09, 0xc8, 0xa6, - 0x1d, 0xce, 0xf1, 0xf0, 0xe6, 0x73, 0x20, 0x91, 0x1c, 0x77, 0xec, 0x60, 0x0a, 0xe0, 0x98, 0x64, - 0x86, 0x8f, 0xa0, 0xe4, 0x0c, 0x06, 0x96, 0x69, 0x63, 0xcd, 0xc5, 0xba, 0xe7, 0xd8, 0x95, 0x0f, - 0x22, 0x27, 0x58, 0xe4, 0x3c, 0x95, 0xb2, 0x50, 0x0d, 0xf2, 0x3e, 0x1e, 0x8d, 0x1d, 0x57, 0x77, - 0xcf, 0x2a, 0x1f, 0x46, 0xdf, 0x02, 0x02, 0x32, 0x3a, 0x82, 0x95, 0x89, 0x8d, 0x4f, 0xc7, 0x8e, - 0x87, 0x0d, 0x8d, 0xe7, 0x74, 0x1e, 0x8d, 0x6f, 0x44, 0x8f, 0xd6, 0xa9, 0x8f, 0x7b, 0xc8, 0x17, - 0x75, 0xe7, 0x85, 0x18, 0xc9, 0x72, 0x3c, 0x16, 0x07, 0x83, 0x4c, 0xef, 0xce, 0x64, 0x26, 0xdb, - 0x58, 0xf9, 0x56, 0x82, 0xf2, 0xa5, 0x98, 0x89, 0xfe, 0x18, 0xb2, 0xb6, 0x63, 0x44, 0x5e, 0x5e, - 0xda, 0x7c, 0x9a, 0x4c, 0xd7, 0x31, 0xd8, 0xc3, 0xcb, 0xe3, 0xb9, 0x1e, 0x1b, 0xe9, 0xaf, 0xf1, - 0xd1, 0x06, 0x13, 0x53, 0x33, 0x04, 0xb5, 0x63, 0xa0, 0x4f, 0x60, 0x11, 0x9f, 0x8e, 0x4d, 0x37, - 0x92, 0x37, 0x26, 0x22, 0x36, 0x5f, 0x0a, 0x99, 0x44, 0x41, 0x78, 0x6f, 0xfc, 0xef, 0x13, 0xb0, - 0x38, 0x15, 0xb1, 0x48, 0xa2, 0x4c, 0xdf, 0x06, 0x63, 0x89, 0x32, 0xa1, 0x5c, 0xf3, 0x90, 0x12, - 0x7d, 0x7a, 0x4f, 0xbe, 0xeb, 0xd3, 0x7b, 0xbc, 0xe7, 0x9c, 0xbe, 0x41, 0xcf, 0xf9, 0xa7, 0x70, - 0xdb, 0xf4, 0x34, 0xdb, 0xb1, 0x45, 0xfb, 0x20, 0xa8, 0x93, 0xa2, 0x0f, 0xa8, 0x4b, 0xa6, 0xd7, - 0x75, 0x6c, 0xd6, 0x38, 0x08, 0x76, 0x1d, 0xbe, 0xb5, 0x66, 0x2f, 0xbf, 0xb5, 0x06, 0xed, 0x81, - 0x94, 0x92, 0x5e, 0xf9, 0x3b, 0x09, 0x72, 0x22, 0x1a, 0xc7, 0x2b, 0x03, 0x69, 0xce, 0xca, 0xe0, - 0xea, 0x73, 0xdc, 0x06, 0xe5, 0x92, 0x52, 0xb2, 0xc2, 0xe4, 0x9e, 0xc8, 0xa6, 0x66, 0xea, 0x62, - 0x69, 0x1c, 0x53, 0x41, 0x7e, 0xbb, 0xdf, 0x48, 0x90, 0x8f, 0xfe, 0xf5, 0x29, 0x11, 0xac, 0x71, - 0x76, 0x99, 0xf3, 0x96, 0x6f, 0x7d, 0xf1, 0xfb, 0x4a, 0xce, 0x7f, 0x5f, 0x7c, 0x99, 0x7f, 0x0a, - 0x72, 0x24, 0x48, 0x4e, 0x57, 0xd1, 0xd2, 0x5b, 0x54, 0xd1, 0xef, 0x43, 0x86, 0x47, 0x06, 0x66, - 0x02, 0x45, 0x2e, 0x9d, 0x66, 0x51, 0x21, 0xfd, 0x15, 0x89, 0x08, 0x7c, 0xf6, 0x7f, 0x4d, 0x42, - 0x21, 0x1a, 0x44, 0x89, 0x1b, 0x31, 0xed, 0xbe, 0x4b, 0x23, 0x18, 0x9d, 0x3d, 0x19, 0x3c, 0x29, - 0x0a, 0x32, 0x09, 0xad, 0x23, 0xd3, 0xd6, 0xe8, 0x33, 0x56, 0xcc, 0xcc, 0x72, 0x23, 0xd3, 0xfe, - 0x92, 0x50, 0xe9, 0x10, 0xfd, 0x94, 0x0f, 0x49, 0xc6, 0x86, 0xe8, 0xa7, 0x6c, 0xc8, 0x0a, 0xcd, - 0x56, 0x5d, 0x9f, 0x96, 0x94, 0xc9, 0x48, 0xfe, 0xe9, 0xfa, 0x68, 0x15, 0xb2, 0x27, 0xa6, 0xeb, - 0x4f, 0x74, 0x8b, 0x56, 0x8f, 0x42, 0x21, 0x05, 0x11, 0xd9, 0x50, 0x0a, 0xd3, 0x86, 0x37, 0x36, - 0x76, 0xa9, 0x8a, 0xcb, 0x5b, 0xf5, 0xb7, 0xc8, 0x1b, 0xc2, 0x0f, 0x02, 0x24, 0x9c, 0xab, 0x17, - 0x25, 0xae, 0xfc, 0x8d, 0x04, 0xc5, 0xd8, 0x30, 0xd4, 0x81, 0x45, 0x3a, 0x71, 0xa4, 0x20, 0x64, - 0x77, 0x75, 0x3f, 0xf8, 0x13, 0x13, 0x61, 0xcf, 0xac, 0x08, 0x8b, 0x4e, 0x84, 0x65, 0xa0, 0xcf, - 0xa1, 0xc4, 0xa0, 0x82, 0xc7, 0xe9, 0xb8, 0xfa, 0x15, 0x28, 0x52, 0xfc, 0x85, 0xba, 0xe0, 0x84, - 0x34, 0x23, 0xfa, 0xee, 0xb6, 0x62, 0x83, 0x1c, 0xc9, 0x4b, 0xe6, 0xd0, 0xfb, 0xdf, 0x85, 0x54, - 0xe0, 0x2f, 0xe7, 0x8c, 0xb7, 0x54, 0x80, 0xcf, 0xf7, 0xb5, 0x04, 0xcb, 0xb3, 0xf2, 0x83, 0x98, - 0x3d, 0x31, 0x45, 0x9a, 0xcb, 0x9e, 0x1e, 0x44, 0xf3, 0x36, 0xa6, 0x5c, 0xe2, 0x2d, 0x28, 0xcc, - 0xdc, 0x3e, 0x08, 0x54, 0x9c, 0xe9, 0xd6, 0x62, 0x4c, 0xc5, 0x49, 0x7d, 0x16, 0x51, 0xf2, 0xda, - 0x63, 0xd1, 0x96, 0x01, 0xc8, 0xec, 0xbf, 0x68, 0xec, 0x75, 0x9a, 0x33, 0x5b, 0x2a, 0x48, 0x86, - 0x6c, 0x6f, 0x7b, 0x7b, 0xaf, 0xd3, 0x6d, 0x2b, 0xc9, 0xda, 0x3a, 0xe4, 0x83, 0x14, 0x0c, 0x15, - 0x20, 0xd7, 0xea, 0x1c, 0xd4, 0x1b, 0x7b, 0xed, 0x96, 0xb2, 0x80, 0x8a, 0x90, 0x57, 0xdb, 0xf5, - 0x16, 0x6d, 0xdc, 0x28, 0xd2, 0x67, 0xb9, 0xbf, 0xf8, 0xba, 0x2a, 0x71, 0x17, 0x99, 0x51, 0xb2, - 0xcf, 0x52, 0x39, 0xa4, 0x2c, 0xd5, 0xfe, 0x56, 0x02, 0xd4, 0xd2, 0x7d, 0x9d, 0xe8, 0xdf, 0x0d, - 0x1a, 0x31, 0x89, 0x6b, 0x6e, 0x2a, 0x5e, 0x5c, 0x27, 0xdf, 0xa5, 0xb8, 0x0e, 0x17, 0x5d, 0xfb, - 0x46, 0x02, 0x88, 0x2c, 0xf0, 0x67, 0xd1, 0xff, 0x88, 0x5e, 0xdd, 0x4b, 0x98, 0xb2, 0xa8, 0x9d, - 0x05, 0xf1, 0x0f, 0xd2, 0xa7, 0x90, 0x33, 0xf8, 0xb6, 0xb9, 0x4a, 0x5d, 0x59, 0xb4, 0x5f, 0x3a, - 0x9d, 0x1d, 0x92, 0x9d, 0x73, 0x2a, 0x6f, 0x70, 0x65, 0x21, 0x3d, 0xb1, 0x4d, 0xc7, 0xfe, 0x89, - 0x1a, 0x7d, 0x5a, 0x10, 0xd1, 0x93, 0x5c, 0x05, 0xfd, 0xad, 0xfb, 0xd8, 0x60, 0xad, 0xb6, 0x17, - 0xf6, 0x49, 0x40, 0x90, 0x50, 0x09, 0x80, 0xf3, 0x4d, 0x7b, 0xa8, 0x24, 0xe8, 0x45, 0xba, 0xce, - 0x78, 0x4c, 0xbe, 0x92, 0x8d, 0x1f, 0x7f, 0xf7, 0x9f, 0xab, 0x0b, 0xdf, 0x5d, 0xac, 0x4a, 0xbf, - 0xbc, 0x58, 0x95, 0x7e, 0x75, 0xb1, 0x2a, 0xfd, 0xc7, 0xc5, 0xaa, 0xf4, 0x57, 0xdf, 0xaf, 0x2e, - 0xfc, 0xf2, 0xfb, 0xd5, 0x85, 0x5f, 0x7d, 0xbf, 0xba, 0xf0, 0x87, 0x59, 0xbe, 0xd8, 0xff, 0x0b, - 0x00, 0x00, 0xff, 0xff, 0x66, 0xd6, 0x54, 0xf0, 0xf0, 0x2b, 0x00, 0x00, + proto.RegisterFile("sql/sqlbase/structured.proto", fileDescriptor_structured_b4380afd7e608b0d) +} + +var fileDescriptor_structured_b4380afd7e608b0d = []byte{ + // 3832 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x5a, 0xcb, 0x6f, 0x1b, 0x49, + 0x7a, 0x57, 0xf3, 0xcd, 0x8f, 0xaf, 0x66, 0x49, 0xb6, 0x69, 0x8d, 0x57, 0x94, 0xe9, 0xf1, 0x8c, + 0x76, 0x67, 0x46, 0xf2, 0xc8, 0x79, 0x78, 0x27, 0xc1, 0x62, 0x28, 0x92, 0xb2, 0x68, 0xc9, 0xa4, + 0xa6, 0x25, 0x8f, 0x37, 0xc1, 0x26, 0x9d, 0x56, 0x77, 0x91, 0xea, 0x71, 0xb3, 0x9b, 0xee, 0x6e, + 0xca, 0x12, 0x90, 0x53, 0x72, 0xc9, 0x29, 0xc8, 0x3f, 0x10, 0x60, 0x10, 0x0c, 0x92, 0xbd, 0xe6, + 0x92, 0xdc, 0x02, 0xe4, 0x12, 0xcc, 0x2d, 0x0b, 0xe4, 0xb2, 0xc8, 0x41, 0x48, 0x34, 0x97, 0x1c, + 0x72, 0xc9, 0x25, 0x01, 0xe6, 0x14, 0xd4, 0xab, 0x1f, 0x14, 0xa5, 0x50, 0xf6, 0xe4, 0xc6, 0xfe, + 0xaa, 0xbe, 0x5f, 0x55, 0x7d, 0xf5, 0xbd, 0x8b, 0x70, 0xcf, 0x7b, 0x6d, 0x6d, 0x78, 0xaf, 0xad, + 0x23, 0xcd, 0xc3, 0x1b, 0x9e, 0xef, 0x4e, 0x74, 0x7f, 0xe2, 0x62, 0x63, 0x7d, 0xec, 0x3a, 0xbe, + 0x83, 0x6e, 0xe9, 0x8e, 0xfe, 0xca, 0x75, 0x34, 0xfd, 0x78, 0xdd, 0x7b, 0x6d, 0xad, 0xf3, 0x79, + 0xcb, 0xb5, 0x89, 0x6f, 0x5a, 0x1b, 0xc7, 0x96, 0xbe, 0xe1, 0x9b, 0x23, 0xec, 0xf9, 0xda, 0x68, + 0xcc, 0x18, 0x96, 0xdf, 0x8b, 0xc2, 0x8d, 0x5d, 0xf3, 0xc4, 0xb4, 0xf0, 0x10, 0xf3, 0xc1, 0xbb, + 0x43, 0xec, 0x6c, 0x0c, 0xb1, 0x63, 0xda, 0x06, 0x3e, 0xdd, 0xd0, 0x1d, 0x7b, 0x60, 0x0e, 0xf9, + 0xd0, 0xd2, 0xd0, 0x19, 0x3a, 0xf4, 0xe7, 0x06, 0xf9, 0xc5, 0xa8, 0x8d, 0x3f, 0x49, 0xc3, 0xe2, + 0xb6, 0xe3, 0x62, 0x73, 0x68, 0xef, 0xe2, 0x33, 0x05, 0x0f, 0xb0, 0x8b, 0x6d, 0x1d, 0xa3, 0x55, + 0x48, 0xfb, 0xda, 0x91, 0x85, 0x6b, 0xd2, 0xaa, 0xb4, 0x56, 0xda, 0x82, 0x6f, 0xcf, 0xeb, 0x0b, + 0xdf, 0x9f, 0xd7, 0x13, 0xdd, 0xb6, 0xc2, 0x06, 0xd0, 0x43, 0x48, 0xd3, 0x55, 0x6a, 0x09, 0x3a, + 0xa3, 0xc2, 0x67, 0x64, 0xbb, 0x84, 0x48, 0xa6, 0xd1, 0x51, 0x54, 0x83, 0x94, 0xad, 0x8d, 0x70, + 0x2d, 0xb9, 0x2a, 0xad, 0xe5, 0xb7, 0x52, 0x64, 0x96, 0x42, 0x29, 0x68, 0x17, 0x72, 0x27, 0x9a, + 0x65, 0x1a, 0xa6, 0x7f, 0x56, 0x4b, 0xad, 0x4a, 0x6b, 0xe5, 0xcd, 0x1f, 0xaf, 0xcf, 0x14, 0xc6, + 0x7a, 0xcb, 0xb1, 0x3d, 0xdf, 0xd5, 0x4c, 0xdb, 0xff, 0x92, 0x33, 0x70, 0xa0, 0x00, 0x00, 0x3d, + 0x82, 0xaa, 0x77, 0xac, 0xb9, 0xd8, 0x50, 0xc7, 0x2e, 0x1e, 0x98, 0xa7, 0xaa, 0x85, 0xed, 0x5a, + 0x7a, 0x55, 0x5a, 0x4b, 0xf3, 0xa9, 0x15, 0x36, 0xbc, 0x4f, 0x47, 0xf7, 0xb0, 0x8d, 0x0e, 0x21, + 0xef, 0xd8, 0xaa, 0x81, 0x2d, 0xec, 0xe3, 0x5a, 0x86, 0xae, 0xff, 0xe9, 0x15, 0xeb, 0xcf, 0x10, + 0xd0, 0x7a, 0x53, 0xf7, 0x4d, 0xc7, 0x16, 0xfb, 0x70, 0xec, 0x36, 0x05, 0xe2, 0xa8, 0x93, 0xb1, + 0xa1, 0xf9, 0xb8, 0x96, 0x7d, 0x67, 0xd4, 0x17, 0x14, 0x08, 0xed, 0x41, 0x7a, 0xa4, 0xf9, 0xfa, + 0x71, 0x2d, 0x47, 0x11, 0x1f, 0xdd, 0x00, 0xf1, 0x39, 0xe1, 0xe3, 0x80, 0x0c, 0xa4, 0xf1, 0x12, + 0x32, 0x6c, 0x1d, 0x54, 0x82, 0x7c, 0xaf, 0xaf, 0x36, 0x5b, 0x87, 0xdd, 0x7e, 0x4f, 0x5e, 0x40, + 0x45, 0xc8, 0x29, 0x9d, 0x83, 0x43, 0xa5, 0xdb, 0x3a, 0x94, 0x25, 0xf2, 0x75, 0xd0, 0x39, 0x54, + 0x7b, 0x2f, 0xf6, 0xf6, 0xe4, 0x04, 0xaa, 0x40, 0x81, 0x7c, 0xb5, 0x3b, 0xdb, 0xcd, 0x17, 0x7b, + 0x87, 0x72, 0x12, 0x15, 0x20, 0xdb, 0x6a, 0x1e, 0xb4, 0x9a, 0xed, 0x8e, 0x9c, 0x5a, 0x4e, 0xfd, + 0xf2, 0x9b, 0x95, 0x85, 0xc6, 0x23, 0x48, 0xd3, 0xe5, 0x10, 0x40, 0xe6, 0xa0, 0xfb, 0x7c, 0x7f, + 0xaf, 0x23, 0x2f, 0xa0, 0x1c, 0xa4, 0xb6, 0x09, 0x84, 0x44, 0x38, 0xf6, 0x9b, 0xca, 0x61, 0xb7, + 0xb9, 0x27, 0x27, 0x18, 0xc7, 0x67, 0xa9, 0xff, 0xf8, 0xba, 0x2e, 0x35, 0xfe, 0x25, 0x03, 0x4b, + 0xe1, 0xde, 0xc3, 0xdb, 0x46, 0x2d, 0xa8, 0x38, 0xae, 0x39, 0x34, 0x6d, 0x95, 0xea, 0x9c, 0x6a, + 0x1a, 0x5c, 0x1f, 0xdf, 0x23, 0xe7, 0xb9, 0x38, 0xaf, 0x97, 0xfa, 0x74, 0xf8, 0x90, 0x8c, 0x76, + 0xdb, 0x5c, 0x41, 0x4b, 0x4e, 0x84, 0x68, 0xa0, 0x5d, 0xa8, 0x72, 0x10, 0xdd, 0xb1, 0x26, 0x23, + 0x5b, 0x35, 0x0d, 0xaf, 0x96, 0x58, 0x4d, 0xae, 0x95, 0xb6, 0xea, 0x17, 0xe7, 0xf5, 0x0a, 0x83, + 0x68, 0xd1, 0xb1, 0x6e, 0xdb, 0xfb, 0xfe, 0xbc, 0x9e, 0x13, 0x1f, 0x0a, 0x5f, 0x9e, 0x7f, 0x1b, + 0x1e, 0x7a, 0x09, 0xb7, 0x5c, 0x21, 0x5b, 0x23, 0x0a, 0x98, 0xa4, 0x80, 0x0f, 0x2e, 0xce, 0xeb, + 0x8b, 0x81, 0xf0, 0x8d, 0xd9, 0xa0, 0x8b, 0xee, 0xf4, 0x04, 0xc3, 0x43, 0x7d, 0x88, 0x90, 0xc3, + 0xe3, 0xa6, 0xe8, 0x71, 0xeb, 0xfc, 0xb8, 0xd5, 0x10, 0x3a, 0x7e, 0xe4, 0xaa, 0x3b, 0x35, 0x60, + 0x04, 0x86, 0x97, 0xbe, 0xd6, 0xf0, 0x32, 0xef, 0x6a, 0x78, 0x31, 0x33, 0xca, 0xfe, 0xbf, 0x98, + 0x51, 0xee, 0x07, 0x37, 0xa3, 0xfc, 0x0f, 0x60, 0x46, 0xa8, 0x09, 0x8b, 0x16, 0x1e, 0x6a, 0xfa, + 0x99, 0xca, 0xd5, 0x8b, 0xb9, 0x43, 0xa0, 0x37, 0x56, 0x9d, 0x72, 0x87, 0x35, 0x49, 0xa9, 0xb2, + 0xd9, 0x4c, 0xdd, 0x28, 0x19, 0x75, 0xe1, 0x0e, 0x87, 0x88, 0xdc, 0x3d, 0x83, 0x29, 0x5c, 0x05, + 0x73, 0x8b, 0x71, 0x84, 0x9a, 0x40, 0x87, 0x98, 0x25, 0x3d, 0x4b, 0xe5, 0x8a, 0x72, 0xe9, 0x59, + 0x2a, 0x57, 0x92, 0xcb, 0x8d, 0xff, 0x4c, 0x82, 0xcc, 0xf4, 0xab, 0x8d, 0x3d, 0xdd, 0x35, 0xc7, + 0xbe, 0xe3, 0x06, 0x5a, 0x21, 0x5d, 0xd2, 0x8a, 0x0f, 0x20, 0x61, 0x1a, 0xdc, 0x99, 0xdf, 0xe6, + 0xfa, 0x96, 0xa0, 0x0a, 0x16, 0x6a, 0x6e, 0xc2, 0x34, 0xd0, 0x1e, 0xa4, 0xfc, 0xb3, 0x31, 0x73, + 0xe8, 0xc5, 0xad, 0x27, 0x64, 0xe6, 0xbf, 0x9e, 0xd7, 0x1f, 0x0d, 0x4d, 0xff, 0x78, 0x72, 0xb4, + 0xae, 0x3b, 0xa3, 0x8d, 0x40, 0xaa, 0xc6, 0x51, 0xf8, 0x7b, 0x63, 0xfc, 0x6a, 0x48, 0xc2, 0xd6, + 0x06, 0x61, 0xf6, 0xd6, 0x0f, 0x15, 0x8a, 0x82, 0x56, 0x21, 0x67, 0x4f, 0x2c, 0x8b, 0x86, 0x1a, + 0xa2, 0xeb, 0x39, 0x71, 0x69, 0x82, 0x8a, 0xee, 0x43, 0xd1, 0xc0, 0x03, 0x6d, 0x62, 0xf9, 0x2a, + 0x3e, 0x1d, 0xbb, 0x4c, 0x9f, 0x95, 0x02, 0xa7, 0x75, 0x4e, 0xc7, 0x2e, 0xba, 0x07, 0x99, 0x63, + 0xd3, 0x30, 0xb0, 0x4d, 0xd5, 0x59, 0x40, 0x70, 0x1a, 0xda, 0x84, 0xea, 0xc4, 0xc3, 0x9e, 0xea, + 0xe1, 0xd7, 0x13, 0x22, 0x30, 0x6a, 0xae, 0x40, 0xcd, 0x35, 0xc3, 0xcd, 0xa7, 0x42, 0x26, 0x1c, + 0xf0, 0x71, 0x62, 0x8d, 0xf7, 0xa1, 0xa8, 0x3b, 0xa3, 0xf1, 0xc4, 0xc7, 0x6c, 0xd1, 0x02, 0x5b, + 0x94, 0xd3, 0xe8, 0xa2, 0x9b, 0x50, 0x75, 0xde, 0xd8, 0x53, 0xb0, 0xc5, 0x38, 0x2c, 0x99, 0x10, + 0x85, 0xdd, 0x02, 0xb0, 0x9c, 0xa1, 0xa9, 0x6b, 0x16, 0xb1, 0xed, 0x12, 0x95, 0xf5, 0x03, 0x2e, + 0xeb, 0xca, 0x1e, 0x1b, 0x11, 0xc2, 0x8e, 0x09, 0x3e, 0xcf, 0xd9, 0xba, 0x46, 0x70, 0xd1, 0x39, + 0x39, 0xff, 0x2c, 0x95, 0xcb, 0xcb, 0xf0, 0x2c, 0x95, 0xcb, 0xca, 0xb9, 0xc6, 0x9f, 0x27, 0xe0, + 0x36, 0x9b, 0xbf, 0xad, 0x8d, 0x4c, 0xeb, 0xec, 0x5d, 0x2f, 0x9d, 0xa1, 0xf0, 0x4b, 0xa7, 0xf2, + 0xa0, 0xbe, 0x8e, 0xb0, 0x31, 0x6f, 0x47, 0xe5, 0x41, 0x68, 0x3d, 0x42, 0x42, 0x4f, 0x00, 0x22, + 0xee, 0x30, 0x45, 0x05, 0x71, 0xf7, 0xe2, 0xbc, 0x9e, 0x9f, 0xed, 0x04, 0xf3, 0x7a, 0xc4, 0xf5, + 0x55, 0xc5, 0x0d, 0x07, 0x08, 0xf4, 0x9a, 0x23, 0xc2, 0x69, 0xb3, 0x09, 0x33, 0x85, 0x53, 0x31, + 0x62, 0x83, 0x5c, 0x44, 0x8d, 0xbf, 0x4f, 0xc0, 0x52, 0xd7, 0xf6, 0xb1, 0x6b, 0x61, 0xed, 0x04, + 0x47, 0xc4, 0xf1, 0x73, 0xc8, 0x6b, 0xb6, 0x8e, 0x3d, 0xdf, 0x71, 0xbd, 0x9a, 0xb4, 0x9a, 0x5c, + 0x2b, 0x6c, 0xfe, 0xc6, 0x15, 0xae, 0x60, 0x16, 0xff, 0x7a, 0x93, 0x33, 0x73, 0x49, 0x86, 0x60, + 0xcb, 0xff, 0x20, 0x41, 0x4e, 0x8c, 0xa2, 0x47, 0x90, 0x9b, 0x8a, 0x5a, 0xb7, 0xf8, 0x69, 0xb2, + 0x71, 0xe7, 0x9d, 0xf5, 0xb9, 0xcb, 0xfe, 0x4d, 0xc8, 0x51, 0xe3, 0x57, 0x83, 0x3b, 0x59, 0x16, + 0x1c, 0xdc, 0xfe, 0xa3, 0x09, 0x56, 0x96, 0xce, 0xed, 0x1a, 0xa8, 0x35, 0x2b, 0xf7, 0x49, 0x52, + 0xfe, 0x3b, 0x42, 0x7e, 0x07, 0xf1, 0xec, 0xe7, 0x52, 0x3a, 0xc4, 0x64, 0xc6, 0x25, 0xf7, 0x77, + 0x12, 0x54, 0x09, 0x83, 0x81, 0x8d, 0x88, 0xd8, 0x1e, 0x00, 0x98, 0x9e, 0xea, 0x31, 0x3a, 0x3d, + 0x91, 0xb0, 0xb4, 0xbc, 0xe9, 0xf1, 0xe9, 0x81, 0xaa, 0x25, 0x2e, 0xa9, 0xda, 0x4f, 0xa1, 0x44, + 0x79, 0xd5, 0xa3, 0x89, 0xfe, 0x0a, 0xfb, 0x1e, 0xdd, 0x61, 0x7a, 0x6b, 0x89, 0xef, 0xb0, 0x48, + 0x11, 0xb6, 0xd8, 0x98, 0x52, 0xf4, 0x22, 0x5f, 0x97, 0xb4, 0x2f, 0x75, 0x49, 0xfb, 0xf8, 0xc6, + 0xff, 0x27, 0x09, 0xb7, 0xf7, 0x35, 0xd7, 0x37, 0x89, 0xfb, 0x37, 0xed, 0x61, 0x64, 0xf7, 0x0f, + 0xa1, 0x60, 0x4f, 0x46, 0x5c, 0xc1, 0x3c, 0x7e, 0x21, 0x6c, 0x7f, 0x60, 0x4f, 0x46, 0x4c, 0x77, + 0x3c, 0xe2, 0xdd, 0x2c, 0xd3, 0xf3, 0x69, 0x7e, 0x50, 0xd8, 0xdc, 0xbc, 0x42, 0x2d, 0x66, 0xaf, + 0xb1, 0xbe, 0x67, 0x7a, 0xbe, 0x38, 0x33, 0x41, 0x41, 0x7d, 0x48, 0xbb, 0x9a, 0x3d, 0xc4, 0xd4, + 0x5e, 0x0a, 0x9b, 0x8f, 0x6f, 0x06, 0xa7, 0x10, 0x56, 0x11, 0x73, 0x28, 0xce, 0xf2, 0x5f, 0x4a, + 0x90, 0x22, 0xab, 0x5c, 0x63, 0xd2, 0xb7, 0x21, 0x73, 0xa2, 0x59, 0x13, 0xcc, 0x72, 0x9c, 0xa2, + 0xc2, 0xbf, 0xd0, 0x1f, 0x40, 0xc5, 0x9b, 0x1c, 0x8d, 0x23, 0x4b, 0xd1, 0x1b, 0x28, 0x6c, 0x7e, + 0x72, 0xa3, 0x5d, 0x05, 0xe9, 0x74, 0x1c, 0x8b, 0x5d, 0xc0, 0xf2, 0x6b, 0x48, 0xd3, 0x5d, 0x5f, + 0xb3, 0xbf, 0xfb, 0x50, 0xf4, 0x1d, 0x15, 0x9f, 0xea, 0xd6, 0xc4, 0x33, 0x4f, 0x98, 0xa6, 0x14, + 0x95, 0x82, 0xef, 0x74, 0x04, 0x09, 0x3d, 0x84, 0xf2, 0xc0, 0x75, 0x46, 0xaa, 0x69, 0x8b, 0x49, + 0x34, 0xd8, 0x28, 0x25, 0x42, 0xed, 0x0a, 0x62, 0x4c, 0x65, 0xff, 0xab, 0x00, 0x15, 0x6a, 0x18, + 0x73, 0xb9, 0xbd, 0x87, 0x11, 0xb7, 0x77, 0x2b, 0xe6, 0xf6, 0x02, 0xeb, 0x22, 0x5e, 0xef, 0x1e, + 0x64, 0x26, 0xb6, 0xf9, 0x7a, 0xc2, 0xd6, 0x0f, 0xe2, 0x0a, 0xa3, 0xcd, 0xa1, 0x95, 0xe8, 0x63, + 0x40, 0xc4, 0x15, 0x60, 0x35, 0x36, 0x31, 0x4d, 0x27, 0xca, 0x74, 0xa4, 0x75, 0xa5, 0x07, 0xcd, + 0xdc, 0xc0, 0x83, 0xee, 0x80, 0x8c, 0x4f, 0x7d, 0x57, 0x8b, 0x26, 0xa4, 0x59, 0xca, 0xbf, 0x72, + 0x71, 0x5e, 0x2f, 0x77, 0xc8, 0xd8, 0x6c, 0x90, 0x32, 0x8e, 0x8c, 0x19, 0x44, 0x4b, 0xaa, 0x1c, + 0xc3, 0x30, 0x5d, 0x4c, 0xd3, 0x28, 0xaf, 0x96, 0x5b, 0x4d, 0x5e, 0x93, 0x2e, 0x4d, 0x89, 0x7d, + 0xbd, 0x2d, 0x18, 0x15, 0x99, 0x41, 0x05, 0x04, 0x0f, 0x1d, 0x40, 0x61, 0xc0, 0xb2, 0x2b, 0xf5, + 0x15, 0x3e, 0xa3, 0x79, 0x58, 0x61, 0xf3, 0x27, 0xf3, 0xe7, 0x61, 0x5b, 0x19, 0x72, 0x05, 0x35, + 0x49, 0x81, 0x41, 0x30, 0x88, 0x5e, 0x42, 0x29, 0x92, 0x3e, 0x1d, 0x9d, 0xd1, 0xe0, 0xfe, 0x76, + 0xb0, 0xc5, 0x10, 0x68, 0xeb, 0x0c, 0x7d, 0x01, 0x60, 0x06, 0x01, 0x80, 0xe6, 0x00, 0x85, 0xcd, + 0x8f, 0x6e, 0x10, 0x29, 0x84, 0x7f, 0x09, 0x41, 0xd0, 0x4b, 0x28, 0x87, 0x5f, 0x74, 0xb3, 0xc5, + 0x1b, 0x6f, 0x96, 0xa1, 0x96, 0x22, 0x38, 0x5b, 0x24, 0x0f, 0x5f, 0x22, 0xd9, 0x89, 0xe3, 0x99, + 0x3e, 0x8e, 0xaa, 0x41, 0x89, 0xaa, 0x41, 0xe3, 0xe2, 0xbc, 0x8e, 0x5a, 0x62, 0x7c, 0xb6, 0x2a, + 0x20, 0x7d, 0x6a, 0x9c, 0x29, 0x56, 0x4c, 0x81, 0x09, 0x62, 0x39, 0x54, 0xac, 0x83, 0x50, 0x85, + 0x2f, 0x29, 0x56, 0x44, 0xbd, 0x59, 0xe1, 0x54, 0x8c, 0xf9, 0x9e, 0xca, 0xdb, 0xfb, 0x9e, 0x18, + 0x10, 0xea, 0xf0, 0x7c, 0x54, 0xa6, 0x39, 0xfd, 0x47, 0x73, 0x2a, 0xe9, 0xe1, 0xd9, 0x58, 0x08, + 0x92, 0x25, 0xa2, 0x8f, 0x01, 0xe9, 0x2e, 0xd6, 0x7c, 0x6c, 0x90, 0x8c, 0xcf, 0x32, 0x75, 0xd3, + 0xb7, 0xce, 0x6a, 0xd5, 0x88, 0xdd, 0x57, 0xf9, 0x78, 0x27, 0x18, 0x46, 0x4f, 0x20, 0x7b, 0x82, + 0x5d, 0xcf, 0x74, 0xec, 0x1a, 0xa2, 0xce, 0x64, 0x85, 0xe7, 0xeb, 0xb7, 0xa7, 0xd6, 0xfb, 0x92, + 0xcd, 0x52, 0xc4, 0x74, 0xb4, 0x03, 0x25, 0x6c, 0xeb, 0x8e, 0x61, 0xda, 0x43, 0x95, 0x6e, 0x7f, + 0x31, 0xcc, 0x77, 0xbe, 0x3f, 0xaf, 0xbf, 0x37, 0xc5, 0xdf, 0xe1, 0x73, 0xc9, 0xb6, 0x95, 0x22, + 0x8e, 0x7c, 0xa1, 0x1d, 0xc8, 0x8a, 0x98, 0xbc, 0x44, 0x65, 0xba, 0x76, 0x85, 0x08, 0x2e, 0x45, + 0x74, 0x7e, 0x2e, 0xc1, 0x4e, 0x72, 0x71, 0xc3, 0xf4, 0x48, 0x2e, 0x62, 0xd4, 0x6e, 0x45, 0x73, + 0x71, 0x41, 0x45, 0x2d, 0x80, 0x21, 0x76, 0x54, 0xd6, 0x57, 0xaa, 0xdd, 0xa6, 0xcb, 0xad, 0x44, + 0x96, 0x1b, 0x62, 0x67, 0x5d, 0x74, 0x9f, 0x48, 0xf1, 0x38, 0x30, 0x87, 0x22, 0x45, 0x18, 0x62, + 0x87, 0x11, 0x1a, 0x2b, 0x90, 0x0f, 0x3c, 0x02, 0xca, 0x42, 0xb2, 0x79, 0xd0, 0x62, 0x6d, 0x82, + 0x76, 0xe7, 0xa0, 0x25, 0x4b, 0x8d, 0xfb, 0x90, 0xa2, 0x07, 0x2b, 0x40, 0x76, 0xbb, 0xaf, 0xbc, + 0x6c, 0x2a, 0x6d, 0xd6, 0x9a, 0xe8, 0xf6, 0xbe, 0xec, 0x28, 0x87, 0x9d, 0xb6, 0x2c, 0x7c, 0xfe, + 0x3f, 0x26, 0x01, 0x85, 0x15, 0xea, 0xa1, 0xc3, 0xab, 0xbc, 0x21, 0x54, 0xf4, 0x80, 0xca, 0x84, + 0x2b, 0xad, 0x26, 0xd6, 0xca, 0x9b, 0x4f, 0xfe, 0xcf, 0x2a, 0x57, 0x60, 0x44, 0x49, 0xa1, 0xa2, + 0x94, 0xf5, 0x18, 0x35, 0x92, 0xeb, 0x24, 0xa6, 0xe2, 0x8b, 0x02, 0x69, 0xfd, 0x18, 0xeb, 0xaf, + 0x78, 0x84, 0xfd, 0xad, 0x2b, 0x16, 0xa6, 0x69, 0x60, 0x44, 0x29, 0x5b, 0x84, 0x27, 0x5c, 0x5a, + 0x84, 0x7e, 0x0a, 0x85, 0x94, 0xb8, 0xeb, 0x4c, 0x5d, 0xeb, 0x8d, 0x66, 0x75, 0x53, 0x84, 0x37, + 0x8a, 0x78, 0xce, 0x27, 0x50, 0xb1, 0x1d, 0x5f, 0x25, 0xb5, 0x16, 0xb7, 0x70, 0x5a, 0x41, 0x95, + 0xb6, 0x64, 0xae, 0x87, 0xa1, 0x3d, 0x97, 0x6c, 0xc7, 0xef, 0x4d, 0x2c, 0x5e, 0x9e, 0x34, 0x3e, + 0x83, 0x72, 0x5c, 0x46, 0x28, 0x0f, 0xe9, 0xd6, 0x4e, 0xa7, 0xb5, 0x2b, 0x2f, 0xa0, 0x0a, 0x14, + 0xb6, 0xfb, 0x4a, 0xa7, 0xfb, 0xb4, 0xa7, 0xee, 0x76, 0x7e, 0x8f, 0xb5, 0x92, 0x7a, 0x7d, 0xd1, + 0x4a, 0x0a, 0x2a, 0x98, 0xb4, 0x9c, 0x69, 0xfc, 0xb7, 0x04, 0xe5, 0x7d, 0xd7, 0x1c, 0x69, 0xee, + 0xd9, 0x2e, 0x3e, 0x3b, 0x78, 0xa3, 0x8d, 0xd1, 0xe7, 0xb0, 0x64, 0xe3, 0x37, 0xea, 0x98, 0x51, + 0xd5, 0x20, 0x23, 0x96, 0x66, 0xf7, 0x19, 0xab, 0x36, 0x7e, 0xc3, 0x11, 0xba, 0x3c, 0x21, 0xfe, + 0x18, 0x0a, 0x8e, 0xc5, 0x0b, 0x69, 0x2c, 0x7a, 0x3d, 0x85, 0x28, 0x13, 0x38, 0x16, 0xab, 0x9b, + 0x69, 0x90, 0x2e, 0x90, 0xf5, 0xc4, 0xec, 0xe4, 0x8c, 0xd9, 0x36, 0x7e, 0x23, 0x66, 0x7f, 0x0e, + 0x4b, 0x04, 0xfb, 0xd2, 0xee, 0x52, 0x57, 0xec, 0xce, 0xb1, 0x8c, 0xf8, 0xee, 0xb8, 0xf2, 0xfe, + 0x53, 0x1a, 0x50, 0x78, 0xf5, 0xcf, 0x27, 0xbe, 0x46, 0xed, 0xa1, 0x09, 0x19, 0x7e, 0x11, 0x12, + 0xbd, 0xe0, 0x0f, 0xaf, 0xd4, 0xd9, 0x78, 0x61, 0xbf, 0xb3, 0xa0, 0x70, 0x46, 0xf4, 0xb3, 0x68, + 0x63, 0xb6, 0xb0, 0xf9, 0xc1, 0x7c, 0x1e, 0x71, 0x67, 0x41, 0x74, 0x6c, 0x77, 0x21, 0xed, 0xf9, + 0x9a, 0xcf, 0x92, 0x9e, 0xf2, 0xe6, 0xc6, 0x15, 0xfc, 0x97, 0x37, 0xbf, 0x7e, 0x40, 0xd8, 0x84, + 0xd6, 0x52, 0x0c, 0xf4, 0x12, 0xf2, 0x41, 0x22, 0xc1, 0xbb, 0xbc, 0x8f, 0xe7, 0x07, 0x0c, 0xfc, + 0x84, 0xf0, 0x22, 0x01, 0x16, 0x6a, 0x42, 0x61, 0xc4, 0xa7, 0x85, 0xe5, 0xe2, 0x2a, 0xcf, 0xe5, + 0x40, 0x20, 0xd0, 0x9c, 0x2e, 0xf2, 0xa5, 0x80, 0x60, 0xea, 0x52, 0x7f, 0xe7, 0x3a, 0x96, 0x75, + 0xa4, 0xe9, 0xaf, 0x68, 0xe7, 0x2a, 0xf0, 0x77, 0x82, 0x8a, 0x76, 0x49, 0x46, 0x26, 0xb4, 0x9c, + 0xf6, 0xa1, 0x0a, 0x73, 0xf4, 0xca, 0x84, 0x17, 0xd9, 0x59, 0x50, 0x22, 0xec, 0xa8, 0x0f, 0xe5, + 0x71, 0x4c, 0xd3, 0x79, 0xfa, 0xf3, 0xf0, 0xaa, 0x18, 0x18, 0x9b, 0xbc, 0xb3, 0xa0, 0x4c, 0xb1, + 0x37, 0x3e, 0x87, 0x34, 0x95, 0x38, 0xf1, 0x94, 0x2f, 0x7a, 0xbb, 0xbd, 0xfe, 0xcb, 0x1e, 0x33, + 0xbe, 0x76, 0x67, 0xaf, 0x73, 0xd8, 0x51, 0xfb, 0xbd, 0x3d, 0x62, 0x7c, 0x77, 0xe1, 0x16, 0x27, + 0x34, 0x7b, 0x6d, 0xf5, 0xa5, 0xd2, 0x15, 0x43, 0x89, 0xc6, 0x5a, 0xd4, 0x15, 0xe7, 0x20, 0xd5, + 0xeb, 0xf7, 0x3a, 0xf2, 0x02, 0x75, 0xca, 0xed, 0xb6, 0x2c, 0x51, 0xa7, 0xac, 0xf4, 0xf7, 0x85, + 0xcd, 0x6e, 0x15, 0x01, 0x8c, 0xe0, 0x96, 0x9e, 0xa5, 0x72, 0x19, 0x39, 0xdb, 0xf8, 0xd3, 0x07, + 0x50, 0x99, 0x72, 0x64, 0xd7, 0x64, 0xde, 0xab, 0x34, 0xf3, 0x4e, 0x86, 0x4e, 0x26, 0xc8, 0xbc, + 0x13, 0x3c, 0xe9, 0x7e, 0x0c, 0xf9, 0xb1, 0xe6, 0x62, 0xdb, 0x0f, 0xad, 0x4a, 0x74, 0x26, 0x72, + 0xfb, 0x74, 0x20, 0x98, 0x9e, 0x63, 0x13, 0xbb, 0x84, 0x29, 0x08, 0xc4, 0x4c, 0x13, 0xee, 0x72, + 0x43, 0xac, 0x5e, 0x13, 0x83, 0xf7, 0xa1, 0x3a, 0x72, 0x0c, 0x73, 0x60, 0xea, 0x4c, 0x8d, 0x7c, + 0x73, 0xc4, 0x5a, 0x98, 0x85, 0xcd, 0x1f, 0x45, 0xee, 0x64, 0xe2, 0x9b, 0xd6, 0xfa, 0xb1, 0xa5, + 0xaf, 0x1f, 0x8a, 0x97, 0x18, 0x7e, 0x22, 0x39, 0xca, 0x4d, 0x06, 0xd1, 0x53, 0xc8, 0x8a, 0x02, + 0x33, 0x47, 0xd3, 0xba, 0x79, 0xcd, 0x57, 0x84, 0x62, 0xce, 0x8d, 0xb6, 0xa1, 0x6c, 0xe3, 0xd3, + 0x68, 0x3f, 0x24, 0x1f, 0x53, 0xf0, 0x62, 0x0f, 0x9f, 0xce, 0x6e, 0x86, 0x14, 0xed, 0x70, 0xc4, + 0x40, 0x5f, 0x40, 0x29, 0xe6, 0xa9, 0x68, 0x77, 0x72, 0x6e, 0x9f, 0x10, 0xe4, 0x5b, 0x11, 0x07, + 0x86, 0xb6, 0x21, 0x2b, 0x5c, 0x65, 0x81, 0x9e, 0xf1, 0x66, 0x60, 0x82, 0x19, 0x6d, 0x41, 0x89, + 0x1e, 0x31, 0xf0, 0xa0, 0xc5, 0x30, 0x83, 0xba, 0x38, 0xaf, 0x17, 0xc8, 0x09, 0x67, 0x74, 0x3d, + 0x0a, 0x76, 0x40, 0x37, 0xd0, 0x33, 0x80, 0xe0, 0x05, 0xcc, 0xa3, 0xfd, 0xb4, 0xab, 0x33, 0xe9, + 0x7d, 0x31, 0x31, 0xdc, 0x92, 0x12, 0xe1, 0x46, 0xcf, 0x21, 0x2f, 0x7c, 0x03, 0xcb, 0x71, 0xaf, + 0x36, 0xf5, 0xcb, 0x9e, 0x4a, 0xf8, 0xa7, 0x00, 0x81, 0xa4, 0x00, 0x16, 0xd6, 0x3c, 0xcc, 0x13, + 0xdd, 0x27, 0x73, 0xa6, 0x00, 0x07, 0xfa, 0x31, 0x1e, 0x69, 0xad, 0x63, 0x52, 0x44, 0xef, 0x11, + 0xfe, 0xad, 0x44, 0x4d, 0x52, 0x18, 0x14, 0xea, 0x81, 0x4c, 0x45, 0x16, 0x75, 0x7c, 0x32, 0x95, + 0xda, 0xfb, 0x5c, 0x6a, 0x65, 0x22, 0xb5, 0x2b, 0x9d, 0x1f, 0xd5, 0xa9, 0xe7, 0xa1, 0x03, 0xfc, + 0x5d, 0x28, 0x0f, 0x1c, 0x77, 0xa4, 0xf9, 0xaa, 0x30, 0x9e, 0x6a, 0x58, 0x12, 0x7f, 0x7f, 0x5e, + 0x2f, 0x6d, 0xd3, 0x51, 0x61, 0x38, 0xa5, 0x41, 0xf4, 0x13, 0xed, 0x88, 0x38, 0xb1, 0x48, 0xdd, + 0xfa, 0xc7, 0xf3, 0x9e, 0xf0, 0x72, 0x90, 0xe8, 0x41, 0x86, 0xe6, 0x38, 0x5e, 0x6d, 0x89, 0xca, + 0xfd, 0x2d, 0xf3, 0x25, 0x85, 0xa3, 0xa0, 0x5f, 0x40, 0xd9, 0x20, 0x14, 0x92, 0x5c, 0xb3, 0x92, + 0xfb, 0x16, 0xc5, 0xdd, 0x98, 0x13, 0x97, 0x94, 0xe3, 0x5d, 0x7b, 0xe0, 0x88, 0x4a, 0x4b, 0x80, + 0xb1, 0x32, 0xbd, 0x0f, 0xb9, 0x81, 0x36, 0x32, 0x2d, 0x13, 0x7b, 0xb5, 0xdb, 0x14, 0xf7, 0x93, + 0x6b, 0xad, 0x7c, 0xba, 0x1d, 0x2b, 0xa2, 0x8c, 0x00, 0x09, 0x8c, 0x9d, 0x12, 0xce, 0xc8, 0xa5, + 0xde, 0xb9, 0x6c, 0xec, 0xa2, 0x1d, 0x1b, 0x6b, 0xcd, 0x52, 0x63, 0xe7, 0x5f, 0x06, 0x7a, 0x00, + 0x70, 0x62, 0xe2, 0x37, 0xea, 0xeb, 0x09, 0x76, 0xcf, 0x6a, 0xb5, 0x88, 0xef, 0xcd, 0x13, 0xfa, + 0x17, 0x84, 0x8c, 0x3e, 0x85, 0xbc, 0x81, 0xc7, 0xd8, 0x36, 0xbc, 0xbe, 0x5d, 0xbb, 0x4b, 0x73, + 0x9d, 0xc5, 0x8b, 0xf3, 0x7a, 0xbe, 0x2d, 0x88, 0xdc, 0xb7, 0x86, 0xb3, 0xd0, 0x57, 0x50, 0x64, + 0x1f, 0xd8, 0xe8, 0xdb, 0x5b, 0x67, 0xb5, 0x65, 0x7a, 0xe8, 0x47, 0x73, 0x0a, 0x33, 0xac, 0x5b, + 0x83, 0x56, 0x5f, 0x3b, 0x82, 0xa6, 0xc4, 0xb0, 0xd1, 0x2f, 0xa0, 0x28, 0xb4, 0xfb, 0x99, 0x73, + 0xe4, 0xd5, 0xde, 0xbb, 0xb6, 0x0f, 0x37, 0xbd, 0xd6, 0xf3, 0x90, 0x55, 0xf8, 0xae, 0x28, 0x1a, + 0xfa, 0x39, 0x94, 0x82, 0x76, 0xbd, 0x33, 0xf6, 0xbd, 0xda, 0x3d, 0x6a, 0x9c, 0x8f, 0xe7, 0x55, + 0x5d, 0xce, 0xdb, 0x1f, 0xd3, 0x16, 0x65, 0xe4, 0x0b, 0xdd, 0x87, 0xbc, 0xe1, 0x3a, 0x63, 0x16, + 0x43, 0x7e, 0xb4, 0x2a, 0xad, 0x25, 0x83, 0xe2, 0xc9, 0x75, 0xc6, 0x34, 0x38, 0xa8, 0x50, 0x76, + 0xf1, 0xd8, 0xd2, 0x74, 0x3c, 0x22, 0xd1, 0xcd, 0x19, 0xd4, 0x56, 0xe8, 0xea, 0x9b, 0x73, 0x0b, + 0x32, 0x60, 0x16, 0x8a, 0x19, 0xc1, 0xeb, 0x0f, 0xd0, 0x0b, 0x00, 0x6d, 0x62, 0x98, 0xbe, 0x3a, + 0x72, 0x0c, 0x5c, 0xab, 0x5f, 0xfb, 0xc6, 0x35, 0x0d, 0xde, 0x24, 0x8c, 0xcf, 0x1d, 0x03, 0x07, + 0x4d, 0x6d, 0x41, 0x40, 0x9f, 0x42, 0x81, 0x1e, 0xed, 0x2b, 0xe7, 0x88, 0xe8, 0xe6, 0x2a, 0x3d, + 0x5c, 0x95, 0xdf, 0x65, 0xbe, 0xed, 0x3a, 0xe3, 0x67, 0xce, 0x11, 0xd5, 0x18, 0xfe, 0xd3, 0x40, + 0x1e, 0x14, 0x87, 0xba, 0x1a, 0xba, 0xd3, 0xfb, 0xf4, 0x16, 0x7f, 0x67, 0xce, 0xbd, 0x3c, 0x6d, + 0xcd, 0x70, 0xb0, 0x8b, 0x22, 0x2e, 0x3c, 0x6d, 0x09, 0x9a, 0xa7, 0x14, 0x86, 0x7a, 0xf0, 0x81, + 0x3e, 0x84, 0x22, 0xab, 0xd0, 0xb9, 0x01, 0x34, 0x22, 0x06, 0x50, 0x60, 0x23, 0xcc, 0x04, 0x7a, + 0xc0, 0x4b, 0x79, 0x55, 0xf3, 0x54, 0x67, 0xc0, 0xee, 0xec, 0xc1, 0xfc, 0x71, 0xbf, 0xcc, 0xb8, + 0x9b, 0x5e, 0x7f, 0x40, 0x2f, 0x56, 0x87, 0xa2, 0x33, 0xf1, 0x8f, 0x9c, 0x89, 0x6d, 0xa8, 0x83, + 0x57, 0x5e, 0xed, 0x7d, 0x7a, 0xda, 0x1b, 0x95, 0x66, 0xc1, 0xe9, 0xfa, 0x1c, 0x68, 0x7b, 0xd7, + 0x53, 0x0a, 0x02, 0x75, 0xfb, 0x95, 0x87, 0xfe, 0x08, 0x0a, 0xa6, 0x1d, 0xae, 0xf1, 0xf0, 0xe6, + 0x6b, 0x20, 0x91, 0x1c, 0x77, 0xed, 0x60, 0x09, 0xe0, 0x98, 0x64, 0x85, 0x8f, 0xa0, 0xec, 0x0c, + 0x06, 0x96, 0x69, 0x63, 0xd5, 0xc5, 0x9a, 0xe7, 0xd8, 0xb5, 0x0f, 0x22, 0x12, 0x2c, 0xf1, 0x31, + 0x85, 0x0e, 0xa1, 0x06, 0xe4, 0x7d, 0x3c, 0x1a, 0x3b, 0xae, 0xe6, 0x9e, 0xd5, 0x3e, 0x8c, 0xbe, + 0x05, 0x04, 0x64, 0x74, 0x04, 0xcb, 0x13, 0x1b, 0x9f, 0x8e, 0x1d, 0x0f, 0x1b, 0x2a, 0xcf, 0xe9, + 0x3c, 0x1a, 0xdf, 0x88, 0x1e, 0xad, 0x51, 0x1f, 0xf7, 0x90, 0x6f, 0xea, 0xce, 0x0b, 0x31, 0x93, + 0xe5, 0x78, 0x2c, 0x0e, 0x06, 0x99, 0xde, 0x9d, 0xc9, 0xcc, 0x61, 0x63, 0xf9, 0x97, 0x12, 0x54, + 0x2f, 0xc5, 0x4c, 0xf4, 0x87, 0x90, 0xb5, 0x1d, 0x23, 0xf2, 0xf2, 0xd2, 0xe1, 0xcb, 0x64, 0x7a, + 0x8e, 0xc1, 0x1e, 0x5e, 0x1e, 0xcf, 0xf5, 0x60, 0x49, 0x7f, 0x8d, 0x8f, 0xd6, 0x19, 0x9b, 0x92, + 0x21, 0xa8, 0x5d, 0x03, 0x7d, 0x02, 0x15, 0x7c, 0x3a, 0x36, 0xdd, 0x48, 0xde, 0x98, 0x88, 0xd8, + 0x7c, 0x39, 0x1c, 0x24, 0x0a, 0xc2, 0x7b, 0xe3, 0x7f, 0x9b, 0x80, 0xca, 0x54, 0xc4, 0x22, 0x89, + 0x32, 0x7d, 0x5f, 0x8c, 0x25, 0xca, 0x84, 0x72, 0xcd, 0x43, 0x4a, 0xf4, 0xf9, 0x3e, 0xf9, 0xae, + 0xcf, 0xf7, 0xf1, 0x9e, 0x73, 0xfa, 0x06, 0x3d, 0xe7, 0x9f, 0xc2, 0x6d, 0xd3, 0x53, 0x6d, 0xc7, + 0x16, 0xed, 0x83, 0xa0, 0x4e, 0x8a, 0x3e, 0xc2, 0x2e, 0x9a, 0x5e, 0xcf, 0xb1, 0x59, 0xe3, 0x20, + 0x38, 0x75, 0xf8, 0x5e, 0x9b, 0xbd, 0xfc, 0x5e, 0x1b, 0xb4, 0x07, 0x52, 0x72, 0x7a, 0xf9, 0x6f, + 0x24, 0xc8, 0x89, 0x68, 0x1c, 0xaf, 0x0c, 0xa4, 0x39, 0x2b, 0x83, 0xab, 0xe5, 0xb8, 0x0d, 0xf2, + 0x25, 0xa5, 0x64, 0x85, 0xc9, 0x3d, 0x91, 0x4d, 0xcd, 0xd4, 0xc5, 0xf2, 0x38, 0xa6, 0x82, 0xfc, + 0x76, 0xbf, 0x91, 0x20, 0x1f, 0xfd, 0xfb, 0x54, 0x22, 0xd8, 0xe3, 0xec, 0x32, 0xe7, 0x2d, 0xdf, + 0xfa, 0xe2, 0xf7, 0x95, 0x9c, 0xff, 0xbe, 0xf8, 0x36, 0xff, 0x18, 0x0a, 0x91, 0x20, 0x39, 0x5d, + 0x45, 0x4b, 0x6f, 0x51, 0x45, 0xbf, 0x0f, 0x19, 0x1e, 0x19, 0x98, 0x09, 0x94, 0x38, 0x77, 0x9a, + 0x45, 0x85, 0xf4, 0x57, 0x24, 0x22, 0xf0, 0xd5, 0xff, 0x39, 0x09, 0xc5, 0x68, 0x10, 0x25, 0x6e, + 0xc4, 0xb4, 0x75, 0x97, 0x46, 0x30, 0xba, 0x7a, 0x32, 0x78, 0x52, 0x14, 0x64, 0x12, 0x5a, 0x47, + 0xa6, 0xad, 0xd2, 0x67, 0xac, 0x98, 0x99, 0xe5, 0x46, 0xa6, 0xfd, 0x25, 0xa1, 0xd2, 0x29, 0xda, + 0x29, 0x9f, 0x92, 0x8c, 0x4d, 0xd1, 0x4e, 0xd9, 0x94, 0x65, 0x9a, 0xad, 0xba, 0x3e, 0x2d, 0x29, + 0x93, 0x91, 0xfc, 0xd3, 0xf5, 0xd1, 0x0a, 0x64, 0x4f, 0x4c, 0xd7, 0x9f, 0x68, 0x16, 0xad, 0x1e, + 0x85, 0x42, 0x0a, 0x22, 0xb2, 0xa1, 0x1c, 0xa6, 0x0d, 0x6f, 0x6c, 0xec, 0x52, 0x15, 0x2f, 0x6c, + 0x36, 0xdf, 0x22, 0x6f, 0x08, 0x3f, 0x08, 0x90, 0x70, 0xae, 0x5e, 0x94, 0xb8, 0xfc, 0x57, 0x12, + 0x94, 0x62, 0xd3, 0x50, 0x17, 0x2a, 0x74, 0xe1, 0x48, 0x41, 0xc8, 0xee, 0xea, 0x7e, 0xf0, 0x47, + 0x28, 0x32, 0x3c, 0xb3, 0x22, 0x2c, 0x39, 0x91, 0x21, 0x03, 0x7d, 0x0e, 0x65, 0x06, 0x15, 0x3c, + 0x4e, 0xc7, 0xd5, 0xaf, 0x48, 0x91, 0xe2, 0x2f, 0xd4, 0x45, 0x27, 0xa4, 0x19, 0xd1, 0x77, 0xb7, + 0x65, 0x1b, 0x0a, 0x91, 0xbc, 0x64, 0x0e, 0xbd, 0xff, 0x6d, 0x48, 0x05, 0xfe, 0x72, 0xce, 0x78, + 0x4b, 0x19, 0xf8, 0x7a, 0x5f, 0x4b, 0xb0, 0x34, 0x2b, 0x3f, 0x88, 0xd9, 0x13, 0x53, 0xa4, 0xb9, + 0xec, 0xe9, 0x41, 0x34, 0x6f, 0x63, 0xca, 0x25, 0xde, 0x82, 0xc2, 0xcc, 0xed, 0x83, 0x40, 0xc5, + 0x99, 0x6e, 0x55, 0x62, 0x2a, 0x4e, 0xea, 0xb3, 0x88, 0x92, 0x37, 0x1e, 0x8b, 0xb6, 0x0c, 0x40, + 0x66, 0xff, 0xc5, 0xd6, 0x5e, 0xb7, 0x35, 0xb3, 0xa5, 0x82, 0x0a, 0x90, 0xed, 0x6f, 0x6f, 0xef, + 0x75, 0x7b, 0x1d, 0x39, 0xd9, 0x58, 0x83, 0x7c, 0x90, 0x82, 0xa1, 0x22, 0xe4, 0xda, 0xdd, 0x83, + 0xe6, 0xd6, 0x5e, 0xa7, 0x2d, 0x2f, 0xa0, 0x12, 0xe4, 0x95, 0x4e, 0xb3, 0x4d, 0x1b, 0x37, 0xb2, + 0xf4, 0x59, 0xee, 0xcf, 0xbe, 0xae, 0x4b, 0xdc, 0x45, 0x66, 0xe4, 0xec, 0xb3, 0x54, 0x0e, 0xc9, + 0x8b, 0x8d, 0xbf, 0x96, 0x00, 0xb5, 0x35, 0x5f, 0x23, 0xfa, 0x77, 0x83, 0x46, 0x4c, 0xe2, 0x9a, + 0x9b, 0x8a, 0x17, 0xd7, 0xc9, 0x77, 0x29, 0xae, 0xc3, 0x4d, 0x37, 0xbe, 0x91, 0x00, 0x22, 0x1b, + 0xfc, 0x59, 0xf4, 0x7f, 0xa6, 0x57, 0xf7, 0x12, 0xa6, 0x2c, 0x6a, 0x67, 0x41, 0xfc, 0x0b, 0xf5, + 0x29, 0xe4, 0x0c, 0x7e, 0x6c, 0xae, 0x52, 0x57, 0x16, 0xed, 0x97, 0xa4, 0xb3, 0x43, 0xb2, 0x73, + 0x4e, 0xe5, 0x0d, 0xae, 0x2c, 0xa4, 0x27, 0xb6, 0xe9, 0xd8, 0x3f, 0x51, 0xa2, 0x4f, 0x0b, 0x22, + 0x7a, 0x92, 0xab, 0xa0, 0xbf, 0x35, 0x1f, 0x1b, 0xac, 0xd5, 0xf6, 0xc2, 0x3e, 0x09, 0x08, 0x12, + 0x2a, 0x03, 0xf0, 0x71, 0xd3, 0x1e, 0xca, 0x09, 0x7a, 0x91, 0xae, 0x33, 0x1e, 0x93, 0xaf, 0xe4, + 0xd6, 0x8f, 0xbf, 0xfd, 0xf7, 0x95, 0x85, 0x6f, 0x2f, 0x56, 0xa4, 0x5f, 0x5d, 0xac, 0x48, 0xbf, + 0xbe, 0x58, 0x91, 0xfe, 0xed, 0x62, 0x45, 0xfa, 0x8b, 0xef, 0x56, 0x16, 0x7e, 0xf5, 0xdd, 0xca, + 0xc2, 0xaf, 0xbf, 0x5b, 0x59, 0xf8, 0xfd, 0x2c, 0xdf, 0xec, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, + 0x2f, 0x16, 0x32, 0x63, 0x34, 0x2c, 0x00, 0x00, } diff --git a/pkg/sql/sqlbase/structured.proto b/pkg/sql/sqlbase/structured.proto index 4c5e72c708c2..9b4b0cc045c5 100644 --- a/pkg/sql/sqlbase/structured.proto +++ b/pkg/sql/sqlbase/structured.proto @@ -130,6 +130,14 @@ message ColumnDescriptor { // Expression to use to compute the value of this column if this is a // computed column. optional string compute_expr = 11; + // LogicalColumnID must be accessed through the accessor, since it is set + // lazily, it is incorrect to access it directly. + // LogicalColumnID represents a column's number in catalog tables. + // This only differs from ID when the Column order is swapped or + // the ColumnDescriptor must be remade while remaining visual ordering. + // This does not exist in TableDescriptors pre 20.2. + optional uint32 logical_id = 13 [(gogoproto.nullable) = false, + (gogoproto.customname) = "LogicalColumnID", (gogoproto.casttype) = "ColumnID"]; } // ColumnFamilyDescriptor is set of columns stored together in one kv entry. diff --git a/pkg/sql/sqlbase/structured_test.go b/pkg/sql/sqlbase/structured_test.go index 687420c28842..cb5afad13bca 100644 --- a/pkg/sql/sqlbase/structured_test.go +++ b/pkg/sql/sqlbase/structured_test.go @@ -1410,3 +1410,24 @@ func TestSQLString(t *testing.T) { t.Errorf("Expected '%s', but got '%s'", expected, got) } } + +func TestLogicalColumnID(t *testing.T) { + tests := []struct { + desc TableDescriptor + expected ColumnID + }{ + {TableDescriptor{Columns: []ColumnDescriptor{{ID: 1, LogicalColumnID: 1}}}, 1}, + // If LogicalColumnID is not explicitly set, it should be lazy loaded as ID. + {TableDescriptor{Columns: []ColumnDescriptor{{ID: 2}}}, 2}, + } + + for i := range tests { + actual := tests[i].desc.Columns[0].GetLogicalColumnID() + expected := tests[i].expected + + if expected != actual { + t.Fatalf("Expected LogicalColumnID to be %d, got %d.", expected, actual) + } + } + +}