fix(logs): stop hasToken and hasAny/hasAll 500s on separator and big int needles - #12261
Merged
Conversation
…int needles hasToken(body, <needle>) returned a 500 whenever the needle contained a token separator or whitespace (ClickHouse code 36). Validate the needle up front in conditionForHasToken (the single choke point for both legacy and JSON modes) and return a clean 400 pointing at CONTAINS instead. hasAny/hasAll on a legacy body array returned a 500 for a quoted integer needle >= 2^32: clickhouse-go binds it as a concrete Array(UInt64), which has no supertype with the Array(Nullable(Int64)) extraction that the function must unify (code 386). CAST the needle array to Array(Int64) to match the extraction. Scalar has() and the scalar OR-fallback are value-level and unaffected.
tushar-signoz
force-pushed
the
fix-has-function-bugs
branch
from
July 24, 2026 11:22
e493af1 to
e905af3
Compare
tushar-signoz
marked this pull request as ready for review
July 24, 2026 11:24
tushar-signoz
requested review from
srikanthccv and
therealpandey
as code owners
July 24, 2026 11:24
therealpandey
approved these changes
Jul 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two pre-existing logs-filter 500s in the has-family functions, each turned into correct behavior.
What
hasTokenseparator/whitespace needle → clean 400 (was 500, both modes). A needle likeuser_id, an IP, or a UUID contains a ClickHouse token separator; CH rejects it (code 36, "Needle must not contain whitespace or separator characters") and it surfaced as a 500. Now validated up front inconditionForHasToken— the single choke point both the legacy and JSON body paths flow through — returning a 400 that points atCONTAINSfor multi-token search.hasAny/hasAllon a quoted integer ≥ 2³² → real match (was 500, legacy flag-off only). clickhouse-go binds the needle as a concreteArray(UInt64), which has no supertype with theArray(Nullable(Int64))extraction thathasAny/hasAllmust unify (code 386, NO_COMMON_TYPE). The needle array is nowCAST(… AS Array(Int64))to match the extraction.Guardrails
hasToken: one guard at the single choke point; no SQL change for valid single-token needles.hasAny/hasAll: the CAST is scoped to the Int64 element type and the legacy path only — JSON mode already handles big ints via typedbody_v2columns, so it's untouched. String/Float64 SQL is unchanged.has()and the scalar OR-fallback are value-level coercion and don't hit the array supertype, so they're unaffected (verified they don't 386).Notes
Array(UInt64)needle for bothhasAny/hasAll, confirmed theCAST … AS Array(Int64)returns the correct match, and confirmed the scalarIN/=fallback does not 386.Testing
hasTokenseparator/whitespace needles → 400; legacy Int64hasAny/hasAllbig-int needles assert theCAST(… AS Array(Int64))in the generated SQL.hasTokenseparator → 400 (legacy + JSON);hasAny/hasAllbig int → 200 with an exact single match (renamed…_errors→…_matches).make go-lint→ 0 issues;make py-fmt/make py-lintclean.