FriendsOfDoctrine / dbal-clickhouse

Doctrine DBAL driver for ClickHouse database
GNU General Public License v3.0
98 stars 80 forks source link

Symbol `?` in query's value #37

Open roma293 opened 4 years ago

roma293 commented 4 years ago

php v7.4 friendsofdoctrine/dbal-clickhouse v1.5.3 clickhouse-server: yandex/clickhouse-server:20.3.8.53 (image from official yandex hub.docker.com)

Table schema:

CREATE TABLE new_table (
    `id` Int32, 
    `payload` String, 
    `date` DateTime
) 
ENGINE = MergeTree 
PARTITION BY toYYYYMMDD(date) 
ORDER BY (id, payload, date) 
SETTINGS index_granularity = 8192;

Code example:

/** @var \FOD\DBALClickHouse\Connection $connection */
$connection = $this->getDoctrine()->getConnection('clickhouse');
$connection->insert('new_table', [
    'id' => 2,
    'payload' => 'test?o',
    'date' => (new DateTime())->format('Y-m-d H:i:s'),
]);

Result:

An exception occurred while executing 'INSERT INTO new_table (id, payload, date) VALUES (?, ?, ?)' with params [2, "test?o", "2020-05-14 13:57:42"]:

Cannot parse expression of type String here: 'test'2020-05-14 13:57:42'o', ?)
IN:INSERT INTO new_table (id, payload, date) VALUES (2, 'test'2020-05-14 13:57:42'o', ?)

If change code to:

/** @var \FOD\DBALClickHouse\Connection $connection */
$connection = $this->getDoctrine()->getConnection('clickhouse');
$data = [
    'id' => 2,
    'payload' => 'test?o',
    'date' => (new DateTime())->format('Y-m-d H:i:s'),
];
$query = sprintf(
    'INSERT INTO new_table (%s) VALUES (%s)',
    implode(', ', array_keys($data)),
    substr(str_repeat('?, ', count($data)), 0, -2)
);
$statement = $connection->prepare($query);
$statement->execute(array_values($data));

Result: insert is successful

LarexSetch commented 3 years ago

The problem in https://github.com/FriendsOfDoctrine/dbal-clickhouse/blob/master/src/ClickHouseStatement.php#L293 When the loop replacing ? to string with ? on the next iteration first found symbol ? will be replaced

P.S. @roma293 thank you for solution!