-
Notifications
You must be signed in to change notification settings - Fork 100
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
Encapsulate format logic within Statement and helper classes #162
base: master
Are you sure you want to change the base?
Encapsulate format logic within Statement and helper classes #162
Conversation
@leboshi need resolve conflicts |
…rgument to `execute`.
…act ActiveRecord code.
…a request without appending a `FORMAT` clause.
…ce to indicate that they're internal/private.
* Restore support for table/database creation with request settings. * Move improved "DB::Exception" handling into ResponseProcessor.
2b4c2dc
to
7fb1a7f
Compare
Sorry that took so long! It's been a busy couple months. |
lib/active_record/connection_adapters/clickhouse/schema_statements.rb
Outdated
Show resolved
Hide resolved
lib/active_record/connection_adapters/clickhouse/schema_statements.rb
Outdated
Show resolved
Hide resolved
module ConnectionAdapters | ||
module Clickhouse | ||
class Statement | ||
class FormatManager |
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.
This incorrect logic for request:
SELECT * FROM table WHERE column LIKE 'insert into%'
We have a method exec_insert
which clearly indicates that this is an insert and what response format should be used.
lib/active_record/connection_adapters/clickhouse/statement/response_processor.rb
Outdated
Show resolved
Hide resolved
end | ||
|
||
def format_from_json_compact_each_row_with_names_and_types(body) | ||
rows = body.split("\n").map { |row| parse_json_payload(row) } |
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.
body.each_line.map
should be more efficient since it doesn't need to allocate an array before iterating over it to parse the JSON.
…erring within FormatManager
OK, all the above should be resolved! Thanks to both of you for the review! |
Summary
Handling different I/O formats added a lot of complexity to the codebase: whenever a specific format is needed or requested, that format has to be passed around to whatever handles the response so that it can be parsed correctly. Various methods around parsing responses according to different formats have been growing and collecting within the SchemaStatements module, where they don't really seem to belong.
process_response
also has nestedcase
statements that are hard to grok.This PR extracts three helper classes:
FormatManager
to determine when to automatically apply aFORMAT
clause to a SQL statement,ResponseProcessor
to parse the response according to the requested format and handle errors, andStatement
to couple them together and maintain the format state.The first two are internal to Statement and have no reason to be used directly outside of it.
Breaking Changes
DEFAULT_RESPONSE_FORMAT
constant into ClickhouseAdapter, since it's now used by helper classes instead of only within the SchemaStatements module.Deprecations
format:
keyword toexecute
is deprecated (with no specific horizon yet) in favor of the newwith_response_format
wrapper method. The deprecation warning points users to the new method.execute
anddo_execute
had effectively identical signatures, sodo_execute
has been deprecated.Next Steps
The
skip_format?
check in the FormatManager really just includes checks that were already being run plus a few more we've found. They are not comprehensive. Ideally, we should go through the documentation to identify exactly which statements do or don't accept aFORMAT
clause.The chain of conditionals is also less than ideal. It's ugly but manageable for now. Whenever the complete list of inclusions/exclusions materializes, it may be better to apply a filter pattern to clean up the checks.