NAME
DBIO::ClickHouse::Util - Shared ClickHouse-specific helper functions for DBIO
VERSION
version 0.900004
SYNOPSIS
use DBIO::ClickHouse::Util qw(mask_error_details);
my $message = mask_error_details(
q{Code: 6. DB::Exception: Cannot parse string 'secret' as Int32: syntax error at begin of string. (CANNOT_PARSE_TEXT)}
);
# Code: 6. DB::Exception: Cannot parse string '***' as Int32: syntax error at begin of string. (CANNOT_PARSE_TEXT)
DESCRIPTION
Helpers of the ClickHouse driver that do not belong to one class.
METHODS
mask_error_details
my $message = mask_error_details($message);
ClickHouse writes the offending value into its error text, also when the value was a bind: the MySQL-wire driver puts the bind values into the statement on the client, and the engine quotes the statement it received. The family's rule is that a message names keys, columns and options, never values; the engine's text is the driver's to keep to it, and this is where the driver does.
Every value in the sentences of the engine that quote one is replaced by ***, and what the caller needs to find the cause stays: the error code, the type, the column, the constraint, the table, the position of a syntax error.
Code: 6. DB::Exception: Cannot parse string '***' as Int32: syntax error at begin of string. ...
Code: 53. DB::Exception: Cannot convert string '***' to type Int32 ...
Code: 38. DB::Exception: Cannot parse date here: ***: Cannot parse Date from String ...
Code: 6. DB::Exception: Cannot parse string '***' as Int32: ...: In scope SELECT CAST(***, ***) FROM t. (CANNOT_PARSE_TEXT)
Code: 62. DB::Exception: Syntax error: failed at position 1 (UPDATE): UPDATE t SET id = *** WHERE id = ***. Expected one of: ...
Code: 469. DB::Exception: Constraint `pos` for table d.t (...) is violated at row 1. Expression: (a > 0). Column values: a = ***. (VIOLATED_CONSTRAINT)
The statement the engine quotes (In scope ..., While processing ..., the rest of a syntax error) keeps its identifiers, keywords and function names; every literal in it, string or number, is replaced by *** without quotes, also the type names of a CAST. The plan of a failed function (while executing 'FUNCTION ...') carries the constants of the statement and is replaced as a whole. The token a syntax error stopped at stays when it is a word or punctuation and is replaced when it is a literal. The values of Column values: are read as name = value pairs; where the text is not readable in one way only (a compound value, a column twice) all of it is masked.
A message the sentences do not know is returned as it is, and so is one without a value, Cannot UPDATE key column `id`..
Two limits are known. A value the engine writes without quotes ends where the next sentence of the engine begins (: Cannot parse Date from String, . (CODE)); a value that contains such a delimiter is masked up to it and its rest stays. And a bare word in a quoted statement is kept because it is indistinguishable from the name of a column; a value the engine writes there without quotes and without a form of a literal is not recognised. The values bound to the statement are taken out of the text beforehand by the storage ("_mask_error_values" in DBIO::ClickHouse::Storage) wherever they stand, which covers both for a value of at least four characters.
SEE ALSO
DBIO::ClickHouse::Storage - the storage whose errors this masks
AUTHOR
DBIO Authors
COPYRIGHT AND LICENSE
Copyright (C) 2026 DBIO Authors
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.