-
Notifications
You must be signed in to change notification settings - Fork 97
Data compression between the CH servers and the drivers #523
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
24b735f
6a8badc
7b92ea0
da17f18
a089e5d
64eab4d
347db71
937b78f
db61e10
b31874f
b15b466
19a0829
9e98da6
638008d
8c82dc3
f0c1f5d
d2c8c05
fae23ed
3a6ce31
d8942dd
76f625b
02dd8e4
773ed70
6541bf9
1384159
77e299c
a944fe6
1ce050c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -93,6 +93,7 @@ Poco::URI Connection::getUri() const { | |
| bool database_set = false; | ||
| bool default_format_set = false; | ||
| bool session_id_set = false; | ||
| bool enable_http_compression_set = false; | ||
|
|
||
| for (const auto& parameter : uri.getQueryParameters()) { | ||
| if (Poco::UTF8::icompare(parameter.first, "default_format") == 0) { | ||
|
|
@@ -118,6 +119,10 @@ Poco::URI Connection::getUri() const { | |
| uri.addQueryParameter("session_id", session_id); | ||
| } | ||
|
|
||
| if (enable_http_compression && !enable_http_compression_set) { | ||
| uri.addQueryParameter("enable_http_compression", enable_http_compression ? "1" : "0"); | ||
| } | ||
|
|
||
| return uri; | ||
| } | ||
|
|
||
|
|
@@ -411,6 +416,20 @@ void Connection::setConfiguration(const key_value_map_t & cs_fields, const key_v | |
| client_name = value; | ||
| } | ||
| } | ||
| else if (Poco::UTF8::icompare(key, INI_COMPRESS) == 0 || Poco::UTF8::icompare(key, INI_USE_COMPRESSION) == 0) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do I get it right that:
|
||
| recognized_key = true; | ||
| unsigned int typed_value = 0; | ||
| valid_value = | ||
| (value.empty() || | ||
| ( | ||
| Poco::NumberParser::tryParseUnsigned(value, typed_value) && | ||
| (typed_value == 1 || typed_value == 0) | ||
| ) || | ||
| isYesOrNo(value)); | ||
| if (valid_value) { | ||
| enable_http_compression = (typed_value == 1 || isYes(value)); | ||
| } | ||
| } | ||
|
|
||
| return std::make_tuple(recognized_key, valid_value); | ||
| }; | ||
|
|
@@ -428,6 +447,8 @@ void Connection::setConfiguration(const key_value_map_t & cs_fields, const key_v | |
| const auto & recognized_key = std::get<0>(res); | ||
| const auto & valid_value = std::get<1>(res); | ||
|
|
||
| // LOG("DSN: known attribute '" << key << "', valid value, '" << valid_value << "'"); | ||
|
|
||
| if (recognized_key) { | ||
| if (!valid_value) | ||
| throw std::runtime_error("DSN: bad value '" + value + "' for attribute '" + key + "'"); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| #include "driver/result_set.h" | ||
| #include "driver/driver.h" | ||
| #include "driver/format/ODBCDriver2.h" | ||
| #include "driver/format/RowBinaryWithNamesAndTypes.h" | ||
|
|
||
|
|
@@ -308,6 +309,13 @@ ResultReader::ResultReader(const std::string & timezone_, std::istream & raw_str | |
| { | ||
| } | ||
|
|
||
| ResultReader::ResultReader(const std::string & timezone_, std::istream & raw_stream, std::unique_ptr<ResultMutator> && mutator, std::unique_ptr<std::istream> && inflating_input_stream_) | ||
| : timezone(timezone_) | ||
| , stream(raw_stream, std::move(inflating_input_stream_)) | ||
| , result_mutator(std::move(mutator)) | ||
| { | ||
| } | ||
|
|
||
| bool ResultReader::hasResultSet() const { | ||
| return static_cast<bool>(result_set); | ||
| } | ||
|
|
@@ -323,15 +331,33 @@ std::unique_ptr<ResultMutator> ResultReader::releaseMutator() { | |
| return std::move(result_mutator); | ||
| } | ||
|
|
||
| std::unique_ptr<ResultReader> make_result_reader(const std::string & format, const std::string & timezone, std::istream & raw_stream, std::unique_ptr<ResultMutator> && mutator) { | ||
| if (format == "ODBCDriver2") { | ||
| return std::make_unique<ODBCDriver2ResultReader>(timezone, raw_stream, std::move(mutator)); | ||
| std::unique_ptr<ResultReader> | ||
| make_result_reader(const std::string &format, const std::string &timezone, | ||
| const std::string &compression, std::istream &raw_stream, | ||
| std::unique_ptr<ResultMutator> &&mutator) { | ||
| std::istream * stream_ptr = nullptr; | ||
| std::unique_ptr<std::istream> inflating_input_stream; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, this ownership model seems a bit clumsy, maybe it would be worth moving ownership of the wrapping stream to the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well spotted, ownership model is proved to be error prone. I moved holder from |
||
|
|
||
| if (compression == "gzip" || compression == "deflate") { | ||
| inflating_input_stream = make_unique<Poco::InflatingInputStream>(raw_stream, Poco::InflatingStreamBuf::STREAM_GZIP); | ||
| stream_ptr = inflating_input_stream.get(); | ||
| } else { | ||
| if (!compression.empty()) | ||
| LOG("Unknown compression method, assuming uncompressed"); | ||
| stream_ptr = &raw_stream; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just in case, if remote party sends compression="foobar", then it is silently assumed to be "no compression"... I suggest either throwing an error or at least writing a warning to a log. |
||
| } | ||
| else if (format == "RowBinaryWithNamesAndTypes") { | ||
|
|
||
| if (format == "ODBCDriver2") { | ||
| return std::make_unique<ODBCDriver2ResultReader>( | ||
| timezone, *stream_ptr, std::move(mutator), std::move(inflating_input_stream)); | ||
| } else if (format == "RowBinaryWithNamesAndTypes") { | ||
| if (!isLittleEndian()) | ||
| throw std::runtime_error("'" + format + "' format is supported only on little-endian platforms"); | ||
| throw std::runtime_error( | ||
| "'" + format + | ||
| "' format is supported only on little-endian platforms"); | ||
|
|
||
| return std::make_unique<RowBinaryWithNamesAndTypesResultReader>(timezone, raw_stream, std::move(mutator)); | ||
| return std::make_unique<RowBinaryWithNamesAndTypesResultReader>( | ||
| timezone, *stream_ptr, std::move(mutator), std::move(inflating_input_stream)); | ||
| } | ||
|
|
||
| throw std::runtime_error("'" + format + "' format is not supported"); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current implementation only adds the
enable_http_compressionparameter to the URI when it's set to true. This means if compression is enabled by default on the server side and you want to explicitly disable it, settingenable_http_compression=0in the connection string won't have any effect. Consider always adding the parameter when it's explicitly set (regardless of value):There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, 'if compression is enabled by default on the server side' it is fine, data will be compressed.