Skip to content
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

bug with array query params #418

Open
zerlok opened this issue Feb 26, 2024 · 0 comments
Open

bug with array query params #418

zerlok opened this issue Feb 26, 2024 · 0 comments
Labels

Comments

@zerlok
Copy link

zerlok commented Feb 26, 2024

Describe the bug

can't pass array parameters to clickhouse driver ordinary statements

To Reproduce

Setup

# setup client, connect to CH
client = Client(...)

# create  users table
client.execute("""
CREATE TABLE IF NOT EXISTS users (
    `id` Int32,
    `name` String
) ENGINE = MergeTree()
	PRIMARY KEY (id)
""")

# insert users test data
client.execute(
   query="""INSERT INTO users (`id`, `name`) VALUES""",
   params=[
      {'id': 0, 'name': 'user-name-000'},
      {'id': 1, 'name': 'user-name-001'},
      {'id': 2, 'name': 'user-name-002'},
      {'id': 3, 'name': 'user-name-003'},
   ],
)

Then execute a valid CH SQL with parameters:

SELECT * FROM users WHERE id IN {ids:Array(Int32)} ORDER BY id
print(client.execute(
   query="""SELECT * FROM users WHERE id IN {ids:Array(Int32)} ORDER BY id""",
   params={"ids": [2, 3]},
))

Throws the exception:

DB::ParsingException: Cannot parse input: expected ']' at end of stream.: value [ cannot be parsed as Array(Int32) for query parameter 'ids'

Traceback (without private files):

.venv/lib/python3.9/site-packages/clickhouse_driver/client.py:373: in execute
    rv = self.process_ordinary_query(
.venv/lib/python3.9/site-packages/clickhouse_driver/client.py:571: in process_ordinary_query
    return self.receive_result(with_column_types=with_column_types,
.venv/lib/python3.9/site-packages/clickhouse_driver/client.py:204: in receive_result
    return result.get_result()
.venv/lib/python3.9/site-packages/clickhouse_driver/result.py:50: in get_result
    for packet in self.packet_generator:
.venv/lib/python3.9/site-packages/clickhouse_driver/client.py:220: in packet_generator
    packet = self.receive_packet()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <clickhouse_driver.client.Client object at 0x7f3511d1b970>

    def receive_packet(self):
        packet = self.connection.receive_packet()
    
        if packet.type == ServerPacketTypes.EXCEPTION:
>           raise packet.exception
E           clickhouse_driver.errors.ServerException: Code: 27.
E           DB::ParsingException. DB::ParsingException: Cannot parse input: expected ']' at end of stream.: value [ cannot be parsed as Array(Int32) for query parameter 'ids'. Stack trace:
E           
E           0. DB::Exception::Exception(DB::Exception::MessageMasked&&, int, bool) @ 0xe3b7135 in /usr/bin/clickhouse
E           1. ? @ 0xe416ae4 in /usr/bin/clickhouse
E           2. DB::throwAtAssertionFailed(char const*, DB::ReadBuffer&) @ 0xe4169e1 in /usr/bin/clickhouse
E           3. DB::SerializationArray::deserializeText(DB::IColumn&, DB::ReadBuffer&, DB::FormatSettings const&, bool) const @ 0x12dee6b8 in /usr/bin/clickhouse
E           4. DB::ReplaceQueryParameterVisitor::visitQueryParameter(std::shared_ptr<DB::IAST>&) @ 0x13eea1db in /usr/bin/clickhouse
E           5. DB::ReplaceQueryParameterVisitor::visitChildren(std::shared_ptr<DB::IAST>&) @ 0x13eed8f8 in /usr/bin/clickhouse
E           6. DB::ReplaceQueryParameterVisitor::visitChildren(std::shared_ptr<DB::IAST>&) @ 0x13eed8f8 in /usr/bin/clickhouse
E           7. DB::ReplaceQueryParameterVisitor::visitChildren(std::shared_ptr<DB::IAST>&) @ 0x13eed8f8 in /usr/bin/clickhouse
E           8. DB::ReplaceQueryParameterVisitor::visitChildren(std::shared_ptr<DB::IAST>&) @ 0x13eed8f8 in /usr/bin/clickhouse
E           9. DB::ReplaceQueryParameterVisitor::visitChildren(std::shared_ptr<DB::IAST>&) @ 0x13eed8f8 in /usr/bin/clickhouse
E           10. ? @ 0x13efc3e6 in /usr/bin/clickhouse
E           11. DB::executeQuery(String const&, std::shared_ptr<DB::Context>, bool, DB::QueryProcessingStage::Enum) @ 0x13efbc4d in /usr/bin/clickhouse
E           12. DB::TCPHandler::runImpl() @ 0x14cd2771 in /usr/bin/clickhouse
E           13. DB::TCPHandler::run() @ 0x14ce8279 in /usr/bin/clickhouse
E           14. Poco::Net::TCPServerConnection::start() @ 0x17c5ac34 in /usr/bin/clickhouse
E           15. Poco::Net::TCPServerDispatcher::run() @ 0x17c5be5b in /usr/bin/clickhouse
E           16. Poco::PooledThread::run() @ 0x17dd9207 in /usr/bin/clickhouse
E           17. Poco::ThreadImpl::runnableEntry(void*) @ 0x17dd6c3d in /usr/bin/clickhouse
E           18. ? @ 0x7f0cde78a609 in ?
E           19. __clone @ 0x7f0cde6af133 in ?

.venv/lib/python3.9/site-packages/clickhouse_driver/client.py:237: ServerException

Expected behavior

According to clickhouse doc, passed ids value should be casted to Array(Int32) on server side and query should be executed successfully with the following console output:

[(2, "user-name-002"), (3, "user-name-003")]

Versions

  • python: 3.9
  • clickhouse-driver version: 0.2.6
  • clickhouse server version (docker image): clickhouse/clickhouse-server:23.4.3.48-alpine

Notes

Simple int param works perfectly:

SELECT * FROM users WHERE id = {id:Int32}
print(client.execute("""SELECT * FROM users WHERE id = {id:Int32}""", params={'id': 7}"""))

Returns

[(7, "user-name-007")]

UPD: just found that clickhouse driver connection class performs parameter escaping and results in the following (added print statement between 708 and 709 lines this module

params={'ids': [2, 3]}; escaped={'ids': "'['2', '3']'"}

I guess the valid escaped value should be

params={'ids': [2, 3]}; escaped={'ids': "[2, 3]"}
@xzkostyan xzkostyan added the bug label Mar 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants