Skip to content

Update dependency ClickHouse.Driver to 1.3.0#219

Open
renovate[bot] wants to merge 1 commit into
masterfrom
renovate/clickhouse.driver-1.x
Open

Update dependency ClickHouse.Driver to 1.3.0#219
renovate[bot] wants to merge 1 commit into
masterfrom
renovate/clickhouse.driver-1.x

Conversation

@renovate

@renovate renovate Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Confidence
ClickHouse.Driver 1.2.01.3.0 age confidence

Release Notes

ClickHouse/clickhouse-cs (ClickHouse.Driver)

v1.3.0

Compare Source

New Features:

  • POCO reads: stream query results directly into your own classes.
    • ClickHouseClient.QueryAsync<T>(...) returns IAsyncEnumerable<T>; rows are materialized lazily and the underlying reader is disposed when enumeration completes, faults, or stops early.
    • ClickHouseDataReader.MapTo<T>() materializes the current row into a registered POCO without advancing the reader.
    • Registration: use RegisterPocoType<T>(), it sets up both the insert and read mappings, validating both up front. RegisterBinaryInsertType<T>() is unchanged and remains insert-only for backwards compatibility.
    • Type requirements: a public parameterless constructor and at least one public property with a public non-init setter. required properties are supported.
    • Column matching is case-sensitive (StringComparer.Ordinal); missing result columns leave properties at their default value, extra result columns are ignored.
    • No automatic conversions: type mismatches throw InvalidOperationException with the POCO type, property, column, and returned CLR type. Static mismatches fail fast at first MapTo<T>() call (or first iteration of QueryAsync<T>()) before any rows are materialized.
    • Registration diagnostics: when a LoggerFactory is configured, RegisterPocoType<T>() / RegisterBinaryInsertType<T>() emit a Debug-level log (category ClickHouse.Driver.Client) listing which properties mapped to which columns and which were skipped and why.
  • Nested array parameters and multidimensional arrays (issue #​320): Array(Array(T)) and deeper nestings are now supported end-to-end via parameterized queries, binary inserts, and bulk inserts. Both jagged CLR shapes (T[][], List<List<T>>) and rectangular multidimensional CLR shapes (T[,], T[,,], …) are accepted on the write path. Reads return jagged T[][] via GetValue; callers who know their data is rectangular can use reader.GetFieldValue<T[,]>(ordinal) and the driver materialises the column as that CLR shape (throws InvalidOperationException on ragged data).
  • ValueTuple support on write path: System.ValueTuple values (C# tuple literals like (1, "hello")) are now supported in binary inserts, HTTP parameterized queries, and automatic type inference. Tuples with more than 7 elements are correctly flattened from the compiler-generated rest-nesting structure. Note: if you need exactly 7 scalar elements followed by a nested tuple as the 8th element, wrap the inner tuple in an extra layer (e.g., Tuple.Create(1,...,7, Tuple.Create(Tuple.Create("a","b")))) so the driver can distinguish it from TRest nesting.
  • Configurable parameter value formatting: new IParameterFormatter interface allowing configuration of how parameter values are serialized for HTTP transport (sibling to IParameterTypeResolver, which governs type resolution). Set ParameterFormatter on ClickHouseClientSettings to override the built-in serialization logic for any CLR type (e.g., custom DateTime precision, decimal culture, string escaping). Includes one implementation, DictionaryParameterFormatter, for simple CLR-type → format-function mappings. Return null from the formatter to fall through to the built-in formatter. Can also be set per-query via QueryOptions.ParameterFormatter. The formatter is also invoked for every element inside composite values (Array, Tuple, Map, Nested); see docs for quoting caveats when formatting string-like types inside composites.
  • Per-query Accept-Encoding override: new QueryOptions.AcceptEncoding (mirrored on ClickHouseCommand.AcceptEncoding) replaces the default gzip, deflate Accept-Encoding header for a single request. Supports multiple algorithms with quality weights (e.g. "zstd, gzip;q=0.5") and forces enable_http_compression=1 on the URL so ClickHouse honours the header. For codecs the BCL cannot decode (zstd, lz4) the underlying HttpClient must be configured with AutomaticDecompression = None and the body consumed via ExecuteRawResultAsync.
  • ClickHouseRawResult.ContentEncoding: exposes the response body's Content-Encoding for callers using ExecuteRawResultAsync to decode it themselves; identity is normalized to null.
  • Customizable read value conversion: new IReadValueConverter interface allows transformation of values returned by the data reader after deserialization (e.g., DateTime.SpecifyKind to set UTC kind, string trimming/normalization). Set ReadValueConverter on ClickHouseClientSettings to apply transformations globally, or override per-query via QueryOptions.ReadValueConverter. The converter intercepts GetValue() and GetFieldValue<T>() calls, and is also applied during POCO materialization (MapTo<T>() / QueryAsync<T>()). When no converter is set, there is zero performance overhead. Includes one implementation, DictionaryReadValueConverter, with a fluent .For<T>(value => …) registration for dispatch based on CLR type.
  • Added a ClickHouseDataReader.GetFieldValue<T>(string name) overload that resolves the column by name, complementing the existing ordinal-based overload.
  • Application-identity tagging in User-Agent: new ClickHouseClientSettings.ApplicationInfo property: an IReadOnlyDictionary<string, string> of free-form tags (e.g. app, ver, env) appended to the HTTP User-Agent header as a comment token (e.g. (app:MyApp; ver:2.3.1; env:prod)).
  • Server-side Identifier query-parameter type: {name:Identifier} parameters (and explicit ClickHouseDbParameter.ClickHouseType = "Identifier") are now supported, letting you safely bind a database/table/column name instead of a quoted string literal — e.g. CREATE DATABASE {name:Identifier} or SELECT {col:Identifier} FROM t. The value is sent verbatim and the server substitutes it as a bare SQL identifier, applying its own backtick quoting/escaping, so identifiers containing special characters (including backticks) round-trip safely with no client-side escaping. Previously these threw ArgumentException: Unknown type: Identifier (surfaced from clickhouse-go#1635).
  • Configurable response read buffer size: new ClickHouseClientSettings.ReadBufferSize (and connection-string key ReadBufferSize) controls the size of the buffer used when reading HTTP query responses. Behavioral change: the default has been lowered from 512 KiB to 8 KiB. The previous 512KiB size exceeded the large object heap limit and could cause substantial performance issues due to GC. Workloads with large responses that prefer fewer buffer refills can set a larger value.

Improvements:

  • HTTP parameter mismatch errors now include the parameter name, the full ClickHouse type, and the value's runtime CLR type. The previous message ("Cannot convert 219 to Array(UInt8)") collapsed the outer type, omitted which parameter failed, and didn't say what the value actually was.
  • GetFieldValue<T[,]> errors are now categorised by cause. InvalidCastException covers type-structure mismatches: the column is null/DBNull, the value isn't a collection, the source's structural depth differs from the target rank (shallower or deeper), or a leaf is the wrong scalar type or null into a non-nullable value-type target. Messages include the column ordinal, target CLR type, and offending indices where applicable. InvalidOperationException is reserved for shape-validation failures — the value's structure matches T but rows are ragged or an intermediate row is null. Previously, structural-depth mismatches and a null leaf into e.g. int[,] either threw InvalidOperationException or were silently coerced to default(int).

Bug Fixes:

  • Breaking Change: Fixed timezone shift for @-style DateTime/DateTimeOffset parameters on non-UTC servers (issue #​350). When a parameter's ClickHouse type was inferred (no explicit {name:Type} hint in SQL and no parameter.ClickHouseType set), the driver previously emitted a bare DateTime hint and the server parsed the wire wall-clock in session_timezone/server tz — silently shifting instant-bearing values by the server's offset. Inferred types for DateTime { Kind: Utc or Local } and DateTimeOffset are now sent as DateTime('UTC'), preserving the instant across any server timezone. Explicit hints ({name:DateTime} in SQL or parameter.ClickHouseType) are untouched, users who specify the type continue to own timezone correctness.
  • Fixed silent 32-bit wraparound on the binary write path for DateTime/DateTime32 values outside ClickHouse's supported range (1970-01-01 .. 2106-02-07 06:28:15 UTC). Out-of-range values, e.g. new DateTime(1900, 1, 1), were being cast through a 32-bit signed int and reinterpreted as UInt32 by the server, producing real-but-wrong timestamps (e.g. 2036-02-07). The same audit fixed analogous silent out-of-range writes for Date32 (server would clamp to [1900-01-01, 2299-12-31]) and tightened the existing Date OverflowException into a descriptive ArgumentOutOfRangeException. All four types now throw ArgumentOutOfRangeException at Write time naming the column type and supported range.
  • Fixed silent wall-clock shift for DateTime and DateTime64 columns declared with ClickHouse's synthetic Fixed/UTC±HH:MM:SS timezone names (e.g. DateTime('Fixed/UTC+05:30:00')). These names are not in the IANA TZDB, so GetZoneOrNull returned null, causing the driver to interpret the stored instant as UTC and return a value shifted by the column's offset. The driver now recognises the Fixed/UTC pattern and constructs a correct fixed-offset DateTimeZone from it (issue #​370).
  • Fixed HTTP parameter serialization for Date, DateTime, and DateTime64 values inside composite types such as Array, Tuple, Map, and Variant. These values are now quoted correctly when sent over HTTP.
  • Fixed type inference for System.Tuple with more than 7 elements. The TRest nesting was not being flattened, causing the 8th+ elements to be inferred as nested tuple types instead of their actual flat types. This could lead to incorrect ClickHouse type inference and serialization errors.
  • Fixed parsing of enum labels containing escaped quotes, parentheses, and = characters. This fixes cases like variantType() on Variant(String, DateTime('UTC')), which could previously round-trip through the driver as an empty string.
  • Fixed ClickHouseServerException.Message returning compressed binary bytes when the server returned a non-2xx response with a Content-Encoding header. The driver now decompresses gzip / deflate / brotli error bodies before attaching them to the exception. Unknown codecs (zstd, lz4) yield a placeholder pointing at system.query_log.

Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants