summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db')
-rw-r--r--src/mongo/db/query/canonical_query_encoder.cpp6
-rw-r--r--src/mongo/db/query/canonical_query_encoder_test.cpp37
-rw-r--r--src/mongo/db/test_output/query/canonical_query_encoder_test/compute_key_s_b_e.txt50
-rw-r--r--src/mongo/db/test_output/query/canonical_query_encoder_test/compute_key_s_b_e_with_pipeline.txt12
-rw-r--r--src/mongo/db/test_output/query/canonical_query_encoder_test/compute_key_s_b_e_with_read_concern.txt6
-rw-r--r--src/mongo/db/test_output/query/canonical_query_encoder_test/compute_key_with_api_strict.txt4
-rw-r--r--src/mongo/db/test_output/query/canonical_query_encoder_test/compute_key_with_needs_merge.txt4
7 files changed, 80 insertions, 39 deletions
diff --git a/src/mongo/db/query/canonical_query_encoder.cpp b/src/mongo/db/query/canonical_query_encoder.cpp
index d86eb8ab37b..3052e3811bc 100644
--- a/src/mongo/db/query/canonical_query_encoder.cpp
+++ b/src/mongo/db/query/canonical_query_encoder.cpp
@@ -1126,6 +1126,12 @@ std::string encodeSBE(const CanonicalQuery& cq) {
cq.getOpCtx() && APIParameters::get(cq.getOpCtx()).getAPIStrict().value_or(false);
bufBuilder.appendChar(apiStrict ? 1 : 0);
+ // We can wind up with different query plans for aggregate commands if 'needsMerge' is set or
+ // not. For instance, when 'needsMerge' is true, $group queries will produce partial aggregates
+ // as output, and complete output otherwise.
+ const bool needsMerge = cq.getExpCtx()->needsMerge;
+ bufBuilder.appendChar(needsMerge ? 1 : 0);
+
encodeFindCommandRequest(cq.getFindCommandRequest(), &bufBuilder);
encodePipeline(cq.pipeline(), &bufBuilder);
diff --git a/src/mongo/db/query/canonical_query_encoder_test.cpp b/src/mongo/db/query/canonical_query_encoder_test.cpp
index cc700609ffa..ef2ac72044d 100644
--- a/src/mongo/db/query/canonical_query_encoder_test.cpp
+++ b/src/mongo/db/query/canonical_query_encoder_test.cpp
@@ -73,7 +73,8 @@ protected:
BSONObj collation,
std::unique_ptr<FindCommandRequest> findCommand = nullptr,
std::vector<BSONObj> pipelineObj = {},
- bool isCountLike = false) {
+ bool isCountLike = false,
+ bool needsMerge = false) {
if (!findCommand) {
findCommand = std::make_unique<FindCommandRequest>(nss);
}
@@ -84,6 +85,7 @@ protected:
const auto expCtx = make_intrusive<ExpressionContextForTest>(opCtx, nss);
expCtx->addResolvedNamespaces({foreignNss});
+ expCtx->needsMerge = needsMerge;
if (!findCommand->getCollation().isEmpty()) {
auto statusWithCollator = CollatorFactoryInterface::get(opCtx->getServiceContext())
->makeFromBSON(findCommand->getCollation());
@@ -147,7 +149,8 @@ protected:
const char* projStr,
std::unique_ptr<FindCommandRequest> findCommand = nullptr,
std::vector<BSONObj> pipelineObj = {},
- bool isCountLike = false) {
+ bool isCountLike = false,
+ bool needsMerge = false) {
auto& stream = gctx.outStream();
stream << "==== VARIATION: sbe, query=" << queryStr << ", sort=" << sortStr
<< ", proj=" << projStr;
@@ -159,6 +162,9 @@ protected:
if (isCountLike) {
stream << ", isCountLike=true";
}
+ if (needsMerge) {
+ stream << ", needsMerge=true";
+ }
stream << std::endl;
BSONObj collation;
unique_ptr<CanonicalQuery> cq(canonicalize(opCtx(),
@@ -168,7 +174,8 @@ protected:
collation,
std::move(findCommand),
std::move(pipelineObj),
- isCountLike));
+ isCountLike,
+ needsMerge));
cq->setSbeCompatible(true);
const auto key = canonical_query_encoder::encodeSBE(*cq);
gctx.outStream() << key << std::endl;
@@ -572,5 +579,29 @@ TEST_F(CanonicalQueryEncoderTest, ComputeKeyWithApiStrict) {
}
}
+TEST_F(CanonicalQueryEncoderTest, ComputeKeyWithNeedsMerge) {
+ unittest::GoldenTestContext gctx(&goldenTestConfig);
+ RAIIServerParameterControllerForTest controllerSBE("internalQueryFrameworkControl",
+ "trySbeEngine");
+ const auto groupStage = fromjson("{$group: {_id: '$a', out: {$sum: 1}}}");
+ testComputeSBEKey(gctx,
+ "{}",
+ "{}",
+ "{}",
+ nullptr /* findCommand */,
+ {groupStage},
+ false /* isCountLike */,
+ false /* needsMerge */);
+
+ testComputeSBEKey(gctx,
+ "{}",
+ "{}",
+ "{}",
+ nullptr /* findCommand */,
+ {groupStage},
+ false /* isCountLike */,
+ true /* needsMerge */);
+}
+
} // namespace
} // namespace mongo
diff --git a/src/mongo/db/test_output/query/canonical_query_encoder_test/compute_key_s_b_e.txt b/src/mongo/db/test_output/query/canonical_query_encoder_test/compute_key_s_b_e.txt
index ead917e1225..aadf96868aa 100644
--- a/src/mongo/db/test_output/query/canonical_query_encoder_test/compute_key_s_b_e.txt
+++ b/src/mongo/db/test_output/query/canonical_query_encoder_test/compute_key_s_b_e.txt
@@ -1,50 +1,50 @@
==== VARIATION: sbe, query={}, sort={}, proj={}
-YW4ABQAAAAAAAAAAAAAAAAAAAG5ubm4FAAAAAGZe
+YW4ABQAAAAAAAAAAAAAAAAAAAABubm5uBQAAAABmXg==
==== VARIATION: sbe, query={$or: [{a: 1}, {b: 2}]}, sort={}, proj={}
-b3IAW2VxAGE/AAAAACxlcQBiPwEAAABdBQAAAAAAAAAAAAAAAAAAAG5ubm4FAAAAAGZe
+b3IAW2VxAGE/AAAAACxlcQBiPwEAAABdBQAAAAAAAAAAAAAAAAAAAABubm5uBQAAAABmXg==
==== VARIATION: sbe, query={a: 1}, sort={}, proj={}
-ZXEAYT8AAAAABQAAAAAAAAAAAAAAAAAAAG5ubm4FAAAAAGZe
+ZXEAYT8AAAAABQAAAAAAAAAAAAAAAAAAAABubm5uBQAAAABmXg==
==== VARIATION: sbe, query={b: 1}, sort={}, proj={}
-ZXEAYj8AAAAABQAAAAAAAAAAAAAAAAAAAG5ubm4FAAAAAGZe
+ZXEAYj8AAAAABQAAAAAAAAAAAAAAAAAAAABubm5uBQAAAABmXg==
==== VARIATION: sbe, query={a: 1, b: 1, c: 1}, sort={}, proj={}
-YW4AW2VxAGE/AAAAACxlcQBiPwEAAAAsZXEAYz8CAAAAXQUAAAAAAAAAAAAAAAAAAABubm5uBQAAAABmXg==
+YW4AW2VxAGE/AAAAACxlcQBiPwEAAAAsZXEAYz8CAAAAXQUAAAAAAAAAAAAAAAAAAAAAbm5ubgUAAAAAZl4=
==== VARIATION: sbe, query={}, sort={a: 1}, proj={}
-YW4ABQAAAAB+YWEAAAAAAAAAAAAAAG5ubm4FAAAAAGZe
+YW4ABQAAAAB+YWEAAAAAAAAAAAAAAABubm5uBQAAAABmXg==
==== VARIATION: sbe, query={}, sort={a: -1}, proj={}
-YW4ABQAAAAB+ZGEAAAAAAAAAAAAAAG5ubm4FAAAAAGZe
+YW4ABQAAAAB+ZGEAAAAAAAAAAAAAAABubm5uBQAAAABmXg==
==== VARIATION: sbe, query={a: 1}, sort={a: 1}, proj={}
-ZXEAYT8AAAAABQAAAAB+YWEAAAAAAAAAAAAAAG5ubm4FAAAAAGZe
+ZXEAYT8AAAAABQAAAAB+YWEAAAAAAAAAAAAAAABubm5uBQAAAABmXg==
==== VARIATION: sbe, query={a: 1}, sort={a: 1}, proj={a: 1}
-ZXEAYT8AAAAADAAAABBhAAEAAAAAfmFhAAAAAAAAAAAAAABubm5uBQAAAABmXg==
+ZXEAYT8AAAAADAAAABBhAAEAAAAAfmFhAAAAAAAAAAAAAAAAbm5ubgUAAAAAZl4=
==== VARIATION: sbe, query={}, sort={a: 1}, proj={a: 1}
-YW4ADAAAABBhAAEAAAAAfmFhAAAAAAAAAAAAAABubm5uBQAAAABmXg==
+YW4ADAAAABBhAAEAAAAAfmFhAAAAAAAAAAAAAAAAbm5ubgUAAAAAZl4=
==== VARIATION: sbe, query={}, sort={a: 1}, proj={a: 1}
-YW4ADAAAABBhAAEAAAAAfmFhAAAAAAAAAAAAAABubm5uBQAAAABmXg==
+YW4ADAAAABBhAAEAAAAAfmFhAAAAAAAAAAAAAAAAbm5ubgUAAAAAZl4=
==== VARIATION: sbe, query={}, sort={}, proj={a: 1}
-YW4ADAAAABBhAAEAAAAAAAAAAAAAAAAAAABubm5uBQAAAABmXg==
+YW4ADAAAABBhAAEAAAAAAAAAAAAAAAAAAAAAbm5ubgUAAAAAZl4=
==== VARIATION: sbe, query={}, sort={}, proj={a: true}
-YW4ACQAAAAhhAAEAAAAAAAAAAAAAAABubm5uBQAAAABmXg==
+YW4ACQAAAAhhAAEAAAAAAAAAAAAAAAAAbm5ubgUAAAAAZl4=
==== VARIATION: sbe, query={}, sort={}, proj={a: false}
-YW4ACQAAAAhhAAAAAAAAAAAAAAAAAABubm5uBQAAAABmXg==
+YW4ACQAAAAhhAAAAAAAAAAAAAAAAAAAAbm5ubgUAAAAAZl4=
==== VARIATION: sbe, query={}, sort={}, proj={}, isCountLike=true
-YW4ABQAAAAAAAQAAAAAAAAAAAG5ubm4FAAAAAGZe
+YW4ABQAAAAAAAQAAAAAAAAAAAABubm5uBQAAAABmXg==
==== VARIATION: sbe, query={a: 1}, sort={a: 1}, proj={}, allowDiskUse=0, returnKey=0, requestResumeToken=0
-ZXEAYT8AAAAABQAAAAB+YWEAAAAAAAAAAAAAAG5ubm4FAAAAAGZe
+ZXEAYT8AAAAABQAAAAB+YWEAAAAAAAAAAAAAAABubm5uBQAAAABmXg==
==== VARIATION: sbe, query={a: 1}, sort={a: 1}, proj={}, allowDiskUse=1, returnKey=0, requestResumeToken=0
-ZXEAYT8AAAAABQAAAAB+YWEAAAAAAAAAAAAAAHRubm4FAAAAAGZe
+ZXEAYT8AAAAABQAAAAB+YWEAAAAAAAAAAAAAAAB0bm5uBQAAAABmXg==
==== VARIATION: sbe, query={a: 1}, sort={a: 1}, proj={}, allowDiskUse=0, returnKey=0, requestResumeToken=0
-ZXEAYT8AAAAABQAAAAB+YWEAAAAAAAAAAAAAAGZubm4FAAAAAGZe
+ZXEAYT8AAAAABQAAAAB+YWEAAAAAAAAAAAAAAABmbm5uBQAAAABmXg==
==== VARIATION: sbe, query={a: 1}, sort={a: 1}, proj={}, allowDiskUse=0, returnKey=1, requestResumeToken=0
-ZXEAYT8AAAAABQAAAAB+YWEAAAAAAAAAAAAAAG50bm4FAAAAAGZe
+ZXEAYT8AAAAABQAAAAB+YWEAAAAAAAAAAAAAAABudG5uBQAAAABmXg==
==== VARIATION: sbe, query={a: 1}, sort={a: 1}, proj={}, allowDiskUse=0, returnKey=0, requestResumeToken=0
-ZXEAYT8AAAAABQAAAAB+YWEAAAAAAAAAAAAAAG5uZm4FAAAAAGZe
+ZXEAYT8AAAAABQAAAAB+YWEAAAAAAAAAAAAAAABubmZuBQAAAABmXg==
==== VARIATION: sbe, query={a: 1}, sort={a: 1}, proj={}, allowDiskUse=0, returnKey=0, requestResumeToken=0
-ZXEAYT8AAAAABQAAAAB+YWEAAAAKAAAAAAAAAAAAAABubm5uBQAAAABmXg==
+ZXEAYT8AAAAABQAAAAB+YWEAAAAACgAAAAAAAAAAAAAAbm5ubgUAAAAAZl4=
==== VARIATION: sbe, query={a: 1}, sort={a: 1}, proj={}, allowDiskUse=0, returnKey=0, requestResumeToken=0
-ZXEAYT8AAAAABQAAAAB+YWEAAAAAAAAACgAAAAAAAABubm5uBQAAAABmXg==
+ZXEAYT8AAAAABQAAAAB+YWEAAAAAAAAAAAoAAAAAAAAAbm5ubgUAAAAAZl4=
==== VARIATION: sbe, query={a: 1}, sort={a: 1}, proj={}, allowDiskUse=0, returnKey=0, requestResumeToken=0
-ZXEAYT8AAAAABQAAAAB+YWEAAAAAAAAAAAAAAG5ubm4FAAAAAGZe
+ZXEAYT8AAAAABQAAAAB+YWEAAAAAAAAAAAAAAABubm5uBQAAAABmXg==
==== VARIATION: sbe, query={a: 1}, sort={a: 1}, proj={}, allowDiskUse=0, returnKey=0, requestResumeToken=0
-ZXEAYT8AAAAABQAAAAB+YWEAAAAAAAAAAAAAAG5ubm4FAAAAAGZe
+ZXEAYT8AAAAABQAAAAB+YWEAAAAAAAAAAAAAAABubm5uBQAAAABmXg==
==== VARIATION: sbe, query={a: 1}, sort={}, proj={}, allowDiskUse=0, returnKey=0, requestResumeToken=1
-ZXEAYT8AAAAABQAAAAAAAAAAAAAAAAAAAG5udG4YAAAAEiRyZWNvcmRJZAABAAAAAAAAAABmXg==
+ZXEAYT8AAAAABQAAAAAAAAAAAAAAAAAAAABubnRuGAAAABIkcmVjb3JkSWQAAQAAAAAAAAAAZl4=
diff --git a/src/mongo/db/test_output/query/canonical_query_encoder_test/compute_key_s_b_e_with_pipeline.txt b/src/mongo/db/test_output/query/canonical_query_encoder_test/compute_key_s_b_e_with_pipeline.txt
index fde58d486b6..1df88586f46 100644
--- a/src/mongo/db/test_output/query/canonical_query_encoder_test/compute_key_s_b_e_with_pipeline.txt
+++ b/src/mongo/db/test_output/query/canonical_query_encoder_test/compute_key_s_b_e_with_pipeline.txt
@@ -1,12 +1,12 @@
==== VARIATION: sbe, query={a: 1}, sort={}, proj={}
-ZXEAYT8AAAAABQAAAAAAAAAAAAAAAAAAAG5ubm4FAAAAAGZe
+ZXEAYT8AAAAABQAAAAAAAAAAAAAAAAAAAABubm5uBQAAAABmXg==
==== VARIATION: sbe, query={a: 1}, sort={}, proj={}
-ZXEAYT8AAAAABQAAAAAAAAAAAAAAAAAAAG5ubm4FAAAAAGZeWgAAAAMkbG9va3VwAEwAAAACZnJvbQAMAAAAZm9yZWlnbmNvbGwAAmFzAAMAAABhcwACbG9jYWxGaWVsZAACAAAAYQACZm9yZWlnbkZpZWxkAAIAAABiAAAA
+ZXEAYT8AAAAABQAAAAAAAAAAAAAAAAAAAABubm5uBQAAAABmXloAAAADJGxvb2t1cABMAAAAAmZyb20ADAAAAGZvcmVpZ25jb2xsAAJhcwADAAAAYXMAAmxvY2FsRmllbGQAAgAAAGEAAmZvcmVpZ25GaWVsZAACAAAAYgAAAA==
==== VARIATION: sbe, query={a: 1}, sort={}, proj={}
-ZXEAYT8AAAAABQAAAAAAAAAAAAAAAAAAAG5ubm4FAAAAAGZeWwAAAAMkbG9va3VwAE0AAAACZnJvbQAMAAAAZm9yZWlnbmNvbGwAAmFzAAMAAABhcwACbG9jYWxGaWVsZAADAAAAYTEAAmZvcmVpZ25GaWVsZAACAAAAYgAAAA==
+ZXEAYT8AAAAABQAAAAAAAAAAAAAAAAAAAABubm5uBQAAAABmXlsAAAADJGxvb2t1cABNAAAAAmZyb20ADAAAAGZvcmVpZ25jb2xsAAJhcwADAAAAYXMAAmxvY2FsRmllbGQAAwAAAGExAAJmb3JlaWduRmllbGQAAgAAAGIAAAA=
==== VARIATION: sbe, query={a: 1}, sort={}, proj={}
-ZXEAYT8AAAAABQAAAAAAAAAAAAAAAAAAAG5ubm4FAAAAAGZeWwAAAAMkbG9va3VwAE0AAAACZnJvbQAMAAAAZm9yZWlnbmNvbGwAAmFzAAMAAABhcwACbG9jYWxGaWVsZAACAAAAYQACZm9yZWlnbkZpZWxkAAMAAABiMQAAAA==
+ZXEAYT8AAAAABQAAAAAAAAAAAAAAAAAAAABubm5uBQAAAABmXlsAAAADJGxvb2t1cABNAAAAAmZyb20ADAAAAGZvcmVpZ25jb2xsAAJhcwADAAAAYXMAAmxvY2FsRmllbGQAAgAAAGEAAmZvcmVpZ25GaWVsZAADAAAAYjEAAAA=
==== VARIATION: sbe, query={a: 1}, sort={}, proj={}
-ZXEAYT8AAAAABQAAAAAAAAAAAAAAAAAAAG5ubm4FAAAAAGZeWwAAAAMkbG9va3VwAE0AAAACZnJvbQAMAAAAZm9yZWlnbmNvbGwAAmFzAAQAAABhczEAAmxvY2FsRmllbGQAAgAAAGEAAmZvcmVpZ25GaWVsZAACAAAAYgAAAA==
+ZXEAYT8AAAAABQAAAAAAAAAAAAAAAAAAAABubm5uBQAAAABmXlsAAAADJGxvb2t1cABNAAAAAmZyb20ADAAAAGZvcmVpZ25jb2xsAAJhcwAEAAAAYXMxAAJsb2NhbEZpZWxkAAIAAABhAAJmb3JlaWduRmllbGQAAgAAAGIAAAA=
==== VARIATION: sbe, query={a: 1}, sort={}, proj={}
-ZXEAYT8AAAAABQAAAAAAAAAAAAAAAAAAAG5ubm4FAAAAAGZeWgAAAAMkbG9va3VwAEwAAAACZnJvbQAMAAAAZm9yZWlnbmNvbGwAAmFzAAMAAABhcwACbG9jYWxGaWVsZAACAAAAYQACZm9yZWlnbkZpZWxkAAIAAABiAAAAXQAAAAMkbG9va3VwAE8AAAACZnJvbQAMAAAAZm9yZWlnbmNvbGwAAmFzAAQAAABhczEAAmxvY2FsRmllbGQAAwAAAGExAAJmb3JlaWduRmllbGQAAwAAAGIxAAAA
+ZXEAYT8AAAAABQAAAAAAAAAAAAAAAAAAAABubm5uBQAAAABmXloAAAADJGxvb2t1cABMAAAAAmZyb20ADAAAAGZvcmVpZ25jb2xsAAJhcwADAAAAYXMAAmxvY2FsRmllbGQAAgAAAGEAAmZvcmVpZ25GaWVsZAACAAAAYgAAAF0AAAADJGxvb2t1cABPAAAAAmZyb20ADAAAAGZvcmVpZ25jb2xsAAJhcwAEAAAAYXMxAAJsb2NhbEZpZWxkAAMAAABhMQACZm9yZWlnbkZpZWxkAAMAAABiMQAAAA==
diff --git a/src/mongo/db/test_output/query/canonical_query_encoder_test/compute_key_s_b_e_with_read_concern.txt b/src/mongo/db/test_output/query/canonical_query_encoder_test/compute_key_s_b_e_with_read_concern.txt
index 15bf8272a09..a9353b5dac0 100644
--- a/src/mongo/db/test_output/query/canonical_query_encoder_test/compute_key_s_b_e_with_read_concern.txt
+++ b/src/mongo/db/test_output/query/canonical_query_encoder_test/compute_key_s_b_e_with_read_concern.txt
@@ -1,6 +1,6 @@
==== VARIATION: sbe, query={a: 1}, sort={a: 1}, proj={}, allowDiskUse=0, returnKey=0, requestResumeToken=0
-ZXEAYT8AAAAABQAAAAB+YWEAAAAAAAAAAAAAAG5ubm4FAAAAAGZe
+ZXEAYT8AAAAABQAAAAB+YWEAAAAAAAAAAAAAAABubm5uBQAAAABmXg==
==== VARIATION: sbe, query={a: 1}, sort={a: 1}, proj={}, allowDiskUse=0, returnKey=0, requestResumeToken=0
-ZXEAYT8AAAAABQAAAAB+YWEAAAAAAAAAAAAAAG5ubm4FAAAAAGZe
+ZXEAYT8AAAAABQAAAAB+YWEAAAAAAAAAAAAAAABubm5uBQAAAABmXg==
==== VARIATION: sbe, query={a: 1}, sort={a: 1}, proj={}, allowDiskUse=0, returnKey=0, requestResumeToken=0
-ZXEAYT8AAAAABQAAAAB+YWEAAAAAAAAAAAAAAG5ubm4FAAAAAHRe
+ZXEAYT8AAAAABQAAAAB+YWEAAAAAAAAAAAAAAABubm5uBQAAAAB0Xg==
diff --git a/src/mongo/db/test_output/query/canonical_query_encoder_test/compute_key_with_api_strict.txt b/src/mongo/db/test_output/query/canonical_query_encoder_test/compute_key_with_api_strict.txt
index b78e050d792..badc3bdf912 100644
--- a/src/mongo/db/test_output/query/canonical_query_encoder_test/compute_key_with_api_strict.txt
+++ b/src/mongo/db/test_output/query/canonical_query_encoder_test/compute_key_with_api_strict.txt
@@ -3,6 +3,6 @@ an@ff
==== VARIATION: query={}, sort={}, proj={}
an@ft
==== VARIATION: sbe, query={}, sort={}, proj={}
-YW4ABQAAAAAAAAAAAAAAAAAAAG5ubm4FAAAAAGZe
+YW4ABQAAAAAAAAAAAAAAAAAAAABubm5uBQAAAABmXg==
==== VARIATION: sbe, query={}, sort={}, proj={}
-YW4ABQAAAAAAAAEAAAAAAAAAAG5ubm4FAAAAAGZe
+YW4ABQAAAAAAAAEAAAAAAAAAAABubm5uBQAAAABmXg==
diff --git a/src/mongo/db/test_output/query/canonical_query_encoder_test/compute_key_with_needs_merge.txt b/src/mongo/db/test_output/query/canonical_query_encoder_test/compute_key_with_needs_merge.txt
new file mode 100644
index 00000000000..8a577dd3a4e
--- /dev/null
+++ b/src/mongo/db/test_output/query/canonical_query_encoder_test/compute_key_with_needs_merge.txt
@@ -0,0 +1,4 @@
+==== VARIATION: sbe, query={}, sort={}, proj={}
+YW4ABQAAAAAAAAAAAAAAAAAAAABubm5uBQAAAABmXj8AAAADJGdyb3VwADIAAAACX2lkAAMAAAAkYQADb3V0ABwAAAADJHN1bQARAAAAECRjb25zdAABAAAAAAAAAA==
+==== VARIATION: sbe, query={}, sort={}, proj={}, needsMerge=true
+YW4ABQAAAAAAAAABAAAAAAAAAABubm5uBQAAAABmXj8AAAADJGdyb3VwADIAAAACX2lkAAMAAAAkYQADb3V0ABwAAAADJHN1bQARAAAAECRjb25zdAABAAAAAAAAAA==