Unexpected readonly mode with specific string in query
Hi! I have experienced exceptions during inserts. It was weird, because out of approx 1B inserts, there were only few that failed on this exception:
In Statement.php line 172:
DatabaseException: default: Cannot execute query in readonly mode. (READONLY)
After some debugging i was able to create minimal query to replicate the problem:
INSERT INTO `log` (`response_body`) VALUES ('{a:b}')
TLDR: the query will match regexp in \ClickHouseDB\Query\Query::isUseInUrlBindingsParams()
public function isUseInUrlBindingsParams():bool
{
// 'query=select {p1:UInt8} + {p2:UInt8}' -F "param_p1=3" -F "param_p2=4"
return preg_match('#{[\w+]+:[\w+()]+}#',$this->sql);
}
Then it removes the readonly: 0 default value - readonly=1 will be added to the database connection URL.
How to replicate:
/** @var \ClickHouseDB\Client $clickhouse */
$clickhouse->insert(
'api_log',
[['{a:b}']],
['response_body'],
);
CREATE TABLE IF NOT EXISTS api_log (
response_body String NOT NULL
) ENGINE = MergeTree()
Expected behaviour - readonly: 0 in the URL (just changed value from {a:b} to {a: b}
Working workaround - adds space after : in the whole query if it matches the regexp:
preg_replace('#{([\w+]+):([\w+()]+)}#', '{$1: $2}', $value);
Is there any way, other than modify the string value inserting? Thank you
@JanMikes you can try https://github.com/simPod/PhpClickHouseClient since there's no magic between usercode and issuing request so it might suite you better.
Same here
A fix has been made