mirror of
https://github.com/hanzoai/datastore.git
synced 2026-09-26 13:55:07 +00:00
Preserve last-wins semantics for duplicate parameter names on the wire
readQueryParameters used NameToNameMap::emplace, which keeps the first occurrence of a duplicate key. The Settings-based path it replaced kept the last occurrence (BaseSettings::read overwrites the same custom setting entry on each occurrence of its name), so a driver relying on appending an override without deduplicating first would see different behavior. Use insert_or_assign to keep the old semantics, and add gtest coverage for the round trip and the duplicate-name case.
This commit is contained in:
@@ -9158,7 +9158,7 @@ NameToNameMap readQueryParameters(ReadBuffer & in)
|
||||
String value;
|
||||
ReadBufferFromOwnString buf(BaseSettingsHelpers::readString(in));
|
||||
readQuoted(value, buf);
|
||||
parameters.emplace(std::move(name), std::move(value));
|
||||
parameters.insert_or_assign(std::move(name), std::move(value));
|
||||
}
|
||||
return parameters;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <Common/Exception.h>
|
||||
#include <Core/BaseSettings.h>
|
||||
#include <Core/Settings.h>
|
||||
#include <Core/SettingsFields.h>
|
||||
#include <Core/SettingsEnums.h>
|
||||
#include <Core/Field.h>
|
||||
#include <IO/ReadBufferFromString.h>
|
||||
#include <IO/WriteBufferFromString.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -141,3 +145,34 @@ GTEST_TEST(SettingMySQLDataTypesSupport, SetInvalidString)
|
||||
ASSERT_TRUE(setting.changed);
|
||||
ASSERT_EQ(std::vector<MySQLDataTypesSupport>{}, setting.value);
|
||||
}
|
||||
|
||||
GTEST_TEST(QueryParameters, RoundTrip)
|
||||
{
|
||||
NameToNameMap parameters{{"max_threads", "0"}, {"name", "John's \\ Doe"}, {"empty", ""}};
|
||||
|
||||
WriteBufferFromOwnString out;
|
||||
writeQueryParameters(parameters, out);
|
||||
|
||||
ReadBufferFromString in(out.str());
|
||||
ASSERT_EQ(readQueryParameters(in), parameters);
|
||||
}
|
||||
|
||||
GTEST_TEST(QueryParameters, DuplicateNameOnTheWireLastOccurrenceWins)
|
||||
{
|
||||
/// A driver that appends an override without deduplicating first relies on the last
|
||||
/// occurrence of a repeated Parameter[] key winning, matching the pre-existing behavior
|
||||
/// of routing parameters through a Settings object (BaseSettings::read overwrites the
|
||||
/// same custom setting entry on each occurrence of its name).
|
||||
WriteBufferFromOwnString out;
|
||||
BaseSettingsHelpers::writeString("x", out);
|
||||
BaseSettingsHelpers::writeFlags(BaseSettingsHelpers::Flags::CUSTOM, out);
|
||||
BaseSettingsHelpers::writeString(SettingFieldCustom(Field(String("1"))).toString(), out);
|
||||
BaseSettingsHelpers::writeString("x", out);
|
||||
BaseSettingsHelpers::writeFlags(BaseSettingsHelpers::Flags::CUSTOM, out);
|
||||
BaseSettingsHelpers::writeString(SettingFieldCustom(Field(String("2"))).toString(), out);
|
||||
BaseSettingsHelpers::writeString(std::string_view{}, out);
|
||||
|
||||
ReadBufferFromString in(out.str());
|
||||
NameToNameMap parameters = readQueryParameters(in);
|
||||
ASSERT_EQ(parameters.at("x"), "2");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user