diff --git a/docs/generated/settings/settings-for-tenants.txt b/docs/generated/settings/settings-for-tenants.txt index 44c936542dcb..a79377d3fa92 100644 --- a/docs/generated/settings/settings-for-tenants.txt +++ b/docs/generated/settings/settings-for-tenants.txt @@ -111,4 +111,4 @@ trace.datadog.project string CockroachDB the project under which traces will be trace.debug.enable boolean false if set, traces for recent requests can be seen at https:///debug/requests trace.lightstep.token string if set, traces go to Lightstep using this token trace.zipkin.collector string if set, traces go to the given Zipkin instance (example: '127.0.0.1:9411'). Only one tracer can be configured at a time. -version version 21.1-12 set the active cluster version in the format '.' +version version 21.1-14 set the active cluster version in the format '.' diff --git a/docs/generated/settings/settings.html b/docs/generated/settings/settings.html index 1e4b846e8641..b19ed46ea949 100644 --- a/docs/generated/settings/settings.html +++ b/docs/generated/settings/settings.html @@ -113,6 +113,6 @@ trace.debug.enablebooleanfalseif set, traces for recent requests can be seen at https:///debug/requests trace.lightstep.tokenstringif set, traces go to Lightstep using this token trace.zipkin.collectorstringif set, traces go to the given Zipkin instance (example: '127.0.0.1:9411'). Only one tracer can be configured at a time. -versionversion21.1-12set the active cluster version in the format '.' +versionversion21.1-14set the active cluster version in the format '.' diff --git a/pkg/ccl/backupccl/restore_planning.go b/pkg/ccl/backupccl/restore_planning.go index 4a803a471a90..029042f9b5b4 100644 --- a/pkg/ccl/backupccl/restore_planning.go +++ b/pkg/ccl/backupccl/restore_planning.go @@ -952,7 +952,7 @@ func maybeUpgradeDescriptors( } else { b = catalogkv.NewBuilder(desc.DescriptorProto()) } - err := b.RunPostDeserializationChanges(ctx, descGetter) + _, err := b.RunPostDeserializationChanges(ctx, descGetter) if err != nil { return err } diff --git a/pkg/cli/testdata/doctor/test_recreate_zipdir b/pkg/cli/testdata/doctor/test_recreate_zipdir index 390916a16a33..a18d18c1a0c6 100644 --- a/pkg/cli/testdata/doctor/test_recreate_zipdir +++ b/pkg/cli/testdata/doctor/test_recreate_zipdir @@ -7,20 +7,20 @@ SELECT crdb_internal.unsafe_delete_descriptor(id, true) FROM system.descriptor W SELECT crdb_internal.unsafe_delete_namespace_entry("parentID", "parentSchemaID", name, id) FROM system.namespace WHERE id >= 50; COMMIT; BEGIN; -SELECT crdb_internal.unsafe_upsert_descriptor(50, decode('12340a0964656661756c74646210321a1d0a090a0561646d696e10020a080a04726f6f7410021204726f6f7418012200280140004a00', 'hex'), true); +SELECT crdb_internal.unsafe_upsert_descriptor(50, decode('12360a0964656661756c74646210321a1d0a090a0561646d696e10020a080a04726f6f7410021204726f6f7418012200280140004a005800', 'hex'), true); SELECT crdb_internal.unsafe_upsert_namespace_entry(0, 0, 'defaultdb', 50, true); -SELECT crdb_internal.unsafe_upsert_descriptor(51, decode('12330a08706f73746772657310331a1d0a090a0561646d696e10020a080a04726f6f7410021204726f6f7418012200280140004a00', 'hex'), true); +SELECT crdb_internal.unsafe_upsert_descriptor(51, decode('12350a08706f73746772657310331a1d0a090a0561646d696e10020a080a04726f6f7410021204726f6f7418012200280140004a005800', 'hex'), true); SELECT crdb_internal.unsafe_upsert_namespace_entry(0, 0, 'postgres', 51, true); -SELECT crdb_internal.unsafe_upsert_descriptor(53, decode('0ad5040a0575736572731835203428013a0042250a02696410011a0d080e10001800300050861760002000300068007000780080010088010042270a046369747910021a0d080710001800300750930860002000300068007000780080010088010042270a046e616d6510031a0d0807100018003007509308600020013000680070007800800100880100422a0a076164647265737310041a0d0807100018003007509308600020013000680070007800800100880100422e0a0b6372656469745f6361726410051a0d0807100018003007509308600020013000680070007800800100880100480652570a077072696d617279100118012204636974792202696430023001400040004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba010060026a1d0a090a0561646d696e10020a080a04726f6f7410021204726f6f741801800101880103980100b2013d0a077072696d61727910001a0269641a04636974791a046e616d651a07616464726573731a0b6372656469745f63617264200120022003200420052800b80101c20100e80100f2010408001200f801008002009202009a0200aa02270836100210041802180120352a11666b5f636974795f7265665f75736572733002380040004800aa02270837100210041802180120352a11666b5f636974795f7265665f75736572733002380040004800aa0227083a100110021802180120352a11666b5f636974795f7265665f75736572733002380040004800b20200b80200c0021dc80200e00200f00200', 'hex'), true); +SELECT crdb_internal.unsafe_upsert_descriptor(53, decode('0ad8040a0575736572731835203428013a0042250a02696410011a0d080e10001800300050861760002000300068007000780080010088010042270a046369747910021a0d080710001800300750930860002000300068007000780080010088010042270a046e616d6510031a0d0807100018003007509308600020013000680070007800800100880100422a0a076164647265737310041a0d0807100018003007509308600020013000680070007800800100880100422e0a0b6372656469745f6361726410051a0d0807100018003007509308600020013000680070007800800100880100480652570a077072696d617279100118012204636974792202696430023001400040004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba010060026a1d0a090a0561646d696e10020a080a04726f6f7410021204726f6f741801800101880103980100b2013d0a077072696d61727910001a0269641a04636974791a046e616d651a07616464726573731a0b6372656469745f63617264200120022003200420052800b80101c20100e80100f2010408001200f801008002009202009a0200aa02270836100210041802180120352a11666b5f636974795f7265665f75736572733002380040004800aa02270837100210041802180120352a11666b5f636974795f7265665f75736572733002380040004800aa0227083a100110021802180120352a11666b5f636974795f7265665f75736572733002380040004800b20200b80200c0021dc80200e00200f00200f80200', 'hex'), true); SELECT crdb_internal.unsafe_upsert_namespace_entry(52, 29, 'users', 53, true); -SELECT crdb_internal.unsafe_upsert_descriptor(54, decode('0aeb060a0876656869636c65731836203428013a0042250a02696410011a0d080e10001800300050861760002000300068007000780080010088010042270a046369747910021a0d080710001800300750930860002000300068007000780080010088010042270a047479706510031a0d0807100018003007509308600020013000680070007800800100880100422b0a086f776e65725f696410041a0d080e10001800300050861760002001300068007000780080010088010042300a0d6372656174696f6e5f74696d6510051a0d080510001800300050da0860002001300068007000780080010088010042290a0673746174757310061a0d080710001800300750930860002001300068007000780080010088010042330a1063757272656e745f6c6f636174696f6e10071a0d080710001800300750930860002001300068007000780080010088010042260a0365787410081a0d081210001800300050da1d600020013000680070007800800100880100480952570a077072696d617279100118012204636974792202696430023001400040004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba01005a7d0a2576656869636c65735f6175746f5f696e6465785f666b5f636974795f7265665f75736572731002180022046369747922086f776e65725f6964300230043801400040004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba010060036a1d0a090a0561646d696e10020a080a04726f6f7410021204726f6f741801800102880103980100b201650a077072696d61727910001a0269641a04636974791a04747970651a086f776e65725f69641a0d6372656174696f6e5f74696d651a067374617475731a1063757272656e745f6c6f636174696f6e1a03657874200120022003200420052006200720082800b80101c20100e80100f2010408001200f801008002009202009a0200a202270836100210041802180120352a11666b5f636974795f7265665f75736572733000380040004800aa02320837100310051802180120362a1c666b5f76656869636c655f636974795f7265665f76656869636c65733002380040004800b20200b80200c0021dc80200e00200f00200', 'hex'), true); +SELECT crdb_internal.unsafe_upsert_descriptor(54, decode('0aee060a0876656869636c65731836203428013a0042250a02696410011a0d080e10001800300050861760002000300068007000780080010088010042270a046369747910021a0d080710001800300750930860002000300068007000780080010088010042270a047479706510031a0d0807100018003007509308600020013000680070007800800100880100422b0a086f776e65725f696410041a0d080e10001800300050861760002001300068007000780080010088010042300a0d6372656174696f6e5f74696d6510051a0d080510001800300050da0860002001300068007000780080010088010042290a0673746174757310061a0d080710001800300750930860002001300068007000780080010088010042330a1063757272656e745f6c6f636174696f6e10071a0d080710001800300750930860002001300068007000780080010088010042260a0365787410081a0d081210001800300050da1d600020013000680070007800800100880100480952570a077072696d617279100118012204636974792202696430023001400040004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba01005a7d0a2576656869636c65735f6175746f5f696e6465785f666b5f636974795f7265665f75736572731002180022046369747922086f776e65725f6964300230043801400040004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba010060036a1d0a090a0561646d696e10020a080a04726f6f7410021204726f6f741801800102880103980100b201650a077072696d61727910001a0269641a04636974791a04747970651a086f776e65725f69641a0d6372656174696f6e5f74696d651a067374617475731a1063757272656e745f6c6f636174696f6e1a03657874200120022003200420052006200720082800b80101c20100e80100f2010408001200f801008002009202009a0200a202270836100210041802180120352a11666b5f636974795f7265665f75736572733000380040004800aa02320837100310051802180120362a1c666b5f76656869636c655f636974795f7265665f76656869636c65733002380040004800b20200b80200c0021dc80200e00200f00200f80200', 'hex'), true); SELECT crdb_internal.unsafe_upsert_namespace_entry(52, 29, 'vehicles', 54, true); -SELECT crdb_internal.unsafe_upsert_descriptor(55, decode('0aeb090a0572696465731837203428013a0042250a02696410011a0d080e10001800300050861760002000300068007000780080010088010042270a046369747910021a0d0807100018003007509308600020003000680070007800800100880100422f0a0c76656869636c655f6369747910031a0d0807100018003007509308600020013000680070007800800100880100422b0a0872696465725f696410041a0d080e100018003000508617600020013000680070007800800100880100422d0a0a76656869636c655f696410051a0d080e10001800300050861760002001300068007000780080010088010042300a0d73746172745f6164647265737310061a0d0807100018003007509308600020013000680070007800800100880100422e0a0b656e645f6164647265737310071a0d0807100018003007509308600020013000680070007800800100880100422d0a0a73746172745f74696d6510081a0d080510001800300050da08600020013000680070007800800100880100422b0a08656e645f74696d6510091a0d080510001800300050da08600020013000680070007800800100880100422a0a07726576656e7565100a1a0d08031002180a300050a40d600020013000680070007800800100880100480b52570a077072696d617279100118012204636974792202696430023001400040004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba01005a7a0a2272696465735f6175746f5f696e6465785f666b5f636974795f7265665f757365727310021800220463697479220872696465725f6964300230043801400040004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba01005a91010a2d72696465735f6175746f5f696e6465785f666b5f76656869636c655f636974795f7265665f76656869636c657310031800220c76656869636c655f63697479220a76656869636c655f69643003300538023801400040004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba010060046a1d0a090a0561646d696e10020a080a04726f6f7410021204726f6f741801800103880103980100a201380a1376656869636c655f63697479203d20636974791217636865636b5f76656869636c655f636974795f6369747918002802280330003800b2018a010a077072696d61727910001a0269641a04636974791a0c76656869636c655f636974791a0872696465725f69641a0a76656869636c655f69641a0d73746172745f616464726573731a0b656e645f616464726573731a0a73746172745f74696d651a08656e645f74696d651a07726576656e7565200120022003200420052006200720082009200a2800b80101c20100e80100f2010408001200f801008002009202009a0200a202270837100210041802180120352a11666b5f636974795f7265665f75736572733000380040004800a202320837100310051802180120362a1c666b5f76656869636c655f636974795f7265665f76656869636c65733000380040004800aa02270838100110021802180120372a11666b5f636974795f7265665f72696465733002380040004800b20200b80200c0021dc80200e00200f00200', 'hex'), true); +SELECT crdb_internal.unsafe_upsert_descriptor(55, decode('0aee090a0572696465731837203428013a0042250a02696410011a0d080e10001800300050861760002000300068007000780080010088010042270a046369747910021a0d0807100018003007509308600020003000680070007800800100880100422f0a0c76656869636c655f6369747910031a0d0807100018003007509308600020013000680070007800800100880100422b0a0872696465725f696410041a0d080e100018003000508617600020013000680070007800800100880100422d0a0a76656869636c655f696410051a0d080e10001800300050861760002001300068007000780080010088010042300a0d73746172745f6164647265737310061a0d0807100018003007509308600020013000680070007800800100880100422e0a0b656e645f6164647265737310071a0d0807100018003007509308600020013000680070007800800100880100422d0a0a73746172745f74696d6510081a0d080510001800300050da08600020013000680070007800800100880100422b0a08656e645f74696d6510091a0d080510001800300050da08600020013000680070007800800100880100422a0a07726576656e7565100a1a0d08031002180a300050a40d600020013000680070007800800100880100480b52570a077072696d617279100118012204636974792202696430023001400040004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba01005a7a0a2272696465735f6175746f5f696e6465785f666b5f636974795f7265665f757365727310021800220463697479220872696465725f6964300230043801400040004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba01005a91010a2d72696465735f6175746f5f696e6465785f666b5f76656869636c655f636974795f7265665f76656869636c657310031800220c76656869636c655f63697479220a76656869636c655f69643003300538023801400040004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba010060046a1d0a090a0561646d696e10020a080a04726f6f7410021204726f6f741801800103880103980100a201380a1376656869636c655f63697479203d20636974791217636865636b5f76656869636c655f636974795f6369747918002802280330003800b2018a010a077072696d61727910001a0269641a04636974791a0c76656869636c655f636974791a0872696465725f69641a0a76656869636c655f69641a0d73746172745f616464726573731a0b656e645f616464726573731a0a73746172745f74696d651a08656e645f74696d651a07726576656e7565200120022003200420052006200720082009200a2800b80101c20100e80100f2010408001200f801008002009202009a0200a202270837100210041802180120352a11666b5f636974795f7265665f75736572733000380040004800a202320837100310051802180120362a1c666b5f76656869636c655f636974795f7265665f76656869636c65733000380040004800aa02270838100110021802180120372a11666b5f636974795f7265665f72696465733002380040004800b20200b80200c0021dc80200e00200f00200f80200', 'hex'), true); SELECT crdb_internal.unsafe_upsert_namespace_entry(52, 29, 'rides', 55, true); -SELECT crdb_internal.unsafe_upsert_descriptor(56, decode('0aa8040a1a76656869636c655f6c6f636174696f6e5f686973746f726965731838203428013a0042270a046369747910011a0d0807100018003007509308600020003000680070007800800100880100422a0a07726964655f696410021a0d080e100018003000508617600020003000680070007800800100880100422c0a0974696d657374616d7010031a0d080510001800300050da0860002000300068007000780080010088010042260a036c617410041a0d080210401800300050bd0560002001300068007000780080010088010042270a046c6f6e6710051a0d080210401800300050bd056000200130006800700078008001008801004806526b0a077072696d617279100118012204636974792207726964655f6964220974696d657374616d703001300230034000400040004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba010060026a1d0a090a0561646d696e10020a080a04726f6f7410021204726f6f741801800102880103980100b2013c0a077072696d61727910001a04636974791a07726964655f69641a0974696d657374616d701a036c61741a046c6f6e67200120022003200420052800b80101c20100e80100f2010408001200f801008002009202009a0200a202270838100110021802180120372a11666b5f636974795f7265665f72696465733000380040004800b20200b80200c0021dc80200e00200f00200', 'hex'), true); +SELECT crdb_internal.unsafe_upsert_descriptor(56, decode('0aab040a1a76656869636c655f6c6f636174696f6e5f686973746f726965731838203428013a0042270a046369747910011a0d0807100018003007509308600020003000680070007800800100880100422a0a07726964655f696410021a0d080e100018003000508617600020003000680070007800800100880100422c0a0974696d657374616d7010031a0d080510001800300050da0860002000300068007000780080010088010042260a036c617410041a0d080210401800300050bd0560002001300068007000780080010088010042270a046c6f6e6710051a0d080210401800300050bd056000200130006800700078008001008801004806526b0a077072696d617279100118012204636974792207726964655f6964220974696d657374616d703001300230034000400040004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba010060026a1d0a090a0561646d696e10020a080a04726f6f7410021204726f6f741801800102880103980100b2013c0a077072696d61727910001a04636974791a07726964655f69641a0974696d657374616d701a036c61741a046c6f6e67200120022003200420052800b80101c20100e80100f2010408001200f801008002009202009a0200a202270838100110021802180120372a11666b5f636974795f7265665f72696465733000380040004800b20200b80200c0021dc80200e00200f00200f80200', 'hex'), true); SELECT crdb_internal.unsafe_upsert_namespace_entry(52, 29, 'vehicle_location_histories', 56, true); -SELECT crdb_internal.unsafe_upsert_descriptor(57, decode('0afd030a0b70726f6d6f5f636f6465731839203428013a0042270a04636f646510011a0d0807100018003007509308600020003000680070007800800100880100422e0a0b6465736372697074696f6e10021a0d080710001800300750930860002001300068007000780080010088010042300a0d6372656174696f6e5f74696d6510031a0d080510001800300050da0860002001300068007000780080010088010042320a0f65787069726174696f6e5f74696d6510041a0d080510001800300050da0860002001300068007000780080010088010042280a0572756c657310051a0d081210001800300050da1d6000200130006800700078008001008801004806524f0a077072696d617279100118012204636f6465300140004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba010060026a1d0a090a0561646d696e10020a080a04726f6f7410021204726f6f741801800101880103980100b201510a077072696d61727910001a04636f64651a0b6465736372697074696f6e1a0d6372656174696f6e5f74696d651a0f65787069726174696f6e5f74696d651a0572756c6573200120022003200420052800b80101c20100e80100f2010408001200f801008002009202009a0200b20200b80200c0021dc80200e00200f00200', 'hex'), true); +SELECT crdb_internal.unsafe_upsert_descriptor(57, decode('0a80040a0b70726f6d6f5f636f6465731839203428013a0042270a04636f646510011a0d0807100018003007509308600020003000680070007800800100880100422e0a0b6465736372697074696f6e10021a0d080710001800300750930860002001300068007000780080010088010042300a0d6372656174696f6e5f74696d6510031a0d080510001800300050da0860002001300068007000780080010088010042320a0f65787069726174696f6e5f74696d6510041a0d080510001800300050da0860002001300068007000780080010088010042280a0572756c657310051a0d081210001800300050da1d6000200130006800700078008001008801004806524f0a077072696d617279100118012204636f6465300140004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba010060026a1d0a090a0561646d696e10020a080a04726f6f7410021204726f6f741801800101880103980100b201510a077072696d61727910001a04636f64651a0b6465736372697074696f6e1a0d6372656174696f6e5f74696d651a0f65787069726174696f6e5f74696d651a0572756c6573200120022003200420052800b80101c20100e80100f2010408001200f801008002009202009a0200b20200b80200c0021dc80200e00200f00200f80200', 'hex'), true); SELECT crdb_internal.unsafe_upsert_namespace_entry(52, 29, 'promo_codes', 57, true); -SELECT crdb_internal.unsafe_upsert_descriptor(58, decode('0aa8040a10757365725f70726f6d6f5f636f646573183a203428013a0042270a046369747910011a0d0807100018003007509308600020003000680070007800800100880100422a0a07757365725f696410021a0d080e10001800300050861760002000300068007000780080010088010042270a04636f646510031a0d0807100018003007509308600020003000680070007800800100880100422c0a0974696d657374616d7010041a0d080510001800300050da08600020013000680070007800800100880100422d0a0b75736167655f636f756e7410051a0c08011040180030005014600020013000680070007800800100880100480652660a077072696d617279100118012204636974792207757365725f69642204636f64653001300230034000400040004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba010060026a1d0a090a0561646d696e10020a080a04726f6f7410021204726f6f741801800102880103980100b201440a077072696d61727910001a04636974791a07757365725f69641a04636f64651a0974696d657374616d701a0b75736167655f636f756e74200120022003200420052800b80101c20100e80100f2010408001200f801008002009202009a0200a20227083a100110021802180120352a11666b5f636974795f7265665f75736572733000380040004800b20200b80200c0021dc80200e00200f00200', 'hex'), true); +SELECT crdb_internal.unsafe_upsert_descriptor(58, decode('0aab040a10757365725f70726f6d6f5f636f646573183a203428013a0042270a046369747910011a0d0807100018003007509308600020003000680070007800800100880100422a0a07757365725f696410021a0d080e10001800300050861760002000300068007000780080010088010042270a04636f646510031a0d0807100018003007509308600020003000680070007800800100880100422c0a0974696d657374616d7010041a0d080510001800300050da08600020013000680070007800800100880100422d0a0b75736167655f636f756e7410051a0c08011040180030005014600020013000680070007800800100880100480652660a077072696d617279100118012204636974792207757365725f69642204636f64653001300230034000400040004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba010060026a1d0a090a0561646d696e10020a080a04726f6f7410021204726f6f741801800102880103980100b201440a077072696d61727910001a04636974791a07757365725f69641a04636f64651a0974696d657374616d701a0b75736167655f636f756e74200120022003200420052800b80101c20100e80100f2010408001200f801008002009202009a0200a20227083a100110021802180120352a11666b5f636974795f7265665f75736572733000380040004800b20200b80200c0021dc80200e00200f00200f80200', 'hex'), true); SELECT crdb_internal.unsafe_upsert_namespace_entry(52, 29, 'user_promo_codes', 58, true); COMMIT; diff --git a/pkg/clusterversion/cockroach_versions.go b/pkg/clusterversion/cockroach_versions.go index 909d7cfd7bc8..5329d52668d6 100644 --- a/pkg/clusterversion/cockroach_versions.go +++ b/pkg/clusterversion/cockroach_versions.go @@ -300,6 +300,8 @@ const ( ExpressionIndexes // DeleteDeprecatedNamespaceTableDescriptorMigration deletes the descriptor at ID=2. DeleteDeprecatedNamespaceTableDescriptorMigration + // FixDescriptors is for the migration to fix all descriptors. + FixDescriptors // Step (1): Add new versions here. ) @@ -501,6 +503,10 @@ var versionsSingleton = keyedVersions([]keyedVersion{ Key: DeleteDeprecatedNamespaceTableDescriptorMigration, Version: roachpb.Version{Major: 21, Minor: 1, Internal: 12}, }, + { + Key: FixDescriptors, + Version: roachpb.Version{Major: 21, Minor: 1, Internal: 14}, + }, // Step (2): Add new versions here. }) diff --git a/pkg/clusterversion/key_string.go b/pkg/clusterversion/key_string.go index a1f22082046b..bc49a6a9d212 100644 --- a/pkg/clusterversion/key_string.go +++ b/pkg/clusterversion/key_string.go @@ -51,11 +51,12 @@ func _() { _ = x[SerializeViewUDTs-40] _ = x[ExpressionIndexes-41] _ = x[DeleteDeprecatedNamespaceTableDescriptorMigration-42] + _ = x[FixDescriptors-43] } -const _Key_name = "Start20_2GeospatialTypeAlterColumnTypeGeneralUserDefinedSchemasNoOriginFKIndexesNodeMembershipStatusMinPasswordLengthAbortSpanBytesMaterializedViewsBox2DTypeCreateLoginPrivilegeHBAForNonTLSV20_2Start21_1EmptyArraysInInvertedIndexesUniqueWithoutIndexConstraintsVirtualComputedColumnsCPutInlineReplicaVersionsreplacedTruncatedAndRangeAppliedStateMigrationreplacedPostTruncatedAndRangeAppliedStateMigrationNewSchemaChangerLongRunningMigrationsTruncatedAndRangeAppliedStateMigrationPostTruncatedAndRangeAppliedStateMigrationSeparatedIntentsTracingVerbosityIndependentSemanticsSequencesRegclassImplicitColumnPartitioningMultiRegionFeaturesClosedTimestampsRaftTransportChangefeedsSupportPrimaryIndexChangesForeignKeyRepresentationMigrationPriorReadSummariesNonVotingReplicasProtectedTsMetaPrivilegesMigrationV21_1Start21_2JoinTokensTableAcquisitionTypeInLeaseHistorySerializeViewUDTsExpressionIndexesDeleteDeprecatedNamespaceTableDescriptorMigration" +const _Key_name = "Start20_2GeospatialTypeAlterColumnTypeGeneralUserDefinedSchemasNoOriginFKIndexesNodeMembershipStatusMinPasswordLengthAbortSpanBytesMaterializedViewsBox2DTypeCreateLoginPrivilegeHBAForNonTLSV20_2Start21_1EmptyArraysInInvertedIndexesUniqueWithoutIndexConstraintsVirtualComputedColumnsCPutInlineReplicaVersionsreplacedTruncatedAndRangeAppliedStateMigrationreplacedPostTruncatedAndRangeAppliedStateMigrationNewSchemaChangerLongRunningMigrationsTruncatedAndRangeAppliedStateMigrationPostTruncatedAndRangeAppliedStateMigrationSeparatedIntentsTracingVerbosityIndependentSemanticsSequencesRegclassImplicitColumnPartitioningMultiRegionFeaturesClosedTimestampsRaftTransportChangefeedsSupportPrimaryIndexChangesForeignKeyRepresentationMigrationPriorReadSummariesNonVotingReplicasProtectedTsMetaPrivilegesMigrationV21_1Start21_2JoinTokensTableAcquisitionTypeInLeaseHistorySerializeViewUDTsExpressionIndexesDeleteDeprecatedNamespaceTableDescriptorMigrationFixedPrivilegeDescriptors" -var _Key_index = [...]uint16{0, 9, 23, 45, 63, 80, 100, 117, 131, 148, 157, 177, 189, 194, 203, 231, 260, 282, 292, 307, 353, 403, 419, 440, 478, 520, 536, 572, 589, 615, 634, 663, 700, 733, 751, 768, 802, 807, 816, 831, 860, 877, 894, 943} +var _Key_index = [...]uint16{0, 9, 23, 45, 63, 80, 100, 117, 131, 148, 157, 177, 189, 194, 203, 231, 260, 282, 292, 307, 353, 403, 419, 440, 478, 520, 536, 572, 589, 615, 634, 663, 700, 733, 751, 768, 802, 807, 816, 831, 860, 877, 894, 943, 968} func (i Key) String() string { if i < 0 || i >= Key(len(_Key_index)-1) { diff --git a/pkg/migration/migrations/BUILD.bazel b/pkg/migration/migrations/BUILD.bazel index 463a94007eff..d7ae548efc3e 100644 --- a/pkg/migration/migrations/BUILD.bazel +++ b/pkg/migration/migrations/BUILD.bazel @@ -4,6 +4,7 @@ go_library( name = "migrations", srcs = [ "delete_deprecated_namespace_tabledesc.go", + "fix_descriptor_migration.go", "foreign_key_representation_upgrade.go", "join_tokens.go", "migrations.go", @@ -20,7 +21,9 @@ go_library( "//pkg/migration", "//pkg/roachpb", "//pkg/server/serverpb", + "//pkg/sql/catalog", "//pkg/sql/catalog/catalogkeys", + "//pkg/sql/catalog/catalogkv", "//pkg/sql/catalog/descpb", "//pkg/sql/catalog/descs", "//pkg/sql/catalog/systemschema", @@ -36,9 +39,9 @@ go_library( go_test( name = "migrations_test", - size = "medium", srcs = [ "delete_deprecated_namespace_tabledesc_external_test.go", + "fix_descriptor_migration_external_test.go", "foreign_key_representation_upgrade_external_test.go", "main_test.go", "protected_ts_meta_migration_external_test.go", diff --git a/pkg/migration/migrations/fix_descriptor_migration.go b/pkg/migration/migrations/fix_descriptor_migration.go new file mode 100644 index 000000000000..af29124a110c --- /dev/null +++ b/pkg/migration/migrations/fix_descriptor_migration.go @@ -0,0 +1,102 @@ +// Copyright 2021 The Cockroach Authors. +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package migrations + +import ( + "context" + + "github.com/cockroachdb/cockroach/pkg/clusterversion" + "github.com/cockroachdb/cockroach/pkg/kv" + "github.com/cockroachdb/cockroach/pkg/migration" + "github.com/cockroachdb/cockroach/pkg/sql/catalog" + "github.com/cockroachdb/cockroach/pkg/sql/catalog/catalogkv" + "github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb" + "github.com/cockroachdb/cockroach/pkg/sql/catalog/descs" + "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" + "github.com/cockroachdb/cockroach/pkg/sql/sqlutil" + "github.com/cockroachdb/cockroach/pkg/util/log" + "github.com/cockroachdb/cockroach/pkg/util/protoutil" + "github.com/cockroachdb/errors" +) + +// fixDescriptorMigration calls RunPostDeserializationChanges on every descriptor. +func fixDescriptorMigration( + ctx context.Context, _ clusterversion.ClusterVersion, d migration.TenantDeps, +) error { + rows, err := d.InternalExecutor.QueryIterator(ctx, "fix-privileges", nil, /* txn */ + ` +SELECT id, descriptor, crdb_internal_mvcc_timestamp FROM system.descriptor ORDER BY ID ASC`) + if err != nil { + return err + } + defer func() { _ = rows.Close() }() + ok, err := rows.Next(ctx) + for ; ok; ok, err = rows.Next(ctx) { + desc, err := getMutableDescFromDescriptorRow(rows) + if err != nil { + return err + } + if desc.GetIsRepaired() { + continue + } + if err := runPostDeserializationChanges(ctx, desc, d); err != nil { + return err + } + } + return err +} + +// getMutableDescFromDescriptorRow takes in an InternalRow from the query: +// SELECT id, descriptor, crdb_internal_mvcc_timestamp FROM system.descriptor ORDER BY ID ASC +// and parses the id, mvcc_timestamp and descriptor fields to create and return +// a MutableDescriptor. +func getMutableDescFromDescriptorRow(rows sqlutil.InternalRows) (catalog.MutableDescriptor, error) { + row := rows.Cur() + id := descpb.ID(*row[0].(*tree.DInt)) + ts, err := tree.DecimalToHLC(&row[2].(*tree.DDecimal).Decimal) + if err != nil { + return nil, errors.Wrapf(err, + "failed to convert MVCC timestamp decimal to HLC for ID %d", id) + } + var desc descpb.Descriptor + if err := protoutil.Unmarshal(([]byte)(*row[1].(*tree.DBytes)), &desc); err != nil { + return nil, errors.Wrapf(err, + "failed to unmarshal descriptor with ID %d", id) + } + + b := catalogkv.NewBuilderWithMVCCTimestamp(&desc, ts) + if b == nil { + return nil, errors.Newf("unable to find descriptor for id %d", id) + } + + return b.BuildExistingMutable(), nil +} + +func runPostDeserializationChanges( + ctx context.Context, desc catalog.MutableDescriptor, d migration.TenantDeps, +) error { + return descs.Txn(ctx, d.Settings, d.LeaseManager, d.InternalExecutor, d.DB, func( + ctx context.Context, txn *kv.Txn, descriptors *descs.Collection) error { + desc := catalogkv.NewBuilder(desc.DescriptorProto()) + dg := catalogkv.NewOneLevelUncachedDescGetter(txn, d.Codec) + changed, err := desc.RunPostDeserializationChanges(ctx, dg) + if err != nil { + return err + } + if changed { + writeDesc := desc.BuildExistingMutable() + writeDesc.SetIsRepaired() + log.Infof(ctx, "upgrading descriptor with id %d", writeDesc.GetID()) + return descriptors.WriteDesc(ctx, false /* kvTrace */, writeDesc, txn) + } + return nil + }) +} diff --git a/pkg/migration/migrations/fix_descriptor_migration_external_test.go b/pkg/migration/migrations/fix_descriptor_migration_external_test.go new file mode 100644 index 000000000000..0f526823f5f1 --- /dev/null +++ b/pkg/migration/migrations/fix_descriptor_migration_external_test.go @@ -0,0 +1,193 @@ +// Copyright 2021 The Cockroach Authors. +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package migrations_test + +import ( + "context" + "encoding/hex" + "errors" + "strings" + "testing" + + "github.com/cockroachdb/cockroach/pkg/base" + "github.com/cockroachdb/cockroach/pkg/clusterversion" + "github.com/cockroachdb/cockroach/pkg/keys" + "github.com/cockroachdb/cockroach/pkg/kv" + "github.com/cockroachdb/cockroach/pkg/server" + "github.com/cockroachdb/cockroach/pkg/sql/catalog/catalogkv" + "github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb" + "github.com/cockroachdb/cockroach/pkg/testutils/sqlutils" + "github.com/cockroachdb/cockroach/pkg/testutils/testcluster" + "github.com/cockroachdb/cockroach/pkg/util/leaktest" + "github.com/cockroachdb/cockroach/pkg/util/protoutil" + "github.com/stretchr/testify/require" +) + +func TestFixPrivilegesMigration(t *testing.T) { + defer leaktest.AfterTest(t)() + // The SQL statements below are run on a 20.1.2 cluster, the ZONECONFIG bit + // becomes the USAGE bit in versions >20.2 causing the privilege descriptor + // to become corrupted since USAGE is not valid on tables and dbs. + /* + CREATE USER testuser; + CREATE DATABASE db; + GRANT ZONECONFIG ON DATABASE db TO testuser; + USE db; + CREATE TABLE tb(); + GRANT ZONECONFIG ON tb TO testuser; + + The descriptors were then extracted using: + + SELECT encode(descriptor, 'hex') AS descriptor + FROM system.descriptor + WHERE id + IN ( + SELECT id + FROM system.namespace + WHERE "parentID" + = ( + SELECT id + FROM system.namespace + WHERE "parentID" = 0 AND name = 'db' + ) + OR "parentID" = 0 AND name = 'db' + ); + */ + const descriptorStringsToInjectZoneConfigFixTest = ` +122c0a026462103b1a240a090a0561646d696e10020a080a04726f6f7410020a0d0a087465737475736572108004 +0afe010a027462183c203b28023a00422b0a05726f77696410011a0c08011040180030005014600020002a0e756e697175655f726f77696428293001480252480a077072696d617279100118012205726f776964300140004a10080010001a00200028003000380040005a007a020800800100880100900100980100a20106080012001800a8010060026a240a090a0561646d696e10020a080a04726f6f7410020a0d0a087465737475736572108004800101880103980100b201160a077072696d61727910001a05726f77696420012800b80101c20100e80100f2010408001200f801008002009202009a020a08d0b7a9c4fcdd9fc416b20200b80200c0021d +` + + // Test fixing a corrupted schema privilege descriptor after converting + // from a database to a schema. The SQL statements below are run on a 20.2.5 + // cluster where ALTER DATABASE ... CONVERT TO SCHEMA did not correctly handle + // privileges. The "schema" is corrupted due to testuser having SELECT + // privilege on it. + /* + CREATE DATABASE parent; + CREATE DATABASE schema; + CREATE USER TESTUSER; + GRANT SELECT ON DATABASE SCHEMA TO TESTUSER; + ALTER DATABASE schema CONVERT TO SCHEMA WITH PARENT parent; + + The descriptors were then extracted using: + + SELECT encode(descriptor, 'hex') AS descriptor + FROM system.descriptor + WHERE id + IN ( + SELECT id + FROM system.namespace + WHERE "parentID" + = ( + SELECT id + FROM system.namespace + WHERE "parentID" = 0 AND name = 'parent' + ) + OR "parentID" = 0 AND name = 'parent' + ); + */ + const descriptorStringsToInjectSchemaTest = ` +12410a06706172656e74103b1a1d0a090a0561646d696e10020a080a04726f6f7410021204726f6f741801220028023a0e0a06736368656d611204083d100040004a00 +2241083b1206736368656d61183d222b0a090a0561646d696e10020a080a04726f6f7410020a0c0a08746573747573657210201204726f6f7418012a00300140004a00 +` + + // Ensure types can also be upgraded. Types in practice should not be corrupted + // and should always have an owner since they're created in 20.2 and onwards. + // We still want to upgrade the Version of the privilege descriptor. + // The following SQL statements were run in a 20.2.5 cluster. + /* + CREATE DATABASE db; + USE db; + CREATE TYPE t AS ENUM(); + + The descriptors were then extracted using: + + SELECT encode(descriptor, 'hex') AS descriptor + FROM system.descriptor + WHERE id + IN ( + SELECT id + FROM system.namespace + WHERE "parentID" + = ( + SELECT id + FROM system.namespace + WHERE "parentID" = 0 AND name = 'db' + ) + OR "parentID" = 0 AND name = 'db' + ); + */ + const descriptorStringsToInjectUserDefinedTypeTest = ` +122d0a026462103d1a1d0a090a0561646d696e10020a080a04726f6f7410021204726f6f7418012200280140004a00 +1a41083d101d1a0174203e2800403f480152006800722a0a090a0561646d696e10020a0b0a067075626c69631080040a080a04726f6f7410021204726f6f7418017a00 +1a6a083d101d1a025f74203f28013a26080f100018003000381850df8d065a14081810001800300050de8d0660007a0410df8d0660004000480152006800722a0a090a0561646d696e10020a0b0a067075626c69631080040a080a04726f6f7410021204726f6f7418017a00 +` + + testCases := []string{ + descriptorStringsToInjectZoneConfigFixTest, + descriptorStringsToInjectSchemaTest, + descriptorStringsToInjectUserDefinedTypeTest, + } + for _, descriptorStringsToInject := range testCases { + var descriptorsToInject []*descpb.Descriptor + for _, s := range strings.Split(strings.TrimSpace(descriptorStringsToInject), "\n") { + encoded, err := hex.DecodeString(s) + require.NoError(t, err) + var desc descpb.Descriptor + require.NoError(t, protoutil.Unmarshal(encoded, &desc)) + descriptorsToInject = append(descriptorsToInject, &desc) + } + + ctx := context.Background() + tc := testcluster.StartTestCluster(t, 1, base.TestClusterArgs{ + ServerArgs: base.TestServerArgs{ + Knobs: base.TestingKnobs{ + Server: &server.TestingKnobs{ + DisableAutomaticVersionUpgrade: 1, + BinaryVersionOverride: clusterversion.ByKey(clusterversion.FixDescriptors - 1), + }, + }, + }, + }) + + db := tc.ServerConn(0) + kvDB := tc.Server(0).DB() + require.NoError(t, sqlutils.InjectDescriptors( + ctx, db, descriptorsToInject, true, /* force */ + )) + + _, err := tc.Conns[0].ExecContext(ctx, `SET CLUSTER SETTING version = $1`, + clusterversion.ByKey(clusterversion.FixDescriptors).String()) + require.NoError(t, err) + + err = kvDB.Txn(ctx, func(ctx context.Context, txn *kv.Txn) error { + // GetAllDescriptors calls PrivilegeDescriptor.Validate, all the invalid + // descriptors should be updated. + descs, err := catalogkv.GetAllDescriptors(ctx, txn, keys.SystemSQLCodec) + if err != nil { + return err + } + + for _, desc := range descs { + privilegeDesc := desc.GetPrivileges() + if privilegeDesc.Version < descpb.Version21_2 { + return errors.New("privilege descriptors must have at least Version21_2") + } + + } + return nil + }) + + require.NoError(t, err) + tc.Stopper().Stop(ctx) + } +} diff --git a/pkg/migration/migrations/foreign_key_representation_upgrade_external_test.go b/pkg/migration/migrations/foreign_key_representation_upgrade_external_test.go index 81592a8f2da6..8a911adee336 100644 --- a/pkg/migration/migrations/foreign_key_representation_upgrade_external_test.go +++ b/pkg/migration/migrations/foreign_key_representation_upgrade_external_test.go @@ -87,7 +87,9 @@ func TestForeignKeyMigration(t *testing.T) { defer tc.Stopper().Stop(ctx) db := tc.ServerConn(0) - require.NoError(t, sqlutils.InjectDescriptors(ctx, db, descriptorsToInject)) + require.NoError(t, sqlutils.InjectDescriptors( + ctx, db, descriptorsToInject, true, /* force */ + )) tdb := sqlutils.MakeSQLRunner(db) numUnupgradedDescriptors := func() (numUnupgraded int) { tdb.QueryRow(t, ` diff --git a/pkg/migration/migrations/migrations.go b/pkg/migration/migrations/migrations.go index f8d3966b09d4..0d25ad58ca96 100644 --- a/pkg/migration/migrations/migrations.go +++ b/pkg/migration/migrations/migrations.go @@ -66,6 +66,10 @@ var migrations = []migration.Migration{ "delete the deprecated namespace table descriptor at ID=2", toCV(clusterversion.DeleteDeprecatedNamespaceTableDescriptorMigration), deleteDeprecatedNamespaceTableDescriptorMigration), + migration.NewTenantMigration( + "fix all descriptors", + toCV(clusterversion.FixDescriptors), + fixDescriptorMigration), } func init() { diff --git a/pkg/migration/migrations/protected_ts_meta_migration_external_test.go b/pkg/migration/migrations/protected_ts_meta_migration_external_test.go index 65fa624df379..887383abd86d 100644 --- a/pkg/migration/migrations/protected_ts_meta_migration_external_test.go +++ b/pkg/migration/migrations/protected_ts_meta_migration_external_test.go @@ -70,7 +70,7 @@ func TestProtectedTimestampMetaMigration(t *testing.T) { `{"ownerProto": "node", "users": [`+ `{"privileges": %d, "userProto": "admin"}, `+ `{"privileges": %d, "userProto": "root"}`+ - `], "version": 1}`, + `], "version": 2}`, expectedPrivileges, expectedPrivileges, ) diff --git a/pkg/sql/catalog/catalog.go b/pkg/sql/catalog/catalog.go index d28dbce15212..18439794151b 100644 --- a/pkg/sql/catalog/catalog.go +++ b/pkg/sql/catalog/catalog.go @@ -44,6 +44,8 @@ type MutableDescriptor interface { SetDropped() // SetOffline sets the descriptor's state to offline, with the provided reason. SetOffline(reason string) + // SetIsRepaired sets the IsRepaired bit to true. + SetIsRepaired() } // VirtualSchemas is a collection of VirtualSchemas. diff --git a/pkg/sql/catalog/catalogkv/catalogkv.go b/pkg/sql/catalog/catalogkv/catalogkv.go index ea75626f02b5..cab18ac0f0e3 100644 --- a/pkg/sql/catalog/catalogkv/catalogkv.go +++ b/pkg/sql/catalog/catalogkv/catalogkv.go @@ -155,7 +155,7 @@ func descriptorFromKeyValue( if err != nil || b == nil { return nil, err } - err = b.RunPostDeserializationChanges(ctx, dg) + _, err = b.RunPostDeserializationChanges(ctx, dg) if err != nil { return nil, err } diff --git a/pkg/sql/catalog/dbdesc/database_desc.go b/pkg/sql/catalog/dbdesc/database_desc.go index 21525676d2c4..c2f9aaddf638 100644 --- a/pkg/sql/catalog/dbdesc/database_desc.go +++ b/pkg/sql/catalog/dbdesc/database_desc.go @@ -386,3 +386,8 @@ func (desc *Mutable) SetInitialMultiRegionConfig(config *multiregion.RegionConfi } return nil } + +// SetIsRepaired sets the IsRepaired bit to true. +func (desc *Mutable) SetIsRepaired() { + desc.IsRepaired = true +} diff --git a/pkg/sql/catalog/dbdesc/database_desc_builder.go b/pkg/sql/catalog/dbdesc/database_desc_builder.go index 840e37c5c534..48ddfb8ac70a 100644 --- a/pkg/sql/catalog/dbdesc/database_desc_builder.go +++ b/pkg/sql/catalog/dbdesc/database_desc_builder.go @@ -17,6 +17,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/catalog" "github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb" "github.com/cockroachdb/cockroach/pkg/sql/catalog/multiregion" + "github.com/cockroachdb/cockroach/pkg/sql/privilege" "github.com/cockroachdb/cockroach/pkg/util/protoutil" ) @@ -53,14 +54,11 @@ func (ddb *databaseDescriptorBuilder) DescriptorType() catalog.DescriptorType { // interface. func (ddb *databaseDescriptorBuilder) RunPostDeserializationChanges( _ context.Context, _ catalog.DescGetter, -) error { - // Fill in any incorrect privileges that may have been missed due to mixed-versions. - // TODO(mberhault): remove this in 2.1 (maybe 2.2) when privilege-fixing migrations have been - // run again and mixed-version clusters always write "good" descriptors. +) (bool, error) { ddb.maybeModified = protoutil.Clone(ddb.original).(*descpb.DatabaseDescriptor) - descpb.MaybeFixPrivileges(ddb.maybeModified.ID, &ddb.maybeModified.Privileges) - descpb.MaybeFixUsagePrivForTablesAndDBs(&ddb.maybeModified.Privileges) - return nil + changed := descpb.MaybeFixPrivileges(ddb.maybeModified.ID, ddb.maybeModified.ID, + &ddb.maybeModified.Privileges, privilege.Database) + return changed, nil } // BuildImmutable implements the catalog.DescriptorBuilder interface. diff --git a/pkg/sql/catalog/descpb/privilege.go b/pkg/sql/catalog/descpb/privilege.go index 12adbae9dc06..a132a18a133d 100644 --- a/pkg/sql/catalog/descpb/privilege.go +++ b/pkg/sql/catalog/descpb/privilege.go @@ -34,6 +34,11 @@ const ( // OwnerVersion corresponds to descriptors created 20.2 and onward. // These descriptors should always have owner set. OwnerVersion + + // Version21_2 corresponds to descriptors created in 21.2 and onwards. + // These descriptors should have all the correct privileges and the owner field + // explicitly set. These descriptors should be strictly validated. + Version21_2 ) func isPrivilegeSet(bits uint32, priv privilege.Kind) bool { @@ -118,7 +123,7 @@ func NewCustomSuperuserPrivilegeDescriptor( Privileges: priv.ToBitField(), }, }, - Version: OwnerVersion, + Version: Version21_2, } } @@ -144,7 +149,7 @@ func NewPrivilegeDescriptor( Privileges: priv.ToBitField(), }, }, - Version: OwnerVersion, + Version: Version21_2, } } @@ -256,56 +261,41 @@ func MaybeFixUsagePrivForTablesAndDBs(ptr **PrivilegeDescriptor) bool { modified = true } } - return modified -} - -// MaybeFixSchemaPrivileges removes all invalid bits set on a schema's -// PrivilegeDescriptor. -// This is necessary due to ALTER DATABASE ... CONVERT TO SCHEMA originally -// copying all database privileges to the schema. Not all database privileges -// are valid for schemas thus after running ALTER DATABASE ... CONVERT TO SCHEMA, -// the schema may become unusable. -func MaybeFixSchemaPrivileges(ptr **PrivilegeDescriptor) { - if *ptr == nil { - *ptr = &PrivilegeDescriptor{} - } - p := *ptr - - validPrivs := privilege.GetValidPrivilegesForObject(privilege.Schema).ToBitField() - for i := range p.Users { - p.Users[i].Privileges &= validPrivs - } + return modified } // MaybeFixPrivileges fixes the privilege descriptor if needed, including: // * adding default privileges for the "admin" role // * fixing default privileges for the "root" user // * fixing maximum privileges for users. -// Returns true if the privilege descriptor was modified. -// -// TODO(ajwerner): Figure out whether this is still needed. It seems like -// perhaps it was intended only for the 2.0 release but then somehow we got -// bad descriptors with bad initial permissions into later versions or we didn't -// properly bake this migration in. -func MaybeFixPrivileges(id ID, ptr **PrivilegeDescriptor) bool { +// * populating the owner field if previously empty. +// * updating version field to Version21_2. +// MaybeFixPrivileges can be removed after v21.2. +func MaybeFixPrivileges( + id ID, parentID ID, ptr **PrivilegeDescriptor, objectType privilege.ObjectType, +) bool { if *ptr == nil { *ptr = &PrivilegeDescriptor{} } p := *ptr - allowedPrivilegesBits := privilege.ALL.Mask() + allowedPrivilegesBits := privilege.GetValidPrivilegesForObject(objectType).ToBitField() if IsReservedID(id) { // System databases and tables have custom maximum allowed privileges. allowedPrivilegesBits = SystemAllowedPrivileges[id].ToBitField() } - var modified bool + changed := false fixSuperUser := func(user security.SQLUsername) { privs := p.findOrCreateUser(user) if privs.Privileges != allowedPrivilegesBits { - privs.Privileges = allowedPrivilegesBits - modified = true + if isPrivilegeSet(allowedPrivilegesBits, privilege.ALL) { + privs.Privileges = privilege.ALL.Mask() + } else { + privs.Privileges = allowedPrivilegesBits + } + changed = true } } @@ -313,9 +303,8 @@ func MaybeFixPrivileges(id ID, ptr **PrivilegeDescriptor) bool { fixSuperUser(security.RootUserName()) fixSuperUser(security.AdminRoleName()) - if isPrivilegeSet(allowedPrivilegesBits, privilege.ALL) { - // ALL privileges allowed, we can skip regular users. - return modified + if objectType == privilege.Table || objectType == privilege.Database { + changed = changed || MaybeFixUsagePrivForTablesAndDBs(&p) } for i := range p.Users { @@ -326,14 +315,26 @@ func MaybeFixPrivileges(id ID, ptr **PrivilegeDescriptor) bool { continue } - if (u.Privileges &^ allowedPrivilegesBits) != 0 { - // User has disallowed privileges: bitwise AND with allowed privileges. - u.Privileges &= allowedPrivilegesBits - modified = true + if u.Privileges&allowedPrivilegesBits != u.Privileges { + changed = true } + u.Privileges &= allowedPrivilegesBits } - return modified + if p.Owner().Undefined() { + if id == keys.SystemDatabaseID || parentID == keys.SystemDatabaseID { + p.SetOwner(security.NodeUserName()) + } else { + p.SetOwner(security.RootUserName()) + } + changed = true + } + + if p.Version < Version21_2 { + p.SetVersion(Version21_2) + changed = true + } + return changed } // ValidateSuperuserPrivileges ensures that superusers have exactly the maximum @@ -387,6 +388,24 @@ func (p PrivilegeDescriptor) Validate(id ID, objectType privilege.ObjectType) er allowedPrivilegesBits := privilege.GetValidPrivilegesForObject(objectType).ToBitField() + // Validate can be called during the fix_privileges_migration introduced in + // 21.2. It is possible for have invalid privileges prior to 21.2 in certain + // cases due to bugs. We can strictly check privileges in 21.2 and onwards. + if p.Version < Version21_2 { + if objectType == privilege.Schema { + // Prior to 21_2, it was possible for a schema to have some database + // privileges on it. This was temporarily fixed by an upgrade on read + // but in 21.2 onwards, it should be permanently fixed with a migration. + allowedPrivilegesBits |= privilege.GetValidPrivilegesForObject(privilege.Database).ToBitField() + } + if objectType == privilege.Table || objectType == privilege.Database { + // Prior to 21_2, it was possible for a table or database to have USAGE + // privilege on it due to a bug when upgrading from 20.1 to 20.2. + // In 21.2 onwards, it should be permanently fixed with a migration. + allowedPrivilegesBits |= privilege.USAGE.Mask() + } + } + // For all non-super users, privileges must not exceed the allowed privileges. // Also the privileges must be valid on the object type. for _, u := range p.Users { @@ -529,6 +548,11 @@ func (p *PrivilegeDescriptor) SetOwner(owner security.SQLUsername) { p.OwnerProto = owner.EncodeProto() } +// SetVersion sets the version of the privilege descriptor. +func (p *PrivilegeDescriptor) SetVersion(version PrivilegeDescVersion) { + p.Version = version +} + // maybeGetSystemString is a helper function that returns "system" with a space // if the id provided is a system id. func maybeGetSystemString(id ID) redact.SafeString { diff --git a/pkg/sql/catalog/descpb/privilege_test.go b/pkg/sql/catalog/descpb/privilege_test.go index 2cfe477ed02a..0c24b55d5407 100644 --- a/pkg/sql/catalog/descpb/privilege_test.go +++ b/pkg/sql/catalog/descpb/privilege_test.go @@ -564,10 +564,7 @@ func TestFixPrivileges(t *testing.T) { desc.Grant(u, p) } - if a, e := MaybeFixPrivileges(testCase.id, &desc), testCase.modified; a != e { - t.Errorf("#%d: expected modified=%t, got modified=%t", num, e, a) - continue - } + MaybeFixPrivileges(testCase.id, testCase.id, &desc, privilege.Any) if a, e := len(desc.Users), len(testCase.output); a != e { t.Errorf("#%d: expected %d users (%v), got %d (%v)", num, e, testCase.output, a, desc.Users) @@ -970,7 +967,8 @@ func TestMaybeFixSchemaPrivileges(t *testing.T) { for u, p := range tc.input { desc.Grant(u, p) } - MaybeFixSchemaPrivileges(&desc) + testID := ID(keys.MaxReservedDescID + 1) + MaybeFixPrivileges(testID, testID, &desc, privilege.Schema) for u, p := range tc.output { outputUser, ok := desc.findUser(u) diff --git a/pkg/sql/catalog/descpb/privilegedescversion_string.go b/pkg/sql/catalog/descpb/privilegedescversion_string.go index 14cf68de7408..25b4896d3792 100644 --- a/pkg/sql/catalog/descpb/privilegedescversion_string.go +++ b/pkg/sql/catalog/descpb/privilegedescversion_string.go @@ -10,11 +10,12 @@ func _() { var x [1]struct{} _ = x[InitialVersion-0] _ = x[OwnerVersion-1] + _ = x[Version21_2-2] } -const _PrivilegeDescVersion_name = "InitialVersionOwnerVersion" +const _PrivilegeDescVersion_name = "InitialVersionOwnerVersionVersion21_2" -var _PrivilegeDescVersion_index = [...]uint8{0, 14, 26} +var _PrivilegeDescVersion_index = [...]uint8{0, 14, 26, 37} func (i PrivilegeDescVersion) String() string { if i >= PrivilegeDescVersion(len(_PrivilegeDescVersion_index)-1) { diff --git a/pkg/sql/catalog/descpb/structured.pb.go b/pkg/sql/catalog/descpb/structured.pb.go index a1c188832c25..89b4b63fc5a8 100644 --- a/pkg/sql/catalog/descpb/structured.pb.go +++ b/pkg/sql/catalog/descpb/structured.pb.go @@ -2141,6 +2141,8 @@ type TableDescriptor struct { // This means that all indexes implicitly inherit all partitioning // from the PARTITION ALL BY clause. PartitionAllBy bool `protobuf:"varint,44,opt,name=partition_all_by,json=partitionAllBy" json:"partition_all_by"` + // IsRepaired is set if the descriptor has been upgrade through fix_descriptor_migration. + IsRepaired bool `protobuf:"varint,47,opt,name=is_repaired,json=isRepaired" json:"is_repaired"` } func (m *TableDescriptor) Reset() { *m = TableDescriptor{} } @@ -2474,6 +2476,13 @@ func (m *TableDescriptor) GetPartitionAllBy() bool { return false } +func (m *TableDescriptor) GetIsRepaired() bool { + if m != nil { + return m.IsRepaired + } + return false +} + // The schema update lease. A single goroutine across a cockroach cluster // can own it, and will execute pending schema changes for this table. // Since the execution of a pending schema change is through transactions, @@ -3043,6 +3052,8 @@ type DatabaseDescriptor struct { OfflineReason string `protobuf:"bytes,9,opt,name=offline_reason,json=offlineReason" json:"offline_reason"` // RegionConfig is only set if multi-region controls are set on the database. RegionConfig *DatabaseDescriptor_RegionConfig `protobuf:"bytes,10,opt,name=region_config,json=regionConfig" json:"region_config,omitempty"` + // IsRepaired is set if the descriptor has been upgrade through fix_descriptor_migration. + IsRepaired bool `protobuf:"varint,11,opt,name=is_repaired,json=isRepaired" json:"is_repaired"` } func (m *DatabaseDescriptor) Reset() { *m = DatabaseDescriptor{} } @@ -3144,6 +3155,13 @@ func (m *DatabaseDescriptor) GetRegionConfig() *DatabaseDescriptor_RegionConfig return nil } +func (m *DatabaseDescriptor) GetIsRepaired() bool { + if m != nil { + return m.IsRepaired + } + return false +} + // SchemaInfo represents the state of a child user defined schema. type DatabaseDescriptor_SchemaInfo struct { // ID is the ID of the schema. @@ -3253,6 +3271,8 @@ type TypeDescriptor struct { // alias is the types.T that this descriptor is an alias for. Alias *types.T `protobuf:"bytes,7,opt,name=alias" json:"alias,omitempty"` RegionConfig *TypeDescriptor_RegionConfig `protobuf:"bytes,16,opt,name=region_config,json=regionConfig" json:"region_config,omitempty"` + // IsRepaired is set if the descriptor has been upgrade through fix_descriptor_migration. + IsRepaired bool `protobuf:"varint,17,opt,name=is_repaired,json=isRepaired" json:"is_repaired"` } func (m *TypeDescriptor) Reset() { *m = TypeDescriptor{} } @@ -3396,6 +3416,13 @@ func (m *TypeDescriptor) GetRegionConfig() *TypeDescriptor_RegionConfig { return nil } +func (m *TypeDescriptor) GetIsRepaired() bool { + if m != nil { + return m.IsRepaired + } + return false +} + // EnumMember represents a value in an enum. type TypeDescriptor_EnumMember struct { PhysicalRepresentation []byte `protobuf:"bytes,1,opt,name=physical_representation,json=physicalRepresentation" json:"physical_representation,omitempty"` @@ -3486,6 +3513,8 @@ type SchemaDescriptor struct { ParentID ID `protobuf:"varint,1,opt,name=parent_id,json=parentId,casttype=ID" json:"parent_id"` // privileges contains the privileges for the schema. Privileges *PrivilegeDescriptor `protobuf:"bytes,4,opt,name=privileges" json:"privileges,omitempty"` + // IsRepaired is set if the descriptor has been upgrade through fix_descriptor_migration. + IsRepaired bool `protobuf:"varint,10,opt,name=is_repaired,json=isRepaired" json:"is_repaired"` } func (m *SchemaDescriptor) Reset() { *m = SchemaDescriptor{} } @@ -3580,6 +3609,13 @@ func (m *SchemaDescriptor) GetPrivileges() *PrivilegeDescriptor { return nil } +func (m *SchemaDescriptor) GetIsRepaired() bool { + if m != nil { + return m.IsRepaired + } + return false +} + // Descriptor is a union type for descriptors for tables, schemas, databases, // and types. type Descriptor struct { @@ -3754,346 +3790,348 @@ func init() { } var fileDescriptor_12dcc21c3bcc9571 = []byte{ - // 5421 bytes of a gzipped FileDescriptorProto + // 5454 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x7c, 0xdd, 0x6f, 0x23, 0xd7, 0x75, 0xb8, 0xf8, 0x4d, 0x1e, 0x7e, 0x8d, 0xee, 0x6a, 0x77, 0x69, 0x65, 0x2d, 0x69, 0xb9, 0x5e, - 0x5b, 0x5e, 0xc7, 0xda, 0xb5, 0xec, 0x24, 0x6b, 0x3b, 0xc9, 0xcf, 0xa4, 0x48, 0xad, 0xb8, 0x2b, - 0x91, 0xeb, 0x11, 0xb5, 0xeb, 0x24, 0xbf, 0x66, 0x32, 0xe2, 0x5c, 0x52, 0x63, 0x0d, 0x67, 0xe8, - 0x99, 0xe1, 0x6a, 0x19, 0xf4, 0xa1, 0xc8, 0x53, 0x9f, 0xda, 0x3e, 0xf4, 0xad, 0x08, 0x1a, 0x14, - 0x01, 0x9a, 0xb7, 0x20, 0x28, 0xd0, 0x02, 0x2d, 0xd0, 0xd7, 0xe6, 0x31, 0x45, 0x80, 0x20, 0x4f, - 0x42, 0xab, 0x3c, 0xb4, 0x7f, 0x40, 0x9f, 0xfc, 0x54, 0xdc, 0xaf, 0xf9, 0xe0, 0x87, 0x4c, 0x49, - 0xdb, 0x3c, 0xd8, 0xd0, 0x9c, 0x7b, 0xce, 0xb9, 0xe7, 0xde, 0x7b, 0xbe, 0xef, 0xe5, 0xc2, 0x1d, - 0xe7, 0x0b, 0xe3, 0x7e, 0x47, 0x75, 0x55, 0xc3, 0xea, 0xdd, 0xd7, 0xb0, 0xd3, 0x19, 0x1c, 0xde, - 0x77, 0x5c, 0x7b, 0xd8, 0x71, 0x87, 0x36, 0xd6, 0x36, 0x06, 0xb6, 0xe5, 0x5a, 0xe8, 0x7a, 0xc7, - 0xea, 0x1c, 0xdb, 0x96, 0xda, 0x39, 0xda, 0x70, 0xbe, 0x30, 0xc8, 0x7f, 0x87, 0xaa, 0x83, 0x97, - 0x4b, 0x43, 0x57, 0x37, 0xee, 0x1f, 0x19, 0x9d, 0xfb, 0xae, 0xde, 0xc7, 0x8e, 0xab, 0xf6, 0x07, - 0x8c, 0x60, 0xb9, 0x3c, 0x85, 0xeb, 0xc0, 0xd6, 0x5f, 0xe8, 0x06, 0xee, 0x61, 0x8e, 0x73, 0x9d, - 0xe0, 0xb8, 0xa3, 0x01, 0x76, 0xd8, 0xff, 0x39, 0xf8, 0xb5, 0x1e, 0xb6, 0xee, 0xf7, 0xb0, 0xa5, - 0x9b, 0x1a, 0x7e, 0x79, 0xbf, 0x63, 0x99, 0x5d, 0xbd, 0xc7, 0x87, 0x96, 0x7a, 0x56, 0xcf, 0xa2, - 0x7f, 0xde, 0x27, 0x7f, 0x31, 0x68, 0xf9, 0x27, 0x09, 0xb8, 0xb6, 0x6d, 0xd9, 0x58, 0xef, 0x99, - 0x4f, 0xf0, 0x48, 0xc6, 0x5d, 0x6c, 0x63, 0xb3, 0x83, 0xd1, 0x1a, 0x24, 0x5c, 0xf5, 0xd0, 0xc0, - 0xa5, 0xc8, 0x5a, 0x64, 0x3d, 0x5f, 0x85, 0x5f, 0x9f, 0xae, 0x2e, 0x7c, 0x79, 0xba, 0x1a, 0x6d, - 0xd4, 0x64, 0x36, 0x80, 0xee, 0x42, 0x82, 0xce, 0x52, 0x8a, 0x52, 0x8c, 0x22, 0xc7, 0x48, 0x35, - 0x08, 0x90, 0xa0, 0xd1, 0x51, 0x54, 0x82, 0xb8, 0xa9, 0xf6, 0x71, 0x29, 0xb6, 0x16, 0x59, 0xcf, - 0x54, 0xe3, 0x04, 0x4b, 0xa6, 0x10, 0xf4, 0x04, 0xd2, 0x2f, 0x54, 0x43, 0xd7, 0x74, 0x77, 0x54, - 0x8a, 0xaf, 0x45, 0xd6, 0x0b, 0x9b, 0x6f, 0x6f, 0x4c, 0xdd, 0xaa, 0x8d, 0x2d, 0xcb, 0x74, 0x5c, - 0x5b, 0xd5, 0x4d, 0xf7, 0x19, 0x27, 0xe0, 0x8c, 0x3c, 0x06, 0xe8, 0x01, 0x2c, 0x3a, 0x47, 0xaa, - 0x8d, 0x35, 0x65, 0x60, 0xe3, 0xae, 0xfe, 0x52, 0x31, 0xb0, 0x59, 0x4a, 0xac, 0x45, 0xd6, 0x13, - 0x1c, 0xb5, 0xc8, 0x86, 0x9f, 0xd2, 0xd1, 0x5d, 0x6c, 0xa2, 0x36, 0x64, 0x2c, 0x53, 0xd1, 0xb0, - 0x81, 0x5d, 0x5c, 0x4a, 0xd2, 0xf9, 0xdf, 0x9b, 0x31, 0xff, 0x94, 0x0d, 0xda, 0xa8, 0x74, 0x5c, - 0xdd, 0x32, 0x85, 0x1c, 0x96, 0x59, 0xa3, 0x8c, 0x38, 0xd7, 0xe1, 0x40, 0x53, 0x5d, 0x5c, 0x4a, - 0x5d, 0x99, 0xeb, 0x01, 0x65, 0x84, 0x76, 0x21, 0xd1, 0x57, 0xdd, 0xce, 0x51, 0x29, 0x4d, 0x39, - 0x3e, 0xb8, 0x00, 0xc7, 0x3d, 0x42, 0xc7, 0x19, 0x32, 0x26, 0xe5, 0xe7, 0x90, 0x64, 0xf3, 0xa0, - 0x3c, 0x64, 0x9a, 0x2d, 0xa5, 0xb2, 0xd5, 0x6e, 0xb4, 0x9a, 0xd2, 0x02, 0xca, 0x41, 0x5a, 0xae, - 0xef, 0xb7, 0xe5, 0xc6, 0x56, 0x5b, 0x8a, 0x90, 0xaf, 0xfd, 0x7a, 0x5b, 0x69, 0x1e, 0xec, 0xee, - 0x4a, 0x51, 0x54, 0x84, 0x2c, 0xf9, 0xaa, 0xd5, 0xb7, 0x2b, 0x07, 0xbb, 0x6d, 0x29, 0x86, 0xb2, - 0x90, 0xda, 0xaa, 0xec, 0x6f, 0x55, 0x6a, 0x75, 0x29, 0xbe, 0x1c, 0xff, 0xc5, 0xcf, 0x57, 0x16, - 0xca, 0x0f, 0x20, 0x41, 0xa7, 0x43, 0x00, 0xc9, 0xfd, 0xc6, 0xde, 0xd3, 0xdd, 0xba, 0xb4, 0x80, - 0xd2, 0x10, 0xdf, 0x26, 0x2c, 0x22, 0x84, 0xe2, 0x69, 0x45, 0x6e, 0x37, 0x2a, 0xbb, 0x52, 0x94, - 0x51, 0x7c, 0x14, 0xff, 0xef, 0x9f, 0xad, 0x46, 0xca, 0xff, 0x9e, 0x80, 0x25, 0x5f, 0x76, 0xff, - 0xb4, 0xd1, 0x16, 0x14, 0x2d, 0x5b, 0xef, 0xe9, 0xa6, 0x42, 0x75, 0x4e, 0xd1, 0x35, 0xae, 0x8f, - 0x5f, 0x23, 0xeb, 0x39, 0x3b, 0x5d, 0xcd, 0xb7, 0xe8, 0x70, 0x9b, 0x8c, 0x36, 0x6a, 0x5c, 0x41, - 0xf3, 0x56, 0x00, 0xa8, 0xa1, 0x27, 0xb0, 0xc8, 0x99, 0x74, 0x2c, 0x63, 0xd8, 0x37, 0x15, 0x5d, - 0x73, 0x4a, 0xd1, 0xb5, 0xd8, 0x7a, 0xbe, 0xba, 0x7a, 0x76, 0xba, 0x5a, 0x64, 0x2c, 0xb6, 0xe8, - 0x58, 0xa3, 0xe6, 0x7c, 0x79, 0xba, 0x9a, 0x16, 0x1f, 0x32, 0x9f, 0x9e, 0x7f, 0x6b, 0x0e, 0x7a, - 0x0e, 0xd7, 0x6d, 0xb1, 0xb7, 0x5a, 0x90, 0x61, 0x8c, 0x32, 0xbc, 0x73, 0x76, 0xba, 0x7a, 0xcd, - 0xdb, 0x7c, 0x6d, 0x3a, 0xd3, 0x6b, 0xf6, 0x38, 0x82, 0xe6, 0xa0, 0x16, 0x04, 0xc0, 0xfe, 0x72, - 0xe3, 0x74, 0xb9, 0xab, 0x7c, 0xb9, 0x8b, 0x3e, 0xeb, 0xf0, 0x92, 0x17, 0xed, 0xb1, 0x01, 0xcd, - 0x33, 0xbc, 0xc4, 0xb9, 0x86, 0x97, 0xbc, 0xaa, 0xe1, 0x85, 0xcc, 0x28, 0xf5, 0x7f, 0x62, 0x46, - 0xe9, 0x57, 0x6e, 0x46, 0x99, 0x57, 0x60, 0x46, 0x4c, 0x77, 0x1f, 0xc7, 0xd3, 0x20, 0x65, 0x1f, - 0xc7, 0xd3, 0x59, 0x29, 0xf7, 0x38, 0x9e, 0xce, 0x49, 0xf9, 0xc7, 0xf1, 0x74, 0x5e, 0x2a, 0x94, - 0xff, 0x26, 0x0a, 0xb7, 0x0e, 0x4c, 0xfd, 0x8b, 0x21, 0x7e, 0xae, 0xbb, 0x47, 0xd6, 0xd0, 0xa5, - 0x7e, 0x31, 0xa0, 0xdb, 0x0f, 0x20, 0x3d, 0xa6, 0xd4, 0xd7, 0xf9, 0x29, 0xa7, 0xc2, 0x67, 0x9b, - 0x72, 0xf9, 0x89, 0x3e, 0x04, 0x98, 0xd0, 0xe0, 0xd7, 0xce, 0x4e, 0x57, 0x33, 0xd3, 0xd5, 0x2c, - 0xd3, 0xf1, 0x94, 0xeb, 0x8f, 0xe4, 0x84, 0xcb, 0x90, 0x19, 0xd8, 0x58, 0xd3, 0x3b, 0xe4, 0xd4, - 0x82, 0x7a, 0xe7, 0x83, 0xb9, 0xc5, 0xff, 0x4b, 0x02, 0x24, 0x26, 0x68, 0x0d, 0x3b, 0x1d, 0x5b, - 0x1f, 0xb8, 0x96, 0xed, 0x49, 0x19, 0x99, 0x90, 0xf2, 0x4d, 0x88, 0xea, 0x1a, 0x0f, 0x34, 0x37, - 0xf8, 0x2e, 0x45, 0xe9, 0x06, 0xf9, 0xcb, 0x8d, 0xea, 0x1a, 0xda, 0x80, 0x38, 0x89, 0x86, 0x74, - 0x9d, 0xd9, 0xcd, 0xe5, 0xf1, 0x95, 0xe0, 0xfe, 0x06, 0x0b, 0x96, 0x6d, 0x99, 0xe2, 0xa1, 0x35, - 0x48, 0x9b, 0x43, 0xc3, 0xa0, 0x81, 0x8e, 0xac, 0x3e, 0x2d, 0x96, 0x24, 0xa0, 0xe8, 0x36, 0xe4, - 0x34, 0xdc, 0x55, 0x87, 0x86, 0xab, 0xe0, 0x97, 0x03, 0x9b, 0xad, 0x4a, 0xce, 0x72, 0x58, 0xfd, - 0xe5, 0xc0, 0x46, 0xb7, 0x20, 0x79, 0xa4, 0x6b, 0x1a, 0x36, 0xa9, 0x31, 0x09, 0x16, 0x1c, 0x86, - 0xd6, 0x21, 0xa7, 0x9b, 0x6a, 0xa7, 0x83, 0x1d, 0x47, 0x27, 0xd3, 0x2c, 0x06, 0x70, 0x42, 0x23, - 0x68, 0x13, 0x16, 0x87, 0x0e, 0x76, 0x14, 0x07, 0x7f, 0x31, 0x24, 0x3a, 0x47, 0x4f, 0x19, 0xe8, - 0x29, 0x27, 0xb9, 0x2a, 0x14, 0x09, 0xc2, 0x3e, 0x1f, 0x27, 0x07, 0xbb, 0x09, 0x8b, 0xd6, 0x89, - 0x39, 0x46, 0x93, 0x0b, 0xd3, 0x10, 0x84, 0x20, 0xcd, 0x6d, 0xc8, 0x75, 0xac, 0xfe, 0x60, 0xe8, - 0x62, 0xb6, 0xa4, 0x2c, 0x5b, 0x12, 0x87, 0xd1, 0x25, 0xad, 0x40, 0xea, 0x85, 0x6e, 0xbb, 0x43, - 0xd5, 0x28, 0x49, 0x01, 0x79, 0x05, 0x10, 0x7d, 0x02, 0xd2, 0xa0, 0xa7, 0xa8, 0xae, 0x6b, 0xeb, - 0x87, 0x84, 0x8f, 0x39, 0xec, 0x97, 0xf2, 0xa1, 0xd3, 0x29, 0x3c, 0x7d, 0x54, 0x11, 0xc3, 0xcd, - 0x61, 0x5f, 0x2e, 0x0c, 0x7a, 0xc1, 0x6f, 0xb4, 0x0d, 0xaf, 0xab, 0x86, 0x8b, 0x6d, 0xe1, 0x42, - 0xc9, 0x71, 0x28, 0xba, 0xa9, 0x0c, 0x6c, 0xab, 0x67, 0x63, 0xc7, 0x29, 0x15, 0x02, 0xf3, 0xbe, - 0x46, 0x51, 0xd9, 0x49, 0xb7, 0x47, 0x03, 0xdc, 0x30, 0x9f, 0x72, 0x34, 0xf4, 0x03, 0x40, 0xce, - 0xc8, 0x71, 0x71, 0x5f, 0x30, 0x3a, 0xd6, 0x4d, 0xad, 0x54, 0xa4, 0x9a, 0xfc, 0xd6, 0x0c, 0x4d, - 0xde, 0xa7, 0x04, 0x8c, 0xdd, 0x13, 0xdd, 0xd4, 0xf8, 0x2c, 0x92, 0x33, 0x06, 0xf7, 0x2c, 0x3c, - 0x2d, 0x65, 0x1e, 0xc7, 0xd3, 0x19, 0x09, 0x1e, 0xc7, 0xd3, 0x29, 0x29, 0x5d, 0xfe, 0x8b, 0x28, - 0xdc, 0x60, 0x68, 0xdb, 0x6a, 0x5f, 0x37, 0x46, 0x57, 0xd5, 0x61, 0xc6, 0x85, 0xeb, 0x30, 0x3d, - 0x1e, 0xba, 0x14, 0x42, 0xc6, 0x02, 0x0b, 0x3d, 0x1e, 0x02, 0x6b, 0x12, 0xd0, 0x98, 0x23, 0x88, - 0x5f, 0xc0, 0x11, 0xb4, 0x60, 0x51, 0xa8, 0xb3, 0xc7, 0x81, 0xea, 0x74, 0xbe, 0x7a, 0x87, 0xcb, - 0x54, 0xac, 0x31, 0x04, 0x41, 0x1e, 0x8e, 0x87, 0x5a, 0x68, 0x90, 0x6f, 0x51, 0xf9, 0x9f, 0xa2, - 0xb0, 0xd4, 0x30, 0x5d, 0x6c, 0x1b, 0x58, 0x7d, 0x81, 0x03, 0xdb, 0xf1, 0x19, 0x64, 0x54, 0xb3, - 0x83, 0x1d, 0xd7, 0xb2, 0x9d, 0x52, 0x64, 0x2d, 0xb6, 0x9e, 0xdd, 0xfc, 0x60, 0xc6, 0xa9, 0x4c, - 0xa3, 0xdf, 0xa8, 0x70, 0x62, 0xe1, 0x47, 0x3c, 0x66, 0xcb, 0xff, 0x1a, 0x81, 0xb4, 0x18, 0xbd, - 0x84, 0x2f, 0xfd, 0x06, 0xa4, 0x69, 0x7e, 0xaa, 0x78, 0x67, 0xb2, 0x2c, 0x28, 0x78, 0x02, 0x1b, - 0xcc, 0x65, 0x53, 0x14, 0xb7, 0xa1, 0xa1, 0xad, 0x69, 0x69, 0x66, 0x8c, 0xd2, 0xdf, 0x14, 0xfb, - 0xb7, 0x1f, 0x4e, 0x34, 0x27, 0x32, 0x4f, 0xb6, 0x67, 0x7c, 0xe7, 0xfe, 0x31, 0x02, 0x8b, 0x84, - 0x40, 0xc3, 0x5a, 0x60, 0xdb, 0xee, 0x00, 0xe8, 0x8e, 0xe2, 0x30, 0x38, 0x5d, 0x91, 0x30, 0x85, - 0x8c, 0xee, 0x70, 0x74, 0x4f, 0xd5, 0xa2, 0x13, 0xaa, 0xf6, 0x21, 0xe4, 0x29, 0xad, 0x72, 0x38, - 0xec, 0x1c, 0x63, 0xd7, 0xa1, 0x12, 0x26, 0xaa, 0x4b, 0x5c, 0xc2, 0x1c, 0xe5, 0x50, 0x65, 0x63, - 0x72, 0xce, 0x09, 0x7c, 0x4d, 0x68, 0x5f, 0x7c, 0x42, 0xfb, 0xb8, 0xe0, 0xbf, 0x8c, 0xc3, 0x8d, - 0xa7, 0xaa, 0xed, 0xea, 0x24, 0xd2, 0xea, 0x66, 0x2f, 0x20, 0xfd, 0x5d, 0xc8, 0x9a, 0x43, 0x61, - 0x90, 0x0e, 0x3f, 0x10, 0x26, 0x1f, 0x98, 0x43, 0x6e, 0x60, 0x0e, 0xfa, 0x26, 0x2c, 0x11, 0x34, - 0xbd, 0x3f, 0x30, 0xf4, 0x8e, 0xee, 0x7a, 0xf8, 0xf1, 0x00, 0x3e, 0x32, 0x87, 0xfd, 0x06, 0x47, - 0x10, 0x74, 0xbb, 0x10, 0x37, 0x74, 0xc7, 0xa5, 0x01, 0x30, 0xbb, 0xb9, 0x39, 0x43, 0x9d, 0xa6, - 0xcb, 0xb6, 0xb1, 0xab, 0x3b, 0xae, 0xd8, 0x2b, 0xc2, 0x05, 0xb5, 0x20, 0x61, 0xab, 0x66, 0x0f, - 0x53, 0x3b, 0xcb, 0x6e, 0xbe, 0x7f, 0x31, 0x76, 0x32, 0x21, 0x15, 0x69, 0x01, 0xe5, 0xb3, 0xfc, - 0xd3, 0x08, 0xc4, 0xc9, 0x2c, 0xe7, 0xb8, 0x82, 0x1b, 0x90, 0x7c, 0xa1, 0x1a, 0x43, 0xcc, 0x82, - 0x78, 0x4e, 0xe6, 0x5f, 0xe8, 0x4f, 0xa0, 0xe8, 0x0c, 0x0f, 0x07, 0x81, 0xa9, 0x78, 0x24, 0x7b, - 0xf7, 0x42, 0x52, 0x79, 0x15, 0x4f, 0x98, 0x17, 0x3b, 0xb8, 0xe5, 0x2f, 0x20, 0x41, 0xa5, 0x3e, - 0x47, 0xbe, 0xbb, 0x50, 0xe8, 0xda, 0x56, 0x5f, 0xd1, 0xcd, 0x8e, 0x31, 0x74, 0xf4, 0x17, 0x2c, - 0xa0, 0xe6, 0xe4, 0x3c, 0x81, 0x36, 0x04, 0x90, 0xe8, 0x8a, 0x6b, 0x29, 0xf8, 0xa5, 0x40, 0x8a, - 0x52, 0xa4, 0xac, 0x6b, 0xd5, 0x05, 0x28, 0xa4, 0xea, 0xff, 0x9c, 0x83, 0x22, 0x35, 0xa8, 0xb9, - 0xdc, 0xe5, 0xdd, 0x80, 0xbb, 0xbc, 0x1e, 0x72, 0x97, 0x9e, 0x55, 0x12, 0x6f, 0x79, 0x0b, 0x92, - 0x43, 0x9a, 0x65, 0x51, 0x11, 0xbd, 0xe0, 0xcb, 0x60, 0xe8, 0x21, 0xa4, 0x5e, 0x60, 0xdb, 0xd1, - 0x2d, 0xb3, 0x84, 0x28, 0xa7, 0x15, 0x5e, 0xa5, 0xde, 0x18, 0x13, 0xe4, 0x19, 0xc3, 0x92, 0x05, - 0x3a, 0x5a, 0x07, 0xe9, 0x18, 0x8f, 0x94, 0x29, 0xb6, 0x50, 0x38, 0x26, 0x25, 0x8a, 0xef, 0x8c, - 0x35, 0xb8, 0x1e, 0xc0, 0xd4, 0x74, 0x1b, 0xd3, 0xe4, 0xd3, 0x29, 0xa5, 0xd7, 0x62, 0xe7, 0x24, - 0x99, 0x63, 0x02, 0x6c, 0xd4, 0x04, 0xa1, 0x7c, 0xcd, 0x9b, 0xc0, 0x83, 0x39, 0xe8, 0xeb, 0x80, - 0x88, 0xa7, 0xc3, 0x61, 0x89, 0x12, 0x54, 0x22, 0x89, 0x8e, 0x04, 0x65, 0xaa, 0x42, 0x21, 0x20, - 0x13, 0x09, 0x12, 0x49, 0x1a, 0x24, 0x6e, 0x11, 0xeb, 0x7f, 0x22, 0xd8, 0x8f, 0xc7, 0x89, 0x9c, - 0x37, 0x31, 0x09, 0x15, 0x07, 0x6c, 0x5d, 0xce, 0xb0, 0x4b, 0xfc, 0x5c, 0x80, 0x55, 0x8a, 0xb2, - 0x2a, 0x9f, 0x9d, 0xae, 0xa2, 0x27, 0x78, 0xb4, 0x4f, 0xc7, 0xa7, 0x33, 0x44, 0xc7, 0x63, 0xe3, - 0x9a, 0x83, 0x76, 0x40, 0x0a, 0x2d, 0x84, 0x70, 0x2c, 0x50, 0x8e, 0x2b, 0x24, 0x6d, 0xd8, 0xf7, - 0x97, 0x32, 0xce, 0xad, 0x10, 0x58, 0x26, 0xe1, 0xd4, 0x86, 0x25, 0x92, 0xb3, 0x58, 0x8e, 0xee, - 0x86, 0xb8, 0xe5, 0x7d, 0xf9, 0xb6, 0xc4, 0xf8, 0x0c, 0xf9, 0x3a, 0x63, 0xe3, 0x9a, 0x83, 0xf6, - 0x21, 0xdb, 0x65, 0xf9, 0xbf, 0x72, 0x8c, 0x47, 0xb4, 0x52, 0xc8, 0x6e, 0xde, 0x9b, 0xbf, 0x52, - 0xa8, 0x26, 0x89, 0x8a, 0x95, 0x22, 0x32, 0x74, 0xbd, 0x41, 0xf4, 0x1c, 0xf2, 0x81, 0xe2, 0xee, - 0x70, 0x44, 0xd3, 0xba, 0xcb, 0xb1, 0xcd, 0xf9, 0x8c, 0xaa, 0x23, 0xf4, 0x29, 0x80, 0xee, 0xc5, - 0x4d, 0x9a, 0xc9, 0x65, 0x37, 0xdf, 0xb9, 0x40, 0x80, 0x15, 0x6e, 0xd9, 0x67, 0x82, 0x9e, 0x43, - 0xc1, 0xff, 0xa2, 0xc2, 0xe6, 0x2e, 0x2c, 0x2c, 0xe3, 0x9a, 0x0f, 0xf0, 0xa9, 0x92, 0x4d, 0xc8, - 0x85, 0x5c, 0x5b, 0xf1, 0xf2, 0xae, 0x2d, 0xc4, 0x08, 0xd5, 0x79, 0xd6, 0x2f, 0xd1, 0xac, 0xef, - 0x9d, 0x39, 0x0d, 0x8e, 0x24, 0x92, 0xc2, 0xe3, 0xd0, 0x62, 0xe0, 0x7d, 0x40, 0x1d, 0x1b, 0xab, - 0x2e, 0xd6, 0x48, 0x5e, 0x4c, 0x43, 0x8e, 0x31, 0x0a, 0xe5, 0xeb, 0x8b, 0x7c, 0xbc, 0xee, 0x0d, - 0xa3, 0x1d, 0xc8, 0x63, 0xb3, 0x63, 0x69, 0xba, 0xd9, 0xa3, 0x39, 0x6c, 0xe9, 0x9a, 0x9f, 0x4c, - 0x7d, 0x79, 0xba, 0xfa, 0xb5, 0xb1, 0x59, 0xeb, 0x1c, 0x97, 0x4c, 0x2e, 0xe7, 0x70, 0xe0, 0x0b, - 0xed, 0x40, 0x4a, 0x04, 0xfc, 0x25, 0xba, 0x33, 0xeb, 0xb3, 0xd2, 0xd7, 0xf1, 0x74, 0x41, 0x64, - 0xe7, 0x9c, 0x9c, 0x54, 0x35, 0x9a, 0xee, 0x90, 0x44, 0x47, 0x2b, 0x5d, 0x0f, 0x56, 0x35, 0x02, - 0x8a, 0xb6, 0x00, 0x7a, 0xd8, 0x52, 0x58, 0x7f, 0xb0, 0x74, 0x83, 0x4e, 0xb7, 0x12, 0x98, 0xae, - 0x87, 0xad, 0x0d, 0xd1, 0x45, 0x24, 0x85, 0x5f, 0x57, 0xef, 0x89, 0xfc, 0xa3, 0x87, 0x2d, 0x06, - 0x08, 0x57, 0x7b, 0x37, 0xa7, 0x56, 0x7b, 0xe5, 0x15, 0xc8, 0x78, 0x4e, 0x0c, 0xa5, 0x20, 0x56, - 0xd9, 0xdf, 0x62, 0x2d, 0xa1, 0x5a, 0x7d, 0x7f, 0x4b, 0x8a, 0x94, 0x6f, 0x43, 0x9c, 0x2e, 0x3e, - 0x0b, 0xa9, 0xed, 0x96, 0xfc, 0xbc, 0x22, 0xd7, 0x58, 0x1b, 0xaa, 0xd1, 0x7c, 0x56, 0x97, 0xdb, - 0xf5, 0x9a, 0x24, 0x82, 0xc7, 0x69, 0x1c, 0x90, 0x5f, 0x81, 0xb6, 0x2d, 0x5e, 0xd1, 0xf7, 0xa0, - 0xd8, 0xf1, 0xa0, 0xec, 0x00, 0x22, 0x6b, 0xd1, 0xf5, 0xc2, 0xe6, 0xc3, 0xaf, 0xac, 0x62, 0x05, - 0x8f, 0x20, 0xc8, 0x57, 0x89, 0x42, 0x27, 0x04, 0x0d, 0x24, 0x5b, 0xd1, 0xb1, 0x40, 0x25, 0x43, - 0xa2, 0x73, 0x84, 0x3b, 0xc7, 0x3c, 0x54, 0x7f, 0x73, 0xc6, 0xc4, 0x34, 0x0f, 0x0d, 0xa8, 0xdf, - 0x16, 0xa1, 0xf1, 0xa7, 0x16, 0x39, 0x04, 0x65, 0x85, 0xe4, 0xb0, 0x13, 0x8a, 0x9f, 0x6b, 0xd7, - 0xd3, 0x3a, 0x67, 0xc2, 0xae, 0x03, 0x3e, 0xe8, 0x21, 0x14, 0x4d, 0xcb, 0x55, 0x48, 0x65, 0xcb, - 0xbd, 0x25, 0xad, 0x57, 0xf3, 0x55, 0x89, 0xeb, 0xaa, 0xef, 0x17, 0xf3, 0xa6, 0xe5, 0x36, 0x87, - 0x86, 0xc1, 0x00, 0xe8, 0xcf, 0x22, 0xb0, 0xca, 0x02, 0xaa, 0x72, 0xc2, 0x7a, 0x19, 0x0a, 0xcb, - 0x9d, 0xfd, 0x3d, 0xa2, 0x9d, 0x9f, 0xd9, 0xd9, 0xd3, 0x79, 0x8d, 0x10, 0x2e, 0xea, 0xad, 0xe1, - 0x39, 0x38, 0xe5, 0x36, 0x14, 0xc2, 0xc7, 0x84, 0x32, 0x90, 0xd8, 0xda, 0xa9, 0x6f, 0x3d, 0x91, - 0x16, 0x50, 0x11, 0xb2, 0xdb, 0x2d, 0xb9, 0xde, 0x78, 0xd4, 0x54, 0x9e, 0xd4, 0xbf, 0xc7, 0x3a, - 0x97, 0xcd, 0x96, 0xd7, 0xb9, 0x2c, 0xc1, 0xd2, 0x41, 0xb3, 0xf1, 0xe9, 0x41, 0x5d, 0x79, 0xde, - 0x68, 0xef, 0xb4, 0x0e, 0xda, 0x4a, 0xa3, 0x59, 0xab, 0x7f, 0x26, 0xc5, 0xbc, 0xfa, 0x2e, 0x21, - 0x25, 0xcb, 0xbf, 0x4d, 0x42, 0xe1, 0xa9, 0xad, 0xf7, 0x55, 0x7b, 0x44, 0xa2, 0xda, 0x89, 0x3a, - 0x40, 0x9f, 0xc0, 0x92, 0x65, 0x90, 0x4c, 0x9f, 0x42, 0x15, 0xaf, 0x5e, 0x88, 0x4f, 0x6f, 0x78, - 0x2f, 0x5a, 0x86, 0xc6, 0x39, 0x34, 0x78, 0xb9, 0xf0, 0x09, 0x2c, 0x99, 0xf8, 0x64, 0x92, 0x43, - 0x64, 0x06, 0x07, 0x13, 0x9f, 0x8c, 0x71, 0xf8, 0x3a, 0x64, 0x89, 0x0c, 0x94, 0x12, 0x8b, 0xa6, - 0x4f, 0x36, 0x48, 0x04, 0x96, 0xa1, 0x35, 0xd8, 0x30, 0xc1, 0x26, 0xf3, 0x09, 0xec, 0xd8, 0x14, - 0x6c, 0x13, 0x9f, 0x08, 0xec, 0x0f, 0xe1, 0xc6, 0xa4, 0x74, 0x13, 0x3d, 0xc3, 0x6b, 0x63, 0x42, - 0x91, 0x0c, 0x03, 0x7d, 0x0e, 0x4b, 0x86, 0xd5, 0x51, 0x0d, 0xdd, 0x1d, 0x71, 0x2f, 0xa2, 0x38, - 0x27, 0xea, 0x80, 0x6a, 0x54, 0x76, 0xa6, 0xf1, 0x85, 0xf7, 0x77, 0x63, 0x97, 0x73, 0x60, 0xfe, - 0x84, 0x80, 0x64, 0x64, 0x4c, 0xc0, 0x96, 0xff, 0x21, 0x06, 0x68, 0x12, 0x15, 0x1d, 0xc3, 0x35, - 0xb2, 0x33, 0x63, 0x62, 0xd0, 0xad, 0xcd, 0x6e, 0x7e, 0x63, 0x4e, 0x2b, 0x0c, 0xf3, 0x15, 0x6e, - 0xde, 0x32, 0xb4, 0xf0, 0x00, 0x99, 0x8c, 0x6c, 0xd5, 0xf8, 0x64, 0xd1, 0x57, 0x30, 0x99, 0x89, - 0x4f, 0xc6, 0x26, 0xd3, 0xe1, 0x75, 0x32, 0x99, 0x8d, 0x7b, 0xba, 0x65, 0xaa, 0x86, 0x72, 0x38, - 0x52, 0x6c, 0xeb, 0x24, 0x50, 0xb0, 0xb3, 0x82, 0x73, 0xfd, 0xec, 0x74, 0xb5, 0xd4, 0xc4, 0x27, - 0x32, 0xc7, 0xab, 0x8e, 0x64, 0xeb, 0x64, 0x6a, 0xd5, 0x5e, 0x32, 0xa7, 0x63, 0x69, 0x48, 0x86, - 0xb7, 0xce, 0x99, 0x2a, 0xd4, 0xf9, 0x8a, 0xd3, 0x36, 0xd1, 0xed, 0xe9, 0xac, 0x6a, 0x7e, 0x3f, - 0x2c, 0x94, 0xf3, 0xff, 0x32, 0x02, 0x34, 0x09, 0x1b, 0xba, 0xa2, 0xd7, 0x4d, 0xcf, 0xee, 0x03, - 0xc8, 0x93, 0x69, 0xfd, 0x15, 0x45, 0x66, 0x78, 0x22, 0xa2, 0xce, 0x9e, 0xb0, 0x1f, 0x40, 0x9e, - 0x9c, 0xb8, 0x4f, 0x15, 0x9d, 0x45, 0x65, 0x19, 0x5e, 0x67, 0x1d, 0xbd, 0x05, 0x39, 0xdd, 0x24, - 0x69, 0x3d, 0x6f, 0x77, 0x05, 0x7b, 0xa0, 0x59, 0x3e, 0xe2, 0xcb, 0x5d, 0xfe, 0x55, 0x14, 0x6e, - 0xee, 0xa9, 0x2e, 0xb6, 0x75, 0xd5, 0xd0, 0x7f, 0x8c, 0xb5, 0x67, 0x3a, 0x59, 0x70, 0xd7, 0xc6, - 0xce, 0x11, 0xfa, 0x0c, 0x16, 0x27, 0x0c, 0x86, 0x2b, 0xdc, 0x9b, 0xf3, 0x65, 0x1d, 0xa2, 0x34, - 0x1b, 0xb3, 0x29, 0xb4, 0x17, 0x36, 0x5c, 0x56, 0xda, 0x5e, 0x8c, 0x67, 0xd0, 0xb2, 0x1f, 0x42, - 0x42, 0x75, 0x14, 0xab, 0xcb, 0x63, 0xd2, 0xeb, 0x01, 0x46, 0x43, 0x57, 0x37, 0x36, 0x8e, 0x8c, - 0xce, 0x46, 0x5b, 0xdc, 0x3a, 0x8a, 0x68, 0xa6, 0x3a, 0xad, 0x2e, 0x7a, 0x17, 0x8a, 0xce, 0x91, - 0x35, 0x34, 0x34, 0xe5, 0x50, 0xed, 0x1c, 0x77, 0x75, 0xc3, 0x08, 0x35, 0x46, 0x0b, 0x6c, 0xb0, - 0xca, 0xc7, 0xf8, 0x9e, 0xfd, 0x65, 0x0a, 0x90, 0x2f, 0xcf, 0xde, 0xd0, 0x55, 0x69, 0xbc, 0xaf, - 0x40, 0x92, 0x07, 0x1a, 0xb6, 0x47, 0x6f, 0xcd, 0x8c, 0xc9, 0xe1, 0x46, 0xf0, 0xce, 0x82, 0xcc, - 0x09, 0xd1, 0x77, 0x83, 0x97, 0x8c, 0x73, 0xef, 0xc8, 0xce, 0x82, 0xb8, 0x7d, 0x7c, 0x02, 0x10, - 0x08, 0x52, 0x69, 0xca, 0xe4, 0xed, 0xb9, 0x53, 0x83, 0x9d, 0x05, 0x39, 0x40, 0x8e, 0x5a, 0x50, - 0x18, 0x84, 0x3c, 0x18, 0xaf, 0x0e, 0xee, 0xce, 0xe5, 0xee, 0x76, 0x16, 0xe4, 0x31, 0x72, 0xf4, - 0x03, 0x40, 0x9d, 0x09, 0xe3, 0x28, 0xc1, 0x57, 0x48, 0x39, 0x4e, 0xb0, 0xb3, 0x20, 0x4f, 0x61, - 0x83, 0x3e, 0x87, 0x9b, 0xfd, 0xe9, 0x7a, 0xcc, 0xeb, 0x84, 0x8d, 0x19, 0x33, 0xcc, 0xd0, 0xfe, - 0x9d, 0x05, 0x79, 0x16, 0x43, 0xf4, 0x04, 0x12, 0x8e, 0x4b, 0xd2, 0xc0, 0x18, 0x4d, 0xc1, 0xef, - 0xcf, 0xe0, 0x3c, 0xa9, 0x23, 0x1b, 0xfb, 0x84, 0x4c, 0x24, 0x3f, 0x94, 0x07, 0x7a, 0x0e, 0x19, - 0xaf, 0x8a, 0xe6, 0x77, 0x12, 0xef, 0xcf, 0xcf, 0xd0, 0x4b, 0x37, 0x45, 0x32, 0xea, 0xf1, 0x42, - 0x15, 0xc8, 0xf6, 0x39, 0x9a, 0xdf, 0xf6, 0x5c, 0xe3, 0xbd, 0x05, 0x10, 0x1c, 0xa8, 0xef, 0x0c, - 0x7c, 0xc9, 0x20, 0x88, 0x1a, 0x34, 0xb5, 0xb6, 0x2d, 0xc3, 0x20, 0xb6, 0x41, 0x53, 0x1e, 0x2f, - 0xb5, 0x16, 0xd0, 0xf2, 0x27, 0x90, 0xa0, 0x6b, 0x22, 0x29, 0xed, 0x41, 0xf3, 0x49, 0xb3, 0xf5, - 0xbc, 0xc9, 0x52, 0x94, 0x5a, 0x7d, 0xb7, 0xde, 0xae, 0x2b, 0xad, 0xe6, 0x2e, 0x49, 0x51, 0x5e, - 0x83, 0xeb, 0x1c, 0x50, 0x69, 0xd6, 0x94, 0xe7, 0x72, 0x43, 0x0c, 0x45, 0xcb, 0xeb, 0xc1, 0x9c, - 0x39, 0x0d, 0xf1, 0x66, 0xab, 0x59, 0x97, 0x16, 0x68, 0xf6, 0x5c, 0xab, 0x49, 0x11, 0x9a, 0x3d, - 0xcb, 0xad, 0xa7, 0x52, 0x94, 0x59, 0x5f, 0x35, 0x07, 0xa0, 0x79, 0xfb, 0xf0, 0x38, 0x9e, 0x4e, - 0x4a, 0xa9, 0xf2, 0xdf, 0x47, 0x20, 0x4d, 0x02, 0x75, 0xc3, 0xec, 0x5a, 0xe8, 0x7d, 0xc8, 0x0c, - 0x54, 0x1b, 0x9b, 0xae, 0xef, 0x69, 0x45, 0x03, 0x3a, 0xfd, 0x94, 0x0e, 0x78, 0xfd, 0xd1, 0x34, - 0x43, 0x6c, 0x68, 0x68, 0x1b, 0x24, 0x4e, 0xe4, 0x74, 0x8e, 0x70, 0x5f, 0xf5, 0xe3, 0xce, 0x2d, - 0xaf, 0xc5, 0x4f, 0xc7, 0xf7, 0xe9, 0xb0, 0xc7, 0xa1, 0x30, 0x08, 0x42, 0xcf, 0xe9, 0x52, 0x72, - 0xdf, 0xf1, 0xd7, 0x6f, 0x43, 0x71, 0x2c, 0x50, 0x9e, 0xd3, 0x15, 0x5a, 0xa3, 0x5d, 0xa1, 0x98, - 0xef, 0xf7, 0xbd, 0xae, 0x50, 0x94, 0x37, 0x84, 0xde, 0xf7, 0x5b, 0x3e, 0xec, 0x80, 0x5f, 0xe3, - 0xe1, 0x61, 0xf1, 0x9c, 0x6e, 0xcf, 0x53, 0x58, 0xec, 0x5b, 0x9a, 0xde, 0x25, 0x45, 0x0b, 0xd1, - 0x0e, 0x57, 0xef, 0x63, 0x9e, 0xd2, 0xce, 0xe5, 0x3b, 0xa5, 0x20, 0x35, 0x19, 0x44, 0xbb, 0x50, - 0xd0, 0x88, 0xd7, 0x20, 0x75, 0x21, 0xeb, 0xd5, 0x5c, 0xa7, 0x3e, 0x7d, 0x75, 0x86, 0x26, 0x8b, - 0xc3, 0x12, 0xa5, 0xb3, 0x20, 0x66, 0xfd, 0x9c, 0xd0, 0x09, 0xc6, 0xe7, 0x3c, 0xc1, 0x43, 0x58, - 0x1e, 0x9a, 0xf8, 0xe5, 0xc0, 0x72, 0xb0, 0xa6, 0x4c, 0x9c, 0xe5, 0x3a, 0xe5, 0x72, 0x97, 0x73, - 0xb9, 0x79, 0x20, 0x30, 0xa7, 0x1e, 0xea, 0xcd, 0xe1, 0xd4, 0x61, 0x0d, 0x3d, 0x82, 0x94, 0x68, - 0xdb, 0xa6, 0xe9, 0xfa, 0xe6, 0xf5, 0xf1, 0xa2, 0x66, 0xe5, 0xd4, 0x68, 0x1b, 0x0a, 0x26, 0x7e, - 0x19, 0xbc, 0x95, 0xc8, 0x84, 0xcc, 0x33, 0xd7, 0xc4, 0x2f, 0xa7, 0x5f, 0x49, 0xe4, 0x4c, 0x7f, - 0x44, 0x43, 0x2d, 0x48, 0x77, 0xd5, 0xbe, 0x6e, 0xe8, 0xd8, 0x29, 0xdd, 0xa0, 0x12, 0xbd, 0x7b, - 0xae, 0x44, 0xe3, 0x17, 0x38, 0xc2, 0x9e, 0x05, 0x13, 0x4f, 0x30, 0x0a, 0x18, 0x11, 0xc1, 0x6e, - 0x4e, 0x0a, 0x26, 0x2e, 0x70, 0x42, 0x97, 0x39, 0x54, 0x30, 0xfe, 0xa5, 0xa1, 0x4f, 0x21, 0x1f, - 0xce, 0x1b, 0xe0, 0x12, 0x79, 0x43, 0x6e, 0x10, 0x4c, 0x1a, 0xb6, 0x21, 0x25, 0x12, 0x86, 0xec, - 0x25, 0x12, 0x06, 0x41, 0x8c, 0xaa, 0x24, 0x1b, 0x7b, 0xe9, 0xfa, 0xe5, 0x49, 0xce, 0xef, 0x95, - 0x9e, 0x9d, 0xae, 0x66, 0xc9, 0x0a, 0xa7, 0x5c, 0x8a, 0x64, 0x4d, 0x0f, 0xae, 0xa1, 0xc7, 0x00, - 0xde, 0x13, 0x25, 0x87, 0xde, 0x05, 0xce, 0xee, 0x18, 0x3d, 0x15, 0x88, 0xbe, 0x48, 0x72, 0x80, - 0x1a, 0xed, 0x41, 0x46, 0xb8, 0x5c, 0xd6, 0x1b, 0x9c, 0x1d, 0x0d, 0x27, 0x03, 0x80, 0x70, 0xfb, - 0x1e, 0x07, 0x52, 0xa0, 0x1b, 0x58, 0x75, 0x30, 0x6f, 0x38, 0x3d, 0x9c, 0x33, 0x5b, 0x67, 0x3a, - 0xbe, 0x75, 0xa4, 0x9a, 0x3d, 0xbc, 0x4b, 0xe8, 0xab, 0xd1, 0x52, 0x44, 0x66, 0xac, 0x50, 0x13, - 0x24, 0xba, 0x65, 0xc1, 0x78, 0x22, 0xd1, 0x5d, 0x7b, 0x43, 0x78, 0x47, 0xb2, 0x6b, 0x33, 0x63, - 0x0a, 0xd5, 0xa9, 0x3d, 0x3f, 0xae, 0x7c, 0x1b, 0x0a, 0x5d, 0xcb, 0xee, 0xab, 0xae, 0x22, 0x9c, - 0xd7, 0xa2, 0xdf, 0xf9, 0xfe, 0xf2, 0x74, 0x35, 0xbf, 0x4d, 0x47, 0x85, 0xe3, 0xca, 0x77, 0x83, - 0x9f, 0xa8, 0x2a, 0xc2, 0xef, 0x35, 0x1a, 0x2d, 0xdf, 0xfc, 0xca, 0xcd, 0x9a, 0x12, 0x75, 0xdf, - 0x81, 0x82, 0xd5, 0xed, 0x1a, 0xba, 0x89, 0x15, 0x1b, 0xab, 0x8e, 0x65, 0x96, 0xde, 0x0c, 0x78, - 0xdf, 0x3c, 0x1f, 0x93, 0xe9, 0x10, 0x6a, 0x42, 0x92, 0x36, 0x2a, 0x9c, 0xd2, 0x12, 0x3d, 0x9e, - 0x4b, 0x36, 0x3d, 0x64, 0xce, 0x05, 0xdd, 0x01, 0x78, 0xa1, 0xe3, 0x13, 0xe5, 0x8b, 0x21, 0xb6, - 0x47, 0xa5, 0x52, 0xb0, 0x97, 0x44, 0xe0, 0x9f, 0x12, 0x30, 0xfa, 0x26, 0x2c, 0xe9, 0x8e, 0x12, - 0x4c, 0x41, 0x14, 0x32, 0x58, 0x7a, 0x3b, 0x10, 0x87, 0x91, 0xee, 0x8c, 0xa7, 0x2f, 0xe8, 0x3d, - 0xc8, 0x68, 0x78, 0x80, 0x4d, 0xcd, 0x69, 0x99, 0xa5, 0xd7, 0x68, 0x49, 0x7c, 0xed, 0xec, 0x74, - 0x35, 0x53, 0x13, 0x40, 0xee, 0xe4, 0x7c, 0x2c, 0xf4, 0x09, 0x14, 0xbc, 0x8f, 0xf6, 0x68, 0x80, - 0x9d, 0xd2, 0xbb, 0x94, 0xae, 0x44, 0x0e, 0xb6, 0x16, 0x1a, 0x11, 0x61, 0x2f, 0x8c, 0x8f, 0x3e, - 0x87, 0x1c, 0x83, 0x60, 0xad, 0x65, 0x56, 0x47, 0xa5, 0x65, 0xba, 0x4f, 0x0f, 0xe6, 0xdc, 0x27, - 0xbf, 0x93, 0xea, 0xdd, 0xd9, 0xd5, 0x02, 0xdc, 0xe4, 0x10, 0x6f, 0xf4, 0xff, 0x21, 0x27, 0xf4, - 0xf0, 0xb1, 0x75, 0xe8, 0x94, 0xbe, 0x76, 0xee, 0xc5, 0xd8, 0xf8, 0x5c, 0x7b, 0x3e, 0xa9, 0xf0, - 0x32, 0x41, 0x6e, 0xa8, 0x0d, 0xa4, 0x7c, 0x14, 0x91, 0xa3, 0x43, 0xed, 0x41, 0xf9, 0xdc, 0x3a, - 0x24, 0x2a, 0xbf, 0xb1, 0x16, 0x59, 0x8f, 0x79, 0x09, 0xc1, 0x52, 0x13, 0x9f, 0x04, 0xad, 0xe6, - 0xb1, 0x75, 0xd8, 0xa8, 0xc9, 0x4b, 0xe6, 0x24, 0x54, 0x43, 0x9f, 0x41, 0xde, 0x7b, 0xb3, 0x60, - 0x0d, 0x5c, 0xa7, 0x74, 0xeb, 0xdc, 0x06, 0xd2, 0x84, 0x71, 0x72, 0xda, 0xd6, 0x80, 0xde, 0x60, - 0x06, 0xbe, 0xd0, 0x6d, 0xc8, 0x68, 0xb6, 0x35, 0x60, 0x31, 0xfc, 0x75, 0x2a, 0xa0, 0x68, 0x7f, - 0xda, 0xd6, 0x80, 0x06, 0x67, 0x05, 0x0a, 0x36, 0x1e, 0x18, 0x6a, 0x07, 0xf7, 0x49, 0x50, 0xb4, - 0xba, 0xa5, 0x15, 0x3a, 0xfb, 0xe6, 0xdc, 0xc7, 0xe3, 0x11, 0x0b, 0xfb, 0x08, 0xf0, 0x6b, 0x75, - 0xd1, 0x01, 0x80, 0x3a, 0xd4, 0x74, 0x57, 0xe9, 0x5b, 0x1a, 0x2e, 0xad, 0x9e, 0xfb, 0xda, 0x68, - 0x9c, 0x79, 0x85, 0x10, 0xee, 0x59, 0x1a, 0xf6, 0xee, 0xbc, 0x05, 0x00, 0xbd, 0x07, 0x59, 0xba, - 0x34, 0xbe, 0xfb, 0x6b, 0x74, 0x71, 0x8b, 0x7c, 0xf7, 0x33, 0x35, 0xdb, 0x1a, 0xb0, 0x2d, 0xa7, - 0x1b, 0xc0, 0xf6, 0xd9, 0x81, 0x5c, 0xaf, 0xa3, 0xf8, 0xee, 0xf4, 0x36, 0xd5, 0x8d, 0x8f, 0xe7, - 0x94, 0xe5, 0xd1, 0xd6, 0x14, 0x07, 0x7b, 0x4d, 0xc4, 0x85, 0x47, 0x5b, 0x02, 0xe6, 0xc8, 0xd9, - 0x5e, 0xc7, 0xfb, 0x20, 0x25, 0x37, 0xeb, 0x94, 0x73, 0x83, 0x2e, 0x07, 0x4b, 0x6e, 0x36, 0xc2, - 0x4c, 0xba, 0x09, 0xbc, 0xa5, 0xae, 0xd0, 0x72, 0x95, 0x9d, 0xd9, 0x9d, 0xf9, 0xf3, 0xae, 0x02, - 0xa3, 0xae, 0x38, 0xad, 0x2e, 0x3d, 0xd8, 0x0e, 0xe4, 0xac, 0xa1, 0x7b, 0x68, 0x0d, 0x4d, 0x4d, - 0xe9, 0x1e, 0x3b, 0xa5, 0x37, 0xe8, 0x6a, 0x2f, 0xd4, 0x38, 0xf5, 0x56, 0xd7, 0xe2, 0x8c, 0xb6, - 0x9f, 0x38, 0x72, 0x56, 0x70, 0xdd, 0x3e, 0x76, 0xd0, 0x8f, 0x20, 0xab, 0x9b, 0xfe, 0x1c, 0x77, - 0x2f, 0x3e, 0x07, 0x12, 0x35, 0x47, 0xc3, 0xf4, 0xa6, 0x00, 0xce, 0x93, 0xcc, 0xf0, 0x93, 0x08, - 0xac, 0x7d, 0x45, 0xc3, 0xd5, 0x29, 0xbd, 0x73, 0xee, 0x7d, 0xf5, 0x1c, 0x1d, 0xd7, 0xd7, 0xcf, - 0xeb, 0xb8, 0x3a, 0xa8, 0x0c, 0x19, 0x17, 0xf7, 0x07, 0x96, 0xad, 0xda, 0xa3, 0xd2, 0x5b, 0xc1, - 0x27, 0x08, 0x1e, 0x18, 0xfd, 0x10, 0x8a, 0xe3, 0x2d, 0xb1, 0x7b, 0x57, 0x68, 0x89, 0xc9, 0x85, - 0x70, 0xfb, 0x0f, 0x6d, 0xd0, 0x22, 0x84, 0xdd, 0xf4, 0x28, 0xaa, 0x61, 0x28, 0x87, 0xa3, 0xd2, - 0xd7, 0x83, 0xed, 0x08, 0x6f, 0xb4, 0x62, 0x18, 0xd5, 0xd1, 0xf2, 0x2f, 0x22, 0xb0, 0x38, 0x11, - 0xb7, 0xd1, 0x0f, 0x21, 0x65, 0x5a, 0x5a, 0xe0, 0x71, 0x48, 0x9d, 0xef, 0x7f, 0xb2, 0x69, 0x69, - 0xec, 0x6d, 0xc8, 0xfb, 0x3d, 0xdd, 0x3d, 0x1a, 0x1e, 0x6e, 0x74, 0xac, 0xfe, 0x7d, 0x4f, 0x72, - 0xed, 0xd0, 0xff, 0xfb, 0xfe, 0xe0, 0xb8, 0x77, 0x9f, 0xfe, 0x35, 0x38, 0xdc, 0x60, 0x64, 0x72, - 0x92, 0x70, 0x6d, 0x68, 0xe8, 0x5d, 0x28, 0xe2, 0x97, 0x03, 0xdd, 0x0e, 0xd4, 0x0e, 0xd1, 0x80, - 0xdf, 0x29, 0xf8, 0x83, 0x44, 0x49, 0xf9, 0x35, 0xfc, 0xaf, 0xa2, 0x50, 0x1c, 0x0b, 0x87, 0xa4, - 0xee, 0xa1, 0x2d, 0xaa, 0x50, 0xdd, 0x43, 0x20, 0xe7, 0xbc, 0xf5, 0x08, 0x3e, 0xe0, 0x8b, 0x5d, - 0xf5, 0x01, 0x5f, 0xf8, 0x61, 0x51, 0xe2, 0x02, 0x0f, 0x8b, 0x3e, 0x84, 0x1b, 0xba, 0xa3, 0x98, - 0x96, 0x29, 0x2e, 0x18, 0xbc, 0xa6, 0x4b, 0xf0, 0x51, 0xdc, 0x35, 0xdd, 0x69, 0x5a, 0x26, 0xbb, - 0x5a, 0xf0, 0x56, 0xed, 0xbf, 0x9f, 0x4b, 0x4d, 0xbe, 0x9f, 0xf3, 0x7a, 0xf4, 0x71, 0x29, 0xb1, - 0xfc, 0x6f, 0x11, 0xc8, 0x04, 0x9f, 0xa8, 0x47, 0xc3, 0x9d, 0xc3, 0x89, 0x5a, 0xf0, 0x92, 0x8f, - 0x7c, 0xc2, 0xbb, 0x10, 0xbb, 0xc0, 0x2e, 0xdc, 0x86, 0xc4, 0xe1, 0x48, 0xd4, 0x68, 0xe9, 0x6a, - 0x8e, 0xcf, 0x16, 0xaf, 0x92, 0x7a, 0x20, 0x7e, 0x38, 0x12, 0x0f, 0xa6, 0x96, 0xff, 0x14, 0xb2, - 0x81, 0xb8, 0x3b, 0xde, 0x99, 0x88, 0x5c, 0xa2, 0x33, 0xf1, 0x06, 0x24, 0x79, 0x58, 0x60, 0xba, - 0x97, 0xe7, 0xd4, 0x09, 0x16, 0x12, 0x12, 0x9f, 0x93, 0x70, 0xc0, 0x67, 0xff, 0x9f, 0x18, 0xe4, - 0x82, 0x11, 0x94, 0xd8, 0xba, 0x6e, 0x76, 0x6c, 0x1a, 0xbe, 0xe8, 0xec, 0x31, 0xef, 0xb9, 0x91, - 0x00, 0x93, 0xb8, 0xda, 0xd7, 0x4d, 0x85, 0x3e, 0x55, 0x09, 0xe9, 0x77, 0xba, 0xaf, 0x9b, 0xcf, - 0x08, 0x94, 0xa2, 0xa8, 0x2f, 0x39, 0x4a, 0x2c, 0x84, 0xa2, 0xbe, 0x64, 0x28, 0xcb, 0x34, 0x55, - 0xb5, 0x5d, 0xba, 0x43, 0xb1, 0x40, 0x0a, 0x6a, 0xbb, 0xc1, 0x57, 0x87, 0x89, 0x69, 0xaf, 0x0e, - 0x4d, 0x28, 0xf8, 0x39, 0xc3, 0x89, 0x89, 0x6d, 0x7e, 0xdd, 0x50, 0xb9, 0x44, 0xd2, 0xe0, 0x7f, - 0x10, 0x46, 0x22, 0x8a, 0x3b, 0x41, 0x20, 0xc9, 0x4a, 0x3b, 0x6a, 0xe7, 0x08, 0x2b, 0x8e, 0xfe, - 0x63, 0xd6, 0x0e, 0xf0, 0xb6, 0x85, 0xc2, 0xf7, 0xf5, 0x1f, 0xe3, 0xe5, 0xbf, 0x8b, 0x40, 0x3e, - 0xc4, 0x0b, 0x35, 0xa0, 0x48, 0xa5, 0x9b, 0x68, 0x6f, 0xdf, 0xf6, 0x1e, 0xad, 0x93, 0xe1, 0xa9, - 0xc5, 0x6c, 0xde, 0x0a, 0x0c, 0x69, 0x24, 0x0f, 0x65, 0xac, 0xbc, 0xd7, 0x6d, 0x61, 0x35, 0xce, - 0x51, 0x4e, 0xe1, 0x27, 0x6e, 0x39, 0xcb, 0x87, 0x69, 0xc1, 0x66, 0xfc, 0xb2, 0x09, 0xd9, 0x40, - 0xe6, 0x32, 0x87, 0xfd, 0x7c, 0x0b, 0xe2, 0x9e, 0x37, 0x9b, 0xb7, 0x8b, 0xec, 0xfa, 0x2e, 0xee, - 0x67, 0x11, 0x58, 0x9a, 0x96, 0x41, 0x84, 0xec, 0x92, 0x69, 0xdb, 0x5c, 0x76, 0x79, 0x27, 0x98, - 0xd9, 0x31, 0x0d, 0x14, 0xaf, 0x22, 0xfc, 0xdc, 0xee, 0x4d, 0xcf, 0x0e, 0x98, 0x02, 0x16, 0x43, - 0x76, 0x40, 0x2a, 0xb8, 0xa0, 0x25, 0xfc, 0x2e, 0x06, 0x85, 0xb1, 0xdb, 0x97, 0x67, 0x90, 0xec, - 0x19, 0xd6, 0xa1, 0x6a, 0xf0, 0xae, 0xf5, 0xb7, 0x2f, 0x15, 0xca, 0x36, 0x1e, 0x51, 0x1e, 0x3b, - 0x0b, 0x32, 0xe7, 0x86, 0x1c, 0x58, 0x0c, 0x5e, 0xb3, 0xb0, 0x5f, 0xd7, 0xb0, 0x9d, 0xad, 0x5f, - 0x6e, 0x0a, 0xff, 0x1e, 0x86, 0x22, 0xee, 0x2c, 0xc8, 0x45, 0x3b, 0x0c, 0x42, 0x7d, 0x28, 0x8e, - 0xdd, 0xed, 0xf0, 0x2b, 0x81, 0xad, 0xab, 0x4e, 0x29, 0x5b, 0x27, 0x3b, 0x34, 0xef, 0x0d, 0x00, - 0x96, 0xff, 0x1f, 0x14, 0xc7, 0x84, 0x22, 0xe7, 0xc1, 0x70, 0x78, 0x54, 0x2b, 0x10, 0x1f, 0xc6, - 0x90, 0x9a, 0x6a, 0x1f, 0xcb, 0x7c, 0x94, 0x9f, 0xc7, 0x5d, 0xc8, 0x87, 0xa6, 0x40, 0x05, 0x88, - 0xaa, 0xec, 0x09, 0x61, 0x46, 0x8e, 0xaa, 0xfc, 0xf1, 0xe1, 0x72, 0x01, 0x92, 0x6c, 0x7f, 0x83, - 0xfa, 0x5d, 0x05, 0x48, 0x8b, 0xfc, 0xa1, 0xbc, 0x0e, 0x19, 0x2f, 0x91, 0x46, 0x39, 0x48, 0xd7, - 0x1a, 0xfb, 0x95, 0xea, 0x6e, 0xbd, 0x26, 0x2d, 0xa0, 0x3c, 0x64, 0xe4, 0x7a, 0xa5, 0x46, 0x7b, - 0xae, 0x52, 0xe4, 0xa3, 0xf4, 0x9f, 0xff, 0x6c, 0x35, 0xc2, 0x83, 0x4c, 0x52, 0x4a, 0x3d, 0x8e, - 0xa7, 0x91, 0x74, 0xad, 0xfc, 0xdb, 0x34, 0xa0, 0x9a, 0xea, 0xaa, 0x64, 0x53, 0x2e, 0xd0, 0x99, - 0x8c, 0x9e, 0x63, 0x4d, 0x53, 0x9b, 0x8c, 0xf1, 0xab, 0x34, 0x19, 0x2f, 0xd5, 0xeb, 0x9c, 0xec, - 0x4c, 0x26, 0xaf, 0xd0, 0x99, 0x0c, 0xf7, 0x7d, 0x62, 0x57, 0xea, 0xfb, 0x3c, 0x83, 0x14, 0xab, - 0x32, 0xd9, 0x1b, 0xb3, 0xd9, 0x6d, 0x85, 0xc9, 0x83, 0xe1, 0xdd, 0x1a, 0xa7, 0x6e, 0xba, 0xf6, - 0xc8, 0x7b, 0x0f, 0xc3, 0x60, 0x7e, 0x7b, 0x24, 0xfd, 0x2a, 0xdb, 0x23, 0x99, 0xd9, 0xed, 0x91, - 0x1f, 0x00, 0xb7, 0x0b, 0x91, 0x14, 0xc3, 0xb9, 0x4f, 0x43, 0xa6, 0x2c, 0x87, 0x19, 0x01, 0xcf, - 0x8a, 0x73, 0x76, 0xe0, 0x6b, 0xb9, 0x0d, 0xc0, 0xdb, 0xaf, 0x66, 0xd7, 0x9a, 0xc3, 0x89, 0xaf, - 0x40, 0x8a, 0x38, 0xc7, 0x01, 0x66, 0xda, 0xe9, 0x45, 0x55, 0x0e, 0xe4, 0x16, 0x35, 0x80, 0x5c, - 0x70, 0x0b, 0x91, 0x04, 0xb1, 0x63, 0x3c, 0xe2, 0x86, 0x47, 0xfe, 0x44, 0x8f, 0x21, 0xe1, 0xc7, - 0xfe, 0xd9, 0xcf, 0xb8, 0x67, 0x9e, 0x0d, 0x11, 0x57, 0x66, 0x2c, 0x3e, 0x8a, 0x3e, 0x8c, 0x2c, - 0xff, 0x57, 0x04, 0x72, 0xc1, 0x65, 0xa2, 0x26, 0xe4, 0x9d, 0xa1, 0xfd, 0x42, 0x7f, 0xa1, 0x1a, - 0x4a, 0xcf, 0x52, 0x0d, 0x3a, 0x51, 0x61, 0xf3, 0xce, 0xac, 0x67, 0x50, 0x1c, 0xf7, 0x91, 0xa5, - 0x1a, 0xa2, 0x71, 0xe1, 0x04, 0x60, 0xe8, 0x43, 0xef, 0xba, 0x8e, 0xdf, 0x6f, 0xf3, 0xab, 0x5f, - 0xc4, 0x8d, 0x24, 0xe8, 0x85, 0x44, 0x6f, 0x96, 0x81, 0x48, 0xdc, 0xe5, 0x07, 0x88, 0xe9, 0x13, - 0x65, 0xd1, 0x74, 0xf7, 0xe2, 0x2e, 0xc3, 0xab, 0x9b, 0xc3, 0xbe, 0x1f, 0x77, 0x6d, 0x1f, 0xe6, - 0xff, 0x74, 0x20, 0x22, 0x45, 0x7d, 0x0f, 0x53, 0xfe, 0x5d, 0x0e, 0x0a, 0xed, 0xd1, 0x60, 0x9a, - 0x47, 0x89, 0xcd, 0xf0, 0x28, 0xf1, 0xf9, 0xee, 0x3a, 0x32, 0x57, 0xbb, 0xeb, 0x80, 0x57, 0x7b, - 0xd7, 0x91, 0x7d, 0x65, 0x1e, 0xa5, 0x70, 0x25, 0x8f, 0xf2, 0xca, 0x6e, 0xbe, 0xa2, 0x97, 0xb8, - 0xf9, 0xfa, 0x0e, 0xe4, 0x55, 0xdb, 0x56, 0x47, 0xfc, 0xb7, 0x2d, 0x1a, 0x75, 0x3f, 0xfc, 0x8c, - 0xce, 0x4e, 0x57, 0xb3, 0x15, 0x32, 0x48, 0x7f, 0xce, 0x22, 0x38, 0x64, 0x55, 0x0f, 0xa4, 0xf9, - 0x5e, 0x2b, 0xff, 0x2a, 0xbd, 0x56, 0x71, 0xb6, 0xd7, 0xaa, 0x41, 0x9c, 0xfe, 0x78, 0x26, 0x41, - 0xe7, 0x9b, 0xb5, 0xe5, 0x61, 0xf5, 0xdd, 0x08, 0xfc, 0x7e, 0x86, 0x52, 0xa3, 0x1f, 0xc1, 0xb2, - 0x78, 0xa1, 0x4a, 0xf4, 0xc1, 0xbf, 0x99, 0x0c, 0xfc, 0x34, 0xa9, 0x7c, 0x76, 0xba, 0x5a, 0x92, - 0x7d, 0x2c, 0x9f, 0x1f, 0xab, 0xad, 0xc8, 0x5e, 0x94, 0xec, 0xa9, 0xe3, 0x9a, 0x83, 0xbe, 0x07, - 0x39, 0x6a, 0x95, 0x7d, 0xdc, 0x3f, 0xc4, 0xb6, 0x08, 0x5f, 0x0f, 0xe6, 0x93, 0x97, 0x98, 0xe7, - 0x1e, 0x25, 0x14, 0xfd, 0x28, 0xec, 0x41, 0x1c, 0xf4, 0x00, 0x12, 0xaa, 0xa1, 0xd3, 0xf8, 0xf3, - 0x55, 0x3f, 0x20, 0x63, 0x88, 0xec, 0x65, 0x6f, 0xd0, 0xd5, 0x4b, 0xe7, 0x77, 0x12, 0xc3, 0xd2, - 0x9c, 0xe3, 0xe6, 0x7f, 0x1a, 0x03, 0xf0, 0x85, 0x45, 0xdf, 0x82, 0x9b, 0x83, 0xa3, 0x91, 0xa3, - 0x77, 0x54, 0x43, 0xb1, 0xf1, 0xc0, 0xc6, 0x0e, 0x36, 0x59, 0x36, 0x4d, 0xf5, 0x3a, 0x27, 0xdf, - 0x10, 0xc3, 0x72, 0x68, 0x14, 0x7d, 0x0c, 0x37, 0x0c, 0xab, 0x37, 0x8d, 0x2e, 0xd8, 0x4b, 0xb8, - 0xce, 0x71, 0xc6, 0x88, 0x55, 0x52, 0x01, 0x0d, 0xd4, 0x43, 0xdd, 0xf0, 0xdb, 0x0b, 0x1f, 0x5f, - 0x74, 0xa3, 0x37, 0xb6, 0x3c, 0x16, 0xe2, 0xa9, 0x8a, 0xcf, 0x14, 0xfd, 0x70, 0xf2, 0xb6, 0xff, - 0xa3, 0x0b, 0xcf, 0x30, 0xfb, 0xd2, 0xbf, 0xfc, 0x06, 0x80, 0x3f, 0x3f, 0xbd, 0x44, 0xdf, 0xdd, - 0xf5, 0x93, 0x40, 0x7e, 0x1d, 0x5f, 0xbe, 0xf7, 0x15, 0x77, 0xee, 0x00, 0x49, 0xb9, 0xbe, 0xd7, - 0x7a, 0x56, 0x17, 0xb7, 0xee, 0xcb, 0xad, 0xb1, 0xe8, 0x35, 0x19, 0x6d, 0x22, 0x73, 0x46, 0x1b, - 0x7e, 0x11, 0xfe, 0x1e, 0xc4, 0x89, 0x31, 0x91, 0xd9, 0xeb, 0xcd, 0x83, 0x3d, 0x69, 0x01, 0x65, - 0x20, 0x51, 0xd9, 0x6d, 0x54, 0xf6, 0xa5, 0x08, 0x5a, 0x02, 0x69, 0xef, 0x60, 0xb7, 0xdd, 0x90, - 0xeb, 0x8f, 0x1a, 0xad, 0xa6, 0x42, 0x11, 0x82, 0x81, 0xe5, 0x6f, 0xe3, 0x20, 0x31, 0xc7, 0x33, - 0x25, 0xb4, 0x44, 0x2f, 0x71, 0x8d, 0xfe, 0x47, 0xcf, 0x99, 0xa6, 0x86, 0xa5, 0xc4, 0x2b, 0xca, - 0x8e, 0x93, 0x57, 0xc8, 0x8e, 0x53, 0xaf, 0xea, 0xde, 0x7e, 0xde, 0xf8, 0x13, 0x0e, 0x80, 0xf1, - 0xab, 0x04, 0xc0, 0x80, 0x86, 0xfc, 0x3c, 0x0a, 0x10, 0xd0, 0x8d, 0xef, 0x06, 0xff, 0x7d, 0x87, - 0xd9, 0x37, 0xc7, 0x63, 0xe5, 0xe0, 0xce, 0x82, 0xf8, 0xd7, 0x1f, 0x1e, 0x41, 0x5a, 0xe3, 0x99, - 0x1e, 0x4f, 0x08, 0xdf, 0x9e, 0x3b, 0x21, 0xdc, 0x59, 0x90, 0x3d, 0x62, 0xf4, 0x71, 0xe8, 0x27, - 0xbb, 0x77, 0xe7, 0x32, 0xfd, 0x1d, 0xf1, 0x64, 0xbf, 0x02, 0x49, 0x16, 0xa3, 0xf9, 0x36, 0xcd, - 0xfc, 0xc5, 0xe7, 0x98, 0x69, 0x90, 0xb2, 0x9c, 0x11, 0xf2, 0xd2, 0x31, 0x05, 0x89, 0xa1, 0xa9, - 0x5b, 0xe6, 0x3d, 0x39, 0xf8, 0xcc, 0x5c, 0xf4, 0x49, 0x89, 0xb7, 0xa0, 0x7f, 0xab, 0x2e, 0xd6, - 0xd8, 0x6b, 0x9e, 0x03, 0xf3, 0x85, 0x07, 0x88, 0xa0, 0x02, 0x00, 0x1f, 0xd7, 0xcd, 0x9e, 0x14, - 0xa5, 0x05, 0x27, 0x49, 0xaf, 0xc9, 0x57, 0xec, 0xde, 0x77, 0x40, 0x1a, 0xff, 0xc9, 0x69, 0xc0, - 0xc7, 0x2c, 0x42, 0x7e, 0xef, 0xd9, 0xd6, 0x56, 0xbb, 0xb1, 0x57, 0xdf, 0x6f, 0x57, 0xf6, 0x9e, - 0xb2, 0xf7, 0xcb, 0x6d, 0x52, 0xad, 0xb6, 0x1a, 0x35, 0x29, 0x7a, 0xef, 0x3b, 0x50, 0x1c, 0x33, - 0x33, 0xe2, 0x8e, 0x9e, 0x1e, 0x54, 0x77, 0x1b, 0x5b, 0x53, 0xdf, 0x05, 0xa1, 0x2c, 0xa4, 0x5a, - 0xdb, 0xdb, 0xbb, 0x8d, 0x66, 0x5d, 0x8a, 0xdd, 0xfb, 0x00, 0x72, 0xc1, 0x54, 0x19, 0x49, 0x90, - 0xfb, 0x7e, 0xab, 0x59, 0x57, 0xb6, 0x2b, 0x8d, 0xdd, 0x03, 0x99, 0x48, 0x80, 0xa0, 0xc0, 0xfd, - 0x8a, 0x80, 0x45, 0xaa, 0xeb, 0xbf, 0xfe, 0xcf, 0x95, 0x85, 0x5f, 0x9f, 0xad, 0x44, 0x7e, 0x73, - 0xb6, 0x12, 0xf9, 0xfd, 0xd9, 0x4a, 0xe4, 0x3f, 0xce, 0x56, 0x22, 0x7f, 0xf5, 0x87, 0x95, 0x85, - 0xdf, 0xfc, 0x61, 0x65, 0xe1, 0xf7, 0x7f, 0x58, 0x59, 0xf8, 0x7e, 0x92, 0xfd, 0xcb, 0x24, 0xff, - 0x1b, 0x00, 0x00, 0xff, 0xff, 0x8b, 0x2e, 0x44, 0x14, 0x04, 0x45, 0x00, 0x00, + 0x5b, 0x5e, 0xc7, 0xd2, 0x5a, 0x76, 0x92, 0xb5, 0x9d, 0xe4, 0x67, 0x4a, 0xa4, 0x56, 0xdc, 0x95, + 0x48, 0x79, 0x44, 0xed, 0x3a, 0xc9, 0xaf, 0x99, 0x8c, 0x38, 0x97, 0xd4, 0x58, 0xc3, 0x19, 0x7a, + 0x66, 0xb8, 0x5a, 0x06, 0x7d, 0x28, 0xf2, 0xd4, 0xa7, 0xb6, 0xef, 0x45, 0x80, 0xa0, 0x08, 0xd0, + 0xbc, 0x05, 0x41, 0x81, 0x16, 0x68, 0x81, 0x3e, 0xb6, 0x79, 0x4c, 0x51, 0xa0, 0xc8, 0x93, 0xd0, + 0xca, 0x0f, 0xed, 0x1f, 0xd0, 0x27, 0x03, 0x05, 0x8a, 0xfb, 0x35, 0x1f, 0xfc, 0x90, 0x29, 0x69, + 0x9b, 0x07, 0x1b, 0x9a, 0x73, 0xcf, 0x39, 0xf7, 0xdc, 0x7b, 0xcf, 0xf7, 0xbd, 0x5c, 0xb8, 0xe7, + 0x7c, 0x61, 0xac, 0xb7, 0x55, 0x57, 0x35, 0xac, 0xee, 0xba, 0x86, 0x9d, 0x76, 0xff, 0x68, 0xdd, + 0x71, 0xed, 0x41, 0xdb, 0x1d, 0xd8, 0x58, 0x5b, 0xeb, 0xdb, 0x96, 0x6b, 0xa1, 0x9b, 0x6d, 0xab, + 0x7d, 0x62, 0x5b, 0x6a, 0xfb, 0x78, 0xcd, 0xf9, 0xc2, 0x20, 0xff, 0x1d, 0xa9, 0x0e, 0x5e, 0x2c, + 0x0d, 0x5c, 0xdd, 0x58, 0x3f, 0x36, 0xda, 0xeb, 0xae, 0xde, 0xc3, 0x8e, 0xab, 0xf6, 0xfa, 0x8c, + 0x60, 0xb1, 0x3c, 0x81, 0x6b, 0xdf, 0xd6, 0x5f, 0xe8, 0x06, 0xee, 0x62, 0x8e, 0x73, 0x93, 0xe0, + 0xb8, 0xc3, 0x3e, 0x76, 0xd8, 0xff, 0x39, 0xf8, 0xb5, 0x2e, 0xb6, 0xd6, 0xbb, 0xd8, 0xd2, 0x4d, + 0x0d, 0xbf, 0x5c, 0x6f, 0x5b, 0x66, 0x47, 0xef, 0xf2, 0xa1, 0x85, 0xae, 0xd5, 0xb5, 0xe8, 0x9f, + 0xeb, 0xe4, 0x2f, 0x06, 0x2d, 0xff, 0x2c, 0x01, 0x37, 0xb6, 0x2d, 0x1b, 0xeb, 0x5d, 0xf3, 0x29, + 0x1e, 0xca, 0xb8, 0x83, 0x6d, 0x6c, 0xb6, 0x31, 0x5a, 0x81, 0x84, 0xab, 0x1e, 0x19, 0xb8, 0x14, + 0x59, 0x89, 0xac, 0xe6, 0x37, 0xe1, 0xb7, 0x67, 0xcb, 0x73, 0x5f, 0x9d, 0x2d, 0x47, 0xeb, 0x55, + 0x99, 0x0d, 0xa0, 0xfb, 0x90, 0xa0, 0xb3, 0x94, 0xa2, 0x14, 0xa3, 0xc8, 0x31, 0x52, 0x75, 0x02, + 0x24, 0x68, 0x74, 0x14, 0x95, 0x20, 0x6e, 0xaa, 0x3d, 0x5c, 0x8a, 0xad, 0x44, 0x56, 0x33, 0x9b, + 0x71, 0x82, 0x25, 0x53, 0x08, 0x7a, 0x0a, 0xe9, 0x17, 0xaa, 0xa1, 0x6b, 0xba, 0x3b, 0x2c, 0xc5, + 0x57, 0x22, 0xab, 0x85, 0x8d, 0xb7, 0xd7, 0x26, 0x6e, 0xd5, 0xda, 0x96, 0x65, 0x3a, 0xae, 0xad, + 0xea, 0xa6, 0xfb, 0x8c, 0x13, 0x70, 0x46, 0x1e, 0x03, 0xf4, 0x10, 0xe6, 0x9d, 0x63, 0xd5, 0xc6, + 0x9a, 0xd2, 0xb7, 0x71, 0x47, 0x7f, 0xa9, 0x18, 0xd8, 0x2c, 0x25, 0x56, 0x22, 0xab, 0x09, 0x8e, + 0x5a, 0x64, 0xc3, 0xfb, 0x74, 0x74, 0x17, 0x9b, 0xa8, 0x05, 0x19, 0xcb, 0x54, 0x34, 0x6c, 0x60, + 0x17, 0x97, 0x92, 0x74, 0xfe, 0xf7, 0xa6, 0xcc, 0x3f, 0x61, 0x83, 0xd6, 0x2a, 0x6d, 0x57, 0xb7, + 0x4c, 0x21, 0x87, 0x65, 0x56, 0x29, 0x23, 0xce, 0x75, 0xd0, 0xd7, 0x54, 0x17, 0x97, 0x52, 0xd7, + 0xe6, 0x7a, 0x48, 0x19, 0xa1, 0x5d, 0x48, 0xf4, 0x54, 0xb7, 0x7d, 0x5c, 0x4a, 0x53, 0x8e, 0x0f, + 0x2f, 0xc1, 0x71, 0x8f, 0xd0, 0x71, 0x86, 0x8c, 0x49, 0xf9, 0x39, 0x24, 0xd9, 0x3c, 0x28, 0x0f, + 0x99, 0x46, 0x53, 0xa9, 0x6c, 0xb5, 0xea, 0xcd, 0x86, 0x34, 0x87, 0x72, 0x90, 0x96, 0x6b, 0x07, + 0x2d, 0xb9, 0xbe, 0xd5, 0x92, 0x22, 0xe4, 0xeb, 0xa0, 0xd6, 0x52, 0x1a, 0x87, 0xbb, 0xbb, 0x52, + 0x14, 0x15, 0x21, 0x4b, 0xbe, 0xaa, 0xb5, 0xed, 0xca, 0xe1, 0x6e, 0x4b, 0x8a, 0xa1, 0x2c, 0xa4, + 0xb6, 0x2a, 0x07, 0x5b, 0x95, 0x6a, 0x4d, 0x8a, 0x2f, 0xc6, 0x7f, 0xf5, 0xcb, 0xa5, 0xb9, 0xf2, + 0x43, 0x48, 0xd0, 0xe9, 0x10, 0x40, 0xf2, 0xa0, 0xbe, 0xb7, 0xbf, 0x5b, 0x93, 0xe6, 0x50, 0x1a, + 0xe2, 0xdb, 0x84, 0x45, 0x84, 0x50, 0xec, 0x57, 0xe4, 0x56, 0xbd, 0xb2, 0x2b, 0x45, 0x19, 0xc5, + 0x47, 0xf1, 0xff, 0xfa, 0xc5, 0x72, 0xa4, 0xfc, 0x2f, 0x09, 0x58, 0xf0, 0x65, 0xf7, 0x4f, 0x1b, + 0x6d, 0x41, 0xd1, 0xb2, 0xf5, 0xae, 0x6e, 0x2a, 0x54, 0xe7, 0x14, 0x5d, 0xe3, 0xfa, 0xf8, 0x0d, + 0xb2, 0x9e, 0xf3, 0xb3, 0xe5, 0x7c, 0x93, 0x0e, 0xb7, 0xc8, 0x68, 0xbd, 0xca, 0x15, 0x34, 0x6f, + 0x05, 0x80, 0x1a, 0x7a, 0x0a, 0xf3, 0x9c, 0x49, 0xdb, 0x32, 0x06, 0x3d, 0x53, 0xd1, 0x35, 0xa7, + 0x14, 0x5d, 0x89, 0xad, 0xe6, 0x37, 0x97, 0xcf, 0xcf, 0x96, 0x8b, 0x8c, 0xc5, 0x16, 0x1d, 0xab, + 0x57, 0x9d, 0xaf, 0xce, 0x96, 0xd3, 0xe2, 0x43, 0xe6, 0xd3, 0xf3, 0x6f, 0xcd, 0x41, 0xcf, 0xe1, + 0xa6, 0x2d, 0xf6, 0x56, 0x0b, 0x32, 0x8c, 0x51, 0x86, 0xf7, 0xce, 0xcf, 0x96, 0x6f, 0x78, 0x9b, + 0xaf, 0x4d, 0x66, 0x7a, 0xc3, 0x1e, 0x45, 0xd0, 0x1c, 0xd4, 0x84, 0x00, 0xd8, 0x5f, 0x6e, 0x9c, + 0x2e, 0x77, 0x99, 0x2f, 0x77, 0xde, 0x67, 0x1d, 0x5e, 0xf2, 0xbc, 0x3d, 0x32, 0xa0, 0x79, 0x86, + 0x97, 0xb8, 0xd0, 0xf0, 0x92, 0xd7, 0x35, 0xbc, 0x90, 0x19, 0xa5, 0xfe, 0x4f, 0xcc, 0x28, 0xfd, + 0xca, 0xcd, 0x28, 0xf3, 0x0a, 0xcc, 0x88, 0xe9, 0xee, 0x93, 0x78, 0x1a, 0xa4, 0xec, 0x93, 0x78, + 0x3a, 0x2b, 0xe5, 0x9e, 0xc4, 0xd3, 0x39, 0x29, 0xff, 0x24, 0x9e, 0xce, 0x4b, 0x85, 0xf2, 0x5f, + 0x46, 0xe1, 0xce, 0xa1, 0xa9, 0x7f, 0x31, 0xc0, 0xcf, 0x75, 0xf7, 0xd8, 0x1a, 0xb8, 0xd4, 0x2f, + 0x06, 0x74, 0xfb, 0x21, 0xa4, 0x47, 0x94, 0xfa, 0x26, 0x3f, 0xe5, 0x54, 0xf8, 0x6c, 0x53, 0x2e, + 0x3f, 0xd1, 0x47, 0x00, 0x63, 0x1a, 0xfc, 0xda, 0xf9, 0xd9, 0x72, 0x66, 0xb2, 0x9a, 0x65, 0xda, + 0x9e, 0x72, 0xfd, 0x81, 0x9c, 0x70, 0x19, 0x32, 0x7d, 0x1b, 0x6b, 0x7a, 0x9b, 0x9c, 0x5a, 0x50, + 0xef, 0x7c, 0x30, 0xb7, 0xf8, 0x7f, 0x48, 0x80, 0xc4, 0x04, 0xad, 0x62, 0xa7, 0x6d, 0xeb, 0x7d, + 0xd7, 0xb2, 0x3d, 0x29, 0x23, 0x63, 0x52, 0xbe, 0x09, 0x51, 0x5d, 0xe3, 0x81, 0xe6, 0x16, 0xdf, + 0xa5, 0x28, 0xdd, 0x20, 0x7f, 0xb9, 0x51, 0x5d, 0x43, 0x6b, 0x10, 0x27, 0xd1, 0x90, 0xae, 0x33, + 0xbb, 0xb1, 0x38, 0xba, 0x12, 0xdc, 0x5b, 0x63, 0xc1, 0xb2, 0x25, 0x53, 0x3c, 0xb4, 0x02, 0x69, + 0x73, 0x60, 0x18, 0x34, 0xd0, 0x91, 0xd5, 0xa7, 0xc5, 0x92, 0x04, 0x14, 0xdd, 0x85, 0x9c, 0x86, + 0x3b, 0xea, 0xc0, 0x70, 0x15, 0xfc, 0xb2, 0x6f, 0xb3, 0x55, 0xc9, 0x59, 0x0e, 0xab, 0xbd, 0xec, + 0xdb, 0xe8, 0x0e, 0x24, 0x8f, 0x75, 0x4d, 0xc3, 0x26, 0x35, 0x26, 0xc1, 0x82, 0xc3, 0xd0, 0x2a, + 0xe4, 0x74, 0x53, 0x6d, 0xb7, 0xb1, 0xe3, 0xe8, 0x64, 0x9a, 0xf9, 0x00, 0x4e, 0x68, 0x04, 0x6d, + 0xc0, 0xfc, 0xc0, 0xc1, 0x8e, 0xe2, 0xe0, 0x2f, 0x06, 0x44, 0xe7, 0xe8, 0x29, 0x03, 0x3d, 0xe5, + 0x24, 0x57, 0x85, 0x22, 0x41, 0x38, 0xe0, 0xe3, 0xe4, 0x60, 0x37, 0x60, 0xde, 0x3a, 0x35, 0x47, + 0x68, 0x72, 0x61, 0x1a, 0x82, 0x10, 0xa4, 0xb9, 0x0b, 0xb9, 0xb6, 0xd5, 0xeb, 0x0f, 0x5c, 0xcc, + 0x96, 0x94, 0x65, 0x4b, 0xe2, 0x30, 0xba, 0xa4, 0x25, 0x48, 0xbd, 0xd0, 0x6d, 0x77, 0xa0, 0x1a, + 0x25, 0x29, 0x20, 0xaf, 0x00, 0xa2, 0x4f, 0x40, 0xea, 0x77, 0x15, 0xd5, 0x75, 0x6d, 0xfd, 0x88, + 0xf0, 0x31, 0x07, 0xbd, 0x52, 0x3e, 0x74, 0x3a, 0x85, 0xfd, 0xc7, 0x15, 0x31, 0xdc, 0x18, 0xf4, + 0xe4, 0x42, 0xbf, 0x1b, 0xfc, 0x46, 0xdb, 0xf0, 0xba, 0x6a, 0xb8, 0xd8, 0x16, 0x2e, 0x94, 0x1c, + 0x87, 0xa2, 0x9b, 0x4a, 0xdf, 0xb6, 0xba, 0x36, 0x76, 0x9c, 0x52, 0x21, 0x30, 0xef, 0x6b, 0x14, + 0x95, 0x9d, 0x74, 0x6b, 0xd8, 0xc7, 0x75, 0x73, 0x9f, 0xa3, 0xa1, 0x1f, 0x01, 0x72, 0x86, 0x8e, + 0x8b, 0x7b, 0x82, 0xd1, 0x89, 0x6e, 0x6a, 0xa5, 0x22, 0xd5, 0xe4, 0xb7, 0xa6, 0x68, 0xf2, 0x01, + 0x25, 0x60, 0xec, 0x9e, 0xea, 0xa6, 0xc6, 0x67, 0x91, 0x9c, 0x11, 0xb8, 0x67, 0xe1, 0x69, 0x29, + 0xf3, 0x24, 0x9e, 0xce, 0x48, 0xf0, 0x24, 0x9e, 0x4e, 0x49, 0xe9, 0xf2, 0x9f, 0x45, 0xe1, 0x16, + 0x43, 0xdb, 0x56, 0x7b, 0xba, 0x31, 0xbc, 0xae, 0x0e, 0x33, 0x2e, 0x5c, 0x87, 0xe9, 0xf1, 0xd0, + 0xa5, 0x10, 0x32, 0x16, 0x58, 0xe8, 0xf1, 0x10, 0x58, 0x83, 0x80, 0x46, 0x1c, 0x41, 0xfc, 0x12, + 0x8e, 0xa0, 0x09, 0xf3, 0x42, 0x9d, 0x3d, 0x0e, 0x54, 0xa7, 0xf3, 0x9b, 0xf7, 0xb8, 0x4c, 0xc5, + 0x2a, 0x43, 0x10, 0xe4, 0xe1, 0x78, 0xa8, 0x85, 0x06, 0xf9, 0x16, 0x95, 0xff, 0x2e, 0x0a, 0x0b, + 0x75, 0xd3, 0xc5, 0xb6, 0x81, 0xd5, 0x17, 0x38, 0xb0, 0x1d, 0x9f, 0x41, 0x46, 0x35, 0xdb, 0xd8, + 0x71, 0x2d, 0xdb, 0x29, 0x45, 0x56, 0x62, 0xab, 0xd9, 0x8d, 0x0f, 0xa6, 0x9c, 0xca, 0x24, 0xfa, + 0xb5, 0x0a, 0x27, 0x16, 0x7e, 0xc4, 0x63, 0xb6, 0xf8, 0x8f, 0x11, 0x48, 0x8b, 0xd1, 0x2b, 0xf8, + 0xd2, 0x6f, 0x41, 0x9a, 0xe6, 0xa7, 0x8a, 0x77, 0x26, 0x8b, 0x82, 0x82, 0x27, 0xb0, 0xc1, 0x5c, + 0x36, 0x45, 0x71, 0xeb, 0x1a, 0xda, 0x9a, 0x94, 0x66, 0xc6, 0x28, 0xfd, 0x6d, 0xb1, 0x7f, 0x07, + 0xe1, 0x44, 0x73, 0x2c, 0xf3, 0x64, 0x7b, 0xc6, 0x77, 0xee, 0x6f, 0x23, 0x30, 0x4f, 0x08, 0x34, + 0xac, 0x05, 0xb6, 0xed, 0x1e, 0x80, 0xee, 0x28, 0x0e, 0x83, 0xd3, 0x15, 0x09, 0x53, 0xc8, 0xe8, + 0x0e, 0x47, 0xf7, 0x54, 0x2d, 0x3a, 0xa6, 0x6a, 0x1f, 0x42, 0x9e, 0xd2, 0x2a, 0x47, 0x83, 0xf6, + 0x09, 0x76, 0x1d, 0x2a, 0x61, 0x62, 0x73, 0x81, 0x4b, 0x98, 0xa3, 0x1c, 0x36, 0xd9, 0x98, 0x9c, + 0x73, 0x02, 0x5f, 0x63, 0xda, 0x17, 0x1f, 0xd3, 0x3e, 0x2e, 0xf8, 0xaf, 0xe3, 0x70, 0x6b, 0x5f, + 0xb5, 0x5d, 0x9d, 0x44, 0x5a, 0xdd, 0xec, 0x06, 0xa4, 0xbf, 0x0f, 0x59, 0x73, 0x20, 0x0c, 0xd2, + 0xe1, 0x07, 0xc2, 0xe4, 0x03, 0x73, 0xc0, 0x0d, 0xcc, 0x41, 0xdf, 0x86, 0x05, 0x82, 0xa6, 0xf7, + 0xfa, 0x86, 0xde, 0xd6, 0x5d, 0x0f, 0x3f, 0x1e, 0xc0, 0x47, 0xe6, 0xa0, 0x57, 0xe7, 0x08, 0x82, + 0x6e, 0x17, 0xe2, 0x86, 0xee, 0xb8, 0x34, 0x00, 0x66, 0x37, 0x36, 0xa6, 0xa8, 0xd3, 0x64, 0xd9, + 0xd6, 0x76, 0x75, 0xc7, 0x15, 0x7b, 0x45, 0xb8, 0xa0, 0x26, 0x24, 0x6c, 0xd5, 0xec, 0x62, 0x6a, + 0x67, 0xd9, 0x8d, 0xf7, 0x2f, 0xc7, 0x4e, 0x26, 0xa4, 0x22, 0x2d, 0xa0, 0x7c, 0x16, 0x7f, 0x1e, + 0x81, 0x38, 0x99, 0xe5, 0x02, 0x57, 0x70, 0x0b, 0x92, 0x2f, 0x54, 0x63, 0x80, 0x59, 0x10, 0xcf, + 0xc9, 0xfc, 0x0b, 0xfd, 0x11, 0x14, 0x9d, 0xc1, 0x51, 0x3f, 0x30, 0x15, 0x8f, 0x64, 0xef, 0x5e, + 0x4a, 0x2a, 0xaf, 0xe2, 0x09, 0xf3, 0x62, 0x07, 0xb7, 0xf8, 0x05, 0x24, 0xa8, 0xd4, 0x17, 0xc8, + 0x77, 0x1f, 0x0a, 0x1d, 0xdb, 0xea, 0x29, 0xba, 0xd9, 0x36, 0x06, 0x8e, 0xfe, 0x82, 0x05, 0xd4, + 0x9c, 0x9c, 0x27, 0xd0, 0xba, 0x00, 0x12, 0x5d, 0x71, 0x2d, 0x05, 0xbf, 0x14, 0x48, 0x51, 0x8a, + 0x94, 0x75, 0xad, 0x9a, 0x00, 0x85, 0x54, 0xfd, 0xef, 0x73, 0x50, 0xa4, 0x06, 0x35, 0x93, 0xbb, + 0xbc, 0x1f, 0x70, 0x97, 0x37, 0x43, 0xee, 0xd2, 0xb3, 0x4a, 0xe2, 0x2d, 0xef, 0x40, 0x72, 0x40, + 0xb3, 0x2c, 0x2a, 0xa2, 0x17, 0x7c, 0x19, 0x0c, 0x3d, 0x82, 0xd4, 0x0b, 0x6c, 0x3b, 0xba, 0x65, + 0x96, 0x10, 0xe5, 0xb4, 0xc4, 0xab, 0xd4, 0x5b, 0x23, 0x82, 0x3c, 0x63, 0x58, 0xb2, 0x40, 0x47, + 0xab, 0x20, 0x9d, 0xe0, 0xa1, 0x32, 0xc1, 0x16, 0x0a, 0x27, 0xa4, 0x44, 0xf1, 0x9d, 0xb1, 0x06, + 0x37, 0x03, 0x98, 0x9a, 0x6e, 0x63, 0x9a, 0x7c, 0x3a, 0xa5, 0xf4, 0x4a, 0xec, 0x82, 0x24, 0x73, + 0x44, 0x80, 0xb5, 0xaa, 0x20, 0x94, 0x6f, 0x78, 0x13, 0x78, 0x30, 0x07, 0x7d, 0x13, 0x10, 0xf1, + 0x74, 0x38, 0x2c, 0x51, 0x82, 0x4a, 0x24, 0xd1, 0x91, 0xa0, 0x4c, 0x9b, 0x50, 0x08, 0xc8, 0x44, + 0x82, 0x44, 0x92, 0x06, 0x89, 0x3b, 0xc4, 0xfa, 0x9f, 0x0a, 0xf6, 0xa3, 0x71, 0x22, 0xe7, 0x4d, + 0x4c, 0x42, 0xc5, 0x21, 0x5b, 0x97, 0x33, 0xe8, 0x10, 0x3f, 0x17, 0x60, 0x95, 0xa2, 0xac, 0xca, + 0xe7, 0x67, 0xcb, 0xe8, 0x29, 0x1e, 0x1e, 0xd0, 0xf1, 0xc9, 0x0c, 0xd1, 0xc9, 0xc8, 0xb8, 0xe6, + 0xa0, 0x1d, 0x90, 0x42, 0x0b, 0x21, 0x1c, 0x0b, 0x94, 0xe3, 0x12, 0x49, 0x1b, 0x0e, 0xfc, 0xa5, + 0x8c, 0x72, 0x2b, 0x04, 0x96, 0x49, 0x38, 0xb5, 0x60, 0x81, 0xe4, 0x2c, 0x96, 0xa3, 0xbb, 0x21, + 0x6e, 0x79, 0x5f, 0xbe, 0x2d, 0x31, 0x3e, 0x45, 0xbe, 0xf6, 0xc8, 0xb8, 0xe6, 0xa0, 0x03, 0xc8, + 0x76, 0x58, 0xfe, 0xaf, 0x9c, 0xe0, 0x21, 0xad, 0x14, 0xb2, 0x1b, 0x0f, 0x66, 0xaf, 0x14, 0x36, + 0x93, 0x44, 0xc5, 0x4a, 0x11, 0x19, 0x3a, 0xde, 0x20, 0x7a, 0x0e, 0xf9, 0x40, 0x71, 0x77, 0x34, + 0xa4, 0x69, 0xdd, 0xd5, 0xd8, 0xe6, 0x7c, 0x46, 0x9b, 0x43, 0xf4, 0x29, 0x80, 0xee, 0xc5, 0x4d, + 0x9a, 0xc9, 0x65, 0x37, 0xde, 0xb9, 0x44, 0x80, 0x15, 0x6e, 0xd9, 0x67, 0x82, 0x9e, 0x43, 0xc1, + 0xff, 0xa2, 0xc2, 0xe6, 0x2e, 0x2d, 0x2c, 0xe3, 0x9a, 0x0f, 0xf0, 0xd9, 0x24, 0x9b, 0x90, 0x0b, + 0xb9, 0xb6, 0xe2, 0xd5, 0x5d, 0x5b, 0x88, 0x11, 0xaa, 0xf1, 0xac, 0x5f, 0xa2, 0x59, 0xdf, 0x3b, + 0x33, 0x1a, 0x1c, 0x49, 0x24, 0x85, 0xc7, 0xa1, 0xc5, 0xc0, 0xfb, 0x80, 0xda, 0x36, 0x56, 0x5d, + 0xac, 0x91, 0xbc, 0x98, 0x86, 0x1c, 0x63, 0x18, 0xca, 0xd7, 0xe7, 0xf9, 0x78, 0xcd, 0x1b, 0x46, + 0x3b, 0x90, 0xc7, 0x66, 0xdb, 0xd2, 0x74, 0xb3, 0x4b, 0x73, 0xd8, 0xd2, 0x0d, 0x3f, 0x99, 0xfa, + 0xea, 0x6c, 0xf9, 0x1b, 0x23, 0xb3, 0xd6, 0x38, 0x2e, 0x99, 0x5c, 0xce, 0xe1, 0xc0, 0x17, 0xda, + 0x81, 0x94, 0x08, 0xf8, 0x0b, 0x74, 0x67, 0x56, 0xa7, 0xa5, 0xaf, 0xa3, 0xe9, 0x82, 0xc8, 0xce, + 0x39, 0x39, 0xa9, 0x6a, 0x34, 0xdd, 0x21, 0x89, 0x8e, 0x56, 0xba, 0x19, 0xac, 0x6a, 0x04, 0x14, + 0x6d, 0x01, 0x74, 0xb1, 0xa5, 0xb0, 0xfe, 0x60, 0xe9, 0x16, 0x9d, 0x6e, 0x29, 0x30, 0x5d, 0x17, + 0x5b, 0x6b, 0xa2, 0x8b, 0x48, 0x0a, 0xbf, 0x8e, 0xde, 0x15, 0xf9, 0x47, 0x17, 0x5b, 0x0c, 0x10, + 0xae, 0xf6, 0x6e, 0x4f, 0xac, 0xf6, 0xca, 0x4b, 0x90, 0xf1, 0x9c, 0x18, 0x4a, 0x41, 0xac, 0x72, + 0xb0, 0xc5, 0x5a, 0x42, 0xd5, 0xda, 0xc1, 0x96, 0x14, 0x29, 0xdf, 0x85, 0x38, 0x5d, 0x7c, 0x16, + 0x52, 0xdb, 0x4d, 0xf9, 0x79, 0x45, 0xae, 0xb2, 0x36, 0x54, 0xbd, 0xf1, 0xac, 0x26, 0xb7, 0x6a, + 0x55, 0x49, 0x04, 0x8f, 0xb3, 0x38, 0x20, 0xbf, 0x02, 0x6d, 0x59, 0xbc, 0xa2, 0xef, 0x42, 0xb1, + 0xed, 0x41, 0xd9, 0x01, 0x44, 0x56, 0xa2, 0xab, 0x85, 0x8d, 0x47, 0x5f, 0x5b, 0xc5, 0x0a, 0x1e, + 0x41, 0x90, 0xaf, 0x12, 0x85, 0x76, 0x08, 0x1a, 0x48, 0xb6, 0xa2, 0x23, 0x81, 0x4a, 0x86, 0x44, + 0xfb, 0x18, 0xb7, 0x4f, 0x78, 0xa8, 0xfe, 0xf6, 0x94, 0x89, 0x69, 0x1e, 0x1a, 0x50, 0xbf, 0x2d, + 0x42, 0xe3, 0x4f, 0x2d, 0x72, 0x08, 0xca, 0x0a, 0xc9, 0x61, 0x27, 0x14, 0xbf, 0xd0, 0xae, 0x27, + 0x75, 0xce, 0x84, 0x5d, 0x07, 0x7c, 0xd0, 0x23, 0x28, 0x9a, 0x96, 0xab, 0x90, 0xca, 0x96, 0x7b, + 0x4b, 0x5a, 0xaf, 0xe6, 0x37, 0x25, 0xae, 0xab, 0xbe, 0x5f, 0xcc, 0x9b, 0x96, 0xdb, 0x18, 0x18, + 0x06, 0x03, 0xa0, 0x3f, 0x89, 0xc0, 0x32, 0x0b, 0xa8, 0xca, 0x29, 0xeb, 0x65, 0x28, 0x2c, 0x77, + 0xf6, 0xf7, 0x88, 0x76, 0x7e, 0xa6, 0x67, 0x4f, 0x17, 0x35, 0x42, 0xb8, 0xa8, 0x77, 0x06, 0x17, + 0xe0, 0x94, 0x5b, 0x50, 0x08, 0x1f, 0x13, 0xca, 0x40, 0x62, 0x6b, 0xa7, 0xb6, 0xf5, 0x54, 0x9a, + 0x43, 0x45, 0xc8, 0x6e, 0x37, 0xe5, 0x5a, 0xfd, 0x71, 0x43, 0x79, 0x5a, 0xfb, 0x01, 0xeb, 0x5c, + 0x36, 0x9a, 0x5e, 0xe7, 0xb2, 0x04, 0x0b, 0x87, 0x8d, 0xfa, 0xa7, 0x87, 0x35, 0xe5, 0x79, 0xbd, + 0xb5, 0xd3, 0x3c, 0x6c, 0x29, 0xf5, 0x46, 0xb5, 0xf6, 0x99, 0x14, 0xf3, 0xea, 0xbb, 0x84, 0x94, + 0x2c, 0xff, 0x6b, 0x12, 0x0a, 0xfb, 0xb6, 0xde, 0x53, 0xed, 0x21, 0x89, 0x6a, 0xa7, 0x6a, 0x1f, + 0x7d, 0x02, 0x0b, 0x96, 0x41, 0x32, 0x7d, 0x0a, 0x55, 0xbc, 0x7a, 0x21, 0x3e, 0xb9, 0xe1, 0x3d, + 0x6f, 0x19, 0x1a, 0xe7, 0x50, 0xe7, 0xe5, 0xc2, 0x27, 0xb0, 0x60, 0xe2, 0xd3, 0x71, 0x0e, 0x91, + 0x29, 0x1c, 0x4c, 0x7c, 0x3a, 0xc2, 0xe1, 0x9b, 0x90, 0x25, 0x32, 0x50, 0x4a, 0x2c, 0x9a, 0x3e, + 0xd9, 0x20, 0x11, 0x58, 0x86, 0x56, 0x67, 0xc3, 0x04, 0x9b, 0xcc, 0x27, 0xb0, 0x63, 0x13, 0xb0, + 0x4d, 0x7c, 0x2a, 0xb0, 0x3f, 0x84, 0x5b, 0xe3, 0xd2, 0x8d, 0xf5, 0x0c, 0x6f, 0x8c, 0x08, 0x45, + 0x32, 0x0c, 0xf4, 0x39, 0x2c, 0x18, 0x56, 0x5b, 0x35, 0x74, 0x77, 0xc8, 0xbd, 0x88, 0xe2, 0x9c, + 0xaa, 0x7d, 0xaa, 0x51, 0xd9, 0xa9, 0xc6, 0x17, 0xde, 0xdf, 0xb5, 0x5d, 0xce, 0x81, 0xf9, 0x13, + 0x02, 0x92, 0x91, 0x31, 0x06, 0x5b, 0xfc, 0x9b, 0x18, 0xa0, 0x71, 0x54, 0x74, 0x02, 0x37, 0xc8, + 0xce, 0x8c, 0x88, 0x41, 0xb7, 0x36, 0xbb, 0xf1, 0xad, 0x19, 0xad, 0x30, 0xcc, 0x57, 0xb8, 0x79, + 0xcb, 0xd0, 0xc2, 0x03, 0x64, 0x32, 0xb2, 0x55, 0xa3, 0x93, 0x45, 0x5f, 0xc1, 0x64, 0x26, 0x3e, + 0x1d, 0x99, 0x4c, 0x87, 0xd7, 0xc9, 0x64, 0x36, 0xee, 0xea, 0x96, 0xa9, 0x1a, 0xca, 0xd1, 0x50, + 0xb1, 0xad, 0xd3, 0x40, 0xc1, 0xce, 0x0a, 0xce, 0xd5, 0xf3, 0xb3, 0xe5, 0x52, 0x03, 0x9f, 0xca, + 0x1c, 0x6f, 0x73, 0x28, 0x5b, 0xa7, 0x13, 0xab, 0xf6, 0x92, 0x39, 0x19, 0x4b, 0x43, 0x32, 0xbc, + 0x75, 0xc1, 0x54, 0xa1, 0xce, 0x57, 0x9c, 0xb6, 0x89, 0xee, 0x4e, 0x66, 0x55, 0xf5, 0xfb, 0x61, + 0xa1, 0x9c, 0xff, 0xd7, 0x11, 0xa0, 0x49, 0xd8, 0xc0, 0x15, 0xbd, 0x6e, 0x7a, 0x76, 0x1f, 0x40, + 0x9e, 0x4c, 0xeb, 0xaf, 0x28, 0x32, 0xc5, 0x13, 0x11, 0x75, 0xf6, 0x84, 0xfd, 0x00, 0xf2, 0xe4, + 0xc4, 0x7d, 0xaa, 0xe8, 0x34, 0x2a, 0xcb, 0xf0, 0x3a, 0xeb, 0xe8, 0x2d, 0xc8, 0xe9, 0x26, 0x49, + 0xeb, 0x79, 0xbb, 0x2b, 0xd8, 0x03, 0xcd, 0xf2, 0x11, 0x5f, 0xee, 0xf2, 0x6f, 0xa2, 0x70, 0x7b, + 0x4f, 0x75, 0xb1, 0xad, 0xab, 0x86, 0xfe, 0x53, 0xac, 0x3d, 0xd3, 0xc9, 0x82, 0x3b, 0x36, 0x76, + 0x8e, 0xd1, 0x67, 0x30, 0x3f, 0x66, 0x30, 0x5c, 0xe1, 0xde, 0x9c, 0x2d, 0xeb, 0x10, 0xa5, 0xd9, + 0x88, 0x4d, 0xa1, 0xbd, 0xb0, 0xe1, 0xb2, 0xd2, 0xf6, 0x72, 0x3c, 0x83, 0x96, 0xfd, 0x08, 0x12, + 0xaa, 0xa3, 0x58, 0x1d, 0x1e, 0x93, 0x5e, 0x0f, 0x30, 0x1a, 0xb8, 0xba, 0xb1, 0x76, 0x6c, 0xb4, + 0xd7, 0x5a, 0xe2, 0xd6, 0x51, 0x44, 0x33, 0xd5, 0x69, 0x76, 0xd0, 0xbb, 0x50, 0x74, 0x8e, 0xad, + 0x81, 0xa1, 0x29, 0x47, 0x6a, 0xfb, 0xa4, 0xa3, 0x1b, 0x46, 0xa8, 0x31, 0x5a, 0x60, 0x83, 0x9b, + 0x7c, 0x8c, 0xef, 0xd9, 0x9f, 0xa7, 0x00, 0xf9, 0xf2, 0xec, 0x0d, 0x5c, 0x95, 0xc6, 0xfb, 0x0a, + 0x24, 0x79, 0xa0, 0x61, 0x7b, 0xf4, 0xd6, 0xd4, 0x98, 0x1c, 0x6e, 0x04, 0xef, 0xcc, 0xc9, 0x9c, + 0x10, 0x7d, 0x3f, 0x78, 0xc9, 0x38, 0xf3, 0x8e, 0xec, 0xcc, 0x89, 0xdb, 0xc7, 0xa7, 0x00, 0x81, + 0x20, 0x95, 0xa6, 0x4c, 0xde, 0x9e, 0x39, 0x35, 0xd8, 0x99, 0x93, 0x03, 0xe4, 0xa8, 0x09, 0x85, + 0x7e, 0xc8, 0x83, 0xf1, 0xea, 0xe0, 0xfe, 0x4c, 0xee, 0x6e, 0x67, 0x4e, 0x1e, 0x21, 0x47, 0x3f, + 0x02, 0xd4, 0x1e, 0x33, 0x8e, 0x12, 0x7c, 0x8d, 0x94, 0xa3, 0x04, 0x3b, 0x73, 0xf2, 0x04, 0x36, + 0xe8, 0x73, 0xb8, 0xdd, 0x9b, 0xac, 0xc7, 0xbc, 0x4e, 0x58, 0x9b, 0x32, 0xc3, 0x14, 0xed, 0xdf, + 0x99, 0x93, 0xa7, 0x31, 0x44, 0x4f, 0x21, 0xe1, 0xb8, 0x24, 0x0d, 0x8c, 0xd1, 0x14, 0x7c, 0x7d, + 0x0a, 0xe7, 0x71, 0x1d, 0x59, 0x3b, 0x20, 0x64, 0x22, 0xf9, 0xa1, 0x3c, 0xd0, 0x73, 0xc8, 0x78, + 0x55, 0x34, 0xbf, 0x93, 0x78, 0x7f, 0x76, 0x86, 0x5e, 0xba, 0x29, 0x92, 0x51, 0x8f, 0x17, 0xaa, + 0x40, 0xb6, 0xc7, 0xd1, 0xfc, 0xb6, 0xe7, 0x0a, 0xef, 0x2d, 0x80, 0xe0, 0x40, 0x7d, 0x67, 0xe0, + 0x4b, 0x06, 0x41, 0x54, 0xa7, 0xa9, 0xb5, 0x6d, 0x19, 0x06, 0xb1, 0x0d, 0x9a, 0xf2, 0x78, 0xa9, + 0xb5, 0x80, 0x96, 0x3f, 0x81, 0x04, 0x5d, 0x13, 0x49, 0x69, 0x0f, 0x1b, 0x4f, 0x1b, 0xcd, 0xe7, + 0x0d, 0x96, 0xa2, 0x54, 0x6b, 0xbb, 0xb5, 0x56, 0x4d, 0x69, 0x36, 0x76, 0x49, 0x8a, 0xf2, 0x1a, + 0xdc, 0xe4, 0x80, 0x4a, 0xa3, 0xaa, 0x3c, 0x97, 0xeb, 0x62, 0x28, 0x5a, 0x5e, 0x0d, 0xe6, 0xcc, + 0x69, 0x88, 0x37, 0x9a, 0x8d, 0x9a, 0x34, 0x47, 0xb3, 0xe7, 0x6a, 0x55, 0x8a, 0xd0, 0xec, 0x59, + 0x6e, 0xee, 0x4b, 0x51, 0x66, 0x7d, 0x9b, 0x39, 0x00, 0xcd, 0xdb, 0x87, 0x27, 0xf1, 0x74, 0x52, + 0x4a, 0x95, 0xff, 0x3a, 0x02, 0x69, 0x12, 0xa8, 0xeb, 0x66, 0xc7, 0x42, 0xef, 0x43, 0xa6, 0xaf, + 0xda, 0xd8, 0x74, 0x7d, 0x4f, 0x2b, 0x1a, 0xd0, 0xe9, 0x7d, 0x3a, 0xe0, 0xf5, 0x47, 0xd3, 0x0c, + 0xb1, 0xae, 0xa1, 0x6d, 0x90, 0x38, 0x91, 0xd3, 0x3e, 0xc6, 0x3d, 0xd5, 0x8f, 0x3b, 0x77, 0xbc, + 0x16, 0x3f, 0x1d, 0x3f, 0xa0, 0xc3, 0x1e, 0x87, 0x42, 0x3f, 0x08, 0xbd, 0xa0, 0x4b, 0x29, 0x6e, + 0x82, 0xde, 0x86, 0xe2, 0x48, 0xa0, 0xbc, 0xa0, 0x2b, 0xb4, 0x42, 0xbb, 0x42, 0x31, 0xdf, 0xef, + 0x7b, 0x5d, 0xa1, 0x28, 0x6f, 0x08, 0xbd, 0xef, 0xb7, 0x7c, 0xd8, 0x01, 0xbf, 0xc6, 0xc3, 0xc3, + 0xfc, 0x05, 0xdd, 0x9e, 0x7d, 0x98, 0xef, 0x59, 0x9a, 0xde, 0x21, 0x45, 0x0b, 0xd1, 0x0e, 0x57, + 0xef, 0x61, 0x9e, 0xd2, 0xce, 0xe4, 0x3b, 0xa5, 0x20, 0x35, 0x19, 0x44, 0xbb, 0x50, 0xd0, 0x88, + 0xd7, 0x20, 0x75, 0x21, 0xeb, 0xd5, 0xdc, 0xa4, 0x3e, 0x7d, 0x79, 0x8a, 0x26, 0x8b, 0xc3, 0x12, + 0xa5, 0xb3, 0x20, 0x66, 0xfd, 0x9c, 0xd0, 0x09, 0xc6, 0x67, 0x3c, 0xc1, 0x23, 0x58, 0x1c, 0x98, + 0xf8, 0x65, 0xdf, 0x72, 0xb0, 0xa6, 0x8c, 0x9d, 0xe5, 0x2a, 0xe5, 0x72, 0x9f, 0x73, 0xb9, 0x7d, + 0x28, 0x30, 0x27, 0x1e, 0xea, 0xed, 0xc1, 0xc4, 0x61, 0x0d, 0x3d, 0x86, 0x94, 0x68, 0xdb, 0xa6, + 0xe9, 0xfa, 0x66, 0xf5, 0xf1, 0xa2, 0x66, 0xe5, 0xd4, 0x68, 0x1b, 0x0a, 0x26, 0x7e, 0x19, 0xbc, + 0x95, 0xc8, 0x84, 0xcc, 0x33, 0xd7, 0xc0, 0x2f, 0x27, 0x5f, 0x49, 0xe4, 0x4c, 0x7f, 0x44, 0x43, + 0x4d, 0x48, 0x77, 0xd4, 0x9e, 0x6e, 0xe8, 0xd8, 0x29, 0xdd, 0xa2, 0x12, 0xbd, 0x7b, 0xa1, 0x44, + 0xa3, 0x17, 0x38, 0xc2, 0x9e, 0x05, 0x13, 0x4f, 0x30, 0x0a, 0x18, 0x12, 0xc1, 0x6e, 0x8f, 0x0b, + 0x26, 0x2e, 0x70, 0x42, 0x97, 0x39, 0x54, 0x30, 0xfe, 0xa5, 0xa1, 0x4f, 0x21, 0x1f, 0xce, 0x1b, + 0xe0, 0x0a, 0x79, 0x43, 0xae, 0x1f, 0x4c, 0x1a, 0xb6, 0x21, 0x25, 0x12, 0x86, 0xec, 0x15, 0x12, + 0x06, 0x41, 0x8c, 0x36, 0x49, 0x36, 0xf6, 0xd2, 0xf5, 0xcb, 0x93, 0x9c, 0xdf, 0x2b, 0x3d, 0x3f, + 0x5b, 0xce, 0x92, 0x15, 0x4e, 0xb8, 0x14, 0xc9, 0x9a, 0x1e, 0x5c, 0x43, 0x4f, 0x00, 0xbc, 0x27, + 0x4a, 0x0e, 0xbd, 0x0b, 0x9c, 0xde, 0x31, 0xda, 0x17, 0x88, 0xbe, 0x48, 0x72, 0x80, 0x1a, 0xed, + 0x41, 0x46, 0xb8, 0x5c, 0xd6, 0x1b, 0x9c, 0x1e, 0x0d, 0xc7, 0x03, 0x80, 0x70, 0xfb, 0x1e, 0x07, + 0x52, 0xa0, 0x1b, 0x58, 0x75, 0x30, 0x6f, 0x38, 0x3d, 0x9a, 0x31, 0x5b, 0x67, 0x3a, 0xbe, 0x75, + 0xac, 0x9a, 0x5d, 0xbc, 0x4b, 0xe8, 0x37, 0xa3, 0xa5, 0x88, 0xcc, 0x58, 0xa1, 0x06, 0x48, 0x74, + 0xcb, 0x82, 0xf1, 0x44, 0xa2, 0xbb, 0xf6, 0x86, 0xf0, 0x8e, 0x64, 0xd7, 0xa6, 0xc6, 0x14, 0xaa, + 0x53, 0x7b, 0x7e, 0x5c, 0xf9, 0x2e, 0x14, 0x3a, 0x96, 0xdd, 0x53, 0x5d, 0x45, 0x38, 0xaf, 0x79, + 0xbf, 0xf3, 0xfd, 0xd5, 0xd9, 0x72, 0x7e, 0x9b, 0x8e, 0x0a, 0xc7, 0x95, 0xef, 0x04, 0x3f, 0xd1, + 0xa6, 0x08, 0xbf, 0x37, 0x68, 0xb4, 0x7c, 0xf3, 0x6b, 0x37, 0x6b, 0x42, 0xd4, 0x7d, 0x07, 0x0a, + 0x56, 0xa7, 0x63, 0xe8, 0x26, 0x56, 0x6c, 0xac, 0x3a, 0x96, 0x59, 0x7a, 0x33, 0xe0, 0x7d, 0xf3, + 0x7c, 0x4c, 0xa6, 0x43, 0xa8, 0x01, 0x49, 0xda, 0xa8, 0x70, 0x4a, 0x0b, 0xf4, 0x78, 0xae, 0xd8, + 0xf4, 0x90, 0x39, 0x17, 0x74, 0x0f, 0xe0, 0x85, 0x8e, 0x4f, 0x95, 0x2f, 0x06, 0xd8, 0x1e, 0x96, + 0x4a, 0xc1, 0x5e, 0x12, 0x81, 0x7f, 0x4a, 0xc0, 0xe8, 0xdb, 0xb0, 0xa0, 0x3b, 0x4a, 0x30, 0x05, + 0x51, 0xc8, 0x60, 0xe9, 0xed, 0x40, 0x1c, 0x46, 0xba, 0x33, 0x9a, 0xbe, 0xa0, 0xf7, 0x20, 0xa3, + 0xe1, 0x3e, 0x36, 0x35, 0xa7, 0x69, 0x96, 0x5e, 0xa3, 0x25, 0xf1, 0x8d, 0xf3, 0xb3, 0xe5, 0x4c, + 0x55, 0x00, 0xb9, 0x93, 0xf3, 0xb1, 0xd0, 0x27, 0x50, 0xf0, 0x3e, 0x5a, 0xc3, 0x3e, 0x76, 0x4a, + 0xef, 0x52, 0xba, 0x12, 0x39, 0xd8, 0x6a, 0x68, 0x44, 0x84, 0xbd, 0x30, 0x3e, 0xfa, 0x1c, 0x72, + 0x0c, 0x82, 0xb5, 0xa6, 0xb9, 0x39, 0x2c, 0x2d, 0xd2, 0x7d, 0x7a, 0x38, 0xe3, 0x3e, 0xf9, 0x9d, + 0x54, 0xef, 0xce, 0xae, 0x1a, 0xe0, 0x26, 0x87, 0x78, 0xa3, 0xff, 0x0f, 0x39, 0xa1, 0x87, 0x4f, + 0xac, 0x23, 0xa7, 0xf4, 0x8d, 0x0b, 0x2f, 0xc6, 0x46, 0xe7, 0xda, 0xf3, 0x49, 0x85, 0x97, 0x09, + 0x72, 0x43, 0x2d, 0x20, 0xe5, 0xa3, 0x88, 0x1c, 0x6d, 0x6a, 0x0f, 0xca, 0xe7, 0xd6, 0x11, 0x51, + 0xf9, 0xb5, 0x95, 0xc8, 0x6a, 0xcc, 0x4b, 0x08, 0x16, 0x1a, 0xf8, 0x34, 0x68, 0x35, 0x4f, 0xac, + 0xa3, 0x7a, 0x55, 0x5e, 0x30, 0xc7, 0xa1, 0x1a, 0xfa, 0x0c, 0xf2, 0xde, 0x9b, 0x05, 0xab, 0xef, + 0x3a, 0xa5, 0x3b, 0x17, 0x36, 0x90, 0xc6, 0x8c, 0x93, 0xd3, 0x36, 0xfb, 0xf4, 0x06, 0x33, 0xf0, + 0x85, 0xee, 0x42, 0x46, 0xb3, 0xad, 0x3e, 0x8b, 0xe1, 0xaf, 0x53, 0x01, 0x45, 0xfb, 0xd3, 0xb6, + 0xfa, 0x34, 0x38, 0x2b, 0x50, 0xb0, 0x71, 0xdf, 0x50, 0xdb, 0xb8, 0x47, 0x82, 0xa2, 0xd5, 0x29, + 0x2d, 0xd1, 0xd9, 0x37, 0x66, 0x3e, 0x1e, 0x8f, 0x58, 0xd8, 0x47, 0x80, 0x5f, 0xb3, 0x83, 0x0e, + 0x01, 0xd4, 0x81, 0xa6, 0xbb, 0x4a, 0xcf, 0xd2, 0x70, 0x69, 0xf9, 0xc2, 0xd7, 0x46, 0xa3, 0xcc, + 0x2b, 0x84, 0x70, 0xcf, 0xd2, 0xb0, 0x77, 0xe7, 0x2d, 0x00, 0xe8, 0x3d, 0xc8, 0xd2, 0xa5, 0xf1, + 0xdd, 0x5f, 0xa1, 0x8b, 0x9b, 0xe7, 0xbb, 0x9f, 0xa9, 0xda, 0x56, 0x9f, 0x6d, 0x39, 0xdd, 0x00, + 0xb6, 0xcf, 0x0e, 0xe4, 0xba, 0x6d, 0xc5, 0x77, 0xa7, 0x77, 0xa9, 0x6e, 0x7c, 0x3c, 0xa3, 0x2c, + 0x8f, 0xb7, 0x26, 0x38, 0xd8, 0x1b, 0x22, 0x2e, 0x3c, 0xde, 0x12, 0x30, 0x47, 0xce, 0x76, 0xdb, + 0xde, 0x07, 0x29, 0xb9, 0x59, 0xa7, 0x9c, 0x1b, 0x74, 0x39, 0x58, 0x72, 0xb3, 0x11, 0x66, 0xd2, + 0x0d, 0xe0, 0x2d, 0x75, 0x85, 0x96, 0xab, 0xec, 0xcc, 0xee, 0xcd, 0x9e, 0x77, 0x15, 0x18, 0x75, + 0xc5, 0x69, 0x76, 0xe8, 0xc1, 0xb6, 0x21, 0x67, 0x0d, 0xdc, 0x23, 0x6b, 0x60, 0x6a, 0x4a, 0xe7, + 0xc4, 0x29, 0xbd, 0x41, 0x57, 0x7b, 0xa9, 0xc6, 0xa9, 0xb7, 0xba, 0x26, 0x67, 0xb4, 0xfd, 0xd4, + 0x91, 0xb3, 0x82, 0xeb, 0xf6, 0x89, 0x83, 0x7e, 0x02, 0x59, 0xdd, 0xf4, 0xe7, 0xb8, 0x7f, 0xf9, + 0x39, 0x90, 0xa8, 0x39, 0xea, 0xa6, 0x37, 0x05, 0x70, 0x9e, 0x64, 0x86, 0x9f, 0x45, 0x60, 0xe5, + 0x6b, 0x1a, 0xae, 0x4e, 0xe9, 0x9d, 0x0b, 0xef, 0xab, 0x67, 0xe8, 0xb8, 0xbe, 0x7e, 0x51, 0xc7, + 0xd5, 0x41, 0x65, 0xc8, 0xb8, 0xb8, 0xd7, 0xb7, 0x6c, 0xd5, 0x1e, 0x96, 0xde, 0x0a, 0x3e, 0x41, + 0xf0, 0xc0, 0xe8, 0xc7, 0x50, 0x1c, 0x6d, 0x89, 0x3d, 0xb8, 0x46, 0x4b, 0x4c, 0x2e, 0x84, 0xdb, + 0x7f, 0x68, 0x8d, 0x16, 0x21, 0xec, 0xa6, 0x47, 0x51, 0x0d, 0x43, 0x39, 0x1a, 0x96, 0xbe, 0x19, + 0x6c, 0x47, 0x78, 0xa3, 0x15, 0xc3, 0xd8, 0x1c, 0xa2, 0xfb, 0x90, 0xd5, 0x1d, 0xc5, 0xc6, 0x7d, + 0x55, 0xb7, 0xb1, 0x56, 0x5a, 0x0f, 0xa0, 0x82, 0xee, 0xc8, 0x1c, 0xbe, 0xf8, 0xab, 0x08, 0xcc, + 0x8f, 0x85, 0x77, 0xf4, 0x63, 0x48, 0x99, 0x96, 0x16, 0x78, 0x43, 0x52, 0xe3, 0xc7, 0x94, 0x6c, + 0x58, 0x1a, 0x7b, 0x42, 0xf2, 0x7e, 0x57, 0x77, 0x8f, 0x07, 0x47, 0x6b, 0x6d, 0xab, 0xb7, 0xee, + 0x2d, 0x50, 0x3b, 0xf2, 0xff, 0x5e, 0xef, 0x9f, 0x74, 0xd7, 0xe9, 0x5f, 0xfd, 0xa3, 0x35, 0x46, + 0x26, 0x27, 0x09, 0xd7, 0xba, 0x86, 0xde, 0x85, 0x22, 0x7e, 0xd9, 0xd7, 0xed, 0x40, 0x89, 0x11, + 0x0d, 0xb8, 0xa7, 0x82, 0x3f, 0x48, 0x74, 0x99, 0xdf, 0xd6, 0xff, 0x26, 0x0a, 0xc5, 0x91, 0xa8, + 0x49, 0xca, 0x23, 0xda, 0xc9, 0x0a, 0x95, 0x47, 0x04, 0x72, 0xc1, 0x93, 0x90, 0xe0, 0x3b, 0xbf, + 0xd8, 0x75, 0xdf, 0xf9, 0x85, 0xdf, 0x1f, 0x25, 0x2e, 0xf1, 0xfe, 0xe8, 0x43, 0xb8, 0xa5, 0x3b, + 0x8a, 0x69, 0x99, 0xe2, 0x1e, 0xc2, 0xeb, 0xcd, 0x04, 0xdf, 0xce, 0xdd, 0xd0, 0x9d, 0x86, 0x65, + 0xb2, 0x1b, 0x08, 0x6f, 0xd5, 0xfe, 0x33, 0xbb, 0xd4, 0xf8, 0x33, 0x3b, 0xaf, 0x95, 0x1f, 0x97, + 0x12, 0x8b, 0xff, 0x1c, 0x81, 0x4c, 0xf0, 0x25, 0x7b, 0x34, 0xdc, 0x60, 0x1c, 0x2b, 0x19, 0xaf, + 0xf8, 0x16, 0x28, 0xbc, 0x0b, 0xb1, 0x4b, 0xec, 0xc2, 0x5d, 0x48, 0x1c, 0x0d, 0x45, 0x29, 0x97, + 0xde, 0xcc, 0xf1, 0xd9, 0xe2, 0x9b, 0xa4, 0x6c, 0x88, 0x1f, 0x0d, 0xc5, 0xbb, 0xaa, 0xc5, 0x3f, + 0x86, 0x6c, 0x20, 0x3c, 0x8f, 0x36, 0x30, 0x22, 0x57, 0x68, 0x60, 0xbc, 0x01, 0x49, 0x1e, 0x3d, + 0x98, 0xee, 0xe5, 0x39, 0x75, 0x82, 0x45, 0x8e, 0xc4, 0xe7, 0x24, 0x6a, 0xf0, 0xd9, 0xff, 0x3b, + 0x06, 0xb9, 0x60, 0xa0, 0x25, 0x2e, 0x41, 0x37, 0xdb, 0x36, 0x8d, 0x72, 0x74, 0xf6, 0x98, 0xf7, + 0x2a, 0x49, 0x80, 0x49, 0xf8, 0xed, 0xe9, 0xa6, 0x42, 0x5f, 0xb4, 0x84, 0xf4, 0x3b, 0xdd, 0xd3, + 0xcd, 0x67, 0x04, 0x4a, 0x51, 0xd4, 0x97, 0x1c, 0x25, 0x16, 0x42, 0x51, 0x5f, 0x32, 0x94, 0x45, + 0x9a, 0xd1, 0xda, 0x2e, 0xdd, 0xa1, 0x58, 0x20, 0x53, 0xb5, 0xdd, 0xe0, 0xe3, 0xc4, 0xc4, 0xa4, + 0xc7, 0x89, 0x26, 0x14, 0xfc, 0xd4, 0xe2, 0xd4, 0xc4, 0x36, 0xbf, 0x95, 0xa8, 0x5c, 0x21, 0xb7, + 0xf0, 0x3f, 0x08, 0x23, 0x11, 0xec, 0x9d, 0x20, 0x90, 0x24, 0xaf, 0x6d, 0xb5, 0x7d, 0x8c, 0x15, + 0x47, 0xff, 0x29, 0xeb, 0x1a, 0x78, 0xdb, 0x42, 0xe1, 0x07, 0xfa, 0x4f, 0xf1, 0xe2, 0x5f, 0x45, + 0x20, 0x1f, 0xe2, 0x85, 0xea, 0x50, 0xa4, 0xd2, 0x8d, 0x75, 0xc1, 0xef, 0x7a, 0x6f, 0xdb, 0xc9, + 0xf0, 0xc4, 0x9a, 0x37, 0x6f, 0x05, 0x86, 0x34, 0x92, 0xae, 0x32, 0x56, 0xde, 0x23, 0xb8, 0xb0, + 0x1a, 0xe7, 0x28, 0xa7, 0xf0, 0x4b, 0xb8, 0x9c, 0xe5, 0xc3, 0xb4, 0x60, 0xcf, 0x7e, 0xd1, 0x84, + 0x6c, 0x20, 0xc1, 0x99, 0xc1, 0x7e, 0xbe, 0x03, 0x71, 0xcf, 0x9b, 0xcd, 0xda, 0x6c, 0x76, 0x7d, + 0x17, 0xf7, 0x8b, 0x08, 0x2c, 0x4c, 0x4a, 0x34, 0x42, 0x76, 0xc9, 0xb4, 0x6d, 0x26, 0xbb, 0xbc, + 0x17, 0x4c, 0x00, 0x99, 0x06, 0x8a, 0xc7, 0x13, 0x7e, 0x0a, 0xf8, 0xa6, 0x67, 0x07, 0x4c, 0x01, + 0x8b, 0x21, 0x3b, 0x20, 0x85, 0x5e, 0xd0, 0x12, 0xfe, 0x2d, 0x06, 0x85, 0x91, 0x4b, 0x9a, 0x67, + 0x90, 0xec, 0x1a, 0xd6, 0x91, 0x6a, 0xf0, 0xe6, 0xf6, 0x77, 0xaf, 0x14, 0xf1, 0xd6, 0x1e, 0x53, + 0x1e, 0x3b, 0x73, 0x32, 0xe7, 0x86, 0x1c, 0x98, 0x0f, 0xde, 0xc6, 0xb0, 0x1f, 0xe1, 0xb0, 0x9d, + 0xad, 0x5d, 0x6d, 0x0a, 0xff, 0xba, 0x86, 0x22, 0xee, 0xcc, 0xc9, 0x45, 0x3b, 0x0c, 0x42, 0x3d, + 0x28, 0x8e, 0x5c, 0x01, 0xf1, 0x9b, 0x83, 0xad, 0xeb, 0x4e, 0x29, 0x5b, 0xa7, 0x3b, 0x34, 0x3d, + 0x0e, 0x00, 0x16, 0xff, 0x1f, 0x14, 0x47, 0x84, 0x22, 0xe7, 0xc1, 0x70, 0x78, 0x54, 0x2b, 0x10, + 0x1f, 0xc6, 0x90, 0x1a, 0x6a, 0x0f, 0xcb, 0x7c, 0x94, 0x9f, 0xc7, 0x7d, 0xc8, 0x87, 0xa6, 0x40, + 0x05, 0x88, 0xaa, 0xec, 0xa5, 0x61, 0x46, 0x8e, 0xaa, 0xfc, 0x8d, 0xe2, 0x62, 0x01, 0x92, 0x6c, + 0x7f, 0x83, 0xfa, 0xbd, 0x09, 0x90, 0x16, 0x69, 0x46, 0x79, 0x15, 0x32, 0x5e, 0xbe, 0x8d, 0x72, + 0x90, 0xae, 0xd6, 0x0f, 0x2a, 0x9b, 0xbb, 0xb5, 0xaa, 0x34, 0x87, 0xf2, 0x90, 0x91, 0x6b, 0x95, + 0x2a, 0x6d, 0xcd, 0x4a, 0x91, 0x8f, 0xd2, 0x7f, 0xfa, 0x8b, 0xe5, 0x08, 0x0f, 0x32, 0x49, 0x29, + 0xf5, 0x24, 0x9e, 0x46, 0xd2, 0x8d, 0xf2, 0x57, 0x69, 0x40, 0x55, 0xd5, 0x55, 0xc9, 0xa6, 0x5c, + 0xa2, 0x81, 0x19, 0xbd, 0xc0, 0x9a, 0x26, 0xf6, 0x22, 0xe3, 0xd7, 0xe9, 0x45, 0x5e, 0xa9, 0x25, + 0x3a, 0xde, 0xc0, 0x4c, 0x5e, 0xa3, 0x81, 0x19, 0x6e, 0x0f, 0xc5, 0xae, 0xd5, 0x1e, 0x7a, 0x06, + 0x29, 0x56, 0x8c, 0xb2, 0xa7, 0x68, 0xd3, 0xbb, 0x0f, 0xe3, 0x07, 0xc3, 0x9b, 0x3a, 0x4e, 0xcd, + 0x74, 0xed, 0xa1, 0xf7, 0x6c, 0x86, 0xc1, 0xfc, 0x2e, 0x4a, 0xfa, 0x55, 0x76, 0x51, 0x32, 0xd3, + 0xbb, 0x28, 0x3f, 0x02, 0x6e, 0x17, 0x22, 0x77, 0x86, 0x0b, 0x5f, 0x90, 0x4c, 0x58, 0x0e, 0x33, + 0x02, 0x9e, 0x3c, 0xe7, 0xec, 0xc0, 0xd7, 0x68, 0x2a, 0x9c, 0x9d, 0x92, 0x0a, 0xb7, 0x00, 0x78, + 0x33, 0xd7, 0xec, 0x58, 0x33, 0xf8, 0xfa, 0x25, 0x48, 0x11, 0x1f, 0xda, 0xc7, 0x4c, 0x89, 0xbd, + 0xe0, 0xcb, 0x81, 0xdc, 0xf0, 0xfa, 0x90, 0x0b, 0xee, 0x34, 0x92, 0x20, 0x76, 0x82, 0x87, 0xdc, + 0x3e, 0xc9, 0x9f, 0xe8, 0x09, 0x24, 0xfc, 0x14, 0x61, 0xfa, 0xa3, 0xf0, 0xa9, 0x47, 0x48, 0xc4, + 0x95, 0x19, 0x8b, 0x8f, 0xa2, 0x8f, 0x22, 0x8b, 0xff, 0x19, 0x81, 0x5c, 0x70, 0x37, 0x50, 0x03, + 0xf2, 0xce, 0xc0, 0x7e, 0xa1, 0xbf, 0x50, 0x0d, 0xa5, 0x6b, 0xa9, 0x06, 0x9d, 0xa8, 0xb0, 0x71, + 0x6f, 0xda, 0xa3, 0x2a, 0x8e, 0xfb, 0xd8, 0x52, 0x0d, 0xd1, 0x06, 0x71, 0x02, 0x30, 0xf4, 0xa1, + 0x77, 0xf9, 0xc7, 0x6f, 0xcb, 0xf9, 0x45, 0x32, 0xe2, 0xb6, 0x14, 0x74, 0x56, 0xa2, 0xd3, 0xcb, + 0x40, 0x24, 0x3c, 0xf3, 0x73, 0xc6, 0xf4, 0xc1, 0xb3, 0x68, 0xe1, 0x7b, 0xe1, 0x99, 0xe1, 0xd5, + 0xcc, 0x41, 0xcf, 0x0f, 0xcf, 0xb6, 0x0f, 0xf3, 0x7f, 0x88, 0x10, 0x91, 0xa2, 0xbe, 0x23, 0x2a, + 0xff, 0x4f, 0x0e, 0x0a, 0xad, 0x61, 0x7f, 0x92, 0xe3, 0x89, 0x4d, 0x71, 0x3c, 0xf1, 0xd9, 0x6e, + 0x4e, 0x32, 0xd7, 0xbb, 0x39, 0x81, 0x57, 0x7b, 0x73, 0x92, 0x7d, 0x65, 0x8e, 0xa7, 0x70, 0x2d, + 0xc7, 0xf3, 0xca, 0xee, 0xd1, 0xa2, 0x57, 0xb8, 0x47, 0xfb, 0x1e, 0xe4, 0x55, 0xdb, 0x56, 0x87, + 0xfc, 0x97, 0x32, 0x1a, 0xf5, 0x52, 0xfc, 0x8c, 0xce, 0xcf, 0x96, 0xb3, 0x15, 0x32, 0x48, 0x7f, + 0x1c, 0x23, 0x38, 0x64, 0x55, 0x0f, 0xa4, 0xf9, 0xce, 0x2d, 0xff, 0x2a, 0x9d, 0x5b, 0x71, 0xba, + 0x73, 0xab, 0x42, 0x9c, 0xfe, 0x14, 0x27, 0x41, 0xe7, 0x9b, 0xb6, 0xe5, 0x61, 0xf5, 0x5d, 0x0b, + 0xfc, 0x1a, 0x87, 0x52, 0xa3, 0x9f, 0xc0, 0xa2, 0x78, 0xef, 0x4a, 0xf4, 0xc1, 0xbf, 0xe7, 0x0c, + 0xfc, 0xd0, 0xa9, 0x7c, 0x7e, 0xb6, 0x5c, 0x92, 0x7d, 0x2c, 0x9f, 0x1f, 0x2b, 0xc1, 0xc8, 0x5e, + 0x94, 0xec, 0x89, 0xe3, 0x9a, 0x83, 0x7e, 0x00, 0x39, 0x6a, 0x95, 0x3d, 0xdc, 0x3b, 0xc2, 0xb6, + 0x88, 0x72, 0x0f, 0x67, 0x93, 0x97, 0x98, 0xe7, 0x1e, 0x25, 0x14, 0xdd, 0x2d, 0xec, 0x41, 0x1c, + 0xf4, 0x10, 0x12, 0xaa, 0xa1, 0xd3, 0x30, 0xf5, 0x75, 0x3f, 0x47, 0x63, 0x88, 0xec, 0x9d, 0x70, + 0x30, 0x22, 0x48, 0x17, 0xf7, 0x25, 0xc3, 0xd2, 0xcc, 0x1e, 0x0d, 0xe6, 0xa7, 0x44, 0x83, 0x9f, + 0xc7, 0x00, 0xfc, 0x35, 0xa1, 0xef, 0xc0, 0xed, 0xfe, 0xf1, 0xd0, 0xd1, 0xdb, 0xaa, 0x41, 0x68, + 0x6d, 0xec, 0x60, 0x93, 0xe5, 0xe6, 0x54, 0xfd, 0x73, 0xf2, 0x2d, 0x31, 0x2c, 0x87, 0x46, 0xd1, + 0xc7, 0x70, 0xcb, 0xb0, 0xba, 0x93, 0xe8, 0x82, 0x9d, 0x89, 0x9b, 0x1c, 0x67, 0x84, 0x58, 0x25, + 0xf5, 0x54, 0x5f, 0x3d, 0xd2, 0x0d, 0xbf, 0x59, 0xf1, 0xf1, 0x65, 0xcf, 0x63, 0x6d, 0xcb, 0x63, + 0x21, 0xd6, 0xe9, 0x33, 0x45, 0x3f, 0x1e, 0x7f, 0x62, 0xf0, 0xd1, 0xa5, 0x67, 0x98, 0xfe, 0xd2, + 0xa0, 0xfc, 0x06, 0x80, 0x3f, 0x3f, 0xbd, 0xb9, 0xdf, 0xdd, 0xf5, 0x53, 0x4a, 0xfe, 0x06, 0xa0, + 0xfc, 0xe0, 0x6b, 0x2e, 0xfa, 0x01, 0x92, 0x72, 0x6d, 0xaf, 0xf9, 0xac, 0x26, 0xae, 0xfa, 0x17, + 0x9b, 0x23, 0x41, 0x6e, 0x3c, 0x28, 0x45, 0x66, 0x0c, 0x4a, 0xfc, 0xf6, 0xfd, 0x3d, 0x88, 0x13, + 0x9b, 0x23, 0xb3, 0xd7, 0x1a, 0x87, 0x7b, 0xd2, 0x1c, 0xca, 0x40, 0xa2, 0xb2, 0x5b, 0xaf, 0x1c, + 0x48, 0x11, 0xb4, 0x00, 0xd2, 0xde, 0xe1, 0x6e, 0xab, 0x2e, 0xd7, 0x1e, 0xd7, 0x9b, 0x0d, 0x85, + 0x22, 0x04, 0xe3, 0xcf, 0x3f, 0xc5, 0x41, 0x62, 0xfe, 0x69, 0x42, 0x04, 0x8a, 0x5e, 0xe1, 0xee, + 0xfe, 0x0f, 0x9e, 0x81, 0x4d, 0x8c, 0x5e, 0x89, 0x57, 0x94, 0x6b, 0x27, 0xaf, 0x91, 0x6b, 0xa7, + 0x5e, 0xd5, 0x63, 0x81, 0x59, 0xc3, 0x54, 0x38, 0x4e, 0xc6, 0xaf, 0x15, 0x27, 0x47, 0x9c, 0x0d, + 0x4c, 0x76, 0x36, 0x01, 0x45, 0xfa, 0x65, 0x14, 0x20, 0xa0, 0x42, 0xdf, 0x0f, 0xfe, 0xdb, 0x13, + 0xd3, 0x6f, 0xb5, 0x47, 0x6a, 0xd0, 0x9d, 0x39, 0xf1, 0x2f, 0x53, 0x3c, 0x86, 0xb4, 0xc6, 0xf3, + 0x46, 0x9e, 0x5e, 0xbe, 0x3d, 0x73, 0x7a, 0xb9, 0x33, 0x27, 0x7b, 0xc4, 0xe8, 0xe3, 0xd0, 0xcf, + 0x89, 0xef, 0xcf, 0xe4, 0x21, 0x76, 0xc4, 0xcf, 0x09, 0x2a, 0x90, 0x64, 0x11, 0x9f, 0xef, 0xe6, + 0xd4, 0x5f, 0xa3, 0x8e, 0x58, 0xd0, 0xce, 0x9c, 0xcc, 0x09, 0x79, 0xbd, 0x9a, 0x82, 0xc4, 0xc0, + 0xd4, 0x2d, 0xf3, 0x81, 0x1c, 0x7c, 0x02, 0x2f, 0x9a, 0xb3, 0xc4, 0xa9, 0xd0, 0xbf, 0x55, 0x17, + 0x6b, 0xec, 0xa5, 0xd1, 0xa1, 0xf9, 0xc2, 0x03, 0x44, 0x50, 0x01, 0x80, 0x8f, 0xeb, 0x66, 0x57, + 0x8a, 0xd2, 0x2a, 0x97, 0x24, 0xeb, 0xe4, 0x2b, 0xf6, 0xe0, 0x7b, 0x20, 0x8d, 0xfe, 0x1c, 0x36, + 0xe0, 0x8a, 0xe6, 0x21, 0xbf, 0xf7, 0x6c, 0x6b, 0xab, 0x55, 0xdf, 0xab, 0x1d, 0xb4, 0x2a, 0x7b, + 0xfb, 0xec, 0x6d, 0x75, 0x8b, 0x94, 0xc8, 0xcd, 0x7a, 0x55, 0x8a, 0x3e, 0xf8, 0x1e, 0x14, 0x47, + 0xac, 0x91, 0x78, 0xad, 0xfd, 0xc3, 0xcd, 0xdd, 0xfa, 0xd6, 0xc4, 0x37, 0x4b, 0x28, 0x0b, 0xa9, + 0xe6, 0xf6, 0xf6, 0x6e, 0xbd, 0x51, 0x93, 0x62, 0x0f, 0x3e, 0x80, 0x5c, 0x30, 0xf1, 0x46, 0x12, + 0xe4, 0x7e, 0xd8, 0x6c, 0xd4, 0x94, 0xed, 0x4a, 0x7d, 0xf7, 0x50, 0x26, 0x12, 0x20, 0x28, 0x70, + 0xf7, 0x23, 0x60, 0x91, 0xcd, 0xd5, 0xdf, 0xfe, 0xc7, 0xd2, 0xdc, 0x6f, 0xcf, 0x97, 0x22, 0xbf, + 0x3b, 0x5f, 0x8a, 0xfc, 0xfe, 0x7c, 0x29, 0xf2, 0xef, 0xe7, 0x4b, 0x91, 0xbf, 0xf8, 0x72, 0x69, + 0xee, 0x77, 0x5f, 0x2e, 0xcd, 0xfd, 0xfe, 0xcb, 0xa5, 0xb9, 0x1f, 0x26, 0xd9, 0xbf, 0x9a, 0xf2, + 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x1a, 0x73, 0xfc, 0xe8, 0xa0, 0x45, 0x00, 0x00, } func (this *ForeignKeyReference) Equal(that interface{}) bool { @@ -5346,6 +5384,9 @@ func (this *TableDescriptor) Equal(that interface{}) bool { if this.PartitionAllBy != that1.PartitionAllBy { return false } + if this.IsRepaired != that1.IsRepaired { + return false + } return true } func (this *TableDescriptor_SchemaChangeLease) Equal(that interface{}) bool { @@ -5854,6 +5895,9 @@ func (this *DatabaseDescriptor) Equal(that interface{}) bool { if !this.RegionConfig.Equal(that1.RegionConfig) { return false } + if this.IsRepaired != that1.IsRepaired { + return false + } return true } func (this *DatabaseDescriptor_SchemaInfo) Equal(that interface{}) bool { @@ -5995,6 +6039,9 @@ func (this *TypeDescriptor) Equal(that interface{}) bool { if !this.RegionConfig.Equal(that1.RegionConfig) { return false } + if this.IsRepaired != that1.IsRepaired { + return false + } return true } func (this *TypeDescriptor_EnumMember) Equal(that interface{}) bool { @@ -6105,6 +6152,9 @@ func (this *SchemaDescriptor) Equal(that interface{}) bool { if !this.Privileges.Equal(that1.Privileges) { return false } + if this.IsRepaired != that1.IsRepaired { + return false + } return true } func (this *Descriptor) Equal(that interface{}) bool { @@ -7545,6 +7595,16 @@ func (m *TableDescriptor) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i-- + if m.IsRepaired { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x2 + i-- + dAtA[i] = 0xf8 i = encodeVarintStructured(dAtA, i, uint64(m.NewSchemaChangeJobID)) i-- dAtA[i] = 0x2 @@ -8476,6 +8536,14 @@ func (m *DatabaseDescriptor) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i-- + if m.IsRepaired { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x58 if m.RegionConfig != nil { { size, err := m.RegionConfig.MarshalToSizedBuffer(dAtA[:i]) @@ -8663,6 +8731,16 @@ func (m *TypeDescriptor) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i-- + if m.IsRepaired { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x88 if m.RegionConfig != nil { { size, err := m.RegionConfig.MarshalToSizedBuffer(dAtA[:i]) @@ -8869,6 +8947,14 @@ func (m *SchemaDescriptor) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i-- + if m.IsRepaired { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x50 i -= len(m.OfflineReason) copy(dAtA[i:], m.OfflineReason) i = encodeVarintStructured(dAtA, i, uint64(len(m.OfflineReason))) @@ -9710,6 +9796,7 @@ func (m *TableDescriptor) Size() (n int) { } } n += 2 + sovStructured(uint64(m.NewSchemaChangeJobID)) + n += 3 return n } @@ -9946,6 +10033,7 @@ func (m *DatabaseDescriptor) Size() (n int) { l = m.RegionConfig.Size() n += 1 + l + sovStructured(uint64(l)) } + n += 2 return n } @@ -10021,6 +10109,7 @@ func (m *TypeDescriptor) Size() (n int) { l = m.RegionConfig.Size() n += 2 + l + sovStructured(uint64(l)) } + n += 3 return n } @@ -10078,6 +10167,7 @@ func (m *SchemaDescriptor) Size() (n int) { n += 1 + sovStructured(uint64(m.State)) l = len(m.OfflineReason) n += 1 + l + sovStructured(uint64(l)) + n += 2 return n } @@ -16148,6 +16238,26 @@ func (m *TableDescriptor) Unmarshal(dAtA []byte) error { break } } + case 47: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IsRepaired", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStructured + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IsRepaired = bool(v != 0) default: iNdEx = preIndex skippy, err := skipStructured(dAtA[iNdEx:]) @@ -18062,6 +18172,26 @@ func (m *DatabaseDescriptor) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IsRepaired", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStructured + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IsRepaired = bool(v != 0) default: iNdEx = preIndex skippy, err := skipStructured(dAtA[iNdEx:]) @@ -18803,6 +18933,26 @@ func (m *TypeDescriptor) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 17: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IsRepaired", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStructured + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IsRepaired = bool(v != 0) default: iNdEx = preIndex skippy, err := skipStructured(dAtA[iNdEx:]) @@ -19332,6 +19482,26 @@ func (m *SchemaDescriptor) Unmarshal(dAtA []byte) error { } m.OfflineReason = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IsRepaired", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStructured + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IsRepaired = bool(v != 0) default: iNdEx = preIndex skippy, err := skipStructured(dAtA[iNdEx:]) diff --git a/pkg/sql/catalog/descpb/structured.proto b/pkg/sql/catalog/descpb/structured.proto index a305aba36d1b..ece8ffc198b7 100644 --- a/pkg/sql/catalog/descpb/structured.proto +++ b/pkg/sql/catalog/descpb/structured.proto @@ -1190,6 +1190,9 @@ message TableDescriptor { // This means that all indexes implicitly inherit all partitioning // from the PARTITION ALL BY clause. optional bool partition_all_by = 44 [(gogoproto.nullable)=false]; + + // IsRepaired is set if the descriptor has been upgrade through fix_descriptor_migration. + optional bool is_repaired = 47 [(gogoproto.nullable)=false]; } // SurvivalGoal is the survival goal for a database. @@ -1254,6 +1257,9 @@ message DatabaseDescriptor { } // RegionConfig is only set if multi-region controls are set on the database. optional RegionConfig region_config = 10; + + // IsRepaired is set if the descriptor has been upgrade through fix_descriptor_migration. + optional bool is_repaired = 11 [(gogoproto.nullable)=false]; } // TypeDescriptor represents a user defined type and is stored in a structured @@ -1369,6 +1375,9 @@ message TypeDescriptor { } optional RegionConfig region_config = 16; + + // IsRepaired is set if the descriptor has been upgrade through fix_descriptor_migration. + optional bool is_repaired = 17 [(gogoproto.nullable)=false]; } // SchemaDescriptor represents a physical schema and is stored in a structured @@ -1401,6 +1410,9 @@ message SchemaDescriptor { // privileges contains the privileges for the schema. optional PrivilegeDescriptor privileges = 4; + + // IsRepaired is set if the descriptor has been upgrade through fix_descriptor_migration. + optional bool is_repaired = 10 [(gogoproto.nullable)=false]; } // Descriptor is a union type for descriptors for tables, schemas, databases, diff --git a/pkg/sql/catalog/descriptor.go b/pkg/sql/catalog/descriptor.go index 0221eaa11a64..5446540abb6e 100644 --- a/pkg/sql/catalog/descriptor.go +++ b/pkg/sql/catalog/descriptor.go @@ -77,7 +77,8 @@ type DescriptorBuilder interface { // arguments other than ctx are optional. As of writing this, the only other // argument is a DescGetter and a nil value will cause table foreign-key // representation upgrades to be skipped. - RunPostDeserializationChanges(ctx context.Context, dg DescGetter) error + // RunPostDeserializationChanges returns if the descriptor changed. + RunPostDeserializationChanges(ctx context.Context, dg DescGetter) (bool, error) // BuildImmutable returns an immutable Descriptor. BuildImmutable() Descriptor @@ -163,6 +164,10 @@ type Descriptor interface { // ValidateTxnCommit performs pre-commit checks. ValidateTxnCommit(vea ValidationErrorAccumulator, vdg ValidationDescGetter) + + // GetIsRepaired returns if the Descriptor has been updated through the + // fix_descriptors_migration. + GetIsRepaired() bool } // DatabaseDescriptor encapsulates the concept of a database. diff --git a/pkg/sql/catalog/schemadesc/schema_desc.go b/pkg/sql/catalog/schemadesc/schema_desc.go index 5fedd81c18b7..0163095056a1 100644 --- a/pkg/sql/catalog/schemadesc/schema_desc.go +++ b/pkg/sql/catalog/schemadesc/schema_desc.go @@ -294,3 +294,8 @@ func IsSchemaNameValid(name string) error { } return nil } + +// SetIsRepaired sets the IsRepaired bit to true. +func (desc *Mutable) SetIsRepaired() { + desc.IsRepaired = true +} diff --git a/pkg/sql/catalog/schemadesc/schema_desc_builder.go b/pkg/sql/catalog/schemadesc/schema_desc_builder.go index f6cbd7067001..f8aa775c9996 100644 --- a/pkg/sql/catalog/schemadesc/schema_desc_builder.go +++ b/pkg/sql/catalog/schemadesc/schema_desc_builder.go @@ -15,6 +15,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/catalog" "github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb" + "github.com/cockroachdb/cockroach/pkg/sql/privilege" "github.com/cockroachdb/cockroach/pkg/util/protoutil" ) @@ -28,7 +29,8 @@ type SchemaDescriptorBuilder interface { } type schemaDescriptorBuilder struct { - original *descpb.SchemaDescriptor + original *descpb.SchemaDescriptor + maybeModified *descpb.SchemaDescriptor } var _ SchemaDescriptorBuilder = &schemaDescriptorBuilder{} @@ -50,10 +52,11 @@ func (sdb *schemaDescriptorBuilder) DescriptorType() catalog.DescriptorType { // interface. func (sdb *schemaDescriptorBuilder) RunPostDeserializationChanges( _ context.Context, _ catalog.DescGetter, -) error { - privDesc := sdb.original.GetPrivileges() - descpb.MaybeFixSchemaPrivileges(&privDesc) - return nil +) (bool, error) { + sdb.maybeModified = protoutil.Clone(sdb.original).(*descpb.SchemaDescriptor) + changed := descpb.MaybeFixPrivileges(sdb.maybeModified.GetID(), sdb.maybeModified.GetParentID(), + &sdb.maybeModified.Privileges, privilege.Schema) + return changed, nil } // BuildImmutable implements the catalog.DescriptorBuilder interface. @@ -63,7 +66,11 @@ func (sdb *schemaDescriptorBuilder) BuildImmutable() catalog.Descriptor { // BuildImmutableSchema returns an immutable schema descriptor. func (sdb *schemaDescriptorBuilder) BuildImmutableSchema() catalog.SchemaDescriptor { - return &immutable{SchemaDescriptor: *sdb.original} + desc := sdb.maybeModified + if desc == nil { + desc = sdb.original + } + return &immutable{SchemaDescriptor: *desc} } // BuildExistingMutable implements the catalog.DescriptorBuilder interface. @@ -74,9 +81,11 @@ func (sdb *schemaDescriptorBuilder) BuildExistingMutable() catalog.MutableDescri // BuildExistingMutableSchema returns a mutable descriptor for a schema // which already exists. func (sdb *schemaDescriptorBuilder) BuildExistingMutableSchema() *Mutable { - desc := protoutil.Clone(sdb.original).(*descpb.SchemaDescriptor) + if sdb.maybeModified == nil { + sdb.maybeModified = protoutil.Clone(sdb.original).(*descpb.SchemaDescriptor) + } return &Mutable{ - immutable: immutable{SchemaDescriptor: *desc}, + immutable: immutable{SchemaDescriptor: *sdb.maybeModified}, ClusterVersion: &immutable{SchemaDescriptor: *sdb.original}, } } diff --git a/pkg/sql/catalog/schemadesc/synthetic_schema_desc.go b/pkg/sql/catalog/schemadesc/synthetic_schema_desc.go index 5a3755fd16cc..108f764cfed8 100644 --- a/pkg/sql/catalog/schemadesc/synthetic_schema_desc.go +++ b/pkg/sql/catalog/schemadesc/synthetic_schema_desc.go @@ -96,3 +96,7 @@ func (p synthetic) SchemaDesc() *descpb.SchemaDescriptor { "synthetic %s cannot be encoded", p.kindName()) return nil // unreachable } + +func (p synthetic) GetIsRepaired() bool { + return false +} diff --git a/pkg/sql/catalog/systemschema/system.go b/pkg/sql/catalog/systemschema/system.go index 6f4c90b10161..4d93489fad3b 100644 --- a/pkg/sql/catalog/systemschema/system.go +++ b/pkg/sql/catalog/systemschema/system.go @@ -406,7 +406,7 @@ func MakeSystemDatabaseDesc() catalog.DatabaseDescriptor { func makeTable(desc descpb.TableDescriptor) catalog.TableDescriptor { ctx := context.Background() b := tabledesc.NewBuilder(&desc) - err := b.RunPostDeserializationChanges(ctx, nil /* DescGetter */) + _, err := b.RunPostDeserializationChanges(ctx, nil /* DescGetter */) if err != nil { log.Fatalf(ctx, "Error when building descriptor of system table %q: %s", desc.Name, err) } @@ -1773,6 +1773,6 @@ func newCommentPrivilegeDescriptor( Privileges: priv.ToBitField(), }, }, - Version: descpb.OwnerVersion, + Version: descpb.Version21_2, } } diff --git a/pkg/sql/catalog/tabledesc/structured.go b/pkg/sql/catalog/tabledesc/structured.go index 9f5c28a53ba7..c27fc3a2d61b 100644 --- a/pkg/sql/catalog/tabledesc/structured.go +++ b/pkg/sql/catalog/tabledesc/structured.go @@ -79,12 +79,6 @@ type PostDeserializationTableDescriptorChanges struct { // one index descriptor was upgraded UpgradedIndexFormatVersion bool - // FixedPrivileges indicates that the privileges were fixed. - // - // TODO(ajwerner): Determine whether this still needs to exist of can be - // removed. - FixedPrivileges bool - // UpgradedForeignKeyRepresentation indicates that the foreign key // representation was upgraded. UpgradedForeignKeyRepresentation bool @@ -95,6 +89,15 @@ type PostDeserializationTableDescriptorChanges struct { // TODO(ajwerner): Remove this and the associated migration in 22.1 as // this will never be true due to the corresponding long-running migration. UpgradedNamespaceName bool + + // UpgradedPrivileges indicates that the PrivilegeDescriptor version was upgraded. + UpgradedPrivileges bool +} + +// Changed returns if any changes were made to the descriptor. +func (p *PostDeserializationTableDescriptorChanges) Changed() bool { + return p.UpgradedPrivileges || p.UpgradedForeignKeyRepresentation || + p.UpgradedFormatVersion || p.UpgradedIndexFormatVersion || p.UpgradedNamespaceName } // DescriptorType returns the type of this descriptor. diff --git a/pkg/sql/catalog/tabledesc/structured_test.go b/pkg/sql/catalog/tabledesc/structured_test.go index 713019fedc1f..0b630f268e12 100644 --- a/pkg/sql/catalog/tabledesc/structured_test.go +++ b/pkg/sql/catalog/tabledesc/structured_test.go @@ -299,7 +299,7 @@ func TestMaybeUpgradeFormatVersion(t *testing.T) { } for i, test := range tests { b := NewBuilder(&test.desc) - err := b.RunPostDeserializationChanges(context.Background(), nil) + _, err := b.RunPostDeserializationChanges(context.Background(), nil) desc := b.BuildImmutableTable() require.NoError(t, err) changes, err := GetPostDeserializationChanges(desc) @@ -414,7 +414,7 @@ func TestMaybeUpgradeIndexFormatVersion(t *testing.T) { } for i, test := range tests { b := NewBuilder(&test.desc) - err := b.RunPostDeserializationChanges(context.Background(), nil) + _, err := b.RunPostDeserializationChanges(context.Background(), nil) desc := b.BuildImmutableTable() require.NoError(t, err) changes, err := GetPostDeserializationChanges(desc) diff --git a/pkg/sql/catalog/tabledesc/table_desc.go b/pkg/sql/catalog/tabledesc/table_desc.go index 698095c08c6a..c2d66f9bf2d2 100644 --- a/pkg/sql/catalog/tabledesc/table_desc.go +++ b/pkg/sql/catalog/tabledesc/table_desc.go @@ -461,3 +461,8 @@ func (desc *wrapper) getExistingOrNewMutationCache() *mutationCache { func (desc *wrapper) AllMutations() []catalog.Mutation { return desc.getExistingOrNewMutationCache().all } + +// SetIsRepaired sets the IsRepaired bit to true. +func (desc *Mutable) SetIsRepaired() { + desc.IsRepaired = true +} diff --git a/pkg/sql/catalog/tabledesc/table_desc_builder.go b/pkg/sql/catalog/tabledesc/table_desc_builder.go index 48e28645ecb7..ea37f3b307e1 100644 --- a/pkg/sql/catalog/tabledesc/table_desc_builder.go +++ b/pkg/sql/catalog/tabledesc/table_desc_builder.go @@ -17,6 +17,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/catalog" "github.com/cockroachdb/cockroach/pkg/sql/catalog/catconstants" "github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb" + "github.com/cockroachdb/cockroach/pkg/sql/privilege" "github.com/cockroachdb/cockroach/pkg/util/protoutil" "github.com/cockroachdb/errors" ) @@ -98,10 +99,11 @@ func (tdb *tableDescriptorBuilder) DescriptorType() catalog.DescriptorType { // interface. func (tdb *tableDescriptorBuilder) RunPostDeserializationChanges( ctx context.Context, dg catalog.DescGetter, -) (err error) { +) (bool, error) { + var err error tdb.maybeModified = protoutil.Clone(tdb.original).(*descpb.TableDescriptor) tdb.changes, err = maybeFillInDescriptor(ctx, dg, tdb.maybeModified, tdb.skipFKsWithNoMatchingTable) - return err + return tdb.changes.Changed(), err } // BuildImmutable implements the catalog.DescriptorBuilder interface. @@ -197,14 +199,7 @@ func maybeFillInDescriptor( } } - // Fill in any incorrect privileges that may have been missed due to mixed-versions. - // TODO(mberhault): remove this in 2.1 (maybe 2.2) when privilege-fixing migrations have been - // run again and mixed-version clusters always write "good" descriptors. - changes.FixedPrivileges = descpb.MaybeFixPrivileges(desc.ID, &desc.Privileges) - - fixedUsagePrivilege := descpb.MaybeFixUsagePrivForTablesAndDBs(&desc.Privileges) - - changes.FixedPrivileges = changes.FixedPrivileges || fixedUsagePrivilege + changes.UpgradedPrivileges = descpb.MaybeFixPrivileges(desc.ID, desc.GetParentID(), &desc.Privileges, privilege.Table) changes.UpgradedNamespaceName = maybeUpgradeNamespaceName(desc) diff --git a/pkg/sql/catalog/tabledesc/validate_test.go b/pkg/sql/catalog/tabledesc/validate_test.go index f1388daca5f7..ba832b8d4eaa 100644 --- a/pkg/sql/catalog/tabledesc/validate_test.go +++ b/pkg/sql/catalog/tabledesc/validate_test.go @@ -125,6 +125,7 @@ var validationMap = []struct { "LocalityConfig": {status: iSolemnlySwearThisFieldIsValidated}, "PartitionAllBy": {status: iSolemnlySwearThisFieldIsValidated}, "NewSchemaChangeJobID": {status: iSolemnlySwearThisFieldIsValidated}, + "IsRepaired": {status: thisFieldReferencesNoObjects}, }, }, { @@ -239,6 +240,7 @@ var validationMap = []struct { "Privileges": {status: iSolemnlySwearThisFieldIsValidated}, "OfflineReason": {status: thisFieldReferencesNoObjects}, "RegionConfig": {status: iSolemnlySwearThisFieldIsValidated}, + "IsRepaired": {status: thisFieldReferencesNoObjects}, }, }, { @@ -254,6 +256,7 @@ var validationMap = []struct { "State": {status: thisFieldReferencesNoObjects}, "OfflineReason": {status: thisFieldReferencesNoObjects}, "RegionConfig": {status: iSolemnlySwearThisFieldIsValidated}, + "IsRepaired": {status: thisFieldReferencesNoObjects}, }, }, { @@ -268,6 +271,7 @@ var validationMap = []struct { "DrainingNames": {status: thisFieldReferencesNoObjects}, "ParentID": {status: iSolemnlySwearThisFieldIsValidated}, "Privileges": {status: iSolemnlySwearThisFieldIsValidated}, + "IsRepaired": {status: thisFieldReferencesNoObjects}, }, }, } diff --git a/pkg/sql/catalog/typedesc/type_desc.go b/pkg/sql/catalog/typedesc/type_desc.go index c71cb219c019..74d10e30f96a 100644 --- a/pkg/sql/catalog/typedesc/type_desc.go +++ b/pkg/sql/catalog/typedesc/type_desc.go @@ -973,3 +973,8 @@ func GetTypeDescriptorClosure(typ *types.T) (map[descpb.ID]struct{}, error) { } return ret, nil } + +// SetIsRepaired sets the IsRepaired bit to true. +func (desc *Mutable) SetIsRepaired() { + desc.IsRepaired = true +} diff --git a/pkg/sql/catalog/typedesc/type_desc_builder.go b/pkg/sql/catalog/typedesc/type_desc_builder.go index 16ad1cf70a27..89279df93679 100644 --- a/pkg/sql/catalog/typedesc/type_desc_builder.go +++ b/pkg/sql/catalog/typedesc/type_desc_builder.go @@ -15,6 +15,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/catalog" "github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb" + "github.com/cockroachdb/cockroach/pkg/sql/privilege" "github.com/cockroachdb/cockroach/pkg/util/protoutil" ) @@ -28,7 +29,8 @@ type TypeDescriptorBuilder interface { } type typeDescriptorBuilder struct { - original *descpb.TypeDescriptor + original *descpb.TypeDescriptor + maybeModified *descpb.TypeDescriptor } var _ TypeDescriptorBuilder = &typeDescriptorBuilder{} @@ -50,8 +52,12 @@ func (tdb *typeDescriptorBuilder) DescriptorType() catalog.DescriptorType { // interface. func (tdb *typeDescriptorBuilder) RunPostDeserializationChanges( _ context.Context, _ catalog.DescGetter, -) error { - return nil +) (bool, error) { + tdb.maybeModified = protoutil.Clone(tdb.original).(*descpb.TypeDescriptor) + changed := descpb.MaybeFixPrivileges(tdb.maybeModified.ID, tdb.maybeModified.ID, + &tdb.maybeModified.Privileges, privilege.Type) + + return changed, nil } // BuildImmutable implements the catalog.DescriptorBuilder interface. @@ -61,7 +67,11 @@ func (tdb *typeDescriptorBuilder) BuildImmutable() catalog.Descriptor { // BuildImmutableType returns an immutable type descriptor. func (tdb *typeDescriptorBuilder) BuildImmutableType() catalog.TypeDescriptor { - imm := makeImmutable(tdb.original) + desc := tdb.maybeModified + if desc == nil { + desc = tdb.original + } + imm := makeImmutable(desc) return &imm } @@ -73,8 +83,14 @@ func (tdb *typeDescriptorBuilder) BuildExistingMutable() catalog.MutableDescript // BuildExistingMutableType returns a mutable descriptor for a type // which already exists. func (tdb *typeDescriptorBuilder) BuildExistingMutableType() *Mutable { - clusterVersion := makeImmutable(protoutil.Clone(tdb.original).(*descpb.TypeDescriptor)) - return &Mutable{immutable: makeImmutable(tdb.original), ClusterVersion: &clusterVersion} + if tdb.maybeModified == nil { + tdb.maybeModified = protoutil.Clone(tdb.original).(*descpb.TypeDescriptor) + } + clusterVersion := makeImmutable(tdb.original) + return &Mutable{ + immutable: makeImmutable(tdb.maybeModified), + ClusterVersion: &clusterVersion, + } } // BuildCreatedMutable implements the catalog.DescriptorBuilder interface. diff --git a/pkg/sql/doctor/BUILD.bazel b/pkg/sql/doctor/BUILD.bazel index 3df33c97959f..9350bfb91461 100644 --- a/pkg/sql/doctor/BUILD.bazel +++ b/pkg/sql/doctor/BUILD.bazel @@ -31,6 +31,7 @@ go_test( "//pkg/security", "//pkg/sql/catalog/descpb", "//pkg/sql/catalog/tabledesc", + "//pkg/sql/privilege", "//pkg/sql/types", "//pkg/util/hlc", "//pkg/util/leaktest", diff --git a/pkg/sql/doctor/doctor.go b/pkg/sql/doctor/doctor.go index 80620ff97fb0..74c894f5e4ed 100644 --- a/pkg/sql/doctor/doctor.go +++ b/pkg/sql/doctor/doctor.go @@ -90,7 +90,7 @@ func newDescGetter( } b := catalogkv.NewBuilderWithMVCCTimestamp(&d, r.ModTime) if b != nil { - if err := b.RunPostDeserializationChanges(ctx, ddg); err != nil { + if _, err := b.RunPostDeserializationChanges(ctx, ddg); err != nil { descReport(stdout, ddg.Descriptors[descpb.ID(r.ID)], "failed to upgrade descriptor: %v", err) } else { ddg.Descriptors[descpb.ID(r.ID)] = b.BuildImmutable() diff --git a/pkg/sql/doctor/doctor_test.go b/pkg/sql/doctor/doctor_test.go index 1d60d620ebc6..ab53fdcb2df6 100644 --- a/pkg/sql/doctor/doctor_test.go +++ b/pkg/sql/doctor/doctor_test.go @@ -24,6 +24,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb" "github.com/cockroachdb/cockroach/pkg/sql/catalog/tabledesc" "github.com/cockroachdb/cockroach/pkg/sql/doctor" + "github.com/cockroachdb/cockroach/pkg/sql/privilege" "github.com/cockroachdb/cockroach/pkg/sql/types" "github.com/cockroachdb/cockroach/pkg/util/hlc" "github.com/cockroachdb/cockroach/pkg/util/leaktest" @@ -66,16 +67,28 @@ var validTableDesc = &descpb.Descriptor{ func toBytes(t *testing.T, desc *descpb.Descriptor) []byte { table, database, typ, schema := descpb.FromDescriptor(desc) if table != nil { - descpb.MaybeFixPrivileges(table.GetID(), &table.Privileges) + descpb.MaybeFixPrivileges( + table.GetID(), table.GetParentID(), + &table.Privileges, privilege.Table, + ) if table.FormatVersion == 0 { table.FormatVersion = descpb.InterleavedFormatVersion } } else if database != nil { - descpb.MaybeFixPrivileges(database.GetID(), &database.Privileges) + descpb.MaybeFixPrivileges( + database.GetID(), database.GetID(), + &database.Privileges, privilege.Database, + ) } else if typ != nil { - descpb.MaybeFixPrivileges(typ.GetID(), &typ.Privileges) + descpb.MaybeFixPrivileges( + typ.GetID(), typ.GetParentID(), + &typ.Privileges, privilege.Type, + ) } else if schema != nil { - descpb.MaybeFixPrivileges(schema.GetID(), &schema.Privileges) + descpb.MaybeFixPrivileges( + schema.GetID(), schema.GetParentID(), + &schema.Privileges, privilege.Schema, + ) } res, err := protoutil.Marshal(desc) require.NoError(t, err) @@ -220,26 +233,26 @@ func TestExamineDescriptors(t *testing.T) { { // 9 descTable: doctor.DescriptorTable{ { - ID: 1, + ID: 51, DescBytes: toBytes(t, &descpb.Descriptor{Union: &descpb.Descriptor_Type{ - Type: &descpb.TypeDescriptor{Name: "type", ID: 1}, + Type: &descpb.TypeDescriptor{Name: "type", ID: 51}, }}), }, }, namespaceTable: doctor.NamespaceTable{ - {NameInfo: descpb.NameInfo{Name: "type"}, ID: 1}, + {NameInfo: descpb.NameInfo{Name: "type"}, ID: 51}, }, expected: `Examining 1 descriptors and 1 namespace entries... - ParentID 0, ParentSchemaID 0: type "type" (1): invalid parentID 0 - ParentID 0, ParentSchemaID 0: type "type" (1): invalid parent schema ID 0 + ParentID 0, ParentSchemaID 0: type "type" (51): invalid parentID 0 + ParentID 0, ParentSchemaID 0: type "type" (51): invalid parent schema ID 0 `, }, { // 10 descTable: doctor.DescriptorTable{ { - ID: 1, + ID: 51, DescBytes: toBytes(t, &descpb.Descriptor{Union: &descpb.Descriptor_Type{ - Type: &descpb.TypeDescriptor{Name: "type", ID: 1, ParentID: 3, ParentSchemaID: 2}, + Type: &descpb.TypeDescriptor{Name: "type", ID: 51, ParentID: 3, ParentSchemaID: 2}, }}), }, { @@ -250,12 +263,12 @@ func TestExamineDescriptors(t *testing.T) { }, }, namespaceTable: doctor.NamespaceTable{ - {NameInfo: descpb.NameInfo{ParentID: 3, ParentSchemaID: 2, Name: "type"}, ID: 1}, + {NameInfo: descpb.NameInfo{ParentID: 3, ParentSchemaID: 2, Name: "type"}, ID: 51}, {NameInfo: descpb.NameInfo{Name: "db"}, ID: 3}, }, expected: `Examining 2 descriptors and 2 namespace entries... - ParentID 3, ParentSchemaID 2: type "type" (1): referenced schema ID 2: descriptor not found - ParentID 3, ParentSchemaID 2: type "type" (1): arrayTypeID 0 does not exist for "ENUM": referenced type ID 0: descriptor not found + ParentID 3, ParentSchemaID 2: type "type" (51): referenced schema ID 2: descriptor not found + ParentID 3, ParentSchemaID 2: type "type" (51): arrayTypeID 0 does not exist for "ENUM": referenced type ID 0: descriptor not found `, }, { // 11 @@ -269,18 +282,6 @@ func TestExamineDescriptors(t *testing.T) { { ID: 52, DescBytes: func() []byte { - // Skip `toBytes` to produce a descriptor with unset privileges field. - // The purpose of this is to produce a nil dereference during validation - // in order to test that doctor recovers from this. - // - // Note that it might be the case that validation aught to check that - // this field is not nil in the first place, in which case this test case - // will need to craft a corrupt descriptor serialization in a more - // creative way. Ideally validation code should never cause runtime errors - // but there's no way to guarantee that short of formally verifying it. We - // therefore have to consider the possibility of runtime errors (sadly) and - // doctor should absolutely make every possible effort to continue executing - // in the face of these, considering its main use case! desc := &descpb.Descriptor{Union: &descpb.Descriptor_Type{ Type: &descpb.TypeDescriptor{Name: "type", ID: 52, ParentID: 51, ParentSchemaID: keys.PublicSchemaID}, }} @@ -295,7 +296,7 @@ func TestExamineDescriptors(t *testing.T) { {NameInfo: descpb.NameInfo{ParentID: 51, ParentSchemaID: keys.PublicSchemaID, Name: "type"}, ID: 52}, }, expected: `Examining 2 descriptors and 2 namespace entries... - ParentID 51, ParentSchemaID 29: type "type" (52): validation: runtime error: invalid memory address or nil pointer dereference + ParentID 51, ParentSchemaID 29: type "type" (52): arrayTypeID 0 does not exist for "ENUM": referenced type ID 0: descriptor not found `, }, { // 12 diff --git a/pkg/sql/logictest/testdata/logic_test/bytes b/pkg/sql/logictest/testdata/logic_test/bytes index 6b1bd9eb13d5..7bc513a1fb6c 100644 --- a/pkg/sql/logictest/testdata/logic_test/bytes +++ b/pkg/sql/logictest/testdata/logic_test/bytes @@ -153,4 +153,4 @@ PREPARE r1(bytes) AS SELECT descriptor::STRING FROM system.descriptor WHERE desc query T EXECUTE r1('abc') ---- -\0224\012\011defaultdb\0202\032\035\012\011\012\005admin\020\002\012\010\012\004root\020\002\022\004root\030\001"\000(\001@\000J\000 +\0226\012\011defaultdb\0202\032\035\012\011\012\005admin\020\002\012\010\012\004root\020\002\022\004root\030\002"\000(\001@\000J\000X\000 diff --git a/pkg/sql/opt/exec/execbuilder/testdata/show_trace_nonmetamorphic b/pkg/sql/opt/exec/execbuilder/testdata/show_trace_nonmetamorphic index d4378bb86b70..417e7b108865 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/show_trace_nonmetamorphic +++ b/pkg/sql/opt/exec/execbuilder/testdata/show_trace_nonmetamorphic @@ -18,7 +18,7 @@ WHERE message NOT LIKE '%Z/%' AND operation != 'dist sender send' ---- batch flow coordinator CPut /NamespaceTable/30/1/0/0/"t"/4/1 -> 53 -batch flow coordinator CPut /Table/3/1/53/2/1 -> database: version:1 privileges: users: owner_proto:"root" version:1 > state:PUBLIC offline_reason:"" > +batch flow coordinator CPut /Table/3/1/53/2/1 -> database: version:1 privileges: users: owner_proto:"root" version:2 > state:PUBLIC offline_reason:"" is_repaired:false > batch flow coordinator CPut /NamespaceTable/30/1/53/0/"public"/4/1 -> 29 exec stmt rows affected: 0 @@ -39,7 +39,7 @@ WHERE message NOT LIKE '%Z/%' AND operation != 'dist sender send' ---- batch flow coordinator CPut /NamespaceTable/30/1/53/29/"kv"/4/1 -> 54 -batch flow coordinator CPut /Table/3/1/54/2/1 -> table: parent_id:53 unexposed_parent_schema_id:29 columns: TypeMeta: > nullable:false hidden:false inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > columns: TypeMeta: > nullable:true hidden:false inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > next_column_id:3 families: next_family_id:1 primary_index: interleave:<> partitioning: type:FORWARD created_explicitly:false encoding_type:1 sharded: disabled:false geo_config:<> predicate:"" > next_index_id:2 privileges: users: owner_proto:"root" version:1 > next_mutation_id:1 format_version:3 state:PUBLIC offline_reason:"" view_query:"" is_materialized_view:false new_schema_change_job_id:0 drop_time:0 replacement_of: > audit_mode:DISABLED drop_job_id:0 create_query:"" create_as_of_time:<> temporary:false partition_all_by:false > +batch flow coordinator CPut /Table/3/1/54/2/1 -> table: parent_id:53 unexposed_parent_schema_id:29 columns: TypeMeta: > nullable:false hidden:false inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > columns: TypeMeta: > nullable:true hidden:false inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > next_column_id:3 families: next_family_id:1 primary_index: interleave:<> partitioning: type:FORWARD created_explicitly:false encoding_type:1 sharded: disabled:false geo_config:<> predicate:"" > next_index_id:2 privileges: users: owner_proto:"root" version:2 > next_mutation_id:1 format_version:3 state:PUBLIC offline_reason:"" view_query:"" is_materialized_view:false new_schema_change_job_id:0 drop_time:0 replacement_of: > audit_mode:DISABLED drop_job_id:0 create_query:"" create_as_of_time:<> temporary:false partition_all_by:false is_repaired:false > exec stmt rows affected: 0 # We avoid using the full trace output, because that would make the @@ -65,7 +65,7 @@ WHERE message NOT LIKE '%Z/%' AND message NOT LIKE 'querying next range at%' AND tag NOT LIKE '%IndexBackfiller%' AND operation != 'dist sender send' ---- -batch flow coordinator Put /Table/3/1/54/2/1 -> table: parent_id:53 unexposed_parent_schema_id:29 columns: TypeMeta: > nullable:false hidden:false inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > columns: TypeMeta: > nullable:true hidden:false inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > next_column_id:3 families: next_family_id:1 primary_index: interleave:<> partitioning: type:FORWARD created_explicitly:false encoding_type:1 sharded: disabled:false geo_config:<> predicate:"" > next_index_id:3 privileges: users: owner_proto:"root" version:1 > mutations: interleave:<> partitioning: type:FORWARD created_explicitly:true encoding_type:0 sharded: disabled:false geo_config:<> predicate:"" > state:DELETE_ONLY direction:ADD mutation_id:1 rollback:false > next_mutation_id:2 format_version:3 state:PUBLIC offline_reason:"" view_query:"" is_materialized_view:false mutationJobs:<...> new_schema_change_job_id:0 drop_time:0 replacement_of: > audit_mode:DISABLED drop_job_id:0 create_query:"" create_as_of_time:<...> temporary:false partition_all_by:false > +batch flow coordinator Put /Table/3/1/54/2/1 -> table: parent_id:53 unexposed_parent_schema_id:29 columns: TypeMeta: > nullable:false hidden:false inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > columns: TypeMeta: > nullable:true hidden:false inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > next_column_id:3 families: next_family_id:1 primary_index: interleave:<> partitioning: type:FORWARD created_explicitly:false encoding_type:1 sharded: disabled:false geo_config:<> predicate:"" > next_index_id:3 privileges: users: owner_proto:"root" version:2 > mutations: interleave:<> partitioning: type:FORWARD created_explicitly:true encoding_type:0 sharded: disabled:false geo_config:<> predicate:"" > state:DELETE_ONLY direction:ADD mutation_id:1 rollback:false > next_mutation_id:2 format_version:3 state:PUBLIC offline_reason:"" view_query:"" is_materialized_view:false mutationJobs:<...> new_schema_change_job_id:0 drop_time:0 replacement_of: > audit_mode:DISABLED drop_job_id:0 create_query:"" create_as_of_time:<...> temporary:false partition_all_by:false is_repaired:false > exec stmt rows affected: 0 statement ok @@ -120,7 +120,7 @@ WHERE message NOT LIKE '%Z/%' AND operation != 'dist sender send' ---- batch flow coordinator CPut /NamespaceTable/30/1/53/29/"kv2"/4/1 -> 55 -batch flow coordinator CPut /Table/3/1/55/2/1 -> table: parent_id:53 unexposed_parent_schema_id:29 columns: TypeMeta: > nullable:true hidden:false inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > columns: TypeMeta: > nullable:true hidden:false inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > columns: TypeMeta: > nullable:false default_expr:"unique_rowid()" hidden:true inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > next_column_id:4 families: next_family_id:1 primary_index: interleave:<> partitioning: type:FORWARD created_explicitly:false encoding_type:1 sharded: disabled:false geo_config:<> predicate:"" > next_index_id:2 privileges: users: owner_proto:"root" version:1 > next_mutation_id:1 format_version:3 state:ADD offline_reason:"" view_query:"" is_materialized_view:false new_schema_change_job_id:0 drop_time:0 replacement_of: > audit_mode:DISABLED drop_job_id:0 create_query:"TABLE t.public.kv" create_as_of_time:<> temporary:false partition_all_by:false > +batch flow coordinator CPut /Table/3/1/55/2/1 -> table: parent_id:53 unexposed_parent_schema_id:29 columns: TypeMeta: > nullable:true hidden:false inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > columns: TypeMeta: > nullable:true hidden:false inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > columns: TypeMeta: > nullable:false default_expr:"unique_rowid()" hidden:true inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > next_column_id:4 families: next_family_id:1 primary_index: interleave:<> partitioning: type:FORWARD created_explicitly:false encoding_type:1 sharded: disabled:false geo_config:<> predicate:"" > next_index_id:2 privileges: users: owner_proto:"root" version:2 > next_mutation_id:1 format_version:3 state:ADD offline_reason:"" view_query:"" is_materialized_view:false new_schema_change_job_id:0 drop_time:0 replacement_of: > audit_mode:DISABLED drop_job_id:0 create_query:"TABLE t.public.kv" create_as_of_time:<> temporary:false partition_all_by:false is_repaired:false > exec stmt rows affected: 0 statement ok @@ -168,7 +168,7 @@ WHERE message NOT LIKE '%Z/%' AND message NOT LIKE 'querying next range at%' AND tag NOT LIKE '%IndexBackfiller%' AND operation != 'dist sender send' ---- -batch flow coordinator Put /Table/3/1/55/2/1 -> table: draining_names: parent_id:53 unexposed_parent_schema_id:29 columns: TypeMeta: > nullable:true hidden:false inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > columns: TypeMeta: > nullable:true hidden:false inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > columns: TypeMeta: > nullable:false default_expr:"unique_rowid()" hidden:true inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > next_column_id:4 families: next_family_id:1 primary_index: interleave:<> partitioning: type:FORWARD created_explicitly:false encoding_type:1 sharded: disabled:false geo_config:<> predicate:"" > next_index_id:2 privileges: users: owner_proto:"root" version:1 > next_mutation_id:1 format_version:3 state:DROP offline_reason:"" view_query:"" is_materialized_view:false new_schema_change_job_id:0 drop_time:... replacement_of: > audit_mode:DISABLED drop_job_id:0 create_query:"TABLE t.public.kv" create_as_of_time:<...> temporary:false partition_all_by:false > +batch flow coordinator Put /Table/3/1/55/2/1 -> table: draining_names: parent_id:53 unexposed_parent_schema_id:29 columns: TypeMeta: > nullable:true hidden:false inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > columns: TypeMeta: > nullable:true hidden:false inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > columns: TypeMeta: > nullable:false default_expr:"unique_rowid()" hidden:true inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > next_column_id:4 families: next_family_id:1 primary_index: interleave:<> partitioning: type:FORWARD created_explicitly:false encoding_type:1 sharded: disabled:false geo_config:<> predicate:"" > next_index_id:2 privileges: users: owner_proto:"root" version:2 > next_mutation_id:1 format_version:3 state:DROP offline_reason:"" view_query:"" is_materialized_view:false new_schema_change_job_id:0 drop_time:... replacement_of: > audit_mode:DISABLED drop_job_id:0 create_query:"TABLE t.public.kv" create_as_of_time:<...> temporary:false partition_all_by:false is_repaired:false > exec stmt rows affected: 0 statement ok @@ -202,7 +202,7 @@ WHERE message NOT LIKE '%Z/%' AND message NOT LIKE 'querying next range at%' AND tag NOT LIKE '%IndexBackfiller%' AND operation != 'dist sender send' ---- -batch flow coordinator Put /Table/3/1/54/2/1 -> table: parent_id:53 unexposed_parent_schema_id:29 columns: TypeMeta: > nullable:false hidden:false inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > columns: TypeMeta: > nullable:true hidden:false inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > next_column_id:3 families: next_family_id:1 primary_index: interleave:<> partitioning: type:FORWARD created_explicitly:false encoding_type:1 sharded: disabled:false geo_config:<> predicate:"" > next_index_id:3 privileges: users: owner_proto:"root" version:1 > mutations: interleave:<> partitioning: type:FORWARD created_explicitly:true encoding_type:0 sharded: disabled:false geo_config:<> predicate:"" > state:DELETE_AND_WRITE_ONLY direction:DROP mutation_id:2 rollback:false > next_mutation_id:3 format_version:3 state:PUBLIC offline_reason:"" view_query:"" is_materialized_view:false mutationJobs:<...> new_schema_change_job_id:0 drop_time:0 replacement_of: > audit_mode:DISABLED drop_job_id:0 create_query:"" create_as_of_time:<...> temporary:false partition_all_by:false > +batch flow coordinator Put /Table/3/1/54/2/1 -> table: parent_id:53 unexposed_parent_schema_id:29 columns: TypeMeta: > nullable:false hidden:false inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > columns: TypeMeta: > nullable:true hidden:false inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > next_column_id:3 families: next_family_id:1 primary_index: interleave:<> partitioning: type:FORWARD created_explicitly:false encoding_type:1 sharded: disabled:false geo_config:<> predicate:"" > next_index_id:3 privileges: users: owner_proto:"root" version:2 > mutations: interleave:<> partitioning: type:FORWARD created_explicitly:true encoding_type:0 sharded: disabled:false geo_config:<> predicate:"" > state:DELETE_AND_WRITE_ONLY direction:DROP mutation_id:2 rollback:false > next_mutation_id:3 format_version:3 state:PUBLIC offline_reason:"" view_query:"" is_materialized_view:false mutationJobs:<...> new_schema_change_job_id:0 drop_time:0 replacement_of: > audit_mode:DISABLED drop_job_id:0 create_query:"" create_as_of_time:<...> temporary:false partition_all_by:false is_repaired:false > exec stmt rows affected: 0 statement ok @@ -219,7 +219,7 @@ WHERE message NOT LIKE '%Z/%' AND message NOT LIKE 'querying next range at%' AND tag NOT LIKE '%IndexBackfiller%' AND operation != 'dist sender send' ---- -batch flow coordinator Put /Table/3/1/54/2/1 -> table: draining_names: parent_id:53 unexposed_parent_schema_id:29 columns: TypeMeta: > nullable:false hidden:false inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > columns: TypeMeta: > nullable:true hidden:false inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > next_column_id:3 families: next_family_id:1 primary_index: interleave:<> partitioning: type:FORWARD created_explicitly:false encoding_type:1 sharded: disabled:false geo_config:<> predicate:"" > next_index_id:3 privileges: users: owner_proto:"root" version:1 > next_mutation_id:3 format_version:3 state:DROP offline_reason:"" view_query:"" is_materialized_view:false new_schema_change_job_id:0 drop_time:... replacement_of: > audit_mode:DISABLED drop_job_id:0 gc_mutations: create_query:"" create_as_of_time:<...> temporary:false partition_all_by:false > +batch flow coordinator Put /Table/3/1/54/2/1 -> table: draining_names: parent_id:53 unexposed_parent_schema_id:29 columns: TypeMeta: > nullable:false hidden:false inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > columns: TypeMeta: > nullable:true hidden:false inaccessible:false virtual:false pg_attribute_num:0 alter_column_type_in_progress:false system_column_kind:NONE > next_column_id:3 families: next_family_id:1 primary_index: interleave:<> partitioning: type:FORWARD created_explicitly:false encoding_type:1 sharded: disabled:false geo_config:<> predicate:"" > next_index_id:3 privileges: users: owner_proto:"root" version:2 > next_mutation_id:3 format_version:3 state:DROP offline_reason:"" view_query:"" is_materialized_view:false new_schema_change_job_id:0 drop_time:... replacement_of: > audit_mode:DISABLED drop_job_id:0 gc_mutations: create_query:"" create_as_of_time:<...> temporary:false partition_all_by:false is_repaired:false > exec stmt rows affected: 0 # Check that session tracing does not inhibit the fast path for inserts & diff --git a/pkg/testutils/sqlutils/inject.go b/pkg/testutils/sqlutils/inject.go index 814779fe5a83..2136ab1db5af 100644 --- a/pkg/testutils/sqlutils/inject.go +++ b/pkg/testutils/sqlutils/inject.go @@ -24,7 +24,10 @@ import ( // InjectDescriptors attempts to inject the provided descriptors into the // database. -func InjectDescriptors(ctx context.Context, db *gosql.DB, input []*descpb.Descriptor) error { +// If force is true, we can inject descriptors that are invalid. +func InjectDescriptors( + ctx context.Context, db *gosql.DB, input []*descpb.Descriptor, force bool, +) error { cloneInput := func() []*descpb.Descriptor { cloned := make([]*descpb.Descriptor, 0, len(input)) for _, d := range input { @@ -49,8 +52,8 @@ func InjectDescriptors(ctx context.Context, db *gosql.DB, input []*descpb.Descri return err } _, err = tx.Exec( - "SELECT crdb_internal.unsafe_upsert_descriptor($1, $2, true)", - id, encoded, + "SELECT crdb_internal.unsafe_upsert_descriptor($1, $2, $3)", + id, encoded, force, ) return err } diff --git a/pkg/testutils/sqlutils/inject_test.go b/pkg/testutils/sqlutils/inject_test.go index a1669e1f9383..76bb6bb09a11 100644 --- a/pkg/testutils/sqlutils/inject_test.go +++ b/pkg/testutils/sqlutils/inject_test.go @@ -77,7 +77,9 @@ ORDER BY gen_random_uuid(); -- to mix it up s, db, _ := serverutils.StartServer(t, base.TestServerArgs{}) defer s.Stopper().Stop(context.Background()) - require.NoError(t, sqlutils.InjectDescriptors(context.Background(), db, descriptors)) + require.NoError(t, sqlutils.InjectDescriptors( + context.Background(), db, descriptors, true, /* force */ + )) tdb := sqlutils.MakeSQLRunner(db) for _, stmt := range afterStmts {